forked from xyzzy/qrpicture
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqrwork.cc
1155 lines (997 loc) · 103 KB
/
qrwork.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* This file is part of qrpicture, photo realistic QR-codes.
* Copyright (C) 2007, [email protected]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <getopt.h>
#include <ctype.h>
#include <sys/times.h>
#include <gd.h>
char *opt_text;
char *opt_infile;
char *opt_outfile;
double opt_gsmin = 0.25;
double opt_gsmax = 0.75;
double opt_contrast = 0.08; // thresshold is 238/256
double opt_outline = 0;
int opt_seed = 0;
int opt_verbose = 0;
int opt_maxsalt = 1;
#define MAXSALT 1
#define QRVERSION 19 // QR dataset
#define EC 0 // error correction level
#define QRSIZE 93 // size of QR
#define NUMMASK 8 // number of mask planes
#define NUMBLOCK 7 // number of RS blocks
#define MAXBLKSIZE 142 // maximum # codewords in block
#define NUMECCWORDS 28 // # ECC codewords in block
#define MAXDATABITS 6360 // total # non-ECC data bits
#define MAXCODEWORDS 991
int rsBlockOrder[] = { 141,141,141,142,142,142,142 };
int formatInformationX1[] = {0,1,2,3,4,5,7,8,8,8,8,8,8,8,8};
int formatInformationY1[] = {8,8,8,8,8,8,8,8,7,5,4,3,2,1,0};
int formatInformationX2[] = {8,8,8,8,8,8,8,85,86,87,88,89,90,91,92};
int formatInformationY2[] = {92,91,90,89,88,87,86,8,8,8,8,8,8,8,8};
int formatInformationArray[] = {
/*L*/ 4599, 26535, 10975, 23695, 31283, 3171, 16667, 14155,
/*M*/ 9237, 21061, 7997, 26989, 20433, 14721, 29945, 681,
/*Q*/ 32086, 2822, 18046, 12334, 5778, 24770, 11706, 23530,
/*H*/ 18612, 16100, 29596, 1484, 9072, 21792, 6232, 28168 };
int matrixRemainBit[] = { 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0 };
int matrixX[] = {92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,84,83,84,83,83,83,83,83,83,83,83,83,84,83,84,83,83,84,83,84,83,84,83,84,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,55,56,55,56,55,56,55,55,56,55,55,55,55,55,55,56,55,55,56,55,56,55,56,55,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,27,28,27,28,27,28,27,28,28,27,28,27,28,27,28,27,27,27,27,27,27,28,27,28,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,20,19,20,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,83,84,83,84,83,84,83,84,84,83,84,83,84,83,84,83,83,84,83,84,83,84,83,84,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,55,55,55,55,56,55,56,55,55,56,55,56,55,56,55,56,56,55,56,55,56,55,56,55,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,27,28,27,28,27,28,27,28,28,27,28,27,28,27,27,27,27,28,27,28,27,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,19,20,19,20,19,20,19,20,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,83,84,83,84,83,84,83,84,84,83,84,83,84,83,84,83,83,84,83,84,83,84,83,84,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,56,55,56,55,56,55,56,55,55,56,55,56,55,56,55,56,56,55,56,55,56,55,56,55,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,28,27,28,27,28,27,28,27,27,28,27,27,27,27,27,27,27,27,27,28,27,28,27,28,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,19,20,19,20,19,20,19,20,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,83,84,83,84,83,84,83,84,84,83,84,83,84,83,84,83,83,84,83,84,83,84,83,84,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,56,55,56,55,56,55,56,55,55,56,55,56,55,56,55,56,56,55,56,55,56,55,56,55,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,27,27,27,27,27,28,27,28,28,27,28,27,28,27,28,27,27,28,27,28,27,28,27,28,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,83,84,83,84,83,84,83,84,84,83,84,83,84,83,84,83,83,84,83,84,83,84,83,84,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,56,55,56,55,56,55,56,55,55,56,55,56,55,56,55,56,56,55,56,55,56,55,56,55,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,27,28,27,28,27,28,27,28,28,27,28,27,28,27,28,27,27,28,27,28,27,28,27,28,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,83,84,83,84,83,84,83,84,84,83,84,83,84,83,84,83,83,81,81,81,81,81,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,56,55,56,55,56,55,56,55,55,56,55,56,55,56,55,56,55,55,55,55,56,55,56,55,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,27,28,27,28,27,28,27,28,28,27,28,27,28,27,28,27,27,28,27,28,27,28,27,28,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,92,91,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,90,89,88,87,88,87,88,87,88,87,88,87,88,87,88,87,88,87,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,86,85,84,83,84,83,83,84,83,84,83,84,83,83,84,83,83,83,83,83,83,84,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,82,81,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,79,80,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,77,78,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,75,76,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,73,74,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,71,72,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,69,70,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,68,67,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,65,66,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,61,62,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,59,60,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,58,57,56,56,55,56,55,56,55,56,55,55,56,55,56,55,55,55,55,56,55,56,55,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,52,51,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,50,49,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,48,47,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,46,45,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,44,43,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,42,41,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,40,39,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,38,37,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,36,35,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,34,33,32,31,32,31,32,31,32,31,32,31,32,31,32,31,32,31,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,30,29,27,28,27,28,27,28,27,28,28,27,28,27,28,27,28,27,27,28,27,28,27,28,27,28,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,25,26,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,23,24,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,21,22,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,19,20,19,20,19,20,19,20,19,20,19,20,19,20,19,20,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,19,20,19,20,19,20,19,20,19,20,19,20,19,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,19,20,19,20,19,20,19,20,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,15,16,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,13,14,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,12,11,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0};
int matrixY[] = {92,92,91,91,90,90,89,89,64,64,63,63,62,62,61,61,36,36,35,35,34,34,33,33,9,9,10,10,11,11,12,12,37,37,38,38,39,39,40,40,65,65,66,66,67,67,68,68,92,92,91,91,90,90,89,89,54,54,53,53,52,52,51,51,21,21,20,20,19,19,18,18,24,24,25,25,26,26,27,27,62,62,63,63,64,64,65,65,90,90,89,89,88,87,86,85,59,58,57,56,55,55,54,54,27,26,26,25,25,24,24,23,11,12,12,13,13,14,14,15,39,40,40,41,41,42,42,43,67,68,68,69,69,70,70,71,90,89,89,88,88,87,87,86,62,61,61,60,60,59,59,58,34,33,33,32,32,31,31,30,5,4,4,3,3,2,2,1,23,24,24,25,25,26,26,27,51,52,52,53,53,54,54,55,79,80,80,81,81,82,82,83,78,77,77,76,76,75,75,74,50,49,49,48,48,47,47,46,22,21,21,20,20,19,19,18,7,8,8,9,9,10,10,11,35,36,36,37,37,38,38,39,63,64,64,65,65,66,66,67,91,92,92,92,92,91,91,90,66,65,65,64,64,63,63,62,38,37,37,36,36,35,35,34,10,9,9,8,8,7,7,5,19,20,20,21,21,22,22,23,47,48,48,49,49,50,50,51,75,76,76,77,77,78,78,79,82,81,81,80,80,79,79,78,54,53,53,52,52,51,51,50,26,25,25,24,24,23,23,22,2,3,3,4,4,5,5,7,31,32,32,33,33,34,34,35,59,60,60,61,61,62,62,63,87,88,88,89,89,90,90,91,70,69,69,68,68,67,67,66,42,41,41,40,40,39,39,38,14,13,13,12,12,11,11,10,15,16,16,17,17,18,18,19,43,44,44,45,45,46,46,47,71,72,72,73,73,74,74,75,81,80,80,79,79,78,78,77,48,47,47,46,46,45,45,44,15,14,14,13,13,12,12,11,22,23,23,24,24,25,25,26,55,61,61,62,62,63,63,64,92,91,91,90,90,89,89,88,61,61,60,59,58,57,56,55,29,28,27,27,26,26,25,25,2,2,3,3,4,4,5,5,31,31,32,32,33,33,34,34,59,59,60,60,61,61,62,62,87,87,88,88,89,89,90,90,70,70,69,69,68,68,67,67,42,42,41,41,40,40,39,39,14,14,13,13,12,12,11,11,15,15,16,16,17,17,18,18,43,43,44,44,45,45,46,46,71,71,72,72,73,73,74,74,86,86,85,85,84,84,83,83,58,58,57,57,56,56,55,55,30,30,29,29,28,28,27,27,1,1,0,0,0,0,1,1,27,27,28,28,29,29,30,30,55,55,56,56,57,57,58,58,83,83,84,84,85,85,86,86,74,74,73,73,72,72,71,71,46,46,45,45,44,44,43,43,18,18,17,17,16,16,15,15,11,11,12,12,13,13,14,14,39,39,40,40,41,41,42,42,67,67,68,68,69,69,70,70,90,90,89,89,88,88,87,87,62,62,61,61,60,60,59,59,34,34,33,33,32,32,31,31,5,5,4,4,3,3,2,2,23,23,24,24,25,25,26,26,51,51,52,52,53,53,54,54,79,79,80,80,81,81,82,82,78,78,77,77,76,76,75,75,50,50,49,49,48,48,47,47,22,22,21,21,20,20,19,19,7,7,8,8,9,9,10,10,35,35,36,36,37,37,38,38,63,63,64,64,65,65,66,66,91,91,92,92,92,92,91,91,61,61,55,55,54,54,53,53,23,23,22,22,21,21,20,20,14,14,15,15,16,16,17,17,47,47,48,48,49,49,50,50,80,80,81,81,82,82,83,83,70,69,69,68,68,67,67,66,39,39,38,38,37,37,36,36,9,8,7,5,4,3,3,2,22,23,23,24,24,25,25,26,50,51,51,52,52,53,53,54,78,79,79,80,80,81,81,82,79,78,78,77,77,76,76,75,51,50,50,49,49,48,48,47,23,22,22,21,21,20,20,19,5,7,7,8,8,9,9,10,34,35,35,36,36,37,37,38,62,63,63,64,64,65,65,66,90,91,91,92,92,92,92,91,88,88,87,87,86,86,85,85,60,60,59,59,58,58,57,57,32,32,31,31,30,30,29,29,13,13,14,14,15,15,16,16,41,41,42,42,43,43,44,44,69,69,70,70,71,71,72,72,83,83,82,82,81,81,80,80,50,50,49,49,48,48,47,47,17,17,16,16,15,15,14,14,33,33,34,34,35,35,36,36,66,66,67,67,68,68,69,69,84,83,83,82,82,81,81,80,53,53,52,52,51,51,50,50,23,22,22,21,21,20,20,19,15,16,16,17,17,18,18,19,43,44,44,45,45,46,46,47,71,72,72,73,73,74,74,75,86,85,85,84,84,83,83,82,58,57,57,56,56,55,55,54,30,29,29,28,28,27,27,26,1,0,0,0,0,1,1,2,27,28,28,29,29,30,30,31,55,56,56,57,57,58,58,59,83,84,84,85,85,86,86,87,74,73,73,72,72,71,71,70,46,45,45,44,44,43,43,42,18,17,17,16,16,15,15,14,11,12,12,13,13,14,14,15,39,40,40,41,41,42,42,43,67,68,68,69,69,70,70,71,90,89,89,88,88,87,87,86,62,61,61,60,60,59,59,58,34,33,33,32,32,31,31,30,5,4,4,3,3,2,2,1,23,24,24,25,25,26,26,27,51,52,52,53,53,54,54,55,79,80,80,81,81,82,82,83,78,77,77,76,76,75,75,74,50,49,49,48,48,47,47,46,22,21,21,20,20,19,19,18,7,8,8,9,9,10,10,11,35,36,36,37,37,38,38,39,63,64,64,65,65,66,66,67,91,92,92,92,92,91,91,90,66,65,65,64,64,63,63,62,38,37,37,36,36,35,35,34,10,9,9,8,8,7,7,5,19,20,20,21,21,22,22,23,47,48,48,49,49,50,50,51,75,76,76,77,77,78,78,79,77,76,76,75,75,74,74,73,44,43,43,42,42,41,41,40,11,10,10,9,9,3,3,2,26,27,27,33,33,34,34,35,64,65,65,66,66,67,67,68,87,86,85,84,83,83,82,82,55,54,54,53,53,52,52,51,24,24,23,23,22,22,21,21,7,7,8,8,9,9,10,10,35,35,36,36,37,37,38,38,63,63,64,64,65,65,66,66,91,91,92,92,92,92,91,91,66,66,65,65,64,64,63,63,38,38,37,37,36,36,35,35,10,10,9,9,8,8,7,7,19,19,20,20,21,21,22,22,47,47,48,48,49,49,50,50,75,75,76,76,77,77,78,78,82,82,81,81,80,80,79,79,54,54,53,53,52,52,51,51,26,26,25,25,24,24,23,23,2,2,3,3,4,4,5,5,31,31,32,32,33,33,34,34,59,59,60,60,61,61,62,62,87,87,88,88,89,89,90,90,70,70,69,69,68,68,67,67,42,42,41,41,40,40,39,39,14,14,13,13,12,12,11,11,15,15,16,16,17,17,18,18,43,43,44,44,45,45,46,46,71,71,72,72,73,73,74,74,86,86,85,85,84,84,83,83,58,58,57,57,56,56,55,55,30,30,29,29,28,28,27,27,1,1,0,0,0,0,1,1,27,27,28,28,29,29,30,30,55,55,56,56,57,57,58,58,83,83,84,84,85,85,86,86,74,74,73,73,72,72,71,71,46,46,45,45,44,44,43,43,18,18,17,17,16,16,15,15,11,11,12,12,13,13,14,14,39,39,40,40,41,41,42,42,67,67,68,68,69,69,70,70,90,90,89,89,83,83,82,82,52,52,51,51,50,50,49,49,19,19,18,18,17,17,16,16,18,18,19,19,20,20,21,21,51,51,52,52,53,53,54,54,89,89,90,90,91,91,92,92,66,65,65,64,64,63,63,62,35,35,34,34,33,33,32,31,2,1,1,0,0,0,0,1,26,27,27,28,28,29,29,30,54,55,55,56,56,57,57,58,82,83,83,84,84,85,85,86,75,74,74,73,73,72,72,71,47,46,46,45,45,44,44,43,19,18,18,17,17,16,16,15,10,11,11,12,12,13,13,14,38,39,39,40,40,41,41,42,66,67,67,68,68,69,69,70,91,90,90,89,89,88,88,87,84,84,83,83,82,82,81,81,56,56,55,55,54,54,53,53,28,28,27,27,26,26,25,25,17,17,18,18,19,19,20,20,45,45,46,46,47,47,48,48,73,73,74,74,75,75,76,76,79,79,78,78,77,77,76,76,46,46,45,45,44,44,43,43,13,13,12,12,11,11,10,10,37,37,38,38,39,39,40,40,70,70,71,71,72,72,73,73,80,79,79,78,78,77,77,76,49,49,48,48,47,47,46,46,19,18,18,17,17,16,16,15,19,20,20,21,21,22,22,23,47,48,48,49,49,50,50,51,75,76,76,77,77,78,78,79,82,81,81,80,80,79,79,78,54,53,53,52,52,51,51,50,26,25,25,24,24,23,23,22,2,3,3,4,4,5,5,7,31,32,32,33,33,34,34,35,59,60,60,61,61,62,62,63,87,88,88,89,89,90,90,91,70,69,69,68,68,67,67,66,42,41,41,40,40,39,39,38,14,13,13,12,12,11,11,10,15,16,16,17,17,18,18,19,43,44,44,45,45,46,46,47,71,72,72,73,73,74,74,75,86,85,85,84,84,83,83,82,58,57,57,56,56,55,55,54,30,29,29,28,28,27,27,26,1,0,0,0,0,1,1,2,27,28,28,29,29,30,30,31,55,56,56,57,57,58,58,59,83,84,84,85,85,86,86,87,74,73,73,72,72,71,71,70,46,45,45,44,44,43,43,42,18,17,17,16,16,15,15,14,11,12,12,13,13,14,14,15,39,40,40,41,41,42,42,43,67,68,68,69,69,70,70,71,90,89,89,88,88,87,87,86,62,61,61,60,60,59,59,58,34,33,33,32,32,31,31,30,5,4,4,3,3,2,2,1,23,24,24,25,25,26,26,27,51,52,52,53,53,54,54,55,79,80,80,81,81,82,82,83,73,72,72,71,71,70,70,69,40,39,39,38,38,37,37,36,2,1,1,0,0,0,0,1,35,36,36,37,37,38,38,39,68,69,69,70,70,71,71,72,81,81,80,80,79,79,78,78,51,50,50,49,49,48,48,47,20,20,19,19,18,18,17,17,11,11,12,12,13,13,14,14,39,39,40,40,41,41,42,42,67,67,68,68,69,69,70,70,90,90,89,89,88,88,87,87,62,62,61,61,60,60,59,59,34,34,33,33,32,32,31,31,5,5,4,4,3,3,2,2,23,23,24,24,25,25,26,26,51,51,52,52,53,53,54,54,79,79,80,80,81,81,82,82,78,78,77,77,76,76,75,75,50,50,49,49,48,48,47,47,22,22,21,21,20,20,19,19,7,7,8,8,9,9,10,10,35,35,36,36,37,37,38,38,63,63,64,64,65,65,66,66,91,91,92,92,92,92,91,91,66,66,65,65,64,64,63,63,38,38,37,37,36,36,35,35,10,10,9,9,8,8,7,7,19,19,20,20,21,21,22,22,47,47,48,48,49,49,50,50,75,75,76,76,77,77,78,78,82,82,81,81,80,80,79,79,54,54,53,53,52,52,51,51,26,26,25,25,24,24,23,23,2,2,3,3,4,4,5,5,31,31,32,32,33,33,34,34,59,59,60,60,61,61,62,62,87,87,88,88,89,89,90,90,70,70,69,69,68,68,67,67,42,42,41,41,40,40,39,39,14,14,13,13,12,12,11,11,15,15,16,16,17,17,18,18,43,43,44,44,45,45,46,46,71,71,72,72,73,73,74,74,81,81,80,80,79,79,78,78,48,48,47,47,46,46,45,45,15,15,14,14,13,13,12,12,22,22,23,23,24,24,25,25,55,55,61,61,62,62,63,63,92,92,91,91,90,90,89,89,62,61,61,60,59,58,57,56,30,29,28,27,27,26,26,25,1,2,2,3,3,4,4,5,30,31,31,32,32,33,33,34,58,59,59,60,60,61,61,62,86,87,87,88,88,89,89,90,71,70,70,69,69,68,68,67,43,42,42,41,41,40,40,39,15,14,14,13,13,12,12,11,14,15,15,16,16,17,17,18,42,43,43,44,44,45,45,46,70,71,71,72,72,73,73,74,87,86,86,85,85,84,84,83,80,80,79,79,78,78,77,77,52,52,51,51,50,50,49,49,24,24,23,23,22,22,21,21,21,21,22,22,23,23,24,24,49,49,50,50,51,51,52,52,77,77,78,78,79,79,80,80,75,75,74,74,73,73,72,72,42,42,41,41,40,40,39,39,9,9,9,9,10,10,11,11,41,41,42,42,43,43,44,44,74,74,75,75,76,76,77,77,76,75,75,74,74,73,73,72,45,45,44,44,43,43,42,42,15,14,14,13,13,12,12,11,23,24,24,25,25,26,26,27,51,52,52,53,53,54,54,55,79,80,80,81,81,82,82,83,78,77,77,76,76,75,75,74,50,49,49,48,48,47,47,46,22,21,21,20,20,19,19,18,7,8,8,9,9,10,10,11,35,36,36,37,37,38,38,39,63,64,64,65,65,66,66,67,91,92,92,92,92,91,91,90,66,65,65,64,64,63,63,62,38,37,37,36,36,35,35,34,10,9,9,8,8,7,7,5,19,20,20,21,21,22,22,23,47,48,48,49,49,50,50,51,75,76,76,77,77,78,78,79,82,81,81,80,80,79,79,78,54,53,53,52,52,51,51,50,26,25,25,24,24,23,23,22,2,3,3,4,4,5,5,7,31,32,32,33,33,34,34,35,59,60,60,61,61,62,62,63,87,88,88,89,89,90,90,91,70,69,69,68,68,67,67,66,42,41,41,40,40,39,39,38,14,13,13,12,12,11,11,10,15,16,16,17,17,18,18,19,43,44,44,45,45,46,46,47,71,72,72,73,73,74,74,75,86,85,85,84,84,83,83,82,58,57,57,56,56,55,55,54,30,29,29,28,28,27,27,26,1,0,0,0,0,1,1,2,27,28,28,29,29,30,30,31,55,56,56,57,57,58,58,59,83,84,84,85,85,86,86,87,69,68,68,67,67,66,66,65,36,35,35,34,34,33,33,27,1,2,2,3,3,9,9,10,39,40,40,41,41,42,42,43,72,73,73,74,74,75,75,76,77,77,76,76,75,75,74,74,47,46,46,45,45,44,44,43,16,16,15,15,14,14,13,13,15,15,16,16,17,17,18,18,43,43,44,44,45,45,46,46,71,71,72,72,73,73,74,74,86,86,85,85,84,84,83,83,58,58,57,57,56,56,55,55,30,30,29,29,28,28,27,27,1,1,0,0,0,0,1,1,27,27,28,28,29,29,30,30,55,55,56,56,57,57,58,58,83,83,84,84,85,85,86,86,74,74,73,73,72,72,71,71,46,46,45,45,44,44,43,43,18,18,17,17,16,16,15,15,11,11,12,12,13,13,14,14,39,39,40,40,41,41,42,42,67,67,68,68,69,69,70,70,90,90,89,89,88,88,87,87,62,62,61,61,60,60,59,59,34,34,33,33,32,32,31,31,5,5,4,4,3,3,2,2,23,23,24,24,25,25,26,26,51,51,52,52,53,53,54,54,79,79,80,80,81,81,82,82,78,78,77,77,76,76,75,75,50,50,49,49,48,48,47,47,22,22,21,21,20,20,19,19,7,7,8,8,9,9,10,10,35,35,36,36,37,37,38,38,63,63,64,64,65,65,66,66,91,91,92,92,92,92,91,91,66,66,65,65,64,64,63,63,38,38,37,37,36,36,35,35,10,10,9,9,8,8,7,7,19,19,20,20,21,21,22,22,47,47,48,48,49,49,50,50,75,75,76,76,77,77,78,78,77,77,76,76,75,75,74,74,44,44,43,43,42,42,41,41,11,11,10,10,9,9,3,3,26,26,27,27,33,33,34,34,64,64,65,65,66,66,67,67,88,87,86,85,84,83,83,82,55,55,54,54,53,53,52,52,25,24,24,23,23,22,22,21,5,7,7,8,8,9,9,10,34,35,35,36,36,37,37,38,62,63,63,64,64,65,65,66,90,91,91,92,92,92,92,91,67,66,66,65,65,64,64,63,39,38,38,37,37,36,36,35,11,10,10,9,9,8,8,7,18,19,19,20,20,21,21,22,46,47,47,48,48,49,49,50,74,75,75,76,76,77,77,78,83,82,82,81,81,80,80,79,67,66,66,65,65,64,64,63,76,76,75,75,74,74,73,73,48,48,47,47,46,46,45,45,20,20,19,19,18,18,17,17,25,25,26,26,27,27,28,28,53,53,54,54,55,55,56,56,81,81,82,82,83,83,84,84,71,71,70,70,69,69,68,68,38,38,37,37,36,36,35,35,12,12,13,13,14,14,15,15,45,45,46,46,47,47,48,48,78,78,79,79,80,80,81,81,72,71,71,70,70,69,69,68,41,41,40,40,39,39,38,38,11,10,10,9,9,8,8,7,27,28,28,29,29,30,30,31,55,56,56,57,57,58,58,59,83,84,84,85,85,86,86,87,74,73,73,72,72,71,71,70,46,45,45,44,44,43,43,42,18,17,17,16,16,15,15,14,11,12,12,13,13,14,14,15,39,40,40,41,41,42,42,43,67,68,68,69,69,70,70,71,90,89,89,88,88,87,87,86,62,61,61,60,60,59,59,58,34,33,33,32,32,31,31,30,5,4,4,3,3,2,2,1,23,24,24,25,25,26,26,27,51,52,52,53,53,54,54,55,79,80,80,81,81,82,82,83,78,77,77,76,76,75,75,74,50,49,49,48,48,47,47,46,22,21,21,20,20,19,19,18,7,8,8,9,9,10,10,11,35,36,36,37,37,38,38,39,63,64,64,65,65,66,66,67,91,92,92,92,92,91,91,90,66,65,65,64,64,63,63,62,38,37,37,36,36,35,35,34,10,9,9,8,8,7,7,5,19,20,20,21,21,22,22,23,47,48,48,49,49,50,50,51,75,76,76,77,77,78,78,79,82,81,81,80,80,79,79,78,54,53,53,52,52,51,51,50,26,25,25,24,24,23,23,22,2,3,3,4,4,5,5,7,31,32,32,33,33,34,34,35,59,60,60,61,61,62,62,63,87,88,88,89,89,90,90,91,65,64,64,63,63,62,62,61,27,26,26,25,25,24,24,23,10,11,11,12,12,13,13,14,43,44,44,45,45,46,46,47,76,77,77,78,78,79,79,80,73,73,72,72,71,71,70,70,43,42,42,41,41,40,40,39,12,12,11,11,10,10,9,9,19,19,20,20,21,21,22,22,47,47,48,48,49,49,50,50,75,75,76,76,77,77,78,78,82,82,81,81,80,80,79,79,54,54,53,53,52,52,51,51,26,26,25,25,24,24,23,23,2,2,3,3,4,4,5,5,31,31,32,32,33,33,34,34,59,59,60,60,61,61,62,62,87,87,88,88,89,89,90,90,70,70,69,69,68,68,67,67,42,42,41,41,40,40,39,39,14,14,13,13,12,12,11,11,15,15,16,16,17,17,18,18,43,43,44,44,45,45,46,46,71,71,72,72,73,73,74,74,86,86,85,85,84,84,83,83,58,58,57,57,56,56,55,55,30,30,29,29,28,28,27,27,1,1,0,0,0,0,1,1,27,27,28,28,29,29,30,30,55,55,56,56,57,57,58,58,83,83,84,84,85,85,86,86,74,74,73,73,72,72,71,71,46,46,45,45,44,44,43,43,18,18,17,17,16,16,15,15,11,11,12,12,13,13,14,14,39,39,40,40,41,41,42,42,67,67,68,68,69,69,70,70,90,90,89,89,88,88,87,87,62,62,61,61,60,60,59,59,34,34,33,33,32,32,31,31,5,5,4,4,3,3,2,2,23,23,24,24,25,25,26,26,51,51,52,52,53,53,54,54,79,79,80,80,81,81,82,82,73,73,72,72,71,71,70,70,40,40,39,39,38,38,37,37,2,2,1,1,0,0,0,0,35,35,36,36,37,37,38,38,68,68,69,69,70,70,71,71,82,81,81,80,80,79,79,78,51,51,50,50,49,49,48,48,21,20,20,19,19,18,18,17,10,11,11,12,12,13,13,14,38,39,39,40,40,41,41,42,66,67,67,68,68,69,69,70,91,90,90,89,89,88,88,87,63,62,62,61,61,60,60,59,35,34,34,33,33,32,32,31,7,5,5,4,4,3,3,2,22,23,23,24,24,25,25,26,50,51,51,52,52,53,53,54,78,79,79,80,80,81,81,82,79,78,78,77,77,76,76,75,63,62,62,61,61,60,60,59,72,72,71,71,70,70,69,69,44,44,43,43,42,42,41,41,16,16,15,15,14,14,13,13,29,29,30,30,31,31,32,32,57,57,58,58,59,59,60,60,85,85,86,86,87,87,88,88,67,67,66,66,65,65,64,64,34,34,33,33,27,27,26,26,16,16,17,17,18,18,19,19,49,49,50,50,51,51,52,52,82,82,83,83,89,89,90,90,68,67,67,66,66,65,65,64,37,37,36,36,35,35,34,34,7,0,1,2,3,4,5,7,31,32,32,33,33,34,34,35,59,60,60,61,61,62,62,63,87,88,88,89,89,90,90,91,70,69,69,68,68,67,67,66,42,41,41,40,40,39,39,38,14,13,13,12,12,11,11,10,15,16,16,17,17,18,18,19,43,44,44,45,45,46,46,47,71,72,72,73,73,74,74,75,86,85,85,84,84,83,83,82,58,57,57,56,56,55,55,54,30,29,29,28,28,27,27,26,1,0,0,0,0,1,1,2,27,28,28,29,29,30,30,31,55,56,56,57,57,58,58,59,83,84,84,85,85,86,86,87,74,73,73,72,72,71,71,70,46,45,45,44,44,43,43,42,18,17,17,16,16,15,15,14,11,12,12,13,13,14,14,15,39,40,40,41,41,42,42,43,67,68,68,69,69,70,70,71,90,89,89,88,88,87,87,86,62,61,61,60,60,59,59,58,34,33,33,32,32,31,31,30,5,4,4,3,3,2,2,1,23,24,24,25,25,26,26,27,51,52,52,53,53,54,54,55,79,80,80,81,81,82,82,83,78,77,77,76,76,75,75,74,50,49,49,48,48,47,47,46,22,21,21,20,20,19,19,18,7,8,8,9,9,10,10,11,35,36,36,37,37,38,38,39,63,64,64,65,65,66,66,67,91,92,92,92,92,91,91,90,61,55,55,54,54,53,53,52,23,22,22,21,21,20,20,19,14,15,15,16,16,17,17,18,47,48,48,49,49,50,50,51,80,81,81,82,82,83,83,89,69,69,68,68,67,67,66,66,39,38,38,37,37,36,36,35,8,7,5,4,3,3,2,2,23,23,24,24,25,25,26,26,51,51,52,52,53,53,54,54,79,79,80,80,81,81,82,82,78,78,77,77,76,76,75,75,50,50,49,49,48,48,47,47,22,22,21,21,20,20,19,19,7,7,8,8,9,9,10,10,35,35,36,36,37,37,38,38,63,63,64,64,65,65,66,66,91,91,92,92,92,92,91,91,66,66,65,65,64,64,63,63,38,38,37,37,36,36,35,35,10,10,9,9,8,8,7,7,19,19,20,20,21,21,22,22,47,47,48,48,49,49,50,50,75,75,76,76,77,77,78,78,82,82,81,81,80,80,79,79,54,54,53,53,52,52,51,51,26,26,25,25,24,24,23,23,2,2,3,3,4,4,5,5,31,31,32,32,33,33,34,34,59,59,60,60,61,61,62,62,87,87,88,88,89,89,90,90,70,70,69,69,68,68,67,67,42,42,41,41,40,40,39,39,14,14,13,13,12,12,11,11,15,15,16,16,17,17,18,18,43,43,44,44,45,45,46,46,71,71,72,72,73,73,74,74,86,86,85,85,84,84,83,83,58,58,57,57,56,56,55,55,30,30,29,29,28,28,27,27,1,1,0,0,0,0,1,1,27,27,28,28,29,29,30,30,55,55,56,56,57,57,58,58,83,83,84,84,85,85,86,86,69,69,68,68,67,67,66,66,36,36,35,35,34,34,33,33,1,1,2,2,3,3,9,9,39,39,40,40,41,41,42,42,72,72,73,73,74,74,75,75,78,77,77,76,76,75,75,74,47,47,46,46,45,45,44,44,17,16,16,15,15,14,14,13,14,15,15,16,16,17,17,18,42,43,43,44,44,45,45,46,70,71,71,72,72,73,73,74,87,86,86,85,85,84,84,83,59,58,58,57,57,56,56,55,31,30,30,29,29,28,28,27,2,1,1,0,0,0,0,1,26,27,27,28,28,29,29,30,54,55,55,56,56,57,57,58,82,83,83,84,84,85,85,86,75,74,74,73,73,72,72,71,59,58,58,57,57,56,56,55,68,68,67,67,66,66,65,65,40,40,39,39,38,38,37,37,12,12,11,11,10,10,9,9,33,33,34,34,35,35,36,36,61,61,62,62,63,63,64,64,89,89,90,90,91,91,92,92,63,63,62,62,61,61,55,55,25,25,24,24,23,23,22,22,20,20,21,21,22,22,23,23,53,53,54,54,55,55,61,61,91,91,92,92,92,92,91,91,64,63,63,62,62,61,61,60,33,33,32,31,30,29,28,27,7,8,8,9,9,10,10,11,35,36,36,37,37,38,38,39,63,64,64,65,65,66,66,67,91,92,92,92,92,91,91,90,66,65,65,64,64,63,63,62,38,37,37,36,36,35,35,34,10,9,9,8,8,7,7,5,19,20,20,21,21,22,22,23,47,48,48,49,49,50,50,51,75,76,76,77,77,78,78,79,82,81,81,80,80,79,79,78,54,53,53,52,52,51,51,50,26,25,25,24,24,23,23,22,2,3,3,4,4,5,5,7,31,32,32,33,33,34,34,35,59,60,60,61,61,62,62,63,87,88,88,89,89,90,90,91,70,69,69,68,68,67,67,66,42,41,41,40,40,39,39,38,14,13,13,12,12,11,11,10,15,16,16,17,17,18,18,19,43,44,44,45,45,46,46,47,71,72,72,73,73,74,74,75,86,85,85,84,84,83,83,82,58,57,57,56,56,55,55,54,30,29,29,28,28,27,27,26,1,0,0,0,0,1,1,2,27,28,28,29,29,30,30,31,55,56,56,57,57,58,58,59,83,84,84,85,85,86,86,87,74,73,73,72,72,71,71,70,46,45,45,44,44,43,43,42,18,17,17,16,16,15,15,14,11,12,12,13,13,14,14,15,39,40,40,41,41,42,42,43,67,68,68,69,69,70,70,71,90,89,89,83,83,82,82,81,52,51,51,50,50,49,49,48,19,18,18,17,17,16,16,15,18,19,19,20,20,21,21,22,51,52,52,53,53,54,54,55,89,90,90,91,91,92,92,92,65,65,64,64,63,63,62,62,35,34,34,33,33,32,31,30,1,1,0,0,0,0,1,1,27,27,28,28,29,29,30,30,55,55,56,56,57,57,58,58,83,83,84,84,85,85,86,86,74,74,73,73,72,72,71,71,46,46,45,45,44,44,43,43,18,18,17,17,16,16,15,15,11,11,12,12,13,13,14,14,39,39,40,40,41,41,42,42,67,67,68,68,69,69,70,70,90,90,89,89,88,88,87,87,62,62,61,61,60,60,59,59,34,34,33,33,32,32,31,31,5,5,4,4,3,3,2,2,23,23,24,24,25,25,26,26,51,51,52,52,53,53,54,54,79,79,80,80,81,81,82,82,78,78,77,77,76,76,75,75,50,50,49,49,48,48,47,47,22,22,21,21,20,20,19,19,7,7,8,8,9,9,10,10,35,35,36,36,37,37,38,38,63,63,64,64,65,65,66,66,91,91,92,92,92,92,91,91,66,66,65,65,64,64,63,63,38,38,37,37,36,36,35,35,10,10,9,9,8,8,7,7,19,19,20,20,21,21,22,22,47,47,48,48,49,49,50,50,75,75,76,76,77,77,78,78,82,82,81,81,80,80,79,79,54,54,53,53,52,52,51,51,26,26,25,25,24,24,23,23,2,2,3,3,4,4,5,5,31,31,32,32,33,33,34,34,59,59,60,60,61,61,62,62,87,87,88,88,89,89,90,90,65,65,64,64,63,63,62,62,27,27,26,26,25,25,24,24,10,10,11,11,12,12,13,13,43,43,44,44,45,45,46,46,76,76,77,77,78,78,79,79,74,73,73,72,72,71,71,70,43,43,42,42,41,41,40,40,13,12,12,11,11,10,10,9,18,19,19,20,20,21,21,22,46,47,47,48,48,49,49,50,74,75,75,76,76,77,77,78,83,82,82,81,81,80,80,79,55,54,54,53,53,52,52,51,27,26,26,25,25,24,24,23,1,2,2,3,3,4,4,5,30,31,31,32,32,33,33,34,58,59,59,60,60,61,61,62,86,87,87,88,88,89,89,90,71,70,70,69,69,68,68,67,55,54,54,53,53,52,52,51,51,50,50,49,49,48,48,47,23,22,22,21,21,20,20,19,5,7,7,8,8,9,9,10,34,35,35,36,36,37,37,38,62,63,63,64,64,65,65,66,90,91,91,92,92,92,92,91,67,66,66,65,65,64,64,63,39,38,38,37,37,36,36,35,11,10,10,9,9,8,8,7,18,19,19,20,20,21,21,22,46,47,47,48,48,49,49,50,74,75,75,76,76,77,77,78,83,82,82,81,81,80,80,79,55,54,54,53,53,52,52,51,27,26,26,25,25,24,24,23,1,2,2,3,3,4,4,5,30,31,31,32,32,33,33,34,58,59,59,60,60,61,61,62,86,87,87,88,88,89,89,90,63,62,62,61,61,55,55,54,25,24,24,23,23,22,22,21,20,21,21,22,22,23,23,24,53,54,54,55,55,61,61,62,77,76,76,75,75,74,74,73,49,48,48,47,47,46,46,45,21,20,20,19,19,18,18,17,24,25,25,26,26,27,27,28,52,53,53,54,54,55,55,56,47,46,46,45,45,44,44,43,19,18,18,17,17,16,16,15,10,11,11,12,12,13,13,14,38,39,39,40,40,41,41,42,66,67,67,68,68,69,69,70,91,90,90,89,89,88,88,87,63,62,62,61,61,60,60,59,35,34,34,33,33,32,32,31,7,5,5,4,4,3,3,2,22,23,23,24,24,25,25,26,50,51,51,52,52,53,53,54,78,79,79,80,80,81,81,82,79,78,78,77,77,76,76,75,51,50,50,49,49,48,48,47,23,22,22,21,21,20,20,19,5,7,7,8,8,9,9,10,34,35,35,36,36,37,37,38,62,63,63,64,64,65,65,66,90,91,91,92,92,84,84,83,54,53,53,52,52,51,51,50,21,20,20,19,19,18,18,17,24,25,25,26,26,27,27,33,62,63,63,64,64,65,65,66,73,72,72,71,71,70,70,69,45,44,44,43,43,42,42,41,17,16,16,15,15,14,14,13,28,29,29,30,30,31,31,32,56,57,57,58,58,59,59,60,43,42,42,41,41,40,40,39,15,14,14,13,13,12,12,11,14,15,15,16,16,17,17,18,42,43,43,44,44,45,45,46,70,71,71,72,72,73,73,74,87,86,86,85,85,84,84,83,59,58,58,57,57,56,56,55,31,30,30,29,29,28,28,27,2,1,1,0,0,0,0,1,26,27,27,28,28,29,29,30,54,55,55,56,56,57,57,58,82,83,83,84,84,85,85,86,75,74,74,73,73,72,72,71,47,46,46,45,45,44,44,43,19,18,18,17,17,16,16,15,10,11,11,12,12,13,13,14,38,39,39,40,40,41,41,42,66,67,67,68,68,69,69,70,83,82,82,81,81,80,80,79,50,49,49,48,48,47,47,46,17,16,16,15,15,14,14,13,33,34,34,35,35,36,36,37,66,67,67,68,68,69,69,70,69,68,68,67,67,66,66,65,41,40,40,39,39,38,38,37,13,12,12,11,11,10,10,9,32,33,33,34,34,35,35,36,60,61,61,62,62,63,63,64,39,38,38,37,37,36,36,35,11,10,10,9,9,8,8,7,18,19,19,20,20,21,21,22,46,47,47,48,48,49,49,50,74,75,75,76,76,77,77,78,83,82,82,81,81,80,80,79,55,54,54,53,53,52,52,51,27,26,26,25,25,24,24,23,1,2,2,3,3,4,4,5,30,31,31,32,32,33,33,34,58,59,59,60,60,61,61,62,86,87,87,88,88,89,89,90,71,70,70,69,69,68,68,67,43,42,42,41,41,40,40,39,15,14,14,13,13,12,12,11,14,15,15,16,16,17,17,18,42,43,43,44,44,45,45,46,70,71,71,72,72,73,73,74,79,78,78,77,77,76,76,75,46,45,45,44,44,43,43,42,13,12,12,11,11,10,10,9,37,38,38,39,39,40,40,41,70,71,71,72,72,73,73,74,65,64,64,63,63,62,62,61,37,36,36,35,35,34,34,33,9,9,9,10,10,11,11,12,36,37,37,38,38,39,39,40,64,65,65,66,66,67,67,68,35,34,34,33,33,32,32,31,7,5,5,4,4,3,3,2,22,23,23,24,24,25,25,26,50,51,51,52,52,53,53,54,78,79,79,80,80,81,81,82,79,78,78,77,77,76,76,75,51,50,50,49,49,48,48,47,23,22,22,21,21,20,20,19,5,7,7,8,8,9,9,10,34,35,35,36,36,37,37,38,62,63,63,64,64,65,65,66,90,91,91,92,92,92,92,91,67,66,66,65,65,64,64,63,39,38,38,37,37,36,36,35,11,10,10,9,9,8,8,7,18,19,19,20,20,21,21,22,46,47,47,48,48,49,49,50,74,75,75,76,76,77,77,78,75,74,74,73,73,72,72,71,42,41,41,40,40,39,39,38,9,9,9,10,10,11,11,12,41,42,42,43,43,44,44,45,74,75,75,76,76,77,77,78,61,60,60,59,59,58,58,57,33,32,32,31,31,30,30,29,12,13,13,14,14,15,15,16,40,41,41,42,42,43,43,44,68,69,69,70,70,71,71,72,31,30,30,29,29,28,28,27,2,1,1,0,0,0,0,1,26,27,27,28,28,29,29,30,54,55,55,56,56,57,57,58,82,83,83,84,84,85,85,86,75,74,74,73,73,72,72,71,47,46,46,45,45,44,44,43,19,18,18,17,17,16,16,15,10,11,11,12,12,13,13,14,38,39,39,40,40,41,41,42,66,67,67,68,68,69,69,70,91,90,90,89,89,88,88,87,63,62,62,61,61,60,60,59,35,34,34,33,33,32,32,31,7,5,5,4,4,3,3,2,22,23,23,24,24,25,25,26,50,51,51,52,52,53,53,54,78,79,79,80,80,81,81,82,71,70,70,69,69,68,68,67,38,37,37,36,36,35,35,34,12,13,13,14,14,15,15,16,45,46,46,47,47,48,48,49,78,79,79,80,80,81,81,81,57,56,56,55,55,54,54,53,29,28,28,27,27,26,26,25,16,17,17,18,18,19,19,20,44,45,45,46,46,47,47,48,72,73,73,74,74,75,75,76,27,26,26,25,25,24,24,23,1,2,2,3,3,4,4,5,30,31,31,32,32,33,33,34,58,59,59,60,60,61,61,62,86,87,87,88,88,89,89,90,71,70,70,69,69,68,68,67,43,42,42,41,41,40,40,39,15,14,14,13,13,12,12,11,14,15,15,16,16,17,17,18,42,43,43,44,44,45,45,46,70,71,71,72,72,73,73,74,87,86,86,85,85,84,84,83,59,58,58,57,57,56,56,55,31,30,30,29,29,28,28,27,2,1,1,0,0,0,0,1,26,27,27,28,28,29,29,30,54,55,55,56,56,57,57,58,82,83,83,84,84,85,85,86,67,66,66,65,65,64,64,63,34,33,33,27,27,26,26,25,16,17,17,18,18,19,19,20,49,50,50,51,51,52,52,53,81,80,80,79,79,78,78,77,53,52,52,51,51,50,50,49,25,24,24,23,23,22,22,21,20,21,21,22,22,23,23,24,48,49,49,50,50,51,51,52,76,77,77,78,78,79,79,80,80,81,81};
int maskArray[] = {19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,203,102,144,149,243,126,72,133,243,126,72,133,3,102,112,157,96,141,203,102,144,149,243,126,243,114,88,81,3,74,96,129,3,74,96,129,219,146,144,153,239,114,116,65,74,145,146,137,81,90,129,130,100,153,239,114,145,231,146,116,137,255,98,100,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,153,219,146,96,129,3,74,88,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,116,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,146,108,145,247,74,116,65,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,247,130,100,153,239,114,116,98,100,81,231,90,124,129,247,145,231,146,116,137,255,98,100,118,88,149,227,110,128,133,219,149,128,133,219,118,112,157,3,90,72,65,227,98,144,153,146,88,81,114,137,130,145,90,72,153,146,96,129,3,74,88,81,231,146,108,145,247,74,116,65,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,116,137,255,98,227,110,128,133,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,72,133,3,102,112,157,219,118,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,19,90,72,65,88,81,72,65,227,98,144,153,128,137,203,130,112,145,19,90,231,146,108,145,247,74,116,65,100,81,255,98,116,137,231,146,247,130,124,129,231,90,100,81,118,96,141,203,102,144,149,243,112,157,219,118,128,133,227,110,141,102,149,133,102,112,157,219,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,133,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,19,90,72,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,88,149,19,118,96,141,203,102,219,118,128,133,227,110,88,149,72,133,3,102,112,157,219,118,112,145,203,130,128,137,243,114,227,98,72,65,19,90,112,145,98,100,81,231,90,124,129,247,116,65,247,74,108,145,231,146,81,231,90,124,129,247,130,100,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,81,243,114,255,98,116,137,231,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,65,247,74,108,145,231,146,116,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,247,74,108,145,231,146,116,130,100,153,239,114,116,65,247,81,231,90,124,129,108,145,231,118,112,157,96,141,19,118,88,102,72,133,243,126,144,149,203,129,74,81,114,128,137,203,130,65,227,98,144,153,219,146,96,243,114,128,137,203,130,112,145,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,219,118,112,157,3,102,72,133,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,128,133,227,110,243,114,88,81,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,227,98,144,153,128,137,203,130,219,146,96,129,3,74,88,81,72,65,227,98,144,153,219,146,239,114,100,153,247,130,124,129,108,145,247,74,116,65,239,114,116,65,239,114,100,153,247,130,126,72,133,3,102,112,157,219,88,149,19,118,96,141,102,149,118,128,133,227,110,243,114,88,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,65,227,98,144,153,219,146,96,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,144,149,243,126,72,133,3,102,19,118,96,141,203,102,144,149,128,133,227,110,88,149,19,118,88,81,3,74,96,129,219,146,203,130,128,137,243,114,88,81,130,100,153,239,114,116,65,247,116,137,255,98,100,81,231,90,153,239,114,116,65,247,74,108,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,146,108,145,247,74,116,65,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,137,255,98,227,110,128,133,219,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,133,3,102,112,157,219,118,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,255,98,100,81,231,90,124,74,108,145,231,146,116,137,255,146,116,137,255,98,227,110,128,149,227,110,128,133,219,118,112,102,96,141,19,118,88,149,227,112,145,19,90,72,65,227,98,129,3,74,88,81,243,114,128,19,90,72,65,227,98,144,153,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,72,133,3,102,112,157,219,118,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,3,74,96,129,219,146,144,153,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,145,19,90,72,65,227,98,243,114,128,137,203,130,112,145,96,129,3,74,88,81,243,114,231,90,100,81,255,98,116,137,100,153,116,137,231,146,108,145,203,102,144,149,243,126,72,133,118,128,133,110,149,118,141,102,126,133,102,112,157,219,118,128,81,3,74,96,129,219,146,144,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,129,3,74,88,81,243,114,128,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,112,157,219,118,128,133,227,110,243,126,72,133,3,102,112,157,96,141,112,145,203,130,128,137,144,153,227,98,72,65,19,90,3,74,96,129,219,146,144,153,74,108,145,231,146,116,137,255,124,129,247,130,100,153,239,114,145,231,146,116,137,255,98,100,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,118,112,157,3,102,72,133,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,133,227,110,243,114,88,81,3,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,247,130,100,153,239,114,116,98,100,81,231,90,124,129,108,133,219,118,112,157,96,141,19,157,3,102,72,133,243,126,144,110,128,133,219,118,112,157,3,144,153,219,146,96,129,3,74,137,203,130,112,145,19,90,72,219,146,96,129,3,74,88,81,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,128,133,227,110,243,114,88,81,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,144,153,219,146,96,129,3,74,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,153,219,146,96,129,3,74,19,90,72,65,227,98,144,153,128,137,203,130,112,145,96,129,231,146,108,145,124,129,231,90,247,74,116,65,239,114,100,153,102,157,118,133,110,88,149,19,144,149,243,126,72,133,3,102,133,227,110,88,149,19,118,96,153,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,88,149,19,118,96,141,203,102,219,118,128,133,227,110,88,149,243,114,88,81,3,74,96,129,112,145,203,130,128,137,243,114,227,98,72,65,19,90,112,145,98,100,81,231,90,124,129,247,116,65,247,74,108,145,231,146,81,231,90,124,129,247,130,100,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,133,3,102,112,157,219,118,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,144,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,74,96,129,219,146,144,153,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,247,74,108,145,231,146,116,145,231,146,116,137,255,98,100,118,88,149,227,110,128,133,219,149,203,102,96,141,19,118,88,102,72,133,243,126,144,149,203,88,81,243,114,128,137,203,130,65,227,98,144,153,219,146,96,243,114,128,137,203,130,112,145,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,3,74,96,129,219,146,144,153,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,88,81,243,114,255,98,116,137,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,116,65,247,74,108,145,231,146,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,81,243,114,128,137,203,130,219,146,96,129,3,74,88,81,3,74,88,81,243,114,255,98,100,81,255,98,116,137,231,146,247,130,124,129,231,90,100,81,118,96,141,203,102,144,149,243,112,157,219,118,128,133,227,110,141,203,102,144,149,243,126,72,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,116,65,247,74,108,145,231,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,144,149,243,126,72,133,3,102,19,118,96,141,112,157,219,118,219,146,144,153,227,98,72,65,88,81,3,74,96,129,219,146,203,130,128,137,144,153,227,98,130,100,153,239,114,116,65,247,116,137,255,98,100,81,231,90,153,110,133,118,157,102,133,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,133,227,110,243,114,88,81,3,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,153,219,146,96,129,3,74,88,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,247,130,100,153,239,137,100,153,239,114,116,65,247,81,231,90,124,129,247,130,100,118,112,157,3,102,72,133,243,149,227,110,128,133,219,118,112,102,96,141,19,118,88,149,72,112,145,19,90,72,65,227,98,129,3,74,88,81,243,114,128,90,65,153,146,96,129,3,74,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,231,146,108,145,247,74,116,65,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,116,137,255,98,227,110,128,133,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,145,19,90,72,65,227,98,243,114,128,137,203,130,112,145,116,137,231,146,108,145,124,129,108,145,247,74,116,65,239,114,255,98,116,137,231,146,108,145,126,72,133,3,102,112,157,219,88,149,19,118,96,141,203,102,133,3,102,112,157,219,118,128,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,146,116,137,255,98,227,110,128,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,112,157,219,118,128,133,144,149,128,133,227,110,88,149,19,118,19,90,112,145,203,130,128,137,144,153,227,98,72,65,88,81,72,65,19,90,247,130,100,153,74,108,145,231,146,116,137,98,124,129,130,153,114,65,74,108,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,144,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,74,96,129,219,146,144,153,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,81,243,114,255,98,116,137,231,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,114,116,65,100,81,231,90,124,74,108,145,231,146,116,137,255,153,239,114,116,65,247,74,108,126,144,149,203,102,96,141,19,157,3,102,72,133,243,126,144,133,243,126,144,149,203,102,19,144,153,219,146,96,129,3,74,137,203,130,112,145,90,65,98,88,81,243,114,255,98,116,137,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,116,65,247,74,108,145,231,146,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,219,118,112,157,3,102,72,133,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,153,219,146,96,129,3,74,96,129,3,74,88,81,243,114,231,90,100,81,255,98,116,137,100,153,247,130,124,129,231,90,247,74,116,65,239,114,100,153,118,128,133,227,110,88,149,19,144,149,243,126,72,133,3,102,133,227,110,88,149,19,118,96,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,133,219,118,112,157,3,102,72,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,65,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,133,219,118,112,157,3,102,72,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,129,3,74,88,81,72,65,227,81,243,114,128,137,203,130,112,203,129,96,90,19,81,88,98,72,114,243,153,144,137,128,146,144,102,219,157,96,118,3,133,88,110,243,149,128,118,203,141,112,102,19,149,72,126,227,133,255,81,116,74,231,129,108,146,247,153,116,98,239,65,100,90,137,203,130,112,145,19,90,72,65,227,98,144,153,219,146,96,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,72,133,3,102,112,157,219,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,133,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,243,114,128,98,144,153,219,146,96,129,3,145,19,90,72,65,227,98,144,227,137,128,146,219,145,112,129,219,145,112,74,3,65,72,114,88,110,243,149,128,118,203,141,112,102,19,149,72,126,227,133,144,102,219,157,96,118,3,133,247,153,116,98,239,65,100,90,247,145,124,130,231,137,100,114,65,227,98,144,153,219,146,96,129,3,74,88,81,243,114,128,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,118,128,133,227,110,243,114,88,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,137,203,130,112,145,19,90,72,74,88,81,243,114,128,137,203,153,219,146,96,129,3,74,88,96,90,19,81,88,98,227,137,243,153,144,130,203,129,96,90,112,102,19,149,72,126,227,133,144,102,219,157,96,118,3,133,88,110,243,149,128,118,203,141,247,145,124,130,231,137,100,114,255,81,116,74,231,129,108,146,129,3,74,88,81,243,114,128,137,203,130,112,145,19,90,72,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,81,3,74,96,129,219,146,144,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,65,227,98,144,153,219,146,96,130,112,145,19,90,72,65,227,81,243,114,128,137,203,130,112,128,146,219,145,112,74,3,65,19,81,88,98,227,137,128,146,144,102,219,157,96,118,3,133,88,110,243,149,128,118,203,141,112,145,124,130,231,137,100,114,255,81,116,74,231,129,108,146,247,153,116,98,239,65,100,90,137,203,130,112,145,19,90,72,65,144,153,219,146,96,129,3,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,153,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,247,130,100,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,129,3,74,88,81,243,114,128,98,144,153,219,146,96,129,3,145,129,96,90,19,81,88,98,72,114,243,153,144,130,203,129,219,145,112,74,3,65,72,114,88,110,243,149,128,118,203,141,112,102,19,149,72,126,227,133,255,81,116,74,231,129,108,146,247,153,116,98,239,65,100,90,247,145,124,130,231,137,100,114,65,227,98,144,153,219,146,96,74,88,81,243,114,255,98,116,146,108,145,247,74,116,65,239,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,157,219,118,128,133,227,110,88,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,130,128,137,243,114,88,81,3,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,153,239,114,116,65,247,74,108,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,116,65,247,74,108,145,231,118,88,149,227,110,128,133,219,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,137,203,130,112,145,19,90,72,74,88,81,243,114,128,137,203,227,137,128,146,219,145,112,74,96,90,19,81,88,98,227,137,243,153,144,130,203,129,96,141,112,102,19,149,72,126,227,133,144,102,219,157,96,118,3,133,247,153,116,98,239,65,100,90,247,145,124,130,231,137,100,114,255,81,116,74,231,129,108,146,129,3,74,88,81,243,114,128,137,231,146,108,145,247,74,116,114,100,153,247,130,124,129,231,90,100,81,255,98,116,137,231,146,108,145,247,74,116,65,239,149,19,118,96,141,203,102,144,149,243,126,72,133,3,102,112,157,219,118,128,133,227,110,88,74,96,129,219,146,144,153,227,98,72,65,19,90,112,145,203,130,128,137,243,114,88,81,3,145,231,146,116,137,255,98,100,81,231,90,124,129,247,130,100,153,239,114,116,65,247,74,108,146,116,137,255,98,227,110,128,118,112,157,3,102,72,133,243,126,144,149,203,102,96,141,19,118,88,149,227,110,128,133,219,65,227,98,144,153,219,146,96,130,112,145,96,129,3,74,88,3,65,72,114,243,153,144,130,128,146,219,145,112,74,3,65,112,102,19,149,72,126,227,133,144,102,219,157,96,118,3,133,88,110,243,149,128,118,203,141,247,145,124,130,231,137,100,114,255,81,116,74,231,129,108,146,247,153,116,98,239,65,100,90,247,145,124};
int dataPos[NUMBLOCK][MAXBLKSIZE];
int erasurePos[NUMBLOCK][NUMECCWORDS];
int saltPos[NUMBLOCK][2];
int payload[MAXBLKSIZE];
double a0[97*97];
double b0[97*97];
double c0[97*97];
int dirty_in;
int dirty_out;
int dirty_flag[97*97];
int dirty_yx[97*97];
int scqPos[97*97];
int scqPosLen;
int rsIndexOf[] = {255,0,1,25,2,50,26,198,3,223,51,238,27,104,199,75,4,100,224,14,52,141,239,129,28,193,105,248,200,8,76,113,5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,29,181,194,125,106,39,249,185,201,154,9,120,77,228,114,166,6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87,7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175};
int rsAlphaTo[] = {1,2,4,8,16,32,64,128,29,58,116,232,205,135,19,38,76,152,45,90,180,117,234,201,143,3,6,12,24,48,96,192,157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,70,140,5,10,20,40,80,160,93,186,105,210,185,111,222,161,95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,130,25,50,100,200,141,7,14,28,56,112,224,221,167,83,166,81,162,89,178,121,242,249,239,195,155,43,86,172,69,138,9,18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,44,88,176,125,250,233,207,131,27,54,108,216,173,71,142,0};
int rsData1[NUMBLOCK][NUMECCWORDS+1];
int rsData2[NUMBLOCK][NUMECCWORDS];
int rsData3[NUMBLOCK][NUMECCWORDS*256];
int rsData4[NUMBLOCK][NUMECCWORDS*256];
int rsData5[NUMBLOCK][NUMECCWORDS*NUMECCWORDS*256];
int rsData6[NUMBLOCK][NUMECCWORDS*256];
int codewords[MAXCODEWORDS];
void init(const char *inputText, int inputTextLength, int outline, int seed0)
{
/*
** Convert text to payload codewords
*/
payload[0] = 0x40;
payload[1] = ((inputTextLength & 0xF0) >> 4);
payload[2] = ((inputTextLength & 0x0F) << 4);
for (int i = 0; i < inputTextLength; i++) {
payload[2 + i] |= ((inputText[i] & 0xF0) >> 4);
payload[3 + i] = ((inputText[i] & 0x0F) << 4);
}
/*
** Sort codewords indices depending on distance to center
*/
int dpos = 0; // first data pos
int epos = MAXDATABITS >> 3; // first ECC pos
for (int blknr=0; blknr<NUMBLOCK; blknr++) {
// dataPos[blknr] = [];
// erasurePos[blknr] = [];
// saltPos[blknr] = [];
int blkSize = rsBlockOrder[blknr];
int sortPos[255]; // indices
int sortWeight[255]; // weight
// deterine indices for block
int k = 0;
for (int j=0; j<blkSize-NUMECCWORDS; j++) sortPos[k++] = dpos++;
for (int j=0; j<NUMECCWORDS; j++) sortPos[k++] = epos++;
// relate weight to distance
for (k=0; k<blkSize; k++) {
int j = sortPos[k];
int dist = 0;
if (outline == 0) {
for (int i = 7; i >= 0; i--) {
dist += sqrt((matrixX[j*8+i]-QRSIZE/2.0)*(matrixX[j*8+i]-QRSIZE/2.0) +
(matrixY[j*8+i]-QRSIZE/2.0)*(matrixY[j*8+i]-QRSIZE/2.0));
}
} else if (outline == 1) {
for (int i = 7; i >= 0; i--) {
int di = abs(matrixX[j*8+i]-QRSIZE/2.0);
int dj = abs(matrixY[j*8+i]-QRSIZE/2.0);
dist += di>dj ? di : dj;
}
} else if (outline == 2) {
for (int i = 7; i >= 0; i--) {
dist += sqrt((matrixY[j*8+i]-QRSIZE/2.0)*(matrixY[j*8+i]-QRSIZE/2.0));
}
} else if (outline == 3) {
for (int i = 7; i >= 0; i--) {
dist += sqrt((matrixX[j*8+i]-QRSIZE/2.0)*(matrixX[j*8+i]-QRSIZE/2.0));
}
} else {
for (int i = 7; i >= 0; i--) {
seed0 = (seed0 * 1103515245 + 12345) & 0x7fffffff;
dist += seed0 % 10000;
}
}
sortWeight[k] = dist;
}
// bubblesort weights in decending distance
int changed;
do {
changed = false;
for (int k=1; k<blkSize; k++) {
if (sortWeight[k-1] < sortWeight[k]) {
// lazy swap
sortWeight[k-1] += sortWeight[k];
sortWeight[k] = sortWeight[k-1] - sortWeight[k];
sortWeight[k-1] = sortWeight[k-1] - sortWeight[k];
sortPos[k-1] += sortPos[k];
sortPos[k] = sortPos[k-1] - sortPos[k];
sortPos[k-1] = sortPos[k-1] - sortPos[k];
changed = 1;
}
}
} while (changed);
// assign codewordsbased on function
int numErasure = 0;
int numSalt = 0;
for (int i=0; i<blkSize; i++) {
// mark erasure odd, data even
if (sortPos[i] < inputTextLength+3) {
dataPos[blknr][i] = sortPos[i]*2;
} else if (numSalt < opt_maxsalt) {
dataPos[blknr][i] = sortPos[i]*2;
saltPos[blknr][numSalt++] = sortPos[i];
} else if (numErasure < NUMECCWORDS) {
dataPos[blknr][i] = sortPos[i]*2+1;
numErasure++;
} else {
dataPos[blknr][i] = sortPos[i]*2;
}
}
if (numErasure < NUMECCWORDS) {
printf("{\"error\":\"Payload too long\"}");
exit(1);
}
// sort ascending for RS calculations
do {
changed = false;
for (int k=1; k<blkSize; k++) {
if (dataPos[blknr][k-1] > dataPos[blknr][k]) {
// lazy swap
dataPos[blknr][k-1] += dataPos[blknr][k];
dataPos[blknr][k] = dataPos[blknr][k-1] - dataPos[blknr][k];
dataPos[blknr][k-1] = dataPos[blknr][k-1] - dataPos[blknr][k];
changed = 1;
}
}
} while (changed);
// extract indicies of erasure codewords
for (int i=0,j=0; i<blkSize; i++) {
if (dataPos[blknr][i]&1)
erasurePos[blknr][j++] = i;
}
}
/*
** Map the pixels that are part of the image
*/
scqPosLen = 0;
for (int blknr=0; blknr<NUMBLOCK; blknr++) {
for (int k=0; k<rsBlockOrder[blknr]; k++) {
if ((dataPos[blknr][k]&1) == 0) {
int j = dataPos[blknr][k]>>1;
if (j < inputTextLength+3) continue;
if (opt_maxsalt >= 1 && saltPos[blknr][0] == j) continue;
if (opt_maxsalt >= 2 && saltPos[blknr][1] == j) continue;
for (int i = 7; i >= 0; i--) {
int ji = j * 8 + i;
scqPos[scqPosLen++] = matrixY[ji]*97+matrixX[ji]+97*2+2;
}
}
}
}
/*
** RS unrolling
*/
for (int blknr=0; blknr<NUMBLOCK; blknr++) {
int *data1 = rsData1[blknr];
data1[0] = 1;
for (int i=1; i<NUMECCWORDS+1; i++)
data1[i] = 0;
// Init lambda to be the erasure locator polynomial
for (int i = 0; i < NUMECCWORDS; i++) {
int u
= 254-erasurePos[blknr][i];
for (int j=i; j >= 0; j--) {
int tmp = rsIndexOf[data1[j]];
if (tmp != 255)
data1[j+1] ^= rsAlphaTo[(u + tmp)%255];
}
}
for (int i=0; i<NUMECCWORDS; i++) {
data1[i] = rsIndexOf[data1[i]];
}
int *data2 = rsData2[blknr];
for (int j = NUMECCWORDS-1; j >=0; j--) {
int tmp = 0;
for (int i = NUMECCWORDS-2; i >= 0; i -=2) {
if (data1[i+1] != 255)
tmp ^= rsAlphaTo[(data1[i+1] + i * (erasurePos[blknr][j]+1))%255];
}
data2[j] = rsIndexOf[tmp];
}
int *data3 = rsData3[blknr];
for (int i=0; i<NUMECCWORDS; i++){
for (int tmp=0; tmp<256; tmp++) {
if (tmp)
data3[i*256+tmp] = rsAlphaTo[(rsIndexOf[tmp] + i)%255];
else
data3[i*256+tmp] = 0;
}
}
int *data4 = rsData4[blknr];
for (int j = 0; j < NUMECCWORDS; j++) {
for (int z=0; z<256; z++) {
if (z != 0 && data1[j] != 255)
data4[j*256+z] = rsAlphaTo[(rsIndexOf[z] + data1[j])%255];
else
data4[j*256+z] = 0;
}
}
int *data5 = rsData5[blknr];
for (int j = 0; j < NUMECCWORDS; j++) {
for (int i = 0; i < NUMECCWORDS; i++) {
for (int z=0; z<256; z++) {
if (z != 0)
data5[j*256*28+i*256+z] = rsAlphaTo[(rsIndexOf[z] + i * (erasurePos[blknr][j]+1))%255];
else
data5[j*256*28+i*256+z] = 0;
}
}
}
int *data6 = rsData6[blknr];
for (int j = 0; j < NUMECCWORDS; j++) {
for (int tmp=0; tmp<256; tmp++) {
if (tmp != 0)
data6[j*256+tmp] = rsAlphaTo[(rsIndexOf[tmp]+254-erasurePos[blknr][j]+255-data2[j])%255];
else
data6[j*256+tmp] = 0;
}
}
}
}
void injectImage(gdImagePtr im)
{
/*
** Convert the input image to grayscaled a0[] and blurred b0[]
*/
// a0 = [];
// b0 = [];
for (int ji=0; ji<97*97; ji++)
b0[ji] = a0[ji] = c0[ji] = 0.5;
// convert to normalized grayscale
double gsmin=opt_gsmin, gsmax = opt_gsmax;
for (int j=2; j<95; j++) {
for (int i=2; i<95; i++) {
int ji = j*97+i;
int v = gdImageGetTrueColorPixel(im, i-2, j-2);
float r = ((v>>16) & 0xFF) / 255.0;
float g = ((v>>8) & 0xFF) / 255.0;
float b = (v & 0xFF) / 255.0;
double gs = r*0.299 + g*0.587 + b*0.114;
if (gsmin > gs) gsmin = gs;
if (gsmax < gs) gsmax = gs;
}
}
for (int j=2; j<95; j++) {
for (int i=2; i<95; i++) {
int ji = j*97+i;
int v = gdImageGetTrueColorPixel(im, i-2, j-2);
float r = ((v>>16) & 0xFF) / 255.0;
float g = ((v>>8) & 0xFF) / 255.0;
float b = (v & 0xFF) / 255.0;
double gs = r*0.299 + g*0.587 + b*0.114;
a0[ji] = (gs-gsmin)*(1-opt_contrast*2)/(gsmax-gsmin)+opt_contrast; // thresshold is 238/256
}
}
// blur with radius 2
for (int j=2; j<95; j++) {
for (int i=2; i<95; i++) {
int ji = j*97+i;
double sum1=0, sum4=0, sum6=0, sum16=0, sum24=0, sum36=0;
int k = ji-2*97-2;
sum1 += a0[k++];
sum4 += a0[k++];
sum6 += a0[k++];
sum4 += a0[k++];
sum1 += a0[k];
k += 97-4;
sum4 += a0[k++];
sum16 += a0[k++];
sum24 += a0[k++];
sum16 += a0[k++];
sum4 += a0[k];
k += 97-4;
sum6 += a0[k++];
sum24 += a0[k++];
sum36 += a0[k++];
sum24 += a0[k++];
sum6 += a0[k];
k += 97-4;
sum4 += a0[k++];
sum16 += a0[k++];
sum24 += a0[k++];
sum16 += a0[k++];
sum4 += a0[k];
k += 97-4;
sum1 += a0[k++];
sum4 += a0[k++];
sum6 += a0[k++];
sum4 += a0[k++];
sum1 += a0[k];
b0[ji] = (sum36*36 + sum24*24 + sum16*16 + sum6*6 + sum4*4 + sum1*1)/256.0;
}
}
/*
** inject overlay into c0
*/
FILE *fil = fopen("qrcode-mask-93x93.png", "rb");
if (fil == NULL) {
printf("{\"error\":\"Could not open mask\"}");
exit(1);
}
im = gdImageCreateFromPng(fil);
for (int j=0; j<QRSIZE; j++) {
for (int i=0; i<QRSIZE; i++) {
int v = gdImageGetTrueColorPixel(im, i, j);
float a = ((v>>24) & 0xFF) / 127.0;
float r = ((v>>16) & 0xFF) / 255.0;
float g = ((v>>8) & 0xFF) / 255.0;
float b = (v & 0xFF) / 255.0;
if (a < 0.5)
c0[j*97+i+2*97+2] = r; // mask
else
c0[j*97+i+2*97+2] = a0[j*97+i+2*97+2]; // sharp image
}
}
}
void injectPayload(int inputTextLength, int maskNumber)
{
/*
** Inject payload
*/
for (int j = 0; j < inputTextLength+3; j++) {
int bits = payload[j];
for (int i = 7; i >= 0; i--) {
int ji = j * 8 + i;
int c = (((255 * (bits & 1)) ^ maskArray[ji]) & (1<<maskNumber)) ? 0 : 1;
c0[matrixY[ji]*97+matrixX[ji]+97*2+2] = c;
bits = bits >> 1;
}
}
}
void injectHeaders(int maskNumber)
{
/*
** Inject headers into c0
*/
int formatInformationValue = (EC << 3 | maskNumber);
for (int i = 0; i < 15; i++) {
int c = ((formatInformationArray[formatInformationValue] >> i) & 1) ? 0 : 1;
c0[formatInformationY1[i]*97+formatInformationX1[i]+97*2+2] = c;
c0[formatInformationY2[i]*97+formatInformationX2[i]+97*2+2] = c;
}
}
void spatialColorQuantize(int seed0)
{
/*
** Spatial Color Quantize, optimized for monochrome
*/
for (int ji=0; ji<97*97; ji++) {
dirty_flag[ji] = 2;
}
for (int loopnr=0; loopnr<2; loopnr++) {
// visit pixels
dirty_in = dirty_out = 0;
for (int k=0; k<scqPosLen; k++) {
int ji = scqPos[k];
dirty_flag[ji] = 1;
dirty_yx[dirty_in++] = ji;
}
// randomize
for (int i=1; i<dirty_in-dirty_out; i++) {
seed0 = (seed0 * 1103515245 + 12345) & 0x7fffffff;
int j = seed0 % (i + 1);
int swap = dirty_yx[i];
dirty_yx[i] = dirty_yx[j];
dirty_yx[j] = swap;
}
// handle bits
while (dirty_out != dirty_in) {
int yx = dirty_yx[dirty_out];
dirty_out = (dirty_out+1)%(97*97);
double sum1=0, sum4=0, sum6=0, sum16=0, sum24=0;
int ji = yx-2*97-2;
sum1 += c0[ji++];
sum4 += c0[ji++];
sum6 += c0[ji++];
sum4 += c0[ji++];
sum1 += c0[ji];
ji += 97-4;
sum4 += c0[ji++];
sum16+= c0[ji++];
sum24+= c0[ji++];
sum16+= c0[ji++];
sum4 += c0[ji];
ji += 97-4;
sum6 += c0[ji++];
sum24+= c0[ji++];
ji++;
sum24+= c0[ji++];
sum6 += c0[ji];
ji += 97-4;
sum4 += c0[ji++];
sum16+= c0[ji++];
sum24+= c0[ji++];
sum16+= c0[ji++];
sum4 += c0[ji];
ji += 97-4;
sum1 += c0[ji++];
sum4 += c0[ji++];
sum6 += c0[ji++];
sum4 += c0[ji++];
sum1 += c0[ji];
double sum = (36/2+sum24*24 + sum16*16 + sum6*6 + sum4*4 + sum1)/256.0;
int old_max_v = (c0[yx] > 0.5) ? 1 : 0;
int new_max_v = (b0[yx] > sum) ? 1 : 0;
c0[yx] = new_max_v;
if (old_max_v != new_max_v) {
for (int j=-2; j<=2; j++) {
for (int i=-2; i<=2; i++) {
int ji = yx + j*97 + i;
if (dirty_flag[ji] == 0) {
dirty_flag[ji] = 1;
dirty_yx[dirty_in] = ji;
dirty_in = (dirty_in+1)%(97*97);
}
}
}
}
dirty_flag[yx] = 0;
}
}
}
int SCQQuality(void)
{
/*
** Spatial Color Quantization Quality
*/
int qual = 0;
for (int y = 2; y < 2+QRSIZE; y++) {
for (int x = 2; x < 2+QRSIZE; x++) {
int yx = y*97+x;
// don't include hard pixels
if (b0[yx] > 0.0001 && b0[yx] < 0.9999) {
double sum1=0, sum4=0, sum6=0, sum16=0, sum24=0;
int ji = yx-2*97-2;
sum1 += c0[ji++];
sum4 += c0[ji++];
sum6 += c0[ji++];
sum4 += c0[ji++];
sum1 += c0[ji];
ji += 97-4;
sum4 += c0[ji++];
sum16+= c0[ji++];
sum24+= c0[ji++];
sum16+= c0[ji++];
sum4 += c0[ji];
ji += 97-4;
sum6 += c0[ji++];
sum24+= c0[ji++];
ji++;
sum24+= c0[ji++];
sum6 += c0[ji];
ji += 97-4;
sum4 += c0[ji++];
sum16+= c0[ji++];
sum24+= c0[ji++];
sum16+= c0[ji++];
sum4 += c0[ji];
ji += 97-4;
sum1 += c0[ji++];
sum4 += c0[ji++];
sum6 += c0[ji++];
sum4 += c0[ji++];
sum1 += c0[ji];
double sum = (36/2+sum24*24 + sum16*16 + sum6*6 + sum4*4 + sum1)/256.0;
int old_max_v = (c0[yx] > 0.5) ? 1 : 0;
int new_max_v = (b0[yx] > sum) ? 1 : 0;
if (old_max_v != new_max_v)
qual++;
}
}
}
return qual;
}
int QRQuality(void)
{
/*
** QR Determine quality
*/
int d4Value[] = { 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 90 };
int d1=0, d2=0, d3=0, d4=0;
int d4Counter=0;
for (int y = 0; y < QRSIZE; y++)
{
int xdata=0, ydata=0;
int xD1Flag=false, yD1Flag=false;
for (int x = 0; x <QRSIZE; x++)
{
int yx = y*97+x+2*97+2;
if (x > 0 && y > 0) {
if ((c0[yx] < 0.5 && c0[yx-1] < 0.5 && c0[yx-97] < 0.5 && c0[yx-97-1] < 0.5) ||
(c0[yx] > 0.5 && c0[yx-1] > 0.5 && c0[yx-97] > 0.5 && c0[yx-97-1] > 0.5))
d2 += 3;
}
xdata = ((xdata & 0x3F) << 1) | (c0[x*97+y+2*97+2] > 0.5 ? 1 : 0);
ydata = ((ydata & 0x3F) << 1) | (c0[y*97+x+2*97+2] > 0.5 ? 1 : 0);
if (c0[yx] < 0.5)
d4Counter++;
if (xdata == 0x5D)
d3 += 40;
if (ydata == 0x5D)
d3 += 40;
if ((xdata & 0x1F) != 0 && (xdata & 0x1F) != 0x1F)
xD1Flag = false;
else if (xD1Flag)
d1++;
else
{
d1 += 3;
xD1Flag = true;
}
if ((ydata & 0x1F) != 0 && (ydata & 0x1F) != 0x1F)
yD1Flag = false;
else if (yD1Flag)
d1++;
else
{
d1 += 3;
yD1Flag = true;
}
}
}
int maxCodewordsBitWithRemain = matrixRemainBit[QRVERSION] + MAXCODEWORDS * 8;
d4 = d4Value[(int)floor(20 * d4Counter / maxCodewordsBitWithRemain)]; // integer divide
return d1 + d2 + d3 + d4;
}
void pixelsToCodewords(int maskNumber)
{
/*
** Convert pixels to codewords
*/
for (int j = 0; j < MAXCODEWORDS; j++) {
int bits = 0;
for (int i = 7; i >= 0; i--) {
int ji = j * 8 + i;
int r = c0[matrixY[ji]*97+matrixX[ji]+97*2+2] > 0.5 ? 0 : 255;
int b = (( r ^ maskArray[ji]) & (1<<maskNumber)) ? 1 : 0;
bits |= b<<(7-i);
}
codewords[j] = bits;
}
}
void calculateReedSolomon(int blknr)
{
/*
** Calculate ECC
*/
int *data3 = rsData3[blknr];
int *data4 = rsData4[blknr];
int *data5 = rsData5[blknr];
int *data6 = rsData6[blknr];
int blkSize = rsBlockOrder[blknr];
int *dpos = dataPos[blknr];
int *epos = erasurePos[blknr];
int s[NUMECCWORDS];
int k = 0;
for (int i=0; i<NUMECCWORDS; i++) {
int tmp = 0;
for (int j=0; j<blkSize; j++)
tmp = data3[k+tmp] ^ codewords[dpos[j]>>1];
for (int j=blkSize; j<255; j++)
tmp = data3[k+tmp];
s[i] = tmp;
k += 256;
}
int omega[NUMECCWORDS];
for (int i = 0; i < NUMECCWORDS; i++){
int tmp = 0;
int k = 0;
for (int j=0; j<=i; j++) {
tmp ^= data4[k+s[i-j]];
k += 256;
}
omega[i] = tmp;
}
k=0;
for (int j=0; j<NUMECCWORDS; j++) {
int tmp = 0;
for (int i=0; i<NUMECCWORDS; i++) {
tmp ^= data5[k+omega[i]];
k += 256;
}
codewords[dpos[epos[j]]>>1] ^= data6[j*256+tmp];
}
}
void codewordsToPixels(int maskNumber)
{
/*
** convert codewords to pixels
*/
for (int j = 0; j < MAXCODEWORDS; j++) {
int bits = codewords[j];
for (int i = 7; i >= 0; i--) {
int ji = j * 8 + i;
int c = (((255 * (bits & 1)) ^ maskArray[ji]) & (1<<maskNumber)) ? 0 : 1;
c0[matrixY[ji]*97+matrixX[ji]+97*2+2] = c;
bits = bits >> 1;
}
}
}
void usage(const char *argv0, int verbose)
{
printf("Usage: %s [options] <text> <source image> <output image>\n", argv0);
if (verbose)
return;
printf("\nsource image is PNG/JPG/GIF\noutput image is PNG\n");
printf("\n\
options:\n\
-v --verbose show progress\n\
--seed=n starting seed of random generator\n\
--gsmin=n normalize lower limit (%.2f)\n\
--gsmax=n normalize upper limit (%.2f)\n\
--contrast=n normalize contrast (%.2f)\n\
--outline=n 0=round, 1=square, 2=horizontal, 3=vertical\n\
--maxsalt=n 0=works, 1=decent, 2=chew on it for an hour\n", opt_gsmin, opt_gsmax, opt_contrast);
}
int main(int argc, char **argv)
{
FILE *fil;
gdImagePtr im = NULL;
struct tms tms0;
times(&tms0);
int ticks_per_sec = sysconf(_SC_CLK_TCK);
int SCQqual, QRqual;
//----------
for(;;) {
int option_index = 0;
enum { LO_SEED=1, LO_GSMIN, LO_GSMAX, LO_CONTRAST, LO_OUTLINE, LO_MAXSALT,
LO_HELP='h', LO_VERBOSE='v', };
static struct option long_options[] = {
/* name, has_arg, flag, val */
{"help", 0, 0, LO_HELP},
{"verbose", 0, 0, LO_VERBOSE},
{"seed", 1, 0, LO_SEED},
{"gsmin", 1, 0, LO_GSMIN},
{"gsmax", 1, 0, LO_GSMAX},
{"contrast", 1, 0, LO_CONTRAST},
{"outline", 1, 0, LO_OUTLINE},
{"maxsalt", 1, 0, LO_MAXSALT},
{NULL, 0, 0, 0}
};
char optstring[128], *cp;
cp = optstring;
for (int i=0; long_options[i].name; i++) {
if (isalpha(long_options[i].val)) {
*cp++ = long_options[i].val;
if (long_options[i].has_arg)
*cp++ = ':';
}
}
*cp++ = '\0';
int c = getopt_long (argc, argv, optstring, long_options, &option_index);
if (c == -1)
break;
switch (c) {
case LO_GSMIN:
opt_gsmin = strtod(optarg, NULL);
break;
case LO_GSMAX:
opt_gsmax = strtod(optarg, NULL);
break;
case LO_CONTRAST:
opt_contrast = strtod(optarg, NULL);
break;
case LO_OUTLINE:
opt_outline = strtol(optarg, NULL, 10);
break;
case LO_SEED:
opt_seed = strtol(optarg, NULL, 10);
break;
case LO_MAXSALT:
opt_maxsalt = strtol(optarg, NULL, 10);
break;
case LO_VERBOSE:
opt_verbose++;
break;
case LO_HELP:
usage(argv[0], 0);
exit(0);
break;
case '?':
fprintf(stdout,"Try `%s --help' for more information.\n", argv[0]);
exit(1);
break;
default:
fprintf (stdout, "getopt returned character code %d\n", c);
exit(1);
}
}
if (argc-optind < 3) {
usage(argv[0], 1);
exit(1);
}
opt_text = argv[optind++];
opt_infile = argv[optind++];
opt_outfile = argv[optind++];
if (opt_outline < 0 || opt_outline > 3) {
fprintf(stdout, "Outline must be in range 0..3\n");
return -1;
}
if (opt_maxsalt < 0 || opt_maxsalt > 2) {
fprintf(stdout, "maxsalt must be in range 0..2\n");
return -1;
}
/* set generator to (un)known state */
if (!opt_seed)
opt_seed = time(NULL);
srand(opt_seed);
if (strcmp(opt_text, "-") == 0) {
// read from stdin
static char stdinbuf[65536];
int len = read(0, stdinbuf, sizeof(stdinbuf)-1);
stdinbuf[len] = 0;
opt_text = stdinbuf;
}
int inputTextLength = strlen(opt_text);
//----------
fil = fopen(opt_infile, "rb");
if (fil == NULL) {
fprintf(stdout, "Could not open source\n");
return -1;
}
im = gdImageCreateFromPng(fil);
if (!im)
im = gdImageCreateFromJpeg(fil);
if (!im)
im = gdImageCreateFromGif(fil);
if (!im) {
fprintf(stdout, "Source not PNG/JPG/GIF\n");
return -1;
}
if (im->sx != QRSIZE || im->sy != QRSIZE) {
fprintf(stdout, "input must be fixed size 93x93. sx:%d sy:%d\n", im->sx, im->sy);
return 1;
}
//step0
int bestSCQ = -1;
int bestQR = -1;
int bestMask = -1;
int bestSeed = -1;
int maxMask = (opt_maxsalt==2) ? 1000 : (opt_maxsalt==1) ? 256 : 1;
int maskLeft[NUMMASK];
for (int i=0; i<NUMMASK; i++)
maskLeft[i] = maxMask;
int maskNumber = 0;
init(opt_text, inputTextLength, opt_outline, opt_seed);
injectImage(im);
injectHeaders(maskNumber);
injectPayload(inputTextLength, maskNumber);
//step1
for(;;) {
/*
** Calculate
*/
// SCQ and determine quality
++opt_seed;
spatialColorQuantize(opt_seed);
/*
** Determine qualities
*/
SCQqual = SCQQuality();
QRqual = QRQuality();
if (bestMask < 0 || (QRqual < bestQR+10 && SCQqual < bestSCQ)) {
bestQR = QRqual;
bestSCQ = SCQqual;
bestMask = maskNumber;
bestSeed = opt_seed;
if (opt_verbose>0) {
printf("#1 SCQqual:%d QRqual:%d\n", bestSCQ, bestQR);
fflush(stdout);
}
// reset counters
for (int i=0; i<NUMMASK; i++)
maskLeft[i] = maxMask;
maskLeft[maskNumber]--;
// bump to next
maskNumber = (maskNumber+1) % NUMMASK;
injectHeaders(maskNumber);
injectPayload(inputTextLength, maskNumber);
// find next candidate
continue;
}
/*
** bump to next
*/
if (--maskLeft[maskNumber] > 0) {
continue;
}
/*
** block exausted
*/
maskNumber = (maskNumber+1) % NUMMASK;
if (maskLeft[maskNumber] > 0) {
injectPayload(inputTextLength, maskNumber);
continue;
}
// done
break;
}
// done1
// reconstruct best
maskNumber = bestMask;