1 /* auto-generated on 2023-07-23 15:03:22 -0400. Do not edit! */
2 /* begin file src/ada.cpp */
3 #include "ada.h"
4 /* begin file src/checkers.cpp */
5 #include <algorithm>
6
7 namespace ada::checkers {
8
is_ipv4(std::string_view view)9 ada_really_inline ada_constexpr bool is_ipv4(std::string_view view) noexcept {
10 size_t last_dot = view.rfind('.');
11 if (last_dot == view.size() - 1) {
12 view.remove_suffix(1);
13 last_dot = view.rfind('.');
14 }
15 std::string_view number =
16 (last_dot == std::string_view::npos) ? view : view.substr(last_dot + 1);
17 if (number.empty()) {
18 return false;
19 }
20 /** Optimization opportunity: we have basically identified the last number of
21 the ipv4 if we return true here. We might as well parse it and have at
22 least one number parsed when we get to parse_ipv4. */
23 if (std::all_of(number.begin(), number.end(), ada::checkers::is_digit)) {
24 return true;
25 }
26 return (checkers::has_hex_prefix(number) &&
27 std::all_of(number.begin() + 2, number.end(),
28 ada::unicode::is_lowercase_hex));
29 }
30
31 // for use with path_signature, we include all characters that need percent
32 // encoding.
33 static constexpr uint8_t path_signature_table[256] = {
34 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
35 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
38 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
40 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
41 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
42 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
43 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
44 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
45 static_assert(path_signature_table[uint8_t('?')] == 1);
46 static_assert(path_signature_table[uint8_t('`')] == 1);
47 static_assert(path_signature_table[uint8_t('{')] == 1);
48 static_assert(path_signature_table[uint8_t('}')] == 1);
49 //
50 static_assert(path_signature_table[uint8_t(' ')] == 1);
51 static_assert(path_signature_table[uint8_t('?')] == 1);
52 static_assert(path_signature_table[uint8_t('"')] == 1);
53 static_assert(path_signature_table[uint8_t('#')] == 1);
54 static_assert(path_signature_table[uint8_t('<')] == 1);
55 static_assert(path_signature_table[uint8_t('>')] == 1);
56 static_assert(path_signature_table[uint8_t('\\')] == 2);
57 static_assert(path_signature_table[uint8_t('.')] == 4);
58 static_assert(path_signature_table[uint8_t('%')] == 8);
59
60 //
61 static_assert(path_signature_table[0] == 1);
62 static_assert(path_signature_table[31] == 1);
63 static_assert(path_signature_table[127] == 1);
64 static_assert(path_signature_table[128] == 1);
65 static_assert(path_signature_table[255] == 1);
66
path_signature(std::string_view input)67 ada_really_inline constexpr uint8_t path_signature(
68 std::string_view input) noexcept {
69 // The path percent-encode set is the query percent-encode set and U+003F (?),
70 // U+0060 (`), U+007B ({), and U+007D (}). The query percent-encode set is the
71 // C0 control percent-encode set and U+0020 SPACE, U+0022 ("), U+0023 (#),
72 // U+003C (<), and U+003E (>). The C0 control percent-encode set are the C0
73 // controls and all code points greater than U+007E (~).
74 size_t i = 0;
75 uint8_t accumulator{};
76 for (; i + 7 < input.size(); i += 8) {
77 accumulator |= uint8_t(path_signature_table[uint8_t(input[i])] |
78 path_signature_table[uint8_t(input[i + 1])] |
79 path_signature_table[uint8_t(input[i + 2])] |
80 path_signature_table[uint8_t(input[i + 3])] |
81 path_signature_table[uint8_t(input[i + 4])] |
82 path_signature_table[uint8_t(input[i + 5])] |
83 path_signature_table[uint8_t(input[i + 6])] |
84 path_signature_table[uint8_t(input[i + 7])]);
85 }
86 for (; i < input.size(); i++) {
87 accumulator |= uint8_t(path_signature_table[uint8_t(input[i])]);
88 }
89 return accumulator;
90 }
91
verify_dns_length(std::string_view input)92 ada_really_inline constexpr bool verify_dns_length(
93 std::string_view input) noexcept {
94 if (input.back() == '.') {
95 if (input.size() > 254) return false;
96 } else if (input.size() > 253)
97 return false;
98
99 size_t start = 0;
100 while (start < input.size()) {
101 auto dot_location = input.find('.', start);
102 // If not found, it's likely the end of the domain
103 if (dot_location == std::string_view::npos) dot_location = input.size();
104
105 auto label_size = dot_location - start;
106 if (label_size > 63 || label_size == 0) return false;
107
108 start = dot_location + 1;
109 }
110
111 return true;
112 }
113 } // namespace ada::checkers
114 /* end file src/checkers.cpp */
115 /* begin file src/unicode.cpp */
116
117 ADA_PUSH_DISABLE_ALL_WARNINGS
118 /* begin file src/ada_idna.cpp */
119 /* auto-generated on 2023-05-07 19:12:14 -0400. Do not edit! */
120 /* begin file src/idna.cpp */
121 /* begin file src/unicode_transcoding.cpp */
122
123 #include <cstdint>
124 #include <cstring>
125
126 namespace ada::idna {
127
utf8_to_utf32(const char * buf,size_t len,char32_t * utf32_output)128 size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output) {
129 const uint8_t* data = reinterpret_cast<const uint8_t*>(buf);
130 size_t pos = 0;
131 char32_t* start{utf32_output};
132 while (pos < len) {
133 // try to convert the next block of 16 ASCII bytes
134 if (pos + 16 <= len) { // if it is safe to read 16 more
135 // bytes, check that they are ascii
136 uint64_t v1;
137 std::memcpy(&v1, data + pos, sizeof(uint64_t));
138 uint64_t v2;
139 std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
140 uint64_t v{v1 | v2};
141 if ((v & 0x8080808080808080) == 0) {
142 size_t final_pos = pos + 16;
143 while (pos < final_pos) {
144 *utf32_output++ = char32_t(buf[pos]);
145 pos++;
146 }
147 continue;
148 }
149 }
150 uint8_t leading_byte = data[pos]; // leading byte
151 if (leading_byte < 0b10000000) {
152 // converting one ASCII byte !!!
153 *utf32_output++ = char32_t(leading_byte);
154 pos++;
155 } else if ((leading_byte & 0b11100000) == 0b11000000) {
156 // We have a two-byte UTF-8
157 if (pos + 1 >= len) {
158 return 0;
159 } // minimal bound checking
160 if ((data[pos + 1] & 0b11000000) != 0b10000000) {
161 return 0;
162 }
163 // range check
164 uint32_t code_point =
165 (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111);
166 if (code_point < 0x80 || 0x7ff < code_point) {
167 return 0;
168 }
169 *utf32_output++ = char32_t(code_point);
170 pos += 2;
171 } else if ((leading_byte & 0b11110000) == 0b11100000) {
172 // We have a three-byte UTF-8
173 if (pos + 2 >= len) {
174 return 0;
175 } // minimal bound checking
176
177 if ((data[pos + 1] & 0b11000000) != 0b10000000) {
178 return 0;
179 }
180 if ((data[pos + 2] & 0b11000000) != 0b10000000) {
181 return 0;
182 }
183 // range check
184 uint32_t code_point = (leading_byte & 0b00001111) << 12 |
185 (data[pos + 1] & 0b00111111) << 6 |
186 (data[pos + 2] & 0b00111111);
187 if (code_point < 0x800 || 0xffff < code_point ||
188 (0xd7ff < code_point && code_point < 0xe000)) {
189 return 0;
190 }
191 *utf32_output++ = char32_t(code_point);
192 pos += 3;
193 } else if ((leading_byte & 0b11111000) == 0b11110000) { // 0b11110000
194 // we have a 4-byte UTF-8 word.
195 if (pos + 3 >= len) {
196 return 0;
197 } // minimal bound checking
198 if ((data[pos + 1] & 0b11000000) != 0b10000000) {
199 return 0;
200 }
201 if ((data[pos + 2] & 0b11000000) != 0b10000000) {
202 return 0;
203 }
204 if ((data[pos + 3] & 0b11000000) != 0b10000000) {
205 return 0;
206 }
207
208 // range check
209 uint32_t code_point = (leading_byte & 0b00000111) << 18 |
210 (data[pos + 1] & 0b00111111) << 12 |
211 (data[pos + 2] & 0b00111111) << 6 |
212 (data[pos + 3] & 0b00111111);
213 if (code_point <= 0xffff || 0x10ffff < code_point) {
214 return 0;
215 }
216 *utf32_output++ = char32_t(code_point);
217 pos += 4;
218 } else {
219 return 0;
220 }
221 }
222 return utf32_output - start;
223 }
224
utf8_length_from_utf32(const char32_t * buf,size_t len)225 size_t utf8_length_from_utf32(const char32_t* buf, size_t len) {
226 // We are not BOM aware.
227 const uint32_t* p = reinterpret_cast<const uint32_t*>(buf);
228 size_t counter{0};
229 for (size_t i = 0; i < len; i++) {
230 /** ASCII **/
231 if (p[i] <= 0x7F) {
232 counter++;
233 }
234 /** two-byte **/
235 else if (p[i] <= 0x7FF) {
236 counter += 2;
237 }
238 /** three-byte **/
239 else if (p[i] <= 0xFFFF) {
240 counter += 3;
241 }
242 /** four-bytes **/
243 else {
244 counter += 4;
245 }
246 }
247 return counter;
248 }
249
utf32_length_from_utf8(const char * buf,size_t len)250 size_t utf32_length_from_utf8(const char* buf, size_t len) {
251 const int8_t* p = reinterpret_cast<const int8_t*>(buf);
252 size_t counter{0};
253 for (size_t i = 0; i < len; i++) {
254 // -65 is 0b10111111, anything larger in two-complement's
255 // should start a new code point.
256 if (p[i] > -65) {
257 counter++;
258 }
259 }
260 return counter;
261 }
262
utf32_to_utf8(const char32_t * buf,size_t len,char * utf8_output)263 size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) {
264 const uint32_t* data = reinterpret_cast<const uint32_t*>(buf);
265 size_t pos = 0;
266 char* start{utf8_output};
267 while (pos < len) {
268 // try to convert the next block of 2 ASCII characters
269 if (pos + 2 <= len) { // if it is safe to read 8 more
270 // bytes, check that they are ascii
271 uint64_t v;
272 std::memcpy(&v, data + pos, sizeof(uint64_t));
273 if ((v & 0xFFFFFF80FFFFFF80) == 0) {
274 *utf8_output++ = char(buf[pos]);
275 *utf8_output++ = char(buf[pos + 1]);
276 pos += 2;
277 continue;
278 }
279 }
280 uint32_t word = data[pos];
281 if ((word & 0xFFFFFF80) == 0) {
282 // will generate one UTF-8 bytes
283 *utf8_output++ = char(word);
284 pos++;
285 } else if ((word & 0xFFFFF800) == 0) {
286 // will generate two UTF-8 bytes
287 // we have 0b110XXXXX 0b10XXXXXX
288 *utf8_output++ = char((word >> 6) | 0b11000000);
289 *utf8_output++ = char((word & 0b111111) | 0b10000000);
290 pos++;
291 } else if ((word & 0xFFFF0000) == 0) {
292 // will generate three UTF-8 bytes
293 // we have 0b1110XXXX 0b10XXXXXX 0b10XXXXXX
294 if (word >= 0xD800 && word <= 0xDFFF) {
295 return 0;
296 }
297 *utf8_output++ = char((word >> 12) | 0b11100000);
298 *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
299 *utf8_output++ = char((word & 0b111111) | 0b10000000);
300 pos++;
301 } else {
302 // will generate four UTF-8 bytes
303 // we have 0b11110XXX 0b10XXXXXX 0b10XXXXXX
304 // 0b10XXXXXX
305 if (word > 0x10FFFF) {
306 return 0;
307 }
308 *utf8_output++ = char((word >> 18) | 0b11110000);
309 *utf8_output++ = char(((word >> 12) & 0b111111) | 0b10000000);
310 *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
311 *utf8_output++ = char((word & 0b111111) | 0b10000000);
312 pos++;
313 }
314 }
315 return utf8_output - start;
316 }
317 } // namespace ada::idna
318 /* end file src/unicode_transcoding.cpp */
319 /* begin file src/mapping.cpp */
320
321 #include <algorithm>
322 #include <array>
323 #include <string>
324
325 /* begin file src/mapping_tables.cpp */
326 // IDNA 15.0.0
327
328 // clang-format off
329 #ifndef ADA_IDNA_TABLES_H
330 #define ADA_IDNA_TABLES_H
331 #include <cstdint>
332
333 namespace ada::idna {
334
335 const uint32_t mappings[5164] =
336 {
337 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
338 114, 115, 116, 117, 118, 119, 120, 121, 122, 32, 32, 776, 32, 772, 50, 51, 32, 769,
339 956, 32, 807, 49, 49, 8260, 52, 49, 8260, 50, 51, 8260, 52, 224, 225, 226, 227,
340 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243,
341 244, 245, 246, 248, 249, 250, 251, 252, 253, 254, 257, 259, 261, 263, 265, 267,
342 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299,
343 301, 303, 105, 775, 309, 311, 314, 316, 318, 108, 183, 322, 324, 326, 328, 700,
344 110, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359,
345 361, 363, 365, 367, 369, 371, 373, 375, 255, 378, 380, 382, 595, 387, 389, 596,
346 392, 598, 599, 396, 477, 601, 603, 402, 608, 611, 617, 616, 409, 623, 626, 629,
347 417, 419, 421, 640, 424, 643, 429, 648, 432, 650, 651, 436, 438, 658, 441, 445,
348 100, 382, 108, 106, 110, 106, 462, 464, 466, 468, 470, 472, 474, 476, 479, 481,
349 483, 485, 487, 489, 491, 493, 495, 100, 122, 501, 405, 447, 505, 507, 509, 511,
350 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, 537, 539, 541, 543,
351 414, 547, 549, 551, 553, 555, 557, 559, 561, 563, 11365, 572, 410, 11366, 578, 384,
352 649, 652, 583, 585, 587, 589, 591, 614, 633, 635, 641, 32, 774, 32, 775, 32, 778,
353 32, 808, 32, 771, 32, 779, 661, 768, 787, 776, 769, 953, 881, 883, 697, 887, 32,
354 953, 59, 1011, 32, 776, 769, 940, 941, 942, 943, 972, 973, 974, 945, 946, 947, 948,
355 949, 950, 951, 952, 954, 955, 957, 958, 959, 960, 961, 963, 964, 965, 966, 967,
356 968, 969, 970, 971, 983, 985, 987, 989, 991, 993, 995, 997, 999, 1001, 1003, 1005,
357 1007, 1016, 1019, 891, 892, 893, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111,
358 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1072, 1073, 1074, 1075, 1076, 1077,
359 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091,
360 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1121, 1123,
361 1125, 1127, 1129, 1131, 1133, 1135, 1137, 1139, 1141, 1143, 1145, 1147, 1149, 1151,
362 1153, 1163, 1165, 1167, 1169, 1171, 1173, 1175, 1177, 1179, 1181, 1183, 1185, 1187,
363 1189, 1191, 1193, 1195, 1197, 1199, 1201, 1203, 1205, 1207, 1209, 1211, 1213, 1215,
364 1218, 1220, 1222, 1224, 1226, 1228, 1230, 1233, 1235, 1237, 1239, 1241, 1243, 1245,
365 1247, 1249, 1251, 1253, 1255, 1257, 1259, 1261, 1263, 1265, 1267, 1269, 1271, 1273,
366 1275, 1277, 1279, 1281, 1283, 1285, 1287, 1289, 1291, 1293, 1295, 1297, 1299, 1301,
367 1303, 1305, 1307, 1309, 1311, 1313, 1315, 1317, 1319, 1321, 1323, 1325, 1327, 1377,
368 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391,
369 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405,
370 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1381, 1410, 1575, 1652, 1608,
371 1652, 1735, 1652, 1610, 1652, 2325, 2364, 2326, 2364, 2327, 2364, 2332, 2364, 2337,
372 2364, 2338, 2364, 2347, 2364, 2351, 2364, 2465, 2492, 2466, 2492, 2479, 2492, 2610,
373 2620, 2616, 2620, 2582, 2620, 2583, 2620, 2588, 2620, 2603, 2620, 2849, 2876, 2850,
374 2876, 3661, 3634, 3789, 3762, 3755, 3737, 3755, 3745, 3851, 3906, 4023, 3916, 4023,
375 3921, 4023, 3926, 4023, 3931, 4023, 3904, 4021, 3953, 3954, 3953, 3956, 4018, 3968,
376 4018, 3953, 3968, 4019, 3968, 4019, 3953, 3968, 3986, 4023, 3996, 4023, 4001, 4023,
377 4006, 4023, 4011, 4023, 3984, 4021, 11559, 11565, 4316, 5104, 5105, 5106, 5107,
378 5108, 5109, 42571, 4304, 4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314,
379 4315, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329,
380 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343,
381 4344, 4345, 4346, 4349, 4350, 4351, 592, 593, 7426, 604, 7446, 7447, 7453, 7461,
382 594, 597, 607, 609, 613, 618, 7547, 669, 621, 7557, 671, 625, 624, 627, 628, 632,
383 642, 427, 7452, 656, 657, 7681, 7683, 7685, 7687, 7689, 7691, 7693, 7695, 7697,
384 7699, 7701, 7703, 7705, 7707, 7709, 7711, 7713, 7715, 7717, 7719, 7721, 7723, 7725,
385 7727, 7729, 7731, 7733, 7735, 7737, 7739, 7741, 7743, 7745, 7747, 7749, 7751, 7753,
386 7755, 7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771, 7773, 7775, 7777, 7779, 7781,
387 7783, 7785, 7787, 7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803, 7805, 7807, 7809,
388 7811, 7813, 7815, 7817, 7819, 7821, 7823, 7825, 7827, 7829, 97, 702, 115, 115, 7841,
389 7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857, 7859, 7861, 7863, 7865, 7867, 7869,
390 7871, 7873, 7875, 7877, 7879, 7881, 7883, 7885, 7887, 7889, 7891, 7893, 7895, 7897,
391 7899, 7901, 7903, 7905, 7907, 7909, 7911, 7913, 7915, 7917, 7919, 7921, 7923, 7925,
392 7927, 7929, 7931, 7933, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7952,
393 7953, 7954, 7955, 7956, 7957, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7984,
394 7985, 7986, 7987, 7988, 7989, 7990, 7991, 8000, 8001, 8002, 8003, 8004, 8005, 8017,
395 8019, 8021, 8023, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 7936, 953, 7937,
396 953, 7938, 953, 7939, 953, 7940, 953, 7941, 953, 7942, 953, 7943, 953, 7968, 953,
397 7969, 953, 7970, 953, 7971, 953, 7972, 953, 7973, 953, 7974, 953, 7975, 953, 8032,
398 953, 8033, 953, 8034, 953, 8035, 953, 8036, 953, 8037, 953, 8038, 953, 8039, 953,
399 8048, 953, 945, 953, 940, 953, 8118, 953, 8112, 8113, 32, 787, 32, 834, 32, 776,
400 834, 8052, 953, 951, 953, 942, 953, 8134, 953, 8050, 32, 787, 768, 32, 787, 769,
401 32, 787, 834, 912, 8144, 8145, 8054, 32, 788, 768, 32, 788, 769, 32, 788, 834, 944,
402 8160, 8161, 8058, 8165, 32, 776, 768, 96, 8060, 953, 969, 953, 974, 953, 8182, 953,
403 8056, 8208, 32, 819, 8242, 8242, 8242, 8242, 8242, 8245, 8245, 8245, 8245, 8245,
404 33, 33, 32, 773, 63, 63, 63, 33, 33, 63, 48, 53, 54, 55, 56, 57, 43, 8722, 61, 40,
405 41, 97, 47, 99, 97, 47, 115, 176, 99, 99, 47, 111, 99, 47, 117, 176, 102, 115, 109,
406 116, 101, 108, 116, 109, 1488, 1489, 1490, 1491, 102, 97, 120, 8721, 49, 8260, 55,
407 49, 8260, 57, 49, 8260, 49, 48, 49, 8260, 51, 50, 8260, 51, 49, 8260, 53, 50, 8260,
408 53, 51, 8260, 53, 52, 8260, 53, 49, 8260, 54, 53, 8260, 54, 49, 8260, 56, 51, 8260,
409 56, 53, 8260, 56, 55, 8260, 56, 105, 105, 105, 105, 105, 105, 118, 118, 105, 118,
410 105, 105, 118, 105, 105, 105, 105, 120, 120, 105, 120, 105, 105, 48, 8260, 51, 8747,
411 8747, 8747, 8747, 8747, 8750, 8750, 8750, 8750, 8750, 12296, 12297, 49, 50, 49,
412 51, 49, 52, 49, 53, 49, 54, 49, 55, 49, 56, 49, 57, 50, 48, 40, 49, 41, 40, 50,
413 41, 40, 51, 41, 40, 52, 41, 40, 53, 41, 40, 54, 41, 40, 55, 41, 40, 56, 41, 40,
414 57, 41, 40, 49, 48, 41, 40, 49, 49, 41, 40, 49, 50, 41, 40, 49, 51, 41, 40, 49,
415 52, 41, 40, 49, 53, 41, 40, 49, 54, 41, 40, 49, 55, 41, 40, 49, 56, 41, 40, 49,
416 57, 41, 40, 50, 48, 41, 40, 97, 41, 40, 98, 41, 40, 99, 41, 40, 100, 41, 40, 101,
417 41, 40, 102, 41, 40, 103, 41, 40, 104, 41, 40, 105, 41, 40, 106, 41, 40, 107, 41,
418 40, 108, 41, 40, 109, 41, 40, 110, 41, 40, 111, 41, 40, 112, 41, 40, 113, 41, 40,
419 114, 41, 40, 115, 41, 40, 116, 41, 40, 117, 41, 40, 118, 41, 40, 119, 41, 40, 120,
420 41, 40, 121, 41, 40, 122, 41, 58, 58, 61, 61, 61, 10973, 824, 11312, 11313, 11314,
421 11315, 11316, 11317, 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 11326,
422 11327, 11328, 11329, 11330, 11331, 11332, 11333, 11334, 11335, 11336, 11337, 11338,
423 11339, 11340, 11341, 11342, 11343, 11344, 11345, 11346, 11347, 11348, 11349, 11350,
424 11351, 11352, 11353, 11354, 11355, 11356, 11357, 11358, 11359, 11361, 619, 7549,
425 637, 11368, 11370, 11372, 11379, 11382, 575, 576, 11393, 11395, 11397, 11399, 11401,
426 11403, 11405, 11407, 11409, 11411, 11413, 11415, 11417, 11419, 11421, 11423, 11425,
427 11427, 11429, 11431, 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449,
428 11451, 11453, 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, 11473,
429 11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, 11500, 11502, 11507,
430 11617, 27597, 40863, 19968, 20008, 20022, 20031, 20057, 20101, 20108, 20128, 20154,
431 20799, 20837, 20843, 20866, 20886, 20907, 20960, 20981, 20992, 21147, 21241, 21269,
432 21274, 21304, 21313, 21340, 21353, 21378, 21430, 21448, 21475, 22231, 22303, 22763,
433 22786, 22794, 22805, 22823, 22899, 23376, 23424, 23544, 23567, 23586, 23608, 23662,
434 23665, 24027, 24037, 24049, 24062, 24178, 24186, 24191, 24308, 24318, 24331, 24339,
435 24400, 24417, 24435, 24515, 25096, 25142, 25163, 25903, 25908, 25991, 26007, 26020,
436 26041, 26080, 26085, 26352, 26376, 26408, 27424, 27490, 27513, 27571, 27595, 27604,
437 27611, 27663, 27668, 27700, 28779, 29226, 29238, 29243, 29247, 29255, 29273, 29275,
438 29356, 29572, 29577, 29916, 29926, 29976, 29983, 29992, 30000, 30091, 30098, 30326,
439 30333, 30382, 30399, 30446, 30683, 30690, 30707, 31034, 31160, 31166, 31348, 31435,
440 31481, 31859, 31992, 32566, 32593, 32650, 32701, 32769, 32780, 32786, 32819, 32895,
441 32905, 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390, 33394, 33400, 34381,
442 34411, 34880, 34892, 34915, 35198, 35211, 35282, 35328, 35895, 35910, 35925, 35960,
443 35997, 36196, 36208, 36275, 36523, 36554, 36763, 36784, 36789, 37009, 37193, 37318,
444 37324, 37329, 38263, 38272, 38428, 38582, 38585, 38632, 38737, 38750, 38754, 38761,
445 38859, 38893, 38899, 38913, 39080, 39131, 39135, 39318, 39321, 39340, 39592, 39640,
446 39647, 39717, 39727, 39730, 39740, 39770, 40165, 40565, 40575, 40613, 40635, 40643,
447 40653, 40657, 40697, 40701, 40718, 40723, 40736, 40763, 40778, 40786, 40845, 40860,
448 40864, 46, 12306, 21316, 21317, 32, 12441, 32, 12442, 12424, 12426, 12467, 12488,
449 4352, 4353, 4522, 4354, 4524, 4525, 4355, 4356, 4357, 4528, 4529, 4530, 4531, 4532,
450 4533, 4378, 4358, 4359, 4360, 4385, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368,
451 4369, 4370, 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460,
452 4461, 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469, 4372, 4373, 4551, 4552, 4556,
453 4558, 4563, 4567, 4569, 4380, 4573, 4575, 4381, 4382, 4384, 4386, 4387, 4391, 4393,
454 4395, 4396, 4397, 4398, 4399, 4402, 4406, 4416, 4423, 4428, 4593, 4594, 4439, 4440,
455 4441, 4484, 4485, 4488, 4497, 4498, 4500, 4510, 4513, 19977, 22235, 19978, 20013,
456 19979, 30002, 19993, 19969, 22825, 22320, 40, 4352, 41, 40, 4354, 41, 40, 4355,
457 41, 40, 4357, 41, 40, 4358, 41, 40, 4359, 41, 40, 4361, 41, 40, 4363, 41, 40, 4364,
458 41, 40, 4366, 41, 40, 4367, 41, 40, 4368, 41, 40, 4369, 41, 40, 4370, 41, 40, 44032,
459 41, 40, 45208, 41, 40, 45796, 41, 40, 46972, 41, 40, 47560, 41, 40, 48148, 41, 40,
460 49324, 41, 40, 50500, 41, 40, 51088, 41, 40, 52264, 41, 40, 52852, 41, 40, 53440,
461 41, 40, 54028, 41, 40, 54616, 41, 40, 51452, 41, 40, 50724, 51204, 41, 40, 50724,
462 54980, 41, 40, 19968, 41, 40, 20108, 41, 40, 19977, 41, 40, 22235, 41, 40, 20116,
463 41, 40, 20845, 41, 40, 19971, 41, 40, 20843, 41, 40, 20061, 41, 40, 21313, 41, 40,
464 26376, 41, 40, 28779, 41, 40, 27700, 41, 40, 26408, 41, 40, 37329, 41, 40, 22303,
465 41, 40, 26085, 41, 40, 26666, 41, 40, 26377, 41, 40, 31038, 41, 40, 21517, 41, 40,
466 29305, 41, 40, 36001, 41, 40, 31069, 41, 40, 21172, 41, 40, 20195, 41, 40, 21628,
467 41, 40, 23398, 41, 40, 30435, 41, 40, 20225, 41, 40, 36039, 41, 40, 21332, 41, 40,
468 31085, 41, 40, 20241, 41, 40, 33258, 41, 40, 33267, 41, 21839, 24188, 31631, 112,
469 116, 101, 50, 50, 50, 52, 50, 53, 50, 54, 50, 55, 50, 56, 50, 57, 51, 48, 51, 51,
470 51, 52, 51, 53, 52280, 44256, 51452, 51032, 50864, 31192, 30007, 36969, 20778, 21360,
471 27880, 38917, 20889, 27491, 24038, 21491, 21307, 23447, 22812, 51, 54, 51, 55, 51,
472 56, 51, 57, 52, 48, 52, 52, 52, 53, 52, 54, 52, 55, 52, 56, 52, 57, 53, 48, 49,
473 26376, 50, 26376, 51, 26376, 52, 26376, 53, 26376, 54, 26376, 55, 26376, 56, 26376,
474 57, 26376, 49, 48, 26376, 49, 49, 26376, 49, 50, 26376, 104, 103, 101, 114, 103,
475 101, 118, 108, 116, 100, 12450, 12452, 12454, 12456, 12458, 12459, 12461, 12463,
476 12465, 12469, 12471, 12473, 12475, 12477, 12479, 12481, 12484, 12486, 12490, 12491,
477 12492, 12493, 12494, 12495, 12498, 12501, 12504, 12507, 12510, 12511, 12512, 12513,
478 12514, 12516, 12518, 12520, 12521, 12522, 12523, 12524, 12525, 12527, 12528, 12529,
479 12530, 20196, 21644, 12450, 12497, 12540, 12488, 12450, 12523, 12501, 12449, 12450,
480 12531, 12506, 12450, 12450, 12540, 12523, 12452, 12491, 12531, 12464, 12452, 12531,
481 12481, 12454, 12457, 12531, 12456, 12473, 12463, 12540, 12489, 12456, 12540, 12459,
482 12540, 12458, 12531, 12473, 12458, 12540, 12512, 12459, 12452, 12522, 12459, 12521,
483 12483, 12488, 12459, 12525, 12522, 12540, 12460, 12525, 12531, 12460, 12531, 12510,
484 12462, 12460, 12462, 12491, 12540, 12461, 12517, 12522, 12540, 12462, 12523, 12480,
485 12540, 12461, 12525, 12461, 12525, 12464, 12521, 12512, 12461, 12525, 12513, 12540,
486 12488, 12523, 12461, 12525, 12527, 12483, 12488, 12464, 12521, 12512, 12488, 12531,
487 12463, 12523, 12476, 12452, 12525, 12463, 12525, 12540, 12493, 12465, 12540, 12473,
488 12467, 12523, 12490, 12467, 12540, 12509, 12469, 12452, 12463, 12523, 12469, 12531,
489 12481, 12540, 12512, 12471, 12522, 12531, 12464, 12475, 12531, 12481, 12475, 12531,
490 12488, 12480, 12540, 12473, 12487, 12471, 12489, 12523, 12490, 12494, 12494, 12483,
491 12488, 12495, 12452, 12484, 12497, 12540, 12475, 12531, 12488, 12497, 12540, 12484,
492 12496, 12540, 12524, 12523, 12500, 12450, 12473, 12488, 12523, 12500, 12463, 12523,
493 12500, 12467, 12499, 12523, 12501, 12449, 12521, 12483, 12489, 12501, 12451, 12540,
494 12488, 12502, 12483, 12471, 12455, 12523, 12501, 12521, 12531, 12504, 12463, 12479,
495 12540, 12523, 12506, 12477, 12506, 12491, 12498, 12504, 12523, 12484, 12506, 12531,
496 12473, 12506, 12540, 12472, 12505, 12540, 12479, 12509, 12452, 12531, 12488, 12508,
497 12523, 12488, 12507, 12531, 12509, 12531, 12489, 12507, 12540, 12523, 12507, 12540,
498 12531, 12510, 12452, 12463, 12525, 12510, 12452, 12523, 12510, 12483, 12495, 12510,
499 12523, 12463, 12510, 12531, 12471, 12519, 12531, 12511, 12463, 12525, 12531, 12511,
500 12522, 12511, 12522, 12496, 12540, 12523, 12513, 12460, 12513, 12460, 12488, 12531,
501 12516, 12540, 12489, 12516, 12540, 12523, 12518, 12450, 12531, 12522, 12483, 12488,
502 12523, 12522, 12521, 12523, 12500, 12540, 12523, 12540, 12502, 12523, 12524, 12512,
503 12524, 12531, 12488, 12466, 12531, 48, 28857, 49, 28857, 50, 28857, 51, 28857, 52,
504 28857, 53, 28857, 54, 28857, 55, 28857, 56, 28857, 57, 28857, 49, 48, 28857, 49,
505 49, 28857, 49, 50, 28857, 49, 51, 28857, 49, 52, 28857, 49, 53, 28857, 49, 54, 28857,
506 49, 55, 28857, 49, 56, 28857, 49, 57, 28857, 50, 48, 28857, 50, 49, 28857, 50, 50,
507 28857, 50, 51, 28857, 50, 52, 28857, 104, 112, 97, 100, 97, 97, 117, 98, 97, 114,
508 111, 118, 112, 99, 100, 109, 100, 109, 50, 100, 109, 51, 105, 117, 24179, 25104,
509 26157, 21644, 22823, 27491, 26126, 27835, 26666, 24335, 20250, 31038, 110, 97, 956,
510 97, 109, 97, 107, 97, 107, 98, 109, 98, 103, 98, 99, 97, 108, 107, 99, 97, 108,
511 112, 102, 110, 102, 956, 102, 956, 103, 109, 103, 107, 103, 104, 122, 107, 104,
512 122, 109, 104, 122, 116, 104, 122, 956, 108, 109, 108, 100, 108, 102, 109, 110,
513 109, 956, 109, 109, 109, 99, 109, 107, 109, 109, 109, 50, 99, 109, 50, 107, 109,
514 50, 109, 109, 51, 99, 109, 51, 107, 109, 51, 109, 8725, 115, 109, 8725, 115, 50,
515 107, 112, 97, 109, 112, 97, 103, 112, 97, 114, 97, 100, 114, 97, 100, 8725, 115,
516 114, 97, 100, 8725, 115, 50, 112, 115, 110, 115, 956, 115, 109, 115, 112, 118, 110,
517 118, 956, 118, 109, 118, 107, 118, 112, 119, 110, 119, 956, 119, 109, 119, 107,
518 119, 107, 969, 109, 969, 98, 113, 99, 8725, 107, 103, 100, 98, 103, 121, 104, 97,
519 105, 110, 107, 107, 107, 116, 108, 110, 108, 111, 103, 108, 120, 109, 105, 108,
520 109, 111, 108, 112, 104, 112, 112, 109, 112, 114, 115, 118, 119, 98, 118, 8725,
521 109, 97, 8725, 109, 49, 26085, 50, 26085, 51, 26085, 52, 26085, 53, 26085, 54, 26085,
522 55, 26085, 56, 26085, 57, 26085, 49, 48, 26085, 49, 49, 26085, 49, 50, 26085, 49,
523 51, 26085, 49, 52, 26085, 49, 53, 26085, 49, 54, 26085, 49, 55, 26085, 49, 56, 26085,
524 49, 57, 26085, 50, 48, 26085, 50, 49, 26085, 50, 50, 26085, 50, 51, 26085, 50, 52,
525 26085, 50, 53, 26085, 50, 54, 26085, 50, 55, 26085, 50, 56, 26085, 50, 57, 26085,
526 51, 48, 26085, 51, 49, 26085, 103, 97, 108, 42561, 42563, 42565, 42567, 42569, 42573,
527 42575, 42577, 42579, 42581, 42583, 42585, 42587, 42589, 42591, 42593, 42595, 42597,
528 42599, 42601, 42603, 42605, 42625, 42627, 42629, 42631, 42633, 42635, 42637, 42639,
529 42641, 42643, 42645, 42647, 42649, 42651, 42787, 42789, 42791, 42793, 42795, 42797,
530 42799, 42803, 42805, 42807, 42809, 42811, 42813, 42815, 42817, 42819, 42821, 42823,
531 42825, 42827, 42829, 42831, 42833, 42835, 42837, 42839, 42841, 42843, 42845, 42847,
532 42849, 42851, 42853, 42855, 42857, 42859, 42861, 42863, 42874, 42876, 7545, 42879,
533 42881, 42883, 42885, 42887, 42892, 42897, 42899, 42903, 42905, 42907, 42909, 42911,
534 42913, 42915, 42917, 42919, 42921, 620, 670, 647, 43859, 42933, 42935, 42937, 42939,
535 42941, 42943, 42945, 42947, 42900, 7566, 42952, 42954, 42961, 42967, 42969, 42998,
536 43831, 43858, 653, 5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, 5033, 5034,
537 5035, 5036, 5037, 5038, 5039, 5040, 5041, 5042, 5043, 5044, 5045, 5046, 5047, 5048,
538 5049, 5050, 5051, 5052, 5053, 5054, 5055, 5056, 5057, 5058, 5059, 5060, 5061, 5062,
539 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, 5074, 5075, 5076,
540 5077, 5078, 5079, 5080, 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, 5089, 5090,
541 5091, 5092, 5093, 5094, 5095, 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, 35912,
542 26356, 36040, 28369, 20018, 21477, 22865, 21895, 22856, 25078, 30313, 32645, 34367,
543 34746, 35064, 37007, 27138, 27931, 28889, 29662, 33853, 37226, 39409, 20098, 21365,
544 27396, 29211, 34349, 40478, 23888, 28651, 34253, 35172, 25289, 33240, 34847, 24266,
545 26391, 28010, 29436, 37070, 20358, 20919, 21214, 25796, 27347, 29200, 30439, 34310,
546 34396, 36335, 38706, 39791, 40442, 30860, 31103, 32160, 33737, 37636, 35542, 22751,
547 24324, 31840, 32894, 29282, 30922, 36034, 38647, 22744, 23650, 27155, 28122, 28431,
548 32047, 32311, 38475, 21202, 32907, 20956, 20940, 31260, 32190, 33777, 38517, 35712,
549 25295, 35582, 20025, 23527, 24594, 29575, 30064, 21271, 30971, 20415, 24489, 19981,
550 27852, 25976, 32034, 21443, 22622, 30465, 33865, 35498, 27578, 27784, 25342, 33509,
551 25504, 30053, 20142, 20841, 20937, 26753, 31975, 33391, 35538, 37327, 21237, 21570,
552 24300, 26053, 28670, 31018, 38317, 39530, 40599, 40654, 26310, 27511, 36706, 24180,
553 24976, 25088, 25754, 28451, 29001, 29833, 31178, 32244, 32879, 36646, 34030, 36899,
554 37706, 21015, 21155, 21693, 28872, 35010, 24265, 24565, 25467, 27566, 31806, 29557,
555 22265, 23994, 24604, 29618, 29801, 32666, 32838, 37428, 38646, 38728, 38936, 20363,
556 31150, 37300, 38584, 24801, 20102, 20698, 23534, 23615, 26009, 29134, 30274, 34044,
557 36988, 26248, 38446, 21129, 26491, 26611, 27969, 28316, 29705, 30041, 30827, 32016,
558 39006, 25134, 38520, 20523, 23833, 28138, 36650, 24459, 24900, 26647, 38534, 21033,
559 21519, 23653, 26131, 26446, 26792, 27877, 29702, 30178, 32633, 35023, 35041, 38626,
560 21311, 28346, 21533, 29136, 29848, 34298, 38563, 40023, 40607, 26519, 28107, 33256,
561 31520, 31890, 29376, 28825, 35672, 20160, 33590, 21050, 20999, 24230, 25299, 31958,
562 23429, 27934, 26292, 36667, 38477, 24275, 20800, 21952, 22618, 26228, 20958, 29482,
563 30410, 31036, 31070, 31077, 31119, 38742, 31934, 34322, 35576, 36920, 37117, 39151,
564 39164, 39208, 40372, 37086, 38583, 20398, 20711, 20813, 21193, 21220, 21329, 21917,
565 22022, 22120, 22592, 22696, 23652, 24724, 24936, 24974, 25074, 25935, 26082, 26257,
566 26757, 28023, 28186, 28450, 29038, 29227, 29730, 30865, 31049, 31048, 31056, 31062,
567 31117, 31118, 31296, 31361, 31680, 32265, 32321, 32626, 32773, 33261, 33401, 33879,
568 35088, 35222, 35585, 35641, 36051, 36104, 36790, 38627, 38911, 38971, 24693, 148206,
569 33304, 20006, 20917, 20840, 20352, 20805, 20864, 21191, 21242, 21845, 21913, 21986,
570 22707, 22852, 22868, 23138, 23336, 24274, 24281, 24425, 24493, 24792, 24910, 24840,
571 24928, 25140, 25540, 25628, 25682, 25942, 26395, 26454, 28379, 28363, 28702, 30631,
572 29237, 29359, 29809, 29958, 30011, 30237, 30239, 30427, 30452, 30538, 30528, 30924,
573 31409, 31867, 32091, 32574, 33618, 33775, 34681, 35137, 35206, 35519, 35531, 35565,
574 35722, 36664, 36978, 37273, 37494, 38524, 38875, 38923, 39698, 141386, 141380, 144341,
575 15261, 16408, 16441, 152137, 154832, 163539, 40771, 40846, 102, 102, 102, 105, 102,
576 108, 102, 102, 108, 1396, 1398, 1396, 1381, 1396, 1387, 1406, 1398, 1396, 1389,
577 1497, 1460, 1522, 1463, 1506, 1492, 1499, 1500, 1501, 1512, 1514, 1513, 1473, 1513,
578 1474, 1513, 1468, 1473, 1513, 1468, 1474, 1488, 1463, 1488, 1464, 1488, 1468, 1489,
579 1468, 1490, 1468, 1491, 1468, 1492, 1468, 1493, 1468, 1494, 1468, 1496, 1468, 1497,
580 1468, 1498, 1468, 1499, 1468, 1500, 1468, 1502, 1468, 1504, 1468, 1505, 1468, 1507,
581 1468, 1508, 1468, 1510, 1468, 1511, 1468, 1512, 1468, 1514, 1468, 1493, 1465, 1489,
582 1471, 1499, 1471, 1508, 1471, 1488, 1500, 1649, 1659, 1662, 1664, 1658, 1663, 1657,
583 1700, 1702, 1668, 1667, 1670, 1671, 1677, 1676, 1678, 1672, 1688, 1681, 1705, 1711,
584 1715, 1713, 1722, 1723, 1728, 1729, 1726, 1746, 1747, 1709, 1734, 1736, 1739, 1733,
585 1737, 1744, 1609, 1574, 1575, 1574, 1749, 1574, 1608, 1574, 1735, 1574, 1734, 1574,
586 1736, 1574, 1744, 1574, 1609, 1740, 1574, 1580, 1574, 1581, 1574, 1605, 1574, 1610,
587 1576, 1580, 1576, 1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576, 1610, 1578, 1580,
588 1578, 1581, 1578, 1582, 1578, 1605, 1578, 1609, 1578, 1610, 1579, 1580, 1579, 1605,
589 1579, 1609, 1579, 1610, 1580, 1581, 1580, 1605, 1581, 1605, 1582, 1580, 1582, 1581,
590 1582, 1605, 1587, 1580, 1587, 1581, 1587, 1582, 1587, 1605, 1589, 1581, 1589, 1605,
591 1590, 1580, 1590, 1581, 1590, 1582, 1590, 1605, 1591, 1581, 1591, 1605, 1592, 1605,
592 1593, 1580, 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601, 1581, 1601, 1582,
593 1601, 1605, 1601, 1609, 1601, 1610, 1602, 1581, 1602, 1605, 1602, 1609, 1602, 1610,
594 1603, 1575, 1603, 1580, 1603, 1581, 1603, 1582, 1603, 1604, 1603, 1605, 1603, 1609,
595 1603, 1610, 1604, 1580, 1604, 1581, 1604, 1582, 1604, 1605, 1604, 1609, 1604, 1610,
596 1605, 1580, 1605, 1605, 1605, 1609, 1605, 1610, 1606, 1580, 1606, 1581, 1606, 1582,
597 1606, 1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607, 1605, 1607, 1609, 1607, 1610,
598 1610, 1581, 1610, 1582, 1610, 1609, 1584, 1648, 1585, 1648, 1609, 1648, 32, 1612,
599 1617, 32, 1613, 1617, 32, 1614, 1617, 32, 1615, 1617, 32, 1616, 1617, 32, 1617,
600 1648, 1574, 1585, 1574, 1586, 1574, 1606, 1576, 1585, 1576, 1586, 1576, 1606, 1578,
601 1585, 1578, 1586, 1578, 1606, 1579, 1585, 1579, 1586, 1579, 1606, 1605, 1575, 1606,
602 1585, 1606, 1586, 1606, 1606, 1610, 1585, 1610, 1586, 1574, 1582, 1574, 1607, 1576,
603 1607, 1578, 1607, 1589, 1582, 1604, 1607, 1606, 1607, 1607, 1648, 1579, 1607, 1587,
604 1607, 1588, 1605, 1588, 1607, 1600, 1614, 1617, 1600, 1615, 1617, 1600, 1616, 1617,
605 1591, 1609, 1591, 1610, 1593, 1609, 1593, 1610, 1594, 1609, 1594, 1610, 1587, 1609,
606 1587, 1610, 1588, 1609, 1588, 1610, 1581, 1609, 1580, 1609, 1580, 1610, 1582, 1609,
607 1589, 1609, 1589, 1610, 1590, 1609, 1590, 1610, 1588, 1580, 1588, 1581, 1588, 1582,
608 1588, 1585, 1587, 1585, 1589, 1585, 1590, 1585, 1575, 1611, 1578, 1580, 1605, 1578,
609 1581, 1580, 1578, 1581, 1605, 1578, 1582, 1605, 1578, 1605, 1580, 1578, 1605, 1581,
610 1578, 1605, 1582, 1581, 1605, 1610, 1581, 1605, 1609, 1587, 1581, 1580, 1587, 1580,
611 1581, 1587, 1580, 1609, 1587, 1605, 1581, 1587, 1605, 1580, 1587, 1605, 1605, 1589,
612 1581, 1581, 1589, 1605, 1605, 1588, 1581, 1605, 1588, 1580, 1610, 1588, 1605, 1582,
613 1588, 1605, 1605, 1590, 1581, 1609, 1590, 1582, 1605, 1591, 1605, 1581, 1591, 1605,
614 1605, 1591, 1605, 1610, 1593, 1580, 1605, 1593, 1605, 1605, 1593, 1605, 1609, 1594,
615 1605, 1605, 1594, 1605, 1610, 1594, 1605, 1609, 1601, 1582, 1605, 1602, 1605, 1581,
616 1602, 1605, 1605, 1604, 1581, 1605, 1604, 1581, 1610, 1604, 1581, 1609, 1604, 1580,
617 1580, 1604, 1582, 1605, 1604, 1605, 1581, 1605, 1581, 1580, 1605, 1581, 1610, 1605,
618 1580, 1581, 1605, 1582, 1605, 1605, 1580, 1582, 1607, 1605, 1580, 1607, 1605, 1605,
619 1606, 1581, 1605, 1606, 1581, 1609, 1606, 1580, 1605, 1606, 1580, 1609, 1606, 1605,
620 1610, 1606, 1605, 1609, 1610, 1605, 1605, 1576, 1582, 1610, 1578, 1580, 1610, 1578,
621 1580, 1609, 1578, 1582, 1610, 1578, 1582, 1609, 1578, 1605, 1610, 1578, 1605, 1609,
622 1580, 1605, 1610, 1580, 1581, 1609, 1580, 1605, 1609, 1587, 1582, 1609, 1589, 1581,
623 1610, 1588, 1581, 1610, 1590, 1581, 1610, 1604, 1580, 1610, 1604, 1605, 1610, 1610,
624 1580, 1610, 1610, 1605, 1610, 1605, 1605, 1610, 1602, 1605, 1610, 1606, 1581, 1610,
625 1593, 1605, 1610, 1603, 1605, 1610, 1606, 1580, 1581, 1605, 1582, 1610, 1604, 1580,
626 1605, 1603, 1605, 1605, 1580, 1581, 1610, 1581, 1580, 1610, 1605, 1580, 1610, 1601,
627 1605, 1610, 1576, 1581, 1610, 1587, 1582, 1610, 1606, 1580, 1610, 1589, 1604, 1746,
628 1602, 1604, 1746, 1575, 1604, 1604, 1607, 1575, 1603, 1576, 1585, 1605, 1581, 1605,
629 1583, 1589, 1604, 1593, 1605, 1585, 1587, 1608, 1604, 1593, 1604, 1610, 1607, 1608,
630 1587, 1604, 1605, 1589, 1604, 1609, 1589, 1604, 1609, 32, 1575, 1604, 1604, 1607,
631 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 1580, 1604, 32, 1580, 1604,
632 1575, 1604, 1607, 1585, 1740, 1575, 1604, 44, 12289, 12310, 12311, 8212, 8211, 95,
633 123, 125, 12308, 12309, 12304, 12305, 12298, 12299, 12300, 12301, 12302, 12303,
634 91, 93, 35, 38, 42, 45, 60, 62, 92, 36, 37, 64, 32, 1611, 1600, 1611, 1600, 1617,
635 32, 1618, 1600, 1618, 1569, 1570, 1571, 1572, 1573, 1577, 1604, 1570, 1604, 1571,
636 1604, 1573, 34, 39, 94, 124, 126, 10629, 10630, 12539, 12453, 12515, 162, 163, 172,
637 166, 165, 8361, 9474, 8592, 8593, 8594, 8595, 9632, 9675, 66600, 66601, 66602, 66603,
638 66604, 66605, 66606, 66607, 66608, 66609, 66610, 66611, 66612, 66613, 66614, 66615,
639 66616, 66617, 66618, 66619, 66620, 66621, 66622, 66623, 66624, 66625, 66626, 66627,
640 66628, 66629, 66630, 66631, 66632, 66633, 66634, 66635, 66636, 66637, 66638, 66639,
641 66776, 66777, 66778, 66779, 66780, 66781, 66782, 66783, 66784, 66785, 66786, 66787,
642 66788, 66789, 66790, 66791, 66792, 66793, 66794, 66795, 66796, 66797, 66798, 66799,
643 66800, 66801, 66802, 66803, 66804, 66805, 66806, 66807, 66808, 66809, 66810, 66811,
644 66967, 66968, 66969, 66970, 66971, 66972, 66973, 66974, 66975, 66976, 66977, 66979,
645 66980, 66981, 66982, 66983, 66984, 66985, 66986, 66987, 66988, 66989, 66990, 66991,
646 66992, 66993, 66995, 66996, 66997, 66998, 66999, 67000, 67001, 67003, 67004, 720,
647 721, 665, 675, 43878, 677, 676, 7569, 600, 606, 681, 612, 610, 667, 668, 615, 644,
648 682, 683, 122628, 42894, 622, 122629, 654, 122630, 630, 631, 634, 122632, 638, 680,
649 678, 43879, 679, 11377, 655, 673, 674, 664, 448, 449, 450, 122634, 122654, 68800,
650 68801, 68802, 68803, 68804, 68805, 68806, 68807, 68808, 68809, 68810, 68811, 68812,
651 68813, 68814, 68815, 68816, 68817, 68818, 68819, 68820, 68821, 68822, 68823, 68824,
652 68825, 68826, 68827, 68828, 68829, 68830, 68831, 68832, 68833, 68834, 68835, 68836,
653 68837, 68838, 68839, 68840, 68841, 68842, 68843, 68844, 68845, 68846, 68847, 68848,
654 68849, 68850, 71872, 71873, 71874, 71875, 71876, 71877, 71878, 71879, 71880, 71881,
655 71882, 71883, 71884, 71885, 71886, 71887, 71888, 71889, 71890, 71891, 71892, 71893,
656 71894, 71895, 71896, 71897, 71898, 71899, 71900, 71901, 71902, 71903, 93792, 93793,
657 93794, 93795, 93796, 93797, 93798, 93799, 93800, 93801, 93802, 93803, 93804, 93805,
658 93806, 93807, 93808, 93809, 93810, 93811, 93812, 93813, 93814, 93815, 93816, 93817,
659 93818, 93819, 93820, 93821, 93822, 93823, 119127, 119141, 119128, 119141, 119128,
660 119141, 119150, 119128, 119141, 119151, 119128, 119141, 119152, 119128, 119141,
661 119153, 119128, 119141, 119154, 119225, 119141, 119226, 119141, 119225, 119141,
662 119150, 119226, 119141, 119150, 119225, 119141, 119151, 119226, 119141, 119151,
663 305, 567, 8711, 8706, 1231, 125218, 125219, 125220, 125221, 125222, 125223, 125224,
664 125225, 125226, 125227, 125228, 125229, 125230, 125231, 125232, 125233, 125234,
665 125235, 125236, 125237, 125238, 125239, 125240, 125241, 125242, 125243, 125244,
666 125245, 125246, 125247, 125248, 125249, 125250, 125251, 1646, 1697, 1647, 48, 44,
667 49, 44, 50, 44, 51, 44, 52, 44, 53, 44, 54, 44, 55, 44, 56, 44, 57, 44, 12308, 115,
668 12309, 119, 122, 104, 118, 115, 100, 112, 112, 118, 119, 99, 109, 114, 100, 106,
669 12411, 12363, 12467, 12467, 23383, 21452, 22810, 35299, 20132, 26144, 28961, 21069,
670 24460, 20877, 26032, 21021, 32066, 36009, 22768, 21561, 28436, 25237, 25429, 36938,
671 25351, 25171, 31105, 31354, 21512, 28288, 30003, 21106, 21942, 37197, 12308, 26412,
672 12309, 12308, 19977, 12309, 12308, 20108, 12309, 12308, 23433, 12309, 12308, 28857,
673 12309, 12308, 25171, 12309, 12308, 30423, 12309, 12308, 21213, 12309, 12308, 25943,
674 12309, 24471, 21487, 20029, 20024, 20033, 131362, 20320, 20411, 20482, 20602, 20633,
675 20687, 13470, 132666, 20820, 20836, 20855, 132380, 13497, 20839, 132427, 20887,
676 20900, 20172, 20908, 168415, 20995, 13535, 21051, 21062, 21111, 13589, 21253, 21254,
677 21321, 21338, 21363, 21373, 21375, 133676, 28784, 21450, 21471, 133987, 21483, 21489,
678 21510, 21662, 21560, 21576, 21608, 21666, 21750, 21776, 21843, 21859, 21892, 21931,
679 21939, 21954, 22294, 22295, 22097, 22132, 22766, 22478, 22516, 22541, 22411, 22578,
680 22577, 22700, 136420, 22770, 22775, 22790, 22818, 22882, 136872, 136938, 23020,
681 23067, 23079, 23000, 23142, 14062, 23304, 23358, 137672, 23491, 23512, 23539, 138008,
682 23551, 23558, 14209, 23648, 23744, 23693, 138724, 23875, 138726, 23918, 23915, 23932,
683 24033, 24034, 14383, 24061, 24104, 24125, 24169, 14434, 139651, 14460, 24240, 24243,
684 24246, 172946, 140081, 33281, 24354, 14535, 144056, 156122, 24418, 24427, 14563,
685 24474, 24525, 24535, 24569, 24705, 14650, 14620, 141012, 24775, 24904, 24908, 24954,
686 25010, 24996, 25007, 25054, 25115, 25181, 25265, 25300, 25424, 142092, 25405, 25340,
687 25448, 25475, 25572, 142321, 25634, 25541, 25513, 14894, 25705, 25726, 25757, 25719,
688 14956, 25964, 143370, 26083, 26360, 26185, 15129, 15112, 15076, 20882, 20885, 26368,
689 26268, 32941, 17369, 26401, 26462, 26451, 144323, 15177, 26618, 26501, 26706, 144493,
690 26766, 26655, 26900, 26946, 27043, 27114, 27304, 145059, 27355, 15384, 27425, 145575,
691 27476, 15438, 27506, 27551, 27579, 146061, 138507, 146170, 27726, 146620, 27839,
692 27853, 27751, 27926, 27966, 28009, 28024, 28037, 146718, 27956, 28207, 28270, 15667,
693 28359, 147153, 28153, 28526, 147294, 147342, 28614, 28729, 28699, 15766, 28746,
694 28797, 28791, 28845, 132389, 28997, 148067, 29084, 29224, 29264, 149000, 29312,
695 29333, 149301, 149524, 29562, 29579, 16044, 29605, 16056, 29767, 29788, 29829, 29898,
696 16155, 29988, 150582, 30014, 150674, 139679, 30224, 151457, 151480, 151620, 16380,
697 16392, 151795, 151794, 151833, 151859, 30494, 30495, 30603, 16454, 16534, 152605,
698 30798, 16611, 153126, 153242, 153285, 31211, 16687, 31306, 31311, 153980, 154279,
699 16898, 154539, 31686, 31689, 16935, 154752, 31954, 17056, 31976, 31971, 32000, 155526,
700 32099, 17153, 32199, 32258, 32325, 17204, 156200, 156231, 17241, 156377, 32634,
701 156478, 32661, 32762, 156890, 156963, 32864, 157096, 32880, 144223, 17365, 32946,
702 33027, 17419, 33086, 23221, 157607, 157621, 144275, 144284, 33284, 36766, 17515,
703 33425, 33419, 33437, 21171, 33457, 33459, 33469, 33510, 158524, 33565, 33635, 33709,
704 33571, 33725, 33767, 33619, 33738, 33740, 33756, 158774, 159083, 158933, 17707,
705 34033, 34035, 34070, 160714, 34148, 159532, 17757, 17761, 159665, 159954, 17771,
706 34384, 34407, 34409, 34473, 34440, 34574, 34530, 34600, 34667, 34694, 34785, 34817,
707 17913, 34912, 161383, 35031, 35038, 17973, 35066, 13499, 161966, 162150, 18110,
708 18119, 35488, 162984, 36011, 36033, 36123, 36215, 163631, 133124, 36299, 36284,
709 36336, 133342, 36564, 165330, 165357, 37012, 37105, 37137, 165678, 37147, 37432,
710 37591, 37592, 37500, 37881, 37909, 166906, 38283, 18837, 38327, 167287, 18918, 38595,
711 23986, 38691, 168261, 168474, 19054, 19062, 38880, 168970, 19122, 169110, 38953,
712 169398, 39138, 19251, 39209, 39335, 39362, 39422, 19406, 170800, 40000, 40189, 19662,
713 19693, 40295, 172238, 19704, 172293, 172558, 172689, 19798, 40702, 40709, 40719,
714 40726, 173568,
715
716 };
717 const uint32_t table[8000][2] =
718 {
719 {0, 1}, {65, 16777219}, {66, 16777475}, {67, 16777731},
720 {68, 16777987}, {69, 16778243}, {70, 16778499}, {71, 16778755},
721 {72, 16779011}, {73, 16779267}, {74, 16779523}, {75, 16779779},
722 {76, 16780035}, {77, 16780291}, {78, 16780547}, {79, 16780803},
723 {80, 16781059}, {81, 16781315}, {82, 16781571}, {83, 16781827},
724 {84, 16782083}, {85, 16782339}, {86, 16782595}, {87, 16782851},
725 {88, 16783107}, {89, 16783363}, {90, 16783619}, {91, 1},
726 {128, 2}, {160, 16783875}, {161, 1}, {168, 33561347},
727 {169, 1}, {170, 16777219}, {171, 1}, {173, 0},
728 {174, 1}, {175, 33561859}, {176, 1}, {178, 16785155},
729 {179, 16785411}, {180, 33562883}, {181, 16786179}, {182, 1},
730 {184, 33563651}, {185, 16786947}, {186, 16780803}, {187, 1},
731 {188, 50341635}, {189, 50342403}, {190, 50343171}, {191, 1},
732 {192, 16789507}, {193, 16789763}, {194, 16790019}, {195, 16790275},
733 {196, 16790531}, {197, 16790787}, {198, 16791043}, {199, 16791299},
734 {200, 16791555}, {201, 16791811}, {202, 16792067}, {203, 16792323},
735 {204, 16792579}, {205, 16792835}, {206, 16793091}, {207, 16793347},
736 {208, 16793603}, {209, 16793859}, {210, 16794115}, {211, 16794371},
737 {212, 16794627}, {213, 16794883}, {214, 16795139}, {215, 1},
738 {216, 16795395}, {217, 16795651}, {218, 16795907}, {219, 16796163},
739 {220, 16796419}, {221, 16796675}, {222, 16796931}, {223, 1},
740 {256, 16797187}, {257, 1}, {258, 16797443}, {259, 1},
741 {260, 16797699}, {261, 1}, {262, 16797955}, {263, 1},
742 {264, 16798211}, {265, 1}, {266, 16798467}, {267, 1},
743 {268, 16798723}, {269, 1}, {270, 16798979}, {271, 1},
744 {272, 16799235}, {273, 1}, {274, 16799491}, {275, 1},
745 {276, 16799747}, {277, 1}, {278, 16800003}, {279, 1},
746 {280, 16800259}, {281, 1}, {282, 16800515}, {283, 1},
747 {284, 16800771}, {285, 1}, {286, 16801027}, {287, 1},
748 {288, 16801283}, {289, 1}, {290, 16801539}, {291, 1},
749 {292, 16801795}, {293, 1}, {294, 16802051}, {295, 1},
750 {296, 16802307}, {297, 1}, {298, 16802563}, {299, 1},
751 {300, 16802819}, {301, 1}, {302, 16803075}, {303, 1},
752 {304, 33580547}, {305, 1}, {306, 33556483}, {308, 16803843},
753 {309, 1}, {310, 16804099}, {311, 1}, {313, 16804355},
754 {314, 1}, {315, 16804611}, {316, 1}, {317, 16804867},
755 {318, 1}, {319, 33582339}, {321, 16805635}, {322, 1},
756 {323, 16805891}, {324, 1}, {325, 16806147}, {326, 1},
757 {327, 16806403}, {328, 1}, {329, 33583875}, {330, 16807171},
758 {331, 1}, {332, 16807427}, {333, 1}, {334, 16807683},
759 {335, 1}, {336, 16807939}, {337, 1}, {338, 16808195},
760 {339, 1}, {340, 16808451}, {341, 1}, {342, 16808707},
761 {343, 1}, {344, 16808963}, {345, 1}, {346, 16809219},
762 {347, 1}, {348, 16809475}, {349, 1}, {350, 16809731},
763 {351, 1}, {352, 16809987}, {353, 1}, {354, 16810243},
764 {355, 1}, {356, 16810499}, {357, 1}, {358, 16810755},
765 {359, 1}, {360, 16811011}, {361, 1}, {362, 16811267},
766 {363, 1}, {364, 16811523}, {365, 1}, {366, 16811779},
767 {367, 1}, {368, 16812035}, {369, 1}, {370, 16812291},
768 {371, 1}, {372, 16812547}, {373, 1}, {374, 16812803},
769 {375, 1}, {376, 16813059}, {377, 16813315}, {378, 1},
770 {379, 16813571}, {380, 1}, {381, 16813827}, {382, 1},
771 {383, 16781827}, {384, 1}, {385, 16814083}, {386, 16814339},
772 {387, 1}, {388, 16814595}, {389, 1}, {390, 16814851},
773 {391, 16815107}, {392, 1}, {393, 16815363}, {394, 16815619},
774 {395, 16815875}, {396, 1}, {398, 16816131}, {399, 16816387},
775 {400, 16816643}, {401, 16816899}, {402, 1}, {403, 16817155},
776 {404, 16817411}, {405, 1}, {406, 16817667}, {407, 16817923},
777 {408, 16818179}, {409, 1}, {412, 16818435}, {413, 16818691},
778 {414, 1}, {415, 16818947}, {416, 16819203}, {417, 1},
779 {418, 16819459}, {419, 1}, {420, 16819715}, {421, 1},
780 {422, 16819971}, {423, 16820227}, {424, 1}, {425, 16820483},
781 {426, 1}, {428, 16820739}, {429, 1}, {430, 16820995},
782 {431, 16821251}, {432, 1}, {433, 16821507}, {434, 16821763},
783 {435, 16822019}, {436, 1}, {437, 16822275}, {438, 1},
784 {439, 16822531}, {440, 16822787}, {441, 1}, {444, 16823043},
785 {445, 1}, {452, 33600515}, {455, 33601027}, {458, 33601539},
786 {461, 16824835}, {462, 1}, {463, 16825091}, {464, 1},
787 {465, 16825347}, {466, 1}, {467, 16825603}, {468, 1},
788 {469, 16825859}, {470, 1}, {471, 16826115}, {472, 1},
789 {473, 16826371}, {474, 1}, {475, 16826627}, {476, 1},
790 {478, 16826883}, {479, 1}, {480, 16827139}, {481, 1},
791 {482, 16827395}, {483, 1}, {484, 16827651}, {485, 1},
792 {486, 16827907}, {487, 1}, {488, 16828163}, {489, 1},
793 {490, 16828419}, {491, 1}, {492, 16828675}, {493, 1},
794 {494, 16828931}, {495, 1}, {497, 33606403}, {500, 16829699},
795 {501, 1}, {502, 16829955}, {503, 16830211}, {504, 16830467},
796 {505, 1}, {506, 16830723}, {507, 1}, {508, 16830979},
797 {509, 1}, {510, 16831235}, {511, 1}, {512, 16831491},
798 {513, 1}, {514, 16831747}, {515, 1}, {516, 16832003},
799 {517, 1}, {518, 16832259}, {519, 1}, {520, 16832515},
800 {521, 1}, {522, 16832771}, {523, 1}, {524, 16833027},
801 {525, 1}, {526, 16833283}, {527, 1}, {528, 16833539},
802 {529, 1}, {530, 16833795}, {531, 1}, {532, 16834051},
803 {533, 1}, {534, 16834307}, {535, 1}, {536, 16834563},
804 {537, 1}, {538, 16834819}, {539, 1}, {540, 16835075},
805 {541, 1}, {542, 16835331}, {543, 1}, {544, 16835587},
806 {545, 1}, {546, 16835843}, {547, 1}, {548, 16836099},
807 {549, 1}, {550, 16836355}, {551, 1}, {552, 16836611},
808 {553, 1}, {554, 16836867}, {555, 1}, {556, 16837123},
809 {557, 1}, {558, 16837379}, {559, 1}, {560, 16837635},
810 {561, 1}, {562, 16837891}, {563, 1}, {570, 16838147},
811 {571, 16838403}, {572, 1}, {573, 16838659}, {574, 16838915},
812 {575, 1}, {577, 16839171}, {578, 1}, {579, 16839427},
813 {580, 16839683}, {581, 16839939}, {582, 16840195}, {583, 1},
814 {584, 16840451}, {585, 1}, {586, 16840707}, {587, 1},
815 {588, 16840963}, {589, 1}, {590, 16841219}, {591, 1},
816 {688, 16779011}, {689, 16841475}, {690, 16779523}, {691, 16781571},
817 {692, 16841731}, {693, 16841987}, {694, 16842243}, {695, 16782851},
818 {696, 16783363}, {697, 1}, {728, 33619715}, {729, 33620227},
819 {730, 33620739}, {731, 33621251}, {732, 33621763}, {733, 33622275},
820 {734, 1}, {736, 16817411}, {737, 16780035}, {738, 16781827},
821 {739, 16783107}, {740, 16845571}, {741, 1}, {832, 16845827},
822 {833, 16785923}, {834, 1}, {835, 16846083}, {836, 33623555},
823 {837, 16846851}, {838, 1}, {847, 0}, {848, 1},
824 {880, 16847107}, {881, 1}, {882, 16847363}, {883, 1},
825 {884, 16847619}, {885, 1}, {886, 16847875}, {887, 1},
826 {888, 2}, {890, 33625347}, {891, 1}, {894, 16848643},
827 {895, 16848899}, {896, 2}, {900, 33562883}, {901, 50403587},
828 {902, 16849923}, {903, 16805379}, {904, 16850179}, {905, 16850435},
829 {906, 16850691}, {907, 2}, {908, 16850947}, {909, 2},
830 {910, 16851203}, {911, 16851459}, {912, 1}, {913, 16851715},
831 {914, 16851971}, {915, 16852227}, {916, 16852483}, {917, 16852739},
832 {918, 16852995}, {919, 16853251}, {920, 16853507}, {921, 16846851},
833 {922, 16853763}, {923, 16854019}, {924, 16786179}, {925, 16854275},
834 {926, 16854531}, {927, 16854787}, {928, 16855043}, {929, 16855299},
835 {930, 2}, {931, 16855555}, {932, 16855811}, {933, 16856067},
836 {934, 16856323}, {935, 16856579}, {936, 16856835}, {937, 16857091},
837 {938, 16857347}, {939, 16857603}, {940, 1}, {975, 16857859},
838 {976, 16851971}, {977, 16853507}, {978, 16856067}, {979, 16851203},
839 {980, 16857603}, {981, 16856323}, {982, 16855043}, {983, 1},
840 {984, 16858115}, {985, 1}, {986, 16858371}, {987, 1},
841 {988, 16858627}, {989, 1}, {990, 16858883}, {991, 1},
842 {992, 16859139}, {993, 1}, {994, 16859395}, {995, 1},
843 {996, 16859651}, {997, 1}, {998, 16859907}, {999, 1},
844 {1000, 16860163}, {1001, 1}, {1002, 16860419}, {1003, 1},
845 {1004, 16860675}, {1005, 1}, {1006, 16860931}, {1007, 1},
846 {1008, 16853763}, {1009, 16855299}, {1010, 16855555}, {1011, 1},
847 {1012, 16853507}, {1013, 16852739}, {1014, 1}, {1015, 16861187},
848 {1016, 1}, {1017, 16855555}, {1018, 16861443}, {1019, 1},
849 {1021, 16861699}, {1022, 16861955}, {1023, 16862211}, {1024, 16862467},
850 {1025, 16862723}, {1026, 16862979}, {1027, 16863235}, {1028, 16863491},
851 {1029, 16863747}, {1030, 16864003}, {1031, 16864259}, {1032, 16864515},
852 {1033, 16864771}, {1034, 16865027}, {1035, 16865283}, {1036, 16865539},
853 {1037, 16865795}, {1038, 16866051}, {1039, 16866307}, {1040, 16866563},
854 {1041, 16866819}, {1042, 16867075}, {1043, 16867331}, {1044, 16867587},
855 {1045, 16867843}, {1046, 16868099}, {1047, 16868355}, {1048, 16868611},
856 {1049, 16868867}, {1050, 16869123}, {1051, 16869379}, {1052, 16869635},
857 {1053, 16869891}, {1054, 16870147}, {1055, 16870403}, {1056, 16870659},
858 {1057, 16870915}, {1058, 16871171}, {1059, 16871427}, {1060, 16871683},
859 {1061, 16871939}, {1062, 16872195}, {1063, 16872451}, {1064, 16872707},
860 {1065, 16872963}, {1066, 16873219}, {1067, 16873475}, {1068, 16873731},
861 {1069, 16873987}, {1070, 16874243}, {1071, 16874499}, {1072, 1},
862 {1120, 16874755}, {1121, 1}, {1122, 16875011}, {1123, 1},
863 {1124, 16875267}, {1125, 1}, {1126, 16875523}, {1127, 1},
864 {1128, 16875779}, {1129, 1}, {1130, 16876035}, {1131, 1},
865 {1132, 16876291}, {1133, 1}, {1134, 16876547}, {1135, 1},
866 {1136, 16876803}, {1137, 1}, {1138, 16877059}, {1139, 1},
867 {1140, 16877315}, {1141, 1}, {1142, 16877571}, {1143, 1},
868 {1144, 16877827}, {1145, 1}, {1146, 16878083}, {1147, 1},
869 {1148, 16878339}, {1149, 1}, {1150, 16878595}, {1151, 1},
870 {1152, 16878851}, {1153, 1}, {1162, 16879107}, {1163, 1},
871 {1164, 16879363}, {1165, 1}, {1166, 16879619}, {1167, 1},
872 {1168, 16879875}, {1169, 1}, {1170, 16880131}, {1171, 1},
873 {1172, 16880387}, {1173, 1}, {1174, 16880643}, {1175, 1},
874 {1176, 16880899}, {1177, 1}, {1178, 16881155}, {1179, 1},
875 {1180, 16881411}, {1181, 1}, {1182, 16881667}, {1183, 1},
876 {1184, 16881923}, {1185, 1}, {1186, 16882179}, {1187, 1},
877 {1188, 16882435}, {1189, 1}, {1190, 16882691}, {1191, 1},
878 {1192, 16882947}, {1193, 1}, {1194, 16883203}, {1195, 1},
879 {1196, 16883459}, {1197, 1}, {1198, 16883715}, {1199, 1},
880 {1200, 16883971}, {1201, 1}, {1202, 16884227}, {1203, 1},
881 {1204, 16884483}, {1205, 1}, {1206, 16884739}, {1207, 1},
882 {1208, 16884995}, {1209, 1}, {1210, 16885251}, {1211, 1},
883 {1212, 16885507}, {1213, 1}, {1214, 16885763}, {1215, 1},
884 {1216, 2}, {1217, 16886019}, {1218, 1}, {1219, 16886275},
885 {1220, 1}, {1221, 16886531}, {1222, 1}, {1223, 16886787},
886 {1224, 1}, {1225, 16887043}, {1226, 1}, {1227, 16887299},
887 {1228, 1}, {1229, 16887555}, {1230, 1}, {1232, 16887811},
888 {1233, 1}, {1234, 16888067}, {1235, 1}, {1236, 16888323},
889 {1237, 1}, {1238, 16888579}, {1239, 1}, {1240, 16888835},
890 {1241, 1}, {1242, 16889091}, {1243, 1}, {1244, 16889347},
891 {1245, 1}, {1246, 16889603}, {1247, 1}, {1248, 16889859},
892 {1249, 1}, {1250, 16890115}, {1251, 1}, {1252, 16890371},
893 {1253, 1}, {1254, 16890627}, {1255, 1}, {1256, 16890883},
894 {1257, 1}, {1258, 16891139}, {1259, 1}, {1260, 16891395},
895 {1261, 1}, {1262, 16891651}, {1263, 1}, {1264, 16891907},
896 {1265, 1}, {1266, 16892163}, {1267, 1}, {1268, 16892419},
897 {1269, 1}, {1270, 16892675}, {1271, 1}, {1272, 16892931},
898 {1273, 1}, {1274, 16893187}, {1275, 1}, {1276, 16893443},
899 {1277, 1}, {1278, 16893699}, {1279, 1}, {1280, 16893955},
900 {1281, 1}, {1282, 16894211}, {1283, 1}, {1284, 16894467},
901 {1285, 1}, {1286, 16894723}, {1287, 1}, {1288, 16894979},
902 {1289, 1}, {1290, 16895235}, {1291, 1}, {1292, 16895491},
903 {1293, 1}, {1294, 16895747}, {1295, 1}, {1296, 16896003},
904 {1297, 1}, {1298, 16896259}, {1299, 1}, {1300, 16896515},
905 {1301, 1}, {1302, 16896771}, {1303, 1}, {1304, 16897027},
906 {1305, 1}, {1306, 16897283}, {1307, 1}, {1308, 16897539},
907 {1309, 1}, {1310, 16897795}, {1311, 1}, {1312, 16898051},
908 {1313, 1}, {1314, 16898307}, {1315, 1}, {1316, 16898563},
909 {1317, 1}, {1318, 16898819}, {1319, 1}, {1320, 16899075},
910 {1321, 1}, {1322, 16899331}, {1323, 1}, {1324, 16899587},
911 {1325, 1}, {1326, 16899843}, {1327, 1}, {1328, 2},
912 {1329, 16900099}, {1330, 16900355}, {1331, 16900611}, {1332, 16900867},
913 {1333, 16901123}, {1334, 16901379}, {1335, 16901635}, {1336, 16901891},
914 {1337, 16902147}, {1338, 16902403}, {1339, 16902659}, {1340, 16902915},
915 {1341, 16903171}, {1342, 16903427}, {1343, 16903683}, {1344, 16903939},
916 {1345, 16904195}, {1346, 16904451}, {1347, 16904707}, {1348, 16904963},
917 {1349, 16905219}, {1350, 16905475}, {1351, 16905731}, {1352, 16905987},
918 {1353, 16906243}, {1354, 16906499}, {1355, 16906755}, {1356, 16907011},
919 {1357, 16907267}, {1358, 16907523}, {1359, 16907779}, {1360, 16908035},
920 {1361, 16908291}, {1362, 16908547}, {1363, 16908803}, {1364, 16909059},
921 {1365, 16909315}, {1366, 16909571}, {1367, 2}, {1369, 1},
922 {1415, 33687043}, {1416, 1}, {1419, 2}, {1421, 1},
923 {1424, 2}, {1425, 1}, {1480, 2}, {1488, 1},
924 {1515, 2}, {1519, 1}, {1525, 2}, {1542, 1},
925 {1564, 2}, {1565, 1}, {1653, 33687555}, {1654, 33688067},
926 {1655, 33688579}, {1656, 33689091}, {1657, 1}, {1757, 2},
927 {1758, 1}, {1806, 2}, {1808, 1}, {1867, 2},
928 {1869, 1}, {1970, 2}, {1984, 1}, {2043, 2},
929 {2045, 1}, {2094, 2}, {2096, 1}, {2111, 2},
930 {2112, 1}, {2140, 2}, {2142, 1}, {2143, 2},
931 {2144, 1}, {2155, 2}, {2160, 1}, {2191, 2},
932 {2200, 1}, {2274, 2}, {2275, 1}, {2392, 33689603},
933 {2393, 33690115}, {2394, 33690627}, {2395, 33691139}, {2396, 33691651},
934 {2397, 33692163}, {2398, 33692675}, {2399, 33693187}, {2400, 1},
935 {2436, 2}, {2437, 1}, {2445, 2}, {2447, 1},
936 {2449, 2}, {2451, 1}, {2473, 2}, {2474, 1},
937 {2481, 2}, {2482, 1}, {2483, 2}, {2486, 1},
938 {2490, 2}, {2492, 1}, {2501, 2}, {2503, 1},
939 {2505, 2}, {2507, 1}, {2511, 2}, {2519, 1},
940 {2520, 2}, {2524, 33693699}, {2525, 33694211}, {2526, 2},
941 {2527, 33694723}, {2528, 1}, {2532, 2}, {2534, 1},
942 {2559, 2}, {2561, 1}, {2564, 2}, {2565, 1},
943 {2571, 2}, {2575, 1}, {2577, 2}, {2579, 1},
944 {2601, 2}, {2602, 1}, {2609, 2}, {2610, 1},
945 {2611, 33695235}, {2612, 2}, {2613, 1}, {2614, 33695747},
946 {2615, 2}, {2616, 1}, {2618, 2}, {2620, 1},
947 {2621, 2}, {2622, 1}, {2627, 2}, {2631, 1},
948 {2633, 2}, {2635, 1}, {2638, 2}, {2641, 1},
949 {2642, 2}, {2649, 33696259}, {2650, 33696771}, {2651, 33697283},
950 {2652, 1}, {2653, 2}, {2654, 33697795}, {2655, 2},
951 {2662, 1}, {2679, 2}, {2689, 1}, {2692, 2},
952 {2693, 1}, {2702, 2}, {2703, 1}, {2706, 2},
953 {2707, 1}, {2729, 2}, {2730, 1}, {2737, 2},
954 {2738, 1}, {2740, 2}, {2741, 1}, {2746, 2},
955 {2748, 1}, {2758, 2}, {2759, 1}, {2762, 2},
956 {2763, 1}, {2766, 2}, {2768, 1}, {2769, 2},
957 {2784, 1}, {2788, 2}, {2790, 1}, {2802, 2},
958 {2809, 1}, {2816, 2}, {2817, 1}, {2820, 2},
959 {2821, 1}, {2829, 2}, {2831, 1}, {2833, 2},
960 {2835, 1}, {2857, 2}, {2858, 1}, {2865, 2},
961 {2866, 1}, {2868, 2}, {2869, 1}, {2874, 2},
962 {2876, 1}, {2885, 2}, {2887, 1}, {2889, 2},
963 {2891, 1}, {2894, 2}, {2901, 1}, {2904, 2},
964 {2908, 33698307}, {2909, 33698819}, {2910, 2}, {2911, 1},
965 {2916, 2}, {2918, 1}, {2936, 2}, {2946, 1},
966 {2948, 2}, {2949, 1}, {2955, 2}, {2958, 1},
967 {2961, 2}, {2962, 1}, {2966, 2}, {2969, 1},
968 {2971, 2}, {2972, 1}, {2973, 2}, {2974, 1},
969 {2976, 2}, {2979, 1}, {2981, 2}, {2984, 1},
970 {2987, 2}, {2990, 1}, {3002, 2}, {3006, 1},
971 {3011, 2}, {3014, 1}, {3017, 2}, {3018, 1},
972 {3022, 2}, {3024, 1}, {3025, 2}, {3031, 1},
973 {3032, 2}, {3046, 1}, {3067, 2}, {3072, 1},
974 {3085, 2}, {3086, 1}, {3089, 2}, {3090, 1},
975 {3113, 2}, {3114, 1}, {3130, 2}, {3132, 1},
976 {3141, 2}, {3142, 1}, {3145, 2}, {3146, 1},
977 {3150, 2}, {3157, 1}, {3159, 2}, {3160, 1},
978 {3163, 2}, {3165, 1}, {3166, 2}, {3168, 1},
979 {3172, 2}, {3174, 1}, {3184, 2}, {3191, 1},
980 {3213, 2}, {3214, 1}, {3217, 2}, {3218, 1},
981 {3241, 2}, {3242, 1}, {3252, 2}, {3253, 1},
982 {3258, 2}, {3260, 1}, {3269, 2}, {3270, 1},
983 {3273, 2}, {3274, 1}, {3278, 2}, {3285, 1},
984 {3287, 2}, {3293, 1}, {3295, 2}, {3296, 1},
985 {3300, 2}, {3302, 1}, {3312, 2}, {3313, 1},
986 {3316, 2}, {3328, 1}, {3341, 2}, {3342, 1},
987 {3345, 2}, {3346, 1}, {3397, 2}, {3398, 1},
988 {3401, 2}, {3402, 1}, {3408, 2}, {3412, 1},
989 {3428, 2}, {3430, 1}, {3456, 2}, {3457, 1},
990 {3460, 2}, {3461, 1}, {3479, 2}, {3482, 1},
991 {3506, 2}, {3507, 1}, {3516, 2}, {3517, 1},
992 {3518, 2}, {3520, 1}, {3527, 2}, {3530, 1},
993 {3531, 2}, {3535, 1}, {3541, 2}, {3542, 1},
994 {3543, 2}, {3544, 1}, {3552, 2}, {3558, 1},
995 {3568, 2}, {3570, 1}, {3573, 2}, {3585, 1},
996 {3635, 33699331}, {3636, 1}, {3643, 2}, {3647, 1},
997 {3676, 2}, {3713, 1}, {3715, 2}, {3716, 1},
998 {3717, 2}, {3718, 1}, {3723, 2}, {3724, 1},
999 {3748, 2}, {3749, 1}, {3750, 2}, {3751, 1},
1000 {3763, 33699843}, {3764, 1}, {3774, 2}, {3776, 1},
1001 {3781, 2}, {3782, 1}, {3783, 2}, {3784, 1},
1002 {3791, 2}, {3792, 1}, {3802, 2}, {3804, 33700355},
1003 {3805, 33700867}, {3806, 1}, {3808, 2}, {3840, 1},
1004 {3852, 16924163}, {3853, 1}, {3907, 33701635}, {3908, 1},
1005 {3912, 2}, {3913, 1}, {3917, 33702147}, {3918, 1},
1006 {3922, 33702659}, {3923, 1}, {3927, 33703171}, {3928, 1},
1007 {3932, 33703683}, {3933, 1}, {3945, 33704195}, {3946, 1},
1008 {3949, 2}, {3953, 1}, {3955, 33704707}, {3956, 1},
1009 {3957, 33705219}, {3958, 33705731}, {3959, 50483459}, {3960, 33707011},
1010 {3961, 50484739}, {3962, 1}, {3969, 33706499}, {3970, 1},
1011 {3987, 33708291}, {3988, 1}, {3992, 2}, {3993, 1},
1012 {3997, 33708803}, {3998, 1}, {4002, 33709315}, {4003, 1},
1013 {4007, 33709827}, {4008, 1}, {4012, 33710339}, {4013, 1},
1014 {4025, 33710851}, {4026, 1}, {4029, 2}, {4030, 1},
1015 {4045, 2}, {4046, 1}, {4059, 2}, {4096, 1},
1016 {4256, 2}, {4295, 16934147}, {4296, 2}, {4301, 16934403},
1017 {4302, 2}, {4304, 1}, {4348, 16934659}, {4349, 1},
1018 {4447, 2}, {4449, 1}, {4681, 2}, {4682, 1},
1019 {4686, 2}, {4688, 1}, {4695, 2}, {4696, 1},
1020 {4697, 2}, {4698, 1}, {4702, 2}, {4704, 1},
1021 {4745, 2}, {4746, 1}, {4750, 2}, {4752, 1},
1022 {4785, 2}, {4786, 1}, {4790, 2}, {4792, 1},
1023 {4799, 2}, {4800, 1}, {4801, 2}, {4802, 1},
1024 {4806, 2}, {4808, 1}, {4823, 2}, {4824, 1},
1025 {4881, 2}, {4882, 1}, {4886, 2}, {4888, 1},
1026 {4955, 2}, {4957, 1}, {4989, 2}, {4992, 1},
1027 {5018, 2}, {5024, 1}, {5110, 2}, {5112, 16934915},
1028 {5113, 16935171}, {5114, 16935427}, {5115, 16935683}, {5116, 16935939},
1029 {5117, 16936195}, {5118, 2}, {5120, 1}, {5760, 2},
1030 {5761, 1}, {5789, 2}, {5792, 1}, {5881, 2},
1031 {5888, 1}, {5910, 2}, {5919, 1}, {5943, 2},
1032 {5952, 1}, {5972, 2}, {5984, 1}, {5997, 2},
1033 {5998, 1}, {6001, 2}, {6002, 1}, {6004, 2},
1034 {6016, 1}, {6068, 2}, {6070, 1}, {6110, 2},
1035 {6112, 1}, {6122, 2}, {6128, 1}, {6138, 2},
1036 {6144, 1}, {6150, 2}, {6151, 1}, {6155, 0},
1037 {6158, 2}, {6159, 0}, {6160, 1}, {6170, 2},
1038 {6176, 1}, {6265, 2}, {6272, 1}, {6315, 2},
1039 {6320, 1}, {6390, 2}, {6400, 1}, {6431, 2},
1040 {6432, 1}, {6444, 2}, {6448, 1}, {6460, 2},
1041 {6464, 1}, {6465, 2}, {6468, 1}, {6510, 2},
1042 {6512, 1}, {6517, 2}, {6528, 1}, {6572, 2},
1043 {6576, 1}, {6602, 2}, {6608, 1}, {6619, 2},
1044 {6622, 1}, {6684, 2}, {6686, 1}, {6751, 2},
1045 {6752, 1}, {6781, 2}, {6783, 1}, {6794, 2},
1046 {6800, 1}, {6810, 2}, {6816, 1}, {6830, 2},
1047 {6832, 1}, {6863, 2}, {6912, 1}, {6989, 2},
1048 {6992, 1}, {7039, 2}, {7040, 1}, {7156, 2},
1049 {7164, 1}, {7224, 2}, {7227, 1}, {7242, 2},
1050 {7245, 1}, {7296, 16867075}, {7297, 16867587}, {7298, 16870147},
1051 {7299, 16870915}, {7300, 16871171}, {7302, 16873219}, {7303, 16875011},
1052 {7304, 16936451}, {7305, 2}, {7312, 16936707}, {7313, 16936963},
1053 {7314, 16937219}, {7315, 16937475}, {7316, 16937731}, {7317, 16937987},
1054 {7318, 16938243}, {7319, 16938499}, {7320, 16938755}, {7321, 16939011},
1055 {7322, 16939267}, {7323, 16939523}, {7324, 16934659}, {7325, 16939779},
1056 {7326, 16940035}, {7327, 16940291}, {7328, 16940547}, {7329, 16940803},
1057 {7330, 16941059}, {7331, 16941315}, {7332, 16941571}, {7333, 16941827},
1058 {7334, 16942083}, {7335, 16942339}, {7336, 16942595}, {7337, 16942851},
1059 {7338, 16943107}, {7339, 16943363}, {7340, 16943619}, {7341, 16943875},
1060 {7342, 16944131}, {7343, 16944387}, {7344, 16944643}, {7345, 16944899},
1061 {7346, 16945155}, {7347, 16945411}, {7348, 16945667}, {7349, 16945923},
1062 {7350, 16946179}, {7351, 16946435}, {7352, 16946691}, {7353, 16946947},
1063 {7354, 16947203}, {7355, 2}, {7357, 16947459}, {7358, 16947715},
1064 {7359, 16947971}, {7360, 1}, {7368, 2}, {7376, 1},
1065 {7419, 2}, {7424, 1}, {7468, 16777219}, {7469, 16791043},
1066 {7470, 16777475}, {7471, 1}, {7472, 16777987}, {7473, 16778243},
1067 {7474, 16816131}, {7475, 16778755}, {7476, 16779011}, {7477, 16779267},
1068 {7478, 16779523}, {7479, 16779779}, {7480, 16780035}, {7481, 16780291},
1069 {7482, 16780547}, {7483, 1}, {7484, 16780803}, {7485, 16835843},
1070 {7486, 16781059}, {7487, 16781571}, {7488, 16782083}, {7489, 16782339},
1071 {7490, 16782851}, {7491, 16777219}, {7492, 16948227}, {7493, 16948483},
1072 {7494, 16948739}, {7495, 16777475}, {7496, 16777987}, {7497, 16778243},
1073 {7498, 16816387}, {7499, 16816643}, {7500, 16948995}, {7501, 16778755},
1074 {7502, 1}, {7503, 16779779}, {7504, 16780291}, {7505, 16807171},
1075 {7506, 16780803}, {7507, 16814851}, {7508, 16949251}, {7509, 16949507},
1076 {7510, 16781059}, {7511, 16782083}, {7512, 16782339}, {7513, 16949763},
1077 {7514, 16818435}, {7515, 16782595}, {7516, 16950019}, {7517, 16851971},
1078 {7518, 16852227}, {7519, 16852483}, {7520, 16856323}, {7521, 16856579},
1079 {7522, 16779267}, {7523, 16781571}, {7524, 16782339}, {7525, 16782595},
1080 {7526, 16851971}, {7527, 16852227}, {7528, 16855299}, {7529, 16856323},
1081 {7530, 16856579}, {7531, 1}, {7544, 16869891}, {7545, 1},
1082 {7579, 16950275}, {7580, 16777731}, {7581, 16950531}, {7582, 16793603},
1083 {7583, 16948995}, {7584, 16778499}, {7585, 16950787}, {7586, 16951043},
1084 {7587, 16951299}, {7588, 16817923}, {7589, 16817667}, {7590, 16951555},
1085 {7591, 16951811}, {7592, 16952067}, {7593, 16952323}, {7594, 16952579},
1086 {7595, 16952835}, {7596, 16953091}, {7597, 16953347}, {7598, 16818691},
1087 {7599, 16953603}, {7600, 16953859}, {7601, 16818947}, {7602, 16954115},
1088 {7603, 16954371}, {7604, 16820483}, {7605, 16954627}, {7606, 16839683},
1089 {7607, 16821507}, {7608, 16954883}, {7609, 16821763}, {7610, 16839939},
1090 {7611, 16783619}, {7612, 16955139}, {7613, 16955395}, {7614, 16822531},
1091 {7615, 16853507}, {7616, 1}, {7680, 16955651}, {7681, 1},
1092 {7682, 16955907}, {7683, 1}, {7684, 16956163}, {7685, 1},
1093 {7686, 16956419}, {7687, 1}, {7688, 16956675}, {7689, 1},
1094 {7690, 16956931}, {7691, 1}, {7692, 16957187}, {7693, 1},
1095 {7694, 16957443}, {7695, 1}, {7696, 16957699}, {7697, 1},
1096 {7698, 16957955}, {7699, 1}, {7700, 16958211}, {7701, 1},
1097 {7702, 16958467}, {7703, 1}, {7704, 16958723}, {7705, 1},
1098 {7706, 16958979}, {7707, 1}, {7708, 16959235}, {7709, 1},
1099 {7710, 16959491}, {7711, 1}, {7712, 16959747}, {7713, 1},
1100 {7714, 16960003}, {7715, 1}, {7716, 16960259}, {7717, 1},
1101 {7718, 16960515}, {7719, 1}, {7720, 16960771}, {7721, 1},
1102 {7722, 16961027}, {7723, 1}, {7724, 16961283}, {7725, 1},
1103 {7726, 16961539}, {7727, 1}, {7728, 16961795}, {7729, 1},
1104 {7730, 16962051}, {7731, 1}, {7732, 16962307}, {7733, 1},
1105 {7734, 16962563}, {7735, 1}, {7736, 16962819}, {7737, 1},
1106 {7738, 16963075}, {7739, 1}, {7740, 16963331}, {7741, 1},
1107 {7742, 16963587}, {7743, 1}, {7744, 16963843}, {7745, 1},
1108 {7746, 16964099}, {7747, 1}, {7748, 16964355}, {7749, 1},
1109 {7750, 16964611}, {7751, 1}, {7752, 16964867}, {7753, 1},
1110 {7754, 16965123}, {7755, 1}, {7756, 16965379}, {7757, 1},
1111 {7758, 16965635}, {7759, 1}, {7760, 16965891}, {7761, 1},
1112 {7762, 16966147}, {7763, 1}, {7764, 16966403}, {7765, 1},
1113 {7766, 16966659}, {7767, 1}, {7768, 16966915}, {7769, 1},
1114 {7770, 16967171}, {7771, 1}, {7772, 16967427}, {7773, 1},
1115 {7774, 16967683}, {7775, 1}, {7776, 16967939}, {7777, 1},
1116 {7778, 16968195}, {7779, 1}, {7780, 16968451}, {7781, 1},
1117 {7782, 16968707}, {7783, 1}, {7784, 16968963}, {7785, 1},
1118 {7786, 16969219}, {7787, 1}, {7788, 16969475}, {7789, 1},
1119 {7790, 16969731}, {7791, 1}, {7792, 16969987}, {7793, 1},
1120 {7794, 16970243}, {7795, 1}, {7796, 16970499}, {7797, 1},
1121 {7798, 16970755}, {7799, 1}, {7800, 16971011}, {7801, 1},
1122 {7802, 16971267}, {7803, 1}, {7804, 16971523}, {7805, 1},
1123 {7806, 16971779}, {7807, 1}, {7808, 16972035}, {7809, 1},
1124 {7810, 16972291}, {7811, 1}, {7812, 16972547}, {7813, 1},
1125 {7814, 16972803}, {7815, 1}, {7816, 16973059}, {7817, 1},
1126 {7818, 16973315}, {7819, 1}, {7820, 16973571}, {7821, 1},
1127 {7822, 16973827}, {7823, 1}, {7824, 16974083}, {7825, 1},
1128 {7826, 16974339}, {7827, 1}, {7828, 16974595}, {7829, 1},
1129 {7834, 33752067}, {7835, 16967939}, {7836, 1}, {7838, 33752579},
1130 {7839, 1}, {7840, 16975875}, {7841, 1}, {7842, 16976131},
1131 {7843, 1}, {7844, 16976387}, {7845, 1}, {7846, 16976643},
1132 {7847, 1}, {7848, 16976899}, {7849, 1}, {7850, 16977155},
1133 {7851, 1}, {7852, 16977411}, {7853, 1}, {7854, 16977667},
1134 {7855, 1}, {7856, 16977923}, {7857, 1}, {7858, 16978179},
1135 {7859, 1}, {7860, 16978435}, {7861, 1}, {7862, 16978691},
1136 {7863, 1}, {7864, 16978947}, {7865, 1}, {7866, 16979203},
1137 {7867, 1}, {7868, 16979459}, {7869, 1}, {7870, 16979715},
1138 {7871, 1}, {7872, 16979971}, {7873, 1}, {7874, 16980227},
1139 {7875, 1}, {7876, 16980483}, {7877, 1}, {7878, 16980739},
1140 {7879, 1}, {7880, 16980995}, {7881, 1}, {7882, 16981251},
1141 {7883, 1}, {7884, 16981507}, {7885, 1}, {7886, 16981763},
1142 {7887, 1}, {7888, 16982019}, {7889, 1}, {7890, 16982275},
1143 {7891, 1}, {7892, 16982531}, {7893, 1}, {7894, 16982787},
1144 {7895, 1}, {7896, 16983043}, {7897, 1}, {7898, 16983299},
1145 {7899, 1}, {7900, 16983555}, {7901, 1}, {7902, 16983811},
1146 {7903, 1}, {7904, 16984067}, {7905, 1}, {7906, 16984323},
1147 {7907, 1}, {7908, 16984579}, {7909, 1}, {7910, 16984835},
1148 {7911, 1}, {7912, 16985091}, {7913, 1}, {7914, 16985347},
1149 {7915, 1}, {7916, 16985603}, {7917, 1}, {7918, 16985859},
1150 {7919, 1}, {7920, 16986115}, {7921, 1}, {7922, 16986371},
1151 {7923, 1}, {7924, 16986627}, {7925, 1}, {7926, 16986883},
1152 {7927, 1}, {7928, 16987139}, {7929, 1}, {7930, 16987395},
1153 {7931, 1}, {7932, 16987651}, {7933, 1}, {7934, 16987907},
1154 {7935, 1}, {7944, 16988163}, {7945, 16988419}, {7946, 16988675},
1155 {7947, 16988931}, {7948, 16989187}, {7949, 16989443}, {7950, 16989699},
1156 {7951, 16989955}, {7952, 1}, {7958, 2}, {7960, 16990211},
1157 {7961, 16990467}, {7962, 16990723}, {7963, 16990979}, {7964, 16991235},
1158 {7965, 16991491}, {7966, 2}, {7968, 1}, {7976, 16991747},
1159 {7977, 16992003}, {7978, 16992259}, {7979, 16992515}, {7980, 16992771},
1160 {7981, 16993027}, {7982, 16993283}, {7983, 16993539}, {7984, 1},
1161 {7992, 16993795}, {7993, 16994051}, {7994, 16994307}, {7995, 16994563},
1162 {7996, 16994819}, {7997, 16995075}, {7998, 16995331}, {7999, 16995587},
1163 {8000, 1}, {8006, 2}, {8008, 16995843}, {8009, 16996099},
1164 {8010, 16996355}, {8011, 16996611}, {8012, 16996867}, {8013, 16997123},
1165 {8014, 2}, {8016, 1}, {8024, 2}, {8025, 16997379},
1166 {8026, 2}, {8027, 16997635}, {8028, 2}, {8029, 16997891},
1167 {8030, 2}, {8031, 16998147}, {8032, 1}, {8040, 16998403},
1168 {8041, 16998659}, {8042, 16998915}, {8043, 16999171}, {8044, 16999427},
1169 {8045, 16999683}, {8046, 16999939}, {8047, 17000195}, {8048, 1},
1170 {8049, 16849923}, {8050, 1}, {8051, 16850179}, {8052, 1},
1171 {8053, 16850435}, {8054, 1}, {8055, 16850691}, {8056, 1},
1172 {8057, 16850947}, {8058, 1}, {8059, 16851203}, {8060, 1},
1173 {8061, 16851459}, {8062, 2}, {8064, 33777667}, {8065, 33778179},
1174 {8066, 33778691}, {8067, 33779203}, {8068, 33779715}, {8069, 33780227},
1175 {8070, 33780739}, {8071, 33781251}, {8072, 33777667}, {8073, 33778179},
1176 {8074, 33778691}, {8075, 33779203}, {8076, 33779715}, {8077, 33780227},
1177 {8078, 33780739}, {8079, 33781251}, {8080, 33781763}, {8081, 33782275},
1178 {8082, 33782787}, {8083, 33783299}, {8084, 33783811}, {8085, 33784323},
1179 {8086, 33784835}, {8087, 33785347}, {8088, 33781763}, {8089, 33782275},
1180 {8090, 33782787}, {8091, 33783299}, {8092, 33783811}, {8093, 33784323},
1181 {8094, 33784835}, {8095, 33785347}, {8096, 33785859}, {8097, 33786371},
1182 {8098, 33786883}, {8099, 33787395}, {8100, 33787907}, {8101, 33788419},
1183 {8102, 33788931}, {8103, 33789443}, {8104, 33785859}, {8105, 33786371},
1184 {8106, 33786883}, {8107, 33787395}, {8108, 33787907}, {8109, 33788419},
1185 {8110, 33788931}, {8111, 33789443}, {8112, 1}, {8114, 33789955},
1186 {8115, 33790467}, {8116, 33790979}, {8117, 2}, {8118, 1},
1187 {8119, 33791491}, {8120, 17014787}, {8121, 17015043}, {8122, 17012739},
1188 {8123, 16849923}, {8124, 33790467}, {8125, 33792515}, {8126, 16846851},
1189 {8127, 33792515}, {8128, 33793027}, {8129, 50570755}, {8130, 33794307},
1190 {8131, 33794819}, {8132, 33795331}, {8133, 2}, {8134, 1},
1191 {8135, 33795843}, {8136, 17019139}, {8137, 16850179}, {8138, 17017091},
1192 {8139, 16850435}, {8140, 33794819}, {8141, 50573827}, {8142, 50574595},
1193 {8143, 50575363}, {8144, 1}, {8147, 17021699}, {8148, 2},
1194 {8150, 1}, {8152, 17021955}, {8153, 17022211}, {8154, 17022467},
1195 {8155, 16850691}, {8156, 2}, {8157, 50577155}, {8158, 50577923},
1196 {8159, 50578691}, {8160, 1}, {8163, 17025027}, {8164, 1},
1197 {8168, 17025283}, {8169, 17025539}, {8170, 17025795}, {8171, 16851203},
1198 {8172, 17026051}, {8173, 50580739}, {8174, 50403587}, {8175, 17027075},
1199 {8176, 2}, {8178, 33804547}, {8179, 33805059}, {8180, 33805571},
1200 {8181, 2}, {8182, 1}, {8183, 33806083}, {8184, 17029379},
1201 {8185, 16850947}, {8186, 17027331}, {8187, 16851459}, {8188, 33805059},
1202 {8189, 33562883}, {8190, 33799939}, {8191, 2}, {8192, 16783875},
1203 {8203, 0}, {8204, 1}, {8206, 2}, {8208, 1},
1204 {8209, 17029635}, {8210, 1}, {8215, 33807107}, {8216, 1},
1205 {8228, 2}, {8231, 1}, {8232, 2}, {8239, 16783875},
1206 {8240, 1}, {8243, 33807619}, {8244, 50585347}, {8245, 1},
1207 {8246, 33808899}, {8247, 50586627}, {8248, 1}, {8252, 33810179},
1208 {8253, 1}, {8254, 33810691}, {8255, 1}, {8263, 33811203},
1209 {8264, 33811715}, {8265, 33812227}, {8266, 1}, {8279, 67362051},
1210 {8280, 1}, {8287, 16783875}, {8288, 0}, {8289, 2},
1211 {8292, 0}, {8293, 2}, {8304, 17035523}, {8305, 16779267},
1212 {8306, 2}, {8308, 16787715}, {8309, 17035779}, {8310, 17036035},
1213 {8311, 17036291}, {8312, 17036547}, {8313, 17036803}, {8314, 17037059},
1214 {8315, 17037315}, {8316, 17037571}, {8317, 17037827}, {8318, 17038083},
1215 {8319, 16780547}, {8320, 17035523}, {8321, 16786947}, {8322, 16785155},
1216 {8323, 16785411}, {8324, 16787715}, {8325, 17035779}, {8326, 17036035},
1217 {8327, 17036291}, {8328, 17036547}, {8329, 17036803}, {8330, 17037059},
1218 {8331, 17037315}, {8332, 17037571}, {8333, 17037827}, {8334, 17038083},
1219 {8335, 2}, {8336, 16777219}, {8337, 16778243}, {8338, 16780803},
1220 {8339, 16783107}, {8340, 16816387}, {8341, 16779011}, {8342, 16779779},
1221 {8343, 16780035}, {8344, 16780291}, {8345, 16780547}, {8346, 16781059},
1222 {8347, 16781827}, {8348, 16782083}, {8349, 2}, {8352, 1},
1223 {8360, 33558787}, {8361, 1}, {8385, 2}, {8400, 1},
1224 {8433, 2}, {8448, 50592771}, {8449, 50593539}, {8450, 16777731},
1225 {8451, 33817091}, {8452, 1}, {8453, 50594819}, {8454, 50595587},
1226 {8455, 16816643}, {8456, 1}, {8457, 33819139}, {8458, 16778755},
1227 {8459, 16779011}, {8463, 16802051}, {8464, 16779267}, {8466, 16780035},
1228 {8468, 1}, {8469, 16780547}, {8470, 33557763}, {8471, 1},
1229 {8473, 16781059}, {8474, 16781315}, {8475, 16781571}, {8478, 1},
1230 {8480, 33819651}, {8481, 50597379}, {8482, 33820931}, {8483, 1},
1231 {8484, 16783619}, {8485, 1}, {8486, 16857091}, {8487, 1},
1232 {8488, 16783619}, {8489, 1}, {8490, 16779779}, {8491, 16790787},
1233 {8492, 16777475}, {8493, 16777731}, {8494, 1}, {8495, 16778243},
1234 {8497, 16778499}, {8498, 2}, {8499, 16780291}, {8500, 16780803},
1235 {8501, 17044227}, {8502, 17044483}, {8503, 17044739}, {8504, 17044995},
1236 {8505, 16779267}, {8506, 1}, {8507, 50599683}, {8508, 16855043},
1237 {8509, 16852227}, {8511, 16855043}, {8512, 17046019}, {8513, 1},
1238 {8517, 16777987}, {8519, 16778243}, {8520, 16779267}, {8521, 16779523},
1239 {8522, 1}, {8528, 50600707}, {8529, 50601475}, {8530, 67379459},
1240 {8531, 50603267}, {8532, 50604035}, {8533, 50604803}, {8534, 50605571},
1241 {8535, 50606339}, {8536, 50607107}, {8537, 50607875}, {8538, 50608643},
1242 {8539, 50609411}, {8540, 50610179}, {8541, 50610947}, {8542, 50611715},
1243 {8543, 33564419}, {8544, 16779267}, {8545, 33835267}, {8546, 50612995},
1244 {8547, 33836547}, {8548, 16782595}, {8549, 33837059}, {8550, 50614787},
1245 {8551, 67392771}, {8552, 33839363}, {8553, 16783107}, {8554, 33839875},
1246 {8555, 50617603}, {8556, 16780035}, {8557, 16777731}, {8558, 16777987},
1247 {8559, 16780291}, {8560, 16779267}, {8561, 33835267}, {8562, 50612483},
1248 {8563, 33836547}, {8564, 16782595}, {8565, 33837059}, {8566, 50614787},
1249 {8567, 67392771}, {8568, 33839363}, {8569, 16783107}, {8570, 33839875},
1250 {8571, 50617603}, {8572, 16780035}, {8573, 16777731}, {8574, 16777987},
1251 {8575, 16780291}, {8576, 1}, {8579, 2}, {8580, 1},
1252 {8585, 50618371}, {8586, 1}, {8588, 2}, {8592, 1},
1253 {8748, 33841923}, {8749, 50619651}, {8750, 1}, {8751, 33843203},
1254 {8752, 50620931}, {8753, 1}, {9001, 17067267}, {9002, 17067523},
1255 {9003, 1}, {9255, 2}, {9280, 1}, {9291, 2},
1256 {9312, 16786947}, {9313, 16785155}, {9314, 16785411}, {9315, 16787715},
1257 {9316, 17035779}, {9317, 17036035}, {9318, 17036291}, {9319, 17036547},
1258 {9320, 17036803}, {9321, 33825539}, {9322, 33564163}, {9323, 33844995},
1259 {9324, 33845507}, {9325, 33846019}, {9326, 33846531}, {9327, 33847043},
1260 {9328, 33847555}, {9329, 33848067}, {9330, 33848579}, {9331, 33849091},
1261 {9332, 50626819}, {9333, 50627587}, {9334, 50628355}, {9335, 50629123},
1262 {9336, 50629891}, {9337, 50630659}, {9338, 50631427}, {9339, 50632195},
1263 {9340, 50632963}, {9341, 67410947}, {9342, 67411971}, {9343, 67412995},
1264 {9344, 67414019}, {9345, 67415043}, {9346, 67416067}, {9347, 67417091},
1265 {9348, 67418115}, {9349, 67419139}, {9350, 67420163}, {9351, 67421187},
1266 {9352, 2}, {9372, 50644995}, {9373, 50645763}, {9374, 50646531},
1267 {9375, 50647299}, {9376, 50648067}, {9377, 50648835}, {9378, 50649603},
1268 {9379, 50650371}, {9380, 50651139}, {9381, 50651907}, {9382, 50652675},
1269 {9383, 50653443}, {9384, 50654211}, {9385, 50654979}, {9386, 50655747},
1270 {9387, 50656515}, {9388, 50657283}, {9389, 50658051}, {9390, 50658819},
1271 {9391, 50659587}, {9392, 50660355}, {9393, 50661123}, {9394, 50661891},
1272 {9395, 50662659}, {9396, 50663427}, {9397, 50664195}, {9398, 16777219},
1273 {9399, 16777475}, {9400, 16777731}, {9401, 16777987}, {9402, 16778243},
1274 {9403, 16778499}, {9404, 16778755}, {9405, 16779011}, {9406, 16779267},
1275 {9407, 16779523}, {9408, 16779779}, {9409, 16780035}, {9410, 16780291},
1276 {9411, 16780547}, {9412, 16780803}, {9413, 16781059}, {9414, 16781315},
1277 {9415, 16781571}, {9416, 16781827}, {9417, 16782083}, {9418, 16782339},
1278 {9419, 16782595}, {9420, 16782851}, {9421, 16783107}, {9422, 16783363},
1279 {9423, 16783619}, {9424, 16777219}, {9425, 16777475}, {9426, 16777731},
1280 {9427, 16777987}, {9428, 16778243}, {9429, 16778499}, {9430, 16778755},
1281 {9431, 16779011}, {9432, 16779267}, {9433, 16779523}, {9434, 16779779},
1282 {9435, 16780035}, {9436, 16780291}, {9437, 16780547}, {9438, 16780803},
1283 {9439, 16781059}, {9440, 16781315}, {9441, 16781571}, {9442, 16781827},
1284 {9443, 16782083}, {9444, 16782339}, {9445, 16782595}, {9446, 16782851},
1285 {9447, 16783107}, {9448, 16783363}, {9449, 16783619}, {9450, 17035523},
1286 {9451, 1}, {10764, 67396355}, {10765, 1}, {10868, 50664963},
1287 {10869, 33888515}, {10870, 50665475}, {10871, 1}, {10972, 33889027},
1288 {10973, 1}, {11124, 2}, {11126, 1}, {11158, 2},
1289 {11159, 1}, {11264, 17112323}, {11265, 17112579}, {11266, 17112835},
1290 {11267, 17113091}, {11268, 17113347}, {11269, 17113603}, {11270, 17113859},
1291 {11271, 17114115}, {11272, 17114371}, {11273, 17114627}, {11274, 17114883},
1292 {11275, 17115139}, {11276, 17115395}, {11277, 17115651}, {11278, 17115907},
1293 {11279, 17116163}, {11280, 17116419}, {11281, 17116675}, {11282, 17116931},
1294 {11283, 17117187}, {11284, 17117443}, {11285, 17117699}, {11286, 17117955},
1295 {11287, 17118211}, {11288, 17118467}, {11289, 17118723}, {11290, 17118979},
1296 {11291, 17119235}, {11292, 17119491}, {11293, 17119747}, {11294, 17120003},
1297 {11295, 17120259}, {11296, 17120515}, {11297, 17120771}, {11298, 17121027},
1298 {11299, 17121283}, {11300, 17121539}, {11301, 17121795}, {11302, 17122051},
1299 {11303, 17122307}, {11304, 17122563}, {11305, 17122819}, {11306, 17123075},
1300 {11307, 17123331}, {11308, 17123587}, {11309, 17123843}, {11310, 17124099},
1301 {11311, 17124355}, {11312, 1}, {11360, 17124611}, {11361, 1},
1302 {11362, 17124867}, {11363, 17125123}, {11364, 17125379}, {11365, 1},
1303 {11367, 17125635}, {11368, 1}, {11369, 17125891}, {11370, 1},
1304 {11371, 17126147}, {11372, 1}, {11373, 16948483}, {11374, 16953091},
1305 {11375, 16948227}, {11376, 16950275}, {11377, 1}, {11378, 17126403},
1306 {11379, 1}, {11381, 17126659}, {11382, 1}, {11388, 16779523},
1307 {11389, 16782595}, {11390, 17126915}, {11391, 17127171}, {11392, 17127427},
1308 {11393, 1}, {11394, 17127683}, {11395, 1}, {11396, 17127939},
1309 {11397, 1}, {11398, 17128195}, {11399, 1}, {11400, 17128451},
1310 {11401, 1}, {11402, 17128707}, {11403, 1}, {11404, 17128963},
1311 {11405, 1}, {11406, 17129219}, {11407, 1}, {11408, 17129475},
1312 {11409, 1}, {11410, 17129731}, {11411, 1}, {11412, 17129987},
1313 {11413, 1}, {11414, 17130243}, {11415, 1}, {11416, 17130499},
1314 {11417, 1}, {11418, 17130755}, {11419, 1}, {11420, 17131011},
1315 {11421, 1}, {11422, 17131267}, {11423, 1}, {11424, 17131523},
1316 {11425, 1}, {11426, 17131779}, {11427, 1}, {11428, 17132035},
1317 {11429, 1}, {11430, 17132291}, {11431, 1}, {11432, 17132547},
1318 {11433, 1}, {11434, 17132803}, {11435, 1}, {11436, 17133059},
1319 {11437, 1}, {11438, 17133315}, {11439, 1}, {11440, 17133571},
1320 {11441, 1}, {11442, 17133827}, {11443, 1}, {11444, 17134083},
1321 {11445, 1}, {11446, 17134339}, {11447, 1}, {11448, 17134595},
1322 {11449, 1}, {11450, 17134851}, {11451, 1}, {11452, 17135107},
1323 {11453, 1}, {11454, 17135363}, {11455, 1}, {11456, 17135619},
1324 {11457, 1}, {11458, 17135875}, {11459, 1}, {11460, 17136131},
1325 {11461, 1}, {11462, 17136387}, {11463, 1}, {11464, 17136643},
1326 {11465, 1}, {11466, 17136899}, {11467, 1}, {11468, 17137155},
1327 {11469, 1}, {11470, 17137411}, {11471, 1}, {11472, 17137667},
1328 {11473, 1}, {11474, 17137923}, {11475, 1}, {11476, 17138179},
1329 {11477, 1}, {11478, 17138435}, {11479, 1}, {11480, 17138691},
1330 {11481, 1}, {11482, 17138947}, {11483, 1}, {11484, 17139203},
1331 {11485, 1}, {11486, 17139459}, {11487, 1}, {11488, 17139715},
1332 {11489, 1}, {11490, 17139971}, {11491, 1}, {11499, 17140227},
1333 {11500, 1}, {11501, 17140483}, {11502, 1}, {11506, 17140739},
1334 {11507, 1}, {11508, 2}, {11513, 1}, {11558, 2},
1335 {11559, 1}, {11560, 2}, {11565, 1}, {11566, 2},
1336 {11568, 1}, {11624, 2}, {11631, 17140995}, {11632, 1},
1337 {11633, 2}, {11647, 1}, {11671, 2}, {11680, 1},
1338 {11687, 2}, {11688, 1}, {11695, 2}, {11696, 1},
1339 {11703, 2}, {11704, 1}, {11711, 2}, {11712, 1},
1340 {11719, 2}, {11720, 1}, {11727, 2}, {11728, 1},
1341 {11735, 2}, {11736, 1}, {11743, 2}, {11744, 1},
1342 {11870, 2}, {11904, 1}, {11930, 2}, {11931, 1},
1343 {11935, 17141251}, {11936, 1}, {12019, 17141507}, {12020, 2},
1344 {12032, 17141763}, {12033, 17142019}, {12034, 17142275}, {12035, 17142531},
1345 {12036, 17142787}, {12037, 17143043}, {12038, 17143299}, {12039, 17143555},
1346 {12040, 17143811}, {12041, 17144067}, {12042, 17144323}, {12043, 17144579},
1347 {12044, 17144835}, {12045, 17145091}, {12046, 17145347}, {12047, 17145603},
1348 {12048, 17145859}, {12049, 17146115}, {12050, 17146371}, {12051, 17146627},
1349 {12052, 17146883}, {12053, 17147139}, {12054, 17147395}, {12055, 17147651},
1350 {12056, 17147907}, {12057, 17148163}, {12058, 17148419}, {12059, 17148675},
1351 {12060, 17148931}, {12061, 17149187}, {12062, 17149443}, {12063, 17149699},
1352 {12064, 17149955}, {12065, 17150211}, {12066, 17150467}, {12067, 17150723},
1353 {12068, 17150979}, {12069, 17151235}, {12070, 17151491}, {12071, 17151747},
1354 {12072, 17152003}, {12073, 17152259}, {12074, 17152515}, {12075, 17152771},
1355 {12076, 17153027}, {12077, 17153283}, {12078, 17153539}, {12079, 17153795},
1356 {12080, 17154051}, {12081, 17154307}, {12082, 17154563}, {12083, 17154819},
1357 {12084, 17155075}, {12085, 17155331}, {12086, 17155587}, {12087, 17155843},
1358 {12088, 17156099}, {12089, 17156355}, {12090, 17156611}, {12091, 17156867},
1359 {12092, 17157123}, {12093, 17157379}, {12094, 17157635}, {12095, 17157891},
1360 {12096, 17158147}, {12097, 17158403}, {12098, 17158659}, {12099, 17158915},
1361 {12100, 17159171}, {12101, 17159427}, {12102, 17159683}, {12103, 17159939},
1362 {12104, 17160195}, {12105, 17160451}, {12106, 17160707}, {12107, 17160963},
1363 {12108, 17161219}, {12109, 17161475}, {12110, 17161731}, {12111, 17161987},
1364 {12112, 17162243}, {12113, 17162499}, {12114, 17162755}, {12115, 17163011},
1365 {12116, 17163267}, {12117, 17163523}, {12118, 17163779}, {12119, 17164035},
1366 {12120, 17164291}, {12121, 17164547}, {12122, 17164803}, {12123, 17165059},
1367 {12124, 17165315}, {12125, 17165571}, {12126, 17165827}, {12127, 17166083},
1368 {12128, 17166339}, {12129, 17166595}, {12130, 17166851}, {12131, 17167107},
1369 {12132, 17167363}, {12133, 17167619}, {12134, 17167875}, {12135, 17168131},
1370 {12136, 17168387}, {12137, 17168643}, {12138, 17168899}, {12139, 17169155},
1371 {12140, 17169411}, {12141, 17169667}, {12142, 17169923}, {12143, 17170179},
1372 {12144, 17170435}, {12145, 17170691}, {12146, 17170947}, {12147, 17171203},
1373 {12148, 17171459}, {12149, 17171715}, {12150, 17171971}, {12151, 17172227},
1374 {12152, 17172483}, {12153, 17172739}, {12154, 17172995}, {12155, 17173251},
1375 {12156, 17173507}, {12157, 17173763}, {12158, 17174019}, {12159, 17174275},
1376 {12160, 17174531}, {12161, 17174787}, {12162, 17175043}, {12163, 17175299},
1377 {12164, 17175555}, {12165, 17175811}, {12166, 17176067}, {12167, 17176323},
1378 {12168, 17176579}, {12169, 17176835}, {12170, 17177091}, {12171, 17177347},
1379 {12172, 17177603}, {12173, 17177859}, {12174, 17178115}, {12175, 17178371},
1380 {12176, 17178627}, {12177, 17178883}, {12178, 17179139}, {12179, 17179395},
1381 {12180, 17179651}, {12181, 17179907}, {12182, 17180163}, {12183, 17180419},
1382 {12184, 17180675}, {12185, 17180931}, {12186, 17181187}, {12187, 17181443},
1383 {12188, 17181699}, {12189, 17181955}, {12190, 17182211}, {12191, 17182467},
1384 {12192, 17182723}, {12193, 17182979}, {12194, 17183235}, {12195, 17183491},
1385 {12196, 17183747}, {12197, 17184003}, {12198, 17184259}, {12199, 17184515},
1386 {12200, 17184771}, {12201, 17185027}, {12202, 17185283}, {12203, 17185539},
1387 {12204, 17185795}, {12205, 17186051}, {12206, 17186307}, {12207, 17186563},
1388 {12208, 17186819}, {12209, 17187075}, {12210, 17187331}, {12211, 17187587},
1389 {12212, 17187843}, {12213, 17188099}, {12214, 17188355}, {12215, 17188611},
1390 {12216, 17188867}, {12217, 17189123}, {12218, 17189379}, {12219, 17189635},
1391 {12220, 17189891}, {12221, 17190147}, {12222, 17190403}, {12223, 17190659},
1392 {12224, 17190915}, {12225, 17191171}, {12226, 17191427}, {12227, 17191683},
1393 {12228, 17191939}, {12229, 17192195}, {12230, 17192451}, {12231, 17192707},
1394 {12232, 17192963}, {12233, 17193219}, {12234, 17193475}, {12235, 17193731},
1395 {12236, 17193987}, {12237, 17194243}, {12238, 17194499}, {12239, 17194755},
1396 {12240, 17195011}, {12241, 17195267}, {12242, 17195523}, {12243, 17195779},
1397 {12244, 17196035}, {12245, 17196291}, {12246, 2}, {12288, 16783875},
1398 {12289, 1}, {12290, 17196547}, {12291, 1}, {12342, 17196803},
1399 {12343, 1}, {12344, 17147651}, {12345, 17197059}, {12346, 17197315},
1400 {12347, 1}, {12352, 2}, {12353, 1}, {12439, 2},
1401 {12441, 1}, {12443, 33974787}, {12444, 33975299}, {12445, 1},
1402 {12447, 33975811}, {12448, 1}, {12543, 33976323}, {12544, 2},
1403 {12549, 1}, {12592, 2}, {12593, 17199619}, {12594, 17199875},
1404 {12595, 17200131}, {12596, 17200387}, {12597, 17200643}, {12598, 17200899},
1405 {12599, 17201155}, {12600, 17201411}, {12601, 17201667}, {12602, 17201923},
1406 {12603, 17202179}, {12604, 17202435}, {12605, 17202691}, {12606, 17202947},
1407 {12607, 17203203}, {12608, 17203459}, {12609, 17203715}, {12610, 17203971},
1408 {12611, 17204227}, {12612, 17204483}, {12613, 17204739}, {12614, 17204995},
1409 {12615, 17205251}, {12616, 17205507}, {12617, 17205763}, {12618, 17206019},
1410 {12619, 17206275}, {12620, 17206531}, {12621, 17206787}, {12622, 17207043},
1411 {12623, 17207299}, {12624, 17207555}, {12625, 17207811}, {12626, 17208067},
1412 {12627, 17208323}, {12628, 17208579}, {12629, 17208835}, {12630, 17209091},
1413 {12631, 17209347}, {12632, 17209603}, {12633, 17209859}, {12634, 17210115},
1414 {12635, 17210371}, {12636, 17210627}, {12637, 17210883}, {12638, 17211139},
1415 {12639, 17211395}, {12640, 17211651}, {12641, 17211907}, {12642, 17212163},
1416 {12643, 17212419}, {12644, 2}, {12645, 17212675}, {12646, 17212931},
1417 {12647, 17213187}, {12648, 17213443}, {12649, 17213699}, {12650, 17213955},
1418 {12651, 17214211}, {12652, 17214467}, {12653, 17214723}, {12654, 17214979},
1419 {12655, 17215235}, {12656, 17215491}, {12657, 17215747}, {12658, 17216003},
1420 {12659, 17216259}, {12660, 17216515}, {12661, 17216771}, {12662, 17217027},
1421 {12663, 17217283}, {12664, 17217539}, {12665, 17217795}, {12666, 17218051},
1422 {12667, 17218307}, {12668, 17218563}, {12669, 17218819}, {12670, 17219075},
1423 {12671, 17219331}, {12672, 17219587}, {12673, 17219843}, {12674, 17220099},
1424 {12675, 17220355}, {12676, 17220611}, {12677, 17220867}, {12678, 17221123},
1425 {12679, 17221379}, {12680, 17221635}, {12681, 17221891}, {12682, 17222147},
1426 {12683, 17222403}, {12684, 17222659}, {12685, 17222915}, {12686, 17223171},
1427 {12687, 2}, {12688, 1}, {12690, 17141763}, {12691, 17143299},
1428 {12692, 17223427}, {12693, 17223683}, {12694, 17223939}, {12695, 17224195},
1429 {12696, 17224451}, {12697, 17224707}, {12698, 17142787}, {12699, 17224963},
1430 {12700, 17225219}, {12701, 17225475}, {12702, 17225731}, {12703, 17143811},
1431 {12704, 1}, {12772, 2}, {12784, 1}, {12800, 50780419},
1432 {12801, 50781187}, {12802, 50781955}, {12803, 50782723}, {12804, 50783491},
1433 {12805, 50784259}, {12806, 50785027}, {12807, 50785795}, {12808, 50786563},
1434 {12809, 50787331}, {12810, 50788099}, {12811, 50788867}, {12812, 50789635},
1435 {12813, 50790403}, {12814, 50791171}, {12815, 50791939}, {12816, 50792707},
1436 {12817, 50793475}, {12818, 50794243}, {12819, 50795011}, {12820, 50795779},
1437 {12821, 50796547}, {12822, 50797315}, {12823, 50798083}, {12824, 50798851},
1438 {12825, 50799619}, {12826, 50800387}, {12827, 50801155}, {12828, 50801923},
1439 {12829, 67579907}, {12830, 67580931}, {12831, 2}, {12832, 50804739},
1440 {12833, 50805507}, {12834, 50806275}, {12835, 50807043}, {12836, 50807811},
1441 {12837, 50808579}, {12838, 50809347}, {12839, 50810115}, {12840, 50810883},
1442 {12841, 50811651}, {12842, 50812419}, {12843, 50813187}, {12844, 50813955},
1443 {12845, 50814723}, {12846, 50815491}, {12847, 50816259}, {12848, 50817027},
1444 {12849, 50817795}, {12850, 50818563}, {12851, 50819331}, {12852, 50820099},
1445 {12853, 50820867}, {12854, 50821635}, {12855, 50822403}, {12856, 50823171},
1446 {12857, 50823939}, {12858, 50824707}, {12859, 50825475}, {12860, 50826243},
1447 {12861, 50827011}, {12862, 50827779}, {12863, 50828547}, {12864, 50829315},
1448 {12865, 50830083}, {12866, 50830851}, {12867, 50831619}, {12868, 17277955},
1449 {12869, 17278211}, {12870, 17158659}, {12871, 17278467}, {12872, 1},
1450 {12880, 50833155}, {12881, 33845251}, {12882, 34056707}, {12883, 33562371},
1451 {12884, 34057219}, {12885, 34057731}, {12886, 34058243}, {12887, 34058755},
1452 {12888, 34059267}, {12889, 34059779}, {12890, 34060291}, {12891, 33827331},
1453 {12892, 33826563}, {12893, 34060803}, {12894, 34061315}, {12895, 34061827},
1454 {12896, 17199619}, {12897, 17200387}, {12898, 17201155}, {12899, 17201667},
1455 {12900, 17203715}, {12901, 17203971}, {12902, 17204739}, {12903, 17205251},
1456 {12904, 17205507}, {12905, 17206019}, {12906, 17206275}, {12907, 17206531},
1457 {12908, 17206787}, {12909, 17207043}, {12910, 17236995}, {12911, 17237763},
1458 {12912, 17238531}, {12913, 17239299}, {12914, 17240067}, {12915, 17240835},
1459 {12916, 17241603}, {12917, 17242371}, {12918, 17243139}, {12919, 17243907},
1460 {12920, 17244675}, {12921, 17245443}, {12922, 17246211}, {12923, 17246979},
1461 {12924, 34062339}, {12925, 34062851}, {12926, 17286147}, {12927, 1},
1462 {12928, 17141763}, {12929, 17143299}, {12930, 17223427}, {12931, 17223683},
1463 {12932, 17253635}, {12933, 17254403}, {12934, 17255171}, {12935, 17144579},
1464 {12936, 17256707}, {12937, 17147651}, {12938, 17160451}, {12939, 17163523},
1465 {12940, 17163267}, {12941, 17160707}, {12942, 17184259}, {12943, 17149699},
1466 {12944, 17159939}, {12945, 17263619}, {12946, 17264387}, {12947, 17265155},
1467 {12948, 17265923}, {12949, 17266691}, {12950, 17267459}, {12951, 17268227},
1468 {12952, 17268995}, {12953, 17286403}, {12954, 17286659}, {12955, 17151235},
1469 {12956, 17286915}, {12957, 17287171}, {12958, 17287427}, {12959, 17287683},
1470 {12960, 17287939}, {12961, 17275907}, {12962, 17288195}, {12963, 17288451},
1471 {12964, 17223939}, {12965, 17224195}, {12966, 17224451}, {12967, 17288707},
1472 {12968, 17288963}, {12969, 17289219}, {12970, 17289475}, {12971, 17271299},
1473 {12972, 17272067}, {12973, 17272835}, {12974, 17273603}, {12975, 17274371},
1474 {12976, 17289731}, {12977, 34067203}, {12978, 34067715}, {12979, 34068227},
1475 {12980, 34068739}, {12981, 34069251}, {12982, 33564931}, {12983, 34057475},
1476 {12984, 34061571}, {12985, 34069763}, {12986, 34070275}, {12987, 34070787},
1477 {12988, 34071299}, {12989, 34071811}, {12990, 34072323}, {12991, 34072835},
1478 {12992, 34073347}, {12993, 34073859}, {12994, 34074371}, {12995, 34074883},
1479 {12996, 34075395}, {12997, 34075907}, {12998, 34076419}, {12999, 34076931},
1480 {13000, 34077443}, {13001, 50855171}, {13002, 50855939}, {13003, 50856707},
1481 {13004, 34080259}, {13005, 50857987}, {13006, 34081539}, {13007, 50859267},
1482 {13008, 17305603}, {13009, 17305859}, {13010, 17306115}, {13011, 17306371},
1483 {13012, 17306627}, {13013, 17306883}, {13014, 17307139}, {13015, 17307395},
1484 {13016, 17307651}, {13017, 17199107}, {13018, 17307907}, {13019, 17308163},
1485 {13020, 17308419}, {13021, 17308675}, {13022, 17308931}, {13023, 17309187},
1486 {13024, 17309443}, {13025, 17309699}, {13026, 17309955}, {13027, 17199363},
1487 {13028, 17310211}, {13029, 17310467}, {13030, 17310723}, {13031, 17310979},
1488 {13032, 17311235}, {13033, 17311491}, {13034, 17311747}, {13035, 17312003},
1489 {13036, 17312259}, {13037, 17312515}, {13038, 17312771}, {13039, 17313027},
1490 {13040, 17313283}, {13041, 17313539}, {13042, 17313795}, {13043, 17314051},
1491 {13044, 17314307}, {13045, 17314563}, {13046, 17314819}, {13047, 17315075},
1492 {13048, 17315331}, {13049, 17315587}, {13050, 17315843}, {13051, 17316099},
1493 {13052, 17316355}, {13053, 17316611}, {13054, 17316867}, {13055, 34094339},
1494 {13056, 67649283}, {13057, 67650307}, {13058, 67651331}, {13059, 50875139},
1495 {13060, 67653123}, {13061, 50876931}, {13062, 50877699}, {13063, 84432899},
1496 {13064, 67656963}, {13065, 50880771}, {13066, 50881539}, {13067, 50882307},
1497 {13068, 67660291}, {13069, 67661315}, {13070, 50885123}, {13071, 50885891},
1498 {13072, 34109443}, {13073, 50887171}, {13074, 67665155}, {13075, 67666179},
1499 {13076, 34112771}, {13077, 84444931}, {13078, 101223427}, {13079, 84447747},
1500 {13080, 50891011}, {13081, 84449027}, {13082, 84450307}, {13083, 67674371},
1501 {13084, 50898179}, {13085, 50898947}, {13086, 50899715}, {13087, 67677699},
1502 {13088, 84455939}, {13089, 67680003}, {13090, 50903811}, {13091, 50904579},
1503 {13092, 50905347}, {13093, 34128899}, {13094, 34129411}, {13095, 34118147},
1504 {13096, 34129923}, {13097, 50907651}, {13098, 50908419}, {13099, 84463619},
1505 {13100, 50910467}, {13101, 67688451}, {13102, 84466691}, {13103, 50913539},
1506 {13104, 34137091}, {13105, 34137603}, {13106, 84469763}, {13107, 67693827},
1507 {13108, 84472067}, {13109, 50918915}, {13110, 84474115}, {13111, 34143747},
1508 {13112, 50921475}, {13113, 50922243}, {13114, 50923011}, {13115, 50923779},
1509 {13116, 50924547}, {13117, 67702531}, {13118, 50926339}, {13119, 34149891},
1510 {13120, 50927619}, {13121, 50928387}, {13122, 50929155}, {13123, 67707139},
1511 {13124, 50930947}, {13125, 50931715}, {13126, 50932483}, {13127, 84487683},
1512 {13128, 67711747}, {13129, 34158339}, {13130, 84490499}, {13131, 34160131},
1513 {13132, 67715075}, {13133, 67669507}, {13134, 50938883}, {13135, 50939651},
1514 {13136, 50940419}, {13137, 67718403}, {13138, 34164995}, {13139, 50942723},
1515 {13140, 67720707}, {13141, 34167299}, {13142, 84499459}, {13143, 50893827},
1516 {13144, 34169091}, {13145, 34169603}, {13146, 34170115}, {13147, 34170627},
1517 {13148, 34171139}, {13149, 34171651}, {13150, 34172163}, {13151, 34172675},
1518 {13152, 34173187}, {13153, 34173699}, {13154, 50951427}, {13155, 50952195},
1519 {13156, 50952963}, {13157, 50953731}, {13158, 50954499}, {13159, 50955267},
1520 {13160, 50956035}, {13161, 50956803}, {13162, 50957571}, {13163, 50958339},
1521 {13164, 50959107}, {13165, 50959875}, {13166, 50960643}, {13167, 50961411},
1522 {13168, 50962179}, {13169, 50962947}, {13170, 34186499}, {13171, 34187011},
1523 {13172, 50964739}, {13173, 34188291}, {13174, 34188803}, {13175, 34189315},
1524 {13176, 50967043}, {13177, 50967811}, {13178, 34191363}, {13179, 34191875},
1525 {13180, 34192387}, {13181, 34192899}, {13182, 34193411}, {13183, 67748355},
1526 {13184, 34185987}, {13185, 34194947}, {13186, 34195459}, {13187, 34195971},
1527 {13188, 34196483}, {13189, 34196995}, {13190, 34197507}, {13191, 34198019},
1528 {13192, 50975747}, {13193, 67753731}, {13194, 34200323}, {13195, 34200835},
1529 {13196, 34201347}, {13197, 34201859}, {13198, 34202371}, {13199, 34202883},
1530 {13200, 34203395}, {13201, 50981123}, {13202, 50981891}, {13203, 50980355},
1531 {13204, 50982659}, {13205, 34206211}, {13206, 34206723}, {13207, 34207235},
1532 {13208, 33556995}, {13209, 34207747}, {13210, 34208259}, {13211, 34208771},
1533 {13212, 34209283}, {13213, 34209795}, {13214, 34210307}, {13215, 50988035},
1534 {13216, 50988803}, {13217, 34190083}, {13218, 50989571}, {13219, 50990339},
1535 {13220, 50991107}, {13221, 34190851}, {13222, 50991875}, {13223, 50992643},
1536 {13224, 67770627}, {13225, 34185987}, {13226, 50994435}, {13227, 50995203},
1537 {13228, 50995971}, {13229, 50996739}, {13230, 84551939}, {13231, 101330435},
1538 {13232, 34223107}, {13233, 34223619}, {13234, 34224131}, {13235, 34224643},
1539 {13236, 34225155}, {13237, 34225667}, {13238, 34226179}, {13239, 34226691},
1540 {13240, 34227203}, {13241, 34226691}, {13242, 34227715}, {13243, 34228227},
1541 {13244, 34228739}, {13245, 34229251}, {13246, 34229763}, {13247, 34229251},
1542 {13248, 34230275}, {13249, 34230787}, {13250, 2}, {13251, 34231299},
1543 {13252, 33817347}, {13253, 33554947}, {13254, 67786243}, {13255, 2},
1544 {13256, 34232835}, {13257, 34233347}, {13258, 34233859}, {13259, 34185731},
1545 {13260, 34234371}, {13261, 34234883}, {13262, 34210307}, {13263, 34235395},
1546 {13264, 33557251}, {13265, 34235907}, {13266, 51013635}, {13267, 34237187},
1547 {13268, 34197507}, {13269, 51014915}, {13270, 51015683}, {13271, 34239235},
1548 {13272, 2}, {13273, 51016963}, {13274, 34240515}, {13275, 34221315},
1549 {13276, 34241027}, {13277, 34241539}, {13278, 51019267}, {13279, 51020035},
1550 {13280, 34243587}, {13281, 34244099}, {13282, 34244611}, {13283, 34245123},
1551 {13284, 34245635}, {13285, 34246147}, {13286, 34246659}, {13287, 34247171},
1552 {13288, 34247683}, {13289, 51025411}, {13290, 51026179}, {13291, 51026947},
1553 {13292, 51027715}, {13293, 51028483}, {13294, 51029251}, {13295, 51030019},
1554 {13296, 51030787}, {13297, 51031555}, {13298, 51032323}, {13299, 51033091},
1555 {13300, 51033859}, {13301, 51034627}, {13302, 51035395}, {13303, 51036163},
1556 {13304, 51036931}, {13305, 51037699}, {13306, 51038467}, {13307, 51039235},
1557 {13308, 51040003}, {13309, 51040771}, {13310, 51041539}, {13311, 51042307},
1558 {13312, 1}, {42125, 2}, {42128, 1}, {42183, 2},
1559 {42192, 1}, {42540, 2}, {42560, 17488643}, {42561, 1},
1560 {42562, 17488899}, {42563, 1}, {42564, 17489155}, {42565, 1},
1561 {42566, 17489411}, {42567, 1}, {42568, 17489667}, {42569, 1},
1562 {42570, 16936451}, {42571, 1}, {42572, 17489923}, {42573, 1},
1563 {42574, 17490179}, {42575, 1}, {42576, 17490435}, {42577, 1},
1564 {42578, 17490691}, {42579, 1}, {42580, 17490947}, {42581, 1},
1565 {42582, 17491203}, {42583, 1}, {42584, 17491459}, {42585, 1},
1566 {42586, 17491715}, {42587, 1}, {42588, 17491971}, {42589, 1},
1567 {42590, 17492227}, {42591, 1}, {42592, 17492483}, {42593, 1},
1568 {42594, 17492739}, {42595, 1}, {42596, 17492995}, {42597, 1},
1569 {42598, 17493251}, {42599, 1}, {42600, 17493507}, {42601, 1},
1570 {42602, 17493763}, {42603, 1}, {42604, 17494019}, {42605, 1},
1571 {42624, 17494275}, {42625, 1}, {42626, 17494531}, {42627, 1},
1572 {42628, 17494787}, {42629, 1}, {42630, 17495043}, {42631, 1},
1573 {42632, 17495299}, {42633, 1}, {42634, 17495555}, {42635, 1},
1574 {42636, 17495811}, {42637, 1}, {42638, 17496067}, {42639, 1},
1575 {42640, 17496323}, {42641, 1}, {42642, 17496579}, {42643, 1},
1576 {42644, 17496835}, {42645, 1}, {42646, 17497091}, {42647, 1},
1577 {42648, 17497347}, {42649, 1}, {42650, 17497603}, {42651, 1},
1578 {42652, 16873219}, {42653, 16873731}, {42654, 1}, {42744, 2},
1579 {42752, 1}, {42786, 17497859}, {42787, 1}, {42788, 17498115},
1580 {42789, 1}, {42790, 17498371}, {42791, 1}, {42792, 17498627},
1581 {42793, 1}, {42794, 17498883}, {42795, 1}, {42796, 17499139},
1582 {42797, 1}, {42798, 17499395}, {42799, 1}, {42802, 17499651},
1583 {42803, 1}, {42804, 17499907}, {42805, 1}, {42806, 17500163},
1584 {42807, 1}, {42808, 17500419}, {42809, 1}, {42810, 17500675},
1585 {42811, 1}, {42812, 17500931}, {42813, 1}, {42814, 17501187},
1586 {42815, 1}, {42816, 17501443}, {42817, 1}, {42818, 17501699},
1587 {42819, 1}, {42820, 17501955}, {42821, 1}, {42822, 17502211},
1588 {42823, 1}, {42824, 17502467}, {42825, 1}, {42826, 17502723},
1589 {42827, 1}, {42828, 17502979}, {42829, 1}, {42830, 17503235},
1590 {42831, 1}, {42832, 17503491}, {42833, 1}, {42834, 17503747},
1591 {42835, 1}, {42836, 17504003}, {42837, 1}, {42838, 17504259},
1592 {42839, 1}, {42840, 17504515}, {42841, 1}, {42842, 17504771},
1593 {42843, 1}, {42844, 17505027}, {42845, 1}, {42846, 17505283},
1594 {42847, 1}, {42848, 17505539}, {42849, 1}, {42850, 17505795},
1595 {42851, 1}, {42852, 17506051}, {42853, 1}, {42854, 17506307},
1596 {42855, 1}, {42856, 17506563}, {42857, 1}, {42858, 17506819},
1597 {42859, 1}, {42860, 17507075}, {42861, 1}, {42862, 17507331},
1598 {42863, 1}, {42864, 17507331}, {42865, 1}, {42873, 17507587},
1599 {42874, 1}, {42875, 17507843}, {42876, 1}, {42877, 17508099},
1600 {42878, 17508355}, {42879, 1}, {42880, 17508611}, {42881, 1},
1601 {42882, 17508867}, {42883, 1}, {42884, 17509123}, {42885, 1},
1602 {42886, 17509379}, {42887, 1}, {42891, 17509635}, {42892, 1},
1603 {42893, 16951299}, {42894, 1}, {42896, 17509891}, {42897, 1},
1604 {42898, 17510147}, {42899, 1}, {42902, 17510403}, {42903, 1},
1605 {42904, 17510659}, {42905, 1}, {42906, 17510915}, {42907, 1},
1606 {42908, 17511171}, {42909, 1}, {42910, 17511427}, {42911, 1},
1607 {42912, 17511683}, {42913, 1}, {42914, 17511939}, {42915, 1},
1608 {42916, 17512195}, {42917, 1}, {42918, 17512451}, {42919, 1},
1609 {42920, 17512707}, {42921, 1}, {42922, 16841475}, {42923, 16948995},
1610 {42924, 16951043}, {42925, 17512963}, {42926, 16951555}, {42927, 1},
1611 {42928, 17513219}, {42929, 17513475}, {42930, 16952067}, {42931, 17513731},
1612 {42932, 17513987}, {42933, 1}, {42934, 17514243}, {42935, 1},
1613 {42936, 17514499}, {42937, 1}, {42938, 17514755}, {42939, 1},
1614 {42940, 17515011}, {42941, 1}, {42942, 17515267}, {42943, 1},
1615 {42944, 17515523}, {42945, 1}, {42946, 17515779}, {42947, 1},
1616 {42948, 17516035}, {42949, 16954371}, {42950, 17516291}, {42951, 17516547},
1617 {42952, 1}, {42953, 17516803}, {42954, 1}, {42955, 2},
1618 {42960, 17517059}, {42961, 1}, {42962, 2}, {42963, 1},
1619 {42964, 2}, {42965, 1}, {42966, 17517315}, {42967, 1},
1620 {42968, 17517571}, {42969, 1}, {42970, 2}, {42994, 16777731},
1621 {42995, 16778499}, {42996, 16781315}, {42997, 17517827}, {42998, 1},
1622 {43000, 16802051}, {43001, 16808195}, {43002, 1}, {43053, 2},
1623 {43056, 1}, {43066, 2}, {43072, 1}, {43128, 2},
1624 {43136, 1}, {43206, 2}, {43214, 1}, {43226, 2},
1625 {43232, 1}, {43348, 2}, {43359, 1}, {43389, 2},
1626 {43392, 1}, {43470, 2}, {43471, 1}, {43482, 2},
1627 {43486, 1}, {43519, 2}, {43520, 1}, {43575, 2},
1628 {43584, 1}, {43598, 2}, {43600, 1}, {43610, 2},
1629 {43612, 1}, {43715, 2}, {43739, 1}, {43767, 2},
1630 {43777, 1}, {43783, 2}, {43785, 1}, {43791, 2},
1631 {43793, 1}, {43799, 2}, {43808, 1}, {43815, 2},
1632 {43816, 1}, {43823, 2}, {43824, 1}, {43868, 17498371},
1633 {43869, 17518083}, {43870, 17124867}, {43871, 17518339}, {43872, 1},
1634 {43881, 17518595}, {43882, 1}, {43884, 2}, {43888, 17518851},
1635 {43889, 17519107}, {43890, 17519363}, {43891, 17519619}, {43892, 17519875},
1636 {43893, 17520131}, {43894, 17520387}, {43895, 17520643}, {43896, 17520899},
1637 {43897, 17521155}, {43898, 17521411}, {43899, 17521667}, {43900, 17521923},
1638 {43901, 17522179}, {43902, 17522435}, {43903, 17522691}, {43904, 17522947},
1639 {43905, 17523203}, {43906, 17523459}, {43907, 17523715}, {43908, 17523971},
1640 {43909, 17524227}, {43910, 17524483}, {43911, 17524739}, {43912, 17524995},
1641 {43913, 17525251}, {43914, 17525507}, {43915, 17525763}, {43916, 17526019},
1642 {43917, 17526275}, {43918, 17526531}, {43919, 17526787}, {43920, 17527043},
1643 {43921, 17527299}, {43922, 17527555}, {43923, 17527811}, {43924, 17528067},
1644 {43925, 17528323}, {43926, 17528579}, {43927, 17528835}, {43928, 17529091},
1645 {43929, 17529347}, {43930, 17529603}, {43931, 17529859}, {43932, 17530115},
1646 {43933, 17530371}, {43934, 17530627}, {43935, 17530883}, {43936, 17531139},
1647 {43937, 17531395}, {43938, 17531651}, {43939, 17531907}, {43940, 17532163},
1648 {43941, 17532419}, {43942, 17532675}, {43943, 17532931}, {43944, 17533187},
1649 {43945, 17533443}, {43946, 17533699}, {43947, 17533955}, {43948, 17534211},
1650 {43949, 17534467}, {43950, 17534723}, {43951, 17534979}, {43952, 17535235},
1651 {43953, 17535491}, {43954, 17535747}, {43955, 17536003}, {43956, 17536259},
1652 {43957, 17536515}, {43958, 17536771}, {43959, 17537027}, {43960, 17537283},
1653 {43961, 17537539}, {43962, 17537795}, {43963, 17538051}, {43964, 17538307},
1654 {43965, 17538563}, {43966, 17538819}, {43967, 17539075}, {43968, 1},
1655 {44014, 2}, {44016, 1}, {44026, 2}, {44032, 1},
1656 {55204, 2}, {55216, 1}, {55239, 2}, {55243, 1},
1657 {55292, 2}, {63744, 17539331}, {63745, 17539587}, {63746, 17182211},
1658 {63747, 17539843}, {63748, 17540099}, {63749, 17540355}, {63750, 17540611},
1659 {63751, 17196035}, {63753, 17540867}, {63754, 17184259}, {63755, 17541123},
1660 {63756, 17541379}, {63757, 17541635}, {63758, 17541891}, {63759, 17542147},
1661 {63760, 17542403}, {63761, 17542659}, {63762, 17542915}, {63763, 17543171},
1662 {63764, 17543427}, {63765, 17543683}, {63766, 17543939}, {63767, 17544195},
1663 {63768, 17544451}, {63769, 17544707}, {63770, 17544963}, {63771, 17545219},
1664 {63772, 17545475}, {63773, 17545731}, {63774, 17545987}, {63775, 17546243},
1665 {63776, 17546499}, {63777, 17546755}, {63778, 17547011}, {63779, 17547267},
1666 {63780, 17547523}, {63781, 17547779}, {63782, 17548035}, {63783, 17548291},
1667 {63784, 17548547}, {63785, 17548803}, {63786, 17549059}, {63787, 17549315},
1668 {63788, 17549571}, {63789, 17549827}, {63790, 17550083}, {63791, 17550339},
1669 {63792, 17550595}, {63793, 17550851}, {63794, 17551107}, {63795, 17551363},
1670 {63796, 17173507}, {63797, 17551619}, {63798, 17551875}, {63799, 17552131},
1671 {63800, 17552387}, {63801, 17552643}, {63802, 17552899}, {63803, 17553155},
1672 {63804, 17553411}, {63805, 17553667}, {63806, 17553923}, {63807, 17554179},
1673 {63808, 17192195}, {63809, 17554435}, {63810, 17554691}, {63811, 17554947},
1674 {63812, 17555203}, {63813, 17555459}, {63814, 17555715}, {63815, 17555971},
1675 {63816, 17556227}, {63817, 17556483}, {63818, 17556739}, {63819, 17556995},
1676 {63820, 17557251}, {63821, 17557507}, {63822, 17557763}, {63823, 17558019},
1677 {63824, 17558275}, {63825, 17558531}, {63826, 17558787}, {63827, 17559043},
1678 {63828, 17559299}, {63829, 17559555}, {63830, 17559811}, {63831, 17560067},
1679 {63832, 17560323}, {63833, 17560579}, {63834, 17560835}, {63835, 17561091},
1680 {63836, 17543427}, {63837, 17561347}, {63838, 17561603}, {63839, 17561859},
1681 {63840, 17562115}, {63841, 17562371}, {63842, 17562627}, {63843, 17562883},
1682 {63844, 17563139}, {63845, 17563395}, {63846, 17563651}, {63847, 17563907},
1683 {63848, 17564163}, {63849, 17564419}, {63850, 17564675}, {63851, 17564931},
1684 {63852, 17565187}, {63853, 17565443}, {63854, 17565699}, {63855, 17565955},
1685 {63856, 17566211}, {63857, 17182723}, {63858, 17566467}, {63859, 17566723},
1686 {63860, 17566979}, {63861, 17567235}, {63862, 17567491}, {63863, 17567747},
1687 {63864, 17568003}, {63865, 17568259}, {63866, 17568515}, {63867, 17568771},
1688 {63868, 17569027}, {63869, 17569283}, {63870, 17569539}, {63871, 17569795},
1689 {63872, 17570051}, {63873, 17151235}, {63874, 17570307}, {63875, 17570563},
1690 {63876, 17570819}, {63877, 17571075}, {63878, 17571331}, {63879, 17571587},
1691 {63880, 17571843}, {63881, 17572099}, {63882, 17146371}, {63883, 17572355},
1692 {63884, 17572611}, {63885, 17572867}, {63886, 17573123}, {63887, 17573379},
1693 {63888, 17573635}, {63889, 17573891}, {63890, 17574147}, {63891, 17574403},
1694 {63892, 17574659}, {63893, 17574915}, {63894, 17575171}, {63895, 17575427},
1695 {63896, 17575683}, {63897, 17575939}, {63898, 17576195}, {63899, 17576451},
1696 {63900, 17576707}, {63901, 17576963}, {63902, 17577219}, {63903, 17577475},
1697 {63904, 17577731}, {63905, 17565955}, {63906, 17577987}, {63907, 17578243},
1698 {63908, 17578499}, {63909, 17578755}, {63910, 17579011}, {63911, 17579267},
1699 {63912, 17317123}, {63913, 17579523}, {63914, 17561859}, {63915, 17579779},
1700 {63916, 17580035}, {63917, 17580291}, {63918, 17580547}, {63919, 17580803},
1701 {63920, 17581059}, {63921, 17581315}, {63922, 17581571}, {63923, 17581827},
1702 {63924, 17582083}, {63925, 17582339}, {63926, 17582595}, {63927, 17582851},
1703 {63928, 17583107}, {63929, 17583363}, {63930, 17583619}, {63931, 17583875},
1704 {63932, 17584131}, {63933, 17584387}, {63934, 17584643}, {63935, 17543427},
1705 {63936, 17584899}, {63937, 17585155}, {63938, 17585411}, {63939, 17585667},
1706 {63940, 17195779}, {63941, 17585923}, {63942, 17586179}, {63943, 17586435},
1707 {63944, 17586691}, {63945, 17586947}, {63946, 17587203}, {63947, 17587459},
1708 {63948, 17587715}, {63949, 17587971}, {63950, 17588227}, {63951, 17588483},
1709 {63952, 17588739}, {63953, 17254403}, {63954, 17588995}, {63955, 17589251},
1710 {63956, 17589507}, {63957, 17589763}, {63958, 17590019}, {63959, 17590275},
1711 {63960, 17590531}, {63961, 17590787}, {63962, 17591043}, {63963, 17562371},
1712 {63964, 17591299}, {63965, 17591555}, {63966, 17591811}, {63967, 17592067},
1713 {63968, 17592323}, {63969, 17592579}, {63970, 17592835}, {63971, 17593091},
1714 {63972, 17593347}, {63973, 17593603}, {63974, 17593859}, {63975, 17594115},
1715 {63976, 17594371}, {63977, 17184003}, {63978, 17594627}, {63979, 17594883},
1716 {63980, 17595139}, {63981, 17595395}, {63982, 17595651}, {63983, 17595907},
1717 {63984, 17596163}, {63985, 17596419}, {63986, 17596675}, {63987, 17596931},
1718 {63988, 17597187}, {63989, 17597443}, {63990, 17597699}, {63991, 17171459},
1719 {63992, 17597955}, {63993, 17598211}, {63994, 17598467}, {63995, 17598723},
1720 {63996, 17598979}, {63997, 17599235}, {63998, 17599491}, {63999, 17599747},
1721 {64000, 17600003}, {64001, 17600259}, {64002, 17600515}, {64003, 17600771},
1722 {64004, 17601027}, {64005, 17601283}, {64006, 17601539}, {64007, 17601795},
1723 {64008, 17178371}, {64009, 17602051}, {64010, 17179139}, {64011, 17602307},
1724 {64012, 17602563}, {64013, 17602819}, {64014, 1}, {64016, 17603075},
1725 {64017, 1}, {64018, 17603331}, {64019, 1}, {64021, 17603587},
1726 {64022, 17603843}, {64023, 17604099}, {64024, 17604355}, {64025, 17604611},
1727 {64026, 17604867}, {64027, 17605123}, {64028, 17605379}, {64029, 17605635},
1728 {64030, 17173251}, {64031, 1}, {64032, 17605891}, {64033, 1},
1729 {64034, 17606147}, {64035, 1}, {64037, 17606403}, {64038, 17606659},
1730 {64039, 1}, {64042, 17606915}, {64043, 17607171}, {64044, 17607427},
1731 {64045, 17607683}, {64046, 17607939}, {64047, 17608195}, {64048, 17608451},
1732 {64049, 17608707}, {64050, 17608963}, {64051, 17609219}, {64052, 17609475},
1733 {64053, 17609731}, {64054, 17609987}, {64055, 17610243}, {64056, 17610499},
1734 {64057, 17610755}, {64058, 17611011}, {64059, 17611267}, {64060, 17153027},
1735 {64061, 17611523}, {64062, 17611779}, {64063, 17612035}, {64064, 17612291},
1736 {64065, 17612547}, {64066, 17612803}, {64067, 17613059}, {64068, 17613315},
1737 {64069, 17613571}, {64070, 17613827}, {64071, 17614083}, {64072, 17614339},
1738 {64073, 17614595}, {64074, 17614851}, {64075, 17615107}, {64076, 17265155},
1739 {64077, 17615363}, {64078, 17615619}, {64079, 17615875}, {64080, 17616131},
1740 {64081, 17268227}, {64082, 17616387}, {64083, 17616643}, {64084, 17616899},
1741 {64085, 17617155}, {64086, 17617411}, {64087, 17575171}, {64088, 17617667},
1742 {64089, 17617923}, {64090, 17618179}, {64091, 17618435}, {64092, 17618691},
1743 {64093, 17618947}, {64095, 17619203}, {64096, 17619459}, {64097, 17619715},
1744 {64098, 17619971}, {64099, 17620227}, {64100, 17620483}, {64101, 17620739},
1745 {64102, 17620995}, {64103, 17606403}, {64104, 17621251}, {64105, 17621507},
1746 {64106, 17621763}, {64107, 17622019}, {64108, 17622275}, {64109, 17622531},
1747 {64110, 2}, {64112, 17622787}, {64113, 17623043}, {64114, 17623299},
1748 {64115, 17623555}, {64116, 17623811}, {64117, 17624067}, {64118, 17624323},
1749 {64119, 17624579}, {64120, 17609987}, {64121, 17624835}, {64122, 17625091},
1750 {64123, 17625347}, {64124, 17603075}, {64125, 17625603}, {64126, 17625859},
1751 {64127, 17626115}, {64128, 17626371}, {64129, 17626627}, {64130, 17626883},
1752 {64131, 17627139}, {64132, 17627395}, {64133, 17627651}, {64134, 17627907},
1753 {64135, 17628163}, {64136, 17628419}, {64137, 17612035}, {64138, 17628675},
1754 {64139, 17612291}, {64140, 17628931}, {64141, 17629187}, {64142, 17629443},
1755 {64143, 17629699}, {64144, 17629955}, {64145, 17603331}, {64146, 17548803},
1756 {64147, 17630211}, {64148, 17630467}, {64149, 17161475}, {64150, 17566211},
1757 {64151, 17587203}, {64152, 17630723}, {64153, 17630979}, {64154, 17614083},
1758 {64155, 17631235}, {64156, 17614339}, {64157, 17631491}, {64158, 17631747},
1759 {64159, 17632003}, {64160, 17603843}, {64161, 17632259}, {64162, 17632515},
1760 {64163, 17632771}, {64164, 17633027}, {64165, 17633283}, {64166, 17604099},
1761 {64167, 17633539}, {64168, 17633795}, {64169, 17634051}, {64170, 17634307},
1762 {64171, 17634563}, {64172, 17634819}, {64173, 17617411}, {64174, 17635075},
1763 {64175, 17635331}, {64176, 17575171}, {64177, 17635587}, {64178, 17618435},
1764 {64179, 17635843}, {64180, 17636099}, {64181, 17636355}, {64182, 17636611},
1765 {64183, 17636867}, {64184, 17619715}, {64185, 17637123}, {64186, 17606147},
1766 {64187, 17637379}, {64188, 17619971}, {64189, 17561347}, {64190, 17637635},
1767 {64191, 17620227}, {64192, 17637891}, {64193, 17620739}, {64194, 17638147},
1768 {64195, 17638403}, {64196, 17638659}, {64197, 17638915}, {64198, 17639171},
1769 {64199, 17621251}, {64200, 17605379}, {64201, 17639427}, {64202, 17621507},
1770 {64203, 17639683}, {64204, 17621763}, {64205, 17639939}, {64206, 17196035},
1771 {64207, 17640195}, {64208, 17640451}, {64209, 17640707}, {64210, 17640963},
1772 {64211, 17641219}, {64212, 17641475}, {64213, 17641731}, {64214, 17641987},
1773 {64215, 17642243}, {64216, 17642499}, {64217, 17642755}, {64218, 2},
1774 {64256, 34420227}, {64257, 34420739}, {64258, 34421251}, {64259, 51197699},
1775 {64260, 51198979}, {64261, 33559043}, {64263, 2}, {64275, 34422531},
1776 {64276, 34423043}, {64277, 34423555}, {64278, 34424067}, {64279, 34424579},
1777 {64280, 2}, {64285, 34425091}, {64286, 1}, {64287, 34425603},
1778 {64288, 17648899}, {64289, 17044227}, {64290, 17044995}, {64291, 17649155},
1779 {64292, 17649411}, {64293, 17649667}, {64294, 17649923}, {64295, 17650179},
1780 {64296, 17650435}, {64297, 17037059}, {64298, 34427907}, {64299, 34428419},
1781 {64300, 51206147}, {64301, 51206915}, {64302, 34430467}, {64303, 34430979},
1782 {64304, 34431491}, {64305, 34432003}, {64306, 34432515}, {64307, 34433027},
1783 {64308, 34433539}, {64309, 34434051}, {64310, 34434563}, {64311, 2},
1784 {64312, 34435075}, {64313, 34435587}, {64314, 34436099}, {64315, 34436611},
1785 {64316, 34437123}, {64317, 2}, {64318, 34437635}, {64319, 2},
1786 {64320, 34438147}, {64321, 34438659}, {64322, 2}, {64323, 34439171},
1787 {64324, 34439683}, {64325, 2}, {64326, 34440195}, {64327, 34440707},
1788 {64328, 34441219}, {64329, 34428931}, {64330, 34441731}, {64331, 34442243},
1789 {64332, 34442755}, {64333, 34443267}, {64334, 34443779}, {64335, 34444291},
1790 {64336, 17667587}, {64338, 17667843}, {64342, 17668099}, {64346, 17668355},
1791 {64350, 17668611}, {64354, 17668867}, {64358, 17669123}, {64362, 17669379},
1792 {64366, 17669635}, {64370, 17669891}, {64374, 17670147}, {64378, 17670403},
1793 {64382, 17670659}, {64386, 17670915}, {64388, 17671171}, {64390, 17671427},
1794 {64392, 17671683}, {64394, 17671939}, {64396, 17672195}, {64398, 17672451},
1795 {64402, 17672707}, {64406, 17672963}, {64410, 17673219}, {64414, 17673475},
1796 {64416, 17673731}, {64420, 17673987}, {64422, 17674243}, {64426, 17674499},
1797 {64430, 17674755}, {64432, 17675011}, {64434, 1}, {64451, 2},
1798 {64467, 17675267}, {64471, 16911363}, {64473, 17675523}, {64475, 17675779},
1799 {64477, 33688579}, {64478, 17676035}, {64480, 17676291}, {64482, 17676547},
1800 {64484, 17676803}, {64488, 17677059}, {64490, 34454531}, {64492, 34455043},
1801 {64494, 34455555}, {64496, 34456067}, {64498, 34456579}, {64500, 34457091},
1802 {64502, 34457603}, {64505, 34458115}, {64508, 17681411}, {64512, 34458883},
1803 {64513, 34459395}, {64514, 34459907}, {64515, 34458115}, {64516, 34460419},
1804 {64517, 34460931}, {64518, 34461443}, {64519, 34461955}, {64520, 34462467},
1805 {64521, 34462979}, {64522, 34463491}, {64523, 34464003}, {64524, 34464515},
1806 {64525, 34465027}, {64526, 34465539}, {64527, 34466051}, {64528, 34466563},
1807 {64529, 34467075}, {64530, 34467587}, {64531, 34468099}, {64532, 34468611},
1808 {64533, 34469123}, {64534, 34469635}, {64535, 34469379}, {64536, 34470147},
1809 {64537, 34470659}, {64538, 34471171}, {64539, 34471683}, {64540, 34472195},
1810 {64541, 34472707}, {64542, 34473219}, {64543, 34473731}, {64544, 34474243},
1811 {64545, 34474755}, {64546, 34475267}, {64547, 34475779}, {64548, 34476291},
1812 {64549, 34476803}, {64550, 34477315}, {64551, 34477827}, {64552, 34478339},
1813 {64553, 34478851}, {64554, 34479363}, {64555, 34479875}, {64556, 34480387},
1814 {64557, 34480899}, {64558, 34481411}, {64559, 34481923}, {64560, 34482435},
1815 {64561, 34482947}, {64562, 34483459}, {64563, 34483971}, {64564, 34484483},
1816 {64565, 34484995}, {64566, 34485507}, {64567, 34486019}, {64568, 34486531},
1817 {64569, 34487043}, {64570, 34487555}, {64571, 34488067}, {64572, 34488579},
1818 {64573, 34489091}, {64574, 34489603}, {64575, 34490115}, {64576, 34490627},
1819 {64577, 34491139}, {64578, 34491651}, {64579, 34492163}, {64580, 34492675},
1820 {64581, 34493187}, {64582, 34469891}, {64583, 34470403}, {64584, 34493699},
1821 {64585, 34494211}, {64586, 34494723}, {64587, 34495235}, {64588, 34495747},
1822 {64589, 34496259}, {64590, 34496771}, {64591, 34497283}, {64592, 34497795},
1823 {64593, 34498307}, {64594, 34498819}, {64595, 34499331}, {64596, 34499843},
1824 {64597, 34468867}, {64598, 34500355}, {64599, 34500867}, {64600, 34492931},
1825 {64601, 34501379}, {64602, 34500099}, {64603, 34501891}, {64604, 34502403},
1826 {64605, 34502915}, {64606, 51280643}, {64607, 51281411}, {64608, 51282179},
1827 {64609, 51282947}, {64610, 51283715}, {64611, 51284483}, {64612, 34508035},
1828 {64613, 34508547}, {64614, 34459907}, {64615, 34509059}, {64616, 34458115},
1829 {64617, 34460419}, {64618, 34509571}, {64619, 34510083}, {64620, 34462467},
1830 {64621, 34510595}, {64622, 34462979}, {64623, 34463491}, {64624, 34511107},
1831 {64625, 34511619}, {64626, 34465539}, {64627, 34512131}, {64628, 34466051},
1832 {64629, 34466563}, {64630, 34512643}, {64631, 34513155}, {64632, 34467587},
1833 {64633, 34513667}, {64634, 34468099}, {64635, 34468611}, {64636, 34482947},
1834 {64637, 34483459}, {64638, 34484995}, {64639, 34485507}, {64640, 34486019},
1835 {64641, 34488067}, {64642, 34488579}, {64643, 34489091}, {64644, 34489603},
1836 {64645, 34491651}, {64646, 34492163}, {64647, 34492675}, {64648, 34514179},
1837 {64649, 34493699}, {64650, 34514691}, {64651, 34515203}, {64652, 34496771},
1838 {64653, 34515715}, {64654, 34497283}, {64655, 34497795}, {64656, 34502915},
1839 {64657, 34516227}, {64658, 34516739}, {64659, 34492931}, {64660, 34494979},
1840 {64661, 34501379}, {64662, 34500099}, {64663, 34458883}, {64664, 34459395},
1841 {64665, 34517251}, {64666, 34459907}, {64667, 34517763}, {64668, 34460931},
1842 {64669, 34461443}, {64670, 34461955}, {64671, 34462467}, {64672, 34518275},
1843 {64673, 34464003}, {64674, 34464515}, {64675, 34465027}, {64676, 34465539},
1844 {64677, 34518787}, {64678, 34467587}, {64679, 34469123}, {64680, 34469635},
1845 {64681, 34469379}, {64682, 34470147}, {64683, 34470659}, {64684, 34471683},
1846 {64685, 34472195}, {64686, 34472707}, {64687, 34473219}, {64688, 34473731},
1847 {64689, 34474243}, {64690, 34519299}, {64691, 34474755}, {64692, 34475267},
1848 {64693, 34475779}, {64694, 34476291}, {64695, 34476803}, {64696, 34477315},
1849 {64697, 34478339}, {64698, 34478851}, {64699, 34479363}, {64700, 34479875},
1850 {64701, 34480387}, {64702, 34480899}, {64703, 34481411}, {64704, 34481923},
1851 {64705, 34482435}, {64706, 34483971}, {64707, 34484483}, {64708, 34486531},
1852 {64709, 34487043}, {64710, 34487555}, {64711, 34488067}, {64712, 34488579},
1853 {64713, 34490115}, {64714, 34490627}, {64715, 34491139}, {64716, 34491651},
1854 {64717, 34519811}, {64718, 34493187}, {64719, 34469891}, {64720, 34470403},
1855 {64721, 34493699}, {64722, 34495235}, {64723, 34495747}, {64724, 34496259},
1856 {64725, 34496771}, {64726, 34520323}, {64727, 34498307}, {64728, 34498819},
1857 {64729, 34520835}, {64730, 34468867}, {64731, 34500355}, {64732, 34500867},
1858 {64733, 34492931}, {64734, 34498051}, {64735, 34459907}, {64736, 34517763},
1859 {64737, 34462467}, {64738, 34518275}, {64739, 34465539}, {64740, 34518787},
1860 {64741, 34467587}, {64742, 34521347}, {64743, 34473731}, {64744, 34521859},
1861 {64745, 34522371}, {64746, 34522883}, {64747, 34488067}, {64748, 34488579},
1862 {64749, 34491651}, {64750, 34496771}, {64751, 34520323}, {64752, 34492931},
1863 {64753, 34498051}, {64754, 51300611}, {64755, 51301379}, {64756, 51302147},
1864 {64757, 34525699}, {64758, 34526211}, {64759, 34526723}, {64760, 34527235},
1865 {64761, 34527747}, {64762, 34528259}, {64763, 34528771}, {64764, 34529283},
1866 {64765, 34529795}, {64766, 34530307}, {64767, 34530819}, {64768, 34500611},
1867 {64769, 34531331}, {64770, 34531843}, {64771, 34532355}, {64772, 34501123},
1868 {64773, 34532867}, {64774, 34533379}, {64775, 34533891}, {64776, 34534403},
1869 {64777, 34534915}, {64778, 34535427}, {64779, 34535939}, {64780, 34522371},
1870 {64781, 34536451}, {64782, 34536963}, {64783, 34537475}, {64784, 34537987},
1871 {64785, 34525699}, {64786, 34526211}, {64787, 34526723}, {64788, 34527235},
1872 {64789, 34527747}, {64790, 34528259}, {64791, 34528771}, {64792, 34529283},
1873 {64793, 34529795}, {64794, 34530307}, {64795, 34530819}, {64796, 34500611},
1874 {64797, 34531331}, {64798, 34531843}, {64799, 34532355}, {64800, 34501123},
1875 {64801, 34532867}, {64802, 34533379}, {64803, 34533891}, {64804, 34534403},
1876 {64805, 34534915}, {64806, 34535427}, {64807, 34535939}, {64808, 34522371},
1877 {64809, 34536451}, {64810, 34536963}, {64811, 34537475}, {64812, 34537987},
1878 {64813, 34534915}, {64814, 34535427}, {64815, 34535939}, {64816, 34522371},
1879 {64817, 34521859}, {64818, 34522883}, {64819, 34477827}, {64820, 34472195},
1880 {64821, 34472707}, {64822, 34473219}, {64823, 34534915}, {64824, 34535427},
1881 {64825, 34535939}, {64826, 34477827}, {64827, 34478339}, {64828, 34538499},
1882 {64830, 1}, {64848, 51316227}, {64849, 51316995}, {64851, 51317763},
1883 {64852, 51318531}, {64853, 51319299}, {64854, 51320067}, {64855, 51320835},
1884 {64856, 51246851}, {64858, 51321603}, {64859, 51322371}, {64860, 51323139},
1885 {64861, 51323907}, {64862, 51324675}, {64863, 51325443}, {64865, 51326211},
1886 {64866, 51326979}, {64868, 51327747}, {64870, 51328515}, {64871, 51329283},
1887 {64873, 51330051}, {64874, 51330819}, {64876, 51331587}, {64878, 51332355},
1888 {64879, 51333123}, {64881, 51333891}, {64883, 51334659}, {64884, 51335427},
1889 {64885, 51336195}, {64886, 51336963}, {64888, 51337731}, {64889, 51338499},
1890 {64890, 51339267}, {64891, 51340035}, {64892, 51340803}, {64894, 51341571},
1891 {64895, 51342339}, {64896, 51343107}, {64897, 51343875}, {64898, 51344643},
1892 {64899, 51345411}, {64901, 51346179}, {64903, 51346947}, {64905, 51347715},
1893 {64906, 51247107}, {64907, 51348483}, {64908, 51349251}, {64909, 51270403},
1894 {64910, 51247619}, {64911, 51350019}, {64912, 2}, {64914, 51350787},
1895 {64915, 51351555}, {64916, 51352323}, {64917, 51353091}, {64918, 51353859},
1896 {64919, 51354627}, {64921, 51355395}, {64922, 51356163}, {64923, 51356931},
1897 {64924, 51357699}, {64926, 51358467}, {64927, 51359235}, {64928, 51360003},
1898 {64929, 51360771}, {64930, 51361539}, {64931, 51362307}, {64932, 51363075},
1899 {64933, 51363843}, {64934, 51364611}, {64935, 51365379}, {64936, 51366147},
1900 {64937, 51366915}, {64938, 51367683}, {64939, 51368451}, {64940, 51369219},
1901 {64941, 51369987}, {64942, 51277571}, {64943, 51370755}, {64944, 51371523},
1902 {64945, 51372291}, {64946, 51373059}, {64947, 51373827}, {64948, 51341571},
1903 {64949, 51343107}, {64950, 51374595}, {64951, 51375363}, {64952, 51376131},
1904 {64953, 51376899}, {64954, 51377667}, {64955, 51378435}, {64956, 51377667},
1905 {64957, 51376131}, {64958, 51379203}, {64959, 51379971}, {64960, 51380739},
1906 {64961, 51381507}, {64962, 51382275}, {64963, 51378435}, {64964, 51336195},
1907 {64965, 51328515}, {64966, 51383043}, {64967, 51383811}, {64968, 2},
1908 {64975, 1}, {64976, 2}, {65008, 51384579}, {65009, 51385347},
1909 {65010, 68163331}, {65011, 68164355}, {65012, 68165379}, {65013, 68166403},
1910 {65014, 68167427}, {65015, 68168451}, {65016, 68169475}, {65017, 51393283},
1911 {65018, 303052291}, {65019, 135284739}, {65020, 68177923}, {65021, 1},
1912 {65024, 0}, {65040, 17847299}, {65041, 17847555}, {65042, 2},
1913 {65043, 17110531}, {65044, 16848643}, {65045, 17032963}, {65046, 17033987},
1914 {65047, 17847811}, {65048, 17848067}, {65049, 2}, {65056, 1},
1915 {65072, 2}, {65073, 17848323}, {65074, 17848579}, {65075, 17848835},
1916 {65077, 17037827}, {65078, 17038083}, {65079, 17849091}, {65080, 17849347},
1917 {65081, 17849603}, {65082, 17849859}, {65083, 17850115}, {65084, 17850371},
1918 {65085, 17850627}, {65086, 17850883}, {65087, 17067267}, {65088, 17067523},
1919 {65089, 17851139}, {65090, 17851395}, {65091, 17851651}, {65092, 17851907},
1920 {65093, 1}, {65095, 17852163}, {65096, 17852419}, {65097, 33810691},
1921 {65101, 17848835}, {65104, 17847299}, {65105, 17847555}, {65106, 2},
1922 {65108, 16848643}, {65109, 17110531}, {65110, 17033987}, {65111, 17032963},
1923 {65112, 17848323}, {65113, 17037827}, {65114, 17038083}, {65115, 17849091},
1924 {65116, 17849347}, {65117, 17849603}, {65118, 17849859}, {65119, 17852675},
1925 {65120, 17852931}, {65121, 17853187}, {65122, 17037059}, {65123, 17853443},
1926 {65124, 17853699}, {65125, 17853955}, {65126, 17037571}, {65127, 2},
1927 {65128, 17854211}, {65129, 17854467}, {65130, 17854723}, {65131, 17854979},
1928 {65132, 2}, {65136, 34632451}, {65137, 34632963}, {65138, 34503427},
1929 {65139, 1}, {65140, 34504195}, {65141, 2}, {65142, 34504963},
1930 {65143, 34523395}, {65144, 34505731}, {65145, 34524163}, {65146, 34506499},
1931 {65147, 34524931}, {65148, 34507267}, {65149, 34633475}, {65150, 34633987},
1932 {65151, 34634499}, {65152, 17857795}, {65153, 17858051}, {65155, 17858307},
1933 {65157, 17858563}, {65159, 17858819}, {65161, 17677315}, {65165, 16910339},
1934 {65167, 17683715}, {65171, 17859075}, {65173, 17686787}, {65177, 17689859},
1935 {65181, 17681923}, {65185, 17682435}, {65189, 17684995}, {65193, 17834499},
1936 {65195, 17724675}, {65197, 17725187}, {65199, 17731587}, {65201, 17694979},
1937 {65205, 17745155}, {65209, 17697027}, {65213, 17698051}, {65217, 17700099},
1938 {65221, 17701123}, {65225, 17701635}, {65229, 17702659}, {65233, 17703683},
1939 {65237, 17706755}, {65241, 17708803}, {65245, 17711107}, {65249, 17682947},
1940 {65253, 17718019}, {65257, 17721091}, {65261, 16910851}, {65263, 17677059},
1941 {65265, 16911875}, {65269, 34636547}, {65271, 34637059}, {65273, 34637571},
1942 {65275, 34622467}, {65277, 2}, {65279, 0}, {65280, 2},
1943 {65281, 17032963}, {65282, 17860867}, {65283, 17852675}, {65284, 17854467},
1944 {65285, 17854723}, {65286, 17852931}, {65287, 17861123}, {65288, 17037827},
1945 {65289, 17038083}, {65290, 17853187}, {65291, 17037059}, {65292, 17847299},
1946 {65293, 17853443}, {65294, 17196547}, {65295, 17038595}, {65296, 17035523},
1947 {65297, 16786947}, {65298, 16785155}, {65299, 16785411}, {65300, 16787715},
1948 {65301, 17035779}, {65302, 17036035}, {65303, 17036291}, {65304, 17036547},
1949 {65305, 17036803}, {65306, 17110531}, {65307, 16848643}, {65308, 17853699},
1950 {65309, 17037571}, {65310, 17853955}, {65311, 17033987}, {65312, 17854979},
1951 {65313, 16777219}, {65314, 16777475}, {65315, 16777731}, {65316, 16777987},
1952 {65317, 16778243}, {65318, 16778499}, {65319, 16778755}, {65320, 16779011},
1953 {65321, 16779267}, {65322, 16779523}, {65323, 16779779}, {65324, 16780035},
1954 {65325, 16780291}, {65326, 16780547}, {65327, 16780803}, {65328, 16781059},
1955 {65329, 16781315}, {65330, 16781571}, {65331, 16781827}, {65332, 16782083},
1956 {65333, 16782339}, {65334, 16782595}, {65335, 16782851}, {65336, 16783107},
1957 {65337, 16783363}, {65338, 16783619}, {65339, 17852163}, {65340, 17854211},
1958 {65341, 17852419}, {65342, 17861379}, {65343, 17848835}, {65344, 17027075},
1959 {65345, 16777219}, {65346, 16777475}, {65347, 16777731}, {65348, 16777987},
1960 {65349, 16778243}, {65350, 16778499}, {65351, 16778755}, {65352, 16779011},
1961 {65353, 16779267}, {65354, 16779523}, {65355, 16779779}, {65356, 16780035},
1962 {65357, 16780291}, {65358, 16780547}, {65359, 16780803}, {65360, 16781059},
1963 {65361, 16781315}, {65362, 16781571}, {65363, 16781827}, {65364, 16782083},
1964 {65365, 16782339}, {65366, 16782595}, {65367, 16782851}, {65368, 16783107},
1965 {65369, 16783363}, {65370, 16783619}, {65371, 17849091}, {65372, 17861635},
1966 {65373, 17849347}, {65374, 17861891}, {65375, 17862147}, {65376, 17862403},
1967 {65377, 17196547}, {65378, 17851139}, {65379, 17851395}, {65380, 17847555},
1968 {65381, 17862659}, {65382, 17316867}, {65383, 17319427}, {65384, 17362435},
1969 {65385, 17862915}, {65386, 17363971}, {65387, 17323523}, {65388, 17863171},
1970 {65389, 17333763}, {65390, 17379587}, {65391, 17329155}, {65392, 17318147},
1971 {65393, 17305603}, {65394, 17305859}, {65395, 17306115}, {65396, 17306371},
1972 {65397, 17306627}, {65398, 17306883}, {65399, 17307139}, {65400, 17307395},
1973 {65401, 17307651}, {65402, 17199107}, {65403, 17307907}, {65404, 17308163},
1974 {65405, 17308419}, {65406, 17308675}, {65407, 17308931}, {65408, 17309187},
1975 {65409, 17309443}, {65410, 17309699}, {65411, 17309955}, {65412, 17199363},
1976 {65413, 17310211}, {65414, 17310467}, {65415, 17310723}, {65416, 17310979},
1977 {65417, 17311235}, {65418, 17311491}, {65419, 17311747}, {65420, 17312003},
1978 {65421, 17312259}, {65422, 17312515}, {65423, 17312771}, {65424, 17313027},
1979 {65425, 17313283}, {65426, 17313539}, {65427, 17313795}, {65428, 17314051},
1980 {65429, 17314307}, {65430, 17314563}, {65431, 17314819}, {65432, 17315075},
1981 {65433, 17315331}, {65434, 17315587}, {65435, 17315843}, {65436, 17316099},
1982 {65437, 17319939}, {65438, 17197827}, {65439, 17198339}, {65440, 2},
1983 {65441, 17199619}, {65442, 17199875}, {65443, 17200131}, {65444, 17200387},
1984 {65445, 17200643}, {65446, 17200899}, {65447, 17201155}, {65448, 17201411},
1985 {65449, 17201667}, {65450, 17201923}, {65451, 17202179}, {65452, 17202435},
1986 {65453, 17202691}, {65454, 17202947}, {65455, 17203203}, {65456, 17203459},
1987 {65457, 17203715}, {65458, 17203971}, {65459, 17204227}, {65460, 17204483},
1988 {65461, 17204739}, {65462, 17204995}, {65463, 17205251}, {65464, 17205507},
1989 {65465, 17205763}, {65466, 17206019}, {65467, 17206275}, {65468, 17206531},
1990 {65469, 17206787}, {65470, 17207043}, {65471, 2}, {65474, 17207299},
1991 {65475, 17207555}, {65476, 17207811}, {65477, 17208067}, {65478, 17208323},
1992 {65479, 17208579}, {65480, 2}, {65482, 17208835}, {65483, 17209091},
1993 {65484, 17209347}, {65485, 17209603}, {65486, 17209859}, {65487, 17210115},
1994 {65488, 2}, {65490, 17210371}, {65491, 17210627}, {65492, 17210883},
1995 {65493, 17211139}, {65494, 17211395}, {65495, 17211651}, {65496, 2},
1996 {65498, 17211907}, {65499, 17212163}, {65500, 17212419}, {65501, 2},
1997 {65504, 17863427}, {65505, 17863683}, {65506, 17863939}, {65507, 33561859},
1998 {65508, 17864195}, {65509, 17864451}, {65510, 17864707}, {65511, 2},
1999 {65512, 17864963}, {65513, 17865219}, {65514, 17865475}, {65515, 17865731},
2000 {65516, 17865987}, {65517, 17866243}, {65518, 17866499}, {65519, 2},
2001 {65536, 1}, {65548, 2}, {65549, 1}, {65575, 2},
2002 {65576, 1}, {65595, 2}, {65596, 1}, {65598, 2},
2003 {65599, 1}, {65614, 2}, {65616, 1}, {65630, 2},
2004 {65664, 1}, {65787, 2}, {65792, 1}, {65795, 2},
2005 {65799, 1}, {65844, 2}, {65847, 1}, {65935, 2},
2006 {65936, 1}, {65949, 2}, {65952, 1}, {65953, 2},
2007 {66000, 1}, {66046, 2}, {66176, 1}, {66205, 2},
2008 {66208, 1}, {66257, 2}, {66272, 1}, {66300, 2},
2009 {66304, 1}, {66340, 2}, {66349, 1}, {66379, 2},
2010 {66384, 1}, {66427, 2}, {66432, 1}, {66462, 2},
2011 {66463, 1}, {66500, 2}, {66504, 1}, {66518, 2},
2012 {66560, 17866755}, {66561, 17867011}, {66562, 17867267}, {66563, 17867523},
2013 {66564, 17867779}, {66565, 17868035}, {66566, 17868291}, {66567, 17868547},
2014 {66568, 17868803}, {66569, 17869059}, {66570, 17869315}, {66571, 17869571},
2015 {66572, 17869827}, {66573, 17870083}, {66574, 17870339}, {66575, 17870595},
2016 {66576, 17870851}, {66577, 17871107}, {66578, 17871363}, {66579, 17871619},
2017 {66580, 17871875}, {66581, 17872131}, {66582, 17872387}, {66583, 17872643},
2018 {66584, 17872899}, {66585, 17873155}, {66586, 17873411}, {66587, 17873667},
2019 {66588, 17873923}, {66589, 17874179}, {66590, 17874435}, {66591, 17874691},
2020 {66592, 17874947}, {66593, 17875203}, {66594, 17875459}, {66595, 17875715},
2021 {66596, 17875971}, {66597, 17876227}, {66598, 17876483}, {66599, 17876739},
2022 {66600, 1}, {66718, 2}, {66720, 1}, {66730, 2},
2023 {66736, 17876995}, {66737, 17877251}, {66738, 17877507}, {66739, 17877763},
2024 {66740, 17878019}, {66741, 17878275}, {66742, 17878531}, {66743, 17878787},
2025 {66744, 17879043}, {66745, 17879299}, {66746, 17879555}, {66747, 17879811},
2026 {66748, 17880067}, {66749, 17880323}, {66750, 17880579}, {66751, 17880835},
2027 {66752, 17881091}, {66753, 17881347}, {66754, 17881603}, {66755, 17881859},
2028 {66756, 17882115}, {66757, 17882371}, {66758, 17882627}, {66759, 17882883},
2029 {66760, 17883139}, {66761, 17883395}, {66762, 17883651}, {66763, 17883907},
2030 {66764, 17884163}, {66765, 17884419}, {66766, 17884675}, {66767, 17884931},
2031 {66768, 17885187}, {66769, 17885443}, {66770, 17885699}, {66771, 17885955},
2032 {66772, 2}, {66776, 1}, {66812, 2}, {66816, 1},
2033 {66856, 2}, {66864, 1}, {66916, 2}, {66927, 1},
2034 {66928, 17886211}, {66929, 17886467}, {66930, 17886723}, {66931, 17886979},
2035 {66932, 17887235}, {66933, 17887491}, {66934, 17887747}, {66935, 17888003},
2036 {66936, 17888259}, {66937, 17888515}, {66938, 17888771}, {66939, 2},
2037 {66940, 17889027}, {66941, 17889283}, {66942, 17889539}, {66943, 17889795},
2038 {66944, 17890051}, {66945, 17890307}, {66946, 17890563}, {66947, 17890819},
2039 {66948, 17891075}, {66949, 17891331}, {66950, 17891587}, {66951, 17891843},
2040 {66952, 17892099}, {66953, 17892355}, {66954, 17892611}, {66955, 2},
2041 {66956, 17892867}, {66957, 17893123}, {66958, 17893379}, {66959, 17893635},
2042 {66960, 17893891}, {66961, 17894147}, {66962, 17894403}, {66963, 2},
2043 {66964, 17894659}, {66965, 17894915}, {66966, 2}, {66967, 1},
2044 {66978, 2}, {66979, 1}, {66994, 2}, {66995, 1},
2045 {67002, 2}, {67003, 1}, {67005, 2}, {67072, 1},
2046 {67383, 2}, {67392, 1}, {67414, 2}, {67424, 1},
2047 {67432, 2}, {67456, 1}, {67457, 17895171}, {67458, 17895427},
2048 {67459, 16791043}, {67460, 17895683}, {67461, 16814083}, {67462, 2},
2049 {67463, 17895939}, {67464, 17896195}, {67465, 17896451}, {67466, 17896707},
2050 {67467, 16815363}, {67468, 16815619}, {67469, 17896963}, {67470, 17897219},
2051 {67471, 17897475}, {67472, 17897731}, {67473, 17897987}, {67474, 17898243},
2052 {67475, 16817155}, {67476, 17898499}, {67477, 16802051}, {67478, 17898755},
2053 {67479, 17899011}, {67480, 17899267}, {67481, 17899523}, {67482, 17899779},
2054 {67483, 17512963}, {67484, 17900035}, {67485, 17900291}, {67486, 17900547},
2055 {67487, 17900803}, {67488, 17901059}, {67489, 17901315}, {67490, 16795395},
2056 {67491, 17901571}, {67492, 17901827}, {67493, 16781315}, {67494, 17902083},
2057 {67495, 17902339}, {67496, 17125379}, {67497, 17902595}, {67498, 16819971},
2058 {67499, 17902851}, {67500, 17903107}, {67501, 17903363}, {67502, 17903619},
2059 {67503, 16820995}, {67504, 17903875}, {67505, 2}, {67506, 17904131},
2060 {67507, 17904387}, {67508, 17904643}, {67509, 17904899}, {67510, 17905155},
2061 {67511, 17905411}, {67512, 17905667}, {67513, 17905923}, {67514, 17906179},
2062 {67515, 2}, {67584, 1}, {67590, 2}, {67592, 1},
2063 {67593, 2}, {67594, 1}, {67638, 2}, {67639, 1},
2064 {67641, 2}, {67644, 1}, {67645, 2}, {67647, 1},
2065 {67670, 2}, {67671, 1}, {67743, 2}, {67751, 1},
2066 {67760, 2}, {67808, 1}, {67827, 2}, {67828, 1},
2067 {67830, 2}, {67835, 1}, {67868, 2}, {67871, 1},
2068 {67898, 2}, {67903, 1}, {67904, 2}, {67968, 1},
2069 {68024, 2}, {68028, 1}, {68048, 2}, {68050, 1},
2070 {68100, 2}, {68101, 1}, {68103, 2}, {68108, 1},
2071 {68116, 2}, {68117, 1}, {68120, 2}, {68121, 1},
2072 {68150, 2}, {68152, 1}, {68155, 2}, {68159, 1},
2073 {68169, 2}, {68176, 1}, {68185, 2}, {68192, 1},
2074 {68256, 2}, {68288, 1}, {68327, 2}, {68331, 1},
2075 {68343, 2}, {68352, 1}, {68406, 2}, {68409, 1},
2076 {68438, 2}, {68440, 1}, {68467, 2}, {68472, 1},
2077 {68498, 2}, {68505, 1}, {68509, 2}, {68521, 1},
2078 {68528, 2}, {68608, 1}, {68681, 2}, {68736, 17906435},
2079 {68737, 17906691}, {68738, 17906947}, {68739, 17907203}, {68740, 17907459},
2080 {68741, 17907715}, {68742, 17907971}, {68743, 17908227}, {68744, 17908483},
2081 {68745, 17908739}, {68746, 17908995}, {68747, 17909251}, {68748, 17909507},
2082 {68749, 17909763}, {68750, 17910019}, {68751, 17910275}, {68752, 17910531},
2083 {68753, 17910787}, {68754, 17911043}, {68755, 17911299}, {68756, 17911555},
2084 {68757, 17911811}, {68758, 17912067}, {68759, 17912323}, {68760, 17912579},
2085 {68761, 17912835}, {68762, 17913091}, {68763, 17913347}, {68764, 17913603},
2086 {68765, 17913859}, {68766, 17914115}, {68767, 17914371}, {68768, 17914627},
2087 {68769, 17914883}, {68770, 17915139}, {68771, 17915395}, {68772, 17915651},
2088 {68773, 17915907}, {68774, 17916163}, {68775, 17916419}, {68776, 17916675},
2089 {68777, 17916931}, {68778, 17917187}, {68779, 17917443}, {68780, 17917699},
2090 {68781, 17917955}, {68782, 17918211}, {68783, 17918467}, {68784, 17918723},
2091 {68785, 17918979}, {68786, 17919235}, {68787, 2}, {68800, 1},
2092 {68851, 2}, {68858, 1}, {68904, 2}, {68912, 1},
2093 {68922, 2}, {69216, 1}, {69247, 2}, {69248, 1},
2094 {69290, 2}, {69291, 1}, {69294, 2}, {69296, 1},
2095 {69298, 2}, {69373, 1}, {69416, 2}, {69424, 1},
2096 {69466, 2}, {69488, 1}, {69514, 2}, {69552, 1},
2097 {69580, 2}, {69600, 1}, {69623, 2}, {69632, 1},
2098 {69710, 2}, {69714, 1}, {69750, 2}, {69759, 1},
2099 {69821, 2}, {69822, 1}, {69827, 2}, {69840, 1},
2100 {69865, 2}, {69872, 1}, {69882, 2}, {69888, 1},
2101 {69941, 2}, {69942, 1}, {69960, 2}, {69968, 1},
2102 {70007, 2}, {70016, 1}, {70112, 2}, {70113, 1},
2103 {70133, 2}, {70144, 1}, {70162, 2}, {70163, 1},
2104 {70210, 2}, {70272, 1}, {70279, 2}, {70280, 1},
2105 {70281, 2}, {70282, 1}, {70286, 2}, {70287, 1},
2106 {70302, 2}, {70303, 1}, {70314, 2}, {70320, 1},
2107 {70379, 2}, {70384, 1}, {70394, 2}, {70400, 1},
2108 {70404, 2}, {70405, 1}, {70413, 2}, {70415, 1},
2109 {70417, 2}, {70419, 1}, {70441, 2}, {70442, 1},
2110 {70449, 2}, {70450, 1}, {70452, 2}, {70453, 1},
2111 {70458, 2}, {70459, 1}, {70469, 2}, {70471, 1},
2112 {70473, 2}, {70475, 1}, {70478, 2}, {70480, 1},
2113 {70481, 2}, {70487, 1}, {70488, 2}, {70493, 1},
2114 {70500, 2}, {70502, 1}, {70509, 2}, {70512, 1},
2115 {70517, 2}, {70656, 1}, {70748, 2}, {70749, 1},
2116 {70754, 2}, {70784, 1}, {70856, 2}, {70864, 1},
2117 {70874, 2}, {71040, 1}, {71094, 2}, {71096, 1},
2118 {71134, 2}, {71168, 1}, {71237, 2}, {71248, 1},
2119 {71258, 2}, {71264, 1}, {71277, 2}, {71296, 1},
2120 {71354, 2}, {71360, 1}, {71370, 2}, {71424, 1},
2121 {71451, 2}, {71453, 1}, {71468, 2}, {71472, 1},
2122 {71495, 2}, {71680, 1}, {71740, 2}, {71840, 17919491},
2123 {71841, 17919747}, {71842, 17920003}, {71843, 17920259}, {71844, 17920515},
2124 {71845, 17920771}, {71846, 17921027}, {71847, 17921283}, {71848, 17921539},
2125 {71849, 17921795}, {71850, 17922051}, {71851, 17922307}, {71852, 17922563},
2126 {71853, 17922819}, {71854, 17923075}, {71855, 17923331}, {71856, 17923587},
2127 {71857, 17923843}, {71858, 17924099}, {71859, 17924355}, {71860, 17924611},
2128 {71861, 17924867}, {71862, 17925123}, {71863, 17925379}, {71864, 17925635},
2129 {71865, 17925891}, {71866, 17926147}, {71867, 17926403}, {71868, 17926659},
2130 {71869, 17926915}, {71870, 17927171}, {71871, 17927427}, {71872, 1},
2131 {71923, 2}, {71935, 1}, {71943, 2}, {71945, 1},
2132 {71946, 2}, {71948, 1}, {71956, 2}, {71957, 1},
2133 {71959, 2}, {71960, 1}, {71990, 2}, {71991, 1},
2134 {71993, 2}, {71995, 1}, {72007, 2}, {72016, 1},
2135 {72026, 2}, {72096, 1}, {72104, 2}, {72106, 1},
2136 {72152, 2}, {72154, 1}, {72165, 2}, {72192, 1},
2137 {72264, 2}, {72272, 1}, {72355, 2}, {72368, 1},
2138 {72441, 2}, {72448, 1}, {72458, 2}, {72704, 1},
2139 {72713, 2}, {72714, 1}, {72759, 2}, {72760, 1},
2140 {72774, 2}, {72784, 1}, {72813, 2}, {72816, 1},
2141 {72848, 2}, {72850, 1}, {72872, 2}, {72873, 1},
2142 {72887, 2}, {72960, 1}, {72967, 2}, {72968, 1},
2143 {72970, 2}, {72971, 1}, {73015, 2}, {73018, 1},
2144 {73019, 2}, {73020, 1}, {73022, 2}, {73023, 1},
2145 {73032, 2}, {73040, 1}, {73050, 2}, {73056, 1},
2146 {73062, 2}, {73063, 1}, {73065, 2}, {73066, 1},
2147 {73103, 2}, {73104, 1}, {73106, 2}, {73107, 1},
2148 {73113, 2}, {73120, 1}, {73130, 2}, {73440, 1},
2149 {73465, 2}, {73472, 1}, {73489, 2}, {73490, 1},
2150 {73531, 2}, {73534, 1}, {73562, 2}, {73648, 1},
2151 {73649, 2}, {73664, 1}, {73714, 2}, {73727, 1},
2152 {74650, 2}, {74752, 1}, {74863, 2}, {74864, 1},
2153 {74869, 2}, {74880, 1}, {75076, 2}, {77712, 1},
2154 {77811, 2}, {77824, 1}, {78896, 2}, {78912, 1},
2155 {78934, 2}, {82944, 1}, {83527, 2}, {92160, 1},
2156 {92729, 2}, {92736, 1}, {92767, 2}, {92768, 1},
2157 {92778, 2}, {92782, 1}, {92863, 2}, {92864, 1},
2158 {92874, 2}, {92880, 1}, {92910, 2}, {92912, 1},
2159 {92918, 2}, {92928, 1}, {92998, 2}, {93008, 1},
2160 {93018, 2}, {93019, 1}, {93026, 2}, {93027, 1},
2161 {93048, 2}, {93053, 1}, {93072, 2}, {93760, 17927683},
2162 {93761, 17927939}, {93762, 17928195}, {93763, 17928451}, {93764, 17928707},
2163 {93765, 17928963}, {93766, 17929219}, {93767, 17929475}, {93768, 17929731},
2164 {93769, 17929987}, {93770, 17930243}, {93771, 17930499}, {93772, 17930755},
2165 {93773, 17931011}, {93774, 17931267}, {93775, 17931523}, {93776, 17931779},
2166 {93777, 17932035}, {93778, 17932291}, {93779, 17932547}, {93780, 17932803},
2167 {93781, 17933059}, {93782, 17933315}, {93783, 17933571}, {93784, 17933827},
2168 {93785, 17934083}, {93786, 17934339}, {93787, 17934595}, {93788, 17934851},
2169 {93789, 17935107}, {93790, 17935363}, {93791, 17935619}, {93792, 1},
2170 {93851, 2}, {93952, 1}, {94027, 2}, {94031, 1},
2171 {94088, 2}, {94095, 1}, {94112, 2}, {94176, 1},
2172 {94181, 2}, {94192, 1}, {94194, 2}, {94208, 1},
2173 {100344, 2}, {100352, 1}, {101590, 2}, {101632, 1},
2174 {101641, 2}, {110576, 1}, {110580, 2}, {110581, 1},
2175 {110588, 2}, {110589, 1}, {110591, 2}, {110592, 1},
2176 {110883, 2}, {110898, 1}, {110899, 2}, {110928, 1},
2177 {110931, 2}, {110933, 1}, {110934, 2}, {110948, 1},
2178 {110952, 2}, {110960, 1}, {111356, 2}, {113664, 1},
2179 {113771, 2}, {113776, 1}, {113789, 2}, {113792, 1},
2180 {113801, 2}, {113808, 1}, {113818, 2}, {113820, 1},
2181 {113824, 0}, {113828, 2}, {118528, 1}, {118574, 2},
2182 {118576, 1}, {118599, 2}, {118608, 1}, {118724, 2},
2183 {118784, 1}, {119030, 2}, {119040, 1}, {119079, 2},
2184 {119081, 1}, {119134, 34713091}, {119135, 34713603}, {119136, 51491331},
2185 {119137, 51492099}, {119138, 51492867}, {119139, 51493635}, {119140, 51494403},
2186 {119141, 1}, {119155, 2}, {119163, 1}, {119227, 34717955},
2187 {119228, 34718467}, {119229, 51496195}, {119230, 51496963}, {119231, 51497731},
2188 {119232, 51498499}, {119233, 1}, {119275, 2}, {119296, 1},
2189 {119366, 2}, {119488, 1}, {119508, 2}, {119520, 1},
2190 {119540, 2}, {119552, 1}, {119639, 2}, {119648, 1},
2191 {119673, 2}, {119808, 16777219}, {119809, 16777475}, {119810, 16777731},
2192 {119811, 16777987}, {119812, 16778243}, {119813, 16778499}, {119814, 16778755},
2193 {119815, 16779011}, {119816, 16779267}, {119817, 16779523}, {119818, 16779779},
2194 {119819, 16780035}, {119820, 16780291}, {119821, 16780547}, {119822, 16780803},
2195 {119823, 16781059}, {119824, 16781315}, {119825, 16781571}, {119826, 16781827},
2196 {119827, 16782083}, {119828, 16782339}, {119829, 16782595}, {119830, 16782851},
2197 {119831, 16783107}, {119832, 16783363}, {119833, 16783619}, {119834, 16777219},
2198 {119835, 16777475}, {119836, 16777731}, {119837, 16777987}, {119838, 16778243},
2199 {119839, 16778499}, {119840, 16778755}, {119841, 16779011}, {119842, 16779267},
2200 {119843, 16779523}, {119844, 16779779}, {119845, 16780035}, {119846, 16780291},
2201 {119847, 16780547}, {119848, 16780803}, {119849, 16781059}, {119850, 16781315},
2202 {119851, 16781571}, {119852, 16781827}, {119853, 16782083}, {119854, 16782339},
2203 {119855, 16782595}, {119856, 16782851}, {119857, 16783107}, {119858, 16783363},
2204 {119859, 16783619}, {119860, 16777219}, {119861, 16777475}, {119862, 16777731},
2205 {119863, 16777987}, {119864, 16778243}, {119865, 16778499}, {119866, 16778755},
2206 {119867, 16779011}, {119868, 16779267}, {119869, 16779523}, {119870, 16779779},
2207 {119871, 16780035}, {119872, 16780291}, {119873, 16780547}, {119874, 16780803},
2208 {119875, 16781059}, {119876, 16781315}, {119877, 16781571}, {119878, 16781827},
2209 {119879, 16782083}, {119880, 16782339}, {119881, 16782595}, {119882, 16782851},
2210 {119883, 16783107}, {119884, 16783363}, {119885, 16783619}, {119886, 16777219},
2211 {119887, 16777475}, {119888, 16777731}, {119889, 16777987}, {119890, 16778243},
2212 {119891, 16778499}, {119892, 16778755}, {119893, 2}, {119894, 16779267},
2213 {119895, 16779523}, {119896, 16779779}, {119897, 16780035}, {119898, 16780291},
2214 {119899, 16780547}, {119900, 16780803}, {119901, 16781059}, {119902, 16781315},
2215 {119903, 16781571}, {119904, 16781827}, {119905, 16782083}, {119906, 16782339},
2216 {119907, 16782595}, {119908, 16782851}, {119909, 16783107}, {119910, 16783363},
2217 {119911, 16783619}, {119912, 16777219}, {119913, 16777475}, {119914, 16777731},
2218 {119915, 16777987}, {119916, 16778243}, {119917, 16778499}, {119918, 16778755},
2219 {119919, 16779011}, {119920, 16779267}, {119921, 16779523}, {119922, 16779779},
2220 {119923, 16780035}, {119924, 16780291}, {119925, 16780547}, {119926, 16780803},
2221 {119927, 16781059}, {119928, 16781315}, {119929, 16781571}, {119930, 16781827},
2222 {119931, 16782083}, {119932, 16782339}, {119933, 16782595}, {119934, 16782851},
2223 {119935, 16783107}, {119936, 16783363}, {119937, 16783619}, {119938, 16777219},
2224 {119939, 16777475}, {119940, 16777731}, {119941, 16777987}, {119942, 16778243},
2225 {119943, 16778499}, {119944, 16778755}, {119945, 16779011}, {119946, 16779267},
2226 {119947, 16779523}, {119948, 16779779}, {119949, 16780035}, {119950, 16780291},
2227 {119951, 16780547}, {119952, 16780803}, {119953, 16781059}, {119954, 16781315},
2228 {119955, 16781571}, {119956, 16781827}, {119957, 16782083}, {119958, 16782339},
2229 {119959, 16782595}, {119960, 16782851}, {119961, 16783107}, {119962, 16783363},
2230 {119963, 16783619}, {119964, 16777219}, {119965, 2}, {119966, 16777731},
2231 {119967, 16777987}, {119968, 2}, {119970, 16778755}, {119971, 2},
2232 {119973, 16779523}, {119974, 16779779}, {119975, 2}, {119977, 16780547},
2233 {119978, 16780803}, {119979, 16781059}, {119980, 16781315}, {119981, 2},
2234 {119982, 16781827}, {119983, 16782083}, {119984, 16782339}, {119985, 16782595},
2235 {119986, 16782851}, {119987, 16783107}, {119988, 16783363}, {119989, 16783619},
2236 {119990, 16777219}, {119991, 16777475}, {119992, 16777731}, {119993, 16777987},
2237 {119994, 2}, {119995, 16778499}, {119996, 2}, {119997, 16779011},
2238 {119998, 16779267}, {119999, 16779523}, {120000, 16779779}, {120001, 16780035},
2239 {120002, 16780291}, {120003, 16780547}, {120004, 2}, {120005, 16781059},
2240 {120006, 16781315}, {120007, 16781571}, {120008, 16781827}, {120009, 16782083},
2241 {120010, 16782339}, {120011, 16782595}, {120012, 16782851}, {120013, 16783107},
2242 {120014, 16783363}, {120015, 16783619}, {120016, 16777219}, {120017, 16777475},
2243 {120018, 16777731}, {120019, 16777987}, {120020, 16778243}, {120021, 16778499},
2244 {120022, 16778755}, {120023, 16779011}, {120024, 16779267}, {120025, 16779523},
2245 {120026, 16779779}, {120027, 16780035}, {120028, 16780291}, {120029, 16780547},
2246 {120030, 16780803}, {120031, 16781059}, {120032, 16781315}, {120033, 16781571},
2247 {120034, 16781827}, {120035, 16782083}, {120036, 16782339}, {120037, 16782595},
2248 {120038, 16782851}, {120039, 16783107}, {120040, 16783363}, {120041, 16783619},
2249 {120042, 16777219}, {120043, 16777475}, {120044, 16777731}, {120045, 16777987},
2250 {120046, 16778243}, {120047, 16778499}, {120048, 16778755}, {120049, 16779011},
2251 {120050, 16779267}, {120051, 16779523}, {120052, 16779779}, {120053, 16780035},
2252 {120054, 16780291}, {120055, 16780547}, {120056, 16780803}, {120057, 16781059},
2253 {120058, 16781315}, {120059, 16781571}, {120060, 16781827}, {120061, 16782083},
2254 {120062, 16782339}, {120063, 16782595}, {120064, 16782851}, {120065, 16783107},
2255 {120066, 16783363}, {120067, 16783619}, {120068, 16777219}, {120069, 16777475},
2256 {120070, 2}, {120071, 16777987}, {120072, 16778243}, {120073, 16778499},
2257 {120074, 16778755}, {120075, 2}, {120077, 16779523}, {120078, 16779779},
2258 {120079, 16780035}, {120080, 16780291}, {120081, 16780547}, {120082, 16780803},
2259 {120083, 16781059}, {120084, 16781315}, {120085, 2}, {120086, 16781827},
2260 {120087, 16782083}, {120088, 16782339}, {120089, 16782595}, {120090, 16782851},
2261 {120091, 16783107}, {120092, 16783363}, {120093, 2}, {120094, 16777219},
2262 {120095, 16777475}, {120096, 16777731}, {120097, 16777987}, {120098, 16778243},
2263 {120099, 16778499}, {120100, 16778755}, {120101, 16779011}, {120102, 16779267},
2264 {120103, 16779523}, {120104, 16779779}, {120105, 16780035}, {120106, 16780291},
2265 {120107, 16780547}, {120108, 16780803}, {120109, 16781059}, {120110, 16781315},
2266 {120111, 16781571}, {120112, 16781827}, {120113, 16782083}, {120114, 16782339},
2267 {120115, 16782595}, {120116, 16782851}, {120117, 16783107}, {120118, 16783363},
2268 {120119, 16783619}, {120120, 16777219}, {120121, 16777475}, {120122, 2},
2269 {120123, 16777987}, {120124, 16778243}, {120125, 16778499}, {120126, 16778755},
2270 {120127, 2}, {120128, 16779267}, {120129, 16779523}, {120130, 16779779},
2271 {120131, 16780035}, {120132, 16780291}, {120133, 2}, {120134, 16780803},
2272 {120135, 2}, {120138, 16781827}, {120139, 16782083}, {120140, 16782339},
2273 {120141, 16782595}, {120142, 16782851}, {120143, 16783107}, {120144, 16783363},
2274 {120145, 2}, {120146, 16777219}, {120147, 16777475}, {120148, 16777731},
2275 {120149, 16777987}, {120150, 16778243}, {120151, 16778499}, {120152, 16778755},
2276 {120153, 16779011}, {120154, 16779267}, {120155, 16779523}, {120156, 16779779},
2277 {120157, 16780035}, {120158, 16780291}, {120159, 16780547}, {120160, 16780803},
2278 {120161, 16781059}, {120162, 16781315}, {120163, 16781571}, {120164, 16781827},
2279 {120165, 16782083}, {120166, 16782339}, {120167, 16782595}, {120168, 16782851},
2280 {120169, 16783107}, {120170, 16783363}, {120171, 16783619}, {120172, 16777219},
2281 {120173, 16777475}, {120174, 16777731}, {120175, 16777987}, {120176, 16778243},
2282 {120177, 16778499}, {120178, 16778755}, {120179, 16779011}, {120180, 16779267},
2283 {120181, 16779523}, {120182, 16779779}, {120183, 16780035}, {120184, 16780291},
2284 {120185, 16780547}, {120186, 16780803}, {120187, 16781059}, {120188, 16781315},
2285 {120189, 16781571}, {120190, 16781827}, {120191, 16782083}, {120192, 16782339},
2286 {120193, 16782595}, {120194, 16782851}, {120195, 16783107}, {120196, 16783363},
2287 {120197, 16783619}, {120198, 16777219}, {120199, 16777475}, {120200, 16777731},
2288 {120201, 16777987}, {120202, 16778243}, {120203, 16778499}, {120204, 16778755},
2289 {120205, 16779011}, {120206, 16779267}, {120207, 16779523}, {120208, 16779779},
2290 {120209, 16780035}, {120210, 16780291}, {120211, 16780547}, {120212, 16780803},
2291 {120213, 16781059}, {120214, 16781315}, {120215, 16781571}, {120216, 16781827},
2292 {120217, 16782083}, {120218, 16782339}, {120219, 16782595}, {120220, 16782851},
2293 {120221, 16783107}, {120222, 16783363}, {120223, 16783619}, {120224, 16777219},
2294 {120225, 16777475}, {120226, 16777731}, {120227, 16777987}, {120228, 16778243},
2295 {120229, 16778499}, {120230, 16778755}, {120231, 16779011}, {120232, 16779267},
2296 {120233, 16779523}, {120234, 16779779}, {120235, 16780035}, {120236, 16780291},
2297 {120237, 16780547}, {120238, 16780803}, {120239, 16781059}, {120240, 16781315},
2298 {120241, 16781571}, {120242, 16781827}, {120243, 16782083}, {120244, 16782339},
2299 {120245, 16782595}, {120246, 16782851}, {120247, 16783107}, {120248, 16783363},
2300 {120249, 16783619}, {120250, 16777219}, {120251, 16777475}, {120252, 16777731},
2301 {120253, 16777987}, {120254, 16778243}, {120255, 16778499}, {120256, 16778755},
2302 {120257, 16779011}, {120258, 16779267}, {120259, 16779523}, {120260, 16779779},
2303 {120261, 16780035}, {120262, 16780291}, {120263, 16780547}, {120264, 16780803},
2304 {120265, 16781059}, {120266, 16781315}, {120267, 16781571}, {120268, 16781827},
2305 {120269, 16782083}, {120270, 16782339}, {120271, 16782595}, {120272, 16782851},
2306 {120273, 16783107}, {120274, 16783363}, {120275, 16783619}, {120276, 16777219},
2307 {120277, 16777475}, {120278, 16777731}, {120279, 16777987}, {120280, 16778243},
2308 {120281, 16778499}, {120282, 16778755}, {120283, 16779011}, {120284, 16779267},
2309 {120285, 16779523}, {120286, 16779779}, {120287, 16780035}, {120288, 16780291},
2310 {120289, 16780547}, {120290, 16780803}, {120291, 16781059}, {120292, 16781315},
2311 {120293, 16781571}, {120294, 16781827}, {120295, 16782083}, {120296, 16782339},
2312 {120297, 16782595}, {120298, 16782851}, {120299, 16783107}, {120300, 16783363},
2313 {120301, 16783619}, {120302, 16777219}, {120303, 16777475}, {120304, 16777731},
2314 {120305, 16777987}, {120306, 16778243}, {120307, 16778499}, {120308, 16778755},
2315 {120309, 16779011}, {120310, 16779267}, {120311, 16779523}, {120312, 16779779},
2316 {120313, 16780035}, {120314, 16780291}, {120315, 16780547}, {120316, 16780803},
2317 {120317, 16781059}, {120318, 16781315}, {120319, 16781571}, {120320, 16781827},
2318 {120321, 16782083}, {120322, 16782339}, {120323, 16782595}, {120324, 16782851},
2319 {120325, 16783107}, {120326, 16783363}, {120327, 16783619}, {120328, 16777219},
2320 {120329, 16777475}, {120330, 16777731}, {120331, 16777987}, {120332, 16778243},
2321 {120333, 16778499}, {120334, 16778755}, {120335, 16779011}, {120336, 16779267},
2322 {120337, 16779523}, {120338, 16779779}, {120339, 16780035}, {120340, 16780291},
2323 {120341, 16780547}, {120342, 16780803}, {120343, 16781059}, {120344, 16781315},
2324 {120345, 16781571}, {120346, 16781827}, {120347, 16782083}, {120348, 16782339},
2325 {120349, 16782595}, {120350, 16782851}, {120351, 16783107}, {120352, 16783363},
2326 {120353, 16783619}, {120354, 16777219}, {120355, 16777475}, {120356, 16777731},
2327 {120357, 16777987}, {120358, 16778243}, {120359, 16778499}, {120360, 16778755},
2328 {120361, 16779011}, {120362, 16779267}, {120363, 16779523}, {120364, 16779779},
2329 {120365, 16780035}, {120366, 16780291}, {120367, 16780547}, {120368, 16780803},
2330 {120369, 16781059}, {120370, 16781315}, {120371, 16781571}, {120372, 16781827},
2331 {120373, 16782083}, {120374, 16782339}, {120375, 16782595}, {120376, 16782851},
2332 {120377, 16783107}, {120378, 16783363}, {120379, 16783619}, {120380, 16777219},
2333 {120381, 16777475}, {120382, 16777731}, {120383, 16777987}, {120384, 16778243},
2334 {120385, 16778499}, {120386, 16778755}, {120387, 16779011}, {120388, 16779267},
2335 {120389, 16779523}, {120390, 16779779}, {120391, 16780035}, {120392, 16780291},
2336 {120393, 16780547}, {120394, 16780803}, {120395, 16781059}, {120396, 16781315},
2337 {120397, 16781571}, {120398, 16781827}, {120399, 16782083}, {120400, 16782339},
2338 {120401, 16782595}, {120402, 16782851}, {120403, 16783107}, {120404, 16783363},
2339 {120405, 16783619}, {120406, 16777219}, {120407, 16777475}, {120408, 16777731},
2340 {120409, 16777987}, {120410, 16778243}, {120411, 16778499}, {120412, 16778755},
2341 {120413, 16779011}, {120414, 16779267}, {120415, 16779523}, {120416, 16779779},
2342 {120417, 16780035}, {120418, 16780291}, {120419, 16780547}, {120420, 16780803},
2343 {120421, 16781059}, {120422, 16781315}, {120423, 16781571}, {120424, 16781827},
2344 {120425, 16782083}, {120426, 16782339}, {120427, 16782595}, {120428, 16782851},
2345 {120429, 16783107}, {120430, 16783363}, {120431, 16783619}, {120432, 16777219},
2346 {120433, 16777475}, {120434, 16777731}, {120435, 16777987}, {120436, 16778243},
2347 {120437, 16778499}, {120438, 16778755}, {120439, 16779011}, {120440, 16779267},
2348 {120441, 16779523}, {120442, 16779779}, {120443, 16780035}, {120444, 16780291},
2349 {120445, 16780547}, {120446, 16780803}, {120447, 16781059}, {120448, 16781315},
2350 {120449, 16781571}, {120450, 16781827}, {120451, 16782083}, {120452, 16782339},
2351 {120453, 16782595}, {120454, 16782851}, {120455, 16783107}, {120456, 16783363},
2352 {120457, 16783619}, {120458, 16777219}, {120459, 16777475}, {120460, 16777731},
2353 {120461, 16777987}, {120462, 16778243}, {120463, 16778499}, {120464, 16778755},
2354 {120465, 16779011}, {120466, 16779267}, {120467, 16779523}, {120468, 16779779},
2355 {120469, 16780035}, {120470, 16780291}, {120471, 16780547}, {120472, 16780803},
2356 {120473, 16781059}, {120474, 16781315}, {120475, 16781571}, {120476, 16781827},
2357 {120477, 16782083}, {120478, 16782339}, {120479, 16782595}, {120480, 16782851},
2358 {120481, 16783107}, {120482, 16783363}, {120483, 16783619}, {120484, 17944835},
2359 {120485, 17945091}, {120486, 2}, {120488, 16851715}, {120489, 16851971},
2360 {120490, 16852227}, {120491, 16852483}, {120492, 16852739}, {120493, 16852995},
2361 {120494, 16853251}, {120495, 16853507}, {120496, 16846851}, {120497, 16853763},
2362 {120498, 16854019}, {120499, 16786179}, {120500, 16854275}, {120501, 16854531},
2363 {120502, 16854787}, {120503, 16855043}, {120504, 16855299}, {120505, 16853507},
2364 {120506, 16855555}, {120507, 16855811}, {120508, 16856067}, {120509, 16856323},
2365 {120510, 16856579}, {120511, 16856835}, {120512, 16857091}, {120513, 17945347},
2366 {120514, 16851715}, {120515, 16851971}, {120516, 16852227}, {120517, 16852483},
2367 {120518, 16852739}, {120519, 16852995}, {120520, 16853251}, {120521, 16853507},
2368 {120522, 16846851}, {120523, 16853763}, {120524, 16854019}, {120525, 16786179},
2369 {120526, 16854275}, {120527, 16854531}, {120528, 16854787}, {120529, 16855043},
2370 {120530, 16855299}, {120531, 16855555}, {120533, 16855811}, {120534, 16856067},
2371 {120535, 16856323}, {120536, 16856579}, {120537, 16856835}, {120538, 16857091},
2372 {120539, 17945603}, {120540, 16852739}, {120541, 16853507}, {120542, 16853763},
2373 {120543, 16856323}, {120544, 16855299}, {120545, 16855043}, {120546, 16851715},
2374 {120547, 16851971}, {120548, 16852227}, {120549, 16852483}, {120550, 16852739},
2375 {120551, 16852995}, {120552, 16853251}, {120553, 16853507}, {120554, 16846851},
2376 {120555, 16853763}, {120556, 16854019}, {120557, 16786179}, {120558, 16854275},
2377 {120559, 16854531}, {120560, 16854787}, {120561, 16855043}, {120562, 16855299},
2378 {120563, 16853507}, {120564, 16855555}, {120565, 16855811}, {120566, 16856067},
2379 {120567, 16856323}, {120568, 16856579}, {120569, 16856835}, {120570, 16857091},
2380 {120571, 17945347}, {120572, 16851715}, {120573, 16851971}, {120574, 16852227},
2381 {120575, 16852483}, {120576, 16852739}, {120577, 16852995}, {120578, 16853251},
2382 {120579, 16853507}, {120580, 16846851}, {120581, 16853763}, {120582, 16854019},
2383 {120583, 16786179}, {120584, 16854275}, {120585, 16854531}, {120586, 16854787},
2384 {120587, 16855043}, {120588, 16855299}, {120589, 16855555}, {120591, 16855811},
2385 {120592, 16856067}, {120593, 16856323}, {120594, 16856579}, {120595, 16856835},
2386 {120596, 16857091}, {120597, 17945603}, {120598, 16852739}, {120599, 16853507},
2387 {120600, 16853763}, {120601, 16856323}, {120602, 16855299}, {120603, 16855043},
2388 {120604, 16851715}, {120605, 16851971}, {120606, 16852227}, {120607, 16852483},
2389 {120608, 16852739}, {120609, 16852995}, {120610, 16853251}, {120611, 16853507},
2390 {120612, 16846851}, {120613, 16853763}, {120614, 16854019}, {120615, 16786179},
2391 {120616, 16854275}, {120617, 16854531}, {120618, 16854787}, {120619, 16855043},
2392 {120620, 16855299}, {120621, 16853507}, {120622, 16855555}, {120623, 16855811},
2393 {120624, 16856067}, {120625, 16856323}, {120626, 16856579}, {120627, 16856835},
2394 {120628, 16857091}, {120629, 17945347}, {120630, 16851715}, {120631, 16851971},
2395 {120632, 16852227}, {120633, 16852483}, {120634, 16852739}, {120635, 16852995},
2396 {120636, 16853251}, {120637, 16853507}, {120638, 16846851}, {120639, 16853763},
2397 {120640, 16854019}, {120641, 16786179}, {120642, 16854275}, {120643, 16854531},
2398 {120644, 16854787}, {120645, 16855043}, {120646, 16855299}, {120647, 16855555},
2399 {120649, 16855811}, {120650, 16856067}, {120651, 16856323}, {120652, 16856579},
2400 {120653, 16856835}, {120654, 16857091}, {120655, 17945603}, {120656, 16852739},
2401 {120657, 16853507}, {120658, 16853763}, {120659, 16856323}, {120660, 16855299},
2402 {120661, 16855043}, {120662, 16851715}, {120663, 16851971}, {120664, 16852227},
2403 {120665, 16852483}, {120666, 16852739}, {120667, 16852995}, {120668, 16853251},
2404 {120669, 16853507}, {120670, 16846851}, {120671, 16853763}, {120672, 16854019},
2405 {120673, 16786179}, {120674, 16854275}, {120675, 16854531}, {120676, 16854787},
2406 {120677, 16855043}, {120678, 16855299}, {120679, 16853507}, {120680, 16855555},
2407 {120681, 16855811}, {120682, 16856067}, {120683, 16856323}, {120684, 16856579},
2408 {120685, 16856835}, {120686, 16857091}, {120687, 17945347}, {120688, 16851715},
2409 {120689, 16851971}, {120690, 16852227}, {120691, 16852483}, {120692, 16852739},
2410 {120693, 16852995}, {120694, 16853251}, {120695, 16853507}, {120696, 16846851},
2411 {120697, 16853763}, {120698, 16854019}, {120699, 16786179}, {120700, 16854275},
2412 {120701, 16854531}, {120702, 16854787}, {120703, 16855043}, {120704, 16855299},
2413 {120705, 16855555}, {120707, 16855811}, {120708, 16856067}, {120709, 16856323},
2414 {120710, 16856579}, {120711, 16856835}, {120712, 16857091}, {120713, 17945603},
2415 {120714, 16852739}, {120715, 16853507}, {120716, 16853763}, {120717, 16856323},
2416 {120718, 16855299}, {120719, 16855043}, {120720, 16851715}, {120721, 16851971},
2417 {120722, 16852227}, {120723, 16852483}, {120724, 16852739}, {120725, 16852995},
2418 {120726, 16853251}, {120727, 16853507}, {120728, 16846851}, {120729, 16853763},
2419 {120730, 16854019}, {120731, 16786179}, {120732, 16854275}, {120733, 16854531},
2420 {120734, 16854787}, {120735, 16855043}, {120736, 16855299}, {120737, 16853507},
2421 {120738, 16855555}, {120739, 16855811}, {120740, 16856067}, {120741, 16856323},
2422 {120742, 16856579}, {120743, 16856835}, {120744, 16857091}, {120745, 17945347},
2423 {120746, 16851715}, {120747, 16851971}, {120748, 16852227}, {120749, 16852483},
2424 {120750, 16852739}, {120751, 16852995}, {120752, 16853251}, {120753, 16853507},
2425 {120754, 16846851}, {120755, 16853763}, {120756, 16854019}, {120757, 16786179},
2426 {120758, 16854275}, {120759, 16854531}, {120760, 16854787}, {120761, 16855043},
2427 {120762, 16855299}, {120763, 16855555}, {120765, 16855811}, {120766, 16856067},
2428 {120767, 16856323}, {120768, 16856579}, {120769, 16856835}, {120770, 16857091},
2429 {120771, 17945603}, {120772, 16852739}, {120773, 16853507}, {120774, 16853763},
2430 {120775, 16856323}, {120776, 16855299}, {120777, 16855043}, {120778, 16858627},
2431 {120780, 2}, {120782, 17035523}, {120783, 16786947}, {120784, 16785155},
2432 {120785, 16785411}, {120786, 16787715}, {120787, 17035779}, {120788, 17036035},
2433 {120789, 17036291}, {120790, 17036547}, {120791, 17036803}, {120792, 17035523},
2434 {120793, 16786947}, {120794, 16785155}, {120795, 16785411}, {120796, 16787715},
2435 {120797, 17035779}, {120798, 17036035}, {120799, 17036291}, {120800, 17036547},
2436 {120801, 17036803}, {120802, 17035523}, {120803, 16786947}, {120804, 16785155},
2437 {120805, 16785411}, {120806, 16787715}, {120807, 17035779}, {120808, 17036035},
2438 {120809, 17036291}, {120810, 17036547}, {120811, 17036803}, {120812, 17035523},
2439 {120813, 16786947}, {120814, 16785155}, {120815, 16785411}, {120816, 16787715},
2440 {120817, 17035779}, {120818, 17036035}, {120819, 17036291}, {120820, 17036547},
2441 {120821, 17036803}, {120822, 17035523}, {120823, 16786947}, {120824, 16785155},
2442 {120825, 16785411}, {120826, 16787715}, {120827, 17035779}, {120828, 17036035},
2443 {120829, 17036291}, {120830, 17036547}, {120831, 17036803}, {120832, 1},
2444 {121484, 2}, {121499, 1}, {121504, 2}, {121505, 1},
2445 {121520, 2}, {122624, 1}, {122655, 2}, {122661, 1},
2446 {122667, 2}, {122880, 1}, {122887, 2}, {122888, 1},
2447 {122905, 2}, {122907, 1}, {122914, 2}, {122915, 1},
2448 {122917, 2}, {122918, 1}, {122923, 2}, {122928, 16866563},
2449 {122929, 16866819}, {122930, 16867075}, {122931, 16867331}, {122932, 16867587},
2450 {122933, 16867843}, {122934, 16868099}, {122935, 16868355}, {122936, 16868611},
2451 {122937, 16869123}, {122938, 16869379}, {122939, 16869635}, {122940, 16870147},
2452 {122941, 16870403}, {122942, 16870659}, {122943, 16870915}, {122944, 16871171},
2453 {122945, 16871427}, {122946, 16871683}, {122947, 16871939}, {122948, 16872195},
2454 {122949, 16872451}, {122950, 16872707}, {122951, 16873475}, {122952, 16873987},
2455 {122953, 16874243}, {122954, 17495299}, {122955, 16888835}, {122956, 16864003},
2456 {122957, 16864515}, {122958, 16890883}, {122959, 16883715}, {122960, 17945859},
2457 {122961, 16866563}, {122962, 16866819}, {122963, 16867075}, {122964, 16867331},
2458 {122965, 16867587}, {122966, 16867843}, {122967, 16868099}, {122968, 16868355},
2459 {122969, 16868611}, {122970, 16869123}, {122971, 16869379}, {122972, 16870147},
2460 {122973, 16870403}, {122974, 16870915}, {122975, 16871427}, {122976, 16871683},
2461 {122977, 16871939}, {122978, 16872195}, {122979, 16872451}, {122980, 16872707},
2462 {122981, 16873219}, {122982, 16873475}, {122983, 16879875}, {122984, 16864003},
2463 {122985, 16863747}, {122986, 16866307}, {122987, 16883203}, {122988, 17490435},
2464 {122989, 16883971}, {122990, 2}, {123023, 1}, {123024, 2},
2465 {123136, 1}, {123181, 2}, {123184, 1}, {123198, 2},
2466 {123200, 1}, {123210, 2}, {123214, 1}, {123216, 2},
2467 {123536, 1}, {123567, 2}, {123584, 1}, {123642, 2},
2468 {123647, 1}, {123648, 2}, {124112, 1}, {124154, 2},
2469 {124896, 1}, {124903, 2}, {124904, 1}, {124908, 2},
2470 {124909, 1}, {124911, 2}, {124912, 1}, {124927, 2},
2471 {124928, 1}, {125125, 2}, {125127, 1}, {125143, 2},
2472 {125184, 17946115}, {125185, 17946371}, {125186, 17946627}, {125187, 17946883},
2473 {125188, 17947139}, {125189, 17947395}, {125190, 17947651}, {125191, 17947907},
2474 {125192, 17948163}, {125193, 17948419}, {125194, 17948675}, {125195, 17948931},
2475 {125196, 17949187}, {125197, 17949443}, {125198, 17949699}, {125199, 17949955},
2476 {125200, 17950211}, {125201, 17950467}, {125202, 17950723}, {125203, 17950979},
2477 {125204, 17951235}, {125205, 17951491}, {125206, 17951747}, {125207, 17952003},
2478 {125208, 17952259}, {125209, 17952515}, {125210, 17952771}, {125211, 17953027},
2479 {125212, 17953283}, {125213, 17953539}, {125214, 17953795}, {125215, 17954051},
2480 {125216, 17954307}, {125217, 17954563}, {125218, 1}, {125260, 2},
2481 {125264, 1}, {125274, 2}, {125278, 1}, {125280, 2},
2482 {126065, 1}, {126133, 2}, {126209, 1}, {126270, 2},
2483 {126464, 16910339}, {126465, 17683715}, {126466, 17681923}, {126467, 17834499},
2484 {126468, 2}, {126469, 16910851}, {126470, 17731587}, {126471, 17682435},
2485 {126472, 17700099}, {126473, 16911875}, {126474, 17708803}, {126475, 17711107},
2486 {126476, 17682947}, {126477, 17718019}, {126478, 17694979}, {126479, 17701635},
2487 {126480, 17703683}, {126481, 17697027}, {126482, 17706755}, {126483, 17725187},
2488 {126484, 17745155}, {126485, 17686787}, {126486, 17689859}, {126487, 17684995},
2489 {126488, 17724675}, {126489, 17698051}, {126490, 17701123}, {126491, 17702659},
2490 {126492, 17954819}, {126493, 17673475}, {126494, 17955075}, {126495, 17955331},
2491 {126496, 2}, {126497, 17683715}, {126498, 17681923}, {126499, 2},
2492 {126500, 17721091}, {126501, 2}, {126503, 17682435}, {126504, 2},
2493 {126505, 16911875}, {126506, 17708803}, {126507, 17711107}, {126508, 17682947},
2494 {126509, 17718019}, {126510, 17694979}, {126511, 17701635}, {126512, 17703683},
2495 {126513, 17697027}, {126514, 17706755}, {126515, 2}, {126516, 17745155},
2496 {126517, 17686787}, {126518, 17689859}, {126519, 17684995}, {126520, 2},
2497 {126521, 17698051}, {126522, 2}, {126523, 17702659}, {126524, 2},
2498 {126530, 17681923}, {126531, 2}, {126535, 17682435}, {126536, 2},
2499 {126537, 16911875}, {126538, 2}, {126539, 17711107}, {126540, 2},
2500 {126541, 17718019}, {126542, 17694979}, {126543, 17701635}, {126544, 2},
2501 {126545, 17697027}, {126546, 17706755}, {126547, 2}, {126548, 17745155},
2502 {126549, 2}, {126551, 17684995}, {126552, 2}, {126553, 17698051},
2503 {126554, 2}, {126555, 17702659}, {126556, 2}, {126557, 17673475},
2504 {126558, 2}, {126559, 17955331}, {126560, 2}, {126561, 17683715},
2505 {126562, 17681923}, {126563, 2}, {126564, 17721091}, {126565, 2},
2506 {126567, 17682435}, {126568, 17700099}, {126569, 16911875}, {126570, 17708803},
2507 {126571, 2}, {126572, 17682947}, {126573, 17718019}, {126574, 17694979},
2508 {126575, 17701635}, {126576, 17703683}, {126577, 17697027}, {126578, 17706755},
2509 {126579, 2}, {126580, 17745155}, {126581, 17686787}, {126582, 17689859},
2510 {126583, 17684995}, {126584, 2}, {126585, 17698051}, {126586, 17701123},
2511 {126587, 17702659}, {126588, 17954819}, {126589, 2}, {126590, 17955075},
2512 {126591, 2}, {126592, 16910339}, {126593, 17683715}, {126594, 17681923},
2513 {126595, 17834499}, {126596, 17721091}, {126597, 16910851}, {126598, 17731587},
2514 {126599, 17682435}, {126600, 17700099}, {126601, 16911875}, {126602, 2},
2515 {126603, 17711107}, {126604, 17682947}, {126605, 17718019}, {126606, 17694979},
2516 {126607, 17701635}, {126608, 17703683}, {126609, 17697027}, {126610, 17706755},
2517 {126611, 17725187}, {126612, 17745155}, {126613, 17686787}, {126614, 17689859},
2518 {126615, 17684995}, {126616, 17724675}, {126617, 17698051}, {126618, 17701123},
2519 {126619, 17702659}, {126620, 2}, {126625, 17683715}, {126626, 17681923},
2520 {126627, 17834499}, {126628, 2}, {126629, 16910851}, {126630, 17731587},
2521 {126631, 17682435}, {126632, 17700099}, {126633, 16911875}, {126634, 2},
2522 {126635, 17711107}, {126636, 17682947}, {126637, 17718019}, {126638, 17694979},
2523 {126639, 17701635}, {126640, 17703683}, {126641, 17697027}, {126642, 17706755},
2524 {126643, 17725187}, {126644, 17745155}, {126645, 17686787}, {126646, 17689859},
2525 {126647, 17684995}, {126648, 17724675}, {126649, 17698051}, {126650, 17701123},
2526 {126651, 17702659}, {126652, 2}, {126704, 1}, {126706, 2},
2527 {126976, 1}, {127020, 2}, {127024, 1}, {127124, 2},
2528 {127136, 1}, {127151, 2}, {127153, 1}, {127168, 2},
2529 {127169, 1}, {127184, 2}, {127185, 1}, {127222, 2},
2530 {127233, 34732803}, {127234, 34733315}, {127235, 34733827}, {127236, 34734339},
2531 {127237, 34734851}, {127238, 34735363}, {127239, 34735875}, {127240, 34736387},
2532 {127241, 34736899}, {127242, 34737411}, {127243, 1}, {127248, 50644995},
2533 {127249, 50645763}, {127250, 50646531}, {127251, 50647299}, {127252, 50648067},
2534 {127253, 50648835}, {127254, 50649603}, {127255, 50650371}, {127256, 50651139},
2535 {127257, 50651907}, {127258, 50652675}, {127259, 50653443}, {127260, 50654211},
2536 {127261, 50654979}, {127262, 50655747}, {127263, 50656515}, {127264, 50657283},
2537 {127265, 50658051}, {127266, 50658819}, {127267, 50659587}, {127268, 50660355},
2538 {127269, 50661123}, {127270, 50661891}, {127271, 50662659}, {127272, 50663427},
2539 {127273, 50664195}, {127274, 51515139}, {127275, 16777731}, {127276, 16781571},
2540 {127277, 33554947}, {127278, 34738691}, {127279, 1}, {127280, 16777219},
2541 {127281, 16777475}, {127282, 16777731}, {127283, 16777987}, {127284, 16778243},
2542 {127285, 16778499}, {127286, 16778755}, {127287, 16779011}, {127288, 16779267},
2543 {127289, 16779523}, {127290, 16779779}, {127291, 16780035}, {127292, 16780291},
2544 {127293, 16780547}, {127294, 16780803}, {127295, 16781059}, {127296, 16781315},
2545 {127297, 16781571}, {127298, 16781827}, {127299, 16782083}, {127300, 16782339},
2546 {127301, 16782595}, {127302, 16782851}, {127303, 16783107}, {127304, 16783363},
2547 {127305, 16783619}, {127306, 34739203}, {127307, 34226691}, {127308, 34739715},
2548 {127309, 33752579}, {127310, 51517443}, {127311, 34740995}, {127312, 1},
2549 {127338, 34209539}, {127339, 34189571}, {127340, 34741507}, {127341, 1},
2550 {127376, 34742019}, {127377, 1}, {127406, 2}, {127462, 1},
2551 {127488, 34742531}, {127489, 34743043}, {127490, 17307907}, {127491, 2},
2552 {127504, 17157891}, {127505, 17966339}, {127506, 17966595}, {127507, 17351683},
2553 {127508, 17143299}, {127509, 17966851}, {127510, 17967107}, {127511, 17225475},
2554 {127512, 17967363}, {127513, 17967619}, {127514, 17967875}, {127515, 17584643},
2555 {127516, 17968131}, {127517, 17968387}, {127518, 17968643}, {127519, 17968899},
2556 {127520, 17969155}, {127521, 17969411}, {127522, 17167107}, {127523, 17969667},
2557 {127524, 17969923}, {127525, 17970179}, {127526, 17970435}, {127527, 17970691},
2558 {127528, 17970947}, {127529, 17141763}, {127530, 17223427}, {127531, 17971203},
2559 {127532, 17288707}, {127533, 17224195}, {127534, 17288963}, {127535, 17971459},
2560 {127536, 17181443}, {127537, 17971715}, {127538, 17971971}, {127539, 17972227},
2561 {127540, 17972483}, {127541, 17972739}, {127542, 17264387}, {127543, 17160451},
2562 {127544, 17972995}, {127545, 17973251}, {127546, 17973507}, {127547, 17973763},
2563 {127548, 2}, {127552, 51528451}, {127553, 51529219}, {127554, 51529987},
2564 {127555, 51530755}, {127556, 51531523}, {127557, 51532291}, {127558, 51533059},
2565 {127559, 51533827}, {127560, 51534595}, {127561, 2}, {127568, 17980931},
2566 {127569, 17981187}, {127570, 2}, {127584, 1}, {127590, 2},
2567 {127744, 1}, {128728, 2}, {128732, 1}, {128749, 2},
2568 {128752, 1}, {128765, 2}, {128768, 1}, {128887, 2},
2569 {128891, 1}, {128986, 2}, {128992, 1}, {129004, 2},
2570 {129008, 1}, {129009, 2}, {129024, 1}, {129036, 2},
2571 {129040, 1}, {129096, 2}, {129104, 1}, {129114, 2},
2572 {129120, 1}, {129160, 2}, {129168, 1}, {129198, 2},
2573 {129200, 1}, {129202, 2}, {129280, 1}, {129620, 2},
2574 {129632, 1}, {129646, 2}, {129648, 1}, {129661, 2},
2575 {129664, 1}, {129673, 2}, {129680, 1}, {129726, 2},
2576 {129727, 1}, {129734, 2}, {129742, 1}, {129756, 2},
2577 {129760, 1}, {129769, 2}, {129776, 1}, {129785, 2},
2578 {129792, 1}, {129939, 2}, {129940, 1}, {129995, 2},
2579 {130032, 17035523}, {130033, 16786947}, {130034, 16785155}, {130035, 16785411},
2580 {130036, 16787715}, {130037, 17035779}, {130038, 17036035}, {130039, 17036291},
2581 {130040, 17036547}, {130041, 17036803}, {130042, 2}, {131072, 1},
2582 {173792, 2}, {173824, 1}, {177978, 2}, {177984, 1},
2583 {178206, 2}, {178208, 1}, {183970, 2}, {183984, 1},
2584 {191457, 2}, {194560, 17981443}, {194561, 17981699}, {194562, 17981955},
2585 {194563, 17982211}, {194564, 17982467}, {194565, 17608451}, {194566, 17982723},
2586 {194567, 17982979}, {194568, 17983235}, {194569, 17983491}, {194570, 17608707},
2587 {194571, 17983747}, {194572, 17984003}, {194573, 17984259}, {194574, 17608963},
2588 {194575, 17984515}, {194576, 17984771}, {194577, 17985027}, {194578, 17985283},
2589 {194579, 17985539}, {194580, 17985795}, {194581, 17968643}, {194582, 17986051},
2590 {194583, 17986307}, {194584, 17986563}, {194585, 17986819}, {194586, 17987075},
2591 {194587, 17623043}, {194588, 17987331}, {194589, 17145859}, {194590, 17987587},
2592 {194591, 17987843}, {194592, 17988099}, {194593, 17988355}, {194594, 17973251},
2593 {194595, 17988611}, {194596, 17988867}, {194597, 17624323}, {194598, 17609219},
2594 {194599, 17609475}, {194600, 17624579}, {194601, 17989123}, {194602, 17989379},
2595 {194603, 17562883}, {194604, 17989635}, {194605, 17609731}, {194606, 17989891},
2596 {194607, 17990147}, {194608, 17990403}, {194609, 17990659}, {194612, 17990915},
2597 {194613, 17991171}, {194614, 17991427}, {194615, 17991683}, {194616, 17991939},
2598 {194617, 17992195}, {194618, 17992451}, {194619, 17992707}, {194620, 17992963},
2599 {194621, 17993219}, {194622, 17993475}, {194623, 17993731}, {194624, 17993987},
2600 {194625, 17994243}, {194626, 17994499}, {194627, 17994755}, {194628, 17995011},
2601 {194629, 17995267}, {194631, 17625091}, {194632, 17995523}, {194633, 17995779},
2602 {194634, 17996035}, {194635, 17996291}, {194636, 17610243}, {194637, 17996547},
2603 {194638, 17996803}, {194639, 17997059}, {194640, 17600003}, {194641, 17997315},
2604 {194642, 17997571}, {194643, 17997827}, {194644, 17998083}, {194645, 17998339},
2605 {194646, 17998595}, {194647, 17998851}, {194648, 17999107}, {194649, 17999363},
2606 {194650, 17999619}, {194651, 17999875}, {194652, 18000131}, {194653, 17966851},
2607 {194654, 18000387}, {194655, 18000643}, {194656, 18000899}, {194657, 18001155},
2608 {194658, 18001411}, {194659, 18001667}, {194660, 18001923}, {194661, 18002179},
2609 {194662, 18002435}, {194663, 18002691}, {194664, 2}, {194665, 18002947},
2610 {194666, 18003203}, {194668, 18003459}, {194669, 18003715}, {194670, 18003971},
2611 {194671, 17561859}, {194672, 18004227}, {194673, 18004483}, {194674, 18004739},
2612 {194675, 18004995}, {194676, 2}, {194677, 17152515}, {194678, 18005251},
2613 {194679, 18005507}, {194680, 17153027}, {194681, 18005763}, {194682, 18006019},
2614 {194683, 18006275}, {194684, 18006531}, {194685, 18006787}, {194686, 18007043},
2615 {194687, 18007299}, {194688, 18007555}, {194689, 18007811}, {194690, 18008067},
2616 {194691, 18008323}, {194692, 18008579}, {194693, 18008835}, {194694, 18009091},
2617 {194695, 18009347}, {194696, 18009603}, {194697, 18009859}, {194698, 18010115},
2618 {194699, 18010371}, {194700, 18010627}, {194701, 18010883}, {194702, 17548547},
2619 {194703, 18011139}, {194704, 17155587}, {194705, 18011395}, {194707, 18011651},
2620 {194708, 18011907}, {194710, 18012163}, {194711, 18012419}, {194712, 18012675},
2621 {194713, 18012931}, {194714, 18013187}, {194715, 18013443}, {194716, 18013699},
2622 {194717, 18013955}, {194718, 18014211}, {194719, 18014467}, {194720, 18014723},
2623 {194721, 18014979}, {194722, 18015235}, {194723, 17611523}, {194724, 18015491},
2624 {194725, 18015747}, {194726, 18016003}, {194727, 18016259}, {194728, 17628163},
2625 {194729, 18016259}, {194730, 18016515}, {194731, 17612035}, {194732, 18016771},
2626 {194733, 18017027}, {194734, 18017283}, {194735, 18017539}, {194736, 17612291},
2627 {194737, 17541635}, {194738, 17414915}, {194739, 18017795}, {194740, 18018051},
2628 {194741, 18018307}, {194742, 18018563}, {194743, 18018819}, {194744, 18019075},
2629 {194745, 18019331}, {194746, 18019587}, {194747, 18019843}, {194748, 18020099},
2630 {194749, 18020355}, {194750, 18020611}, {194751, 18020867}, {194752, 18021123},
2631 {194753, 18021379}, {194754, 18021635}, {194755, 18021891}, {194756, 18022147},
2632 {194757, 18022403}, {194758, 18022659}, {194759, 18022915}, {194760, 17612547},
2633 {194761, 18023171}, {194762, 18023427}, {194763, 18023683}, {194764, 18023939},
2634 {194765, 18024195}, {194766, 18024451}, {194767, 17613059}, {194768, 18024707},
2635 {194769, 18024963}, {194770, 18025219}, {194771, 18025475}, {194772, 18025731},
2636 {194773, 18025987}, {194774, 18026243}, {194775, 18026499}, {194776, 17548803},
2637 {194777, 17630211}, {194778, 18026755}, {194779, 18027011}, {194780, 18027267},
2638 {194781, 18027523}, {194782, 18027779}, {194783, 18028035}, {194784, 18028291},
2639 {194785, 18028547}, {194786, 17613315}, {194787, 18028803}, {194788, 18029059},
2640 {194789, 18029315}, {194790, 18029571}, {194791, 17640963}, {194792, 18029827},
2641 {194793, 18030083}, {194794, 18030339}, {194795, 18030595}, {194796, 18030851},
2642 {194797, 18031107}, {194798, 18031363}, {194799, 18031619}, {194800, 18031875},
2643 {194801, 18032131}, {194802, 18032387}, {194803, 18032643}, {194804, 18032899},
2644 {194805, 17566211}, {194806, 18033155}, {194807, 18033411}, {194808, 18033667},
2645 {194809, 18033923}, {194810, 18034179}, {194811, 18034435}, {194812, 18034691},
2646 {194813, 18034947}, {194814, 18035203}, {194815, 18035459}, {194816, 18035715},
2647 {194817, 17613571}, {194818, 17587203}, {194819, 18035971}, {194820, 18036227},
2648 {194821, 18036483}, {194822, 18036739}, {194823, 18036995}, {194824, 18037251},
2649 {194825, 18037507}, {194826, 18037763}, {194827, 17630979}, {194828, 18038019},
2650 {194829, 18038275}, {194830, 18038531}, {194831, 18038787}, {194832, 18039043},
2651 {194833, 18039299}, {194834, 18039555}, {194835, 18039811}, {194836, 17631235},
2652 {194837, 18040067}, {194838, 18040323}, {194839, 18040579}, {194840, 18040835},
2653 {194841, 18041091}, {194842, 18041347}, {194843, 18041603}, {194844, 18041859},
2654 {194845, 18042115}, {194846, 18042371}, {194847, 2}, {194848, 18042627},
2655 {194849, 17631747}, {194850, 18042883}, {194851, 18043139}, {194852, 18043395},
2656 {194853, 18043651}, {194854, 18043907}, {194855, 18044163}, {194856, 18044419},
2657 {194857, 18044675}, {194858, 18044931}, {194859, 18045187}, {194860, 18045443},
2658 {194862, 18045699}, {194863, 18045955}, {194864, 17632259}, {194865, 18046211},
2659 {194866, 18046467}, {194867, 18046723}, {194868, 18046979}, {194869, 18047235},
2660 {194870, 18047491}, {194871, 18047747}, {194872, 17562627}, {194873, 18048003},
2661 {194874, 18048259}, {194875, 18048515}, {194876, 18048771}, {194877, 18049027},
2662 {194878, 18049283}, {194879, 18049539}, {194880, 17633795}, {194881, 18049795},
2663 {194882, 18050051}, {194883, 18050307}, {194884, 18050563}, {194885, 18050819},
2664 {194886, 18051075}, {194888, 17634051}, {194889, 17641475}, {194890, 18051331},
2665 {194891, 18051587}, {194892, 18051843}, {194893, 18052099}, {194894, 18052355},
2666 {194895, 17553155}, {194896, 17634563}, {194897, 18052611}, {194898, 18052867},
2667 {194899, 17616131}, {194900, 18053123}, {194901, 18053379}, {194902, 17605123},
2668 {194903, 18053635}, {194904, 18053891}, {194905, 17616899}, {194906, 18054147},
2669 {194907, 18054403}, {194908, 18054659}, {194909, 18054915}, {194911, 2},
2670 {194912, 18055171}, {194913, 18055427}, {194914, 18055683}, {194915, 18055939},
2671 {194916, 18056195}, {194917, 18056451}, {194918, 18056707}, {194919, 18056963},
2672 {194920, 18057219}, {194921, 18057475}, {194922, 18057731}, {194923, 18057987},
2673 {194924, 18058243}, {194925, 18058499}, {194926, 18058755}, {194927, 18059011},
2674 {194928, 18059267}, {194929, 18059523}, {194930, 18059779}, {194931, 18060035},
2675 {194932, 18060291}, {194933, 18060547}, {194934, 18060803}, {194935, 18061059},
2676 {194936, 18061315}, {194937, 18061571}, {194938, 17618435}, {194939, 18061827},
2677 {194940, 18062083}, {194941, 18062339}, {194942, 18062595}, {194943, 18062851},
2678 {194944, 18063107}, {194945, 18063363}, {194946, 18063619}, {194947, 18063875},
2679 {194948, 18064131}, {194949, 18064387}, {194950, 18064643}, {194951, 18064899},
2680 {194952, 18065155}, {194953, 18065411}, {194954, 18065667}, {194955, 18011651},
2681 {194956, 18065923}, {194957, 18066179}, {194958, 18066435}, {194959, 18066691},
2682 {194960, 18066947}, {194961, 18067203}, {194962, 18067459}, {194963, 18067715},
2683 {194964, 18067971}, {194965, 18068227}, {194966, 18068483}, {194967, 18068739},
2684 {194968, 17566979}, {194969, 18068995}, {194970, 18069251}, {194971, 18069507},
2685 {194972, 18069763}, {194973, 18070019}, {194974, 18070275}, {194975, 17619203},
2686 {194976, 18070531}, {194977, 18070787}, {194978, 18071043}, {194979, 18071299},
2687 {194980, 18071555}, {194981, 18071811}, {194982, 18072067}, {194983, 18072323},
2688 {194984, 18072579}, {194985, 18072835}, {194986, 18073091}, {194987, 18073347},
2689 {194988, 18073603}, {194989, 18073859}, {194990, 18074115}, {194991, 18074371},
2690 {194992, 18074627}, {194993, 18074883}, {194994, 18075139}, {194995, 18075395},
2691 {194996, 17551875}, {194997, 18075651}, {194998, 18075907}, {194999, 18076163},
2692 {195000, 18076419}, {195001, 18076675}, {195002, 18076931}, {195003, 17636355},
2693 {195004, 18077187}, {195005, 18077443}, {195006, 18077699}, {195007, 2},
2694 {195008, 18077955}, {195009, 18078211}, {195010, 18078467}, {195011, 18078723},
2695 {195012, 17178627}, {195013, 18078979}, {195014, 18079235}, {195015, 18079491},
2696 {195016, 18079747}, {195017, 18080003}, {195018, 18080259}, {195019, 18080515},
2697 {195020, 18080771}, {195021, 18081027}, {195022, 18081283}, {195023, 18081539},
2698 {195024, 17637635}, {195025, 17637891}, {195026, 17180419}, {195027, 18081795},
2699 {195028, 18082051}, {195029, 18082307}, {195030, 18082563}, {195031, 18082819},
2700 {195032, 18083075}, {195033, 18083331}, {195034, 18083587}, {195035, 18083843},
2701 {195036, 18084099}, {195037, 18084355}, {195038, 18084611}, {195039, 17638147},
2702 {195040, 18084867}, {195041, 18085123}, {195042, 18085379}, {195043, 18085635},
2703 {195044, 18085891}, {195045, 18086147}, {195046, 18086403}, {195047, 18086659},
2704 {195048, 18086915}, {195049, 18087171}, {195050, 18087427}, {195051, 18087683},
2705 {195052, 18087939}, {195053, 18088195}, {195054, 18088451}, {195055, 18088707},
2706 {195056, 18088963}, {195057, 18089219}, {195058, 18089475}, {195059, 18089731},
2707 {195060, 18089987}, {195061, 18090243}, {195062, 18090499}, {195063, 18090755},
2708 {195064, 18091011}, {195065, 18091267}, {195066, 18091523}, {195067, 18091779},
2709 {195068, 18092035}, {195069, 18092291}, {195070, 17639683}, {195072, 18092547},
2710 {195073, 18092803}, {195074, 18093059}, {195075, 18093315}, {195076, 18093571},
2711 {195077, 18093827}, {195078, 18094083}, {195079, 18094339}, {195080, 18094595},
2712 {195081, 18094851}, {195082, 17639939}, {195083, 18095107}, {195084, 18095363},
2713 {195085, 18095619}, {195086, 18095875}, {195087, 18096131}, {195088, 18096387},
2714 {195089, 18096643}, {195090, 18096899}, {195091, 18097155}, {195092, 18097411},
2715 {195093, 17192707}, {195094, 18097667}, {195095, 17193731}, {195096, 18097923},
2716 {195097, 18098179}, {195098, 18098435}, {195099, 18098691}, {195100, 17195011},
2717 {195101, 18098947}, {195102, 2}, {196608, 1}, {201547, 2},
2718 {201552, 1}, {205744, 2}, {917760, 0}, {918000, 2}
2719 };
2720
2721
2722 } // namespace ada::idna
2723 #endif // ADA_IDNA_TABLES_H
2724
2725 /* end file src/mapping_tables.cpp */
2726
2727 namespace ada::idna {
2728
2729 // This can be greatly accelerated. For now we just use a simply
2730 // binary search. In practice, you should *not* do that.
find_range_index(uint32_t key)2731 uint32_t find_range_index(uint32_t key) {
2732 ////////////////
2733 // This could be implemented with std::lower_bound, but we roll our own
2734 // because we want to allow further optimizations in the future.
2735 ////////////////
2736 uint32_t len = std::size(table);
2737 uint32_t low = 0;
2738 uint32_t high = len - 1;
2739 while (low <= high) {
2740 uint32_t middle_index = (low + high) >> 1; // cannot overflow
2741 uint32_t middle_value = table[middle_index][0];
2742 if (middle_value < key) {
2743 low = middle_index + 1;
2744 } else if (middle_value > key) {
2745 high = middle_index - 1;
2746 } else {
2747 return middle_index; // perfect match
2748 }
2749 }
2750 return low == 0 ? 0 : low - 1;
2751 }
2752
ascii_has_upper_case(char * input,size_t length)2753 bool ascii_has_upper_case(char* input, size_t length) {
2754 auto broadcast = [](uint8_t v) -> uint64_t {
2755 return 0x101010101010101ull * v;
2756 };
2757 uint64_t broadcast_80 = broadcast(0x80);
2758 uint64_t broadcast_Ap = broadcast(128 - 'A');
2759 uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
2760 size_t i = 0;
2761
2762 uint64_t runner{0};
2763
2764 for (; i + 7 < length; i += 8) {
2765 uint64_t word{};
2766 memcpy(&word, input + i, sizeof(word));
2767 runner |= (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80);
2768 }
2769 if (i < length) {
2770 uint64_t word{};
2771 memcpy(&word, input + i, length - i);
2772 runner |= (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80);
2773 }
2774 return runner != 0;
2775 }
2776
ascii_map(char * input,size_t length)2777 void ascii_map(char* input, size_t length) {
2778 auto broadcast = [](uint8_t v) -> uint64_t {
2779 return 0x101010101010101ull * v;
2780 };
2781 uint64_t broadcast_80 = broadcast(0x80);
2782 uint64_t broadcast_Ap = broadcast(128 - 'A');
2783 uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
2784 size_t i = 0;
2785
2786 for (; i + 7 < length; i += 8) {
2787 uint64_t word{};
2788 memcpy(&word, input + i, sizeof(word));
2789 word ^=
2790 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
2791 memcpy(input + i, &word, sizeof(word));
2792 }
2793 if (i < length) {
2794 uint64_t word{};
2795 memcpy(&word, input + i, length - i);
2796 word ^=
2797 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
2798 memcpy(input + i, &word, length - i);
2799 }
2800 }
2801
2802 // Map the characters according to IDNA, returning the empty string on error.
map(std::u32string_view input)2803 std::u32string map(std::u32string_view input) {
2804 // [Map](https://www.unicode.org/reports/tr46/#ProcessingStepMap).
2805 // For each code point in the domain_name string, look up the status
2806 // value in Section 5, [IDNA Mapping
2807 // Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table),
2808 // and take the following actions:
2809 // * disallowed: Leave the code point unchanged in the string, and
2810 // record that there was an error.
2811 // * ignored: Remove the code point from the string. This is
2812 // equivalent to mapping the code point to an empty string.
2813 // * mapped: Replace the code point in the string by the value for
2814 // the mapping in Section 5, [IDNA Mapping
2815 // Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table).
2816 // * valid: Leave the code point unchanged in the string.
2817 static std::u32string error = U"";
2818 std::u32string answer;
2819 answer.reserve(input.size());
2820 for (char32_t x : input) {
2821 size_t index = find_range_index(x);
2822 uint32_t descriptor = table[index][1];
2823 uint8_t code = uint8_t(descriptor);
2824 switch (code) {
2825 case 0:
2826 break; // nothing to do, ignored
2827 case 1:
2828 answer.push_back(x); // valid, we just copy it to output
2829 break;
2830 case 2:
2831 return error; // disallowed
2832 // case 3 :
2833 default:
2834 // We have a mapping
2835 {
2836 size_t char_count = (descriptor >> 24);
2837 uint16_t char_index = uint16_t(descriptor >> 8);
2838 for (size_t idx = char_index; idx < char_index + char_count; idx++) {
2839 answer.push_back(mappings[idx]);
2840 }
2841 }
2842 }
2843 }
2844 return answer;
2845 }
2846 } // namespace ada::idna
2847 /* end file src/mapping.cpp */
2848 /* begin file src/normalization.cpp */
2849 /* begin file src/normalization_tables.cpp */
2850 // IDNA 15.0.0
2851
2852 // clang-format off
2853 #ifndef ADA_IDNA_NORMALIZATION_TABLES_H
2854 #define ADA_IDNA_NORMALIZATION_TABLES_H
2855 #include <cstdint>
2856
2857 /**
2858 * Unicode Standard Annex #15
2859 *
2860 * UNICODE NORMALIZATION FORMS
2861 * https://www.unicode.org/reports/tr15/
2862 *
2863 * See https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/data/data_norm.h for reference.
2864 */
2865
2866 namespace ada::idna {
2867
2868 const uint8_t decomposition_index[4352] = {
2869 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 7,
2870 7, 7, 7, 7, 7, 7, 7, 7, 16, 7, 17, 18, 19, 20, 21, 22, 23, 24, 7,
2871 7, 7, 7, 7, 25, 7, 26, 27, 28, 29, 30, 31, 32, 33, 7, 7, 7, 7, 7,
2872 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2873 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2874 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2875 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2876 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2877 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 34, 35, 7, 7, 7,
2878 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2879 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2880 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2881 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2882 7, 7, 37, 38, 39, 40, 41, 42, 43, 7, 7, 7, 7, 7, 7, 7, 44, 7, 7,
2883 7, 7, 7, 7, 7, 7, 45, 46, 7, 47, 48, 49, 7, 7, 7, 50, 7, 7, 7,
2884 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2885 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2886 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2887 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2888 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2889 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2890 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2891 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2892 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2893 7, 7, 7, 7, 7, 7, 7, 7, 7, 51, 7, 52, 53, 54, 55, 56, 7, 7, 7,
2894 7, 7, 7, 7, 7, 57, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 58,
2895 59, 7, 60, 61, 62, 7, 7, 7, 7, 7, 7, 7, 7, 63, 7, 7, 7, 7, 7,
2896 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2897 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2898 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2899 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2900 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2901 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2902 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2903 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2904 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2905 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2906 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2907 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2908 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2909 64, 65, 66, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2910 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2911 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2912 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2913 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2914 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2915 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2916 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2917 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2918 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2919 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2920 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2921 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2922 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2923 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2924 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2925 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2926 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2927 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2928 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2929 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2930 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2931 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2932 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2933 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2934 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2935 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2936 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2937 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2938 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2939 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2940 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2941 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2942 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2943 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2944 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2945 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2946 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2947 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2948 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2949 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2950 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2951 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2952 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2953 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2954 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2955 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2956 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2957 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2958 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2959 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2960 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2961 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2962 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2963 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2964 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2965 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2966 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2967 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2968 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2969 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2970 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2971 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2972 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2973 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2974 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2975 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2976 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2977 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2978 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2979 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2980 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2981 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2982 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2983 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2984 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2985 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2986 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2987 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2988 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2989 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2990 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2991 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2992 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2993 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2994 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2995 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2996 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2997 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2998 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2999 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3000 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3001 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3002 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3003 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3004 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3005 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3006 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3007 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3008 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3009 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3010 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3011 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3012 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3013 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3014 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3015 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3016 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3017 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3018 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3019 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3020 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3021 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3022 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3023 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3024 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3025 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3026 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3027 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3028 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3029 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3030 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3031 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3032 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3033 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3034 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3035 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3036 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3037 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3038 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3039 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3040 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3041 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3042 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3043 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3044 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3045 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3046 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3047 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3048 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3049 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3050 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3051 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3052 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3053 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3054 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3055 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3056 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3057 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3058 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3059 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3060 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3061 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3062 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3063 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3064 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3065 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3066 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3067 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3068 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3069 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3070 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3071 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3072 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3073 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3074 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3075 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3076 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3077 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3078 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3079 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3080 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3081 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3082 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3083 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3084 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3085 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3086 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3087 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3088 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3089 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3090 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3091 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3092 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3093 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3094 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3095 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3096 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3097 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3098 7};
3099
3100 const uint16_t decomposition_block[67][257] = {
3101 {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3102 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3103 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3104 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3105 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3106 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3107 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3108 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3109 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3110 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3111 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 8, 8, 8, 8,
3112 8, 8, 8, 9, 16, 17, 20, 20, 20, 20, 21, 28, 28, 29, 33,
3113 37, 45, 48, 48, 49, 57, 61, 64, 65, 77, 89, 100, 100, 108, 116,
3114 124, 132, 140, 148, 148, 156, 164, 172, 180, 188, 196, 204, 212, 220, 220,
3115 228, 236, 244, 252, 260, 268, 268, 268, 276, 284, 292, 300, 308, 308, 308,
3116 316, 324, 332, 340, 348, 356, 356, 364, 372, 380, 388, 396, 404, 412, 420,
3117 428, 428, 436, 444, 452, 460, 468, 476, 476, 476, 484, 492, 500, 508, 516,
3118 516, 524},
3119 {524, 532, 540, 548, 556, 564, 572, 580, 588, 596, 604, 612,
3120 620, 628, 636, 644, 652, 652, 652, 660, 668, 676, 684, 692,
3121 700, 708, 716, 724, 732, 740, 748, 756, 764, 772, 780, 788,
3122 796, 804, 812, 812, 812, 820, 828, 836, 844, 852, 860, 868,
3123 876, 884, 885, 893, 900, 908, 916, 924, 932, 932, 940, 948,
3124 956, 964, 972, 981, 989, 996, 996, 996, 1004, 1012, 1020, 1028,
3125 1036, 1045, 1052, 1052, 1052, 1060, 1068, 1076, 1084, 1092, 1100, 1100,
3126 1100, 1108, 1116, 1124, 1132, 1140, 1148, 1156, 1164, 1172, 1180, 1188,
3127 1196, 1204, 1212, 1220, 1228, 1236, 1244, 1244, 1244, 1252, 1260, 1268,
3128 1276, 1284, 1292, 1300, 1308, 1316, 1324, 1332, 1340, 1348, 1356, 1364,
3129 1372, 1380, 1388, 1396, 1404, 1412, 1420, 1429, 1432, 1432, 1432, 1432,
3130 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
3131 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
3132 1432, 1432, 1432, 1432, 1432, 1440, 1448, 1448, 1448, 1448, 1448, 1448,
3133 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1456, 1464, 1464, 1464,
3134 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464,
3135 1464, 1464, 1464, 1464, 1465, 1477, 1489, 1501, 1509, 1517, 1525, 1533,
3136 1541, 1548, 1556, 1564, 1572, 1580, 1588, 1596, 1604, 1612, 1624, 1636,
3137 1648, 1660, 1672, 1684, 1696, 1708, 1708, 1720, 1732, 1744, 1756, 1764,
3138 1772, 1772, 1772, 1780, 1788, 1796, 1804, 1812, 1820, 1832, 1844, 1852,
3139 1860, 1869, 1877, 1885, 1892, 1900, 1908, 1908, 1908, 1916, 1924, 1936,
3140 1948, 1956, 1964, 1972, 1980},
3141 {1980, 1988, 1996, 2004, 2012, 2020, 2028, 2036, 2044, 2052, 2060, 2068,
3142 2076, 2084, 2092, 2100, 2108, 2116, 2124, 2132, 2140, 2148, 2156, 2164,
3143 2172, 2180, 2188, 2196, 2204, 2204, 2204, 2212, 2220, 2220, 2220, 2220,
3144 2220, 2220, 2220, 2228, 2236, 2244, 2252, 2264, 2276, 2288, 2300, 2308,
3145 2316, 2328, 2340, 2348, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3146 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3147 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3148 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3149 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3150 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3151 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3152 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3153 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3154 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3155 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2357, 2361, 2365, 2369,
3156 2373, 2377, 2381, 2385, 2389, 2392, 2392, 2392, 2392, 2392, 2392, 2392,
3157 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392,
3158 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392,
3159 2393, 2401, 2409, 2417, 2425, 2433, 2440, 2440, 2441, 2445, 2449, 2453,
3160 2457, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3161 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3162 2460, 2460, 2460, 2460, 2460},
3163 {2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3164 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3165 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3166 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3167 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3168 2460, 2460, 2460, 2460, 2460, 2464, 2468, 2468, 2472, 2480, 2480, 2480,
3169 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,
3170 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,
3171 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,
3172 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2484, 2484, 2484,
3173 2484, 2484, 2485, 2492, 2492, 2492, 2492, 2496, 2496, 2496, 2496, 2496,
3174 2497, 2506, 2512, 2520, 2524, 2532, 2540, 2548, 2548, 2556, 2556, 2564,
3175 2572, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584,
3176 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584,
3177 2584, 2584, 2584, 2592, 2600, 2608, 2616, 2624, 2632, 2644, 2644, 2644,
3178 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644,
3179 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2652,
3180 2660, 2668, 2676, 2684, 2685, 2689, 2693, 2698, 2706, 2713, 2717, 2720,
3181 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720,
3182 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720,
3183 2721, 2725, 2729, 2732, 2733, 2737, 2740, 2740, 2740, 2741, 2744, 2744,
3184 2744, 2744, 2744, 2744, 2744},
3185 {2744, 2752, 2760, 2760, 2768, 2768, 2768, 2768, 2776, 2776, 2776, 2776,
3186 2776, 2784, 2792, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800,
3187 2800, 2800, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808,
3188 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808,
3189 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2816, 2816,
3190 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816,
3191 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2824, 2832, 2832,
3192 2840, 2840, 2840, 2840, 2848, 2848, 2848, 2848, 2848, 2856, 2864, 2872,
3193 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872,
3194 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2880,
3195 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3196 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3197 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3198 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3199 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3200 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3201 2888, 2888, 2896, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904,
3202 2904, 2904, 2904, 2904, 2904, 2912, 2920, 2928, 2936, 2936, 2936, 2944,
3203 2952, 2952, 2952, 2960, 2968, 2976, 2984, 2992, 3000, 3000, 3000, 3008,
3204 3016, 3024, 3032, 3040, 3048, 3048, 3048, 3056, 3064, 3072, 3080, 3088,
3205 3096, 3104, 3112, 3120, 3128, 3136, 3144, 3144, 3144, 3152, 3160, 3160,
3206 3160, 3160, 3160, 3160, 3160},
3207 {3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3208 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3209 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3210 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3211 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3212 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3213 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3214 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3215 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3216 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3217 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3218 3160, 3160, 3160, 3161, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3219 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3220 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3221 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3222 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3223 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3224 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3225 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3226 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3227 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3228 3168, 3168, 3168, 3168, 3168},
3229 {3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3230 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3231 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3176,
3232 3184, 3192, 3200, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3233 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3234 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3235 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3236 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3237 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3238 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3209, 3217, 3225,
3239 3233, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3240 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3241 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3242 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3243 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3244 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3245 3240, 3248, 3248, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256,
3246 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3264, 3264, 3264, 3264,
3247 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3248 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3249 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3250 3264, 3264, 3264, 3264, 3264},
3251 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3252 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3255 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3257 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3262 {3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3263 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3264 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3265 3264, 3264, 3264, 3264, 3264, 3264, 3272, 3272, 3272, 3272, 3272, 3272,
3266 3272, 3272, 3280, 3280, 3280, 3288, 3288, 3288, 3288, 3288, 3288, 3288,
3267 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288,
3268 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288,
3269 3288, 3288, 3288, 3288, 3288, 3296, 3304, 3312, 3320, 3328, 3336, 3344,
3270 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3271 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3272 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3273 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3274 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3275 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3276 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3277 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3278 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3279 3360, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368,
3280 3368, 3368, 3368, 3368, 3368, 3376, 3384, 3384, 3392, 3392, 3392, 3392,
3281 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3282 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3283 3392, 3392, 3392, 3392, 3392},
3284 {3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3285 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3286 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3287 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3288 3392, 3392, 3392, 3392, 3400, 3400, 3400, 3408, 3408, 3408, 3408, 3408,
3289 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408,
3290 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408,
3291 3408, 3408, 3408, 3408, 3408, 3408, 3416, 3424, 3432, 3432, 3432, 3440,
3292 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3293 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3294 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3295 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3296 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3297 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3298 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3299 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3300 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3301 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3302 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3303 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3304 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3305 3440, 3440, 3440, 3440, 3440},
3306 {3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3307 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3308 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3309 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3310 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3311 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3312 3440, 3448, 3448, 3448, 3456, 3464, 3464, 3464, 3464, 3464, 3464, 3464,
3313 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3472, 3480, 3480,
3314 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3315 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3316 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3317 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3318 3480, 3480, 3480, 3480, 3480, 3488, 3488, 3488, 3488, 3488, 3488, 3488,
3319 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,
3320 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,
3321 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,
3322 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3496,
3323 3504, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3324 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3325 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3326 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3327 3512, 3512, 3512, 3512, 3512},
3328 {3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3329 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3330 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3331 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3332 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3333 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3334 3512, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3335 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3336 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3337 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3338 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3339 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3340 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3341 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3342 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3343 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3344 3520, 3528, 3528, 3528, 3528, 3528, 3528, 3528, 3536, 3544, 3544, 3552,
3345 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3346 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3347 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3348 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3349 3564, 3564, 3564, 3564, 3564},
3350 {3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3351 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3352 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3353 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3354 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3355 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3356 3564, 3564, 3564, 3572, 3580, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3357 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3358 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3359 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3360 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3361 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3362 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3363 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3364 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3365 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3366 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3367 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3368 3588, 3588, 3588, 3596, 3596, 3604, 3616, 3624, 3624, 3624, 3624, 3624,
3369 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3370 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3371 3624, 3624, 3624, 3624, 3624},
3372 {3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3373 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3374 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3375 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3376 3624, 3624, 3624, 3625, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3377 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3378 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3379 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3380 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3381 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3382 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3383 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3384 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3385 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3386 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3633,
3387 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,
3388 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,
3389 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,
3390 3640, 3640, 3640, 3640, 3641, 3649, 3656, 3656, 3656, 3656, 3656, 3656,
3391 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,
3392 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,
3393 3656, 3656, 3656, 3656, 3656},
3394 {3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,
3395 3657, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3396 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3397 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3398 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3399 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3668, 3668, 3668, 3668,
3400 3668, 3668, 3668, 3668, 3668, 3668, 3676, 3676, 3676, 3676, 3676, 3684,
3401 3684, 3684, 3684, 3684, 3692, 3692, 3692, 3692, 3692, 3700, 3700, 3700,
3402 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3708, 3708,
3403 3708, 3708, 3708, 3708, 3708, 3708, 3708, 3708, 3716, 3716, 3724, 3733,
3404 3744, 3753, 3764, 3764, 3764, 3764, 3764, 3764, 3764, 3764, 3772, 3772,
3405 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772,
3406 3772, 3772, 3772, 3772, 3780, 3780, 3780, 3780, 3780, 3780, 3780, 3780,
3407 3780, 3780, 3788, 3788, 3788, 3788, 3788, 3796, 3796, 3796, 3796, 3796,
3408 3804, 3804, 3804, 3804, 3804, 3812, 3812, 3812, 3812, 3812, 3812, 3812,
3409 3812, 3812, 3812, 3812, 3812, 3812, 3820, 3820, 3820, 3820, 3820, 3820,
3410 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3411 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3412 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3413 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3414 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3415 3820, 3820, 3820, 3820, 3820},
3416 {3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3417 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3418 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3419 3820, 3820, 3820, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3420 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3421 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3422 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3423 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3424 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3425 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3426 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3427 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3428 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3429 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3430 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3431 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3432 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3433 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3434 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3435 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3436 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3437 3829, 3832, 3832, 3832, 3832},
3438 {3832, 3832, 3832, 3832, 3832, 3832, 3832, 3840, 3840, 3848, 3848, 3856,
3439 3856, 3864, 3864, 3872, 3872, 3872, 3872, 3880, 3880, 3880, 3880, 3880,
3440 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,
3441 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,
3442 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,
3443 3888, 3888, 3896, 3896, 3896, 3904, 3912, 3912, 3920, 3920, 3920, 3920,
3444 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3445 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3446 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3447 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3448 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3449 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3450 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3451 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3452 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3453 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3454 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3455 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3456 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3457 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3458 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3459 3920, 3920, 3920, 3920, 3920},
3460 {3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3461 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3462 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3463 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3921, 3925, 3929, 3932,
3464 3933, 3937, 3941, 3945, 3949, 3953, 3957, 3961, 3965, 3969, 3973, 3976,
3465 3977, 3981, 3985, 3989, 3993, 3997, 4001, 4005, 4009, 4013, 4017, 4021,
3466 4025, 4029, 4033, 4037, 4041, 4045, 4048, 4049, 4053, 4057, 4061, 4065,
3467 4069, 4073, 4077, 4081, 4085, 4089, 4093, 4097, 4101, 4105, 4109, 4113,
3468 4117, 4121, 4125, 4129, 4133, 4137, 4141, 4145, 4149, 4153, 4157, 4160,
3469 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160,
3470 4161, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164,
3471 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164,
3472 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4165,
3473 4169, 4173, 4177, 4181, 4185, 4189, 4193, 4197, 4201, 4205, 4209, 4213,
3474 4217, 4221, 4225, 4229, 4233, 4237, 4241, 4245, 4249, 4253, 4257, 4261,
3475 4265, 4269, 4273, 4277, 4281, 4285, 4289, 4293, 4297, 4301, 4305, 4309,
3476 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3477 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3478 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3479 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3480 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3481 4312, 4312, 4312, 4312, 4312},
3482 {4312, 4320, 4328, 4336, 4344, 4352, 4360, 4368, 4376, 4388, 4400, 4408,
3483 4416, 4424, 4432, 4440, 4448, 4456, 4464, 4472, 4480, 4492, 4504, 4516,
3484 4528, 4536, 4544, 4552, 4560, 4572, 4584, 4592, 4600, 4608, 4616, 4624,
3485 4632, 4640, 4648, 4656, 4664, 4672, 4680, 4688, 4696, 4704, 4712, 4724,
3486 4736, 4744, 4752, 4760, 4768, 4776, 4784, 4792, 4800, 4812, 4824, 4832,
3487 4840, 4848, 4856, 4864, 4872, 4880, 4888, 4896, 4904, 4912, 4920, 4928,
3488 4936, 4944, 4952, 4960, 4968, 4980, 4992, 5004, 5016, 5028, 5040, 5052,
3489 5064, 5072, 5080, 5088, 5096, 5104, 5112, 5120, 5128, 5140, 5152, 5160,
3490 5168, 5176, 5184, 5192, 5200, 5212, 5224, 5236, 5248, 5260, 5272, 5280,
3491 5288, 5296, 5304, 5312, 5320, 5328, 5336, 5344, 5352, 5360, 5368, 5376,
3492 5384, 5396, 5408, 5420, 5432, 5440, 5448, 5456, 5464, 5472, 5480, 5488,
3493 5496, 5504, 5512, 5520, 5528, 5536, 5544, 5552, 5560, 5568, 5576, 5584,
3494 5592, 5600, 5608, 5616, 5624, 5632, 5640, 5648, 5656, 5664, 5673, 5682,
3495 5688, 5688, 5688, 5688, 5688, 5696, 5704, 5712, 5720, 5732, 5744, 5756,
3496 5768, 5780, 5792, 5804, 5816, 5828, 5840, 5852, 5864, 5876, 5888, 5900,
3497 5912, 5924, 5936, 5948, 5960, 5968, 5976, 5984, 5992, 6000, 6008, 6020,
3498 6032, 6044, 6056, 6068, 6080, 6092, 6104, 6116, 6128, 6136, 6144, 6152,
3499 6160, 6168, 6176, 6184, 6192, 6204, 6216, 6228, 6240, 6252, 6264, 6276,
3500 6288, 6300, 6312, 6324, 6336, 6348, 6360, 6372, 6384, 6396, 6408, 6420,
3501 6432, 6440, 6448, 6456, 6464, 6476, 6488, 6500, 6512, 6524, 6536, 6548,
3502 6560, 6572, 6584, 6592, 6600, 6608, 6616, 6624, 6632, 6640, 6648, 6648,
3503 6648, 6648, 6648, 6648, 6648},
3504 {6648, 6656, 6664, 6676, 6688, 6700, 6712, 6724, 6736, 6744, 6752, 6764,
3505 6776, 6788, 6800, 6812, 6824, 6832, 6840, 6852, 6864, 6876, 6888, 6888,
3506 6888, 6896, 6904, 6916, 6928, 6940, 6952, 6952, 6952, 6960, 6968, 6980,
3507 6992, 7004, 7016, 7028, 7040, 7048, 7056, 7068, 7080, 7092, 7104, 7116,
3508 7128, 7136, 7144, 7156, 7168, 7180, 7192, 7204, 7216, 7224, 7232, 7244,
3509 7256, 7268, 7280, 7292, 7304, 7312, 7320, 7332, 7344, 7356, 7368, 7368,
3510 7368, 7376, 7384, 7396, 7408, 7420, 7432, 7432, 7432, 7440, 7448, 7460,
3511 7472, 7484, 7496, 7508, 7520, 7520, 7528, 7528, 7540, 7540, 7552, 7552,
3512 7564, 7572, 7580, 7592, 7604, 7616, 7628, 7640, 7652, 7660, 7668, 7680,
3513 7692, 7704, 7716, 7728, 7740, 7748, 7756, 7764, 7772, 7780, 7788, 7796,
3514 7804, 7812, 7820, 7828, 7836, 7844, 7852, 7852, 7852, 7864, 7876, 7892,
3515 7908, 7924, 7940, 7956, 7972, 7984, 7996, 8012, 8028, 8044, 8060, 8076,
3516 8092, 8104, 8116, 8132, 8148, 8164, 8180, 8196, 8212, 8224, 8236, 8252,
3517 8268, 8284, 8300, 8316, 8332, 8344, 8356, 8372, 8388, 8404, 8420, 8436,
3518 8452, 8464, 8476, 8492, 8508, 8524, 8540, 8556, 8572, 8580, 8588, 8600,
3519 8608, 8620, 8620, 8628, 8640, 8648, 8656, 8664, 8672, 8681, 8688, 8693,
3520 8701, 8710, 8716, 8728, 8736, 8748, 8748, 8756, 8768, 8776, 8784, 8792,
3521 8800, 8810, 8818, 8826, 8832, 8840, 8848, 8860, 8872, 8872, 8872, 8880,
3522 8892, 8900, 8908, 8916, 8924, 8926, 8934, 8942, 8948, 8956, 8964, 8976,
3523 8988, 8996, 9004, 9012, 9024, 9032, 9040, 9048, 9056, 9066, 9074, 9080,
3524 9084, 9084, 9084, 9096, 9104, 9116, 9116, 9124, 9136, 9144, 9152, 9160,
3525 9168, 9178, 9181, 9188, 9190},
3526 {9190, 9194, 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9232,
3527 9232, 9232, 9232, 9232, 9232, 9233, 9236, 9236, 9236, 9236, 9236, 9237,
3528 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244,
3529 9245, 9249, 9257, 9268, 9268, 9268, 9268, 9268, 9268, 9268, 9268, 9269,
3530 9272, 9272, 9272, 9273, 9281, 9292, 9293, 9301, 9312, 9312, 9312, 9312,
3531 9313, 9320, 9321, 9328, 9328, 9328, 9328, 9328, 9328, 9328, 9328, 9329,
3532 9337, 9345, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352,
3533 9352, 9352, 9352, 9353, 9368, 9368, 9368, 9368, 9368, 9368, 9368, 9369,
3534 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372,
3535 9372, 9372, 9372, 9372, 9373, 9377, 9380, 9380, 9381, 9385, 9389, 9393,
3536 9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, 9433, 9437, 9441,
3537 9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, 9481, 9485, 9488,
3538 9489, 9493, 9497, 9501, 9505, 9509, 9513, 9517, 9521, 9525, 9529, 9533,
3539 9537, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540,
3540 9541, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3541 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3542 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3543 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3544 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3545 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3546 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3547 9548, 9548, 9548, 9548, 9549},
3548 {9549, 9561, 9573, 9577, 9584, 9585, 9597, 9609, 9612, 9613,
3549 9621, 9625, 9629, 9633, 9637, 9641, 9645, 9649, 9653, 9657,
3550 9660, 9661, 9665, 9672, 9672, 9673, 9677, 9681, 9685, 9689,
3551 9692, 9692, 9693, 9701, 9713, 9720, 9721, 9724, 9724, 9728,
3552 9729, 9732, 9732, 9736, 9745, 9749, 9752, 9753, 9757, 9761,
3553 9764, 9765, 9769, 9773, 9777, 9781, 9785, 9789, 9792, 9793,
3554 9805, 9809, 9813, 9817, 9821, 9824, 9824, 9824, 9824, 9825,
3555 9829, 9833, 9837, 9841, 9844, 9844, 9844, 9844, 9844, 9844,
3556 9845, 9857, 9869, 9885, 9897, 9909, 9921, 9933, 9945, 9957,
3557 9969, 9981, 9993, 10005, 10017, 10029, 10037, 10041, 10049, 10061,
3558 10069, 10073, 10081, 10093, 10109, 10117, 10121, 10129, 10141, 10145,
3559 10149, 10153, 10157, 10161, 10169, 10181, 10189, 10193, 10201, 10213,
3560 10229, 10237, 10241, 10249, 10261, 10265, 10269, 10273, 10276, 10276,
3561 10276, 10276, 10276, 10276, 10276, 10276, 10276, 10277, 10288, 10288,
3562 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288,
3563 10288, 10288, 10288, 10288, 10288, 10296, 10304, 10304, 10304, 10304,
3564 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304,
3565 10304, 10304, 10304, 10304, 10304, 10312, 10312, 10312, 10312, 10312,
3566 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312,
3567 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312,
3568 10312, 10312, 10312, 10312, 10312, 10312, 10320, 10328, 10336, 10336,
3569 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,
3570 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,
3571 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,
3572 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,
3573 10336, 10336, 10336, 10336, 10336, 10336, 10336},
3574 {10336, 10336, 10336, 10336, 10336, 10344, 10344, 10344, 10344, 10344,
3575 10352, 10352, 10352, 10360, 10360, 10360, 10360, 10360, 10360, 10360,
3576 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360,
3577 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10368, 10368, 10376,
3578 10376, 10376, 10376, 10376, 10377, 10385, 10396, 10397, 10405, 10416,
3579 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416,
3580 10416, 10416, 10416, 10416, 10416, 10416, 10424, 10424, 10424, 10432,
3581 10432, 10432, 10440, 10440, 10448, 10448, 10448, 10448, 10448, 10448,
3582 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448,
3583 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10456, 10456, 10464,
3584 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464,
3585 10472, 10480, 10488, 10496, 10504, 10504, 10504, 10512, 10520, 10520,
3586 10520, 10528, 10536, 10536, 10536, 10536, 10536, 10536, 10536, 10544,
3587 10552, 10552, 10552, 10560, 10568, 10568, 10568, 10576, 10584, 10584,
3588 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,
3589 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,
3590 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,
3591 10584, 10584, 10584, 10592, 10600, 10608, 10616, 10616, 10616, 10616,
3592 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,
3593 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,
3594 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,
3595 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,
3596 10616, 10616, 10616, 10616, 10616, 10624, 10632, 10640, 10648, 10648,
3597 10648, 10648, 10648, 10648, 10648, 10656, 10664, 10672, 10680, 10680,
3598 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3599 10680, 10680, 10680, 10680, 10680, 10680, 10680},
3600 {10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3601 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3602 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3603 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3604 10680, 10680, 10684, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3605 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3606 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3607 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3608 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3609 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3610 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3611 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3612 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3613 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3614 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3615 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3616 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3617 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3618 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3619 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3620 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3621 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3622 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3623 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3624 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3625 10688, 10688, 10688, 10688, 10688, 10688, 10688},
3626 {10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3627 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3628 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3629 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3630 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3631 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3632 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3633 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3634 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3635 10688, 10688, 10688, 10688, 10688, 10688, 10689, 10693, 10697, 10701,
3636 10705, 10709, 10713, 10717, 10721, 10725, 10733, 10741, 10749, 10757,
3637 10765, 10773, 10781, 10789, 10797, 10805, 10813, 10825, 10837, 10849,
3638 10861, 10873, 10885, 10897, 10909, 10921, 10937, 10953, 10969, 10985,
3639 11001, 11017, 11033, 11049, 11065, 11081, 11097, 11105, 11113, 11121,
3640 11129, 11137, 11145, 11153, 11161, 11169, 11181, 11193, 11205, 11217,
3641 11229, 11241, 11253, 11265, 11277, 11289, 11301, 11313, 11325, 11337,
3642 11349, 11361, 11373, 11385, 11397, 11409, 11421, 11433, 11445, 11457,
3643 11469, 11481, 11493, 11505, 11517, 11529, 11541, 11553, 11565, 11577,
3644 11589, 11601, 11613, 11617, 11621, 11625, 11629, 11633, 11637, 11641,
3645 11645, 11649, 11653, 11657, 11661, 11665, 11669, 11673, 11677, 11681,
3646 11685, 11689, 11693, 11697, 11701, 11705, 11709, 11713, 11717, 11721,
3647 11725, 11729, 11733, 11737, 11741, 11745, 11749, 11753, 11757, 11761,
3648 11765, 11769, 11773, 11777, 11781, 11785, 11789, 11793, 11797, 11801,
3649 11805, 11809, 11813, 11817, 11821, 11824, 11824, 11824, 11824, 11824,
3650 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824,
3651 11824, 11824, 11824, 11824, 11824, 11824, 11824},
3652 {11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824,
3653 11824, 11824, 11825, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3654 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3655 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3656 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3657 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3658 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3659 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3660 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3661 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3662 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3663 11840, 11840, 11840, 11840, 11840, 11840, 11841, 11853, 11861, 11872,
3664 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3665 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3666 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3667 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3668 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3669 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3670 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3671 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3672 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3673 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3674 11872, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3675 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3676 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3677 11880, 11880, 11880, 11880, 11880, 11880, 11880},
3678 {11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3679 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3680 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3681 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3682 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3683 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3684 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3685 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3686 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3687 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3688 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3689 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3690 11880, 11880, 11880, 11880, 11881, 11885, 11888, 11888, 11888, 11888,
3691 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3692 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3693 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3694 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3695 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3696 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3697 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3698 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3699 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3700 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3701 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3702 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3703 11888, 11888, 11888, 11888, 11888, 11888, 11888},
3704 {11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3705 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3706 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3707 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3708 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3709 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3710 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3711 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3712 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3713 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3714 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3715 11888, 11889, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3716 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3717 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3718 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3719 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3720 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3721 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3722 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3723 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3724 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3725 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3726 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3727 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3728 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3729 11892, 11892, 11892, 11892, 11892, 11892, 11892},
3730 {11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3731 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3732 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3733 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3734 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3735 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3736 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3737 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3738 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3739 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3740 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3741 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3742 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3743 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3744 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3745 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11893,
3746 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3747 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3748 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3749 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3750 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3751 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3752 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3753 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3754 11896, 11896, 11896, 11897, 11900, 11900, 11900, 11900, 11900, 11900,
3755 11900, 11900, 11900, 11900, 11900, 11900, 11901},
3756 {11901, 11905, 11909, 11913, 11917, 11921, 11925, 11929, 11933, 11937,
3757 11941, 11945, 11949, 11953, 11957, 11961, 11965, 11969, 11973, 11977,
3758 11981, 11985, 11989, 11993, 11997, 12001, 12005, 12009, 12013, 12017,
3759 12021, 12025, 12029, 12033, 12037, 12041, 12045, 12049, 12053, 12057,
3760 12061, 12065, 12069, 12073, 12077, 12081, 12085, 12089, 12093, 12097,
3761 12101, 12105, 12109, 12113, 12117, 12121, 12125, 12129, 12133, 12137,
3762 12141, 12145, 12149, 12153, 12157, 12161, 12165, 12169, 12173, 12177,
3763 12181, 12185, 12189, 12193, 12197, 12201, 12205, 12209, 12213, 12217,
3764 12221, 12225, 12229, 12233, 12237, 12241, 12245, 12249, 12253, 12257,
3765 12261, 12265, 12269, 12273, 12277, 12281, 12285, 12289, 12293, 12297,
3766 12301, 12305, 12309, 12313, 12317, 12321, 12325, 12329, 12333, 12337,
3767 12341, 12345, 12349, 12353, 12357, 12361, 12365, 12369, 12373, 12377,
3768 12381, 12385, 12389, 12393, 12397, 12401, 12405, 12409, 12413, 12417,
3769 12421, 12425, 12429, 12433, 12437, 12441, 12445, 12449, 12453, 12457,
3770 12461, 12465, 12469, 12473, 12477, 12481, 12485, 12489, 12493, 12497,
3771 12501, 12505, 12509, 12513, 12517, 12521, 12525, 12529, 12533, 12537,
3772 12541, 12545, 12549, 12553, 12557, 12561, 12565, 12569, 12573, 12577,
3773 12581, 12585, 12589, 12593, 12597, 12601, 12605, 12609, 12613, 12617,
3774 12621, 12625, 12629, 12633, 12637, 12641, 12645, 12649, 12653, 12657,
3775 12661, 12665, 12669, 12673, 12677, 12681, 12685, 12689, 12693, 12697,
3776 12701, 12705, 12709, 12713, 12717, 12721, 12725, 12729, 12733, 12737,
3777 12741, 12745, 12749, 12753, 12756, 12756, 12756, 12756, 12756, 12756,
3778 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,
3779 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,
3780 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,
3781 12756, 12756, 12756, 12756, 12756, 12756, 12757},
3782 {12757, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3783 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3784 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3785 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3786 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3787 12760, 12760, 12760, 12760, 12761, 12764, 12765, 12769, 12773, 12776,
3788 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776,
3789 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12784, 12784, 12792,
3790 12792, 12800, 12800, 12808, 12808, 12816, 12816, 12824, 12824, 12832,
3791 12832, 12840, 12840, 12848, 12848, 12856, 12856, 12864, 12864, 12872,
3792 12872, 12872, 12880, 12880, 12888, 12888, 12896, 12896, 12896, 12896,
3793 12896, 12896, 12896, 12904, 12912, 12912, 12920, 12928, 12928, 12936,
3794 12944, 12944, 12952, 12960, 12960, 12968, 12976, 12976, 12976, 12976,
3795 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976,
3796 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12984,
3797 12984, 12984, 12984, 12984, 12984, 12985, 12993, 13000, 13000, 13009,
3798 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016,
3799 13016, 13016, 13016, 13024, 13024, 13032, 13032, 13040, 13040, 13048,
3800 13048, 13056, 13056, 13064, 13064, 13072, 13072, 13080, 13080, 13088,
3801 13088, 13096, 13096, 13104, 13104, 13112, 13112, 13112, 13120, 13120,
3802 13128, 13128, 13136, 13136, 13136, 13136, 13136, 13136, 13136, 13144,
3803 13152, 13152, 13160, 13168, 13168, 13176, 13184, 13184, 13192, 13200,
3804 13200, 13208, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216,
3805 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216,
3806 13216, 13216, 13216, 13216, 13216, 13224, 13224, 13224, 13232, 13240,
3807 13248, 13256, 13256, 13256, 13256, 13265, 13272},
3808 {13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,
3809 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,
3810 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,
3811 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,
3812 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13273,
3813 13277, 13281, 13285, 13289, 13293, 13297, 13301, 13305, 13309, 13313,
3814 13317, 13321, 13325, 13329, 13333, 13337, 13341, 13345, 13349, 13353,
3815 13357, 13361, 13365, 13369, 13373, 13377, 13381, 13385, 13389, 13393,
3816 13397, 13401, 13405, 13409, 13413, 13417, 13421, 13425, 13429, 13433,
3817 13437, 13441, 13445, 13449, 13453, 13457, 13461, 13465, 13469, 13473,
3818 13477, 13481, 13485, 13489, 13493, 13497, 13501, 13505, 13509, 13513,
3819 13517, 13521, 13525, 13529, 13533, 13537, 13541, 13545, 13549, 13553,
3820 13557, 13561, 13565, 13569, 13573, 13577, 13581, 13585, 13589, 13593,
3821 13597, 13601, 13605, 13609, 13613, 13617, 13621, 13625, 13629, 13633,
3822 13637, 13641, 13645, 13648, 13648, 13648, 13649, 13653, 13657, 13661,
3823 13665, 13669, 13673, 13677, 13681, 13685, 13689, 13693, 13697, 13701,
3824 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3825 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3826 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3827 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3828 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3829 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3830 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3831 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3832 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3833 13704, 13704, 13704, 13704, 13704, 13704, 13705},
3834 {13705, 13717, 13729, 13741, 13753, 13765, 13777, 13789, 13801, 13813,
3835 13825, 13837, 13849, 13861, 13873, 13889, 13905, 13921, 13937, 13953,
3836 13969, 13985, 14001, 14017, 14033, 14049, 14065, 14081, 14097, 14113,
3837 14141, 14164, 14165, 14177, 14189, 14201, 14213, 14225, 14237, 14249,
3838 14261, 14273, 14285, 14297, 14309, 14321, 14333, 14345, 14357, 14369,
3839 14381, 14393, 14405, 14417, 14429, 14441, 14453, 14465, 14477, 14489,
3840 14501, 14513, 14525, 14537, 14549, 14561, 14573, 14585, 14597, 14601,
3841 14605, 14609, 14612, 14612, 14612, 14612, 14612, 14612, 14612, 14612,
3842 14613, 14625, 14633, 14641, 14649, 14657, 14665, 14673, 14681, 14689,
3843 14697, 14705, 14713, 14721, 14729, 14737, 14745, 14749, 14753, 14757,
3844 14761, 14765, 14769, 14773, 14777, 14781, 14785, 14789, 14793, 14797,
3845 14801, 14809, 14817, 14825, 14833, 14841, 14849, 14857, 14865, 14873,
3846 14881, 14889, 14897, 14905, 14913, 14933, 14949, 14956, 14957, 14961,
3847 14965, 14969, 14973, 14977, 14981, 14985, 14989, 14993, 14997, 15001,
3848 15005, 15009, 15013, 15017, 15021, 15025, 15029, 15033, 15037, 15041,
3849 15045, 15049, 15053, 15057, 15061, 15065, 15069, 15073, 15077, 15081,
3850 15085, 15089, 15093, 15097, 15101, 15105, 15109, 15113, 15117, 15121,
3851 15125, 15129, 15133, 15137, 15141, 15145, 15149, 15153, 15161, 15169,
3852 15177, 15185, 15193, 15201, 15209, 15217, 15225, 15233, 15241, 15249,
3853 15257, 15265, 15273, 15281, 15289, 15297, 15305, 15313, 15321, 15329,
3854 15337, 15345, 15357, 15369, 15381, 15389, 15401, 15409, 15421, 15425,
3855 15429, 15433, 15437, 15441, 15445, 15449, 15453, 15457, 15461, 15465,
3856 15469, 15473, 15477, 15481, 15485, 15489, 15493, 15497, 15501, 15505,
3857 15509, 15513, 15517, 15521, 15525, 15529, 15533, 15537, 15541, 15545,
3858 15549, 15553, 15557, 15561, 15565, 15569, 15573, 15577, 15581, 15585,
3859 15589, 15593, 15597, 15601, 15605, 15609, 15617},
3860 {15617, 15637, 15653, 15673, 15685, 15705, 15717, 15729, 15753, 15769,
3861 15781, 15793, 15805, 15821, 15837, 15853, 15869, 15885, 15901, 15917,
3862 15941, 15949, 15973, 15997, 16017, 16033, 16057, 16081, 16097, 16109,
3863 16121, 16137, 16153, 16173, 16193, 16205, 16217, 16233, 16245, 16257,
3864 16265, 16273, 16285, 16297, 16321, 16337, 16357, 16381, 16397, 16409,
3865 16421, 16445, 16461, 16485, 16497, 16517, 16529, 16545, 16557, 16573,
3866 16593, 16609, 16629, 16645, 16653, 16673, 16685, 16697, 16713, 16725,
3867 16737, 16749, 16769, 16785, 16793, 16817, 16829, 16849, 16865, 16881,
3868 16893, 16905, 16921, 16929, 16945, 16965, 16973, 16997, 17009, 17017,
3869 17025, 17033, 17041, 17049, 17057, 17065, 17073, 17081, 17089, 17101,
3870 17113, 17125, 17137, 17149, 17161, 17173, 17185, 17197, 17209, 17221,
3871 17233, 17245, 17257, 17269, 17281, 17289, 17297, 17309, 17317, 17325,
3872 17333, 17345, 17357, 17365, 17373, 17381, 17389, 17397, 17413, 17421,
3873 17429, 17437, 17445, 17453, 17461, 17469, 17477, 17489, 17505, 17513,
3874 17521, 17529, 17537, 17545, 17553, 17561, 17573, 17585, 17597, 17609,
3875 17617, 17625, 17633, 17641, 17649, 17657, 17665, 17673, 17681, 17689,
3876 17701, 17713, 17721, 17733, 17745, 17757, 17765, 17777, 17789, 17805,
3877 17813, 17825, 17837, 17849, 17861, 17881, 17905, 17913, 17921, 17929,
3878 17937, 17945, 17953, 17961, 17969, 17977, 17985, 17993, 18001, 18009,
3879 18017, 18025, 18033, 18041, 18049, 18065, 18073, 18081, 18089, 18105,
3880 18117, 18125, 18133, 18141, 18149, 18157, 18165, 18173, 18181, 18189,
3881 18197, 18209, 18217, 18225, 18237, 18249, 18257, 18273, 18285, 18293,
3882 18301, 18309, 18317, 18329, 18341, 18349, 18357, 18365, 18373, 18381,
3883 18389, 18397, 18405, 18413, 18425, 18437, 18449, 18461, 18473, 18485,
3884 18497, 18509, 18521, 18533, 18545, 18557, 18569, 18581, 18593, 18605,
3885 18617, 18629, 18641, 18653, 18665, 18677, 18688},
3886 {18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3887 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3888 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3889 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3890 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3891 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3892 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3893 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3894 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3895 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3896 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3897 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3898 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3899 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3900 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3901 18688, 18688, 18688, 18688, 18688, 18688, 18689, 18693, 18696, 18696,
3902 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3903 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3904 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3905 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3906 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3907 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3908 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3909 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3910 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3911 18696, 18696, 18696, 18696, 18696, 18696, 18696},
3912 {18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3913 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3914 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3915 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3916 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3917 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3918 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3919 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3920 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3921 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3922 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3923 18696, 18696, 18697, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3924 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3925 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3926 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3927 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3928 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3929 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3930 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3931 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3932 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3933 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3934 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3935 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3936 18700, 18700, 18701, 18705, 18709, 18712, 18712, 18712, 18713, 18717,
3937 18720, 18720, 18720, 18720, 18720, 18720, 18720},
3938 {18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3939 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3940 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3941 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3942 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3943 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3944 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3945 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3946 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3947 18720, 18720, 18721, 18725, 18729, 18733, 18736, 18736, 18736, 18736,
3948 18736, 18736, 18736, 18736, 18736, 18737, 18740, 18740, 18740, 18740,
3949 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3950 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3951 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3952 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3953 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3954 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3955 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3956 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3957 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3958 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3959 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3960 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3961 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3962 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3963 18740, 18740, 18740, 18740, 18740, 18740, 18740},
3964 {18740, 18744, 18748, 18752, 18756, 18760, 18764, 18768, 18772, 18776,
3965 18780, 18784, 18788, 18792, 18796, 18800, 18804, 18808, 18812, 18816,
3966 18820, 18824, 18828, 18832, 18836, 18840, 18844, 18848, 18852, 18856,
3967 18860, 18864, 18868, 18872, 18876, 18880, 18884, 18888, 18892, 18896,
3968 18900, 18904, 18908, 18912, 18916, 18920, 18924, 18928, 18932, 18936,
3969 18940, 18944, 18948, 18952, 18956, 18960, 18964, 18968, 18972, 18976,
3970 18980, 18984, 18988, 18992, 18996, 19000, 19004, 19008, 19012, 19016,
3971 19020, 19024, 19028, 19032, 19036, 19040, 19044, 19048, 19052, 19056,
3972 19060, 19064, 19068, 19072, 19076, 19080, 19084, 19088, 19092, 19096,
3973 19100, 19104, 19108, 19112, 19116, 19120, 19124, 19128, 19132, 19136,
3974 19140, 19144, 19148, 19152, 19156, 19160, 19164, 19168, 19172, 19176,
3975 19180, 19184, 19188, 19192, 19196, 19200, 19204, 19208, 19212, 19216,
3976 19220, 19224, 19228, 19232, 19236, 19240, 19244, 19248, 19252, 19256,
3977 19260, 19264, 19268, 19272, 19276, 19280, 19284, 19288, 19292, 19296,
3978 19300, 19304, 19308, 19312, 19316, 19320, 19324, 19328, 19332, 19336,
3979 19340, 19344, 19348, 19352, 19356, 19360, 19364, 19368, 19372, 19376,
3980 19380, 19384, 19388, 19392, 19396, 19400, 19404, 19408, 19412, 19416,
3981 19420, 19424, 19428, 19432, 19436, 19440, 19444, 19448, 19452, 19456,
3982 19460, 19464, 19468, 19472, 19476, 19480, 19484, 19488, 19492, 19496,
3983 19500, 19504, 19508, 19512, 19516, 19520, 19524, 19528, 19532, 19536,
3984 19540, 19544, 19548, 19552, 19556, 19560, 19564, 19568, 19572, 19576,
3985 19580, 19584, 19588, 19592, 19596, 19600, 19604, 19608, 19612, 19616,
3986 19620, 19624, 19628, 19632, 19636, 19640, 19644, 19648, 19652, 19656,
3987 19660, 19664, 19668, 19672, 19676, 19680, 19684, 19688, 19692, 19696,
3988 19700, 19704, 19708, 19712, 19716, 19720, 19724, 19728, 19732, 19736,
3989 19740, 19744, 19748, 19752, 19756, 19760, 19764},
3990 {19764, 19768, 19772, 19776, 19780, 19784, 19788, 19792, 19796, 19800,
3991 19804, 19808, 19812, 19816, 19820, 19820, 19820, 19824, 19824, 19828,
3992 19828, 19828, 19832, 19836, 19840, 19844, 19848, 19852, 19856, 19860,
3993 19864, 19868, 19868, 19872, 19872, 19876, 19876, 19876, 19880, 19884,
3994 19884, 19884, 19884, 19888, 19892, 19896, 19900, 19904, 19908, 19912,
3995 19916, 19920, 19924, 19928, 19932, 19936, 19940, 19944, 19948, 19952,
3996 19956, 19960, 19964, 19968, 19972, 19976, 19980, 19984, 19988, 19992,
3997 19996, 20000, 20004, 20008, 20012, 20016, 20020, 20024, 20028, 20032,
3998 20036, 20040, 20044, 20048, 20052, 20056, 20060, 20064, 20068, 20072,
3999 20076, 20080, 20084, 20088, 20092, 20096, 20100, 20104, 20108, 20112,
4000 20116, 20120, 20124, 20128, 20132, 20136, 20140, 20144, 20148, 20152,
4001 20156, 20156, 20156, 20160, 20164, 20168, 20172, 20176, 20180, 20184,
4002 20188, 20192, 20196, 20200, 20204, 20208, 20212, 20216, 20220, 20224,
4003 20228, 20232, 20236, 20240, 20244, 20248, 20252, 20256, 20260, 20264,
4004 20268, 20272, 20276, 20280, 20284, 20288, 20292, 20296, 20300, 20304,
4005 20308, 20312, 20316, 20320, 20324, 20328, 20332, 20336, 20340, 20344,
4006 20348, 20352, 20356, 20360, 20364, 20368, 20372, 20376, 20380, 20384,
4007 20388, 20392, 20396, 20400, 20404, 20408, 20412, 20416, 20420, 20424,
4008 20428, 20432, 20436, 20440, 20444, 20448, 20452, 20456, 20460, 20464,
4009 20468, 20472, 20476, 20480, 20484, 20488, 20492, 20496, 20500, 20504,
4010 20508, 20512, 20516, 20520, 20524, 20528, 20532, 20536, 20540, 20544,
4011 20548, 20552, 20556, 20560, 20564, 20568, 20572, 20576, 20580, 20580,
4012 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,
4013 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,
4014 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,
4015 20580, 20580, 20580, 20580, 20580, 20580, 20581},
4016 {20581, 20589, 20597, 20605, 20617, 20629, 20637, 20644, 20644, 20644,
4017 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20645,
4018 20653, 20661, 20669, 20677, 20684, 20684, 20684, 20684, 20684, 20684,
4019 20692, 20692, 20701, 20705, 20709, 20713, 20717, 20721, 20725, 20729,
4020 20733, 20737, 20740, 20748, 20756, 20768, 20780, 20788, 20796, 20804,
4021 20812, 20820, 20828, 20836, 20844, 20852, 20852, 20860, 20868, 20876,
4022 20884, 20892, 20892, 20900, 20900, 20908, 20916, 20916, 20924, 20932,
4023 20932, 20940, 20948, 20956, 20964, 20972, 20980, 20988, 20996, 21005,
4024 21013, 21017, 21021, 21025, 21029, 21033, 21037, 21041, 21045, 21049,
4025 21053, 21057, 21061, 21065, 21069, 21073, 21077, 21081, 21085, 21089,
4026 21093, 21097, 21101, 21105, 21109, 21113, 21117, 21121, 21125, 21129,
4027 21133, 21137, 21141, 21145, 21149, 21153, 21157, 21161, 21165, 21169,
4028 21173, 21177, 21181, 21185, 21189, 21193, 21197, 21201, 21205, 21209,
4029 21213, 21217, 21221, 21225, 21229, 21233, 21237, 21241, 21245, 21249,
4030 21253, 21257, 21261, 21265, 21269, 21273, 21277, 21281, 21285, 21289,
4031 21293, 21297, 21301, 21305, 21309, 21313, 21317, 21321, 21325, 21329,
4032 21333, 21337, 21341, 21345, 21349, 21357, 21365, 21369, 21373, 21377,
4033 21381, 21385, 21389, 21393, 21397, 21401, 21405, 21413, 21420, 21420,
4034 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,
4035 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,
4036 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,
4037 21420, 21421, 21425, 21429, 21433, 21437, 21441, 21445, 21449, 21453,
4038 21457, 21461, 21469, 21473, 21477, 21481, 21485, 21489, 21493, 21497,
4039 21501, 21505, 21509, 21513, 21517, 21529, 21541, 21553, 21565, 21577,
4040 21589, 21601, 21613, 21625, 21637, 21649, 21661, 21673, 21685, 21697,
4041 21709, 21721, 21733, 21737, 21741, 21745, 21749},
4042 {21749, 21761, 21773, 21785, 21797, 21809, 21817, 21825, 21833, 21841,
4043 21849, 21857, 21865, 21873, 21881, 21889, 21897, 21905, 21913, 21921,
4044 21929, 21937, 21945, 21953, 21961, 21969, 21977, 21985, 21993, 22001,
4045 22009, 22017, 22025, 22033, 22041, 22049, 22057, 22065, 22073, 22081,
4046 22089, 22097, 22105, 22113, 22121, 22129, 22137, 22145, 22153, 22161,
4047 22169, 22177, 22185, 22193, 22201, 22209, 22217, 22225, 22233, 22241,
4048 22249, 22257, 22265, 22273, 22281, 22289, 22297, 22305, 22313, 22321,
4049 22329, 22337, 22345, 22353, 22361, 22369, 22377, 22385, 22393, 22401,
4050 22409, 22417, 22425, 22433, 22441, 22449, 22457, 22465, 22473, 22481,
4051 22489, 22497, 22505, 22513, 22521, 22533, 22545, 22557, 22569, 22581,
4052 22593, 22605, 22617, 22629, 22641, 22653, 22665, 22673, 22681, 22689,
4053 22697, 22705, 22713, 22721, 22729, 22737, 22745, 22753, 22761, 22769,
4054 22777, 22785, 22793, 22801, 22809, 22817, 22825, 22833, 22841, 22849,
4055 22857, 22865, 22873, 22881, 22889, 22897, 22905, 22913, 22921, 22929,
4056 22937, 22945, 22953, 22961, 22969, 22977, 22985, 22993, 23001, 23009,
4057 23017, 23025, 23037, 23049, 23061, 23073, 23085, 23093, 23101, 23109,
4058 23117, 23125, 23133, 23141, 23149, 23157, 23165, 23173, 23181, 23189,
4059 23197, 23205, 23213, 23221, 23229, 23237, 23245, 23253, 23261, 23269,
4060 23277, 23285, 23293, 23301, 23309, 23317, 23325, 23333, 23341, 23349,
4061 23357, 23365, 23373, 23381, 23389, 23397, 23405, 23413, 23421, 23429,
4062 23437, 23445, 23453, 23461, 23469, 23477, 23485, 23493, 23501, 23509,
4063 23517, 23525, 23533, 23541, 23549, 23557, 23565, 23573, 23581, 23589,
4064 23597, 23605, 23613, 23621, 23633, 23645, 23653, 23661, 23669, 23677,
4065 23685, 23693, 23701, 23709, 23717, 23725, 23733, 23741, 23749, 23757,
4066 23765, 23773, 23781, 23793, 23805, 23817, 23825, 23833, 23841, 23849,
4067 23857, 23865, 23873, 23881, 23889, 23897, 23905},
4068 {23905, 23913, 23921, 23929, 23937, 23945, 23953, 23961, 23969, 23977,
4069 23985, 23993, 24001, 24009, 24017, 24025, 24033, 24041, 24049, 24057,
4070 24065, 24073, 24081, 24089, 24097, 24105, 24113, 24121, 24129, 24137,
4071 24145, 24153, 24161, 24169, 24177, 24185, 24193, 24201, 24209, 24217,
4072 24225, 24233, 24241, 24249, 24257, 24265, 24273, 24281, 24289, 24297,
4073 24305, 24313, 24321, 24329, 24337, 24345, 24353, 24361, 24369, 24377,
4074 24385, 24393, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400,
4075 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400,
4076 24401, 24413, 24425, 24437, 24449, 24461, 24473, 24485, 24497, 24509,
4077 24521, 24533, 24545, 24557, 24569, 24581, 24593, 24605, 24617, 24629,
4078 24641, 24653, 24665, 24677, 24689, 24701, 24713, 24725, 24737, 24749,
4079 24761, 24773, 24785, 24797, 24809, 24821, 24833, 24845, 24857, 24869,
4080 24881, 24893, 24905, 24917, 24929, 24941, 24953, 24965, 24977, 24989,
4081 25001, 25013, 25025, 25037, 25049, 25061, 25073, 25085, 25097, 25109,
4082 25121, 25133, 25145, 25157, 25168, 25168, 25169, 25181, 25193, 25205,
4083 25217, 25229, 25241, 25253, 25265, 25277, 25289, 25301, 25313, 25325,
4084 25337, 25349, 25361, 25373, 25385, 25397, 25409, 25421, 25433, 25445,
4085 25457, 25469, 25481, 25493, 25505, 25517, 25529, 25541, 25553, 25565,
4086 25577, 25589, 25601, 25613, 25625, 25637, 25649, 25661, 25673, 25685,
4087 25697, 25709, 25721, 25733, 25745, 25757, 25769, 25781, 25793, 25805,
4088 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4089 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4090 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4091 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4092 25817, 25829, 25841, 25857, 25873, 25889, 25905, 25921, 25937, 25953,
4093 25965, 26037, 26069, 26084, 26084, 26084, 26084},
4094 {26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084,
4095 26084, 26084, 26084, 26084, 26084, 26084, 26085, 26089, 26093, 26097,
4096 26101, 26105, 26109, 26113, 26117, 26121, 26132, 26132, 26132, 26132,
4097 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132,
4098 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26133, 26141,
4099 26145, 26149, 26153, 26157, 26161, 26165, 26169, 26173, 26177, 26181,
4100 26185, 26189, 26193, 26197, 26201, 26205, 26209, 26213, 26217, 26220,
4101 26220, 26221, 26225, 26229, 26237, 26245, 26253, 26261, 26265, 26269,
4102 26273, 26277, 26281, 26284, 26285, 26289, 26293, 26297, 26301, 26305,
4103 26309, 26313, 26317, 26321, 26325, 26329, 26333, 26337, 26341, 26345,
4104 26349, 26353, 26357, 26360, 26361, 26365, 26369, 26373, 26376, 26376,
4105 26376, 26376, 26377, 26385, 26393, 26400, 26401, 26408, 26409, 26417,
4106 26425, 26433, 26441, 26449, 26457, 26465, 26473, 26481, 26489, 26493,
4107 26501, 26509, 26517, 26525, 26533, 26541, 26549, 26557, 26565, 26573,
4108 26581, 26589, 26593, 26597, 26601, 26605, 26609, 26613, 26617, 26621,
4109 26625, 26629, 26633, 26637, 26641, 26645, 26649, 26653, 26657, 26661,
4110 26665, 26669, 26673, 26677, 26681, 26685, 26689, 26693, 26697, 26701,
4111 26705, 26709, 26713, 26717, 26721, 26725, 26729, 26733, 26737, 26741,
4112 26745, 26749, 26753, 26757, 26761, 26765, 26769, 26773, 26777, 26781,
4113 26785, 26789, 26793, 26797, 26801, 26805, 26809, 26813, 26817, 26821,
4114 26825, 26829, 26833, 26837, 26841, 26845, 26849, 26853, 26857, 26861,
4115 26865, 26869, 26873, 26877, 26881, 26885, 26889, 26893, 26897, 26901,
4116 26905, 26909, 26913, 26917, 26921, 26925, 26929, 26933, 26937, 26941,
4117 26945, 26949, 26953, 26957, 26961, 26965, 26969, 26973, 26977, 26981,
4118 26985, 26989, 26993, 26997, 27001, 27005, 27017, 27029, 27041, 27053,
4119 27065, 27077, 27085, 27092, 27092, 27092, 27092},
4120 {27092, 27093, 27097, 27101, 27105, 27109, 27113, 27117, 27121, 27125,
4121 27129, 27133, 27137, 27141, 27145, 27149, 27153, 27157, 27161, 27165,
4122 27169, 27173, 27177, 27181, 27185, 27189, 27193, 27197, 27201, 27205,
4123 27209, 27213, 27217, 27221, 27225, 27229, 27233, 27237, 27241, 27245,
4124 27249, 27253, 27257, 27261, 27265, 27269, 27273, 27277, 27281, 27285,
4125 27289, 27293, 27297, 27301, 27305, 27309, 27313, 27317, 27321, 27325,
4126 27329, 27333, 27337, 27341, 27345, 27349, 27353, 27357, 27361, 27365,
4127 27369, 27373, 27377, 27381, 27385, 27389, 27393, 27397, 27401, 27405,
4128 27409, 27413, 27417, 27421, 27425, 27429, 27433, 27437, 27441, 27445,
4129 27449, 27453, 27457, 27461, 27465, 27469, 27473, 27477, 27481, 27485,
4130 27489, 27493, 27497, 27501, 27505, 27509, 27513, 27517, 27521, 27525,
4131 27529, 27533, 27537, 27541, 27545, 27549, 27553, 27557, 27561, 27565,
4132 27569, 27573, 27577, 27581, 27585, 27589, 27593, 27597, 27601, 27605,
4133 27609, 27613, 27617, 27621, 27625, 27629, 27633, 27637, 27641, 27645,
4134 27649, 27653, 27657, 27661, 27665, 27669, 27673, 27677, 27681, 27685,
4135 27689, 27693, 27697, 27701, 27705, 27709, 27713, 27717, 27721, 27725,
4136 27729, 27733, 27737, 27741, 27745, 27749, 27753, 27757, 27761, 27765,
4137 27769, 27773, 27777, 27781, 27785, 27789, 27793, 27797, 27801, 27805,
4138 27809, 27813, 27817, 27821, 27825, 27829, 27833, 27837, 27841, 27845,
4139 27849, 27852, 27852, 27852, 27853, 27857, 27861, 27865, 27869, 27873,
4140 27876, 27876, 27877, 27881, 27885, 27889, 27893, 27897, 27900, 27900,
4141 27901, 27905, 27909, 27913, 27917, 27921, 27924, 27924, 27925, 27929,
4142 27933, 27936, 27936, 27936, 27937, 27941, 27945, 27949, 27957, 27961,
4143 27965, 27968, 27969, 27973, 27977, 27981, 27985, 27989, 27993, 27996,
4144 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4145 27996, 27996, 27996, 27996, 27996, 27996, 27996},
4146 {27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4147 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4148 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4149 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4150 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4151 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4152 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4153 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4154 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4155 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4156 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4157 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4158 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27997,
4159 28001, 28005, 28009, 28013, 28016, 28017, 28021, 28025, 28029, 28033,
4160 28037, 28041, 28045, 28049, 28053, 28057, 28061, 28065, 28069, 28073,
4161 28077, 28081, 28085, 28089, 28093, 28097, 28101, 28105, 28109, 28113,
4162 28117, 28121, 28125, 28129, 28133, 28137, 28141, 28145, 28149, 28153,
4163 28157, 28161, 28165, 28169, 28173, 28177, 28181, 28184, 28185, 28189,
4164 28193, 28197, 28201, 28205, 28209, 28213, 28217, 28220, 28220, 28220,
4165 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4166 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4167 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4168 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4169 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4170 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4171 28220, 28220, 28220, 28220, 28220, 28220, 28220},
4172 {28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4173 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4174 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4175 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4176 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4177 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4178 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4179 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4180 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4181 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4182 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4183 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4184 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4185 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4186 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4187 28220, 28220, 28220, 28220, 28220, 28228, 28228, 28236, 28236, 28236,
4188 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236,
4189 28236, 28236, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4190 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4191 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4192 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4193 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4194 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4195 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4196 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4197 28244, 28244, 28244, 28244, 28244, 28244, 28244},
4198 {28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4199 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4200 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4201 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4202 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28252, 28260, 28260,
4203 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4204 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4205 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4206 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4207 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4208 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4209 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4210 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4211 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4212 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4213 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4214 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4215 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4216 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4217 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4218 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4219 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4220 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4221 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4222 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4223 28260, 28260, 28260, 28260, 28260, 28260, 28260},
4224 {28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4225 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4226 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4227 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4228 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4229 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4230 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4231 28260, 28260, 28260, 28260, 28260, 28260, 28268, 28276, 28276, 28276,
4232 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4233 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4234 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4235 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4236 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4237 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4238 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4239 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4240 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4241 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4242 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4243 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4244 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4245 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4246 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4247 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4248 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4249 28276, 28276, 28276, 28276, 28276, 28276, 28276},
4250 {28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4251 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4252 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4253 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4254 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4255 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4256 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4257 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4258 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4259 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4260 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4261 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4262 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4263 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4264 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4265 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4266 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4267 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4268 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28284, 28292,
4269 28292, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4270 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4271 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4272 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4273 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4274 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4275 28300, 28300, 28300, 28300, 28300, 28300, 28300},
4276 {28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4277 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4278 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4279 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4280 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4281 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4282 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4283 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4284 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4285 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4286 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4287 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4288 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4289 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4290 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4291 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4292 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4293 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4294 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28308, 28316, 28316,
4295 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4296 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4297 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4298 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4299 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4300 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4301 28316, 28316, 28316, 28316, 28316, 28316, 28316},
4302 {28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4303 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4304 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4305 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4306 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4307 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28324, 28324, 28324,
4308 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4309 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4310 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4311 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4312 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4313 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4314 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4315 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4316 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4317 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4318 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4319 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4320 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4321 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4322 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4323 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4324 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4325 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4326 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4327 28324, 28324, 28324, 28324, 28324, 28324, 28324},
4328 {28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4329 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4330 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4331 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4332 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4333 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4334 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4335 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4336 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4337 28324, 28324, 28324, 28324, 28324, 28332, 28340, 28352, 28364, 28376,
4338 28388, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4339 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4340 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4341 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4342 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4343 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4344 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4345 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4346 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28408, 28416,
4347 28428, 28440, 28452, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4348 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4349 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4350 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4351 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4352 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4353 28464, 28464, 28464, 28464, 28464, 28464, 28464},
4354 {28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4355 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4356 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4357 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4358 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4359 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4360 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4361 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4362 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4363 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4364 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4365 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4366 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4367 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4368 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4369 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4370 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4371 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4372 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4373 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4374 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4375 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4376 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4377 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4378 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4379 28464, 28464, 28464, 28464, 28464, 28464, 28465},
4380 {28465, 28469, 28473, 28477, 28481, 28485, 28489, 28493, 28497, 28501,
4381 28505, 28509, 28513, 28517, 28521, 28525, 28529, 28533, 28537, 28541,
4382 28545, 28549, 28553, 28557, 28561, 28565, 28569, 28573, 28577, 28581,
4383 28585, 28589, 28593, 28597, 28601, 28605, 28609, 28613, 28617, 28621,
4384 28625, 28629, 28633, 28637, 28641, 28645, 28649, 28653, 28657, 28661,
4385 28665, 28669, 28673, 28677, 28681, 28685, 28689, 28693, 28697, 28701,
4386 28705, 28709, 28713, 28717, 28721, 28725, 28729, 28733, 28737, 28741,
4387 28745, 28749, 28753, 28757, 28761, 28765, 28769, 28773, 28777, 28781,
4388 28785, 28789, 28793, 28797, 28801, 28804, 28805, 28809, 28813, 28817,
4389 28821, 28825, 28829, 28833, 28837, 28841, 28845, 28849, 28853, 28857,
4390 28861, 28865, 28869, 28873, 28877, 28881, 28885, 28889, 28893, 28897,
4391 28901, 28905, 28909, 28913, 28917, 28921, 28925, 28929, 28933, 28937,
4392 28941, 28945, 28949, 28953, 28957, 28961, 28965, 28969, 28973, 28977,
4393 28981, 28985, 28989, 28993, 28997, 29001, 29005, 29009, 29013, 29017,
4394 29021, 29025, 29029, 29033, 29037, 29041, 29045, 29049, 29053, 29057,
4395 29061, 29065, 29069, 29073, 29077, 29081, 29085, 29088, 29089, 29093,
4396 29096, 29096, 29097, 29100, 29100, 29101, 29105, 29108, 29108, 29109,
4397 29113, 29117, 29121, 29124, 29125, 29129, 29133, 29137, 29141, 29145,
4398 29149, 29153, 29157, 29161, 29165, 29169, 29172, 29173, 29176, 29177,
4399 29181, 29185, 29189, 29193, 29197, 29201, 29204, 29205, 29209, 29213,
4400 29217, 29221, 29225, 29229, 29233, 29237, 29241, 29245, 29249, 29253,
4401 29257, 29261, 29265, 29269, 29273, 29277, 29281, 29285, 29289, 29293,
4402 29297, 29301, 29305, 29309, 29313, 29317, 29321, 29325, 29329, 29333,
4403 29337, 29341, 29345, 29349, 29353, 29357, 29361, 29365, 29369, 29373,
4404 29377, 29381, 29385, 29389, 29393, 29397, 29401, 29405, 29409, 29413,
4405 29417, 29421, 29425, 29429, 29433, 29437, 29441},
4406 {29441, 29445, 29449, 29453, 29457, 29461, 29464, 29465, 29469, 29473,
4407 29477, 29480, 29480, 29481, 29485, 29489, 29493, 29497, 29501, 29505,
4408 29509, 29512, 29513, 29517, 29521, 29525, 29529, 29533, 29537, 29540,
4409 29541, 29545, 29549, 29553, 29557, 29561, 29565, 29569, 29573, 29577,
4410 29581, 29585, 29589, 29593, 29597, 29601, 29605, 29609, 29613, 29617,
4411 29621, 29625, 29629, 29633, 29637, 29641, 29645, 29649, 29652, 29653,
4412 29657, 29661, 29665, 29668, 29669, 29673, 29677, 29681, 29685, 29688,
4413 29689, 29692, 29692, 29692, 29693, 29697, 29701, 29705, 29709, 29713,
4414 29717, 29720, 29721, 29725, 29729, 29733, 29737, 29741, 29745, 29749,
4415 29753, 29757, 29761, 29765, 29769, 29773, 29777, 29781, 29785, 29789,
4416 29793, 29797, 29801, 29805, 29809, 29813, 29817, 29821, 29825, 29829,
4417 29833, 29837, 29841, 29845, 29849, 29853, 29857, 29861, 29865, 29869,
4418 29873, 29877, 29881, 29885, 29889, 29893, 29897, 29901, 29905, 29909,
4419 29913, 29917, 29921, 29925, 29929, 29933, 29937, 29941, 29945, 29949,
4420 29953, 29957, 29961, 29965, 29969, 29973, 29977, 29981, 29985, 29989,
4421 29993, 29997, 30001, 30005, 30009, 30013, 30017, 30021, 30025, 30029,
4422 30033, 30037, 30041, 30045, 30049, 30053, 30057, 30061, 30065, 30069,
4423 30073, 30077, 30081, 30085, 30089, 30093, 30097, 30101, 30105, 30109,
4424 30113, 30117, 30121, 30125, 30129, 30133, 30137, 30141, 30145, 30149,
4425 30153, 30157, 30161, 30165, 30169, 30173, 30177, 30181, 30185, 30189,
4426 30193, 30197, 30201, 30205, 30209, 30213, 30217, 30221, 30225, 30229,
4427 30233, 30237, 30241, 30245, 30249, 30253, 30257, 30261, 30265, 30269,
4428 30273, 30277, 30281, 30285, 30289, 30293, 30297, 30301, 30305, 30309,
4429 30313, 30317, 30321, 30325, 30329, 30333, 30337, 30341, 30345, 30349,
4430 30353, 30357, 30361, 30365, 30369, 30373, 30377, 30381, 30385, 30389,
4431 30393, 30397, 30401, 30405, 30409, 30413, 30417},
4432 {30417, 30421, 30425, 30429, 30433, 30437, 30441, 30445, 30449, 30453,
4433 30457, 30461, 30465, 30469, 30473, 30477, 30481, 30485, 30489, 30493,
4434 30497, 30501, 30505, 30509, 30513, 30517, 30521, 30525, 30529, 30533,
4435 30537, 30541, 30545, 30549, 30553, 30557, 30561, 30565, 30569, 30573,
4436 30577, 30581, 30585, 30589, 30593, 30597, 30601, 30605, 30609, 30613,
4437 30617, 30621, 30625, 30629, 30633, 30637, 30641, 30645, 30649, 30653,
4438 30657, 30661, 30665, 30669, 30673, 30677, 30681, 30685, 30689, 30693,
4439 30697, 30701, 30705, 30709, 30713, 30717, 30721, 30725, 30729, 30733,
4440 30737, 30741, 30745, 30749, 30753, 30757, 30761, 30765, 30769, 30773,
4441 30777, 30781, 30785, 30789, 30793, 30797, 30801, 30805, 30809, 30813,
4442 30817, 30821, 30825, 30829, 30833, 30837, 30841, 30845, 30849, 30853,
4443 30857, 30861, 30865, 30869, 30873, 30877, 30881, 30885, 30889, 30893,
4444 30897, 30901, 30905, 30909, 30913, 30917, 30921, 30925, 30929, 30933,
4445 30937, 30941, 30945, 30949, 30953, 30957, 30961, 30965, 30969, 30973,
4446 30977, 30981, 30985, 30989, 30993, 30997, 31001, 31005, 31009, 31013,
4447 31017, 31021, 31025, 31029, 31033, 31037, 31041, 31045, 31049, 31053,
4448 31057, 31061, 31065, 31069, 31073, 31077, 31080, 31080, 31081, 31085,
4449 31089, 31093, 31097, 31101, 31105, 31109, 31113, 31117, 31121, 31125,
4450 31129, 31133, 31137, 31141, 31145, 31149, 31153, 31157, 31161, 31165,
4451 31169, 31173, 31177, 31181, 31185, 31189, 31193, 31197, 31201, 31205,
4452 31209, 31213, 31217, 31221, 31225, 31229, 31233, 31237, 31241, 31245,
4453 31249, 31253, 31257, 31261, 31265, 31269, 31273, 31277, 31281, 31285,
4454 31289, 31293, 31297, 31301, 31305, 31309, 31313, 31317, 31321, 31325,
4455 31329, 31333, 31337, 31341, 31345, 31349, 31353, 31357, 31361, 31365,
4456 31369, 31373, 31377, 31381, 31385, 31389, 31393, 31397, 31401, 31405,
4457 31409, 31413, 31417, 31421, 31425, 31429, 31433},
4458 {31433, 31437, 31441, 31445, 31449, 31453, 31457, 31461, 31465, 31469,
4459 31473, 31477, 31481, 31485, 31489, 31493, 31497, 31501, 31505, 31509,
4460 31513, 31517, 31521, 31525, 31529, 31533, 31537, 31541, 31545, 31549,
4461 31553, 31557, 31561, 31565, 31569, 31573, 31577, 31581, 31585, 31589,
4462 31593, 31597, 31601, 31605, 31609, 31613, 31617, 31621, 31625, 31629,
4463 31633, 31637, 31641, 31645, 31649, 31653, 31657, 31661, 31665, 31669,
4464 31673, 31677, 31681, 31685, 31689, 31693, 31697, 31701, 31705, 31709,
4465 31713, 31717, 31721, 31725, 31729, 31733, 31737, 31741, 31745, 31749,
4466 31753, 31757, 31761, 31765, 31769, 31773, 31777, 31781, 31785, 31789,
4467 31793, 31797, 31801, 31805, 31809, 31813, 31817, 31821, 31825, 31829,
4468 31833, 31837, 31841, 31845, 31849, 31853, 31857, 31861, 31865, 31869,
4469 31873, 31877, 31881, 31885, 31889, 31893, 31897, 31901, 31905, 31909,
4470 31913, 31917, 31921, 31925, 31929, 31933, 31937, 31941, 31945, 31949,
4471 31953, 31957, 31961, 31965, 31969, 31973, 31977, 31981, 31985, 31989,
4472 31993, 31997, 32001, 32005, 32009, 32013, 32017, 32021, 32025, 32029,
4473 32033, 32037, 32041, 32045, 32049, 32053, 32057, 32061, 32065, 32069,
4474 32073, 32077, 32081, 32085, 32089, 32093, 32097, 32101, 32105, 32109,
4475 32113, 32117, 32121, 32125, 32129, 32133, 32137, 32141, 32145, 32149,
4476 32153, 32157, 32161, 32165, 32169, 32173, 32177, 32181, 32185, 32189,
4477 32193, 32197, 32201, 32205, 32209, 32213, 32217, 32221, 32225, 32229,
4478 32233, 32237, 32241, 32245, 32248, 32248, 32249, 32253, 32257, 32261,
4479 32265, 32269, 32273, 32277, 32281, 32285, 32289, 32293, 32297, 32301,
4480 32305, 32309, 32313, 32317, 32321, 32325, 32329, 32333, 32337, 32341,
4481 32345, 32349, 32353, 32357, 32361, 32365, 32369, 32373, 32377, 32381,
4482 32385, 32389, 32393, 32397, 32401, 32405, 32409, 32413, 32417, 32421,
4483 32425, 32429, 32433, 32437, 32441, 32445, 32448},
4484 {32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,
4485 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,
4486 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,
4487 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,
4488 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32449, 32453,
4489 32457, 32461, 32465, 32469, 32473, 32477, 32481, 32485, 32489, 32493,
4490 32497, 32501, 32505, 32509, 32513, 32517, 32521, 32525, 32529, 32533,
4491 32537, 32541, 32545, 32549, 32553, 32557, 32561, 32565, 32569, 32573,
4492 32577, 32581, 32585, 32589, 32593, 32597, 32601, 32605, 32609, 32613,
4493 32617, 32621, 32625, 32629, 32633, 32637, 32641, 32645, 32649, 32653,
4494 32657, 32661, 32665, 32669, 32673, 32677, 32681, 32685, 32689, 32693,
4495 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4496 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4497 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4498 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4499 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4500 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4501 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4502 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4503 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4504 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4505 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4506 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4507 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4508 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4509 32696, 32696, 32696, 32696, 32696, 32696, 32696},
4510 {32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4511 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4512 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4513 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4514 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4515 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4516 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4517 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4518 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4519 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4520 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4521 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4522 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4523 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4524 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4525 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4526 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4527 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4528 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4529 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4530 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4531 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4532 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4533 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4534 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4535 32696, 32696, 32696, 32696, 32696, 32696, 32697},
4536 {32697, 32701, 32705, 32709, 32712, 32713, 32717, 32721, 32725, 32729,
4537 32733, 32737, 32741, 32745, 32749, 32753, 32757, 32761, 32765, 32769,
4538 32773, 32777, 32781, 32785, 32789, 32793, 32797, 32801, 32805, 32809,
4539 32813, 32817, 32820, 32821, 32825, 32828, 32829, 32832, 32832, 32833,
4540 32836, 32837, 32841, 32845, 32849, 32853, 32857, 32861, 32865, 32869,
4541 32873, 32876, 32877, 32881, 32885, 32889, 32892, 32893, 32896, 32897,
4542 32900, 32900, 32900, 32900, 32900, 32900, 32901, 32904, 32904, 32904,
4543 32904, 32905, 32908, 32909, 32912, 32913, 32916, 32917, 32921, 32925,
4544 32928, 32929, 32933, 32936, 32937, 32940, 32940, 32941, 32944, 32945,
4545 32948, 32949, 32952, 32953, 32956, 32957, 32960, 32961, 32965, 32968,
4546 32969, 32972, 32972, 32973, 32977, 32981, 32985, 32988, 32989, 32993,
4547 32997, 33001, 33005, 33009, 33013, 33016, 33017, 33021, 33025, 33029,
4548 33032, 33033, 33037, 33041, 33045, 33048, 33049, 33052, 33053, 33057,
4549 33061, 33065, 33069, 33073, 33077, 33081, 33085, 33089, 33092, 33093,
4550 33097, 33101, 33105, 33109, 33113, 33117, 33121, 33125, 33129, 33133,
4551 33137, 33141, 33145, 33149, 33153, 33157, 33160, 33160, 33160, 33160,
4552 33160, 33161, 33165, 33169, 33172, 33173, 33177, 33181, 33185, 33189,
4553 33192, 33193, 33197, 33201, 33205, 33209, 33213, 33217, 33221, 33225,
4554 33229, 33233, 33237, 33241, 33245, 33249, 33253, 33257, 33260, 33260,
4555 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4556 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4557 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4558 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4559 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4560 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4561 33260, 33260, 33260, 33260, 33260, 33260, 33260},
4562 {33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4563 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4564 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4565 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4566 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4567 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4568 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4569 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4570 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4571 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4572 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4573 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4574 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4575 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4576 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4577 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4578 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4579 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4580 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4581 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4582 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4583 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4584 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4585 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4586 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4587 33260, 33260, 33260, 33260, 33260, 33260, 33261},
4588 {33261, 33269, 33277, 33285, 33293, 33301, 33309, 33317, 33325, 33333,
4589 33341, 33348, 33348, 33348, 33348, 33348, 33349, 33361, 33373, 33385,
4590 33397, 33409, 33421, 33433, 33445, 33457, 33469, 33481, 33493, 33505,
4591 33517, 33529, 33541, 33553, 33565, 33577, 33589, 33601, 33613, 33625,
4592 33637, 33649, 33661, 33673, 33677, 33681, 33689, 33696, 33697, 33701,
4593 33705, 33709, 33713, 33717, 33721, 33725, 33729, 33733, 33737, 33741,
4594 33745, 33749, 33753, 33757, 33761, 33765, 33769, 33773, 33777, 33781,
4595 33785, 33789, 33793, 33797, 33801, 33809, 33817, 33825, 33833, 33845,
4596 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852,
4597 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852,
4598 33852, 33852, 33852, 33852, 33852, 33852, 33853, 33861, 33869, 33876,
4599 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,
4600 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,
4601 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,
4602 33876, 33876, 33876, 33876, 33877, 33884, 33884, 33884, 33884, 33884,
4603 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4604 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4605 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4606 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4607 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4608 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4609 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4610 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4611 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4612 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4613 33884, 33884, 33884, 33884, 33884, 33884, 33885},
4614 {33885, 33893, 33901, 33904, 33904, 33904, 33904, 33904, 33904, 33904,
4615 33904, 33904, 33904, 33904, 33904, 33904, 33905, 33909, 33913, 33917,
4616 33925, 33929, 33933, 33937, 33941, 33945, 33949, 33953, 33957, 33961,
4617 33965, 33969, 33973, 33977, 33981, 33985, 33989, 33993, 33997, 34001,
4618 34005, 34009, 34013, 34017, 34021, 34025, 34029, 34033, 34037, 34041,
4619 34045, 34049, 34053, 34057, 34061, 34065, 34069, 34073, 34077, 34081,
4620 34084, 34084, 34084, 34084, 34085, 34097, 34109, 34121, 34133, 34145,
4621 34157, 34169, 34181, 34192, 34192, 34192, 34192, 34192, 34192, 34192,
4622 34193, 34197, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4623 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4624 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4625 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4626 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4627 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4628 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4629 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4630 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4631 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4632 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4633 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4634 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4635 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4636 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4637 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4638 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4639 34200, 34200, 34200, 34200, 34200, 34200, 34200},
4640 {34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4641 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4642 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4643 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4644 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4645 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4646 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4647 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4648 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4649 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4650 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4651 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4652 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4653 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4654 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4655 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4656 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4657 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4658 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4659 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4660 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4661 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4662 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4663 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4664 34201, 34205, 34209, 34213, 34217, 34221, 34225, 34229, 34233, 34237,
4665 34240, 34240, 34240, 34240, 34240, 34240, 34240},
4666 {34240, 34244, 34248, 34252, 34256, 34260, 34264, 34268, 34272, 34276,
4667 34280, 34284, 34288, 34292, 34296, 34300, 34304, 34308, 34312, 34316,
4668 34320, 34324, 34328, 34332, 34336, 34340, 34344, 34348, 34352, 34356,
4669 34360, 34364, 34368, 34372, 34376, 34380, 34384, 34388, 34392, 34396,
4670 34400, 34404, 34408, 34412, 34416, 34420, 34424, 34428, 34432, 34436,
4671 34440, 34444, 34448, 34452, 34456, 34460, 34464, 34468, 34472, 34476,
4672 34480, 34484, 34488, 34492, 34496, 34500, 34504, 34508, 34512, 34516,
4673 34520, 34524, 34528, 34532, 34536, 34540, 34544, 34548, 34552, 34556,
4674 34560, 34564, 34568, 34572, 34576, 34580, 34584, 34588, 34592, 34596,
4675 34600, 34604, 34608, 34612, 34616, 34620, 34624, 34628, 34632, 34636,
4676 34640, 34644, 34648, 34652, 34656, 34660, 34664, 34668, 34672, 34676,
4677 34680, 34684, 34688, 34692, 34696, 34700, 34704, 34708, 34712, 34716,
4678 34720, 34724, 34728, 34732, 34736, 34740, 34744, 34748, 34752, 34756,
4679 34760, 34764, 34768, 34772, 34776, 34780, 34784, 34788, 34792, 34796,
4680 34800, 34804, 34808, 34812, 34816, 34820, 34824, 34828, 34832, 34836,
4681 34840, 34844, 34848, 34852, 34856, 34860, 34864, 34868, 34872, 34876,
4682 34880, 34884, 34888, 34892, 34896, 34900, 34904, 34908, 34912, 34916,
4683 34920, 34924, 34928, 34932, 34936, 34940, 34944, 34948, 34952, 34956,
4684 34960, 34964, 34968, 34972, 34976, 34980, 34984, 34988, 34992, 34996,
4685 35000, 35004, 35008, 35012, 35016, 35020, 35024, 35028, 35032, 35036,
4686 35040, 35044, 35048, 35052, 35056, 35060, 35064, 35068, 35072, 35076,
4687 35080, 35084, 35088, 35092, 35096, 35100, 35104, 35108, 35112, 35116,
4688 35120, 35124, 35128, 35132, 35136, 35140, 35144, 35148, 35152, 35156,
4689 35160, 35164, 35168, 35172, 35176, 35180, 35184, 35188, 35192, 35196,
4690 35200, 35204, 35208, 35212, 35216, 35220, 35224, 35228, 35232, 35236,
4691 35240, 35244, 35248, 35252, 35256, 35260, 35264},
4692 {35264, 35268, 35272, 35276, 35280, 35284, 35288, 35292, 35296, 35300,
4693 35304, 35308, 35312, 35316, 35320, 35324, 35328, 35332, 35336, 35340,
4694 35344, 35348, 35352, 35356, 35360, 35364, 35368, 35372, 35376, 35380,
4695 35384, 35388, 35392, 35396, 35400, 35404, 35408, 35412, 35416, 35420,
4696 35424, 35428, 35432, 35436, 35440, 35444, 35448, 35452, 35456, 35460,
4697 35464, 35468, 35472, 35476, 35480, 35484, 35488, 35492, 35496, 35500,
4698 35504, 35508, 35512, 35516, 35520, 35524, 35528, 35532, 35536, 35540,
4699 35544, 35548, 35552, 35556, 35560, 35564, 35568, 35572, 35576, 35580,
4700 35584, 35588, 35592, 35596, 35600, 35604, 35608, 35612, 35616, 35620,
4701 35624, 35628, 35632, 35636, 35640, 35644, 35648, 35652, 35656, 35660,
4702 35664, 35668, 35672, 35676, 35680, 35684, 35688, 35692, 35696, 35700,
4703 35704, 35708, 35712, 35716, 35720, 35724, 35728, 35732, 35736, 35740,
4704 35744, 35748, 35752, 35756, 35760, 35764, 35768, 35772, 35776, 35780,
4705 35784, 35788, 35792, 35796, 35800, 35804, 35808, 35812, 35816, 35820,
4706 35824, 35828, 35832, 35836, 35840, 35844, 35848, 35852, 35856, 35860,
4707 35864, 35868, 35872, 35876, 35880, 35884, 35888, 35892, 35896, 35900,
4708 35904, 35908, 35912, 35916, 35920, 35924, 35928, 35932, 35936, 35940,
4709 35944, 35948, 35952, 35956, 35960, 35964, 35968, 35972, 35976, 35980,
4710 35984, 35988, 35992, 35996, 36000, 36004, 36008, 36012, 36016, 36020,
4711 36024, 36028, 36032, 36036, 36040, 36044, 36048, 36052, 36056, 36060,
4712 36064, 36068, 36072, 36076, 36080, 36084, 36088, 36092, 36096, 36100,
4713 36104, 36108, 36112, 36116, 36120, 36124, 36128, 36132, 36136, 36140,
4714 36144, 36148, 36152, 36156, 36160, 36164, 36168, 36172, 36176, 36180,
4715 36184, 36188, 36192, 36196, 36200, 36204, 36208, 36212, 36216, 36220,
4716 36224, 36228, 36232, 36236, 36240, 36244, 36248, 36252, 36256, 36260,
4717 36264, 36268, 36272, 36276, 36280, 36284, 36288},
4718 {36288, 36292, 36296, 36300, 36304, 36308, 36312, 36316, 36320, 36324,
4719 36328, 36332, 36336, 36340, 36344, 36348, 36352, 36356, 36360, 36364,
4720 36368, 36372, 36376, 36380, 36384, 36388, 36392, 36396, 36400, 36404,
4721 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4722 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4723 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4724 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4725 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4726 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4727 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4728 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4729 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4730 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4731 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4732 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4733 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4734 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4735 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4736 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4737 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4738 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4739 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4740 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4741 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4742 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4743 36408, 36408, 36408, 36408, 36408, 36408, 36408}};
4744 const char32_t decomposition_data[9102] = {
4745 0, 32, 32, 776, 97, 32, 772, 50, 51,
4746 32, 769, 956, 32, 807, 49, 111, 49, 8260,
4747 52, 49, 8260, 50, 51, 8260, 52, 65, 768,
4748 65, 769, 65, 770, 65, 771, 65, 776, 65,
4749 778, 67, 807, 69, 768, 69, 769, 69, 770,
4750 69, 776, 73, 768, 73, 769, 73, 770, 73,
4751 776, 78, 771, 79, 768, 79, 769, 79, 770,
4752 79, 771, 79, 776, 85, 768, 85, 769, 85,
4753 770, 85, 776, 89, 769, 97, 768, 97, 769,
4754 97, 770, 97, 771, 97, 776, 97, 778, 99,
4755 807, 101, 768, 101, 769, 101, 770, 101, 776,
4756 105, 768, 105, 769, 105, 770, 105, 776, 110,
4757 771, 111, 768, 111, 769, 111, 770, 111, 771,
4758 111, 776, 117, 768, 117, 769, 117, 770, 117,
4759 776, 121, 769, 121, 776, 65, 772, 97, 772,
4760 65, 774, 97, 774, 65, 808, 97, 808, 67,
4761 769, 99, 769, 67, 770, 99, 770, 67, 775,
4762 99, 775, 67, 780, 99, 780, 68, 780, 100,
4763 780, 69, 772, 101, 772, 69, 774, 101, 774,
4764 69, 775, 101, 775, 69, 808, 101, 808, 69,
4765 780, 101, 780, 71, 770, 103, 770, 71, 774,
4766 103, 774, 71, 775, 103, 775, 71, 807, 103,
4767 807, 72, 770, 104, 770, 73, 771, 105, 771,
4768 73, 772, 105, 772, 73, 774, 105, 774, 73,
4769 808, 105, 808, 73, 775, 73, 74, 105, 106,
4770 74, 770, 106, 770, 75, 807, 107, 807, 76,
4771 769, 108, 769, 76, 807, 108, 807, 76, 780,
4772 108, 780, 76, 183, 108, 183, 78, 769, 110,
4773 769, 78, 807, 110, 807, 78, 780, 110, 780,
4774 700, 110, 79, 772, 111, 772, 79, 774, 111,
4775 774, 79, 779, 111, 779, 82, 769, 114, 769,
4776 82, 807, 114, 807, 82, 780, 114, 780, 83,
4777 769, 115, 769, 83, 770, 115, 770, 83, 807,
4778 115, 807, 83, 780, 115, 780, 84, 807, 116,
4779 807, 84, 780, 116, 780, 85, 771, 117, 771,
4780 85, 772, 117, 772, 85, 774, 117, 774, 85,
4781 778, 117, 778, 85, 779, 117, 779, 85, 808,
4782 117, 808, 87, 770, 119, 770, 89, 770, 121,
4783 770, 89, 776, 90, 769, 122, 769, 90, 775,
4784 122, 775, 90, 780, 122, 780, 115, 79, 795,
4785 111, 795, 85, 795, 117, 795, 68, 90, 780,
4786 68, 122, 780, 100, 122, 780, 76, 74, 76,
4787 106, 108, 106, 78, 74, 78, 106, 110, 106,
4788 65, 780, 97, 780, 73, 780, 105, 780, 79,
4789 780, 111, 780, 85, 780, 117, 780, 85, 776,
4790 772, 117, 776, 772, 85, 776, 769, 117, 776,
4791 769, 85, 776, 780, 117, 776, 780, 85, 776,
4792 768, 117, 776, 768, 65, 776, 772, 97, 776,
4793 772, 65, 775, 772, 97, 775, 772, 198, 772,
4794 230, 772, 71, 780, 103, 780, 75, 780, 107,
4795 780, 79, 808, 111, 808, 79, 808, 772, 111,
4796 808, 772, 439, 780, 658, 780, 106, 780, 68,
4797 90, 68, 122, 100, 122, 71, 769, 103, 769,
4798 78, 768, 110, 768, 65, 778, 769, 97, 778,
4799 769, 198, 769, 230, 769, 216, 769, 248, 769,
4800 65, 783, 97, 783, 65, 785, 97, 785, 69,
4801 783, 101, 783, 69, 785, 101, 785, 73, 783,
4802 105, 783, 73, 785, 105, 785, 79, 783, 111,
4803 783, 79, 785, 111, 785, 82, 783, 114, 783,
4804 82, 785, 114, 785, 85, 783, 117, 783, 85,
4805 785, 117, 785, 83, 806, 115, 806, 84, 806,
4806 116, 806, 72, 780, 104, 780, 65, 775, 97,
4807 775, 69, 807, 101, 807, 79, 776, 772, 111,
4808 776, 772, 79, 771, 772, 111, 771, 772, 79,
4809 775, 111, 775, 79, 775, 772, 111, 775, 772,
4810 89, 772, 121, 772, 104, 614, 106, 114, 633,
4811 635, 641, 119, 121, 32, 774, 32, 775, 32,
4812 778, 32, 808, 32, 771, 32, 779, 611, 108,
4813 115, 120, 661, 768, 769, 787, 776, 769, 697,
4814 32, 837, 59, 32, 769, 168, 769, 913, 769,
4815 183, 917, 769, 919, 769, 921, 769, 927, 769,
4816 933, 769, 937, 769, 953, 776, 769, 921, 776,
4817 933, 776, 945, 769, 949, 769, 951, 769, 953,
4818 769, 965, 776, 769, 953, 776, 965, 776, 959,
4819 769, 965, 769, 969, 769, 946, 952, 933, 978,
4820 769, 978, 776, 966, 960, 954, 961, 962, 920,
4821 949, 931, 1045, 768, 1045, 776, 1043, 769, 1030,
4822 776, 1050, 769, 1048, 768, 1059, 774, 1048, 774,
4823 1080, 774, 1077, 768, 1077, 776, 1075, 769, 1110,
4824 776, 1082, 769, 1080, 768, 1091, 774, 1140, 783,
4825 1141, 783, 1046, 774, 1078, 774, 1040, 774, 1072,
4826 774, 1040, 776, 1072, 776, 1045, 774, 1077, 774,
4827 1240, 776, 1241, 776, 1046, 776, 1078, 776, 1047,
4828 776, 1079, 776, 1048, 772, 1080, 772, 1048, 776,
4829 1080, 776, 1054, 776, 1086, 776, 1256, 776, 1257,
4830 776, 1069, 776, 1101, 776, 1059, 772, 1091, 772,
4831 1059, 776, 1091, 776, 1059, 779, 1091, 779, 1063,
4832 776, 1095, 776, 1067, 776, 1099, 776, 1381, 1410,
4833 1575, 1619, 1575, 1620, 1608, 1620, 1575, 1621, 1610,
4834 1620, 1575, 1652, 1608, 1652, 1735, 1652, 1610, 1652,
4835 1749, 1620, 1729, 1620, 1746, 1620, 2344, 2364, 2352,
4836 2364, 2355, 2364, 2325, 2364, 2326, 2364, 2327, 2364,
4837 2332, 2364, 2337, 2364, 2338, 2364, 2347, 2364, 2351,
4838 2364, 2503, 2494, 2503, 2519, 2465, 2492, 2466, 2492,
4839 2479, 2492, 2610, 2620, 2616, 2620, 2582, 2620, 2583,
4840 2620, 2588, 2620, 2603, 2620, 2887, 2902, 2887, 2878,
4841 2887, 2903, 2849, 2876, 2850, 2876, 2962, 3031, 3014,
4842 3006, 3015, 3006, 3014, 3031, 3142, 3158, 3263, 3285,
4843 3270, 3285, 3270, 3286, 3270, 3266, 3270, 3266, 3285,
4844 3398, 3390, 3399, 3390, 3398, 3415, 3545, 3530, 3545,
4845 3535, 3545, 3535, 3530, 3545, 3551, 3661, 3634, 3789,
4846 3762, 3755, 3737, 3755, 3745, 3851, 3906, 4023, 3916,
4847 4023, 3921, 4023, 3926, 4023, 3931, 4023, 3904, 4021,
4848 3953, 3954, 3953, 3956, 4018, 3968, 4018, 3953, 3968,
4849 4019, 3968, 4019, 3953, 3968, 3953, 3968, 3986, 4023,
4850 3996, 4023, 4001, 4023, 4006, 4023, 4011, 4023, 3984,
4851 4021, 4133, 4142, 4316, 6917, 6965, 6919, 6965, 6921,
4852 6965, 6923, 6965, 6925, 6965, 6929, 6965, 6970, 6965,
4853 6972, 6965, 6974, 6965, 6975, 6965, 6978, 6965, 65,
4854 198, 66, 68, 69, 398, 71, 72, 73, 74,
4855 75, 76, 77, 78, 79, 546, 80, 82, 84,
4856 85, 87, 97, 592, 593, 7426, 98, 100, 101,
4857 601, 603, 604, 103, 107, 109, 331, 111, 596,
4858 7446, 7447, 112, 116, 117, 7453, 623, 118, 7461,
4859 946, 947, 948, 966, 967, 105, 114, 117, 118,
4860 946, 947, 961, 966, 967, 1085, 594, 99, 597,
4861 240, 604, 102, 607, 609, 613, 616, 617, 618,
4862 7547, 669, 621, 7557, 671, 625, 624, 626, 627,
4863 628, 629, 632, 642, 643, 427, 649, 650, 7452,
4864 651, 652, 122, 656, 657, 658, 952, 65, 805,
4865 97, 805, 66, 775, 98, 775, 66, 803, 98,
4866 803, 66, 817, 98, 817, 67, 807, 769, 99,
4867 807, 769, 68, 775, 100, 775, 68, 803, 100,
4868 803, 68, 817, 100, 817, 68, 807, 100, 807,
4869 68, 813, 100, 813, 69, 772, 768, 101, 772,
4870 768, 69, 772, 769, 101, 772, 769, 69, 813,
4871 101, 813, 69, 816, 101, 816, 69, 807, 774,
4872 101, 807, 774, 70, 775, 102, 775, 71, 772,
4873 103, 772, 72, 775, 104, 775, 72, 803, 104,
4874 803, 72, 776, 104, 776, 72, 807, 104, 807,
4875 72, 814, 104, 814, 73, 816, 105, 816, 73,
4876 776, 769, 105, 776, 769, 75, 769, 107, 769,
4877 75, 803, 107, 803, 75, 817, 107, 817, 76,
4878 803, 108, 803, 76, 803, 772, 108, 803, 772,
4879 76, 817, 108, 817, 76, 813, 108, 813, 77,
4880 769, 109, 769, 77, 775, 109, 775, 77, 803,
4881 109, 803, 78, 775, 110, 775, 78, 803, 110,
4882 803, 78, 817, 110, 817, 78, 813, 110, 813,
4883 79, 771, 769, 111, 771, 769, 79, 771, 776,
4884 111, 771, 776, 79, 772, 768, 111, 772, 768,
4885 79, 772, 769, 111, 772, 769, 80, 769, 112,
4886 769, 80, 775, 112, 775, 82, 775, 114, 775,
4887 82, 803, 114, 803, 82, 803, 772, 114, 803,
4888 772, 82, 817, 114, 817, 83, 775, 115, 775,
4889 83, 803, 115, 803, 83, 769, 775, 115, 769,
4890 775, 83, 780, 775, 115, 780, 775, 83, 803,
4891 775, 115, 803, 775, 84, 775, 116, 775, 84,
4892 803, 116, 803, 84, 817, 116, 817, 84, 813,
4893 116, 813, 85, 804, 117, 804, 85, 816, 117,
4894 816, 85, 813, 117, 813, 85, 771, 769, 117,
4895 771, 769, 85, 772, 776, 117, 772, 776, 86,
4896 771, 118, 771, 86, 803, 118, 803, 87, 768,
4897 119, 768, 87, 769, 119, 769, 87, 776, 119,
4898 776, 87, 775, 119, 775, 87, 803, 119, 803,
4899 88, 775, 120, 775, 88, 776, 120, 776, 89,
4900 775, 121, 775, 90, 770, 122, 770, 90, 803,
4901 122, 803, 90, 817, 122, 817, 104, 817, 116,
4902 776, 119, 778, 121, 778, 97, 702, 383, 775,
4903 65, 803, 97, 803, 65, 777, 97, 777, 65,
4904 770, 769, 97, 770, 769, 65, 770, 768, 97,
4905 770, 768, 65, 770, 777, 97, 770, 777, 65,
4906 770, 771, 97, 770, 771, 65, 803, 770, 97,
4907 803, 770, 65, 774, 769, 97, 774, 769, 65,
4908 774, 768, 97, 774, 768, 65, 774, 777, 97,
4909 774, 777, 65, 774, 771, 97, 774, 771, 65,
4910 803, 774, 97, 803, 774, 69, 803, 101, 803,
4911 69, 777, 101, 777, 69, 771, 101, 771, 69,
4912 770, 769, 101, 770, 769, 69, 770, 768, 101,
4913 770, 768, 69, 770, 777, 101, 770, 777, 69,
4914 770, 771, 101, 770, 771, 69, 803, 770, 101,
4915 803, 770, 73, 777, 105, 777, 73, 803, 105,
4916 803, 79, 803, 111, 803, 79, 777, 111, 777,
4917 79, 770, 769, 111, 770, 769, 79, 770, 768,
4918 111, 770, 768, 79, 770, 777, 111, 770, 777,
4919 79, 770, 771, 111, 770, 771, 79, 803, 770,
4920 111, 803, 770, 79, 795, 769, 111, 795, 769,
4921 79, 795, 768, 111, 795, 768, 79, 795, 777,
4922 111, 795, 777, 79, 795, 771, 111, 795, 771,
4923 79, 795, 803, 111, 795, 803, 85, 803, 117,
4924 803, 85, 777, 117, 777, 85, 795, 769, 117,
4925 795, 769, 85, 795, 768, 117, 795, 768, 85,
4926 795, 777, 117, 795, 777, 85, 795, 771, 117,
4927 795, 771, 85, 795, 803, 117, 795, 803, 89,
4928 768, 121, 768, 89, 803, 121, 803, 89, 777,
4929 121, 777, 89, 771, 121, 771, 945, 787, 945,
4930 788, 945, 787, 768, 945, 788, 768, 945, 787,
4931 769, 945, 788, 769, 945, 787, 834, 945, 788,
4932 834, 913, 787, 913, 788, 913, 787, 768, 913,
4933 788, 768, 913, 787, 769, 913, 788, 769, 913,
4934 787, 834, 913, 788, 834, 949, 787, 949, 788,
4935 949, 787, 768, 949, 788, 768, 949, 787, 769,
4936 949, 788, 769, 917, 787, 917, 788, 917, 787,
4937 768, 917, 788, 768, 917, 787, 769, 917, 788,
4938 769, 951, 787, 951, 788, 951, 787, 768, 951,
4939 788, 768, 951, 787, 769, 951, 788, 769, 951,
4940 787, 834, 951, 788, 834, 919, 787, 919, 788,
4941 919, 787, 768, 919, 788, 768, 919, 787, 769,
4942 919, 788, 769, 919, 787, 834, 919, 788, 834,
4943 953, 787, 953, 788, 953, 787, 768, 953, 788,
4944 768, 953, 787, 769, 953, 788, 769, 953, 787,
4945 834, 953, 788, 834, 921, 787, 921, 788, 921,
4946 787, 768, 921, 788, 768, 921, 787, 769, 921,
4947 788, 769, 921, 787, 834, 921, 788, 834, 959,
4948 787, 959, 788, 959, 787, 768, 959, 788, 768,
4949 959, 787, 769, 959, 788, 769, 927, 787, 927,
4950 788, 927, 787, 768, 927, 788, 768, 927, 787,
4951 769, 927, 788, 769, 965, 787, 965, 788, 965,
4952 787, 768, 965, 788, 768, 965, 787, 769, 965,
4953 788, 769, 965, 787, 834, 965, 788, 834, 933,
4954 788, 933, 788, 768, 933, 788, 769, 933, 788,
4955 834, 969, 787, 969, 788, 969, 787, 768, 969,
4956 788, 768, 969, 787, 769, 969, 788, 769, 969,
4957 787, 834, 969, 788, 834, 937, 787, 937, 788,
4958 937, 787, 768, 937, 788, 768, 937, 787, 769,
4959 937, 788, 769, 937, 787, 834, 937, 788, 834,
4960 945, 768, 945, 769, 949, 768, 949, 769, 951,
4961 768, 951, 769, 953, 768, 953, 769, 959, 768,
4962 959, 769, 965, 768, 965, 769, 969, 768, 969,
4963 769, 945, 787, 837, 945, 788, 837, 945, 787,
4964 768, 837, 945, 788, 768, 837, 945, 787, 769,
4965 837, 945, 788, 769, 837, 945, 787, 834, 837,
4966 945, 788, 834, 837, 913, 787, 837, 913, 788,
4967 837, 913, 787, 768, 837, 913, 788, 768, 837,
4968 913, 787, 769, 837, 913, 788, 769, 837, 913,
4969 787, 834, 837, 913, 788, 834, 837, 951, 787,
4970 837, 951, 788, 837, 951, 787, 768, 837, 951,
4971 788, 768, 837, 951, 787, 769, 837, 951, 788,
4972 769, 837, 951, 787, 834, 837, 951, 788, 834,
4973 837, 919, 787, 837, 919, 788, 837, 919, 787,
4974 768, 837, 919, 788, 768, 837, 919, 787, 769,
4975 837, 919, 788, 769, 837, 919, 787, 834, 837,
4976 919, 788, 834, 837, 969, 787, 837, 969, 788,
4977 837, 969, 787, 768, 837, 969, 788, 768, 837,
4978 969, 787, 769, 837, 969, 788, 769, 837, 969,
4979 787, 834, 837, 969, 788, 834, 837, 937, 787,
4980 837, 937, 788, 837, 937, 787, 768, 837, 937,
4981 788, 768, 837, 937, 787, 769, 837, 937, 788,
4982 769, 837, 937, 787, 834, 837, 937, 788, 834,
4983 837, 945, 774, 945, 772, 945, 768, 837, 945,
4984 837, 945, 769, 837, 945, 834, 945, 834, 837,
4985 913, 774, 913, 772, 913, 768, 913, 769, 913,
4986 837, 32, 787, 953, 32, 787, 32, 834, 168,
4987 834, 951, 768, 837, 951, 837, 951, 769, 837,
4988 951, 834, 951, 834, 837, 917, 768, 917, 769,
4989 919, 768, 919, 769, 919, 837, 8127, 768, 8127,
4990 769, 8127, 834, 953, 774, 953, 772, 953, 776,
4991 768, 953, 776, 769, 953, 834, 953, 776, 834,
4992 921, 774, 921, 772, 921, 768, 921, 769, 8190,
4993 768, 8190, 769, 8190, 834, 965, 774, 965, 772,
4994 965, 776, 768, 965, 776, 769, 961, 787, 961,
4995 788, 965, 834, 965, 776, 834, 933, 774, 933,
4996 772, 933, 768, 933, 769, 929, 788, 168, 768,
4997 168, 769, 96, 969, 768, 837, 969, 837, 969,
4998 769, 837, 969, 834, 969, 834, 837, 927, 768,
4999 927, 769, 937, 768, 937, 769, 937, 837, 180,
5000 32, 788, 8194, 8195, 32, 32, 32, 32, 32,
5001 32, 32, 32, 32, 8208, 32, 819, 46, 46,
5002 46, 46, 46, 46, 32, 8242, 8242, 8242, 8242,
5003 8242, 8245, 8245, 8245, 8245, 8245, 33, 33, 32,
5004 773, 63, 63, 63, 33, 33, 63, 8242, 8242,
5005 8242, 8242, 32, 48, 105, 52, 53, 54, 55,
5006 56, 57, 43, 8722, 61, 40, 41, 110, 48,
5007 49, 50, 51, 52, 53, 54, 55, 56, 57,
5008 43, 8722, 61, 40, 41, 97, 101, 111, 120,
5009 601, 104, 107, 108, 109, 110, 112, 115, 116,
5010 82, 115, 97, 47, 99, 97, 47, 115, 67,
5011 176, 67, 99, 47, 111, 99, 47, 117, 400,
5012 176, 70, 103, 72, 72, 72, 104, 295, 73,
5013 73, 76, 108, 78, 78, 111, 80, 81, 82,
5014 82, 82, 83, 77, 84, 69, 76, 84, 77,
5015 90, 937, 90, 75, 65, 778, 66, 67, 101,
5016 69, 70, 77, 111, 1488, 1489, 1490, 1491, 105,
5017 70, 65, 88, 960, 947, 915, 928, 8721, 68,
5018 100, 101, 105, 106, 49, 8260, 55, 49, 8260,
5019 57, 49, 8260, 49, 48, 49, 8260, 51, 50,
5020 8260, 51, 49, 8260, 53, 50, 8260, 53, 51,
5021 8260, 53, 52, 8260, 53, 49, 8260, 54, 53,
5022 8260, 54, 49, 8260, 56, 51, 8260, 56, 53,
5023 8260, 56, 55, 8260, 56, 49, 8260, 73, 73,
5024 73, 73, 73, 73, 73, 86, 86, 86, 73,
5025 86, 73, 73, 86, 73, 73, 73, 73, 88,
5026 88, 88, 73, 88, 73, 73, 76, 67, 68,
5027 77, 105, 105, 105, 105, 105, 105, 105, 118,
5028 118, 118, 105, 118, 105, 105, 118, 105, 105,
5029 105, 105, 120, 120, 120, 105, 120, 105, 105,
5030 108, 99, 100, 109, 48, 8260, 51, 8592, 824,
5031 8594, 824, 8596, 824, 8656, 824, 8660, 824, 8658,
5032 824, 8707, 824, 8712, 824, 8715, 824, 8739, 824,
5033 8741, 824, 8747, 8747, 8747, 8747, 8747, 8750, 8750,
5034 8750, 8750, 8750, 8764, 824, 8771, 824, 8773, 824,
5035 8776, 824, 61, 824, 8801, 824, 8781, 824, 60,
5036 824, 62, 824, 8804, 824, 8805, 824, 8818, 824,
5037 8819, 824, 8822, 824, 8823, 824, 8826, 824, 8827,
5038 824, 8834, 824, 8835, 824, 8838, 824, 8839, 824,
5039 8866, 824, 8872, 824, 8873, 824, 8875, 824, 8828,
5040 824, 8829, 824, 8849, 824, 8850, 824, 8882, 824,
5041 8883, 824, 8884, 824, 8885, 824, 12296, 12297, 49,
5042 50, 51, 52, 53, 54, 55, 56, 57, 49,
5043 48, 49, 49, 49, 50, 49, 51, 49, 52,
5044 49, 53, 49, 54, 49, 55, 49, 56, 49,
5045 57, 50, 48, 40, 49, 41, 40, 50, 41,
5046 40, 51, 41, 40, 52, 41, 40, 53, 41,
5047 40, 54, 41, 40, 55, 41, 40, 56, 41,
5048 40, 57, 41, 40, 49, 48, 41, 40, 49,
5049 49, 41, 40, 49, 50, 41, 40, 49, 51,
5050 41, 40, 49, 52, 41, 40, 49, 53, 41,
5051 40, 49, 54, 41, 40, 49, 55, 41, 40,
5052 49, 56, 41, 40, 49, 57, 41, 40, 50,
5053 48, 41, 49, 46, 50, 46, 51, 46, 52,
5054 46, 53, 46, 54, 46, 55, 46, 56, 46,
5055 57, 46, 49, 48, 46, 49, 49, 46, 49,
5056 50, 46, 49, 51, 46, 49, 52, 46, 49,
5057 53, 46, 49, 54, 46, 49, 55, 46, 49,
5058 56, 46, 49, 57, 46, 50, 48, 46, 40,
5059 97, 41, 40, 98, 41, 40, 99, 41, 40,
5060 100, 41, 40, 101, 41, 40, 102, 41, 40,
5061 103, 41, 40, 104, 41, 40, 105, 41, 40,
5062 106, 41, 40, 107, 41, 40, 108, 41, 40,
5063 109, 41, 40, 110, 41, 40, 111, 41, 40,
5064 112, 41, 40, 113, 41, 40, 114, 41, 40,
5065 115, 41, 40, 116, 41, 40, 117, 41, 40,
5066 118, 41, 40, 119, 41, 40, 120, 41, 40,
5067 121, 41, 40, 122, 41, 65, 66, 67, 68,
5068 69, 70, 71, 72, 73, 74, 75, 76, 77,
5069 78, 79, 80, 81, 82, 83, 84, 85, 86,
5070 87, 88, 89, 90, 97, 98, 99, 100, 101,
5071 102, 103, 104, 105, 106, 107, 108, 109, 110,
5072 111, 112, 113, 114, 115, 116, 117, 118, 119,
5073 120, 121, 122, 48, 8747, 8747, 8747, 8747, 58,
5074 58, 61, 61, 61, 61, 61, 61, 10973, 824,
5075 106, 86, 11617, 27597, 40863, 19968, 20008, 20022, 20031,
5076 20057, 20101, 20108, 20128, 20154, 20799, 20837, 20843, 20866,
5077 20886, 20907, 20960, 20981, 20992, 21147, 21241, 21269, 21274,
5078 21304, 21313, 21340, 21353, 21378, 21430, 21448, 21475, 22231,
5079 22303, 22763, 22786, 22794, 22805, 22823, 22899, 23376, 23424,
5080 23544, 23567, 23586, 23608, 23662, 23665, 24027, 24037, 24049,
5081 24062, 24178, 24186, 24191, 24308, 24318, 24331, 24339, 24400,
5082 24417, 24435, 24515, 25096, 25142, 25163, 25903, 25908, 25991,
5083 26007, 26020, 26041, 26080, 26085, 26352, 26376, 26408, 27424,
5084 27490, 27513, 27571, 27595, 27604, 27611, 27663, 27668, 27700,
5085 28779, 29226, 29238, 29243, 29247, 29255, 29273, 29275, 29356,
5086 29572, 29577, 29916, 29926, 29976, 29983, 29992, 30000, 30091,
5087 30098, 30326, 30333, 30382, 30399, 30446, 30683, 30690, 30707,
5088 31034, 31160, 31166, 31348, 31435, 31481, 31859, 31992, 32566,
5089 32593, 32650, 32701, 32769, 32780, 32786, 32819, 32895, 32905,
5090 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390, 33394,
5091 33400, 34381, 34411, 34880, 34892, 34915, 35198, 35211, 35282,
5092 35328, 35895, 35910, 35925, 35960, 35997, 36196, 36208, 36275,
5093 36523, 36554, 36763, 36784, 36789, 37009, 37193, 37318, 37324,
5094 37329, 38263, 38272, 38428, 38582, 38585, 38632, 38737, 38750,
5095 38754, 38761, 38859, 38893, 38899, 38913, 39080, 39131, 39135,
5096 39318, 39321, 39340, 39592, 39640, 39647, 39717, 39727, 39730,
5097 39740, 39770, 40165, 40565, 40575, 40613, 40635, 40643, 40653,
5098 40657, 40697, 40701, 40718, 40723, 40736, 40763, 40778, 40786,
5099 40845, 40860, 40864, 32, 12306, 21313, 21316, 21317, 12363,
5100 12441, 12365, 12441, 12367, 12441, 12369, 12441, 12371, 12441,
5101 12373, 12441, 12375, 12441, 12377, 12441, 12379, 12441, 12381,
5102 12441, 12383, 12441, 12385, 12441, 12388, 12441, 12390, 12441,
5103 12392, 12441, 12399, 12441, 12399, 12442, 12402, 12441, 12402,
5104 12442, 12405, 12441, 12405, 12442, 12408, 12441, 12408, 12442,
5105 12411, 12441, 12411, 12442, 12358, 12441, 32, 12441, 32,
5106 12442, 12445, 12441, 12424, 12426, 12459, 12441, 12461, 12441,
5107 12463, 12441, 12465, 12441, 12467, 12441, 12469, 12441, 12471,
5108 12441, 12473, 12441, 12475, 12441, 12477, 12441, 12479, 12441,
5109 12481, 12441, 12484, 12441, 12486, 12441, 12488, 12441, 12495,
5110 12441, 12495, 12442, 12498, 12441, 12498, 12442, 12501, 12441,
5111 12501, 12442, 12504, 12441, 12504, 12442, 12507, 12441, 12507,
5112 12442, 12454, 12441, 12527, 12441, 12528, 12441, 12529, 12441,
5113 12530, 12441, 12541, 12441, 12467, 12488, 4352, 4353, 4522,
5114 4354, 4524, 4525, 4355, 4356, 4357, 4528, 4529, 4530,
5115 4531, 4532, 4533, 4378, 4358, 4359, 4360, 4385, 4361,
5116 4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370,
5117 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457,
5118 4458, 4459, 4460, 4461, 4462, 4463, 4464, 4465, 4466,
5119 4467, 4468, 4469, 4448, 4372, 4373, 4551, 4552, 4556,
5120 4558, 4563, 4567, 4569, 4380, 4573, 4575, 4381, 4382,
5121 4384, 4386, 4387, 4391, 4393, 4395, 4396, 4397, 4398,
5122 4399, 4402, 4406, 4416, 4423, 4428, 4593, 4594, 4439,
5123 4440, 4441, 4484, 4485, 4488, 4497, 4498, 4500, 4510,
5124 4513, 19968, 20108, 19977, 22235, 19978, 20013, 19979, 30002,
5125 20057, 19993, 19969, 22825, 22320, 20154, 40, 4352, 41,
5126 40, 4354, 41, 40, 4355, 41, 40, 4357, 41,
5127 40, 4358, 41, 40, 4359, 41, 40, 4361, 41,
5128 40, 4363, 41, 40, 4364, 41, 40, 4366, 41,
5129 40, 4367, 41, 40, 4368, 41, 40, 4369, 41,
5130 40, 4370, 41, 40, 4352, 4449, 41, 40, 4354,
5131 4449, 41, 40, 4355, 4449, 41, 40, 4357, 4449,
5132 41, 40, 4358, 4449, 41, 40, 4359, 4449, 41,
5133 40, 4361, 4449, 41, 40, 4363, 4449, 41, 40,
5134 4364, 4449, 41, 40, 4366, 4449, 41, 40, 4367,
5135 4449, 41, 40, 4368, 4449, 41, 40, 4369, 4449,
5136 41, 40, 4370, 4449, 41, 40, 4364, 4462, 41,
5137 40, 4363, 4457, 4364, 4453, 4523, 41, 40, 4363,
5138 4457, 4370, 4462, 41, 40, 19968, 41, 40, 20108,
5139 41, 40, 19977, 41, 40, 22235, 41, 40, 20116,
5140 41, 40, 20845, 41, 40, 19971, 41, 40, 20843,
5141 41, 40, 20061, 41, 40, 21313, 41, 40, 26376,
5142 41, 40, 28779, 41, 40, 27700, 41, 40, 26408,
5143 41, 40, 37329, 41, 40, 22303, 41, 40, 26085,
5144 41, 40, 26666, 41, 40, 26377, 41, 40, 31038,
5145 41, 40, 21517, 41, 40, 29305, 41, 40, 36001,
5146 41, 40, 31069, 41, 40, 21172, 41, 40, 20195,
5147 41, 40, 21628, 41, 40, 23398, 41, 40, 30435,
5148 41, 40, 20225, 41, 40, 36039, 41, 40, 21332,
5149 41, 40, 31085, 41, 40, 20241, 41, 40, 33258,
5150 41, 40, 33267, 41, 21839, 24188, 25991, 31631, 80,
5151 84, 69, 50, 49, 50, 50, 50, 51, 50,
5152 52, 50, 53, 50, 54, 50, 55, 50, 56,
5153 50, 57, 51, 48, 51, 49, 51, 50, 51,
5154 51, 51, 52, 51, 53, 4352, 4354, 4355, 4357,
5155 4358, 4359, 4361, 4363, 4364, 4366, 4367, 4368, 4369,
5156 4370, 4352, 4449, 4354, 4449, 4355, 4449, 4357, 4449,
5157 4358, 4449, 4359, 4449, 4361, 4449, 4363, 4449, 4364,
5158 4449, 4366, 4449, 4367, 4449, 4368, 4449, 4369, 4449,
5159 4370, 4449, 4366, 4449, 4535, 4352, 4457, 4364, 4462,
5160 4363, 4468, 4363, 4462, 19968, 20108, 19977, 22235, 20116,
5161 20845, 19971, 20843, 20061, 21313, 26376, 28779, 27700, 26408,
5162 37329, 22303, 26085, 26666, 26377, 31038, 21517, 29305, 36001,
5163 31069, 21172, 31192, 30007, 22899, 36969, 20778, 21360, 27880,
5164 38917, 20241, 20889, 27491, 19978, 20013, 19979, 24038, 21491,
5165 21307, 23447, 23398, 30435, 20225, 36039, 21332, 22812, 51,
5166 54, 51, 55, 51, 56, 51, 57, 52, 48,
5167 52, 49, 52, 50, 52, 51, 52, 52, 52,
5168 53, 52, 54, 52, 55, 52, 56, 52, 57,
5169 53, 48, 49, 26376, 50, 26376, 51, 26376, 52,
5170 26376, 53, 26376, 54, 26376, 55, 26376, 56, 26376,
5171 57, 26376, 49, 48, 26376, 49, 49, 26376, 49,
5172 50, 26376, 72, 103, 101, 114, 103, 101, 86,
5173 76, 84, 68, 12450, 12452, 12454, 12456, 12458, 12459,
5174 12461, 12463, 12465, 12467, 12469, 12471, 12473, 12475, 12477,
5175 12479, 12481, 12484, 12486, 12488, 12490, 12491, 12492, 12493,
5176 12494, 12495, 12498, 12501, 12504, 12507, 12510, 12511, 12512,
5177 12513, 12514, 12516, 12518, 12520, 12521, 12522, 12523, 12524,
5178 12525, 12527, 12528, 12529, 12530, 20196, 21644, 12450, 12495,
5179 12442, 12540, 12488, 12450, 12523, 12501, 12449, 12450, 12531,
5180 12504, 12442, 12450, 12450, 12540, 12523, 12452, 12491, 12531,
5181 12463, 12441, 12452, 12531, 12481, 12454, 12457, 12531, 12456,
5182 12473, 12463, 12540, 12488, 12441, 12456, 12540, 12459, 12540,
5183 12458, 12531, 12473, 12458, 12540, 12512, 12459, 12452, 12522,
5184 12459, 12521, 12483, 12488, 12459, 12525, 12522, 12540, 12459,
5185 12441, 12525, 12531, 12459, 12441, 12531, 12510, 12461, 12441,
5186 12459, 12441, 12461, 12441, 12491, 12540, 12461, 12517, 12522,
5187 12540, 12461, 12441, 12523, 12479, 12441, 12540, 12461, 12525,
5188 12461, 12525, 12463, 12441, 12521, 12512, 12461, 12525, 12513,
5189 12540, 12488, 12523, 12461, 12525, 12527, 12483, 12488, 12463,
5190 12441, 12521, 12512, 12463, 12441, 12521, 12512, 12488, 12531,
5191 12463, 12523, 12475, 12441, 12452, 12525, 12463, 12525, 12540,
5192 12493, 12465, 12540, 12473, 12467, 12523, 12490, 12467, 12540,
5193 12507, 12442, 12469, 12452, 12463, 12523, 12469, 12531, 12481,
5194 12540, 12512, 12471, 12522, 12531, 12463, 12441, 12475, 12531,
5195 12481, 12475, 12531, 12488, 12479, 12441, 12540, 12473, 12486,
5196 12441, 12471, 12488, 12441, 12523, 12488, 12531, 12490, 12494,
5197 12494, 12483, 12488, 12495, 12452, 12484, 12495, 12442, 12540,
5198 12475, 12531, 12488, 12495, 12442, 12540, 12484, 12495, 12441,
5199 12540, 12524, 12523, 12498, 12442, 12450, 12473, 12488, 12523,
5200 12498, 12442, 12463, 12523, 12498, 12442, 12467, 12498, 12441,
5201 12523, 12501, 12449, 12521, 12483, 12488, 12441, 12501, 12451,
5202 12540, 12488, 12501, 12441, 12483, 12471, 12455, 12523, 12501,
5203 12521, 12531, 12504, 12463, 12479, 12540, 12523, 12504, 12442,
5204 12477, 12504, 12442, 12491, 12498, 12504, 12523, 12484, 12504,
5205 12442, 12531, 12473, 12504, 12442, 12540, 12471, 12441, 12504,
5206 12441, 12540, 12479, 12507, 12442, 12452, 12531, 12488, 12507,
5207 12441, 12523, 12488, 12507, 12531, 12507, 12442, 12531, 12488,
5208 12441, 12507, 12540, 12523, 12507, 12540, 12531, 12510, 12452,
5209 12463, 12525, 12510, 12452, 12523, 12510, 12483, 12495, 12510,
5210 12523, 12463, 12510, 12531, 12471, 12519, 12531, 12511, 12463,
5211 12525, 12531, 12511, 12522, 12511, 12522, 12495, 12441, 12540,
5212 12523, 12513, 12459, 12441, 12513, 12459, 12441, 12488, 12531,
5213 12513, 12540, 12488, 12523, 12516, 12540, 12488, 12441, 12516,
5214 12540, 12523, 12518, 12450, 12531, 12522, 12483, 12488, 12523,
5215 12522, 12521, 12523, 12498, 12442, 12540, 12523, 12540, 12501,
5216 12441, 12523, 12524, 12512, 12524, 12531, 12488, 12465, 12441,
5217 12531, 12527, 12483, 12488, 48, 28857, 49, 28857, 50,
5218 28857, 51, 28857, 52, 28857, 53, 28857, 54, 28857,
5219 55, 28857, 56, 28857, 57, 28857, 49, 48, 28857,
5220 49, 49, 28857, 49, 50, 28857, 49, 51, 28857,
5221 49, 52, 28857, 49, 53, 28857, 49, 54, 28857,
5222 49, 55, 28857, 49, 56, 28857, 49, 57, 28857,
5223 50, 48, 28857, 50, 49, 28857, 50, 50, 28857,
5224 50, 51, 28857, 50, 52, 28857, 104, 80, 97,
5225 100, 97, 65, 85, 98, 97, 114, 111, 86,
5226 112, 99, 100, 109, 100, 109, 50, 100, 109,
5227 51, 73, 85, 24179, 25104, 26157, 21644, 22823, 27491,
5228 26126, 27835, 26666, 24335, 20250, 31038, 112, 65, 110,
5229 65, 956, 65, 109, 65, 107, 65, 75, 66,
5230 77, 66, 71, 66, 99, 97, 108, 107, 99,
5231 97, 108, 112, 70, 110, 70, 956, 70, 956,
5232 103, 109, 103, 107, 103, 72, 122, 107, 72,
5233 122, 77, 72, 122, 71, 72, 122, 84, 72,
5234 122, 956, 108, 109, 108, 100, 108, 107, 108,
5235 102, 109, 110, 109, 956, 109, 109, 109, 99,
5236 109, 107, 109, 109, 109, 50, 99, 109, 50,
5237 109, 50, 107, 109, 50, 109, 109, 51, 99,
5238 109, 51, 109, 51, 107, 109, 51, 109, 8725,
5239 115, 109, 8725, 115, 50, 80, 97, 107, 80,
5240 97, 77, 80, 97, 71, 80, 97, 114, 97,
5241 100, 114, 97, 100, 8725, 115, 114, 97, 100,
5242 8725, 115, 50, 112, 115, 110, 115, 956, 115,
5243 109, 115, 112, 86, 110, 86, 956, 86, 109,
5244 86, 107, 86, 77, 86, 112, 87, 110, 87,
5245 956, 87, 109, 87, 107, 87, 77, 87, 107,
5246 937, 77, 937, 97, 46, 109, 46, 66, 113,
5247 99, 99, 99, 100, 67, 8725, 107, 103, 67,
5248 111, 46, 100, 66, 71, 121, 104, 97, 72,
5249 80, 105, 110, 75, 75, 75, 77, 107, 116,
5250 108, 109, 108, 110, 108, 111, 103, 108, 120,
5251 109, 98, 109, 105, 108, 109, 111, 108, 80,
5252 72, 112, 46, 109, 46, 80, 80, 77, 80,
5253 82, 115, 114, 83, 118, 87, 98, 86, 8725,
5254 109, 65, 8725, 109, 49, 26085, 50, 26085, 51,
5255 26085, 52, 26085, 53, 26085, 54, 26085, 55, 26085,
5256 56, 26085, 57, 26085, 49, 48, 26085, 49, 49,
5257 26085, 49, 50, 26085, 49, 51, 26085, 49, 52,
5258 26085, 49, 53, 26085, 49, 54, 26085, 49, 55,
5259 26085, 49, 56, 26085, 49, 57, 26085, 50, 48,
5260 26085, 50, 49, 26085, 50, 50, 26085, 50, 51,
5261 26085, 50, 52, 26085, 50, 53, 26085, 50, 54,
5262 26085, 50, 55, 26085, 50, 56, 26085, 50, 57,
5263 26085, 51, 48, 26085, 51, 49, 26085, 103, 97,
5264 108, 1098, 1100, 42863, 67, 70, 81, 294, 339,
5265 42791, 43831, 619, 43858, 653, 35912, 26356, 36554, 36040,
5266 28369, 20018, 21477, 40860, 40860, 22865, 37329, 21895, 22856,
5267 25078, 30313, 32645, 34367, 34746, 35064, 37007, 27138, 27931,
5268 28889, 29662, 33853, 37226, 39409, 20098, 21365, 27396, 29211,
5269 34349, 40478, 23888, 28651, 34253, 35172, 25289, 33240, 34847,
5270 24266, 26391, 28010, 29436, 37070, 20358, 20919, 21214, 25796,
5271 27347, 29200, 30439, 32769, 34310, 34396, 36335, 38706, 39791,
5272 40442, 30860, 31103, 32160, 33737, 37636, 40575, 35542, 22751,
5273 24324, 31840, 32894, 29282, 30922, 36034, 38647, 22744, 23650,
5274 27155, 28122, 28431, 32047, 32311, 38475, 21202, 32907, 20956,
5275 20940, 31260, 32190, 33777, 38517, 35712, 25295, 27138, 35582,
5276 20025, 23527, 24594, 29575, 30064, 21271, 30971, 20415, 24489,
5277 19981, 27852, 25976, 32034, 21443, 22622, 30465, 33865, 35498,
5278 27578, 36784, 27784, 25342, 33509, 25504, 30053, 20142, 20841,
5279 20937, 26753, 31975, 33391, 35538, 37327, 21237, 21570, 22899,
5280 24300, 26053, 28670, 31018, 38317, 39530, 40599, 40654, 21147,
5281 26310, 27511, 36706, 24180, 24976, 25088, 25754, 28451, 29001,
5282 29833, 31178, 32244, 32879, 36646, 34030, 36899, 37706, 21015,
5283 21155, 21693, 28872, 35010, 35498, 24265, 24565, 25467, 27566,
5284 31806, 29557, 20196, 22265, 23527, 23994, 24604, 29618, 29801,
5285 32666, 32838, 37428, 38646, 38728, 38936, 20363, 31150, 37300,
5286 38584, 24801, 20102, 20698, 23534, 23615, 26009, 27138, 29134,
5287 30274, 34044, 36988, 40845, 26248, 38446, 21129, 26491, 26611,
5288 27969, 28316, 29705, 30041, 30827, 32016, 39006, 20845, 25134,
5289 38520, 20523, 23833, 28138, 36650, 24459, 24900, 26647, 29575,
5290 38534, 21033, 21519, 23653, 26131, 26446, 26792, 27877, 29702,
5291 30178, 32633, 35023, 35041, 37324, 38626, 21311, 28346, 21533,
5292 29136, 29848, 34298, 38563, 40023, 40607, 26519, 28107, 33256,
5293 31435, 31520, 31890, 29376, 28825, 35672, 20160, 33590, 21050,
5294 20999, 24230, 25299, 31958, 23429, 27934, 26292, 36667, 34892,
5295 38477, 35211, 24275, 20800, 21952, 22618, 26228, 20958, 29482,
5296 30410, 31036, 31070, 31077, 31119, 38742, 31934, 32701, 34322,
5297 35576, 36920, 37117, 39151, 39164, 39208, 40372, 37086, 38583,
5298 20398, 20711, 20813, 21193, 21220, 21329, 21917, 22022, 22120,
5299 22592, 22696, 23652, 23662, 24724, 24936, 24974, 25074, 25935,
5300 26082, 26257, 26757, 28023, 28186, 28450, 29038, 29227, 29730,
5301 30865, 31038, 31049, 31048, 31056, 31062, 31069, 31117, 31118,
5302 31296, 31361, 31680, 32244, 32265, 32321, 32626, 32773, 33261,
5303 33401, 33401, 33879, 35088, 35222, 35585, 35641, 36051, 36104,
5304 36790, 36920, 38627, 38911, 38971, 24693, 148206, 33304, 20006,
5305 20917, 20840, 20352, 20805, 20864, 21191, 21242, 21917, 21845,
5306 21913, 21986, 22618, 22707, 22852, 22868, 23138, 23336, 24274,
5307 24281, 24425, 24493, 24792, 24910, 24840, 24974, 24928, 25074,
5308 25140, 25540, 25628, 25682, 25942, 26228, 26391, 26395, 26454,
5309 27513, 27578, 27969, 28379, 28363, 28450, 28702, 29038, 30631,
5310 29237, 29359, 29482, 29809, 29958, 30011, 30237, 30239, 30410,
5311 30427, 30452, 30538, 30528, 30924, 31409, 31680, 31867, 32091,
5312 32244, 32574, 32773, 33618, 33775, 34681, 35137, 35206, 35222,
5313 35519, 35576, 35531, 35585, 35582, 35565, 35641, 35722, 36104,
5314 36664, 36978, 37273, 37494, 38524, 38627, 38742, 38875, 38911,
5315 38923, 38971, 39698, 40860, 141386, 141380, 144341, 15261, 16408,
5316 16441, 152137, 154832, 163539, 40771, 40846, 102, 102, 102,
5317 105, 102, 108, 102, 102, 105, 102, 102, 108,
5318 115, 116, 115, 116, 1396, 1398, 1396, 1381, 1396,
5319 1387, 1406, 1398, 1396, 1389, 1497, 1460, 1522, 1463,
5320 1506, 1488, 1491, 1492, 1499, 1500, 1501, 1512, 1514,
5321 43, 1513, 1473, 1513, 1474, 1513, 1468, 1473, 1513,
5322 1468, 1474, 1488, 1463, 1488, 1464, 1488, 1468, 1489,
5323 1468, 1490, 1468, 1491, 1468, 1492, 1468, 1493, 1468,
5324 1494, 1468, 1496, 1468, 1497, 1468, 1498, 1468, 1499,
5325 1468, 1500, 1468, 1502, 1468, 1504, 1468, 1505, 1468,
5326 1507, 1468, 1508, 1468, 1510, 1468, 1511, 1468, 1512,
5327 1468, 1513, 1468, 1514, 1468, 1493, 1465, 1489, 1471,
5328 1499, 1471, 1508, 1471, 1488, 1500, 1649, 1649, 1659,
5329 1659, 1659, 1659, 1662, 1662, 1662, 1662, 1664, 1664,
5330 1664, 1664, 1658, 1658, 1658, 1658, 1663, 1663, 1663,
5331 1663, 1657, 1657, 1657, 1657, 1700, 1700, 1700, 1700,
5332 1702, 1702, 1702, 1702, 1668, 1668, 1668, 1668, 1667,
5333 1667, 1667, 1667, 1670, 1670, 1670, 1670, 1671, 1671,
5334 1671, 1671, 1677, 1677, 1676, 1676, 1678, 1678, 1672,
5335 1672, 1688, 1688, 1681, 1681, 1705, 1705, 1705, 1705,
5336 1711, 1711, 1711, 1711, 1715, 1715, 1715, 1715, 1713,
5337 1713, 1713, 1713, 1722, 1722, 1723, 1723, 1723, 1723,
5338 1749, 1620, 1749, 1620, 1729, 1729, 1729, 1729, 1726,
5339 1726, 1726, 1726, 1746, 1746, 1746, 1620, 1746, 1620,
5340 1709, 1709, 1709, 1709, 1735, 1735, 1734, 1734, 1736,
5341 1736, 1735, 1652, 1739, 1739, 1733, 1733, 1737, 1737,
5342 1744, 1744, 1744, 1744, 1609, 1609, 1610, 1620, 1575,
5343 1610, 1620, 1575, 1610, 1620, 1749, 1610, 1620, 1749,
5344 1610, 1620, 1608, 1610, 1620, 1608, 1610, 1620, 1735,
5345 1610, 1620, 1735, 1610, 1620, 1734, 1610, 1620, 1734,
5346 1610, 1620, 1736, 1610, 1620, 1736, 1610, 1620, 1744,
5347 1610, 1620, 1744, 1610, 1620, 1744, 1610, 1620, 1609,
5348 1610, 1620, 1609, 1610, 1620, 1609, 1740, 1740, 1740,
5349 1740, 1610, 1620, 1580, 1610, 1620, 1581, 1610, 1620,
5350 1605, 1610, 1620, 1609, 1610, 1620, 1610, 1576, 1580,
5351 1576, 1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576,
5352 1610, 1578, 1580, 1578, 1581, 1578, 1582, 1578, 1605,
5353 1578, 1609, 1578, 1610, 1579, 1580, 1579, 1605, 1579,
5354 1609, 1579, 1610, 1580, 1581, 1580, 1605, 1581, 1580,
5355 1581, 1605, 1582, 1580, 1582, 1581, 1582, 1605, 1587,
5356 1580, 1587, 1581, 1587, 1582, 1587, 1605, 1589, 1581,
5357 1589, 1605, 1590, 1580, 1590, 1581, 1590, 1582, 1590,
5358 1605, 1591, 1581, 1591, 1605, 1592, 1605, 1593, 1580,
5359 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601,
5360 1581, 1601, 1582, 1601, 1605, 1601, 1609, 1601, 1610,
5361 1602, 1581, 1602, 1605, 1602, 1609, 1602, 1610, 1603,
5362 1575, 1603, 1580, 1603, 1581, 1603, 1582, 1603, 1604,
5363 1603, 1605, 1603, 1609, 1603, 1610, 1604, 1580, 1604,
5364 1581, 1604, 1582, 1604, 1605, 1604, 1609, 1604, 1610,
5365 1605, 1580, 1605, 1581, 1605, 1582, 1605, 1605, 1605,
5366 1609, 1605, 1610, 1606, 1580, 1606, 1581, 1606, 1582,
5367 1606, 1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607,
5368 1605, 1607, 1609, 1607, 1610, 1610, 1580, 1610, 1581,
5369 1610, 1582, 1610, 1605, 1610, 1609, 1610, 1610, 1584,
5370 1648, 1585, 1648, 1609, 1648, 32, 1612, 1617, 32,
5371 1613, 1617, 32, 1614, 1617, 32, 1615, 1617, 32,
5372 1616, 1617, 32, 1617, 1648, 1610, 1620, 1585, 1610,
5373 1620, 1586, 1610, 1620, 1605, 1610, 1620, 1606, 1610,
5374 1620, 1609, 1610, 1620, 1610, 1576, 1585, 1576, 1586,
5375 1576, 1605, 1576, 1606, 1576, 1609, 1576, 1610, 1578,
5376 1585, 1578, 1586, 1578, 1605, 1578, 1606, 1578, 1609,
5377 1578, 1610, 1579, 1585, 1579, 1586, 1579, 1605, 1579,
5378 1606, 1579, 1609, 1579, 1610, 1601, 1609, 1601, 1610,
5379 1602, 1609, 1602, 1610, 1603, 1575, 1603, 1604, 1603,
5380 1605, 1603, 1609, 1603, 1610, 1604, 1605, 1604, 1609,
5381 1604, 1610, 1605, 1575, 1605, 1605, 1606, 1585, 1606,
5382 1586, 1606, 1605, 1606, 1606, 1606, 1609, 1606, 1610,
5383 1609, 1648, 1610, 1585, 1610, 1586, 1610, 1605, 1610,
5384 1606, 1610, 1609, 1610, 1610, 1610, 1620, 1580, 1610,
5385 1620, 1581, 1610, 1620, 1582, 1610, 1620, 1605, 1610,
5386 1620, 1607, 1576, 1580, 1576, 1581, 1576, 1582, 1576,
5387 1605, 1576, 1607, 1578, 1580, 1578, 1581, 1578, 1582,
5388 1578, 1605, 1578, 1607, 1579, 1605, 1580, 1581, 1580,
5389 1605, 1581, 1580, 1581, 1605, 1582, 1580, 1582, 1605,
5390 1587, 1580, 1587, 1581, 1587, 1582, 1587, 1605, 1589,
5391 1581, 1589, 1582, 1589, 1605, 1590, 1580, 1590, 1581,
5392 1590, 1582, 1590, 1605, 1591, 1581, 1592, 1605, 1593,
5393 1580, 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580,
5394 1601, 1581, 1601, 1582, 1601, 1605, 1602, 1581, 1602,
5395 1605, 1603, 1580, 1603, 1581, 1603, 1582, 1603, 1604,
5396 1603, 1605, 1604, 1580, 1604, 1581, 1604, 1582, 1604,
5397 1605, 1604, 1607, 1605, 1580, 1605, 1581, 1605, 1582,
5398 1605, 1605, 1606, 1580, 1606, 1581, 1606, 1582, 1606,
5399 1605, 1606, 1607, 1607, 1580, 1607, 1605, 1607, 1648,
5400 1610, 1580, 1610, 1581, 1610, 1582, 1610, 1605, 1610,
5401 1607, 1610, 1620, 1605, 1610, 1620, 1607, 1576, 1605,
5402 1576, 1607, 1578, 1605, 1578, 1607, 1579, 1605, 1579,
5403 1607, 1587, 1605, 1587, 1607, 1588, 1605, 1588, 1607,
5404 1603, 1604, 1603, 1605, 1604, 1605, 1606, 1605, 1606,
5405 1607, 1610, 1605, 1610, 1607, 1600, 1614, 1617, 1600,
5406 1615, 1617, 1600, 1616, 1617, 1591, 1609, 1591, 1610,
5407 1593, 1609, 1593, 1610, 1594, 1609, 1594, 1610, 1587,
5408 1609, 1587, 1610, 1588, 1609, 1588, 1610, 1581, 1609,
5409 1581, 1610, 1580, 1609, 1580, 1610, 1582, 1609, 1582,
5410 1610, 1589, 1609, 1589, 1610, 1590, 1609, 1590, 1610,
5411 1588, 1580, 1588, 1581, 1588, 1582, 1588, 1605, 1588,
5412 1585, 1587, 1585, 1589, 1585, 1590, 1585, 1591, 1609,
5413 1591, 1610, 1593, 1609, 1593, 1610, 1594, 1609, 1594,
5414 1610, 1587, 1609, 1587, 1610, 1588, 1609, 1588, 1610,
5415 1581, 1609, 1581, 1610, 1580, 1609, 1580, 1610, 1582,
5416 1609, 1582, 1610, 1589, 1609, 1589, 1610, 1590, 1609,
5417 1590, 1610, 1588, 1580, 1588, 1581, 1588, 1582, 1588,
5418 1605, 1588, 1585, 1587, 1585, 1589, 1585, 1590, 1585,
5419 1588, 1580, 1588, 1581, 1588, 1582, 1588, 1605, 1587,
5420 1607, 1588, 1607, 1591, 1605, 1587, 1580, 1587, 1581,
5421 1587, 1582, 1588, 1580, 1588, 1581, 1588, 1582, 1591,
5422 1605, 1592, 1605, 1575, 1611, 1575, 1611, 1578, 1580,
5423 1605, 1578, 1581, 1580, 1578, 1581, 1580, 1578, 1581,
5424 1605, 1578, 1582, 1605, 1578, 1605, 1580, 1578, 1605,
5425 1581, 1578, 1605, 1582, 1580, 1605, 1581, 1580, 1605,
5426 1581, 1581, 1605, 1610, 1581, 1605, 1609, 1587, 1581,
5427 1580, 1587, 1580, 1581, 1587, 1580, 1609, 1587, 1605,
5428 1581, 1587, 1605, 1581, 1587, 1605, 1580, 1587, 1605,
5429 1605, 1587, 1605, 1605, 1589, 1581, 1581, 1589, 1581,
5430 1581, 1589, 1605, 1605, 1588, 1581, 1605, 1588, 1581,
5431 1605, 1588, 1580, 1610, 1588, 1605, 1582, 1588, 1605,
5432 1582, 1588, 1605, 1605, 1588, 1605, 1605, 1590, 1581,
5433 1609, 1590, 1582, 1605, 1590, 1582, 1605, 1591, 1605,
5434 1581, 1591, 1605, 1581, 1591, 1605, 1605, 1591, 1605,
5435 1610, 1593, 1580, 1605, 1593, 1605, 1605, 1593, 1605,
5436 1605, 1593, 1605, 1609, 1594, 1605, 1605, 1594, 1605,
5437 1610, 1594, 1605, 1609, 1601, 1582, 1605, 1601, 1582,
5438 1605, 1602, 1605, 1581, 1602, 1605, 1605, 1604, 1581,
5439 1605, 1604, 1581, 1610, 1604, 1581, 1609, 1604, 1580,
5440 1580, 1604, 1580, 1580, 1604, 1582, 1605, 1604, 1582,
5441 1605, 1604, 1605, 1581, 1604, 1605, 1581, 1605, 1581,
5442 1580, 1605, 1581, 1605, 1605, 1581, 1610, 1605, 1580,
5443 1581, 1605, 1580, 1605, 1605, 1582, 1580, 1605, 1582,
5444 1605, 1605, 1580, 1582, 1607, 1605, 1580, 1607, 1605,
5445 1605, 1606, 1581, 1605, 1606, 1581, 1609, 1606, 1580,
5446 1605, 1606, 1580, 1605, 1606, 1580, 1609, 1606, 1605,
5447 1610, 1606, 1605, 1609, 1610, 1605, 1605, 1610, 1605,
5448 1605, 1576, 1582, 1610, 1578, 1580, 1610, 1578, 1580,
5449 1609, 1578, 1582, 1610, 1578, 1582, 1609, 1578, 1605,
5450 1610, 1578, 1605, 1609, 1580, 1605, 1610, 1580, 1581,
5451 1609, 1580, 1605, 1609, 1587, 1582, 1609, 1589, 1581,
5452 1610, 1588, 1581, 1610, 1590, 1581, 1610, 1604, 1580,
5453 1610, 1604, 1605, 1610, 1610, 1581, 1610, 1610, 1580,
5454 1610, 1610, 1605, 1610, 1605, 1605, 1610, 1602, 1605,
5455 1610, 1606, 1581, 1610, 1602, 1605, 1581, 1604, 1581,
5456 1605, 1593, 1605, 1610, 1603, 1605, 1610, 1606, 1580,
5457 1581, 1605, 1582, 1610, 1604, 1580, 1605, 1603, 1605,
5458 1605, 1604, 1580, 1605, 1606, 1580, 1581, 1580, 1581,
5459 1610, 1581, 1580, 1610, 1605, 1580, 1610, 1601, 1605,
5460 1610, 1576, 1581, 1610, 1603, 1605, 1605, 1593, 1580,
5461 1605, 1589, 1605, 1605, 1587, 1582, 1610, 1606, 1580,
5462 1610, 1589, 1604, 1746, 1602, 1604, 1746, 1575, 1604,
5463 1604, 1607, 1575, 1603, 1576, 1585, 1605, 1581, 1605,
5464 1583, 1589, 1604, 1593, 1605, 1585, 1587, 1608, 1604,
5465 1593, 1604, 1610, 1607, 1608, 1587, 1604, 1605, 1589,
5466 1604, 1609, 1589, 1604, 1609, 32, 1575, 1604, 1604,
5467 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587,
5468 1604, 1605, 1580, 1604, 32, 1580, 1604, 1575, 1604,
5469 1607, 1585, 1740, 1575, 1604, 44, 12289, 12290, 58,
5470 59, 33, 63, 12310, 12311, 46, 46, 46, 46,
5471 46, 8212, 8211, 95, 95, 40, 41, 123, 125,
5472 12308, 12309, 12304, 12305, 12298, 12299, 12296, 12297, 12300,
5473 12301, 12302, 12303, 91, 93, 32, 773, 32, 773,
5474 32, 773, 32, 773, 95, 95, 95, 44, 12289,
5475 46, 59, 58, 63, 33, 8212, 40, 41, 123,
5476 125, 12308, 12309, 35, 38, 42, 43, 45, 60,
5477 62, 61, 92, 36, 37, 64, 32, 1611, 1600,
5478 1611, 32, 1612, 32, 1613, 32, 1614, 1600, 1614,
5479 32, 1615, 1600, 1615, 32, 1616, 1600, 1616, 32,
5480 1617, 1600, 1617, 32, 1618, 1600, 1618, 1569, 1575,
5481 1619, 1575, 1619, 1575, 1620, 1575, 1620, 1608, 1620,
5482 1608, 1620, 1575, 1621, 1575, 1621, 1610, 1620, 1610,
5483 1620, 1610, 1620, 1610, 1620, 1575, 1575, 1576, 1576,
5484 1576, 1576, 1577, 1577, 1578, 1578, 1578, 1578, 1579,
5485 1579, 1579, 1579, 1580, 1580, 1580, 1580, 1581, 1581,
5486 1581, 1581, 1582, 1582, 1582, 1582, 1583, 1583, 1584,
5487 1584, 1585, 1585, 1586, 1586, 1587, 1587, 1587, 1587,
5488 1588, 1588, 1588, 1588, 1589, 1589, 1589, 1589, 1590,
5489 1590, 1590, 1590, 1591, 1591, 1591, 1591, 1592, 1592,
5490 1592, 1592, 1593, 1593, 1593, 1593, 1594, 1594, 1594,
5491 1594, 1601, 1601, 1601, 1601, 1602, 1602, 1602, 1602,
5492 1603, 1603, 1603, 1603, 1604, 1604, 1604, 1604, 1605,
5493 1605, 1605, 1605, 1606, 1606, 1606, 1606, 1607, 1607,
5494 1607, 1607, 1608, 1608, 1609, 1609, 1610, 1610, 1610,
5495 1610, 1604, 1575, 1619, 1604, 1575, 1619, 1604, 1575,
5496 1620, 1604, 1575, 1620, 1604, 1575, 1621, 1604, 1575,
5497 1621, 1604, 1575, 1604, 1575, 33, 34, 35, 36,
5498 37, 38, 39, 40, 41, 42, 43, 44, 45,
5499 46, 47, 48, 49, 50, 51, 52, 53, 54,
5500 55, 56, 57, 58, 59, 60, 61, 62, 63,
5501 64, 65, 66, 67, 68, 69, 70, 71, 72,
5502 73, 74, 75, 76, 77, 78, 79, 80, 81,
5503 82, 83, 84, 85, 86, 87, 88, 89, 90,
5504 91, 92, 93, 94, 95, 96, 97, 98, 99,
5505 100, 101, 102, 103, 104, 105, 106, 107, 108,
5506 109, 110, 111, 112, 113, 114, 115, 116, 117,
5507 118, 119, 120, 121, 122, 123, 124, 125, 126,
5508 10629, 10630, 12290, 12300, 12301, 12289, 12539, 12530, 12449,
5509 12451, 12453, 12455, 12457, 12515, 12517, 12519, 12483, 12540,
5510 12450, 12452, 12454, 12456, 12458, 12459, 12461, 12463, 12465,
5511 12467, 12469, 12471, 12473, 12475, 12477, 12479, 12481, 12484,
5512 12486, 12488, 12490, 12491, 12492, 12493, 12494, 12495, 12498,
5513 12501, 12504, 12507, 12510, 12511, 12512, 12513, 12514, 12516,
5514 12518, 12520, 12521, 12522, 12523, 12524, 12525, 12527, 12531,
5515 12441, 12442, 4448, 4352, 4353, 4522, 4354, 4524, 4525,
5516 4355, 4356, 4357, 4528, 4529, 4530, 4531, 4532, 4533,
5517 4378, 4358, 4359, 4360, 4385, 4361, 4362, 4363, 4364,
5518 4365, 4366, 4367, 4368, 4369, 4370, 4449, 4450, 4451,
5519 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460,
5520 4461, 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469,
5521 162, 163, 172, 32, 772, 166, 165, 8361, 9474,
5522 8592, 8593, 8594, 8595, 9632, 9675, 720, 721, 230,
5523 665, 595, 675, 43878, 677, 676, 598, 599, 7569,
5524 600, 606, 681, 612, 610, 608, 667, 295, 668,
5525 615, 644, 682, 683, 620, 122628, 42894, 622, 122629,
5526 654, 122630, 248, 630, 631, 113, 634, 122632, 637,
5527 638, 640, 680, 678, 43879, 679, 648, 11377, 655,
5528 673, 674, 664, 448, 449, 450, 122634, 122654, 69785,
5529 69818, 69787, 69818, 69797, 69818, 69937, 69927, 69938, 69927,
5530 70471, 70462, 70471, 70487, 70841, 70842, 70841, 70832, 70841,
5531 70845, 71096, 71087, 71097, 71087, 71989, 71984, 119127, 119141,
5532 119128, 119141, 119128, 119141, 119150, 119128, 119141, 119151, 119128,
5533 119141, 119152, 119128, 119141, 119153, 119128, 119141, 119154, 119225,
5534 119141, 119226, 119141, 119225, 119141, 119150, 119226, 119141, 119150,
5535 119225, 119141, 119151, 119226, 119141, 119151, 65, 66, 67,
5536 68, 69, 70, 71, 72, 73, 74, 75, 76,
5537 77, 78, 79, 80, 81, 82, 83, 84, 85,
5538 86, 87, 88, 89, 90, 97, 98, 99, 100,
5539 101, 102, 103, 104, 105, 106, 107, 108, 109,
5540 110, 111, 112, 113, 114, 115, 116, 117, 118,
5541 119, 120, 121, 122, 65, 66, 67, 68, 69,
5542 70, 71, 72, 73, 74, 75, 76, 77, 78,
5543 79, 80, 81, 82, 83, 84, 85, 86, 87,
5544 88, 89, 90, 97, 98, 99, 100, 101, 102,
5545 103, 105, 106, 107, 108, 109, 110, 111, 112,
5546 113, 114, 115, 116, 117, 118, 119, 120, 121,
5547 122, 65, 66, 67, 68, 69, 70, 71, 72,
5548 73, 74, 75, 76, 77, 78, 79, 80, 81,
5549 82, 83, 84, 85, 86, 87, 88, 89, 90,
5550 97, 98, 99, 100, 101, 102, 103, 104, 105,
5551 106, 107, 108, 109, 110, 111, 112, 113, 114,
5552 115, 116, 117, 118, 119, 120, 121, 122, 65,
5553 67, 68, 71, 74, 75, 78, 79, 80, 81,
5554 83, 84, 85, 86, 87, 88, 89, 90, 97,
5555 98, 99, 100, 102, 104, 105, 106, 107, 108,
5556 109, 110, 112, 113, 114, 115, 116, 117, 118,
5557 119, 120, 121, 122, 65, 66, 67, 68, 69,
5558 70, 71, 72, 73, 74, 75, 76, 77, 78,
5559 79, 80, 81, 82, 83, 84, 85, 86, 87,
5560 88, 89, 90, 97, 98, 99, 100, 101, 102,
5561 103, 104, 105, 106, 107, 108, 109, 110, 111,
5562 112, 113, 114, 115, 116, 117, 118, 119, 120,
5563 121, 122, 65, 66, 68, 69, 70, 71, 74,
5564 75, 76, 77, 78, 79, 80, 81, 83, 84,
5565 85, 86, 87, 88, 89, 97, 98, 99, 100,
5566 101, 102, 103, 104, 105, 106, 107, 108, 109,
5567 110, 111, 112, 113, 114, 115, 116, 117, 118,
5568 119, 120, 121, 122, 65, 66, 68, 69, 70,
5569 71, 73, 74, 75, 76, 77, 79, 83, 84,
5570 85, 86, 87, 88, 89, 97, 98, 99, 100,
5571 101, 102, 103, 104, 105, 106, 107, 108, 109,
5572 110, 111, 112, 113, 114, 115, 116, 117, 118,
5573 119, 120, 121, 122, 65, 66, 67, 68, 69,
5574 70, 71, 72, 73, 74, 75, 76, 77, 78,
5575 79, 80, 81, 82, 83, 84, 85, 86, 87,
5576 88, 89, 90, 97, 98, 99, 100, 101, 102,
5577 103, 104, 105, 106, 107, 108, 109, 110, 111,
5578 112, 113, 114, 115, 116, 117, 118, 119, 120,
5579 121, 122, 65, 66, 67, 68, 69, 70, 71,
5580 72, 73, 74, 75, 76, 77, 78, 79, 80,
5581 81, 82, 83, 84, 85, 86, 87, 88, 89,
5582 90, 97, 98, 99, 100, 101, 102, 103, 104,
5583 105, 106, 107, 108, 109, 110, 111, 112, 113,
5584 114, 115, 116, 117, 118, 119, 120, 121, 122,
5585 65, 66, 67, 68, 69, 70, 71, 72, 73,
5586 74, 75, 76, 77, 78, 79, 80, 81, 82,
5587 83, 84, 85, 86, 87, 88, 89, 90, 97,
5588 98, 99, 100, 101, 102, 103, 104, 105, 106,
5589 107, 108, 109, 110, 111, 112, 113, 114, 115,
5590 116, 117, 118, 119, 120, 121, 122, 65, 66,
5591 67, 68, 69, 70, 71, 72, 73, 74, 75,
5592 76, 77, 78, 79, 80, 81, 82, 83, 84,
5593 85, 86, 87, 88, 89, 90, 97, 98, 99,
5594 100, 101, 102, 103, 104, 105, 106, 107, 108,
5595 109, 110, 111, 112, 113, 114, 115, 116, 117,
5596 118, 119, 120, 121, 122, 65, 66, 67, 68,
5597 69, 70, 71, 72, 73, 74, 75, 76, 77,
5598 78, 79, 80, 81, 82, 83, 84, 85, 86,
5599 87, 88, 89, 90, 97, 98, 99, 100, 101,
5600 102, 103, 104, 105, 106, 107, 108, 109, 110,
5601 111, 112, 113, 114, 115, 116, 117, 118, 119,
5602 120, 121, 122, 65, 66, 67, 68, 69, 70,
5603 71, 72, 73, 74, 75, 76, 77, 78, 79,
5604 80, 81, 82, 83, 84, 85, 86, 87, 88,
5605 89, 90, 97, 98, 99, 100, 101, 102, 103,
5606 104, 105, 106, 107, 108, 109, 110, 111, 112,
5607 113, 114, 115, 116, 117, 118, 119, 120, 121,
5608 122, 305, 567, 913, 914, 915, 916, 917, 918,
5609 919, 920, 921, 922, 923, 924, 925, 926, 927,
5610 928, 929, 920, 931, 932, 933, 934, 935, 936,
5611 937, 8711, 945, 946, 947, 948, 949, 950, 951,
5612 952, 953, 954, 955, 956, 957, 958, 959, 960,
5613 961, 962, 963, 964, 965, 966, 967, 968, 969,
5614 8706, 949, 952, 954, 966, 961, 960, 913, 914,
5615 915, 916, 917, 918, 919, 920, 921, 922, 923,
5616 924, 925, 926, 927, 928, 929, 920, 931, 932,
5617 933, 934, 935, 936, 937, 8711, 945, 946, 947,
5618 948, 949, 950, 951, 952, 953, 954, 955, 956,
5619 957, 958, 959, 960, 961, 962, 963, 964, 965,
5620 966, 967, 968, 969, 8706, 949, 952, 954, 966,
5621 961, 960, 913, 914, 915, 916, 917, 918, 919,
5622 920, 921, 922, 923, 924, 925, 926, 927, 928,
5623 929, 920, 931, 932, 933, 934, 935, 936, 937,
5624 8711, 945, 946, 947, 948, 949, 950, 951, 952,
5625 953, 954, 955, 956, 957, 958, 959, 960, 961,
5626 962, 963, 964, 965, 966, 967, 968, 969, 8706,
5627 949, 952, 954, 966, 961, 960, 913, 914, 915,
5628 916, 917, 918, 919, 920, 921, 922, 923, 924,
5629 925, 926, 927, 928, 929, 920, 931, 932, 933,
5630 934, 935, 936, 937, 8711, 945, 946, 947, 948,
5631 949, 950, 951, 952, 953, 954, 955, 956, 957,
5632 958, 959, 960, 961, 962, 963, 964, 965, 966,
5633 967, 968, 969, 8706, 949, 952, 954, 966, 961,
5634 960, 913, 914, 915, 916, 917, 918, 919, 920,
5635 921, 922, 923, 924, 925, 926, 927, 928, 929,
5636 920, 931, 932, 933, 934, 935, 936, 937, 8711,
5637 945, 946, 947, 948, 949, 950, 951, 952, 953,
5638 954, 955, 956, 957, 958, 959, 960, 961, 962,
5639 963, 964, 965, 966, 967, 968, 969, 8706, 949,
5640 952, 954, 966, 961, 960, 988, 989, 48, 49,
5641 50, 51, 52, 53, 54, 55, 56, 57, 48,
5642 49, 50, 51, 52, 53, 54, 55, 56, 57,
5643 48, 49, 50, 51, 52, 53, 54, 55, 56,
5644 57, 48, 49, 50, 51, 52, 53, 54, 55,
5645 56, 57, 48, 49, 50, 51, 52, 53, 54,
5646 55, 56, 57, 1072, 1073, 1074, 1075, 1076, 1077,
5647 1078, 1079, 1080, 1082, 1083, 1084, 1086, 1087, 1088,
5648 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1099,
5649 1101, 1102, 42633, 1241, 1110, 1112, 1257, 1199, 1231,
5650 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080,
5651 1082, 1083, 1086, 1087, 1089, 1091, 1092, 1093, 1094,
5652 1095, 1096, 1098, 1099, 1169, 1110, 1109, 1119, 1195,
5653 42577, 1201, 1575, 1576, 1580, 1583, 1608, 1586, 1581,
5654 1591, 1610, 1603, 1604, 1605, 1606, 1587, 1593, 1601,
5655 1589, 1602, 1585, 1588, 1578, 1579, 1582, 1584, 1590,
5656 1592, 1594, 1646, 1722, 1697, 1647, 1576, 1580, 1607,
5657 1581, 1610, 1603, 1604, 1605, 1606, 1587, 1593, 1601,
5658 1589, 1602, 1588, 1578, 1579, 1582, 1590, 1594, 1580,
5659 1581, 1610, 1604, 1606, 1587, 1593, 1589, 1602, 1588,
5660 1582, 1590, 1594, 1722, 1647, 1576, 1580, 1607, 1581,
5661 1591, 1610, 1603, 1605, 1606, 1587, 1593, 1601, 1589,
5662 1602, 1588, 1578, 1579, 1582, 1590, 1592, 1594, 1646,
5663 1697, 1575, 1576, 1580, 1583, 1607, 1608, 1586, 1581,
5664 1591, 1610, 1604, 1605, 1606, 1587, 1593, 1601, 1589,
5665 1602, 1585, 1588, 1578, 1579, 1582, 1584, 1590, 1592,
5666 1594, 1576, 1580, 1583, 1608, 1586, 1581, 1591, 1610,
5667 1604, 1605, 1606, 1587, 1593, 1601, 1589, 1602, 1585,
5668 1588, 1578, 1579, 1582, 1584, 1590, 1592, 1594, 48,
5669 46, 48, 44, 49, 44, 50, 44, 51, 44,
5670 52, 44, 53, 44, 54, 44, 55, 44, 56,
5671 44, 57, 44, 40, 65, 41, 40, 66, 41,
5672 40, 67, 41, 40, 68, 41, 40, 69, 41,
5673 40, 70, 41, 40, 71, 41, 40, 72, 41,
5674 40, 73, 41, 40, 74, 41, 40, 75, 41,
5675 40, 76, 41, 40, 77, 41, 40, 78, 41,
5676 40, 79, 41, 40, 80, 41, 40, 81, 41,
5677 40, 82, 41, 40, 83, 41, 40, 84, 41,
5678 40, 85, 41, 40, 86, 41, 40, 87, 41,
5679 40, 88, 41, 40, 89, 41, 40, 90, 41,
5680 12308, 83, 12309, 67, 82, 67, 68, 87, 90,
5681 65, 66, 67, 68, 69, 70, 71, 72, 73,
5682 74, 75, 76, 77, 78, 79, 80, 81, 82,
5683 83, 84, 85, 86, 87, 88, 89, 90, 72,
5684 86, 77, 86, 83, 68, 83, 83, 80, 80,
5685 86, 87, 67, 77, 67, 77, 68, 77, 82,
5686 68, 74, 12411, 12363, 12467, 12467, 12469, 25163, 23383,
5687 21452, 12486, 12441, 20108, 22810, 35299, 22825, 20132, 26144,
5688 28961, 26009, 21069, 24460, 20877, 26032, 21021, 32066, 29983,
5689 36009, 22768, 21561, 28436, 25237, 25429, 19968, 19977, 36938,
5690 24038, 20013, 21491, 25351, 36208, 25171, 31105, 31354, 21512,
5691 28288, 26377, 26376, 30003, 21106, 21942, 37197, 12308, 26412,
5692 12309, 12308, 19977, 12309, 12308, 20108, 12309, 12308, 23433,
5693 12309, 12308, 28857, 12309, 12308, 25171, 12309, 12308, 30423,
5694 12309, 12308, 21213, 12309, 12308, 25943, 12309, 24471, 21487,
5695 48, 49, 50, 51, 52, 53, 54, 55, 56,
5696 57, 20029, 20024, 20033, 131362, 20320, 20398, 20411, 20482,
5697 20602, 20633, 20711, 20687, 13470, 132666, 20813, 20820, 20836,
5698 20855, 132380, 13497, 20839, 20877, 132427, 20887, 20900, 20172,
5699 20908, 20917, 168415, 20981, 20995, 13535, 21051, 21062, 21106,
5700 21111, 13589, 21191, 21193, 21220, 21242, 21253, 21254, 21271,
5701 21321, 21329, 21338, 21363, 21373, 21375, 21375, 21375, 133676,
5702 28784, 21450, 21471, 133987, 21483, 21489, 21510, 21662, 21560,
5703 21576, 21608, 21666, 21750, 21776, 21843, 21859, 21892, 21892,
5704 21913, 21931, 21939, 21954, 22294, 22022, 22295, 22097, 22132,
5705 20999, 22766, 22478, 22516, 22541, 22411, 22578, 22577, 22700,
5706 136420, 22770, 22775, 22790, 22810, 22818, 22882, 136872, 136938,
5707 23020, 23067, 23079, 23000, 23142, 14062, 14076, 23304, 23358,
5708 23358, 137672, 23491, 23512, 23527, 23539, 138008, 23551, 23558,
5709 24403, 23586, 14209, 23648, 23662, 23744, 23693, 138724, 23875,
5710 138726, 23918, 23915, 23932, 24033, 24034, 14383, 24061, 24104,
5711 24125, 24169, 14434, 139651, 14460, 24240, 24243, 24246, 24266,
5712 172946, 24318, 140081, 140081, 33281, 24354, 24354, 14535, 144056,
5713 156122, 24418, 24427, 14563, 24474, 24525, 24535, 24569, 24705,
5714 14650, 14620, 24724, 141012, 24775, 24904, 24908, 24910, 24908,
5715 24954, 24974, 25010, 24996, 25007, 25054, 25074, 25078, 25104,
5716 25115, 25181, 25265, 25300, 25424, 142092, 25405, 25340, 25448,
5717 25475, 25572, 142321, 25634, 25541, 25513, 14894, 25705, 25726,
5718 25757, 25719, 14956, 25935, 25964, 143370, 26083, 26360, 26185,
5719 15129, 26257, 15112, 15076, 20882, 20885, 26368, 26268, 32941,
5720 17369, 26391, 26395, 26401, 26462, 26451, 144323, 15177, 26618,
5721 26501, 26706, 26757, 144493, 26766, 26655, 26900, 15261, 26946,
5722 27043, 27114, 27304, 145059, 27355, 15384, 27425, 145575, 27476,
5723 15438, 27506, 27551, 27578, 27579, 146061, 138507, 146170, 27726,
5724 146620, 27839, 27853, 27751, 27926, 27966, 28023, 27969, 28009,
5725 28024, 28037, 146718, 27956, 28207, 28270, 15667, 28363, 28359,
5726 147153, 28153, 28526, 147294, 147342, 28614, 28729, 28702, 28699,
5727 15766, 28746, 28797, 28791, 28845, 132389, 28997, 148067, 29084,
5728 148395, 29224, 29237, 29264, 149000, 29312, 29333, 149301, 149524,
5729 29562, 29579, 16044, 29605, 16056, 16056, 29767, 29788, 29809,
5730 29829, 29898, 16155, 29988, 150582, 30014, 150674, 30064, 139679,
5731 30224, 151457, 151480, 151620, 16380, 16392, 30452, 151795, 151794,
5732 151833, 151859, 30494, 30495, 30495, 30538, 16441, 30603, 16454,
5733 16534, 152605, 30798, 30860, 30924, 16611, 153126, 31062, 153242,
5734 153285, 31119, 31211, 16687, 31296, 31306, 31311, 153980, 154279,
5735 154279, 31470, 16898, 154539, 31686, 31689, 16935, 154752, 31954,
5736 17056, 31976, 31971, 32000, 155526, 32099, 17153, 32199, 32258,
5737 32325, 17204, 156200, 156231, 17241, 156377, 32634, 156478, 32661,
5738 32762, 32773, 156890, 156963, 32864, 157096, 32880, 144223, 17365,
5739 32946, 33027, 17419, 33086, 23221, 157607, 157621, 144275, 144284,
5740 33281, 33284, 36766, 17515, 33425, 33419, 33437, 21171, 33457,
5741 33459, 33469, 33510, 158524, 33509, 33565, 33635, 33709, 33571,
5742 33725, 33767, 33879, 33619, 33738, 33740, 33756, 158774, 159083,
5743 158933, 17707, 34033, 34035, 34070, 160714, 34148, 159532, 17757,
5744 17761, 159665, 159954, 17771, 34384, 34396, 34407, 34409, 34473,
5745 34440, 34574, 34530, 34681, 34600, 34667, 34694, 17879, 34785,
5746 34817, 17913, 34912, 34915, 161383, 35031, 35038, 17973, 35066,
5747 13499, 161966, 162150, 18110, 18119, 35488, 35565, 35722, 35925,
5748 162984, 36011, 36033, 36123, 36215, 163631, 133124, 36299, 36284,
5749 36336, 133342, 36564, 36664, 165330, 165357, 37012, 37105, 37137,
5750 165678, 37147, 37432, 37591, 37592, 37500, 37881, 37909, 166906,
5751 38283, 18837, 38327, 167287, 18918, 38595, 23986, 38691, 168261,
5752 168474, 19054, 19062, 38880, 168970, 19122, 169110, 38923, 38923,
5753 38953, 169398, 39138, 19251, 39209, 39335, 39362, 39422, 19406,
5754 170800, 39698, 40000, 40189, 19662, 19693, 40295, 172238, 19704,
5755 172293, 172558, 172689, 40635, 19798, 40697, 40702, 40709, 40719,
5756 40726, 40763, 173568};
5757
5758 const uint8_t canonical_combining_class_index[4352] = {
5759 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0,
5760 15, 0, 0, 0, 16, 17, 18, 19, 20, 21, 22, 0, 0, 23, 0, 0, 0, 0, 0,
5761 0, 0, 0, 0, 0, 0, 24, 25, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0,
5762 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5763 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5764 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5765 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5766 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5767 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 28, 29, 30,
5768 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5769 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5770 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5771 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5772 0, 0, 0, 0, 32, 0, 0, 33, 0, 0, 34, 35, 36, 0, 0, 0, 0, 0, 0,
5773 37, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 52,
5774 53, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5775 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5776 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5777 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5778 0, 55, 56, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5779 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5781 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5782 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5783 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 0, 0,
5784 0, 0, 0, 0, 0, 61, 56, 62, 0, 63, 0, 0, 0, 64, 65, 0, 0, 0, 0,
5785 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5786 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5787 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5788 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5789 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5790 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5791 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5792 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5793 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5794 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5795 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5796 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5797 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5798 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5799 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5800 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5801 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5802 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5803 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5804 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5805 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5806 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5807 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5808 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5811 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5812 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5814 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5815 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5816 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5817 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5818 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5819 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5820 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5821 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5823 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5824 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5826 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5827 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5828 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5829 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5830 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5831 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5832 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5833 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5834 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5836 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5840 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5841 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5842 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5843 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5844 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5845 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5846 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5847 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5848 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5849 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5850 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5851 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5852 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5853 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5854 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5855 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5856 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5857 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5858 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5859 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5860 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5861 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5862 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5863 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5864 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5865 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5866 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5867 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5868 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5869 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5870 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5871 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5872 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5873 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5874 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5875 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5876 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5877 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5878 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5879 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5880 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5881 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5882 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5883 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5884 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5885 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5886 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5887 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5888 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5889 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5890 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5891 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5892 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5893 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5894 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5895 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5896 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5897 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5898 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5899 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5900 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5901 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5902 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5903 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5904 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5905 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5906 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5907 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5908 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5909 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5910 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5911 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5912 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5913 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5914 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5915 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5916 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5917 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5918 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5919 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5920 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5921 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5922 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5923 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5924 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5925 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5926 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5927 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5928 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5929 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5930 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5931 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5933 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5934 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5935 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5936 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5937 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5938 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5939 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5940 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5941 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5942 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5943 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5944 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5945 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5946 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5947 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5948 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5949 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5950 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5951 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5952 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5953 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5954 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5955 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5956 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5957 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5958 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5959 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5960 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5961 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5962 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5963 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5964 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5965 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5966 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5967 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5968 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5969 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5970 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5971 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5972 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5973 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5974 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5975 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5976 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5977 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5978 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5979 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5980 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5981 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5982 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5983 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5984 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5985 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5986 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5987 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5988 0};
5989 const uint8_t canonical_combining_class_block[67][256] = {
5990 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5991 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5992 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5993 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5994 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5995 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5996 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5997 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5998 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5999 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6000 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6001 {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6002 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220,
6003 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220,
6004 220, 220, 220, 220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 220, 220,
6005 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230,
6006 230, 230, 220, 220, 0, 230, 230, 230, 220, 220, 220, 220, 230, 232, 220,
6007 220, 230, 233, 234, 234, 233, 234, 234, 233, 230, 230, 230, 230, 230, 230,
6008 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0,
6009 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6010 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6011 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6012 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6013 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6014 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6015 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6016 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6017 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6018 0},
6019 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6020 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6021 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6022 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6023 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6024 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,
6025 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6026 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6027 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6028 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6029 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6030 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6031 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6032 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6033 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6034 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6035 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6036 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6037 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6038 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6039 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6040 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 230, 230, 230, 230,
6041 220, 230, 230, 230, 222, 220, 230, 230, 230, 230, 230, 230, 220, 220, 220,
6042 220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230, 10, 11, 12, 13,
6043 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25,
6044 0, 230, 220, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6045 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6046 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6047 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6048 0},
6049 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6050 0, 230, 230, 230, 230, 230, 230, 230, 230, 30, 31, 32, 0, 0, 0,
6051 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6052 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6053 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6054 27, 28, 29, 30, 31, 32, 33, 34, 230, 230, 220, 220, 230, 230, 230,
6055 230, 230, 220, 230, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6056 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0,
6057 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6058 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6059 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6060 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6061 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6062 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6063 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230, 230,
6064 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, 230, 220, 0, 0,
6065 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6066 0},
6067 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6068 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6069 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6070 0, 0, 0, 230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220,
6071 220, 230, 220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230,
6072 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6073 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6074 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6075 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6076 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6077 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6078 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6079 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6080 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6081 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6082 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230,
6083 230, 230, 220, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0,
6084 0},
6085 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6086 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 230, 230, 230,
6087 230, 230, 230, 230, 230, 230, 0, 230, 230, 230, 0, 230, 230, 230, 230,
6088 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6089 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6090 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220,
6091 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6092 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6093 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6094 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6095 0, 0, 230, 220, 220, 220, 230, 230, 230, 230, 0, 0, 0, 0, 0,
6096 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6097 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6098 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 220, 220, 220,
6099 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6100 230, 0, 220, 230, 230, 220, 230, 230, 220, 230, 230, 230, 220, 220, 220,
6101 27, 28, 29, 230, 230, 230, 220, 230, 230, 220, 220, 230, 230, 230, 230,
6102 230},
6103 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0,
6106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 230, 220, 230, 230, 0, 0, 0,
6107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6112 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0},
6115 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6118 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
6123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6126 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6129 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6135 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6137 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6138 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6139 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6140 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6143 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
6145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6148 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6151 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6152 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6153 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6154 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6155 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6156 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6157 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6158 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6159 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6161 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6162 0, 0, 103, 103, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6163 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6166 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6169 0, 0, 0, 0, 118, 118, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6170 0, 0, 122, 122, 122, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6173 0, 0, 0, 0},
6174 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6175 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 0, 0, 0, 0,
6176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6177 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 220, 0, 216, 0, 0,
6178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6181 0, 0, 0, 0, 0, 0, 0, 0, 129, 130, 0, 132, 0, 0, 0,
6182 0, 0, 130, 130, 130, 130, 0, 0, 130, 0, 230, 230, 9, 0, 230,
6183 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6186 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6187 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6188 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6190 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6191 0},
6192 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6193 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6194 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6195 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6196 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6197 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0,
6198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6203 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6204 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6205 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6206 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6207 0, 0, 0, 0, 0, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6208 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6209 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6211 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6212 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6213 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6214 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6215 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0,
6216 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6217 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6223 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
6224 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6225 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6226 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6227 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6229 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6231 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6233 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6234 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6235 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6236 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6237 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6238 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6239 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 230, 220, 0, 0, 0, 0, 0, 0,
6240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6246 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6247 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6249 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6250 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 0, 0, 0, 0, 0,
6251 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6252 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6255 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,
6256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230,
6257 230, 230, 230, 230, 230, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0,
6258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230,
6261 230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 0, 220, 220, 230, 230,
6262 220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 230, 230, 0, 0, 0,
6263 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6264 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6266 0},
6267 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6269 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
6270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
6271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 230, 230, 230,
6273 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6274 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6275 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
6276 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6279 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,
6280 0, 0, 0, 0, 0, 0, 0, 0, 0},
6281 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6283 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6284 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
6285 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6286 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6287 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6288 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6290 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6291 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6292 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6293 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6294 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230,
6295 230, 0, 1, 220, 220, 220, 220, 220, 230, 230, 220, 220, 220, 220, 230,
6296 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 220, 0, 0,
6297 0, 0, 0, 0, 230, 0, 0, 0, 230, 230, 0, 0, 0, 0, 0,
6298 0},
6299 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6301 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6302 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6303 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6304 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 220,
6312 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 234, 214, 220, 202, 230,
6313 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6314 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6315 230, 230, 230, 230, 230, 230, 232, 228, 228, 220, 218, 230, 233, 220, 230,
6316 220},
6317 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6318 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6322 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6323 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6324 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6325 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6328 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6329 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6330 230, 230, 1, 1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 0, 0, 0,
6331 0, 230, 0, 0, 0, 1, 1, 230, 220, 230, 1, 1, 220, 220, 220, 220,
6332 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6333 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6334 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6339 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6340 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6341 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6342 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6343 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230,
6344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6345 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6346 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6347 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6348 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6349 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6350 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6351 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6352 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6353 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
6354 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6355 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6357 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6358 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6359 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,
6360 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6361 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6362 230},
6363 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6364 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6365 0, 0, 218, 228, 232, 222, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6366 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6367 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6368 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6369 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6370 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
6371 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6372 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6373 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6374 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6375 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6376 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6377 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6378 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6379 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6380 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6381 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6382 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,
6383 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0,
6384 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230,
6386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6387 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6388 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6389 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6390 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6391 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6392 {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,
6393 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6394 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
6395 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6396 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6398 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6399 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6400 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6401 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6402 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6403 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6404 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6405 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6406 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,
6407 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6408 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6409 0},
6410 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6411 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220,
6412 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6413 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
6414 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6415 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6416 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6417 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6418 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
6419 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6420 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6421 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6422 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6423 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6424 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6425 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6426 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6427 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6428 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6429 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6430 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6431 0, 0, 0, 0, 0, 230, 0, 230, 230, 220, 0, 0, 230, 230, 0, 0, 0, 0, 0,
6432 230, 230, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6433 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6434 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
6435 0, 0, 0, 0, 0, 0, 0, 0, 0},
6436 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6437 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6438 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6439 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6440 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6441 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6442 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6443 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6444 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6445 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
6446 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6447 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6448 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6449 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6450 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6451 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6452 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6453 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6454 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6455 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6456 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6457 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6458 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6459 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6460 0, 0, 230, 230, 230, 230, 230, 230, 230, 220, 220, 220, 220, 220, 220,
6461 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6462 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6463 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6464 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6465 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6466 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6467 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6468 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6469 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6470 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6471 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6472 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6473 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6474 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6475 0},
6476 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6477 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6478 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6479 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6480 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6481 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6482 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6483 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6484 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6485 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6486 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0},
6487 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6488 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6489 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6490 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6491 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6492 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6493 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6494 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6495 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6496 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6497 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6498 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6499 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6500 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6501 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6502 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6503 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6504 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6505 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6506 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6507 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6508 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6509 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6510 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 230, 0, 0, 0, 0,
6511 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6512 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 1, 220, 0,
6513 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6514 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6515 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6516 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6517 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6518 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6519 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6520 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6521 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6522 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6523 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6524 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0, 0, 0,
6525 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6526 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6527 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6528 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6529 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6530 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6531 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6532 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6533 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6534 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6535 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6536 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6537 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6538 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6539 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6540 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6541 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6542 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 0, 0, 0,
6543 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6544 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6545 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6546 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220},
6547 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6548 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6549 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6550 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220,
6551 230, 230, 230, 220, 230, 220, 220, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6552 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6553 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6554 0, 0, 0, 0, 230, 220, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6555 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6556 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6557 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6558 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6559 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6560 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6561 0, 0, 0, 0},
6562 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6563 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6564 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,
6565 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6566 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
6567 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6568 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6569 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0,
6570 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6571 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6572 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6573 {230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6574 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6575 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6576 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6577 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6578 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6579 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6580 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6581 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
6582 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6583 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6584 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6585 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6586 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6587 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6588 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6590 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6591 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6592 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6593 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6594 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 0, 0, 0,
6595 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6596 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6597 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6598 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6599 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0,
6600 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
6601 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6602 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0,
6603 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6604 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6605 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6606 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6607 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6608 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6609 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6610 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6611 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6612 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6613 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6614 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 7, 0,
6615 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0,
6616 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6617 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6618 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6619 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6620 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6621 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6622 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6623 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6624 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6625 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6626 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6627 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6628 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6629 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6630 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
6631 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6632 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6633 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6634 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6635 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6636 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,
6637 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6638 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6639 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6641 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,
6642 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6643 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6644 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6645 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6646 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
6647 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6648 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6649 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6650 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6651 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6652 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6653 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6654 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6655 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6656 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6657 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6658 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6659 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6660 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6661 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6662 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6663 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6664 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6665 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6666 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6667 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6668 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6669 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 7, 0, 0, 0, 0,
6670 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6671 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6672 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6673 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6674 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6675 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6676 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6677 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6678 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6679 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6680 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
6681 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6682 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6683 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6684 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6685 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6686 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6687 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6688 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6689 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6690 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6691 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,
6692 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6693 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6694 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6695 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6696 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6697 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6698 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6699 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6700 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6701 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6702 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0,
6703 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6704 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6705 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6706 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6707 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6708 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6709 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6710 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6711 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6712 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6713 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0,
6714 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6715 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6716 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6717 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6718 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6719 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6720 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6721 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6722 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6723 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6724 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6725 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6726 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6727 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6728 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6729 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6730 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6731 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6732 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6733 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6734 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6735 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0,
6736 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6737 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6738 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6739 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6740 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6741 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6742 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6743 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6744 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6745 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6746 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6747 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6748 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6749 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6750 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6751 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6752 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6753 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6754 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6755 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6756 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6757 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6758 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6759 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6760 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6761 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6762 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6763 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6764 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6765 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6766 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6767 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6768 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6769 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6770 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6771 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6772 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6773 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6774 0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216,
6775 216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220,
6776 220, 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0, 0, 0, 0,
6777 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6778 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0,
6779 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6781 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6782 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6783 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6784 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6785 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6786 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6787 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6788 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6789 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6790 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6791 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6792 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6793 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6794 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6795 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6796 {230, 230, 230, 230, 230, 230, 230, 0, 230, 230, 230, 230, 230, 230, 230,
6797 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230, 230, 230,
6798 230, 230, 230, 230, 0, 230, 230, 0, 230, 230, 230, 230, 230, 0, 0,
6799 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6800 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6801 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6802 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6803 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6804 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6805 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0,
6806 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6807 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6808 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6811 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6812 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6813 0},
6814 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6815 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6816 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6817 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6818 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6819 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6820 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6821 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0,
6822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6823 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6824 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0,
6825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6826 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6827 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6828 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6829 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6830 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6831 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6832 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6833 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6834 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6836 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 232, 220, 230, 0, 0,
6837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6838 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6840 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6841 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6842 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6843 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6844 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6845 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6846 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6847 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6848 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, 220, 0, 0, 0, 0, 0,
6849 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6850 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6851 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6852 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6853 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6854 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 7, 0, 0, 0, 0, 0,
6855 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6856 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6857 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6858 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6859 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6860 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6861 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6862 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6863 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
6864
6865 const uint8_t composition_index[4352] = {
6866 0, 1, 2, 3, 4, 5, 6, 5, 5, 7, 5, 8, 9, 10, 5, 5, 11, 5, 5, 5, 5, 5,
6867 5, 5, 5, 5, 5, 12, 5, 5, 13, 14, 5, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6868 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6869 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6870 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6871 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6872 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6873 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6874 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6875 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6876 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6877 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6878 5, 5, 5, 5, 5, 5, 5, 5, 18, 19, 5, 20, 21, 22, 5, 5, 5, 23, 5, 5, 5, 5,
6879 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6880 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6881 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6882 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6883 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6884 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6885 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6886 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6887 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6888 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6889 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6890 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6891 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6892 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6893 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6894 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6895 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6896 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6897 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6898 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6899 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6900 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6901 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6902 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6903 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6904 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6905 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6906 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6907 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6908 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6909 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6910 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6911 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6912 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6913 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6914 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6915 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6916 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6917 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6918 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6919 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6920 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6921 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6922 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6923 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6924 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6925 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6926 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6927 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6928 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6929 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6930 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6931 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6932 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6933 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6934 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6935 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6936 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6937 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6938 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6939 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6940 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6941 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6942 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6943 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6944 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6945 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6946 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6947 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6948 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6949 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6950 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6951 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6952 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6953 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6954 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6955 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6956 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6957 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6958 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6959 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6960 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6961 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6962 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6963 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6964 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6965 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6966 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6967 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6968 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6969 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6970 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6971 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6972 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6973 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6974 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6975 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6976 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6977 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6978 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6979 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6980 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6981 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6982 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6983 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6984 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6985 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6986 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6987 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6988 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6989 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6990 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6991 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6992 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6993 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6994 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6995 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6996 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6997 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6998 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6999 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7000 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7001 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7002 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7003 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7004 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7005 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7006 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7007 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7008 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7009 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7010 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7011 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7012 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7013 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7014 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7015 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7016 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7017 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7018 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7019 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7020 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7021 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7022 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7023 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7024 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7025 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7026 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7027 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7028 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7029 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7030 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7031 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7032 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7033 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7034 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7035 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7036 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7037 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7038 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7039 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7040 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7041 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7042 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7043 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7044 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7045 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7046 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7047 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7048 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7049 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7050 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7051 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7052 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7053 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7054 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7055 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7056 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7057 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7058 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7059 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7060 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7061 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7062 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7063 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
7064 const uint16_t composition_block[67][257] = {
7065 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
7066 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
7067 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
7068 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
7069 1, 3, 5, 7, 7, 7, 39, 45, 55, 67, 101, 103, 117, 131, 161,
7070 163, 173, 185, 191, 209, 241, 245, 245, 261, 275, 289, 327, 331, 343, 347,
7071 365, 377, 377, 377, 377, 377, 377, 377, 409, 415, 425, 437, 471, 473, 487,
7072 503, 531, 535, 545, 557, 563, 581, 613, 617, 617, 633, 647, 663, 701, 705,
7073 719, 723, 743, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,
7074 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,
7075 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,
7076 755, 755, 755, 755, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
7077 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
7078 769, 769, 771, 773, 777, 779, 779, 779, 787, 787, 787, 787, 787, 789, 789,
7079 789, 789, 789, 797, 803, 805, 805, 807, 807, 807, 807, 815, 815, 815, 815,
7080 815, 815, 823, 823, 825, 827, 831, 833, 833, 833, 841, 841, 841, 841, 841,
7081 843, 843, 843, 843, 843, 851, 857, 859, 859, 861, 861, 861, 861, 869, 869,
7082 869, 869},
7083 {869, 869, 869, 877, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885,
7084 885, 885, 885, 885, 889, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7085 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7086 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7087 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7088 893, 893, 897, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901,
7089 901, 903, 905, 905, 905, 905, 905, 907, 909, 909, 909, 909, 909, 909, 909,
7090 911, 913, 915, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917,
7091 917, 917, 917, 917, 917, 917, 917, 917, 919, 919, 919, 919, 919, 919, 919,
7092 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919,
7093 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 929, 939, 939, 939,
7094 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, 949, 959, 959, 959,
7095 959, 959, 959, 959, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,
7096 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,
7097 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,
7098 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 963, 965, 965, 965, 965,
7099 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,
7100 965, 965},
7101 {965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,
7102 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,
7103 965, 965, 965, 965, 965, 965, 965, 965, 965, 967, 969, 971, 973, 973, 973,
7104 973, 973, 975, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7105 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7106 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7107 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7108 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7109 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7110 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 979, 979, 979,
7111 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7112 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7113 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7114 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7115 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7116 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7117 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7118 979, 979},
7119 {979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7120 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7121 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7122 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7123 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7124 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7125 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7126 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7127 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7128 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7129 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7130 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7131 979, 979, 993, 993, 993, 993, 1001, 1001, 1011, 1011, 1025, 1025,
7132 1025, 1025, 1025, 1025, 1033, 1033, 1035, 1035, 1035, 1035, 1047, 1047,
7133 1047, 1047, 1057, 1057, 1057, 1059, 1059, 1061, 1061, 1061, 1077, 1077,
7134 1077, 1077, 1085, 1085, 1097, 1097, 1113, 1113, 1113, 1113, 1113, 1113,
7135 1121, 1121, 1125, 1125, 1125, 1125, 1141, 1141, 1141, 1141, 1153, 1159,
7136 1165, 1165, 1165, 1167, 1167, 1167, 1167, 1171, 1171, 1171, 1171, 1171,
7137 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
7138 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
7139 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
7140 1171, 1171, 1171, 1171, 1171},
7141 {1171, 1171, 1171, 1171, 1171, 1171, 1171, 1173, 1173, 1173, 1173, 1173,
7142 1173, 1173, 1173, 1173, 1173, 1177, 1177, 1177, 1179, 1179, 1185, 1189,
7143 1191, 1199, 1199, 1201, 1201, 1201, 1201, 1203, 1203, 1203, 1203, 1203,
7144 1211, 1211, 1211, 1211, 1213, 1213, 1213, 1213, 1215, 1215, 1217, 1217,
7145 1217, 1221, 1221, 1221, 1223, 1223, 1229, 1233, 1235, 1243, 1243, 1245,
7146 1245, 1245, 1245, 1247, 1247, 1247, 1247, 1247, 1255, 1255, 1255, 1255,
7147 1257, 1257, 1257, 1257, 1259, 1259, 1261, 1261, 1261, 1261, 1261, 1261,
7148 1261, 1261, 1261, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263,
7149 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263,
7150 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1265, 1267, 1267,
7151 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7152 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7153 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7154 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7155 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7156 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7157 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7158 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7159 1267, 1269, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271,
7160 1271, 1271, 1271, 1271, 1271, 1273, 1275, 1275, 1275, 1275, 1275, 1275,
7161 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7162 1275, 1275, 1275, 1275, 1275},
7163 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7166 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
7174 {1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7175 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7176 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7177 1275, 1275, 1275, 1275, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
7178 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
7179 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
7180 1281, 1283, 1283, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7181 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7182 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7183 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7184 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7185 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7186 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7187 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7188 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7189 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7190 1285, 1285, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
7191 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1289, 1289, 1289, 1291, 1291,
7192 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7193 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7194 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7195 1291, 1291, 1291, 1291, 1291},
7196 {1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7197 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7198 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7199 1291, 1291, 1291, 1291, 1291, 1293, 1293, 1293, 1293, 1293, 1293, 1293,
7200 1293, 1295, 1295, 1295, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7201 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7202 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7203 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7204 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7205 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7206 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7207 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7208 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7209 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7210 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7211 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7212 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1301, 1301, 1301, 1301,
7213 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7214 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7215 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7216 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7217 1301, 1301, 1301, 1301, 1301},
7218 {1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7219 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7220 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7221 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7222 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7223 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7224 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7225 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7226 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7227 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7228 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7229 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7230 1307, 1307, 1307, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
7231 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
7232 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
7233 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
7234 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1313, 1315, 1315, 1315, 1315,
7235 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7236 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7237 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7238 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7239 1315, 1315, 1315, 1315, 1315},
7240 {1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7241 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7242 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7243 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7244 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7245 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1317,
7246 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7247 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7248 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7249 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7250 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7251 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7252 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7253 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7254 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7255 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7256 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1325, 1325, 1325, 1325, 1327,
7257 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7258 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7259 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7260 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7261 1327, 1327, 1327, 1327, 1327},
7262 {1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7263 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7264 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7265 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7266 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7267 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1331,
7268 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7269 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7270 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7271 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7272 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7273 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7274 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7275 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7276 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7277 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7278 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7279 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7280 1333, 1333, 1339, 1339, 1339, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7281 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7282 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7283 1341, 1341, 1341, 1341, 1341},
7284 {1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7285 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7286 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7287 1341, 1341, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7288 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7289 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7290 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7291 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7292 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7293 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7294 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7295 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7296 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7297 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7298 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7299 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7300 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7301 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7302 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7303 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7304 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7305 1343, 1343, 1343, 1343, 1343},
7306 {1343, 1343, 1343, 1343, 1343, 1343, 1345, 1345, 1347, 1347, 1349, 1349,
7307 1351, 1351, 1353, 1353, 1353, 1353, 1355, 1355, 1355, 1355, 1355, 1355,
7308 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355,
7309 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355,
7310 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1357,
7311 1357, 1359, 1359, 1361, 1363, 1363, 1363, 1365, 1365, 1365, 1365, 1365,
7312 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7313 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7314 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7315 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7316 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7317 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7318 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7319 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7320 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7321 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7322 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7323 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7324 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7325 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7326 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7327 1365, 1365, 1365, 1365, 1365},
7328 {1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7329 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7330 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7331 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7332 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1367, 1369, 1369, 1369, 1369,
7333 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369,
7334 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369,
7335 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1371, 1373, 1373, 1373, 1373,
7336 1373, 1373, 1373, 1375, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7337 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7338 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7339 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7340 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7341 1377, 1377, 1377, 1377, 1377, 1381, 1385, 1385, 1385, 1385, 1385, 1385,
7342 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
7343 1385, 1385, 1385, 1385, 1385, 1387, 1389, 1389, 1389, 1389, 1389, 1389,
7344 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389,
7345 1389, 1391, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7346 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7347 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7348 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7349 1393, 1393, 1393, 1393, 1393},
7350 {1393, 1401, 1409, 1411, 1413, 1415, 1417, 1419, 1421, 1429, 1437, 1439,
7351 1441, 1443, 1445, 1447, 1449, 1453, 1457, 1457, 1457, 1457, 1457, 1457,
7352 1457, 1461, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1473, 1481, 1483,
7353 1485, 1487, 1489, 1491, 1493, 1501, 1509, 1511, 1513, 1515, 1517, 1519,
7354 1521, 1527, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1539, 1545, 1545,
7355 1545, 1545, 1545, 1545, 1545, 1549, 1553, 1553, 1553, 1553, 1553, 1553,
7356 1553, 1557, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1567, 1573, 1573,
7357 1573, 1573, 1573, 1573, 1573, 1573, 1579, 1579, 1579, 1579, 1579, 1579,
7358 1579, 1587, 1595, 1597, 1599, 1601, 1603, 1605, 1607, 1615, 1623, 1625,
7359 1627, 1629, 1631, 1633, 1635, 1637, 1637, 1637, 1637, 1639, 1639, 1639,
7360 1639, 1639, 1639, 1639, 1639, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7361 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7362 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7363 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7364 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7365 1641, 1641, 1641, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643,
7366 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1651, 1651, 1651, 1651, 1651,
7367 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,
7368 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,
7369 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,
7370 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1653, 1653, 1653, 1653, 1653,
7371 1653, 1653, 1653, 1659, 1659},
7372 {1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7373 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7374 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7375 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7376 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7377 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7378 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7379 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7380 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7381 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7382 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7383 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7384 1659, 1661, 1661, 1663, 1663, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7385 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7386 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7387 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7388 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7389 1665, 1665, 1665, 1665, 1665, 1667, 1667, 1669, 1669, 1671, 1671, 1671,
7390 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
7391 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
7392 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
7393 1671, 1671, 1671, 1671, 1671},
7394 {1671, 1671, 1671, 1671, 1673, 1673, 1673, 1673, 1673, 1675, 1675, 1675,
7395 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
7396 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
7397 1679, 1679, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
7398 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
7399 1681, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1685, 1685, 1687, 1687,
7400 1687, 1689, 1689, 1689, 1689, 1689, 1691, 1691, 1691, 1691, 1691, 1691,
7401 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691,
7402 1691, 1691, 1693, 1693, 1693, 1695, 1697, 1697, 1697, 1697, 1697, 1697,
7403 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1699, 1701, 1701, 1701, 1703,
7404 1705, 1705, 1705, 1707, 1709, 1711, 1713, 1713, 1713, 1713, 1713, 1715,
7405 1717, 1717, 1717, 1719, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
7406 1721, 1721, 1723, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725,
7407 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1727, 1727, 1727, 1727, 1727,
7408 1727, 1729, 1731, 1731, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1735,
7409 1737, 1739, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7410 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7411 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7412 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7413 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7414 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7415 1741, 1741, 1741, 1741, 1741},
7416 {1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7417 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7418 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7419 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7420 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7421 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1743,
7422 1743, 1743, 1743, 1743, 1745, 1745, 1747, 1747, 1749, 1749, 1751, 1751,
7423 1753, 1753, 1755, 1755, 1757, 1757, 1759, 1759, 1761, 1761, 1763, 1763,
7424 1765, 1765, 1767, 1767, 1767, 1769, 1769, 1771, 1771, 1773, 1773, 1773,
7425 1773, 1773, 1773, 1773, 1777, 1777, 1777, 1781, 1781, 1781, 1785, 1785,
7426 1785, 1789, 1789, 1789, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,
7427 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,
7428 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,
7429 1793, 1793, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1797,
7430 1797, 1797, 1797, 1797, 1799, 1799, 1801, 1801, 1803, 1803, 1805, 1805,
7431 1807, 1807, 1809, 1809, 1811, 1811, 1813, 1813, 1815, 1815, 1817, 1817,
7432 1819, 1819, 1821, 1821, 1821, 1823, 1823, 1825, 1825, 1827, 1827, 1827,
7433 1827, 1827, 1827, 1827, 1831, 1831, 1831, 1835, 1835, 1835, 1839, 1839,
7434 1839, 1843, 1843, 1843, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
7435 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
7436 1849, 1851, 1853, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855,
7437 1855, 1855, 1857, 1857, 1857},
7438 {1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7439 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7440 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7441 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7442 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7443 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7444 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7445 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7446 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7447 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7448 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7449 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7450 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1859, 1859,
7451 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1863, 1863,
7452 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7453 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7454 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7455 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7456 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7457 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7458 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7459 1863, 1863, 1863, 1863, 1863},
7460 {1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7461 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7462 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7463 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7464 1863, 1863, 1865, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7465 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7466 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7467 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7468 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7469 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7470 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7471 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7472 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7473 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7474 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7475 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7476 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7477 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7478 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7479 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7480 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7481 1867, 1867, 1867, 1867, 1867},
7482 {1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7483 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7484 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7485 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7486 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7487 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7488 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7489 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7490 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7491 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7492 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7493 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7494 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7495 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7496 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7497 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7498 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7499 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7500 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7501 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7502 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7503 1871, 1871, 1871, 1871, 1871},
7504 {1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7505 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7506 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7507 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7508 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7509 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7510 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7511 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7512 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7513 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7514 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7515 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7516 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7517 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7518 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7519 1871, 1871, 1871, 1871, 1871, 1871, 1877, 1877, 1877, 1877, 1877, 1877,
7520 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7521 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7522 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7523 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7524 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7525 1877, 1877, 1877, 1877, 1877},
7526 {1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7527 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7528 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7529 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7530 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7531 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7532 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7533 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7534 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7535 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7536 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7537 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7538 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7539 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7540 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7541 1877, 1877, 1877, 1877, 1877, 1879, 1881, 1881, 1881, 1881, 1881, 1881,
7542 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7543 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7544 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7545 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7546 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7547 1881, 1881, 1881, 1881, 1881},
7548 {1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7549 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7550 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7551 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7552 1881, 1881, 1881, 1881, 1881, 1881, 1883, 1883, 1883, 1883, 1883, 1883,
7553 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7554 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7555 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7556 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7557 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7558 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7559 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7560 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7561 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7562 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7563 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7564 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7565 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7566 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7567 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7568 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7569 1883, 1883, 1883, 1883, 1883}};
7570 const char32_t composition_data[1883] = {
7571 0, 824, 8814, 824, 8800, 824, 8815, 768, 192, 769, 193,
7572 770, 194, 771, 195, 772, 256, 774, 258, 775, 550, 776,
7573 196, 777, 7842, 778, 197, 780, 461, 783, 512, 785, 514,
7574 803, 7840, 805, 7680, 808, 260, 775, 7682, 803, 7684, 817,
7575 7686, 769, 262, 770, 264, 775, 266, 780, 268, 807, 199,
7576 775, 7690, 780, 270, 803, 7692, 807, 7696, 813, 7698, 817,
7577 7694, 768, 200, 769, 201, 770, 202, 771, 7868, 772, 274,
7578 774, 276, 775, 278, 776, 203, 777, 7866, 780, 282, 783,
7579 516, 785, 518, 803, 7864, 807, 552, 808, 280, 813, 7704,
7580 816, 7706, 775, 7710, 769, 500, 770, 284, 772, 7712, 774,
7581 286, 775, 288, 780, 486, 807, 290, 770, 292, 775, 7714,
7582 776, 7718, 780, 542, 803, 7716, 807, 7720, 814, 7722, 768,
7583 204, 769, 205, 770, 206, 771, 296, 772, 298, 774, 300,
7584 775, 304, 776, 207, 777, 7880, 780, 463, 783, 520, 785,
7585 522, 803, 7882, 808, 302, 816, 7724, 770, 308, 769, 7728,
7586 780, 488, 803, 7730, 807, 310, 817, 7732, 769, 313, 780,
7587 317, 803, 7734, 807, 315, 813, 7740, 817, 7738, 769, 7742,
7588 775, 7744, 803, 7746, 768, 504, 769, 323, 771, 209, 775,
7589 7748, 780, 327, 803, 7750, 807, 325, 813, 7754, 817, 7752,
7590 768, 210, 769, 211, 770, 212, 771, 213, 772, 332, 774,
7591 334, 775, 558, 776, 214, 777, 7886, 779, 336, 780, 465,
7592 783, 524, 785, 526, 795, 416, 803, 7884, 808, 490, 769,
7593 7764, 775, 7766, 769, 340, 775, 7768, 780, 344, 783, 528,
7594 785, 530, 803, 7770, 807, 342, 817, 7774, 769, 346, 770,
7595 348, 775, 7776, 780, 352, 803, 7778, 806, 536, 807, 350,
7596 775, 7786, 780, 356, 803, 7788, 806, 538, 807, 354, 813,
7597 7792, 817, 7790, 768, 217, 769, 218, 770, 219, 771, 360,
7598 772, 362, 774, 364, 776, 220, 777, 7910, 778, 366, 779,
7599 368, 780, 467, 783, 532, 785, 534, 795, 431, 803, 7908,
7600 804, 7794, 808, 370, 813, 7798, 816, 7796, 771, 7804, 803,
7601 7806, 768, 7808, 769, 7810, 770, 372, 775, 7814, 776, 7812,
7602 803, 7816, 775, 7818, 776, 7820, 768, 7922, 769, 221, 770,
7603 374, 771, 7928, 772, 562, 775, 7822, 776, 376, 777, 7926,
7604 803, 7924, 769, 377, 770, 7824, 775, 379, 780, 381, 803,
7605 7826, 817, 7828, 768, 224, 769, 225, 770, 226, 771, 227,
7606 772, 257, 774, 259, 775, 551, 776, 228, 777, 7843, 778,
7607 229, 780, 462, 783, 513, 785, 515, 803, 7841, 805, 7681,
7608 808, 261, 775, 7683, 803, 7685, 817, 7687, 769, 263, 770,
7609 265, 775, 267, 780, 269, 807, 231, 775, 7691, 780, 271,
7610 803, 7693, 807, 7697, 813, 7699, 817, 7695, 768, 232, 769,
7611 233, 770, 234, 771, 7869, 772, 275, 774, 277, 775, 279,
7612 776, 235, 777, 7867, 780, 283, 783, 517, 785, 519, 803,
7613 7865, 807, 553, 808, 281, 813, 7705, 816, 7707, 775, 7711,
7614 769, 501, 770, 285, 772, 7713, 774, 287, 775, 289, 780,
7615 487, 807, 291, 770, 293, 775, 7715, 776, 7719, 780, 543,
7616 803, 7717, 807, 7721, 814, 7723, 817, 7830, 768, 236, 769,
7617 237, 770, 238, 771, 297, 772, 299, 774, 301, 776, 239,
7618 777, 7881, 780, 464, 783, 521, 785, 523, 803, 7883, 808,
7619 303, 816, 7725, 770, 309, 780, 496, 769, 7729, 780, 489,
7620 803, 7731, 807, 311, 817, 7733, 769, 314, 780, 318, 803,
7621 7735, 807, 316, 813, 7741, 817, 7739, 769, 7743, 775, 7745,
7622 803, 7747, 768, 505, 769, 324, 771, 241, 775, 7749, 780,
7623 328, 803, 7751, 807, 326, 813, 7755, 817, 7753, 768, 242,
7624 769, 243, 770, 244, 771, 245, 772, 333, 774, 335, 775,
7625 559, 776, 246, 777, 7887, 779, 337, 780, 466, 783, 525,
7626 785, 527, 795, 417, 803, 7885, 808, 491, 769, 7765, 775,
7627 7767, 769, 341, 775, 7769, 780, 345, 783, 529, 785, 531,
7628 803, 7771, 807, 343, 817, 7775, 769, 347, 770, 349, 775,
7629 7777, 780, 353, 803, 7779, 806, 537, 807, 351, 775, 7787,
7630 776, 7831, 780, 357, 803, 7789, 806, 539, 807, 355, 813,
7631 7793, 817, 7791, 768, 249, 769, 250, 770, 251, 771, 361,
7632 772, 363, 774, 365, 776, 252, 777, 7911, 778, 367, 779,
7633 369, 780, 468, 783, 533, 785, 535, 795, 432, 803, 7909,
7634 804, 7795, 808, 371, 813, 7799, 816, 7797, 771, 7805, 803,
7635 7807, 768, 7809, 769, 7811, 770, 373, 775, 7815, 776, 7813,
7636 778, 7832, 803, 7817, 775, 7819, 776, 7821, 768, 7923, 769,
7637 253, 770, 375, 771, 7929, 772, 563, 775, 7823, 776, 255,
7638 777, 7927, 778, 7833, 803, 7925, 769, 378, 770, 7825, 775,
7639 380, 780, 382, 803, 7827, 817, 7829, 768, 8173, 769, 901,
7640 834, 8129, 768, 7846, 769, 7844, 771, 7850, 777, 7848, 772,
7641 478, 769, 506, 769, 508, 772, 482, 769, 7688, 768, 7872,
7642 769, 7870, 771, 7876, 777, 7874, 769, 7726, 768, 7890, 769,
7643 7888, 771, 7894, 777, 7892, 769, 7756, 772, 556, 776, 7758,
7644 772, 554, 769, 510, 768, 475, 769, 471, 772, 469, 780,
7645 473, 768, 7847, 769, 7845, 771, 7851, 777, 7849, 772, 479,
7646 769, 507, 769, 509, 772, 483, 769, 7689, 768, 7873, 769,
7647 7871, 771, 7877, 777, 7875, 769, 7727, 768, 7891, 769, 7889,
7648 771, 7895, 777, 7893, 769, 7757, 772, 557, 776, 7759, 772,
7649 555, 769, 511, 768, 476, 769, 472, 772, 470, 780, 474,
7650 768, 7856, 769, 7854, 771, 7860, 777, 7858, 768, 7857, 769,
7651 7855, 771, 7861, 777, 7859, 768, 7700, 769, 7702, 768, 7701,
7652 769, 7703, 768, 7760, 769, 7762, 768, 7761, 769, 7763, 775,
7653 7780, 775, 7781, 775, 7782, 775, 7783, 769, 7800, 769, 7801,
7654 776, 7802, 776, 7803, 775, 7835, 768, 7900, 769, 7898, 771,
7655 7904, 777, 7902, 803, 7906, 768, 7901, 769, 7899, 771, 7905,
7656 777, 7903, 803, 7907, 768, 7914, 769, 7912, 771, 7918, 777,
7657 7916, 803, 7920, 768, 7915, 769, 7913, 771, 7919, 777, 7917,
7658 803, 7921, 780, 494, 772, 492, 772, 493, 772, 480, 772,
7659 481, 774, 7708, 774, 7709, 772, 560, 772, 561, 780, 495,
7660 768, 8122, 769, 902, 772, 8121, 774, 8120, 787, 7944, 788,
7661 7945, 837, 8124, 768, 8136, 769, 904, 787, 7960, 788, 7961,
7662 768, 8138, 769, 905, 787, 7976, 788, 7977, 837, 8140, 768,
7663 8154, 769, 906, 772, 8153, 774, 8152, 776, 938, 787, 7992,
7664 788, 7993, 768, 8184, 769, 908, 787, 8008, 788, 8009, 788,
7665 8172, 768, 8170, 769, 910, 772, 8169, 774, 8168, 776, 939,
7666 788, 8025, 768, 8186, 769, 911, 787, 8040, 788, 8041, 837,
7667 8188, 837, 8116, 837, 8132, 768, 8048, 769, 940, 772, 8113,
7668 774, 8112, 787, 7936, 788, 7937, 834, 8118, 837, 8115, 768,
7669 8050, 769, 941, 787, 7952, 788, 7953, 768, 8052, 769, 942,
7670 787, 7968, 788, 7969, 834, 8134, 837, 8131, 768, 8054, 769,
7671 943, 772, 8145, 774, 8144, 776, 970, 787, 7984, 788, 7985,
7672 834, 8150, 768, 8056, 769, 972, 787, 8000, 788, 8001, 787,
7673 8164, 788, 8165, 768, 8058, 769, 973, 772, 8161, 774, 8160,
7674 776, 971, 787, 8016, 788, 8017, 834, 8166, 768, 8060, 769,
7675 974, 787, 8032, 788, 8033, 834, 8182, 837, 8179, 768, 8146,
7676 769, 912, 834, 8151, 768, 8162, 769, 944, 834, 8167, 837,
7677 8180, 769, 979, 776, 980, 776, 1031, 774, 1232, 776, 1234,
7678 769, 1027, 768, 1024, 774, 1238, 776, 1025, 774, 1217, 776,
7679 1244, 776, 1246, 768, 1037, 772, 1250, 774, 1049, 776, 1252,
7680 769, 1036, 776, 1254, 772, 1262, 774, 1038, 776, 1264, 779,
7681 1266, 776, 1268, 776, 1272, 776, 1260, 774, 1233, 776, 1235,
7682 769, 1107, 768, 1104, 774, 1239, 776, 1105, 774, 1218, 776,
7683 1245, 776, 1247, 768, 1117, 772, 1251, 774, 1081, 776, 1253,
7684 769, 1116, 776, 1255, 772, 1263, 774, 1118, 776, 1265, 779,
7685 1267, 776, 1269, 776, 1273, 776, 1261, 776, 1111, 783, 1142,
7686 783, 1143, 776, 1242, 776, 1243, 776, 1258, 776, 1259, 1619,
7687 1570, 1620, 1571, 1621, 1573, 1620, 1572, 1620, 1574, 1620, 1730,
7688 1620, 1747, 1620, 1728, 2364, 2345, 2364, 2353, 2364, 2356, 2494,
7689 2507, 2519, 2508, 2878, 2891, 2902, 2888, 2903, 2892, 3031, 2964,
7690 3006, 3018, 3031, 3020, 3006, 3019, 3158, 3144, 3285, 3264, 3266,
7691 3274, 3285, 3271, 3286, 3272, 3285, 3275, 3390, 3402, 3415, 3404,
7692 3390, 3403, 3530, 3546, 3535, 3548, 3551, 3550, 3530, 3549, 4142,
7693 4134, 6965, 6918, 6965, 6920, 6965, 6922, 6965, 6924, 6965, 6926,
7694 6965, 6930, 6965, 6971, 6965, 6973, 6965, 6976, 6965, 6977, 6965,
7695 6979, 772, 7736, 772, 7737, 772, 7772, 772, 7773, 775, 7784,
7696 775, 7785, 770, 7852, 774, 7862, 770, 7853, 774, 7863, 770,
7697 7878, 770, 7879, 770, 7896, 770, 7897, 768, 7938, 769, 7940,
7698 834, 7942, 837, 8064, 768, 7939, 769, 7941, 834, 7943, 837,
7699 8065, 837, 8066, 837, 8067, 837, 8068, 837, 8069, 837, 8070,
7700 837, 8071, 768, 7946, 769, 7948, 834, 7950, 837, 8072, 768,
7701 7947, 769, 7949, 834, 7951, 837, 8073, 837, 8074, 837, 8075,
7702 837, 8076, 837, 8077, 837, 8078, 837, 8079, 768, 7954, 769,
7703 7956, 768, 7955, 769, 7957, 768, 7962, 769, 7964, 768, 7963,
7704 769, 7965, 768, 7970, 769, 7972, 834, 7974, 837, 8080, 768,
7705 7971, 769, 7973, 834, 7975, 837, 8081, 837, 8082, 837, 8083,
7706 837, 8084, 837, 8085, 837, 8086, 837, 8087, 768, 7978, 769,
7707 7980, 834, 7982, 837, 8088, 768, 7979, 769, 7981, 834, 7983,
7708 837, 8089, 837, 8090, 837, 8091, 837, 8092, 837, 8093, 837,
7709 8094, 837, 8095, 768, 7986, 769, 7988, 834, 7990, 768, 7987,
7710 769, 7989, 834, 7991, 768, 7994, 769, 7996, 834, 7998, 768,
7711 7995, 769, 7997, 834, 7999, 768, 8002, 769, 8004, 768, 8003,
7712 769, 8005, 768, 8010, 769, 8012, 768, 8011, 769, 8013, 768,
7713 8018, 769, 8020, 834, 8022, 768, 8019, 769, 8021, 834, 8023,
7714 768, 8027, 769, 8029, 834, 8031, 768, 8034, 769, 8036, 834,
7715 8038, 837, 8096, 768, 8035, 769, 8037, 834, 8039, 837, 8097,
7716 837, 8098, 837, 8099, 837, 8100, 837, 8101, 837, 8102, 837,
7717 8103, 768, 8042, 769, 8044, 834, 8046, 837, 8104, 768, 8043,
7718 769, 8045, 834, 8047, 837, 8105, 837, 8106, 837, 8107, 837,
7719 8108, 837, 8109, 837, 8110, 837, 8111, 837, 8114, 837, 8130,
7720 837, 8178, 837, 8119, 768, 8141, 769, 8142, 834, 8143, 837,
7721 8135, 837, 8183, 768, 8157, 769, 8158, 834, 8159, 824, 8602,
7722 824, 8603, 824, 8622, 824, 8653, 824, 8655, 824, 8654, 824,
7723 8708, 824, 8713, 824, 8716, 824, 8740, 824, 8742, 824, 8769,
7724 824, 8772, 824, 8775, 824, 8777, 824, 8813, 824, 8802, 824,
7725 8816, 824, 8817, 824, 8820, 824, 8821, 824, 8824, 824, 8825,
7726 824, 8832, 824, 8833, 824, 8928, 824, 8929, 824, 8836, 824,
7727 8837, 824, 8840, 824, 8841, 824, 8930, 824, 8931, 824, 8876,
7728 824, 8877, 824, 8878, 824, 8879, 824, 8938, 824, 8939, 824,
7729 8940, 824, 8941, 12441, 12436, 12441, 12364, 12441, 12366, 12441, 12368,
7730 12441, 12370, 12441, 12372, 12441, 12374, 12441, 12376, 12441, 12378, 12441,
7731 12380, 12441, 12382, 12441, 12384, 12441, 12386, 12441, 12389, 12441, 12391,
7732 12441, 12393, 12441, 12400, 12442, 12401, 12441, 12403, 12442, 12404, 12441,
7733 12406, 12442, 12407, 12441, 12409, 12442, 12410, 12441, 12412, 12442, 12413,
7734 12441, 12446, 12441, 12532, 12441, 12460, 12441, 12462, 12441, 12464, 12441,
7735 12466, 12441, 12468, 12441, 12470, 12441, 12472, 12441, 12474, 12441, 12476,
7736 12441, 12478, 12441, 12480, 12441, 12482, 12441, 12485, 12441, 12487, 12441,
7737 12489, 12441, 12496, 12442, 12497, 12441, 12499, 12442, 12500, 12441, 12502,
7738 12442, 12503, 12441, 12505, 12442, 12506, 12441, 12508, 12442, 12509, 12441,
7739 12535, 12441, 12536, 12441, 12537, 12441, 12538, 12441, 12542, 69818, 69786,
7740 69818, 69788, 69818, 69803, 69927, 69934, 69927, 69935, 70462, 70475, 70487,
7741 70476, 70832, 70844, 70842, 70843, 70845, 70846, 71087, 71098, 71087, 71099,
7742 71984, 71992};
7743
7744 } // namespace ada::idna
7745 #endif // ADA_IDNA_NORMALIZATION_TABLES_H
7746 /* end file src/normalization_tables.cpp */
7747
7748 namespace ada::idna {
7749
7750 // See
7751 // https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/impl_norm.h#L467
7752 constexpr char32_t hangul_sbase = 0xAC00;
7753 constexpr char32_t hangul_tbase = 0x11A7;
7754 constexpr char32_t hangul_vbase = 0x1161;
7755 constexpr char32_t hangul_lbase = 0x1100;
7756 constexpr char32_t hangul_lcount = 19;
7757 constexpr char32_t hangul_vcount = 21;
7758 constexpr char32_t hangul_tcount = 28;
7759 constexpr char32_t hangul_ncount = hangul_vcount * hangul_tcount;
7760 constexpr char32_t hangul_scount =
7761 hangul_lcount * hangul_vcount * hangul_tcount;
7762
compute_decomposition_length(const std::u32string_view input)7763 std::pair<bool, size_t> compute_decomposition_length(
7764 const std::u32string_view input) noexcept {
7765 bool decomposition_needed{false};
7766 size_t additional_elements{0};
7767 for (char32_t current_character : input) {
7768 size_t decomposition_length{0};
7769
7770 if (current_character >= hangul_sbase &&
7771 current_character < hangul_sbase + hangul_scount) {
7772 decomposition_length = 2;
7773 if ((current_character - hangul_sbase) % hangul_tcount) {
7774 decomposition_length = 3;
7775 }
7776 } else if (current_character < 0x110000) {
7777 const uint8_t di = decomposition_index[current_character >> 8];
7778 const uint16_t* const decomposition =
7779 decomposition_block[di] + (current_character % 256);
7780 decomposition_length = (decomposition[1] >> 2) - (decomposition[0] >> 2);
7781 if ((decomposition_length > 0) && (decomposition[0] & 1)) {
7782 decomposition_length = 0;
7783 }
7784 }
7785 if (decomposition_length != 0) {
7786 decomposition_needed = true;
7787 additional_elements += decomposition_length - 1;
7788 }
7789 }
7790 return {decomposition_needed, additional_elements};
7791 }
7792
decompose(std::u32string & input,size_t additional_elements)7793 void decompose(std::u32string& input, size_t additional_elements) {
7794 input.resize(input.size() + additional_elements);
7795 for (size_t descending_idx = input.size(),
7796 input_count = descending_idx - additional_elements;
7797 input_count--;) {
7798 if (input[input_count] >= hangul_sbase &&
7799 input[input_count] < hangul_sbase + hangul_scount) {
7800 // Hangul decomposition.
7801 char32_t s_index = input[input_count] - hangul_sbase;
7802 if (s_index % hangul_tcount != 0) {
7803 input[--descending_idx] = hangul_tbase + s_index % hangul_tcount;
7804 }
7805 input[--descending_idx] =
7806 hangul_vbase + (s_index % hangul_ncount) / hangul_tcount;
7807 input[--descending_idx] = hangul_lbase + s_index / hangul_ncount;
7808 } else if (input[input_count] < 0x110000) {
7809 // Check decomposition_data.
7810 const uint16_t* decomposition =
7811 decomposition_block[decomposition_index[input[input_count] >> 8]] +
7812 (input[input_count] % 256);
7813 uint16_t decomposition_length =
7814 (decomposition[1] >> 2) - (decomposition[0] >> 2);
7815 if (decomposition_length > 0 && (decomposition[0] & 1)) {
7816 decomposition_length = 0;
7817 }
7818 if (decomposition_length > 0) {
7819 // Non-recursive decomposition.
7820 while (decomposition_length-- > 0) {
7821 input[--descending_idx] = decomposition_data[(decomposition[0] >> 2) +
7822 decomposition_length];
7823 }
7824 } else {
7825 // No decomposition.
7826 input[--descending_idx] = input[input_count];
7827 }
7828 } else {
7829 // Non-Unicode character.
7830 input[--descending_idx] = input[input_count];
7831 }
7832 }
7833 }
7834
get_ccc(char32_t c)7835 uint8_t get_ccc(char32_t c) noexcept {
7836 return c < 0x110000 ? canonical_combining_class_block
7837 [canonical_combining_class_index[c >> 8]][c % 256]
7838 : 0;
7839 }
7840
sort_marks(std::u32string & input)7841 void sort_marks(std::u32string& input) {
7842 for (size_t idx = 1; idx < input.size(); idx++) {
7843 uint8_t ccc = get_ccc(input[idx]);
7844 if (ccc == 0) {
7845 continue;
7846 } // Skip non-combining characters.
7847 auto current_character = input[idx];
7848 size_t back_idx = idx;
7849 while (back_idx != 0 && get_ccc(input[back_idx - 1]) > ccc) {
7850 input[back_idx] = input[back_idx - 1];
7851 back_idx--;
7852 }
7853 input[back_idx] = current_character;
7854 }
7855 }
7856
decompose_nfc(std::u32string & input)7857 void decompose_nfc(std::u32string& input) {
7858 /**
7859 * Decompose the domain_name string to Unicode Normalization Form C.
7860 * @see https://www.unicode.org/reports/tr46/#ProcessingStepDecompose
7861 */
7862 auto [decomposition_needed, additional_elements] =
7863 compute_decomposition_length(input);
7864 if (decomposition_needed) {
7865 decompose(input, additional_elements);
7866 }
7867 sort_marks(input);
7868 }
7869
compose(std::u32string & input)7870 void compose(std::u32string& input) {
7871 /**
7872 * Compose the domain_name string to Unicode Normalization Form C.
7873 * @see https://www.unicode.org/reports/tr46/#ProcessingStepCompose
7874 */
7875 size_t input_count{0};
7876 size_t composition_count{0};
7877 for (; input_count < input.size(); input_count++, composition_count++) {
7878 input[composition_count] = input[input_count];
7879 if (input[input_count] >= hangul_lbase &&
7880 input[input_count] < hangul_lbase + hangul_lcount) {
7881 if (input_count + 1 < input.size() &&
7882 input[input_count + 1] >= hangul_vbase &&
7883 input[input_count + 1] < hangul_vbase + hangul_vcount) {
7884 input[composition_count] =
7885 hangul_sbase +
7886 ((input[input_count] - hangul_lbase) * hangul_vcount +
7887 input[input_count + 1] - hangul_vbase) *
7888 hangul_tcount;
7889 input_count++;
7890 if (input_count + 1 < input.size() &&
7891 input[input_count + 1] > hangul_tbase &&
7892 input[input_count + 1] < hangul_tbase + hangul_tcount) {
7893 input[composition_count] += input[++input_count] - hangul_tbase;
7894 }
7895 }
7896 } else if (input[input_count] >= hangul_sbase &&
7897 input[input_count] < hangul_sbase + hangul_scount) {
7898 if ((input[input_count] - hangul_sbase) % hangul_tcount &&
7899 input_count + 1 < input.size() &&
7900 input[input_count + 1] > hangul_tbase &&
7901 input[input_count + 1] < hangul_tbase + hangul_tcount) {
7902 input[composition_count] += input[++input_count] - hangul_tbase;
7903 }
7904 } else if (input[input_count] < 0x110000) {
7905 const uint16_t* composition =
7906 &composition_block[composition_index[input[input_count] >> 8]]
7907 [input[input_count] % 256];
7908 size_t initial_composition_count = composition_count;
7909 for (int32_t previous_ccc = -1; input_count + 1 < input.size();
7910 input_count++) {
7911 uint8_t ccc = get_ccc(input[input_count + 1]);
7912
7913 if (composition[1] != composition[0] && previous_ccc < ccc) {
7914 // Try finding a composition.
7915 uint16_t left = composition[0];
7916 uint16_t right = composition[1];
7917 while (left + 2 < right) {
7918 // mean without overflow
7919 uint16_t middle = left + (((right - left) >> 1) & ~1);
7920 if (composition_data[middle] <= input[input_count + 1]) {
7921 left = middle;
7922 }
7923 if (composition_data[middle] >= input[input_count + 1]) {
7924 right = middle;
7925 }
7926 }
7927 if (composition_data[left] == input[input_count + 1]) {
7928 input[initial_composition_count] = composition_data[left + 1];
7929 composition =
7930 &composition_block
7931 [composition_index[composition_data[left + 1] >> 8]]
7932 [composition_data[left + 1] % 256];
7933 continue;
7934 }
7935 }
7936
7937 if (ccc == 0) {
7938 break;
7939 } // Not a combining character.
7940 previous_ccc = ccc;
7941 input[++composition_count] = input[input_count + 1];
7942 }
7943 }
7944 }
7945
7946 if (composition_count < input_count) {
7947 input.resize(composition_count);
7948 }
7949 }
7950
normalize(std::u32string & input)7951 void normalize(std::u32string& input) {
7952 /**
7953 * Normalize the domain_name string to Unicode Normalization Form C.
7954 * @see https://www.unicode.org/reports/tr46/#ProcessingStepNormalize
7955 */
7956 decompose_nfc(input);
7957 compose(input);
7958 }
7959
7960 } // namespace ada::idna
7961 /* end file src/normalization.cpp */
7962 /* begin file src/punycode.cpp */
7963
7964 #include <cstdint>
7965
7966 namespace ada::idna {
7967
7968 constexpr int32_t base = 36;
7969 constexpr int32_t tmin = 1;
7970 constexpr int32_t tmax = 26;
7971 constexpr int32_t skew = 38;
7972 constexpr int32_t damp = 700;
7973 constexpr int32_t initial_bias = 72;
7974 constexpr uint32_t initial_n = 128;
7975
char_to_digit_value(char value)7976 static constexpr int32_t char_to_digit_value(char value) {
7977 if (value >= 'a' && value <= 'z') return value - 'a';
7978 if (value >= '0' && value <= '9') return value - '0' + 26;
7979 return -1;
7980 }
7981
digit_to_char(int32_t digit)7982 static constexpr char digit_to_char(int32_t digit) {
7983 return digit < 26 ? char(digit + 97) : char(digit + 22);
7984 }
7985
adapt(int32_t d,int32_t n,bool firsttime)7986 static constexpr int32_t adapt(int32_t d, int32_t n, bool firsttime) {
7987 if (firsttime) {
7988 d = d / damp;
7989 } else {
7990 d = d / 2;
7991 }
7992 d += d / n;
7993 int32_t k = 0;
7994 while (d > ((base - tmin) * tmax) / 2) {
7995 d /= base - tmin;
7996 k += base;
7997 }
7998 return k + (((base - tmin + 1) * d) / (d + skew));
7999 }
8000
punycode_to_utf32(std::string_view input,std::u32string & out)8001 bool punycode_to_utf32(std::string_view input, std::u32string &out) {
8002 int32_t written_out{0};
8003 out.reserve(out.size() + input.size());
8004 uint32_t n = initial_n;
8005 int32_t i = 0;
8006 int32_t bias = initial_bias;
8007 // grab ascii content
8008 size_t end_of_ascii = input.find_last_of('-');
8009 if (end_of_ascii != std::string_view::npos) {
8010 for (uint8_t c : input.substr(0, end_of_ascii)) {
8011 if (c >= 0x80) {
8012 return false;
8013 }
8014 out.push_back(c);
8015 written_out++;
8016 }
8017 input.remove_prefix(end_of_ascii + 1);
8018 }
8019 while (!input.empty()) {
8020 int32_t oldi = i;
8021 int32_t w = 1;
8022 for (int32_t k = base;; k += base) {
8023 if (input.empty()) {
8024 return false;
8025 }
8026 uint8_t code_point = input.front();
8027 input.remove_prefix(1);
8028 int32_t digit = char_to_digit_value(code_point);
8029 if (digit < 0) {
8030 return false;
8031 }
8032 if (digit > (0x7fffffff - i) / w) {
8033 return false;
8034 }
8035 i = i + digit * w;
8036 int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
8037 if (digit < t) {
8038 break;
8039 }
8040 if (w > 0x7fffffff / (base - t)) {
8041 return false;
8042 }
8043 w = w * (base - t);
8044 }
8045 bias = adapt(i - oldi, written_out + 1, oldi == 0);
8046 if (i / (written_out + 1) > int32_t(0x7fffffff - n)) {
8047 return false;
8048 }
8049 n = n + i / (written_out + 1);
8050 i = i % (written_out + 1);
8051 if (n < 0x80) {
8052 return false;
8053 }
8054 out.insert(out.begin() + i, n);
8055 written_out++;
8056 ++i;
8057 }
8058
8059 return true;
8060 }
8061
verify_punycode(std::string_view input)8062 bool verify_punycode(std::string_view input) {
8063 size_t written_out{0};
8064 uint32_t n = initial_n;
8065 int32_t i = 0;
8066 int32_t bias = initial_bias;
8067 // grab ascii content
8068 size_t end_of_ascii = input.find_last_of('-');
8069 if (end_of_ascii != std::string_view::npos) {
8070 for (uint8_t c : input.substr(0, end_of_ascii)) {
8071 if (c >= 0x80) {
8072 return false;
8073 }
8074 written_out++;
8075 }
8076 input.remove_prefix(end_of_ascii + 1);
8077 }
8078 while (!input.empty()) {
8079 int32_t oldi = i;
8080 int32_t w = 1;
8081 for (int32_t k = base;; k += base) {
8082 if (input.empty()) {
8083 return false;
8084 }
8085 uint8_t code_point = input.front();
8086 input.remove_prefix(1);
8087 int32_t digit = char_to_digit_value(code_point);
8088 if (digit < 0) {
8089 return false;
8090 }
8091 if (digit > (0x7fffffff - i) / w) {
8092 return false;
8093 }
8094 i = i + digit * w;
8095 int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
8096 if (digit < t) {
8097 break;
8098 }
8099 if (w > 0x7fffffff / (base - t)) {
8100 return false;
8101 }
8102 w = w * (base - t);
8103 }
8104 bias = adapt(i - oldi, int32_t(written_out + 1), oldi == 0);
8105 if (i / (written_out + 1) > 0x7fffffff - n) {
8106 return false;
8107 }
8108 n = n + i / int32_t(written_out + 1);
8109 i = i % int32_t(written_out + 1);
8110 if (n < 0x80) {
8111 return false;
8112 }
8113 written_out++;
8114 ++i;
8115 }
8116
8117 return true;
8118 }
8119
utf32_to_punycode(std::u32string_view input,std::string & out)8120 bool utf32_to_punycode(std::u32string_view input, std::string &out) {
8121 out.reserve(input.size() + out.size());
8122 uint32_t n = initial_n;
8123 int32_t d = 0;
8124 int32_t bias = initial_bias;
8125 size_t h = 0;
8126 // first push the ascii content
8127 for (uint32_t c : input) {
8128 if (c < 0x80) {
8129 ++h;
8130 out.push_back(char(c));
8131 }
8132 if (c > 0x10ffff || (c >= 0xd880 && c < 0xe000)) {
8133 return false;
8134 }
8135 }
8136 size_t b = h;
8137 if (b > 0) {
8138 out.push_back('-');
8139 }
8140 while (h < input.size()) {
8141 uint32_t m = 0x10FFFF;
8142 for (auto code_point : input) {
8143 if (code_point >= n && code_point < m) m = code_point;
8144 }
8145
8146 if ((m - n) > (0x7fffffff - d) / (h + 1)) {
8147 return false;
8148 }
8149 d = d + int32_t((m - n) * (h + 1));
8150 n = m;
8151 for (auto c : input) {
8152 if (c < n) {
8153 if (d == 0x7fffffff) {
8154 return false;
8155 }
8156 ++d;
8157 }
8158 if (c == n) {
8159 int32_t q = d;
8160 for (int32_t k = base;; k += base) {
8161 int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
8162
8163 if (q < t) {
8164 break;
8165 }
8166 out.push_back(digit_to_char(t + ((q - t) % (base - t))));
8167 q = (q - t) / (base - t);
8168 }
8169 out.push_back(digit_to_char(q));
8170 bias = adapt(d, int32_t(h + 1), h == b);
8171 d = 0;
8172 ++h;
8173 }
8174 }
8175 ++d;
8176 ++n;
8177 }
8178 return true;
8179 }
8180
8181 } // namespace ada::idna
8182 /* end file src/punycode.cpp */
8183 /* begin file src/validity.cpp */
8184 #include <algorithm>
8185 #include <string_view>
8186
8187 namespace ada::idna {
8188
8189 enum direction : uint8_t {
8190 NONE,
8191 BN,
8192 CS,
8193 ES,
8194 ON,
8195 EN,
8196 L,
8197 R,
8198 NSM,
8199 AL,
8200 AN,
8201 ET,
8202 WS,
8203 RLO,
8204 LRO,
8205 PDF,
8206 RLE,
8207 RLI,
8208 FSI,
8209 PDI,
8210 LRI,
8211 B,
8212 S,
8213 LRE
8214 };
8215
8216 struct directions {
8217 uint32_t start_code;
8218 uint32_t final_code;
8219 direction direct;
8220 };
8221
8222 static directions dir_table[] = {
8223 {0x0, 0x8, direction::BN}, {0x9, 0x9, direction::S},
8224 {0xa, 0xa, direction::B}, {0xb, 0xb, direction::S},
8225 {0xc, 0xc, direction::WS}, {0xd, 0xd, direction::B},
8226 {0xe, 0x1b, direction::BN}, {0x1c, 0x1e, direction::B},
8227 {0x1f, 0x1f, direction::S}, {0x20, 0x20, direction::WS},
8228 {0x21, 0x22, direction::ON}, {0x23, 0x25, direction::ET},
8229 {0x26, 0x2a, direction::ON}, {0x2b, 0x2b, direction::ES},
8230 {0x2c, 0x2c, direction::CS}, {0x2d, 0x2d, direction::ES},
8231 {0x2e, 0x2f, direction::CS}, {0x30, 0x39, direction::EN},
8232 {0x3a, 0x3a, direction::CS}, {0x3b, 0x40, direction::ON},
8233 {0x41, 0x5a, direction::L}, {0x5b, 0x60, direction::ON},
8234 {0x61, 0x7a, direction::L}, {0x7b, 0x7e, direction::ON},
8235 {0x7f, 0x84, direction::BN}, {0x85, 0x85, direction::B},
8236 {0x86, 0x9f, direction::BN}, {0xa0, 0xa0, direction::CS},
8237 {0xa1, 0xa1, direction::ON}, {0xa2, 0xa5, direction::ET},
8238 {0xa6, 0xa9, direction::ON}, {0xaa, 0xaa, direction::L},
8239 {0xab, 0xac, direction::ON}, {0xad, 0xad, direction::BN},
8240 {0xae, 0xaf, direction::ON}, {0xb0, 0xb1, direction::ET},
8241 {0xb2, 0xb3, direction::EN}, {0xb4, 0xb4, direction::ON},
8242 {0xb5, 0xb5, direction::L}, {0xb6, 0xb8, direction::ON},
8243 {0xb9, 0xb9, direction::EN}, {0xba, 0xba, direction::L},
8244 {0xbb, 0xbf, direction::ON}, {0xc0, 0xd6, direction::L},
8245 {0xd7, 0xd7, direction::ON}, {0xd8, 0xf6, direction::L},
8246 {0xf7, 0xf7, direction::ON}, {0xf8, 0x2b8, direction::L},
8247 {0x2b9, 0x2ba, direction::ON}, {0x2bb, 0x2c1, direction::L},
8248 {0x2c2, 0x2cf, direction::ON}, {0x2d0, 0x2d1, direction::L},
8249 {0x2d2, 0x2df, direction::ON}, {0x2e0, 0x2e4, direction::L},
8250 {0x2e5, 0x2ed, direction::ON}, {0x2ee, 0x2ee, direction::L},
8251 {0x2ef, 0x2ff, direction::ON}, {0x300, 0x36f, direction::NSM},
8252 {0x370, 0x373, direction::L}, {0x374, 0x375, direction::ON},
8253 {0x376, 0x377, direction::L}, {0x37a, 0x37d, direction::L},
8254 {0x37e, 0x37e, direction::ON}, {0x37f, 0x37f, direction::L},
8255 {0x384, 0x385, direction::ON}, {0x386, 0x386, direction::L},
8256 {0x387, 0x387, direction::ON}, {0x388, 0x38a, direction::L},
8257 {0x38c, 0x38c, direction::L}, {0x38e, 0x3a1, direction::L},
8258 {0x3a3, 0x3f5, direction::L}, {0x3f6, 0x3f6, direction::ON},
8259 {0x3f7, 0x482, direction::L}, {0x483, 0x489, direction::NSM},
8260 {0x48a, 0x52f, direction::L}, {0x531, 0x556, direction::L},
8261 {0x559, 0x589, direction::L}, {0x58a, 0x58a, direction::ON},
8262 {0x58d, 0x58e, direction::ON}, {0x58f, 0x58f, direction::ET},
8263 {0x591, 0x5bd, direction::NSM}, {0x5be, 0x5be, direction::R},
8264 {0x5bf, 0x5bf, direction::NSM}, {0x5c0, 0x5c0, direction::R},
8265 {0x5c1, 0x5c2, direction::NSM}, {0x5c3, 0x5c3, direction::R},
8266 {0x5c4, 0x5c5, direction::NSM}, {0x5c6, 0x5c6, direction::R},
8267 {0x5c7, 0x5c7, direction::NSM}, {0x5d0, 0x5ea, direction::R},
8268 {0x5ef, 0x5f4, direction::R}, {0x600, 0x605, direction::AN},
8269 {0x606, 0x607, direction::ON}, {0x608, 0x608, direction::AL},
8270 {0x609, 0x60a, direction::ET}, {0x60b, 0x60b, direction::AL},
8271 {0x60c, 0x60c, direction::CS}, {0x60d, 0x60d, direction::AL},
8272 {0x60e, 0x60f, direction::ON}, {0x610, 0x61a, direction::NSM},
8273 {0x61b, 0x61c, direction::AL}, {0x61e, 0x64a, direction::AL},
8274 {0x64b, 0x65f, direction::NSM}, {0x660, 0x669, direction::AN},
8275 {0x66a, 0x66a, direction::ET}, {0x66b, 0x66c, direction::AN},
8276 {0x66d, 0x66f, direction::AL}, {0x670, 0x670, direction::NSM},
8277 {0x671, 0x6d5, direction::AL}, {0x6d6, 0x6dc, direction::NSM},
8278 {0x6dd, 0x6dd, direction::AN}, {0x6de, 0x6de, direction::ON},
8279 {0x6df, 0x6e4, direction::NSM}, {0x6e5, 0x6e6, direction::AL},
8280 {0x6e7, 0x6e8, direction::NSM}, {0x6e9, 0x6e9, direction::ON},
8281 {0x6ea, 0x6ed, direction::NSM}, {0x6ee, 0x6ef, direction::AL},
8282 {0x6f0, 0x6f9, direction::EN}, {0x6fa, 0x70d, direction::AL},
8283 {0x70f, 0x710, direction::AL}, {0x711, 0x711, direction::NSM},
8284 {0x712, 0x72f, direction::AL}, {0x730, 0x74a, direction::NSM},
8285 {0x74d, 0x7a5, direction::AL}, {0x7a6, 0x7b0, direction::NSM},
8286 {0x7b1, 0x7b1, direction::AL}, {0x7c0, 0x7ea, direction::R},
8287 {0x7eb, 0x7f3, direction::NSM}, {0x7f4, 0x7f5, direction::R},
8288 {0x7f6, 0x7f9, direction::ON}, {0x7fa, 0x7fa, direction::R},
8289 {0x7fd, 0x7fd, direction::NSM}, {0x7fe, 0x815, direction::R},
8290 {0x816, 0x819, direction::NSM}, {0x81a, 0x81a, direction::R},
8291 {0x81b, 0x823, direction::NSM}, {0x824, 0x824, direction::R},
8292 {0x825, 0x827, direction::NSM}, {0x828, 0x828, direction::R},
8293 {0x829, 0x82d, direction::NSM}, {0x830, 0x83e, direction::R},
8294 {0x840, 0x858, direction::R}, {0x859, 0x85b, direction::NSM},
8295 {0x85e, 0x85e, direction::R}, {0x860, 0x86a, direction::AL},
8296 {0x8a0, 0x8b4, direction::AL}, {0x8b6, 0x8c7, direction::AL},
8297 {0x8d3, 0x8e1, direction::NSM}, {0x8e2, 0x8e2, direction::AN},
8298 {0x8e3, 0x902, direction::NSM}, {0x903, 0x939, direction::L},
8299 {0x93a, 0x93a, direction::NSM}, {0x93b, 0x93b, direction::L},
8300 {0x93c, 0x93c, direction::NSM}, {0x93d, 0x940, direction::L},
8301 {0x941, 0x948, direction::NSM}, {0x949, 0x94c, direction::L},
8302 {0x94d, 0x94d, direction::NSM}, {0x94e, 0x950, direction::L},
8303 {0x951, 0x957, direction::NSM}, {0x958, 0x961, direction::L},
8304 {0x962, 0x963, direction::NSM}, {0x964, 0x980, direction::L},
8305 {0x981, 0x981, direction::NSM}, {0x982, 0x983, direction::L},
8306 {0x985, 0x98c, direction::L}, {0x98f, 0x990, direction::L},
8307 {0x993, 0x9a8, direction::L}, {0x9aa, 0x9b0, direction::L},
8308 {0x9b2, 0x9b2, direction::L}, {0x9b6, 0x9b9, direction::L},
8309 {0x9bc, 0x9bc, direction::NSM}, {0x9bd, 0x9c0, direction::L},
8310 {0x9c1, 0x9c4, direction::NSM}, {0x9c7, 0x9c8, direction::L},
8311 {0x9cb, 0x9cc, direction::L}, {0x9cd, 0x9cd, direction::NSM},
8312 {0x9ce, 0x9ce, direction::L}, {0x9d7, 0x9d7, direction::L},
8313 {0x9dc, 0x9dd, direction::L}, {0x9df, 0x9e1, direction::L},
8314 {0x9e2, 0x9e3, direction::NSM}, {0x9e6, 0x9f1, direction::L},
8315 {0x9f2, 0x9f3, direction::ET}, {0x9f4, 0x9fa, direction::L},
8316 {0x9fb, 0x9fb, direction::ET}, {0x9fc, 0x9fd, direction::L},
8317 {0x9fe, 0x9fe, direction::NSM}, {0xa01, 0xa02, direction::NSM},
8318 {0xa03, 0xa03, direction::L}, {0xa05, 0xa0a, direction::L},
8319 {0xa0f, 0xa10, direction::L}, {0xa13, 0xa28, direction::L},
8320 {0xa2a, 0xa30, direction::L}, {0xa32, 0xa33, direction::L},
8321 {0xa35, 0xa36, direction::L}, {0xa38, 0xa39, direction::L},
8322 {0xa3c, 0xa3c, direction::NSM}, {0xa3e, 0xa40, direction::L},
8323 {0xa41, 0xa42, direction::NSM}, {0xa47, 0xa48, direction::NSM},
8324 {0xa4b, 0xa4d, direction::NSM}, {0xa51, 0xa51, direction::NSM},
8325 {0xa59, 0xa5c, direction::L}, {0xa5e, 0xa5e, direction::L},
8326 {0xa66, 0xa6f, direction::L}, {0xa70, 0xa71, direction::NSM},
8327 {0xa72, 0xa74, direction::L}, {0xa75, 0xa75, direction::NSM},
8328 {0xa76, 0xa76, direction::L}, {0xa81, 0xa82, direction::NSM},
8329 {0xa83, 0xa83, direction::L}, {0xa85, 0xa8d, direction::L},
8330 {0xa8f, 0xa91, direction::L}, {0xa93, 0xaa8, direction::L},
8331 {0xaaa, 0xab0, direction::L}, {0xab2, 0xab3, direction::L},
8332 {0xab5, 0xab9, direction::L}, {0xabc, 0xabc, direction::NSM},
8333 {0xabd, 0xac0, direction::L}, {0xac1, 0xac5, direction::NSM},
8334 {0xac7, 0xac8, direction::NSM}, {0xac9, 0xac9, direction::L},
8335 {0xacb, 0xacc, direction::L}, {0xacd, 0xacd, direction::NSM},
8336 {0xad0, 0xad0, direction::L}, {0xae0, 0xae1, direction::L},
8337 {0xae2, 0xae3, direction::NSM}, {0xae6, 0xaf0, direction::L},
8338 {0xaf1, 0xaf1, direction::ET}, {0xaf9, 0xaf9, direction::L},
8339 {0xafa, 0xaff, direction::NSM}, {0xb01, 0xb01, direction::NSM},
8340 {0xb02, 0xb03, direction::L}, {0xb05, 0xb0c, direction::L},
8341 {0xb0f, 0xb10, direction::L}, {0xb13, 0xb28, direction::L},
8342 {0xb2a, 0xb30, direction::L}, {0xb32, 0xb33, direction::L},
8343 {0xb35, 0xb39, direction::L}, {0xb3c, 0xb3c, direction::NSM},
8344 {0xb3d, 0xb3e, direction::L}, {0xb3f, 0xb3f, direction::NSM},
8345 {0xb40, 0xb40, direction::L}, {0xb41, 0xb44, direction::NSM},
8346 {0xb47, 0xb48, direction::L}, {0xb4b, 0xb4c, direction::L},
8347 {0xb4d, 0xb4d, direction::NSM}, {0xb55, 0xb56, direction::NSM},
8348 {0xb57, 0xb57, direction::L}, {0xb5c, 0xb5d, direction::L},
8349 {0xb5f, 0xb61, direction::L}, {0xb62, 0xb63, direction::NSM},
8350 {0xb66, 0xb77, direction::L}, {0xb82, 0xb82, direction::NSM},
8351 {0xb83, 0xb83, direction::L}, {0xb85, 0xb8a, direction::L},
8352 {0xb8e, 0xb90, direction::L}, {0xb92, 0xb95, direction::L},
8353 {0xb99, 0xb9a, direction::L}, {0xb9c, 0xb9c, direction::L},
8354 {0xb9e, 0xb9f, direction::L}, {0xba3, 0xba4, direction::L},
8355 {0xba8, 0xbaa, direction::L}, {0xbae, 0xbb9, direction::L},
8356 {0xbbe, 0xbbf, direction::L}, {0xbc0, 0xbc0, direction::NSM},
8357 {0xbc1, 0xbc2, direction::L}, {0xbc6, 0xbc8, direction::L},
8358 {0xbca, 0xbcc, direction::L}, {0xbcd, 0xbcd, direction::NSM},
8359 {0xbd0, 0xbd0, direction::L}, {0xbd7, 0xbd7, direction::L},
8360 {0xbe6, 0xbf2, direction::L}, {0xbf3, 0xbf8, direction::ON},
8361 {0xbf9, 0xbf9, direction::ET}, {0xbfa, 0xbfa, direction::ON},
8362 {0xc00, 0xc00, direction::NSM}, {0xc01, 0xc03, direction::L},
8363 {0xc04, 0xc04, direction::NSM}, {0xc05, 0xc0c, direction::L},
8364 {0xc0e, 0xc10, direction::L}, {0xc12, 0xc28, direction::L},
8365 {0xc2a, 0xc39, direction::L}, {0xc3d, 0xc3d, direction::L},
8366 {0xc3e, 0xc40, direction::NSM}, {0xc41, 0xc44, direction::L},
8367 {0xc46, 0xc48, direction::NSM}, {0xc4a, 0xc4d, direction::NSM},
8368 {0xc55, 0xc56, direction::NSM}, {0xc58, 0xc5a, direction::L},
8369 {0xc60, 0xc61, direction::L}, {0xc62, 0xc63, direction::NSM},
8370 {0xc66, 0xc6f, direction::L}, {0xc77, 0xc77, direction::L},
8371 {0xc78, 0xc7e, direction::ON}, {0xc7f, 0xc80, direction::L},
8372 {0xc81, 0xc81, direction::NSM}, {0xc82, 0xc8c, direction::L},
8373 {0xc8e, 0xc90, direction::L}, {0xc92, 0xca8, direction::L},
8374 {0xcaa, 0xcb3, direction::L}, {0xcb5, 0xcb9, direction::L},
8375 {0xcbc, 0xcbc, direction::NSM}, {0xcbd, 0xcc4, direction::L},
8376 {0xcc6, 0xcc8, direction::L}, {0xcca, 0xccb, direction::L},
8377 {0xccc, 0xccd, direction::NSM}, {0xcd5, 0xcd6, direction::L},
8378 {0xcde, 0xcde, direction::L}, {0xce0, 0xce1, direction::L},
8379 {0xce2, 0xce3, direction::NSM}, {0xce6, 0xcef, direction::L},
8380 {0xcf1, 0xcf2, direction::L}, {0xd00, 0xd01, direction::NSM},
8381 {0xd02, 0xd0c, direction::L}, {0xd0e, 0xd10, direction::L},
8382 {0xd12, 0xd3a, direction::L}, {0xd3b, 0xd3c, direction::NSM},
8383 {0xd3d, 0xd40, direction::L}, {0xd41, 0xd44, direction::NSM},
8384 {0xd46, 0xd48, direction::L}, {0xd4a, 0xd4c, direction::L},
8385 {0xd4d, 0xd4d, direction::NSM}, {0xd4e, 0xd4f, direction::L},
8386 {0xd54, 0xd61, direction::L}, {0xd62, 0xd63, direction::NSM},
8387 {0xd66, 0xd7f, direction::L}, {0xd81, 0xd81, direction::NSM},
8388 {0xd82, 0xd83, direction::L}, {0xd85, 0xd96, direction::L},
8389 {0xd9a, 0xdb1, direction::L}, {0xdb3, 0xdbb, direction::L},
8390 {0xdbd, 0xdbd, direction::L}, {0xdc0, 0xdc6, direction::L},
8391 {0xdca, 0xdca, direction::NSM}, {0xdcf, 0xdd1, direction::L},
8392 {0xdd2, 0xdd4, direction::NSM}, {0xdd6, 0xdd6, direction::NSM},
8393 {0xdd8, 0xddf, direction::L}, {0xde6, 0xdef, direction::L},
8394 {0xdf2, 0xdf4, direction::L}, {0xe01, 0xe30, direction::L},
8395 {0xe31, 0xe31, direction::NSM}, {0xe32, 0xe33, direction::L},
8396 {0xe34, 0xe3a, direction::NSM}, {0xe3f, 0xe3f, direction::ET},
8397 {0xe40, 0xe46, direction::L}, {0xe47, 0xe4e, direction::NSM},
8398 {0xe4f, 0xe5b, direction::L}, {0xe81, 0xe82, direction::L},
8399 {0xe84, 0xe84, direction::L}, {0xe86, 0xe8a, direction::L},
8400 {0xe8c, 0xea3, direction::L}, {0xea5, 0xea5, direction::L},
8401 {0xea7, 0xeb0, direction::L}, {0xeb1, 0xeb1, direction::NSM},
8402 {0xeb2, 0xeb3, direction::L}, {0xeb4, 0xebc, direction::NSM},
8403 {0xebd, 0xebd, direction::L}, {0xec0, 0xec4, direction::L},
8404 {0xec6, 0xec6, direction::L}, {0xec8, 0xecd, direction::NSM},
8405 {0xed0, 0xed9, direction::L}, {0xedc, 0xedf, direction::L},
8406 {0xf00, 0xf17, direction::L}, {0xf18, 0xf19, direction::NSM},
8407 {0xf1a, 0xf34, direction::L}, {0xf35, 0xf35, direction::NSM},
8408 {0xf36, 0xf36, direction::L}, {0xf37, 0xf37, direction::NSM},
8409 {0xf38, 0xf38, direction::L}, {0xf39, 0xf39, direction::NSM},
8410 {0xf3a, 0xf3d, direction::ON}, {0xf3e, 0xf47, direction::L},
8411 {0xf49, 0xf6c, direction::L}, {0xf71, 0xf7e, direction::NSM},
8412 {0xf7f, 0xf7f, direction::L}, {0xf80, 0xf84, direction::NSM},
8413 {0xf85, 0xf85, direction::L}, {0xf86, 0xf87, direction::NSM},
8414 {0xf88, 0xf8c, direction::L}, {0xf8d, 0xf97, direction::NSM},
8415 {0xf99, 0xfbc, direction::NSM}, {0xfbe, 0xfc5, direction::L},
8416 {0xfc6, 0xfc6, direction::NSM}, {0xfc7, 0xfcc, direction::L},
8417 {0xfce, 0xfda, direction::L}, {0x1000, 0x102c, direction::L},
8418 {0x102d, 0x1030, direction::NSM}, {0x1031, 0x1031, direction::L},
8419 {0x1032, 0x1037, direction::NSM}, {0x1038, 0x1038, direction::L},
8420 {0x1039, 0x103a, direction::NSM}, {0x103b, 0x103c, direction::L},
8421 {0x103d, 0x103e, direction::NSM}, {0x103f, 0x1057, direction::L},
8422 {0x1058, 0x1059, direction::NSM}, {0x105a, 0x105d, direction::L},
8423 {0x105e, 0x1060, direction::NSM}, {0x1061, 0x1070, direction::L},
8424 {0x1071, 0x1074, direction::NSM}, {0x1075, 0x1081, direction::L},
8425 {0x1082, 0x1082, direction::NSM}, {0x1083, 0x1084, direction::L},
8426 {0x1085, 0x1086, direction::NSM}, {0x1087, 0x108c, direction::L},
8427 {0x108d, 0x108d, direction::NSM}, {0x108e, 0x109c, direction::L},
8428 {0x109d, 0x109d, direction::NSM}, {0x109e, 0x10c5, direction::L},
8429 {0x10c7, 0x10c7, direction::L}, {0x10cd, 0x10cd, direction::L},
8430 {0x10d0, 0x1248, direction::L}, {0x124a, 0x124d, direction::L},
8431 {0x1250, 0x1256, direction::L}, {0x1258, 0x1258, direction::L},
8432 {0x125a, 0x125d, direction::L}, {0x1260, 0x1288, direction::L},
8433 {0x128a, 0x128d, direction::L}, {0x1290, 0x12b0, direction::L},
8434 {0x12b2, 0x12b5, direction::L}, {0x12b8, 0x12be, direction::L},
8435 {0x12c0, 0x12c0, direction::L}, {0x12c2, 0x12c5, direction::L},
8436 {0x12c8, 0x12d6, direction::L}, {0x12d8, 0x1310, direction::L},
8437 {0x1312, 0x1315, direction::L}, {0x1318, 0x135a, direction::L},
8438 {0x135d, 0x135f, direction::NSM}, {0x1360, 0x137c, direction::L},
8439 {0x1380, 0x138f, direction::L}, {0x1390, 0x1399, direction::ON},
8440 {0x13a0, 0x13f5, direction::L}, {0x13f8, 0x13fd, direction::L},
8441 {0x1400, 0x1400, direction::ON}, {0x1401, 0x167f, direction::L},
8442 {0x1680, 0x1680, direction::WS}, {0x1681, 0x169a, direction::L},
8443 {0x169b, 0x169c, direction::ON}, {0x16a0, 0x16f8, direction::L},
8444 {0x1700, 0x170c, direction::L}, {0x170e, 0x1711, direction::L},
8445 {0x1712, 0x1714, direction::NSM}, {0x1720, 0x1731, direction::L},
8446 {0x1732, 0x1734, direction::NSM}, {0x1735, 0x1736, direction::L},
8447 {0x1740, 0x1751, direction::L}, {0x1752, 0x1753, direction::NSM},
8448 {0x1760, 0x176c, direction::L}, {0x176e, 0x1770, direction::L},
8449 {0x1772, 0x1773, direction::NSM}, {0x1780, 0x17b3, direction::L},
8450 {0x17b4, 0x17b5, direction::NSM}, {0x17b6, 0x17b6, direction::L},
8451 {0x17b7, 0x17bd, direction::NSM}, {0x17be, 0x17c5, direction::L},
8452 {0x17c6, 0x17c6, direction::NSM}, {0x17c7, 0x17c8, direction::L},
8453 {0x17c9, 0x17d3, direction::NSM}, {0x17d4, 0x17da, direction::L},
8454 {0x17db, 0x17db, direction::ET}, {0x17dc, 0x17dc, direction::L},
8455 {0x17dd, 0x17dd, direction::NSM}, {0x17e0, 0x17e9, direction::L},
8456 {0x17f0, 0x17f9, direction::ON}, {0x1800, 0x180a, direction::ON},
8457 {0x180b, 0x180d, direction::NSM}, {0x180e, 0x180e, direction::BN},
8458 {0x1810, 0x1819, direction::L}, {0x1820, 0x1878, direction::L},
8459 {0x1880, 0x1884, direction::L}, {0x1885, 0x1886, direction::NSM},
8460 {0x1887, 0x18a8, direction::L}, {0x18a9, 0x18a9, direction::NSM},
8461 {0x18aa, 0x18aa, direction::L}, {0x18b0, 0x18f5, direction::L},
8462 {0x1900, 0x191e, direction::L}, {0x1920, 0x1922, direction::NSM},
8463 {0x1923, 0x1926, direction::L}, {0x1927, 0x1928, direction::NSM},
8464 {0x1929, 0x192b, direction::L}, {0x1930, 0x1931, direction::L},
8465 {0x1932, 0x1932, direction::NSM}, {0x1933, 0x1938, direction::L},
8466 {0x1939, 0x193b, direction::NSM}, {0x1940, 0x1940, direction::ON},
8467 {0x1944, 0x1945, direction::ON}, {0x1946, 0x196d, direction::L},
8468 {0x1970, 0x1974, direction::L}, {0x1980, 0x19ab, direction::L},
8469 {0x19b0, 0x19c9, direction::L}, {0x19d0, 0x19da, direction::L},
8470 {0x19de, 0x19ff, direction::ON}, {0x1a00, 0x1a16, direction::L},
8471 {0x1a17, 0x1a18, direction::NSM}, {0x1a19, 0x1a1a, direction::L},
8472 {0x1a1b, 0x1a1b, direction::NSM}, {0x1a1e, 0x1a55, direction::L},
8473 {0x1a56, 0x1a56, direction::NSM}, {0x1a57, 0x1a57, direction::L},
8474 {0x1a58, 0x1a5e, direction::NSM}, {0x1a60, 0x1a60, direction::NSM},
8475 {0x1a61, 0x1a61, direction::L}, {0x1a62, 0x1a62, direction::NSM},
8476 {0x1a63, 0x1a64, direction::L}, {0x1a65, 0x1a6c, direction::NSM},
8477 {0x1a6d, 0x1a72, direction::L}, {0x1a73, 0x1a7c, direction::NSM},
8478 {0x1a7f, 0x1a7f, direction::NSM}, {0x1a80, 0x1a89, direction::L},
8479 {0x1a90, 0x1a99, direction::L}, {0x1aa0, 0x1aad, direction::L},
8480 {0x1ab0, 0x1ac0, direction::NSM}, {0x1b00, 0x1b03, direction::NSM},
8481 {0x1b04, 0x1b33, direction::L}, {0x1b34, 0x1b34, direction::NSM},
8482 {0x1b35, 0x1b35, direction::L}, {0x1b36, 0x1b3a, direction::NSM},
8483 {0x1b3b, 0x1b3b, direction::L}, {0x1b3c, 0x1b3c, direction::NSM},
8484 {0x1b3d, 0x1b41, direction::L}, {0x1b42, 0x1b42, direction::NSM},
8485 {0x1b43, 0x1b4b, direction::L}, {0x1b50, 0x1b6a, direction::L},
8486 {0x1b6b, 0x1b73, direction::NSM}, {0x1b74, 0x1b7c, direction::L},
8487 {0x1b80, 0x1b81, direction::NSM}, {0x1b82, 0x1ba1, direction::L},
8488 {0x1ba2, 0x1ba5, direction::NSM}, {0x1ba6, 0x1ba7, direction::L},
8489 {0x1ba8, 0x1ba9, direction::NSM}, {0x1baa, 0x1baa, direction::L},
8490 {0x1bab, 0x1bad, direction::NSM}, {0x1bae, 0x1be5, direction::L},
8491 {0x1be6, 0x1be6, direction::NSM}, {0x1be7, 0x1be7, direction::L},
8492 {0x1be8, 0x1be9, direction::NSM}, {0x1bea, 0x1bec, direction::L},
8493 {0x1bed, 0x1bed, direction::NSM}, {0x1bee, 0x1bee, direction::L},
8494 {0x1bef, 0x1bf1, direction::NSM}, {0x1bf2, 0x1bf3, direction::L},
8495 {0x1bfc, 0x1c2b, direction::L}, {0x1c2c, 0x1c33, direction::NSM},
8496 {0x1c34, 0x1c35, direction::L}, {0x1c36, 0x1c37, direction::NSM},
8497 {0x1c3b, 0x1c49, direction::L}, {0x1c4d, 0x1c88, direction::L},
8498 {0x1c90, 0x1cba, direction::L}, {0x1cbd, 0x1cc7, direction::L},
8499 {0x1cd0, 0x1cd2, direction::NSM}, {0x1cd3, 0x1cd3, direction::L},
8500 {0x1cd4, 0x1ce0, direction::NSM}, {0x1ce1, 0x1ce1, direction::L},
8501 {0x1ce2, 0x1ce8, direction::NSM}, {0x1ce9, 0x1cec, direction::L},
8502 {0x1ced, 0x1ced, direction::NSM}, {0x1cee, 0x1cf3, direction::L},
8503 {0x1cf4, 0x1cf4, direction::NSM}, {0x1cf5, 0x1cf7, direction::L},
8504 {0x1cf8, 0x1cf9, direction::NSM}, {0x1cfa, 0x1cfa, direction::L},
8505 {0x1d00, 0x1dbf, direction::L}, {0x1dc0, 0x1df9, direction::NSM},
8506 {0x1dfb, 0x1dff, direction::NSM}, {0x1e00, 0x1f15, direction::L},
8507 {0x1f18, 0x1f1d, direction::L}, {0x1f20, 0x1f45, direction::L},
8508 {0x1f48, 0x1f4d, direction::L}, {0x1f50, 0x1f57, direction::L},
8509 {0x1f59, 0x1f59, direction::L}, {0x1f5b, 0x1f5b, direction::L},
8510 {0x1f5d, 0x1f5d, direction::L}, {0x1f5f, 0x1f7d, direction::L},
8511 {0x1f80, 0x1fb4, direction::L}, {0x1fb6, 0x1fbc, direction::L},
8512 {0x1fbd, 0x1fbd, direction::ON}, {0x1fbe, 0x1fbe, direction::L},
8513 {0x1fbf, 0x1fc1, direction::ON}, {0x1fc2, 0x1fc4, direction::L},
8514 {0x1fc6, 0x1fcc, direction::L}, {0x1fcd, 0x1fcf, direction::ON},
8515 {0x1fd0, 0x1fd3, direction::L}, {0x1fd6, 0x1fdb, direction::L},
8516 {0x1fdd, 0x1fdf, direction::ON}, {0x1fe0, 0x1fec, direction::L},
8517 {0x1fed, 0x1fef, direction::ON}, {0x1ff2, 0x1ff4, direction::L},
8518 {0x1ff6, 0x1ffc, direction::L}, {0x1ffd, 0x1ffe, direction::ON},
8519 {0x2000, 0x200a, direction::WS}, {0x200b, 0x200d, direction::BN},
8520 {0x200e, 0x200e, direction::L}, {0x200f, 0x200f, direction::R},
8521 {0x2010, 0x2027, direction::ON}, {0x2028, 0x2028, direction::WS},
8522 {0x2029, 0x2029, direction::B}, {0x202a, 0x202a, direction::LRE},
8523 {0x202b, 0x202b, direction::RLE}, {0x202c, 0x202c, direction::PDF},
8524 {0x202d, 0x202d, direction::LRO}, {0x202e, 0x202e, direction::RLO},
8525 {0x202f, 0x202f, direction::CS}, {0x2030, 0x2034, direction::ET},
8526 {0x2035, 0x2043, direction::ON}, {0x2044, 0x2044, direction::CS},
8527 {0x2045, 0x205e, direction::ON}, {0x205f, 0x205f, direction::WS},
8528 {0x2060, 0x2064, direction::BN}, {0x2066, 0x2066, direction::LRI},
8529 {0x2067, 0x2067, direction::RLI}, {0x2068, 0x2068, direction::FSI},
8530 {0x2069, 0x2069, direction::PDI}, {0x206a, 0x206f, direction::BN},
8531 {0x2070, 0x2070, direction::EN}, {0x2071, 0x2071, direction::L},
8532 {0x2074, 0x2079, direction::EN}, {0x207a, 0x207b, direction::ES},
8533 {0x207c, 0x207e, direction::ON}, {0x207f, 0x207f, direction::L},
8534 {0x2080, 0x2089, direction::EN}, {0x208a, 0x208b, direction::ES},
8535 {0x208c, 0x208e, direction::ON}, {0x2090, 0x209c, direction::L},
8536 {0x20a0, 0x20bf, direction::ET}, {0x20d0, 0x20f0, direction::NSM},
8537 {0x2100, 0x2101, direction::ON}, {0x2102, 0x2102, direction::L},
8538 {0x2103, 0x2106, direction::ON}, {0x2107, 0x2107, direction::L},
8539 {0x2108, 0x2109, direction::ON}, {0x210a, 0x2113, direction::L},
8540 {0x2114, 0x2114, direction::ON}, {0x2115, 0x2115, direction::L},
8541 {0x2116, 0x2118, direction::ON}, {0x2119, 0x211d, direction::L},
8542 {0x211e, 0x2123, direction::ON}, {0x2124, 0x2124, direction::L},
8543 {0x2125, 0x2125, direction::ON}, {0x2126, 0x2126, direction::L},
8544 {0x2127, 0x2127, direction::ON}, {0x2128, 0x2128, direction::L},
8545 {0x2129, 0x2129, direction::ON}, {0x212a, 0x212d, direction::L},
8546 {0x212e, 0x212e, direction::ET}, {0x212f, 0x2139, direction::L},
8547 {0x213a, 0x213b, direction::ON}, {0x213c, 0x213f, direction::L},
8548 {0x2140, 0x2144, direction::ON}, {0x2145, 0x2149, direction::L},
8549 {0x214a, 0x214d, direction::ON}, {0x214e, 0x214f, direction::L},
8550 {0x2150, 0x215f, direction::ON}, {0x2160, 0x2188, direction::L},
8551 {0x2189, 0x218b, direction::ON}, {0x2190, 0x2211, direction::ON},
8552 {0x2212, 0x2212, direction::ES}, {0x2213, 0x2213, direction::ET},
8553 {0x2214, 0x2335, direction::ON}, {0x2336, 0x237a, direction::L},
8554 {0x237b, 0x2394, direction::ON}, {0x2395, 0x2395, direction::L},
8555 {0x2396, 0x2426, direction::ON}, {0x2440, 0x244a, direction::ON},
8556 {0x2460, 0x2487, direction::ON}, {0x2488, 0x249b, direction::EN},
8557 {0x249c, 0x24e9, direction::L}, {0x24ea, 0x26ab, direction::ON},
8558 {0x26ac, 0x26ac, direction::L}, {0x26ad, 0x27ff, direction::ON},
8559 {0x2800, 0x28ff, direction::L}, {0x2900, 0x2b73, direction::ON},
8560 {0x2b76, 0x2b95, direction::ON}, {0x2b97, 0x2bff, direction::ON},
8561 {0x2c00, 0x2c2e, direction::L}, {0x2c30, 0x2c5e, direction::L},
8562 {0x2c60, 0x2ce4, direction::L}, {0x2ce5, 0x2cea, direction::ON},
8563 {0x2ceb, 0x2cee, direction::L}, {0x2cef, 0x2cf1, direction::NSM},
8564 {0x2cf2, 0x2cf3, direction::L}, {0x2cf9, 0x2cff, direction::ON},
8565 {0x2d00, 0x2d25, direction::L}, {0x2d27, 0x2d27, direction::L},
8566 {0x2d2d, 0x2d2d, direction::L}, {0x2d30, 0x2d67, direction::L},
8567 {0x2d6f, 0x2d70, direction::L}, {0x2d7f, 0x2d7f, direction::NSM},
8568 {0x2d80, 0x2d96, direction::L}, {0x2da0, 0x2da6, direction::L},
8569 {0x2da8, 0x2dae, direction::L}, {0x2db0, 0x2db6, direction::L},
8570 {0x2db8, 0x2dbe, direction::L}, {0x2dc0, 0x2dc6, direction::L},
8571 {0x2dc8, 0x2dce, direction::L}, {0x2dd0, 0x2dd6, direction::L},
8572 {0x2dd8, 0x2dde, direction::L}, {0x2de0, 0x2dff, direction::NSM},
8573 {0x2e00, 0x2e52, direction::ON}, {0x2e80, 0x2e99, direction::ON},
8574 {0x2e9b, 0x2ef3, direction::ON}, {0x2f00, 0x2fd5, direction::ON},
8575 {0x2ff0, 0x2ffb, direction::ON}, {0x3000, 0x3000, direction::WS},
8576 {0x3001, 0x3004, direction::ON}, {0x3005, 0x3007, direction::L},
8577 {0x3008, 0x3020, direction::ON}, {0x3021, 0x3029, direction::L},
8578 {0x302a, 0x302d, direction::NSM}, {0x302e, 0x302f, direction::L},
8579 {0x3030, 0x3030, direction::ON}, {0x3031, 0x3035, direction::L},
8580 {0x3036, 0x3037, direction::ON}, {0x3038, 0x303c, direction::L},
8581 {0x303d, 0x303f, direction::ON}, {0x3041, 0x3096, direction::L},
8582 {0x3099, 0x309a, direction::NSM}, {0x309b, 0x309c, direction::ON},
8583 {0x309d, 0x309f, direction::L}, {0x30a0, 0x30a0, direction::ON},
8584 {0x30a1, 0x30fa, direction::L}, {0x30fb, 0x30fb, direction::ON},
8585 {0x30fc, 0x30ff, direction::L}, {0x3105, 0x312f, direction::L},
8586 {0x3131, 0x318e, direction::L}, {0x3190, 0x31bf, direction::L},
8587 {0x31c0, 0x31e3, direction::ON}, {0x31f0, 0x321c, direction::L},
8588 {0x321d, 0x321e, direction::ON}, {0x3220, 0x324f, direction::L},
8589 {0x3250, 0x325f, direction::ON}, {0x3260, 0x327b, direction::L},
8590 {0x327c, 0x327e, direction::ON}, {0x327f, 0x32b0, direction::L},
8591 {0x32b1, 0x32bf, direction::ON}, {0x32c0, 0x32cb, direction::L},
8592 {0x32cc, 0x32cf, direction::ON}, {0x32d0, 0x3376, direction::L},
8593 {0x3377, 0x337a, direction::ON}, {0x337b, 0x33dd, direction::L},
8594 {0x33de, 0x33df, direction::ON}, {0x33e0, 0x33fe, direction::L},
8595 {0x33ff, 0x33ff, direction::ON}, {0x3400, 0x4dbf, direction::L},
8596 {0x4dc0, 0x4dff, direction::ON}, {0x4e00, 0x9ffc, direction::L},
8597 {0xa000, 0xa48c, direction::L}, {0xa490, 0xa4c6, direction::ON},
8598 {0xa4d0, 0xa60c, direction::L}, {0xa60d, 0xa60f, direction::ON},
8599 {0xa610, 0xa62b, direction::L}, {0xa640, 0xa66e, direction::L},
8600 {0xa66f, 0xa672, direction::NSM}, {0xa673, 0xa673, direction::ON},
8601 {0xa674, 0xa67d, direction::NSM}, {0xa67e, 0xa67f, direction::ON},
8602 {0xa680, 0xa69d, direction::L}, {0xa69e, 0xa69f, direction::NSM},
8603 {0xa6a0, 0xa6ef, direction::L}, {0xa6f0, 0xa6f1, direction::NSM},
8604 {0xa6f2, 0xa6f7, direction::L}, {0xa700, 0xa721, direction::ON},
8605 {0xa722, 0xa787, direction::L}, {0xa788, 0xa788, direction::ON},
8606 {0xa789, 0xa7bf, direction::L}, {0xa7c2, 0xa7ca, direction::L},
8607 {0xa7f5, 0xa801, direction::L}, {0xa802, 0xa802, direction::NSM},
8608 {0xa803, 0xa805, direction::L}, {0xa806, 0xa806, direction::NSM},
8609 {0xa807, 0xa80a, direction::L}, {0xa80b, 0xa80b, direction::NSM},
8610 {0xa80c, 0xa824, direction::L}, {0xa825, 0xa826, direction::NSM},
8611 {0xa827, 0xa827, direction::L}, {0xa828, 0xa82b, direction::ON},
8612 {0xa82c, 0xa82c, direction::NSM}, {0xa830, 0xa837, direction::L},
8613 {0xa838, 0xa839, direction::ET}, {0xa840, 0xa873, direction::L},
8614 {0xa874, 0xa877, direction::ON}, {0xa880, 0xa8c3, direction::L},
8615 {0xa8c4, 0xa8c5, direction::NSM}, {0xa8ce, 0xa8d9, direction::L},
8616 {0xa8e0, 0xa8f1, direction::NSM}, {0xa8f2, 0xa8fe, direction::L},
8617 {0xa8ff, 0xa8ff, direction::NSM}, {0xa900, 0xa925, direction::L},
8618 {0xa926, 0xa92d, direction::NSM}, {0xa92e, 0xa946, direction::L},
8619 {0xa947, 0xa951, direction::NSM}, {0xa952, 0xa953, direction::L},
8620 {0xa95f, 0xa97c, direction::L}, {0xa980, 0xa982, direction::NSM},
8621 {0xa983, 0xa9b2, direction::L}, {0xa9b3, 0xa9b3, direction::NSM},
8622 {0xa9b4, 0xa9b5, direction::L}, {0xa9b6, 0xa9b9, direction::NSM},
8623 {0xa9ba, 0xa9bb, direction::L}, {0xa9bc, 0xa9bd, direction::NSM},
8624 {0xa9be, 0xa9cd, direction::L}, {0xa9cf, 0xa9d9, direction::L},
8625 {0xa9de, 0xa9e4, direction::L}, {0xa9e5, 0xa9e5, direction::NSM},
8626 {0xa9e6, 0xa9fe, direction::L}, {0xaa00, 0xaa28, direction::L},
8627 {0xaa29, 0xaa2e, direction::NSM}, {0xaa2f, 0xaa30, direction::L},
8628 {0xaa31, 0xaa32, direction::NSM}, {0xaa33, 0xaa34, direction::L},
8629 {0xaa35, 0xaa36, direction::NSM}, {0xaa40, 0xaa42, direction::L},
8630 {0xaa43, 0xaa43, direction::NSM}, {0xaa44, 0xaa4b, direction::L},
8631 {0xaa4c, 0xaa4c, direction::NSM}, {0xaa4d, 0xaa4d, direction::L},
8632 {0xaa50, 0xaa59, direction::L}, {0xaa5c, 0xaa7b, direction::L},
8633 {0xaa7c, 0xaa7c, direction::NSM}, {0xaa7d, 0xaaaf, direction::L},
8634 {0xaab0, 0xaab0, direction::NSM}, {0xaab1, 0xaab1, direction::L},
8635 {0xaab2, 0xaab4, direction::NSM}, {0xaab5, 0xaab6, direction::L},
8636 {0xaab7, 0xaab8, direction::NSM}, {0xaab9, 0xaabd, direction::L},
8637 {0xaabe, 0xaabf, direction::NSM}, {0xaac0, 0xaac0, direction::L},
8638 {0xaac1, 0xaac1, direction::NSM}, {0xaac2, 0xaac2, direction::L},
8639 {0xaadb, 0xaaeb, direction::L}, {0xaaec, 0xaaed, direction::NSM},
8640 {0xaaee, 0xaaf5, direction::L}, {0xaaf6, 0xaaf6, direction::NSM},
8641 {0xab01, 0xab06, direction::L}, {0xab09, 0xab0e, direction::L},
8642 {0xab11, 0xab16, direction::L}, {0xab20, 0xab26, direction::L},
8643 {0xab28, 0xab2e, direction::L}, {0xab30, 0xab69, direction::L},
8644 {0xab6a, 0xab6b, direction::ON}, {0xab70, 0xabe4, direction::L},
8645 {0xabe5, 0xabe5, direction::NSM}, {0xabe6, 0xabe7, direction::L},
8646 {0xabe8, 0xabe8, direction::NSM}, {0xabe9, 0xabec, direction::L},
8647 {0xabed, 0xabed, direction::NSM}, {0xabf0, 0xabf9, direction::L},
8648 {0xac00, 0xd7a3, direction::L}, {0xd7b0, 0xd7c6, direction::L},
8649 {0xd7cb, 0xd7fb, direction::L}, {0xd800, 0xfa6d, direction::L},
8650 {0xfa70, 0xfad9, direction::L}, {0xfb00, 0xfb06, direction::L},
8651 {0xfb13, 0xfb17, direction::L}, {0xfb1d, 0xfb1d, direction::R},
8652 {0xfb1e, 0xfb1e, direction::NSM}, {0xfb1f, 0xfb28, direction::R},
8653 {0xfb29, 0xfb29, direction::ES}, {0xfb2a, 0xfb36, direction::R},
8654 {0xfb38, 0xfb3c, direction::R}, {0xfb3e, 0xfb3e, direction::R},
8655 {0xfb40, 0xfb41, direction::R}, {0xfb43, 0xfb44, direction::R},
8656 {0xfb46, 0xfb4f, direction::R}, {0xfb50, 0xfbc1, direction::AL},
8657 {0xfbd3, 0xfd3d, direction::AL}, {0xfd3e, 0xfd3f, direction::ON},
8658 {0xfd50, 0xfd8f, direction::AL}, {0xfd92, 0xfdc7, direction::AL},
8659 {0xfdf0, 0xfdfc, direction::AL}, {0xfdfd, 0xfdfd, direction::ON},
8660 {0xfe00, 0xfe0f, direction::NSM}, {0xfe10, 0xfe19, direction::ON},
8661 {0xfe20, 0xfe2f, direction::NSM}, {0xfe30, 0xfe4f, direction::ON},
8662 {0xfe50, 0xfe50, direction::CS}, {0xfe51, 0xfe51, direction::ON},
8663 {0xfe52, 0xfe52, direction::CS}, {0xfe54, 0xfe54, direction::ON},
8664 {0xfe55, 0xfe55, direction::CS}, {0xfe56, 0xfe5e, direction::ON},
8665 {0xfe5f, 0xfe5f, direction::ET}, {0xfe60, 0xfe61, direction::ON},
8666 {0xfe62, 0xfe63, direction::ES}, {0xfe64, 0xfe66, direction::ON},
8667 {0xfe68, 0xfe68, direction::ON}, {0xfe69, 0xfe6a, direction::ET},
8668 {0xfe6b, 0xfe6b, direction::ON}, {0xfe70, 0xfe74, direction::AL},
8669 {0xfe76, 0xfefc, direction::AL}, {0xfeff, 0xfeff, direction::BN},
8670 {0xff01, 0xff02, direction::ON}, {0xff03, 0xff05, direction::ET},
8671 {0xff06, 0xff0a, direction::ON}, {0xff0b, 0xff0b, direction::ES},
8672 {0xff0c, 0xff0c, direction::CS}, {0xff0d, 0xff0d, direction::ES},
8673 {0xff0e, 0xff0f, direction::CS}, {0xff10, 0xff19, direction::EN},
8674 {0xff1a, 0xff1a, direction::CS}, {0xff1b, 0xff20, direction::ON},
8675 {0xff21, 0xff3a, direction::L}, {0xff3b, 0xff40, direction::ON},
8676 {0xff41, 0xff5a, direction::L}, {0xff5b, 0xff65, direction::ON},
8677 {0xff66, 0xffbe, direction::L}, {0xffc2, 0xffc7, direction::L},
8678 {0xffca, 0xffcf, direction::L}, {0xffd2, 0xffd7, direction::L},
8679 {0xffda, 0xffdc, direction::L}, {0xffe0, 0xffe1, direction::ET},
8680 {0xffe2, 0xffe4, direction::ON}, {0xffe5, 0xffe6, direction::ET},
8681 {0xffe8, 0xffee, direction::ON}, {0xfff9, 0xfffd, direction::ON},
8682 {0x10000, 0x1000b, direction::L}, {0x1000d, 0x10026, direction::L},
8683 {0x10028, 0x1003a, direction::L}, {0x1003c, 0x1003d, direction::L},
8684 {0x1003f, 0x1004d, direction::L}, {0x10050, 0x1005d, direction::L},
8685 {0x10080, 0x100fa, direction::L}, {0x10100, 0x10100, direction::L},
8686 {0x10101, 0x10101, direction::ON}, {0x10102, 0x10102, direction::L},
8687 {0x10107, 0x10133, direction::L}, {0x10137, 0x1013f, direction::L},
8688 {0x10140, 0x1018c, direction::ON}, {0x1018d, 0x1018e, direction::L},
8689 {0x10190, 0x1019c, direction::ON}, {0x101a0, 0x101a0, direction::ON},
8690 {0x101d0, 0x101fc, direction::L}, {0x101fd, 0x101fd, direction::NSM},
8691 {0x10280, 0x1029c, direction::L}, {0x102a0, 0x102d0, direction::L},
8692 {0x102e0, 0x102e0, direction::NSM}, {0x102e1, 0x102fb, direction::EN},
8693 {0x10300, 0x10323, direction::L}, {0x1032d, 0x1034a, direction::L},
8694 {0x10350, 0x10375, direction::L}, {0x10376, 0x1037a, direction::NSM},
8695 {0x10380, 0x1039d, direction::L}, {0x1039f, 0x103c3, direction::L},
8696 {0x103c8, 0x103d5, direction::L}, {0x10400, 0x1049d, direction::L},
8697 {0x104a0, 0x104a9, direction::L}, {0x104b0, 0x104d3, direction::L},
8698 {0x104d8, 0x104fb, direction::L}, {0x10500, 0x10527, direction::L},
8699 {0x10530, 0x10563, direction::L}, {0x1056f, 0x1056f, direction::L},
8700 {0x10600, 0x10736, direction::L}, {0x10740, 0x10755, direction::L},
8701 {0x10760, 0x10767, direction::L}, {0x10800, 0x10805, direction::R},
8702 {0x10808, 0x10808, direction::R}, {0x1080a, 0x10835, direction::R},
8703 {0x10837, 0x10838, direction::R}, {0x1083c, 0x1083c, direction::R},
8704 {0x1083f, 0x10855, direction::R}, {0x10857, 0x1089e, direction::R},
8705 {0x108a7, 0x108af, direction::R}, {0x108e0, 0x108f2, direction::R},
8706 {0x108f4, 0x108f5, direction::R}, {0x108fb, 0x1091b, direction::R},
8707 {0x1091f, 0x1091f, direction::ON}, {0x10920, 0x10939, direction::R},
8708 {0x1093f, 0x1093f, direction::R}, {0x10980, 0x109b7, direction::R},
8709 {0x109bc, 0x109cf, direction::R}, {0x109d2, 0x10a00, direction::R},
8710 {0x10a01, 0x10a03, direction::NSM}, {0x10a05, 0x10a06, direction::NSM},
8711 {0x10a0c, 0x10a0f, direction::NSM}, {0x10a10, 0x10a13, direction::R},
8712 {0x10a15, 0x10a17, direction::R}, {0x10a19, 0x10a35, direction::R},
8713 {0x10a38, 0x10a3a, direction::NSM}, {0x10a3f, 0x10a3f, direction::NSM},
8714 {0x10a40, 0x10a48, direction::R}, {0x10a50, 0x10a58, direction::R},
8715 {0x10a60, 0x10a9f, direction::R}, {0x10ac0, 0x10ae4, direction::R},
8716 {0x10ae5, 0x10ae6, direction::NSM}, {0x10aeb, 0x10af6, direction::R},
8717 {0x10b00, 0x10b35, direction::R}, {0x10b39, 0x10b3f, direction::ON},
8718 {0x10b40, 0x10b55, direction::R}, {0x10b58, 0x10b72, direction::R},
8719 {0x10b78, 0x10b91, direction::R}, {0x10b99, 0x10b9c, direction::R},
8720 {0x10ba9, 0x10baf, direction::R}, {0x10c00, 0x10c48, direction::R},
8721 {0x10c80, 0x10cb2, direction::R}, {0x10cc0, 0x10cf2, direction::R},
8722 {0x10cfa, 0x10cff, direction::R}, {0x10d00, 0x10d23, direction::AL},
8723 {0x10d24, 0x10d27, direction::NSM}, {0x10d30, 0x10d39, direction::AN},
8724 {0x10e60, 0x10e7e, direction::AN}, {0x10e80, 0x10ea9, direction::R},
8725 {0x10eab, 0x10eac, direction::NSM}, {0x10ead, 0x10ead, direction::R},
8726 {0x10eb0, 0x10eb1, direction::R}, {0x10f00, 0x10f27, direction::R},
8727 {0x10f30, 0x10f45, direction::AL}, {0x10f46, 0x10f50, direction::NSM},
8728 {0x10f51, 0x10f59, direction::AL}, {0x10fb0, 0x10fcb, direction::R},
8729 {0x10fe0, 0x10ff6, direction::R}, {0x11000, 0x11000, direction::L},
8730 {0x11001, 0x11001, direction::NSM}, {0x11002, 0x11037, direction::L},
8731 {0x11038, 0x11046, direction::NSM}, {0x11047, 0x1104d, direction::L},
8732 {0x11052, 0x11065, direction::ON}, {0x11066, 0x1106f, direction::L},
8733 {0x1107f, 0x11081, direction::NSM}, {0x11082, 0x110b2, direction::L},
8734 {0x110b3, 0x110b6, direction::NSM}, {0x110b7, 0x110b8, direction::L},
8735 {0x110b9, 0x110ba, direction::NSM}, {0x110bb, 0x110c1, direction::L},
8736 {0x110cd, 0x110cd, direction::L}, {0x110d0, 0x110e8, direction::L},
8737 {0x110f0, 0x110f9, direction::L}, {0x11100, 0x11102, direction::NSM},
8738 {0x11103, 0x11126, direction::L}, {0x11127, 0x1112b, direction::NSM},
8739 {0x1112c, 0x1112c, direction::L}, {0x1112d, 0x11134, direction::NSM},
8740 {0x11136, 0x11147, direction::L}, {0x11150, 0x11172, direction::L},
8741 {0x11173, 0x11173, direction::NSM}, {0x11174, 0x11176, direction::L},
8742 {0x11180, 0x11181, direction::NSM}, {0x11182, 0x111b5, direction::L},
8743 {0x111b6, 0x111be, direction::NSM}, {0x111bf, 0x111c8, direction::L},
8744 {0x111c9, 0x111cc, direction::NSM}, {0x111cd, 0x111ce, direction::L},
8745 {0x111cf, 0x111cf, direction::NSM}, {0x111d0, 0x111df, direction::L},
8746 {0x111e1, 0x111f4, direction::L}, {0x11200, 0x11211, direction::L},
8747 {0x11213, 0x1122e, direction::L}, {0x1122f, 0x11231, direction::NSM},
8748 {0x11232, 0x11233, direction::L}, {0x11234, 0x11234, direction::NSM},
8749 {0x11235, 0x11235, direction::L}, {0x11236, 0x11237, direction::NSM},
8750 {0x11238, 0x1123d, direction::L}, {0x1123e, 0x1123e, direction::NSM},
8751 {0x11280, 0x11286, direction::L}, {0x11288, 0x11288, direction::L},
8752 {0x1128a, 0x1128d, direction::L}, {0x1128f, 0x1129d, direction::L},
8753 {0x1129f, 0x112a9, direction::L}, {0x112b0, 0x112de, direction::L},
8754 {0x112df, 0x112df, direction::NSM}, {0x112e0, 0x112e2, direction::L},
8755 {0x112e3, 0x112ea, direction::NSM}, {0x112f0, 0x112f9, direction::L},
8756 {0x11300, 0x11301, direction::NSM}, {0x11302, 0x11303, direction::L},
8757 {0x11305, 0x1130c, direction::L}, {0x1130f, 0x11310, direction::L},
8758 {0x11313, 0x11328, direction::L}, {0x1132a, 0x11330, direction::L},
8759 {0x11332, 0x11333, direction::L}, {0x11335, 0x11339, direction::L},
8760 {0x1133b, 0x1133c, direction::NSM}, {0x1133d, 0x1133f, direction::L},
8761 {0x11340, 0x11340, direction::NSM}, {0x11341, 0x11344, direction::L},
8762 {0x11347, 0x11348, direction::L}, {0x1134b, 0x1134d, direction::L},
8763 {0x11350, 0x11350, direction::L}, {0x11357, 0x11357, direction::L},
8764 {0x1135d, 0x11363, direction::L}, {0x11366, 0x1136c, direction::NSM},
8765 {0x11370, 0x11374, direction::NSM}, {0x11400, 0x11437, direction::L},
8766 {0x11438, 0x1143f, direction::NSM}, {0x11440, 0x11441, direction::L},
8767 {0x11442, 0x11444, direction::NSM}, {0x11445, 0x11445, direction::L},
8768 {0x11446, 0x11446, direction::NSM}, {0x11447, 0x1145b, direction::L},
8769 {0x1145d, 0x1145d, direction::L}, {0x1145e, 0x1145e, direction::NSM},
8770 {0x1145f, 0x11461, direction::L}, {0x11480, 0x114b2, direction::L},
8771 {0x114b3, 0x114b8, direction::NSM}, {0x114b9, 0x114b9, direction::L},
8772 {0x114ba, 0x114ba, direction::NSM}, {0x114bb, 0x114be, direction::L},
8773 {0x114bf, 0x114c0, direction::NSM}, {0x114c1, 0x114c1, direction::L},
8774 {0x114c2, 0x114c3, direction::NSM}, {0x114c4, 0x114c7, direction::L},
8775 {0x114d0, 0x114d9, direction::L}, {0x11580, 0x115b1, direction::L},
8776 {0x115b2, 0x115b5, direction::NSM}, {0x115b8, 0x115bb, direction::L},
8777 {0x115bc, 0x115bd, direction::NSM}, {0x115be, 0x115be, direction::L},
8778 {0x115bf, 0x115c0, direction::NSM}, {0x115c1, 0x115db, direction::L},
8779 {0x115dc, 0x115dd, direction::NSM}, {0x11600, 0x11632, direction::L},
8780 {0x11633, 0x1163a, direction::NSM}, {0x1163b, 0x1163c, direction::L},
8781 {0x1163d, 0x1163d, direction::NSM}, {0x1163e, 0x1163e, direction::L},
8782 {0x1163f, 0x11640, direction::NSM}, {0x11641, 0x11644, direction::L},
8783 {0x11650, 0x11659, direction::L}, {0x11660, 0x1166c, direction::ON},
8784 {0x11680, 0x116aa, direction::L}, {0x116ab, 0x116ab, direction::NSM},
8785 {0x116ac, 0x116ac, direction::L}, {0x116ad, 0x116ad, direction::NSM},
8786 {0x116ae, 0x116af, direction::L}, {0x116b0, 0x116b5, direction::NSM},
8787 {0x116b6, 0x116b6, direction::L}, {0x116b7, 0x116b7, direction::NSM},
8788 {0x116b8, 0x116b8, direction::L}, {0x116c0, 0x116c9, direction::L},
8789 {0x11700, 0x1171a, direction::L}, {0x1171d, 0x1171f, direction::NSM},
8790 {0x11720, 0x11721, direction::L}, {0x11722, 0x11725, direction::NSM},
8791 {0x11726, 0x11726, direction::L}, {0x11727, 0x1172b, direction::NSM},
8792 {0x11730, 0x1173f, direction::L}, {0x11800, 0x1182e, direction::L},
8793 {0x1182f, 0x11837, direction::NSM}, {0x11838, 0x11838, direction::L},
8794 {0x11839, 0x1183a, direction::NSM}, {0x1183b, 0x1183b, direction::L},
8795 {0x118a0, 0x118f2, direction::L}, {0x118ff, 0x11906, direction::L},
8796 {0x11909, 0x11909, direction::L}, {0x1190c, 0x11913, direction::L},
8797 {0x11915, 0x11916, direction::L}, {0x11918, 0x11935, direction::L},
8798 {0x11937, 0x11938, direction::L}, {0x1193b, 0x1193c, direction::NSM},
8799 {0x1193d, 0x1193d, direction::L}, {0x1193e, 0x1193e, direction::NSM},
8800 {0x1193f, 0x11942, direction::L}, {0x11943, 0x11943, direction::NSM},
8801 {0x11944, 0x11946, direction::L}, {0x11950, 0x11959, direction::L},
8802 {0x119a0, 0x119a7, direction::L}, {0x119aa, 0x119d3, direction::L},
8803 {0x119d4, 0x119d7, direction::NSM}, {0x119da, 0x119db, direction::NSM},
8804 {0x119dc, 0x119df, direction::L}, {0x119e0, 0x119e0, direction::NSM},
8805 {0x119e1, 0x119e4, direction::L}, {0x11a00, 0x11a00, direction::L},
8806 {0x11a01, 0x11a06, direction::NSM}, {0x11a07, 0x11a08, direction::L},
8807 {0x11a09, 0x11a0a, direction::NSM}, {0x11a0b, 0x11a32, direction::L},
8808 {0x11a33, 0x11a38, direction::NSM}, {0x11a39, 0x11a3a, direction::L},
8809 {0x11a3b, 0x11a3e, direction::NSM}, {0x11a3f, 0x11a46, direction::L},
8810 {0x11a47, 0x11a47, direction::NSM}, {0x11a50, 0x11a50, direction::L},
8811 {0x11a51, 0x11a56, direction::NSM}, {0x11a57, 0x11a58, direction::L},
8812 {0x11a59, 0x11a5b, direction::NSM}, {0x11a5c, 0x11a89, direction::L},
8813 {0x11a8a, 0x11a96, direction::NSM}, {0x11a97, 0x11a97, direction::L},
8814 {0x11a98, 0x11a99, direction::NSM}, {0x11a9a, 0x11aa2, direction::L},
8815 {0x11ac0, 0x11af8, direction::L}, {0x11c00, 0x11c08, direction::L},
8816 {0x11c0a, 0x11c2f, direction::L}, {0x11c30, 0x11c36, direction::NSM},
8817 {0x11c38, 0x11c3d, direction::NSM}, {0x11c3e, 0x11c45, direction::L},
8818 {0x11c50, 0x11c6c, direction::L}, {0x11c70, 0x11c8f, direction::L},
8819 {0x11c92, 0x11ca7, direction::NSM}, {0x11ca9, 0x11ca9, direction::L},
8820 {0x11caa, 0x11cb0, direction::NSM}, {0x11cb1, 0x11cb1, direction::L},
8821 {0x11cb2, 0x11cb3, direction::NSM}, {0x11cb4, 0x11cb4, direction::L},
8822 {0x11cb5, 0x11cb6, direction::NSM}, {0x11d00, 0x11d06, direction::L},
8823 {0x11d08, 0x11d09, direction::L}, {0x11d0b, 0x11d30, direction::L},
8824 {0x11d31, 0x11d36, direction::NSM}, {0x11d3a, 0x11d3a, direction::NSM},
8825 {0x11d3c, 0x11d3d, direction::NSM}, {0x11d3f, 0x11d45, direction::NSM},
8826 {0x11d46, 0x11d46, direction::L}, {0x11d47, 0x11d47, direction::NSM},
8827 {0x11d50, 0x11d59, direction::L}, {0x11d60, 0x11d65, direction::L},
8828 {0x11d67, 0x11d68, direction::L}, {0x11d6a, 0x11d8e, direction::L},
8829 {0x11d90, 0x11d91, direction::NSM}, {0x11d93, 0x11d94, direction::L},
8830 {0x11d95, 0x11d95, direction::NSM}, {0x11d96, 0x11d96, direction::L},
8831 {0x11d97, 0x11d97, direction::NSM}, {0x11d98, 0x11d98, direction::L},
8832 {0x11da0, 0x11da9, direction::L}, {0x11ee0, 0x11ef2, direction::L},
8833 {0x11ef3, 0x11ef4, direction::NSM}, {0x11ef5, 0x11ef8, direction::L},
8834 {0x11fb0, 0x11fb0, direction::L}, {0x11fc0, 0x11fd4, direction::L},
8835 {0x11fd5, 0x11fdc, direction::ON}, {0x11fdd, 0x11fe0, direction::ET},
8836 {0x11fe1, 0x11ff1, direction::ON}, {0x11fff, 0x12399, direction::L},
8837 {0x12400, 0x1246e, direction::L}, {0x12470, 0x12474, direction::L},
8838 {0x12480, 0x12543, direction::L}, {0x13000, 0x1342e, direction::L},
8839 {0x13430, 0x13438, direction::L}, {0x14400, 0x14646, direction::L},
8840 {0x16800, 0x16a38, direction::L}, {0x16a40, 0x16a5e, direction::L},
8841 {0x16a60, 0x16a69, direction::L}, {0x16a6e, 0x16a6f, direction::L},
8842 {0x16ad0, 0x16aed, direction::L}, {0x16af0, 0x16af4, direction::NSM},
8843 {0x16af5, 0x16af5, direction::L}, {0x16b00, 0x16b2f, direction::L},
8844 {0x16b30, 0x16b36, direction::NSM}, {0x16b37, 0x16b45, direction::L},
8845 {0x16b50, 0x16b59, direction::L}, {0x16b5b, 0x16b61, direction::L},
8846 {0x16b63, 0x16b77, direction::L}, {0x16b7d, 0x16b8f, direction::L},
8847 {0x16e40, 0x16e9a, direction::L}, {0x16f00, 0x16f4a, direction::L},
8848 {0x16f4f, 0x16f4f, direction::NSM}, {0x16f50, 0x16f87, direction::L},
8849 {0x16f8f, 0x16f92, direction::NSM}, {0x16f93, 0x16f9f, direction::L},
8850 {0x16fe0, 0x16fe1, direction::L}, {0x16fe2, 0x16fe2, direction::ON},
8851 {0x16fe3, 0x16fe3, direction::L}, {0x16fe4, 0x16fe4, direction::NSM},
8852 {0x16ff0, 0x16ff1, direction::L}, {0x17000, 0x187f7, direction::L},
8853 {0x18800, 0x18cd5, direction::L}, {0x18d00, 0x18d08, direction::L},
8854 {0x1b000, 0x1b11e, direction::L}, {0x1b150, 0x1b152, direction::L},
8855 {0x1b164, 0x1b167, direction::L}, {0x1b170, 0x1b2fb, direction::L},
8856 {0x1bc00, 0x1bc6a, direction::L}, {0x1bc70, 0x1bc7c, direction::L},
8857 {0x1bc80, 0x1bc88, direction::L}, {0x1bc90, 0x1bc99, direction::L},
8858 {0x1bc9c, 0x1bc9c, direction::L}, {0x1bc9d, 0x1bc9e, direction::NSM},
8859 {0x1bc9f, 0x1bc9f, direction::L}, {0x1bca0, 0x1bca3, direction::BN},
8860 {0x1d000, 0x1d0f5, direction::L}, {0x1d100, 0x1d126, direction::L},
8861 {0x1d129, 0x1d166, direction::L}, {0x1d167, 0x1d169, direction::NSM},
8862 {0x1d16a, 0x1d172, direction::L}, {0x1d173, 0x1d17a, direction::BN},
8863 {0x1d17b, 0x1d182, direction::NSM}, {0x1d183, 0x1d184, direction::L},
8864 {0x1d185, 0x1d18b, direction::NSM}, {0x1d18c, 0x1d1a9, direction::L},
8865 {0x1d1aa, 0x1d1ad, direction::NSM}, {0x1d1ae, 0x1d1e8, direction::L},
8866 {0x1d200, 0x1d241, direction::ON}, {0x1d242, 0x1d244, direction::NSM},
8867 {0x1d245, 0x1d245, direction::ON}, {0x1d2e0, 0x1d2f3, direction::L},
8868 {0x1d300, 0x1d356, direction::ON}, {0x1d360, 0x1d378, direction::L},
8869 {0x1d400, 0x1d454, direction::L}, {0x1d456, 0x1d49c, direction::L},
8870 {0x1d49e, 0x1d49f, direction::L}, {0x1d4a2, 0x1d4a2, direction::L},
8871 {0x1d4a5, 0x1d4a6, direction::L}, {0x1d4a9, 0x1d4ac, direction::L},
8872 {0x1d4ae, 0x1d4b9, direction::L}, {0x1d4bb, 0x1d4bb, direction::L},
8873 {0x1d4bd, 0x1d4c3, direction::L}, {0x1d4c5, 0x1d505, direction::L},
8874 {0x1d507, 0x1d50a, direction::L}, {0x1d50d, 0x1d514, direction::L},
8875 {0x1d516, 0x1d51c, direction::L}, {0x1d51e, 0x1d539, direction::L},
8876 {0x1d53b, 0x1d53e, direction::L}, {0x1d540, 0x1d544, direction::L},
8877 {0x1d546, 0x1d546, direction::L}, {0x1d54a, 0x1d550, direction::L},
8878 {0x1d552, 0x1d6a5, direction::L}, {0x1d6a8, 0x1d6da, direction::L},
8879 {0x1d6db, 0x1d6db, direction::ON}, {0x1d6dc, 0x1d714, direction::L},
8880 {0x1d715, 0x1d715, direction::ON}, {0x1d716, 0x1d74e, direction::L},
8881 {0x1d74f, 0x1d74f, direction::ON}, {0x1d750, 0x1d788, direction::L},
8882 {0x1d789, 0x1d789, direction::ON}, {0x1d78a, 0x1d7c2, direction::L},
8883 {0x1d7c3, 0x1d7c3, direction::ON}, {0x1d7c4, 0x1d7cb, direction::L},
8884 {0x1d7ce, 0x1d7ff, direction::EN}, {0x1d800, 0x1d9ff, direction::L},
8885 {0x1da00, 0x1da36, direction::NSM}, {0x1da37, 0x1da3a, direction::L},
8886 {0x1da3b, 0x1da6c, direction::NSM}, {0x1da6d, 0x1da74, direction::L},
8887 {0x1da75, 0x1da75, direction::NSM}, {0x1da76, 0x1da83, direction::L},
8888 {0x1da84, 0x1da84, direction::NSM}, {0x1da85, 0x1da8b, direction::L},
8889 {0x1da9b, 0x1da9f, direction::NSM}, {0x1daa1, 0x1daaf, direction::NSM},
8890 {0x1e000, 0x1e006, direction::NSM}, {0x1e008, 0x1e018, direction::NSM},
8891 {0x1e01b, 0x1e021, direction::NSM}, {0x1e023, 0x1e024, direction::NSM},
8892 {0x1e026, 0x1e02a, direction::NSM}, {0x1e100, 0x1e12c, direction::L},
8893 {0x1e130, 0x1e136, direction::NSM}, {0x1e137, 0x1e13d, direction::L},
8894 {0x1e140, 0x1e149, direction::L}, {0x1e14e, 0x1e14f, direction::L},
8895 {0x1e2c0, 0x1e2eb, direction::L}, {0x1e2ec, 0x1e2ef, direction::NSM},
8896 {0x1e2f0, 0x1e2f9, direction::L}, {0x1e2ff, 0x1e2ff, direction::ET},
8897 {0x1e800, 0x1e8c4, direction::R}, {0x1e8c7, 0x1e8cf, direction::R},
8898 {0x1e8d0, 0x1e8d6, direction::NSM}, {0x1e900, 0x1e943, direction::R},
8899 {0x1e944, 0x1e94a, direction::NSM}, {0x1e94b, 0x1e94b, direction::R},
8900 {0x1e950, 0x1e959, direction::R}, {0x1e95e, 0x1e95f, direction::R},
8901 {0x1ec71, 0x1ecb4, direction::AL}, {0x1ed01, 0x1ed3d, direction::AL},
8902 {0x1ee00, 0x1ee03, direction::AL}, {0x1ee05, 0x1ee1f, direction::AL},
8903 {0x1ee21, 0x1ee22, direction::AL}, {0x1ee24, 0x1ee24, direction::AL},
8904 {0x1ee27, 0x1ee27, direction::AL}, {0x1ee29, 0x1ee32, direction::AL},
8905 {0x1ee34, 0x1ee37, direction::AL}, {0x1ee39, 0x1ee39, direction::AL},
8906 {0x1ee3b, 0x1ee3b, direction::AL}, {0x1ee42, 0x1ee42, direction::AL},
8907 {0x1ee47, 0x1ee47, direction::AL}, {0x1ee49, 0x1ee49, direction::AL},
8908 {0x1ee4b, 0x1ee4b, direction::AL}, {0x1ee4d, 0x1ee4f, direction::AL},
8909 {0x1ee51, 0x1ee52, direction::AL}, {0x1ee54, 0x1ee54, direction::AL},
8910 {0x1ee57, 0x1ee57, direction::AL}, {0x1ee59, 0x1ee59, direction::AL},
8911 {0x1ee5b, 0x1ee5b, direction::AL}, {0x1ee5d, 0x1ee5d, direction::AL},
8912 {0x1ee5f, 0x1ee5f, direction::AL}, {0x1ee61, 0x1ee62, direction::AL},
8913 {0x1ee64, 0x1ee64, direction::AL}, {0x1ee67, 0x1ee6a, direction::AL},
8914 {0x1ee6c, 0x1ee72, direction::AL}, {0x1ee74, 0x1ee77, direction::AL},
8915 {0x1ee79, 0x1ee7c, direction::AL}, {0x1ee7e, 0x1ee7e, direction::AL},
8916 {0x1ee80, 0x1ee89, direction::AL}, {0x1ee8b, 0x1ee9b, direction::AL},
8917 {0x1eea1, 0x1eea3, direction::AL}, {0x1eea5, 0x1eea9, direction::AL},
8918 {0x1eeab, 0x1eebb, direction::AL}, {0x1eef0, 0x1eef1, direction::ON},
8919 {0x1f000, 0x1f02b, direction::ON}, {0x1f030, 0x1f093, direction::ON},
8920 {0x1f0a0, 0x1f0ae, direction::ON}, {0x1f0b1, 0x1f0bf, direction::ON},
8921 {0x1f0c1, 0x1f0cf, direction::ON}, {0x1f0d1, 0x1f0f5, direction::ON},
8922 {0x1f100, 0x1f10a, direction::EN}, {0x1f10b, 0x1f10f, direction::ON},
8923 {0x1f110, 0x1f12e, direction::L}, {0x1f12f, 0x1f12f, direction::ON},
8924 {0x1f130, 0x1f169, direction::L}, {0x1f16a, 0x1f16f, direction::ON},
8925 {0x1f170, 0x1f1ac, direction::L}, {0x1f1ad, 0x1f1ad, direction::ON},
8926 {0x1f1e6, 0x1f202, direction::L}, {0x1f210, 0x1f23b, direction::L},
8927 {0x1f240, 0x1f248, direction::L}, {0x1f250, 0x1f251, direction::L},
8928 {0x1f260, 0x1f265, direction::ON}, {0x1f300, 0x1f6d7, direction::ON},
8929 {0x1f6e0, 0x1f6ec, direction::ON}, {0x1f6f0, 0x1f6fc, direction::ON},
8930 {0x1f700, 0x1f773, direction::ON}, {0x1f780, 0x1f7d8, direction::ON},
8931 {0x1f7e0, 0x1f7eb, direction::ON}, {0x1f800, 0x1f80b, direction::ON},
8932 {0x1f810, 0x1f847, direction::ON}, {0x1f850, 0x1f859, direction::ON},
8933 {0x1f860, 0x1f887, direction::ON}, {0x1f890, 0x1f8ad, direction::ON},
8934 {0x1f8b0, 0x1f8b1, direction::ON}, {0x1f900, 0x1f978, direction::ON},
8935 {0x1f97a, 0x1f9cb, direction::ON}, {0x1f9cd, 0x1fa53, direction::ON},
8936 {0x1fa60, 0x1fa6d, direction::ON}, {0x1fa70, 0x1fa74, direction::ON},
8937 {0x1fa78, 0x1fa7a, direction::ON}, {0x1fa80, 0x1fa86, direction::ON},
8938 {0x1fa90, 0x1faa8, direction::ON}, {0x1fab0, 0x1fab6, direction::ON},
8939 {0x1fac0, 0x1fac2, direction::ON}, {0x1fad0, 0x1fad6, direction::ON},
8940 {0x1fb00, 0x1fb92, direction::ON}, {0x1fb94, 0x1fbca, direction::ON},
8941 {0x1fbf0, 0x1fbf9, direction::EN}, {0x20000, 0x2a6dd, direction::L},
8942 {0x2a700, 0x2b734, direction::L}, {0x2b740, 0x2b81d, direction::L},
8943 {0x2b820, 0x2cea1, direction::L}, {0x2ceb0, 0x2ebe0, direction::L},
8944 {0x2f800, 0x2fa1d, direction::L}, {0x30000, 0x3134a, direction::L},
8945 {0xe0001, 0xe0001, direction::BN}, {0xe0020, 0xe007f, direction::BN},
8946 {0xe0100, 0xe01ef, direction::NSM}, {0xf0000, 0xffffd, direction::L},
8947 {0x100000, 0x10fffd, direction::L}};
8948
8949 // CheckJoiners and CheckBidi are true for URL specification.
8950
find_direction(uint32_t code_point)8951 inline static direction find_direction(uint32_t code_point) noexcept {
8952 auto it = std::lower_bound(
8953 std::begin(dir_table), std::end(dir_table), code_point,
8954 [](const directions& d, uint32_t c) { return d.final_code < c; });
8955
8956 // next check is almost surely in vain, but we use it for safety.
8957 if (it == std::end(dir_table)) {
8958 return direction::NONE;
8959 }
8960 // We have that d.final_code >= c.
8961 if (code_point >= it->start_code) {
8962 return it->direct;
8963 }
8964 return direction::NONE;
8965 }
8966
find_last_not_of_nsm(const std::u32string_view label)8967 inline static size_t find_last_not_of_nsm(
8968 const std::u32string_view label) noexcept {
8969 for (int i = label.size() - 1; i >= 0; i--)
8970 if (find_direction(label[i]) != direction::NSM) return i;
8971
8972 return std::u32string_view::npos;
8973 }
8974
8975 // An RTL label is a label that contains at least one character of type R, AL,
8976 // or AN. https://www.rfc-editor.org/rfc/rfc5893#section-2
is_rtl_label(const std::u32string_view label)8977 inline static bool is_rtl_label(const std::u32string_view label) noexcept {
8978 const size_t mask =
8979 (1u << direction::R) | (1u << direction::AL) | (1u << direction::AN);
8980
8981 size_t directions = 0;
8982 for (size_t i = 0; i < label.size(); i++) {
8983 directions |= 1u << find_direction(label[i]);
8984 }
8985 return (directions & mask) != 0;
8986 }
8987
is_label_valid(const std::u32string_view label)8988 bool is_label_valid(const std::u32string_view label) {
8989 if (label.empty()) {
8990 return true;
8991 }
8992
8993 ///////////////
8994 // We have a normalization step which ensures that we are in NFC.
8995 // If we receive punycode, we normalize and check that the normalized
8996 // version matches the original.
8997 // --------------------------------------
8998 // The label must be in Unicode Normalization Form NFC.
8999
9000 // Current URL standard indicatest that CheckHyphens is set to false.
9001 // ---------------------------------------
9002 // If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character
9003 // in both the third and fourth positions. If CheckHyphens, the label must
9004 // neither begin nor end with a U+002D HYPHEN-MINUS character.
9005
9006 // This is not necessary because we segment the
9007 // labels by '.'.
9008 // ---------------------------------------
9009 // The label must not contain a U+002E ( . ) FULL STOP.
9010 // if (label.find('.') != std::string_view::npos) return false;
9011
9012 // The label must not begin with a combining mark, that is:
9013 // General_Category=Mark.
9014 constexpr static uint32_t combining[] = {
9015 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, 0x307,
9016 0x308, 0x309, 0x30a, 0x30b, 0x30c, 0x30d, 0x30e, 0x30f,
9017 0x310, 0x311, 0x312, 0x313, 0x314, 0x315, 0x316, 0x317,
9018 0x318, 0x319, 0x31a, 0x31b, 0x31c, 0x31d, 0x31e, 0x31f,
9019 0x320, 0x321, 0x322, 0x323, 0x324, 0x325, 0x326, 0x327,
9020 0x328, 0x329, 0x32a, 0x32b, 0x32c, 0x32d, 0x32e, 0x32f,
9021 0x330, 0x331, 0x332, 0x333, 0x334, 0x335, 0x336, 0x337,
9022 0x338, 0x339, 0x33a, 0x33b, 0x33c, 0x33d, 0x33e, 0x33f,
9023 0x340, 0x341, 0x342, 0x343, 0x344, 0x345, 0x346, 0x347,
9024 0x348, 0x349, 0x34a, 0x34b, 0x34c, 0x34d, 0x34e, 0x34f,
9025 0x350, 0x351, 0x352, 0x353, 0x354, 0x355, 0x356, 0x357,
9026 0x358, 0x359, 0x35a, 0x35b, 0x35c, 0x35d, 0x35e, 0x35f,
9027 0x360, 0x361, 0x362, 0x363, 0x364, 0x365, 0x366, 0x367,
9028 0x368, 0x369, 0x36a, 0x36b, 0x36c, 0x36d, 0x36e, 0x36f,
9029 0x483, 0x484, 0x485, 0x486, 0x487, 0x488, 0x489, 0x591,
9030 0x592, 0x593, 0x594, 0x595, 0x596, 0x597, 0x598, 0x599,
9031 0x59a, 0x59b, 0x59c, 0x59d, 0x59e, 0x59f, 0x5a0, 0x5a1,
9032 0x5a2, 0x5a3, 0x5a4, 0x5a5, 0x5a6, 0x5a7, 0x5a8, 0x5a9,
9033 0x5aa, 0x5ab, 0x5ac, 0x5ad, 0x5ae, 0x5af, 0x5b0, 0x5b1,
9034 0x5b2, 0x5b3, 0x5b4, 0x5b5, 0x5b6, 0x5b7, 0x5b8, 0x5b9,
9035 0x5ba, 0x5bb, 0x5bc, 0x5bd, 0x5bf, 0x5c1, 0x5c2, 0x5c4,
9036 0x5c5, 0x5c7, 0x610, 0x611, 0x612, 0x613, 0x614, 0x615,
9037 0x616, 0x617, 0x618, 0x619, 0x61a, 0x64b, 0x64c, 0x64d,
9038 0x64e, 0x64f, 0x650, 0x651, 0x652, 0x653, 0x654, 0x655,
9039 0x656, 0x657, 0x658, 0x659, 0x65a, 0x65b, 0x65c, 0x65d,
9040 0x65e, 0x65f, 0x670, 0x6d6, 0x6d7, 0x6d8, 0x6d9, 0x6da,
9041 0x6db, 0x6dc, 0x6df, 0x6e0, 0x6e1, 0x6e2, 0x6e3, 0x6e4,
9042 0x6e7, 0x6e8, 0x6ea, 0x6eb, 0x6ec, 0x6ed, 0x711, 0x730,
9043 0x731, 0x732, 0x733, 0x734, 0x735, 0x736, 0x737, 0x738,
9044 0x739, 0x73a, 0x73b, 0x73c, 0x73d, 0x73e, 0x73f, 0x740,
9045 0x741, 0x742, 0x743, 0x744, 0x745, 0x746, 0x747, 0x748,
9046 0x749, 0x74a, 0x7a6, 0x7a7, 0x7a8, 0x7a9, 0x7aa, 0x7ab,
9047 0x7ac, 0x7ad, 0x7ae, 0x7af, 0x7b0, 0x7eb, 0x7ec, 0x7ed,
9048 0x7ee, 0x7ef, 0x7f0, 0x7f1, 0x7f2, 0x7f3, 0x7fd, 0x816,
9049 0x817, 0x818, 0x819, 0x81b, 0x81c, 0x81d, 0x81e, 0x81f,
9050 0x820, 0x821, 0x822, 0x823, 0x825, 0x826, 0x827, 0x829,
9051 0x82a, 0x82b, 0x82c, 0x82d, 0x859, 0x85a, 0x85b, 0x8d3,
9052 0x8d4, 0x8d5, 0x8d6, 0x8d7, 0x8d8, 0x8d9, 0x8da, 0x8db,
9053 0x8dc, 0x8dd, 0x8de, 0x8df, 0x8e0, 0x8e1, 0x8e3, 0x8e4,
9054 0x8e5, 0x8e6, 0x8e7, 0x8e8, 0x8e9, 0x8ea, 0x8eb, 0x8ec,
9055 0x8ed, 0x8ee, 0x8ef, 0x8f0, 0x8f1, 0x8f2, 0x8f3, 0x8f4,
9056 0x8f5, 0x8f6, 0x8f7, 0x8f8, 0x8f9, 0x8fa, 0x8fb, 0x8fc,
9057 0x8fd, 0x8fe, 0x8ff, 0x900, 0x901, 0x902, 0x903, 0x93a,
9058 0x93b, 0x93c, 0x93e, 0x93f, 0x940, 0x941, 0x942, 0x943,
9059 0x944, 0x945, 0x946, 0x947, 0x948, 0x949, 0x94a, 0x94b,
9060 0x94c, 0x94d, 0x94e, 0x94f, 0x951, 0x952, 0x953, 0x954,
9061 0x955, 0x956, 0x957, 0x962, 0x963, 0x981, 0x982, 0x983,
9062 0x9bc, 0x9be, 0x9bf, 0x9c0, 0x9c1, 0x9c2, 0x9c3, 0x9c4,
9063 0x9c7, 0x9c8, 0x9cb, 0x9cc, 0x9cd, 0x9d7, 0x9e2, 0x9e3,
9064 0x9fe, 0xa01, 0xa02, 0xa03, 0xa3c, 0xa3e, 0xa3f, 0xa40,
9065 0xa41, 0xa42, 0xa47, 0xa48, 0xa4b, 0xa4c, 0xa4d, 0xa51,
9066 0xa70, 0xa71, 0xa75, 0xa81, 0xa82, 0xa83, 0xabc, 0xabe,
9067 0xabf, 0xac0, 0xac1, 0xac2, 0xac3, 0xac4, 0xac5, 0xac7,
9068 0xac8, 0xac9, 0xacb, 0xacc, 0xacd, 0xae2, 0xae3, 0xafa,
9069 0xafb, 0xafc, 0xafd, 0xafe, 0xaff, 0xb01, 0xb02, 0xb03,
9070 0xb3c, 0xb3e, 0xb3f, 0xb40, 0xb41, 0xb42, 0xb43, 0xb44,
9071 0xb47, 0xb48, 0xb4b, 0xb4c, 0xb4d, 0xb55, 0xb56, 0xb57,
9072 0xb62, 0xb63, 0xb82, 0xbbe, 0xbbf, 0xbc0, 0xbc1, 0xbc2,
9073 0xbc6, 0xbc7, 0xbc8, 0xbca, 0xbcb, 0xbcc, 0xbcd, 0xbd7,
9074 0xc00, 0xc01, 0xc02, 0xc03, 0xc04, 0xc3e, 0xc3f, 0xc40,
9075 0xc41, 0xc42, 0xc43, 0xc44, 0xc46, 0xc47, 0xc48, 0xc4a,
9076 0xc4b, 0xc4c, 0xc4d, 0xc55, 0xc56, 0xc62, 0xc63, 0xc81,
9077 0xc82, 0xc83, 0xcbc, 0xcbe, 0xcbf, 0xcc0, 0xcc1, 0xcc2,
9078 0xcc3, 0xcc4, 0xcc6, 0xcc7, 0xcc8, 0xcca, 0xccb, 0xccc,
9079 0xccd, 0xcd5, 0xcd6, 0xce2, 0xce3, 0xd00, 0xd01, 0xd02,
9080 0xd03, 0xd3b, 0xd3c, 0xd3e, 0xd3f, 0xd40, 0xd41, 0xd42,
9081 0xd43, 0xd44, 0xd46, 0xd47, 0xd48, 0xd4a, 0xd4b, 0xd4c,
9082 0xd4d, 0xd57, 0xd62, 0xd63, 0xd81, 0xd82, 0xd83, 0xdca,
9083 0xdcf, 0xdd0, 0xdd1, 0xdd2, 0xdd3, 0xdd4, 0xdd6, 0xdd8,
9084 0xdd9, 0xdda, 0xddb, 0xddc, 0xddd, 0xdde, 0xddf, 0xdf2,
9085 0xdf3, 0xe31, 0xe34, 0xe35, 0xe36, 0xe37, 0xe38, 0xe39,
9086 0xe3a, 0xe47, 0xe48, 0xe49, 0xe4a, 0xe4b, 0xe4c, 0xe4d,
9087 0xe4e, 0xeb1, 0xeb4, 0xeb5, 0xeb6, 0xeb7, 0xeb8, 0xeb9,
9088 0xeba, 0xebb, 0xebc, 0xec8, 0xec9, 0xeca, 0xecb, 0xecc,
9089 0xecd, 0xf18, 0xf19, 0xf35, 0xf37, 0xf39, 0xf3e, 0xf3f,
9090 0xf71, 0xf72, 0xf73, 0xf74, 0xf75, 0xf76, 0xf77, 0xf78,
9091 0xf79, 0xf7a, 0xf7b, 0xf7c, 0xf7d, 0xf7e, 0xf7f, 0xf80,
9092 0xf81, 0xf82, 0xf83, 0xf84, 0xf86, 0xf87, 0xf8d, 0xf8e,
9093 0xf8f, 0xf90, 0xf91, 0xf92, 0xf93, 0xf94, 0xf95, 0xf96,
9094 0xf97, 0xf99, 0xf9a, 0xf9b, 0xf9c, 0xf9d, 0xf9e, 0xf9f,
9095 0xfa0, 0xfa1, 0xfa2, 0xfa3, 0xfa4, 0xfa5, 0xfa6, 0xfa7,
9096 0xfa8, 0xfa9, 0xfaa, 0xfab, 0xfac, 0xfad, 0xfae, 0xfaf,
9097 0xfb0, 0xfb1, 0xfb2, 0xfb3, 0xfb4, 0xfb5, 0xfb6, 0xfb7,
9098 0xfb8, 0xfb9, 0xfba, 0xfbb, 0xfbc, 0xfc6, 0x102b, 0x102c,
9099 0x102d, 0x102e, 0x102f, 0x1030, 0x1031, 0x1032, 0x1033, 0x1034,
9100 0x1035, 0x1036, 0x1037, 0x1038, 0x1039, 0x103a, 0x103b, 0x103c,
9101 0x103d, 0x103e, 0x1056, 0x1057, 0x1058, 0x1059, 0x105e, 0x105f,
9102 0x1060, 0x1062, 0x1063, 0x1064, 0x1067, 0x1068, 0x1069, 0x106a,
9103 0x106b, 0x106c, 0x106d, 0x1071, 0x1072, 0x1073, 0x1074, 0x1082,
9104 0x1083, 0x1084, 0x1085, 0x1086, 0x1087, 0x1088, 0x1089, 0x108a,
9105 0x108b, 0x108c, 0x108d, 0x108f, 0x109a, 0x109b, 0x109c, 0x109d,
9106 0x135d, 0x135e, 0x135f, 0x1712, 0x1713, 0x1714, 0x1732, 0x1733,
9107 0x1734, 0x1752, 0x1753, 0x1772, 0x1773, 0x17b4, 0x17b5, 0x17b6,
9108 0x17b7, 0x17b8, 0x17b9, 0x17ba, 0x17bb, 0x17bc, 0x17bd, 0x17be,
9109 0x17bf, 0x17c0, 0x17c1, 0x17c2, 0x17c3, 0x17c4, 0x17c5, 0x17c6,
9110 0x17c7, 0x17c8, 0x17c9, 0x17ca, 0x17cb, 0x17cc, 0x17cd, 0x17ce,
9111 0x17cf, 0x17d0, 0x17d1, 0x17d2, 0x17d3, 0x17dd, 0x180b, 0x180c,
9112 0x180d, 0x1885, 0x1886, 0x18a9, 0x1920, 0x1921, 0x1922, 0x1923,
9113 0x1924, 0x1925, 0x1926, 0x1927, 0x1928, 0x1929, 0x192a, 0x192b,
9114 0x1930, 0x1931, 0x1932, 0x1933, 0x1934, 0x1935, 0x1936, 0x1937,
9115 0x1938, 0x1939, 0x193a, 0x193b, 0x1a17, 0x1a18, 0x1a19, 0x1a1a,
9116 0x1a1b, 0x1a55, 0x1a56, 0x1a57, 0x1a58, 0x1a59, 0x1a5a, 0x1a5b,
9117 0x1a5c, 0x1a5d, 0x1a5e, 0x1a60, 0x1a61, 0x1a62, 0x1a63, 0x1a64,
9118 0x1a65, 0x1a66, 0x1a67, 0x1a68, 0x1a69, 0x1a6a, 0x1a6b, 0x1a6c,
9119 0x1a6d, 0x1a6e, 0x1a6f, 0x1a70, 0x1a71, 0x1a72, 0x1a73, 0x1a74,
9120 0x1a75, 0x1a76, 0x1a77, 0x1a78, 0x1a79, 0x1a7a, 0x1a7b, 0x1a7c,
9121 0x1a7f, 0x1ab0, 0x1ab1, 0x1ab2, 0x1ab3, 0x1ab4, 0x1ab5, 0x1ab6,
9122 0x1ab7, 0x1ab8, 0x1ab9, 0x1aba, 0x1abb, 0x1abc, 0x1abd, 0x1abe,
9123 0x1abf, 0x1ac0, 0x1b00, 0x1b01, 0x1b02, 0x1b03, 0x1b04, 0x1b34,
9124 0x1b35, 0x1b36, 0x1b37, 0x1b38, 0x1b39, 0x1b3a, 0x1b3b, 0x1b3c,
9125 0x1b3d, 0x1b3e, 0x1b3f, 0x1b40, 0x1b41, 0x1b42, 0x1b43, 0x1b44,
9126 0x1b6b, 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b70, 0x1b71, 0x1b72,
9127 0x1b73, 0x1b80, 0x1b81, 0x1b82, 0x1ba1, 0x1ba2, 0x1ba3, 0x1ba4,
9128 0x1ba5, 0x1ba6, 0x1ba7, 0x1ba8, 0x1ba9, 0x1baa, 0x1bab, 0x1bac,
9129 0x1bad, 0x1be6, 0x1be7, 0x1be8, 0x1be9, 0x1bea, 0x1beb, 0x1bec,
9130 0x1bed, 0x1bee, 0x1bef, 0x1bf0, 0x1bf1, 0x1bf2, 0x1bf3, 0x1c24,
9131 0x1c25, 0x1c26, 0x1c27, 0x1c28, 0x1c29, 0x1c2a, 0x1c2b, 0x1c2c,
9132 0x1c2d, 0x1c2e, 0x1c2f, 0x1c30, 0x1c31, 0x1c32, 0x1c33, 0x1c34,
9133 0x1c35, 0x1c36, 0x1c37, 0x1cd0, 0x1cd1, 0x1cd2, 0x1cd4, 0x1cd5,
9134 0x1cd6, 0x1cd7, 0x1cd8, 0x1cd9, 0x1cda, 0x1cdb, 0x1cdc, 0x1cdd,
9135 0x1cde, 0x1cdf, 0x1ce0, 0x1ce1, 0x1ce2, 0x1ce3, 0x1ce4, 0x1ce5,
9136 0x1ce6, 0x1ce7, 0x1ce8, 0x1ced, 0x1cf4, 0x1cf7, 0x1cf8, 0x1cf9,
9137 0x1dc0, 0x1dc1, 0x1dc2, 0x1dc3, 0x1dc4, 0x1dc5, 0x1dc6, 0x1dc7,
9138 0x1dc8, 0x1dc9, 0x1dca, 0x1dcb, 0x1dcc, 0x1dcd, 0x1dce, 0x1dcf,
9139 0x1dd0, 0x1dd1, 0x1dd2, 0x1dd3, 0x1dd4, 0x1dd5, 0x1dd6, 0x1dd7,
9140 0x1dd8, 0x1dd9, 0x1dda, 0x1ddb, 0x1ddc, 0x1ddd, 0x1dde, 0x1ddf,
9141 0x1de0, 0x1de1, 0x1de2, 0x1de3, 0x1de4, 0x1de5, 0x1de6, 0x1de7,
9142 0x1de8, 0x1de9, 0x1dea, 0x1deb, 0x1dec, 0x1ded, 0x1dee, 0x1def,
9143 0x1df0, 0x1df1, 0x1df2, 0x1df3, 0x1df4, 0x1df5, 0x1df6, 0x1df7,
9144 0x1df8, 0x1df9, 0x1dfb, 0x1dfc, 0x1dfd, 0x1dfe, 0x1dff, 0x20d0,
9145 0x20d1, 0x20d2, 0x20d3, 0x20d4, 0x20d5, 0x20d6, 0x20d7, 0x20d8,
9146 0x20d9, 0x20da, 0x20db, 0x20dc, 0x20dd, 0x20de, 0x20df, 0x20e0,
9147 0x20e1, 0x20e2, 0x20e3, 0x20e4, 0x20e5, 0x20e6, 0x20e7, 0x20e8,
9148 0x20e9, 0x20ea, 0x20eb, 0x20ec, 0x20ed, 0x20ee, 0x20ef, 0x20f0,
9149 0x2cef, 0x2cf0, 0x2cf1, 0x2d7f, 0x2de0, 0x2de1, 0x2de2, 0x2de3,
9150 0x2de4, 0x2de5, 0x2de6, 0x2de7, 0x2de8, 0x2de9, 0x2dea, 0x2deb,
9151 0x2dec, 0x2ded, 0x2dee, 0x2def, 0x2df0, 0x2df1, 0x2df2, 0x2df3,
9152 0x2df4, 0x2df5, 0x2df6, 0x2df7, 0x2df8, 0x2df9, 0x2dfa, 0x2dfb,
9153 0x2dfc, 0x2dfd, 0x2dfe, 0x2dff, 0x302a, 0x302b, 0x302c, 0x302d,
9154 0x302e, 0x302f, 0x3099, 0x309a, 0xa66f, 0xa670, 0xa671, 0xa672,
9155 0xa674, 0xa675, 0xa676, 0xa677, 0xa678, 0xa679, 0xa67a, 0xa67b,
9156 0xa67c, 0xa67d, 0xa69e, 0xa69f, 0xa6f0, 0xa6f1, 0xa802, 0xa806,
9157 0xa80b, 0xa823, 0xa824, 0xa825, 0xa826, 0xa827, 0xa82c, 0xa880,
9158 0xa881, 0xa8b4, 0xa8b5, 0xa8b6, 0xa8b7, 0xa8b8, 0xa8b9, 0xa8ba,
9159 0xa8bb, 0xa8bc, 0xa8bd, 0xa8be, 0xa8bf, 0xa8c0, 0xa8c1, 0xa8c2,
9160 0xa8c3, 0xa8c4, 0xa8c5, 0xa8e0, 0xa8e1, 0xa8e2, 0xa8e3, 0xa8e4,
9161 0xa8e5, 0xa8e6, 0xa8e7, 0xa8e8, 0xa8e9, 0xa8ea, 0xa8eb, 0xa8ec,
9162 0xa8ed, 0xa8ee, 0xa8ef, 0xa8f0, 0xa8f1, 0xa8ff, 0xa926, 0xa927,
9163 0xa928, 0xa929, 0xa92a, 0xa92b, 0xa92c, 0xa92d, 0xa947, 0xa948,
9164 0xa949, 0xa94a, 0xa94b, 0xa94c, 0xa94d, 0xa94e, 0xa94f, 0xa950,
9165 0xa951, 0xa952, 0xa953, 0xa980, 0xa981, 0xa982, 0xa983, 0xa9b3,
9166 0xa9b4, 0xa9b5, 0xa9b6, 0xa9b7, 0xa9b8, 0xa9b9, 0xa9ba, 0xa9bb,
9167 0xa9bc, 0xa9bd, 0xa9be, 0xa9bf, 0xa9c0, 0xa9e5, 0xaa29, 0xaa2a,
9168 0xaa2b, 0xaa2c, 0xaa2d, 0xaa2e, 0xaa2f, 0xaa30, 0xaa31, 0xaa32,
9169 0xaa33, 0xaa34, 0xaa35, 0xaa36, 0xaa43, 0xaa4c, 0xaa4d, 0xaa7b,
9170 0xaa7c, 0xaa7d, 0xaab0, 0xaab2, 0xaab3, 0xaab4, 0xaab7, 0xaab8,
9171 0xaabe, 0xaabf, 0xaac1, 0xaaeb, 0xaaec, 0xaaed, 0xaaee, 0xaaef,
9172 0xaaf5, 0xaaf6, 0xabe3, 0xabe4, 0xabe5, 0xabe6, 0xabe7, 0xabe8,
9173 0xabe9, 0xabea, 0xabec, 0xabed, 0xfb1e, 0xfe00, 0xfe01, 0xfe02,
9174 0xfe03, 0xfe04, 0xfe05, 0xfe06, 0xfe07, 0xfe08, 0xfe09, 0xfe0a,
9175 0xfe0b, 0xfe0c, 0xfe0d, 0xfe0e, 0xfe0f, 0xfe20, 0xfe21, 0xfe22,
9176 0xfe23, 0xfe24, 0xfe25, 0xfe26, 0xfe27, 0xfe28, 0xfe29, 0xfe2a,
9177 0xfe2b, 0xfe2c, 0xfe2d, 0xfe2e, 0xfe2f, 0x101fd, 0x102e0, 0x10376,
9178 0x10377, 0x10378, 0x10379, 0x1037a, 0x10a01, 0x10a02, 0x10a03, 0x10a05,
9179 0x10a06, 0x10a0c, 0x10a0d, 0x10a0e, 0x10a0f, 0x10a38, 0x10a39, 0x10a3a,
9180 0x10a3f, 0x10ae5, 0x10ae6, 0x10d24, 0x10d25, 0x10d26, 0x10d27, 0x10eab,
9181 0x10eac, 0x10f46, 0x10f47, 0x10f48, 0x10f49, 0x10f4a, 0x10f4b, 0x10f4c,
9182 0x10f4d, 0x10f4e, 0x10f4f, 0x10f50, 0x11000, 0x11001, 0x11002, 0x11038,
9183 0x11039, 0x1103a, 0x1103b, 0x1103c, 0x1103d, 0x1103e, 0x1103f, 0x11040,
9184 0x11041, 0x11042, 0x11043, 0x11044, 0x11045, 0x11046, 0x1107f, 0x11080,
9185 0x11081, 0x11082, 0x110b0, 0x110b1, 0x110b2, 0x110b3, 0x110b4, 0x110b5,
9186 0x110b6, 0x110b7, 0x110b8, 0x110b9, 0x110ba, 0x11100, 0x11101, 0x11102,
9187 0x11127, 0x11128, 0x11129, 0x1112a, 0x1112b, 0x1112c, 0x1112d, 0x1112e,
9188 0x1112f, 0x11130, 0x11131, 0x11132, 0x11133, 0x11134, 0x11145, 0x11146,
9189 0x11173, 0x11180, 0x11181, 0x11182, 0x111b3, 0x111b4, 0x111b5, 0x111b6,
9190 0x111b7, 0x111b8, 0x111b9, 0x111ba, 0x111bb, 0x111bc, 0x111bd, 0x111be,
9191 0x111bf, 0x111c0, 0x111c9, 0x111ca, 0x111cb, 0x111cc, 0x111ce, 0x111cf,
9192 0x1122c, 0x1122d, 0x1122e, 0x1122f, 0x11230, 0x11231, 0x11232, 0x11233,
9193 0x11234, 0x11235, 0x11236, 0x11237, 0x1123e, 0x112df, 0x112e0, 0x112e1,
9194 0x112e2, 0x112e3, 0x112e4, 0x112e5, 0x112e6, 0x112e7, 0x112e8, 0x112e9,
9195 0x112ea, 0x11300, 0x11301, 0x11302, 0x11303, 0x1133b, 0x1133c, 0x1133e,
9196 0x1133f, 0x11340, 0x11341, 0x11342, 0x11343, 0x11344, 0x11347, 0x11348,
9197 0x1134b, 0x1134c, 0x1134d, 0x11357, 0x11362, 0x11363, 0x11366, 0x11367,
9198 0x11368, 0x11369, 0x1136a, 0x1136b, 0x1136c, 0x11370, 0x11371, 0x11372,
9199 0x11373, 0x11374, 0x11435, 0x11436, 0x11437, 0x11438, 0x11439, 0x1143a,
9200 0x1143b, 0x1143c, 0x1143d, 0x1143e, 0x1143f, 0x11440, 0x11441, 0x11442,
9201 0x11443, 0x11444, 0x11445, 0x11446, 0x1145e, 0x114b0, 0x114b1, 0x114b2,
9202 0x114b3, 0x114b4, 0x114b5, 0x114b6, 0x114b7, 0x114b8, 0x114b9, 0x114ba,
9203 0x114bb, 0x114bc, 0x114bd, 0x114be, 0x114bf, 0x114c0, 0x114c1, 0x114c2,
9204 0x114c3, 0x115af, 0x115b0, 0x115b1, 0x115b2, 0x115b3, 0x115b4, 0x115b5,
9205 0x115b8, 0x115b9, 0x115ba, 0x115bb, 0x115bc, 0x115bd, 0x115be, 0x115bf,
9206 0x115c0, 0x115dc, 0x115dd, 0x11630, 0x11631, 0x11632, 0x11633, 0x11634,
9207 0x11635, 0x11636, 0x11637, 0x11638, 0x11639, 0x1163a, 0x1163b, 0x1163c,
9208 0x1163d, 0x1163e, 0x1163f, 0x11640, 0x116ab, 0x116ac, 0x116ad, 0x116ae,
9209 0x116af, 0x116b0, 0x116b1, 0x116b2, 0x116b3, 0x116b4, 0x116b5, 0x116b6,
9210 0x116b7, 0x1171d, 0x1171e, 0x1171f, 0x11720, 0x11721, 0x11722, 0x11723,
9211 0x11724, 0x11725, 0x11726, 0x11727, 0x11728, 0x11729, 0x1172a, 0x1172b,
9212 0x1182c, 0x1182d, 0x1182e, 0x1182f, 0x11830, 0x11831, 0x11832, 0x11833,
9213 0x11834, 0x11835, 0x11836, 0x11837, 0x11838, 0x11839, 0x1183a, 0x11930,
9214 0x11931, 0x11932, 0x11933, 0x11934, 0x11935, 0x11937, 0x11938, 0x1193b,
9215 0x1193c, 0x1193d, 0x1193e, 0x11940, 0x11942, 0x11943, 0x119d1, 0x119d2,
9216 0x119d3, 0x119d4, 0x119d5, 0x119d6, 0x119d7, 0x119da, 0x119db, 0x119dc,
9217 0x119dd, 0x119de, 0x119df, 0x119e0, 0x119e4, 0x11a01, 0x11a02, 0x11a03,
9218 0x11a04, 0x11a05, 0x11a06, 0x11a07, 0x11a08, 0x11a09, 0x11a0a, 0x11a33,
9219 0x11a34, 0x11a35, 0x11a36, 0x11a37, 0x11a38, 0x11a39, 0x11a3b, 0x11a3c,
9220 0x11a3d, 0x11a3e, 0x11a47, 0x11a51, 0x11a52, 0x11a53, 0x11a54, 0x11a55,
9221 0x11a56, 0x11a57, 0x11a58, 0x11a59, 0x11a5a, 0x11a5b, 0x11a8a, 0x11a8b,
9222 0x11a8c, 0x11a8d, 0x11a8e, 0x11a8f, 0x11a90, 0x11a91, 0x11a92, 0x11a93,
9223 0x11a94, 0x11a95, 0x11a96, 0x11a97, 0x11a98, 0x11a99, 0x11c2f, 0x11c30,
9224 0x11c31, 0x11c32, 0x11c33, 0x11c34, 0x11c35, 0x11c36, 0x11c38, 0x11c39,
9225 0x11c3a, 0x11c3b, 0x11c3c, 0x11c3d, 0x11c3e, 0x11c3f, 0x11c92, 0x11c93,
9226 0x11c94, 0x11c95, 0x11c96, 0x11c97, 0x11c98, 0x11c99, 0x11c9a, 0x11c9b,
9227 0x11c9c, 0x11c9d, 0x11c9e, 0x11c9f, 0x11ca0, 0x11ca1, 0x11ca2, 0x11ca3,
9228 0x11ca4, 0x11ca5, 0x11ca6, 0x11ca7, 0x11ca9, 0x11caa, 0x11cab, 0x11cac,
9229 0x11cad, 0x11cae, 0x11caf, 0x11cb0, 0x11cb1, 0x11cb2, 0x11cb3, 0x11cb4,
9230 0x11cb5, 0x11cb6, 0x11d31, 0x11d32, 0x11d33, 0x11d34, 0x11d35, 0x11d36,
9231 0x11d3a, 0x11d3c, 0x11d3d, 0x11d3f, 0x11d40, 0x11d41, 0x11d42, 0x11d43,
9232 0x11d44, 0x11d45, 0x11d47, 0x11d8a, 0x11d8b, 0x11d8c, 0x11d8d, 0x11d8e,
9233 0x11d90, 0x11d91, 0x11d93, 0x11d94, 0x11d95, 0x11d96, 0x11d97, 0x11ef3,
9234 0x11ef4, 0x11ef5, 0x11ef6, 0x16af0, 0x16af1, 0x16af2, 0x16af3, 0x16af4,
9235 0x16b30, 0x16b31, 0x16b32, 0x16b33, 0x16b34, 0x16b35, 0x16b36, 0x16f4f,
9236 0x16f51, 0x16f52, 0x16f53, 0x16f54, 0x16f55, 0x16f56, 0x16f57, 0x16f58,
9237 0x16f59, 0x16f5a, 0x16f5b, 0x16f5c, 0x16f5d, 0x16f5e, 0x16f5f, 0x16f60,
9238 0x16f61, 0x16f62, 0x16f63, 0x16f64, 0x16f65, 0x16f66, 0x16f67, 0x16f68,
9239 0x16f69, 0x16f6a, 0x16f6b, 0x16f6c, 0x16f6d, 0x16f6e, 0x16f6f, 0x16f70,
9240 0x16f71, 0x16f72, 0x16f73, 0x16f74, 0x16f75, 0x16f76, 0x16f77, 0x16f78,
9241 0x16f79, 0x16f7a, 0x16f7b, 0x16f7c, 0x16f7d, 0x16f7e, 0x16f7f, 0x16f80,
9242 0x16f81, 0x16f82, 0x16f83, 0x16f84, 0x16f85, 0x16f86, 0x16f87, 0x16f8f,
9243 0x16f90, 0x16f91, 0x16f92, 0x16fe4, 0x16ff0, 0x16ff1, 0x1bc9d, 0x1bc9e,
9244 0x1d165, 0x1d166, 0x1d167, 0x1d168, 0x1d169, 0x1d16d, 0x1d16e, 0x1d16f,
9245 0x1d170, 0x1d171, 0x1d172, 0x1d17b, 0x1d17c, 0x1d17d, 0x1d17e, 0x1d17f,
9246 0x1d180, 0x1d181, 0x1d182, 0x1d185, 0x1d186, 0x1d187, 0x1d188, 0x1d189,
9247 0x1d18a, 0x1d18b, 0x1d1aa, 0x1d1ab, 0x1d1ac, 0x1d1ad, 0x1d242, 0x1d243,
9248 0x1d244, 0x1da00, 0x1da01, 0x1da02, 0x1da03, 0x1da04, 0x1da05, 0x1da06,
9249 0x1da07, 0x1da08, 0x1da09, 0x1da0a, 0x1da0b, 0x1da0c, 0x1da0d, 0x1da0e,
9250 0x1da0f, 0x1da10, 0x1da11, 0x1da12, 0x1da13, 0x1da14, 0x1da15, 0x1da16,
9251 0x1da17, 0x1da18, 0x1da19, 0x1da1a, 0x1da1b, 0x1da1c, 0x1da1d, 0x1da1e,
9252 0x1da1f, 0x1da20, 0x1da21, 0x1da22, 0x1da23, 0x1da24, 0x1da25, 0x1da26,
9253 0x1da27, 0x1da28, 0x1da29, 0x1da2a, 0x1da2b, 0x1da2c, 0x1da2d, 0x1da2e,
9254 0x1da2f, 0x1da30, 0x1da31, 0x1da32, 0x1da33, 0x1da34, 0x1da35, 0x1da36,
9255 0x1da3b, 0x1da3c, 0x1da3d, 0x1da3e, 0x1da3f, 0x1da40, 0x1da41, 0x1da42,
9256 0x1da43, 0x1da44, 0x1da45, 0x1da46, 0x1da47, 0x1da48, 0x1da49, 0x1da4a,
9257 0x1da4b, 0x1da4c, 0x1da4d, 0x1da4e, 0x1da4f, 0x1da50, 0x1da51, 0x1da52,
9258 0x1da53, 0x1da54, 0x1da55, 0x1da56, 0x1da57, 0x1da58, 0x1da59, 0x1da5a,
9259 0x1da5b, 0x1da5c, 0x1da5d, 0x1da5e, 0x1da5f, 0x1da60, 0x1da61, 0x1da62,
9260 0x1da63, 0x1da64, 0x1da65, 0x1da66, 0x1da67, 0x1da68, 0x1da69, 0x1da6a,
9261 0x1da6b, 0x1da6c, 0x1da75, 0x1da84, 0x1da9b, 0x1da9c, 0x1da9d, 0x1da9e,
9262 0x1da9f, 0x1daa1, 0x1daa2, 0x1daa3, 0x1daa4, 0x1daa5, 0x1daa6, 0x1daa7,
9263 0x1daa8, 0x1daa9, 0x1daaa, 0x1daab, 0x1daac, 0x1daad, 0x1daae, 0x1daaf,
9264 0x1e000, 0x1e001, 0x1e002, 0x1e003, 0x1e004, 0x1e005, 0x1e006, 0x1e008,
9265 0x1e009, 0x1e00a, 0x1e00b, 0x1e00c, 0x1e00d, 0x1e00e, 0x1e00f, 0x1e010,
9266 0x1e011, 0x1e012, 0x1e013, 0x1e014, 0x1e015, 0x1e016, 0x1e017, 0x1e018,
9267 0x1e01b, 0x1e01c, 0x1e01d, 0x1e01e, 0x1e01f, 0x1e020, 0x1e021, 0x1e023,
9268 0x1e024, 0x1e026, 0x1e027, 0x1e028, 0x1e029, 0x1e02a, 0x1e130, 0x1e131,
9269 0x1e132, 0x1e133, 0x1e134, 0x1e135, 0x1e136, 0x1e2ec, 0x1e2ed, 0x1e2ee,
9270 0x1e2ef, 0x1e8d0, 0x1e8d1, 0x1e8d2, 0x1e8d3, 0x1e8d4, 0x1e8d5, 0x1e8d6,
9271 0x1e944, 0x1e945, 0x1e946, 0x1e947, 0x1e948, 0x1e949, 0x1e94a, 0xe0100,
9272 0xe0101, 0xe0102, 0xe0103, 0xe0104, 0xe0105, 0xe0106, 0xe0107, 0xe0108,
9273 0xe0109, 0xe010a, 0xe010b, 0xe010c, 0xe010d, 0xe010e, 0xe010f, 0xe0110,
9274 0xe0111, 0xe0112, 0xe0113, 0xe0114, 0xe0115, 0xe0116, 0xe0117, 0xe0118,
9275 0xe0119, 0xe011a, 0xe011b, 0xe011c, 0xe011d, 0xe011e, 0xe011f, 0xe0120,
9276 0xe0121, 0xe0122, 0xe0123, 0xe0124, 0xe0125, 0xe0126, 0xe0127, 0xe0128,
9277 0xe0129, 0xe012a, 0xe012b, 0xe012c, 0xe012d, 0xe012e, 0xe012f, 0xe0130,
9278 0xe0131, 0xe0132, 0xe0133, 0xe0134, 0xe0135, 0xe0136, 0xe0137, 0xe0138,
9279 0xe0139, 0xe013a, 0xe013b, 0xe013c, 0xe013d, 0xe013e, 0xe013f, 0xe0140,
9280 0xe0141, 0xe0142, 0xe0143, 0xe0144, 0xe0145, 0xe0146, 0xe0147, 0xe0148,
9281 0xe0149, 0xe014a, 0xe014b, 0xe014c, 0xe014d, 0xe014e, 0xe014f, 0xe0150,
9282 0xe0151, 0xe0152, 0xe0153, 0xe0154, 0xe0155, 0xe0156, 0xe0157, 0xe0158,
9283 0xe0159, 0xe015a, 0xe015b, 0xe015c, 0xe015d, 0xe015e, 0xe015f, 0xe0160,
9284 0xe0161, 0xe0162, 0xe0163, 0xe0164, 0xe0165, 0xe0166, 0xe0167, 0xe0168,
9285 0xe0169, 0xe016a, 0xe016b, 0xe016c, 0xe016d, 0xe016e, 0xe016f, 0xe0170,
9286 0xe0171, 0xe0172, 0xe0173, 0xe0174, 0xe0175, 0xe0176, 0xe0177, 0xe0178,
9287 0xe0179, 0xe017a, 0xe017b, 0xe017c, 0xe017d, 0xe017e, 0xe017f, 0xe0180,
9288 0xe0181, 0xe0182, 0xe0183, 0xe0184, 0xe0185, 0xe0186, 0xe0187, 0xe0188,
9289 0xe0189, 0xe018a, 0xe018b, 0xe018c, 0xe018d, 0xe018e, 0xe018f, 0xe0190,
9290 0xe0191, 0xe0192, 0xe0193, 0xe0194, 0xe0195, 0xe0196, 0xe0197, 0xe0198,
9291 0xe0199, 0xe019a, 0xe019b, 0xe019c, 0xe019d, 0xe019e, 0xe019f, 0xe01a0,
9292 0xe01a1, 0xe01a2, 0xe01a3, 0xe01a4, 0xe01a5, 0xe01a6, 0xe01a7, 0xe01a8,
9293 0xe01a9, 0xe01aa, 0xe01ab, 0xe01ac, 0xe01ad, 0xe01ae, 0xe01af, 0xe01b0,
9294 0xe01b1, 0xe01b2, 0xe01b3, 0xe01b4, 0xe01b5, 0xe01b6, 0xe01b7, 0xe01b8,
9295 0xe01b9, 0xe01ba, 0xe01bb, 0xe01bc, 0xe01bd, 0xe01be, 0xe01bf, 0xe01c0,
9296 0xe01c1, 0xe01c2, 0xe01c3, 0xe01c4, 0xe01c5, 0xe01c6, 0xe01c7, 0xe01c8,
9297 0xe01c9, 0xe01ca, 0xe01cb, 0xe01cc, 0xe01cd, 0xe01ce, 0xe01cf, 0xe01d0,
9298 0xe01d1, 0xe01d2, 0xe01d3, 0xe01d4, 0xe01d5, 0xe01d6, 0xe01d7, 0xe01d8,
9299 0xe01d9, 0xe01da, 0xe01db, 0xe01dc, 0xe01dd, 0xe01de, 0xe01df, 0xe01e0,
9300 0xe01e1, 0xe01e2, 0xe01e3, 0xe01e4, 0xe01e5, 0xe01e6, 0xe01e7, 0xe01e8,
9301 0xe01e9, 0xe01ea, 0xe01eb, 0xe01ec, 0xe01ed, 0xe01ee, 0xe01ef};
9302 if (std::binary_search(std::begin(combining), std::end(combining),
9303 label.front())) {
9304 return false;
9305 }
9306 // We verify this next step as part of the mapping:
9307 // ---------------------------------------------
9308 // Each code point in the label must only have certain status values
9309 // according to Section 5, IDNA Mapping Table:
9310 // - For Transitional Processing, each value must be valid.
9311 // - For Nontransitional Processing, each value must be either valid or
9312 // deviation.
9313
9314 // If CheckJoiners, the label must satisfy the ContextJ rules from Appendix
9315 // A, in The Unicode Code Points and Internationalized Domain Names for
9316 // Applications (IDNA) [IDNA2008].
9317 constexpr static uint32_t virama[] = {
9318 0x094D, 0x09CD, 0x0A4D, 0x0ACD, 0x0B4D, 0x0BCD, 0x0C4D, 0x0CCD,
9319 0x0D3B, 0x0D3C, 0x0D4D, 0x0DCA, 0x0E3A, 0x0EBA, 0x0F84, 0x1039,
9320 0x103A, 0x1714, 0x1734, 0x17D2, 0x1A60, 0x1B44, 0x1BAA, 0x1BAB,
9321 0x1BF2, 0x1BF3, 0x2D7F, 0xA806, 0xA82C, 0xA8C4, 0xA953, 0xA9C0,
9322 0xAAF6, 0xABED, 0x10A3F, 0x11046, 0x1107F, 0x110B9, 0x11133, 0x11134,
9323 0x111C0, 0x11235, 0x112EA, 0x1134D, 0x11442, 0x114C2, 0x115BF, 0x1163F,
9324 0x116B6, 0x1172B, 0x11839, 0x1193D, 0x1193E, 0x119E0, 0x11A34, 0x11A47,
9325 0x11A99, 0x11C3F, 0x11D44, 0x11D45, 0x11D97};
9326 constexpr static uint32_t R[] = {
9327 0x622, 0x623, 0x624, 0x625, 0x627, 0x629, 0x62f, 0x630, 0x631,
9328 0x632, 0x648, 0x671, 0x672, 0x673, 0x675, 0x676, 0x677, 0x688,
9329 0x689, 0x68a, 0x68b, 0x68c, 0x68d, 0x68e, 0x68f, 0x690, 0x691,
9330 0x692, 0x693, 0x694, 0x695, 0x696, 0x697, 0x698, 0x699, 0x6c0,
9331 0x6c3, 0x6c4, 0x6c5, 0x6c6, 0x6c7, 0x6c8, 0x6c9, 0x6ca, 0x6cb,
9332 0x6cd, 0x6cf, 0x6d2, 0x6d3, 0x6d5, 0x6ee, 0x6ef, 0x710, 0x715,
9333 0x716, 0x717, 0x718, 0x719, 0x71e, 0x728, 0x72a, 0x72c, 0x72f,
9334 0x74d, 0x759, 0x75a, 0x75b, 0x854, 0x8aa, 0x8ab, 0x8ac};
9335 constexpr static uint32_t L[] = {0xa872};
9336 constexpr static uint32_t D[] = {
9337 0x620, 0x626, 0x628, 0x62a, 0x62b, 0x62c, 0x62d, 0x62e, 0x633,
9338 0x634, 0x635, 0x636, 0x637, 0x638, 0x639, 0x63a, 0x63b, 0x63c,
9339 0x63d, 0x63e, 0x63f, 0x641, 0x642, 0x643, 0x644, 0x645, 0x646,
9340 0x647, 0x649, 0x64a, 0x66e, 0x66f, 0x678, 0x679, 0x67a, 0x67b,
9341 0x67c, 0x67d, 0x67e, 0x67f, 0x680, 0x681, 0x682, 0x683, 0x684,
9342 0x685, 0x686, 0x687, 0x69a, 0x69b, 0x69c, 0x69d, 0x69e, 0x69f,
9343 0x6a0, 0x6a1, 0x6a2, 0x6a3, 0x6a4, 0x6a5, 0x6a6, 0x6a7, 0x6a8,
9344 0x6a9, 0x6aa, 0x6ab, 0x6ac, 0x6ad, 0x6ae, 0x6af, 0x6b0, 0x6b1,
9345 0x6b2, 0x6b3, 0x6b4, 0x6b5, 0x6b6, 0x6b7, 0x6b8, 0x6b9, 0x6ba,
9346 0x6bb, 0x6bc, 0x6bd, 0x6be, 0x6bf, 0x6c1, 0x6c2, 0x6cc, 0x6ce,
9347 0x6d0, 0x6d1, 0x6fa, 0x6fb, 0x6fc, 0x6ff, 0x712, 0x713, 0x714,
9348 0x71a, 0x71b, 0x71c, 0x71d, 0x71f, 0x720, 0x721, 0x722, 0x723,
9349 0x724, 0x725, 0x726, 0x727, 0x729, 0x72b, 0x72d, 0x72e, 0x74e,
9350 0x74f, 0x750, 0x751, 0x752, 0x753, 0x754, 0x755, 0x756, 0x757,
9351 0x758, 0x75c, 0x75d, 0x75e, 0x75f, 0x760, 0x761, 0x762, 0x763,
9352 0x764, 0x765, 0x766, 0x850, 0x851, 0x852, 0x853, 0x855, 0x8a0,
9353 0x8a2, 0x8a3, 0x8a4, 0x8a5, 0x8a6, 0x8a7, 0x8a8, 0x8a9, 0x1807,
9354 0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827, 0x1828,
9355 0x1829, 0x182a, 0x182b, 0x182c, 0x182d, 0x182e, 0x182f, 0x1830, 0x1831,
9356 0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837, 0x1838, 0x1839, 0x183a,
9357 0x183b, 0x183c, 0x183d, 0x183e, 0x183f, 0x1840, 0x1841, 0x1842, 0x1843,
9358 0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x184a, 0x184b, 0x184c,
9359 0x184d, 0x184e, 0x184f, 0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855,
9360 0x1856, 0x1857, 0x1858, 0x1859, 0x185a, 0x185b, 0x185c, 0x185d, 0x185e,
9361 0x185f, 0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867,
9362 0x1868, 0x1869, 0x186a, 0x186b, 0x186c, 0x186d, 0x186e, 0x186f, 0x1870,
9363 0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877, 0x1887, 0x1888,
9364 0x1889, 0x188a, 0x188b, 0x188c, 0x188d, 0x188e, 0x188f, 0x1890, 0x1891,
9365 0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897, 0x1898, 0x1899, 0x189a,
9366 0x189b, 0x189c, 0x189d, 0x189e, 0x189f, 0x18a0, 0x18a1, 0x18a2, 0x18a3,
9367 0x18a4, 0x18a5, 0x18a6, 0x18a7, 0x18a8, 0x18aa, 0xa840, 0xa841, 0xa842,
9368 0xa843, 0xa844, 0xa845, 0xa846, 0xa847, 0xa848, 0xa849, 0xa84a, 0xa84b,
9369 0xa84c, 0xa84d, 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa853, 0xa854,
9370 0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c, 0xa85d,
9371 0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864, 0xa865, 0xa866,
9372 0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c, 0xa86d, 0xa86e, 0xa86f,
9373 0xa870, 0xa871};
9374
9375 for (size_t i = 0; i < label.size(); i++) {
9376 uint32_t c = label[i];
9377 if (c == 0x200c) {
9378 if (i > 0) {
9379 if (std::binary_search(std::begin(virama), std::end(virama),
9380 label[i - 1])) {
9381 return true;
9382 }
9383 }
9384 if ((i == 0) || (i + 1 >= label.size())) {
9385 return false;
9386 }
9387 // we go backward looking for L or D
9388 auto is_l_or_d = [](uint32_t code) {
9389 return std::binary_search(std::begin(L), std::end(L), code) ||
9390 std::binary_search(std::begin(D), std::end(D), code);
9391 };
9392 auto is_r_or_d = [](uint32_t code) {
9393 return std::binary_search(std::begin(R), std::end(R), code) ||
9394 std::binary_search(std::begin(D), std::end(D), code);
9395 };
9396 std::u32string_view before = label.substr(0, i);
9397 std::u32string_view after = label.substr(i + 1);
9398 return (std::find_if(before.begin(), before.end(), is_l_or_d) !=
9399 before.end()) &&
9400 (std::find_if(after.begin(), after.end(), is_r_or_d) !=
9401 after.end());
9402 } else if (c == 0x200d) {
9403 if (i > 0) {
9404 if (std::binary_search(std::begin(virama), std::end(virama),
9405 label[i - 1])) {
9406 return true;
9407 }
9408 }
9409 return false;
9410 }
9411 }
9412
9413 // If CheckBidi, and if the domain name is a Bidi domain name, then the label
9414 // must satisfy all six of the numbered conditions in [IDNA2008] RFC 5893,
9415 // Section 2.
9416
9417 // The following rule, consisting of six conditions, applies to labels
9418 // in Bidi domain names. The requirements that this rule satisfies are
9419 // described in Section 3. All of the conditions must be satisfied for
9420 // the rule to be satisfied.
9421 //
9422 // 1. The first character must be a character with Bidi property L, R,
9423 // or AL. If it has the R or AL property, it is an RTL label; if it
9424 // has the L property, it is an LTR label.
9425 //
9426 // 2. In an RTL label, only characters with the Bidi properties R, AL,
9427 // AN, EN, ES, CS, ET, ON, BN, or NSM are allowed.
9428 //
9429 // 3. In an RTL label, the end of the label must be a character with
9430 // Bidi property R, AL, EN, or AN, followed by zero or more
9431 // characters with Bidi property NSM.
9432 //
9433 // 4. In an RTL label, if an EN is present, no AN may be present, and
9434 // vice versa.
9435 //
9436 // 5. In an LTR label, only characters with the Bidi properties L, EN,
9437 // ES, CS, ET, ON, BN, or NSM are allowed.
9438 //
9439 // 6. In an LTR label, the end of the label must be a character with
9440 // Bidi property L or EN, followed by zero or more characters with
9441 // Bidi property NSM.
9442
9443 size_t last_non_nsm_char = find_last_not_of_nsm(label);
9444 if (last_non_nsm_char == std::u32string_view::npos) {
9445 return false;
9446 }
9447
9448 // A "Bidi domain name" is a domain name that contains at least one RTL label.
9449 // The following rule, consisting of six conditions, applies to labels in Bidi
9450 // domain names.
9451 if (is_rtl_label(label)) {
9452 // The first character must be a character with Bidi property L, R,
9453 // or AL. If it has the R or AL property, it is an RTL label; if it
9454 // has the L property, it is an LTR label.
9455
9456 if (find_direction(label[0]) == direction::L) {
9457 // Eval as LTR
9458
9459 // In an LTR label, only characters with the Bidi properties L, EN,
9460 // ES, CS, ET, ON, BN, or NSM are allowed.
9461 for (size_t i = 0; i < last_non_nsm_char; i++) {
9462 const direction d = find_direction(label[i]);
9463 if (!(d == direction::L || d == direction::EN || d == direction::ES ||
9464 d == direction::CS || d == direction::ET || d == direction::ON ||
9465 d == direction::BN || d == direction::NSM)) {
9466 return false;
9467 }
9468
9469 if ((i == last_non_nsm_char) &&
9470 !(d == direction::L || d == direction::EN)) {
9471 return false;
9472 }
9473 }
9474
9475 return true;
9476
9477 } else {
9478 // Eval as RTL
9479
9480 bool has_an = false;
9481 bool has_en = false;
9482 for (size_t i = 0; i <= last_non_nsm_char; i++) {
9483 const direction d = find_direction(label[i]);
9484
9485 // In an RTL label, if an EN is present, no AN may be present, and vice
9486 // versa.
9487 if ((d == direction::EN && ((has_en = true) && has_an)) ||
9488 (d == direction::AN && ((has_an = true) && has_en))) {
9489 return false;
9490 }
9491
9492 if (!(d == direction::R || d == direction::AL || d == direction::AN ||
9493 d == direction::EN || d == direction::ES || d == direction::CS ||
9494 d == direction::ET || d == direction::ON || d == direction::BN ||
9495 d == direction::NSM)) {
9496 return false;
9497 }
9498
9499 if (i == last_non_nsm_char &&
9500 !(d == direction::R || d == direction::AL || d == direction::AN ||
9501 d == direction::EN)) {
9502 return false;
9503 }
9504 }
9505
9506 return true;
9507 }
9508 }
9509
9510 return true;
9511 }
9512
9513 } // namespace ada::idna
9514 /* end file src/validity.cpp */
9515 /* begin file src/to_ascii.cpp */
9516
9517 #include <algorithm>
9518 #include <cstdint>
9519
9520
9521 namespace ada::idna {
9522
begins_with(std::u32string_view view,std::u32string_view prefix)9523 bool constexpr begins_with(std::u32string_view view,
9524 std::u32string_view prefix) {
9525 if (view.size() < prefix.size()) {
9526 return false;
9527 }
9528 return view.substr(0, prefix.size()) == prefix;
9529 }
9530
begins_with(std::string_view view,std::string_view prefix)9531 bool constexpr begins_with(std::string_view view, std::string_view prefix) {
9532 if (view.size() < prefix.size()) {
9533 return false;
9534 }
9535 return view.substr(0, prefix.size()) == prefix;
9536 }
9537
is_ascii(std::u32string_view view)9538 bool constexpr is_ascii(std::u32string_view view) {
9539 for (uint32_t c : view) {
9540 if (c >= 0x80) {
9541 return false;
9542 }
9543 }
9544 return true;
9545 }
9546
is_ascii(std::string_view view)9547 bool constexpr is_ascii(std::string_view view) {
9548 for (uint8_t c : view) {
9549 if (c >= 0x80) {
9550 return false;
9551 }
9552 }
9553 return true;
9554 }
9555
9556 constexpr static uint8_t is_forbidden_domain_code_point_table[] = {
9557 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9558 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
9559 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
9560 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
9561 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9562 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9563 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9564 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9565 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9566 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9567 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
9568
9569 static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
9570
is_forbidden_domain_code_point(const char c)9571 inline bool is_forbidden_domain_code_point(const char c) noexcept {
9572 return is_forbidden_domain_code_point_table[uint8_t(c)];
9573 }
9574
contains_forbidden_domain_code_point(std::string_view view)9575 bool contains_forbidden_domain_code_point(std::string_view view) {
9576 return (
9577 std::any_of(view.begin(), view.end(), is_forbidden_domain_code_point));
9578 }
9579
9580 // We return "" on error.
from_ascii_to_ascii(std::string_view ut8_string)9581 static std::string from_ascii_to_ascii(std::string_view ut8_string) {
9582 static const std::string error = "";
9583 // copy and map
9584 // we could be more efficient by avoiding the copy when unnecessary.
9585 std::string mapped_string = std::string(ut8_string);
9586 ascii_map(mapped_string.data(), mapped_string.size());
9587 std::string out;
9588 size_t label_start = 0;
9589
9590 while (label_start != mapped_string.size()) {
9591 size_t loc_dot = mapped_string.find('.', label_start);
9592 bool is_last_label = (loc_dot == std::string_view::npos);
9593 size_t label_size = is_last_label ? mapped_string.size() - label_start
9594 : loc_dot - label_start;
9595 size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;
9596 std::string_view label_view(mapped_string.data() + label_start, label_size);
9597 label_start += label_size_with_dot;
9598 if (label_size == 0) {
9599 // empty label? Nothing to do.
9600 } else if (begins_with(label_view, "xn--")) {
9601 // The xn-- part is the expensive game.
9602 out.append(label_view);
9603 std::string_view puny_segment_ascii(
9604 out.data() + out.size() - label_view.size() + 4,
9605 label_view.size() - 4);
9606 std::u32string tmp_buffer;
9607 bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);
9608 if (!is_ok) {
9609 return error;
9610 }
9611 std::u32string post_map = ada::idna::map(tmp_buffer);
9612 if (tmp_buffer != post_map) {
9613 return error;
9614 }
9615 std::u32string pre_normal = post_map;
9616 normalize(post_map);
9617 if (post_map != pre_normal) {
9618 return error;
9619 }
9620 if (post_map.empty()) {
9621 return error;
9622 }
9623 if (!is_label_valid(post_map)) {
9624 return error;
9625 }
9626 } else {
9627 out.append(label_view);
9628 }
9629 if (!is_last_label) {
9630 out.push_back('.');
9631 }
9632 }
9633 return out;
9634 }
9635
9636 // We return "" on error.
to_ascii(std::string_view ut8_string)9637 std::string to_ascii(std::string_view ut8_string) {
9638 if (is_ascii(ut8_string)) {
9639 return from_ascii_to_ascii(ut8_string);
9640 }
9641 static const std::string error = "";
9642 // We convert to UTF-32
9643 size_t utf32_length =
9644 ada::idna::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
9645 std::u32string utf32(utf32_length, '\0');
9646 size_t actual_utf32_length = ada::idna::utf8_to_utf32(
9647 ut8_string.data(), ut8_string.size(), utf32.data());
9648 if (actual_utf32_length == 0) {
9649 return error;
9650 }
9651 // mapping
9652 utf32 = ada::idna::map(utf32);
9653 normalize(utf32);
9654 std::string out;
9655 size_t label_start = 0;
9656
9657 while (label_start != utf32.size()) {
9658 size_t loc_dot = utf32.find('.', label_start);
9659 bool is_last_label = (loc_dot == std::string_view::npos);
9660 size_t label_size =
9661 is_last_label ? utf32.size() - label_start : loc_dot - label_start;
9662 size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;
9663 std::u32string_view label_view(utf32.data() + label_start, label_size);
9664 label_start += label_size_with_dot;
9665 if (label_size == 0) {
9666 // empty label? Nothing to do.
9667 } else if (begins_with(label_view, U"xn--")) {
9668 // we do not need to check, e.g., Xn-- because mapping goes to lower case
9669 for (char32_t c : label_view) {
9670 if (c >= 0x80) {
9671 return error;
9672 }
9673 out += (unsigned char)(c);
9674 }
9675 std::string_view puny_segment_ascii(
9676 out.data() + out.size() - label_view.size() + 4,
9677 label_view.size() - 4);
9678 std::u32string tmp_buffer;
9679 bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);
9680 if (!is_ok) {
9681 return error;
9682 }
9683 std::u32string post_map = ada::idna::map(tmp_buffer);
9684 if (tmp_buffer != post_map) {
9685 return error;
9686 }
9687 std::u32string pre_normal = post_map;
9688 normalize(post_map);
9689 if (post_map != pre_normal) {
9690 return error;
9691 }
9692 if (post_map.empty()) {
9693 return error;
9694 }
9695 if (!is_label_valid(post_map)) {
9696 return error;
9697 }
9698 } else {
9699 // The fast path here is an ascii label.
9700 if (is_ascii(label_view)) {
9701 // no validation needed.
9702 for (char32_t c : label_view) {
9703 out += (unsigned char)(c);
9704 }
9705 } else {
9706 // slow path.
9707 // first check validity.
9708 if (!is_label_valid(label_view)) {
9709 return error;
9710 }
9711 // It is valid! So now we must encode it as punycode...
9712 out.append("xn--");
9713 bool is_ok = ada::idna::utf32_to_punycode(label_view, out);
9714 if (!is_ok) {
9715 return error;
9716 }
9717 }
9718 }
9719 if (!is_last_label) {
9720 out.push_back('.');
9721 }
9722 }
9723 return out;
9724 }
9725 } // namespace ada::idna
9726 /* end file src/to_ascii.cpp */
9727 /* begin file src/to_unicode.cpp */
9728
9729 #include <algorithm>
9730 #include <string>
9731
9732
9733 namespace ada::idna {
to_unicode(std::string_view input)9734 std::string to_unicode(std::string_view input) {
9735 std::string output;
9736 output.reserve(input.size());
9737
9738 size_t label_start = 0;
9739 while (label_start < input.size()) {
9740 size_t loc_dot = input.find('.', label_start);
9741 bool is_last_label = (loc_dot == std::string_view::npos);
9742 size_t label_size =
9743 is_last_label ? input.size() - label_start : loc_dot - label_start;
9744 auto label_view = std::string_view(input.data() + label_start, label_size);
9745
9746 if (ada::idna::begins_with(label_view, "xn--") &&
9747 ada::idna::is_ascii(label_view)) {
9748 label_view.remove_prefix(4);
9749 if (ada::idna::verify_punycode(label_view)) {
9750 std::u32string tmp_buffer;
9751 if (ada::idna::punycode_to_utf32(label_view, tmp_buffer)) {
9752 auto utf8_size = ada::idna::utf8_length_from_utf32(tmp_buffer.data(),
9753 tmp_buffer.size());
9754 std::string final_utf8(utf8_size, '\0');
9755 ada::idna::utf32_to_utf8(tmp_buffer.data(), tmp_buffer.size(),
9756 final_utf8.data());
9757 output.append(final_utf8);
9758 } else {
9759 // ToUnicode never fails. If any step fails, then the original input
9760 // sequence is returned immediately in that step.
9761 output.append(
9762 std::string_view(input.data() + label_start, label_size));
9763 }
9764 } else {
9765 output.append(std::string_view(input.data() + label_start, label_size));
9766 }
9767 } else {
9768 output.append(label_view);
9769 }
9770
9771 if (!is_last_label) {
9772 output.push_back('.');
9773 }
9774
9775 label_start += label_size + 1;
9776 }
9777
9778 return output;
9779 }
9780 } // namespace ada::idna
9781 /* end file src/to_unicode.cpp */
9782 /* end file src/idna.cpp */
9783 /* end file src/ada_idna.cpp */
9784 ADA_POP_DISABLE_WARNINGS
9785
9786 #include <algorithm>
9787 #if ADA_NEON
9788 #include <arm_neon.h>
9789 #elif ADA_SSE2
9790 #include <emmintrin.h>
9791 #endif
9792
9793 namespace ada::unicode {
9794
broadcast(uint8_t v)9795 constexpr uint64_t broadcast(uint8_t v) noexcept {
9796 return 0x101010101010101ull * v;
9797 }
9798
to_lower_ascii(char * input,size_t length)9799 constexpr bool to_lower_ascii(char* input, size_t length) noexcept {
9800 uint64_t broadcast_80 = broadcast(0x80);
9801 uint64_t broadcast_Ap = broadcast(128 - 'A');
9802 uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
9803 uint64_t non_ascii = 0;
9804 size_t i = 0;
9805
9806 for (; i + 7 < length; i += 8) {
9807 uint64_t word{};
9808 memcpy(&word, input + i, sizeof(word));
9809 non_ascii |= (word & broadcast_80);
9810 word ^=
9811 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
9812 memcpy(input + i, &word, sizeof(word));
9813 }
9814 if (i < length) {
9815 uint64_t word{};
9816 memcpy(&word, input + i, length - i);
9817 non_ascii |= (word & broadcast_80);
9818 word ^=
9819 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
9820 memcpy(input + i, &word, length - i);
9821 }
9822 return non_ascii == 0;
9823 }
9824 #if ADA_NEON
has_tabs_or_newline(std::string_view user_input)9825 ada_really_inline bool has_tabs_or_newline(
9826 std::string_view user_input) noexcept {
9827 size_t i = 0;
9828 const uint8x16_t mask1 = vmovq_n_u8('\r');
9829 const uint8x16_t mask2 = vmovq_n_u8('\n');
9830 const uint8x16_t mask3 = vmovq_n_u8('\t');
9831 uint8x16_t running{0};
9832 for (; i + 15 < user_input.size(); i += 16) {
9833 uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i);
9834 running = vorrq_u8(vorrq_u8(running, vorrq_u8(vceqq_u8(word, mask1),
9835 vceqq_u8(word, mask2))),
9836 vceqq_u8(word, mask3));
9837 }
9838 if (i < user_input.size()) {
9839 uint8_t buffer[16]{};
9840 memcpy(buffer, user_input.data() + i, user_input.size() - i);
9841 uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i);
9842 running = vorrq_u8(vorrq_u8(running, vorrq_u8(vceqq_u8(word, mask1),
9843 vceqq_u8(word, mask2))),
9844 vceqq_u8(word, mask3));
9845 }
9846 return vmaxvq_u8(running) != 0;
9847 }
9848 #elif ADA_SSE2
has_tabs_or_newline(std::string_view user_input)9849 ada_really_inline bool has_tabs_or_newline(
9850 std::string_view user_input) noexcept {
9851 size_t i = 0;
9852 const __m128i mask1 = _mm_set1_epi8('\r');
9853 const __m128i mask2 = _mm_set1_epi8('\n');
9854 const __m128i mask3 = _mm_set1_epi8('\t');
9855 __m128i running{0};
9856 for (; i + 15 < user_input.size(); i += 16) {
9857 __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));
9858 running = _mm_or_si128(
9859 _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
9860 _mm_cmpeq_epi8(word, mask2))),
9861 _mm_cmpeq_epi8(word, mask3));
9862 }
9863 if (i < user_input.size()) {
9864 alignas(16) uint8_t buffer[16]{};
9865 memcpy(buffer, user_input.data() + i, user_input.size() - i);
9866 __m128i word = _mm_load_si128((const __m128i*)buffer);
9867 running = _mm_or_si128(
9868 _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
9869 _mm_cmpeq_epi8(word, mask2))),
9870 _mm_cmpeq_epi8(word, mask3));
9871 }
9872 return _mm_movemask_epi8(running) != 0;
9873 }
9874 #else
has_tabs_or_newline(std::string_view user_input)9875 ada_really_inline bool has_tabs_or_newline(
9876 std::string_view user_input) noexcept {
9877 auto has_zero_byte = [](uint64_t v) {
9878 return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);
9879 };
9880 size_t i = 0;
9881 uint64_t mask1 = broadcast('\r');
9882 uint64_t mask2 = broadcast('\n');
9883 uint64_t mask3 = broadcast('\t');
9884 uint64_t running{0};
9885 for (; i + 7 < user_input.size(); i += 8) {
9886 uint64_t word{};
9887 memcpy(&word, user_input.data() + i, sizeof(word));
9888 uint64_t xor1 = word ^ mask1;
9889 uint64_t xor2 = word ^ mask2;
9890 uint64_t xor3 = word ^ mask3;
9891 running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
9892 }
9893 if (i < user_input.size()) {
9894 uint64_t word{};
9895 memcpy(&word, user_input.data() + i, user_input.size() - i);
9896 uint64_t xor1 = word ^ mask1;
9897 uint64_t xor2 = word ^ mask2;
9898 uint64_t xor3 = word ^ mask3;
9899 running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
9900 }
9901 return running;
9902 }
9903 #endif
9904
9905 // A forbidden host code point is U+0000 NULL, U+0009 TAB, U+000A LF, U+000D CR,
9906 // U+0020 SPACE, U+0023 (#), U+002F (/), U+003A (:), U+003C (<), U+003E (>),
9907 // U+003F (?), U+0040 (@), U+005B ([), U+005C (\), U+005D (]), U+005E (^), or
9908 // U+007C (|).
9909 constexpr static bool is_forbidden_host_code_point_table[] = {
9910 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9911 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
9912 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
9913 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
9914 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9915 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9916 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9917 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9918 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9919 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9920 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
9921 static_assert(sizeof(is_forbidden_host_code_point_table) == 256);
9922
is_forbidden_host_code_point(const char c)9923 ada_really_inline constexpr bool is_forbidden_host_code_point(
9924 const char c) noexcept {
9925 return is_forbidden_host_code_point_table[uint8_t(c)];
9926 }
9927
9928 static_assert(unicode::is_forbidden_host_code_point('\0'));
9929 static_assert(unicode::is_forbidden_host_code_point('\t'));
9930 static_assert(unicode::is_forbidden_host_code_point('\n'));
9931 static_assert(unicode::is_forbidden_host_code_point('\r'));
9932 static_assert(unicode::is_forbidden_host_code_point(' '));
9933 static_assert(unicode::is_forbidden_host_code_point('#'));
9934 static_assert(unicode::is_forbidden_host_code_point('/'));
9935 static_assert(unicode::is_forbidden_host_code_point(':'));
9936 static_assert(unicode::is_forbidden_host_code_point('?'));
9937 static_assert(unicode::is_forbidden_host_code_point('@'));
9938 static_assert(unicode::is_forbidden_host_code_point('['));
9939 static_assert(unicode::is_forbidden_host_code_point('?'));
9940 static_assert(unicode::is_forbidden_host_code_point('<'));
9941 static_assert(unicode::is_forbidden_host_code_point('>'));
9942 static_assert(unicode::is_forbidden_host_code_point('\\'));
9943 static_assert(unicode::is_forbidden_host_code_point(']'));
9944 static_assert(unicode::is_forbidden_host_code_point('^'));
9945 static_assert(unicode::is_forbidden_host_code_point('|'));
9946
9947 constexpr static uint8_t is_forbidden_domain_code_point_table[] = {
9948 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9949 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
9950 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
9951 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
9952 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9953 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9954 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9955 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9956 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9957 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9958 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
9959
9960 static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
9961
is_forbidden_domain_code_point(const char c)9962 ada_really_inline constexpr bool is_forbidden_domain_code_point(
9963 const char c) noexcept {
9964 return is_forbidden_domain_code_point_table[uint8_t(c)];
9965 }
9966
contains_forbidden_domain_code_point(const char * input,size_t length)9967 ada_really_inline constexpr bool contains_forbidden_domain_code_point(
9968 const char* input, size_t length) noexcept {
9969 size_t i = 0;
9970 uint8_t accumulator{};
9971 for (; i + 4 <= length; i += 4) {
9972 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
9973 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 1])];
9974 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 2])];
9975 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 3])];
9976 }
9977 for (; i < length; i++) {
9978 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
9979 }
9980 return accumulator;
9981 }
9982
9983 constexpr static uint8_t is_forbidden_domain_code_point_table_or_upper[] = {
9984 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9985 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
9986 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
9987 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0,
9988 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9989 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9990 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9991 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9992 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9993 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9994 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
9995
9996 static_assert(sizeof(is_forbidden_domain_code_point_table_or_upper) == 256);
9997 static_assert(is_forbidden_domain_code_point_table_or_upper[uint8_t('A')] == 2);
9998 static_assert(is_forbidden_domain_code_point_table_or_upper[uint8_t('Z')] == 2);
9999
10000 ada_really_inline constexpr uint8_t
contains_forbidden_domain_code_point_or_upper(const char * input,size_t length)10001 contains_forbidden_domain_code_point_or_upper(const char* input,
10002 size_t length) noexcept {
10003 size_t i = 0;
10004 uint8_t accumulator{};
10005 for (; i + 4 <= length; i += 4) {
10006 accumulator |=
10007 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
10008 accumulator |=
10009 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 1])];
10010 accumulator |=
10011 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 2])];
10012 accumulator |=
10013 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 3])];
10014 }
10015 for (; i < length; i++) {
10016 accumulator |=
10017 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
10018 }
10019 return accumulator;
10020 }
10021
10022 static_assert(unicode::is_forbidden_domain_code_point('%'));
10023 static_assert(unicode::is_forbidden_domain_code_point('\x7f'));
10024 static_assert(unicode::is_forbidden_domain_code_point('\0'));
10025 static_assert(unicode::is_forbidden_domain_code_point('\t'));
10026 static_assert(unicode::is_forbidden_domain_code_point('\n'));
10027 static_assert(unicode::is_forbidden_domain_code_point('\r'));
10028 static_assert(unicode::is_forbidden_domain_code_point(' '));
10029 static_assert(unicode::is_forbidden_domain_code_point('#'));
10030 static_assert(unicode::is_forbidden_domain_code_point('/'));
10031 static_assert(unicode::is_forbidden_domain_code_point(':'));
10032 static_assert(unicode::is_forbidden_domain_code_point('?'));
10033 static_assert(unicode::is_forbidden_domain_code_point('@'));
10034 static_assert(unicode::is_forbidden_domain_code_point('['));
10035 static_assert(unicode::is_forbidden_domain_code_point('?'));
10036 static_assert(unicode::is_forbidden_domain_code_point('<'));
10037 static_assert(unicode::is_forbidden_domain_code_point('>'));
10038 static_assert(unicode::is_forbidden_domain_code_point('\\'));
10039 static_assert(unicode::is_forbidden_domain_code_point(']'));
10040 static_assert(unicode::is_forbidden_domain_code_point('^'));
10041 static_assert(unicode::is_forbidden_domain_code_point('|'));
10042
10043 constexpr static bool is_alnum_plus_table[] = {
10044 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10045 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
10046 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
10047 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
10048 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
10049 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10050 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10051 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10052 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10053 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10054 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
10055
10056 static_assert(sizeof(is_alnum_plus_table) == 256);
10057
is_alnum_plus(const char c)10058 ada_really_inline constexpr bool is_alnum_plus(const char c) noexcept {
10059 return is_alnum_plus_table[uint8_t(c)];
10060 // A table is almost surely much faster than the
10061 // following under most compilers: return
10062 // return (std::isalnum(c) || c == '+' || c == '-' || c == '.');
10063 }
10064 static_assert(unicode::is_alnum_plus('+'));
10065 static_assert(unicode::is_alnum_plus('-'));
10066 static_assert(unicode::is_alnum_plus('.'));
10067 static_assert(unicode::is_alnum_plus('0'));
10068 static_assert(unicode::is_alnum_plus('1'));
10069 static_assert(unicode::is_alnum_plus('a'));
10070 static_assert(unicode::is_alnum_plus('b'));
10071
is_ascii_hex_digit(const char c)10072 ada_really_inline constexpr bool is_ascii_hex_digit(const char c) noexcept {
10073 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
10074 (c >= 'a' && c <= 'f');
10075 }
10076
is_c0_control_or_space(const char c)10077 ada_really_inline constexpr bool is_c0_control_or_space(const char c) noexcept {
10078 return (unsigned char)c <= ' ';
10079 }
10080
is_ascii_tab_or_newline(const char c)10081 ada_really_inline constexpr bool is_ascii_tab_or_newline(
10082 const char c) noexcept {
10083 return c == '\t' || c == '\n' || c == '\r';
10084 }
10085
10086 constexpr std::string_view table_is_double_dot_path_segment[] = {
10087 "..", "%2e.", ".%2e", "%2e%2e"};
10088
is_double_dot_path_segment(std::string_view input)10089 ada_really_inline ada_constexpr bool is_double_dot_path_segment(
10090 std::string_view input) noexcept {
10091 // This will catch most cases:
10092 // The length must be 2,4 or 6.
10093 // We divide by two and require
10094 // that the result be between 1 and 3 inclusively.
10095 uint64_t half_length = uint64_t(input.size()) / 2;
10096 if (half_length - 1 > 2) {
10097 return false;
10098 }
10099 // We have a string of length 2, 4 or 6.
10100 // We now check the first character:
10101 if ((input[0] != '.') && (input[0] != '%')) {
10102 return false;
10103 }
10104 // We are unlikely the get beyond this point.
10105 int hash_value = (input.size() + (unsigned)(input[0])) & 3;
10106 const std::string_view target = table_is_double_dot_path_segment[hash_value];
10107 if (target.size() != input.size()) {
10108 return false;
10109 }
10110 // We almost never get here.
10111 // Optimizing the rest is relatively unimportant.
10112 auto prefix_equal_unsafe = [](std::string_view a, std::string_view b) {
10113 uint16_t A, B;
10114 memcpy(&A, a.data(), sizeof(A));
10115 memcpy(&B, b.data(), sizeof(B));
10116 return A == B;
10117 };
10118 if (!prefix_equal_unsafe(input, target)) {
10119 return false;
10120 }
10121 for (size_t i = 2; i < input.size(); i++) {
10122 char c = input[i];
10123 if ((uint8_t((c | 0x20) - 0x61) <= 25 ? (c | 0x20) : c) != target[i]) {
10124 return false;
10125 }
10126 }
10127 return true;
10128 // The above code might be a bit better than the code below. Compilers
10129 // are not stupid and may use the fact that these strings have length 2,4 and
10130 // 6 and other tricks.
10131 // return input == ".." ||
10132 // input == ".%2e" || input == ".%2E" ||
10133 // input == "%2e." || input == "%2E." ||
10134 // input == "%2e%2e" || input == "%2E%2E" || input == "%2E%2e" || input ==
10135 // "%2e%2E";
10136 }
10137
is_single_dot_path_segment(std::string_view input)10138 ada_really_inline constexpr bool is_single_dot_path_segment(
10139 std::string_view input) noexcept {
10140 return input == "." || input == "%2e" || input == "%2E";
10141 }
10142
is_lowercase_hex(const char c)10143 ada_really_inline constexpr bool is_lowercase_hex(const char c) noexcept {
10144 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
10145 }
10146
convert_hex_to_binary(const char c)10147 unsigned constexpr convert_hex_to_binary(const char c) noexcept {
10148 // this code can be optimized.
10149 if (c <= '9') {
10150 return c - '0';
10151 }
10152 char del = c >= 'a' ? 'a' : 'A';
10153 return 10 + (c - del);
10154 }
10155
percent_decode(const std::string_view input,size_t first_percent)10156 std::string percent_decode(const std::string_view input, size_t first_percent) {
10157 // next line is for safety only, we expect users to avoid calling
10158 // percent_decode when first_percent is outside the range.
10159 if (first_percent == std::string_view::npos) {
10160 return std::string(input);
10161 }
10162 std::string dest(input.substr(0, first_percent));
10163 dest.reserve(input.length());
10164 const char* pointer = input.data() + first_percent;
10165 const char* end = input.data() + input.size();
10166 // Optimization opportunity: if the following code gets
10167 // called often, it can be optimized quite a bit.
10168 while (pointer < end) {
10169 const char ch = pointer[0];
10170 size_t remaining = end - pointer - 1;
10171 if (ch != '%' || remaining < 2 ||
10172 ( // ch == '%' && // It is unnecessary to check that ch == '%'.
10173 (!is_ascii_hex_digit(pointer[1]) ||
10174 !is_ascii_hex_digit(pointer[2])))) {
10175 dest += ch;
10176 pointer++;
10177 continue;
10178 } else {
10179 unsigned a = convert_hex_to_binary(pointer[1]);
10180 unsigned b = convert_hex_to_binary(pointer[2]);
10181 char c = static_cast<char>(a * 16 + b);
10182 dest += c;
10183 pointer += 3;
10184 }
10185 }
10186 return dest;
10187 }
10188
percent_encode(const std::string_view input,const uint8_t character_set[])10189 std::string percent_encode(const std::string_view input,
10190 const uint8_t character_set[]) {
10191 auto pointer =
10192 std::find_if(input.begin(), input.end(), [character_set](const char c) {
10193 return character_sets::bit_at(character_set, c);
10194 });
10195 // Optimization: Don't iterate if percent encode is not required
10196 if (pointer == input.end()) {
10197 return std::string(input);
10198 }
10199
10200 std::string result(input.substr(0, std::distance(input.begin(), pointer)));
10201 result.reserve(input.length()); // in the worst case, percent encoding might
10202 // produce 3 characters.
10203
10204 for (; pointer != input.end(); pointer++) {
10205 if (character_sets::bit_at(character_set, *pointer)) {
10206 result.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
10207 } else {
10208 result += *pointer;
10209 }
10210 }
10211
10212 return result;
10213 }
10214
10215 template <bool append>
percent_encode(const std::string_view input,const uint8_t character_set[],std::string & out)10216 bool percent_encode(const std::string_view input, const uint8_t character_set[],
10217 std::string& out) {
10218 ada_log("percent_encode ", input, " to output string while ",
10219 append ? "appending" : "overwriting");
10220 auto pointer =
10221 std::find_if(input.begin(), input.end(), [character_set](const char c) {
10222 return character_sets::bit_at(character_set, c);
10223 });
10224 ada_log("percent_encode done checking, moved to ",
10225 std::distance(input.begin(), pointer));
10226
10227 // Optimization: Don't iterate if percent encode is not required
10228 if (pointer == input.end()) {
10229 ada_log("percent_encode encoding not needed.");
10230 return false;
10231 }
10232 if (!append) {
10233 out.clear();
10234 }
10235 ada_log("percent_encode appending ", std::distance(input.begin(), pointer),
10236 " bytes");
10237 out.append(input.data(), std::distance(input.begin(), pointer));
10238 ada_log("percent_encode processing ", std::distance(pointer, input.end()),
10239 " bytes");
10240 for (; pointer != input.end(); pointer++) {
10241 if (character_sets::bit_at(character_set, *pointer)) {
10242 out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
10243 } else {
10244 out += *pointer;
10245 }
10246 }
10247 return true;
10248 }
10249
to_ascii(std::optional<std::string> & out,const std::string_view plain,size_t first_percent)10250 bool to_ascii(std::optional<std::string>& out, const std::string_view plain,
10251 size_t first_percent) {
10252 std::string percent_decoded_buffer;
10253 std::string_view input = plain;
10254 if (first_percent != std::string_view::npos) {
10255 percent_decoded_buffer = unicode::percent_decode(plain, first_percent);
10256 input = percent_decoded_buffer;
10257 }
10258 // input is a non-empty UTF-8 string, must be percent decoded
10259 std::string idna_ascii = ada::idna::to_ascii(input);
10260 if (idna_ascii.empty() || contains_forbidden_domain_code_point(
10261 idna_ascii.data(), idna_ascii.size())) {
10262 return false;
10263 }
10264 out = std::move(idna_ascii);
10265 return true;
10266 }
10267
percent_encode(const std::string_view input,const uint8_t character_set[],size_t index)10268 std::string percent_encode(const std::string_view input,
10269 const uint8_t character_set[], size_t index) {
10270 std::string out;
10271 out.append(input.data(), index);
10272 auto pointer = input.begin() + index;
10273 for (; pointer != input.end(); pointer++) {
10274 if (character_sets::bit_at(character_set, *pointer)) {
10275 out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
10276 } else {
10277 out += *pointer;
10278 }
10279 }
10280 return out;
10281 }
10282
to_unicode(std::string_view input)10283 std::string to_unicode(std::string_view input) {
10284 return ada::idna::to_unicode(input);
10285 }
10286
10287 } // namespace ada::unicode
10288 /* end file src/unicode.cpp */
10289 /* begin file src/serializers.cpp */
10290
10291 #include <array>
10292 #include <string>
10293
10294 namespace ada::serializers {
10295
find_longest_sequence_of_ipv6_pieces(const std::array<uint16_t,8> & address,size_t & compress,size_t & compress_length)10296 void find_longest_sequence_of_ipv6_pieces(
10297 const std::array<uint16_t, 8>& address, size_t& compress,
10298 size_t& compress_length) noexcept {
10299 for (size_t i = 0; i < 8; i++) {
10300 if (address[i] == 0) {
10301 size_t next = i + 1;
10302 while (next != 8 && address[next] == 0) ++next;
10303 const size_t count = next - i;
10304 if (compress_length < count) {
10305 compress_length = count;
10306 compress = i;
10307 if (next == 8) break;
10308 i = next;
10309 }
10310 }
10311 }
10312 }
10313
ipv6(const std::array<uint16_t,8> & address)10314 std::string ipv6(const std::array<uint16_t, 8>& address) noexcept {
10315 size_t compress_length = 0; // The length of a long sequence of zeros.
10316 size_t compress = 0; // The start of a long sequence of zeros.
10317 find_longest_sequence_of_ipv6_pieces(address, compress, compress_length);
10318
10319 if (compress_length <= 1) {
10320 // Optimization opportunity: Find a faster way then snprintf for imploding
10321 // and return here.
10322 compress = compress_length = 8;
10323 }
10324
10325 std::string output(4 * 8 + 7 + 2, '\0');
10326 size_t piece_index = 0;
10327 char* point = output.data();
10328 char* point_end = output.data() + output.size();
10329 *point++ = '[';
10330 while (true) {
10331 if (piece_index == compress) {
10332 *point++ = ':';
10333 // If we skip a value initially, we need to write '::', otherwise
10334 // a single ':' will do since it follows a previous ':'.
10335 if (piece_index == 0) {
10336 *point++ = ':';
10337 }
10338 piece_index += compress_length;
10339 if (piece_index == 8) {
10340 break;
10341 }
10342 }
10343 point = std::to_chars(point, point_end, address[piece_index], 16).ptr;
10344 piece_index++;
10345 if (piece_index == 8) {
10346 break;
10347 }
10348 *point++ = ':';
10349 }
10350 *point++ = ']';
10351 output.resize(point - output.data());
10352 return output;
10353 }
10354
ipv4(const uint64_t address)10355 std::string ipv4(const uint64_t address) noexcept {
10356 std::string output(15, '\0');
10357 char* point = output.data();
10358 char* point_end = output.data() + output.size();
10359 point = std::to_chars(point, point_end, uint8_t(address >> 24)).ptr;
10360 for (int i = 2; i >= 0; i--) {
10361 *point++ = '.';
10362 point = std::to_chars(point, point_end, uint8_t(address >> (i * 8))).ptr;
10363 }
10364 output.resize(point - output.data());
10365 return output;
10366 }
10367
10368 } // namespace ada::serializers
10369 /* end file src/serializers.cpp */
10370 /* begin file src/implementation.cpp */
10371 #include <string_view>
10372
10373
10374 namespace ada {
10375
10376 template <class result_type>
parse(std::string_view input,const result_type * base_url)10377 ada_warn_unused tl::expected<result_type, ada::errors> parse(
10378 std::string_view input, const result_type* base_url) {
10379 result_type u = ada::parser::parse_url<result_type>(input, base_url);
10380 if (!u.is_valid) {
10381 return tl::unexpected(errors::generic_error);
10382 }
10383 return u;
10384 }
10385
10386 template ada::result<url> parse<url>(std::string_view input,
10387 const url* base_url = nullptr);
10388 template ada::result<url_aggregator> parse<url_aggregator>(
10389 std::string_view input, const url_aggregator* base_url = nullptr);
10390
href_from_file(std::string_view input)10391 std::string href_from_file(std::string_view input) {
10392 // This is going to be much faster than constructing a URL.
10393 std::string tmp_buffer;
10394 std::string_view internal_input;
10395 if (unicode::has_tabs_or_newline(input)) {
10396 tmp_buffer = input;
10397 helpers::remove_ascii_tab_or_newline(tmp_buffer);
10398 internal_input = tmp_buffer;
10399 } else {
10400 internal_input = input;
10401 }
10402 std::string path;
10403 if (internal_input.empty()) {
10404 path = "/";
10405 } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
10406 helpers::parse_prepared_path(internal_input.substr(1),
10407 ada::scheme::type::FILE, path);
10408 } else {
10409 helpers::parse_prepared_path(internal_input, ada::scheme::type::FILE, path);
10410 }
10411 return "file://" + path;
10412 }
10413
can_parse(std::string_view input,const std::string_view * base_input)10414 bool can_parse(std::string_view input, const std::string_view* base_input) {
10415 ada::result<ada::url_aggregator> base;
10416 ada::url_aggregator* base_pointer = nullptr;
10417 if (base_input != nullptr) {
10418 base = ada::parse<url_aggregator>(*base_input);
10419 if (!base) {
10420 return false;
10421 }
10422 base_pointer = &base.value();
10423 }
10424 return ada::parse<url_aggregator>(input, base_pointer).has_value();
10425 }
10426
to_string(ada::encoding_type type)10427 ada_warn_unused std::string to_string(ada::encoding_type type) {
10428 switch (type) {
10429 case ada::encoding_type::UTF8:
10430 return "UTF-8";
10431 case ada::encoding_type::UTF_16LE:
10432 return "UTF-16LE";
10433 case ada::encoding_type::UTF_16BE:
10434 return "UTF-16BE";
10435 default:
10436 unreachable();
10437 }
10438 }
10439
10440 } // namespace ada
10441 /* end file src/implementation.cpp */
10442 /* begin file src/helpers.cpp */
10443
10444 #include <algorithm>
10445 #include <charconv>
10446 #include <cstring>
10447 #include <sstream>
10448
10449 namespace ada::helpers {
10450
10451 template <typename out_iter>
encode_json(std::string_view view,out_iter out)10452 void encode_json(std::string_view view, out_iter out) {
10453 // trivial implementation. could be faster.
10454 const char* hexvalues =
10455 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
10456 for (uint8_t c : view) {
10457 if (c == '\\') {
10458 *out++ = '\\';
10459 *out++ = '\\';
10460 } else if (c == '"') {
10461 *out++ = '\\';
10462 *out++ = '"';
10463 } else if (c <= 0x1f) {
10464 *out++ = '\\';
10465 *out++ = 'u';
10466 *out++ = '0';
10467 *out++ = '0';
10468 *out++ = hexvalues[2 * c];
10469 *out++ = hexvalues[2 * c + 1];
10470 } else {
10471 *out++ = c;
10472 }
10473 }
10474 }
10475
get_state(ada::state s)10476 ada_unused std::string get_state(ada::state s) {
10477 switch (s) {
10478 case ada::state::AUTHORITY:
10479 return "Authority";
10480 case ada::state::SCHEME_START:
10481 return "Scheme Start";
10482 case ada::state::SCHEME:
10483 return "Scheme";
10484 case ada::state::HOST:
10485 return "Host";
10486 case ada::state::NO_SCHEME:
10487 return "No Scheme";
10488 case ada::state::FRAGMENT:
10489 return "Fragment";
10490 case ada::state::RELATIVE_SCHEME:
10491 return "Relative Scheme";
10492 case ada::state::RELATIVE_SLASH:
10493 return "Relative Slash";
10494 case ada::state::FILE:
10495 return "File";
10496 case ada::state::FILE_HOST:
10497 return "File Host";
10498 case ada::state::FILE_SLASH:
10499 return "File Slash";
10500 case ada::state::PATH_OR_AUTHORITY:
10501 return "Path or Authority";
10502 case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES:
10503 return "Special Authority Ignore Slashes";
10504 case ada::state::SPECIAL_AUTHORITY_SLASHES:
10505 return "Special Authority Slashes";
10506 case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY:
10507 return "Special Relative or Authority";
10508 case ada::state::QUERY:
10509 return "Query";
10510 case ada::state::PATH:
10511 return "Path";
10512 case ada::state::PATH_START:
10513 return "Path Start";
10514 case ada::state::OPAQUE_PATH:
10515 return "Opaque Path";
10516 case ada::state::PORT:
10517 return "Port";
10518 default:
10519 return "unknown state";
10520 }
10521 }
10522
prune_hash(std::string_view & input)10523 ada_really_inline std::optional<std::string_view> prune_hash(
10524 std::string_view& input) noexcept {
10525 // compiles down to 20--30 instructions including a class to memchr (C
10526 // function). this function should be quite fast.
10527 size_t location_of_first = input.find('#');
10528 if (location_of_first == std::string_view::npos) {
10529 return std::nullopt;
10530 }
10531 std::string_view hash = input;
10532 hash.remove_prefix(location_of_first + 1);
10533 input.remove_suffix(input.size() - location_of_first);
10534 return hash;
10535 }
10536
shorten_path(std::string & path,ada::scheme::type type)10537 ada_really_inline bool shorten_path(std::string& path,
10538 ada::scheme::type type) noexcept {
10539 size_t first_delimiter = path.find_first_of('/', 1);
10540
10541 // Let path be url's path.
10542 // If url's scheme is "file", path's size is 1, and path[0] is a normalized
10543 // Windows drive letter, then return.
10544 if (type == ada::scheme::type::FILE &&
10545 first_delimiter == std::string_view::npos && !path.empty()) {
10546 if (checkers::is_normalized_windows_drive_letter(
10547 helpers::substring(path, 1))) {
10548 return false;
10549 }
10550 }
10551
10552 // Remove path's last item, if any.
10553 size_t last_delimiter = path.rfind('/');
10554 if (last_delimiter != std::string::npos) {
10555 path.erase(last_delimiter);
10556 return true;
10557 }
10558
10559 return false;
10560 }
10561
shorten_path(std::string_view & path,ada::scheme::type type)10562 ada_really_inline bool shorten_path(std::string_view& path,
10563 ada::scheme::type type) noexcept {
10564 size_t first_delimiter = path.find_first_of('/', 1);
10565
10566 // Let path be url's path.
10567 // If url's scheme is "file", path's size is 1, and path[0] is a normalized
10568 // Windows drive letter, then return.
10569 if (type == ada::scheme::type::FILE &&
10570 first_delimiter == std::string_view::npos && !path.empty()) {
10571 if (checkers::is_normalized_windows_drive_letter(
10572 helpers::substring(path, 1))) {
10573 return false;
10574 }
10575 }
10576
10577 // Remove path's last item, if any.
10578 if (!path.empty()) {
10579 size_t slash_loc = path.rfind('/');
10580 if (slash_loc != std::string_view::npos) {
10581 path.remove_suffix(path.size() - slash_loc);
10582 return true;
10583 }
10584 }
10585
10586 return false;
10587 }
10588
remove_ascii_tab_or_newline(std::string & input)10589 ada_really_inline void remove_ascii_tab_or_newline(
10590 std::string& input) noexcept {
10591 // if this ever becomes a performance issue, we could use an approach similar
10592 // to has_tabs_or_newline
10593 input.erase(std::remove_if(input.begin(), input.end(),
10594 [](char c) {
10595 return ada::unicode::is_ascii_tab_or_newline(c);
10596 }),
10597 input.end());
10598 }
10599
substring(std::string_view input,size_t pos)10600 ada_really_inline std::string_view substring(std::string_view input,
10601 size_t pos) noexcept {
10602 ADA_ASSERT_TRUE(pos <= input.size());
10603 // The following is safer but unneeded if we have the above line:
10604 // return pos > input.size() ? std::string_view() : input.substr(pos);
10605 return input.substr(pos);
10606 }
10607
resize(std::string_view & input,size_t pos)10608 ada_really_inline void resize(std::string_view& input, size_t pos) noexcept {
10609 ADA_ASSERT_TRUE(pos <= input.size());
10610 input.remove_suffix(input.size() - pos);
10611 }
10612
10613 // Reverse the byte order.
swap_bytes(uint64_t val)10614 ada_really_inline uint64_t swap_bytes(uint64_t val) noexcept {
10615 // performance: this often compiles to a single instruction (e.g., bswap)
10616 return ((((val)&0xff00000000000000ull) >> 56) |
10617 (((val)&0x00ff000000000000ull) >> 40) |
10618 (((val)&0x0000ff0000000000ull) >> 24) |
10619 (((val)&0x000000ff00000000ull) >> 8) |
10620 (((val)&0x00000000ff000000ull) << 8) |
10621 (((val)&0x0000000000ff0000ull) << 24) |
10622 (((val)&0x000000000000ff00ull) << 40) |
10623 (((val)&0x00000000000000ffull) << 56));
10624 }
10625
swap_bytes_if_big_endian(uint64_t val)10626 ada_really_inline uint64_t swap_bytes_if_big_endian(uint64_t val) noexcept {
10627 // performance: under little-endian systems (most systems), this function
10628 // is free (just returns the input).
10629 #if ADA_IS_BIG_ENDIAN
10630 return swap_bytes(val);
10631 #else
10632 return val; // unchanged (trivial)
10633 #endif
10634 }
10635
10636 // starting at index location, this finds the next location of a character
10637 // :, /, \\, ? or [. If none is found, view.size() is returned.
10638 // For use within get_host_delimiter_location.
find_next_host_delimiter_special(std::string_view view,size_t location)10639 ada_really_inline size_t find_next_host_delimiter_special(
10640 std::string_view view, size_t location) noexcept {
10641 // performance: if you plan to call find_next_host_delimiter more than once,
10642 // you *really* want find_next_host_delimiter to be inlined, because
10643 // otherwise, the constants may get reloaded each time (bad).
10644 auto has_zero_byte = [](uint64_t v) {
10645 return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);
10646 };
10647 auto index_of_first_set_byte = [](uint64_t v) {
10648 return ((((v - 1) & 0x101010101010101) * 0x101010101010101) >> 56) - 1;
10649 };
10650 auto broadcast = [](uint8_t v) -> uint64_t {
10651 return 0x101010101010101ull * v;
10652 };
10653 size_t i = location;
10654 uint64_t mask1 = broadcast(':');
10655 uint64_t mask2 = broadcast('/');
10656 uint64_t mask3 = broadcast('\\');
10657 uint64_t mask4 = broadcast('?');
10658 uint64_t mask5 = broadcast('[');
10659 // This loop will get autovectorized under many optimizing compilers,
10660 // so you get actually SIMD!
10661 for (; i + 7 < view.size(); i += 8) {
10662 uint64_t word{};
10663 // performance: the next memcpy translates into a single CPU instruction.
10664 memcpy(&word, view.data() + i, sizeof(word));
10665 // performance: on little-endian systems (most systems), this next line is
10666 // free.
10667 word = swap_bytes_if_big_endian(word);
10668 uint64_t xor1 = word ^ mask1;
10669 uint64_t xor2 = word ^ mask2;
10670 uint64_t xor3 = word ^ mask3;
10671 uint64_t xor4 = word ^ mask4;
10672 uint64_t xor5 = word ^ mask5;
10673 uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |
10674 has_zero_byte(xor3) | has_zero_byte(xor4) |
10675 has_zero_byte(xor5);
10676 if (is_match) {
10677 return size_t(i + index_of_first_set_byte(is_match));
10678 }
10679 }
10680 if (i < view.size()) {
10681 uint64_t word{};
10682 // performance: the next memcpy translates into a function call, but
10683 // that is difficult to avoid. Might be a bit expensive.
10684 memcpy(&word, view.data() + i, view.size() - i);
10685 word = swap_bytes_if_big_endian(word);
10686 uint64_t xor1 = word ^ mask1;
10687 uint64_t xor2 = word ^ mask2;
10688 uint64_t xor3 = word ^ mask3;
10689 uint64_t xor4 = word ^ mask4;
10690 uint64_t xor5 = word ^ mask5;
10691 uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |
10692 has_zero_byte(xor3) | has_zero_byte(xor4) |
10693 has_zero_byte(xor5);
10694 if (is_match) {
10695 return size_t(i + index_of_first_set_byte(is_match));
10696 }
10697 }
10698 return view.size();
10699 }
10700
10701 // starting at index location, this finds the next location of a character
10702 // :, /, ? or [. If none is found, view.size() is returned.
10703 // For use within get_host_delimiter_location.
find_next_host_delimiter(std::string_view view,size_t location)10704 ada_really_inline size_t find_next_host_delimiter(std::string_view view,
10705 size_t location) noexcept {
10706 // performance: if you plan to call find_next_host_delimiter more than once,
10707 // you *really* want find_next_host_delimiter to be inlined, because
10708 // otherwise, the constants may get reloaded each time (bad).
10709 auto has_zero_byte = [](uint64_t v) {
10710 return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);
10711 };
10712 auto index_of_first_set_byte = [](uint64_t v) {
10713 return ((((v - 1) & 0x101010101010101) * 0x101010101010101) >> 56) - 1;
10714 };
10715 auto broadcast = [](uint8_t v) -> uint64_t {
10716 return 0x101010101010101ull * v;
10717 };
10718 size_t i = location;
10719 uint64_t mask1 = broadcast(':');
10720 uint64_t mask2 = broadcast('/');
10721 uint64_t mask4 = broadcast('?');
10722 uint64_t mask5 = broadcast('[');
10723 // This loop will get autovectorized under many optimizing compilers,
10724 // so you get actually SIMD!
10725 for (; i + 7 < view.size(); i += 8) {
10726 uint64_t word{};
10727 // performance: the next memcpy translates into a single CPU instruction.
10728 memcpy(&word, view.data() + i, sizeof(word));
10729 // performance: on little-endian systems (most systems), this next line is
10730 // free.
10731 word = swap_bytes_if_big_endian(word);
10732 uint64_t xor1 = word ^ mask1;
10733 uint64_t xor2 = word ^ mask2;
10734 uint64_t xor4 = word ^ mask4;
10735 uint64_t xor5 = word ^ mask5;
10736 uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |
10737 has_zero_byte(xor4) | has_zero_byte(xor5);
10738 if (is_match) {
10739 return size_t(i + index_of_first_set_byte(is_match));
10740 }
10741 }
10742 if (i < view.size()) {
10743 uint64_t word{};
10744 // performance: the next memcpy translates into a function call, but
10745 // that is difficult to avoid. Might be a bit expensive.
10746 memcpy(&word, view.data() + i, view.size() - i);
10747 // performance: on little-endian systems (most systems), this next line is
10748 // free.
10749 word = swap_bytes_if_big_endian(word);
10750 uint64_t xor1 = word ^ mask1;
10751 uint64_t xor2 = word ^ mask2;
10752 uint64_t xor4 = word ^ mask4;
10753 uint64_t xor5 = word ^ mask5;
10754 uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |
10755 has_zero_byte(xor4) | has_zero_byte(xor5);
10756 if (is_match) {
10757 return size_t(i + index_of_first_set_byte(is_match));
10758 }
10759 }
10760 return view.size();
10761 }
10762
get_host_delimiter_location(const bool is_special,std::string_view & view)10763 ada_really_inline std::pair<size_t, bool> get_host_delimiter_location(
10764 const bool is_special, std::string_view& view) noexcept {
10765 /**
10766 * The spec at https://url.spec.whatwg.org/#hostname-state expects us to
10767 * compute a variable called insideBrackets but this variable is only used
10768 * once, to check whether a ':' character was found outside brackets. Exact
10769 * text: "Otherwise, if c is U+003A (:) and insideBrackets is false, then:".
10770 * It is conceptually simpler and arguably more efficient to just return a
10771 * Boolean indicating whether ':' was found outside brackets.
10772 */
10773 const size_t view_size = view.size();
10774 size_t location = 0;
10775 bool found_colon = false;
10776 /**
10777 * Performance analysis:
10778 *
10779 * We are basically seeking the end of the hostname which can be indicated
10780 * by the end of the view, or by one of the characters ':', '/', '?', '\\'
10781 * (where '\\' is only applicable for special URLs). However, these must
10782 * appear outside a bracket range. E.g., if you have [something?]fd: then the
10783 * '?' does not count.
10784 *
10785 * So we can skip ahead to the next delimiter, as long as we include '[' in
10786 * the set of delimiters, and that we handle it first.
10787 *
10788 * So the trick is to have a fast function that locates the next delimiter.
10789 * Unless we find '[', then it only needs to be called once! Ideally, such a
10790 * function would be provided by the C++ standard library, but it seems that
10791 * find_first_of is not very fast, so we are forced to roll our own.
10792 *
10793 * We do not break into two loops for speed, but for clarity.
10794 */
10795 if (is_special) {
10796 // We move to the next delimiter.
10797 location = find_next_host_delimiter_special(view, location);
10798 // Unless we find '[' then we are going only going to have to call
10799 // find_next_host_delimiter_special once.
10800 for (; location < view_size;
10801 location = find_next_host_delimiter_special(view, location)) {
10802 if (view[location] == '[') {
10803 location = view.find(']', location);
10804 if (location == std::string_view::npos) {
10805 // performance: view.find might get translated to a memchr, which
10806 // has no notion of std::string_view::npos, so the code does not
10807 // reflect the assembly.
10808 location = view_size;
10809 break;
10810 }
10811 } else {
10812 found_colon = view[location] == ':';
10813 break;
10814 }
10815 }
10816 } else {
10817 // We move to the next delimiter.
10818 location = find_next_host_delimiter(view, location);
10819 // Unless we find '[' then we are going only going to have to call
10820 // find_next_host_delimiter_special once.
10821 for (; location < view_size;
10822 location = find_next_host_delimiter(view, location)) {
10823 if (view[location] == '[') {
10824 location = view.find(']', location);
10825 if (location == std::string_view::npos) {
10826 // performance: view.find might get translated to a memchr, which
10827 // has no notion of std::string_view::npos, so the code does not
10828 // reflect the assembly.
10829 location = view_size;
10830 break;
10831 }
10832 } else {
10833 found_colon = view[location] == ':';
10834 break;
10835 }
10836 }
10837 }
10838 // performance: remove_suffix may translate into a single instruction.
10839 view.remove_suffix(view_size - location);
10840 return {location, found_colon};
10841 }
10842
trim_c0_whitespace(std::string_view & input)10843 ada_really_inline void trim_c0_whitespace(std::string_view& input) noexcept {
10844 while (!input.empty() &&
10845 ada::unicode::is_c0_control_or_space(input.front())) {
10846 input.remove_prefix(1);
10847 }
10848 while (!input.empty() && ada::unicode::is_c0_control_or_space(input.back())) {
10849 input.remove_suffix(1);
10850 }
10851 }
10852
parse_prepared_path(std::string_view input,ada::scheme::type type,std::string & path)10853 ada_really_inline void parse_prepared_path(std::string_view input,
10854 ada::scheme::type type,
10855 std::string& path) {
10856 ada_log("parse_prepared_path ", input);
10857 uint8_t accumulator = checkers::path_signature(input);
10858 // Let us first detect a trivial case.
10859 // If it is special, we check that we have no dot, no %, no \ and no
10860 // character needing percent encoding. Otherwise, we check that we have no %,
10861 // no dot, and no character needing percent encoding.
10862 constexpr uint8_t need_encoding = 1;
10863 constexpr uint8_t backslash_char = 2;
10864 constexpr uint8_t dot_char = 4;
10865 constexpr uint8_t percent_char = 8;
10866 bool special = type != ada::scheme::NOT_SPECIAL;
10867 bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
10868 checkers::is_windows_drive_letter(input));
10869 bool trivial_path =
10870 (special ? (accumulator == 0)
10871 : ((accumulator & (need_encoding | dot_char | percent_char)) ==
10872 0)) &&
10873 (!may_need_slow_file_handling);
10874 if (accumulator == dot_char && !may_need_slow_file_handling) {
10875 // '4' means that we have at least one dot, but nothing that requires
10876 // percent encoding or decoding. The only part that is not trivial is
10877 // that we may have single dots and double dots path segments.
10878 // If we have such segments, then we either have a path that begins
10879 // with '.' (easy to check), or we have the sequence './'.
10880 // Note: input cannot be empty, it must at least contain one character ('.')
10881 // Note: we know that '\' is not present.
10882 if (input[0] != '.') {
10883 size_t slashdot = input.find("/.");
10884 if (slashdot == std::string_view::npos) { // common case
10885 trivial_path = true;
10886 } else { // uncommon
10887 // only three cases matter: /./, /.. or a final /
10888 trivial_path =
10889 !(slashdot + 2 == input.size() || input[slashdot + 2] == '.' ||
10890 input[slashdot + 2] == '/');
10891 }
10892 }
10893 }
10894 if (trivial_path) {
10895 ada_log("parse_path trivial");
10896 path += '/';
10897 path += input;
10898 return;
10899 }
10900 // We are going to need to look a bit at the path, but let us see if we can
10901 // ignore percent encoding *and* backslashes *and* percent characters.
10902 // Except for the trivial case, this is likely to capture 99% of paths out
10903 // there.
10904 bool fast_path =
10905 (special &&
10906 (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
10907 (type != ada::scheme::type::FILE);
10908 if (fast_path) {
10909 ada_log("parse_prepared_path fast");
10910 // Here we don't need to worry about \ or percent encoding.
10911 // We also do not have a file protocol. We might have dots, however,
10912 // but dots must as appear as '.', and they cannot be encoded because
10913 // the symbol '%' is not present.
10914 size_t previous_location = 0; // We start at 0.
10915 do {
10916 size_t new_location = input.find('/', previous_location);
10917 // std::string_view path_view = input;
10918 // We process the last segment separately:
10919 if (new_location == std::string_view::npos) {
10920 std::string_view path_view = input.substr(previous_location);
10921 if (path_view == "..") { // The path ends with ..
10922 // e.g., if you receive ".." with an empty path, you go to "/".
10923 if (path.empty()) {
10924 path = '/';
10925 return;
10926 }
10927 // Fast case where we have nothing to do:
10928 if (path.back() == '/') {
10929 return;
10930 }
10931 // If you have the path "/joe/myfriend",
10932 // then you delete 'myfriend'.
10933 path.resize(path.rfind('/') + 1);
10934 return;
10935 }
10936 path += '/';
10937 if (path_view != ".") {
10938 path.append(path_view);
10939 }
10940 return;
10941 } else {
10942 // This is a non-final segment.
10943 std::string_view path_view =
10944 input.substr(previous_location, new_location - previous_location);
10945 previous_location = new_location + 1;
10946 if (path_view == "..") {
10947 size_t last_delimiter = path.rfind('/');
10948 if (last_delimiter != std::string::npos) {
10949 path.erase(last_delimiter);
10950 }
10951 } else if (path_view != ".") {
10952 path += '/';
10953 path.append(path_view);
10954 }
10955 }
10956 } while (true);
10957 } else {
10958 ada_log("parse_path slow");
10959 // we have reached the general case
10960 bool needs_percent_encoding = (accumulator & 1);
10961 std::string path_buffer_tmp;
10962 do {
10963 size_t location = (special && (accumulator & 2))
10964 ? input.find_first_of("/\\")
10965 : input.find('/');
10966 std::string_view path_view = input;
10967 if (location != std::string_view::npos) {
10968 path_view.remove_suffix(path_view.size() - location);
10969 input.remove_prefix(location + 1);
10970 }
10971 // path_buffer is either path_view or it might point at a percent encoded
10972 // temporary file.
10973 std::string_view path_buffer =
10974 (needs_percent_encoding &&
10975 ada::unicode::percent_encode<false>(
10976 path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
10977 ? path_buffer_tmp
10978 : path_view;
10979 if (unicode::is_double_dot_path_segment(path_buffer)) {
10980 if ((helpers::shorten_path(path, type) || special) &&
10981 location == std::string_view::npos) {
10982 path += '/';
10983 }
10984 } else if (unicode::is_single_dot_path_segment(path_buffer) &&
10985 (location == std::string_view::npos)) {
10986 path += '/';
10987 }
10988 // Otherwise, if path_buffer is not a single-dot path segment, then:
10989 else if (!unicode::is_single_dot_path_segment(path_buffer)) {
10990 // If url's scheme is "file", url's path is empty, and path_buffer is a
10991 // Windows drive letter, then replace the second code point in
10992 // path_buffer with U+003A (:).
10993 if (type == ada::scheme::type::FILE && path.empty() &&
10994 checkers::is_windows_drive_letter(path_buffer)) {
10995 path += '/';
10996 path += path_buffer[0];
10997 path += ':';
10998 path_buffer.remove_prefix(2);
10999 path.append(path_buffer);
11000 } else {
11001 // Append path_buffer to url's path.
11002 path += '/';
11003 path.append(path_buffer);
11004 }
11005 }
11006 if (location == std::string_view::npos) {
11007 return;
11008 }
11009 } while (true);
11010 }
11011 }
11012
overlaps(std::string_view input1,const std::string & input2)11013 bool overlaps(std::string_view input1, const std::string& input2) noexcept {
11014 ada_log("helpers::overlaps check if string_view '", input1, "' [",
11015 input1.size(), " bytes] is part of string '", input2, "' [",
11016 input2.size(), " bytes]");
11017 return !input1.empty() && !input2.empty() && input1.data() >= input2.data() &&
11018 input1.data() < input2.data() + input2.size();
11019 }
11020
11021 template <class url_type>
strip_trailing_spaces_from_opaque_path(url_type & url)11022 ada_really_inline void strip_trailing_spaces_from_opaque_path(
11023 url_type& url) noexcept {
11024 ada_log("helpers::strip_trailing_spaces_from_opaque_path");
11025 if (!url.has_opaque_path) return;
11026 if (url.has_hash()) return;
11027 if (url.has_search()) return;
11028
11029 auto path = std::string(url.get_pathname());
11030 while (!path.empty() && path.back() == ' ') {
11031 path.resize(path.size() - 1);
11032 }
11033 url.update_base_pathname(path);
11034 }
11035
11036 ada_really_inline size_t
find_authority_delimiter_special(std::string_view view)11037 find_authority_delimiter_special(std::string_view view) noexcept {
11038 auto has_zero_byte = [](uint64_t v) {
11039 return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);
11040 };
11041 auto index_of_first_set_byte = [](uint64_t v) {
11042 return ((((v - 1) & 0x101010101010101) * 0x101010101010101) >> 56) - 1;
11043 };
11044 auto broadcast = [](uint8_t v) -> uint64_t {
11045 return 0x101010101010101ull * v;
11046 };
11047 size_t i = 0;
11048 uint64_t mask1 = broadcast('@');
11049 uint64_t mask2 = broadcast('/');
11050 uint64_t mask3 = broadcast('?');
11051 uint64_t mask4 = broadcast('\\');
11052
11053 for (; i + 7 < view.size(); i += 8) {
11054 uint64_t word{};
11055 memcpy(&word, view.data() + i, sizeof(word));
11056 word = swap_bytes_if_big_endian(word);
11057 uint64_t xor1 = word ^ mask1;
11058 uint64_t xor2 = word ^ mask2;
11059 uint64_t xor3 = word ^ mask3;
11060 uint64_t xor4 = word ^ mask4;
11061 uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |
11062 has_zero_byte(xor3) | has_zero_byte(xor4);
11063 if (is_match) {
11064 return size_t(i + index_of_first_set_byte(is_match));
11065 }
11066 }
11067
11068 if (i < view.size()) {
11069 uint64_t word{};
11070 memcpy(&word, view.data() + i, view.size() - i);
11071 word = swap_bytes_if_big_endian(word);
11072 uint64_t xor1 = word ^ mask1;
11073 uint64_t xor2 = word ^ mask2;
11074 uint64_t xor3 = word ^ mask3;
11075 uint64_t xor4 = word ^ mask4;
11076 uint64_t is_match = has_zero_byte(xor1) | has_zero_byte(xor2) |
11077 has_zero_byte(xor3) | has_zero_byte(xor4);
11078 if (is_match) {
11079 return size_t(i + index_of_first_set_byte(is_match));
11080 }
11081 }
11082
11083 return view.size();
11084 }
11085
11086 ada_really_inline size_t
find_authority_delimiter(std::string_view view)11087 find_authority_delimiter(std::string_view view) noexcept {
11088 auto has_zero_byte = [](uint64_t v) {
11089 return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);
11090 };
11091 auto index_of_first_set_byte = [](uint64_t v) {
11092 return ((((v - 1) & 0x101010101010101) * 0x101010101010101) >> 56) - 1;
11093 };
11094 auto broadcast = [](uint8_t v) -> uint64_t {
11095 return 0x101010101010101ull * v;
11096 };
11097 size_t i = 0;
11098 uint64_t mask1 = broadcast('@');
11099 uint64_t mask2 = broadcast('/');
11100 uint64_t mask3 = broadcast('?');
11101
11102 for (; i + 7 < view.size(); i += 8) {
11103 uint64_t word{};
11104 memcpy(&word, view.data() + i, sizeof(word));
11105 word = swap_bytes_if_big_endian(word);
11106 uint64_t xor1 = word ^ mask1;
11107 uint64_t xor2 = word ^ mask2;
11108 uint64_t xor3 = word ^ mask3;
11109 uint64_t is_match =
11110 has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
11111 if (is_match) {
11112 return size_t(i + index_of_first_set_byte(is_match));
11113 }
11114 }
11115
11116 if (i < view.size()) {
11117 uint64_t word{};
11118 memcpy(&word, view.data() + i, view.size() - i);
11119 word = swap_bytes_if_big_endian(word);
11120 uint64_t xor1 = word ^ mask1;
11121 uint64_t xor2 = word ^ mask2;
11122 uint64_t xor3 = word ^ mask3;
11123 uint64_t is_match =
11124 has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
11125 if (is_match) {
11126 return size_t(i + index_of_first_set_byte(is_match));
11127 }
11128 }
11129
11130 return view.size();
11131 }
11132
11133 } // namespace ada::helpers
11134
11135 namespace ada {
to_string(ada::state state)11136 ada_warn_unused std::string to_string(ada::state state) {
11137 return ada::helpers::get_state(state);
11138 }
11139 } // namespace ada
11140 /* end file src/helpers.cpp */
11141 /* begin file src/url.cpp */
11142
11143 #include <numeric>
11144 #include <algorithm>
11145 #include <string>
11146
11147 namespace ada {
11148
parse_opaque_host(std::string_view input)11149 bool url::parse_opaque_host(std::string_view input) {
11150 ada_log("parse_opaque_host ", input, "[", input.size(), " bytes]");
11151 if (std::any_of(input.begin(), input.end(),
11152 ada::unicode::is_forbidden_host_code_point)) {
11153 return is_valid = false;
11154 }
11155
11156 // Return the result of running UTF-8 percent-encode on input using the C0
11157 // control percent-encode set.
11158 host = ada::unicode::percent_encode(
11159 input, ada::character_sets::C0_CONTROL_PERCENT_ENCODE);
11160 return true;
11161 }
11162
parse_ipv4(std::string_view input)11163 bool url::parse_ipv4(std::string_view input) {
11164 ada_log("parse_ipv4 ", input, "[", input.size(), " bytes]");
11165 if (input.back() == '.') {
11166 input.remove_suffix(1);
11167 }
11168 size_t digit_count{0};
11169 int pure_decimal_count = 0; // entries that are decimal
11170 std::string_view original_input =
11171 input; // we might use this if pure_decimal_count == 4.
11172 uint64_t ipv4{0};
11173 // we could unroll for better performance?
11174 for (; (digit_count < 4) && !(input.empty()); digit_count++) {
11175 uint32_t
11176 segment_result{}; // If any number exceeds 32 bits, we have an error.
11177 bool is_hex = checkers::has_hex_prefix(input);
11178 if (is_hex && ((input.length() == 2) ||
11179 ((input.length() > 2) && (input[2] == '.')))) {
11180 // special case
11181 segment_result = 0;
11182 input.remove_prefix(2);
11183 } else {
11184 std::from_chars_result r;
11185 if (is_hex) {
11186 r = std::from_chars(input.data() + 2, input.data() + input.size(),
11187 segment_result, 16);
11188 } else if ((input.length() >= 2) && input[0] == '0' &&
11189 checkers::is_digit(input[1])) {
11190 r = std::from_chars(input.data() + 1, input.data() + input.size(),
11191 segment_result, 8);
11192 } else {
11193 pure_decimal_count++;
11194 r = std::from_chars(input.data(), input.data() + input.size(),
11195 segment_result, 10);
11196 }
11197 if (r.ec != std::errc()) {
11198 return is_valid = false;
11199 }
11200 input.remove_prefix(r.ptr - input.data());
11201 }
11202 if (input.empty()) {
11203 // We have the last value.
11204 // At this stage, ipv4 contains digit_count*8 bits.
11205 // So we have 32-digit_count*8 bits left.
11206 if (segment_result > (uint64_t(1) << (32 - digit_count * 8))) {
11207 return is_valid = false;
11208 }
11209 ipv4 <<= (32 - digit_count * 8);
11210 ipv4 |= segment_result;
11211 goto final;
11212 } else {
11213 // There is more, so that the value must no be larger than 255
11214 // and we must have a '.'.
11215 if ((segment_result > 255) || (input[0] != '.')) {
11216 return is_valid = false;
11217 }
11218 ipv4 <<= 8;
11219 ipv4 |= segment_result;
11220 input.remove_prefix(1); // remove '.'
11221 }
11222 }
11223 if ((digit_count != 4) || (!input.empty())) {
11224 return is_valid = false;
11225 }
11226 final:
11227 // We could also check r.ptr to see where the parsing ended.
11228 if (pure_decimal_count == 4) {
11229 host = original_input; // The original input was already all decimal and we
11230 // validated it.
11231 } else {
11232 host = ada::serializers::ipv4(ipv4); // We have to reserialize the address.
11233 }
11234 return true;
11235 }
11236
parse_ipv6(std::string_view input)11237 bool url::parse_ipv6(std::string_view input) {
11238 ada_log("parse_ipv6 ", input, "[", input.size(), " bytes]");
11239
11240 if (input.empty()) {
11241 return is_valid = false;
11242 }
11243 // Let address be a new IPv6 address whose IPv6 pieces are all 0.
11244 std::array<uint16_t, 8> address{};
11245
11246 // Let pieceIndex be 0.
11247 int piece_index = 0;
11248
11249 // Let compress be null.
11250 std::optional<int> compress{};
11251
11252 // Let pointer be a pointer for input.
11253 std::string_view::iterator pointer = input.begin();
11254
11255 // If c is U+003A (:), then:
11256 if (input[0] == ':') {
11257 // If remaining does not start with U+003A (:), validation error, return
11258 // failure.
11259 if (input.size() == 1 || input[1] != ':') {
11260 ada_log("parse_ipv6 starts with : but the rest does not start with :");
11261 return is_valid = false;
11262 }
11263
11264 // Increase pointer by 2.
11265 pointer += 2;
11266
11267 // Increase pieceIndex by 1 and then set compress to pieceIndex.
11268 compress = ++piece_index;
11269 }
11270
11271 // While c is not the EOF code point:
11272 while (pointer != input.end()) {
11273 // If pieceIndex is 8, validation error, return failure.
11274 if (piece_index == 8) {
11275 ada_log("parse_ipv6 piece_index == 8");
11276 return is_valid = false;
11277 }
11278
11279 // If c is U+003A (:), then:
11280 if (*pointer == ':') {
11281 // If compress is non-null, validation error, return failure.
11282 if (compress.has_value()) {
11283 ada_log("parse_ipv6 compress is non-null");
11284 return is_valid = false;
11285 }
11286
11287 // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and
11288 // then continue.
11289 pointer++;
11290 compress = ++piece_index;
11291 continue;
11292 }
11293
11294 // Let value and length be 0.
11295 uint16_t value = 0, length = 0;
11296
11297 // While length is less than 4 and c is an ASCII hex digit,
11298 // set value to value times 0x10 + c interpreted as hexadecimal number, and
11299 // increase pointer and length by 1.
11300 while (length < 4 && pointer != input.end() &&
11301 unicode::is_ascii_hex_digit(*pointer)) {
11302 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
11303 value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));
11304 pointer++;
11305 length++;
11306 }
11307
11308 // If c is U+002E (.), then:
11309 if (pointer != input.end() && *pointer == '.') {
11310 // If length is 0, validation error, return failure.
11311 if (length == 0) {
11312 ada_log("parse_ipv6 length is 0");
11313 return is_valid = false;
11314 }
11315
11316 // Decrease pointer by length.
11317 pointer -= length;
11318
11319 // If pieceIndex is greater than 6, validation error, return failure.
11320 if (piece_index > 6) {
11321 ada_log("parse_ipv6 piece_index > 6");
11322 return is_valid = false;
11323 }
11324
11325 // Let numbersSeen be 0.
11326 int numbers_seen = 0;
11327
11328 // While c is not the EOF code point:
11329 while (pointer != input.end()) {
11330 // Let ipv4Piece be null.
11331 std::optional<uint16_t> ipv4_piece{};
11332
11333 // If numbersSeen is greater than 0, then:
11334 if (numbers_seen > 0) {
11335 // If c is a U+002E (.) and numbersSeen is less than 4, then increase
11336 // pointer by 1.
11337 if (*pointer == '.' && numbers_seen < 4) {
11338 pointer++;
11339 }
11340 // Otherwise, validation error, return failure.
11341 else {
11342 ada_log("parse_ipv6 Otherwise, validation error, return failure");
11343 return is_valid = false;
11344 }
11345 }
11346
11347 // If c is not an ASCII digit, validation error, return failure.
11348 if (pointer == input.end() || !checkers::is_digit(*pointer)) {
11349 ada_log(
11350 "parse_ipv6 If c is not an ASCII digit, validation error, return "
11351 "failure");
11352 return is_valid = false;
11353 }
11354
11355 // While c is an ASCII digit:
11356 while (pointer != input.end() && checkers::is_digit(*pointer)) {
11357 // Let number be c interpreted as decimal number.
11358 int number = *pointer - '0';
11359
11360 // If ipv4Piece is null, then set ipv4Piece to number.
11361 if (!ipv4_piece.has_value()) {
11362 ipv4_piece = number;
11363 }
11364 // Otherwise, if ipv4Piece is 0, validation error, return failure.
11365 else if (ipv4_piece == 0) {
11366 ada_log("parse_ipv6 if ipv4Piece is 0, validation error");
11367 return is_valid = false;
11368 }
11369 // Otherwise, set ipv4Piece to ipv4Piece times 10 + number.
11370 else {
11371 ipv4_piece = *ipv4_piece * 10 + number;
11372 }
11373
11374 // If ipv4Piece is greater than 255, validation error, return failure.
11375 if (ipv4_piece > 255) {
11376 ada_log("parse_ipv6 ipv4_piece > 255");
11377 return is_valid = false;
11378 }
11379
11380 // Increase pointer by 1.
11381 pointer++;
11382 }
11383
11384 // Set address[pieceIndex] to address[pieceIndex] times 0x100 +
11385 // ipv4Piece.
11386 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
11387 address[piece_index] =
11388 uint16_t(address[piece_index] * 0x100 + *ipv4_piece);
11389
11390 // Increase numbersSeen by 1.
11391 numbers_seen++;
11392
11393 // If numbersSeen is 2 or 4, then increase pieceIndex by 1.
11394 if (numbers_seen == 2 || numbers_seen == 4) {
11395 piece_index++;
11396 }
11397 }
11398
11399 // If numbersSeen is not 4, validation error, return failure.
11400 if (numbers_seen != 4) {
11401 return is_valid = false;
11402 }
11403
11404 // Break.
11405 break;
11406 }
11407 // Otherwise, if c is U+003A (:):
11408 else if ((pointer != input.end()) && (*pointer == ':')) {
11409 // Increase pointer by 1.
11410 pointer++;
11411
11412 // If c is the EOF code point, validation error, return failure.
11413 if (pointer == input.end()) {
11414 ada_log(
11415 "parse_ipv6 If c is the EOF code point, validation error, return "
11416 "failure");
11417 return is_valid = false;
11418 }
11419 }
11420 // Otherwise, if c is not the EOF code point, validation error, return
11421 // failure.
11422 else if (pointer != input.end()) {
11423 ada_log(
11424 "parse_ipv6 Otherwise, if c is not the EOF code point, validation "
11425 "error, return failure");
11426 return is_valid = false;
11427 }
11428
11429 // Set address[pieceIndex] to value.
11430 address[piece_index] = value;
11431
11432 // Increase pieceIndex by 1.
11433 piece_index++;
11434 }
11435
11436 // If compress is non-null, then:
11437 if (compress.has_value()) {
11438 // Let swaps be pieceIndex - compress.
11439 int swaps = piece_index - *compress;
11440
11441 // Set pieceIndex to 7.
11442 piece_index = 7;
11443
11444 // While pieceIndex is not 0 and swaps is greater than 0,
11445 // swap address[pieceIndex] with address[compress + swaps - 1], and then
11446 // decrease both pieceIndex and swaps by 1.
11447 while (piece_index != 0 && swaps > 0) {
11448 std::swap(address[piece_index], address[*compress + swaps - 1]);
11449 piece_index--;
11450 swaps--;
11451 }
11452 }
11453 // Otherwise, if compress is null and pieceIndex is not 8, validation error,
11454 // return failure.
11455 else if (piece_index != 8) {
11456 ada_log(
11457 "parse_ipv6 if compress is null and pieceIndex is not 8, validation "
11458 "error, return failure");
11459 return is_valid = false;
11460 }
11461 host = ada::serializers::ipv6(address);
11462 ada_log("parse_ipv6 ", *host);
11463 return true;
11464 }
11465
11466 template <bool has_state_override>
parse_scheme(const std::string_view input)11467 ada_really_inline bool url::parse_scheme(const std::string_view input) {
11468 auto parsed_type = ada::scheme::get_scheme_type(input);
11469 bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
11470 /**
11471 * In the common case, we will immediately recognize a special scheme (e.g.,
11472 *http, https), in which case, we can go really fast.
11473 **/
11474 if (is_input_special) { // fast path!!!
11475 if (has_state_override) {
11476 // If url's scheme is not a special scheme and buffer is a special scheme,
11477 // then return.
11478 if (is_special() != is_input_special) {
11479 return true;
11480 }
11481
11482 // If url includes credentials or has a non-null port, and buffer is
11483 // "file", then return.
11484 if ((has_credentials() || port.has_value()) &&
11485 parsed_type == ada::scheme::type::FILE) {
11486 return true;
11487 }
11488
11489 // If url's scheme is "file" and its host is an empty host, then return.
11490 // An empty host is the empty string.
11491 if (type == ada::scheme::type::FILE && host.has_value() &&
11492 host.value().empty()) {
11493 return true;
11494 }
11495 }
11496
11497 type = parsed_type;
11498
11499 if (has_state_override) {
11500 // This is uncommon.
11501 uint16_t urls_scheme_port = get_special_port();
11502
11503 if (urls_scheme_port) {
11504 // If url's port is url's scheme's default port, then set url's port to
11505 // null.
11506 if (port.has_value() && *port == urls_scheme_port) {
11507 port = std::nullopt;
11508 }
11509 }
11510 }
11511 } else { // slow path
11512 std::string _buffer = std::string(input);
11513 // Next function is only valid if the input is ASCII and returns false
11514 // otherwise, but it seems that we always have ascii content so we do not
11515 // need to check the return value.
11516 // bool is_ascii =
11517 unicode::to_lower_ascii(_buffer.data(), _buffer.size());
11518
11519 if (has_state_override) {
11520 // If url's scheme is a special scheme and buffer is not a special scheme,
11521 // then return. If url's scheme is not a special scheme and buffer is a
11522 // special scheme, then return.
11523 if (is_special() != ada::scheme::is_special(_buffer)) {
11524 return true;
11525 }
11526
11527 // If url includes credentials or has a non-null port, and buffer is
11528 // "file", then return.
11529 if ((has_credentials() || port.has_value()) && _buffer == "file") {
11530 return true;
11531 }
11532
11533 // If url's scheme is "file" and its host is an empty host, then return.
11534 // An empty host is the empty string.
11535 if (type == ada::scheme::type::FILE && host.has_value() &&
11536 host.value().empty()) {
11537 return true;
11538 }
11539 }
11540
11541 set_scheme(std::move(_buffer));
11542
11543 if (has_state_override) {
11544 // This is uncommon.
11545 uint16_t urls_scheme_port = get_special_port();
11546
11547 if (urls_scheme_port) {
11548 // If url's port is url's scheme's default port, then set url's port to
11549 // null.
11550 if (port.has_value() && *port == urls_scheme_port) {
11551 port = std::nullopt;
11552 }
11553 }
11554 }
11555 }
11556
11557 return true;
11558 }
11559
parse_host(std::string_view input)11560 ada_really_inline bool url::parse_host(std::string_view input) {
11561 ada_log("parse_host ", input, "[", input.size(), " bytes]");
11562 if (input.empty()) {
11563 return is_valid = false;
11564 } // technically unnecessary.
11565 // If input starts with U+005B ([), then:
11566 if (input[0] == '[') {
11567 // If input does not end with U+005D (]), validation error, return failure.
11568 if (input.back() != ']') {
11569 return is_valid = false;
11570 }
11571 ada_log("parse_host ipv6");
11572
11573 // Return the result of IPv6 parsing input with its leading U+005B ([) and
11574 // trailing U+005D (]) removed.
11575 input.remove_prefix(1);
11576 input.remove_suffix(1);
11577 return parse_ipv6(input);
11578 }
11579
11580 // If isNotSpecial is true, then return the result of opaque-host parsing
11581 // input.
11582 if (!is_special()) {
11583 return parse_opaque_host(input);
11584 }
11585 // Let domain be the result of running UTF-8 decode without BOM on the
11586 // percent-decoding of input. Let asciiDomain be the result of running domain
11587 // to ASCII with domain and false. The most common case is an ASCII input, in
11588 // which case we do not need to call the expensive 'to_ascii' if a few
11589 // conditions are met: no '%' and no 'xn-' subsequence.
11590 std::string buffer = std::string(input);
11591 // This next function checks that the result is ascii, but we are going to
11592 // to check anyhow with is_forbidden.
11593 // bool is_ascii =
11594 unicode::to_lower_ascii(buffer.data(), buffer.size());
11595 bool is_forbidden = unicode::contains_forbidden_domain_code_point(
11596 buffer.data(), buffer.size());
11597 if (is_forbidden == 0 && buffer.find("xn-") == std::string_view::npos) {
11598 // fast path
11599 host = std::move(buffer);
11600 if (checkers::is_ipv4(host.value())) {
11601 ada_log("parse_host fast path ipv4");
11602 return parse_ipv4(host.value());
11603 }
11604 ada_log("parse_host fast path ", *host);
11605 return true;
11606 }
11607 ada_log("parse_host calling to_ascii");
11608 is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
11609 if (!is_valid) {
11610 ada_log("parse_host to_ascii returns false");
11611 return is_valid = false;
11612 }
11613
11614 if (std::any_of(host.value().begin(), host.value().end(),
11615 ada::unicode::is_forbidden_domain_code_point)) {
11616 host = std::nullopt;
11617 return is_valid = false;
11618 }
11619
11620 // If asciiDomain ends in a number, then return the result of IPv4 parsing
11621 // asciiDomain.
11622 if (checkers::is_ipv4(host.value())) {
11623 ada_log("parse_host got ipv4", *host);
11624 return parse_ipv4(host.value());
11625 }
11626
11627 return true;
11628 }
11629
parse_path(std::string_view input)11630 ada_really_inline void url::parse_path(std::string_view input) {
11631 ada_log("parse_path ", input);
11632 std::string tmp_buffer;
11633 std::string_view internal_input;
11634 if (unicode::has_tabs_or_newline(input)) {
11635 tmp_buffer = input;
11636 // Optimization opportunity: Instead of copying and then pruning, we could
11637 // just directly build the string from user_input.
11638 helpers::remove_ascii_tab_or_newline(tmp_buffer);
11639 internal_input = tmp_buffer;
11640 } else {
11641 internal_input = input;
11642 }
11643
11644 // If url is special, then:
11645 if (is_special()) {
11646 if (internal_input.empty()) {
11647 path = "/";
11648 } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
11649 helpers::parse_prepared_path(internal_input.substr(1), type, path);
11650 return;
11651 } else {
11652 helpers::parse_prepared_path(internal_input, type, path);
11653 return;
11654 }
11655 } else if (!internal_input.empty()) {
11656 if (internal_input[0] == '/') {
11657 helpers::parse_prepared_path(internal_input.substr(1), type, path);
11658 return;
11659 } else {
11660 helpers::parse_prepared_path(internal_input, type, path);
11661 return;
11662 }
11663 } else {
11664 if (!host.has_value()) {
11665 path = "/";
11666 }
11667 }
11668 return;
11669 }
11670
to_string() const11671 std::string url::to_string() const {
11672 if (!is_valid) {
11673 return "null";
11674 }
11675 std::string answer;
11676 auto back = std::back_insert_iterator(answer);
11677 answer.append("{\n");
11678 answer.append("\t\"protocol\":\"");
11679 helpers::encode_json(get_protocol(), back);
11680 answer.append("\",\n");
11681 if (has_credentials()) {
11682 answer.append("\t\"username\":\"");
11683 helpers::encode_json(username, back);
11684 answer.append("\",\n");
11685 answer.append("\t\"password\":\"");
11686 helpers::encode_json(password, back);
11687 answer.append("\",\n");
11688 }
11689 if (host.has_value()) {
11690 answer.append("\t\"host\":\"");
11691 helpers::encode_json(host.value(), back);
11692 answer.append("\",\n");
11693 }
11694 if (port.has_value()) {
11695 answer.append("\t\"port\":\"");
11696 answer.append(std::to_string(port.value()));
11697 answer.append("\",\n");
11698 }
11699 answer.append("\t\"path\":\"");
11700 helpers::encode_json(path, back);
11701 answer.append("\",\n");
11702 answer.append("\t\"opaque path\":");
11703 answer.append((has_opaque_path ? "true" : "false"));
11704 if (has_search()) {
11705 answer.append(",\n");
11706 answer.append("\t\"query\":\"");
11707 helpers::encode_json(query.value(), back);
11708 answer.append("\"");
11709 }
11710 if (hash.has_value()) {
11711 answer.append(",\n");
11712 answer.append("\t\"hash\":\"");
11713 helpers::encode_json(hash.value(), back);
11714 answer.append("\"");
11715 }
11716 answer.append("\n}");
11717 return answer;
11718 }
11719
has_valid_domain() const11720 [[nodiscard]] bool url::has_valid_domain() const noexcept {
11721 if (!host.has_value()) {
11722 return false;
11723 }
11724 return checkers::verify_dns_length(host.value());
11725 }
11726
11727 } // namespace ada
11728 /* end file src/url.cpp */
11729 /* begin file src/url-getters.cpp */
11730 /**
11731 * @file url-getters.cpp
11732 * Includes all the getters of `ada::url`
11733 */
11734
11735 #include <algorithm>
11736 #include <string>
11737
11738 namespace ada {
get_origin() const11739 [[nodiscard]] std::string url::get_origin() const noexcept {
11740 if (is_special()) {
11741 // Return a new opaque origin.
11742 if (type == scheme::FILE) {
11743 return "null";
11744 }
11745 return ada::helpers::concat(get_protocol(), "//", get_host());
11746 }
11747
11748 if (non_special_scheme == "blob") {
11749 if (!path.empty()) {
11750 auto result = ada::parse<ada::url>(path);
11751 if (result &&
11752 (result->type == scheme::HTTP || result->type == scheme::HTTPS)) {
11753 // If pathURL's scheme is not "http" and not "https", then return a
11754 // new opaque origin.
11755 return ada::helpers::concat(result->get_protocol(), "//",
11756 result->get_host());
11757 }
11758 }
11759 }
11760
11761 // Return a new opaque origin.
11762 return "null";
11763 }
11764
get_protocol() const11765 [[nodiscard]] std::string url::get_protocol() const noexcept {
11766 if (is_special()) {
11767 return helpers::concat(ada::scheme::details::is_special_list[type], ":");
11768 }
11769 // We only move the 'scheme' if it is non-special.
11770 return helpers::concat(non_special_scheme, ":");
11771 }
11772
get_host() const11773 [[nodiscard]] std::string url::get_host() const noexcept {
11774 // If url's host is null, then return the empty string.
11775 // If url's port is null, return url's host, serialized.
11776 // Return url's host, serialized, followed by U+003A (:) and url's port,
11777 // serialized.
11778 if (!host.has_value()) {
11779 return "";
11780 }
11781 if (port.has_value()) {
11782 return host.value() + ":" + get_port();
11783 }
11784 return host.value();
11785 }
11786
get_hostname() const11787 [[nodiscard]] std::string url::get_hostname() const noexcept {
11788 return host.value_or("");
11789 }
11790
get_pathname() const11791 [[nodiscard]] const std::string_view url::get_pathname() const noexcept {
11792 return path;
11793 }
11794
get_search() const11795 [[nodiscard]] std::string url::get_search() const noexcept {
11796 // If this's URL's query is either null or the empty string, then return the
11797 // empty string. Return U+003F (?), followed by this's URL's query.
11798 return (!query.has_value() || (query.value().empty())) ? ""
11799 : "?" + query.value();
11800 }
11801
get_username() const11802 [[nodiscard]] const std::string& url::get_username() const noexcept {
11803 return username;
11804 }
11805
get_password() const11806 [[nodiscard]] const std::string& url::get_password() const noexcept {
11807 return password;
11808 }
11809
get_port() const11810 [[nodiscard]] std::string url::get_port() const noexcept {
11811 return port.has_value() ? std::to_string(port.value()) : "";
11812 }
11813
get_hash() const11814 [[nodiscard]] std::string url::get_hash() const noexcept {
11815 // If this's URL's fragment is either null or the empty string, then return
11816 // the empty string. Return U+0023 (#), followed by this's URL's fragment.
11817 return (!hash.has_value() || (hash.value().empty())) ? ""
11818 : "#" + hash.value();
11819 }
11820
11821 } // namespace ada
11822 /* end file src/url-getters.cpp */
11823 /* begin file src/url-setters.cpp */
11824 /**
11825 * @file url-setters.cpp
11826 * Includes all the setters of `ada::url`
11827 */
11828
11829 #include <optional>
11830 #include <string>
11831
11832 namespace ada {
11833
11834 template <bool override_hostname>
set_host_or_hostname(const std::string_view input)11835 bool url::set_host_or_hostname(const std::string_view input) {
11836 if (has_opaque_path) {
11837 return false;
11838 }
11839
11840 std::optional<std::string> previous_host = host;
11841 std::optional<uint16_t> previous_port = port;
11842
11843 size_t host_end_pos = input.find('#');
11844 std::string _host(input.data(), host_end_pos != std::string_view::npos
11845 ? host_end_pos
11846 : input.size());
11847 helpers::remove_ascii_tab_or_newline(_host);
11848 std::string_view new_host(_host);
11849
11850 // If url's scheme is "file", then set state to file host state, instead of
11851 // host state.
11852 if (type != ada::scheme::type::FILE) {
11853 std::string_view host_view(_host.data(), _host.length());
11854 auto [location, found_colon] =
11855 helpers::get_host_delimiter_location(is_special(), host_view);
11856
11857 // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
11858 // Note: the 'found_colon' value is true if and only if a colon was
11859 // encountered while not inside brackets.
11860 if (found_colon) {
11861 if (override_hostname) {
11862 return false;
11863 }
11864 std::string_view buffer = new_host.substr(location + 1);
11865 if (!buffer.empty()) {
11866 set_port(buffer);
11867 }
11868 }
11869 // If url is special and host_view is the empty string, validation error,
11870 // return failure. Otherwise, if state override is given, host_view is the
11871 // empty string, and either url includes credentials or url's port is
11872 // non-null, return.
11873 else if (host_view.empty() &&
11874 (is_special() || has_credentials() || port.has_value())) {
11875 return false;
11876 }
11877
11878 // Let host be the result of host parsing host_view with url is not special.
11879 if (host_view.empty()) {
11880 host = "";
11881 return true;
11882 }
11883
11884 bool succeeded = parse_host(host_view);
11885 if (!succeeded) {
11886 host = previous_host;
11887 update_base_port(previous_port);
11888 }
11889 return succeeded;
11890 }
11891
11892 size_t location = new_host.find_first_of("/\\?");
11893 if (location != std::string_view::npos) {
11894 new_host.remove_suffix(new_host.length() - location);
11895 }
11896
11897 if (new_host.empty()) {
11898 // Set url's host to the empty string.
11899 host = "";
11900 } else {
11901 // Let host be the result of host parsing buffer with url is not special.
11902 if (!parse_host(new_host)) {
11903 host = previous_host;
11904 update_base_port(previous_port);
11905 return false;
11906 }
11907
11908 // If host is "localhost", then set host to the empty string.
11909 if (host.has_value() && host.value() == "localhost") {
11910 host = "";
11911 }
11912 }
11913 return true;
11914 }
11915
set_host(const std::string_view input)11916 bool url::set_host(const std::string_view input) {
11917 return set_host_or_hostname<false>(input);
11918 }
11919
set_hostname(const std::string_view input)11920 bool url::set_hostname(const std::string_view input) {
11921 return set_host_or_hostname<true>(input);
11922 }
11923
set_username(const std::string_view input)11924 bool url::set_username(const std::string_view input) {
11925 if (cannot_have_credentials_or_port()) {
11926 return false;
11927 }
11928 username = ada::unicode::percent_encode(
11929 input, character_sets::USERINFO_PERCENT_ENCODE);
11930 return true;
11931 }
11932
set_password(const std::string_view input)11933 bool url::set_password(const std::string_view input) {
11934 if (cannot_have_credentials_or_port()) {
11935 return false;
11936 }
11937 password = ada::unicode::percent_encode(
11938 input, character_sets::USERINFO_PERCENT_ENCODE);
11939 return true;
11940 }
11941
set_port(const std::string_view input)11942 bool url::set_port(const std::string_view input) {
11943 if (cannot_have_credentials_or_port()) {
11944 return false;
11945 }
11946 std::string trimmed(input);
11947 helpers::remove_ascii_tab_or_newline(trimmed);
11948 if (trimmed.empty()) {
11949 port = std::nullopt;
11950 return true;
11951 }
11952 // Input should not start with control characters.
11953 if (ada::unicode::is_c0_control_or_space(trimmed.front())) {
11954 return false;
11955 }
11956 // Input should contain at least one ascii digit.
11957 if (input.find_first_of("0123456789") == std::string_view::npos) {
11958 return false;
11959 }
11960
11961 // Revert changes if parse_port fails.
11962 std::optional<uint16_t> previous_port = port;
11963 parse_port(trimmed);
11964 if (is_valid) {
11965 return true;
11966 }
11967 port = previous_port;
11968 is_valid = true;
11969 return false;
11970 }
11971
set_hash(const std::string_view input)11972 void url::set_hash(const std::string_view input) {
11973 if (input.empty()) {
11974 hash = std::nullopt;
11975 helpers::strip_trailing_spaces_from_opaque_path(*this);
11976 return;
11977 }
11978
11979 std::string new_value;
11980 new_value = input[0] == '#' ? input.substr(1) : input;
11981 helpers::remove_ascii_tab_or_newline(new_value);
11982 hash = unicode::percent_encode(new_value,
11983 ada::character_sets::FRAGMENT_PERCENT_ENCODE);
11984 return;
11985 }
11986
set_search(const std::string_view input)11987 void url::set_search(const std::string_view input) {
11988 if (input.empty()) {
11989 query = std::nullopt;
11990 helpers::strip_trailing_spaces_from_opaque_path(*this);
11991 return;
11992 }
11993
11994 std::string new_value;
11995 new_value = input[0] == '?' ? input.substr(1) : input;
11996 helpers::remove_ascii_tab_or_newline(new_value);
11997
11998 auto query_percent_encode_set =
11999 is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
12000 : ada::character_sets::QUERY_PERCENT_ENCODE;
12001
12002 query = ada::unicode::percent_encode(std::string_view(new_value),
12003 query_percent_encode_set);
12004 }
12005
set_pathname(const std::string_view input)12006 bool url::set_pathname(const std::string_view input) {
12007 if (has_opaque_path) {
12008 return false;
12009 }
12010 path = "";
12011 parse_path(input);
12012 return true;
12013 }
12014
set_protocol(const std::string_view input)12015 bool url::set_protocol(const std::string_view input) {
12016 std::string view(input);
12017 helpers::remove_ascii_tab_or_newline(view);
12018 if (view.empty()) {
12019 return true;
12020 }
12021
12022 // Schemes should start with alpha values.
12023 if (!checkers::is_alpha(view[0])) {
12024 return false;
12025 }
12026
12027 view.append(":");
12028
12029 std::string::iterator pointer =
12030 std::find_if_not(view.begin(), view.end(), unicode::is_alnum_plus);
12031
12032 if (pointer != view.end() && *pointer == ':') {
12033 return parse_scheme<true>(
12034 std::string_view(view.data(), pointer - view.begin()));
12035 }
12036 return false;
12037 }
12038
set_href(const std::string_view input)12039 bool url::set_href(const std::string_view input) {
12040 ada::result<ada::url> out = ada::parse<ada::url>(input);
12041
12042 if (out) {
12043 username = out->username;
12044 password = out->password;
12045 host = out->host;
12046 port = out->port;
12047 path = out->path;
12048 query = out->query;
12049 hash = out->hash;
12050 type = out->type;
12051 non_special_scheme = out->non_special_scheme;
12052 has_opaque_path = out->has_opaque_path;
12053 }
12054
12055 return out.has_value();
12056 }
12057
12058 } // namespace ada
12059 /* end file src/url-setters.cpp */
12060 /* begin file src/parser.cpp */
12061
12062 #include <numeric>
12063 #include <limits>
12064
12065 namespace ada::parser {
12066
12067 template <class result_type>
parse_url(std::string_view user_input,const result_type * base_url)12068 result_type parse_url(std::string_view user_input,
12069 const result_type* base_url) {
12070 // We can specialize the implementation per type.
12071 // Important: result_type_is_ada_url is evaluated at *compile time*. This
12072 // means that doing if constexpr(result_type_is_ada_url) { something } else {
12073 // something else } is free (at runtime). This means that ada::url_aggregator
12074 // and ada::url **do not have to support the exact same API**.
12075 constexpr bool result_type_is_ada_url =
12076 std::is_same<ada::url, result_type>::value;
12077 constexpr bool result_type_is_ada_url_aggregator =
12078 std::is_same<ada::url_aggregator, result_type>::value;
12079 static_assert(result_type_is_ada_url ||
12080 result_type_is_ada_url_aggregator); // We don't support
12081 // anything else for now.
12082
12083 ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(),
12084 " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),
12085 ")");
12086
12087 ada::state state = ada::state::SCHEME_START;
12088 result_type url{};
12089
12090 // We refuse to parse URL strings that exceed 4GB. Such strings are almost
12091 // surely the result of a bug or are otherwise a security concern.
12092 if (user_input.size() > std::numeric_limits<uint32_t>::max()) {
12093 url.is_valid = false;
12094 }
12095 // Going forward, user_input.size() is in [0,
12096 // std::numeric_limits<uint32_t>::max). If we are provided with an invalid
12097 // base, or the optional_url was invalid, we must return.
12098 if (base_url != nullptr) {
12099 url.is_valid &= base_url->is_valid;
12100 }
12101 if (!url.is_valid) {
12102 return url;
12103 }
12104 if constexpr (result_type_is_ada_url_aggregator) {
12105 // Most of the time, we just need user_input.size().
12106 // In some instances, we may need a bit more.
12107 ///////////////////////////
12108 // This is *very* important. This line should *not* be removed
12109 // hastily. There are principled reasons why reserve is important
12110 // for performance. If you have a benchmark with small inputs,
12111 // it may not matter, but in other instances, it could.
12112 ////
12113 // This rounds up to the next power of two.
12114 // We know that user_input.size() is in [0,
12115 // std::numeric_limits<uint32_t>::max).
12116 uint32_t reserve_capacity =
12117 (0xFFFFFFFF >>
12118 helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +
12119 1;
12120 url.reserve(reserve_capacity);
12121 //
12122 //
12123 //
12124 }
12125 std::string tmp_buffer;
12126 std::string_view internal_input;
12127 if (unicode::has_tabs_or_newline(user_input)) {
12128 tmp_buffer = user_input;
12129 // Optimization opportunity: Instead of copying and then pruning, we could
12130 // just directly build the string from user_input.
12131 helpers::remove_ascii_tab_or_newline(tmp_buffer);
12132 internal_input = tmp_buffer;
12133 } else {
12134 internal_input = user_input;
12135 }
12136
12137 // Leading and trailing control characters are uncommon and easy to deal with
12138 // (no performance concern).
12139 std::string_view url_data = internal_input;
12140 helpers::trim_c0_whitespace(url_data);
12141
12142 // Optimization opportunity. Most websites do not have fragment.
12143 std::optional<std::string_view> fragment = helpers::prune_hash(url_data);
12144 // We add it last so that an implementation like ada::url_aggregator
12145 // can append it last to its internal buffer, thus improving performance.
12146
12147 // Here url_data no longer has its fragment.
12148 // We are going to access the data from url_data (it is immutable).
12149 // At any given time, we are pointing at byte 'input_position' in url_data.
12150 // The input_position variable should range from 0 to input_size.
12151 // It is illegal to access url_data at input_size.
12152 size_t input_position = 0;
12153 const size_t input_size = url_data.size();
12154 // Keep running the following state machine by switching on state.
12155 // If after a run pointer points to the EOF code point, go to the next step.
12156 // Otherwise, increase pointer by 1 and continue with the state machine.
12157 // We never decrement input_position.
12158 while (input_position <= input_size) {
12159 ada_log("In parsing at ", input_position, " out of ", input_size,
12160 " in state ", ada::to_string(state));
12161 switch (state) {
12162 case ada::state::SCHEME_START: {
12163 ada_log("SCHEME_START ", helpers::substring(url_data, input_position));
12164 // If c is an ASCII alpha, append c, lowercased, to buffer, and set
12165 // state to scheme state.
12166 if ((input_position != input_size) &&
12167 checkers::is_alpha(url_data[input_position])) {
12168 state = ada::state::SCHEME;
12169 input_position++;
12170 } else {
12171 // Otherwise, if state override is not given, set state to no scheme
12172 // state and decrease pointer by 1.
12173 state = ada::state::NO_SCHEME;
12174 }
12175 break;
12176 }
12177 case ada::state::SCHEME: {
12178 ada_log("SCHEME ", helpers::substring(url_data, input_position));
12179 // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),
12180 // append c, lowercased, to buffer.
12181 while ((input_position != input_size) &&
12182 (ada::unicode::is_alnum_plus(url_data[input_position]))) {
12183 input_position++;
12184 }
12185 // Otherwise, if c is U+003A (:), then:
12186 if ((input_position != input_size) &&
12187 (url_data[input_position] == ':')) {
12188 ada_log("SCHEME the scheme should be ",
12189 url_data.substr(0, input_position));
12190 if constexpr (result_type_is_ada_url) {
12191 if (!url.parse_scheme(url_data.substr(0, input_position))) {
12192 return url;
12193 }
12194 } else {
12195 // we pass the colon along instead of painfully adding it back.
12196 if (!url.parse_scheme_with_colon(
12197 url_data.substr(0, input_position + 1))) {
12198 return url;
12199 }
12200 }
12201 ada_log("SCHEME the scheme is ", url.get_protocol());
12202
12203 // If url's scheme is "file", then:
12204 if (url.type == ada::scheme::type::FILE) {
12205 // Set state to file state.
12206 state = ada::state::FILE;
12207 }
12208 // Otherwise, if url is special, base is non-null, and base's scheme
12209 // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url
12210 // != nullptr is false.
12211 else if (url.is_special() && base_url != nullptr &&
12212 base_url->type == url.type) {
12213 // Set state to special relative or authority state.
12214 state = ada::state::SPECIAL_RELATIVE_OR_AUTHORITY;
12215 }
12216 // Otherwise, if url is special, set state to special authority
12217 // slashes state.
12218 else if (url.is_special()) {
12219 state = ada::state::SPECIAL_AUTHORITY_SLASHES;
12220 }
12221 // Otherwise, if remaining starts with an U+002F (/), set state to
12222 // path or authority state and increase pointer by 1.
12223 else if (input_position + 1 < input_size &&
12224 url_data[input_position + 1] == '/') {
12225 state = ada::state::PATH_OR_AUTHORITY;
12226 input_position++;
12227 }
12228 // Otherwise, set url's path to the empty string and set state to
12229 // opaque path state.
12230 else {
12231 state = ada::state::OPAQUE_PATH;
12232 }
12233 }
12234 // Otherwise, if state override is not given, set buffer to the empty
12235 // string, state to no scheme state, and start over (from the first code
12236 // point in input).
12237 else {
12238 state = ada::state::NO_SCHEME;
12239 input_position = 0;
12240 break;
12241 }
12242 input_position++;
12243 break;
12244 }
12245 case ada::state::NO_SCHEME: {
12246 ada_log("NO_SCHEME ", helpers::substring(url_data, input_position));
12247 // If base is null, or base has an opaque path and c is not U+0023 (#),
12248 // validation error, return failure.
12249 if (base_url == nullptr ||
12250 (base_url->has_opaque_path && !fragment.has_value())) {
12251 ada_log("NO_SCHEME validation error");
12252 url.is_valid = false;
12253 return url;
12254 }
12255 // Otherwise, if base has an opaque path and c is U+0023 (#),
12256 // set url's scheme to base's scheme, url's path to base's path, url's
12257 // query to base's query, and set state to fragment state.
12258 else if (base_url->has_opaque_path && fragment.has_value() &&
12259 input_position == input_size) {
12260 ada_log("NO_SCHEME opaque base with fragment");
12261 url.copy_scheme(*base_url);
12262 url.has_opaque_path = base_url->has_opaque_path;
12263
12264 if constexpr (result_type_is_ada_url) {
12265 url.path = base_url->path;
12266 url.query = base_url->query;
12267 } else {
12268 url.update_base_pathname(base_url->get_pathname());
12269 url.update_base_search(base_url->get_search());
12270 }
12271 url.update_unencoded_base_hash(*fragment);
12272 return url;
12273 }
12274 // Otherwise, if base's scheme is not "file", set state to relative
12275 // state and decrease pointer by 1.
12276 else if (base_url->type != ada::scheme::type::FILE) {
12277 ada_log("NO_SCHEME non-file relative path");
12278 state = ada::state::RELATIVE_SCHEME;
12279 }
12280 // Otherwise, set state to file state and decrease pointer by 1.
12281 else {
12282 ada_log("NO_SCHEME file base type");
12283 state = ada::state::FILE;
12284 }
12285 break;
12286 }
12287 case ada::state::AUTHORITY: {
12288 ada_log("AUTHORITY ", helpers::substring(url_data, input_position));
12289 // most URLs have no @. Having no @ tells us that we don't have to worry
12290 // about AUTHORITY. Of course, we could have @ and still not have to
12291 // worry about AUTHORITY.
12292 // TODO: Instead of just collecting a bool, collect the location of the
12293 // '@' and do something useful with it.
12294 // TODO: We could do various processing early on, using a single pass
12295 // over the string to collect information about it, e.g., telling us
12296 // whether there is a @ and if so, where (or how many).
12297 const bool contains_ampersand =
12298 (url_data.find('@', input_position) != std::string_view::npos);
12299
12300 if (!contains_ampersand) {
12301 state = ada::state::HOST;
12302 break;
12303 }
12304 bool at_sign_seen{false};
12305 bool password_token_seen{false};
12306 /**
12307 * We expect something of the sort...
12308 * https://user:pass@example.com:1234/foo/bar?baz#quux
12309 * --------^
12310 */
12311 do {
12312 std::string_view view = helpers::substring(url_data, input_position);
12313 // The delimiters are @, /, ? \\.
12314 size_t location =
12315 url.is_special() ? helpers::find_authority_delimiter_special(view)
12316 : helpers::find_authority_delimiter(view);
12317 std::string_view authority_view(view.data(), location);
12318 size_t end_of_authority = input_position + authority_view.size();
12319 // If c is U+0040 (@), then:
12320 if ((end_of_authority != input_size) &&
12321 (url_data[end_of_authority] == '@')) {
12322 // If atSignSeen is true, then prepend "%40" to buffer.
12323 if (at_sign_seen) {
12324 if (password_token_seen) {
12325 if constexpr (result_type_is_ada_url) {
12326 url.password += "%40";
12327 } else {
12328 url.append_base_password("%40");
12329 }
12330 } else {
12331 if constexpr (result_type_is_ada_url) {
12332 url.username += "%40";
12333 } else {
12334 url.append_base_username("%40");
12335 }
12336 }
12337 }
12338
12339 at_sign_seen = true;
12340
12341 if (!password_token_seen) {
12342 size_t password_token_location = authority_view.find(':');
12343 password_token_seen =
12344 password_token_location != std::string_view::npos;
12345
12346 if (!password_token_seen) {
12347 if constexpr (result_type_is_ada_url) {
12348 url.username += unicode::percent_encode(
12349 authority_view, character_sets::USERINFO_PERCENT_ENCODE);
12350 } else {
12351 url.append_base_username(unicode::percent_encode(
12352 authority_view, character_sets::USERINFO_PERCENT_ENCODE));
12353 }
12354 } else {
12355 if constexpr (result_type_is_ada_url) {
12356 url.username += unicode::percent_encode(
12357 authority_view.substr(0, password_token_location),
12358 character_sets::USERINFO_PERCENT_ENCODE);
12359 url.password += unicode::percent_encode(
12360 authority_view.substr(password_token_location + 1),
12361 character_sets::USERINFO_PERCENT_ENCODE);
12362 } else {
12363 url.append_base_username(unicode::percent_encode(
12364 authority_view.substr(0, password_token_location),
12365 character_sets::USERINFO_PERCENT_ENCODE));
12366 url.append_base_password(unicode::percent_encode(
12367 authority_view.substr(password_token_location + 1),
12368 character_sets::USERINFO_PERCENT_ENCODE));
12369 }
12370 }
12371 } else {
12372 if constexpr (result_type_is_ada_url) {
12373 url.password += unicode::percent_encode(
12374 authority_view, character_sets::USERINFO_PERCENT_ENCODE);
12375 } else {
12376 url.append_base_password(unicode::percent_encode(
12377 authority_view, character_sets::USERINFO_PERCENT_ENCODE));
12378 }
12379 }
12380 }
12381 // Otherwise, if one of the following is true:
12382 // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
12383 // - url is special and c is U+005C (\)
12384 else if (end_of_authority == input_size ||
12385 url_data[end_of_authority] == '/' ||
12386 url_data[end_of_authority] == '?' ||
12387 (url.is_special() && url_data[end_of_authority] == '\\')) {
12388 // If atSignSeen is true and authority_view is the empty string,
12389 // validation error, return failure.
12390 if (at_sign_seen && authority_view.empty()) {
12391 url.is_valid = false;
12392 return url;
12393 }
12394 state = ada::state::HOST;
12395 break;
12396 }
12397 if (end_of_authority == input_size) {
12398 if (fragment.has_value()) {
12399 url.update_unencoded_base_hash(*fragment);
12400 }
12401 return url;
12402 }
12403 input_position = end_of_authority + 1;
12404 } while (true);
12405
12406 break;
12407 }
12408 case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY: {
12409 ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ",
12410 helpers::substring(url_data, input_position));
12411
12412 // If c is U+002F (/) and remaining starts with U+002F (/),
12413 // then set state to special authority ignore slashes state and increase
12414 // pointer by 1.
12415 std::string_view view = helpers::substring(url_data, input_position);
12416 if (ada::checkers::begins_with(view, "//")) {
12417 state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
12418 input_position += 2;
12419 } else {
12420 // Otherwise, validation error, set state to relative state and
12421 // decrease pointer by 1.
12422 state = ada::state::RELATIVE_SCHEME;
12423 }
12424
12425 break;
12426 }
12427 case ada::state::PATH_OR_AUTHORITY: {
12428 ada_log("PATH_OR_AUTHORITY ",
12429 helpers::substring(url_data, input_position));
12430
12431 // If c is U+002F (/), then set state to authority state.
12432 if ((input_position != input_size) &&
12433 (url_data[input_position] == '/')) {
12434 state = ada::state::AUTHORITY;
12435 input_position++;
12436 } else {
12437 // Otherwise, set state to path state, and decrease pointer by 1.
12438 state = ada::state::PATH;
12439 }
12440
12441 break;
12442 }
12443 case ada::state::RELATIVE_SCHEME: {
12444 ada_log("RELATIVE_SCHEME ",
12445 helpers::substring(url_data, input_position));
12446
12447 // Set url's scheme to base's scheme.
12448 url.copy_scheme(*base_url);
12449
12450 // If c is U+002F (/), then set state to relative slash state.
12451 if ((input_position != input_size) &&
12452 (url_data[input_position] == '/')) {
12453 ada_log(
12454 "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "
12455 "slash state");
12456 state = ada::state::RELATIVE_SLASH;
12457 } else if (url.is_special() && (input_position != input_size) &&
12458 (url_data[input_position] == '\\')) {
12459 // Otherwise, if url is special and c is U+005C (\), validation error,
12460 // set state to relative slash state.
12461 ada_log(
12462 "RELATIVE_SCHEME if url is special and c is U+005C, validation "
12463 "error, set state to relative slash state");
12464 state = ada::state::RELATIVE_SLASH;
12465 } else {
12466 ada_log("RELATIVE_SCHEME otherwise");
12467 // Set url's username to base's username, url's password to base's
12468 // password, url's host to base's host, url's port to base's port,
12469 // url's path to a clone of base's path, and url's query to base's
12470 // query.
12471 if constexpr (result_type_is_ada_url) {
12472 url.username = base_url->username;
12473 url.password = base_url->password;
12474 url.host = base_url->host;
12475 url.port = base_url->port;
12476 // cloning the base path includes cloning the has_opaque_path flag
12477 url.has_opaque_path = base_url->has_opaque_path;
12478 url.path = base_url->path;
12479 url.query = base_url->query;
12480 } else {
12481 url.update_base_authority(base_url->get_href(),
12482 base_url->get_components());
12483 // TODO: Get rid of set_hostname and replace it with
12484 // update_base_hostname
12485 url.set_hostname(base_url->get_hostname());
12486 url.update_base_port(base_url->retrieve_base_port());
12487 // cloning the base path includes cloning the has_opaque_path flag
12488 url.has_opaque_path = base_url->has_opaque_path;
12489 url.update_base_pathname(base_url->get_pathname());
12490 url.update_base_search(base_url->get_search());
12491 }
12492
12493 url.has_opaque_path = base_url->has_opaque_path;
12494
12495 // If c is U+003F (?), then set url's query to the empty string, and
12496 // state to query state.
12497 if ((input_position != input_size) &&
12498 (url_data[input_position] == '?')) {
12499 state = ada::state::QUERY;
12500 }
12501 // Otherwise, if c is not the EOF code point:
12502 else if (input_position != input_size) {
12503 // Set url's query to null.
12504 url.clear_search();
12505 if constexpr (result_type_is_ada_url) {
12506 // Shorten url's path.
12507 helpers::shorten_path(url.path, url.type);
12508 } else {
12509 std::string_view path = url.get_pathname();
12510 if (helpers::shorten_path(path, url.type)) {
12511 url.update_base_pathname(std::string(path));
12512 }
12513 }
12514 // Set state to path state and decrease pointer by 1.
12515 state = ada::state::PATH;
12516 break;
12517 }
12518 }
12519 input_position++;
12520 break;
12521 }
12522 case ada::state::RELATIVE_SLASH: {
12523 ada_log("RELATIVE_SLASH ",
12524 helpers::substring(url_data, input_position));
12525
12526 // If url is special and c is U+002F (/) or U+005C (\), then:
12527 if (url.is_special() && (input_position != input_size) &&
12528 (url_data[input_position] == '/' ||
12529 url_data[input_position] == '\\')) {
12530 // Set state to special authority ignore slashes state.
12531 state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
12532 }
12533 // Otherwise, if c is U+002F (/), then set state to authority state.
12534 else if ((input_position != input_size) &&
12535 (url_data[input_position] == '/')) {
12536 state = ada::state::AUTHORITY;
12537 }
12538 // Otherwise, set
12539 // - url's username to base's username,
12540 // - url's password to base's password,
12541 // - url's host to base's host,
12542 // - url's port to base's port,
12543 // - state to path state, and then, decrease pointer by 1.
12544 else {
12545 if constexpr (result_type_is_ada_url) {
12546 url.username = base_url->username;
12547 url.password = base_url->password;
12548 url.host = base_url->host;
12549 url.port = base_url->port;
12550 } else {
12551 url.update_base_authority(base_url->get_href(),
12552 base_url->get_components());
12553 // TODO: Get rid of set_hostname and replace it with
12554 // update_base_hostname
12555 url.set_hostname(base_url->get_hostname());
12556 url.update_base_port(base_url->retrieve_base_port());
12557 }
12558 state = ada::state::PATH;
12559 break;
12560 }
12561
12562 input_position++;
12563 break;
12564 }
12565 case ada::state::SPECIAL_AUTHORITY_SLASHES: {
12566 ada_log("SPECIAL_AUTHORITY_SLASHES ",
12567 helpers::substring(url_data, input_position));
12568
12569 // If c is U+002F (/) and remaining starts with U+002F (/),
12570 // then set state to special authority ignore slashes state and increase
12571 // pointer by 1.
12572 state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
12573 std::string_view view = helpers::substring(url_data, input_position);
12574 if (ada::checkers::begins_with(view, "//")) {
12575 input_position += 2;
12576 }
12577
12578 [[fallthrough]];
12579 }
12580 case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES: {
12581 ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ",
12582 helpers::substring(url_data, input_position));
12583
12584 // If c is neither U+002F (/) nor U+005C (\), then set state to
12585 // authority state and decrease pointer by 1.
12586 while ((input_position != input_size) &&
12587 ((url_data[input_position] == '/') ||
12588 (url_data[input_position] == '\\'))) {
12589 input_position++;
12590 }
12591 state = ada::state::AUTHORITY;
12592
12593 break;
12594 }
12595 case ada::state::QUERY: {
12596 ada_log("QUERY ", helpers::substring(url_data, input_position));
12597 // Let queryPercentEncodeSet be the special-query percent-encode set if
12598 // url is special; otherwise the query percent-encode set.
12599 const uint8_t* query_percent_encode_set =
12600 url.is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
12601 : ada::character_sets::QUERY_PERCENT_ENCODE;
12602
12603 // Percent-encode after encoding, with encoding, buffer, and
12604 // queryPercentEncodeSet, and append the result to url's query.
12605 url.update_base_search(helpers::substring(url_data, input_position),
12606 query_percent_encode_set);
12607 ada_log("QUERY update_base_search completed ");
12608 if (fragment.has_value()) {
12609 url.update_unencoded_base_hash(*fragment);
12610 }
12611 return url;
12612 }
12613 case ada::state::HOST: {
12614 ada_log("HOST ", helpers::substring(url_data, input_position));
12615
12616 std::string_view host_view =
12617 helpers::substring(url_data, input_position);
12618 auto [location, found_colon] =
12619 helpers::get_host_delimiter_location(url.is_special(), host_view);
12620 input_position = (location != std::string_view::npos)
12621 ? input_position + location
12622 : input_size;
12623 // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
12624 // Note: the 'found_colon' value is true if and only if a colon was
12625 // encountered while not inside brackets.
12626 if (found_colon) {
12627 // If buffer is the empty string, validation error, return failure.
12628 // Let host be the result of host parsing buffer with url is not
12629 // special.
12630 ada_log("HOST parsing ", host_view);
12631 if (!url.parse_host(host_view)) {
12632 return url;
12633 }
12634 ada_log("HOST parsing results in ", url.get_hostname());
12635 // Set url's host to host, buffer to the empty string, and state to
12636 // port state.
12637 state = ada::state::PORT;
12638 input_position++;
12639 }
12640 // Otherwise, if one of the following is true:
12641 // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
12642 // - url is special and c is U+005C (\)
12643 // The get_host_delimiter_location function either brings us to
12644 // the colon outside of the bracket, or to one of those characters.
12645 else {
12646 // If url is special and host_view is the empty string, validation
12647 // error, return failure.
12648 if (url.is_special() && host_view.empty()) {
12649 url.is_valid = false;
12650 return url;
12651 }
12652 ada_log("HOST parsing ", host_view, " href=", url.get_href());
12653 // Let host be the result of host parsing host_view with url is not
12654 // special.
12655 if (host_view.empty()) {
12656 url.update_base_hostname("");
12657 } else if (!url.parse_host(host_view)) {
12658 return url;
12659 }
12660 ada_log("HOST parsing results in ", url.get_hostname(),
12661 " href=", url.get_href());
12662
12663 // Set url's host to host, and state to path start state.
12664 state = ada::state::PATH_START;
12665 }
12666
12667 break;
12668 }
12669 case ada::state::OPAQUE_PATH: {
12670 ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position));
12671 std::string_view view = helpers::substring(url_data, input_position);
12672 // If c is U+003F (?), then set url's query to the empty string and
12673 // state to query state.
12674 size_t location = view.find('?');
12675 if (location != std::string_view::npos) {
12676 view.remove_suffix(view.size() - location);
12677 state = ada::state::QUERY;
12678 input_position += location + 1;
12679 } else {
12680 input_position = input_size + 1;
12681 }
12682 url.has_opaque_path = true;
12683 // This is a really unlikely scenario in real world. We should not seek
12684 // to optimize it.
12685 url.update_base_pathname(unicode::percent_encode(
12686 view, character_sets::C0_CONTROL_PERCENT_ENCODE));
12687 break;
12688 }
12689 case ada::state::PORT: {
12690 ada_log("PORT ", helpers::substring(url_data, input_position));
12691 std::string_view port_view =
12692 helpers::substring(url_data, input_position);
12693 size_t consumed_bytes = url.parse_port(port_view, true);
12694 input_position += consumed_bytes;
12695 if (!url.is_valid) {
12696 return url;
12697 }
12698 state = state::PATH_START;
12699 [[fallthrough]];
12700 }
12701 case ada::state::PATH_START: {
12702 ada_log("PATH_START ", helpers::substring(url_data, input_position));
12703
12704 // If url is special, then:
12705 if (url.is_special()) {
12706 // Set state to path state.
12707 state = ada::state::PATH;
12708
12709 // Optimization: Avoiding going into PATH state improves the
12710 // performance of urls ending with /.
12711 if (input_position == input_size) {
12712 url.update_base_pathname("/");
12713 if (fragment.has_value()) {
12714 url.update_unencoded_base_hash(*fragment);
12715 }
12716 return url;
12717 }
12718 // If c is neither U+002F (/) nor U+005C (\), then decrease pointer
12719 // by 1. We know that (input_position == input_size) is impossible
12720 // here, because of the previous if-check.
12721 if ((url_data[input_position] != '/') &&
12722 (url_data[input_position] != '\\')) {
12723 break;
12724 }
12725 }
12726 // Otherwise, if state override is not given and c is U+003F (?),
12727 // set url's query to the empty string and state to query state.
12728 else if ((input_position != input_size) &&
12729 (url_data[input_position] == '?')) {
12730 state = ada::state::QUERY;
12731 }
12732 // Otherwise, if c is not the EOF code point:
12733 else if (input_position != input_size) {
12734 // Set state to path state.
12735 state = ada::state::PATH;
12736
12737 // If c is not U+002F (/), then decrease pointer by 1.
12738 if (url_data[input_position] != '/') {
12739 break;
12740 }
12741 }
12742
12743 input_position++;
12744 break;
12745 }
12746 case ada::state::PATH: {
12747 std::string_view view = helpers::substring(url_data, input_position);
12748 ada_log("PATH ", helpers::substring(url_data, input_position));
12749
12750 // Most time, we do not need percent encoding.
12751 // Furthermore, we can immediately locate the '?'.
12752 size_t locofquestionmark = view.find('?');
12753 if (locofquestionmark != std::string_view::npos) {
12754 state = ada::state::QUERY;
12755 view.remove_suffix(view.size() - locofquestionmark);
12756 input_position += locofquestionmark + 1;
12757 } else {
12758 input_position = input_size + 1;
12759 }
12760 if constexpr (result_type_is_ada_url) {
12761 helpers::parse_prepared_path(view, url.type, url.path);
12762 } else {
12763 url.consume_prepared_path(view);
12764 ADA_ASSERT_TRUE(url.validate());
12765 }
12766 break;
12767 }
12768 case ada::state::FILE_SLASH: {
12769 ada_log("FILE_SLASH ", helpers::substring(url_data, input_position));
12770
12771 // If c is U+002F (/) or U+005C (\), then:
12772 if ((input_position != input_size) &&
12773 (url_data[input_position] == '/' ||
12774 url_data[input_position] == '\\')) {
12775 ada_log("FILE_SLASH c is U+002F or U+005C");
12776 // Set state to file host state.
12777 state = ada::state::FILE_HOST;
12778 input_position++;
12779 } else {
12780 ada_log("FILE_SLASH otherwise");
12781 // If base is non-null and base's scheme is "file", then:
12782 // Note: it is unsafe to do base_url->scheme unless you know that
12783 // base_url_has_value() is true.
12784 if (base_url != nullptr &&
12785 base_url->type == ada::scheme::type::FILE) {
12786 // Set url's host to base's host.
12787 if constexpr (result_type_is_ada_url) {
12788 url.host = base_url->host;
12789 } else {
12790 // TODO: Optimization opportunity.
12791 url.set_host(base_url->get_host());
12792 }
12793 // If the code point substring from pointer to the end of input does
12794 // not start with a Windows drive letter and base's path[0] is a
12795 // normalized Windows drive letter, then append base's path[0] to
12796 // url's path.
12797 if (!base_url->get_pathname().empty()) {
12798 if (!checkers::is_windows_drive_letter(
12799 helpers::substring(url_data, input_position))) {
12800 std::string_view first_base_url_path =
12801 base_url->get_pathname().substr(1);
12802 size_t loc = first_base_url_path.find('/');
12803 if (loc != std::string_view::npos) {
12804 helpers::resize(first_base_url_path, loc);
12805 }
12806 if (checkers::is_normalized_windows_drive_letter(
12807 first_base_url_path)) {
12808 if constexpr (result_type_is_ada_url) {
12809 url.path += '/';
12810 url.path += first_base_url_path;
12811 } else {
12812 url.append_base_pathname(
12813 helpers::concat("/", first_base_url_path));
12814 }
12815 }
12816 }
12817 }
12818 }
12819
12820 // Set state to path state, and decrease pointer by 1.
12821 state = ada::state::PATH;
12822 }
12823
12824 break;
12825 }
12826 case ada::state::FILE_HOST: {
12827 std::string_view view = helpers::substring(url_data, input_position);
12828 ada_log("FILE_HOST ", helpers::substring(url_data, input_position));
12829
12830 size_t location = view.find_first_of("/\\?");
12831 std::string_view file_host_buffer(
12832 view.data(),
12833 (location != std::string_view::npos) ? location : view.size());
12834
12835 if (checkers::is_windows_drive_letter(file_host_buffer)) {
12836 state = ada::state::PATH;
12837 } else if (file_host_buffer.empty()) {
12838 // Set url's host to the empty string.
12839 if constexpr (result_type_is_ada_url) {
12840 url.host = "";
12841 } else {
12842 url.update_base_hostname("");
12843 }
12844 // Set state to path start state.
12845 state = ada::state::PATH_START;
12846 } else {
12847 size_t consumed_bytes = file_host_buffer.size();
12848 input_position += consumed_bytes;
12849 // Let host be the result of host parsing buffer with url is not
12850 // special.
12851 if (!url.parse_host(file_host_buffer)) {
12852 return url;
12853 }
12854
12855 if constexpr (result_type_is_ada_url) {
12856 // If host is "localhost", then set host to the empty string.
12857 if (url.host.has_value() && url.host.value() == "localhost") {
12858 url.host = "";
12859 }
12860 } else {
12861 if (url.get_hostname() == "localhost") {
12862 url.update_base_hostname("");
12863 }
12864 }
12865
12866 // Set buffer to the empty string and state to path start state.
12867 state = ada::state::PATH_START;
12868 }
12869
12870 break;
12871 }
12872 case ada::state::FILE: {
12873 ada_log("FILE ", helpers::substring(url_data, input_position));
12874 std::string_view file_view =
12875 helpers::substring(url_data, input_position);
12876
12877 url.set_protocol_as_file();
12878 if constexpr (result_type_is_ada_url) {
12879 // Set url's host to the empty string.
12880 url.host = "";
12881 } else {
12882 url.update_base_hostname("");
12883 }
12884 // If c is U+002F (/) or U+005C (\), then:
12885 if (input_position != input_size &&
12886 (url_data[input_position] == '/' ||
12887 url_data[input_position] == '\\')) {
12888 ada_log("FILE c is U+002F or U+005C");
12889 // Set state to file slash state.
12890 state = ada::state::FILE_SLASH;
12891 }
12892 // Otherwise, if base is non-null and base's scheme is "file":
12893 else if (base_url != nullptr &&
12894 base_url->type == ada::scheme::type::FILE) {
12895 // Set url's host to base's host, url's path to a clone of base's
12896 // path, and url's query to base's query.
12897 ada_log("FILE base non-null");
12898 if constexpr (result_type_is_ada_url) {
12899 url.host = base_url->host;
12900 url.path = base_url->path;
12901 url.query = base_url->query;
12902 } else {
12903 // TODO: Get rid of set_hostname and replace it with
12904 // update_base_hostname
12905 url.set_hostname(base_url->get_hostname());
12906 url.update_base_pathname(base_url->get_pathname());
12907 url.update_base_search(base_url->get_search());
12908 }
12909 url.has_opaque_path = base_url->has_opaque_path;
12910
12911 // If c is U+003F (?), then set url's query to the empty string and
12912 // state to query state.
12913 if (input_position != input_size && url_data[input_position] == '?') {
12914 state = ada::state::QUERY;
12915 }
12916 // Otherwise, if c is not the EOF code point:
12917 else if (input_position != input_size) {
12918 // Set url's query to null.
12919 url.clear_search();
12920 // If the code point substring from pointer to the end of input does
12921 // not start with a Windows drive letter, then shorten url's path.
12922 if (!checkers::is_windows_drive_letter(file_view)) {
12923 if constexpr (result_type_is_ada_url) {
12924 helpers::shorten_path(url.path, url.type);
12925 } else {
12926 std::string_view path = url.get_pathname();
12927 if (helpers::shorten_path(path, url.type)) {
12928 url.update_base_pathname(std::string(path));
12929 }
12930 }
12931 }
12932 // Otherwise:
12933 else {
12934 // Set url's path to an empty list.
12935 url.clear_pathname();
12936 url.has_opaque_path = true;
12937 }
12938
12939 // Set state to path state and decrease pointer by 1.
12940 state = ada::state::PATH;
12941 break;
12942 }
12943 }
12944 // Otherwise, set state to path state, and decrease pointer by 1.
12945 else {
12946 ada_log("FILE go to path");
12947 state = ada::state::PATH;
12948 break;
12949 }
12950
12951 input_position++;
12952 break;
12953 }
12954 default:
12955 ada::unreachable();
12956 }
12957 }
12958 if (fragment.has_value()) {
12959 url.update_unencoded_base_hash(*fragment);
12960 }
12961 return url;
12962 }
12963
12964 template url parse_url<url>(std::string_view user_input,
12965 const url* base_url = nullptr);
12966 template url_aggregator parse_url<url_aggregator>(
12967 std::string_view user_input, const url_aggregator* base_url = nullptr);
12968
12969 } // namespace ada::parser
12970 /* end file src/parser.cpp */
12971 /* begin file src/url_components.cpp */
12972
12973 #include <numeric>
12974 #include <string>
12975
12976 namespace ada {
12977
check_offset_consistency() const12978 bool url_components::check_offset_consistency() const noexcept {
12979 /**
12980 * https://user:pass@example.com:1234/foo/bar?baz#quux
12981 * | | | | ^^^^| | |
12982 * | | | | | | | `----- hash_start
12983 * | | | | | | `--------- search_start
12984 * | | | | | `----------------- pathname_start
12985 * | | | | `--------------------- port
12986 * | | | `----------------------- host_end
12987 * | | `---------------------------------- host_start
12988 * | `--------------------------------------- username_end
12989 * `--------------------------------------------- protocol_end
12990 */
12991 // These conditions can be made more strict.
12992 uint32_t index = 0;
12993
12994 if (protocol_end == url_components::omitted) {
12995 return false;
12996 }
12997 if (protocol_end < index) {
12998 return false;
12999 }
13000 index = protocol_end;
13001
13002 if (username_end == url_components::omitted) {
13003 return false;
13004 }
13005 if (username_end < index) {
13006 return false;
13007 }
13008 index = username_end;
13009
13010 if (host_start == url_components::omitted) {
13011 return false;
13012 }
13013 if (host_start < index) {
13014 return false;
13015 }
13016 index = host_start;
13017
13018 if (port != url_components::omitted) {
13019 if (port > 0xffff) {
13020 return false;
13021 }
13022 uint32_t port_length = helpers::fast_digit_count(port) + 1;
13023 if (index + port_length < index) {
13024 return false;
13025 }
13026 index += port_length;
13027 }
13028
13029 if (pathname_start == url_components::omitted) {
13030 return false;
13031 }
13032 if (pathname_start < index) {
13033 return false;
13034 }
13035 index = pathname_start;
13036
13037 if (search_start != url_components::omitted) {
13038 if (search_start < index) {
13039 return false;
13040 }
13041 index = search_start;
13042 }
13043
13044 if (hash_start != url_components::omitted) {
13045 if (hash_start < index) {
13046 return false;
13047 }
13048 index = hash_start;
13049 }
13050
13051 return true;
13052 }
13053
to_string() const13054 std::string url_components::to_string() const {
13055 std::string answer;
13056 auto back = std::back_insert_iterator(answer);
13057 answer.append("{\n");
13058
13059 answer.append("\t\"protocol_end\":\"");
13060 helpers::encode_json(std::to_string(protocol_end), back);
13061 answer.append("\",\n");
13062
13063 answer.append("\t\"username_end\":\"");
13064 helpers::encode_json(std::to_string(username_end), back);
13065 answer.append("\",\n");
13066
13067 answer.append("\t\"host_start\":\"");
13068 helpers::encode_json(std::to_string(host_start), back);
13069 answer.append("\",\n");
13070
13071 answer.append("\t\"host_end\":\"");
13072 helpers::encode_json(std::to_string(host_end), back);
13073 answer.append("\",\n");
13074
13075 answer.append("\t\"port\":\"");
13076 helpers::encode_json(std::to_string(port), back);
13077 answer.append("\",\n");
13078
13079 answer.append("\t\"pathname_start\":\"");
13080 helpers::encode_json(std::to_string(pathname_start), back);
13081 answer.append("\",\n");
13082
13083 answer.append("\t\"search_start\":\"");
13084 helpers::encode_json(std::to_string(search_start), back);
13085 answer.append("\",\n");
13086
13087 answer.append("\t\"hash_start\":\"");
13088 helpers::encode_json(std::to_string(hash_start), back);
13089 answer.append("\",\n");
13090
13091 answer.append("\n}");
13092 return answer;
13093 }
13094
13095 } // namespace ada
13096 /* end file src/url_components.cpp */
13097 /* begin file src/url_aggregator.cpp */
13098
13099 #include <string>
13100 #include <string_view>
13101
13102 namespace ada {
13103 template <bool has_state_override>
parse_scheme_with_colon(const std::string_view input_with_colon)13104 [[nodiscard]] ada_really_inline bool url_aggregator::parse_scheme_with_colon(
13105 const std::string_view input_with_colon) {
13106 ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon);
13107 ADA_ASSERT_TRUE(validate());
13108 ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));
13109 std::string_view input{input_with_colon};
13110 input.remove_suffix(1);
13111 auto parsed_type = ada::scheme::get_scheme_type(input);
13112 bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
13113 /**
13114 * In the common case, we will immediately recognize a special scheme (e.g.,
13115 *http, https), in which case, we can go really fast.
13116 **/
13117 if (is_input_special) { // fast path!!!
13118 if (has_state_override) {
13119 // If url's scheme is not a special scheme and buffer is a special scheme,
13120 // then return.
13121 if (is_special() != is_input_special) {
13122 return true;
13123 }
13124
13125 // If url includes credentials or has a non-null port, and buffer is
13126 // "file", then return.
13127 if ((has_credentials() || components.port != url_components::omitted) &&
13128 parsed_type == ada::scheme::type::FILE) {
13129 return true;
13130 }
13131
13132 // If url's scheme is "file" and its host is an empty host, then return.
13133 // An empty host is the empty string.
13134 if (type == ada::scheme::type::FILE &&
13135 components.host_start == components.host_end) {
13136 return true;
13137 }
13138 }
13139
13140 type = parsed_type;
13141 set_scheme_from_view_with_colon(input_with_colon);
13142
13143 if (has_state_override) {
13144 // This is uncommon.
13145 uint16_t urls_scheme_port = get_special_port();
13146
13147 // If url's port is url's scheme's default port, then set url's port to
13148 // null.
13149 if (components.port == urls_scheme_port) {
13150 clear_port();
13151 }
13152 }
13153 } else { // slow path
13154 std::string _buffer = std::string(input);
13155 // Next function is only valid if the input is ASCII and returns false
13156 // otherwise, but it seems that we always have ascii content so we do not
13157 // need to check the return value.
13158 unicode::to_lower_ascii(_buffer.data(), _buffer.size());
13159
13160 if (has_state_override) {
13161 // If url's scheme is a special scheme and buffer is not a special scheme,
13162 // then return. If url's scheme is not a special scheme and buffer is a
13163 // special scheme, then return.
13164 if (is_special() != ada::scheme::is_special(_buffer)) {
13165 return true;
13166 }
13167
13168 // If url includes credentials or has a non-null port, and buffer is
13169 // "file", then return.
13170 if ((has_credentials() || components.port != url_components::omitted) &&
13171 _buffer == "file") {
13172 return true;
13173 }
13174
13175 // If url's scheme is "file" and its host is an empty host, then return.
13176 // An empty host is the empty string.
13177 if (type == ada::scheme::type::FILE &&
13178 components.host_start == components.host_end) {
13179 return true;
13180 }
13181 }
13182
13183 set_scheme(_buffer);
13184
13185 if (has_state_override) {
13186 // This is uncommon.
13187 uint16_t urls_scheme_port = get_special_port();
13188
13189 // If url's port is url's scheme's default port, then set url's port to
13190 // null.
13191 if (components.port == urls_scheme_port) {
13192 clear_port();
13193 }
13194 }
13195 }
13196 ADA_ASSERT_TRUE(validate());
13197 return true;
13198 }
13199
copy_scheme(const url_aggregator & u)13200 inline void url_aggregator::copy_scheme(const url_aggregator& u) noexcept {
13201 ada_log("url_aggregator::copy_scheme ", u.buffer);
13202 ADA_ASSERT_TRUE(validate());
13203 // next line could overflow but unsigned arithmetic has well-defined
13204 // overflows.
13205 uint32_t new_difference = u.components.protocol_end - components.protocol_end;
13206 type = u.type;
13207 buffer.erase(0, components.protocol_end);
13208 buffer.insert(0, u.get_protocol());
13209 components.protocol_end = u.components.protocol_end;
13210
13211 // No need to update the components
13212 if (new_difference == 0) {
13213 return;
13214 }
13215
13216 // Update the rest of the components.
13217 components.username_end += new_difference;
13218 components.host_start += new_difference;
13219 components.host_end += new_difference;
13220 components.pathname_start += new_difference;
13221 if (components.search_start != url_components::omitted) {
13222 components.search_start += new_difference;
13223 }
13224 if (components.hash_start != url_components::omitted) {
13225 components.hash_start += new_difference;
13226 }
13227 ADA_ASSERT_TRUE(validate());
13228 }
13229
set_scheme_from_view_with_colon(std::string_view new_scheme_with_colon)13230 inline void url_aggregator::set_scheme_from_view_with_colon(
13231 std::string_view new_scheme_with_colon) noexcept {
13232 ada_log("url_aggregator::set_scheme_from_view_with_colon ",
13233 new_scheme_with_colon);
13234 ADA_ASSERT_TRUE(validate());
13235 ADA_ASSERT_TRUE(!new_scheme_with_colon.empty() &&
13236 new_scheme_with_colon.back() == ':');
13237 // next line could overflow but unsigned arithmetic has well-defined
13238 // overflows.
13239 uint32_t new_difference =
13240 uint32_t(new_scheme_with_colon.size()) - components.protocol_end;
13241
13242 if (buffer.empty()) {
13243 buffer.append(new_scheme_with_colon);
13244 } else {
13245 buffer.erase(0, components.protocol_end);
13246 buffer.insert(0, new_scheme_with_colon);
13247 }
13248 components.protocol_end += new_difference;
13249
13250 // Update the rest of the components.
13251 components.username_end += new_difference;
13252 components.host_start += new_difference;
13253 components.host_end += new_difference;
13254 components.pathname_start += new_difference;
13255 if (components.search_start != url_components::omitted) {
13256 components.search_start += new_difference;
13257 }
13258 if (components.hash_start != url_components::omitted) {
13259 components.hash_start += new_difference;
13260 }
13261 ADA_ASSERT_TRUE(validate());
13262 }
13263
set_scheme(std::string_view new_scheme)13264 inline void url_aggregator::set_scheme(std::string_view new_scheme) noexcept {
13265 ada_log("url_aggregator::set_scheme ", new_scheme);
13266 ADA_ASSERT_TRUE(validate());
13267 ADA_ASSERT_TRUE(new_scheme.empty() || new_scheme.back() != ':');
13268 // next line could overflow but unsigned arithmetic has well-defined
13269 // overflows.
13270 uint32_t new_difference =
13271 uint32_t(new_scheme.size()) - components.protocol_end + 1;
13272
13273 type = ada::scheme::get_scheme_type(new_scheme);
13274 if (buffer.empty()) {
13275 buffer.append(helpers::concat(new_scheme, ":"));
13276 } else {
13277 buffer.erase(0, components.protocol_end);
13278 buffer.insert(0, helpers::concat(new_scheme, ":"));
13279 }
13280 components.protocol_end = uint32_t(new_scheme.size() + 1);
13281
13282 // Update the rest of the components.
13283 components.username_end += new_difference;
13284 components.host_start += new_difference;
13285 components.host_end += new_difference;
13286 components.pathname_start += new_difference;
13287 if (components.search_start != url_components::omitted) {
13288 components.search_start += new_difference;
13289 }
13290 if (components.hash_start != url_components::omitted) {
13291 components.hash_start += new_difference;
13292 }
13293 ADA_ASSERT_TRUE(validate());
13294 }
13295
set_protocol(const std::string_view input)13296 bool url_aggregator::set_protocol(const std::string_view input) {
13297 ada_log("url_aggregator::set_protocol ", input);
13298 ADA_ASSERT_TRUE(validate());
13299 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13300 std::string view(input);
13301 helpers::remove_ascii_tab_or_newline(view);
13302 if (view.empty()) {
13303 return true;
13304 }
13305
13306 // Schemes should start with alpha values.
13307 if (!checkers::is_alpha(view[0])) {
13308 return false;
13309 }
13310
13311 view.append(":");
13312
13313 std::string::iterator pointer =
13314 std::find_if_not(view.begin(), view.end(), unicode::is_alnum_plus);
13315
13316 if (pointer != view.end() && *pointer == ':') {
13317 return parse_scheme_with_colon<true>(
13318 std::string_view(view.data(), pointer - view.begin() + 1));
13319 }
13320 return false;
13321 }
13322
set_username(const std::string_view input)13323 bool url_aggregator::set_username(const std::string_view input) {
13324 ada_log("url_aggregator::set_username '", input, "' ");
13325 ADA_ASSERT_TRUE(validate());
13326 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13327 if (cannot_have_credentials_or_port()) {
13328 return false;
13329 }
13330 size_t idx = ada::unicode::percent_encode_index(
13331 input, character_sets::USERINFO_PERCENT_ENCODE);
13332 if (idx == input.size()) {
13333 update_base_username(input);
13334 } else {
13335 // We only create a temporary string if we have to!
13336 update_base_username(ada::unicode::percent_encode(
13337 input, character_sets::USERINFO_PERCENT_ENCODE, idx));
13338 }
13339 ADA_ASSERT_TRUE(validate());
13340 return true;
13341 }
13342
set_password(const std::string_view input)13343 bool url_aggregator::set_password(const std::string_view input) {
13344 ada_log("url_aggregator::set_password '", input, "'");
13345 ADA_ASSERT_TRUE(validate());
13346 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13347 if (cannot_have_credentials_or_port()) {
13348 return false;
13349 }
13350 size_t idx = ada::unicode::percent_encode_index(
13351 input, character_sets::USERINFO_PERCENT_ENCODE);
13352 if (idx == input.size()) {
13353 update_base_password(input);
13354 } else {
13355 // We only create a temporary string if we have to!
13356 update_base_password(ada::unicode::percent_encode(
13357 input, character_sets::USERINFO_PERCENT_ENCODE, idx));
13358 }
13359 ADA_ASSERT_TRUE(validate());
13360 return true;
13361 }
13362
set_port(const std::string_view input)13363 bool url_aggregator::set_port(const std::string_view input) {
13364 ada_log("url_aggregator::set_port ", input);
13365 ADA_ASSERT_TRUE(validate());
13366 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13367 if (cannot_have_credentials_or_port()) {
13368 return false;
13369 }
13370 std::string trimmed(input);
13371 helpers::remove_ascii_tab_or_newline(trimmed);
13372 if (trimmed.empty()) {
13373 clear_port();
13374 return true;
13375 }
13376 // Input should not start with control characters.
13377 if (ada::unicode::is_c0_control_or_space(trimmed.front())) {
13378 return false;
13379 }
13380 // Input should contain at least one ascii digit.
13381 if (input.find_first_of("0123456789") == std::string_view::npos) {
13382 return false;
13383 }
13384
13385 // Revert changes if parse_port fails.
13386 uint32_t previous_port = components.port;
13387 parse_port(trimmed);
13388 if (is_valid) {
13389 return true;
13390 }
13391 update_base_port(previous_port);
13392 is_valid = true;
13393 ADA_ASSERT_TRUE(validate());
13394 return false;
13395 }
13396
set_pathname(const std::string_view input)13397 bool url_aggregator::set_pathname(const std::string_view input) {
13398 ada_log("url_aggregator::set_pathname ", input);
13399 ADA_ASSERT_TRUE(validate());
13400 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13401 if (has_opaque_path) {
13402 return false;
13403 }
13404 clear_pathname();
13405 parse_path(input);
13406 if (checkers::begins_with(input, "//") && !has_authority() &&
13407 !has_dash_dot()) {
13408 buffer.insert(components.pathname_start, "/.");
13409 components.pathname_start += 2;
13410 }
13411 ADA_ASSERT_TRUE(validate());
13412 return true;
13413 }
13414
parse_path(std::string_view input)13415 ada_really_inline void url_aggregator::parse_path(std::string_view input) {
13416 ada_log("url_aggregator::parse_path ", input);
13417 ADA_ASSERT_TRUE(validate());
13418 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13419 std::string tmp_buffer;
13420 std::string_view internal_input;
13421 if (unicode::has_tabs_or_newline(input)) {
13422 tmp_buffer = input;
13423 // Optimization opportunity: Instead of copying and then pruning, we could
13424 // just directly build the string from user_input.
13425 helpers::remove_ascii_tab_or_newline(tmp_buffer);
13426 internal_input = tmp_buffer;
13427 } else {
13428 internal_input = input;
13429 }
13430
13431 // If url is special, then:
13432 if (is_special()) {
13433 if (internal_input.empty()) {
13434 update_base_pathname("/");
13435 } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
13436 consume_prepared_path(internal_input.substr(1));
13437 } else {
13438 consume_prepared_path(internal_input);
13439 }
13440 } else if (!internal_input.empty()) {
13441 if (internal_input[0] == '/') {
13442 consume_prepared_path(internal_input.substr(1));
13443 } else {
13444 consume_prepared_path(internal_input);
13445 }
13446 } else {
13447 // Non-special URLs with an empty host can have their paths erased
13448 // Path-only URLs cannot have their paths erased
13449 if (components.host_start == components.host_end && !has_authority()) {
13450 update_base_pathname("/");
13451 }
13452 }
13453 ADA_ASSERT_TRUE(validate());
13454 }
13455
set_search(const std::string_view input)13456 void url_aggregator::set_search(const std::string_view input) {
13457 ada_log("url_aggregator::set_search ", input);
13458 ADA_ASSERT_TRUE(validate());
13459 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13460 if (input.empty()) {
13461 clear_search();
13462 helpers::strip_trailing_spaces_from_opaque_path(*this);
13463 return;
13464 }
13465
13466 std::string new_value;
13467 new_value = input[0] == '?' ? input.substr(1) : input;
13468 helpers::remove_ascii_tab_or_newline(new_value);
13469
13470 auto query_percent_encode_set =
13471 is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
13472 : ada::character_sets::QUERY_PERCENT_ENCODE;
13473
13474 update_base_search(new_value, query_percent_encode_set);
13475 ADA_ASSERT_TRUE(validate());
13476 }
13477
set_hash(const std::string_view input)13478 void url_aggregator::set_hash(const std::string_view input) {
13479 ada_log("url_aggregator::set_hash ", input);
13480 ADA_ASSERT_TRUE(validate());
13481 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13482 if (input.empty()) {
13483 if (components.hash_start != url_components::omitted) {
13484 buffer.resize(components.hash_start);
13485 components.hash_start = url_components::omitted;
13486 }
13487 helpers::strip_trailing_spaces_from_opaque_path(*this);
13488 return;
13489 }
13490
13491 std::string new_value;
13492 new_value = input[0] == '#' ? input.substr(1) : input;
13493 helpers::remove_ascii_tab_or_newline(new_value);
13494 update_unencoded_base_hash(new_value);
13495 ADA_ASSERT_TRUE(validate());
13496 }
13497
set_href(const std::string_view input)13498 bool url_aggregator::set_href(const std::string_view input) {
13499 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13500 ada_log("url_aggregator::set_href ", input, "[", input.size(), " bytes]");
13501 ada::result<url_aggregator> out = ada::parse<url_aggregator>(input);
13502 ada_log("url_aggregator::set_href, success :", out.has_value());
13503
13504 if (out) {
13505 ada_log("url_aggregator::set_href, parsed ", out->to_string());
13506 // TODO: Figure out why the following line puts test to never finish.
13507 *this = *out;
13508 }
13509
13510 return out.has_value();
13511 }
13512
parse_host(std::string_view input)13513 ada_really_inline bool url_aggregator::parse_host(std::string_view input) {
13514 ada_log("url_aggregator:parse_host ", input, "[", input.size(), " bytes]");
13515 ADA_ASSERT_TRUE(validate());
13516 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13517 if (input.empty()) {
13518 return is_valid = false;
13519 } // technically unnecessary.
13520 // If input starts with U+005B ([), then:
13521 if (input[0] == '[') {
13522 // If input does not end with U+005D (]), validation error, return failure.
13523 if (input.back() != ']') {
13524 return is_valid = false;
13525 }
13526 ada_log("parse_host ipv6");
13527
13528 // Return the result of IPv6 parsing input with its leading U+005B ([) and
13529 // trailing U+005D (]) removed.
13530 input.remove_prefix(1);
13531 input.remove_suffix(1);
13532 return parse_ipv6(input);
13533 }
13534
13535 // If isNotSpecial is true, then return the result of opaque-host parsing
13536 // input.
13537 if (!is_special()) {
13538 return parse_opaque_host(input);
13539 }
13540 // Let domain be the result of running UTF-8 decode without BOM on the
13541 // percent-decoding of input. Let asciiDomain be the result of running domain
13542 // to ASCII with domain and false. The most common case is an ASCII input, in
13543 // which case we do not need to call the expensive 'to_ascii' if a few
13544 // conditions are met: no '%' and no 'xn-' subsequence.
13545
13546 // Often, the input does not contain any forbidden code points, and no upper
13547 // case ASCII letter, then we can just copy it to the buffer. We want to
13548 // optimize for such a common case.
13549 uint8_t is_forbidden_or_upper =
13550 unicode::contains_forbidden_domain_code_point_or_upper(input.data(),
13551 input.size());
13552 // Minor optimization opportunity:
13553 // contains_forbidden_domain_code_point_or_upper could be extend to check for
13554 // the presence of characters that cannot appear in the ipv4 address and we
13555 // could also check whether x and n and - are present, and so we could skip
13556 // some of the checks below. However, the gains are likely to be small, and
13557 // the code would be more complex.
13558 if (is_forbidden_or_upper == 0 &&
13559 input.find("xn-") == std::string_view::npos) {
13560 // fast path
13561 update_base_hostname(input);
13562 if (checkers::is_ipv4(get_hostname())) {
13563 ada_log("parse_host fast path ipv4");
13564 return parse_ipv4(get_hostname());
13565 }
13566 ada_log("parse_host fast path ", get_hostname());
13567 return true;
13568 }
13569 // We have encountered at least one forbidden code point or the input contains
13570 // 'xn-' (case insensitive), so we need to call 'to_ascii' to perform the full
13571 // conversion.
13572
13573 ada_log("parse_host calling to_ascii");
13574 std::optional<std::string> host = std::string(get_hostname());
13575 is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
13576 if (!is_valid) {
13577 ada_log("parse_host to_ascii returns false");
13578 return is_valid = false;
13579 }
13580
13581 if (std::any_of(host.value().begin(), host.value().end(),
13582 ada::unicode::is_forbidden_domain_code_point)) {
13583 return is_valid = false;
13584 }
13585
13586 // If asciiDomain ends in a number, then return the result of IPv4 parsing
13587 // asciiDomain.
13588 if (checkers::is_ipv4(host.value())) {
13589 ada_log("parse_host got ipv4", *host);
13590 return parse_ipv4(host.value());
13591 }
13592
13593 update_base_hostname(host.value());
13594 ADA_ASSERT_TRUE(validate());
13595 return true;
13596 }
13597
13598 template <bool override_hostname>
set_host_or_hostname(const std::string_view input)13599 bool url_aggregator::set_host_or_hostname(const std::string_view input) {
13600 ada_log("url_aggregator::set_host_or_hostname ", input);
13601 ADA_ASSERT_TRUE(validate());
13602 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13603 if (has_opaque_path) {
13604 return false;
13605 }
13606
13607 std::string previous_host = std::string(get_hostname());
13608 uint32_t previous_port = components.port;
13609
13610 size_t host_end_pos = input.find('#');
13611 std::string _host(input.data(), host_end_pos != std::string_view::npos
13612 ? host_end_pos
13613 : input.size());
13614 helpers::remove_ascii_tab_or_newline(_host);
13615 std::string_view new_host(_host);
13616
13617 // If url's scheme is "file", then set state to file host state, instead of
13618 // host state.
13619 if (type != ada::scheme::type::FILE) {
13620 std::string_view host_view(_host.data(), _host.length());
13621 auto [location, found_colon] =
13622 helpers::get_host_delimiter_location(is_special(), host_view);
13623
13624 // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
13625 // Note: the 'found_colon' value is true if and only if a colon was
13626 // encountered while not inside brackets.
13627 if (found_colon) {
13628 if (override_hostname) {
13629 return false;
13630 }
13631 std::string_view sub_buffer = new_host.substr(location + 1);
13632 if (!sub_buffer.empty()) {
13633 set_port(sub_buffer);
13634 }
13635 }
13636 // If url is special and host_view is the empty string, validation error,
13637 // return failure. Otherwise, if state override is given, host_view is the
13638 // empty string, and either url includes credentials or url's port is
13639 // non-null, return.
13640 else if (host_view.empty() &&
13641 (is_special() || has_credentials() ||
13642 components.port != url_components::omitted)) {
13643 return false;
13644 }
13645
13646 // Let host be the result of host parsing host_view with url is not special.
13647 if (host_view.empty()) {
13648 if (has_hostname()) {
13649 clear_hostname(); // easy!
13650 } else if (has_dash_dot()) {
13651 add_authority_slashes_if_needed();
13652 delete_dash_dot();
13653 }
13654 return true;
13655 }
13656
13657 bool succeeded = parse_host(host_view);
13658 if (!succeeded) {
13659 update_base_hostname(previous_host);
13660 update_base_port(previous_port);
13661 } else if (has_dash_dot()) {
13662 // Should remove dash_dot from pathname
13663 delete_dash_dot();
13664 }
13665 return succeeded;
13666 }
13667
13668 size_t location = new_host.find_first_of("/\\?");
13669 if (location != std::string_view::npos) {
13670 new_host.remove_suffix(new_host.length() - location);
13671 }
13672
13673 if (new_host.empty()) {
13674 // Set url's host to the empty string.
13675 clear_hostname();
13676 } else {
13677 // Let host be the result of host parsing buffer with url is not special.
13678 if (!parse_host(new_host)) {
13679 update_base_hostname(previous_host);
13680 update_base_port(previous_port);
13681 return false;
13682 }
13683
13684 // If host is "localhost", then set host to the empty string.
13685 if (helpers::substring(buffer, components.host_start,
13686 components.host_end) == "localhost") {
13687 clear_hostname();
13688 }
13689 }
13690 ADA_ASSERT_TRUE(validate());
13691 return true;
13692 }
13693
set_host(const std::string_view input)13694 bool url_aggregator::set_host(const std::string_view input) {
13695 ada_log("url_aggregator::set_host '", input, "'");
13696 ADA_ASSERT_TRUE(validate());
13697 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13698 return set_host_or_hostname<false>(input);
13699 }
13700
set_hostname(const std::string_view input)13701 bool url_aggregator::set_hostname(const std::string_view input) {
13702 ada_log("url_aggregator::set_hostname '", input, "'");
13703 ADA_ASSERT_TRUE(validate());
13704 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13705 return set_host_or_hostname<true>(input);
13706 }
13707
get_origin() const13708 [[nodiscard]] std::string url_aggregator::get_origin() const noexcept {
13709 ada_log("url_aggregator::get_origin");
13710 if (is_special()) {
13711 // Return a new opaque origin.
13712 if (type == scheme::FILE) {
13713 return "null";
13714 }
13715
13716 return helpers::concat(get_protocol(), "//", get_host());
13717 }
13718
13719 if (get_protocol() == "blob:") {
13720 std::string_view path = get_pathname();
13721 if (!path.empty()) {
13722 auto out = ada::parse<ada::url_aggregator>(path);
13723 if (out && (out->type == scheme::HTTP || out->type == scheme::HTTPS)) {
13724 // If pathURL's scheme is not "http" and not "https", then return a
13725 // new opaque origin.
13726 return helpers::concat(out->get_protocol(), "//", out->get_host());
13727 }
13728 }
13729 }
13730
13731 // Return a new opaque origin.
13732 return "null";
13733 }
13734
get_username() const13735 [[nodiscard]] std::string_view url_aggregator::get_username() const noexcept {
13736 ada_log("url_aggregator::get_username");
13737 if (has_non_empty_username()) {
13738 return helpers::substring(buffer, components.protocol_end + 2,
13739 components.username_end);
13740 }
13741 return "";
13742 }
13743
get_password() const13744 [[nodiscard]] std::string_view url_aggregator::get_password() const noexcept {
13745 ada_log("url_aggregator::get_password");
13746 if (has_non_empty_password()) {
13747 return helpers::substring(buffer, components.username_end + 1,
13748 components.host_start);
13749 }
13750 return "";
13751 }
13752
get_port() const13753 [[nodiscard]] std::string_view url_aggregator::get_port() const noexcept {
13754 ada_log("url_aggregator::get_port");
13755 if (components.port == url_components::omitted) {
13756 return "";
13757 }
13758 return helpers::substring(buffer, components.host_end + 1,
13759 components.pathname_start);
13760 }
13761
get_hash() const13762 [[nodiscard]] std::string_view url_aggregator::get_hash() const noexcept {
13763 ada_log("url_aggregator::get_hash");
13764 // If this's URL's fragment is either null or the empty string, then return
13765 // the empty string. Return U+0023 (#), followed by this's URL's fragment.
13766 if (components.hash_start == url_components::omitted) {
13767 return "";
13768 }
13769 if (buffer.size() - components.hash_start <= 1) {
13770 return "";
13771 }
13772 return helpers::substring(buffer, components.hash_start);
13773 }
13774
get_host() const13775 [[nodiscard]] std::string_view url_aggregator::get_host() const noexcept {
13776 ada_log("url_aggregator::get_host");
13777 // Technically, we should check if there is a hostname, but
13778 // the code below works even if there isn't.
13779 // if(!has_hostname()) { return ""; }
13780 size_t start = components.host_start;
13781 if (components.host_end > components.host_start &&
13782 buffer[components.host_start] == '@') {
13783 start++;
13784 }
13785 // if we have an empty host, then the space between components.host_end and
13786 // components.pathname_start may be occupied by /.
13787 if (start == components.host_end) {
13788 return std::string_view();
13789 }
13790 return helpers::substring(buffer, start, components.pathname_start);
13791 }
13792
get_hostname() const13793 [[nodiscard]] std::string_view url_aggregator::get_hostname() const noexcept {
13794 ada_log("url_aggregator::get_hostname");
13795 // Technically, we should check if there is a hostname, but
13796 // the code below works even if there isn't.
13797 // if(!has_hostname()) { return ""; }
13798 size_t start = components.host_start;
13799 // So host_start is not where the host begins.
13800 if (components.host_end > components.host_start &&
13801 buffer[components.host_start] == '@') {
13802 start++;
13803 }
13804 return helpers::substring(buffer, start, components.host_end);
13805 }
13806
get_pathname() const13807 [[nodiscard]] std::string_view url_aggregator::get_pathname() const noexcept {
13808 ada_log("url_aggregator::get_pathname pathname_start = ",
13809 components.pathname_start, " buffer.size() = ", buffer.size(),
13810 " components.search_start = ", components.search_start,
13811 " components.hash_start = ", components.hash_start);
13812 uint32_t ending_index = uint32_t(buffer.size());
13813 if (components.search_start != url_components::omitted) {
13814 ending_index = components.search_start;
13815 } else if (components.hash_start != url_components::omitted) {
13816 ending_index = components.hash_start;
13817 }
13818 return helpers::substring(buffer, components.pathname_start, ending_index);
13819 }
13820
get_search() const13821 [[nodiscard]] std::string_view url_aggregator::get_search() const noexcept {
13822 ada_log("url_aggregator::get_search");
13823 // If this's URL's query is either null or the empty string, then return the
13824 // empty string. Return U+003F (?), followed by this's URL's query.
13825 if (components.search_start == url_components::omitted) {
13826 return "";
13827 }
13828 uint32_t ending_index = uint32_t(buffer.size());
13829 if (components.hash_start != url_components::omitted) {
13830 ending_index = components.hash_start;
13831 }
13832 if (ending_index - components.search_start <= 1) {
13833 return "";
13834 }
13835 return helpers::substring(buffer, components.search_start, ending_index);
13836 }
13837
get_protocol() const13838 [[nodiscard]] std::string_view url_aggregator::get_protocol() const noexcept {
13839 ada_log("url_aggregator::get_protocol");
13840 return helpers::substring(buffer, 0, components.protocol_end);
13841 }
13842
to_string() const13843 std::string ada::url_aggregator::to_string() const {
13844 ada_log("url_aggregator::to_string buffer:", buffer, "[", buffer.size(),
13845 " bytes]");
13846 if (!is_valid) {
13847 return "null";
13848 }
13849
13850 std::string answer;
13851 auto back = std::back_insert_iterator(answer);
13852 answer.append("{\n");
13853
13854 answer.append("\t\"buffer\":\"");
13855 helpers::encode_json(buffer, back);
13856 answer.append("\",\n");
13857
13858 answer.append("\t\"protocol\":\"");
13859 helpers::encode_json(get_protocol(), back);
13860 answer.append("\",\n");
13861
13862 if (has_credentials()) {
13863 answer.append("\t\"username\":\"");
13864 helpers::encode_json(get_username(), back);
13865 answer.append("\",\n");
13866 answer.append("\t\"password\":\"");
13867 helpers::encode_json(get_password(), back);
13868 answer.append("\",\n");
13869 }
13870
13871 answer.append("\t\"host\":\"");
13872 helpers::encode_json(get_host(), back);
13873 answer.append("\",\n");
13874
13875 answer.append("\t\"path\":\"");
13876 helpers::encode_json(get_pathname(), back);
13877 answer.append("\",\n");
13878 answer.append("\t\"opaque path\":");
13879 answer.append((has_opaque_path ? "true" : "false"));
13880 answer.append(",\n");
13881
13882 if (components.search_start != url_components::omitted) {
13883 answer.append("\t\"query\":\"");
13884 helpers::encode_json(get_search(), back);
13885 answer.append("\",\n");
13886 }
13887 if (components.hash_start != url_components::omitted) {
13888 answer.append("\t\"fragment\":\"");
13889 helpers::encode_json(get_hash(), back);
13890 answer.append("\",\n");
13891 }
13892
13893 auto convert_offset_to_string = [](uint32_t offset) -> std::string {
13894 if (offset == url_components::omitted) {
13895 return "null";
13896 } else {
13897 return std::to_string(offset);
13898 }
13899 };
13900
13901 answer.append("\t\"protocol_end\":");
13902 answer.append(convert_offset_to_string(components.protocol_end));
13903 answer.append(",\n");
13904
13905 answer.append("\t\"username_end\":");
13906 answer.append(convert_offset_to_string(components.username_end));
13907 answer.append(",\n");
13908
13909 answer.append("\t\"host_start\":");
13910 answer.append(convert_offset_to_string(components.host_start));
13911 answer.append(",\n");
13912
13913 answer.append("\t\"host_end\":");
13914 answer.append(convert_offset_to_string(components.host_end));
13915 answer.append(",\n");
13916
13917 answer.append("\t\"port\":");
13918 answer.append(convert_offset_to_string(components.port));
13919 answer.append(",\n");
13920
13921 answer.append("\t\"pathname_start\":");
13922 answer.append(convert_offset_to_string(components.pathname_start));
13923 answer.append(",\n");
13924
13925 answer.append("\t\"search_start\":");
13926 answer.append(convert_offset_to_string(components.search_start));
13927 answer.append(",\n");
13928
13929 answer.append("\t\"hash_start\":");
13930 answer.append(convert_offset_to_string(components.hash_start));
13931 answer.append("\n}");
13932
13933 return answer;
13934 }
13935
has_valid_domain() const13936 [[nodiscard]] bool url_aggregator::has_valid_domain() const noexcept {
13937 if (components.host_start == components.host_end) {
13938 return false;
13939 }
13940 return checkers::verify_dns_length(get_hostname());
13941 }
13942
parse_ipv4(std::string_view input)13943 bool url_aggregator::parse_ipv4(std::string_view input) {
13944 ada_log("parse_ipv4 ", input, "[", input.size(),
13945 " bytes], overlaps with buffer: ",
13946 helpers::overlaps(input, buffer) ? "yes" : "no");
13947 ADA_ASSERT_TRUE(validate());
13948 const bool trailing_dot = (input.back() == '.');
13949 if (trailing_dot) {
13950 input.remove_suffix(1);
13951 }
13952 size_t digit_count{0};
13953 int pure_decimal_count = 0; // entries that are decimal
13954 uint64_t ipv4{0};
13955 // we could unroll for better performance?
13956 for (; (digit_count < 4) && !(input.empty()); digit_count++) {
13957 uint32_t
13958 segment_result{}; // If any number exceeds 32 bits, we have an error.
13959 bool is_hex = checkers::has_hex_prefix(input);
13960 if (is_hex && ((input.length() == 2) ||
13961 ((input.length() > 2) && (input[2] == '.')))) {
13962 // special case
13963 segment_result = 0;
13964 input.remove_prefix(2);
13965 } else {
13966 std::from_chars_result r;
13967 if (is_hex) {
13968 r = std::from_chars(input.data() + 2, input.data() + input.size(),
13969 segment_result, 16);
13970 } else if ((input.length() >= 2) && input[0] == '0' &&
13971 checkers::is_digit(input[1])) {
13972 r = std::from_chars(input.data() + 1, input.data() + input.size(),
13973 segment_result, 8);
13974 } else {
13975 pure_decimal_count++;
13976 r = std::from_chars(input.data(), input.data() + input.size(),
13977 segment_result, 10);
13978 }
13979 if (r.ec != std::errc()) {
13980 return is_valid = false;
13981 }
13982 input.remove_prefix(r.ptr - input.data());
13983 }
13984 if (input.empty()) {
13985 // We have the last value.
13986 // At this stage, ipv4 contains digit_count*8 bits.
13987 // So we have 32-digit_count*8 bits left.
13988 if (segment_result > (uint64_t(1) << (32 - digit_count * 8))) {
13989 return is_valid = false;
13990 }
13991 ipv4 <<= (32 - digit_count * 8);
13992 ipv4 |= segment_result;
13993 goto final;
13994 } else {
13995 // There is more, so that the value must no be larger than 255
13996 // and we must have a '.'.
13997 if ((segment_result > 255) || (input[0] != '.')) {
13998 return is_valid = false;
13999 }
14000 ipv4 <<= 8;
14001 ipv4 |= segment_result;
14002 input.remove_prefix(1); // remove '.'
14003 }
14004 }
14005 if ((digit_count != 4) || (!input.empty())) {
14006 return is_valid = false;
14007 }
14008 final:
14009 ada_log("url_aggregator::parse_ipv4 completed ", get_href(),
14010 " host: ", get_host());
14011
14012 // We could also check r.ptr to see where the parsing ended.
14013 if (pure_decimal_count == 4 && !trailing_dot) {
14014 // The original input was already all decimal and we validated it. So we
14015 // don't need to do anything.
14016 } else {
14017 // Optimization opportunity: Get rid of unnecessary string return in ipv4
14018 // serializer.
14019 // TODO: This is likely a bug because it goes back update_base_hostname, not
14020 // what we want to do.
14021 update_base_hostname(
14022 ada::serializers::ipv4(ipv4)); // We have to reserialize the address.
14023 }
14024 ADA_ASSERT_TRUE(validate());
14025 return true;
14026 }
14027
parse_ipv6(std::string_view input)14028 bool url_aggregator::parse_ipv6(std::string_view input) {
14029 // TODO: Find a way to merge parse_ipv6 with url.cpp implementation.
14030 ada_log("parse_ipv6 ", input, "[", input.size(), " bytes]");
14031 ADA_ASSERT_TRUE(validate());
14032 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14033 if (input.empty()) {
14034 return is_valid = false;
14035 }
14036 // Let address be a new IPv6 address whose IPv6 pieces are all 0.
14037 std::array<uint16_t, 8> address{};
14038
14039 // Let pieceIndex be 0.
14040 int piece_index = 0;
14041
14042 // Let compress be null.
14043 std::optional<int> compress{};
14044
14045 // Let pointer be a pointer for input.
14046 std::string_view::iterator pointer = input.begin();
14047
14048 // If c is U+003A (:), then:
14049 if (input[0] == ':') {
14050 // If remaining does not start with U+003A (:), validation error, return
14051 // failure.
14052 if (input.size() == 1 || input[1] != ':') {
14053 ada_log("parse_ipv6 starts with : but the rest does not start with :");
14054 return is_valid = false;
14055 }
14056
14057 // Increase pointer by 2.
14058 pointer += 2;
14059
14060 // Increase pieceIndex by 1 and then set compress to pieceIndex.
14061 compress = ++piece_index;
14062 }
14063
14064 // While c is not the EOF code point:
14065 while (pointer != input.end()) {
14066 // If pieceIndex is 8, validation error, return failure.
14067 if (piece_index == 8) {
14068 ada_log("parse_ipv6 piece_index == 8");
14069 return is_valid = false;
14070 }
14071
14072 // If c is U+003A (:), then:
14073 if (*pointer == ':') {
14074 // If compress is non-null, validation error, return failure.
14075 if (compress.has_value()) {
14076 ada_log("parse_ipv6 compress is non-null");
14077 return is_valid = false;
14078 }
14079
14080 // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and
14081 // then continue.
14082 pointer++;
14083 compress = ++piece_index;
14084 continue;
14085 }
14086
14087 // Let value and length be 0.
14088 uint16_t value = 0, length = 0;
14089
14090 // While length is less than 4 and c is an ASCII hex digit,
14091 // set value to value times 0x10 + c interpreted as hexadecimal number, and
14092 // increase pointer and length by 1.
14093 while (length < 4 && pointer != input.end() &&
14094 unicode::is_ascii_hex_digit(*pointer)) {
14095 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
14096 value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));
14097 pointer++;
14098 length++;
14099 }
14100
14101 // If c is U+002E (.), then:
14102 if (pointer != input.end() && *pointer == '.') {
14103 // If length is 0, validation error, return failure.
14104 if (length == 0) {
14105 ada_log("parse_ipv6 length is 0");
14106 return is_valid = false;
14107 }
14108
14109 // Decrease pointer by length.
14110 pointer -= length;
14111
14112 // If pieceIndex is greater than 6, validation error, return failure.
14113 if (piece_index > 6) {
14114 ada_log("parse_ipv6 piece_index > 6");
14115 return is_valid = false;
14116 }
14117
14118 // Let numbersSeen be 0.
14119 int numbers_seen = 0;
14120
14121 // While c is not the EOF code point:
14122 while (pointer != input.end()) {
14123 // Let ipv4Piece be null.
14124 std::optional<uint16_t> ipv4_piece{};
14125
14126 // If numbersSeen is greater than 0, then:
14127 if (numbers_seen > 0) {
14128 // If c is a U+002E (.) and numbersSeen is less than 4, then increase
14129 // pointer by 1.
14130 if (*pointer == '.' && numbers_seen < 4) {
14131 pointer++;
14132 } else {
14133 // Otherwise, validation error, return failure.
14134 ada_log("parse_ipv6 Otherwise, validation error, return failure");
14135 return is_valid = false;
14136 }
14137 }
14138
14139 // If c is not an ASCII digit, validation error, return failure.
14140 if (pointer == input.end() || !checkers::is_digit(*pointer)) {
14141 ada_log(
14142 "parse_ipv6 If c is not an ASCII digit, validation error, return "
14143 "failure");
14144 return is_valid = false;
14145 }
14146
14147 // While c is an ASCII digit:
14148 while (pointer != input.end() && checkers::is_digit(*pointer)) {
14149 // Let number be c interpreted as decimal number.
14150 int number = *pointer - '0';
14151
14152 // If ipv4Piece is null, then set ipv4Piece to number.
14153 if (!ipv4_piece.has_value()) {
14154 ipv4_piece = number;
14155 }
14156 // Otherwise, if ipv4Piece is 0, validation error, return failure.
14157 else if (ipv4_piece == 0) {
14158 ada_log("parse_ipv6 if ipv4Piece is 0, validation error");
14159 return is_valid = false;
14160 }
14161 // Otherwise, set ipv4Piece to ipv4Piece times 10 + number.
14162 else {
14163 ipv4_piece = *ipv4_piece * 10 + number;
14164 }
14165
14166 // If ipv4Piece is greater than 255, validation error, return failure.
14167 if (ipv4_piece > 255) {
14168 ada_log("parse_ipv6 ipv4_piece > 255");
14169 return is_valid = false;
14170 }
14171
14172 // Increase pointer by 1.
14173 pointer++;
14174 }
14175
14176 // Set address[pieceIndex] to address[pieceIndex] times 0x100 +
14177 // ipv4Piece.
14178 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
14179 address[piece_index] =
14180 uint16_t(address[piece_index] * 0x100 + *ipv4_piece);
14181
14182 // Increase numbersSeen by 1.
14183 numbers_seen++;
14184
14185 // If numbersSeen is 2 or 4, then increase pieceIndex by 1.
14186 if (numbers_seen == 2 || numbers_seen == 4) {
14187 piece_index++;
14188 }
14189 }
14190
14191 // If numbersSeen is not 4, validation error, return failure.
14192 if (numbers_seen != 4) {
14193 return is_valid = false;
14194 }
14195
14196 // Break.
14197 break;
14198 }
14199 // Otherwise, if c is U+003A (:):
14200 else if ((pointer != input.end()) && (*pointer == ':')) {
14201 // Increase pointer by 1.
14202 pointer++;
14203
14204 // If c is the EOF code point, validation error, return failure.
14205 if (pointer == input.end()) {
14206 ada_log(
14207 "parse_ipv6 If c is the EOF code point, validation error, return "
14208 "failure");
14209 return is_valid = false;
14210 }
14211 }
14212 // Otherwise, if c is not the EOF code point, validation error, return
14213 // failure.
14214 else if (pointer != input.end()) {
14215 ada_log(
14216 "parse_ipv6 Otherwise, if c is not the EOF code point, validation "
14217 "error, return failure");
14218 return is_valid = false;
14219 }
14220
14221 // Set address[pieceIndex] to value.
14222 address[piece_index] = value;
14223
14224 // Increase pieceIndex by 1.
14225 piece_index++;
14226 }
14227
14228 // If compress is non-null, then:
14229 if (compress.has_value()) {
14230 // Let swaps be pieceIndex - compress.
14231 int swaps = piece_index - *compress;
14232
14233 // Set pieceIndex to 7.
14234 piece_index = 7;
14235
14236 // While pieceIndex is not 0 and swaps is greater than 0,
14237 // swap address[pieceIndex] with address[compress + swaps - 1], and then
14238 // decrease both pieceIndex and swaps by 1.
14239 while (piece_index != 0 && swaps > 0) {
14240 std::swap(address[piece_index], address[*compress + swaps - 1]);
14241 piece_index--;
14242 swaps--;
14243 }
14244 }
14245 // Otherwise, if compress is null and pieceIndex is not 8, validation error,
14246 // return failure.
14247 else if (piece_index != 8) {
14248 ada_log(
14249 "parse_ipv6 if compress is null and pieceIndex is not 8, validation "
14250 "error, return failure");
14251 return is_valid = false;
14252 }
14253 // TODO: Optimization opportunity: Get rid of unnecessary string creation.
14254 // TODO: This is likely a bug because it goes back update_base_hostname, not
14255 // what we want to do.
14256 update_base_hostname(ada::serializers::ipv6(address));
14257 ada_log("parse_ipv6 ", get_hostname());
14258 ADA_ASSERT_TRUE(validate());
14259 return true;
14260 }
14261
parse_opaque_host(std::string_view input)14262 bool url_aggregator::parse_opaque_host(std::string_view input) {
14263 ada_log("parse_opaque_host ", input, "[", input.size(), " bytes]");
14264 ADA_ASSERT_TRUE(validate());
14265 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14266 if (std::any_of(input.begin(), input.end(),
14267 ada::unicode::is_forbidden_host_code_point)) {
14268 return is_valid = false;
14269 }
14270
14271 // Return the result of running UTF-8 percent-encode on input using the C0
14272 // control percent-encode set.
14273 size_t idx = ada::unicode::percent_encode_index(
14274 input, character_sets::C0_CONTROL_PERCENT_ENCODE);
14275 if (idx == input.size()) {
14276 update_base_hostname(input);
14277 } else {
14278 // We only create a temporary string if we need to.
14279 update_base_hostname(ada::unicode::percent_encode(
14280 input, character_sets::C0_CONTROL_PERCENT_ENCODE, idx));
14281 }
14282 ADA_ASSERT_TRUE(validate());
14283 return true;
14284 }
14285
to_diagram() const14286 std::string url_aggregator::to_diagram() const {
14287 if (!is_valid) {
14288 return "invalid";
14289 }
14290 std::string answer;
14291 answer.append(buffer);
14292 answer.append(" [");
14293 answer.append(std::to_string(buffer.size()));
14294 answer.append(" bytes]");
14295 answer.append("\n");
14296 // first line
14297 std::string line1;
14298 line1.resize(buffer.size(), ' ');
14299 if (components.hash_start != url_components::omitted) {
14300 line1[components.hash_start] = '|';
14301 }
14302 if (components.search_start != url_components::omitted) {
14303 line1[components.search_start] = '|';
14304 }
14305 if (components.pathname_start != buffer.size()) {
14306 line1[components.pathname_start] = '|';
14307 }
14308 if (components.host_end != buffer.size()) {
14309 line1[components.host_end] = '|';
14310 }
14311 if (components.host_start != buffer.size()) {
14312 line1[components.host_start] = '|';
14313 }
14314 if (components.username_end != buffer.size()) {
14315 line1[components.username_end] = '|';
14316 }
14317 if (components.protocol_end != buffer.size()) {
14318 line1[components.protocol_end] = '|';
14319 }
14320 answer.append(line1);
14321 answer.append("\n");
14322
14323 std::string line2 = line1;
14324 if (components.hash_start != url_components::omitted) {
14325 line2[components.hash_start] = '`';
14326 line1[components.hash_start] = ' ';
14327
14328 for (size_t i = components.hash_start + 1; i < line2.size(); i++) {
14329 line2[i] = '-';
14330 }
14331 line2.append(" hash_start");
14332 answer.append(line2);
14333 answer.append("\n");
14334 }
14335
14336 std::string line3 = line1;
14337 if (components.search_start != url_components::omitted) {
14338 line3[components.search_start] = '`';
14339 line1[components.search_start] = ' ';
14340
14341 for (size_t i = components.search_start + 1; i < line3.size(); i++) {
14342 line3[i] = '-';
14343 }
14344 line3.append(" search_start ");
14345 line3.append(std::to_string(components.search_start));
14346 answer.append(line3);
14347 answer.append("\n");
14348 }
14349
14350 std::string line4 = line1;
14351 if (components.pathname_start != buffer.size()) {
14352 line4[components.pathname_start] = '`';
14353 line1[components.pathname_start] = ' ';
14354 for (size_t i = components.pathname_start + 1; i < line4.size(); i++) {
14355 line4[i] = '-';
14356 }
14357 line4.append(" pathname_start ");
14358 line4.append(std::to_string(components.pathname_start));
14359 answer.append(line4);
14360 answer.append("\n");
14361 }
14362
14363 std::string line5 = line1;
14364 if (components.host_end != buffer.size()) {
14365 line5[components.host_end] = '`';
14366 line1[components.host_end] = ' ';
14367
14368 for (size_t i = components.host_end + 1; i < line5.size(); i++) {
14369 line5[i] = '-';
14370 }
14371 line5.append(" host_end ");
14372 line5.append(std::to_string(components.host_end));
14373 answer.append(line5);
14374 answer.append("\n");
14375 }
14376
14377 std::string line6 = line1;
14378 if (components.host_start != buffer.size()) {
14379 line6[components.host_start] = '`';
14380 line1[components.host_start] = ' ';
14381
14382 for (size_t i = components.host_start + 1; i < line6.size(); i++) {
14383 line6[i] = '-';
14384 }
14385 line6.append(" host_start ");
14386 line6.append(std::to_string(components.host_start));
14387 answer.append(line6);
14388 answer.append("\n");
14389 }
14390
14391 std::string line7 = line1;
14392 if (components.username_end != buffer.size()) {
14393 line7[components.username_end] = '`';
14394 line1[components.username_end] = ' ';
14395
14396 for (size_t i = components.username_end + 1; i < line7.size(); i++) {
14397 line7[i] = '-';
14398 }
14399 line7.append(" username_end ");
14400 line7.append(std::to_string(components.username_end));
14401 answer.append(line7);
14402 answer.append("\n");
14403 }
14404
14405 std::string line8 = line1;
14406 if (components.protocol_end != buffer.size()) {
14407 line8[components.protocol_end] = '`';
14408 line1[components.protocol_end] = ' ';
14409
14410 for (size_t i = components.protocol_end + 1; i < line8.size(); i++) {
14411 line8[i] = '-';
14412 }
14413 line8.append(" protocol_end ");
14414 line8.append(std::to_string(components.protocol_end));
14415 answer.append(line8);
14416 answer.append("\n");
14417 }
14418
14419 if (components.hash_start == url_components::omitted) {
14420 answer.append("note: hash omitted\n");
14421 }
14422 if (components.search_start == url_components::omitted) {
14423 answer.append("note: search omitted\n");
14424 }
14425 if (components.protocol_end > buffer.size()) {
14426 answer.append("warning: protocol_end overflows\n");
14427 }
14428 if (components.username_end > buffer.size()) {
14429 answer.append("warning: username_end overflows\n");
14430 }
14431 if (components.host_start > buffer.size()) {
14432 answer.append("warning: host_start overflows\n");
14433 }
14434 if (components.host_end > buffer.size()) {
14435 answer.append("warning: host_end overflows\n");
14436 }
14437 if (components.pathname_start > buffer.size()) {
14438 answer.append("warning: pathname_start overflows\n");
14439 }
14440 return answer;
14441 }
14442
validate() const14443 bool url_aggregator::validate() const noexcept {
14444 if (!is_valid) {
14445 return true;
14446 }
14447 if (!components.check_offset_consistency()) {
14448 ada_log("url_aggregator::validate inconsistent components \n",
14449 to_diagram());
14450 return false;
14451 }
14452 // We have a credible components struct, but let us investivate more
14453 // carefully:
14454 /**
14455 * https://user:pass@example.com:1234/foo/bar?baz#quux
14456 * | | | | ^^^^| | |
14457 * | | | | | | | `----- hash_start
14458 * | | | | | | `--------- search_start
14459 * | | | | | `----------------- pathname_start
14460 * | | | | `--------------------- port
14461 * | | | `----------------------- host_end
14462 * | | `---------------------------------- host_start
14463 * | `--------------------------------------- username_end
14464 * `--------------------------------------------- protocol_end
14465 */
14466 if (components.protocol_end == url_components::omitted) {
14467 ada_log("url_aggregator::validate omitted protocol_end \n", to_diagram());
14468 return false;
14469 }
14470 if (components.username_end == url_components::omitted) {
14471 ada_log("url_aggregator::validate omitted username_end \n", to_diagram());
14472 return false;
14473 }
14474 if (components.host_start == url_components::omitted) {
14475 ada_log("url_aggregator::validate omitted host_start \n", to_diagram());
14476 return false;
14477 }
14478 if (components.host_end == url_components::omitted) {
14479 ada_log("url_aggregator::validate omitted host_end \n", to_diagram());
14480 return false;
14481 }
14482 if (components.pathname_start == url_components::omitted) {
14483 ada_log("url_aggregator::validate omitted pathname_start \n", to_diagram());
14484 return false;
14485 }
14486
14487 if (components.protocol_end > buffer.size()) {
14488 ada_log("url_aggregator::validate protocol_end overflow \n", to_diagram());
14489 return false;
14490 }
14491 if (components.username_end > buffer.size()) {
14492 ada_log("url_aggregator::validate username_end overflow \n", to_diagram());
14493 return false;
14494 }
14495 if (components.host_start > buffer.size()) {
14496 ada_log("url_aggregator::validate host_start overflow \n", to_diagram());
14497 return false;
14498 }
14499 if (components.host_end > buffer.size()) {
14500 ada_log("url_aggregator::validate host_end overflow \n", to_diagram());
14501 return false;
14502 }
14503 if (components.pathname_start > buffer.size()) {
14504 ada_log("url_aggregator::validate pathname_start overflow \n",
14505 to_diagram());
14506 return false;
14507 }
14508
14509 if (components.protocol_end > 0) {
14510 if (buffer[components.protocol_end - 1] != ':') {
14511 ada_log(
14512 "url_aggregator::validate missing : at the end of the protocol \n",
14513 to_diagram());
14514 return false;
14515 }
14516 }
14517
14518 if (components.username_end != buffer.size() &&
14519 components.username_end > components.protocol_end + 2) {
14520 if (buffer[components.username_end] != ':' &&
14521 buffer[components.username_end] != '@') {
14522 ada_log(
14523 "url_aggregator::validate missing : or @ at the end of the username "
14524 "\n",
14525 to_diagram());
14526 return false;
14527 }
14528 }
14529
14530 if (components.host_start != buffer.size()) {
14531 if (components.host_start > components.username_end) {
14532 if (buffer[components.host_start] != '@') {
14533 ada_log(
14534 "url_aggregator::validate missing @ at the end of the password \n",
14535 to_diagram());
14536 return false;
14537 }
14538 } else if (components.host_start == components.username_end &&
14539 components.host_end > components.host_start) {
14540 if (components.host_start == components.protocol_end + 2) {
14541 if (buffer[components.protocol_end] != '/' ||
14542 buffer[components.protocol_end + 1] != '/') {
14543 ada_log(
14544 "url_aggregator::validate missing // between protocol and host "
14545 "\n",
14546 to_diagram());
14547 return false;
14548 }
14549 } else {
14550 if (components.host_start > components.protocol_end &&
14551 buffer[components.host_start] != '@') {
14552 ada_log(
14553 "url_aggregator::validate missing @ at the end of the username "
14554 "\n",
14555 to_diagram());
14556 return false;
14557 }
14558 }
14559 } else {
14560 if (components.host_end != components.host_start) {
14561 ada_log("url_aggregator::validate expected omitted host \n",
14562 to_diagram());
14563 return false;
14564 }
14565 }
14566 }
14567 if (components.host_end != buffer.size() &&
14568 components.pathname_start > components.host_end) {
14569 if (components.pathname_start == components.host_end + 2 &&
14570 buffer[components.host_end] == '/' &&
14571 buffer[components.host_end + 1] == '.') {
14572 if (components.pathname_start + 1 >= buffer.size() ||
14573 buffer[components.pathname_start] != '/' ||
14574 buffer[components.pathname_start + 1] != '/') {
14575 ada_log(
14576 "url_aggregator::validate expected the path to begin with // \n",
14577 to_diagram());
14578 return false;
14579 }
14580 } else if (buffer[components.host_end] != ':') {
14581 ada_log("url_aggregator::validate missing : at the port \n",
14582 to_diagram());
14583 return false;
14584 }
14585 }
14586 if (components.pathname_start != buffer.size() &&
14587 components.pathname_start < components.search_start &&
14588 components.pathname_start < components.hash_start && !has_opaque_path) {
14589 if (buffer[components.pathname_start] != '/') {
14590 ada_log("url_aggregator::validate missing / at the path \n",
14591 to_diagram());
14592 return false;
14593 }
14594 }
14595 if (components.search_start != url_components::omitted) {
14596 if (buffer[components.search_start] != '?') {
14597 ada_log("url_aggregator::validate missing ? at the search \n",
14598 to_diagram());
14599 return false;
14600 }
14601 }
14602 if (components.hash_start != url_components::omitted) {
14603 if (buffer[components.hash_start] != '#') {
14604 ada_log("url_aggregator::validate missing # at the hash \n",
14605 to_diagram());
14606 return false;
14607 }
14608 }
14609
14610 return true;
14611 }
14612
delete_dash_dot()14613 void url_aggregator::delete_dash_dot() {
14614 ada_log("url_aggregator::delete_dash_dot");
14615 ADA_ASSERT_TRUE(validate());
14616 ADA_ASSERT_TRUE(has_dash_dot());
14617 buffer.erase(components.host_end, 2);
14618 components.pathname_start -= 2;
14619 if (components.search_start != url_components::omitted) {
14620 components.search_start -= 2;
14621 }
14622 if (components.hash_start != url_components::omitted) {
14623 components.hash_start -= 2;
14624 }
14625 ADA_ASSERT_TRUE(validate());
14626 ADA_ASSERT_TRUE(!has_dash_dot());
14627 }
14628
consume_prepared_path(std::string_view input)14629 inline void url_aggregator::consume_prepared_path(std::string_view input) {
14630 ada_log("url_aggregator::consume_prepared_path ", input);
14631 /***
14632 * This is largely duplicated code from helpers::parse_prepared_path, which is
14633 * unfortunate. This particular function is nearly identical, except that it
14634 * is a method on url_aggregator. The idea is that the trivial path (which is
14635 * very common) merely appends to the buffer. This is the same trivial path as
14636 * with helpers::parse_prepared_path, except that we have the additional check
14637 * for is_at_path(). Otherwise, we grab a copy of the current path and we
14638 * modify it, and then insert it back into the buffer.
14639 */
14640 uint8_t accumulator = checkers::path_signature(input);
14641 // Let us first detect a trivial case.
14642 // If it is special, we check that we have no dot, no %, no \ and no
14643 // character needing percent encoding. Otherwise, we check that we have no %,
14644 // no dot, and no character needing percent encoding.
14645 constexpr uint8_t need_encoding = 1;
14646 constexpr uint8_t backslash_char = 2;
14647 constexpr uint8_t dot_char = 4;
14648 constexpr uint8_t percent_char = 8;
14649 bool special = type != ada::scheme::NOT_SPECIAL;
14650 bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
14651 checkers::is_windows_drive_letter(input));
14652 bool trivial_path =
14653 (special ? (accumulator == 0)
14654 : ((accumulator & (need_encoding | dot_char | percent_char)) ==
14655 0)) &&
14656 (!may_need_slow_file_handling);
14657 if (accumulator == dot_char && !may_need_slow_file_handling) {
14658 // '4' means that we have at least one dot, but nothing that requires
14659 // percent encoding or decoding. The only part that is not trivial is
14660 // that we may have single dots and double dots path segments.
14661 // If we have such segments, then we either have a path that begins
14662 // with '.' (easy to check), or we have the sequence './'.
14663 // Note: input cannot be empty, it must at least contain one character ('.')
14664 // Note: we know that '\' is not present.
14665 if (input[0] != '.') {
14666 size_t slashdot = input.find("/.");
14667 if (slashdot == std::string_view::npos) { // common case
14668 trivial_path = true;
14669 } else { // uncommon
14670 // only three cases matter: /./, /.. or a final /
14671 trivial_path =
14672 !(slashdot + 2 == input.size() || input[slashdot + 2] == '.' ||
14673 input[slashdot + 2] == '/');
14674 }
14675 }
14676 }
14677 if (trivial_path && is_at_path()) {
14678 ada_log("parse_path trivial");
14679 buffer += '/';
14680 buffer += input;
14681 return;
14682 }
14683 std::string path = std::string(get_pathname());
14684 // We are going to need to look a bit at the path, but let us see if we can
14685 // ignore percent encoding *and* backslashes *and* percent characters.
14686 // Except for the trivial case, this is likely to capture 99% of paths out
14687 // there.
14688 bool fast_path =
14689 (special &&
14690 (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
14691 (type != ada::scheme::type::FILE);
14692 if (fast_path) {
14693 ada_log("parse_prepared_path fast");
14694 // Here we don't need to worry about \ or percent encoding.
14695 // We also do not have a file protocol. We might have dots, however,
14696 // but dots must as appear as '.', and they cannot be encoded because
14697 // the symbol '%' is not present.
14698 size_t previous_location = 0; // We start at 0.
14699 do {
14700 size_t new_location = input.find('/', previous_location);
14701 // std::string_view path_view = input;
14702 // We process the last segment separately:
14703 if (new_location == std::string_view::npos) {
14704 std::string_view path_view = input.substr(previous_location);
14705 if (path_view == "..") { // The path ends with ..
14706 // e.g., if you receive ".." with an empty path, you go to "/".
14707 if (path.empty()) {
14708 path = '/';
14709 update_base_pathname(path);
14710 return;
14711 }
14712 // Fast case where we have nothing to do:
14713 if (path.back() == '/') {
14714 update_base_pathname(path);
14715 return;
14716 }
14717 // If you have the path "/joe/myfriend",
14718 // then you delete 'myfriend'.
14719 path.resize(path.rfind('/') + 1);
14720 update_base_pathname(path);
14721 return;
14722 }
14723 path += '/';
14724 if (path_view != ".") {
14725 path.append(path_view);
14726 }
14727 update_base_pathname(path);
14728 return;
14729 } else {
14730 // This is a non-final segment.
14731 std::string_view path_view =
14732 input.substr(previous_location, new_location - previous_location);
14733 previous_location = new_location + 1;
14734 if (path_view == "..") {
14735 size_t last_delimiter = path.rfind('/');
14736 if (last_delimiter != std::string::npos) {
14737 path.erase(last_delimiter);
14738 }
14739 } else if (path_view != ".") {
14740 path += '/';
14741 path.append(path_view);
14742 }
14743 }
14744 } while (true);
14745 } else {
14746 ada_log("parse_path slow");
14747 // we have reached the general case
14748 bool needs_percent_encoding = (accumulator & 1);
14749 std::string path_buffer_tmp;
14750 do {
14751 size_t location = (special && (accumulator & 2))
14752 ? input.find_first_of("/\\")
14753 : input.find('/');
14754 std::string_view path_view = input;
14755 if (location != std::string_view::npos) {
14756 path_view.remove_suffix(path_view.size() - location);
14757 input.remove_prefix(location + 1);
14758 }
14759 // path_buffer is either path_view or it might point at a percent encoded
14760 // temporary string.
14761 std::string_view path_buffer =
14762 (needs_percent_encoding &&
14763 ada::unicode::percent_encode<false>(
14764 path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
14765 ? path_buffer_tmp
14766 : path_view;
14767 if (unicode::is_double_dot_path_segment(path_buffer)) {
14768 if ((helpers::shorten_path(path, type) || special) &&
14769 location == std::string_view::npos) {
14770 path += '/';
14771 }
14772 } else if (unicode::is_single_dot_path_segment(path_buffer) &&
14773 (location == std::string_view::npos)) {
14774 path += '/';
14775 }
14776 // Otherwise, if path_buffer is not a single-dot path segment, then:
14777 else if (!unicode::is_single_dot_path_segment(path_buffer)) {
14778 // If url's scheme is "file", url's path is empty, and path_buffer is a
14779 // Windows drive letter, then replace the second code point in
14780 // path_buffer with U+003A (:).
14781 if (type == ada::scheme::type::FILE && path.empty() &&
14782 checkers::is_windows_drive_letter(path_buffer)) {
14783 path += '/';
14784 path += path_buffer[0];
14785 path += ':';
14786 path_buffer.remove_prefix(2);
14787 path.append(path_buffer);
14788 } else {
14789 // Append path_buffer to url's path.
14790 path += '/';
14791 path.append(path_buffer);
14792 }
14793 }
14794 if (location == std::string_view::npos) {
14795 update_base_pathname(path);
14796 return;
14797 }
14798 } while (true);
14799 }
14800 }
14801 } // namespace ada
14802 /* end file src/url_aggregator.cpp */
14803 /* begin file src/ada_c.cpp */
14804
get_instance(void * result)14805 ada::result<ada::url_aggregator>& get_instance(void* result) noexcept {
14806 return *(ada::result<ada::url_aggregator>*)result;
14807 }
14808
14809 extern "C" {
14810 typedef void* ada_url;
14811
14812 struct ada_string {
14813 const char* data;
14814 size_t length;
14815 };
14816
14817 struct ada_owned_string {
14818 const char* data;
14819 size_t length;
14820 };
14821
ada_string_create(const char * data,size_t length)14822 ada_string ada_string_create(const char* data, size_t length) {
14823 ada_string out{};
14824 out.data = data;
14825 out.length = length;
14826 return out;
14827 }
14828
14829 struct ada_url_components {
14830 /*
14831 * By using 32-bit integers, we implicitly assume that the URL string
14832 * cannot exceed 4 GB.
14833 *
14834 * https://user:pass@example.com:1234/foo/bar?baz#quux
14835 * | | | | ^^^^| | |
14836 * | | | | | | | `----- hash_start
14837 * | | | | | | `--------- search_start
14838 * | | | | | `----------------- pathname_start
14839 * | | | | `--------------------- port
14840 * | | | `----------------------- host_end
14841 * | | `---------------------------------- host_start
14842 * | `--------------------------------------- username_end
14843 * `--------------------------------------------- protocol_end
14844 */
14845 uint32_t protocol_end;
14846 /**
14847 * Username end is not `omitted` by default (-1) to make username and password
14848 * getters less costly to implement.
14849 */
14850 uint32_t username_end;
14851 uint32_t host_start;
14852 uint32_t host_end;
14853 uint32_t port;
14854 uint32_t pathname_start;
14855 uint32_t search_start;
14856 uint32_t hash_start;
14857 };
14858
ada_parse(const char * input,size_t length)14859 ada_url ada_parse(const char* input, size_t length) noexcept {
14860 return new ada::result<ada::url_aggregator>(
14861 ada::parse<ada::url_aggregator>(std::string_view(input, length)));
14862 }
14863
ada_parse_with_base(const char * input,size_t input_length,const char * base,size_t base_length)14864 ada_url ada_parse_with_base(const char* input, size_t input_length,
14865 const char* base, size_t base_length) noexcept {
14866 auto base_out =
14867 ada::parse<ada::url_aggregator>(std::string_view(base, base_length));
14868
14869 if (!base_out) {
14870 return new ada::result<ada::url_aggregator>(base_out);
14871 }
14872
14873 return new ada::result<ada::url_aggregator>(ada::parse<ada::url_aggregator>(
14874 std::string_view(input, input_length), &base_out.value()));
14875 }
14876
ada_can_parse(const char * input,size_t length)14877 bool ada_can_parse(const char* input, size_t length) noexcept {
14878 return ada::can_parse(std::string_view(input, length));
14879 }
14880
ada_can_parse_with_base(const char * input,size_t input_length,const char * base,size_t base_length)14881 bool ada_can_parse_with_base(const char* input, size_t input_length,
14882 const char* base, size_t base_length) noexcept {
14883 auto base_view = std::string_view(base, base_length);
14884 return ada::can_parse(std::string_view(input, input_length), &base_view);
14885 }
14886
ada_free(ada_url result)14887 void ada_free(ada_url result) noexcept {
14888 ada::result<ada::url_aggregator>* r =
14889 (ada::result<ada::url_aggregator>*)result;
14890 delete r;
14891 }
14892
ada_is_valid(ada_url result)14893 bool ada_is_valid(ada_url result) noexcept {
14894 ada::result<ada::url_aggregator>& r = get_instance(result);
14895 return r.has_value();
14896 }
14897
14898 // caller must free the result with ada_free_owned_string
ada_get_origin(ada_url result)14899 ada_owned_string ada_get_origin(ada_url result) noexcept {
14900 ada::result<ada::url_aggregator>& r = get_instance(result);
14901 ada_owned_string owned;
14902 if (!r) {
14903 owned.data = nullptr;
14904 owned.length = 0;
14905 return owned;
14906 }
14907 std::string out = r->get_origin();
14908 owned.length = out.size();
14909 owned.data = new char[owned.length];
14910 memcpy((void*)owned.data, out.data(), owned.length);
14911 return owned;
14912 }
14913
ada_free_owned_string(ada_owned_string owned)14914 void ada_free_owned_string(ada_owned_string owned) noexcept {
14915 delete[] owned.data;
14916 owned.data = nullptr;
14917 owned.length = 0;
14918 }
14919
ada_get_href(ada_url result)14920 ada_string ada_get_href(ada_url result) noexcept {
14921 ada::result<ada::url_aggregator>& r = get_instance(result);
14922 if (!r) {
14923 return ada_string_create(NULL, 0);
14924 }
14925 std::string_view out = r->get_href();
14926 return ada_string_create(out.data(), out.length());
14927 }
14928
ada_get_username(ada_url result)14929 ada_string ada_get_username(ada_url result) noexcept {
14930 ada::result<ada::url_aggregator>& r = get_instance(result);
14931 if (!r) {
14932 return ada_string_create(NULL, 0);
14933 }
14934 std::string_view out = r->get_username();
14935 return ada_string_create(out.data(), out.length());
14936 }
14937
ada_get_password(ada_url result)14938 ada_string ada_get_password(ada_url result) noexcept {
14939 ada::result<ada::url_aggregator>& r = get_instance(result);
14940 if (!r) {
14941 return ada_string_create(NULL, 0);
14942 }
14943 std::string_view out = r->get_password();
14944 return ada_string_create(out.data(), out.length());
14945 }
14946
ada_get_port(ada_url result)14947 ada_string ada_get_port(ada_url result) noexcept {
14948 ada::result<ada::url_aggregator>& r = get_instance(result);
14949 if (!r) {
14950 return ada_string_create(NULL, 0);
14951 }
14952 std::string_view out = r->get_port();
14953 return ada_string_create(out.data(), out.length());
14954 }
14955
ada_get_hash(ada_url result)14956 ada_string ada_get_hash(ada_url result) noexcept {
14957 ada::result<ada::url_aggregator>& r = get_instance(result);
14958 if (!r) {
14959 return ada_string_create(NULL, 0);
14960 }
14961 std::string_view out = r->get_hash();
14962 return ada_string_create(out.data(), out.length());
14963 }
14964
ada_get_host(ada_url result)14965 ada_string ada_get_host(ada_url result) noexcept {
14966 ada::result<ada::url_aggregator>& r = get_instance(result);
14967 if (!r) {
14968 return ada_string_create(NULL, 0);
14969 }
14970 std::string_view out = r->get_host();
14971 return ada_string_create(out.data(), out.length());
14972 }
14973
ada_get_hostname(ada_url result)14974 ada_string ada_get_hostname(ada_url result) noexcept {
14975 ada::result<ada::url_aggregator>& r = get_instance(result);
14976 if (!r) {
14977 return ada_string_create(NULL, 0);
14978 }
14979 std::string_view out = r->get_hostname();
14980 return ada_string_create(out.data(), out.length());
14981 }
14982
ada_get_pathname(ada_url result)14983 ada_string ada_get_pathname(ada_url result) noexcept {
14984 ada::result<ada::url_aggregator>& r = get_instance(result);
14985 if (!r) {
14986 return ada_string_create(NULL, 0);
14987 }
14988 std::string_view out = r->get_pathname();
14989 return ada_string_create(out.data(), out.length());
14990 }
14991
ada_get_search(ada_url result)14992 ada_string ada_get_search(ada_url result) noexcept {
14993 ada::result<ada::url_aggregator>& r = get_instance(result);
14994 if (!r) {
14995 return ada_string_create(NULL, 0);
14996 }
14997 std::string_view out = r->get_search();
14998 return ada_string_create(out.data(), out.length());
14999 }
15000
ada_get_protocol(ada_url result)15001 ada_string ada_get_protocol(ada_url result) noexcept {
15002 ada::result<ada::url_aggregator>& r = get_instance(result);
15003 if (!r) {
15004 return ada_string_create(NULL, 0);
15005 }
15006 std::string_view out = r->get_protocol();
15007 return ada_string_create(out.data(), out.length());
15008 }
15009
ada_set_href(ada_url result,const char * input,size_t length)15010 bool ada_set_href(ada_url result, const char* input, size_t length) noexcept {
15011 ada::result<ada::url_aggregator>& r = get_instance(result);
15012 if (!r) {
15013 return false;
15014 }
15015 return r->set_href(std::string_view(input, length));
15016 }
15017
ada_set_host(ada_url result,const char * input,size_t length)15018 bool ada_set_host(ada_url result, const char* input, size_t length) noexcept {
15019 ada::result<ada::url_aggregator>& r = get_instance(result);
15020 if (!r) {
15021 return false;
15022 }
15023 return r->set_host(std::string_view(input, length));
15024 }
15025
ada_set_hostname(ada_url result,const char * input,size_t length)15026 bool ada_set_hostname(ada_url result, const char* input,
15027 size_t length) noexcept {
15028 ada::result<ada::url_aggregator>& r = get_instance(result);
15029 if (!r) {
15030 return false;
15031 }
15032 return r->set_hostname(std::string_view(input, length));
15033 }
15034
ada_set_protocol(ada_url result,const char * input,size_t length)15035 bool ada_set_protocol(ada_url result, const char* input,
15036 size_t length) noexcept {
15037 ada::result<ada::url_aggregator>& r = get_instance(result);
15038 if (!r) {
15039 return false;
15040 }
15041 return r->set_protocol(std::string_view(input, length));
15042 }
15043
ada_set_username(ada_url result,const char * input,size_t length)15044 bool ada_set_username(ada_url result, const char* input,
15045 size_t length) noexcept {
15046 ada::result<ada::url_aggregator>& r = get_instance(result);
15047 if (!r) {
15048 return false;
15049 }
15050 return r->set_username(std::string_view(input, length));
15051 }
15052
ada_set_password(ada_url result,const char * input,size_t length)15053 bool ada_set_password(ada_url result, const char* input,
15054 size_t length) noexcept {
15055 ada::result<ada::url_aggregator>& r = get_instance(result);
15056 if (!r) {
15057 return false;
15058 }
15059 return r->set_password(std::string_view(input, length));
15060 }
15061
ada_set_port(ada_url result,const char * input,size_t length)15062 bool ada_set_port(ada_url result, const char* input, size_t length) noexcept {
15063 ada::result<ada::url_aggregator>& r = get_instance(result);
15064 if (!r) {
15065 return false;
15066 }
15067 return r->set_port(std::string_view(input, length));
15068 }
15069
ada_set_pathname(ada_url result,const char * input,size_t length)15070 bool ada_set_pathname(ada_url result, const char* input,
15071 size_t length) noexcept {
15072 ada::result<ada::url_aggregator>& r = get_instance(result);
15073 if (!r) {
15074 return false;
15075 }
15076 return r->set_pathname(std::string_view(input, length));
15077 }
15078
ada_set_search(ada_url result,const char * input,size_t length)15079 void ada_set_search(ada_url result, const char* input, size_t length) noexcept {
15080 ada::result<ada::url_aggregator>& r = get_instance(result);
15081 if (r) {
15082 r->set_search(std::string_view(input, length));
15083 }
15084 }
15085
ada_set_hash(ada_url result,const char * input,size_t length)15086 void ada_set_hash(ada_url result, const char* input, size_t length) noexcept {
15087 ada::result<ada::url_aggregator>& r = get_instance(result);
15088 if (r) {
15089 r->set_hash(std::string_view(input, length));
15090 }
15091 }
15092
ada_has_credentials(ada_url result)15093 bool ada_has_credentials(ada_url result) noexcept {
15094 ada::result<ada::url_aggregator>& r = get_instance(result);
15095 if (!r) {
15096 return false;
15097 }
15098 return r->has_credentials();
15099 }
15100
ada_has_empty_hostname(ada_url result)15101 bool ada_has_empty_hostname(ada_url result) noexcept {
15102 ada::result<ada::url_aggregator>& r = get_instance(result);
15103 if (!r) {
15104 return false;
15105 }
15106 return r->has_empty_hostname();
15107 }
15108
ada_has_hostname(ada_url result)15109 bool ada_has_hostname(ada_url result) noexcept {
15110 ada::result<ada::url_aggregator>& r = get_instance(result);
15111 if (!r) {
15112 return false;
15113 }
15114 return r->has_hostname();
15115 }
15116
ada_has_non_empty_username(ada_url result)15117 bool ada_has_non_empty_username(ada_url result) noexcept {
15118 ada::result<ada::url_aggregator>& r = get_instance(result);
15119 if (!r) {
15120 return false;
15121 }
15122 return r->has_non_empty_username();
15123 }
15124
ada_has_non_empty_password(ada_url result)15125 bool ada_has_non_empty_password(ada_url result) noexcept {
15126 ada::result<ada::url_aggregator>& r = get_instance(result);
15127 if (!r) {
15128 return false;
15129 }
15130 return r->has_non_empty_password();
15131 }
15132
ada_has_port(ada_url result)15133 bool ada_has_port(ada_url result) noexcept {
15134 ada::result<ada::url_aggregator>& r = get_instance(result);
15135 if (!r) {
15136 return false;
15137 }
15138 return r->has_port();
15139 }
15140
ada_has_password(ada_url result)15141 bool ada_has_password(ada_url result) noexcept {
15142 ada::result<ada::url_aggregator>& r = get_instance(result);
15143 if (!r) {
15144 return false;
15145 }
15146 return r->has_password();
15147 }
15148
ada_has_hash(ada_url result)15149 bool ada_has_hash(ada_url result) noexcept {
15150 ada::result<ada::url_aggregator>& r = get_instance(result);
15151 if (!r) {
15152 return false;
15153 }
15154 return r->has_hash();
15155 }
15156
ada_has_search(ada_url result)15157 bool ada_has_search(ada_url result) noexcept {
15158 ada::result<ada::url_aggregator>& r = get_instance(result);
15159 if (!r) {
15160 return false;
15161 }
15162 return r->has_search();
15163 }
15164
15165 // returns a pointer to the internal url_aggregator::url_components
ada_get_components(ada_url result)15166 const ada_url_components* ada_get_components(ada_url result) noexcept {
15167 static_assert(sizeof(ada_url_components) == sizeof(ada::url_components));
15168 ada::result<ada::url_aggregator>& r = get_instance(result);
15169 if (!r) {
15170 return nullptr;
15171 }
15172 return reinterpret_cast<const ada_url_components*>(&r->get_components());
15173 }
15174
ada_idna_to_unicode(const char * input,size_t length)15175 ada_owned_string ada_idna_to_unicode(const char* input, size_t length) {
15176 std::string out = ada::idna::to_unicode(std::string_view(input, length));
15177 ada_owned_string owned{};
15178 owned.length = out.length();
15179 owned.data = new char[owned.length];
15180 memcpy((void*)owned.data, out.data(), owned.length);
15181 return owned;
15182 }
15183
ada_idna_to_ascii(const char * input,size_t length)15184 ada_owned_string ada_idna_to_ascii(const char* input, size_t length) {
15185 std::string out = ada::idna::to_ascii(std::string_view(input, length));
15186 ada_owned_string owned{};
15187 owned.length = out.size();
15188 owned.data = new char[owned.length];
15189 memcpy((void*)owned.data, out.data(), owned.length);
15190 return owned;
15191 }
15192
15193 } // extern "C"
15194 /* end file src/ada_c.cpp */
15195 /* end file src/ada.cpp */
15196