├── README.md ├── data ├── Amazon-book │ ├── item_list.txt │ ├── test.txt │ ├── train.txt │ └── user_list.txt ├── Gowella │ ├── item_list.txt │ ├── test.txt │ ├── train.txt │ └── user_list.txt └── ml-100k │ ├── test.txt │ └── train.txt ├── ngcf.py ├── run_ngcf.py └── utils ├── helper_functions.py ├── load_data.py └── parser.py /README.md: -------------------------------------------------------------------------------- 1 | # ngcf_pytorch_g61 2 | A reproduction of the Neural Graph Collaborative Filtering algorithm in PyTorch. 3 | 4 | Medium link: https://medium.com/@yusufnoor_88274/implementing-neural-graph-collaborative-filtering-in-pytorch-4d021dff25f3 5 | -------------------------------------------------------------------------------- /data/ml-100k/test.txt: -------------------------------------------------------------------------------- 1 | 0 188 32 264 221 252 89 30 59 259 79 234 5 103 48 95 257 211 142 106 261 96 209 156 241 147 251 90 9 240 254 102 117 53 23 195 35 22 189 225 178 186 134 67 165 137 88 62 248 31 39 74 33 270 118 157 168 161 198 49 191 10 34 126 24 250 54 138 18 171 2 | 1 296 312 110 294 241 293 24 272 236 274 295 3 | 2 334 244 322 349 340 347 259 338 316 337 321 343 335 4 | 3 356 49 327 257 209 326 323 358 361 5 | 4 423 362 240 153 41 401 99 371 420 412 88 399 409 213 363 380 98 426 225 28 49 437 249 449 430 364 445 238 424 180 403 382 209 374 6 | 5 85 13 257 356 179 476 18 187 212 132 135 134 124 487 192 525 458 80 422 485 469 247 533 99 21 481 509 309 185 511 426 11 308 167 172 126 461 215 110 7 236 7 | 6 31 491 377 450 575 527 558 152 192 267 299 9 653 284 53 656 141 586 504 569 209 460 165 682 541 130 120 447 259 272 125 547 680 621 160 71 258 479 96 611 587 659 582 615 99 608 76 599 592 156 214 323 596 193 435 619 443 416 203 401 651 634 669 385 386 543 512 144 432 473 355 213 614 442 462 364 124 274 143 11 606 163 308 151 8 | 7 337 181 510 55 240 509 565 9 | 8 486 482 401 10 | 9 174 99 284 503 504 488 199 134 175 434 496 268 185 557 55 651 473 81 509 210 530 696 431 691 662 512 628 477 58 481 588 429 69 524 39 178 11 | 10 724 109 745 229 520 720 721 732 572 240 523 93 50 11 748 257 744 653 316 404 78 68 23 97 38 41 526 317 82 426 212 746 12 | 11 299 734 470 317 169 132 194 201 215 327 87 237 479 13 | 12 197 55 228 779 120 149 450 337 876 225 1 427 912 262 787 813 415 302 785 611 189 383 906 442 538 856 889 153 362 664 316 616 545 623 865 275 267 804 339 23 26 384 476 108 877 209 549 537 3 837 461 605 199 349 341 854 879 553 882 67 708 870 116 790 493 564 176 182 732 746 354 866 402 491 567 223 760 409 774 654 156 788 560 667 575 345 198 447 159 872 896 831 69 834 57 601 196 506 750 510 37 287 309 274 565 473 183 173 48 234 164 766 778 437 208 186 444 548 175 361 59 357 279 521 217 7 792 833 14 | 13 212 473 356 150 602 167 595 11 318 426 264 922 172 653 185 381 587 15 | 14 221 923 273 306 936 0 299 307 302 13 926 332 14 279 865 309 281 180 327 16 | 15 193 760 26 417 160 75 181 155 232 628 194 466 142 199 509 108 236 207 0 320 97 731 126 17 | 16 743 116 149 285 470 6 110 474 627 18 | 17 949 190 970 13 609 275 731 56 185 427 422 130 450 69 431 5 653 78 415 44 286 167 152 210 518 8 780 131 581 41 65 156 22 177 516 268 207 174 80 381 142 21 87 957 632 492 611 19 | 18 152 309 381 257 287 293 20 | 19 207 175 117 185 930 143 97 173 21 49 21 | 20 557 323 947 298 456 217 994 233 291 843 594 117 440 716 984 293 930 546 321 299 853 558 199 572 636 563 982 768 979 989 320 875 0 22 | 21 376 172 185 293 682 120 221 237 406 1000 514 861 1002 162 16 999 383 429 3 49 23 | 22 257 527 187 418 132 218 69 511 709 293 13 274 282 855 81 6 385 229 78 431 203 193 95 540 693 366 55 88 422 448 386 24 | 23 366 426 257 215 357 68 175 728 288 401 654 222 6 517 275 25 | 24 356 126 479 49 168 196 113 473 403 182 22 132 133 611 691 656 26 | 25 124 285 314 475 321 925 315 125 180 830 23 1011 545 404 49 251 750 287 27 | 26 595 924 324 243 8 1016 122 28 | 27 200 379 233 49 11 894 183 217 221 449 435 442 199 194 608 184 446 229 95 447 30 443 195 528 29 | 28 188 268 301 263 11 30 | 29 434 1006 27 1012 241 257 258 1 891 314 402 28 31 | 30 483 503 320 78 31 1019 302 1018 191 32 | 31 289 150 116 121 287 8 306 110 49 33 | 32 871 342 244 677 270 338 287 34 | 33 311 241 331 328 323 287 35 | 34 1024 679 260 880 357 265 36 | 35 747 287 260 37 | 36 539 116 78 23 160 21 88 117 49 229 6 61 120 38 | 37 572 251 549 199 680 126 187 394 312 154 143 325 939 184 672 39 | 38 351 293 271 338 287 301 318 40 | 39 302 242 336 320 241 357 1037 41 | 40 27 288 195 356 1038 237 151 204 134 42 | 41 422 142 47 784 356 130 366 735 182 731 478 229 0 426 172 82 581 755 124 174 160 282 467 522 150 110 180 1 43 | 42 322 819 552 14 6 930 314 595 965 704 152 401 683 55 731 50 1053 495 24 1022 195 139 85 777 173 11 293 247 472 698 624 538 925 99 101 3 276 143 201 44 | 43 239 94 249 664 87 227 237 541 226 8 147 473 433 377 469 273 244 199 99 158 24 447 68 120 98 196 143 86 522 45 | 44 475 275 595 410 596 925 23 825 763 46 | 45 150 180 1023 908 49 92 47 | 46 682 287 285 1021 304 261 48 | 47 308 602 186 510 27 518 522 356 523 214 322 49 | 48 958 994 624 368 627 417 346 298 475 121 1008 712 507 736 461 1081 217 81 158 691 639 556 1082 70 1073 180 286 92 160 327 3 366 300 651 288 199 812 153 50 | 49 245 1083 323 14 51 | 50 678 495 143 171 49 52 | 51 747 497 256 844 92 741 587 110 472 317 918 99 301 190 53 | 52 249 120 567 1086 6 54 | 53 297 1015 146 740 49 339 23 0 929 294 180 327 150 239 633 404 55 | 54 677 404 272 596 78 120 56 | 55 868 67 173 238 567 425 97 180 390 194 768 848 391 553 727 780 482 182 231 190 322 522 945 442 228 577 203 595 420 279 49 677 1090 870 57 | 56 303 418 242 755 830 408 865 150 1094 280 221 747 283 404 104 287 844 14 1015 256 58 | 57 99 41 339 155 236 245 181 683 482 215 88 495 691 513 212 1083 180 772 366 0 133 353 59 | 58 195 91 234 417 582 285 587 701 1116 548 12 404 9 558 229 384 13 870 125 133 569 64 381 925 447 658 691 168 44 526 639 505 418 527 1117 698 763 512 226 706 918 434 55 275 231 2 614 209 674 431 507 134 740 402 10 609 483 78 146 57 287 745 211 457 1110 590 643 632 450 88 264 218 41 29 1092 192 80 115 72 1119 391 90 952 601 272 60 | 59 497 632 185 479 97 217 672 20 522 12 137 477 592 660 509 493 434 1049 607 172 735 72 29 527 649 226 683 8 744 1059 483 518 418 61 | 60 341 346 299 332 750 300 62 | 61 1015 85 58 287 131 463 137 1117 156 134 280 715 420 95 526 1059 305 99 234 231 814 1130 1073 124 741 163 513 215 228 269 167 920 272 604 654 874 90 282 650 1017 195 158 581 126 70 707 951 270 703 1027 189 454 171 71 1132 746 214 923 63 63 | 62 241 1066 1006 19 49 287 1010 407 923 107 14 675 281 479 812 320 261 136 284 64 | 63 380 683 777 526 332 704 428 221 55 172 283 239 216 160 237 366 155 745 450 174 153 51 299 49 510 190 178 422 189 134 339 545 530 558 418 227 185 624 131 86 462 495 731 65 | 64 124 1141 99 201 55 69 1128 426 317 134 238 210 6 955 184 293 254 650 475 86 654 355 8 66 | 65 279 474 120 294 8 67 | 66 404 742 471 234 411 116 68 | 67 741 470 124 457 110 24 274 712 275 925 69 | 68 688 8 590 747 507 885 97 49 293 297 288 1015 287 627 70 | 69 1132 418 209 750 175 382 210 431 337 95 404 482 23 7 82 312 94 403 173 142 677 448 1029 93 71 | 70 461 474 134 356 51 301 167 72 | 71 1109 53 88 175 63 264 355 99 37 442 14 117 627 193 240 590 97 24 379 1146 971 492 57 707 197 236 22 843 648 73 | 72 479 1148 195 922 268 31 152 212 174 95 182 187 74 | 73 8 149 257 275 12 507 314 75 | 74 283 146 495 136 951 99 289 410 117 224 755 476 677 407 12 1058 24 321 1047 832 863 472 76 | 75 1128 11 689 58 1157 196 287 384 41 6 1154 92 191 269 1158 77 | 76 180 275 143 356 132 55 249 126 832 30 24 198 133 182 78 | 77 1159 268 326 812 236 879 92 293 79 | 78 136 300 6 1021 267 318 257 901 675 256 514 9 80 | 79 581 57 212 482 81 | 80 431 741 475 470 272 117 99 149 288 24 275 455 927 78 209 82 | 81 507 595 146 190 10 126 475 24 413 471 656 526 184 7 198 512 201 167 210 461 423 819 945 132 821 1127 99 894 317 133 236 581 83 | 82 209 42 117 138 475 253 94 464 794 608 931 451 105 116 109 691 422 104 93 567 596 579 14 24 110 405 273 173 754 408 224 234 247 78 126 150 844 84 | 83 404 288 283 63 0 299 627 78 85 | 84 426 258 603 82 174 85 487 55 202 507 123 498 1167 479 274 1152 299 44 339 567 1020 153 1008 417 189 149 392 505 704 193 411 133 309 228 515 229 781 135 1135 64 844 482 237 518 427 203 404 140 1038 714 324 332 86 | 85 287 269 303 87 | 86 553 366 400 176 8 995 232 1071 650 208 789 230 565 410 67 185 237 701 229 574 47 1040 780 448 1048 509 823 234 925 801 46 577 71 1178 943 178 534 807 450 93 475 684 1185 55 597 88 | 87 749 320 880 689 353 89 | 88 215 245 935 386 150 706 948 738 276 516 814 212 12 136 320 236 201 49 221 172 404 450 90 | 89 97 505 11 944 689 957 658 198 322 41 520 189 691 613 327 82 215 126 302 301 484 305 316 19 862 152 233 55 9 140 495 220 217 481 522 1201 269 211 504 219 191 749 752 136 499 91 | 90 682 192 506 263 194 509 180 481 133 747 514 613 388 135 186 191 749 21 650 204 417 342 78 92 | 91 1078 76 500 240 175 179 215 708 78 762 780 1015 927 133 755 1094 672 1046 122 280 180 929 214 101 747 52 183 147 1032 65 92 962 402 202 507 247 844 1011 924 1 954 72 825 199 741 239 70 1010 448 503 1045 382 267 8 757 770 281 565 933 49 451 450 227 684 401 68 211 368 39 216 238 93 | 92 234 124 94 | 93 1216 1219 173 345 167 346 555 88 454 185 156 32 737 560 132 213 384 312 231 561 1205 471 419 945 575 649 615 69 442 11 174 51 91 317 509 1090 189 727 1013 527 89 808 182 124 749 48 807 715 863 685 229 141 172 53 163 929 734 943 301 1210 214 691 367 476 657 958 1208 176 93 745 464 1009 70 822 181 292 95 | 94 545 0 1228 415 1229 173 635 572 719 377 517 473 416 727 141 444 587 2 47 100 626 497 495 228 285 559 1230 126 81 448 707 192 648 355 778 274 447 71 541 202 66 959 57 196 1046 227 494 50 1115 380 194 738 461 472 96 | 95 22 189 444 485 182 264 199 97 | 96 96 465 78 191 660 356 430 131 190 662 194 22 171 172 192 98 | 97 46 162 69 937 172 628 321 427 209 658 99 | 98 3 267 1015 872 273 180 167 894 1051 1118 257 55 401 408 63 344 470 366 590 331 239 974 432 100 | 99 354 287 322 1234 1236 293 886 270 897 101 | 100 303 470 251 927 1050 1033 120 49 844 279 116 819 825 818 224 545 102 | 101 733 398 985 201 172 325 175 402 688 745 357 564 509 674 143 747 180 78 719 1238 666 326 777 181 184 671 408 244 90 331 770 435 1239 81 187 372 217 268 199 410 333 395 840 233 434 1 6 103 | 102 125 49 300 249 486 55 104 | 103 755 299 326 1016 545 1225 1010 244 353 712 1011 839 312 507 332 129 870 677 120 105 | 104 271 269 747 106 | 105 434 272 76 85 47 698 273 160 13 565 317 107 | 106 339 268 322 285 324 321 326 1242 108 | 107 12 124 120 303 747 283 123 404 109 | 108 630 401 974 4 146 356 664 277 741 244 1012 930 392 90 355 391 195 848 1027 761 156 294 161 545 213 230 210 943 734 180 28 1073 238 738 70 121 176 11 155 541 16 209 190 287 563 281 208 571 62 52 475 27 594 409 923 110 | 109 1245 1178 300 1249 539 714 790 574 383 805 366 758 95 68 1217 904 585 872 450 1221 42 565 325 396 365 363 1054 111 | 110 1023 301 285 306 112 | 111 353 299 327 257 887 113 | 112 326 507 285 245 267 49 257 741 114 | 113 504 203 190 481 95 185 854 645 97 521 115 | 114 88 309 92 8 76 95 55 979 228 283 78 191 116 557 116 | 115 254 941 1215 6 184 300 186 256 759 530 321 259 298 323 1213 287 301 19 252 284 348 747 10 677 271 297 117 | 116 596 239 97 627 885 194 312 1094 297 1013 178 32 236 762 95 1164 10 131 183 251 163 118 | 117 432 155 435 217 420 78 959 200 174 257 187 426 119 | 118 236 696 274 192 1262 271 86 187 110 273 173 23 249 1085 549 828 1196 510 39 49 812 688 331 55 328 915 411 209 180 8 69 81 348 1136 120 | 119 923 14 257 120 121 | 120 513 290 739 116 173 121 124 293 791 716 471 743 49 10 122 | 121 508 509 186 469 381 428 723 10 134 1118 1167 1044 512 123 | 122 274 486 961 131 461 97 522 288 513 13 186 124 | 123 615 156 173 125 | 124 234 317 238 1179 1035 510 1271 237 385 406 1182 235 197 86 356 721 49 478 473 747 209 215 789 584 180 339 190 1114 392 116 7 208 69 745 48 201 242 204 1169 167 288 94 709 126 | 125 904 261 331 242 318 751 326 312 343 339 325 989 309 127 | 126 228 299 749 342 128 | 127 370 602 181 738 227 142 275 215 96 377 789 55 293 150 47 493 264 1038 281 872 131 120 196 651 654 217 418 923 470 24 704 69 489 1052 87 432 160 391 404 431 222 379 27 129 | 128 330 271 338 287 285 303 299 309 130 | 129 215 108 1216 541 814 992 875 203 929 49 412 54 89 228 221 157 182 1046 1015 778 1273 507 357 1206 98 68 254 172 755 688 384 40 1272 432 889 330 217 248 657 53 1150 1266 268 247 234 691 30 664 180 448 469 61 863 288 23 762 464 530 537 391 1 289 807 178 943 328 1275 187 452 346 470 256 551 801 1219 329 143 232 131 | 130 99 0 285 126 812 132 | 131 274 174 1153 250 285 133 | 132 327 303 312 299 244 268 285 354 134 | 133 312 891 315 300 0 293 135 | 134 38 293 53 175 76 801 378 324 743 78 257 938 55 233 136 | 135 285 236 115 743 137 | 136 143 299 14 50 249 259 865 410 78 138 | 137 120 110 517 11 116 508 473 741 139 | 138 245 507 1175 296 99 140 | 139 318 288 879 301 285 302 141 | 140 534 1257 280 1012 879 0 814 243 312 297 146 283 618 987 142 | 141 168 188 361 349 54 407 6 143 | 142 327 1037 293 144 | 143 181 960 777 65 746 402 327 301 460 844 520 899 21 203 761 1285 470 409 392 104 179 64 784 220 530 941 654 469 846 195 434 325 143 116 318 1196 474 69 650 356 473 126 275 1027 71 293 689 145 | 144 447 590 0 49 298 442 1216 895 228 6 712 684 68 99 297 265 269 630 1001 687 312 379 1072 878 362 256 378 355 761 133 281 651 649 404 315 30 858 689 328 1008 1288 175 346 635 117 627 8 95 868 10 925 217 52 96 146 | 145 1021 306 687 301 270 271 310 147 | 146 291 304 268 750 749 300 148 | 147 494 508 992 208 189 173 132 193 149 | 148 326 268 309 320 322 336 299 257 339 150 | 149 128 220 99 49 457 318 275 149 151 | 150 175 11 928 484 316 386 489 428 190 404 299 90 485 273 708 192 1064 416 504 1073 734 230 735 82 171 199 653 355 419 545 184 715 602 377 30 516 844 760 214 25 80 462 515 87 747 627 198 723 955 193 3 276 426 173 944 257 142 27 72 835 189 152 | 151 131 124 97 166 219 190 698 50 285 409 48 401 526 1135 283 142 154 774 87 392 943 153 | 152 21 55 215 322 264 324 154 | 153 241 181 478 918 196 210 199 184 151 155 | 154 747 331 244 156 | 155 275 204 123 345 317 186 82 514 156 157 | 156 273 1131 747 126 1282 99 268 117 275 158 | 157 664 728 413 0 227 10 824 175 228 730 215 529 238 172 984 249 180 575 230 225 28 232 977 384 1302 284 289 708 159 | 158 929 236 594 587 259 71 1048 194 275 627 1047 357 14 1131 160 | 159 92 1018 117 23 692 563 136 229 49 843 272 247 409 191 194 588 1133 407 487 126 161 | 160 47 317 97 161 581 13 522 273 1265 472 99 203 68 14 117 162 | 161 1018 229 49 116 0 357 236 178 473 163 | 162 55 233 317 300 27 164 | 163 619 116 321 147 925 117 618 322 275 292 369 99 933 297 251 406 328 327 165 | 164 215 331 90 269 168 186 431 166 | 165 345 257 893 750 167 | 166 363 47 221 168 380 289 529 673 168 | 167 234 408 987 257 471 256 14 618 258 8 274 596 324 684 224 1011 930 275 272 169 | 168 878 171 307 603 683 257 481 170 | 169 298 322 171 | 170 301 261 886 268 172 | 171 487 602 429 462 173 | 172 327 259 1264 330 318 244 174 | 173 159 395 901 254 1052 247 844 267 1031 13 1311 767 1138 346 432 237 1034 450 738 661 746 14 339 400 762 370 904 285 715 1085 131 406 166 97 175 | 174 70 182 99 660 233 185 272 176 | 175 287 249 239 49 235 342 24 740 221 320 1007 507 875 457 339 177 | 176 68 55 298 959 78 650 149 196 947 402 46 507 335 333 21 167 474 469 49 216 287 526 257 301 128 339 1109 203 178 | 177 730 198 275 677 301 244 283 82 464 270 116 95 14 539 325 618 894 1314 236 339 1100 237 818 422 154 143 228 167 155 232 221 330 193 992 880 294 132 327 172 338 179 | 178 894 1315 309 320 306 332 339 287 1233 346 312 180 | 179 1118 736 120 715 110 659 1045 468 654 181 | 180 219 2 740 869 13 1331 1333 327 873 1341 368 1197 1066 823 881 318 1201 932 828 1271 268 275 977 739 255 367 9 1016 1056 845 265 681 928 1128 1133 975 250 259 824 1051 1378 224 1329 1353 276 1173 1027 1394 287 872 930 1338 234 1388 1336 919 359 290 412 1113 748 1330 281 306 1371 92 241 274 1021 262 235 1172 1390 1344 475 1116 874 1364 258 594 1320 273 1085 302 1162 597 507 1033 1381 332 1024 716 545 1007 987 244 119 272 236 182 | 181 863 120 99 470 125 180 47 183 | 182 87 226 175 225 180 374 379 227 93 184 | 183 97 601 1136 497 46 520 274 530 461 33 69 510 1395 1397 173 446 249 605 1396 66 163 656 116 401 175 944 737 24 284 528 638 738 50 181 92 844 234 706 475 590 222 6 1296 487 271 505 316 1120 237 367 1085 196 185 | 184 527 195 317 27 85 446 422 479 186 | 185 565 769 256 30 938 545 337 716 298 94 78 567 302 202 819 1384 187 | 186 214 731 426 190 432 1118 734 662 64 178 22 172 709 188 | 187 691 142 95 768 190 210 627 172 194 325 78 201 180 184 482 650 63 117 565 179 75 454 355 258 189 | 188 519 55 19 633 750 202 90 461 275 693 631 846 14 267 595 88 131 237 526 629 486 165 316 208 82 377 933 174 989 1314 417 132 485 530 27 185 190 | 189 750 716 741 117 362 332 822 684 596 327 99 23 191 | 190 342 269 271 899 314 192 | 191 1159 257 283 234 6 288 8 193 | 192 940 367 392 484 173 110 300 442 99 193 186 762 475 22 1167 904 293 68 152 23 194 | 193 164 180 1027 171 211 190 159 477 195 755 430 734 61 522 510 316 647 807 630 432 123 184 526 525 231 945 221 478 481 1092 94 490 153 632 193 502 497 1010 836 224 1206 1065 639 431 275 1090 418 870 487 281 539 77 386 366 124 66 660 549 711 195 | 194 750 299 185 590 66 778 45 303 770 46 126 981 1415 1406 507 432 312 450 133 506 196 | 195 250 24 427 1240 172 844 197 | 196 346 514 293 517 67 747 719 807 778 91 285 361 312 585 683 55 38 10 321 402 1419 567 305 198 | 197 6 639 548 155 356 401 96 1013 317 635 409 175 78 227 659 279 978 692 689 167 299 55 5 142 160 199 1243 236 152 368 430 68 163 126 822 517 30 180 342 70 366 469 95 80 199 | 198 220 321 275 284 258 988 115 268 750 1353 200 | 199 221 10 477 664 408 585 830 217 28 293 173 230 583 839 928 7 147 146 122 87 55 738 98 494 825 1418 68 176 53 759 757 500 567 551 1090 422 495 117 923 409 233 741 930 203 21 238 201 | 200 145 648 271 202 147 208 508 659 1244 331 22 650 843 979 822 209 212 379 954 274 356 536 275 446 174 1193 1097 481 526 76 466 49 88 330 1168 1007 52 233 1010 454 734 437 94 590 1072 407 802 206 520 678 457 1044 221 117 1127 227 195 136 201 1135 182 1169 1400 1055 9 769 200 231 1102 582 238 799 470 236 202 | 201 282 514 257 203 241 178 203 | 202 270 287 275 256 1048 878 457 204 | 203 215 257 314 1193 1295 321 287 879 8 205 | 204 315 677 983 325 257 242 285 874 321 747 206 | 205 902 1126 989 358 1430 1061 336 1175 309 681 325 207 | 206 590 12 64 24 863 13 467 293 52 155 244 539 519 58 193 321 579 160 627 865 180 78 14 659 136 482 755 695 318 280 513 848 126 413 508 470 195 434 520 356 68 469 292 81 124 142 95 210 72 2 537 516 172 208 | 207 196 380 207 96 193 370 392 209 | 208 250 257 241 320 49 0 13 248 210 | 209 526 57 630 464 256 210 678 275 863 925 410 179 820 656 955 731 442 754 683 791 968 167 113 211 | 210 126 525 256 262 454 68 1126 198 212 | 211 514 644 85 317 213 | 212 514 689 7 508 10 0 134 683 677 96 199 627 179 1214 131 777 198 155 285 174 510 984 392 283 55 454 457 507 63 194 287 193 214 | 213 41 651 44 530 247 511 220 312 21 11 31 245 526 318 426 153 248 602 581 172 97 187 181 215 | 214 211 193 182 450 442 433 353 522 194 516 27 167 691 76 87 225 207 216 | 215 530 195 763 6 14 107 152 281 149 187 220 411 279 789 214 81 401 317 168 654 90 415 26 64 180 217 | 216 181 539 796 257 225 678 49 171 218 | 217 264 515 153 3 99 641 152 219 | 218 81 302 214 70 935 663 432 220 | 219 305 257 339 221 | 220 47 68 507 267 249 1066 52 495 160 1133 823 402 567 63 357 239 78 58 107 28 762 281 468 185 1184 214 575 390 41 93 54 120 11 846 116 222 | 221 365 96 811 172 48 21 105 1283 156 24 216 1088 61 367 782 431 267 203 839 1178 1058 384 894 809 1418 80 299 372 590 832 158 762 807 110 824 182 771 768 228 474 678 650 281 175 337 731 1335 641 325 711 327 1187 190 376 1065 1044 1034 1219 99 636 445 197 737 173 47 89 565 1144 229 161 223 | 222 907 257 469 68 716 119 320 741 110 825 299 294 1290 973 923 681 124 332 283 534 258 1283 328 545 224 | 223 68 177 582 677 214 21 777 1118 976 321 324 1084 703 391 281 1043 1052 317 580 1057 555 1400 332 688 364 675 659 320 379 236 728 225 | 224 244 97 226 | 225 23 173 506 108 202 11 473 227 | 226 49 294 292 275 92 287 1027 1046 1010 1142 404 1067 14 228 | 227 654 229 | 228 327 346 230 | 229 679 418 237 198 1049 581 95 925 140 620 649 279 283 131 621 204 134 142 626 68 231 | 230 126 150 0 312 232 | 231 196 629 90 174 704 637 522 214 80 55 233 201 460 746 97 514 269 208 132 245 602 47 588 233 | 232 201 176 98 957 68 116 653 204 81 312 602 191 46 13 526 196 7 142 317 215 477 120 461 3 234 | 233 140 1185 616 70 656 499 958 670 518 212 489 94 327 116 1148 169 434 299 167 492 1197 20 843 432 420 286 426 1125 750 418 1202 284 629 215 173 46 429 1120 1167 745 155 184 545 609 1444 101 527 969 1449 476 187 691 496 110 648 674 524 612 223 39 316 488 649 442 510 171 835 356 477 10 624 285 1062 652 272 357 124 444 377 662 556 748 105 723 685 81 464 494 463 630 614 634 257 698 1002 622 791 1 1447 235 | 234 418 510 274 99 432 51 187 746 82 180 194 178 81 428 462 284 236 | 235 631 56 728 186 288 199 171 306 203 184 595 65 1101 297 442 503 522 209 431 672 461 274 195 749 206 132 116 97 654 525 281 519 237 | 236 527 178 407 8 177 126 473 655 57 238 | 237 251 814 1189 124 1257 236 150 239 | 238 1098 8 429 922 311 529 653 496 515 557 700 953 662 317 483 180 184 49 227 44 164 418 461 920 179 481 1114 504 185 240 | 239 244 241 | 240 291 886 334 681 345 894 242 | 241 304 236 305 474 293 243 | 242 207 712 27 172 316 68 777 1280 214 508 317 21 110 25 305 245 244 | 243 380 549 171 661 408 379 154 6 215 675 99 96 742 156 277 427 89 286 121 410 179 1044 1106 885 71 553 68 723 558 160 455 737 76 41 684 300 144 627 958 470 409 91 536 945 779 731 520 245 317 400 1167 467 696 1108 69 157 870 1094 1040 1027 57 923 734 120 66 245 | 244 221 132 1046 257 150 246 | 245 200 415 7 405 848 108 567 450 230 839 719 540 235 229 175 742 411 852 253 1138 172 1027 197 632 575 797 549 66 840 615 650 49 383 738 247 | 246 0 339 180 248 | 247 233 474 152 483 677 234 404 113 68 342 249 | 248 254 22 475 992 471 168 99 197 38 23 270 215 217 297 1046 209 11 587 740 63 124 482 1010 461 190 241 602 194 317 250 | 249 263 6 403 0 183 22 1160 1136 95 500 234 987 257 180 417 97 233 90 258 587 322 468 990 628 143 983 251 | 250 99 143 182 236 14 865 426 294 63 312 44 247 249 78 0 184 24 252 | 251 8 99 0 474 223 253 | 252 464 293 126 297 88 78 97 522 342 14 484 189 80 152 0 233 81 131 254 | 253 228 120 356 378 187 648 576 595 239 242 237 14 754 185 233 560 1132 135 497 312 63 195 77 1468 226 70 621 464 385 615 342 495 841 255 | 254 216 878 257 824 975 322 321 828 199 684 146 263 342 826 596 742 218 256 | 255 85 412 818 234 194 201 981 1206 1 225 973 187 226 1060 684 1209 472 830 97 88 37 117 1227 683 184 87 14 232 656 322 281 282 318 1207 987 386 181 217 525 553 228 985 221 257 | 256 344 49 164 461 128 165 274 1009 935 258 | 257 312 747 259 | 258 116 958 268 761 11 107 356 97 316 146 474 287 270 172 747 167 260 | 259 332 261 | 260 339 596 987 341 1236 595 262 | 261 930 567 95 49 274 43 144 194 928 317 190 121 357 814 199 6 168 472 68 99 293 419 426 1134 282 954 545 64 57 81 69 698 263 | 262 418 95 1450 415 196 920 520 126 133 185 63 264 527 167 1125 689 542 57 514 0 257 198 30 180 264 | 263 69 400 24 202 3 671 282 380 167 381 761 601 237 203 191 221 701 193 675 287 18 513 855 25 1008 655 602 745 155 636 200 46 149 265 | 264 278 408 476 257 299 244 292 814 272 266 | 265 271 123 285 236 8 267 | 266 385 738 545 27 469 383 684 392 646 171 175 731 654 407 168 140 208 229 216 202 97 68 1109 187 67 709 88 180 1034 1 194 268 | 267 929 823 385 1040 683 720 82 120 98 251 403 153 140 948 482 264 1156 152 6 243 473 168 698 731 824 483 664 133 237 121 54 799 96 301 581 1475 9 398 119 70 728 1090 380 1221 259 179 657 505 940 52 49 94 55 801 158 560 524 256 1187 293 1117 199 91 229 1412 200 217 24 549 218 36 175 209 1177 407 1109 434 448 269 | 268 245 21 251 792 209 167 171 804 14 483 208 653 212 524 474 182 526 808 1064 1027 1167 664 253 432 927 424 706 1147 196 153 527 777 95 76 80 1010 930 41 317 659 2 416 1443 529 121 207 180 450 463 774 734 603 16 431 1477 707 123 270 | 269 451 780 229 158 1118 702 1013 294 715 713 1209 281 257 76 545 144 530 355 726 256 6 793 859 442 218 184 241 282 271 | 270 198 481 513 10 623 21 1090 247 712 581 14 191 509 401 310 1132 63 383 641 741 69 515 116 311 30 86 392 1045 662 284 160 460 3 955 1119 510 80 480 47 728 99 734 135 272 | 271 126 482 513 49 95 41 603 422 174 233 193 173 55 133 186 273 | 272 310 306 285 274 | 273 147 318 0 117 923 684 627 628 743 1059 275 | 274 97 519 522 587 495 116 221 27 929 626 450 434 825 195 98 0 161 419 95 120 168 469 449 198 228 824 678 276 | 275 53 1090 77 156 245 405 290 1134 249 562 968 785 683 229 227 630 138 736 1072 237 839 449 648 403 402 314 426 470 1470 805 67 469 287 155 124 195 815 222 575 408 548 153 627 197 97 85 1005 1244 1220 83 822 191 61 127 157 98 602 143 914 714 754 288 357 432 23 355 238 1027 770 654 420 52 657 457 122 200 1117 678 767 81 758 327 768 66 71 386 253 623 2 24 404 6 259 216 471 1482 302 901 427 95 96 684 331 695 451 292 948 412 174 771 181 299 1089 277 | 276 254 278 128 747 404 273 472 136 292 257 761 283 1007 0 278 | 277 310 244 751 922 279 | 278 740 724 95 486 826 1491 1112 1141 417 396 1494 215 991 761 468 489 23 1132 0 227 49 1229 997 1051 79 653 249 116 803 24 540 840 72 1500 1107 155 593 531 823 989 152 128 420 98 131 400 931 596 290 1265 977 108 1401 394 123 1498 842 402 11 665 759 557 165 975 60 479 1026 976 670 197 513 363 94 1000 430 190 1038 1480 832 427 26 46 230 241 743 373 485 900 778 280 | 279 539 1048 126 471 98 570 315 322 380 482 285 6 116 1478 575 558 156 101 537 662 3 281 467 464 68 714 131 76 157 1132 231 745 97 175 506 323 199 196 730 388 139 12 154 401 415 228 1216 70 1050 102 202 741 470 383 87 659 71 391 2 111 450 32 945 11 181 587 281 | 280 257 325 293 258 282 | 281 339 267 318 283 | 282 587 708 237 454 1486 167 48 20 408 392 150 1078 411 172 284 | 283 303 304 681 299 331 271 937 686 302 288 285 | 284 150 627 312 204 193 257 182 286 | 285 1013 170 356 43 84 153 157 1264 641 227 703 558 10 404 106 511 1112 1181 28 553 403 160 777 791 126 422 392 380 1279 185 410 1104 110 923 143 120 211 338 475 1037 314 131 482 738 136 568 3 1073 277 21 115 733 41 231 40 249 347 234 1132 855 287 | 286 326 925 293 256 10 55 345 239 460 116 200 297 120 475 651 167 245 741 288 | 287 304 96 201 11 156 68 229 345 21 543 174 189 434 1357 519 173 631 1064 326 198 204 209 289 | 288 281 409 1015 146 124 116 290 | 289 87 160 475 20 428 1012 201 157 242 684 226 171 514 1078 14 682 1284 166 1046 731 173 27 179 404 808 234 471 291 | 290 69 731 1027 626 98 823 323 557 573 409 554 1108 100 45 173 71 155 1214 714 793 88 618 1504 728 283 824 289 468 1477 402 562 762 568 974 163 567 324 84 734 426 973 281 123 779 596 1078 755 244 635 199 630 157 976 1089 248 183 574 843 26 784 401 942 292 561 832 507 292 | 291 173 660 588 8 327 182 131 487 225 854 653 110 78 284 658 124 189 152 6 1141 297 179 527 263 498 180 281 601 293 | 292 684 470 136 165 411 747 778 628 664 728 226 704 194 848 123 209 645 67 942 321 54 678 182 154 32 976 553 750 631 648 746 289 296 855 587 745 481 402 549 198 47 482 293 232 221 894 714 233 517 788 231 244 692 99 172 10 142 184 236 237 72 557 500 1118 121 294 | 293 930 929 126 1198 119 677 23 602 741 78 410 299 901 748 121 751 306 239 290 534 1253 1088 323 1013 272 519 293 295 | 294 960 189 171 703 482 66 172 3 721 492 411 1134 736 163 6 52 1169 945 173 87 132 190 419 1472 512 104 133 136 430 558 212 356 380 185 384 742 78 415 296 | 295 704 257 509 1072 254 9 21 503 474 962 481 23 133 520 197 124 302 236 250 110 220 627 314 482 631 658 695 297 | 296 715 233 232 735 627 201 651 222 281 175 628 115 142 107 470 128 434 136 52 507 7 212 108 229 418 155 247 180 195 945 207 99 658 283 298 | 297 1345 7 841 659 70 704 293 142 167 195 503 275 478 332 203 678 299 | 298 228 954 133 285 644 1226 366 741 484 346 317 508 332 915 751 949 918 12 135 169 474 203 263 18 166 189 1505 483 507 46 227 208 0 791 212 47 401 726 512 193 238 98 395 165 117 11 855 854 380 113 60 178 300 | 299 408 880 832 686 1011 301 | 300 400 78 226 605 171 609 10 122 510 76 406 159 683 379 215 581 160 422 163 268 275 200 870 221 198 21 587 142 75 117 402 80 126 46 558 38 196 120 192 81 701 149 757 575 801 1012 1051 419 217 684 3 127 401 204 232 386 635 257 89 79 40 216 302 | 301 302 306 293 265 303 | 302 841 251 392 425 93 119 1036 747 329 866 548 1006 1089 1507 372 449 8 317 505 79 230 248 163 66 293 1011 117 791 1225 728 650 1257 448 550 217 684 228 481 1269 28 457 846 116 2 549 269 657 1509 49 1141 618 167 1231 1410 708 105 469 534 412 194 959 501 473 250 81 170 424 254 745 844 394 40 828 281 1051 384 227 318 72 563 594 431 678 91 460 96 513 45 1227 483 541 190 1085 362 304 | 303 293 285 273 305 | 304 116 511 482 78 188 959 185 86 13 732 946 356 637 155 244 177 529 1455 288 200 11 581 689 167 1512 630 285 1072 180 750 178 281 1017 1 159 862 473 274 85 59 468 662 649 221 1285 306 | 305 99 149 257 1250 307 | 306 508 174 228 462 745 80 152 238 654 473 213 81 82 400 418 134 394 630 69 177 98 1064 131 108 120 308 | 307 80 515 214 162 558 377 580 633 416 466 3 568 446 810 108 1018 745 825 232 489 482 143 204 69 1403 90 71 99 30 596 234 472 29 87 1410 200 522 356 604 493 170 1251 427 7 530 613 21 49 658 419 652 292 708 636 6 391 217 524 823 479 1117 120 254 309 | 308 325 305 1024 318 310 | 309 23 535 844 831 250 293 311 | 310 385 715 848 27 365 212 21 719 309 37 470 432 950 173 225 364 626 186 233 920 522 386 641 575 784 184 305 215 482 767 320 176 175 561 1041 422 503 478 7 30 217 793 699 683 65 185 580 498 1216 237 53 1296 75 230 746 90 442 965 240 229 414 391 312 | 311 493 920 227 143 674 497 131 495 274 7 704 434 587 189 515 182 70 275 487 69 462 173 175 653 509 210 207 165 662 834 153 426 151 529 49 168 458 643 82 429 313 | 312 435 147 64 244 174 204 179 207 138 414 150 43 317 656 830 198 472 68 664 55 163 603 154 470 1049 413 661 327 822 769 419 427 482 408 417 392 537 819 483 891 743 498 210 299 330 27 201 567 384 518 142 653 221 236 126 575 489 314 | 313 534 1262 1517 89 928 590 940 401 104 1219 405 121 1027 1056 947 1516 1177 794 408 1472 1228 761 594 500 422 124 366 283 1266 805 684 698 1518 55 1015 1468 746 1011 14 1093 116 172 1052 418 948 476 1224 567 1296 315 | 314 304 650 656 97 229 210 503 284 126 602 179 708 237 11 791 270 323 519 300 78 92 316 | 315 1083 189 520 179 21 82 677 186 285 434 191 274 581 126 987 317 | 316 330 878 259 318 | 317 647 247 193 314 502 395 400 87 574 62 185 14 139 210 656 864 696 23 160 841 69 863 84 268 214 721 1047 731 13 187 306 967 120 274 808 133 734 186 940 1029 450 392 319 | 318 688 750 681 349 320 | 319 1156 147 975 1010 158 53 32 402 894 404 770 275 61 37 155 549 420 65 81 287 1521 299 232 144 571 731 1046 1290 50 247 291 321 | 320 130 522 1027 506 482 493 7 134 123 513 496 215 662 461 13 210 498 6 59 131 653 656 431 181 85 274 610 650 18 126 132 658 497 51 427 477 322 | 321 184 11 652 590 149 607 155 602 156 345 506 482 323 | 322 116 149 150 1049 874 120 762 49 761 293 1072 155 650 324 | 323 1032 596 257 876 8 287 254 878 247 258 291 284 124 267 409 325 | 324 429 513 97 176 473 180 163 491 151 834 312 136 603 960 501 81 113 15 104 133 529 1017 194 770 510 92 407 385 234 326 | 325 21 479 167 281 731 447 184 558 451 203 664 968 602 85 207 7 510 789 180 316 227 231 181 392 662 497 509 848 448 1125 96 327 | 326 299 557 473 49 214 434 187 237 232 202 1055 195 1011 263 178 95 410 264 225 146 87 958 7 189 217 427 1068 501 918 864 675 208 300 231 99 116 657 844 97 85 98 107 94 683 1217 173 1128 748 120 274 627 328 | 327 567 9 522 3 143 401 749 187 283 131 450 81 348 264 509 330 30 482 1014 695 331 227 545 321 689 568 176 272 747 197 61 648 343 600 154 636 259 76 548 955 193 743 797 191 661 938 63 158 68 902 346 312 326 315 517 480 565 329 | 328 123 275 299 180 654 281 283 136 184 173 116 10 301 247 321 330 | 329 135 446 7 484 207 1027 199 152 87 276 417 472 173 131 62 292 650 968 201 693 24 467 383 331 | 330 485 478 132 189 304 701 213 1198 159 510 332 | 331 565 232 594 257 331 1217 248 341 1243 21 94 683 1314 292 981 596 369 823 69 251 281 404 894 650 171 120 405 229 95 117 72 306 410 172 384 1209 49 301 333 | 332 315 179 872 434 482 334 | 333 1162 1107 268 288 301 1314 501 310 1410 513 6 226 662 1050 524 887 325 657 1403 475 134 448 530 110 276 654 590 124 196 509 1040 311 12 126 1524 286 935 885 864 507 202 247 163 81 237 300 282 336 606 520 72 243 949 528 28 306 120 809 560 217 1010 335 | 334 259 677 346 299 336 | 335 863 48 153 1073 1011 721 152 120 93 104 1040 387 55 1010 382 69 283 1078 150 0 293 367 24 590 948 84 337 | 336 105 256 370 134 449 514 470 227 150 338 | 337 603 483 662 173 707 174 524 285 339 | 338 1029 855 225 474 72 430 692 153 513 1300 22 769 97 495 193 162 257 0 268 178 446 435 356 160 156 507 196 133 207 28 526 656 1266 1134 484 190 167 502 654 210 653 249 735 789 216 340 | 339 171 434 180 503 214 65 178 341 | 340 875 287 886 342 | 341 722 973 174 55 256 239 94 656 654 583 31 273 296 133 507 814 208 300 422 123 285 124 534 477 655 481 755 377 964 92 250 318 2 486 460 288 168 292 762 248 487 136 475 152 513 343 | 342 1106 43 134 186 11 24 142 791 950 302 723 918 129 249 777 707 195 497 381 120 116 78 76 520 613 41 228 1072 230 929 356 67 472 235 64 80 196 522 275 475 402 197 201 1266 257 582 1046 1116 344 | 343 214 118 507 174 203 476 450 312 1006 243 124 244 285 212 558 221 895 485 72 271 954 136 290 404 486 925 120 150 215 197 1081 95 693 12 97 275 477 21 430 528 68 172 301 345 | 344 47 955 1081 1314 558 281 450 1047 1015 723 32 0 300 738 1013 76 534 290 747 12 271 1052 1095 169 42 222 954 43 8 236 203 219 714 267 279 737 64 117 1008 1006 199 979 243 468 683 346 | 345 244 186 217 560 133 30 293 830 784 93 52 454 404 21 430 747 214 1134 365 801 958 1 495 469 711 99 577 1024 167 90 390 540 152 232 67 195 87 57 364 639 347 | 346 1034 78 226 464 287 11 840 229 323 698 384 126 150 272 596 171 232 270 156 225 762 180 182 201 202 404 191 23 927 685 90 747 1243 348 | 347 627 974 293 1119 830 411 987 110 120 545 755 242 476 349 | 348 287 324 99 275 105 284 283 695 350 | 349 656 615 514 488 182 270 167 428 351 | 350 1104 291 989 325 300 688 327 352 | 351 54 745 172 233 182 567 99 691 652 353 | 352 285 315 897 354 | 353 241 190 179 903 317 952 731 413 606 427 658 528 173 628 133 497 478 957 515 99 136 514 192 8 97 168 87 257 1084 250 240 59 527 108 269 810 304 1465 12 675 526 9 743 886 355 | 354 871 263 270 356 | 355 325 314 315 330 293 357 | 356 283 927 290 333 865 712 931 282 507 358 | 357 481 642 917 510 267 126 581 178 44 257 359 | 358 750 0 120 747 929 360 | 359 308 422 743 482 514 325 522 186 209 55 296 284 954 650 361 | 360 25 274 948 110 184 11 1073 683 202 738 434 653 1102 149 672 236 211 420 706 217 227 175 193 442 282 602 366 362 | 361 311 301 747 1024 299 363 | 362 404 1494 287 315 905 1266 162 1 143 86 65 264 545 386 168 36 80 553 43 567 652 10 215 321 6 858 894 602 706 570 178 263 656 773 709 31 558 505 746 549 690 247 945 37 186 918 327 66 734 72 222 175 454 255 704 1477 259 41 223 364 | 363 689 268 947 260 365 | 364 257 288 1419 150 99 845 315 366 | 365 163 560 216 233 670 52 772 757 367 | 366 1011 773 435 99 550 325 233 768 217 636 4 163 368 | 367 550 435 319 88 180 10 144 560 669 4 447 446 440 369 | 368 167 171 315 357 750 178 370 | 369 264 11 21 321 284 424 322 660 442 301 136 649 56 172 371 | 370 236 54 422 654 522 185 182 448 30 65 495 372 | 371 199 182 285 261 446 331 55 435 594 43 217 871 843 272 373 | 372 587 138 848 80 426 595 116 450 19 841 473 703 317 205 493 81 526 1086 47 479 402 654 188 162 141 381 164 70 213 549 95 552 180 1132 165 238 678 430 82 258 389 212 134 527 528 738 631 683 237 734 186 173 374 | 373 1046 684 355 161 121 8 181 194 539 6 86 474 233 551 149 1041 368 167 232 465 55 147 818 762 143 1214 973 927 740 63 4 664 977 1512 1093 76 567 1209 321 978 228 819 281 974 636 283 16 571 287 275 54 828 712 238 1193 405 136 81 30 163 375 | 374 760 565 299 217 76 4 572 1045 376 | 375 236 268 288 662 706 320 356 814 99 377 | 376 218 55 315 270 257 378 | 377 366 288 273 195 541 3 507 178 464 395 283 450 971 526 65 300 938 47 99 404 432 635 1106 767 294 61 386 1406 216 199 98 968 449 628 1008 226 484 795 702 27 233 1530 929 179 478 93 1034 1 94 774 596 662 779 219 392 467 42 274 254 316 565 380 927 381 97 82 215 55 163 264 312 560 659 1146 77 379 | 378 636 7 229 97 1218 215 685 198 238 151 186 683 700 1021 397 152 384 171 728 562 130 237 185 513 305 709 172 226 193 501 6 184 708 525 473 706 380 | 379 171 58 752 427 184 630 182 30 133 735 565 750 505 1064 520 151 99 193 356 728 237 189 49 479 178 609 233 301 381 | 380 211 190 723 693 659 76 29 606 78 149 138 98 101 704 216 150 343 302 0 293 306 595 382 | 381 126 24 170 97 99 121 134 285 383 | 382 504 640 424 662 602 136 512 13 18 8 80 222 88 284 202 192 179 477 187 212 384 | 383 354 988 328 385 | 384 1366 523 223 422 1352 336 248 662 81 252 155 193 484 964 41 285 522 256 454 110 135 150 23 142 168 143 505 899 1006 738 121 491 1120 304 1461 88 432 57 651 1498 36 528 653 60 214 873 1069 655 1117 250 1064 692 203 447 386 | 385 545 832 684 839 387 | 386 513 199 422 1096 1114 200 207 332 167 696 287 487 80 983 853 443 201 293 1198 272 214 222 1239 95 292 221 745 126 581 237 98 507 495 683 714 514 618 557 428 21 26 473 128 204 384 1077 247 515 549 398 171 27 0 587 654 52 567 173 388 | 387 4 146 116 325 287 299 257 217 327 275 199 52 389 | 388 108 844 655 491 215 1202 517 735 777 401 1073 3 698 1285 46 567 49 557 409 151 89 383 80 453 630 502 178 24 284 55 382 93 185 925 1006 210 76 134 370 0 160 558 552 662 154 487 411 239 238 390 | 389 125 282 844 689 391 | 390 25 923 529 30 293 57 962 420 236 99 181 21 147 321 704 176 714 695 647 392 | 391 332 257 491 318 537 7 297 98 168 324 487 208 481 188 259 49 180 588 509 516 268 393 | 392 401 952 1091 526 385 168 1313 780 782 365 553 379 1178 66 37 724 99 830 222 322 315 1406 80 1073 996 416 684 256 1227 629 355 403 273 422 94 1039 1238 414 551 193 172 63 750 950 825 1054 27 107 269 1538 654 131 560 85 4 41 1336 643 471 6 384 549 458 190 622 121 57 332 878 258 287 281 79 331 383 747 981 832 789 624 65 247 0 366 1000 773 398 394 | 393 226 449 120 422 560 153 575 78 678 49 209 155 171 418 363 762 225 539 256 27 72 385 67 215 251 140 28 11 117 89 175 293 626 61 719 32 395 | 394 364 63 312 209 595 230 251 99 185 162 747 317 257 396 | 395 750 259 1024 327 321 287 590 1027 299 1214 716 236 124 117 397 | 396 107 260 182 321 478 287 895 503 587 344 877 170 1000 610 180 679 389 108 64 288 692 342 528 398 | 397 226 68 519 14 203 30 275 1118 57 662 162 157 94 62 87 479 124 490 81 384 518 429 116 210 126 131 520 55 201 609 683 632 477 184 282 134 399 | 398 218 283 1313 72 923 32 654 417 113 388 272 227 66 139 90 156 1230 96 430 225 431 1089 233 411 142 392 47 381 116 1243 940 1073 52 1177 109 621 398 563 55 146 163 131 238 379 56 400 237 8 387 418 889 793 150 27 461 327 53 1206 560 432 510 231 46 400 | 399 258 748 322 293 257 268 312 401 | 400 116 518 110 197 602 64 660 224 484 70 143 201 236 587 429 152 364 146 13 355 480 356 650 10 301 180 370 277 210 633 402 | 401 126 234 510 221 123 49 9 474 18 275 94 227 136 403 | 402 257 6 122 126 239 470 283 747 684 8 150 404 | 403 891 257 1237 738 347 677 878 900 244 322 937 285 338 405 | 404 579 691 77 1117 1337 655 1560 439 1564 213 449 718 89 365 1554 698 450 770 187 349 431 649 360 550 784 1316 1518 794 1556 578 466 767 651 216 227 622 1109 307 558 188 663 1239 48 647 771 1588 184 178 1591 1266 1399 1220 1589 970 398 84 1557 38 1574 719 1073 1111 709 1183 1538 1230 1584 67 1559 938 21 4 738 514 1567 715 382 232 194 481 355 809 602 1029 782 7 683 11 142 1414 735 1571 850 744 316 419 565 1064 1227 138 207 674 920 230 42 101 1580 443 364 859 853 1061 567 204 417 969 1307 1590 424 541 702 442 212 1573 639 1265 371 34 45 1026 1100 1528 169 1089 620 664 971 581 85 1422 406 | 405 317 644 13 435 413 661 395 180 98 39 731 237 510 68 6 734 41 768 480 755 62 426 651 467 173 518 239 211 427 944 606 86 4 219 38 574 0 610 157 9 484 659 179 557 465 96 562 149 656 123 1072 56 424 1152 501 366 143 25 97 600 407 | 406 210 615 641 654 477 162 417 509 415 858 98 243 226 501 207 402 180 971 122 422 478 249 7 1089 513 231 602 674 795 394 387 738 490 183 174 736 442 190 93 408 | 407 688 747 346 750 409 | 408 1294 49 222 287 98 198 994 269 683 380 167 132 603 526 428 96 675 8 263 209 482 614 165 1523 432 426 876 27 57 460 617 1193 480 285 1448 607 497 1368 713 99 356 1511 704 537 44 170 1327 889 133 510 82 465 410 | 409 311 897 885 257 310 411 | 410 181 1469 167 719 194 567 37 72 57 116 88 412 | 411 201 91 507 95 171 275 650 80 22 213 430 0 413 | 412 6 325 180 256 301 274 249 302 49 257 306 320 99 272 414 | 413 263 293 271 345 300 301 287 312 894 415 | 414 1523 153 478 184 416 | 415 249 873 355 55 720 426 1502 818 478 91 265 229 606 212 167 257 287 722 479 203 365 1494 258 104 196 54 82 141 76 224 745 914 784 392 782 12 247 447 971 69 244 826 297 402 468 917 558 431 306 1539 274 563 711 761 695 87 28 659 777 661 136 238 186 394 833 280 712 814 41 65 806 411 64 132 692 1263 410 508 417 1188 937 89 231 541 741 923 281 414 570 868 268 1151 123 230 110 183 1132 679 290 417 | 416 780 596 1094 146 119 1043 709 41 11 195 1022 1035 194 97 424 1046 1549 691 175 483 637 714 999 1231 1040 19 153 15 269 578 67 180 322 384 339 1246 213 143 1156 814 471 673 962 172 14 824 394 387 708 96 939 363 432 50 558 398 121 1415 945 1039 43 141 1085 218 1090 1538 766 210 731 342 410 229 449 211 110 770 575 120 817 190 418 | 417 326 327 419 | 418 1450 704 285 222 256 616 99 404 190 173 196 493 420 | 419 330 301 136 250 99 300 172 123 492 421 | 420 442 193 181 6 173 175 116 212 163 99 218 128 878 171 422 | 421 108 558 918 476 323 1198 557 1186 123 306 446 772 332 716 562 270 423 | 422 314 976 1264 275 327 244 822 126 9 424 | 423 260 688 242 287 434 114 99 425 | 424 270 190 226 55 280 209 321 52 256 251 31 67 16 444 97 852 197 339 337 635 218 288 144 116 1594 187 537 397 342 354 878 4 293 442 671 156 325 63 742 333 402 3 96 292 826 426 | 425 602 492 632 613 485 526 650 753 834 1063 491 97 331 654 49 177 431 1019 204 142 518 967 481 483 660 658 670 495 427 | 426 318 331 267 321 428 | 427 342 749 876 299 333 349 1023 1312 1279 321 293 301 351 287 241 429 | 428 1221 1118 1038 272 218 409 1223 25 1284 793 567 127 88 819 704 194 279 210 672 136 691 1016 456 150 1109 504 545 47 149 731 61 217 832 116 300 670 249 760 275 68 182 94 474 499 657 67 81 51 201 536 392 725 418 960 49 683 173 87 71 1019 24 110 615 225 227 771 1300 807 234 41 1138 736 745 696 299 582 461 938 155 181 408 198 430 | 429 252 1346 220 1239 1006 164 247 257 41 136 151 299 120 1374 747 431 | 430 285 432 | 431 221 741 545 122 409 149 1015 180 470 0 283 844 474 433 | 432 172 193 332 918 357 204 456 136 299 434 | 433 545 120 755 1094 832 818 287 14 410 423 435 | 434 1033 114 651 759 159 695 380 381 615 81 51 840 122 49 253 89 541 791 1400 174 337 350 833 1230 150 41 108 326 121 519 454 731 227 245 587 23 923 683 545 161 104 565 238 2 171 6 639 423 540 398 566 820 221 70 925 107 475 264 43 686 267 608 180 1 38 193 192 945 817 78 595 207 7 721 436 | 435 160 410 1205 844 156 1060 89 126 391 324 793 20 215 761 312 973 91 1047 584 64 110 422 347 49 868 1247 426 634 855 437 | 436 164 13 664 450 213 657 64 478 1133 392 516 517 656 780 131 1074 683 133 659 253 735 150 182 287 264 954 842 1097 691 841 708 173 194 628 431 582 120 93 442 171 188 138 475 248 128 201 65 438 | 437 285 219 244 20 814 0 283 280 256 618 439 | 438 13 474 299 236 284 272 245 120 275 440 | 439 514 936 1190 85 735 311 241 360 56 441 | 440 8 287 0 293 312 337 442 | 441 400 30 28 285 349 684 481 280 55 272 694 549 507 216 293 218 208 575 858 432 226 469 870 737 741 89 443 | 442 677 686 174 747 306 244 444 | 443 49 911 244 306 445 | 444 1590 122 885 208 478 116 958 747 312 894 1600 741 8 339 1096 180 743 643 1013 299 95 901 270 1008 446 | 445 301 291 267 337 321 339 298 447 | 446 1033 68 822 257 677 110 482 469 88 149 156 468 208 497 97 221 155 581 715 222 273 410 264 448 | 447 291 883 1175 270 326 873 269 449 | 448 1008 292 126 104 701 557 1366 178 1371 1403 982 1072 639 592 450 | 449 99 141 161 461 178 37 658 251 941 466 96 142 1 381 709 493 210 176 28 1183 173 154 467 94 153 711 1151 100 93 271 735 417 257 1478 130 98 377 131 1602 764 613 304 872 483 198 789 356 413 1220 282 163 134 244 3 429 1424 204 920 650 232 1152 238 526 730 822 124 844 608 1219 196 1434 935 111 81 421 938 607 647 116 654 1162 950 632 1302 556 416 569 132 619 510 434 747 661 733 42 344 518 545 77 1296 43 600 520 503 21 355 1125 233 398 731 451 | 450 288 322 881 871 261 302 269 1295 936 335 287 300 332 876 937 1279 306 325 987 260 947 886 1037 747 452 | 451 1108 494 60 1533 497 482 206 1426 516 203 457 96 490 7 418 635 187 285 431 63 210 47 61 417 211 461 134 6 471 236 575 662 82 22 178 198 473 1254 515 70 163 222 212 1409 453 | 452 124 247 6 411 187 96 577 233 58 650 720 49 78 585 142 237 76 257 11 253 180 183 422 203 3 225 214 119 789 574 201 143 66 454 | 453 163 81 172 87 233 641 10 685 55 734 132 202 653 130 602 269 450 106 434 938 210 68 1034 482 258 391 299 525 161 133 422 98 723 113 609 192 65 467 221 631 366 529 146 134 370 94 731 588 386 85 63 747 455 | 454 19 254 195 581 464 503 203 1136 726 583 221 514 190 461 169 196 1196 404 300 175 70 269 216 13 52 290 192 448 941 76 923 21 1166 384 735 10 285 522 258 456 | 455 1247 962 79 442 459 67 1266 368 85 215 692 173 169 12 431 1327 489 70 231 1009 78 45 180 185 196 654 1239 394 479 366 1603 149 587 32 1128 457 | 456 365 526 1029 719 57 227 979 228 167 104 171 229 356 424 508 21 622 82 76 303 230 93 64 628 472 184 13 96 287 203 182 195 627 565 370 955 146 1046 224 124 293 68 422 87 450 458 | 457 529 318 846 12 1260 287 233 520 752 56 595 303 424 404 528 650 300 288 588 587 142 525 194 466 285 653 843 128 237 459 203 0 301 512 51 63 68 6 459 | 458 133 357 977 294 410 335 251 21 249 741 865 1015 99 545 968 1050 1038 285 650 872 695 293 460 | 459 256 743 531 292 220 272 457 514 846 278 116 150 8 12 461 | 460 49 157 462 | 461 865 463 | 462 249 220 13 243 1604 234 256 115 19 750 869 282 1008 274 739 464 | 463 288 677 708 257 285 292 175 256 519 478 126 465 | 464 113 480 524 178 587 190 198 655 528 168 180 0 173 403 614 650 131 99 512 466 | 465 127 231 1312 314 881 26 901 182 323 86 61 55 325 257 81 299 32 467 | 466 1016 267 275 326 9 268 126 468 | 467 641 70 12 181 7 474 855 1050 156 194 21 461 191 296 152 426 530 646 217 142 160 126 63 469 | 468 9 653 482 305 581 167 151 509 470 | 469 1096 18 287 49 117 234 359 180 275 1133 304 471 | 470 0 931 392 431 1218 472 | 471 930 939 755 249 150 746 140 216 96 742 632 1052 430 195 745 923 549 1227 770 383 227 67 1089 833 27 77 391 225 81 1 464 495 93 385 160 431 365 1078 149 425 230 1214 650 830 337 548 95 473 | 472 272 546 24 255 302 128 241 474 | 473 734 483 160 315 648 190 78 284 10 41 494 460 297 257 379 275 381 98 208 641 68 1420 616 217 663 106 658 206 1133 474 192 301 21 519 247 384 325 529 312 57 429 314 285 656 747 514 670 212 221 478 422 955 136 481 651 426 1123 430 8 491 46 189 123 475 | 474 285 901 126 257 476 | 475 1036 32 174 193 208 185 889 711 201 998 737 25 172 3 207 55 745 392 93 398 477 | 476 279 14 281 730 293 793 273 478 | 477 121 150 495 738 402 287 349 78 144 71 742 339 68 654 25 409 0 133 466 201 194 392 63 707 479 | 478 527 160 1243 751 839 116 420 57 534 482 731 81 397 944 182 327 317 280 726 1006 1607 95 147 293 65 7 299 21 407 489 201 985 142 204 61 339 495 480 | 479 202 614 509 297 165 641 208 478 257 1387 99 97 481 | 480 317 434 215 366 426 189 162 478 69 321 251 197 497 87 392 499 210 482 | 481 294 310 126 314 268 327 293 483 | 482 461 249 248 276 611 19 1151 115 273 479 317 256 221 226 675 484 | 483 194 299 553 24 140 227 577 143 238 398 256 167 404 81 70 28 384 471 950 116 414 120 86 485 | 484 346 293 327 747 345 241 486 | 485 220 320 689 993 881 5 2 275 124 1513 330 1092 1016 180 12 1271 110 92 627 247 297 1196 9 150 1046 1010 994 1321 1608 300 15 323 267 288 105 250 291 457 458 292 531 1609 824 545 487 | 486 55 596 473 75 171 11 142 264 548 94 539 182 127 844 683 27 685 238 684 95 403 377 87 81 771 1439 256 271 626 1409 70 1073 65 595 288 221 808 965 66 1313 300 21 93 10 61 488 | 487 479 404 473 490 661 185 209 198 520 259 229 82 1038 95 658 167 49 268 1049 526 525 417 14 293 143 88 96 78 222 126 491 489 | 488 291 320 880 330 907 354 686 259 538 988 326 750 1264 348 244 753 748 879 359 983 682 490 | 489 14 276 6 454 474 136 49 301 846 126 99 117 986 491 | 490 189 695 115 407 683 492 | 491 317 123 63 656 771 241 204 698 1097 493 | 492 251 81 99 10 410 179 249 264 762 257 58 116 454 11 21 237 208 270 322 287 368 173 1015 1012 169 832 494 | 493 182 0 106 125 321 426 527 85 142 602 244 126 706 495 | 494 70 673 450 390 171 108 565 580 506 1118 213 503 200 549 87 670 167 190 478 842 923 63 1181 1468 789 401 89 218 230 233 420 3 120 231 1156 575 1187 581 418 232 8 447 636 217 1038 1090 496 | 495 317 96 745 41 419 10 32 49 226 1285 55 185 606 483 146 468 494 720 650 154 1156 194 415 150 205 418 497 | 496 565 507 187 99 548 256 173 196 154 12 249 407 454 411 383 808 404 186 185 939 172 650 596 576 10 372 69 715 95 1239 422 162 1176 796 419 180 1029 194 471 431 628 61 236 48 449 683 230 825 140 150 540 742 943 773 412 738 62 390 387 72 299 762 498 | 497 301 511 22 1006 163 627 143 1130 1285 932 602 221 593 171 52 446 78 753 448 463 508 656 409 429 179 264 499 | 498 180 513 481 660 426 317 176 515 691 126 274 294 299 131 689 96 306 300 519 473 152 116 256 587 172 524 99 500 | 499 664 132 163 826 814 274 69 497 146 234 987 1225 96 638 1008 463 44 530 392 618 568 210 411 447 280 470 216 256 820 120 116 285 30 15 581 294 1047 1134 1468 167 556 366 501 | 500 24 281 236 507 287 1009 844 1013 221 92 927 273 502 | 501 300 293 878 337 892 341 894 686 342 503 | 502 180 68 384 96 381 487 653 19 434 204 37 481 49 1316 18 701 738 284 165 422 743 212 233 822 483 198 189 355 99 65 282 474 7 504 | 503 1262 401 198 280 528 692 1414 1003 132 715 1135 615 50 182 53 622 256 1109 96 179 1132 317 322 941 446 1276 218 1049 398 391 627 356 716 306 1146 186 204 281 355 180 704 755 448 666 738 741 370 505 | 504 139 98 497 467 421 194 78 1284 401 87 6 175 613 264 525 171 176 201 603 1408 189 494 312 131 143 94 81 506 | 505 469 280 464 71 1218 474 1013 519 175 96 55 746 249 174 233 355 877 46 402 1243 72 260 54 202 390 240 424 714 801 422 95 431 698 745 93 477 392 327 575 567 496 89 398 517 270 201 1018 30 761 11 88 513 362 685 507 | 506 825 1033 688 351 878 677 287 840 257 508 | 507 68 567 149 108 81 442 316 527 153 228 422 229 95 199 231 523 628 377 174 227 509 | 508 309 878 753 306 267 308 510 | 509 288 329 285 293 875 680 456 291 747 872 323 511 | 510 293 894 879 681 886 512 | 511 317 312 190 526 513 | 512 116 180 126 117 256 514 | 513 46 747 608 0 44 1013 658 1034 657 256 68 404 650 630 108 734 712 64 257 258 646 282 434 651 168 6 429 233 647 48 175 110 94 143 1038 207 271 167 21 948 709 264 473 273 187 432 515 | 514 343 309 681 1429 288 904 299 325 339 516 | 515 522 473 517 | 516 299 282 110 221 822 332 310 747 518 | 517 24 1016 6 150 594 695 12 119 475 9 846 105 0 712 236 507 919 519 | 518 1591 877 1061 265 258 312 750 345 520 | 519 282 1050 1027 689 309 989 521 | 520 229 71 175 249 1058 131 745 1243 24 384 392 98 239 108 171 1 1012 88 323 225 86 107 207 209 826 525 182 173 238 41 522 | 521 99 127 429 191 133 542 520 134 479 179 523 | 522 185 49 628 513 180 166 162 193 24 865 383 721 1013 94 1046 522 637 256 431 201 1471 1035 55 1068 948 524 | 523 649 941 478 186 482 192 183 524 930 212 641 468 1453 493 435 300 379 503 196 577 128 318 572 512 404 557 1123 93 483 477 237 446 185 366 747 605 497 418 272 215 817 522 169 234 3 514 795 11 738 21 22 525 268 134 662 675 656 1072 500 417 492 613 264 317 525 | 524 299 120 254 249 126 927 1314 471 290 675 741 526 | 525 874 269 918 935 249 292 331 878 299 306 99 301 259 247 284 149 297 257 122 527 | 526 955 63 206 98 209 189 652 192 651 6 3 181 646 672 182 495 510 1100 491 191 167 11 134 173 174 1148 317 133 528 | 527 484 192 81 177 504 167 82 293 540 30 844 1253 529 | 528 872 322 325 327 308 990 299 332 530 | 529 475 55 162 659 87 97 194 175 1225 236 531 | 530 904 456 311 687 750 689 893 532 | 531 602 215 398 411 590 240 299 1209 152 402 301 328 194 544 830 150 525 418 657 196 449 163 291 0 553 306 505 1038 134 146 314 51 317 497 180 495 832 1015 225 106 1091 185 81 479 1167 135 366 276 494 203 310 839 247 447 522 406 533 | 532 948 476 525 287 102 302 344 117 878 478 189 8 150 192 194 0 180 741 209 90 99 1040 791 283 108 296 12 65 124 1146 147 173 202 131 488 747 214 659 401 134 241 37 590 482 579 291 176 207 43 450 507 167 920 146 171 264 534 | 533 454 236 929 594 239 369 618 822 293 545 1053 6 1214 117 535 | 534 0 285 518 835 1092 284 38 922 184 69 507 432 478 21 282 237 3 504 1165 203 10 120 130 43 970 209 8 151 653 941 193 187 777 701 63 698 424 222 197 46 962 516 565 85 470 143 300 613 196 847 191 134 49 6 536 | 535 273 602 132 216 30 386 384 469 1117 53 214 134 96 707 150 209 497 479 492 735 167 379 140 567 435 93 426 587 208 221 482 415 1049 537 | 536 601 681 556 873 686 1110 1138 587 1049 735 680 515 206 240 1007 101 936 193 171 874 21 964 490 181 398 300 743 918 43 64 306 488 146 424 280 242 1450 320 413 781 580 31 941 391 444 1334 1133 140 624 235 974 637 261 1266 465 19 179 233 745 115 479 978 13 332 473 211 489 1128 14 229 381 271 606 1444 672 788 1165 713 288 549 1024 278 182 641 327 139 512 196 731 318 275 29 688 310 1153 194 55 380 498 1010 517 207 370 269 495 11 314 302 1047 299 744 927 24 674 442 538 | 537 962 236 194 97 215 167 182 30 709 186 41 293 99 27 3 275 272 288 175 539 | 538 241 57 21 238 961 495 203 305 530 58 201 540 | 539 740 322 1013 292 116 761 541 | 540 27 209 464 273 809 238 81 1034 224 117 61 87 526 167 1083 626 62 426 277 473 150 930 203 303 622 708 94 172 1029 1411 257 542 | 541 865 1217 186 381 190 57 345 178 22 126 191 12 426 432 171 419 167 779 320 86 292 89 63 383 193 543 | 542 209 981 198 84 206 175 189 663 164 87 225 518 43 528 517 238 55 160 719 1523 15 101 210 10 635 113 191 28 197 701 21 514 691 507 211 777 468 323 68 58 8 65 731 13 190 527 946 544 | 543 269 326 545 | 544 709 227 21 647 218 567 216 54 70 0 180 257 540 372 28 98 390 750 587 626 231 402 678 1187 141 217 138 546 | 545 671 285 929 716 221 6 321 233 768 815 218 108 759 891 270 547 | 546 288 301 548 | 547 263 990 602 306 531 22 13 1024 1013 1088 283 465 881 641 330 750 294 16 54 304 346 251 682 293 327 549 | 548 287 126 236 747 281 150 550 | 549 254 49 287 876 293 221 236 274 256 242 551 | 550 689 259 580 180 131 317 236 90 315 160 615 237 354 1266 342 192 126 954 470 1066 1086 807 845 182 826 478 974 874 117 1168 420 942 594 216 10 709 54 281 94 67 410 197 923 323 27 808 186 469 596 450 385 672 208 279 508 195 8 217 152 218 1302 209 32 726 275 627 48 88 685 894 57 582 552 | 551 759 741 863 248 1151 124 1047 747 825 590 287 814 283 755 844 553 | 552 504 181 1450 477 130 495 198 484 489 204 640 134 614 518 55 196 274 131 49 588 604 554 | 553 285 541 66 844 85 251 173 819 124 595 281 229 3 244 1045 14 525 734 283 69 287 116 555 | 554 545 284 116 168 747 327 273 117 556 | 555 131 63 293 177 317 267 323 320 134 557 | 556 293 7 253 886 299 251 269 304 558 | 557 13 274 559 | 558 293 434 3 126 426 522 518 196 510 181 384 256 519 565 346 560 | 559 318 477 257 1162 249 974 1332 410 88 182 99 488 495 254 180 283 263 167 1018 21 274 256 10 561 | 560 1100 203 468 52 108 488 1008 505 162 153 670 64 639 204 409 644 169 13 97 257 7 228 1229 178 519 1448 446 567 424 276 174 361 955 945 514 745 216 549 379 45 21 180 502 402 425 199 674 510 478 732 2 3 541 771 659 209 801 495 543 87 477 200 924 384 530 205 184 132 143 565 503 562 | 561 442 55 461 190 476 683 217 0 72 132 140 143 590 193 87 549 81 563 | 562 232 256 293 564 | 563 256 471 299 1033 117 271 565 | 564 9 69 29 712 165 82 511 508 566 | 565 394 7 1192 70 241 153 726 484 14 94 704 404 95 96 53 581 1436 402 154 180 741 507 135 384 107 264 567 | 566 1018 301 0 317 1019 503 305 602 429 173 835 658 478 193 233 202 846 486 473 197 99 194 296 678 491 526 672 95 433 198 426 189 151 522 488 302 704 512 524 568 | 567 268 953 524 987 854 611 518 99 1136 569 | 568 110 282 49 286 116 251 120 507 747 320 299 283 570 | 569 304 257 288 878 320 571 | 570 963 180 572 | 571 1009 1170 288 276 12 318 573 | 572 204 182 177 143 684 49 257 346 21 215 653 574 | 573 271 330 909 288 326 261 212 287 1021 753 575 | 574 214 126 175 576 | 575 279 136 124 275 123 677 203 0 6 577 | 576 719 217 844 1031 865 43 86 446 209 264 99 68 227 190 117 738 578 398 142 81 1516 741 312 101 567 61 469 47 178 201 316 549 49 97 426 120 578 | 577 342 257 245 267 324 579 | 578 0 654 287 215 237 432 210 257 513 244 876 203 434 519 201 288 233 49 580 | 579 824 470 686 1013 2 256 581 | 580 220 274 843 136 1352 582 | 581 249 92 1214 454 14 410 368 256 840 270 312 327 117 583 | 582 264 11 197 174 512 199 584 | 583 228 422 430 229 226 449 227 585 | 584 729 211 706 1534 206 1120 922 1004 18 17 164 918 169 542 59 1148 556 586 | 585 38 558 925 27 402 469 160 650 848 26 237 180 201 317 840 126 187 294 929 778 182 117 264 1217 181 779 409 43 355 550 78 977 587 | 586 348 271 886 268 904 689 690 352 285 894 322 333 357 332 889 259 327 291 588 | 587 431 70 143 39 259 142 72 332 450 214 750 96 271 171 317 530 216 93 418 780 398 153 809 141 872 131 958 392 730 577 120 723 41 746 161 1060 7 560 841 221 106 379 209 28 11 312 734 1310 355 55 293 589 | 588 293 285 299 338 337 335 876 327 590 | 589 284 753 863 1016 14 129 115 1013 475 297 1008 591 | 590 739 920 614 507 78 305 865 708 63 69 65 236 711 592 | 591 417 78 968 741 254 846 346 1376 194 410 55 951 237 272 261 318 651 822 214 249 312 630 282 256 319 366 853 172 1513 404 120 1084 897 478 7 844 121 521 233 677 327 743 326 465 331 193 468 1047 1066 223 381 115 91 54 324 356 14 116 284 221 8 679 128 426 526 181 23 891 408 511 734 281 747 530 134 602 294 12 1078 1011 593 | 592 391 99 181 192 865 240 14 285 277 965 55 105 156 698 10 199 762 731 317 300 404 120 467 284 72 283 594 | 593 285 49 482 244 198 595 | 594 1263 927 128 993 150 323 843 293 8 297 234 545 543 221 257 844 459 1027 596 | 595 312 12 597 | 596 327 292 14 294 322 325 1015 598 | 597 257 21 259 599 | 598 281 987 236 534 1314 947 275 279 293 600 | 599 91 1 175 264 402 88 539 561 509 187 540 514 95 678 173 52 1418 801 601 | 600 323 833 418 38 739 20 471 57 90 819 21 153 503 162 155 240 131 257 1539 1062 356 317 482 177 120 81 364 386 194 197 602 | 601 303 49 180 8 258 299 603 | 602 173 215 449 209 55 604 | 603 443 184 200 199 163 126 557 99 442 605 | 604 530 173 292 117 293 356 404 948 618 209 78 407 337 525 186 110 606 | 605 122 94 227 257 32 264 131 224 124 1189 312 175 427 748 90 194 815 938 646 249 236 99 651 306 167 384 178 54 805 248 716 500 49 474 843 941 590 80 283 650 636 545 183 197 187 1064 587 691 925 607 | 606 44 482 473 310 136 608 | 607 489 1114 68 418 57 477 237 505 701 968 15 212 24 299 479 27 460 474 461 693 741 605 125 847 482 181 194 734 468 167 735 286 91 609 | 608 287 947 312 351 610 | 609 750 6 274 476 116 94 418 271 182 282 126 186 606 422 484 611 | 610 886 354 335 287 881 339 689 612 | 611 1062 321 14 476 201 99 613 | 612 257 49 175 614 | 613 121 471 1133 293 457 0 870 840 285 615 | 614 169 86 178 526 528 174 236 677 270 434 261 520 285 267 331 616 | 615 1312 347 285 312 342 338 878 315 617 | 616 6 859 564 293 97 133 88 589 174 643 630 1018 237 344 173 439 634 566 854 652 301 16 440 618 | 617 203 495 49 548 149 191 317 384 422 954 965 418 426 175 1065 124 1184 403 789 97 961 53 51 158 63 730 1211 72 171 232 173 712 147 619 | 618 808 49 126 182 575 565 807 180 120 390 160 596 326 620 | 619 564 464 1034 624 98 682 894 408 173 242 137 180 171 77 405 741 172 111 233 757 1218 559 421 621 | 620 566 134 450 180 875 3 207 300 299 768 623 70 400 583 122 23 824 809 870 409 878 49 567 587 54 275 789 81 794 803 584 383 808 622 | 621 729 282 366 71 65 131 721 431 14 1551 1206 45 736 141 495 211 402 117 232 30 432 27 832 168 1078 1077 203 481 1202 580 247 7 664 95 624 418 94 228 23 738 3 8 230 1227 175 217 976 768 177 1405 184 1230 623 | 622 814 658 78 226 221 126 120 215 227 450 257 152 184 624 | 623 863 345 107 248 686 287 1027 123 590 269 904 247 13 596 23 299 126 1066 618 245 1011 311 507 404 254 325 749 274 625 | 624 221 583 201 189 153 180 639 22 602 211 215 677 99 21 521 518 475 596 651 485 731 197 626 | 625 323 681 322 291 679 627 | 626 178 1003 580 684 214 116 213 68 1073 190 948 553 75 38 57 182 561 650 95 577 226 160 1134 287 734 678 288 467 527 1043 187 529 147 657 659 540 469 384 1266 628 | 627 983 629 | 628 186 331 990 708 134 181 146 983 422 650 299 54 22 172 209 272 85 269 1037 267 270 159 38 193 630 | 629 475 116 476 171 69 594 294 95 99 1054 734 495 931 120 212 818 272 14 863 471 194 63 814 631 | 630 345 312 293 331 632 | 631 621 163 171 67 469 403 422 401 509 274 762 275 155 160 90 54 142 98 194 94 1182 172 68 99 549 317 474 209 1027 21 633 | 632 1131 78 171 650 116 176 96 44 147 634 | 633 475 272 1007 923 105 120 716 282 474 271 677 739 675 932 284 108 24 590 1083 293 299 635 | 634 12 300 357 876 149 636 | 635 0 312 812 274 637 | 636 99 594 470 716 474 288 925 117 285 148 123 274 6 930 739 146 1059 92 507 638 | 637 553 513 88 237 99 173 194 434 167 522 116 639 | 638 169 552 1193 197 1162 196 795 512 470 177 746 701 581 134 450 646 660 579 1004 282 85 355 672 640 | 639 172 37 731 750 549 567 232 179 345 188 41 32 1 372 1009 801 641 | 640 123 88 241 1193 510 22 269 335 202 482 431 642 | 641 37 131 1414 49 150 71 467 500 1010 1177 995 1075 698 70 958 1472 540 249 596 1284 0 574 484 1530 394 730 1013 137 1310 215 863 312 417 576 48 464 376 65 164 12 77 201 1145 1135 121 140 155 650 471 587 397 287 244 974 795 1424 219 811 659 57 826 401 1286 643 | 642 207 366 76 500 409 208 968 1011 1138 267 49 504 41 184 1064 480 126 495 402 324 245 185 508 214 955 57 392 570 629 644 | 643 299 822 49 257 1619 327 236 321 987 329 116 249 124 645 | 644 747 657 54 285 72 10 267 663 238 242 557 46 95 640 653 505 184 49 652 134 38 673 197 646 | 645 891 258 894 327 647 | 646 553 603 116 133 290 426 254 236 495 76 1062 81 146 173 648 | 647 472 410 796 177 674 563 117 522 239 173 174 384 635 66 402 429 322 815 171 413 93 126 839 167 930 21 1227 199 483 1027 779 88 294 1029 228 411 196 6 120 564 89 745 574 863 584 628 683 808 185 293 762 739 575 670 447 457 109 649 | 648 1282 146 650 | 649 629 308 707 750 94 218 54 670 312 662 678 1246 62 90 433 626 848 630 154 575 133 1109 704 1059 1038 78 199 186 204 1034 401 567 213 577 214 79 477 481 120 132 430 234 28 388 562 624 822 322 578 596 210 1418 362 503 897 190 641 257 289 144 158 264 1 510 67 61 152 22 564 651 | 650 284 652 | 651 698 537 306 332 124 747 653 | 652 565 225 82 1139 731 86 1619 387 473 229 447 238 457 448 233 519 549 203 818 151 10 193 510 120 943 424 657 801 427 185 226 175 155 131 692 669 68 53 770 738 618 264 75 1041 370 209 134 654 | 653 545 68 312 968 467 21 962 287 173 53 275 738 590 237 0 331 248 150 1282 153 688 86 587 145 595 23 507 1114 281 11 417 784 655 | 654 273 669 280 51 944 804 726 743 504 706 791 935 671 1066 1196 165 1193 874 655 738 1461 521 752 353 646 536 1060 309 123 287 894 520 1061 1195 201 517 416 305 1170 1420 296 1166 1631 395 173 701 1505 1374 1405 530 336 511 1197 1070 180 134 324 729 788 519 286 300 78 170 1040 708 249 765 4 1128 1110 979 239 734 210 750 143 339 254 1647 644 1160 941 911 11 261 181 291 952 1134 55 316 1023 245 962 222 1173 1265 12 358 42 802 1444 1111 1175 573 698 131 506 1152 326 711 1043 974 1247 1135 60 356 914 1637 1136 761 512 953 1172 1011 366 1244 1165 1464 1640 691 871 656 | 655 688 326 244 346 337 300 657 | 656 0 345 108 110 116 507 658 | 657 7 510 69 1078 1100 85 918 21 659 | 658 606 271 257 143 201 565 804 793 49 366 130 3 489 96 184 196 1167 314 659 177 293 505 610 213 513 466 656 660 | 659 81 166 183 96 461 62 248 401 23 160 70 929 602 131 215 1073 889 194 21 214 144 61 738 221 28 289 238 404 1482 134 2 469 218 785 390 258 7 428 162 181 297 678 443 270 661 | 660 675 94 530 407 167 221 602 271 172 567 537 171 1034 139 174 180 134 196 63 209 95 120 57 662 | 661 1380 9 12 1341 663 | 662 657 923 740 404 22 95 761 1323 1275 68 709 1085 681 507 88 123 306 1010 275 317 8 409 2 97 327 325 974 1160 281 1326 181 664 | 663 432 477 6 465 672 677 804 63 126 211 478 51 208 179 221 285 131 174 1100 630 190 49 284 663 517 52 656 30 641 481 94 316 665 | 664 64 507 426 314 190 78 404 619 108 422 471 630 720 133 156 125 97 545 91 221 199 416 666 | 665 637 205 178 830 1097 257 1265 428 473 24 603 683 426 237 287 923 661 12 509 524 204 944 470 317 263 518 431 199 519 708 221 285 543 1020 146 477 404 309 483 656 171 545 653 497 652 695 22 293 706 68 11 235 482 667 | 666 284 434 317 526 191 271 97 68 659 8 282 181 426 668 | 667 402 285 256 270 881 287 136 12 474 901 895 669 | 668 536 116 173 426 323 257 193 221 646 190 322 149 186 180 613 267 482 195 312 247 602 670 | 669 97 483 968 82 473 482 671 | 670 946 203 22 52 1238 577 181 590 176 28 509 596 32 4 160 78 801 55 778 565 209 678 175 545 510 450 120 525 503 672 | 671 930 14 873 673 | 672 257 326 291 322 325 674 | 673 928 684 314 741 750 288 291 180 675 | 674 305 508 649 317 462 676 | 675 519 180 353 256 317 113 878 915 172 63 344 327 538 173 268 479 992 315 911 677 | 676 285 404 125 267 13 150 538 293 287 454 739 987 678 | 677 286 14 126 679 | 678 326 356 168 415 240 195 530 720 153 152 49 99 41 285 680 | 679 1011 407 97 168 14 284 272 142 150 681 | 680 538 293 682 | 681 923 264 351 779 508 356 93 292 540 121 68 181 1304 762 378 187 355 411 861 8 82 1231 808 14 1439 555 1027 805 251 258 686 78 20 778 365 419 723 253 771 565 990 958 88 1089 57 66 947 245 25 275 432 1078 298 942 541 550 231 185 147 238 789 800 362 557 780 361 394 218 931 1038 158 75 364 921 755 720 179 171 526 215 41 803 469 70 683 | 682 267 747 301 307 1279 311 753 310 269 270 346 353 677 327 682 293 684 | 683 37 552 160 120 401 1282 595 150 81 281 172 216 49 215 82 685 | 684 268 324 323 874 686 | 685 473 186 356 479 134 466 55 526 429 172 196 177 541 426 687 | 686 312 688 | 687 681 689 | 688 878 150 110 108 747 762 409 595 474 12 236 690 | 689 79 84 97 63 1206 793 87 711 215 50 580 1027 3 654 1117 201 147 992 202 68 513 691 | 690 169 7 477 523 630 317 747 734 692 | 691 55 286 755 320 1053 1046 207 410 522 1131 1027 65 693 | 692 130 288 1521 38 24 161 522 422 672 571 487 526 281 6 192 707 491 1247 854 280 120 976 55 527 448 938 229 653 76 8 57 694 | 693 1049 228 49 274 215 1262 490 1454 30 156 209 519 238 510 51 656 70 434 99 201 660 483 695 | 694 312 345 304 353 311 988 696 | 695 311 343 905 177 697 | 696 149 1244 753 595 124 988 123 817 282 294 747 285 287 269 1011 6 814 545 368 125 253 259 290 236 1021 698 | 697 511 82 484 306 1148 193 420 329 504 605 524 1114 142 498 708 430 482 197 434 182 9 194 186 356 213 514 699 | 698 747 0 543 748 234 299 824 306 976 270 1128 928 1614 117 404 128 879 977 1012 1010 1027 97 321 274 282 929 49 457 8 618 481 827 303 1642 1008 105 327 700 | 699 143 78 530 422 55 701 | 700 296 99 314 271 302 312 126 343 702 | 701 258 747 306 703 | 702 293 457 49 221 844 14 818 704 | 703 208 353 210 179 1295 153 190 653 606 496 343 21 647 527 678 68 13 299 487 97 285 381 57 522 705 | 704 274 281 1 254 110 225 143 285 21 88 224 194 683 402 192 654 698 1034 596 95 362 565 116 796 706 | 705 24 6 293 409 8 707 | 706 255 301 165 485 123 162 524 164 777 292 190 722 1017 629 601 497 7 487 215 949 718 1007 605 961 448 952 173 659 1173 1067 735 1162 746 380 316 247 484 702 640 1203 12 1020 196 198 706 769 935 506 286 312 1141 504 708 | 707 470 1046 537 254 865 236 595 24 475 257 268 318 844 14 298 1053 275 627 739 180 709 | 708 27 632 124 199 738 292 469 180 362 52 171 1217 78 412 558 230 4 249 294 514 232 575 710 | 709 299 98 602 22 334 317 186 0 203 298 417 94 1018 339 55 326 180 300 482 302 78 711 | 710 228 1118 462 282 229 64 131 734 9 730 143 965 7 192 142 280 1445 844 51 15 424 659 85 484 565 1167 353 1052 426 754 960 402 87 377 728 904 418 315 968 21 714 47 712 | 711 1177 727 811 430 109 1090 72 721 420 58 1468 60 167 1502 364 171 793 194 995 414 392 293 39 41 1073 142 94 82 399 1479 713 | 712 1126 310 268 714 | 713 180 254 596 476 404 1015 2 470 409 110 116 1151 280 275 322 715 | 714 755 424 57 238 249 82 158 88 975 264 1046 127 545 39 1214 273 657 157 221 95 207 194 96 154 124 366 712 1187 49 182 575 99 716 | 715 90 152 835 483 95 132 490 237 94 413 130 1202 1049 422 110 191 503 281 525 704 214 472 87 1019 473 174 659 10 240 403 68 72 723 161 236 1112 497 632 30 141 226 825 167 504 82 189 131 203 717 | 716 292 293 270 339 49 677 887 249 268 325 23 1050 475 257 259 718 | 717 755 221 925 283 1164 814 1046 117 750 749 1027 719 | 718 22 78 96 219 70 126 184 293 136 720 | 719 257 905 748 301 267 901 310 721 | 720 304 301 357 1391 356 392 654 214 1295 317 193 687 1038 64 144 260 83 581 677 683 57 161 630 281 947 124 681 321 1220 283 738 994 722 | 721 121 6 150 146 306 677 99 332 293 285 822 865 147 870 596 723 | 722 321 163 987 177 149 724 | 723 265 1616 907 360 325 271 335 875 1061 307 892 258 1126 288 257 987 894 350 331 330 351 725 | 724 299 99 357 18 726 | 725 256 1027 408 727 | 726 440 67 124 932 627 258 830 32 131 568 154 889 202 311 746 538 423 68 41 992 120 247 506 679 264 377 158 402 177 100 1228 205 925 166 195 1243 759 198 69 357 392 267 277 684 422 81 1034 1214 396 163 99 221 134 567 229 575 24 398 747 929 208 228 82 878 446 91 728 | 727 321 115 242 470 729 | 728 327 287 271 337 730 | 729 747 299 257 339 731 | 730 191 182 356 392 215 152 7 479 135 65 484 27 1085 844 519 1086 732 | 731 244 268 733 | 732 675 1008 287 1170 1022 984 219 125 323 1225 1162 12 257 1046 514 273 949 244 923 734 | 733 197 173 661 171 317 190 212 464 229 49 735 | 734 0 8 146 292 288 49 122 12 299 126 736 | 735 295 531 285 253 532 747 737 | 736 185 11 57 31 257 738 | 737 95 94 207 392 256 232 173 649 88 213 160 63 422 259 658 178 117 127 140 120 270 116 215 99 153 53 239 918 739 | 738 131 96 317 464 194 740 | 739 321 937 301 327 1037 741 | 740 53 76 784 81 814 287 214 422 280 264 789 120 698 273 91 16 681 208 78 225 215 312 695 742 | 741 180 507 0 590 743 | 742 99 296 307 300 258 180 744 | 743 507 962 427 27 1133 237 745 | 744 491 214 518 173 202 285 99 97 123 257 203 509 95 11 126 602 746 | 745 95 116 183 522 225 430 229 221 182 280 63 1 120 719 747 | 746 222 1374 649 647 704 151 155 496 1141 27 162 587 3 81 950 1455 1158 29 886 624 417 415 116 268 662 68 518 189 1204 317 528 841 654 153 581 234 69 198 1426 31 516 173 171 16 648 275 554 1178 402 99 123 748 | 747 7 257 85 473 691 88 180 63 497 327 646 193 186 526 317 270 203 196 78 749 | 748 662 365 1088 943 292 186 293 174 181 116 131 433 244 230 81 540 357 109 483 495 741 509 156 403 627 413 641 811 24 97 163 417 214 299 190 585 37 422 70 1187 1012 620 66 199 484 297 565 983 93 1015 355 419 202 364 185 46 822 635 750 | 749 300 270 321 747 326 751 | 750 315 249 486 1010 658 99 55 61 733 404 290 754 268 385 747 94 192 1077 1100 755 299 301 86 97 110 371 393 81 432 493 171 630 427 213 331 496 864 117 212 738 98 737 201 483 808 688 478 752 | 751 271 312 287 346 325 689 904 310 258 347 1175 259 753 | 752 181 321 503 22 293 346 70 356 271 749 97 303 315 182 88 754 | 753 741 594 921 294 339 755 | 754 689 301 871 886 287 936 244 322 327 756 | 755 62 366 602 99 54 929 408 730 234 146 140 227 8 621 402 255 757 | 756 160 225 677 3 57 684 1187 332 683 37 473 155 154 569 384 938 750 175 470 349 664 741 230 95 226 404 1013 187 163 68 573 758 | 757 134 430 287 618 55 196 154 171 63 285 996 836 158 296 715 120 763 528 182 545 546 122 656 1018 202 1021 1045 602 504 628 747 183 435 170 539 226 330 897 337 530 1011 480 140 570 27 251 216 146 174 310 651 128 342 221 1089 98 749 505 208 11 76 195 288 238 575 311 840 339 210 299 319 1282 759 | 758 299 936 274 219 590 760 | 759 722 119 110 775 254 257 97 761 | 760 277 545 677 260 257 221 234 470 987 292 274 122 457 876 747 124 476 507 762 | 761 874 933 763 | 762 587 366 460 150 175 110 68 96 4 69 504 55 172 38 729 221 701 54 356 381 391 49 279 3 132 1038 691 514 124 158 465 84 736 764 | 763 244 139 320 526 1151 8 175 695 742 12 120 279 1027 217 94 590 116 844 254 274 863 280 765 | 764 284 521 970 136 221 49 506 169 766 | 765 52 228 482 97 201 647 587 653 493 446 418 130 210 51 430 503 230 174 632 401 132 413 204 1020 629 604 180 522 193 1297 196 517 218 608 738 464 379 711 767 | 766 1067 206 99 723 241 523 431 768 | 767 1015 116 590 965 309 475 99 345 769 | 768 1010 410 221 117 236 475 770 | 769 476 507 0 299 294 252 243 330 49 13 301 128 923 771 | 770 689 202 82 27 241 948 402 78 143 188 136 891 461 168 163 651 772 | 771 311 325 326 314 747 327 270 773 | 772 958 90 432 664 1474 768 1186 99 13 203 46 587 402 353 546 381 0 854 120 789 939 215 385 356 108 407 1035 317 731 567 250 263 199 947 521 23 839 126 774 | 773 1418 919 510 27 833 185 257 848 649 653 67 691 160 683 117 410 448 366 500 209 1078 392 807 549 446 195 509 28 187 385 1015 90 567 186 100 507 654 379 249 210 61 87 1273 81 775 | 774 285 299 326 328 301 689 899 749 312 244 776 | 775 768 441 442 438 568 759 705 440 193 617 524 523 522 216 777 | 776 215 520 126 272 778 | 777 93 1034 229 261 194 173 55 779 | 778 470 20 108 925 234 595 254 780 | 779 69 661 207 356 507 886 509 21 78 658 384 418 27 603 781 | 780 126 186 317 194 134 877 231 96 782 | 781 937 682 309 242 1476 342 871 1243 1643 749 1378 314 1024 1404 257 1282 680 291 323 534 1416 1381 1295 1299 1159 1390 1141 1095 1011 1126 1614 354 535 256 1597 1189 1172 255 879 1277 894 748 884 1588 268 993 1386 271 331 783 | 782 875 327 259 880 306 947 298 879 784 | 783 268 285 270 311 269 753 897 257 325 876 303 333 259 345 326 785 | 784 11 78 786 | 785 176 448 230 179 98 870 356 500 202 288 207 209 97 3 274 187 418 702 457 496 94 0 787 | 786 360 347 341 244 1433 897 936 327 312 287 750 788 | 787 753 228 50 234 707 300 446 434 450 797 698 81 578 194 428 199 0 227 491 1276 517 257 226 84 192 11 549 725 930 269 143 683 430 43 552 648 288 42 10 28 134 527 225 510 370 158 293 299 356 156 789 | 788 180 0 110 248 149 99 790 | 789 153 138 375 789 377 55 1043 171 582 785 0 773 825 172 495 214 551 65 40 1090 157 708 207 416 121 185 741 64 221 62 67 677 248 50 549 401 861 392 943 390 115 927 71 1184 948 1027 21 469 89 239 209 130 99 754 791 | 790 318 792 | 791 1131 20 6 281 1196 12 1046 150 925 120 839 124 117 793 | 792 1066 297 120 823 108 249 507 1364 150 99 180 0 741 794 | 793 886 750 268 149 180 13 472 454 272 1250 248 795 | 794 99 234 674 218 718 163 432 180 553 1554 1198 208 120 88 188 142 471 381 1412 122 545 11 566 424 201 1040 409 61 1094 746 143 46 796 | 795 1041 526 163 398 741 495 487 173 854 3 1268 321 277 356 281 730 1039 325 55 290 217 486 1100 172 927 0 473 401 754 820 271 548 285 738 237 44 1302 1056 483 300 553 280 858 784 1047 413 499 297 105 85 933 767 117 428 264 338 317 848 976 14 199 1054 1414 549 244 386 476 606 283 370 94 590 648 782 661 449 233 322 605 57 93 797 | 796 947 1253 339 798 | 797 115 269 51 70 86 1269 282 78 320 238 258 404 227 462 288 224 755 768 960 708 203 587 376 1468 219 94 416 419 393 877 111 647 242 171 745 754 583 733 180 943 727 814 698 82 1 659 923 799 | 798 478 483 172 288 126 190 1544 305 800 | 799 741 456 299 291 221 24 180 274 14 801 | 800 325 331 244 354 342 680 802 | 801 285 326 656 566 259 303 216 183 668 258 263 265 564 747 803 | 802 270 747 302 324 260 303 321 804 | 803 545 587 398 197 549 1221 364 608 150 174 1487 184 214 134 94 0 567 242 183 738 656 931 638 1284 527 1073 678 718 971 623 377 1046 947 1040 225 182 83 259 236 509 88 422 133 479 143 194 1227 1209 1410 283 171 24 90 1139 70 1049 575 446 636 1138 215 392 981 54 528 553 428 327 1 448 646 654 1243 631 96 948 1100 161 927 244 228 762 192 478 290 196 805 | 804 386 175 474 95 469 199 568 182 215 31 11 222 90 419 647 381 549 141 100 6 4 104 382 771 121 117 865 134 1097 21 427 1117 941 67 161 431 678 958 400 366 227 921 78 70 120 405 806 | 805 237 342 156 285 185 1070 132 432 194 94 121 167 239 155 257 1017 110 483 173 627 230 69 272 0 199 1128 236 420 807 | 806 1443 841 526 142 583 0 945 126 629 379 677 373 100 209 683 172 553 28 967 490 193 609 134 565 549 472 540 1065 297 1077 143 427 402 719 658 997 1273 117 407 185 227 595 203 808 | 807 324 299 287 750 345 809 | 808 288 271 285 306 339 318 332 810 | 809 293 312 303 901 872 811 | 810 242 812 | 811 677 288 813 | 812 679 749 269 750 299 814 | 813 655 558 673 674 16 440 666 144 357 815 | 814 385 523 130 131 470 201 595 49 173 664 133 64 433 613 711 85 157 1038 517 581 670 401 1298 226 638 82 225 178 120 442 312 227 587 150 816 | 815 686 331 263 321 817 | 816 117 357 288 923 8 818 | 817 244 819 | 818 267 532 820 | 819 288 323 327 346 750 821 | 820 179 274 117 99 131 356 434 0 78 475 116 236 94 280 147 388 494 97 150 822 | 821 1239 357 90 750 100 823 | 822 30 6 1106 21 373 195 641 158 54 67 187 181 89 238 124 400 97 7 477 27 186 653 624 791 205 237 57 513 101 135 741 472 824 | 823 288 686 988 825 | 824 985 282 275 840 863 869 13 175 412 924 180 405 124 826 321 930 120 684 99 236 221 273 24 369 283 125 97 1048 136 826 | 825 335 1238 91 160 183 819 402 230 767 434 509 180 225 0 232 577 38 549 61 827 | 826 312 828 | 827 268 873 212 269 381 1621 274 282 901 693 1067 327 511 302 461 462 639 829 | 828 188 1017 12 152 236 274 99 461 309 256 124 85 528 638 104 830 | 829 180 229 431 1 500 160 497 95 293 417 647 230 833 831 | 830 876 590 339 297 49 686 353 312 209 326 1118 749 55 832 | 831 680 875 293 872 894 287 833 | 832 545 160 186 21 156 511 210 97 110 918 695 551 503 143 669 976 6 1011 825 239 176 68 117 121 151 99 187 237 1385 54 226 181 133 454 163 741 225 432 216 590 859 22 173 196 297 466 229 356 760 823 266 346 801 283 25 640 10 834 | 833 281 99 761 116 126 293 275 835 | 834 0 707 156 1152 672 161 457 96 195 190 27 485 987 126 204 1044 159 404 224 286 836 | 835 164 11 506 418 88 191 1064 602 321 41 899 184 173 837 | 836 844 627 595 275 761 293 283 110 180 838 | 837 297 595 731 747 479 275 110 186 285 113 704 717 254 120 418 126 152 839 | 838 236 259 280 219 110 409 49 741 257 254 1047 117 126 105 844 0 1380 840 | 839 151 844 168 190 505 528 530 209 193 654 169 7 404 164 514 142 565 63 429 663 6 639 172 153 49 579 527 99 615 203 492 498 211 208 174 614 854 674 197 479 841 | 840 891 330 747 271 753 872 314 301 315 887 842 | 841 361 885 1104 1394 314 748 843 | 842 97 635 194 448 264 216 602 207 287 78 401 96 22 449 175 562 589 224 132 68 442 549 51 627 205 257 434 1064 689 215 153 670 631 526 213 445 527 384 196 529 1156 217 377 126 131 844 | 843 89 49 215 430 88 69 254 82 54 293 81 404 171 945 175 845 | 844 749 1237 895 302 305 846 | 845 1073 1517 204 35 735 673 422 482 795 621 519 515 215 658 131 185 179 316 769 1017 399 1539 63 481 377 30 70 551 779 468 218 587 425 720 478 564 195 714 132 22 504 68 41 451 541 1450 3 58 731 430 184 607 226 558 696 484 440 704 60 173 202 791 1296 447 53 139 140 943 232 133 301 418 210 86 214 212 380 62 462 96 420 1219 727 585 486 548 525 940 391 141 557 508 186 198 434 395 490 941 97 100 847 | 846 433 657 224 472 257 175 478 644 731 403 1085 410 172 150 526 446 741 46 739 418 506 65 454 227 76 194 132 87 848 | 847 151 206 184 150 898 94 587 153 134 970 180 488 526 179 108 404 237 402 162 126 431 209 849 | 848 426 850 | 849 203 55 299 209 171 14 173 120 293 96 647 21 851 | 850 303 9 312 342 290 865 1088 352 594 263 405 747 840 298 121 411 1675 472 159 832 339 911 230 91 301 332 874 222 471 894 844 331 175 479 251 1253 1539 317 16 3 338 1012 1336 852 | 851 117 150 126 24 357 108 567 289 853 | 852 325 291 300 322 329 876 879 339 681 854 | 853 272 317 116 236 267 332 190 269 6 199 2 1676 3 357 828 134 243 663 462 7 743 596 48 49 132 187 117 1133 63 454 202 327 631 55 1334 761 172 259 511 824 465 798 1280 695 420 196 88 854 184 430 627 704 170 321 281 110 855 | 854 197 58 581 856 | 855 325 306 299 311 271 327 857 | 856 686 115 987 891 858 | 857 291 288 689 99 332 292 326 859 | 858 110 275 1314 1280 475 117 860 | 859 288 244 285 310 948 312 1040 55 1046 306 331 309 662 780 861 | 860 169 1226 51 291 461 9 508 19 304 862 | 861 1010 490 477 432 428 918 116 78 461 830 415 181 435 422 58 514 543 844 567 822 98 187 134 482 195 81 196 90 264 91 747 204 863 | 862 753 300 1061 1037 257 293 1606 1236 690 750 345 876 305 1242 1677 902 320 682 905 1394 884 303 989 361 894 886 864 | 863 70 52 641 707 207 21 221 1134 97 950 175 6 421 1209 482 160 1 46 143 90 627 769 561 289 628 274 95 1111 84 202 132 51 127 65 156 158 403 48 257 224 393 287 596 110 464 256 728 142 450 780 1032 342 401 78 1139 120 182 733 150 865 | 864 267 70 454 500 587 94 404 866 | 865 268 346 867 | 866 210 78 173 1607 497 97 275 206 182 185 650 203 131 1153 6 187 197 689 293 868 | 867 397 737 88 447 172 451 231 201 166 187 500 209 97 227 824 446 22 46 58 152 578 236 645 433 777 157 630 565 1187 519 588 267 171 869 | 868 411 595 252 1060 695 1013 287 281 870 | 869 520 53 510 254 602 769 51 503 271 208 395 394 1111 442 648 1 482 301 331 21 76 326 400 314 64 353 478 683 257 473 488 69 63 176 126 698 197 476 87 569 203 168 1209 11 366 653 1019 434 871 | 870 514 1118 176 746 1344 274 434 574 182 314 194 359 358 288 650 330 906 565 160 903 872 | 871 105 110 362 762 349 1027 404 973 150 120 545 289 873 | 872 293 285 878 268 341 306 874 | 873 305 320 196 310 312 136 274 875 | 874 168 170 175 526 511 495 134 357 651 461 31 179 133 21 876 | 875 293 47 275 528 526 877 877 | 876 236 948 285 59 215 701 175 196 110 206 548 556 55 691 154 474 743 305 878 | 877 691 654 529 7 19 69 224 497 18 481 731 528 13 173 738 701 552 698 50 154 879 | 878 126 865 180 303 24 880 | 879 823 306 298 397 231 300 768 79 180 1015 227 347 1000 801 64 1275 39 366 78 11 70 602 624 677 688 20 434 583 947 769 283 684 81 455 618 567 379 104 63 1257 654 199 574 467 249 762 299 770 1040 176 540 383 400 730 95 760 1046 569 38 1043 402 186 97 1183 880 1156 200 94 627 0 375 406 939 317 93 2 881 | 880 132 422 670 48 558 1045 182 513 629 150 117 80 433 102 126 942 738 1539 116 933 471 128 476 303 332 523 522 374 213 464 98 62 191 413 139 192 207 1132 863 1214 21 1065 1479 273 0 418 214 321 519 581 224 704 1056 1163 1077 78 119 882 | 881 192 139 14 1014 116 475 472 931 928 167 418 49 1443 226 1411 95 392 195 411 65 567 410 120 406 287 368 264 283 587 883 | 882 128 406 866 223 560 193 1044 171 8 269 706 173 321 1221 226 54 88 702 345 18 175 747 518 318 955 1226 1064 711 153 895 301 899 272 1170 954 274 384 264 478 46 693 353 47 21 221 712 514 240 81 344 744 846 233 884 | 883 69 380 257 99 922 1017 197 212 509 284 885 | 884 172 232 96 945 87 150 385 820 244 141 166 814 81 93 178 289 180 160 886 | 885 146 272 2 6 482 97 237 66 823 75 370 95 186 42 656 474 238 199 590 684 1266 9 465 47 267 126 543 1066 327 99 939 152 709 1420 918 404 57 264 658 583 88 630 627 685 208 195 887 | 886 992 368 199 767 825 81 90 831 415 186 717 317 476 175 945 239 1028 21 201 124 163 120 595 150 127 64 114 49 454 1083 24 288 104 203 577 89 403 547 217 273 1062 888 | 887 68 190 889 | 888 653 1266 401 80 493 216 478 497 128 1418 174 770 186 38 93 69 66 171 179 511 434 150 190 748 1261 261 635 649 865 407 32 176 472 168 427 561 1152 278 1064 146 257 2 164 513 163 473 481 264 1552 880 296 233 317 1047 602 208 549 890 | 889 180 624 478 141 523 422 636 736 653 173 1148 519 588 22 674 433 199 603 209 204 228 495 891 | 890 933 530 24 458 932 312 110 106 99 120 322 739 892 | 891 133 272 780 86 440 283 4 11 173 290 49 366 57 424 738 421 434 950 1034 356 575 66 435 472 14 1117 97 128 524 61 417 69 158 317 522 227 21 1284 0 469 478 238 496 691 275 893 | 892 147 0 723 848 10 844 287 894 | 893 14 332 245 133 301 243 739 581 862 354 263 318 514 380 897 106 747 274 903 12 884 251 342 474 255 1461 1500 244 278 753 235 292 31 901 259 675 8 330 0 92 874 211 197 269 241 24 638 1591 56 1088 1006 533 136 895 | 894 274 1013 896 | 895 383 81 143 221 671 1671 548 75 413 871 173 430 186 195 941 134 274 85 720 225 567 695 568 1521 1182 507 120 574 835 142 233 650 53 180 126 8 264 319 205 6 79 171 615 116 392 449 492 481 678 1248 178 951 653 709 218 1010 398 1621 41 641 391 257 99 1045 224 897 | 896 226 185 418 1253 203 476 408 587 925 198 565 96 409 54 237 464 264 239 469 405 632 280 520 1032 865 39 234 24 119 1530 759 75 669 704 272 179 214 173 898 | 897 318 323 269 357 688 346 326 327 301 899 | 898 208 684 274 659 229 171 249 24 495 427 134 72 256 238 478 283 290 254 741 565 173 514 160 402 517 172 70 739 88 180 7 27 150 132 900 | 899 507 833 470 324 287 185 1131 477 660 409 901 | 900 508 286 545 567 160 173 522 442 661 154 234 401 0 150 635 450 825 402 19 1034 1119 731 37 251 902 | 901 514 303 171 227 190 325 256 1015 903 | 902 99 202 222 466 185 46 442 179 128 51 187 870 292 8 12 11 78 58 29 45 1008 409 1380 904 | 903 420 154 401 273 731 116 534 279 110 905 | 904 257 281 299 716 470 321 906 | 905 306 14 275 116 472 128 269 404 285 239 276 907 | 906 339 812 712 1118 41 7 688 87 1162 355 321 698 470 1219 122 743 172 312 49 78 290 475 495 696 923 761 4 1046 234 128 106 14 763 270 908 | 907 191 203 184 478 356 433 193 171 194 477 263 317 909 | 908 291 508 260 879 910 | 909 244 297 299 312 24 309 911 | 910 184 1202 98 101 968 20 506 431 427 208 215 464 196 426 626 190 86 418 214 912 | 911 171 495 422 196 245 516 654 426 913 | 912 91 182 209 301 221 497 183 267 150 190 422 595 530 418 728 918 21 142 407 180 202 27 317 914 | 913 87 691 780 915 | 914 303 309 269 320 300 751 749 301 690 895 916 | 915 228 243 1134 213 174 80 1112 16 654 38 221 720 529 726 426 234 32 216 958 762 70 4 763 54 432 117 218 172 510 734 255 754 203 182 41 791 596 384 285 143 124 568 582 63 1010 82 401 1681 202 2 805 156 22 194 1008 79 108 214 917 | 916 254 918 | 917 1064 418 210 486 178 169 442 791 920 494 630 165 0 164 152 1098 703 994 919 | 918 1100 242 461 49 203 1136 474 200 285 741 1085 267 1113 325 245 716 686 216 111 1277 10 627 530 20 557 236 283 260 115 87 81 286 124 318 92 1172 381 11 222 920 | 919 299 681 312 921 | 920 1059 719 1046 691 81 189 1033 124 394 368 201 239 327 195 777 1316 127 399 258 244 796 68 121 922 | 921 142 1034 88 248 394 405 171 948 158 236 426 1109 746 21 82 659 76 833 121 67 218 630 384 561 234 698 595 923 | 922 147 761 1027 287 2 221 279 150 740 924 | 923 194 835 0 172 704 12 204 432 113 236 848 428 518 55 70 470 925 | 924 322 562 875 787 324 566 926 | 925 287 302 324 288 257 236 927 | 926 293 78 1088 738 299 865 71 256 737 167 767 927 131 194 567 7 410 721 173 0 209 928 | 927 171 133 929 | 928 208 133 22 317 31 482 194 99 27 203 11 196 143 97 930 | 929 120 7 282 150 268 404 125 174 136 0 13 273 209 931 | 930 236 475 361 311 254 282 299 908 301 271 932 | 931 6 434 175 54 613 496 524 378 156 1049 171 1204 212 575 675 744 1453 967 648 658 132 518 428 66 192 177 523 221 162 356 164 76 1115 469 204 194 133 615 211 495 664 489 510 135 234 1448 44 473 502 1148 1120 413 404 63 933 | 932 1016 27 63 155 522 398 214 1245 404 0 764 160 558 217 156 788 238 86 229 473 227 1187 193 228 126 209 577 183 68 423 6 409 272 57 176 8 173 192 11 934 | 933 49 422 296 410 460 238 553 628 708 770 435 392 663 383 1 662 167 854 174 189 301 236 426 12 791 315 161 731 427 88 901 285 185 580 156 656 804 509 1202 704 143 583 195 95 785 935 | 934 470 716 236 923 814 281 254 124 936 | 935 1257 817 1085 926 546 300 136 1096 404 324 257 1010 15 345 323 5 275 1376 824 318 294 99 236 987 1170 342 254 844 311 765 937 | 936 125 285 863 235 294 49 507 1006 938 | 937 762 1011 180 110 404 675 126 24 755 327 342 677 596 6 289 125 870 590 251 0 684 275 939 | 938 930 1053 117 254 1027 284 14 940 | 939 609 173 627 315 167 285 293 49 381 208 163 160 346 435 136 878 6 470 237 941 | 940 123 116 297 272 293 942 | 941 422 171 215 606 361 94 182 527 173 98 327 1220 519 479 134 434 123 943 | 942 569 1066 355 11 470 594 180 183 95 126 225 26 422 123 580 120 317 63 815 96 201 425 398 193 230 55 624 1329 226 23 27 830 200 227 575 567 414 944 | -------------------------------------------------------------------------------- /ngcf.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Pytorch Implementation of Neural Graph Collaborative Filtering (NGCF) (https://doi.org/10.1145/3331184.3331267) 3 | 4 | This file contains the NGCF class 5 | 6 | authors: Mohammed Yusuf Noor, Muhammed Imran Özyar, Calin Vasile Simon 7 | ''' 8 | 9 | import numpy as np 10 | import scipy.sparse as sp 11 | import torch 12 | import torch.nn.functional as F 13 | import scipy.sparse as sp 14 | 15 | from torch import nn 16 | 17 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu") 18 | 19 | class NGCF(nn.Module): 20 | def __init__(self, n_users, n_items, emb_dim, layers, reg, node_dropout, mess_dropout, 21 | adj_mtx): 22 | super().__init__() 23 | 24 | # initialize Class attributes 25 | self.n_users = n_users 26 | self.n_items = n_items 27 | self.emb_dim = emb_dim 28 | self.adj_mtx = adj_mtx 29 | self.laplacian = adj_mtx - sp.eye(adj_mtx.shape[0]) 30 | self.reg = reg 31 | self.layers = layers 32 | self.n_layers = len(self.layers) 33 | self.node_dropout = node_dropout 34 | self.mess_dropout = mess_dropout 35 | 36 | #self.u_g_embeddings = nn.Parameter(torch.empty(n_users, emb_dim+np.sum(self.layers))) 37 | #self.i_g_embeddings = nn.Parameter(torch.empty(n_items, emb_dim+np.sum(self.layers))) 38 | 39 | # Initialize weights 40 | self.weight_dict = self._init_weights() 41 | print("Weights initialized.") 42 | 43 | # Create Matrix 'A', PyTorch sparse tensor of SP adjacency_mtx 44 | self.A = self._convert_sp_mat_to_sp_tensor(self.adj_mtx) 45 | self.L = self._convert_sp_mat_to_sp_tensor(self.laplacian) 46 | 47 | # initialize weights 48 | def _init_weights(self): 49 | print("Initializing weights...") 50 | weight_dict = nn.ParameterDict() 51 | 52 | initializer = torch.nn.init.xavier_uniform_ 53 | 54 | weight_dict['user_embedding'] = nn.Parameter(initializer(torch.empty(self.n_users, self.emb_dim).to(device))) 55 | weight_dict['item_embedding'] = nn.Parameter(initializer(torch.empty(self.n_items, self.emb_dim).to(device))) 56 | 57 | weight_size_list = [self.emb_dim] + self.layers 58 | 59 | for k in range(self.n_layers): 60 | weight_dict['W_gc_%d' %k] = nn.Parameter(initializer(torch.empty(weight_size_list[k], weight_size_list[k+1]).to(device))) 61 | weight_dict['b_gc_%d' %k] = nn.Parameter(initializer(torch.empty(1, weight_size_list[k+1]).to(device))) 62 | 63 | weight_dict['W_bi_%d' %k] = nn.Parameter(initializer(torch.empty(weight_size_list[k], weight_size_list[k+1]).to(device))) 64 | weight_dict['b_bi_%d' %k] = nn.Parameter(initializer(torch.empty(1, weight_size_list[k+1]).to(device))) 65 | 66 | return weight_dict 67 | 68 | # convert sparse matrix into sparse PyTorch tensor 69 | def _convert_sp_mat_to_sp_tensor(self, X): 70 | """ 71 | Convert scipy sparse matrix to PyTorch sparse matrix 72 | 73 | Arguments: 74 | ---------- 75 | X = Adjacency matrix, scipy sparse matrix 76 | """ 77 | coo = X.tocoo().astype(np.float32) 78 | i = torch.LongTensor(np.mat([coo.row, coo.col])) 79 | v = torch.FloatTensor(coo.data) 80 | res = torch.sparse.FloatTensor(i, v, coo.shape).to(device) 81 | return res 82 | 83 | # apply node_dropout 84 | def _droupout_sparse(self, X): 85 | """ 86 | Drop individual locations in X 87 | 88 | Arguments: 89 | --------- 90 | X = adjacency matrix (PyTorch sparse tensor) 91 | dropout = fraction of nodes to drop 92 | noise_shape = number of non non-zero entries of X 93 | """ 94 | 95 | node_dropout_mask = ((self.node_dropout) + torch.rand(X._nnz())).floor().bool().to(device) 96 | i = X.coalesce().indices() 97 | v = X.coalesce()._values() 98 | i[:,node_dropout_mask] = 0 99 | v[node_dropout_mask] = 0 100 | X_dropout = torch.sparse.FloatTensor(i, v, X.shape).to(X.device) 101 | 102 | return X_dropout.mul(1/(1-self.node_dropout)) 103 | 104 | def forward(self, u, i, j): 105 | """ 106 | Computes the forward pass 107 | 108 | Arguments: 109 | --------- 110 | u = user 111 | i = positive item (user interacted with item) 112 | j = negative item (user did not interact with item) 113 | """ 114 | # apply drop-out mask 115 | A_hat = self._droupout_sparse(self.A) if self.node_dropout > 0 else self.A 116 | L_hat = self._droupout_sparse(self.L) if self.node_dropout > 0 else self.L 117 | 118 | ego_embeddings = torch.cat([self.weight_dict['user_embedding'], self.weight_dict['item_embedding']], 0) 119 | 120 | all_embeddings = [ego_embeddings] 121 | 122 | # forward pass for 'n' propagation layers 123 | for k in range(self.n_layers): 124 | 125 | # weighted sum messages of neighbours 126 | side_embeddings = torch.sparse.mm(A_hat, ego_embeddings) 127 | side_L_embeddings = torch.sparse.mm(L_hat, ego_embeddings) 128 | 129 | # transformed sum weighted sum messages of neighbours 130 | sum_embeddings = torch.matmul(side_embeddings, self.weight_dict['W_gc_%d' % k]) + self.weight_dict['b_gc_%d' % k] 131 | 132 | # bi messages of neighbours 133 | bi_embeddings = torch.mul(ego_embeddings, side_L_embeddings) 134 | # transformed bi messages of neighbours 135 | bi_embeddings = torch.matmul(bi_embeddings, self.weight_dict['W_bi_%d' % k]) + self.weight_dict['b_bi_%d' % k] 136 | 137 | # non-linear activation 138 | ego_embeddings = F.leaky_relu(sum_embeddings + bi_embeddings) 139 | # + message dropout 140 | mess_dropout_mask = nn.Dropout(self.mess_dropout) 141 | ego_embeddings = mess_dropout_mask(ego_embeddings) 142 | 143 | # normalize activation 144 | norm_embeddings = F.normalize(ego_embeddings, p=2, dim=1) 145 | 146 | all_embeddings.append(norm_embeddings) 147 | 148 | all_embeddings = torch.cat(all_embeddings, 1) 149 | 150 | # back to user/item dimension 151 | u_g_embeddings, i_g_embeddings = all_embeddings.split([self.n_users, self.n_items], 0) 152 | 153 | self.u_g_embeddings = nn.Parameter(u_g_embeddings) 154 | self.i_g_embeddings = nn.Parameter(i_g_embeddings) 155 | 156 | u_emb = u_g_embeddings[u] # user embeddings 157 | p_emb = i_g_embeddings[i] # positive item embeddings 158 | n_emb = i_g_embeddings[j] # negative item embeddings 159 | 160 | y_ui = torch.mul(u_emb, p_emb).sum(dim=1) 161 | y_uj = torch.mul(u_emb, n_emb).sum(dim=1) 162 | log_prob = (torch.log(torch.sigmoid(y_ui-y_uj))).mean() 163 | 164 | # compute bpr-loss 165 | bpr_loss = -log_prob 166 | if self.reg > 0.: 167 | l2norm = (torch.sum(u_emb**2)/2. + torch.sum(p_emb**2)/2. + torch.sum(n_emb**2)/2.) / u_emb.shape[0] 168 | l2reg = self.reg*l2norm 169 | bpr_loss = -log_prob + l2reg 170 | 171 | return bpr_loss 172 | -------------------------------------------------------------------------------- /run_ngcf.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Pytorch Implementation of Neural Graph Collaborative Filtering (NGCF) (https://doi.org/10.1145/3331184.3331267) 3 | 4 | Run this file in terminal with arguments, per example: 5 | >> run.py --dataset Gowella --emb_dim 64 --layers [64] 6 | 7 | authors: Mohammed Yusuf Noor, Muhammed Imran Özyar, Calin Vasile Simon 8 | ''' 9 | 10 | import pandas as pd 11 | import torch 12 | 13 | import os 14 | from time import time 15 | from datetime import datetime 16 | 17 | from utils.load_data import Data 18 | from utils.parser import parse_args 19 | from utils.helper_functions import early_stopping,\ 20 | train,\ 21 | split_matrix,\ 22 | compute_ndcg_k,\ 23 | eval_model 24 | from ngcf import NGCF 25 | 26 | use_cuda = torch.cuda.is_available() 27 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu") 28 | torch.cuda.set_device(0) 29 | 30 | if __name__ == '__main__': 31 | 32 | # read parsed arguments 33 | args = parse_args() 34 | data_dir = args.data_dir 35 | dataset = args.dataset 36 | batch_size = args.batch_size 37 | layers = eval(args.layers) 38 | emb_dim = args.emb_dim 39 | lr = args.lr 40 | reg = args.reg 41 | mess_dropout = args.mess_dropout 42 | node_dropout = args.node_dropout 43 | k = args.k 44 | 45 | # generate the NGCF-adjacency matrix 46 | data_generator = Data(path=data_dir + dataset, batch_size=batch_size) 47 | adj_mtx = data_generator.get_adj_mat() 48 | 49 | # create model name and save 50 | modelname = "NGCF" + \ 51 | "_bs_" + str(batch_size) + \ 52 | "_nemb_" + str(emb_dim) + \ 53 | "_layers_" + str(layers) + \ 54 | "_nodedr_" + str(node_dropout) + \ 55 | "_messdr_" + str(mess_dropout) + \ 56 | "_reg_" + str(reg) + \ 57 | "_lr_" + str(lr) 58 | 59 | # create NGCF model 60 | model = NGCF(data_generator.n_users, 61 | data_generator.n_items, 62 | emb_dim, 63 | layers, 64 | reg, 65 | node_dropout, 66 | mess_dropout, 67 | adj_mtx) 68 | if use_cuda: 69 | model = model.cuda() 70 | 71 | # current best metric 72 | cur_best_metric = 0 73 | 74 | # Adam optimizer 75 | optimizer = torch.optim.Adam(model.parameters(), lr=args.lr) 76 | 77 | # Set values for early stopping 78 | cur_best_loss, stopping_step, should_stop = 1e3, 0, False 79 | today = datetime.now() 80 | 81 | print("Start at " + str(today)) 82 | print("Using " + str(device) + " for computations") 83 | print("Params on CUDA: " + str(next(model.parameters()).is_cuda)) 84 | 85 | results = {"Epoch": [], 86 | "Loss": [], 87 | "Recall": [], 88 | "NDCG": [], 89 | "Training Time": []} 90 | 91 | for epoch in range(args.n_epochs): 92 | 93 | t1 = time() 94 | loss = train(model, data_generator, optimizer) 95 | training_time = time()-t1 96 | print("Epoch: {}, Training time: {:.2f}s, Loss: {:.4f}". 97 | format(epoch, training_time, loss)) 98 | 99 | # print test evaluation metrics every N epochs (provided by args.eval_N) 100 | if epoch % args.eval_N == (args.eval_N - 1): 101 | with torch.no_grad(): 102 | t2 = time() 103 | recall, ndcg = eval_model(model.u_g_embeddings.detach(), 104 | model.i_g_embeddings.detach(), 105 | data_generator.R_train, 106 | data_generator.R_test, 107 | k) 108 | print( 109 | "Evaluate current model:\n", 110 | "Epoch: {}, Validation time: {:.2f}s".format(epoch, time()-t2),"\n", 111 | "Loss: {:.4f}:".format(loss), "\n", 112 | "Recall@{}: {:.4f}".format(k, recall), "\n", 113 | "NDCG@{}: {:.4f}".format(k, ndcg) 114 | ) 115 | 116 | cur_best_metric, stopping_step, should_stop = \ 117 | early_stopping(recall, cur_best_metric, stopping_step, flag_step=5) 118 | 119 | # save results in dict 120 | results['Epoch'].append(epoch) 121 | results['Loss'].append(loss) 122 | results['Recall'].append(recall.item()) 123 | results['NDCG'].append(ndcg.item()) 124 | results['Training Time'].append(training_time) 125 | else: 126 | # save results in dict 127 | results['Epoch'].append(epoch) 128 | results['Loss'].append(loss) 129 | results['Recall'].append(None) 130 | results['NDCG'].append(None) 131 | results['Training Time'].append(training_time) 132 | 133 | if should_stop == True: break 134 | 135 | # save 136 | if args.save_results: 137 | date = today.strftime("%d%m%Y_%H%M") 138 | 139 | # save model as .pt file 140 | if os.path.isdir("./models"): 141 | torch.save(model.state_dict(), "./models/" + str(date) + "_" + modelname + "_" + dataset + ".pt") 142 | else: 143 | os.mkdir("./models") 144 | torch.save(model.state_dict(), "./models/" + str(date) + "_" + modelname + "_" + dataset + ".pt") 145 | 146 | # save results as pandas dataframe 147 | results_df = pd.DataFrame(results) 148 | results_df.set_index('Epoch', inplace=True) 149 | if os.path.isdir("./results"): 150 | results_df.to_csv("./results/" + str(date) + "_" + modelname + "_" + dataset + ".csv") 151 | else: 152 | os.mkdir("./results") 153 | results_df.to_csv("./results/" + str(date) + "_" + modelname + "_" + dataset + ".csv") 154 | # plot loss 155 | results_df['Loss'].plot(figsize=(12,8), title='Loss') 156 | -------------------------------------------------------------------------------- /utils/helper_functions.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Pytorch Implementation of Neural Graph Collaborative Filtering (NGCF) (https://doi.org/10.1145/3331184.3331267) 3 | 4 | This file contains the following helper functions: 5 | - early_stopping() 6 | - train() 7 | - split_matrix() 8 | - ndcg_k() 9 | - eval_model 10 | 11 | authors: Mohammed Yusuf Noor, Muhammed Imran Özyar, Calin Vasile Simon 12 | ''' 13 | 14 | import numpy as np 15 | import torch 16 | 17 | def early_stopping(log_value, best_value, stopping_step, flag_step, expected_order='asc'): 18 | """ 19 | Check if early_stopping is needed 20 | Function copied from original code 21 | """ 22 | assert expected_order in ['asc', 'des'] 23 | if (expected_order == 'asc' and log_value >= best_value) or (expected_order == 'des' and log_value <= best_value): 24 | stopping_step = 0 25 | best_value = log_value 26 | else: 27 | stopping_step += 1 28 | 29 | if stopping_step >= flag_step: 30 | print("Early stopping at step: {} log:{}".format(flag_step, log_value)) 31 | should_stop = True 32 | else: 33 | should_stop = False 34 | 35 | return best_value, stopping_step, should_stop 36 | 37 | def train(model, data_generator, optimizer): 38 | """ 39 | Train the model PyTorch style 40 | 41 | Arguments: 42 | --------- 43 | model: PyTorch model 44 | data_generator: Data object 45 | optimizer: PyTorch optimizer 46 | """ 47 | model.train() 48 | n_batch = data_generator.n_train // data_generator.batch_size + 1 49 | running_loss=0 50 | for _ in range(n_batch): 51 | u, i, j = data_generator.sample() 52 | optimizer.zero_grad() 53 | loss = model(u,i,j) 54 | loss.backward() 55 | optimizer.step() 56 | running_loss += loss.item() 57 | return running_loss 58 | 59 | def split_matrix(X, n_splits=100): 60 | """ 61 | Split a matrix/Tensor into n_folds (for the user embeddings and the R matrices) 62 | 63 | Arguments: 64 | --------- 65 | X: matrix to be split 66 | n_folds: number of folds 67 | 68 | Returns: 69 | ------- 70 | splits: split matrices 71 | """ 72 | splits = [] 73 | chunk_size = X.shape[0] // n_splits 74 | for i in range(n_splits): 75 | start = i * chunk_size 76 | end = X.shape[0] if i == n_splits - 1 else (i + 1) * chunk_size 77 | splits.append(X[start:end]) 78 | return splits 79 | 80 | def compute_ndcg_k(pred_items, test_items, test_indices, k): 81 | """ 82 | Compute NDCG@k 83 | 84 | Arguments: 85 | --------- 86 | pred_items: binary tensor with 1s in those locations corresponding to the predicted item interactions 87 | test_items: binary tensor with 1s in locations corresponding to the real test interactions 88 | test_indices: tensor with the location of the top-k predicted items 89 | k: k'th-order 90 | 91 | Returns: 92 | ------- 93 | NDCG@k 94 | """ 95 | r = (test_items * pred_items).gather(1, test_indices) 96 | f = torch.from_numpy(np.log2(np.arange(2, k+2))).float().cuda() 97 | dcg = (r[:, :k]/f).sum(1) 98 | dcg_max = (torch.sort(r, dim=1, descending=True)[0][:, :k]/f).sum(1) 99 | ndcg = dcg/dcg_max 100 | ndcg[torch.isnan(ndcg)] = 0 101 | return ndcg 102 | 103 | 104 | def eval_model(u_emb, i_emb, Rtr, Rte, k): 105 | """ 106 | Evaluate the model 107 | 108 | Arguments: 109 | --------- 110 | u_emb: User embeddings 111 | i_emb: Item embeddings 112 | Rtr: Sparse matrix with the training interactions 113 | Rte: Sparse matrix with the testing interactions 114 | k : kth-order for metrics 115 | 116 | Returns: 117 | -------- 118 | result: Dictionary with lists correponding to the metrics at order k for k in Ks 119 | """ 120 | # split matrices 121 | ue_splits = split_matrix(u_emb) 122 | tr_splits = split_matrix(Rtr) 123 | te_splits = split_matrix(Rte) 124 | 125 | recall_k, ndcg_k= [], [] 126 | # compute results for split matrices 127 | for ue_f, tr_f, te_f in zip(ue_splits, tr_splits, te_splits): 128 | 129 | scores = torch.mm(ue_f, i_emb.t()) 130 | 131 | test_items = torch.from_numpy(te_f.todense()).float().cuda() 132 | non_train_items = torch.from_numpy(1-(tr_f.todense())).float().cuda() 133 | scores = scores * non_train_items 134 | 135 | _, test_indices = torch.topk(scores, dim=1, k=k) 136 | pred_items = torch.zeros_like(scores).float() 137 | pred_items.scatter_(dim=1,index=test_indices,src=torch.tensor(1.0).cuda()) 138 | 139 | topk_preds = torch.zeros_like(scores).float() 140 | topk_preds.scatter_(dim=1,index=test_indices[:, :k],src=torch.tensor(1.0)) 141 | 142 | TP = (test_items * topk_preds).sum(1) 143 | rec = TP/test_items.sum(1) 144 | ndcg = compute_ndcg_k(pred_items, test_items, test_indices, k) 145 | 146 | recall_k.append(rec) 147 | ndcg_k.append(ndcg) 148 | 149 | return torch.cat(recall_k).mean(), torch.cat(ndcg_k).mean() -------------------------------------------------------------------------------- /utils/load_data.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Pytorch Implementation of Neural Graph Collaborative Filtering (NGCF) (https://doi.org/10.1145/3331184.3331267) 3 | 4 | This file contains the Data class which reads the data and creates 5 | the adjacency matrix. The code is mostly taken from the original 6 | repo with minor adjustments 7 | 8 | authors: Mohammed Yusuf Noor, Muhammed Imran Özyar, Calin Vasile Simon 9 | ''' 10 | import numpy as np 11 | import random as rd 12 | import scipy.sparse as sp 13 | import torch 14 | from time import time 15 | 16 | class Data(object): 17 | def __init__(self, path, batch_size): 18 | self.path = path 19 | self.batch_size = batch_size 20 | 21 | train_file = path + '/train.txt' 22 | test_file = path + '/test.txt' 23 | 24 | #get number of users and items 25 | self.n_users, self.n_items = 0, 0 26 | self.n_train, self.n_test = 0, 0 27 | self.neg_pools = {} 28 | 29 | self.exist_users = [] 30 | 31 | # search train_file for max user_id/item_id 32 | with open(train_file) as f: 33 | for l in f.readlines(): 34 | if len(l) > 0: 35 | l = l.strip('\n').split(' ') 36 | items = [int(i) for i in l[1:]] 37 | # first element is the user_id, rest are items 38 | uid = int(l[0]) 39 | self.exist_users.append(uid) 40 | # item/user with highest number is number of items/users 41 | self.n_items = max(self.n_items, max(items)) 42 | self.n_users = max(self.n_users, uid) 43 | # number of interactions 44 | self.n_train += len(items) 45 | 46 | # search test_file for max item_id 47 | with open(test_file) as f: 48 | for l in f.readlines(): 49 | if len(l) > 0: 50 | l = l.strip('\n') 51 | try: 52 | items = [int(i) for i in l.split(' ')[1:]] 53 | except Exception: 54 | continue 55 | if not items: 56 | print("empyt test exists") 57 | pass 58 | else: 59 | self.n_items = max(self.n_items, max(items)) 60 | self.n_test += len(items) 61 | # adjust counters: user_id/item_id starts at 0 62 | self.n_items += 1 63 | self.n_users += 1 64 | 65 | self.print_statistics() 66 | 67 | # create interactions/ratings matrix 'R' # dok = dictionary of keys 68 | print('Creating interaction matrices R_train and R_test...') 69 | t1 = time() 70 | self.R_train = sp.dok_matrix((self.n_users, self.n_items), dtype=np.float32) 71 | self.R_test = sp.dok_matrix((self.n_users, self.n_items), dtype=np.float32) 72 | 73 | self.train_items, self.test_set = {}, {} 74 | with open(train_file) as f_train: 75 | with open(test_file) as f_test: 76 | for l in f_train.readlines(): 77 | if len(l) == 0: break 78 | l = l.strip('\n') 79 | items = [int(i) for i in l.split(' ')] 80 | uid, train_items = items[0], items[1:] 81 | # enter 1 if user interacted with item 82 | for i in train_items: 83 | self.R_train[uid, i] = 1. 84 | self.train_items[uid] = train_items 85 | 86 | for l in f_test.readlines(): 87 | if len(l) == 0: break 88 | l = l.strip('\n') 89 | try: 90 | items = [int(i) for i in l.split(' ')] 91 | except Exception: 92 | continue 93 | uid, test_items = items[0], items[1:] 94 | for i in test_items: 95 | self.R_test[uid, i] = 1.0 96 | self.test_set[uid] = test_items 97 | print('Complete. Interaction matrices R_train and R_test created in', time() - t1, 'sec') 98 | 99 | # if exist, get adjacency matrix 100 | def get_adj_mat(self): 101 | try: 102 | t1 = time() 103 | adj_mat = sp.load_npz(self.path + '/s_adj_mat.npz') 104 | print('Loaded adjacency-matrix (shape:', adj_mat.shape,') in', time() - t1, 'sec.') 105 | 106 | except Exception: 107 | print('Creating adjacency-matrix...') 108 | adj_mat = self.create_adj_mat() 109 | sp.save_npz(self.path + '/s_adj_mat.npz', adj_mat) 110 | return adj_mat 111 | 112 | # create adjancency matrix 113 | def create_adj_mat(self): 114 | t1 = time() 115 | 116 | adj_mat = sp.dok_matrix((self.n_users + self.n_items, self.n_users + self.n_items), dtype=np.float32) 117 | adj_mat = adj_mat.tolil() 118 | R = self.R_train.tolil() # to list of lists 119 | 120 | adj_mat[:self.n_users, self.n_users:] = R 121 | adj_mat[self.n_users:, :self.n_users] = R.T 122 | adj_mat = adj_mat.todok() 123 | print('Complete. Adjacency-matrix created in', adj_mat.shape, time() - t1, 'sec.') 124 | 125 | t2 = time() 126 | 127 | # normalize adjacency matrix 128 | def normalized_adj_single(adj): 129 | rowsum = np.array(adj.sum(1)) 130 | 131 | d_inv = np.power(rowsum, -.5).flatten() 132 | d_inv[np.isinf(d_inv)] = 0. 133 | d_mat_inv = sp.diags(d_inv) 134 | 135 | norm_adj = d_mat_inv.dot(adj).dot(d_mat_inv) 136 | return norm_adj.tocoo() 137 | 138 | print('Transforming adjacency-matrix to NGCF-adjacency matrix...') 139 | ngcf_adj_mat = normalized_adj_single(adj_mat) + sp.eye(adj_mat.shape[0]) 140 | 141 | print('Complete. Transformed adjacency-matrix to NGCF-adjacency matrix in', time() - t2, 'sec.') 142 | return ngcf_adj_mat.tocsr() 143 | 144 | # create collections of N items that users never interacted with 145 | def negative_pool(self): 146 | t1 = time() 147 | for u in self.train_items.keys(): 148 | neg_items = list(set(range(self.n_items)) - set(self.train_items[u])) 149 | pools = [rd.choice(neg_items) for _ in range(100)] 150 | self.neg_pools[u] = pools 151 | print('refresh negative pools', time() - t1) 152 | 153 | # sample data for mini-batches 154 | def sample(self): 155 | if self.batch_size <= self.n_users: 156 | users = rd.sample(self.exist_users, self.batch_size) 157 | else: 158 | users = [rd.choice(self.exist_users) for _ in range(self.batch_size)] 159 | 160 | def sample_pos_items_for_u(u, num): 161 | pos_items = self.train_items[u] 162 | n_pos_items = len(pos_items) 163 | pos_batch = [] 164 | while True: 165 | if len(pos_batch) == num: break 166 | pos_id = np.random.randint(low=0, high=n_pos_items, size=1)[0] 167 | pos_i_id = pos_items[pos_id] 168 | 169 | if pos_i_id not in pos_batch: 170 | pos_batch.append(pos_i_id) 171 | return pos_batch 172 | 173 | def sample_neg_items_for_u(u, num): 174 | neg_items = [] 175 | while True: 176 | if len(neg_items) == num: break 177 | neg_id = np.random.randint(low=0, high=self.n_items,size=1)[0] 178 | if neg_id not in self.train_items[u] and neg_id not in neg_items: 179 | neg_items.append(neg_id) 180 | return neg_items 181 | 182 | def sample_neg_items_for_u_from_pools(u, num): 183 | neg_items = list(set(self.neg_pools[u]) - set(self.train_items[u])) 184 | return rd.sample(neg_items, num) 185 | 186 | pos_items, neg_items = [], [] 187 | for u in users: 188 | pos_items += sample_pos_items_for_u(u, 1) 189 | neg_items += sample_neg_items_for_u(u, 1) 190 | 191 | return users, pos_items, neg_items 192 | 193 | def get_num_users_items(self): 194 | return self.n_users, self.n_items 195 | 196 | def print_statistics(self): 197 | print('n_users=%d, n_items=%d' % (self.n_users, self.n_items)) 198 | print('n_interactions=%d' % (self.n_train + self.n_test)) 199 | print('n_train=%d, n_test=%d, sparsity=%.5f' % (self.n_train, self.n_test, (self.n_train + self.n_test)/(self.n_users * self.n_items))) 200 | -------------------------------------------------------------------------------- /utils/parser.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Pytorch Implementation of Neural Graph Collaborative Filtering (NGCF) (https://doi.org/10.1145/3331184.3331267) 3 | 4 | This file contains the parser function 5 | 6 | authors: Mohammed Yusuf Noor, Muhammed Imran Özyar, Calin Vasile Simon 7 | ''' 8 | 9 | import argparse 10 | 11 | def parse_args(): 12 | parser = argparse.ArgumentParser(description="Run NGCF.") 13 | parser.add_argument('--data_dir', type=str, 14 | default='./data/', 15 | help='Input data path.') 16 | parser.add_argument('--dataset', type=str, default='Gowella', 17 | help='Dataset name: Amazond-book, Gowella, ml-100k') 18 | parser.add_argument('--results_dir', type=str, default='results', 19 | help='Store model to path.') 20 | parser.add_argument('--n_epochs', type=int, default=400, 21 | help='Number of epoch.') 22 | parser.add_argument('--reg', type=float, default=1e-5, 23 | help='l2 reg.') 24 | parser.add_argument('--lr', type=float, default=0.0001, 25 | help='Learning rate.') 26 | parser.add_argument('--emb_dim', type=int, default=64, 27 | help='number of embeddings.') 28 | parser.add_argument('--layers', type=str, default='[64,64]', 29 | help='Output sizes of every layer') 30 | parser.add_argument('--batch_size', type=int, default=1024, 31 | help='Batch size.') 32 | parser.add_argument('--node_dropout', type=float, default=0., 33 | help='Graph Node dropout.') 34 | parser.add_argument('--mess_dropout', type=float, default=0.1, 35 | help='Message dropout.') 36 | parser.add_argument('--k', type=str, default=20, 37 | help='k order of metric evaluation (e.g. NDCG@k)') 38 | parser.add_argument('--eval_N', type=int, default=1, 39 | help='Evaluate every N epochs') 40 | parser.add_argument('--save_results', type=int, default=1, 41 | help='Save model and results') 42 | 43 | return parser.parse_args() 44 | --------------------------------------------------------------------------------