1 /* auto-generated on 2024-01-29 13:13:24 -0500. 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 // The string is not empty and does not contain upper case ASCII characters.
11 //
12 // Optimization. To be considered as a possible ipv4, the string must end
13 // with 'x' or a lowercase hex character.
14 // Most of the time, this will be false so this simple check will save a lot
15 // of effort.
16 char last_char = view.back();
17 // If the address ends with a dot, we need to prune it (special case).
18 if (last_char == '.') {
19 view.remove_suffix(1);
20 if (view.empty()) {
21 return false;
22 }
23 last_char = view.back();
24 }
25 bool possible_ipv4 = (last_char >= '0' && last_char <= '9') ||
26 (last_char >= 'a' && last_char <= 'f') ||
27 last_char == 'x';
28 if (!possible_ipv4) {
29 return false;
30 }
31 // From the last character, find the last dot.
32 size_t last_dot = view.rfind('.');
33 if (last_dot != std::string_view::npos) {
34 // We have at least one dot.
35 view = view.substr(last_dot + 1);
36 }
37 /** Optimization opportunity: we have basically identified the last number of
38 the ipv4 if we return true here. We might as well parse it and have at
39 least one number parsed when we get to parse_ipv4. */
40 if (std::all_of(view.begin(), view.end(), ada::checkers::is_digit)) {
41 return true;
42 }
43 // It could be hex (0x), but not if there is a single character.
44 if (view.size() == 1) {
45 return false;
46 }
47 // It must start with 0x.
48 if (!std::equal(view.begin(), view.begin() + 2, "0x")) {
49 return false;
50 }
51 // We must allow "0x".
52 if (view.size() == 2) {
53 return true;
54 }
55 // We have 0x followed by some characters, we need to check that they are
56 // hexadecimals.
57 return std::all_of(view.begin() + 2, view.end(),
58 ada::unicode::is_lowercase_hex);
59 }
60
61 // for use with path_signature, we include all characters that need percent
62 // encoding.
63 static constexpr std::array<uint8_t, 256> path_signature_table =
__anon4ddc785e0102() 64 []() constexpr {
65 std::array<uint8_t, 256> result{};
66 for (size_t i = 0; i < 256; i++) {
67 if (i <= 0x20 || i == 0x22 || i == 0x23 || i == 0x3c || i == 0x3e ||
68 i == 0x3f || i == 0x60 || i == 0x7b || i == 0x7b || i == 0x7d ||
69 i > 0x7e) {
70 result[i] = 1;
71 } else if (i == 0x25) {
72 result[i] = 8;
73 } else if (i == 0x2e) {
74 result[i] = 4;
75 } else if (i == 0x5c) {
76 result[i] = 2;
77 } else {
78 result[i] = 0;
79 }
80 }
81 return result;
82 }();
83
path_signature(std::string_view input)84 ada_really_inline constexpr uint8_t path_signature(
85 std::string_view input) noexcept {
86 // The path percent-encode set is the query percent-encode set and U+003F (?),
87 // U+0060 (`), U+007B ({), and U+007D (}). The query percent-encode set is the
88 // C0 control percent-encode set and U+0020 SPACE, U+0022 ("), U+0023 (#),
89 // U+003C (<), and U+003E (>). The C0 control percent-encode set are the C0
90 // controls and all code points greater than U+007E (~).
91 size_t i = 0;
92 uint8_t accumulator{};
93 for (; i + 7 < input.size(); i += 8) {
94 accumulator |= uint8_t(path_signature_table[uint8_t(input[i])] |
95 path_signature_table[uint8_t(input[i + 1])] |
96 path_signature_table[uint8_t(input[i + 2])] |
97 path_signature_table[uint8_t(input[i + 3])] |
98 path_signature_table[uint8_t(input[i + 4])] |
99 path_signature_table[uint8_t(input[i + 5])] |
100 path_signature_table[uint8_t(input[i + 6])] |
101 path_signature_table[uint8_t(input[i + 7])]);
102 }
103 for (; i < input.size(); i++) {
104 accumulator |= uint8_t(path_signature_table[uint8_t(input[i])]);
105 }
106 return accumulator;
107 }
108
verify_dns_length(std::string_view input)109 ada_really_inline constexpr bool verify_dns_length(
110 std::string_view input) noexcept {
111 if (input.back() == '.') {
112 if (input.size() > 254) return false;
113 } else if (input.size() > 253)
114 return false;
115
116 size_t start = 0;
117 while (start < input.size()) {
118 auto dot_location = input.find('.', start);
119 // If not found, it's likely the end of the domain
120 if (dot_location == std::string_view::npos) dot_location = input.size();
121
122 auto label_size = dot_location - start;
123 if (label_size > 63 || label_size == 0) return false;
124
125 start = dot_location + 1;
126 }
127
128 return true;
129 }
130 } // namespace ada::checkers
131 /* end file src/checkers.cpp */
132 /* begin file src/unicode.cpp */
133
134 ADA_PUSH_DISABLE_ALL_WARNINGS
135 /* begin file src/ada_idna.cpp */
136 /* auto-generated on 2023-09-19 15:58:51 -0400. Do not edit! */
137 /* begin file src/idna.cpp */
138 /* begin file src/unicode_transcoding.cpp */
139
140 #include <algorithm>
141 #include <cstdint>
142 #include <cstring>
143
144 namespace ada::idna {
145
utf8_to_utf32(const char * buf,size_t len,char32_t * utf32_output)146 size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output) {
147 const uint8_t* data = reinterpret_cast<const uint8_t*>(buf);
148 size_t pos = 0;
149 char32_t* start{utf32_output};
150 while (pos < len) {
151 // try to convert the next block of 16 ASCII bytes
152 if (pos + 16 <= len) { // if it is safe to read 16 more
153 // bytes, check that they are ascii
154 uint64_t v1;
155 std::memcpy(&v1, data + pos, sizeof(uint64_t));
156 uint64_t v2;
157 std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
158 uint64_t v{v1 | v2};
159 if ((v & 0x8080808080808080) == 0) {
160 size_t final_pos = pos + 16;
161 while (pos < final_pos) {
162 *utf32_output++ = char32_t(buf[pos]);
163 pos++;
164 }
165 continue;
166 }
167 }
168 uint8_t leading_byte = data[pos]; // leading byte
169 if (leading_byte < 0b10000000) {
170 // converting one ASCII byte !!!
171 *utf32_output++ = char32_t(leading_byte);
172 pos++;
173 } else if ((leading_byte & 0b11100000) == 0b11000000) {
174 // We have a two-byte UTF-8
175 if (pos + 1 >= len) {
176 return 0;
177 } // minimal bound checking
178 if ((data[pos + 1] & 0b11000000) != 0b10000000) {
179 return 0;
180 }
181 // range check
182 uint32_t code_point =
183 (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111);
184 if (code_point < 0x80 || 0x7ff < code_point) {
185 return 0;
186 }
187 *utf32_output++ = char32_t(code_point);
188 pos += 2;
189 } else if ((leading_byte & 0b11110000) == 0b11100000) {
190 // We have a three-byte UTF-8
191 if (pos + 2 >= len) {
192 return 0;
193 } // minimal bound checking
194
195 if ((data[pos + 1] & 0b11000000) != 0b10000000) {
196 return 0;
197 }
198 if ((data[pos + 2] & 0b11000000) != 0b10000000) {
199 return 0;
200 }
201 // range check
202 uint32_t code_point = (leading_byte & 0b00001111) << 12 |
203 (data[pos + 1] & 0b00111111) << 6 |
204 (data[pos + 2] & 0b00111111);
205 if (code_point < 0x800 || 0xffff < code_point ||
206 (0xd7ff < code_point && code_point < 0xe000)) {
207 return 0;
208 }
209 *utf32_output++ = char32_t(code_point);
210 pos += 3;
211 } else if ((leading_byte & 0b11111000) == 0b11110000) { // 0b11110000
212 // we have a 4-byte UTF-8 word.
213 if (pos + 3 >= len) {
214 return 0;
215 } // minimal bound checking
216 if ((data[pos + 1] & 0b11000000) != 0b10000000) {
217 return 0;
218 }
219 if ((data[pos + 2] & 0b11000000) != 0b10000000) {
220 return 0;
221 }
222 if ((data[pos + 3] & 0b11000000) != 0b10000000) {
223 return 0;
224 }
225
226 // range check
227 uint32_t code_point = (leading_byte & 0b00000111) << 18 |
228 (data[pos + 1] & 0b00111111) << 12 |
229 (data[pos + 2] & 0b00111111) << 6 |
230 (data[pos + 3] & 0b00111111);
231 if (code_point <= 0xffff || 0x10ffff < code_point) {
232 return 0;
233 }
234 *utf32_output++ = char32_t(code_point);
235 pos += 4;
236 } else {
237 return 0;
238 }
239 }
240 return utf32_output - start;
241 }
242
utf8_length_from_utf32(const char32_t * buf,size_t len)243 size_t utf8_length_from_utf32(const char32_t* buf, size_t len) {
244 // We are not BOM aware.
245 const uint32_t* p = reinterpret_cast<const uint32_t*>(buf);
246 size_t counter{0};
247 for (size_t i = 0; i != len; ++i) {
248 ++counter; // ASCII
249 counter += static_cast<size_t>(p[i] > 0x7F); // two-byte
250 counter += static_cast<size_t>(p[i] > 0x7FF); // three-byte
251 counter += static_cast<size_t>(p[i] > 0xFFFF); // four-bytes
252 }
253 return counter;
254 }
255
utf32_length_from_utf8(const char * buf,size_t len)256 size_t utf32_length_from_utf8(const char* buf, size_t len) {
257 const int8_t* p = reinterpret_cast<const int8_t*>(buf);
258 return std::count_if(p, std::next(p, len), [](int8_t c) {
259 // -65 is 0b10111111, anything larger in two-complement's
260 // should start a new code point.
261 return c > -65;
262 });
263 }
264
utf32_to_utf8(const char32_t * buf,size_t len,char * utf8_output)265 size_t utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) {
266 const uint32_t* data = reinterpret_cast<const uint32_t*>(buf);
267 size_t pos = 0;
268 char* start{utf8_output};
269 while (pos < len) {
270 // try to convert the next block of 2 ASCII characters
271 if (pos + 2 <= len) { // if it is safe to read 8 more
272 // bytes, check that they are ascii
273 uint64_t v;
274 std::memcpy(&v, data + pos, sizeof(uint64_t));
275 if ((v & 0xFFFFFF80FFFFFF80) == 0) {
276 *utf8_output++ = char(buf[pos]);
277 *utf8_output++ = char(buf[pos + 1]);
278 pos += 2;
279 continue;
280 }
281 }
282 uint32_t word = data[pos];
283 if ((word & 0xFFFFFF80) == 0) {
284 // will generate one UTF-8 bytes
285 *utf8_output++ = char(word);
286 pos++;
287 } else if ((word & 0xFFFFF800) == 0) {
288 // will generate two UTF-8 bytes
289 // we have 0b110XXXXX 0b10XXXXXX
290 *utf8_output++ = char((word >> 6) | 0b11000000);
291 *utf8_output++ = char((word & 0b111111) | 0b10000000);
292 pos++;
293 } else if ((word & 0xFFFF0000) == 0) {
294 // will generate three UTF-8 bytes
295 // we have 0b1110XXXX 0b10XXXXXX 0b10XXXXXX
296 if (word >= 0xD800 && word <= 0xDFFF) {
297 return 0;
298 }
299 *utf8_output++ = char((word >> 12) | 0b11100000);
300 *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
301 *utf8_output++ = char((word & 0b111111) | 0b10000000);
302 pos++;
303 } else {
304 // will generate four UTF-8 bytes
305 // we have 0b11110XXX 0b10XXXXXX 0b10XXXXXX
306 // 0b10XXXXXX
307 if (word > 0x10FFFF) {
308 return 0;
309 }
310 *utf8_output++ = char((word >> 18) | 0b11110000);
311 *utf8_output++ = char(((word >> 12) & 0b111111) | 0b10000000);
312 *utf8_output++ = char(((word >> 6) & 0b111111) | 0b10000000);
313 *utf8_output++ = char((word & 0b111111) | 0b10000000);
314 pos++;
315 }
316 }
317 return utf8_output - start;
318 }
319 } // namespace ada::idna
320 /* end file src/unicode_transcoding.cpp */
321 /* begin file src/mapping.cpp */
322
323 #include <algorithm>
324 #include <array>
325 #include <string>
326
327 /* begin file src/mapping_tables.cpp */
328 // IDNA 15.0.0
329
330 // clang-format off
331 #ifndef ADA_IDNA_TABLES_H
332 #define ADA_IDNA_TABLES_H
333 #include <cstdint>
334
335 namespace ada::idna {
336
337 const uint32_t mappings[5164] =
338 {
339 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
340 114, 115, 116, 117, 118, 119, 120, 121, 122, 32, 32, 776, 32, 772, 50, 51, 32, 769,
341 956, 32, 807, 49, 49, 8260, 52, 49, 8260, 50, 51, 8260, 52, 224, 225, 226, 227,
342 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243,
343 244, 245, 246, 248, 249, 250, 251, 252, 253, 254, 257, 259, 261, 263, 265, 267,
344 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299,
345 301, 303, 105, 775, 309, 311, 314, 316, 318, 108, 183, 322, 324, 326, 328, 700,
346 110, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359,
347 361, 363, 365, 367, 369, 371, 373, 375, 255, 378, 380, 382, 595, 387, 389, 596,
348 392, 598, 599, 396, 477, 601, 603, 402, 608, 611, 617, 616, 409, 623, 626, 629,
349 417, 419, 421, 640, 424, 643, 429, 648, 432, 650, 651, 436, 438, 658, 441, 445,
350 100, 382, 108, 106, 110, 106, 462, 464, 466, 468, 470, 472, 474, 476, 479, 481,
351 483, 485, 487, 489, 491, 493, 495, 100, 122, 501, 405, 447, 505, 507, 509, 511,
352 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, 537, 539, 541, 543,
353 414, 547, 549, 551, 553, 555, 557, 559, 561, 563, 11365, 572, 410, 11366, 578, 384,
354 649, 652, 583, 585, 587, 589, 591, 614, 633, 635, 641, 32, 774, 32, 775, 32, 778,
355 32, 808, 32, 771, 32, 779, 661, 768, 787, 776, 769, 953, 881, 883, 697, 887, 32,
356 953, 59, 1011, 32, 776, 769, 940, 941, 942, 943, 972, 973, 974, 945, 946, 947, 948,
357 949, 950, 951, 952, 954, 955, 957, 958, 959, 960, 961, 963, 964, 965, 966, 967,
358 968, 969, 970, 971, 983, 985, 987, 989, 991, 993, 995, 997, 999, 1001, 1003, 1005,
359 1007, 1016, 1019, 891, 892, 893, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111,
360 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1072, 1073, 1074, 1075, 1076, 1077,
361 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091,
362 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1121, 1123,
363 1125, 1127, 1129, 1131, 1133, 1135, 1137, 1139, 1141, 1143, 1145, 1147, 1149, 1151,
364 1153, 1163, 1165, 1167, 1169, 1171, 1173, 1175, 1177, 1179, 1181, 1183, 1185, 1187,
365 1189, 1191, 1193, 1195, 1197, 1199, 1201, 1203, 1205, 1207, 1209, 1211, 1213, 1215,
366 1218, 1220, 1222, 1224, 1226, 1228, 1230, 1233, 1235, 1237, 1239, 1241, 1243, 1245,
367 1247, 1249, 1251, 1253, 1255, 1257, 1259, 1261, 1263, 1265, 1267, 1269, 1271, 1273,
368 1275, 1277, 1279, 1281, 1283, 1285, 1287, 1289, 1291, 1293, 1295, 1297, 1299, 1301,
369 1303, 1305, 1307, 1309, 1311, 1313, 1315, 1317, 1319, 1321, 1323, 1325, 1327, 1377,
370 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391,
371 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405,
372 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1381, 1410, 1575, 1652, 1608,
373 1652, 1735, 1652, 1610, 1652, 2325, 2364, 2326, 2364, 2327, 2364, 2332, 2364, 2337,
374 2364, 2338, 2364, 2347, 2364, 2351, 2364, 2465, 2492, 2466, 2492, 2479, 2492, 2610,
375 2620, 2616, 2620, 2582, 2620, 2583, 2620, 2588, 2620, 2603, 2620, 2849, 2876, 2850,
376 2876, 3661, 3634, 3789, 3762, 3755, 3737, 3755, 3745, 3851, 3906, 4023, 3916, 4023,
377 3921, 4023, 3926, 4023, 3931, 4023, 3904, 4021, 3953, 3954, 3953, 3956, 4018, 3968,
378 4018, 3953, 3968, 4019, 3968, 4019, 3953, 3968, 3986, 4023, 3996, 4023, 4001, 4023,
379 4006, 4023, 4011, 4023, 3984, 4021, 11559, 11565, 4316, 5104, 5105, 5106, 5107,
380 5108, 5109, 42571, 4304, 4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314,
381 4315, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329,
382 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343,
383 4344, 4345, 4346, 4349, 4350, 4351, 592, 593, 7426, 604, 7446, 7447, 7453, 7461,
384 594, 597, 607, 609, 613, 618, 7547, 669, 621, 7557, 671, 625, 624, 627, 628, 632,
385 642, 427, 7452, 656, 657, 7681, 7683, 7685, 7687, 7689, 7691, 7693, 7695, 7697,
386 7699, 7701, 7703, 7705, 7707, 7709, 7711, 7713, 7715, 7717, 7719, 7721, 7723, 7725,
387 7727, 7729, 7731, 7733, 7735, 7737, 7739, 7741, 7743, 7745, 7747, 7749, 7751, 7753,
388 7755, 7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771, 7773, 7775, 7777, 7779, 7781,
389 7783, 7785, 7787, 7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803, 7805, 7807, 7809,
390 7811, 7813, 7815, 7817, 7819, 7821, 7823, 7825, 7827, 7829, 97, 702, 115, 115, 7841,
391 7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857, 7859, 7861, 7863, 7865, 7867, 7869,
392 7871, 7873, 7875, 7877, 7879, 7881, 7883, 7885, 7887, 7889, 7891, 7893, 7895, 7897,
393 7899, 7901, 7903, 7905, 7907, 7909, 7911, 7913, 7915, 7917, 7919, 7921, 7923, 7925,
394 7927, 7929, 7931, 7933, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7952,
395 7953, 7954, 7955, 7956, 7957, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7984,
396 7985, 7986, 7987, 7988, 7989, 7990, 7991, 8000, 8001, 8002, 8003, 8004, 8005, 8017,
397 8019, 8021, 8023, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 7936, 953, 7937,
398 953, 7938, 953, 7939, 953, 7940, 953, 7941, 953, 7942, 953, 7943, 953, 7968, 953,
399 7969, 953, 7970, 953, 7971, 953, 7972, 953, 7973, 953, 7974, 953, 7975, 953, 8032,
400 953, 8033, 953, 8034, 953, 8035, 953, 8036, 953, 8037, 953, 8038, 953, 8039, 953,
401 8048, 953, 945, 953, 940, 953, 8118, 953, 8112, 8113, 32, 787, 32, 834, 32, 776,
402 834, 8052, 953, 951, 953, 942, 953, 8134, 953, 8050, 32, 787, 768, 32, 787, 769,
403 32, 787, 834, 912, 8144, 8145, 8054, 32, 788, 768, 32, 788, 769, 32, 788, 834, 944,
404 8160, 8161, 8058, 8165, 32, 776, 768, 96, 8060, 953, 969, 953, 974, 953, 8182, 953,
405 8056, 8208, 32, 819, 8242, 8242, 8242, 8242, 8242, 8245, 8245, 8245, 8245, 8245,
406 33, 33, 32, 773, 63, 63, 63, 33, 33, 63, 48, 53, 54, 55, 56, 57, 43, 8722, 61, 40,
407 41, 97, 47, 99, 97, 47, 115, 176, 99, 99, 47, 111, 99, 47, 117, 176, 102, 115, 109,
408 116, 101, 108, 116, 109, 1488, 1489, 1490, 1491, 102, 97, 120, 8721, 49, 8260, 55,
409 49, 8260, 57, 49, 8260, 49, 48, 49, 8260, 51, 50, 8260, 51, 49, 8260, 53, 50, 8260,
410 53, 51, 8260, 53, 52, 8260, 53, 49, 8260, 54, 53, 8260, 54, 49, 8260, 56, 51, 8260,
411 56, 53, 8260, 56, 55, 8260, 56, 105, 105, 105, 105, 105, 105, 118, 118, 105, 118,
412 105, 105, 118, 105, 105, 105, 105, 120, 120, 105, 120, 105, 105, 48, 8260, 51, 8747,
413 8747, 8747, 8747, 8747, 8750, 8750, 8750, 8750, 8750, 12296, 12297, 49, 50, 49,
414 51, 49, 52, 49, 53, 49, 54, 49, 55, 49, 56, 49, 57, 50, 48, 40, 49, 41, 40, 50,
415 41, 40, 51, 41, 40, 52, 41, 40, 53, 41, 40, 54, 41, 40, 55, 41, 40, 56, 41, 40,
416 57, 41, 40, 49, 48, 41, 40, 49, 49, 41, 40, 49, 50, 41, 40, 49, 51, 41, 40, 49,
417 52, 41, 40, 49, 53, 41, 40, 49, 54, 41, 40, 49, 55, 41, 40, 49, 56, 41, 40, 49,
418 57, 41, 40, 50, 48, 41, 40, 97, 41, 40, 98, 41, 40, 99, 41, 40, 100, 41, 40, 101,
419 41, 40, 102, 41, 40, 103, 41, 40, 104, 41, 40, 105, 41, 40, 106, 41, 40, 107, 41,
420 40, 108, 41, 40, 109, 41, 40, 110, 41, 40, 111, 41, 40, 112, 41, 40, 113, 41, 40,
421 114, 41, 40, 115, 41, 40, 116, 41, 40, 117, 41, 40, 118, 41, 40, 119, 41, 40, 120,
422 41, 40, 121, 41, 40, 122, 41, 58, 58, 61, 61, 61, 10973, 824, 11312, 11313, 11314,
423 11315, 11316, 11317, 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 11326,
424 11327, 11328, 11329, 11330, 11331, 11332, 11333, 11334, 11335, 11336, 11337, 11338,
425 11339, 11340, 11341, 11342, 11343, 11344, 11345, 11346, 11347, 11348, 11349, 11350,
426 11351, 11352, 11353, 11354, 11355, 11356, 11357, 11358, 11359, 11361, 619, 7549,
427 637, 11368, 11370, 11372, 11379, 11382, 575, 576, 11393, 11395, 11397, 11399, 11401,
428 11403, 11405, 11407, 11409, 11411, 11413, 11415, 11417, 11419, 11421, 11423, 11425,
429 11427, 11429, 11431, 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449,
430 11451, 11453, 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, 11473,
431 11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, 11500, 11502, 11507,
432 11617, 27597, 40863, 19968, 20008, 20022, 20031, 20057, 20101, 20108, 20128, 20154,
433 20799, 20837, 20843, 20866, 20886, 20907, 20960, 20981, 20992, 21147, 21241, 21269,
434 21274, 21304, 21313, 21340, 21353, 21378, 21430, 21448, 21475, 22231, 22303, 22763,
435 22786, 22794, 22805, 22823, 22899, 23376, 23424, 23544, 23567, 23586, 23608, 23662,
436 23665, 24027, 24037, 24049, 24062, 24178, 24186, 24191, 24308, 24318, 24331, 24339,
437 24400, 24417, 24435, 24515, 25096, 25142, 25163, 25903, 25908, 25991, 26007, 26020,
438 26041, 26080, 26085, 26352, 26376, 26408, 27424, 27490, 27513, 27571, 27595, 27604,
439 27611, 27663, 27668, 27700, 28779, 29226, 29238, 29243, 29247, 29255, 29273, 29275,
440 29356, 29572, 29577, 29916, 29926, 29976, 29983, 29992, 30000, 30091, 30098, 30326,
441 30333, 30382, 30399, 30446, 30683, 30690, 30707, 31034, 31160, 31166, 31348, 31435,
442 31481, 31859, 31992, 32566, 32593, 32650, 32701, 32769, 32780, 32786, 32819, 32895,
443 32905, 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390, 33394, 33400, 34381,
444 34411, 34880, 34892, 34915, 35198, 35211, 35282, 35328, 35895, 35910, 35925, 35960,
445 35997, 36196, 36208, 36275, 36523, 36554, 36763, 36784, 36789, 37009, 37193, 37318,
446 37324, 37329, 38263, 38272, 38428, 38582, 38585, 38632, 38737, 38750, 38754, 38761,
447 38859, 38893, 38899, 38913, 39080, 39131, 39135, 39318, 39321, 39340, 39592, 39640,
448 39647, 39717, 39727, 39730, 39740, 39770, 40165, 40565, 40575, 40613, 40635, 40643,
449 40653, 40657, 40697, 40701, 40718, 40723, 40736, 40763, 40778, 40786, 40845, 40860,
450 40864, 46, 12306, 21316, 21317, 32, 12441, 32, 12442, 12424, 12426, 12467, 12488,
451 4352, 4353, 4522, 4354, 4524, 4525, 4355, 4356, 4357, 4528, 4529, 4530, 4531, 4532,
452 4533, 4378, 4358, 4359, 4360, 4385, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368,
453 4369, 4370, 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460,
454 4461, 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469, 4372, 4373, 4551, 4552, 4556,
455 4558, 4563, 4567, 4569, 4380, 4573, 4575, 4381, 4382, 4384, 4386, 4387, 4391, 4393,
456 4395, 4396, 4397, 4398, 4399, 4402, 4406, 4416, 4423, 4428, 4593, 4594, 4439, 4440,
457 4441, 4484, 4485, 4488, 4497, 4498, 4500, 4510, 4513, 19977, 22235, 19978, 20013,
458 19979, 30002, 19993, 19969, 22825, 22320, 40, 4352, 41, 40, 4354, 41, 40, 4355,
459 41, 40, 4357, 41, 40, 4358, 41, 40, 4359, 41, 40, 4361, 41, 40, 4363, 41, 40, 4364,
460 41, 40, 4366, 41, 40, 4367, 41, 40, 4368, 41, 40, 4369, 41, 40, 4370, 41, 40, 44032,
461 41, 40, 45208, 41, 40, 45796, 41, 40, 46972, 41, 40, 47560, 41, 40, 48148, 41, 40,
462 49324, 41, 40, 50500, 41, 40, 51088, 41, 40, 52264, 41, 40, 52852, 41, 40, 53440,
463 41, 40, 54028, 41, 40, 54616, 41, 40, 51452, 41, 40, 50724, 51204, 41, 40, 50724,
464 54980, 41, 40, 19968, 41, 40, 20108, 41, 40, 19977, 41, 40, 22235, 41, 40, 20116,
465 41, 40, 20845, 41, 40, 19971, 41, 40, 20843, 41, 40, 20061, 41, 40, 21313, 41, 40,
466 26376, 41, 40, 28779, 41, 40, 27700, 41, 40, 26408, 41, 40, 37329, 41, 40, 22303,
467 41, 40, 26085, 41, 40, 26666, 41, 40, 26377, 41, 40, 31038, 41, 40, 21517, 41, 40,
468 29305, 41, 40, 36001, 41, 40, 31069, 41, 40, 21172, 41, 40, 20195, 41, 40, 21628,
469 41, 40, 23398, 41, 40, 30435, 41, 40, 20225, 41, 40, 36039, 41, 40, 21332, 41, 40,
470 31085, 41, 40, 20241, 41, 40, 33258, 41, 40, 33267, 41, 21839, 24188, 31631, 112,
471 116, 101, 50, 50, 50, 52, 50, 53, 50, 54, 50, 55, 50, 56, 50, 57, 51, 48, 51, 51,
472 51, 52, 51, 53, 52280, 44256, 51452, 51032, 50864, 31192, 30007, 36969, 20778, 21360,
473 27880, 38917, 20889, 27491, 24038, 21491, 21307, 23447, 22812, 51, 54, 51, 55, 51,
474 56, 51, 57, 52, 48, 52, 52, 52, 53, 52, 54, 52, 55, 52, 56, 52, 57, 53, 48, 49,
475 26376, 50, 26376, 51, 26376, 52, 26376, 53, 26376, 54, 26376, 55, 26376, 56, 26376,
476 57, 26376, 49, 48, 26376, 49, 49, 26376, 49, 50, 26376, 104, 103, 101, 114, 103,
477 101, 118, 108, 116, 100, 12450, 12452, 12454, 12456, 12458, 12459, 12461, 12463,
478 12465, 12469, 12471, 12473, 12475, 12477, 12479, 12481, 12484, 12486, 12490, 12491,
479 12492, 12493, 12494, 12495, 12498, 12501, 12504, 12507, 12510, 12511, 12512, 12513,
480 12514, 12516, 12518, 12520, 12521, 12522, 12523, 12524, 12525, 12527, 12528, 12529,
481 12530, 20196, 21644, 12450, 12497, 12540, 12488, 12450, 12523, 12501, 12449, 12450,
482 12531, 12506, 12450, 12450, 12540, 12523, 12452, 12491, 12531, 12464, 12452, 12531,
483 12481, 12454, 12457, 12531, 12456, 12473, 12463, 12540, 12489, 12456, 12540, 12459,
484 12540, 12458, 12531, 12473, 12458, 12540, 12512, 12459, 12452, 12522, 12459, 12521,
485 12483, 12488, 12459, 12525, 12522, 12540, 12460, 12525, 12531, 12460, 12531, 12510,
486 12462, 12460, 12462, 12491, 12540, 12461, 12517, 12522, 12540, 12462, 12523, 12480,
487 12540, 12461, 12525, 12461, 12525, 12464, 12521, 12512, 12461, 12525, 12513, 12540,
488 12488, 12523, 12461, 12525, 12527, 12483, 12488, 12464, 12521, 12512, 12488, 12531,
489 12463, 12523, 12476, 12452, 12525, 12463, 12525, 12540, 12493, 12465, 12540, 12473,
490 12467, 12523, 12490, 12467, 12540, 12509, 12469, 12452, 12463, 12523, 12469, 12531,
491 12481, 12540, 12512, 12471, 12522, 12531, 12464, 12475, 12531, 12481, 12475, 12531,
492 12488, 12480, 12540, 12473, 12487, 12471, 12489, 12523, 12490, 12494, 12494, 12483,
493 12488, 12495, 12452, 12484, 12497, 12540, 12475, 12531, 12488, 12497, 12540, 12484,
494 12496, 12540, 12524, 12523, 12500, 12450, 12473, 12488, 12523, 12500, 12463, 12523,
495 12500, 12467, 12499, 12523, 12501, 12449, 12521, 12483, 12489, 12501, 12451, 12540,
496 12488, 12502, 12483, 12471, 12455, 12523, 12501, 12521, 12531, 12504, 12463, 12479,
497 12540, 12523, 12506, 12477, 12506, 12491, 12498, 12504, 12523, 12484, 12506, 12531,
498 12473, 12506, 12540, 12472, 12505, 12540, 12479, 12509, 12452, 12531, 12488, 12508,
499 12523, 12488, 12507, 12531, 12509, 12531, 12489, 12507, 12540, 12523, 12507, 12540,
500 12531, 12510, 12452, 12463, 12525, 12510, 12452, 12523, 12510, 12483, 12495, 12510,
501 12523, 12463, 12510, 12531, 12471, 12519, 12531, 12511, 12463, 12525, 12531, 12511,
502 12522, 12511, 12522, 12496, 12540, 12523, 12513, 12460, 12513, 12460, 12488, 12531,
503 12516, 12540, 12489, 12516, 12540, 12523, 12518, 12450, 12531, 12522, 12483, 12488,
504 12523, 12522, 12521, 12523, 12500, 12540, 12523, 12540, 12502, 12523, 12524, 12512,
505 12524, 12531, 12488, 12466, 12531, 48, 28857, 49, 28857, 50, 28857, 51, 28857, 52,
506 28857, 53, 28857, 54, 28857, 55, 28857, 56, 28857, 57, 28857, 49, 48, 28857, 49,
507 49, 28857, 49, 50, 28857, 49, 51, 28857, 49, 52, 28857, 49, 53, 28857, 49, 54, 28857,
508 49, 55, 28857, 49, 56, 28857, 49, 57, 28857, 50, 48, 28857, 50, 49, 28857, 50, 50,
509 28857, 50, 51, 28857, 50, 52, 28857, 104, 112, 97, 100, 97, 97, 117, 98, 97, 114,
510 111, 118, 112, 99, 100, 109, 100, 109, 50, 100, 109, 51, 105, 117, 24179, 25104,
511 26157, 21644, 22823, 27491, 26126, 27835, 26666, 24335, 20250, 31038, 110, 97, 956,
512 97, 109, 97, 107, 97, 107, 98, 109, 98, 103, 98, 99, 97, 108, 107, 99, 97, 108,
513 112, 102, 110, 102, 956, 102, 956, 103, 109, 103, 107, 103, 104, 122, 107, 104,
514 122, 109, 104, 122, 116, 104, 122, 956, 108, 109, 108, 100, 108, 102, 109, 110,
515 109, 956, 109, 109, 109, 99, 109, 107, 109, 109, 109, 50, 99, 109, 50, 107, 109,
516 50, 109, 109, 51, 99, 109, 51, 107, 109, 51, 109, 8725, 115, 109, 8725, 115, 50,
517 107, 112, 97, 109, 112, 97, 103, 112, 97, 114, 97, 100, 114, 97, 100, 8725, 115,
518 114, 97, 100, 8725, 115, 50, 112, 115, 110, 115, 956, 115, 109, 115, 112, 118, 110,
519 118, 956, 118, 109, 118, 107, 118, 112, 119, 110, 119, 956, 119, 109, 119, 107,
520 119, 107, 969, 109, 969, 98, 113, 99, 8725, 107, 103, 100, 98, 103, 121, 104, 97,
521 105, 110, 107, 107, 107, 116, 108, 110, 108, 111, 103, 108, 120, 109, 105, 108,
522 109, 111, 108, 112, 104, 112, 112, 109, 112, 114, 115, 118, 119, 98, 118, 8725,
523 109, 97, 8725, 109, 49, 26085, 50, 26085, 51, 26085, 52, 26085, 53, 26085, 54, 26085,
524 55, 26085, 56, 26085, 57, 26085, 49, 48, 26085, 49, 49, 26085, 49, 50, 26085, 49,
525 51, 26085, 49, 52, 26085, 49, 53, 26085, 49, 54, 26085, 49, 55, 26085, 49, 56, 26085,
526 49, 57, 26085, 50, 48, 26085, 50, 49, 26085, 50, 50, 26085, 50, 51, 26085, 50, 52,
527 26085, 50, 53, 26085, 50, 54, 26085, 50, 55, 26085, 50, 56, 26085, 50, 57, 26085,
528 51, 48, 26085, 51, 49, 26085, 103, 97, 108, 42561, 42563, 42565, 42567, 42569, 42573,
529 42575, 42577, 42579, 42581, 42583, 42585, 42587, 42589, 42591, 42593, 42595, 42597,
530 42599, 42601, 42603, 42605, 42625, 42627, 42629, 42631, 42633, 42635, 42637, 42639,
531 42641, 42643, 42645, 42647, 42649, 42651, 42787, 42789, 42791, 42793, 42795, 42797,
532 42799, 42803, 42805, 42807, 42809, 42811, 42813, 42815, 42817, 42819, 42821, 42823,
533 42825, 42827, 42829, 42831, 42833, 42835, 42837, 42839, 42841, 42843, 42845, 42847,
534 42849, 42851, 42853, 42855, 42857, 42859, 42861, 42863, 42874, 42876, 7545, 42879,
535 42881, 42883, 42885, 42887, 42892, 42897, 42899, 42903, 42905, 42907, 42909, 42911,
536 42913, 42915, 42917, 42919, 42921, 620, 670, 647, 43859, 42933, 42935, 42937, 42939,
537 42941, 42943, 42945, 42947, 42900, 7566, 42952, 42954, 42961, 42967, 42969, 42998,
538 43831, 43858, 653, 5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, 5033, 5034,
539 5035, 5036, 5037, 5038, 5039, 5040, 5041, 5042, 5043, 5044, 5045, 5046, 5047, 5048,
540 5049, 5050, 5051, 5052, 5053, 5054, 5055, 5056, 5057, 5058, 5059, 5060, 5061, 5062,
541 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, 5072, 5073, 5074, 5075, 5076,
542 5077, 5078, 5079, 5080, 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, 5089, 5090,
543 5091, 5092, 5093, 5094, 5095, 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103, 35912,
544 26356, 36040, 28369, 20018, 21477, 22865, 21895, 22856, 25078, 30313, 32645, 34367,
545 34746, 35064, 37007, 27138, 27931, 28889, 29662, 33853, 37226, 39409, 20098, 21365,
546 27396, 29211, 34349, 40478, 23888, 28651, 34253, 35172, 25289, 33240, 34847, 24266,
547 26391, 28010, 29436, 37070, 20358, 20919, 21214, 25796, 27347, 29200, 30439, 34310,
548 34396, 36335, 38706, 39791, 40442, 30860, 31103, 32160, 33737, 37636, 35542, 22751,
549 24324, 31840, 32894, 29282, 30922, 36034, 38647, 22744, 23650, 27155, 28122, 28431,
550 32047, 32311, 38475, 21202, 32907, 20956, 20940, 31260, 32190, 33777, 38517, 35712,
551 25295, 35582, 20025, 23527, 24594, 29575, 30064, 21271, 30971, 20415, 24489, 19981,
552 27852, 25976, 32034, 21443, 22622, 30465, 33865, 35498, 27578, 27784, 25342, 33509,
553 25504, 30053, 20142, 20841, 20937, 26753, 31975, 33391, 35538, 37327, 21237, 21570,
554 24300, 26053, 28670, 31018, 38317, 39530, 40599, 40654, 26310, 27511, 36706, 24180,
555 24976, 25088, 25754, 28451, 29001, 29833, 31178, 32244, 32879, 36646, 34030, 36899,
556 37706, 21015, 21155, 21693, 28872, 35010, 24265, 24565, 25467, 27566, 31806, 29557,
557 22265, 23994, 24604, 29618, 29801, 32666, 32838, 37428, 38646, 38728, 38936, 20363,
558 31150, 37300, 38584, 24801, 20102, 20698, 23534, 23615, 26009, 29134, 30274, 34044,
559 36988, 26248, 38446, 21129, 26491, 26611, 27969, 28316, 29705, 30041, 30827, 32016,
560 39006, 25134, 38520, 20523, 23833, 28138, 36650, 24459, 24900, 26647, 38534, 21033,
561 21519, 23653, 26131, 26446, 26792, 27877, 29702, 30178, 32633, 35023, 35041, 38626,
562 21311, 28346, 21533, 29136, 29848, 34298, 38563, 40023, 40607, 26519, 28107, 33256,
563 31520, 31890, 29376, 28825, 35672, 20160, 33590, 21050, 20999, 24230, 25299, 31958,
564 23429, 27934, 26292, 36667, 38477, 24275, 20800, 21952, 22618, 26228, 20958, 29482,
565 30410, 31036, 31070, 31077, 31119, 38742, 31934, 34322, 35576, 36920, 37117, 39151,
566 39164, 39208, 40372, 37086, 38583, 20398, 20711, 20813, 21193, 21220, 21329, 21917,
567 22022, 22120, 22592, 22696, 23652, 24724, 24936, 24974, 25074, 25935, 26082, 26257,
568 26757, 28023, 28186, 28450, 29038, 29227, 29730, 30865, 31049, 31048, 31056, 31062,
569 31117, 31118, 31296, 31361, 31680, 32265, 32321, 32626, 32773, 33261, 33401, 33879,
570 35088, 35222, 35585, 35641, 36051, 36104, 36790, 38627, 38911, 38971, 24693, 148206,
571 33304, 20006, 20917, 20840, 20352, 20805, 20864, 21191, 21242, 21845, 21913, 21986,
572 22707, 22852, 22868, 23138, 23336, 24274, 24281, 24425, 24493, 24792, 24910, 24840,
573 24928, 25140, 25540, 25628, 25682, 25942, 26395, 26454, 28379, 28363, 28702, 30631,
574 29237, 29359, 29809, 29958, 30011, 30237, 30239, 30427, 30452, 30538, 30528, 30924,
575 31409, 31867, 32091, 32574, 33618, 33775, 34681, 35137, 35206, 35519, 35531, 35565,
576 35722, 36664, 36978, 37273, 37494, 38524, 38875, 38923, 39698, 141386, 141380, 144341,
577 15261, 16408, 16441, 152137, 154832, 163539, 40771, 40846, 102, 102, 102, 105, 102,
578 108, 102, 102, 108, 1396, 1398, 1396, 1381, 1396, 1387, 1406, 1398, 1396, 1389,
579 1497, 1460, 1522, 1463, 1506, 1492, 1499, 1500, 1501, 1512, 1514, 1513, 1473, 1513,
580 1474, 1513, 1468, 1473, 1513, 1468, 1474, 1488, 1463, 1488, 1464, 1488, 1468, 1489,
581 1468, 1490, 1468, 1491, 1468, 1492, 1468, 1493, 1468, 1494, 1468, 1496, 1468, 1497,
582 1468, 1498, 1468, 1499, 1468, 1500, 1468, 1502, 1468, 1504, 1468, 1505, 1468, 1507,
583 1468, 1508, 1468, 1510, 1468, 1511, 1468, 1512, 1468, 1514, 1468, 1493, 1465, 1489,
584 1471, 1499, 1471, 1508, 1471, 1488, 1500, 1649, 1659, 1662, 1664, 1658, 1663, 1657,
585 1700, 1702, 1668, 1667, 1670, 1671, 1677, 1676, 1678, 1672, 1688, 1681, 1705, 1711,
586 1715, 1713, 1722, 1723, 1728, 1729, 1726, 1746, 1747, 1709, 1734, 1736, 1739, 1733,
587 1737, 1744, 1609, 1574, 1575, 1574, 1749, 1574, 1608, 1574, 1735, 1574, 1734, 1574,
588 1736, 1574, 1744, 1574, 1609, 1740, 1574, 1580, 1574, 1581, 1574, 1605, 1574, 1610,
589 1576, 1580, 1576, 1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576, 1610, 1578, 1580,
590 1578, 1581, 1578, 1582, 1578, 1605, 1578, 1609, 1578, 1610, 1579, 1580, 1579, 1605,
591 1579, 1609, 1579, 1610, 1580, 1581, 1580, 1605, 1581, 1605, 1582, 1580, 1582, 1581,
592 1582, 1605, 1587, 1580, 1587, 1581, 1587, 1582, 1587, 1605, 1589, 1581, 1589, 1605,
593 1590, 1580, 1590, 1581, 1590, 1582, 1590, 1605, 1591, 1581, 1591, 1605, 1592, 1605,
594 1593, 1580, 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601, 1581, 1601, 1582,
595 1601, 1605, 1601, 1609, 1601, 1610, 1602, 1581, 1602, 1605, 1602, 1609, 1602, 1610,
596 1603, 1575, 1603, 1580, 1603, 1581, 1603, 1582, 1603, 1604, 1603, 1605, 1603, 1609,
597 1603, 1610, 1604, 1580, 1604, 1581, 1604, 1582, 1604, 1605, 1604, 1609, 1604, 1610,
598 1605, 1580, 1605, 1605, 1605, 1609, 1605, 1610, 1606, 1580, 1606, 1581, 1606, 1582,
599 1606, 1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607, 1605, 1607, 1609, 1607, 1610,
600 1610, 1581, 1610, 1582, 1610, 1609, 1584, 1648, 1585, 1648, 1609, 1648, 32, 1612,
601 1617, 32, 1613, 1617, 32, 1614, 1617, 32, 1615, 1617, 32, 1616, 1617, 32, 1617,
602 1648, 1574, 1585, 1574, 1586, 1574, 1606, 1576, 1585, 1576, 1586, 1576, 1606, 1578,
603 1585, 1578, 1586, 1578, 1606, 1579, 1585, 1579, 1586, 1579, 1606, 1605, 1575, 1606,
604 1585, 1606, 1586, 1606, 1606, 1610, 1585, 1610, 1586, 1574, 1582, 1574, 1607, 1576,
605 1607, 1578, 1607, 1589, 1582, 1604, 1607, 1606, 1607, 1607, 1648, 1579, 1607, 1587,
606 1607, 1588, 1605, 1588, 1607, 1600, 1614, 1617, 1600, 1615, 1617, 1600, 1616, 1617,
607 1591, 1609, 1591, 1610, 1593, 1609, 1593, 1610, 1594, 1609, 1594, 1610, 1587, 1609,
608 1587, 1610, 1588, 1609, 1588, 1610, 1581, 1609, 1580, 1609, 1580, 1610, 1582, 1609,
609 1589, 1609, 1589, 1610, 1590, 1609, 1590, 1610, 1588, 1580, 1588, 1581, 1588, 1582,
610 1588, 1585, 1587, 1585, 1589, 1585, 1590, 1585, 1575, 1611, 1578, 1580, 1605, 1578,
611 1581, 1580, 1578, 1581, 1605, 1578, 1582, 1605, 1578, 1605, 1580, 1578, 1605, 1581,
612 1578, 1605, 1582, 1581, 1605, 1610, 1581, 1605, 1609, 1587, 1581, 1580, 1587, 1580,
613 1581, 1587, 1580, 1609, 1587, 1605, 1581, 1587, 1605, 1580, 1587, 1605, 1605, 1589,
614 1581, 1581, 1589, 1605, 1605, 1588, 1581, 1605, 1588, 1580, 1610, 1588, 1605, 1582,
615 1588, 1605, 1605, 1590, 1581, 1609, 1590, 1582, 1605, 1591, 1605, 1581, 1591, 1605,
616 1605, 1591, 1605, 1610, 1593, 1580, 1605, 1593, 1605, 1605, 1593, 1605, 1609, 1594,
617 1605, 1605, 1594, 1605, 1610, 1594, 1605, 1609, 1601, 1582, 1605, 1602, 1605, 1581,
618 1602, 1605, 1605, 1604, 1581, 1605, 1604, 1581, 1610, 1604, 1581, 1609, 1604, 1580,
619 1580, 1604, 1582, 1605, 1604, 1605, 1581, 1605, 1581, 1580, 1605, 1581, 1610, 1605,
620 1580, 1581, 1605, 1582, 1605, 1605, 1580, 1582, 1607, 1605, 1580, 1607, 1605, 1605,
621 1606, 1581, 1605, 1606, 1581, 1609, 1606, 1580, 1605, 1606, 1580, 1609, 1606, 1605,
622 1610, 1606, 1605, 1609, 1610, 1605, 1605, 1576, 1582, 1610, 1578, 1580, 1610, 1578,
623 1580, 1609, 1578, 1582, 1610, 1578, 1582, 1609, 1578, 1605, 1610, 1578, 1605, 1609,
624 1580, 1605, 1610, 1580, 1581, 1609, 1580, 1605, 1609, 1587, 1582, 1609, 1589, 1581,
625 1610, 1588, 1581, 1610, 1590, 1581, 1610, 1604, 1580, 1610, 1604, 1605, 1610, 1610,
626 1580, 1610, 1610, 1605, 1610, 1605, 1605, 1610, 1602, 1605, 1610, 1606, 1581, 1610,
627 1593, 1605, 1610, 1603, 1605, 1610, 1606, 1580, 1581, 1605, 1582, 1610, 1604, 1580,
628 1605, 1603, 1605, 1605, 1580, 1581, 1610, 1581, 1580, 1610, 1605, 1580, 1610, 1601,
629 1605, 1610, 1576, 1581, 1610, 1587, 1582, 1610, 1606, 1580, 1610, 1589, 1604, 1746,
630 1602, 1604, 1746, 1575, 1604, 1604, 1607, 1575, 1603, 1576, 1585, 1605, 1581, 1605,
631 1583, 1589, 1604, 1593, 1605, 1585, 1587, 1608, 1604, 1593, 1604, 1610, 1607, 1608,
632 1587, 1604, 1605, 1589, 1604, 1609, 1589, 1604, 1609, 32, 1575, 1604, 1604, 1607,
633 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 1580, 1604, 32, 1580, 1604,
634 1575, 1604, 1607, 1585, 1740, 1575, 1604, 44, 12289, 12310, 12311, 8212, 8211, 95,
635 123, 125, 12308, 12309, 12304, 12305, 12298, 12299, 12300, 12301, 12302, 12303,
636 91, 93, 35, 38, 42, 45, 60, 62, 92, 36, 37, 64, 32, 1611, 1600, 1611, 1600, 1617,
637 32, 1618, 1600, 1618, 1569, 1570, 1571, 1572, 1573, 1577, 1604, 1570, 1604, 1571,
638 1604, 1573, 34, 39, 94, 124, 126, 10629, 10630, 12539, 12453, 12515, 162, 163, 172,
639 166, 165, 8361, 9474, 8592, 8593, 8594, 8595, 9632, 9675, 66600, 66601, 66602, 66603,
640 66604, 66605, 66606, 66607, 66608, 66609, 66610, 66611, 66612, 66613, 66614, 66615,
641 66616, 66617, 66618, 66619, 66620, 66621, 66622, 66623, 66624, 66625, 66626, 66627,
642 66628, 66629, 66630, 66631, 66632, 66633, 66634, 66635, 66636, 66637, 66638, 66639,
643 66776, 66777, 66778, 66779, 66780, 66781, 66782, 66783, 66784, 66785, 66786, 66787,
644 66788, 66789, 66790, 66791, 66792, 66793, 66794, 66795, 66796, 66797, 66798, 66799,
645 66800, 66801, 66802, 66803, 66804, 66805, 66806, 66807, 66808, 66809, 66810, 66811,
646 66967, 66968, 66969, 66970, 66971, 66972, 66973, 66974, 66975, 66976, 66977, 66979,
647 66980, 66981, 66982, 66983, 66984, 66985, 66986, 66987, 66988, 66989, 66990, 66991,
648 66992, 66993, 66995, 66996, 66997, 66998, 66999, 67000, 67001, 67003, 67004, 720,
649 721, 665, 675, 43878, 677, 676, 7569, 600, 606, 681, 612, 610, 667, 668, 615, 644,
650 682, 683, 122628, 42894, 622, 122629, 654, 122630, 630, 631, 634, 122632, 638, 680,
651 678, 43879, 679, 11377, 655, 673, 674, 664, 448, 449, 450, 122634, 122654, 68800,
652 68801, 68802, 68803, 68804, 68805, 68806, 68807, 68808, 68809, 68810, 68811, 68812,
653 68813, 68814, 68815, 68816, 68817, 68818, 68819, 68820, 68821, 68822, 68823, 68824,
654 68825, 68826, 68827, 68828, 68829, 68830, 68831, 68832, 68833, 68834, 68835, 68836,
655 68837, 68838, 68839, 68840, 68841, 68842, 68843, 68844, 68845, 68846, 68847, 68848,
656 68849, 68850, 71872, 71873, 71874, 71875, 71876, 71877, 71878, 71879, 71880, 71881,
657 71882, 71883, 71884, 71885, 71886, 71887, 71888, 71889, 71890, 71891, 71892, 71893,
658 71894, 71895, 71896, 71897, 71898, 71899, 71900, 71901, 71902, 71903, 93792, 93793,
659 93794, 93795, 93796, 93797, 93798, 93799, 93800, 93801, 93802, 93803, 93804, 93805,
660 93806, 93807, 93808, 93809, 93810, 93811, 93812, 93813, 93814, 93815, 93816, 93817,
661 93818, 93819, 93820, 93821, 93822, 93823, 119127, 119141, 119128, 119141, 119128,
662 119141, 119150, 119128, 119141, 119151, 119128, 119141, 119152, 119128, 119141,
663 119153, 119128, 119141, 119154, 119225, 119141, 119226, 119141, 119225, 119141,
664 119150, 119226, 119141, 119150, 119225, 119141, 119151, 119226, 119141, 119151,
665 305, 567, 8711, 8706, 1231, 125218, 125219, 125220, 125221, 125222, 125223, 125224,
666 125225, 125226, 125227, 125228, 125229, 125230, 125231, 125232, 125233, 125234,
667 125235, 125236, 125237, 125238, 125239, 125240, 125241, 125242, 125243, 125244,
668 125245, 125246, 125247, 125248, 125249, 125250, 125251, 1646, 1697, 1647, 48, 44,
669 49, 44, 50, 44, 51, 44, 52, 44, 53, 44, 54, 44, 55, 44, 56, 44, 57, 44, 12308, 115,
670 12309, 119, 122, 104, 118, 115, 100, 112, 112, 118, 119, 99, 109, 114, 100, 106,
671 12411, 12363, 12467, 12467, 23383, 21452, 22810, 35299, 20132, 26144, 28961, 21069,
672 24460, 20877, 26032, 21021, 32066, 36009, 22768, 21561, 28436, 25237, 25429, 36938,
673 25351, 25171, 31105, 31354, 21512, 28288, 30003, 21106, 21942, 37197, 12308, 26412,
674 12309, 12308, 19977, 12309, 12308, 20108, 12309, 12308, 23433, 12309, 12308, 28857,
675 12309, 12308, 25171, 12309, 12308, 30423, 12309, 12308, 21213, 12309, 12308, 25943,
676 12309, 24471, 21487, 20029, 20024, 20033, 131362, 20320, 20411, 20482, 20602, 20633,
677 20687, 13470, 132666, 20820, 20836, 20855, 132380, 13497, 20839, 132427, 20887,
678 20900, 20172, 20908, 168415, 20995, 13535, 21051, 21062, 21111, 13589, 21253, 21254,
679 21321, 21338, 21363, 21373, 21375, 133676, 28784, 21450, 21471, 133987, 21483, 21489,
680 21510, 21662, 21560, 21576, 21608, 21666, 21750, 21776, 21843, 21859, 21892, 21931,
681 21939, 21954, 22294, 22295, 22097, 22132, 22766, 22478, 22516, 22541, 22411, 22578,
682 22577, 22700, 136420, 22770, 22775, 22790, 22818, 22882, 136872, 136938, 23020,
683 23067, 23079, 23000, 23142, 14062, 23304, 23358, 137672, 23491, 23512, 23539, 138008,
684 23551, 23558, 14209, 23648, 23744, 23693, 138724, 23875, 138726, 23918, 23915, 23932,
685 24033, 24034, 14383, 24061, 24104, 24125, 24169, 14434, 139651, 14460, 24240, 24243,
686 24246, 172946, 140081, 33281, 24354, 14535, 144056, 156122, 24418, 24427, 14563,
687 24474, 24525, 24535, 24569, 24705, 14650, 14620, 141012, 24775, 24904, 24908, 24954,
688 25010, 24996, 25007, 25054, 25115, 25181, 25265, 25300, 25424, 142092, 25405, 25340,
689 25448, 25475, 25572, 142321, 25634, 25541, 25513, 14894, 25705, 25726, 25757, 25719,
690 14956, 25964, 143370, 26083, 26360, 26185, 15129, 15112, 15076, 20882, 20885, 26368,
691 26268, 32941, 17369, 26401, 26462, 26451, 144323, 15177, 26618, 26501, 26706, 144493,
692 26766, 26655, 26900, 26946, 27043, 27114, 27304, 145059, 27355, 15384, 27425, 145575,
693 27476, 15438, 27506, 27551, 27579, 146061, 138507, 146170, 27726, 146620, 27839,
694 27853, 27751, 27926, 27966, 28009, 28024, 28037, 146718, 27956, 28207, 28270, 15667,
695 28359, 147153, 28153, 28526, 147294, 147342, 28614, 28729, 28699, 15766, 28746,
696 28797, 28791, 28845, 132389, 28997, 148067, 29084, 29224, 29264, 149000, 29312,
697 29333, 149301, 149524, 29562, 29579, 16044, 29605, 16056, 29767, 29788, 29829, 29898,
698 16155, 29988, 150582, 30014, 150674, 139679, 30224, 151457, 151480, 151620, 16380,
699 16392, 151795, 151794, 151833, 151859, 30494, 30495, 30603, 16454, 16534, 152605,
700 30798, 16611, 153126, 153242, 153285, 31211, 16687, 31306, 31311, 153980, 154279,
701 16898, 154539, 31686, 31689, 16935, 154752, 31954, 17056, 31976, 31971, 32000, 155526,
702 32099, 17153, 32199, 32258, 32325, 17204, 156200, 156231, 17241, 156377, 32634,
703 156478, 32661, 32762, 156890, 156963, 32864, 157096, 32880, 144223, 17365, 32946,
704 33027, 17419, 33086, 23221, 157607, 157621, 144275, 144284, 33284, 36766, 17515,
705 33425, 33419, 33437, 21171, 33457, 33459, 33469, 33510, 158524, 33565, 33635, 33709,
706 33571, 33725, 33767, 33619, 33738, 33740, 33756, 158774, 159083, 158933, 17707,
707 34033, 34035, 34070, 160714, 34148, 159532, 17757, 17761, 159665, 159954, 17771,
708 34384, 34407, 34409, 34473, 34440, 34574, 34530, 34600, 34667, 34694, 34785, 34817,
709 17913, 34912, 161383, 35031, 35038, 17973, 35066, 13499, 161966, 162150, 18110,
710 18119, 35488, 162984, 36011, 36033, 36123, 36215, 163631, 133124, 36299, 36284,
711 36336, 133342, 36564, 165330, 165357, 37012, 37105, 37137, 165678, 37147, 37432,
712 37591, 37592, 37500, 37881, 37909, 166906, 38283, 18837, 38327, 167287, 18918, 38595,
713 23986, 38691, 168261, 168474, 19054, 19062, 38880, 168970, 19122, 169110, 38953,
714 169398, 39138, 19251, 39209, 39335, 39362, 39422, 19406, 170800, 40000, 40189, 19662,
715 19693, 40295, 172238, 19704, 172293, 172558, 172689, 19798, 40702, 40709, 40719,
716 40726, 173568,
717
718 };
719 const uint32_t table[8000][2] =
720 {
721 {0, 1}, {65, 16777219}, {66, 16777475}, {67, 16777731},
722 {68, 16777987}, {69, 16778243}, {70, 16778499}, {71, 16778755},
723 {72, 16779011}, {73, 16779267}, {74, 16779523}, {75, 16779779},
724 {76, 16780035}, {77, 16780291}, {78, 16780547}, {79, 16780803},
725 {80, 16781059}, {81, 16781315}, {82, 16781571}, {83, 16781827},
726 {84, 16782083}, {85, 16782339}, {86, 16782595}, {87, 16782851},
727 {88, 16783107}, {89, 16783363}, {90, 16783619}, {91, 1},
728 {128, 2}, {160, 16783875}, {161, 1}, {168, 33561347},
729 {169, 1}, {170, 16777219}, {171, 1}, {173, 0},
730 {174, 1}, {175, 33561859}, {176, 1}, {178, 16785155},
731 {179, 16785411}, {180, 33562883}, {181, 16786179}, {182, 1},
732 {184, 33563651}, {185, 16786947}, {186, 16780803}, {187, 1},
733 {188, 50341635}, {189, 50342403}, {190, 50343171}, {191, 1},
734 {192, 16789507}, {193, 16789763}, {194, 16790019}, {195, 16790275},
735 {196, 16790531}, {197, 16790787}, {198, 16791043}, {199, 16791299},
736 {200, 16791555}, {201, 16791811}, {202, 16792067}, {203, 16792323},
737 {204, 16792579}, {205, 16792835}, {206, 16793091}, {207, 16793347},
738 {208, 16793603}, {209, 16793859}, {210, 16794115}, {211, 16794371},
739 {212, 16794627}, {213, 16794883}, {214, 16795139}, {215, 1},
740 {216, 16795395}, {217, 16795651}, {218, 16795907}, {219, 16796163},
741 {220, 16796419}, {221, 16796675}, {222, 16796931}, {223, 1},
742 {256, 16797187}, {257, 1}, {258, 16797443}, {259, 1},
743 {260, 16797699}, {261, 1}, {262, 16797955}, {263, 1},
744 {264, 16798211}, {265, 1}, {266, 16798467}, {267, 1},
745 {268, 16798723}, {269, 1}, {270, 16798979}, {271, 1},
746 {272, 16799235}, {273, 1}, {274, 16799491}, {275, 1},
747 {276, 16799747}, {277, 1}, {278, 16800003}, {279, 1},
748 {280, 16800259}, {281, 1}, {282, 16800515}, {283, 1},
749 {284, 16800771}, {285, 1}, {286, 16801027}, {287, 1},
750 {288, 16801283}, {289, 1}, {290, 16801539}, {291, 1},
751 {292, 16801795}, {293, 1}, {294, 16802051}, {295, 1},
752 {296, 16802307}, {297, 1}, {298, 16802563}, {299, 1},
753 {300, 16802819}, {301, 1}, {302, 16803075}, {303, 1},
754 {304, 33580547}, {305, 1}, {306, 33556483}, {308, 16803843},
755 {309, 1}, {310, 16804099}, {311, 1}, {313, 16804355},
756 {314, 1}, {315, 16804611}, {316, 1}, {317, 16804867},
757 {318, 1}, {319, 33582339}, {321, 16805635}, {322, 1},
758 {323, 16805891}, {324, 1}, {325, 16806147}, {326, 1},
759 {327, 16806403}, {328, 1}, {329, 33583875}, {330, 16807171},
760 {331, 1}, {332, 16807427}, {333, 1}, {334, 16807683},
761 {335, 1}, {336, 16807939}, {337, 1}, {338, 16808195},
762 {339, 1}, {340, 16808451}, {341, 1}, {342, 16808707},
763 {343, 1}, {344, 16808963}, {345, 1}, {346, 16809219},
764 {347, 1}, {348, 16809475}, {349, 1}, {350, 16809731},
765 {351, 1}, {352, 16809987}, {353, 1}, {354, 16810243},
766 {355, 1}, {356, 16810499}, {357, 1}, {358, 16810755},
767 {359, 1}, {360, 16811011}, {361, 1}, {362, 16811267},
768 {363, 1}, {364, 16811523}, {365, 1}, {366, 16811779},
769 {367, 1}, {368, 16812035}, {369, 1}, {370, 16812291},
770 {371, 1}, {372, 16812547}, {373, 1}, {374, 16812803},
771 {375, 1}, {376, 16813059}, {377, 16813315}, {378, 1},
772 {379, 16813571}, {380, 1}, {381, 16813827}, {382, 1},
773 {383, 16781827}, {384, 1}, {385, 16814083}, {386, 16814339},
774 {387, 1}, {388, 16814595}, {389, 1}, {390, 16814851},
775 {391, 16815107}, {392, 1}, {393, 16815363}, {394, 16815619},
776 {395, 16815875}, {396, 1}, {398, 16816131}, {399, 16816387},
777 {400, 16816643}, {401, 16816899}, {402, 1}, {403, 16817155},
778 {404, 16817411}, {405, 1}, {406, 16817667}, {407, 16817923},
779 {408, 16818179}, {409, 1}, {412, 16818435}, {413, 16818691},
780 {414, 1}, {415, 16818947}, {416, 16819203}, {417, 1},
781 {418, 16819459}, {419, 1}, {420, 16819715}, {421, 1},
782 {422, 16819971}, {423, 16820227}, {424, 1}, {425, 16820483},
783 {426, 1}, {428, 16820739}, {429, 1}, {430, 16820995},
784 {431, 16821251}, {432, 1}, {433, 16821507}, {434, 16821763},
785 {435, 16822019}, {436, 1}, {437, 16822275}, {438, 1},
786 {439, 16822531}, {440, 16822787}, {441, 1}, {444, 16823043},
787 {445, 1}, {452, 33600515}, {455, 33601027}, {458, 33601539},
788 {461, 16824835}, {462, 1}, {463, 16825091}, {464, 1},
789 {465, 16825347}, {466, 1}, {467, 16825603}, {468, 1},
790 {469, 16825859}, {470, 1}, {471, 16826115}, {472, 1},
791 {473, 16826371}, {474, 1}, {475, 16826627}, {476, 1},
792 {478, 16826883}, {479, 1}, {480, 16827139}, {481, 1},
793 {482, 16827395}, {483, 1}, {484, 16827651}, {485, 1},
794 {486, 16827907}, {487, 1}, {488, 16828163}, {489, 1},
795 {490, 16828419}, {491, 1}, {492, 16828675}, {493, 1},
796 {494, 16828931}, {495, 1}, {497, 33606403}, {500, 16829699},
797 {501, 1}, {502, 16829955}, {503, 16830211}, {504, 16830467},
798 {505, 1}, {506, 16830723}, {507, 1}, {508, 16830979},
799 {509, 1}, {510, 16831235}, {511, 1}, {512, 16831491},
800 {513, 1}, {514, 16831747}, {515, 1}, {516, 16832003},
801 {517, 1}, {518, 16832259}, {519, 1}, {520, 16832515},
802 {521, 1}, {522, 16832771}, {523, 1}, {524, 16833027},
803 {525, 1}, {526, 16833283}, {527, 1}, {528, 16833539},
804 {529, 1}, {530, 16833795}, {531, 1}, {532, 16834051},
805 {533, 1}, {534, 16834307}, {535, 1}, {536, 16834563},
806 {537, 1}, {538, 16834819}, {539, 1}, {540, 16835075},
807 {541, 1}, {542, 16835331}, {543, 1}, {544, 16835587},
808 {545, 1}, {546, 16835843}, {547, 1}, {548, 16836099},
809 {549, 1}, {550, 16836355}, {551, 1}, {552, 16836611},
810 {553, 1}, {554, 16836867}, {555, 1}, {556, 16837123},
811 {557, 1}, {558, 16837379}, {559, 1}, {560, 16837635},
812 {561, 1}, {562, 16837891}, {563, 1}, {570, 16838147},
813 {571, 16838403}, {572, 1}, {573, 16838659}, {574, 16838915},
814 {575, 1}, {577, 16839171}, {578, 1}, {579, 16839427},
815 {580, 16839683}, {581, 16839939}, {582, 16840195}, {583, 1},
816 {584, 16840451}, {585, 1}, {586, 16840707}, {587, 1},
817 {588, 16840963}, {589, 1}, {590, 16841219}, {591, 1},
818 {688, 16779011}, {689, 16841475}, {690, 16779523}, {691, 16781571},
819 {692, 16841731}, {693, 16841987}, {694, 16842243}, {695, 16782851},
820 {696, 16783363}, {697, 1}, {728, 33619715}, {729, 33620227},
821 {730, 33620739}, {731, 33621251}, {732, 33621763}, {733, 33622275},
822 {734, 1}, {736, 16817411}, {737, 16780035}, {738, 16781827},
823 {739, 16783107}, {740, 16845571}, {741, 1}, {832, 16845827},
824 {833, 16785923}, {834, 1}, {835, 16846083}, {836, 33623555},
825 {837, 16846851}, {838, 1}, {847, 0}, {848, 1},
826 {880, 16847107}, {881, 1}, {882, 16847363}, {883, 1},
827 {884, 16847619}, {885, 1}, {886, 16847875}, {887, 1},
828 {888, 2}, {890, 33625347}, {891, 1}, {894, 16848643},
829 {895, 16848899}, {896, 2}, {900, 33562883}, {901, 50403587},
830 {902, 16849923}, {903, 16805379}, {904, 16850179}, {905, 16850435},
831 {906, 16850691}, {907, 2}, {908, 16850947}, {909, 2},
832 {910, 16851203}, {911, 16851459}, {912, 1}, {913, 16851715},
833 {914, 16851971}, {915, 16852227}, {916, 16852483}, {917, 16852739},
834 {918, 16852995}, {919, 16853251}, {920, 16853507}, {921, 16846851},
835 {922, 16853763}, {923, 16854019}, {924, 16786179}, {925, 16854275},
836 {926, 16854531}, {927, 16854787}, {928, 16855043}, {929, 16855299},
837 {930, 2}, {931, 16855555}, {932, 16855811}, {933, 16856067},
838 {934, 16856323}, {935, 16856579}, {936, 16856835}, {937, 16857091},
839 {938, 16857347}, {939, 16857603}, {940, 1}, {975, 16857859},
840 {976, 16851971}, {977, 16853507}, {978, 16856067}, {979, 16851203},
841 {980, 16857603}, {981, 16856323}, {982, 16855043}, {983, 1},
842 {984, 16858115}, {985, 1}, {986, 16858371}, {987, 1},
843 {988, 16858627}, {989, 1}, {990, 16858883}, {991, 1},
844 {992, 16859139}, {993, 1}, {994, 16859395}, {995, 1},
845 {996, 16859651}, {997, 1}, {998, 16859907}, {999, 1},
846 {1000, 16860163}, {1001, 1}, {1002, 16860419}, {1003, 1},
847 {1004, 16860675}, {1005, 1}, {1006, 16860931}, {1007, 1},
848 {1008, 16853763}, {1009, 16855299}, {1010, 16855555}, {1011, 1},
849 {1012, 16853507}, {1013, 16852739}, {1014, 1}, {1015, 16861187},
850 {1016, 1}, {1017, 16855555}, {1018, 16861443}, {1019, 1},
851 {1021, 16861699}, {1022, 16861955}, {1023, 16862211}, {1024, 16862467},
852 {1025, 16862723}, {1026, 16862979}, {1027, 16863235}, {1028, 16863491},
853 {1029, 16863747}, {1030, 16864003}, {1031, 16864259}, {1032, 16864515},
854 {1033, 16864771}, {1034, 16865027}, {1035, 16865283}, {1036, 16865539},
855 {1037, 16865795}, {1038, 16866051}, {1039, 16866307}, {1040, 16866563},
856 {1041, 16866819}, {1042, 16867075}, {1043, 16867331}, {1044, 16867587},
857 {1045, 16867843}, {1046, 16868099}, {1047, 16868355}, {1048, 16868611},
858 {1049, 16868867}, {1050, 16869123}, {1051, 16869379}, {1052, 16869635},
859 {1053, 16869891}, {1054, 16870147}, {1055, 16870403}, {1056, 16870659},
860 {1057, 16870915}, {1058, 16871171}, {1059, 16871427}, {1060, 16871683},
861 {1061, 16871939}, {1062, 16872195}, {1063, 16872451}, {1064, 16872707},
862 {1065, 16872963}, {1066, 16873219}, {1067, 16873475}, {1068, 16873731},
863 {1069, 16873987}, {1070, 16874243}, {1071, 16874499}, {1072, 1},
864 {1120, 16874755}, {1121, 1}, {1122, 16875011}, {1123, 1},
865 {1124, 16875267}, {1125, 1}, {1126, 16875523}, {1127, 1},
866 {1128, 16875779}, {1129, 1}, {1130, 16876035}, {1131, 1},
867 {1132, 16876291}, {1133, 1}, {1134, 16876547}, {1135, 1},
868 {1136, 16876803}, {1137, 1}, {1138, 16877059}, {1139, 1},
869 {1140, 16877315}, {1141, 1}, {1142, 16877571}, {1143, 1},
870 {1144, 16877827}, {1145, 1}, {1146, 16878083}, {1147, 1},
871 {1148, 16878339}, {1149, 1}, {1150, 16878595}, {1151, 1},
872 {1152, 16878851}, {1153, 1}, {1162, 16879107}, {1163, 1},
873 {1164, 16879363}, {1165, 1}, {1166, 16879619}, {1167, 1},
874 {1168, 16879875}, {1169, 1}, {1170, 16880131}, {1171, 1},
875 {1172, 16880387}, {1173, 1}, {1174, 16880643}, {1175, 1},
876 {1176, 16880899}, {1177, 1}, {1178, 16881155}, {1179, 1},
877 {1180, 16881411}, {1181, 1}, {1182, 16881667}, {1183, 1},
878 {1184, 16881923}, {1185, 1}, {1186, 16882179}, {1187, 1},
879 {1188, 16882435}, {1189, 1}, {1190, 16882691}, {1191, 1},
880 {1192, 16882947}, {1193, 1}, {1194, 16883203}, {1195, 1},
881 {1196, 16883459}, {1197, 1}, {1198, 16883715}, {1199, 1},
882 {1200, 16883971}, {1201, 1}, {1202, 16884227}, {1203, 1},
883 {1204, 16884483}, {1205, 1}, {1206, 16884739}, {1207, 1},
884 {1208, 16884995}, {1209, 1}, {1210, 16885251}, {1211, 1},
885 {1212, 16885507}, {1213, 1}, {1214, 16885763}, {1215, 1},
886 {1216, 2}, {1217, 16886019}, {1218, 1}, {1219, 16886275},
887 {1220, 1}, {1221, 16886531}, {1222, 1}, {1223, 16886787},
888 {1224, 1}, {1225, 16887043}, {1226, 1}, {1227, 16887299},
889 {1228, 1}, {1229, 16887555}, {1230, 1}, {1232, 16887811},
890 {1233, 1}, {1234, 16888067}, {1235, 1}, {1236, 16888323},
891 {1237, 1}, {1238, 16888579}, {1239, 1}, {1240, 16888835},
892 {1241, 1}, {1242, 16889091}, {1243, 1}, {1244, 16889347},
893 {1245, 1}, {1246, 16889603}, {1247, 1}, {1248, 16889859},
894 {1249, 1}, {1250, 16890115}, {1251, 1}, {1252, 16890371},
895 {1253, 1}, {1254, 16890627}, {1255, 1}, {1256, 16890883},
896 {1257, 1}, {1258, 16891139}, {1259, 1}, {1260, 16891395},
897 {1261, 1}, {1262, 16891651}, {1263, 1}, {1264, 16891907},
898 {1265, 1}, {1266, 16892163}, {1267, 1}, {1268, 16892419},
899 {1269, 1}, {1270, 16892675}, {1271, 1}, {1272, 16892931},
900 {1273, 1}, {1274, 16893187}, {1275, 1}, {1276, 16893443},
901 {1277, 1}, {1278, 16893699}, {1279, 1}, {1280, 16893955},
902 {1281, 1}, {1282, 16894211}, {1283, 1}, {1284, 16894467},
903 {1285, 1}, {1286, 16894723}, {1287, 1}, {1288, 16894979},
904 {1289, 1}, {1290, 16895235}, {1291, 1}, {1292, 16895491},
905 {1293, 1}, {1294, 16895747}, {1295, 1}, {1296, 16896003},
906 {1297, 1}, {1298, 16896259}, {1299, 1}, {1300, 16896515},
907 {1301, 1}, {1302, 16896771}, {1303, 1}, {1304, 16897027},
908 {1305, 1}, {1306, 16897283}, {1307, 1}, {1308, 16897539},
909 {1309, 1}, {1310, 16897795}, {1311, 1}, {1312, 16898051},
910 {1313, 1}, {1314, 16898307}, {1315, 1}, {1316, 16898563},
911 {1317, 1}, {1318, 16898819}, {1319, 1}, {1320, 16899075},
912 {1321, 1}, {1322, 16899331}, {1323, 1}, {1324, 16899587},
913 {1325, 1}, {1326, 16899843}, {1327, 1}, {1328, 2},
914 {1329, 16900099}, {1330, 16900355}, {1331, 16900611}, {1332, 16900867},
915 {1333, 16901123}, {1334, 16901379}, {1335, 16901635}, {1336, 16901891},
916 {1337, 16902147}, {1338, 16902403}, {1339, 16902659}, {1340, 16902915},
917 {1341, 16903171}, {1342, 16903427}, {1343, 16903683}, {1344, 16903939},
918 {1345, 16904195}, {1346, 16904451}, {1347, 16904707}, {1348, 16904963},
919 {1349, 16905219}, {1350, 16905475}, {1351, 16905731}, {1352, 16905987},
920 {1353, 16906243}, {1354, 16906499}, {1355, 16906755}, {1356, 16907011},
921 {1357, 16907267}, {1358, 16907523}, {1359, 16907779}, {1360, 16908035},
922 {1361, 16908291}, {1362, 16908547}, {1363, 16908803}, {1364, 16909059},
923 {1365, 16909315}, {1366, 16909571}, {1367, 2}, {1369, 1},
924 {1415, 33687043}, {1416, 1}, {1419, 2}, {1421, 1},
925 {1424, 2}, {1425, 1}, {1480, 2}, {1488, 1},
926 {1515, 2}, {1519, 1}, {1525, 2}, {1542, 1},
927 {1564, 2}, {1565, 1}, {1653, 33687555}, {1654, 33688067},
928 {1655, 33688579}, {1656, 33689091}, {1657, 1}, {1757, 2},
929 {1758, 1}, {1806, 2}, {1808, 1}, {1867, 2},
930 {1869, 1}, {1970, 2}, {1984, 1}, {2043, 2},
931 {2045, 1}, {2094, 2}, {2096, 1}, {2111, 2},
932 {2112, 1}, {2140, 2}, {2142, 1}, {2143, 2},
933 {2144, 1}, {2155, 2}, {2160, 1}, {2191, 2},
934 {2200, 1}, {2274, 2}, {2275, 1}, {2392, 33689603},
935 {2393, 33690115}, {2394, 33690627}, {2395, 33691139}, {2396, 33691651},
936 {2397, 33692163}, {2398, 33692675}, {2399, 33693187}, {2400, 1},
937 {2436, 2}, {2437, 1}, {2445, 2}, {2447, 1},
938 {2449, 2}, {2451, 1}, {2473, 2}, {2474, 1},
939 {2481, 2}, {2482, 1}, {2483, 2}, {2486, 1},
940 {2490, 2}, {2492, 1}, {2501, 2}, {2503, 1},
941 {2505, 2}, {2507, 1}, {2511, 2}, {2519, 1},
942 {2520, 2}, {2524, 33693699}, {2525, 33694211}, {2526, 2},
943 {2527, 33694723}, {2528, 1}, {2532, 2}, {2534, 1},
944 {2559, 2}, {2561, 1}, {2564, 2}, {2565, 1},
945 {2571, 2}, {2575, 1}, {2577, 2}, {2579, 1},
946 {2601, 2}, {2602, 1}, {2609, 2}, {2610, 1},
947 {2611, 33695235}, {2612, 2}, {2613, 1}, {2614, 33695747},
948 {2615, 2}, {2616, 1}, {2618, 2}, {2620, 1},
949 {2621, 2}, {2622, 1}, {2627, 2}, {2631, 1},
950 {2633, 2}, {2635, 1}, {2638, 2}, {2641, 1},
951 {2642, 2}, {2649, 33696259}, {2650, 33696771}, {2651, 33697283},
952 {2652, 1}, {2653, 2}, {2654, 33697795}, {2655, 2},
953 {2662, 1}, {2679, 2}, {2689, 1}, {2692, 2},
954 {2693, 1}, {2702, 2}, {2703, 1}, {2706, 2},
955 {2707, 1}, {2729, 2}, {2730, 1}, {2737, 2},
956 {2738, 1}, {2740, 2}, {2741, 1}, {2746, 2},
957 {2748, 1}, {2758, 2}, {2759, 1}, {2762, 2},
958 {2763, 1}, {2766, 2}, {2768, 1}, {2769, 2},
959 {2784, 1}, {2788, 2}, {2790, 1}, {2802, 2},
960 {2809, 1}, {2816, 2}, {2817, 1}, {2820, 2},
961 {2821, 1}, {2829, 2}, {2831, 1}, {2833, 2},
962 {2835, 1}, {2857, 2}, {2858, 1}, {2865, 2},
963 {2866, 1}, {2868, 2}, {2869, 1}, {2874, 2},
964 {2876, 1}, {2885, 2}, {2887, 1}, {2889, 2},
965 {2891, 1}, {2894, 2}, {2901, 1}, {2904, 2},
966 {2908, 33698307}, {2909, 33698819}, {2910, 2}, {2911, 1},
967 {2916, 2}, {2918, 1}, {2936, 2}, {2946, 1},
968 {2948, 2}, {2949, 1}, {2955, 2}, {2958, 1},
969 {2961, 2}, {2962, 1}, {2966, 2}, {2969, 1},
970 {2971, 2}, {2972, 1}, {2973, 2}, {2974, 1},
971 {2976, 2}, {2979, 1}, {2981, 2}, {2984, 1},
972 {2987, 2}, {2990, 1}, {3002, 2}, {3006, 1},
973 {3011, 2}, {3014, 1}, {3017, 2}, {3018, 1},
974 {3022, 2}, {3024, 1}, {3025, 2}, {3031, 1},
975 {3032, 2}, {3046, 1}, {3067, 2}, {3072, 1},
976 {3085, 2}, {3086, 1}, {3089, 2}, {3090, 1},
977 {3113, 2}, {3114, 1}, {3130, 2}, {3132, 1},
978 {3141, 2}, {3142, 1}, {3145, 2}, {3146, 1},
979 {3150, 2}, {3157, 1}, {3159, 2}, {3160, 1},
980 {3163, 2}, {3165, 1}, {3166, 2}, {3168, 1},
981 {3172, 2}, {3174, 1}, {3184, 2}, {3191, 1},
982 {3213, 2}, {3214, 1}, {3217, 2}, {3218, 1},
983 {3241, 2}, {3242, 1}, {3252, 2}, {3253, 1},
984 {3258, 2}, {3260, 1}, {3269, 2}, {3270, 1},
985 {3273, 2}, {3274, 1}, {3278, 2}, {3285, 1},
986 {3287, 2}, {3293, 1}, {3295, 2}, {3296, 1},
987 {3300, 2}, {3302, 1}, {3312, 2}, {3313, 1},
988 {3316, 2}, {3328, 1}, {3341, 2}, {3342, 1},
989 {3345, 2}, {3346, 1}, {3397, 2}, {3398, 1},
990 {3401, 2}, {3402, 1}, {3408, 2}, {3412, 1},
991 {3428, 2}, {3430, 1}, {3456, 2}, {3457, 1},
992 {3460, 2}, {3461, 1}, {3479, 2}, {3482, 1},
993 {3506, 2}, {3507, 1}, {3516, 2}, {3517, 1},
994 {3518, 2}, {3520, 1}, {3527, 2}, {3530, 1},
995 {3531, 2}, {3535, 1}, {3541, 2}, {3542, 1},
996 {3543, 2}, {3544, 1}, {3552, 2}, {3558, 1},
997 {3568, 2}, {3570, 1}, {3573, 2}, {3585, 1},
998 {3635, 33699331}, {3636, 1}, {3643, 2}, {3647, 1},
999 {3676, 2}, {3713, 1}, {3715, 2}, {3716, 1},
1000 {3717, 2}, {3718, 1}, {3723, 2}, {3724, 1},
1001 {3748, 2}, {3749, 1}, {3750, 2}, {3751, 1},
1002 {3763, 33699843}, {3764, 1}, {3774, 2}, {3776, 1},
1003 {3781, 2}, {3782, 1}, {3783, 2}, {3784, 1},
1004 {3791, 2}, {3792, 1}, {3802, 2}, {3804, 33700355},
1005 {3805, 33700867}, {3806, 1}, {3808, 2}, {3840, 1},
1006 {3852, 16924163}, {3853, 1}, {3907, 33701635}, {3908, 1},
1007 {3912, 2}, {3913, 1}, {3917, 33702147}, {3918, 1},
1008 {3922, 33702659}, {3923, 1}, {3927, 33703171}, {3928, 1},
1009 {3932, 33703683}, {3933, 1}, {3945, 33704195}, {3946, 1},
1010 {3949, 2}, {3953, 1}, {3955, 33704707}, {3956, 1},
1011 {3957, 33705219}, {3958, 33705731}, {3959, 50483459}, {3960, 33707011},
1012 {3961, 50484739}, {3962, 1}, {3969, 33706499}, {3970, 1},
1013 {3987, 33708291}, {3988, 1}, {3992, 2}, {3993, 1},
1014 {3997, 33708803}, {3998, 1}, {4002, 33709315}, {4003, 1},
1015 {4007, 33709827}, {4008, 1}, {4012, 33710339}, {4013, 1},
1016 {4025, 33710851}, {4026, 1}, {4029, 2}, {4030, 1},
1017 {4045, 2}, {4046, 1}, {4059, 2}, {4096, 1},
1018 {4256, 2}, {4295, 16934147}, {4296, 2}, {4301, 16934403},
1019 {4302, 2}, {4304, 1}, {4348, 16934659}, {4349, 1},
1020 {4447, 2}, {4449, 1}, {4681, 2}, {4682, 1},
1021 {4686, 2}, {4688, 1}, {4695, 2}, {4696, 1},
1022 {4697, 2}, {4698, 1}, {4702, 2}, {4704, 1},
1023 {4745, 2}, {4746, 1}, {4750, 2}, {4752, 1},
1024 {4785, 2}, {4786, 1}, {4790, 2}, {4792, 1},
1025 {4799, 2}, {4800, 1}, {4801, 2}, {4802, 1},
1026 {4806, 2}, {4808, 1}, {4823, 2}, {4824, 1},
1027 {4881, 2}, {4882, 1}, {4886, 2}, {4888, 1},
1028 {4955, 2}, {4957, 1}, {4989, 2}, {4992, 1},
1029 {5018, 2}, {5024, 1}, {5110, 2}, {5112, 16934915},
1030 {5113, 16935171}, {5114, 16935427}, {5115, 16935683}, {5116, 16935939},
1031 {5117, 16936195}, {5118, 2}, {5120, 1}, {5760, 2},
1032 {5761, 1}, {5789, 2}, {5792, 1}, {5881, 2},
1033 {5888, 1}, {5910, 2}, {5919, 1}, {5943, 2},
1034 {5952, 1}, {5972, 2}, {5984, 1}, {5997, 2},
1035 {5998, 1}, {6001, 2}, {6002, 1}, {6004, 2},
1036 {6016, 1}, {6068, 2}, {6070, 1}, {6110, 2},
1037 {6112, 1}, {6122, 2}, {6128, 1}, {6138, 2},
1038 {6144, 1}, {6150, 2}, {6151, 1}, {6155, 0},
1039 {6158, 2}, {6159, 0}, {6160, 1}, {6170, 2},
1040 {6176, 1}, {6265, 2}, {6272, 1}, {6315, 2},
1041 {6320, 1}, {6390, 2}, {6400, 1}, {6431, 2},
1042 {6432, 1}, {6444, 2}, {6448, 1}, {6460, 2},
1043 {6464, 1}, {6465, 2}, {6468, 1}, {6510, 2},
1044 {6512, 1}, {6517, 2}, {6528, 1}, {6572, 2},
1045 {6576, 1}, {6602, 2}, {6608, 1}, {6619, 2},
1046 {6622, 1}, {6684, 2}, {6686, 1}, {6751, 2},
1047 {6752, 1}, {6781, 2}, {6783, 1}, {6794, 2},
1048 {6800, 1}, {6810, 2}, {6816, 1}, {6830, 2},
1049 {6832, 1}, {6863, 2}, {6912, 1}, {6989, 2},
1050 {6992, 1}, {7039, 2}, {7040, 1}, {7156, 2},
1051 {7164, 1}, {7224, 2}, {7227, 1}, {7242, 2},
1052 {7245, 1}, {7296, 16867075}, {7297, 16867587}, {7298, 16870147},
1053 {7299, 16870915}, {7300, 16871171}, {7302, 16873219}, {7303, 16875011},
1054 {7304, 16936451}, {7305, 2}, {7312, 16936707}, {7313, 16936963},
1055 {7314, 16937219}, {7315, 16937475}, {7316, 16937731}, {7317, 16937987},
1056 {7318, 16938243}, {7319, 16938499}, {7320, 16938755}, {7321, 16939011},
1057 {7322, 16939267}, {7323, 16939523}, {7324, 16934659}, {7325, 16939779},
1058 {7326, 16940035}, {7327, 16940291}, {7328, 16940547}, {7329, 16940803},
1059 {7330, 16941059}, {7331, 16941315}, {7332, 16941571}, {7333, 16941827},
1060 {7334, 16942083}, {7335, 16942339}, {7336, 16942595}, {7337, 16942851},
1061 {7338, 16943107}, {7339, 16943363}, {7340, 16943619}, {7341, 16943875},
1062 {7342, 16944131}, {7343, 16944387}, {7344, 16944643}, {7345, 16944899},
1063 {7346, 16945155}, {7347, 16945411}, {7348, 16945667}, {7349, 16945923},
1064 {7350, 16946179}, {7351, 16946435}, {7352, 16946691}, {7353, 16946947},
1065 {7354, 16947203}, {7355, 2}, {7357, 16947459}, {7358, 16947715},
1066 {7359, 16947971}, {7360, 1}, {7368, 2}, {7376, 1},
1067 {7419, 2}, {7424, 1}, {7468, 16777219}, {7469, 16791043},
1068 {7470, 16777475}, {7471, 1}, {7472, 16777987}, {7473, 16778243},
1069 {7474, 16816131}, {7475, 16778755}, {7476, 16779011}, {7477, 16779267},
1070 {7478, 16779523}, {7479, 16779779}, {7480, 16780035}, {7481, 16780291},
1071 {7482, 16780547}, {7483, 1}, {7484, 16780803}, {7485, 16835843},
1072 {7486, 16781059}, {7487, 16781571}, {7488, 16782083}, {7489, 16782339},
1073 {7490, 16782851}, {7491, 16777219}, {7492, 16948227}, {7493, 16948483},
1074 {7494, 16948739}, {7495, 16777475}, {7496, 16777987}, {7497, 16778243},
1075 {7498, 16816387}, {7499, 16816643}, {7500, 16948995}, {7501, 16778755},
1076 {7502, 1}, {7503, 16779779}, {7504, 16780291}, {7505, 16807171},
1077 {7506, 16780803}, {7507, 16814851}, {7508, 16949251}, {7509, 16949507},
1078 {7510, 16781059}, {7511, 16782083}, {7512, 16782339}, {7513, 16949763},
1079 {7514, 16818435}, {7515, 16782595}, {7516, 16950019}, {7517, 16851971},
1080 {7518, 16852227}, {7519, 16852483}, {7520, 16856323}, {7521, 16856579},
1081 {7522, 16779267}, {7523, 16781571}, {7524, 16782339}, {7525, 16782595},
1082 {7526, 16851971}, {7527, 16852227}, {7528, 16855299}, {7529, 16856323},
1083 {7530, 16856579}, {7531, 1}, {7544, 16869891}, {7545, 1},
1084 {7579, 16950275}, {7580, 16777731}, {7581, 16950531}, {7582, 16793603},
1085 {7583, 16948995}, {7584, 16778499}, {7585, 16950787}, {7586, 16951043},
1086 {7587, 16951299}, {7588, 16817923}, {7589, 16817667}, {7590, 16951555},
1087 {7591, 16951811}, {7592, 16952067}, {7593, 16952323}, {7594, 16952579},
1088 {7595, 16952835}, {7596, 16953091}, {7597, 16953347}, {7598, 16818691},
1089 {7599, 16953603}, {7600, 16953859}, {7601, 16818947}, {7602, 16954115},
1090 {7603, 16954371}, {7604, 16820483}, {7605, 16954627}, {7606, 16839683},
1091 {7607, 16821507}, {7608, 16954883}, {7609, 16821763}, {7610, 16839939},
1092 {7611, 16783619}, {7612, 16955139}, {7613, 16955395}, {7614, 16822531},
1093 {7615, 16853507}, {7616, 1}, {7680, 16955651}, {7681, 1},
1094 {7682, 16955907}, {7683, 1}, {7684, 16956163}, {7685, 1},
1095 {7686, 16956419}, {7687, 1}, {7688, 16956675}, {7689, 1},
1096 {7690, 16956931}, {7691, 1}, {7692, 16957187}, {7693, 1},
1097 {7694, 16957443}, {7695, 1}, {7696, 16957699}, {7697, 1},
1098 {7698, 16957955}, {7699, 1}, {7700, 16958211}, {7701, 1},
1099 {7702, 16958467}, {7703, 1}, {7704, 16958723}, {7705, 1},
1100 {7706, 16958979}, {7707, 1}, {7708, 16959235}, {7709, 1},
1101 {7710, 16959491}, {7711, 1}, {7712, 16959747}, {7713, 1},
1102 {7714, 16960003}, {7715, 1}, {7716, 16960259}, {7717, 1},
1103 {7718, 16960515}, {7719, 1}, {7720, 16960771}, {7721, 1},
1104 {7722, 16961027}, {7723, 1}, {7724, 16961283}, {7725, 1},
1105 {7726, 16961539}, {7727, 1}, {7728, 16961795}, {7729, 1},
1106 {7730, 16962051}, {7731, 1}, {7732, 16962307}, {7733, 1},
1107 {7734, 16962563}, {7735, 1}, {7736, 16962819}, {7737, 1},
1108 {7738, 16963075}, {7739, 1}, {7740, 16963331}, {7741, 1},
1109 {7742, 16963587}, {7743, 1}, {7744, 16963843}, {7745, 1},
1110 {7746, 16964099}, {7747, 1}, {7748, 16964355}, {7749, 1},
1111 {7750, 16964611}, {7751, 1}, {7752, 16964867}, {7753, 1},
1112 {7754, 16965123}, {7755, 1}, {7756, 16965379}, {7757, 1},
1113 {7758, 16965635}, {7759, 1}, {7760, 16965891}, {7761, 1},
1114 {7762, 16966147}, {7763, 1}, {7764, 16966403}, {7765, 1},
1115 {7766, 16966659}, {7767, 1}, {7768, 16966915}, {7769, 1},
1116 {7770, 16967171}, {7771, 1}, {7772, 16967427}, {7773, 1},
1117 {7774, 16967683}, {7775, 1}, {7776, 16967939}, {7777, 1},
1118 {7778, 16968195}, {7779, 1}, {7780, 16968451}, {7781, 1},
1119 {7782, 16968707}, {7783, 1}, {7784, 16968963}, {7785, 1},
1120 {7786, 16969219}, {7787, 1}, {7788, 16969475}, {7789, 1},
1121 {7790, 16969731}, {7791, 1}, {7792, 16969987}, {7793, 1},
1122 {7794, 16970243}, {7795, 1}, {7796, 16970499}, {7797, 1},
1123 {7798, 16970755}, {7799, 1}, {7800, 16971011}, {7801, 1},
1124 {7802, 16971267}, {7803, 1}, {7804, 16971523}, {7805, 1},
1125 {7806, 16971779}, {7807, 1}, {7808, 16972035}, {7809, 1},
1126 {7810, 16972291}, {7811, 1}, {7812, 16972547}, {7813, 1},
1127 {7814, 16972803}, {7815, 1}, {7816, 16973059}, {7817, 1},
1128 {7818, 16973315}, {7819, 1}, {7820, 16973571}, {7821, 1},
1129 {7822, 16973827}, {7823, 1}, {7824, 16974083}, {7825, 1},
1130 {7826, 16974339}, {7827, 1}, {7828, 16974595}, {7829, 1},
1131 {7834, 33752067}, {7835, 16967939}, {7836, 1}, {7838, 33752579},
1132 {7839, 1}, {7840, 16975875}, {7841, 1}, {7842, 16976131},
1133 {7843, 1}, {7844, 16976387}, {7845, 1}, {7846, 16976643},
1134 {7847, 1}, {7848, 16976899}, {7849, 1}, {7850, 16977155},
1135 {7851, 1}, {7852, 16977411}, {7853, 1}, {7854, 16977667},
1136 {7855, 1}, {7856, 16977923}, {7857, 1}, {7858, 16978179},
1137 {7859, 1}, {7860, 16978435}, {7861, 1}, {7862, 16978691},
1138 {7863, 1}, {7864, 16978947}, {7865, 1}, {7866, 16979203},
1139 {7867, 1}, {7868, 16979459}, {7869, 1}, {7870, 16979715},
1140 {7871, 1}, {7872, 16979971}, {7873, 1}, {7874, 16980227},
1141 {7875, 1}, {7876, 16980483}, {7877, 1}, {7878, 16980739},
1142 {7879, 1}, {7880, 16980995}, {7881, 1}, {7882, 16981251},
1143 {7883, 1}, {7884, 16981507}, {7885, 1}, {7886, 16981763},
1144 {7887, 1}, {7888, 16982019}, {7889, 1}, {7890, 16982275},
1145 {7891, 1}, {7892, 16982531}, {7893, 1}, {7894, 16982787},
1146 {7895, 1}, {7896, 16983043}, {7897, 1}, {7898, 16983299},
1147 {7899, 1}, {7900, 16983555}, {7901, 1}, {7902, 16983811},
1148 {7903, 1}, {7904, 16984067}, {7905, 1}, {7906, 16984323},
1149 {7907, 1}, {7908, 16984579}, {7909, 1}, {7910, 16984835},
1150 {7911, 1}, {7912, 16985091}, {7913, 1}, {7914, 16985347},
1151 {7915, 1}, {7916, 16985603}, {7917, 1}, {7918, 16985859},
1152 {7919, 1}, {7920, 16986115}, {7921, 1}, {7922, 16986371},
1153 {7923, 1}, {7924, 16986627}, {7925, 1}, {7926, 16986883},
1154 {7927, 1}, {7928, 16987139}, {7929, 1}, {7930, 16987395},
1155 {7931, 1}, {7932, 16987651}, {7933, 1}, {7934, 16987907},
1156 {7935, 1}, {7944, 16988163}, {7945, 16988419}, {7946, 16988675},
1157 {7947, 16988931}, {7948, 16989187}, {7949, 16989443}, {7950, 16989699},
1158 {7951, 16989955}, {7952, 1}, {7958, 2}, {7960, 16990211},
1159 {7961, 16990467}, {7962, 16990723}, {7963, 16990979}, {7964, 16991235},
1160 {7965, 16991491}, {7966, 2}, {7968, 1}, {7976, 16991747},
1161 {7977, 16992003}, {7978, 16992259}, {7979, 16992515}, {7980, 16992771},
1162 {7981, 16993027}, {7982, 16993283}, {7983, 16993539}, {7984, 1},
1163 {7992, 16993795}, {7993, 16994051}, {7994, 16994307}, {7995, 16994563},
1164 {7996, 16994819}, {7997, 16995075}, {7998, 16995331}, {7999, 16995587},
1165 {8000, 1}, {8006, 2}, {8008, 16995843}, {8009, 16996099},
1166 {8010, 16996355}, {8011, 16996611}, {8012, 16996867}, {8013, 16997123},
1167 {8014, 2}, {8016, 1}, {8024, 2}, {8025, 16997379},
1168 {8026, 2}, {8027, 16997635}, {8028, 2}, {8029, 16997891},
1169 {8030, 2}, {8031, 16998147}, {8032, 1}, {8040, 16998403},
1170 {8041, 16998659}, {8042, 16998915}, {8043, 16999171}, {8044, 16999427},
1171 {8045, 16999683}, {8046, 16999939}, {8047, 17000195}, {8048, 1},
1172 {8049, 16849923}, {8050, 1}, {8051, 16850179}, {8052, 1},
1173 {8053, 16850435}, {8054, 1}, {8055, 16850691}, {8056, 1},
1174 {8057, 16850947}, {8058, 1}, {8059, 16851203}, {8060, 1},
1175 {8061, 16851459}, {8062, 2}, {8064, 33777667}, {8065, 33778179},
1176 {8066, 33778691}, {8067, 33779203}, {8068, 33779715}, {8069, 33780227},
1177 {8070, 33780739}, {8071, 33781251}, {8072, 33777667}, {8073, 33778179},
1178 {8074, 33778691}, {8075, 33779203}, {8076, 33779715}, {8077, 33780227},
1179 {8078, 33780739}, {8079, 33781251}, {8080, 33781763}, {8081, 33782275},
1180 {8082, 33782787}, {8083, 33783299}, {8084, 33783811}, {8085, 33784323},
1181 {8086, 33784835}, {8087, 33785347}, {8088, 33781763}, {8089, 33782275},
1182 {8090, 33782787}, {8091, 33783299}, {8092, 33783811}, {8093, 33784323},
1183 {8094, 33784835}, {8095, 33785347}, {8096, 33785859}, {8097, 33786371},
1184 {8098, 33786883}, {8099, 33787395}, {8100, 33787907}, {8101, 33788419},
1185 {8102, 33788931}, {8103, 33789443}, {8104, 33785859}, {8105, 33786371},
1186 {8106, 33786883}, {8107, 33787395}, {8108, 33787907}, {8109, 33788419},
1187 {8110, 33788931}, {8111, 33789443}, {8112, 1}, {8114, 33789955},
1188 {8115, 33790467}, {8116, 33790979}, {8117, 2}, {8118, 1},
1189 {8119, 33791491}, {8120, 17014787}, {8121, 17015043}, {8122, 17012739},
1190 {8123, 16849923}, {8124, 33790467}, {8125, 33792515}, {8126, 16846851},
1191 {8127, 33792515}, {8128, 33793027}, {8129, 50570755}, {8130, 33794307},
1192 {8131, 33794819}, {8132, 33795331}, {8133, 2}, {8134, 1},
1193 {8135, 33795843}, {8136, 17019139}, {8137, 16850179}, {8138, 17017091},
1194 {8139, 16850435}, {8140, 33794819}, {8141, 50573827}, {8142, 50574595},
1195 {8143, 50575363}, {8144, 1}, {8147, 17021699}, {8148, 2},
1196 {8150, 1}, {8152, 17021955}, {8153, 17022211}, {8154, 17022467},
1197 {8155, 16850691}, {8156, 2}, {8157, 50577155}, {8158, 50577923},
1198 {8159, 50578691}, {8160, 1}, {8163, 17025027}, {8164, 1},
1199 {8168, 17025283}, {8169, 17025539}, {8170, 17025795}, {8171, 16851203},
1200 {8172, 17026051}, {8173, 50580739}, {8174, 50403587}, {8175, 17027075},
1201 {8176, 2}, {8178, 33804547}, {8179, 33805059}, {8180, 33805571},
1202 {8181, 2}, {8182, 1}, {8183, 33806083}, {8184, 17029379},
1203 {8185, 16850947}, {8186, 17027331}, {8187, 16851459}, {8188, 33805059},
1204 {8189, 33562883}, {8190, 33799939}, {8191, 2}, {8192, 16783875},
1205 {8203, 0}, {8204, 1}, {8206, 2}, {8208, 1},
1206 {8209, 17029635}, {8210, 1}, {8215, 33807107}, {8216, 1},
1207 {8228, 2}, {8231, 1}, {8232, 2}, {8239, 16783875},
1208 {8240, 1}, {8243, 33807619}, {8244, 50585347}, {8245, 1},
1209 {8246, 33808899}, {8247, 50586627}, {8248, 1}, {8252, 33810179},
1210 {8253, 1}, {8254, 33810691}, {8255, 1}, {8263, 33811203},
1211 {8264, 33811715}, {8265, 33812227}, {8266, 1}, {8279, 67362051},
1212 {8280, 1}, {8287, 16783875}, {8288, 0}, {8289, 2},
1213 {8292, 0}, {8293, 2}, {8304, 17035523}, {8305, 16779267},
1214 {8306, 2}, {8308, 16787715}, {8309, 17035779}, {8310, 17036035},
1215 {8311, 17036291}, {8312, 17036547}, {8313, 17036803}, {8314, 17037059},
1216 {8315, 17037315}, {8316, 17037571}, {8317, 17037827}, {8318, 17038083},
1217 {8319, 16780547}, {8320, 17035523}, {8321, 16786947}, {8322, 16785155},
1218 {8323, 16785411}, {8324, 16787715}, {8325, 17035779}, {8326, 17036035},
1219 {8327, 17036291}, {8328, 17036547}, {8329, 17036803}, {8330, 17037059},
1220 {8331, 17037315}, {8332, 17037571}, {8333, 17037827}, {8334, 17038083},
1221 {8335, 2}, {8336, 16777219}, {8337, 16778243}, {8338, 16780803},
1222 {8339, 16783107}, {8340, 16816387}, {8341, 16779011}, {8342, 16779779},
1223 {8343, 16780035}, {8344, 16780291}, {8345, 16780547}, {8346, 16781059},
1224 {8347, 16781827}, {8348, 16782083}, {8349, 2}, {8352, 1},
1225 {8360, 33558787}, {8361, 1}, {8385, 2}, {8400, 1},
1226 {8433, 2}, {8448, 50592771}, {8449, 50593539}, {8450, 16777731},
1227 {8451, 33817091}, {8452, 1}, {8453, 50594819}, {8454, 50595587},
1228 {8455, 16816643}, {8456, 1}, {8457, 33819139}, {8458, 16778755},
1229 {8459, 16779011}, {8463, 16802051}, {8464, 16779267}, {8466, 16780035},
1230 {8468, 1}, {8469, 16780547}, {8470, 33557763}, {8471, 1},
1231 {8473, 16781059}, {8474, 16781315}, {8475, 16781571}, {8478, 1},
1232 {8480, 33819651}, {8481, 50597379}, {8482, 33820931}, {8483, 1},
1233 {8484, 16783619}, {8485, 1}, {8486, 16857091}, {8487, 1},
1234 {8488, 16783619}, {8489, 1}, {8490, 16779779}, {8491, 16790787},
1235 {8492, 16777475}, {8493, 16777731}, {8494, 1}, {8495, 16778243},
1236 {8497, 16778499}, {8498, 2}, {8499, 16780291}, {8500, 16780803},
1237 {8501, 17044227}, {8502, 17044483}, {8503, 17044739}, {8504, 17044995},
1238 {8505, 16779267}, {8506, 1}, {8507, 50599683}, {8508, 16855043},
1239 {8509, 16852227}, {8511, 16855043}, {8512, 17046019}, {8513, 1},
1240 {8517, 16777987}, {8519, 16778243}, {8520, 16779267}, {8521, 16779523},
1241 {8522, 1}, {8528, 50600707}, {8529, 50601475}, {8530, 67379459},
1242 {8531, 50603267}, {8532, 50604035}, {8533, 50604803}, {8534, 50605571},
1243 {8535, 50606339}, {8536, 50607107}, {8537, 50607875}, {8538, 50608643},
1244 {8539, 50609411}, {8540, 50610179}, {8541, 50610947}, {8542, 50611715},
1245 {8543, 33564419}, {8544, 16779267}, {8545, 33835267}, {8546, 50612995},
1246 {8547, 33836547}, {8548, 16782595}, {8549, 33837059}, {8550, 50614787},
1247 {8551, 67392771}, {8552, 33839363}, {8553, 16783107}, {8554, 33839875},
1248 {8555, 50617603}, {8556, 16780035}, {8557, 16777731}, {8558, 16777987},
1249 {8559, 16780291}, {8560, 16779267}, {8561, 33835267}, {8562, 50612483},
1250 {8563, 33836547}, {8564, 16782595}, {8565, 33837059}, {8566, 50614787},
1251 {8567, 67392771}, {8568, 33839363}, {8569, 16783107}, {8570, 33839875},
1252 {8571, 50617603}, {8572, 16780035}, {8573, 16777731}, {8574, 16777987},
1253 {8575, 16780291}, {8576, 1}, {8579, 2}, {8580, 1},
1254 {8585, 50618371}, {8586, 1}, {8588, 2}, {8592, 1},
1255 {8748, 33841923}, {8749, 50619651}, {8750, 1}, {8751, 33843203},
1256 {8752, 50620931}, {8753, 1}, {9001, 17067267}, {9002, 17067523},
1257 {9003, 1}, {9255, 2}, {9280, 1}, {9291, 2},
1258 {9312, 16786947}, {9313, 16785155}, {9314, 16785411}, {9315, 16787715},
1259 {9316, 17035779}, {9317, 17036035}, {9318, 17036291}, {9319, 17036547},
1260 {9320, 17036803}, {9321, 33825539}, {9322, 33564163}, {9323, 33844995},
1261 {9324, 33845507}, {9325, 33846019}, {9326, 33846531}, {9327, 33847043},
1262 {9328, 33847555}, {9329, 33848067}, {9330, 33848579}, {9331, 33849091},
1263 {9332, 50626819}, {9333, 50627587}, {9334, 50628355}, {9335, 50629123},
1264 {9336, 50629891}, {9337, 50630659}, {9338, 50631427}, {9339, 50632195},
1265 {9340, 50632963}, {9341, 67410947}, {9342, 67411971}, {9343, 67412995},
1266 {9344, 67414019}, {9345, 67415043}, {9346, 67416067}, {9347, 67417091},
1267 {9348, 67418115}, {9349, 67419139}, {9350, 67420163}, {9351, 67421187},
1268 {9352, 2}, {9372, 50644995}, {9373, 50645763}, {9374, 50646531},
1269 {9375, 50647299}, {9376, 50648067}, {9377, 50648835}, {9378, 50649603},
1270 {9379, 50650371}, {9380, 50651139}, {9381, 50651907}, {9382, 50652675},
1271 {9383, 50653443}, {9384, 50654211}, {9385, 50654979}, {9386, 50655747},
1272 {9387, 50656515}, {9388, 50657283}, {9389, 50658051}, {9390, 50658819},
1273 {9391, 50659587}, {9392, 50660355}, {9393, 50661123}, {9394, 50661891},
1274 {9395, 50662659}, {9396, 50663427}, {9397, 50664195}, {9398, 16777219},
1275 {9399, 16777475}, {9400, 16777731}, {9401, 16777987}, {9402, 16778243},
1276 {9403, 16778499}, {9404, 16778755}, {9405, 16779011}, {9406, 16779267},
1277 {9407, 16779523}, {9408, 16779779}, {9409, 16780035}, {9410, 16780291},
1278 {9411, 16780547}, {9412, 16780803}, {9413, 16781059}, {9414, 16781315},
1279 {9415, 16781571}, {9416, 16781827}, {9417, 16782083}, {9418, 16782339},
1280 {9419, 16782595}, {9420, 16782851}, {9421, 16783107}, {9422, 16783363},
1281 {9423, 16783619}, {9424, 16777219}, {9425, 16777475}, {9426, 16777731},
1282 {9427, 16777987}, {9428, 16778243}, {9429, 16778499}, {9430, 16778755},
1283 {9431, 16779011}, {9432, 16779267}, {9433, 16779523}, {9434, 16779779},
1284 {9435, 16780035}, {9436, 16780291}, {9437, 16780547}, {9438, 16780803},
1285 {9439, 16781059}, {9440, 16781315}, {9441, 16781571}, {9442, 16781827},
1286 {9443, 16782083}, {9444, 16782339}, {9445, 16782595}, {9446, 16782851},
1287 {9447, 16783107}, {9448, 16783363}, {9449, 16783619}, {9450, 17035523},
1288 {9451, 1}, {10764, 67396355}, {10765, 1}, {10868, 50664963},
1289 {10869, 33888515}, {10870, 50665475}, {10871, 1}, {10972, 33889027},
1290 {10973, 1}, {11124, 2}, {11126, 1}, {11158, 2},
1291 {11159, 1}, {11264, 17112323}, {11265, 17112579}, {11266, 17112835},
1292 {11267, 17113091}, {11268, 17113347}, {11269, 17113603}, {11270, 17113859},
1293 {11271, 17114115}, {11272, 17114371}, {11273, 17114627}, {11274, 17114883},
1294 {11275, 17115139}, {11276, 17115395}, {11277, 17115651}, {11278, 17115907},
1295 {11279, 17116163}, {11280, 17116419}, {11281, 17116675}, {11282, 17116931},
1296 {11283, 17117187}, {11284, 17117443}, {11285, 17117699}, {11286, 17117955},
1297 {11287, 17118211}, {11288, 17118467}, {11289, 17118723}, {11290, 17118979},
1298 {11291, 17119235}, {11292, 17119491}, {11293, 17119747}, {11294, 17120003},
1299 {11295, 17120259}, {11296, 17120515}, {11297, 17120771}, {11298, 17121027},
1300 {11299, 17121283}, {11300, 17121539}, {11301, 17121795}, {11302, 17122051},
1301 {11303, 17122307}, {11304, 17122563}, {11305, 17122819}, {11306, 17123075},
1302 {11307, 17123331}, {11308, 17123587}, {11309, 17123843}, {11310, 17124099},
1303 {11311, 17124355}, {11312, 1}, {11360, 17124611}, {11361, 1},
1304 {11362, 17124867}, {11363, 17125123}, {11364, 17125379}, {11365, 1},
1305 {11367, 17125635}, {11368, 1}, {11369, 17125891}, {11370, 1},
1306 {11371, 17126147}, {11372, 1}, {11373, 16948483}, {11374, 16953091},
1307 {11375, 16948227}, {11376, 16950275}, {11377, 1}, {11378, 17126403},
1308 {11379, 1}, {11381, 17126659}, {11382, 1}, {11388, 16779523},
1309 {11389, 16782595}, {11390, 17126915}, {11391, 17127171}, {11392, 17127427},
1310 {11393, 1}, {11394, 17127683}, {11395, 1}, {11396, 17127939},
1311 {11397, 1}, {11398, 17128195}, {11399, 1}, {11400, 17128451},
1312 {11401, 1}, {11402, 17128707}, {11403, 1}, {11404, 17128963},
1313 {11405, 1}, {11406, 17129219}, {11407, 1}, {11408, 17129475},
1314 {11409, 1}, {11410, 17129731}, {11411, 1}, {11412, 17129987},
1315 {11413, 1}, {11414, 17130243}, {11415, 1}, {11416, 17130499},
1316 {11417, 1}, {11418, 17130755}, {11419, 1}, {11420, 17131011},
1317 {11421, 1}, {11422, 17131267}, {11423, 1}, {11424, 17131523},
1318 {11425, 1}, {11426, 17131779}, {11427, 1}, {11428, 17132035},
1319 {11429, 1}, {11430, 17132291}, {11431, 1}, {11432, 17132547},
1320 {11433, 1}, {11434, 17132803}, {11435, 1}, {11436, 17133059},
1321 {11437, 1}, {11438, 17133315}, {11439, 1}, {11440, 17133571},
1322 {11441, 1}, {11442, 17133827}, {11443, 1}, {11444, 17134083},
1323 {11445, 1}, {11446, 17134339}, {11447, 1}, {11448, 17134595},
1324 {11449, 1}, {11450, 17134851}, {11451, 1}, {11452, 17135107},
1325 {11453, 1}, {11454, 17135363}, {11455, 1}, {11456, 17135619},
1326 {11457, 1}, {11458, 17135875}, {11459, 1}, {11460, 17136131},
1327 {11461, 1}, {11462, 17136387}, {11463, 1}, {11464, 17136643},
1328 {11465, 1}, {11466, 17136899}, {11467, 1}, {11468, 17137155},
1329 {11469, 1}, {11470, 17137411}, {11471, 1}, {11472, 17137667},
1330 {11473, 1}, {11474, 17137923}, {11475, 1}, {11476, 17138179},
1331 {11477, 1}, {11478, 17138435}, {11479, 1}, {11480, 17138691},
1332 {11481, 1}, {11482, 17138947}, {11483, 1}, {11484, 17139203},
1333 {11485, 1}, {11486, 17139459}, {11487, 1}, {11488, 17139715},
1334 {11489, 1}, {11490, 17139971}, {11491, 1}, {11499, 17140227},
1335 {11500, 1}, {11501, 17140483}, {11502, 1}, {11506, 17140739},
1336 {11507, 1}, {11508, 2}, {11513, 1}, {11558, 2},
1337 {11559, 1}, {11560, 2}, {11565, 1}, {11566, 2},
1338 {11568, 1}, {11624, 2}, {11631, 17140995}, {11632, 1},
1339 {11633, 2}, {11647, 1}, {11671, 2}, {11680, 1},
1340 {11687, 2}, {11688, 1}, {11695, 2}, {11696, 1},
1341 {11703, 2}, {11704, 1}, {11711, 2}, {11712, 1},
1342 {11719, 2}, {11720, 1}, {11727, 2}, {11728, 1},
1343 {11735, 2}, {11736, 1}, {11743, 2}, {11744, 1},
1344 {11870, 2}, {11904, 1}, {11930, 2}, {11931, 1},
1345 {11935, 17141251}, {11936, 1}, {12019, 17141507}, {12020, 2},
1346 {12032, 17141763}, {12033, 17142019}, {12034, 17142275}, {12035, 17142531},
1347 {12036, 17142787}, {12037, 17143043}, {12038, 17143299}, {12039, 17143555},
1348 {12040, 17143811}, {12041, 17144067}, {12042, 17144323}, {12043, 17144579},
1349 {12044, 17144835}, {12045, 17145091}, {12046, 17145347}, {12047, 17145603},
1350 {12048, 17145859}, {12049, 17146115}, {12050, 17146371}, {12051, 17146627},
1351 {12052, 17146883}, {12053, 17147139}, {12054, 17147395}, {12055, 17147651},
1352 {12056, 17147907}, {12057, 17148163}, {12058, 17148419}, {12059, 17148675},
1353 {12060, 17148931}, {12061, 17149187}, {12062, 17149443}, {12063, 17149699},
1354 {12064, 17149955}, {12065, 17150211}, {12066, 17150467}, {12067, 17150723},
1355 {12068, 17150979}, {12069, 17151235}, {12070, 17151491}, {12071, 17151747},
1356 {12072, 17152003}, {12073, 17152259}, {12074, 17152515}, {12075, 17152771},
1357 {12076, 17153027}, {12077, 17153283}, {12078, 17153539}, {12079, 17153795},
1358 {12080, 17154051}, {12081, 17154307}, {12082, 17154563}, {12083, 17154819},
1359 {12084, 17155075}, {12085, 17155331}, {12086, 17155587}, {12087, 17155843},
1360 {12088, 17156099}, {12089, 17156355}, {12090, 17156611}, {12091, 17156867},
1361 {12092, 17157123}, {12093, 17157379}, {12094, 17157635}, {12095, 17157891},
1362 {12096, 17158147}, {12097, 17158403}, {12098, 17158659}, {12099, 17158915},
1363 {12100, 17159171}, {12101, 17159427}, {12102, 17159683}, {12103, 17159939},
1364 {12104, 17160195}, {12105, 17160451}, {12106, 17160707}, {12107, 17160963},
1365 {12108, 17161219}, {12109, 17161475}, {12110, 17161731}, {12111, 17161987},
1366 {12112, 17162243}, {12113, 17162499}, {12114, 17162755}, {12115, 17163011},
1367 {12116, 17163267}, {12117, 17163523}, {12118, 17163779}, {12119, 17164035},
1368 {12120, 17164291}, {12121, 17164547}, {12122, 17164803}, {12123, 17165059},
1369 {12124, 17165315}, {12125, 17165571}, {12126, 17165827}, {12127, 17166083},
1370 {12128, 17166339}, {12129, 17166595}, {12130, 17166851}, {12131, 17167107},
1371 {12132, 17167363}, {12133, 17167619}, {12134, 17167875}, {12135, 17168131},
1372 {12136, 17168387}, {12137, 17168643}, {12138, 17168899}, {12139, 17169155},
1373 {12140, 17169411}, {12141, 17169667}, {12142, 17169923}, {12143, 17170179},
1374 {12144, 17170435}, {12145, 17170691}, {12146, 17170947}, {12147, 17171203},
1375 {12148, 17171459}, {12149, 17171715}, {12150, 17171971}, {12151, 17172227},
1376 {12152, 17172483}, {12153, 17172739}, {12154, 17172995}, {12155, 17173251},
1377 {12156, 17173507}, {12157, 17173763}, {12158, 17174019}, {12159, 17174275},
1378 {12160, 17174531}, {12161, 17174787}, {12162, 17175043}, {12163, 17175299},
1379 {12164, 17175555}, {12165, 17175811}, {12166, 17176067}, {12167, 17176323},
1380 {12168, 17176579}, {12169, 17176835}, {12170, 17177091}, {12171, 17177347},
1381 {12172, 17177603}, {12173, 17177859}, {12174, 17178115}, {12175, 17178371},
1382 {12176, 17178627}, {12177, 17178883}, {12178, 17179139}, {12179, 17179395},
1383 {12180, 17179651}, {12181, 17179907}, {12182, 17180163}, {12183, 17180419},
1384 {12184, 17180675}, {12185, 17180931}, {12186, 17181187}, {12187, 17181443},
1385 {12188, 17181699}, {12189, 17181955}, {12190, 17182211}, {12191, 17182467},
1386 {12192, 17182723}, {12193, 17182979}, {12194, 17183235}, {12195, 17183491},
1387 {12196, 17183747}, {12197, 17184003}, {12198, 17184259}, {12199, 17184515},
1388 {12200, 17184771}, {12201, 17185027}, {12202, 17185283}, {12203, 17185539},
1389 {12204, 17185795}, {12205, 17186051}, {12206, 17186307}, {12207, 17186563},
1390 {12208, 17186819}, {12209, 17187075}, {12210, 17187331}, {12211, 17187587},
1391 {12212, 17187843}, {12213, 17188099}, {12214, 17188355}, {12215, 17188611},
1392 {12216, 17188867}, {12217, 17189123}, {12218, 17189379}, {12219, 17189635},
1393 {12220, 17189891}, {12221, 17190147}, {12222, 17190403}, {12223, 17190659},
1394 {12224, 17190915}, {12225, 17191171}, {12226, 17191427}, {12227, 17191683},
1395 {12228, 17191939}, {12229, 17192195}, {12230, 17192451}, {12231, 17192707},
1396 {12232, 17192963}, {12233, 17193219}, {12234, 17193475}, {12235, 17193731},
1397 {12236, 17193987}, {12237, 17194243}, {12238, 17194499}, {12239, 17194755},
1398 {12240, 17195011}, {12241, 17195267}, {12242, 17195523}, {12243, 17195779},
1399 {12244, 17196035}, {12245, 17196291}, {12246, 2}, {12288, 16783875},
1400 {12289, 1}, {12290, 17196547}, {12291, 1}, {12342, 17196803},
1401 {12343, 1}, {12344, 17147651}, {12345, 17197059}, {12346, 17197315},
1402 {12347, 1}, {12352, 2}, {12353, 1}, {12439, 2},
1403 {12441, 1}, {12443, 33974787}, {12444, 33975299}, {12445, 1},
1404 {12447, 33975811}, {12448, 1}, {12543, 33976323}, {12544, 2},
1405 {12549, 1}, {12592, 2}, {12593, 17199619}, {12594, 17199875},
1406 {12595, 17200131}, {12596, 17200387}, {12597, 17200643}, {12598, 17200899},
1407 {12599, 17201155}, {12600, 17201411}, {12601, 17201667}, {12602, 17201923},
1408 {12603, 17202179}, {12604, 17202435}, {12605, 17202691}, {12606, 17202947},
1409 {12607, 17203203}, {12608, 17203459}, {12609, 17203715}, {12610, 17203971},
1410 {12611, 17204227}, {12612, 17204483}, {12613, 17204739}, {12614, 17204995},
1411 {12615, 17205251}, {12616, 17205507}, {12617, 17205763}, {12618, 17206019},
1412 {12619, 17206275}, {12620, 17206531}, {12621, 17206787}, {12622, 17207043},
1413 {12623, 17207299}, {12624, 17207555}, {12625, 17207811}, {12626, 17208067},
1414 {12627, 17208323}, {12628, 17208579}, {12629, 17208835}, {12630, 17209091},
1415 {12631, 17209347}, {12632, 17209603}, {12633, 17209859}, {12634, 17210115},
1416 {12635, 17210371}, {12636, 17210627}, {12637, 17210883}, {12638, 17211139},
1417 {12639, 17211395}, {12640, 17211651}, {12641, 17211907}, {12642, 17212163},
1418 {12643, 17212419}, {12644, 2}, {12645, 17212675}, {12646, 17212931},
1419 {12647, 17213187}, {12648, 17213443}, {12649, 17213699}, {12650, 17213955},
1420 {12651, 17214211}, {12652, 17214467}, {12653, 17214723}, {12654, 17214979},
1421 {12655, 17215235}, {12656, 17215491}, {12657, 17215747}, {12658, 17216003},
1422 {12659, 17216259}, {12660, 17216515}, {12661, 17216771}, {12662, 17217027},
1423 {12663, 17217283}, {12664, 17217539}, {12665, 17217795}, {12666, 17218051},
1424 {12667, 17218307}, {12668, 17218563}, {12669, 17218819}, {12670, 17219075},
1425 {12671, 17219331}, {12672, 17219587}, {12673, 17219843}, {12674, 17220099},
1426 {12675, 17220355}, {12676, 17220611}, {12677, 17220867}, {12678, 17221123},
1427 {12679, 17221379}, {12680, 17221635}, {12681, 17221891}, {12682, 17222147},
1428 {12683, 17222403}, {12684, 17222659}, {12685, 17222915}, {12686, 17223171},
1429 {12687, 2}, {12688, 1}, {12690, 17141763}, {12691, 17143299},
1430 {12692, 17223427}, {12693, 17223683}, {12694, 17223939}, {12695, 17224195},
1431 {12696, 17224451}, {12697, 17224707}, {12698, 17142787}, {12699, 17224963},
1432 {12700, 17225219}, {12701, 17225475}, {12702, 17225731}, {12703, 17143811},
1433 {12704, 1}, {12772, 2}, {12784, 1}, {12800, 50780419},
1434 {12801, 50781187}, {12802, 50781955}, {12803, 50782723}, {12804, 50783491},
1435 {12805, 50784259}, {12806, 50785027}, {12807, 50785795}, {12808, 50786563},
1436 {12809, 50787331}, {12810, 50788099}, {12811, 50788867}, {12812, 50789635},
1437 {12813, 50790403}, {12814, 50791171}, {12815, 50791939}, {12816, 50792707},
1438 {12817, 50793475}, {12818, 50794243}, {12819, 50795011}, {12820, 50795779},
1439 {12821, 50796547}, {12822, 50797315}, {12823, 50798083}, {12824, 50798851},
1440 {12825, 50799619}, {12826, 50800387}, {12827, 50801155}, {12828, 50801923},
1441 {12829, 67579907}, {12830, 67580931}, {12831, 2}, {12832, 50804739},
1442 {12833, 50805507}, {12834, 50806275}, {12835, 50807043}, {12836, 50807811},
1443 {12837, 50808579}, {12838, 50809347}, {12839, 50810115}, {12840, 50810883},
1444 {12841, 50811651}, {12842, 50812419}, {12843, 50813187}, {12844, 50813955},
1445 {12845, 50814723}, {12846, 50815491}, {12847, 50816259}, {12848, 50817027},
1446 {12849, 50817795}, {12850, 50818563}, {12851, 50819331}, {12852, 50820099},
1447 {12853, 50820867}, {12854, 50821635}, {12855, 50822403}, {12856, 50823171},
1448 {12857, 50823939}, {12858, 50824707}, {12859, 50825475}, {12860, 50826243},
1449 {12861, 50827011}, {12862, 50827779}, {12863, 50828547}, {12864, 50829315},
1450 {12865, 50830083}, {12866, 50830851}, {12867, 50831619}, {12868, 17277955},
1451 {12869, 17278211}, {12870, 17158659}, {12871, 17278467}, {12872, 1},
1452 {12880, 50833155}, {12881, 33845251}, {12882, 34056707}, {12883, 33562371},
1453 {12884, 34057219}, {12885, 34057731}, {12886, 34058243}, {12887, 34058755},
1454 {12888, 34059267}, {12889, 34059779}, {12890, 34060291}, {12891, 33827331},
1455 {12892, 33826563}, {12893, 34060803}, {12894, 34061315}, {12895, 34061827},
1456 {12896, 17199619}, {12897, 17200387}, {12898, 17201155}, {12899, 17201667},
1457 {12900, 17203715}, {12901, 17203971}, {12902, 17204739}, {12903, 17205251},
1458 {12904, 17205507}, {12905, 17206019}, {12906, 17206275}, {12907, 17206531},
1459 {12908, 17206787}, {12909, 17207043}, {12910, 17236995}, {12911, 17237763},
1460 {12912, 17238531}, {12913, 17239299}, {12914, 17240067}, {12915, 17240835},
1461 {12916, 17241603}, {12917, 17242371}, {12918, 17243139}, {12919, 17243907},
1462 {12920, 17244675}, {12921, 17245443}, {12922, 17246211}, {12923, 17246979},
1463 {12924, 34062339}, {12925, 34062851}, {12926, 17286147}, {12927, 1},
1464 {12928, 17141763}, {12929, 17143299}, {12930, 17223427}, {12931, 17223683},
1465 {12932, 17253635}, {12933, 17254403}, {12934, 17255171}, {12935, 17144579},
1466 {12936, 17256707}, {12937, 17147651}, {12938, 17160451}, {12939, 17163523},
1467 {12940, 17163267}, {12941, 17160707}, {12942, 17184259}, {12943, 17149699},
1468 {12944, 17159939}, {12945, 17263619}, {12946, 17264387}, {12947, 17265155},
1469 {12948, 17265923}, {12949, 17266691}, {12950, 17267459}, {12951, 17268227},
1470 {12952, 17268995}, {12953, 17286403}, {12954, 17286659}, {12955, 17151235},
1471 {12956, 17286915}, {12957, 17287171}, {12958, 17287427}, {12959, 17287683},
1472 {12960, 17287939}, {12961, 17275907}, {12962, 17288195}, {12963, 17288451},
1473 {12964, 17223939}, {12965, 17224195}, {12966, 17224451}, {12967, 17288707},
1474 {12968, 17288963}, {12969, 17289219}, {12970, 17289475}, {12971, 17271299},
1475 {12972, 17272067}, {12973, 17272835}, {12974, 17273603}, {12975, 17274371},
1476 {12976, 17289731}, {12977, 34067203}, {12978, 34067715}, {12979, 34068227},
1477 {12980, 34068739}, {12981, 34069251}, {12982, 33564931}, {12983, 34057475},
1478 {12984, 34061571}, {12985, 34069763}, {12986, 34070275}, {12987, 34070787},
1479 {12988, 34071299}, {12989, 34071811}, {12990, 34072323}, {12991, 34072835},
1480 {12992, 34073347}, {12993, 34073859}, {12994, 34074371}, {12995, 34074883},
1481 {12996, 34075395}, {12997, 34075907}, {12998, 34076419}, {12999, 34076931},
1482 {13000, 34077443}, {13001, 50855171}, {13002, 50855939}, {13003, 50856707},
1483 {13004, 34080259}, {13005, 50857987}, {13006, 34081539}, {13007, 50859267},
1484 {13008, 17305603}, {13009, 17305859}, {13010, 17306115}, {13011, 17306371},
1485 {13012, 17306627}, {13013, 17306883}, {13014, 17307139}, {13015, 17307395},
1486 {13016, 17307651}, {13017, 17199107}, {13018, 17307907}, {13019, 17308163},
1487 {13020, 17308419}, {13021, 17308675}, {13022, 17308931}, {13023, 17309187},
1488 {13024, 17309443}, {13025, 17309699}, {13026, 17309955}, {13027, 17199363},
1489 {13028, 17310211}, {13029, 17310467}, {13030, 17310723}, {13031, 17310979},
1490 {13032, 17311235}, {13033, 17311491}, {13034, 17311747}, {13035, 17312003},
1491 {13036, 17312259}, {13037, 17312515}, {13038, 17312771}, {13039, 17313027},
1492 {13040, 17313283}, {13041, 17313539}, {13042, 17313795}, {13043, 17314051},
1493 {13044, 17314307}, {13045, 17314563}, {13046, 17314819}, {13047, 17315075},
1494 {13048, 17315331}, {13049, 17315587}, {13050, 17315843}, {13051, 17316099},
1495 {13052, 17316355}, {13053, 17316611}, {13054, 17316867}, {13055, 34094339},
1496 {13056, 67649283}, {13057, 67650307}, {13058, 67651331}, {13059, 50875139},
1497 {13060, 67653123}, {13061, 50876931}, {13062, 50877699}, {13063, 84432899},
1498 {13064, 67656963}, {13065, 50880771}, {13066, 50881539}, {13067, 50882307},
1499 {13068, 67660291}, {13069, 67661315}, {13070, 50885123}, {13071, 50885891},
1500 {13072, 34109443}, {13073, 50887171}, {13074, 67665155}, {13075, 67666179},
1501 {13076, 34112771}, {13077, 84444931}, {13078, 101223427}, {13079, 84447747},
1502 {13080, 50891011}, {13081, 84449027}, {13082, 84450307}, {13083, 67674371},
1503 {13084, 50898179}, {13085, 50898947}, {13086, 50899715}, {13087, 67677699},
1504 {13088, 84455939}, {13089, 67680003}, {13090, 50903811}, {13091, 50904579},
1505 {13092, 50905347}, {13093, 34128899}, {13094, 34129411}, {13095, 34118147},
1506 {13096, 34129923}, {13097, 50907651}, {13098, 50908419}, {13099, 84463619},
1507 {13100, 50910467}, {13101, 67688451}, {13102, 84466691}, {13103, 50913539},
1508 {13104, 34137091}, {13105, 34137603}, {13106, 84469763}, {13107, 67693827},
1509 {13108, 84472067}, {13109, 50918915}, {13110, 84474115}, {13111, 34143747},
1510 {13112, 50921475}, {13113, 50922243}, {13114, 50923011}, {13115, 50923779},
1511 {13116, 50924547}, {13117, 67702531}, {13118, 50926339}, {13119, 34149891},
1512 {13120, 50927619}, {13121, 50928387}, {13122, 50929155}, {13123, 67707139},
1513 {13124, 50930947}, {13125, 50931715}, {13126, 50932483}, {13127, 84487683},
1514 {13128, 67711747}, {13129, 34158339}, {13130, 84490499}, {13131, 34160131},
1515 {13132, 67715075}, {13133, 67669507}, {13134, 50938883}, {13135, 50939651},
1516 {13136, 50940419}, {13137, 67718403}, {13138, 34164995}, {13139, 50942723},
1517 {13140, 67720707}, {13141, 34167299}, {13142, 84499459}, {13143, 50893827},
1518 {13144, 34169091}, {13145, 34169603}, {13146, 34170115}, {13147, 34170627},
1519 {13148, 34171139}, {13149, 34171651}, {13150, 34172163}, {13151, 34172675},
1520 {13152, 34173187}, {13153, 34173699}, {13154, 50951427}, {13155, 50952195},
1521 {13156, 50952963}, {13157, 50953731}, {13158, 50954499}, {13159, 50955267},
1522 {13160, 50956035}, {13161, 50956803}, {13162, 50957571}, {13163, 50958339},
1523 {13164, 50959107}, {13165, 50959875}, {13166, 50960643}, {13167, 50961411},
1524 {13168, 50962179}, {13169, 50962947}, {13170, 34186499}, {13171, 34187011},
1525 {13172, 50964739}, {13173, 34188291}, {13174, 34188803}, {13175, 34189315},
1526 {13176, 50967043}, {13177, 50967811}, {13178, 34191363}, {13179, 34191875},
1527 {13180, 34192387}, {13181, 34192899}, {13182, 34193411}, {13183, 67748355},
1528 {13184, 34185987}, {13185, 34194947}, {13186, 34195459}, {13187, 34195971},
1529 {13188, 34196483}, {13189, 34196995}, {13190, 34197507}, {13191, 34198019},
1530 {13192, 50975747}, {13193, 67753731}, {13194, 34200323}, {13195, 34200835},
1531 {13196, 34201347}, {13197, 34201859}, {13198, 34202371}, {13199, 34202883},
1532 {13200, 34203395}, {13201, 50981123}, {13202, 50981891}, {13203, 50980355},
1533 {13204, 50982659}, {13205, 34206211}, {13206, 34206723}, {13207, 34207235},
1534 {13208, 33556995}, {13209, 34207747}, {13210, 34208259}, {13211, 34208771},
1535 {13212, 34209283}, {13213, 34209795}, {13214, 34210307}, {13215, 50988035},
1536 {13216, 50988803}, {13217, 34190083}, {13218, 50989571}, {13219, 50990339},
1537 {13220, 50991107}, {13221, 34190851}, {13222, 50991875}, {13223, 50992643},
1538 {13224, 67770627}, {13225, 34185987}, {13226, 50994435}, {13227, 50995203},
1539 {13228, 50995971}, {13229, 50996739}, {13230, 84551939}, {13231, 101330435},
1540 {13232, 34223107}, {13233, 34223619}, {13234, 34224131}, {13235, 34224643},
1541 {13236, 34225155}, {13237, 34225667}, {13238, 34226179}, {13239, 34226691},
1542 {13240, 34227203}, {13241, 34226691}, {13242, 34227715}, {13243, 34228227},
1543 {13244, 34228739}, {13245, 34229251}, {13246, 34229763}, {13247, 34229251},
1544 {13248, 34230275}, {13249, 34230787}, {13250, 2}, {13251, 34231299},
1545 {13252, 33817347}, {13253, 33554947}, {13254, 67786243}, {13255, 2},
1546 {13256, 34232835}, {13257, 34233347}, {13258, 34233859}, {13259, 34185731},
1547 {13260, 34234371}, {13261, 34234883}, {13262, 34210307}, {13263, 34235395},
1548 {13264, 33557251}, {13265, 34235907}, {13266, 51013635}, {13267, 34237187},
1549 {13268, 34197507}, {13269, 51014915}, {13270, 51015683}, {13271, 34239235},
1550 {13272, 2}, {13273, 51016963}, {13274, 34240515}, {13275, 34221315},
1551 {13276, 34241027}, {13277, 34241539}, {13278, 51019267}, {13279, 51020035},
1552 {13280, 34243587}, {13281, 34244099}, {13282, 34244611}, {13283, 34245123},
1553 {13284, 34245635}, {13285, 34246147}, {13286, 34246659}, {13287, 34247171},
1554 {13288, 34247683}, {13289, 51025411}, {13290, 51026179}, {13291, 51026947},
1555 {13292, 51027715}, {13293, 51028483}, {13294, 51029251}, {13295, 51030019},
1556 {13296, 51030787}, {13297, 51031555}, {13298, 51032323}, {13299, 51033091},
1557 {13300, 51033859}, {13301, 51034627}, {13302, 51035395}, {13303, 51036163},
1558 {13304, 51036931}, {13305, 51037699}, {13306, 51038467}, {13307, 51039235},
1559 {13308, 51040003}, {13309, 51040771}, {13310, 51041539}, {13311, 51042307},
1560 {13312, 1}, {42125, 2}, {42128, 1}, {42183, 2},
1561 {42192, 1}, {42540, 2}, {42560, 17488643}, {42561, 1},
1562 {42562, 17488899}, {42563, 1}, {42564, 17489155}, {42565, 1},
1563 {42566, 17489411}, {42567, 1}, {42568, 17489667}, {42569, 1},
1564 {42570, 16936451}, {42571, 1}, {42572, 17489923}, {42573, 1},
1565 {42574, 17490179}, {42575, 1}, {42576, 17490435}, {42577, 1},
1566 {42578, 17490691}, {42579, 1}, {42580, 17490947}, {42581, 1},
1567 {42582, 17491203}, {42583, 1}, {42584, 17491459}, {42585, 1},
1568 {42586, 17491715}, {42587, 1}, {42588, 17491971}, {42589, 1},
1569 {42590, 17492227}, {42591, 1}, {42592, 17492483}, {42593, 1},
1570 {42594, 17492739}, {42595, 1}, {42596, 17492995}, {42597, 1},
1571 {42598, 17493251}, {42599, 1}, {42600, 17493507}, {42601, 1},
1572 {42602, 17493763}, {42603, 1}, {42604, 17494019}, {42605, 1},
1573 {42624, 17494275}, {42625, 1}, {42626, 17494531}, {42627, 1},
1574 {42628, 17494787}, {42629, 1}, {42630, 17495043}, {42631, 1},
1575 {42632, 17495299}, {42633, 1}, {42634, 17495555}, {42635, 1},
1576 {42636, 17495811}, {42637, 1}, {42638, 17496067}, {42639, 1},
1577 {42640, 17496323}, {42641, 1}, {42642, 17496579}, {42643, 1},
1578 {42644, 17496835}, {42645, 1}, {42646, 17497091}, {42647, 1},
1579 {42648, 17497347}, {42649, 1}, {42650, 17497603}, {42651, 1},
1580 {42652, 16873219}, {42653, 16873731}, {42654, 1}, {42744, 2},
1581 {42752, 1}, {42786, 17497859}, {42787, 1}, {42788, 17498115},
1582 {42789, 1}, {42790, 17498371}, {42791, 1}, {42792, 17498627},
1583 {42793, 1}, {42794, 17498883}, {42795, 1}, {42796, 17499139},
1584 {42797, 1}, {42798, 17499395}, {42799, 1}, {42802, 17499651},
1585 {42803, 1}, {42804, 17499907}, {42805, 1}, {42806, 17500163},
1586 {42807, 1}, {42808, 17500419}, {42809, 1}, {42810, 17500675},
1587 {42811, 1}, {42812, 17500931}, {42813, 1}, {42814, 17501187},
1588 {42815, 1}, {42816, 17501443}, {42817, 1}, {42818, 17501699},
1589 {42819, 1}, {42820, 17501955}, {42821, 1}, {42822, 17502211},
1590 {42823, 1}, {42824, 17502467}, {42825, 1}, {42826, 17502723},
1591 {42827, 1}, {42828, 17502979}, {42829, 1}, {42830, 17503235},
1592 {42831, 1}, {42832, 17503491}, {42833, 1}, {42834, 17503747},
1593 {42835, 1}, {42836, 17504003}, {42837, 1}, {42838, 17504259},
1594 {42839, 1}, {42840, 17504515}, {42841, 1}, {42842, 17504771},
1595 {42843, 1}, {42844, 17505027}, {42845, 1}, {42846, 17505283},
1596 {42847, 1}, {42848, 17505539}, {42849, 1}, {42850, 17505795},
1597 {42851, 1}, {42852, 17506051}, {42853, 1}, {42854, 17506307},
1598 {42855, 1}, {42856, 17506563}, {42857, 1}, {42858, 17506819},
1599 {42859, 1}, {42860, 17507075}, {42861, 1}, {42862, 17507331},
1600 {42863, 1}, {42864, 17507331}, {42865, 1}, {42873, 17507587},
1601 {42874, 1}, {42875, 17507843}, {42876, 1}, {42877, 17508099},
1602 {42878, 17508355}, {42879, 1}, {42880, 17508611}, {42881, 1},
1603 {42882, 17508867}, {42883, 1}, {42884, 17509123}, {42885, 1},
1604 {42886, 17509379}, {42887, 1}, {42891, 17509635}, {42892, 1},
1605 {42893, 16951299}, {42894, 1}, {42896, 17509891}, {42897, 1},
1606 {42898, 17510147}, {42899, 1}, {42902, 17510403}, {42903, 1},
1607 {42904, 17510659}, {42905, 1}, {42906, 17510915}, {42907, 1},
1608 {42908, 17511171}, {42909, 1}, {42910, 17511427}, {42911, 1},
1609 {42912, 17511683}, {42913, 1}, {42914, 17511939}, {42915, 1},
1610 {42916, 17512195}, {42917, 1}, {42918, 17512451}, {42919, 1},
1611 {42920, 17512707}, {42921, 1}, {42922, 16841475}, {42923, 16948995},
1612 {42924, 16951043}, {42925, 17512963}, {42926, 16951555}, {42927, 1},
1613 {42928, 17513219}, {42929, 17513475}, {42930, 16952067}, {42931, 17513731},
1614 {42932, 17513987}, {42933, 1}, {42934, 17514243}, {42935, 1},
1615 {42936, 17514499}, {42937, 1}, {42938, 17514755}, {42939, 1},
1616 {42940, 17515011}, {42941, 1}, {42942, 17515267}, {42943, 1},
1617 {42944, 17515523}, {42945, 1}, {42946, 17515779}, {42947, 1},
1618 {42948, 17516035}, {42949, 16954371}, {42950, 17516291}, {42951, 17516547},
1619 {42952, 1}, {42953, 17516803}, {42954, 1}, {42955, 2},
1620 {42960, 17517059}, {42961, 1}, {42962, 2}, {42963, 1},
1621 {42964, 2}, {42965, 1}, {42966, 17517315}, {42967, 1},
1622 {42968, 17517571}, {42969, 1}, {42970, 2}, {42994, 16777731},
1623 {42995, 16778499}, {42996, 16781315}, {42997, 17517827}, {42998, 1},
1624 {43000, 16802051}, {43001, 16808195}, {43002, 1}, {43053, 2},
1625 {43056, 1}, {43066, 2}, {43072, 1}, {43128, 2},
1626 {43136, 1}, {43206, 2}, {43214, 1}, {43226, 2},
1627 {43232, 1}, {43348, 2}, {43359, 1}, {43389, 2},
1628 {43392, 1}, {43470, 2}, {43471, 1}, {43482, 2},
1629 {43486, 1}, {43519, 2}, {43520, 1}, {43575, 2},
1630 {43584, 1}, {43598, 2}, {43600, 1}, {43610, 2},
1631 {43612, 1}, {43715, 2}, {43739, 1}, {43767, 2},
1632 {43777, 1}, {43783, 2}, {43785, 1}, {43791, 2},
1633 {43793, 1}, {43799, 2}, {43808, 1}, {43815, 2},
1634 {43816, 1}, {43823, 2}, {43824, 1}, {43868, 17498371},
1635 {43869, 17518083}, {43870, 17124867}, {43871, 17518339}, {43872, 1},
1636 {43881, 17518595}, {43882, 1}, {43884, 2}, {43888, 17518851},
1637 {43889, 17519107}, {43890, 17519363}, {43891, 17519619}, {43892, 17519875},
1638 {43893, 17520131}, {43894, 17520387}, {43895, 17520643}, {43896, 17520899},
1639 {43897, 17521155}, {43898, 17521411}, {43899, 17521667}, {43900, 17521923},
1640 {43901, 17522179}, {43902, 17522435}, {43903, 17522691}, {43904, 17522947},
1641 {43905, 17523203}, {43906, 17523459}, {43907, 17523715}, {43908, 17523971},
1642 {43909, 17524227}, {43910, 17524483}, {43911, 17524739}, {43912, 17524995},
1643 {43913, 17525251}, {43914, 17525507}, {43915, 17525763}, {43916, 17526019},
1644 {43917, 17526275}, {43918, 17526531}, {43919, 17526787}, {43920, 17527043},
1645 {43921, 17527299}, {43922, 17527555}, {43923, 17527811}, {43924, 17528067},
1646 {43925, 17528323}, {43926, 17528579}, {43927, 17528835}, {43928, 17529091},
1647 {43929, 17529347}, {43930, 17529603}, {43931, 17529859}, {43932, 17530115},
1648 {43933, 17530371}, {43934, 17530627}, {43935, 17530883}, {43936, 17531139},
1649 {43937, 17531395}, {43938, 17531651}, {43939, 17531907}, {43940, 17532163},
1650 {43941, 17532419}, {43942, 17532675}, {43943, 17532931}, {43944, 17533187},
1651 {43945, 17533443}, {43946, 17533699}, {43947, 17533955}, {43948, 17534211},
1652 {43949, 17534467}, {43950, 17534723}, {43951, 17534979}, {43952, 17535235},
1653 {43953, 17535491}, {43954, 17535747}, {43955, 17536003}, {43956, 17536259},
1654 {43957, 17536515}, {43958, 17536771}, {43959, 17537027}, {43960, 17537283},
1655 {43961, 17537539}, {43962, 17537795}, {43963, 17538051}, {43964, 17538307},
1656 {43965, 17538563}, {43966, 17538819}, {43967, 17539075}, {43968, 1},
1657 {44014, 2}, {44016, 1}, {44026, 2}, {44032, 1},
1658 {55204, 2}, {55216, 1}, {55239, 2}, {55243, 1},
1659 {55292, 2}, {63744, 17539331}, {63745, 17539587}, {63746, 17182211},
1660 {63747, 17539843}, {63748, 17540099}, {63749, 17540355}, {63750, 17540611},
1661 {63751, 17196035}, {63753, 17540867}, {63754, 17184259}, {63755, 17541123},
1662 {63756, 17541379}, {63757, 17541635}, {63758, 17541891}, {63759, 17542147},
1663 {63760, 17542403}, {63761, 17542659}, {63762, 17542915}, {63763, 17543171},
1664 {63764, 17543427}, {63765, 17543683}, {63766, 17543939}, {63767, 17544195},
1665 {63768, 17544451}, {63769, 17544707}, {63770, 17544963}, {63771, 17545219},
1666 {63772, 17545475}, {63773, 17545731}, {63774, 17545987}, {63775, 17546243},
1667 {63776, 17546499}, {63777, 17546755}, {63778, 17547011}, {63779, 17547267},
1668 {63780, 17547523}, {63781, 17547779}, {63782, 17548035}, {63783, 17548291},
1669 {63784, 17548547}, {63785, 17548803}, {63786, 17549059}, {63787, 17549315},
1670 {63788, 17549571}, {63789, 17549827}, {63790, 17550083}, {63791, 17550339},
1671 {63792, 17550595}, {63793, 17550851}, {63794, 17551107}, {63795, 17551363},
1672 {63796, 17173507}, {63797, 17551619}, {63798, 17551875}, {63799, 17552131},
1673 {63800, 17552387}, {63801, 17552643}, {63802, 17552899}, {63803, 17553155},
1674 {63804, 17553411}, {63805, 17553667}, {63806, 17553923}, {63807, 17554179},
1675 {63808, 17192195}, {63809, 17554435}, {63810, 17554691}, {63811, 17554947},
1676 {63812, 17555203}, {63813, 17555459}, {63814, 17555715}, {63815, 17555971},
1677 {63816, 17556227}, {63817, 17556483}, {63818, 17556739}, {63819, 17556995},
1678 {63820, 17557251}, {63821, 17557507}, {63822, 17557763}, {63823, 17558019},
1679 {63824, 17558275}, {63825, 17558531}, {63826, 17558787}, {63827, 17559043},
1680 {63828, 17559299}, {63829, 17559555}, {63830, 17559811}, {63831, 17560067},
1681 {63832, 17560323}, {63833, 17560579}, {63834, 17560835}, {63835, 17561091},
1682 {63836, 17543427}, {63837, 17561347}, {63838, 17561603}, {63839, 17561859},
1683 {63840, 17562115}, {63841, 17562371}, {63842, 17562627}, {63843, 17562883},
1684 {63844, 17563139}, {63845, 17563395}, {63846, 17563651}, {63847, 17563907},
1685 {63848, 17564163}, {63849, 17564419}, {63850, 17564675}, {63851, 17564931},
1686 {63852, 17565187}, {63853, 17565443}, {63854, 17565699}, {63855, 17565955},
1687 {63856, 17566211}, {63857, 17182723}, {63858, 17566467}, {63859, 17566723},
1688 {63860, 17566979}, {63861, 17567235}, {63862, 17567491}, {63863, 17567747},
1689 {63864, 17568003}, {63865, 17568259}, {63866, 17568515}, {63867, 17568771},
1690 {63868, 17569027}, {63869, 17569283}, {63870, 17569539}, {63871, 17569795},
1691 {63872, 17570051}, {63873, 17151235}, {63874, 17570307}, {63875, 17570563},
1692 {63876, 17570819}, {63877, 17571075}, {63878, 17571331}, {63879, 17571587},
1693 {63880, 17571843}, {63881, 17572099}, {63882, 17146371}, {63883, 17572355},
1694 {63884, 17572611}, {63885, 17572867}, {63886, 17573123}, {63887, 17573379},
1695 {63888, 17573635}, {63889, 17573891}, {63890, 17574147}, {63891, 17574403},
1696 {63892, 17574659}, {63893, 17574915}, {63894, 17575171}, {63895, 17575427},
1697 {63896, 17575683}, {63897, 17575939}, {63898, 17576195}, {63899, 17576451},
1698 {63900, 17576707}, {63901, 17576963}, {63902, 17577219}, {63903, 17577475},
1699 {63904, 17577731}, {63905, 17565955}, {63906, 17577987}, {63907, 17578243},
1700 {63908, 17578499}, {63909, 17578755}, {63910, 17579011}, {63911, 17579267},
1701 {63912, 17317123}, {63913, 17579523}, {63914, 17561859}, {63915, 17579779},
1702 {63916, 17580035}, {63917, 17580291}, {63918, 17580547}, {63919, 17580803},
1703 {63920, 17581059}, {63921, 17581315}, {63922, 17581571}, {63923, 17581827},
1704 {63924, 17582083}, {63925, 17582339}, {63926, 17582595}, {63927, 17582851},
1705 {63928, 17583107}, {63929, 17583363}, {63930, 17583619}, {63931, 17583875},
1706 {63932, 17584131}, {63933, 17584387}, {63934, 17584643}, {63935, 17543427},
1707 {63936, 17584899}, {63937, 17585155}, {63938, 17585411}, {63939, 17585667},
1708 {63940, 17195779}, {63941, 17585923}, {63942, 17586179}, {63943, 17586435},
1709 {63944, 17586691}, {63945, 17586947}, {63946, 17587203}, {63947, 17587459},
1710 {63948, 17587715}, {63949, 17587971}, {63950, 17588227}, {63951, 17588483},
1711 {63952, 17588739}, {63953, 17254403}, {63954, 17588995}, {63955, 17589251},
1712 {63956, 17589507}, {63957, 17589763}, {63958, 17590019}, {63959, 17590275},
1713 {63960, 17590531}, {63961, 17590787}, {63962, 17591043}, {63963, 17562371},
1714 {63964, 17591299}, {63965, 17591555}, {63966, 17591811}, {63967, 17592067},
1715 {63968, 17592323}, {63969, 17592579}, {63970, 17592835}, {63971, 17593091},
1716 {63972, 17593347}, {63973, 17593603}, {63974, 17593859}, {63975, 17594115},
1717 {63976, 17594371}, {63977, 17184003}, {63978, 17594627}, {63979, 17594883},
1718 {63980, 17595139}, {63981, 17595395}, {63982, 17595651}, {63983, 17595907},
1719 {63984, 17596163}, {63985, 17596419}, {63986, 17596675}, {63987, 17596931},
1720 {63988, 17597187}, {63989, 17597443}, {63990, 17597699}, {63991, 17171459},
1721 {63992, 17597955}, {63993, 17598211}, {63994, 17598467}, {63995, 17598723},
1722 {63996, 17598979}, {63997, 17599235}, {63998, 17599491}, {63999, 17599747},
1723 {64000, 17600003}, {64001, 17600259}, {64002, 17600515}, {64003, 17600771},
1724 {64004, 17601027}, {64005, 17601283}, {64006, 17601539}, {64007, 17601795},
1725 {64008, 17178371}, {64009, 17602051}, {64010, 17179139}, {64011, 17602307},
1726 {64012, 17602563}, {64013, 17602819}, {64014, 1}, {64016, 17603075},
1727 {64017, 1}, {64018, 17603331}, {64019, 1}, {64021, 17603587},
1728 {64022, 17603843}, {64023, 17604099}, {64024, 17604355}, {64025, 17604611},
1729 {64026, 17604867}, {64027, 17605123}, {64028, 17605379}, {64029, 17605635},
1730 {64030, 17173251}, {64031, 1}, {64032, 17605891}, {64033, 1},
1731 {64034, 17606147}, {64035, 1}, {64037, 17606403}, {64038, 17606659},
1732 {64039, 1}, {64042, 17606915}, {64043, 17607171}, {64044, 17607427},
1733 {64045, 17607683}, {64046, 17607939}, {64047, 17608195}, {64048, 17608451},
1734 {64049, 17608707}, {64050, 17608963}, {64051, 17609219}, {64052, 17609475},
1735 {64053, 17609731}, {64054, 17609987}, {64055, 17610243}, {64056, 17610499},
1736 {64057, 17610755}, {64058, 17611011}, {64059, 17611267}, {64060, 17153027},
1737 {64061, 17611523}, {64062, 17611779}, {64063, 17612035}, {64064, 17612291},
1738 {64065, 17612547}, {64066, 17612803}, {64067, 17613059}, {64068, 17613315},
1739 {64069, 17613571}, {64070, 17613827}, {64071, 17614083}, {64072, 17614339},
1740 {64073, 17614595}, {64074, 17614851}, {64075, 17615107}, {64076, 17265155},
1741 {64077, 17615363}, {64078, 17615619}, {64079, 17615875}, {64080, 17616131},
1742 {64081, 17268227}, {64082, 17616387}, {64083, 17616643}, {64084, 17616899},
1743 {64085, 17617155}, {64086, 17617411}, {64087, 17575171}, {64088, 17617667},
1744 {64089, 17617923}, {64090, 17618179}, {64091, 17618435}, {64092, 17618691},
1745 {64093, 17618947}, {64095, 17619203}, {64096, 17619459}, {64097, 17619715},
1746 {64098, 17619971}, {64099, 17620227}, {64100, 17620483}, {64101, 17620739},
1747 {64102, 17620995}, {64103, 17606403}, {64104, 17621251}, {64105, 17621507},
1748 {64106, 17621763}, {64107, 17622019}, {64108, 17622275}, {64109, 17622531},
1749 {64110, 2}, {64112, 17622787}, {64113, 17623043}, {64114, 17623299},
1750 {64115, 17623555}, {64116, 17623811}, {64117, 17624067}, {64118, 17624323},
1751 {64119, 17624579}, {64120, 17609987}, {64121, 17624835}, {64122, 17625091},
1752 {64123, 17625347}, {64124, 17603075}, {64125, 17625603}, {64126, 17625859},
1753 {64127, 17626115}, {64128, 17626371}, {64129, 17626627}, {64130, 17626883},
1754 {64131, 17627139}, {64132, 17627395}, {64133, 17627651}, {64134, 17627907},
1755 {64135, 17628163}, {64136, 17628419}, {64137, 17612035}, {64138, 17628675},
1756 {64139, 17612291}, {64140, 17628931}, {64141, 17629187}, {64142, 17629443},
1757 {64143, 17629699}, {64144, 17629955}, {64145, 17603331}, {64146, 17548803},
1758 {64147, 17630211}, {64148, 17630467}, {64149, 17161475}, {64150, 17566211},
1759 {64151, 17587203}, {64152, 17630723}, {64153, 17630979}, {64154, 17614083},
1760 {64155, 17631235}, {64156, 17614339}, {64157, 17631491}, {64158, 17631747},
1761 {64159, 17632003}, {64160, 17603843}, {64161, 17632259}, {64162, 17632515},
1762 {64163, 17632771}, {64164, 17633027}, {64165, 17633283}, {64166, 17604099},
1763 {64167, 17633539}, {64168, 17633795}, {64169, 17634051}, {64170, 17634307},
1764 {64171, 17634563}, {64172, 17634819}, {64173, 17617411}, {64174, 17635075},
1765 {64175, 17635331}, {64176, 17575171}, {64177, 17635587}, {64178, 17618435},
1766 {64179, 17635843}, {64180, 17636099}, {64181, 17636355}, {64182, 17636611},
1767 {64183, 17636867}, {64184, 17619715}, {64185, 17637123}, {64186, 17606147},
1768 {64187, 17637379}, {64188, 17619971}, {64189, 17561347}, {64190, 17637635},
1769 {64191, 17620227}, {64192, 17637891}, {64193, 17620739}, {64194, 17638147},
1770 {64195, 17638403}, {64196, 17638659}, {64197, 17638915}, {64198, 17639171},
1771 {64199, 17621251}, {64200, 17605379}, {64201, 17639427}, {64202, 17621507},
1772 {64203, 17639683}, {64204, 17621763}, {64205, 17639939}, {64206, 17196035},
1773 {64207, 17640195}, {64208, 17640451}, {64209, 17640707}, {64210, 17640963},
1774 {64211, 17641219}, {64212, 17641475}, {64213, 17641731}, {64214, 17641987},
1775 {64215, 17642243}, {64216, 17642499}, {64217, 17642755}, {64218, 2},
1776 {64256, 34420227}, {64257, 34420739}, {64258, 34421251}, {64259, 51197699},
1777 {64260, 51198979}, {64261, 33559043}, {64263, 2}, {64275, 34422531},
1778 {64276, 34423043}, {64277, 34423555}, {64278, 34424067}, {64279, 34424579},
1779 {64280, 2}, {64285, 34425091}, {64286, 1}, {64287, 34425603},
1780 {64288, 17648899}, {64289, 17044227}, {64290, 17044995}, {64291, 17649155},
1781 {64292, 17649411}, {64293, 17649667}, {64294, 17649923}, {64295, 17650179},
1782 {64296, 17650435}, {64297, 17037059}, {64298, 34427907}, {64299, 34428419},
1783 {64300, 51206147}, {64301, 51206915}, {64302, 34430467}, {64303, 34430979},
1784 {64304, 34431491}, {64305, 34432003}, {64306, 34432515}, {64307, 34433027},
1785 {64308, 34433539}, {64309, 34434051}, {64310, 34434563}, {64311, 2},
1786 {64312, 34435075}, {64313, 34435587}, {64314, 34436099}, {64315, 34436611},
1787 {64316, 34437123}, {64317, 2}, {64318, 34437635}, {64319, 2},
1788 {64320, 34438147}, {64321, 34438659}, {64322, 2}, {64323, 34439171},
1789 {64324, 34439683}, {64325, 2}, {64326, 34440195}, {64327, 34440707},
1790 {64328, 34441219}, {64329, 34428931}, {64330, 34441731}, {64331, 34442243},
1791 {64332, 34442755}, {64333, 34443267}, {64334, 34443779}, {64335, 34444291},
1792 {64336, 17667587}, {64338, 17667843}, {64342, 17668099}, {64346, 17668355},
1793 {64350, 17668611}, {64354, 17668867}, {64358, 17669123}, {64362, 17669379},
1794 {64366, 17669635}, {64370, 17669891}, {64374, 17670147}, {64378, 17670403},
1795 {64382, 17670659}, {64386, 17670915}, {64388, 17671171}, {64390, 17671427},
1796 {64392, 17671683}, {64394, 17671939}, {64396, 17672195}, {64398, 17672451},
1797 {64402, 17672707}, {64406, 17672963}, {64410, 17673219}, {64414, 17673475},
1798 {64416, 17673731}, {64420, 17673987}, {64422, 17674243}, {64426, 17674499},
1799 {64430, 17674755}, {64432, 17675011}, {64434, 1}, {64451, 2},
1800 {64467, 17675267}, {64471, 16911363}, {64473, 17675523}, {64475, 17675779},
1801 {64477, 33688579}, {64478, 17676035}, {64480, 17676291}, {64482, 17676547},
1802 {64484, 17676803}, {64488, 17677059}, {64490, 34454531}, {64492, 34455043},
1803 {64494, 34455555}, {64496, 34456067}, {64498, 34456579}, {64500, 34457091},
1804 {64502, 34457603}, {64505, 34458115}, {64508, 17681411}, {64512, 34458883},
1805 {64513, 34459395}, {64514, 34459907}, {64515, 34458115}, {64516, 34460419},
1806 {64517, 34460931}, {64518, 34461443}, {64519, 34461955}, {64520, 34462467},
1807 {64521, 34462979}, {64522, 34463491}, {64523, 34464003}, {64524, 34464515},
1808 {64525, 34465027}, {64526, 34465539}, {64527, 34466051}, {64528, 34466563},
1809 {64529, 34467075}, {64530, 34467587}, {64531, 34468099}, {64532, 34468611},
1810 {64533, 34469123}, {64534, 34469635}, {64535, 34469379}, {64536, 34470147},
1811 {64537, 34470659}, {64538, 34471171}, {64539, 34471683}, {64540, 34472195},
1812 {64541, 34472707}, {64542, 34473219}, {64543, 34473731}, {64544, 34474243},
1813 {64545, 34474755}, {64546, 34475267}, {64547, 34475779}, {64548, 34476291},
1814 {64549, 34476803}, {64550, 34477315}, {64551, 34477827}, {64552, 34478339},
1815 {64553, 34478851}, {64554, 34479363}, {64555, 34479875}, {64556, 34480387},
1816 {64557, 34480899}, {64558, 34481411}, {64559, 34481923}, {64560, 34482435},
1817 {64561, 34482947}, {64562, 34483459}, {64563, 34483971}, {64564, 34484483},
1818 {64565, 34484995}, {64566, 34485507}, {64567, 34486019}, {64568, 34486531},
1819 {64569, 34487043}, {64570, 34487555}, {64571, 34488067}, {64572, 34488579},
1820 {64573, 34489091}, {64574, 34489603}, {64575, 34490115}, {64576, 34490627},
1821 {64577, 34491139}, {64578, 34491651}, {64579, 34492163}, {64580, 34492675},
1822 {64581, 34493187}, {64582, 34469891}, {64583, 34470403}, {64584, 34493699},
1823 {64585, 34494211}, {64586, 34494723}, {64587, 34495235}, {64588, 34495747},
1824 {64589, 34496259}, {64590, 34496771}, {64591, 34497283}, {64592, 34497795},
1825 {64593, 34498307}, {64594, 34498819}, {64595, 34499331}, {64596, 34499843},
1826 {64597, 34468867}, {64598, 34500355}, {64599, 34500867}, {64600, 34492931},
1827 {64601, 34501379}, {64602, 34500099}, {64603, 34501891}, {64604, 34502403},
1828 {64605, 34502915}, {64606, 51280643}, {64607, 51281411}, {64608, 51282179},
1829 {64609, 51282947}, {64610, 51283715}, {64611, 51284483}, {64612, 34508035},
1830 {64613, 34508547}, {64614, 34459907}, {64615, 34509059}, {64616, 34458115},
1831 {64617, 34460419}, {64618, 34509571}, {64619, 34510083}, {64620, 34462467},
1832 {64621, 34510595}, {64622, 34462979}, {64623, 34463491}, {64624, 34511107},
1833 {64625, 34511619}, {64626, 34465539}, {64627, 34512131}, {64628, 34466051},
1834 {64629, 34466563}, {64630, 34512643}, {64631, 34513155}, {64632, 34467587},
1835 {64633, 34513667}, {64634, 34468099}, {64635, 34468611}, {64636, 34482947},
1836 {64637, 34483459}, {64638, 34484995}, {64639, 34485507}, {64640, 34486019},
1837 {64641, 34488067}, {64642, 34488579}, {64643, 34489091}, {64644, 34489603},
1838 {64645, 34491651}, {64646, 34492163}, {64647, 34492675}, {64648, 34514179},
1839 {64649, 34493699}, {64650, 34514691}, {64651, 34515203}, {64652, 34496771},
1840 {64653, 34515715}, {64654, 34497283}, {64655, 34497795}, {64656, 34502915},
1841 {64657, 34516227}, {64658, 34516739}, {64659, 34492931}, {64660, 34494979},
1842 {64661, 34501379}, {64662, 34500099}, {64663, 34458883}, {64664, 34459395},
1843 {64665, 34517251}, {64666, 34459907}, {64667, 34517763}, {64668, 34460931},
1844 {64669, 34461443}, {64670, 34461955}, {64671, 34462467}, {64672, 34518275},
1845 {64673, 34464003}, {64674, 34464515}, {64675, 34465027}, {64676, 34465539},
1846 {64677, 34518787}, {64678, 34467587}, {64679, 34469123}, {64680, 34469635},
1847 {64681, 34469379}, {64682, 34470147}, {64683, 34470659}, {64684, 34471683},
1848 {64685, 34472195}, {64686, 34472707}, {64687, 34473219}, {64688, 34473731},
1849 {64689, 34474243}, {64690, 34519299}, {64691, 34474755}, {64692, 34475267},
1850 {64693, 34475779}, {64694, 34476291}, {64695, 34476803}, {64696, 34477315},
1851 {64697, 34478339}, {64698, 34478851}, {64699, 34479363}, {64700, 34479875},
1852 {64701, 34480387}, {64702, 34480899}, {64703, 34481411}, {64704, 34481923},
1853 {64705, 34482435}, {64706, 34483971}, {64707, 34484483}, {64708, 34486531},
1854 {64709, 34487043}, {64710, 34487555}, {64711, 34488067}, {64712, 34488579},
1855 {64713, 34490115}, {64714, 34490627}, {64715, 34491139}, {64716, 34491651},
1856 {64717, 34519811}, {64718, 34493187}, {64719, 34469891}, {64720, 34470403},
1857 {64721, 34493699}, {64722, 34495235}, {64723, 34495747}, {64724, 34496259},
1858 {64725, 34496771}, {64726, 34520323}, {64727, 34498307}, {64728, 34498819},
1859 {64729, 34520835}, {64730, 34468867}, {64731, 34500355}, {64732, 34500867},
1860 {64733, 34492931}, {64734, 34498051}, {64735, 34459907}, {64736, 34517763},
1861 {64737, 34462467}, {64738, 34518275}, {64739, 34465539}, {64740, 34518787},
1862 {64741, 34467587}, {64742, 34521347}, {64743, 34473731}, {64744, 34521859},
1863 {64745, 34522371}, {64746, 34522883}, {64747, 34488067}, {64748, 34488579},
1864 {64749, 34491651}, {64750, 34496771}, {64751, 34520323}, {64752, 34492931},
1865 {64753, 34498051}, {64754, 51300611}, {64755, 51301379}, {64756, 51302147},
1866 {64757, 34525699}, {64758, 34526211}, {64759, 34526723}, {64760, 34527235},
1867 {64761, 34527747}, {64762, 34528259}, {64763, 34528771}, {64764, 34529283},
1868 {64765, 34529795}, {64766, 34530307}, {64767, 34530819}, {64768, 34500611},
1869 {64769, 34531331}, {64770, 34531843}, {64771, 34532355}, {64772, 34501123},
1870 {64773, 34532867}, {64774, 34533379}, {64775, 34533891}, {64776, 34534403},
1871 {64777, 34534915}, {64778, 34535427}, {64779, 34535939}, {64780, 34522371},
1872 {64781, 34536451}, {64782, 34536963}, {64783, 34537475}, {64784, 34537987},
1873 {64785, 34525699}, {64786, 34526211}, {64787, 34526723}, {64788, 34527235},
1874 {64789, 34527747}, {64790, 34528259}, {64791, 34528771}, {64792, 34529283},
1875 {64793, 34529795}, {64794, 34530307}, {64795, 34530819}, {64796, 34500611},
1876 {64797, 34531331}, {64798, 34531843}, {64799, 34532355}, {64800, 34501123},
1877 {64801, 34532867}, {64802, 34533379}, {64803, 34533891}, {64804, 34534403},
1878 {64805, 34534915}, {64806, 34535427}, {64807, 34535939}, {64808, 34522371},
1879 {64809, 34536451}, {64810, 34536963}, {64811, 34537475}, {64812, 34537987},
1880 {64813, 34534915}, {64814, 34535427}, {64815, 34535939}, {64816, 34522371},
1881 {64817, 34521859}, {64818, 34522883}, {64819, 34477827}, {64820, 34472195},
1882 {64821, 34472707}, {64822, 34473219}, {64823, 34534915}, {64824, 34535427},
1883 {64825, 34535939}, {64826, 34477827}, {64827, 34478339}, {64828, 34538499},
1884 {64830, 1}, {64848, 51316227}, {64849, 51316995}, {64851, 51317763},
1885 {64852, 51318531}, {64853, 51319299}, {64854, 51320067}, {64855, 51320835},
1886 {64856, 51246851}, {64858, 51321603}, {64859, 51322371}, {64860, 51323139},
1887 {64861, 51323907}, {64862, 51324675}, {64863, 51325443}, {64865, 51326211},
1888 {64866, 51326979}, {64868, 51327747}, {64870, 51328515}, {64871, 51329283},
1889 {64873, 51330051}, {64874, 51330819}, {64876, 51331587}, {64878, 51332355},
1890 {64879, 51333123}, {64881, 51333891}, {64883, 51334659}, {64884, 51335427},
1891 {64885, 51336195}, {64886, 51336963}, {64888, 51337731}, {64889, 51338499},
1892 {64890, 51339267}, {64891, 51340035}, {64892, 51340803}, {64894, 51341571},
1893 {64895, 51342339}, {64896, 51343107}, {64897, 51343875}, {64898, 51344643},
1894 {64899, 51345411}, {64901, 51346179}, {64903, 51346947}, {64905, 51347715},
1895 {64906, 51247107}, {64907, 51348483}, {64908, 51349251}, {64909, 51270403},
1896 {64910, 51247619}, {64911, 51350019}, {64912, 2}, {64914, 51350787},
1897 {64915, 51351555}, {64916, 51352323}, {64917, 51353091}, {64918, 51353859},
1898 {64919, 51354627}, {64921, 51355395}, {64922, 51356163}, {64923, 51356931},
1899 {64924, 51357699}, {64926, 51358467}, {64927, 51359235}, {64928, 51360003},
1900 {64929, 51360771}, {64930, 51361539}, {64931, 51362307}, {64932, 51363075},
1901 {64933, 51363843}, {64934, 51364611}, {64935, 51365379}, {64936, 51366147},
1902 {64937, 51366915}, {64938, 51367683}, {64939, 51368451}, {64940, 51369219},
1903 {64941, 51369987}, {64942, 51277571}, {64943, 51370755}, {64944, 51371523},
1904 {64945, 51372291}, {64946, 51373059}, {64947, 51373827}, {64948, 51341571},
1905 {64949, 51343107}, {64950, 51374595}, {64951, 51375363}, {64952, 51376131},
1906 {64953, 51376899}, {64954, 51377667}, {64955, 51378435}, {64956, 51377667},
1907 {64957, 51376131}, {64958, 51379203}, {64959, 51379971}, {64960, 51380739},
1908 {64961, 51381507}, {64962, 51382275}, {64963, 51378435}, {64964, 51336195},
1909 {64965, 51328515}, {64966, 51383043}, {64967, 51383811}, {64968, 2},
1910 {64975, 1}, {64976, 2}, {65008, 51384579}, {65009, 51385347},
1911 {65010, 68163331}, {65011, 68164355}, {65012, 68165379}, {65013, 68166403},
1912 {65014, 68167427}, {65015, 68168451}, {65016, 68169475}, {65017, 51393283},
1913 {65018, 303052291}, {65019, 135284739}, {65020, 68177923}, {65021, 1},
1914 {65024, 0}, {65040, 17847299}, {65041, 17847555}, {65042, 2},
1915 {65043, 17110531}, {65044, 16848643}, {65045, 17032963}, {65046, 17033987},
1916 {65047, 17847811}, {65048, 17848067}, {65049, 2}, {65056, 1},
1917 {65072, 2}, {65073, 17848323}, {65074, 17848579}, {65075, 17848835},
1918 {65077, 17037827}, {65078, 17038083}, {65079, 17849091}, {65080, 17849347},
1919 {65081, 17849603}, {65082, 17849859}, {65083, 17850115}, {65084, 17850371},
1920 {65085, 17850627}, {65086, 17850883}, {65087, 17067267}, {65088, 17067523},
1921 {65089, 17851139}, {65090, 17851395}, {65091, 17851651}, {65092, 17851907},
1922 {65093, 1}, {65095, 17852163}, {65096, 17852419}, {65097, 33810691},
1923 {65101, 17848835}, {65104, 17847299}, {65105, 17847555}, {65106, 2},
1924 {65108, 16848643}, {65109, 17110531}, {65110, 17033987}, {65111, 17032963},
1925 {65112, 17848323}, {65113, 17037827}, {65114, 17038083}, {65115, 17849091},
1926 {65116, 17849347}, {65117, 17849603}, {65118, 17849859}, {65119, 17852675},
1927 {65120, 17852931}, {65121, 17853187}, {65122, 17037059}, {65123, 17853443},
1928 {65124, 17853699}, {65125, 17853955}, {65126, 17037571}, {65127, 2},
1929 {65128, 17854211}, {65129, 17854467}, {65130, 17854723}, {65131, 17854979},
1930 {65132, 2}, {65136, 34632451}, {65137, 34632963}, {65138, 34503427},
1931 {65139, 1}, {65140, 34504195}, {65141, 2}, {65142, 34504963},
1932 {65143, 34523395}, {65144, 34505731}, {65145, 34524163}, {65146, 34506499},
1933 {65147, 34524931}, {65148, 34507267}, {65149, 34633475}, {65150, 34633987},
1934 {65151, 34634499}, {65152, 17857795}, {65153, 17858051}, {65155, 17858307},
1935 {65157, 17858563}, {65159, 17858819}, {65161, 17677315}, {65165, 16910339},
1936 {65167, 17683715}, {65171, 17859075}, {65173, 17686787}, {65177, 17689859},
1937 {65181, 17681923}, {65185, 17682435}, {65189, 17684995}, {65193, 17834499},
1938 {65195, 17724675}, {65197, 17725187}, {65199, 17731587}, {65201, 17694979},
1939 {65205, 17745155}, {65209, 17697027}, {65213, 17698051}, {65217, 17700099},
1940 {65221, 17701123}, {65225, 17701635}, {65229, 17702659}, {65233, 17703683},
1941 {65237, 17706755}, {65241, 17708803}, {65245, 17711107}, {65249, 17682947},
1942 {65253, 17718019}, {65257, 17721091}, {65261, 16910851}, {65263, 17677059},
1943 {65265, 16911875}, {65269, 34636547}, {65271, 34637059}, {65273, 34637571},
1944 {65275, 34622467}, {65277, 2}, {65279, 0}, {65280, 2},
1945 {65281, 17032963}, {65282, 17860867}, {65283, 17852675}, {65284, 17854467},
1946 {65285, 17854723}, {65286, 17852931}, {65287, 17861123}, {65288, 17037827},
1947 {65289, 17038083}, {65290, 17853187}, {65291, 17037059}, {65292, 17847299},
1948 {65293, 17853443}, {65294, 17196547}, {65295, 17038595}, {65296, 17035523},
1949 {65297, 16786947}, {65298, 16785155}, {65299, 16785411}, {65300, 16787715},
1950 {65301, 17035779}, {65302, 17036035}, {65303, 17036291}, {65304, 17036547},
1951 {65305, 17036803}, {65306, 17110531}, {65307, 16848643}, {65308, 17853699},
1952 {65309, 17037571}, {65310, 17853955}, {65311, 17033987}, {65312, 17854979},
1953 {65313, 16777219}, {65314, 16777475}, {65315, 16777731}, {65316, 16777987},
1954 {65317, 16778243}, {65318, 16778499}, {65319, 16778755}, {65320, 16779011},
1955 {65321, 16779267}, {65322, 16779523}, {65323, 16779779}, {65324, 16780035},
1956 {65325, 16780291}, {65326, 16780547}, {65327, 16780803}, {65328, 16781059},
1957 {65329, 16781315}, {65330, 16781571}, {65331, 16781827}, {65332, 16782083},
1958 {65333, 16782339}, {65334, 16782595}, {65335, 16782851}, {65336, 16783107},
1959 {65337, 16783363}, {65338, 16783619}, {65339, 17852163}, {65340, 17854211},
1960 {65341, 17852419}, {65342, 17861379}, {65343, 17848835}, {65344, 17027075},
1961 {65345, 16777219}, {65346, 16777475}, {65347, 16777731}, {65348, 16777987},
1962 {65349, 16778243}, {65350, 16778499}, {65351, 16778755}, {65352, 16779011},
1963 {65353, 16779267}, {65354, 16779523}, {65355, 16779779}, {65356, 16780035},
1964 {65357, 16780291}, {65358, 16780547}, {65359, 16780803}, {65360, 16781059},
1965 {65361, 16781315}, {65362, 16781571}, {65363, 16781827}, {65364, 16782083},
1966 {65365, 16782339}, {65366, 16782595}, {65367, 16782851}, {65368, 16783107},
1967 {65369, 16783363}, {65370, 16783619}, {65371, 17849091}, {65372, 17861635},
1968 {65373, 17849347}, {65374, 17861891}, {65375, 17862147}, {65376, 17862403},
1969 {65377, 17196547}, {65378, 17851139}, {65379, 17851395}, {65380, 17847555},
1970 {65381, 17862659}, {65382, 17316867}, {65383, 17319427}, {65384, 17362435},
1971 {65385, 17862915}, {65386, 17363971}, {65387, 17323523}, {65388, 17863171},
1972 {65389, 17333763}, {65390, 17379587}, {65391, 17329155}, {65392, 17318147},
1973 {65393, 17305603}, {65394, 17305859}, {65395, 17306115}, {65396, 17306371},
1974 {65397, 17306627}, {65398, 17306883}, {65399, 17307139}, {65400, 17307395},
1975 {65401, 17307651}, {65402, 17199107}, {65403, 17307907}, {65404, 17308163},
1976 {65405, 17308419}, {65406, 17308675}, {65407, 17308931}, {65408, 17309187},
1977 {65409, 17309443}, {65410, 17309699}, {65411, 17309955}, {65412, 17199363},
1978 {65413, 17310211}, {65414, 17310467}, {65415, 17310723}, {65416, 17310979},
1979 {65417, 17311235}, {65418, 17311491}, {65419, 17311747}, {65420, 17312003},
1980 {65421, 17312259}, {65422, 17312515}, {65423, 17312771}, {65424, 17313027},
1981 {65425, 17313283}, {65426, 17313539}, {65427, 17313795}, {65428, 17314051},
1982 {65429, 17314307}, {65430, 17314563}, {65431, 17314819}, {65432, 17315075},
1983 {65433, 17315331}, {65434, 17315587}, {65435, 17315843}, {65436, 17316099},
1984 {65437, 17319939}, {65438, 17197827}, {65439, 17198339}, {65440, 2},
1985 {65441, 17199619}, {65442, 17199875}, {65443, 17200131}, {65444, 17200387},
1986 {65445, 17200643}, {65446, 17200899}, {65447, 17201155}, {65448, 17201411},
1987 {65449, 17201667}, {65450, 17201923}, {65451, 17202179}, {65452, 17202435},
1988 {65453, 17202691}, {65454, 17202947}, {65455, 17203203}, {65456, 17203459},
1989 {65457, 17203715}, {65458, 17203971}, {65459, 17204227}, {65460, 17204483},
1990 {65461, 17204739}, {65462, 17204995}, {65463, 17205251}, {65464, 17205507},
1991 {65465, 17205763}, {65466, 17206019}, {65467, 17206275}, {65468, 17206531},
1992 {65469, 17206787}, {65470, 17207043}, {65471, 2}, {65474, 17207299},
1993 {65475, 17207555}, {65476, 17207811}, {65477, 17208067}, {65478, 17208323},
1994 {65479, 17208579}, {65480, 2}, {65482, 17208835}, {65483, 17209091},
1995 {65484, 17209347}, {65485, 17209603}, {65486, 17209859}, {65487, 17210115},
1996 {65488, 2}, {65490, 17210371}, {65491, 17210627}, {65492, 17210883},
1997 {65493, 17211139}, {65494, 17211395}, {65495, 17211651}, {65496, 2},
1998 {65498, 17211907}, {65499, 17212163}, {65500, 17212419}, {65501, 2},
1999 {65504, 17863427}, {65505, 17863683}, {65506, 17863939}, {65507, 33561859},
2000 {65508, 17864195}, {65509, 17864451}, {65510, 17864707}, {65511, 2},
2001 {65512, 17864963}, {65513, 17865219}, {65514, 17865475}, {65515, 17865731},
2002 {65516, 17865987}, {65517, 17866243}, {65518, 17866499}, {65519, 2},
2003 {65536, 1}, {65548, 2}, {65549, 1}, {65575, 2},
2004 {65576, 1}, {65595, 2}, {65596, 1}, {65598, 2},
2005 {65599, 1}, {65614, 2}, {65616, 1}, {65630, 2},
2006 {65664, 1}, {65787, 2}, {65792, 1}, {65795, 2},
2007 {65799, 1}, {65844, 2}, {65847, 1}, {65935, 2},
2008 {65936, 1}, {65949, 2}, {65952, 1}, {65953, 2},
2009 {66000, 1}, {66046, 2}, {66176, 1}, {66205, 2},
2010 {66208, 1}, {66257, 2}, {66272, 1}, {66300, 2},
2011 {66304, 1}, {66340, 2}, {66349, 1}, {66379, 2},
2012 {66384, 1}, {66427, 2}, {66432, 1}, {66462, 2},
2013 {66463, 1}, {66500, 2}, {66504, 1}, {66518, 2},
2014 {66560, 17866755}, {66561, 17867011}, {66562, 17867267}, {66563, 17867523},
2015 {66564, 17867779}, {66565, 17868035}, {66566, 17868291}, {66567, 17868547},
2016 {66568, 17868803}, {66569, 17869059}, {66570, 17869315}, {66571, 17869571},
2017 {66572, 17869827}, {66573, 17870083}, {66574, 17870339}, {66575, 17870595},
2018 {66576, 17870851}, {66577, 17871107}, {66578, 17871363}, {66579, 17871619},
2019 {66580, 17871875}, {66581, 17872131}, {66582, 17872387}, {66583, 17872643},
2020 {66584, 17872899}, {66585, 17873155}, {66586, 17873411}, {66587, 17873667},
2021 {66588, 17873923}, {66589, 17874179}, {66590, 17874435}, {66591, 17874691},
2022 {66592, 17874947}, {66593, 17875203}, {66594, 17875459}, {66595, 17875715},
2023 {66596, 17875971}, {66597, 17876227}, {66598, 17876483}, {66599, 17876739},
2024 {66600, 1}, {66718, 2}, {66720, 1}, {66730, 2},
2025 {66736, 17876995}, {66737, 17877251}, {66738, 17877507}, {66739, 17877763},
2026 {66740, 17878019}, {66741, 17878275}, {66742, 17878531}, {66743, 17878787},
2027 {66744, 17879043}, {66745, 17879299}, {66746, 17879555}, {66747, 17879811},
2028 {66748, 17880067}, {66749, 17880323}, {66750, 17880579}, {66751, 17880835},
2029 {66752, 17881091}, {66753, 17881347}, {66754, 17881603}, {66755, 17881859},
2030 {66756, 17882115}, {66757, 17882371}, {66758, 17882627}, {66759, 17882883},
2031 {66760, 17883139}, {66761, 17883395}, {66762, 17883651}, {66763, 17883907},
2032 {66764, 17884163}, {66765, 17884419}, {66766, 17884675}, {66767, 17884931},
2033 {66768, 17885187}, {66769, 17885443}, {66770, 17885699}, {66771, 17885955},
2034 {66772, 2}, {66776, 1}, {66812, 2}, {66816, 1},
2035 {66856, 2}, {66864, 1}, {66916, 2}, {66927, 1},
2036 {66928, 17886211}, {66929, 17886467}, {66930, 17886723}, {66931, 17886979},
2037 {66932, 17887235}, {66933, 17887491}, {66934, 17887747}, {66935, 17888003},
2038 {66936, 17888259}, {66937, 17888515}, {66938, 17888771}, {66939, 2},
2039 {66940, 17889027}, {66941, 17889283}, {66942, 17889539}, {66943, 17889795},
2040 {66944, 17890051}, {66945, 17890307}, {66946, 17890563}, {66947, 17890819},
2041 {66948, 17891075}, {66949, 17891331}, {66950, 17891587}, {66951, 17891843},
2042 {66952, 17892099}, {66953, 17892355}, {66954, 17892611}, {66955, 2},
2043 {66956, 17892867}, {66957, 17893123}, {66958, 17893379}, {66959, 17893635},
2044 {66960, 17893891}, {66961, 17894147}, {66962, 17894403}, {66963, 2},
2045 {66964, 17894659}, {66965, 17894915}, {66966, 2}, {66967, 1},
2046 {66978, 2}, {66979, 1}, {66994, 2}, {66995, 1},
2047 {67002, 2}, {67003, 1}, {67005, 2}, {67072, 1},
2048 {67383, 2}, {67392, 1}, {67414, 2}, {67424, 1},
2049 {67432, 2}, {67456, 1}, {67457, 17895171}, {67458, 17895427},
2050 {67459, 16791043}, {67460, 17895683}, {67461, 16814083}, {67462, 2},
2051 {67463, 17895939}, {67464, 17896195}, {67465, 17896451}, {67466, 17896707},
2052 {67467, 16815363}, {67468, 16815619}, {67469, 17896963}, {67470, 17897219},
2053 {67471, 17897475}, {67472, 17897731}, {67473, 17897987}, {67474, 17898243},
2054 {67475, 16817155}, {67476, 17898499}, {67477, 16802051}, {67478, 17898755},
2055 {67479, 17899011}, {67480, 17899267}, {67481, 17899523}, {67482, 17899779},
2056 {67483, 17512963}, {67484, 17900035}, {67485, 17900291}, {67486, 17900547},
2057 {67487, 17900803}, {67488, 17901059}, {67489, 17901315}, {67490, 16795395},
2058 {67491, 17901571}, {67492, 17901827}, {67493, 16781315}, {67494, 17902083},
2059 {67495, 17902339}, {67496, 17125379}, {67497, 17902595}, {67498, 16819971},
2060 {67499, 17902851}, {67500, 17903107}, {67501, 17903363}, {67502, 17903619},
2061 {67503, 16820995}, {67504, 17903875}, {67505, 2}, {67506, 17904131},
2062 {67507, 17904387}, {67508, 17904643}, {67509, 17904899}, {67510, 17905155},
2063 {67511, 17905411}, {67512, 17905667}, {67513, 17905923}, {67514, 17906179},
2064 {67515, 2}, {67584, 1}, {67590, 2}, {67592, 1},
2065 {67593, 2}, {67594, 1}, {67638, 2}, {67639, 1},
2066 {67641, 2}, {67644, 1}, {67645, 2}, {67647, 1},
2067 {67670, 2}, {67671, 1}, {67743, 2}, {67751, 1},
2068 {67760, 2}, {67808, 1}, {67827, 2}, {67828, 1},
2069 {67830, 2}, {67835, 1}, {67868, 2}, {67871, 1},
2070 {67898, 2}, {67903, 1}, {67904, 2}, {67968, 1},
2071 {68024, 2}, {68028, 1}, {68048, 2}, {68050, 1},
2072 {68100, 2}, {68101, 1}, {68103, 2}, {68108, 1},
2073 {68116, 2}, {68117, 1}, {68120, 2}, {68121, 1},
2074 {68150, 2}, {68152, 1}, {68155, 2}, {68159, 1},
2075 {68169, 2}, {68176, 1}, {68185, 2}, {68192, 1},
2076 {68256, 2}, {68288, 1}, {68327, 2}, {68331, 1},
2077 {68343, 2}, {68352, 1}, {68406, 2}, {68409, 1},
2078 {68438, 2}, {68440, 1}, {68467, 2}, {68472, 1},
2079 {68498, 2}, {68505, 1}, {68509, 2}, {68521, 1},
2080 {68528, 2}, {68608, 1}, {68681, 2}, {68736, 17906435},
2081 {68737, 17906691}, {68738, 17906947}, {68739, 17907203}, {68740, 17907459},
2082 {68741, 17907715}, {68742, 17907971}, {68743, 17908227}, {68744, 17908483},
2083 {68745, 17908739}, {68746, 17908995}, {68747, 17909251}, {68748, 17909507},
2084 {68749, 17909763}, {68750, 17910019}, {68751, 17910275}, {68752, 17910531},
2085 {68753, 17910787}, {68754, 17911043}, {68755, 17911299}, {68756, 17911555},
2086 {68757, 17911811}, {68758, 17912067}, {68759, 17912323}, {68760, 17912579},
2087 {68761, 17912835}, {68762, 17913091}, {68763, 17913347}, {68764, 17913603},
2088 {68765, 17913859}, {68766, 17914115}, {68767, 17914371}, {68768, 17914627},
2089 {68769, 17914883}, {68770, 17915139}, {68771, 17915395}, {68772, 17915651},
2090 {68773, 17915907}, {68774, 17916163}, {68775, 17916419}, {68776, 17916675},
2091 {68777, 17916931}, {68778, 17917187}, {68779, 17917443}, {68780, 17917699},
2092 {68781, 17917955}, {68782, 17918211}, {68783, 17918467}, {68784, 17918723},
2093 {68785, 17918979}, {68786, 17919235}, {68787, 2}, {68800, 1},
2094 {68851, 2}, {68858, 1}, {68904, 2}, {68912, 1},
2095 {68922, 2}, {69216, 1}, {69247, 2}, {69248, 1},
2096 {69290, 2}, {69291, 1}, {69294, 2}, {69296, 1},
2097 {69298, 2}, {69373, 1}, {69416, 2}, {69424, 1},
2098 {69466, 2}, {69488, 1}, {69514, 2}, {69552, 1},
2099 {69580, 2}, {69600, 1}, {69623, 2}, {69632, 1},
2100 {69710, 2}, {69714, 1}, {69750, 2}, {69759, 1},
2101 {69821, 2}, {69822, 1}, {69827, 2}, {69840, 1},
2102 {69865, 2}, {69872, 1}, {69882, 2}, {69888, 1},
2103 {69941, 2}, {69942, 1}, {69960, 2}, {69968, 1},
2104 {70007, 2}, {70016, 1}, {70112, 2}, {70113, 1},
2105 {70133, 2}, {70144, 1}, {70162, 2}, {70163, 1},
2106 {70210, 2}, {70272, 1}, {70279, 2}, {70280, 1},
2107 {70281, 2}, {70282, 1}, {70286, 2}, {70287, 1},
2108 {70302, 2}, {70303, 1}, {70314, 2}, {70320, 1},
2109 {70379, 2}, {70384, 1}, {70394, 2}, {70400, 1},
2110 {70404, 2}, {70405, 1}, {70413, 2}, {70415, 1},
2111 {70417, 2}, {70419, 1}, {70441, 2}, {70442, 1},
2112 {70449, 2}, {70450, 1}, {70452, 2}, {70453, 1},
2113 {70458, 2}, {70459, 1}, {70469, 2}, {70471, 1},
2114 {70473, 2}, {70475, 1}, {70478, 2}, {70480, 1},
2115 {70481, 2}, {70487, 1}, {70488, 2}, {70493, 1},
2116 {70500, 2}, {70502, 1}, {70509, 2}, {70512, 1},
2117 {70517, 2}, {70656, 1}, {70748, 2}, {70749, 1},
2118 {70754, 2}, {70784, 1}, {70856, 2}, {70864, 1},
2119 {70874, 2}, {71040, 1}, {71094, 2}, {71096, 1},
2120 {71134, 2}, {71168, 1}, {71237, 2}, {71248, 1},
2121 {71258, 2}, {71264, 1}, {71277, 2}, {71296, 1},
2122 {71354, 2}, {71360, 1}, {71370, 2}, {71424, 1},
2123 {71451, 2}, {71453, 1}, {71468, 2}, {71472, 1},
2124 {71495, 2}, {71680, 1}, {71740, 2}, {71840, 17919491},
2125 {71841, 17919747}, {71842, 17920003}, {71843, 17920259}, {71844, 17920515},
2126 {71845, 17920771}, {71846, 17921027}, {71847, 17921283}, {71848, 17921539},
2127 {71849, 17921795}, {71850, 17922051}, {71851, 17922307}, {71852, 17922563},
2128 {71853, 17922819}, {71854, 17923075}, {71855, 17923331}, {71856, 17923587},
2129 {71857, 17923843}, {71858, 17924099}, {71859, 17924355}, {71860, 17924611},
2130 {71861, 17924867}, {71862, 17925123}, {71863, 17925379}, {71864, 17925635},
2131 {71865, 17925891}, {71866, 17926147}, {71867, 17926403}, {71868, 17926659},
2132 {71869, 17926915}, {71870, 17927171}, {71871, 17927427}, {71872, 1},
2133 {71923, 2}, {71935, 1}, {71943, 2}, {71945, 1},
2134 {71946, 2}, {71948, 1}, {71956, 2}, {71957, 1},
2135 {71959, 2}, {71960, 1}, {71990, 2}, {71991, 1},
2136 {71993, 2}, {71995, 1}, {72007, 2}, {72016, 1},
2137 {72026, 2}, {72096, 1}, {72104, 2}, {72106, 1},
2138 {72152, 2}, {72154, 1}, {72165, 2}, {72192, 1},
2139 {72264, 2}, {72272, 1}, {72355, 2}, {72368, 1},
2140 {72441, 2}, {72448, 1}, {72458, 2}, {72704, 1},
2141 {72713, 2}, {72714, 1}, {72759, 2}, {72760, 1},
2142 {72774, 2}, {72784, 1}, {72813, 2}, {72816, 1},
2143 {72848, 2}, {72850, 1}, {72872, 2}, {72873, 1},
2144 {72887, 2}, {72960, 1}, {72967, 2}, {72968, 1},
2145 {72970, 2}, {72971, 1}, {73015, 2}, {73018, 1},
2146 {73019, 2}, {73020, 1}, {73022, 2}, {73023, 1},
2147 {73032, 2}, {73040, 1}, {73050, 2}, {73056, 1},
2148 {73062, 2}, {73063, 1}, {73065, 2}, {73066, 1},
2149 {73103, 2}, {73104, 1}, {73106, 2}, {73107, 1},
2150 {73113, 2}, {73120, 1}, {73130, 2}, {73440, 1},
2151 {73465, 2}, {73472, 1}, {73489, 2}, {73490, 1},
2152 {73531, 2}, {73534, 1}, {73562, 2}, {73648, 1},
2153 {73649, 2}, {73664, 1}, {73714, 2}, {73727, 1},
2154 {74650, 2}, {74752, 1}, {74863, 2}, {74864, 1},
2155 {74869, 2}, {74880, 1}, {75076, 2}, {77712, 1},
2156 {77811, 2}, {77824, 1}, {78896, 2}, {78912, 1},
2157 {78934, 2}, {82944, 1}, {83527, 2}, {92160, 1},
2158 {92729, 2}, {92736, 1}, {92767, 2}, {92768, 1},
2159 {92778, 2}, {92782, 1}, {92863, 2}, {92864, 1},
2160 {92874, 2}, {92880, 1}, {92910, 2}, {92912, 1},
2161 {92918, 2}, {92928, 1}, {92998, 2}, {93008, 1},
2162 {93018, 2}, {93019, 1}, {93026, 2}, {93027, 1},
2163 {93048, 2}, {93053, 1}, {93072, 2}, {93760, 17927683},
2164 {93761, 17927939}, {93762, 17928195}, {93763, 17928451}, {93764, 17928707},
2165 {93765, 17928963}, {93766, 17929219}, {93767, 17929475}, {93768, 17929731},
2166 {93769, 17929987}, {93770, 17930243}, {93771, 17930499}, {93772, 17930755},
2167 {93773, 17931011}, {93774, 17931267}, {93775, 17931523}, {93776, 17931779},
2168 {93777, 17932035}, {93778, 17932291}, {93779, 17932547}, {93780, 17932803},
2169 {93781, 17933059}, {93782, 17933315}, {93783, 17933571}, {93784, 17933827},
2170 {93785, 17934083}, {93786, 17934339}, {93787, 17934595}, {93788, 17934851},
2171 {93789, 17935107}, {93790, 17935363}, {93791, 17935619}, {93792, 1},
2172 {93851, 2}, {93952, 1}, {94027, 2}, {94031, 1},
2173 {94088, 2}, {94095, 1}, {94112, 2}, {94176, 1},
2174 {94181, 2}, {94192, 1}, {94194, 2}, {94208, 1},
2175 {100344, 2}, {100352, 1}, {101590, 2}, {101632, 1},
2176 {101641, 2}, {110576, 1}, {110580, 2}, {110581, 1},
2177 {110588, 2}, {110589, 1}, {110591, 2}, {110592, 1},
2178 {110883, 2}, {110898, 1}, {110899, 2}, {110928, 1},
2179 {110931, 2}, {110933, 1}, {110934, 2}, {110948, 1},
2180 {110952, 2}, {110960, 1}, {111356, 2}, {113664, 1},
2181 {113771, 2}, {113776, 1}, {113789, 2}, {113792, 1},
2182 {113801, 2}, {113808, 1}, {113818, 2}, {113820, 1},
2183 {113824, 0}, {113828, 2}, {118528, 1}, {118574, 2},
2184 {118576, 1}, {118599, 2}, {118608, 1}, {118724, 2},
2185 {118784, 1}, {119030, 2}, {119040, 1}, {119079, 2},
2186 {119081, 1}, {119134, 34713091}, {119135, 34713603}, {119136, 51491331},
2187 {119137, 51492099}, {119138, 51492867}, {119139, 51493635}, {119140, 51494403},
2188 {119141, 1}, {119155, 2}, {119163, 1}, {119227, 34717955},
2189 {119228, 34718467}, {119229, 51496195}, {119230, 51496963}, {119231, 51497731},
2190 {119232, 51498499}, {119233, 1}, {119275, 2}, {119296, 1},
2191 {119366, 2}, {119488, 1}, {119508, 2}, {119520, 1},
2192 {119540, 2}, {119552, 1}, {119639, 2}, {119648, 1},
2193 {119673, 2}, {119808, 16777219}, {119809, 16777475}, {119810, 16777731},
2194 {119811, 16777987}, {119812, 16778243}, {119813, 16778499}, {119814, 16778755},
2195 {119815, 16779011}, {119816, 16779267}, {119817, 16779523}, {119818, 16779779},
2196 {119819, 16780035}, {119820, 16780291}, {119821, 16780547}, {119822, 16780803},
2197 {119823, 16781059}, {119824, 16781315}, {119825, 16781571}, {119826, 16781827},
2198 {119827, 16782083}, {119828, 16782339}, {119829, 16782595}, {119830, 16782851},
2199 {119831, 16783107}, {119832, 16783363}, {119833, 16783619}, {119834, 16777219},
2200 {119835, 16777475}, {119836, 16777731}, {119837, 16777987}, {119838, 16778243},
2201 {119839, 16778499}, {119840, 16778755}, {119841, 16779011}, {119842, 16779267},
2202 {119843, 16779523}, {119844, 16779779}, {119845, 16780035}, {119846, 16780291},
2203 {119847, 16780547}, {119848, 16780803}, {119849, 16781059}, {119850, 16781315},
2204 {119851, 16781571}, {119852, 16781827}, {119853, 16782083}, {119854, 16782339},
2205 {119855, 16782595}, {119856, 16782851}, {119857, 16783107}, {119858, 16783363},
2206 {119859, 16783619}, {119860, 16777219}, {119861, 16777475}, {119862, 16777731},
2207 {119863, 16777987}, {119864, 16778243}, {119865, 16778499}, {119866, 16778755},
2208 {119867, 16779011}, {119868, 16779267}, {119869, 16779523}, {119870, 16779779},
2209 {119871, 16780035}, {119872, 16780291}, {119873, 16780547}, {119874, 16780803},
2210 {119875, 16781059}, {119876, 16781315}, {119877, 16781571}, {119878, 16781827},
2211 {119879, 16782083}, {119880, 16782339}, {119881, 16782595}, {119882, 16782851},
2212 {119883, 16783107}, {119884, 16783363}, {119885, 16783619}, {119886, 16777219},
2213 {119887, 16777475}, {119888, 16777731}, {119889, 16777987}, {119890, 16778243},
2214 {119891, 16778499}, {119892, 16778755}, {119893, 2}, {119894, 16779267},
2215 {119895, 16779523}, {119896, 16779779}, {119897, 16780035}, {119898, 16780291},
2216 {119899, 16780547}, {119900, 16780803}, {119901, 16781059}, {119902, 16781315},
2217 {119903, 16781571}, {119904, 16781827}, {119905, 16782083}, {119906, 16782339},
2218 {119907, 16782595}, {119908, 16782851}, {119909, 16783107}, {119910, 16783363},
2219 {119911, 16783619}, {119912, 16777219}, {119913, 16777475}, {119914, 16777731},
2220 {119915, 16777987}, {119916, 16778243}, {119917, 16778499}, {119918, 16778755},
2221 {119919, 16779011}, {119920, 16779267}, {119921, 16779523}, {119922, 16779779},
2222 {119923, 16780035}, {119924, 16780291}, {119925, 16780547}, {119926, 16780803},
2223 {119927, 16781059}, {119928, 16781315}, {119929, 16781571}, {119930, 16781827},
2224 {119931, 16782083}, {119932, 16782339}, {119933, 16782595}, {119934, 16782851},
2225 {119935, 16783107}, {119936, 16783363}, {119937, 16783619}, {119938, 16777219},
2226 {119939, 16777475}, {119940, 16777731}, {119941, 16777987}, {119942, 16778243},
2227 {119943, 16778499}, {119944, 16778755}, {119945, 16779011}, {119946, 16779267},
2228 {119947, 16779523}, {119948, 16779779}, {119949, 16780035}, {119950, 16780291},
2229 {119951, 16780547}, {119952, 16780803}, {119953, 16781059}, {119954, 16781315},
2230 {119955, 16781571}, {119956, 16781827}, {119957, 16782083}, {119958, 16782339},
2231 {119959, 16782595}, {119960, 16782851}, {119961, 16783107}, {119962, 16783363},
2232 {119963, 16783619}, {119964, 16777219}, {119965, 2}, {119966, 16777731},
2233 {119967, 16777987}, {119968, 2}, {119970, 16778755}, {119971, 2},
2234 {119973, 16779523}, {119974, 16779779}, {119975, 2}, {119977, 16780547},
2235 {119978, 16780803}, {119979, 16781059}, {119980, 16781315}, {119981, 2},
2236 {119982, 16781827}, {119983, 16782083}, {119984, 16782339}, {119985, 16782595},
2237 {119986, 16782851}, {119987, 16783107}, {119988, 16783363}, {119989, 16783619},
2238 {119990, 16777219}, {119991, 16777475}, {119992, 16777731}, {119993, 16777987},
2239 {119994, 2}, {119995, 16778499}, {119996, 2}, {119997, 16779011},
2240 {119998, 16779267}, {119999, 16779523}, {120000, 16779779}, {120001, 16780035},
2241 {120002, 16780291}, {120003, 16780547}, {120004, 2}, {120005, 16781059},
2242 {120006, 16781315}, {120007, 16781571}, {120008, 16781827}, {120009, 16782083},
2243 {120010, 16782339}, {120011, 16782595}, {120012, 16782851}, {120013, 16783107},
2244 {120014, 16783363}, {120015, 16783619}, {120016, 16777219}, {120017, 16777475},
2245 {120018, 16777731}, {120019, 16777987}, {120020, 16778243}, {120021, 16778499},
2246 {120022, 16778755}, {120023, 16779011}, {120024, 16779267}, {120025, 16779523},
2247 {120026, 16779779}, {120027, 16780035}, {120028, 16780291}, {120029, 16780547},
2248 {120030, 16780803}, {120031, 16781059}, {120032, 16781315}, {120033, 16781571},
2249 {120034, 16781827}, {120035, 16782083}, {120036, 16782339}, {120037, 16782595},
2250 {120038, 16782851}, {120039, 16783107}, {120040, 16783363}, {120041, 16783619},
2251 {120042, 16777219}, {120043, 16777475}, {120044, 16777731}, {120045, 16777987},
2252 {120046, 16778243}, {120047, 16778499}, {120048, 16778755}, {120049, 16779011},
2253 {120050, 16779267}, {120051, 16779523}, {120052, 16779779}, {120053, 16780035},
2254 {120054, 16780291}, {120055, 16780547}, {120056, 16780803}, {120057, 16781059},
2255 {120058, 16781315}, {120059, 16781571}, {120060, 16781827}, {120061, 16782083},
2256 {120062, 16782339}, {120063, 16782595}, {120064, 16782851}, {120065, 16783107},
2257 {120066, 16783363}, {120067, 16783619}, {120068, 16777219}, {120069, 16777475},
2258 {120070, 2}, {120071, 16777987}, {120072, 16778243}, {120073, 16778499},
2259 {120074, 16778755}, {120075, 2}, {120077, 16779523}, {120078, 16779779},
2260 {120079, 16780035}, {120080, 16780291}, {120081, 16780547}, {120082, 16780803},
2261 {120083, 16781059}, {120084, 16781315}, {120085, 2}, {120086, 16781827},
2262 {120087, 16782083}, {120088, 16782339}, {120089, 16782595}, {120090, 16782851},
2263 {120091, 16783107}, {120092, 16783363}, {120093, 2}, {120094, 16777219},
2264 {120095, 16777475}, {120096, 16777731}, {120097, 16777987}, {120098, 16778243},
2265 {120099, 16778499}, {120100, 16778755}, {120101, 16779011}, {120102, 16779267},
2266 {120103, 16779523}, {120104, 16779779}, {120105, 16780035}, {120106, 16780291},
2267 {120107, 16780547}, {120108, 16780803}, {120109, 16781059}, {120110, 16781315},
2268 {120111, 16781571}, {120112, 16781827}, {120113, 16782083}, {120114, 16782339},
2269 {120115, 16782595}, {120116, 16782851}, {120117, 16783107}, {120118, 16783363},
2270 {120119, 16783619}, {120120, 16777219}, {120121, 16777475}, {120122, 2},
2271 {120123, 16777987}, {120124, 16778243}, {120125, 16778499}, {120126, 16778755},
2272 {120127, 2}, {120128, 16779267}, {120129, 16779523}, {120130, 16779779},
2273 {120131, 16780035}, {120132, 16780291}, {120133, 2}, {120134, 16780803},
2274 {120135, 2}, {120138, 16781827}, {120139, 16782083}, {120140, 16782339},
2275 {120141, 16782595}, {120142, 16782851}, {120143, 16783107}, {120144, 16783363},
2276 {120145, 2}, {120146, 16777219}, {120147, 16777475}, {120148, 16777731},
2277 {120149, 16777987}, {120150, 16778243}, {120151, 16778499}, {120152, 16778755},
2278 {120153, 16779011}, {120154, 16779267}, {120155, 16779523}, {120156, 16779779},
2279 {120157, 16780035}, {120158, 16780291}, {120159, 16780547}, {120160, 16780803},
2280 {120161, 16781059}, {120162, 16781315}, {120163, 16781571}, {120164, 16781827},
2281 {120165, 16782083}, {120166, 16782339}, {120167, 16782595}, {120168, 16782851},
2282 {120169, 16783107}, {120170, 16783363}, {120171, 16783619}, {120172, 16777219},
2283 {120173, 16777475}, {120174, 16777731}, {120175, 16777987}, {120176, 16778243},
2284 {120177, 16778499}, {120178, 16778755}, {120179, 16779011}, {120180, 16779267},
2285 {120181, 16779523}, {120182, 16779779}, {120183, 16780035}, {120184, 16780291},
2286 {120185, 16780547}, {120186, 16780803}, {120187, 16781059}, {120188, 16781315},
2287 {120189, 16781571}, {120190, 16781827}, {120191, 16782083}, {120192, 16782339},
2288 {120193, 16782595}, {120194, 16782851}, {120195, 16783107}, {120196, 16783363},
2289 {120197, 16783619}, {120198, 16777219}, {120199, 16777475}, {120200, 16777731},
2290 {120201, 16777987}, {120202, 16778243}, {120203, 16778499}, {120204, 16778755},
2291 {120205, 16779011}, {120206, 16779267}, {120207, 16779523}, {120208, 16779779},
2292 {120209, 16780035}, {120210, 16780291}, {120211, 16780547}, {120212, 16780803},
2293 {120213, 16781059}, {120214, 16781315}, {120215, 16781571}, {120216, 16781827},
2294 {120217, 16782083}, {120218, 16782339}, {120219, 16782595}, {120220, 16782851},
2295 {120221, 16783107}, {120222, 16783363}, {120223, 16783619}, {120224, 16777219},
2296 {120225, 16777475}, {120226, 16777731}, {120227, 16777987}, {120228, 16778243},
2297 {120229, 16778499}, {120230, 16778755}, {120231, 16779011}, {120232, 16779267},
2298 {120233, 16779523}, {120234, 16779779}, {120235, 16780035}, {120236, 16780291},
2299 {120237, 16780547}, {120238, 16780803}, {120239, 16781059}, {120240, 16781315},
2300 {120241, 16781571}, {120242, 16781827}, {120243, 16782083}, {120244, 16782339},
2301 {120245, 16782595}, {120246, 16782851}, {120247, 16783107}, {120248, 16783363},
2302 {120249, 16783619}, {120250, 16777219}, {120251, 16777475}, {120252, 16777731},
2303 {120253, 16777987}, {120254, 16778243}, {120255, 16778499}, {120256, 16778755},
2304 {120257, 16779011}, {120258, 16779267}, {120259, 16779523}, {120260, 16779779},
2305 {120261, 16780035}, {120262, 16780291}, {120263, 16780547}, {120264, 16780803},
2306 {120265, 16781059}, {120266, 16781315}, {120267, 16781571}, {120268, 16781827},
2307 {120269, 16782083}, {120270, 16782339}, {120271, 16782595}, {120272, 16782851},
2308 {120273, 16783107}, {120274, 16783363}, {120275, 16783619}, {120276, 16777219},
2309 {120277, 16777475}, {120278, 16777731}, {120279, 16777987}, {120280, 16778243},
2310 {120281, 16778499}, {120282, 16778755}, {120283, 16779011}, {120284, 16779267},
2311 {120285, 16779523}, {120286, 16779779}, {120287, 16780035}, {120288, 16780291},
2312 {120289, 16780547}, {120290, 16780803}, {120291, 16781059}, {120292, 16781315},
2313 {120293, 16781571}, {120294, 16781827}, {120295, 16782083}, {120296, 16782339},
2314 {120297, 16782595}, {120298, 16782851}, {120299, 16783107}, {120300, 16783363},
2315 {120301, 16783619}, {120302, 16777219}, {120303, 16777475}, {120304, 16777731},
2316 {120305, 16777987}, {120306, 16778243}, {120307, 16778499}, {120308, 16778755},
2317 {120309, 16779011}, {120310, 16779267}, {120311, 16779523}, {120312, 16779779},
2318 {120313, 16780035}, {120314, 16780291}, {120315, 16780547}, {120316, 16780803},
2319 {120317, 16781059}, {120318, 16781315}, {120319, 16781571}, {120320, 16781827},
2320 {120321, 16782083}, {120322, 16782339}, {120323, 16782595}, {120324, 16782851},
2321 {120325, 16783107}, {120326, 16783363}, {120327, 16783619}, {120328, 16777219},
2322 {120329, 16777475}, {120330, 16777731}, {120331, 16777987}, {120332, 16778243},
2323 {120333, 16778499}, {120334, 16778755}, {120335, 16779011}, {120336, 16779267},
2324 {120337, 16779523}, {120338, 16779779}, {120339, 16780035}, {120340, 16780291},
2325 {120341, 16780547}, {120342, 16780803}, {120343, 16781059}, {120344, 16781315},
2326 {120345, 16781571}, {120346, 16781827}, {120347, 16782083}, {120348, 16782339},
2327 {120349, 16782595}, {120350, 16782851}, {120351, 16783107}, {120352, 16783363},
2328 {120353, 16783619}, {120354, 16777219}, {120355, 16777475}, {120356, 16777731},
2329 {120357, 16777987}, {120358, 16778243}, {120359, 16778499}, {120360, 16778755},
2330 {120361, 16779011}, {120362, 16779267}, {120363, 16779523}, {120364, 16779779},
2331 {120365, 16780035}, {120366, 16780291}, {120367, 16780547}, {120368, 16780803},
2332 {120369, 16781059}, {120370, 16781315}, {120371, 16781571}, {120372, 16781827},
2333 {120373, 16782083}, {120374, 16782339}, {120375, 16782595}, {120376, 16782851},
2334 {120377, 16783107}, {120378, 16783363}, {120379, 16783619}, {120380, 16777219},
2335 {120381, 16777475}, {120382, 16777731}, {120383, 16777987}, {120384, 16778243},
2336 {120385, 16778499}, {120386, 16778755}, {120387, 16779011}, {120388, 16779267},
2337 {120389, 16779523}, {120390, 16779779}, {120391, 16780035}, {120392, 16780291},
2338 {120393, 16780547}, {120394, 16780803}, {120395, 16781059}, {120396, 16781315},
2339 {120397, 16781571}, {120398, 16781827}, {120399, 16782083}, {120400, 16782339},
2340 {120401, 16782595}, {120402, 16782851}, {120403, 16783107}, {120404, 16783363},
2341 {120405, 16783619}, {120406, 16777219}, {120407, 16777475}, {120408, 16777731},
2342 {120409, 16777987}, {120410, 16778243}, {120411, 16778499}, {120412, 16778755},
2343 {120413, 16779011}, {120414, 16779267}, {120415, 16779523}, {120416, 16779779},
2344 {120417, 16780035}, {120418, 16780291}, {120419, 16780547}, {120420, 16780803},
2345 {120421, 16781059}, {120422, 16781315}, {120423, 16781571}, {120424, 16781827},
2346 {120425, 16782083}, {120426, 16782339}, {120427, 16782595}, {120428, 16782851},
2347 {120429, 16783107}, {120430, 16783363}, {120431, 16783619}, {120432, 16777219},
2348 {120433, 16777475}, {120434, 16777731}, {120435, 16777987}, {120436, 16778243},
2349 {120437, 16778499}, {120438, 16778755}, {120439, 16779011}, {120440, 16779267},
2350 {120441, 16779523}, {120442, 16779779}, {120443, 16780035}, {120444, 16780291},
2351 {120445, 16780547}, {120446, 16780803}, {120447, 16781059}, {120448, 16781315},
2352 {120449, 16781571}, {120450, 16781827}, {120451, 16782083}, {120452, 16782339},
2353 {120453, 16782595}, {120454, 16782851}, {120455, 16783107}, {120456, 16783363},
2354 {120457, 16783619}, {120458, 16777219}, {120459, 16777475}, {120460, 16777731},
2355 {120461, 16777987}, {120462, 16778243}, {120463, 16778499}, {120464, 16778755},
2356 {120465, 16779011}, {120466, 16779267}, {120467, 16779523}, {120468, 16779779},
2357 {120469, 16780035}, {120470, 16780291}, {120471, 16780547}, {120472, 16780803},
2358 {120473, 16781059}, {120474, 16781315}, {120475, 16781571}, {120476, 16781827},
2359 {120477, 16782083}, {120478, 16782339}, {120479, 16782595}, {120480, 16782851},
2360 {120481, 16783107}, {120482, 16783363}, {120483, 16783619}, {120484, 17944835},
2361 {120485, 17945091}, {120486, 2}, {120488, 16851715}, {120489, 16851971},
2362 {120490, 16852227}, {120491, 16852483}, {120492, 16852739}, {120493, 16852995},
2363 {120494, 16853251}, {120495, 16853507}, {120496, 16846851}, {120497, 16853763},
2364 {120498, 16854019}, {120499, 16786179}, {120500, 16854275}, {120501, 16854531},
2365 {120502, 16854787}, {120503, 16855043}, {120504, 16855299}, {120505, 16853507},
2366 {120506, 16855555}, {120507, 16855811}, {120508, 16856067}, {120509, 16856323},
2367 {120510, 16856579}, {120511, 16856835}, {120512, 16857091}, {120513, 17945347},
2368 {120514, 16851715}, {120515, 16851971}, {120516, 16852227}, {120517, 16852483},
2369 {120518, 16852739}, {120519, 16852995}, {120520, 16853251}, {120521, 16853507},
2370 {120522, 16846851}, {120523, 16853763}, {120524, 16854019}, {120525, 16786179},
2371 {120526, 16854275}, {120527, 16854531}, {120528, 16854787}, {120529, 16855043},
2372 {120530, 16855299}, {120531, 16855555}, {120533, 16855811}, {120534, 16856067},
2373 {120535, 16856323}, {120536, 16856579}, {120537, 16856835}, {120538, 16857091},
2374 {120539, 17945603}, {120540, 16852739}, {120541, 16853507}, {120542, 16853763},
2375 {120543, 16856323}, {120544, 16855299}, {120545, 16855043}, {120546, 16851715},
2376 {120547, 16851971}, {120548, 16852227}, {120549, 16852483}, {120550, 16852739},
2377 {120551, 16852995}, {120552, 16853251}, {120553, 16853507}, {120554, 16846851},
2378 {120555, 16853763}, {120556, 16854019}, {120557, 16786179}, {120558, 16854275},
2379 {120559, 16854531}, {120560, 16854787}, {120561, 16855043}, {120562, 16855299},
2380 {120563, 16853507}, {120564, 16855555}, {120565, 16855811}, {120566, 16856067},
2381 {120567, 16856323}, {120568, 16856579}, {120569, 16856835}, {120570, 16857091},
2382 {120571, 17945347}, {120572, 16851715}, {120573, 16851971}, {120574, 16852227},
2383 {120575, 16852483}, {120576, 16852739}, {120577, 16852995}, {120578, 16853251},
2384 {120579, 16853507}, {120580, 16846851}, {120581, 16853763}, {120582, 16854019},
2385 {120583, 16786179}, {120584, 16854275}, {120585, 16854531}, {120586, 16854787},
2386 {120587, 16855043}, {120588, 16855299}, {120589, 16855555}, {120591, 16855811},
2387 {120592, 16856067}, {120593, 16856323}, {120594, 16856579}, {120595, 16856835},
2388 {120596, 16857091}, {120597, 17945603}, {120598, 16852739}, {120599, 16853507},
2389 {120600, 16853763}, {120601, 16856323}, {120602, 16855299}, {120603, 16855043},
2390 {120604, 16851715}, {120605, 16851971}, {120606, 16852227}, {120607, 16852483},
2391 {120608, 16852739}, {120609, 16852995}, {120610, 16853251}, {120611, 16853507},
2392 {120612, 16846851}, {120613, 16853763}, {120614, 16854019}, {120615, 16786179},
2393 {120616, 16854275}, {120617, 16854531}, {120618, 16854787}, {120619, 16855043},
2394 {120620, 16855299}, {120621, 16853507}, {120622, 16855555}, {120623, 16855811},
2395 {120624, 16856067}, {120625, 16856323}, {120626, 16856579}, {120627, 16856835},
2396 {120628, 16857091}, {120629, 17945347}, {120630, 16851715}, {120631, 16851971},
2397 {120632, 16852227}, {120633, 16852483}, {120634, 16852739}, {120635, 16852995},
2398 {120636, 16853251}, {120637, 16853507}, {120638, 16846851}, {120639, 16853763},
2399 {120640, 16854019}, {120641, 16786179}, {120642, 16854275}, {120643, 16854531},
2400 {120644, 16854787}, {120645, 16855043}, {120646, 16855299}, {120647, 16855555},
2401 {120649, 16855811}, {120650, 16856067}, {120651, 16856323}, {120652, 16856579},
2402 {120653, 16856835}, {120654, 16857091}, {120655, 17945603}, {120656, 16852739},
2403 {120657, 16853507}, {120658, 16853763}, {120659, 16856323}, {120660, 16855299},
2404 {120661, 16855043}, {120662, 16851715}, {120663, 16851971}, {120664, 16852227},
2405 {120665, 16852483}, {120666, 16852739}, {120667, 16852995}, {120668, 16853251},
2406 {120669, 16853507}, {120670, 16846851}, {120671, 16853763}, {120672, 16854019},
2407 {120673, 16786179}, {120674, 16854275}, {120675, 16854531}, {120676, 16854787},
2408 {120677, 16855043}, {120678, 16855299}, {120679, 16853507}, {120680, 16855555},
2409 {120681, 16855811}, {120682, 16856067}, {120683, 16856323}, {120684, 16856579},
2410 {120685, 16856835}, {120686, 16857091}, {120687, 17945347}, {120688, 16851715},
2411 {120689, 16851971}, {120690, 16852227}, {120691, 16852483}, {120692, 16852739},
2412 {120693, 16852995}, {120694, 16853251}, {120695, 16853507}, {120696, 16846851},
2413 {120697, 16853763}, {120698, 16854019}, {120699, 16786179}, {120700, 16854275},
2414 {120701, 16854531}, {120702, 16854787}, {120703, 16855043}, {120704, 16855299},
2415 {120705, 16855555}, {120707, 16855811}, {120708, 16856067}, {120709, 16856323},
2416 {120710, 16856579}, {120711, 16856835}, {120712, 16857091}, {120713, 17945603},
2417 {120714, 16852739}, {120715, 16853507}, {120716, 16853763}, {120717, 16856323},
2418 {120718, 16855299}, {120719, 16855043}, {120720, 16851715}, {120721, 16851971},
2419 {120722, 16852227}, {120723, 16852483}, {120724, 16852739}, {120725, 16852995},
2420 {120726, 16853251}, {120727, 16853507}, {120728, 16846851}, {120729, 16853763},
2421 {120730, 16854019}, {120731, 16786179}, {120732, 16854275}, {120733, 16854531},
2422 {120734, 16854787}, {120735, 16855043}, {120736, 16855299}, {120737, 16853507},
2423 {120738, 16855555}, {120739, 16855811}, {120740, 16856067}, {120741, 16856323},
2424 {120742, 16856579}, {120743, 16856835}, {120744, 16857091}, {120745, 17945347},
2425 {120746, 16851715}, {120747, 16851971}, {120748, 16852227}, {120749, 16852483},
2426 {120750, 16852739}, {120751, 16852995}, {120752, 16853251}, {120753, 16853507},
2427 {120754, 16846851}, {120755, 16853763}, {120756, 16854019}, {120757, 16786179},
2428 {120758, 16854275}, {120759, 16854531}, {120760, 16854787}, {120761, 16855043},
2429 {120762, 16855299}, {120763, 16855555}, {120765, 16855811}, {120766, 16856067},
2430 {120767, 16856323}, {120768, 16856579}, {120769, 16856835}, {120770, 16857091},
2431 {120771, 17945603}, {120772, 16852739}, {120773, 16853507}, {120774, 16853763},
2432 {120775, 16856323}, {120776, 16855299}, {120777, 16855043}, {120778, 16858627},
2433 {120780, 2}, {120782, 17035523}, {120783, 16786947}, {120784, 16785155},
2434 {120785, 16785411}, {120786, 16787715}, {120787, 17035779}, {120788, 17036035},
2435 {120789, 17036291}, {120790, 17036547}, {120791, 17036803}, {120792, 17035523},
2436 {120793, 16786947}, {120794, 16785155}, {120795, 16785411}, {120796, 16787715},
2437 {120797, 17035779}, {120798, 17036035}, {120799, 17036291}, {120800, 17036547},
2438 {120801, 17036803}, {120802, 17035523}, {120803, 16786947}, {120804, 16785155},
2439 {120805, 16785411}, {120806, 16787715}, {120807, 17035779}, {120808, 17036035},
2440 {120809, 17036291}, {120810, 17036547}, {120811, 17036803}, {120812, 17035523},
2441 {120813, 16786947}, {120814, 16785155}, {120815, 16785411}, {120816, 16787715},
2442 {120817, 17035779}, {120818, 17036035}, {120819, 17036291}, {120820, 17036547},
2443 {120821, 17036803}, {120822, 17035523}, {120823, 16786947}, {120824, 16785155},
2444 {120825, 16785411}, {120826, 16787715}, {120827, 17035779}, {120828, 17036035},
2445 {120829, 17036291}, {120830, 17036547}, {120831, 17036803}, {120832, 1},
2446 {121484, 2}, {121499, 1}, {121504, 2}, {121505, 1},
2447 {121520, 2}, {122624, 1}, {122655, 2}, {122661, 1},
2448 {122667, 2}, {122880, 1}, {122887, 2}, {122888, 1},
2449 {122905, 2}, {122907, 1}, {122914, 2}, {122915, 1},
2450 {122917, 2}, {122918, 1}, {122923, 2}, {122928, 16866563},
2451 {122929, 16866819}, {122930, 16867075}, {122931, 16867331}, {122932, 16867587},
2452 {122933, 16867843}, {122934, 16868099}, {122935, 16868355}, {122936, 16868611},
2453 {122937, 16869123}, {122938, 16869379}, {122939, 16869635}, {122940, 16870147},
2454 {122941, 16870403}, {122942, 16870659}, {122943, 16870915}, {122944, 16871171},
2455 {122945, 16871427}, {122946, 16871683}, {122947, 16871939}, {122948, 16872195},
2456 {122949, 16872451}, {122950, 16872707}, {122951, 16873475}, {122952, 16873987},
2457 {122953, 16874243}, {122954, 17495299}, {122955, 16888835}, {122956, 16864003},
2458 {122957, 16864515}, {122958, 16890883}, {122959, 16883715}, {122960, 17945859},
2459 {122961, 16866563}, {122962, 16866819}, {122963, 16867075}, {122964, 16867331},
2460 {122965, 16867587}, {122966, 16867843}, {122967, 16868099}, {122968, 16868355},
2461 {122969, 16868611}, {122970, 16869123}, {122971, 16869379}, {122972, 16870147},
2462 {122973, 16870403}, {122974, 16870915}, {122975, 16871427}, {122976, 16871683},
2463 {122977, 16871939}, {122978, 16872195}, {122979, 16872451}, {122980, 16872707},
2464 {122981, 16873219}, {122982, 16873475}, {122983, 16879875}, {122984, 16864003},
2465 {122985, 16863747}, {122986, 16866307}, {122987, 16883203}, {122988, 17490435},
2466 {122989, 16883971}, {122990, 2}, {123023, 1}, {123024, 2},
2467 {123136, 1}, {123181, 2}, {123184, 1}, {123198, 2},
2468 {123200, 1}, {123210, 2}, {123214, 1}, {123216, 2},
2469 {123536, 1}, {123567, 2}, {123584, 1}, {123642, 2},
2470 {123647, 1}, {123648, 2}, {124112, 1}, {124154, 2},
2471 {124896, 1}, {124903, 2}, {124904, 1}, {124908, 2},
2472 {124909, 1}, {124911, 2}, {124912, 1}, {124927, 2},
2473 {124928, 1}, {125125, 2}, {125127, 1}, {125143, 2},
2474 {125184, 17946115}, {125185, 17946371}, {125186, 17946627}, {125187, 17946883},
2475 {125188, 17947139}, {125189, 17947395}, {125190, 17947651}, {125191, 17947907},
2476 {125192, 17948163}, {125193, 17948419}, {125194, 17948675}, {125195, 17948931},
2477 {125196, 17949187}, {125197, 17949443}, {125198, 17949699}, {125199, 17949955},
2478 {125200, 17950211}, {125201, 17950467}, {125202, 17950723}, {125203, 17950979},
2479 {125204, 17951235}, {125205, 17951491}, {125206, 17951747}, {125207, 17952003},
2480 {125208, 17952259}, {125209, 17952515}, {125210, 17952771}, {125211, 17953027},
2481 {125212, 17953283}, {125213, 17953539}, {125214, 17953795}, {125215, 17954051},
2482 {125216, 17954307}, {125217, 17954563}, {125218, 1}, {125260, 2},
2483 {125264, 1}, {125274, 2}, {125278, 1}, {125280, 2},
2484 {126065, 1}, {126133, 2}, {126209, 1}, {126270, 2},
2485 {126464, 16910339}, {126465, 17683715}, {126466, 17681923}, {126467, 17834499},
2486 {126468, 2}, {126469, 16910851}, {126470, 17731587}, {126471, 17682435},
2487 {126472, 17700099}, {126473, 16911875}, {126474, 17708803}, {126475, 17711107},
2488 {126476, 17682947}, {126477, 17718019}, {126478, 17694979}, {126479, 17701635},
2489 {126480, 17703683}, {126481, 17697027}, {126482, 17706755}, {126483, 17725187},
2490 {126484, 17745155}, {126485, 17686787}, {126486, 17689859}, {126487, 17684995},
2491 {126488, 17724675}, {126489, 17698051}, {126490, 17701123}, {126491, 17702659},
2492 {126492, 17954819}, {126493, 17673475}, {126494, 17955075}, {126495, 17955331},
2493 {126496, 2}, {126497, 17683715}, {126498, 17681923}, {126499, 2},
2494 {126500, 17721091}, {126501, 2}, {126503, 17682435}, {126504, 2},
2495 {126505, 16911875}, {126506, 17708803}, {126507, 17711107}, {126508, 17682947},
2496 {126509, 17718019}, {126510, 17694979}, {126511, 17701635}, {126512, 17703683},
2497 {126513, 17697027}, {126514, 17706755}, {126515, 2}, {126516, 17745155},
2498 {126517, 17686787}, {126518, 17689859}, {126519, 17684995}, {126520, 2},
2499 {126521, 17698051}, {126522, 2}, {126523, 17702659}, {126524, 2},
2500 {126530, 17681923}, {126531, 2}, {126535, 17682435}, {126536, 2},
2501 {126537, 16911875}, {126538, 2}, {126539, 17711107}, {126540, 2},
2502 {126541, 17718019}, {126542, 17694979}, {126543, 17701635}, {126544, 2},
2503 {126545, 17697027}, {126546, 17706755}, {126547, 2}, {126548, 17745155},
2504 {126549, 2}, {126551, 17684995}, {126552, 2}, {126553, 17698051},
2505 {126554, 2}, {126555, 17702659}, {126556, 2}, {126557, 17673475},
2506 {126558, 2}, {126559, 17955331}, {126560, 2}, {126561, 17683715},
2507 {126562, 17681923}, {126563, 2}, {126564, 17721091}, {126565, 2},
2508 {126567, 17682435}, {126568, 17700099}, {126569, 16911875}, {126570, 17708803},
2509 {126571, 2}, {126572, 17682947}, {126573, 17718019}, {126574, 17694979},
2510 {126575, 17701635}, {126576, 17703683}, {126577, 17697027}, {126578, 17706755},
2511 {126579, 2}, {126580, 17745155}, {126581, 17686787}, {126582, 17689859},
2512 {126583, 17684995}, {126584, 2}, {126585, 17698051}, {126586, 17701123},
2513 {126587, 17702659}, {126588, 17954819}, {126589, 2}, {126590, 17955075},
2514 {126591, 2}, {126592, 16910339}, {126593, 17683715}, {126594, 17681923},
2515 {126595, 17834499}, {126596, 17721091}, {126597, 16910851}, {126598, 17731587},
2516 {126599, 17682435}, {126600, 17700099}, {126601, 16911875}, {126602, 2},
2517 {126603, 17711107}, {126604, 17682947}, {126605, 17718019}, {126606, 17694979},
2518 {126607, 17701635}, {126608, 17703683}, {126609, 17697027}, {126610, 17706755},
2519 {126611, 17725187}, {126612, 17745155}, {126613, 17686787}, {126614, 17689859},
2520 {126615, 17684995}, {126616, 17724675}, {126617, 17698051}, {126618, 17701123},
2521 {126619, 17702659}, {126620, 2}, {126625, 17683715}, {126626, 17681923},
2522 {126627, 17834499}, {126628, 2}, {126629, 16910851}, {126630, 17731587},
2523 {126631, 17682435}, {126632, 17700099}, {126633, 16911875}, {126634, 2},
2524 {126635, 17711107}, {126636, 17682947}, {126637, 17718019}, {126638, 17694979},
2525 {126639, 17701635}, {126640, 17703683}, {126641, 17697027}, {126642, 17706755},
2526 {126643, 17725187}, {126644, 17745155}, {126645, 17686787}, {126646, 17689859},
2527 {126647, 17684995}, {126648, 17724675}, {126649, 17698051}, {126650, 17701123},
2528 {126651, 17702659}, {126652, 2}, {126704, 1}, {126706, 2},
2529 {126976, 1}, {127020, 2}, {127024, 1}, {127124, 2},
2530 {127136, 1}, {127151, 2}, {127153, 1}, {127168, 2},
2531 {127169, 1}, {127184, 2}, {127185, 1}, {127222, 2},
2532 {127233, 34732803}, {127234, 34733315}, {127235, 34733827}, {127236, 34734339},
2533 {127237, 34734851}, {127238, 34735363}, {127239, 34735875}, {127240, 34736387},
2534 {127241, 34736899}, {127242, 34737411}, {127243, 1}, {127248, 50644995},
2535 {127249, 50645763}, {127250, 50646531}, {127251, 50647299}, {127252, 50648067},
2536 {127253, 50648835}, {127254, 50649603}, {127255, 50650371}, {127256, 50651139},
2537 {127257, 50651907}, {127258, 50652675}, {127259, 50653443}, {127260, 50654211},
2538 {127261, 50654979}, {127262, 50655747}, {127263, 50656515}, {127264, 50657283},
2539 {127265, 50658051}, {127266, 50658819}, {127267, 50659587}, {127268, 50660355},
2540 {127269, 50661123}, {127270, 50661891}, {127271, 50662659}, {127272, 50663427},
2541 {127273, 50664195}, {127274, 51515139}, {127275, 16777731}, {127276, 16781571},
2542 {127277, 33554947}, {127278, 34738691}, {127279, 1}, {127280, 16777219},
2543 {127281, 16777475}, {127282, 16777731}, {127283, 16777987}, {127284, 16778243},
2544 {127285, 16778499}, {127286, 16778755}, {127287, 16779011}, {127288, 16779267},
2545 {127289, 16779523}, {127290, 16779779}, {127291, 16780035}, {127292, 16780291},
2546 {127293, 16780547}, {127294, 16780803}, {127295, 16781059}, {127296, 16781315},
2547 {127297, 16781571}, {127298, 16781827}, {127299, 16782083}, {127300, 16782339},
2548 {127301, 16782595}, {127302, 16782851}, {127303, 16783107}, {127304, 16783363},
2549 {127305, 16783619}, {127306, 34739203}, {127307, 34226691}, {127308, 34739715},
2550 {127309, 33752579}, {127310, 51517443}, {127311, 34740995}, {127312, 1},
2551 {127338, 34209539}, {127339, 34189571}, {127340, 34741507}, {127341, 1},
2552 {127376, 34742019}, {127377, 1}, {127406, 2}, {127462, 1},
2553 {127488, 34742531}, {127489, 34743043}, {127490, 17307907}, {127491, 2},
2554 {127504, 17157891}, {127505, 17966339}, {127506, 17966595}, {127507, 17351683},
2555 {127508, 17143299}, {127509, 17966851}, {127510, 17967107}, {127511, 17225475},
2556 {127512, 17967363}, {127513, 17967619}, {127514, 17967875}, {127515, 17584643},
2557 {127516, 17968131}, {127517, 17968387}, {127518, 17968643}, {127519, 17968899},
2558 {127520, 17969155}, {127521, 17969411}, {127522, 17167107}, {127523, 17969667},
2559 {127524, 17969923}, {127525, 17970179}, {127526, 17970435}, {127527, 17970691},
2560 {127528, 17970947}, {127529, 17141763}, {127530, 17223427}, {127531, 17971203},
2561 {127532, 17288707}, {127533, 17224195}, {127534, 17288963}, {127535, 17971459},
2562 {127536, 17181443}, {127537, 17971715}, {127538, 17971971}, {127539, 17972227},
2563 {127540, 17972483}, {127541, 17972739}, {127542, 17264387}, {127543, 17160451},
2564 {127544, 17972995}, {127545, 17973251}, {127546, 17973507}, {127547, 17973763},
2565 {127548, 2}, {127552, 51528451}, {127553, 51529219}, {127554, 51529987},
2566 {127555, 51530755}, {127556, 51531523}, {127557, 51532291}, {127558, 51533059},
2567 {127559, 51533827}, {127560, 51534595}, {127561, 2}, {127568, 17980931},
2568 {127569, 17981187}, {127570, 2}, {127584, 1}, {127590, 2},
2569 {127744, 1}, {128728, 2}, {128732, 1}, {128749, 2},
2570 {128752, 1}, {128765, 2}, {128768, 1}, {128887, 2},
2571 {128891, 1}, {128986, 2}, {128992, 1}, {129004, 2},
2572 {129008, 1}, {129009, 2}, {129024, 1}, {129036, 2},
2573 {129040, 1}, {129096, 2}, {129104, 1}, {129114, 2},
2574 {129120, 1}, {129160, 2}, {129168, 1}, {129198, 2},
2575 {129200, 1}, {129202, 2}, {129280, 1}, {129620, 2},
2576 {129632, 1}, {129646, 2}, {129648, 1}, {129661, 2},
2577 {129664, 1}, {129673, 2}, {129680, 1}, {129726, 2},
2578 {129727, 1}, {129734, 2}, {129742, 1}, {129756, 2},
2579 {129760, 1}, {129769, 2}, {129776, 1}, {129785, 2},
2580 {129792, 1}, {129939, 2}, {129940, 1}, {129995, 2},
2581 {130032, 17035523}, {130033, 16786947}, {130034, 16785155}, {130035, 16785411},
2582 {130036, 16787715}, {130037, 17035779}, {130038, 17036035}, {130039, 17036291},
2583 {130040, 17036547}, {130041, 17036803}, {130042, 2}, {131072, 1},
2584 {173792, 2}, {173824, 1}, {177978, 2}, {177984, 1},
2585 {178206, 2}, {178208, 1}, {183970, 2}, {183984, 1},
2586 {191457, 2}, {194560, 17981443}, {194561, 17981699}, {194562, 17981955},
2587 {194563, 17982211}, {194564, 17982467}, {194565, 17608451}, {194566, 17982723},
2588 {194567, 17982979}, {194568, 17983235}, {194569, 17983491}, {194570, 17608707},
2589 {194571, 17983747}, {194572, 17984003}, {194573, 17984259}, {194574, 17608963},
2590 {194575, 17984515}, {194576, 17984771}, {194577, 17985027}, {194578, 17985283},
2591 {194579, 17985539}, {194580, 17985795}, {194581, 17968643}, {194582, 17986051},
2592 {194583, 17986307}, {194584, 17986563}, {194585, 17986819}, {194586, 17987075},
2593 {194587, 17623043}, {194588, 17987331}, {194589, 17145859}, {194590, 17987587},
2594 {194591, 17987843}, {194592, 17988099}, {194593, 17988355}, {194594, 17973251},
2595 {194595, 17988611}, {194596, 17988867}, {194597, 17624323}, {194598, 17609219},
2596 {194599, 17609475}, {194600, 17624579}, {194601, 17989123}, {194602, 17989379},
2597 {194603, 17562883}, {194604, 17989635}, {194605, 17609731}, {194606, 17989891},
2598 {194607, 17990147}, {194608, 17990403}, {194609, 17990659}, {194612, 17990915},
2599 {194613, 17991171}, {194614, 17991427}, {194615, 17991683}, {194616, 17991939},
2600 {194617, 17992195}, {194618, 17992451}, {194619, 17992707}, {194620, 17992963},
2601 {194621, 17993219}, {194622, 17993475}, {194623, 17993731}, {194624, 17993987},
2602 {194625, 17994243}, {194626, 17994499}, {194627, 17994755}, {194628, 17995011},
2603 {194629, 17995267}, {194631, 17625091}, {194632, 17995523}, {194633, 17995779},
2604 {194634, 17996035}, {194635, 17996291}, {194636, 17610243}, {194637, 17996547},
2605 {194638, 17996803}, {194639, 17997059}, {194640, 17600003}, {194641, 17997315},
2606 {194642, 17997571}, {194643, 17997827}, {194644, 17998083}, {194645, 17998339},
2607 {194646, 17998595}, {194647, 17998851}, {194648, 17999107}, {194649, 17999363},
2608 {194650, 17999619}, {194651, 17999875}, {194652, 18000131}, {194653, 17966851},
2609 {194654, 18000387}, {194655, 18000643}, {194656, 18000899}, {194657, 18001155},
2610 {194658, 18001411}, {194659, 18001667}, {194660, 18001923}, {194661, 18002179},
2611 {194662, 18002435}, {194663, 18002691}, {194664, 2}, {194665, 18002947},
2612 {194666, 18003203}, {194668, 18003459}, {194669, 18003715}, {194670, 18003971},
2613 {194671, 17561859}, {194672, 18004227}, {194673, 18004483}, {194674, 18004739},
2614 {194675, 18004995}, {194676, 2}, {194677, 17152515}, {194678, 18005251},
2615 {194679, 18005507}, {194680, 17153027}, {194681, 18005763}, {194682, 18006019},
2616 {194683, 18006275}, {194684, 18006531}, {194685, 18006787}, {194686, 18007043},
2617 {194687, 18007299}, {194688, 18007555}, {194689, 18007811}, {194690, 18008067},
2618 {194691, 18008323}, {194692, 18008579}, {194693, 18008835}, {194694, 18009091},
2619 {194695, 18009347}, {194696, 18009603}, {194697, 18009859}, {194698, 18010115},
2620 {194699, 18010371}, {194700, 18010627}, {194701, 18010883}, {194702, 17548547},
2621 {194703, 18011139}, {194704, 17155587}, {194705, 18011395}, {194707, 18011651},
2622 {194708, 18011907}, {194710, 18012163}, {194711, 18012419}, {194712, 18012675},
2623 {194713, 18012931}, {194714, 18013187}, {194715, 18013443}, {194716, 18013699},
2624 {194717, 18013955}, {194718, 18014211}, {194719, 18014467}, {194720, 18014723},
2625 {194721, 18014979}, {194722, 18015235}, {194723, 17611523}, {194724, 18015491},
2626 {194725, 18015747}, {194726, 18016003}, {194727, 18016259}, {194728, 17628163},
2627 {194729, 18016259}, {194730, 18016515}, {194731, 17612035}, {194732, 18016771},
2628 {194733, 18017027}, {194734, 18017283}, {194735, 18017539}, {194736, 17612291},
2629 {194737, 17541635}, {194738, 17414915}, {194739, 18017795}, {194740, 18018051},
2630 {194741, 18018307}, {194742, 18018563}, {194743, 18018819}, {194744, 18019075},
2631 {194745, 18019331}, {194746, 18019587}, {194747, 18019843}, {194748, 18020099},
2632 {194749, 18020355}, {194750, 18020611}, {194751, 18020867}, {194752, 18021123},
2633 {194753, 18021379}, {194754, 18021635}, {194755, 18021891}, {194756, 18022147},
2634 {194757, 18022403}, {194758, 18022659}, {194759, 18022915}, {194760, 17612547},
2635 {194761, 18023171}, {194762, 18023427}, {194763, 18023683}, {194764, 18023939},
2636 {194765, 18024195}, {194766, 18024451}, {194767, 17613059}, {194768, 18024707},
2637 {194769, 18024963}, {194770, 18025219}, {194771, 18025475}, {194772, 18025731},
2638 {194773, 18025987}, {194774, 18026243}, {194775, 18026499}, {194776, 17548803},
2639 {194777, 17630211}, {194778, 18026755}, {194779, 18027011}, {194780, 18027267},
2640 {194781, 18027523}, {194782, 18027779}, {194783, 18028035}, {194784, 18028291},
2641 {194785, 18028547}, {194786, 17613315}, {194787, 18028803}, {194788, 18029059},
2642 {194789, 18029315}, {194790, 18029571}, {194791, 17640963}, {194792, 18029827},
2643 {194793, 18030083}, {194794, 18030339}, {194795, 18030595}, {194796, 18030851},
2644 {194797, 18031107}, {194798, 18031363}, {194799, 18031619}, {194800, 18031875},
2645 {194801, 18032131}, {194802, 18032387}, {194803, 18032643}, {194804, 18032899},
2646 {194805, 17566211}, {194806, 18033155}, {194807, 18033411}, {194808, 18033667},
2647 {194809, 18033923}, {194810, 18034179}, {194811, 18034435}, {194812, 18034691},
2648 {194813, 18034947}, {194814, 18035203}, {194815, 18035459}, {194816, 18035715},
2649 {194817, 17613571}, {194818, 17587203}, {194819, 18035971}, {194820, 18036227},
2650 {194821, 18036483}, {194822, 18036739}, {194823, 18036995}, {194824, 18037251},
2651 {194825, 18037507}, {194826, 18037763}, {194827, 17630979}, {194828, 18038019},
2652 {194829, 18038275}, {194830, 18038531}, {194831, 18038787}, {194832, 18039043},
2653 {194833, 18039299}, {194834, 18039555}, {194835, 18039811}, {194836, 17631235},
2654 {194837, 18040067}, {194838, 18040323}, {194839, 18040579}, {194840, 18040835},
2655 {194841, 18041091}, {194842, 18041347}, {194843, 18041603}, {194844, 18041859},
2656 {194845, 18042115}, {194846, 18042371}, {194847, 2}, {194848, 18042627},
2657 {194849, 17631747}, {194850, 18042883}, {194851, 18043139}, {194852, 18043395},
2658 {194853, 18043651}, {194854, 18043907}, {194855, 18044163}, {194856, 18044419},
2659 {194857, 18044675}, {194858, 18044931}, {194859, 18045187}, {194860, 18045443},
2660 {194862, 18045699}, {194863, 18045955}, {194864, 17632259}, {194865, 18046211},
2661 {194866, 18046467}, {194867, 18046723}, {194868, 18046979}, {194869, 18047235},
2662 {194870, 18047491}, {194871, 18047747}, {194872, 17562627}, {194873, 18048003},
2663 {194874, 18048259}, {194875, 18048515}, {194876, 18048771}, {194877, 18049027},
2664 {194878, 18049283}, {194879, 18049539}, {194880, 17633795}, {194881, 18049795},
2665 {194882, 18050051}, {194883, 18050307}, {194884, 18050563}, {194885, 18050819},
2666 {194886, 18051075}, {194888, 17634051}, {194889, 17641475}, {194890, 18051331},
2667 {194891, 18051587}, {194892, 18051843}, {194893, 18052099}, {194894, 18052355},
2668 {194895, 17553155}, {194896, 17634563}, {194897, 18052611}, {194898, 18052867},
2669 {194899, 17616131}, {194900, 18053123}, {194901, 18053379}, {194902, 17605123},
2670 {194903, 18053635}, {194904, 18053891}, {194905, 17616899}, {194906, 18054147},
2671 {194907, 18054403}, {194908, 18054659}, {194909, 18054915}, {194911, 2},
2672 {194912, 18055171}, {194913, 18055427}, {194914, 18055683}, {194915, 18055939},
2673 {194916, 18056195}, {194917, 18056451}, {194918, 18056707}, {194919, 18056963},
2674 {194920, 18057219}, {194921, 18057475}, {194922, 18057731}, {194923, 18057987},
2675 {194924, 18058243}, {194925, 18058499}, {194926, 18058755}, {194927, 18059011},
2676 {194928, 18059267}, {194929, 18059523}, {194930, 18059779}, {194931, 18060035},
2677 {194932, 18060291}, {194933, 18060547}, {194934, 18060803}, {194935, 18061059},
2678 {194936, 18061315}, {194937, 18061571}, {194938, 17618435}, {194939, 18061827},
2679 {194940, 18062083}, {194941, 18062339}, {194942, 18062595}, {194943, 18062851},
2680 {194944, 18063107}, {194945, 18063363}, {194946, 18063619}, {194947, 18063875},
2681 {194948, 18064131}, {194949, 18064387}, {194950, 18064643}, {194951, 18064899},
2682 {194952, 18065155}, {194953, 18065411}, {194954, 18065667}, {194955, 18011651},
2683 {194956, 18065923}, {194957, 18066179}, {194958, 18066435}, {194959, 18066691},
2684 {194960, 18066947}, {194961, 18067203}, {194962, 18067459}, {194963, 18067715},
2685 {194964, 18067971}, {194965, 18068227}, {194966, 18068483}, {194967, 18068739},
2686 {194968, 17566979}, {194969, 18068995}, {194970, 18069251}, {194971, 18069507},
2687 {194972, 18069763}, {194973, 18070019}, {194974, 18070275}, {194975, 17619203},
2688 {194976, 18070531}, {194977, 18070787}, {194978, 18071043}, {194979, 18071299},
2689 {194980, 18071555}, {194981, 18071811}, {194982, 18072067}, {194983, 18072323},
2690 {194984, 18072579}, {194985, 18072835}, {194986, 18073091}, {194987, 18073347},
2691 {194988, 18073603}, {194989, 18073859}, {194990, 18074115}, {194991, 18074371},
2692 {194992, 18074627}, {194993, 18074883}, {194994, 18075139}, {194995, 18075395},
2693 {194996, 17551875}, {194997, 18075651}, {194998, 18075907}, {194999, 18076163},
2694 {195000, 18076419}, {195001, 18076675}, {195002, 18076931}, {195003, 17636355},
2695 {195004, 18077187}, {195005, 18077443}, {195006, 18077699}, {195007, 2},
2696 {195008, 18077955}, {195009, 18078211}, {195010, 18078467}, {195011, 18078723},
2697 {195012, 17178627}, {195013, 18078979}, {195014, 18079235}, {195015, 18079491},
2698 {195016, 18079747}, {195017, 18080003}, {195018, 18080259}, {195019, 18080515},
2699 {195020, 18080771}, {195021, 18081027}, {195022, 18081283}, {195023, 18081539},
2700 {195024, 17637635}, {195025, 17637891}, {195026, 17180419}, {195027, 18081795},
2701 {195028, 18082051}, {195029, 18082307}, {195030, 18082563}, {195031, 18082819},
2702 {195032, 18083075}, {195033, 18083331}, {195034, 18083587}, {195035, 18083843},
2703 {195036, 18084099}, {195037, 18084355}, {195038, 18084611}, {195039, 17638147},
2704 {195040, 18084867}, {195041, 18085123}, {195042, 18085379}, {195043, 18085635},
2705 {195044, 18085891}, {195045, 18086147}, {195046, 18086403}, {195047, 18086659},
2706 {195048, 18086915}, {195049, 18087171}, {195050, 18087427}, {195051, 18087683},
2707 {195052, 18087939}, {195053, 18088195}, {195054, 18088451}, {195055, 18088707},
2708 {195056, 18088963}, {195057, 18089219}, {195058, 18089475}, {195059, 18089731},
2709 {195060, 18089987}, {195061, 18090243}, {195062, 18090499}, {195063, 18090755},
2710 {195064, 18091011}, {195065, 18091267}, {195066, 18091523}, {195067, 18091779},
2711 {195068, 18092035}, {195069, 18092291}, {195070, 17639683}, {195072, 18092547},
2712 {195073, 18092803}, {195074, 18093059}, {195075, 18093315}, {195076, 18093571},
2713 {195077, 18093827}, {195078, 18094083}, {195079, 18094339}, {195080, 18094595},
2714 {195081, 18094851}, {195082, 17639939}, {195083, 18095107}, {195084, 18095363},
2715 {195085, 18095619}, {195086, 18095875}, {195087, 18096131}, {195088, 18096387},
2716 {195089, 18096643}, {195090, 18096899}, {195091, 18097155}, {195092, 18097411},
2717 {195093, 17192707}, {195094, 18097667}, {195095, 17193731}, {195096, 18097923},
2718 {195097, 18098179}, {195098, 18098435}, {195099, 18098691}, {195100, 17195011},
2719 {195101, 18098947}, {195102, 2}, {196608, 1}, {201547, 2},
2720 {201552, 1}, {205744, 2}, {917760, 0}, {918000, 2}
2721 };
2722
2723
2724 } // namespace ada::idna
2725 #endif // ADA_IDNA_TABLES_H
2726
2727 /* end file src/mapping_tables.cpp */
2728
2729 namespace ada::idna {
2730
2731 // This can be greatly accelerated. For now we just use a simply
2732 // binary search. In practice, you should *not* do that.
find_range_index(uint32_t key)2733 uint32_t find_range_index(uint32_t key) {
2734 ////////////////
2735 // This could be implemented with std::lower_bound, but we roll our own
2736 // because we want to allow further optimizations in the future.
2737 ////////////////
2738 uint32_t len = std::size(table);
2739 uint32_t low = 0;
2740 uint32_t high = len - 1;
2741 while (low <= high) {
2742 uint32_t middle_index = (low + high) >> 1; // cannot overflow
2743 uint32_t middle_value = table[middle_index][0];
2744 if (middle_value < key) {
2745 low = middle_index + 1;
2746 } else if (middle_value > key) {
2747 high = middle_index - 1;
2748 } else {
2749 return middle_index; // perfect match
2750 }
2751 }
2752 return low == 0 ? 0 : low - 1;
2753 }
2754
ascii_has_upper_case(char * input,size_t length)2755 bool ascii_has_upper_case(char* input, size_t length) {
2756 auto broadcast = [](uint8_t v) -> uint64_t {
2757 return 0x101010101010101ull * v;
2758 };
2759 uint64_t broadcast_80 = broadcast(0x80);
2760 uint64_t broadcast_Ap = broadcast(128 - 'A');
2761 uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
2762 size_t i = 0;
2763
2764 uint64_t runner{0};
2765
2766 for (; i + 7 < length; i += 8) {
2767 uint64_t word{};
2768 memcpy(&word, input + i, sizeof(word));
2769 runner |= (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80);
2770 }
2771 if (i < length) {
2772 uint64_t word{};
2773 memcpy(&word, input + i, length - i);
2774 runner |= (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80);
2775 }
2776 return runner != 0;
2777 }
2778
ascii_map(char * input,size_t length)2779 void ascii_map(char* input, size_t length) {
2780 auto broadcast = [](uint8_t v) -> uint64_t {
2781 return 0x101010101010101ull * v;
2782 };
2783 uint64_t broadcast_80 = broadcast(0x80);
2784 uint64_t broadcast_Ap = broadcast(128 - 'A');
2785 uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
2786 size_t i = 0;
2787
2788 for (; i + 7 < length; i += 8) {
2789 uint64_t word{};
2790 memcpy(&word, input + i, sizeof(word));
2791 word ^=
2792 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
2793 memcpy(input + i, &word, sizeof(word));
2794 }
2795 if (i < length) {
2796 uint64_t word{};
2797 memcpy(&word, input + i, length - i);
2798 word ^=
2799 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
2800 memcpy(input + i, &word, length - i);
2801 }
2802 }
2803
2804 // Map the characters according to IDNA, returning the empty string on error.
map(std::u32string_view input)2805 std::u32string map(std::u32string_view input) {
2806 // [Map](https://www.unicode.org/reports/tr46/#ProcessingStepMap).
2807 // For each code point in the domain_name string, look up the status
2808 // value in Section 5, [IDNA Mapping
2809 // Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table),
2810 // and take the following actions:
2811 // * disallowed: Leave the code point unchanged in the string, and
2812 // record that there was an error.
2813 // * ignored: Remove the code point from the string. This is
2814 // equivalent to mapping the code point to an empty string.
2815 // * mapped: Replace the code point in the string by the value for
2816 // the mapping in Section 5, [IDNA Mapping
2817 // Table](https://www.unicode.org/reports/tr46/#IDNA_Mapping_Table).
2818 // * valid: Leave the code point unchanged in the string.
2819 static std::u32string error = U"";
2820 std::u32string answer;
2821 answer.reserve(input.size());
2822 for (char32_t x : input) {
2823 size_t index = find_range_index(x);
2824 uint32_t descriptor = table[index][1];
2825 uint8_t code = uint8_t(descriptor);
2826 switch (code) {
2827 case 0:
2828 break; // nothing to do, ignored
2829 case 1:
2830 answer.push_back(x); // valid, we just copy it to output
2831 break;
2832 case 2:
2833 return error; // disallowed
2834 // case 3 :
2835 default:
2836 // We have a mapping
2837 {
2838 size_t char_count = (descriptor >> 24);
2839 uint16_t char_index = uint16_t(descriptor >> 8);
2840 for (size_t idx = char_index; idx < char_index + char_count; idx++) {
2841 answer.push_back(mappings[idx]);
2842 }
2843 }
2844 }
2845 }
2846 return answer;
2847 }
2848 } // namespace ada::idna
2849 /* end file src/mapping.cpp */
2850 /* begin file src/normalization.cpp */
2851 /* begin file src/normalization_tables.cpp */
2852 // IDNA 15.0.0
2853
2854 // clang-format off
2855 #ifndef ADA_IDNA_NORMALIZATION_TABLES_H
2856 #define ADA_IDNA_NORMALIZATION_TABLES_H
2857 #include <cstdint>
2858
2859 /**
2860 * Unicode Standard Annex #15
2861 *
2862 * UNICODE NORMALIZATION FORMS
2863 * https://www.unicode.org/reports/tr15/
2864 *
2865 * See https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/data/data_norm.h for reference.
2866 */
2867
2868 namespace ada::idna {
2869
2870 const uint8_t decomposition_index[4352] = {
2871 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 7,
2872 7, 7, 7, 7, 7, 7, 7, 7, 16, 7, 17, 18, 19, 20, 21, 22, 23, 24, 7,
2873 7, 7, 7, 7, 25, 7, 26, 27, 28, 29, 30, 31, 32, 33, 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, 7, 7, 7, 7, 7,
2878 7, 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, 34, 35, 7, 7, 7,
2880 36, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2883 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2884 7, 7, 37, 38, 39, 40, 41, 42, 43, 7, 7, 7, 7, 7, 7, 7, 44, 7, 7,
2885 7, 7, 7, 7, 7, 7, 45, 46, 7, 47, 48, 49, 7, 7, 7, 50, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2894 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2895 7, 7, 7, 7, 7, 7, 7, 7, 7, 51, 7, 52, 53, 54, 55, 56, 7, 7, 7,
2896 7, 7, 7, 7, 7, 57, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 58,
2897 59, 7, 60, 61, 62, 7, 7, 7, 7, 7, 7, 7, 7, 63, 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 7, 7, 7, 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 64, 65, 66, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3099 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3100 7};
3101
3102 const uint16_t decomposition_block[67][257] = {
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, 4, 4, 4, 4, 4,
3112 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
3113 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 8, 8, 8, 8,
3114 8, 8, 8, 9, 16, 17, 20, 20, 20, 20, 21, 28, 28, 29, 33,
3115 37, 45, 48, 48, 49, 57, 61, 64, 65, 77, 89, 100, 100, 108, 116,
3116 124, 132, 140, 148, 148, 156, 164, 172, 180, 188, 196, 204, 212, 220, 220,
3117 228, 236, 244, 252, 260, 268, 268, 268, 276, 284, 292, 300, 308, 308, 308,
3118 316, 324, 332, 340, 348, 356, 356, 364, 372, 380, 388, 396, 404, 412, 420,
3119 428, 428, 436, 444, 452, 460, 468, 476, 476, 476, 484, 492, 500, 508, 516,
3120 516, 524},
3121 {524, 532, 540, 548, 556, 564, 572, 580, 588, 596, 604, 612,
3122 620, 628, 636, 644, 652, 652, 652, 660, 668, 676, 684, 692,
3123 700, 708, 716, 724, 732, 740, 748, 756, 764, 772, 780, 788,
3124 796, 804, 812, 812, 812, 820, 828, 836, 844, 852, 860, 868,
3125 876, 884, 885, 893, 900, 908, 916, 924, 932, 932, 940, 948,
3126 956, 964, 972, 981, 989, 996, 996, 996, 1004, 1012, 1020, 1028,
3127 1036, 1045, 1052, 1052, 1052, 1060, 1068, 1076, 1084, 1092, 1100, 1100,
3128 1100, 1108, 1116, 1124, 1132, 1140, 1148, 1156, 1164, 1172, 1180, 1188,
3129 1196, 1204, 1212, 1220, 1228, 1236, 1244, 1244, 1244, 1252, 1260, 1268,
3130 1276, 1284, 1292, 1300, 1308, 1316, 1324, 1332, 1340, 1348, 1356, 1364,
3131 1372, 1380, 1388, 1396, 1404, 1412, 1420, 1429, 1432, 1432, 1432, 1432,
3132 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
3133 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
3134 1432, 1432, 1432, 1432, 1432, 1440, 1448, 1448, 1448, 1448, 1448, 1448,
3135 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1456, 1464, 1464, 1464,
3136 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464,
3137 1464, 1464, 1464, 1464, 1465, 1477, 1489, 1501, 1509, 1517, 1525, 1533,
3138 1541, 1548, 1556, 1564, 1572, 1580, 1588, 1596, 1604, 1612, 1624, 1636,
3139 1648, 1660, 1672, 1684, 1696, 1708, 1708, 1720, 1732, 1744, 1756, 1764,
3140 1772, 1772, 1772, 1780, 1788, 1796, 1804, 1812, 1820, 1832, 1844, 1852,
3141 1860, 1869, 1877, 1885, 1892, 1900, 1908, 1908, 1908, 1916, 1924, 1936,
3142 1948, 1956, 1964, 1972, 1980},
3143 {1980, 1988, 1996, 2004, 2012, 2020, 2028, 2036, 2044, 2052, 2060, 2068,
3144 2076, 2084, 2092, 2100, 2108, 2116, 2124, 2132, 2140, 2148, 2156, 2164,
3145 2172, 2180, 2188, 2196, 2204, 2204, 2204, 2212, 2220, 2220, 2220, 2220,
3146 2220, 2220, 2220, 2228, 2236, 2244, 2252, 2264, 2276, 2288, 2300, 2308,
3147 2316, 2328, 2340, 2348, 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, 2356, 2356, 2356, 2356,
3156 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356,
3157 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2357, 2361, 2365, 2369,
3158 2373, 2377, 2381, 2385, 2389, 2392, 2392, 2392, 2392, 2392, 2392, 2392,
3159 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392,
3160 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392, 2392,
3161 2393, 2401, 2409, 2417, 2425, 2433, 2440, 2440, 2441, 2445, 2449, 2453,
3162 2457, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3163 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3164 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, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3169 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460, 2460,
3170 2460, 2460, 2460, 2460, 2460, 2464, 2468, 2468, 2472, 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, 2480, 2480, 2480,
3173 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480,
3174 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2480, 2484, 2484, 2484,
3175 2484, 2484, 2485, 2492, 2492, 2492, 2492, 2496, 2496, 2496, 2496, 2496,
3176 2497, 2506, 2512, 2520, 2524, 2532, 2540, 2548, 2548, 2556, 2556, 2564,
3177 2572, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584,
3178 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584,
3179 2584, 2584, 2584, 2592, 2600, 2608, 2616, 2624, 2632, 2644, 2644, 2644,
3180 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644,
3181 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2652,
3182 2660, 2668, 2676, 2684, 2685, 2689, 2693, 2698, 2706, 2713, 2717, 2720,
3183 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720,
3184 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720,
3185 2721, 2725, 2729, 2732, 2733, 2737, 2740, 2740, 2740, 2741, 2744, 2744,
3186 2744, 2744, 2744, 2744, 2744},
3187 {2744, 2752, 2760, 2760, 2768, 2768, 2768, 2768, 2776, 2776, 2776, 2776,
3188 2776, 2784, 2792, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800,
3189 2800, 2800, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808,
3190 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808,
3191 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2816, 2816,
3192 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816,
3193 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2816, 2824, 2832, 2832,
3194 2840, 2840, 2840, 2840, 2848, 2848, 2848, 2848, 2848, 2856, 2864, 2872,
3195 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872,
3196 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2872, 2880,
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, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3202 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888,
3203 2888, 2888, 2896, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904,
3204 2904, 2904, 2904, 2904, 2904, 2912, 2920, 2928, 2936, 2936, 2936, 2944,
3205 2952, 2952, 2952, 2960, 2968, 2976, 2984, 2992, 3000, 3000, 3000, 3008,
3206 3016, 3024, 3032, 3040, 3048, 3048, 3048, 3056, 3064, 3072, 3080, 3088,
3207 3096, 3104, 3112, 3120, 3128, 3136, 3144, 3144, 3144, 3152, 3160, 3160,
3208 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, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3219 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160, 3160,
3220 3160, 3160, 3160, 3161, 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, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3229 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3230 3168, 3168, 3168, 3168, 3168},
3231 {3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3232 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168,
3233 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3168, 3176,
3234 3184, 3192, 3200, 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, 3208, 3208, 3208,
3239 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208,
3240 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3208, 3209, 3217, 3225,
3241 3233, 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, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3246 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240,
3247 3240, 3248, 3248, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256,
3248 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3264, 3264, 3264, 3264,
3249 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3250 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3251 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3252 3264, 3264, 3264, 3264, 3264},
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, 0, 0, 0, 0, 0, 0, 0,
3262 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3263 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3264 {3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3265 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3266 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,
3267 3264, 3264, 3264, 3264, 3264, 3264, 3272, 3272, 3272, 3272, 3272, 3272,
3268 3272, 3272, 3280, 3280, 3280, 3288, 3288, 3288, 3288, 3288, 3288, 3288,
3269 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288,
3270 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288, 3288,
3271 3288, 3288, 3288, 3288, 3288, 3296, 3304, 3312, 3320, 3328, 3336, 3344,
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 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3280 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352, 3352,
3281 3360, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368, 3368,
3282 3368, 3368, 3368, 3368, 3368, 3376, 3384, 3384, 3392, 3392, 3392, 3392,
3283 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3284 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3285 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, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3289 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392, 3392,
3290 3392, 3392, 3392, 3392, 3400, 3400, 3400, 3408, 3408, 3408, 3408, 3408,
3291 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408,
3292 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408, 3408,
3293 3408, 3408, 3408, 3408, 3408, 3408, 3416, 3424, 3432, 3432, 3432, 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, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3306 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3307 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, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3313 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
3314 3440, 3448, 3448, 3448, 3456, 3464, 3464, 3464, 3464, 3464, 3464, 3464,
3315 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3464, 3472, 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, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3319 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480, 3480,
3320 3480, 3480, 3480, 3480, 3480, 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, 3488,
3323 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488,
3324 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3488, 3496,
3325 3504, 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, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3328 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3329 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, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3335 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512,
3336 3512, 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, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3345 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
3346 3520, 3528, 3528, 3528, 3528, 3528, 3528, 3528, 3536, 3544, 3544, 3552,
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, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3350 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3351 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, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3357 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564, 3564,
3358 3564, 3564, 3564, 3572, 3580, 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, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3369 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588, 3588,
3370 3588, 3588, 3588, 3596, 3596, 3604, 3616, 3624, 3624, 3624, 3624, 3624,
3371 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3372 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3373 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, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3377 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624, 3624,
3378 3624, 3624, 3624, 3625, 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, 3632,
3387 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632,
3388 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3633,
3389 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,
3390 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,
3391 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640,
3392 3640, 3640, 3640, 3640, 3641, 3649, 3656, 3656, 3656, 3656, 3656, 3656,
3393 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,
3394 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,
3395 3656, 3656, 3656, 3656, 3656},
3396 {3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,
3397 3657, 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, 3660, 3660, 3660, 3660,
3400 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3401 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3668, 3668, 3668, 3668,
3402 3668, 3668, 3668, 3668, 3668, 3668, 3676, 3676, 3676, 3676, 3676, 3684,
3403 3684, 3684, 3684, 3684, 3692, 3692, 3692, 3692, 3692, 3700, 3700, 3700,
3404 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3708, 3708,
3405 3708, 3708, 3708, 3708, 3708, 3708, 3708, 3708, 3716, 3716, 3724, 3733,
3406 3744, 3753, 3764, 3764, 3764, 3764, 3764, 3764, 3764, 3764, 3772, 3772,
3407 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772, 3772,
3408 3772, 3772, 3772, 3772, 3780, 3780, 3780, 3780, 3780, 3780, 3780, 3780,
3409 3780, 3780, 3788, 3788, 3788, 3788, 3788, 3796, 3796, 3796, 3796, 3796,
3410 3804, 3804, 3804, 3804, 3804, 3812, 3812, 3812, 3812, 3812, 3812, 3812,
3411 3812, 3812, 3812, 3812, 3812, 3812, 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, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3416 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3417 3820, 3820, 3820, 3820, 3820},
3418 {3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3419 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3420 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820, 3820,
3421 3820, 3820, 3820, 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 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3438 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828, 3828,
3439 3829, 3832, 3832, 3832, 3832},
3440 {3832, 3832, 3832, 3832, 3832, 3832, 3832, 3840, 3840, 3848, 3848, 3856,
3441 3856, 3864, 3864, 3872, 3872, 3872, 3872, 3880, 3880, 3880, 3880, 3880,
3442 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,
3443 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,
3444 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880, 3880,
3445 3888, 3888, 3896, 3896, 3896, 3904, 3912, 3912, 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, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3460 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3461 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, 3920, 3920, 3920, 3920,
3464 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920,
3465 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3920, 3921, 3925, 3929, 3932,
3466 3933, 3937, 3941, 3945, 3949, 3953, 3957, 3961, 3965, 3969, 3973, 3976,
3467 3977, 3981, 3985, 3989, 3993, 3997, 4001, 4005, 4009, 4013, 4017, 4021,
3468 4025, 4029, 4033, 4037, 4041, 4045, 4048, 4049, 4053, 4057, 4061, 4065,
3469 4069, 4073, 4077, 4081, 4085, 4089, 4093, 4097, 4101, 4105, 4109, 4113,
3470 4117, 4121, 4125, 4129, 4133, 4137, 4141, 4145, 4149, 4153, 4157, 4160,
3471 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160,
3472 4161, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164,
3473 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164,
3474 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4165,
3475 4169, 4173, 4177, 4181, 4185, 4189, 4193, 4197, 4201, 4205, 4209, 4213,
3476 4217, 4221, 4225, 4229, 4233, 4237, 4241, 4245, 4249, 4253, 4257, 4261,
3477 4265, 4269, 4273, 4277, 4281, 4285, 4289, 4293, 4297, 4301, 4305, 4309,
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, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3482 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312,
3483 4312, 4312, 4312, 4312, 4312},
3484 {4312, 4320, 4328, 4336, 4344, 4352, 4360, 4368, 4376, 4388, 4400, 4408,
3485 4416, 4424, 4432, 4440, 4448, 4456, 4464, 4472, 4480, 4492, 4504, 4516,
3486 4528, 4536, 4544, 4552, 4560, 4572, 4584, 4592, 4600, 4608, 4616, 4624,
3487 4632, 4640, 4648, 4656, 4664, 4672, 4680, 4688, 4696, 4704, 4712, 4724,
3488 4736, 4744, 4752, 4760, 4768, 4776, 4784, 4792, 4800, 4812, 4824, 4832,
3489 4840, 4848, 4856, 4864, 4872, 4880, 4888, 4896, 4904, 4912, 4920, 4928,
3490 4936, 4944, 4952, 4960, 4968, 4980, 4992, 5004, 5016, 5028, 5040, 5052,
3491 5064, 5072, 5080, 5088, 5096, 5104, 5112, 5120, 5128, 5140, 5152, 5160,
3492 5168, 5176, 5184, 5192, 5200, 5212, 5224, 5236, 5248, 5260, 5272, 5280,
3493 5288, 5296, 5304, 5312, 5320, 5328, 5336, 5344, 5352, 5360, 5368, 5376,
3494 5384, 5396, 5408, 5420, 5432, 5440, 5448, 5456, 5464, 5472, 5480, 5488,
3495 5496, 5504, 5512, 5520, 5528, 5536, 5544, 5552, 5560, 5568, 5576, 5584,
3496 5592, 5600, 5608, 5616, 5624, 5632, 5640, 5648, 5656, 5664, 5673, 5682,
3497 5688, 5688, 5688, 5688, 5688, 5696, 5704, 5712, 5720, 5732, 5744, 5756,
3498 5768, 5780, 5792, 5804, 5816, 5828, 5840, 5852, 5864, 5876, 5888, 5900,
3499 5912, 5924, 5936, 5948, 5960, 5968, 5976, 5984, 5992, 6000, 6008, 6020,
3500 6032, 6044, 6056, 6068, 6080, 6092, 6104, 6116, 6128, 6136, 6144, 6152,
3501 6160, 6168, 6176, 6184, 6192, 6204, 6216, 6228, 6240, 6252, 6264, 6276,
3502 6288, 6300, 6312, 6324, 6336, 6348, 6360, 6372, 6384, 6396, 6408, 6420,
3503 6432, 6440, 6448, 6456, 6464, 6476, 6488, 6500, 6512, 6524, 6536, 6548,
3504 6560, 6572, 6584, 6592, 6600, 6608, 6616, 6624, 6632, 6640, 6648, 6648,
3505 6648, 6648, 6648, 6648, 6648},
3506 {6648, 6656, 6664, 6676, 6688, 6700, 6712, 6724, 6736, 6744, 6752, 6764,
3507 6776, 6788, 6800, 6812, 6824, 6832, 6840, 6852, 6864, 6876, 6888, 6888,
3508 6888, 6896, 6904, 6916, 6928, 6940, 6952, 6952, 6952, 6960, 6968, 6980,
3509 6992, 7004, 7016, 7028, 7040, 7048, 7056, 7068, 7080, 7092, 7104, 7116,
3510 7128, 7136, 7144, 7156, 7168, 7180, 7192, 7204, 7216, 7224, 7232, 7244,
3511 7256, 7268, 7280, 7292, 7304, 7312, 7320, 7332, 7344, 7356, 7368, 7368,
3512 7368, 7376, 7384, 7396, 7408, 7420, 7432, 7432, 7432, 7440, 7448, 7460,
3513 7472, 7484, 7496, 7508, 7520, 7520, 7528, 7528, 7540, 7540, 7552, 7552,
3514 7564, 7572, 7580, 7592, 7604, 7616, 7628, 7640, 7652, 7660, 7668, 7680,
3515 7692, 7704, 7716, 7728, 7740, 7748, 7756, 7764, 7772, 7780, 7788, 7796,
3516 7804, 7812, 7820, 7828, 7836, 7844, 7852, 7852, 7852, 7864, 7876, 7892,
3517 7908, 7924, 7940, 7956, 7972, 7984, 7996, 8012, 8028, 8044, 8060, 8076,
3518 8092, 8104, 8116, 8132, 8148, 8164, 8180, 8196, 8212, 8224, 8236, 8252,
3519 8268, 8284, 8300, 8316, 8332, 8344, 8356, 8372, 8388, 8404, 8420, 8436,
3520 8452, 8464, 8476, 8492, 8508, 8524, 8540, 8556, 8572, 8580, 8588, 8600,
3521 8608, 8620, 8620, 8628, 8640, 8648, 8656, 8664, 8672, 8681, 8688, 8693,
3522 8701, 8710, 8716, 8728, 8736, 8748, 8748, 8756, 8768, 8776, 8784, 8792,
3523 8800, 8810, 8818, 8826, 8832, 8840, 8848, 8860, 8872, 8872, 8872, 8880,
3524 8892, 8900, 8908, 8916, 8924, 8926, 8934, 8942, 8948, 8956, 8964, 8976,
3525 8988, 8996, 9004, 9012, 9024, 9032, 9040, 9048, 9056, 9066, 9074, 9080,
3526 9084, 9084, 9084, 9096, 9104, 9116, 9116, 9124, 9136, 9144, 9152, 9160,
3527 9168, 9178, 9181, 9188, 9190},
3528 {9190, 9194, 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9232,
3529 9232, 9232, 9232, 9232, 9232, 9233, 9236, 9236, 9236, 9236, 9236, 9237,
3530 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244, 9244,
3531 9245, 9249, 9257, 9268, 9268, 9268, 9268, 9268, 9268, 9268, 9268, 9269,
3532 9272, 9272, 9272, 9273, 9281, 9292, 9293, 9301, 9312, 9312, 9312, 9312,
3533 9313, 9320, 9321, 9328, 9328, 9328, 9328, 9328, 9328, 9328, 9328, 9329,
3534 9337, 9345, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352, 9352,
3535 9352, 9352, 9352, 9353, 9368, 9368, 9368, 9368, 9368, 9368, 9368, 9369,
3536 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372, 9372,
3537 9372, 9372, 9372, 9372, 9373, 9377, 9380, 9380, 9381, 9385, 9389, 9393,
3538 9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, 9433, 9437, 9441,
3539 9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, 9481, 9485, 9488,
3540 9489, 9493, 9497, 9501, 9505, 9509, 9513, 9517, 9521, 9525, 9529, 9533,
3541 9537, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540, 9540,
3542 9541, 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, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3548 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548, 9548,
3549 9548, 9548, 9548, 9548, 9549},
3550 {9549, 9561, 9573, 9577, 9584, 9585, 9597, 9609, 9612, 9613,
3551 9621, 9625, 9629, 9633, 9637, 9641, 9645, 9649, 9653, 9657,
3552 9660, 9661, 9665, 9672, 9672, 9673, 9677, 9681, 9685, 9689,
3553 9692, 9692, 9693, 9701, 9713, 9720, 9721, 9724, 9724, 9728,
3554 9729, 9732, 9732, 9736, 9745, 9749, 9752, 9753, 9757, 9761,
3555 9764, 9765, 9769, 9773, 9777, 9781, 9785, 9789, 9792, 9793,
3556 9805, 9809, 9813, 9817, 9821, 9824, 9824, 9824, 9824, 9825,
3557 9829, 9833, 9837, 9841, 9844, 9844, 9844, 9844, 9844, 9844,
3558 9845, 9857, 9869, 9885, 9897, 9909, 9921, 9933, 9945, 9957,
3559 9969, 9981, 9993, 10005, 10017, 10029, 10037, 10041, 10049, 10061,
3560 10069, 10073, 10081, 10093, 10109, 10117, 10121, 10129, 10141, 10145,
3561 10149, 10153, 10157, 10161, 10169, 10181, 10189, 10193, 10201, 10213,
3562 10229, 10237, 10241, 10249, 10261, 10265, 10269, 10273, 10276, 10276,
3563 10276, 10276, 10276, 10276, 10276, 10276, 10276, 10277, 10288, 10288,
3564 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288, 10288,
3565 10288, 10288, 10288, 10288, 10288, 10296, 10304, 10304, 10304, 10304,
3566 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304, 10304,
3567 10304, 10304, 10304, 10304, 10304, 10312, 10312, 10312, 10312, 10312,
3568 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312,
3569 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312, 10312,
3570 10312, 10312, 10312, 10312, 10312, 10312, 10320, 10328, 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, 10336, 10336, 10336,
3574 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336, 10336,
3575 10336, 10336, 10336, 10336, 10336, 10336, 10336},
3576 {10336, 10336, 10336, 10336, 10336, 10344, 10344, 10344, 10344, 10344,
3577 10352, 10352, 10352, 10360, 10360, 10360, 10360, 10360, 10360, 10360,
3578 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10360,
3579 10360, 10360, 10360, 10360, 10360, 10360, 10360, 10368, 10368, 10376,
3580 10376, 10376, 10376, 10376, 10377, 10385, 10396, 10397, 10405, 10416,
3581 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416, 10416,
3582 10416, 10416, 10416, 10416, 10416, 10416, 10424, 10424, 10424, 10432,
3583 10432, 10432, 10440, 10440, 10448, 10448, 10448, 10448, 10448, 10448,
3584 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10448,
3585 10448, 10448, 10448, 10448, 10448, 10448, 10448, 10456, 10456, 10464,
3586 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464, 10464,
3587 10472, 10480, 10488, 10496, 10504, 10504, 10504, 10512, 10520, 10520,
3588 10520, 10528, 10536, 10536, 10536, 10536, 10536, 10536, 10536, 10544,
3589 10552, 10552, 10552, 10560, 10568, 10568, 10568, 10576, 10584, 10584,
3590 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,
3591 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,
3592 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584, 10584,
3593 10584, 10584, 10584, 10592, 10600, 10608, 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, 10616, 10616, 10616, 10616, 10616,
3597 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616, 10616,
3598 10616, 10616, 10616, 10616, 10616, 10624, 10632, 10640, 10648, 10648,
3599 10648, 10648, 10648, 10648, 10648, 10656, 10664, 10672, 10680, 10680,
3600 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3601 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, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3605 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680, 10680,
3606 10680, 10680, 10684, 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, 10688, 10688, 10688,
3626 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3627 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, 10688, 10688, 10688, 10688,
3636 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688, 10688,
3637 10688, 10688, 10688, 10688, 10688, 10688, 10689, 10693, 10697, 10701,
3638 10705, 10709, 10713, 10717, 10721, 10725, 10733, 10741, 10749, 10757,
3639 10765, 10773, 10781, 10789, 10797, 10805, 10813, 10825, 10837, 10849,
3640 10861, 10873, 10885, 10897, 10909, 10921, 10937, 10953, 10969, 10985,
3641 11001, 11017, 11033, 11049, 11065, 11081, 11097, 11105, 11113, 11121,
3642 11129, 11137, 11145, 11153, 11161, 11169, 11181, 11193, 11205, 11217,
3643 11229, 11241, 11253, 11265, 11277, 11289, 11301, 11313, 11325, 11337,
3644 11349, 11361, 11373, 11385, 11397, 11409, 11421, 11433, 11445, 11457,
3645 11469, 11481, 11493, 11505, 11517, 11529, 11541, 11553, 11565, 11577,
3646 11589, 11601, 11613, 11617, 11621, 11625, 11629, 11633, 11637, 11641,
3647 11645, 11649, 11653, 11657, 11661, 11665, 11669, 11673, 11677, 11681,
3648 11685, 11689, 11693, 11697, 11701, 11705, 11709, 11713, 11717, 11721,
3649 11725, 11729, 11733, 11737, 11741, 11745, 11749, 11753, 11757, 11761,
3650 11765, 11769, 11773, 11777, 11781, 11785, 11789, 11793, 11797, 11801,
3651 11805, 11809, 11813, 11817, 11821, 11824, 11824, 11824, 11824, 11824,
3652 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824,
3653 11824, 11824, 11824, 11824, 11824, 11824, 11824},
3654 {11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824, 11824,
3655 11824, 11824, 11825, 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, 11840, 11840, 11840, 11840,
3664 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840, 11840,
3665 11840, 11840, 11840, 11840, 11840, 11840, 11841, 11853, 11861, 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, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3675 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872, 11872,
3676 11872, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3677 11880, 11880, 11880, 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},
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, 11880, 11880, 11880, 11880, 11880, 11880,
3691 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880, 11880,
3692 11880, 11880, 11880, 11880, 11881, 11885, 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, 11888, 11888, 11888,
3704 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3705 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, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3716 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888, 11888,
3717 11888, 11889, 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, 11892, 11892, 11892,
3730 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3731 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, 11892,
3746 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892,
3747 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11892, 11893,
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, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3755 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896, 11896,
3756 11896, 11896, 11896, 11897, 11900, 11900, 11900, 11900, 11900, 11900,
3757 11900, 11900, 11900, 11900, 11900, 11900, 11901},
3758 {11901, 11905, 11909, 11913, 11917, 11921, 11925, 11929, 11933, 11937,
3759 11941, 11945, 11949, 11953, 11957, 11961, 11965, 11969, 11973, 11977,
3760 11981, 11985, 11989, 11993, 11997, 12001, 12005, 12009, 12013, 12017,
3761 12021, 12025, 12029, 12033, 12037, 12041, 12045, 12049, 12053, 12057,
3762 12061, 12065, 12069, 12073, 12077, 12081, 12085, 12089, 12093, 12097,
3763 12101, 12105, 12109, 12113, 12117, 12121, 12125, 12129, 12133, 12137,
3764 12141, 12145, 12149, 12153, 12157, 12161, 12165, 12169, 12173, 12177,
3765 12181, 12185, 12189, 12193, 12197, 12201, 12205, 12209, 12213, 12217,
3766 12221, 12225, 12229, 12233, 12237, 12241, 12245, 12249, 12253, 12257,
3767 12261, 12265, 12269, 12273, 12277, 12281, 12285, 12289, 12293, 12297,
3768 12301, 12305, 12309, 12313, 12317, 12321, 12325, 12329, 12333, 12337,
3769 12341, 12345, 12349, 12353, 12357, 12361, 12365, 12369, 12373, 12377,
3770 12381, 12385, 12389, 12393, 12397, 12401, 12405, 12409, 12413, 12417,
3771 12421, 12425, 12429, 12433, 12437, 12441, 12445, 12449, 12453, 12457,
3772 12461, 12465, 12469, 12473, 12477, 12481, 12485, 12489, 12493, 12497,
3773 12501, 12505, 12509, 12513, 12517, 12521, 12525, 12529, 12533, 12537,
3774 12541, 12545, 12549, 12553, 12557, 12561, 12565, 12569, 12573, 12577,
3775 12581, 12585, 12589, 12593, 12597, 12601, 12605, 12609, 12613, 12617,
3776 12621, 12625, 12629, 12633, 12637, 12641, 12645, 12649, 12653, 12657,
3777 12661, 12665, 12669, 12673, 12677, 12681, 12685, 12689, 12693, 12697,
3778 12701, 12705, 12709, 12713, 12717, 12721, 12725, 12729, 12733, 12737,
3779 12741, 12745, 12749, 12753, 12756, 12756, 12756, 12756, 12756, 12756,
3780 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,
3781 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,
3782 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756, 12756,
3783 12756, 12756, 12756, 12756, 12756, 12756, 12757},
3784 {12757, 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, 12760, 12760, 12760, 12760, 12760, 12760,
3788 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760, 12760,
3789 12760, 12760, 12760, 12760, 12761, 12764, 12765, 12769, 12773, 12776,
3790 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12776,
3791 12776, 12776, 12776, 12776, 12776, 12776, 12776, 12784, 12784, 12792,
3792 12792, 12800, 12800, 12808, 12808, 12816, 12816, 12824, 12824, 12832,
3793 12832, 12840, 12840, 12848, 12848, 12856, 12856, 12864, 12864, 12872,
3794 12872, 12872, 12880, 12880, 12888, 12888, 12896, 12896, 12896, 12896,
3795 12896, 12896, 12896, 12904, 12912, 12912, 12920, 12928, 12928, 12936,
3796 12944, 12944, 12952, 12960, 12960, 12968, 12976, 12976, 12976, 12976,
3797 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976,
3798 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12976, 12984,
3799 12984, 12984, 12984, 12984, 12984, 12985, 12993, 13000, 13000, 13009,
3800 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016, 13016,
3801 13016, 13016, 13016, 13024, 13024, 13032, 13032, 13040, 13040, 13048,
3802 13048, 13056, 13056, 13064, 13064, 13072, 13072, 13080, 13080, 13088,
3803 13088, 13096, 13096, 13104, 13104, 13112, 13112, 13112, 13120, 13120,
3804 13128, 13128, 13136, 13136, 13136, 13136, 13136, 13136, 13136, 13144,
3805 13152, 13152, 13160, 13168, 13168, 13176, 13184, 13184, 13192, 13200,
3806 13200, 13208, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216,
3807 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216, 13216,
3808 13216, 13216, 13216, 13216, 13216, 13224, 13224, 13224, 13232, 13240,
3809 13248, 13256, 13256, 13256, 13256, 13265, 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, 13272,
3813 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272,
3814 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13272, 13273,
3815 13277, 13281, 13285, 13289, 13293, 13297, 13301, 13305, 13309, 13313,
3816 13317, 13321, 13325, 13329, 13333, 13337, 13341, 13345, 13349, 13353,
3817 13357, 13361, 13365, 13369, 13373, 13377, 13381, 13385, 13389, 13393,
3818 13397, 13401, 13405, 13409, 13413, 13417, 13421, 13425, 13429, 13433,
3819 13437, 13441, 13445, 13449, 13453, 13457, 13461, 13465, 13469, 13473,
3820 13477, 13481, 13485, 13489, 13493, 13497, 13501, 13505, 13509, 13513,
3821 13517, 13521, 13525, 13529, 13533, 13537, 13541, 13545, 13549, 13553,
3822 13557, 13561, 13565, 13569, 13573, 13577, 13581, 13585, 13589, 13593,
3823 13597, 13601, 13605, 13609, 13613, 13617, 13621, 13625, 13629, 13633,
3824 13637, 13641, 13645, 13648, 13648, 13648, 13649, 13653, 13657, 13661,
3825 13665, 13669, 13673, 13677, 13681, 13685, 13689, 13693, 13697, 13701,
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, 13704, 13704, 13704, 13704,
3834 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704, 13704,
3835 13704, 13704, 13704, 13704, 13704, 13704, 13705},
3836 {13705, 13717, 13729, 13741, 13753, 13765, 13777, 13789, 13801, 13813,
3837 13825, 13837, 13849, 13861, 13873, 13889, 13905, 13921, 13937, 13953,
3838 13969, 13985, 14001, 14017, 14033, 14049, 14065, 14081, 14097, 14113,
3839 14141, 14164, 14165, 14177, 14189, 14201, 14213, 14225, 14237, 14249,
3840 14261, 14273, 14285, 14297, 14309, 14321, 14333, 14345, 14357, 14369,
3841 14381, 14393, 14405, 14417, 14429, 14441, 14453, 14465, 14477, 14489,
3842 14501, 14513, 14525, 14537, 14549, 14561, 14573, 14585, 14597, 14601,
3843 14605, 14609, 14612, 14612, 14612, 14612, 14612, 14612, 14612, 14612,
3844 14613, 14625, 14633, 14641, 14649, 14657, 14665, 14673, 14681, 14689,
3845 14697, 14705, 14713, 14721, 14729, 14737, 14745, 14749, 14753, 14757,
3846 14761, 14765, 14769, 14773, 14777, 14781, 14785, 14789, 14793, 14797,
3847 14801, 14809, 14817, 14825, 14833, 14841, 14849, 14857, 14865, 14873,
3848 14881, 14889, 14897, 14905, 14913, 14933, 14949, 14956, 14957, 14961,
3849 14965, 14969, 14973, 14977, 14981, 14985, 14989, 14993, 14997, 15001,
3850 15005, 15009, 15013, 15017, 15021, 15025, 15029, 15033, 15037, 15041,
3851 15045, 15049, 15053, 15057, 15061, 15065, 15069, 15073, 15077, 15081,
3852 15085, 15089, 15093, 15097, 15101, 15105, 15109, 15113, 15117, 15121,
3853 15125, 15129, 15133, 15137, 15141, 15145, 15149, 15153, 15161, 15169,
3854 15177, 15185, 15193, 15201, 15209, 15217, 15225, 15233, 15241, 15249,
3855 15257, 15265, 15273, 15281, 15289, 15297, 15305, 15313, 15321, 15329,
3856 15337, 15345, 15357, 15369, 15381, 15389, 15401, 15409, 15421, 15425,
3857 15429, 15433, 15437, 15441, 15445, 15449, 15453, 15457, 15461, 15465,
3858 15469, 15473, 15477, 15481, 15485, 15489, 15493, 15497, 15501, 15505,
3859 15509, 15513, 15517, 15521, 15525, 15529, 15533, 15537, 15541, 15545,
3860 15549, 15553, 15557, 15561, 15565, 15569, 15573, 15577, 15581, 15585,
3861 15589, 15593, 15597, 15601, 15605, 15609, 15617},
3862 {15617, 15637, 15653, 15673, 15685, 15705, 15717, 15729, 15753, 15769,
3863 15781, 15793, 15805, 15821, 15837, 15853, 15869, 15885, 15901, 15917,
3864 15941, 15949, 15973, 15997, 16017, 16033, 16057, 16081, 16097, 16109,
3865 16121, 16137, 16153, 16173, 16193, 16205, 16217, 16233, 16245, 16257,
3866 16265, 16273, 16285, 16297, 16321, 16337, 16357, 16381, 16397, 16409,
3867 16421, 16445, 16461, 16485, 16497, 16517, 16529, 16545, 16557, 16573,
3868 16593, 16609, 16629, 16645, 16653, 16673, 16685, 16697, 16713, 16725,
3869 16737, 16749, 16769, 16785, 16793, 16817, 16829, 16849, 16865, 16881,
3870 16893, 16905, 16921, 16929, 16945, 16965, 16973, 16997, 17009, 17017,
3871 17025, 17033, 17041, 17049, 17057, 17065, 17073, 17081, 17089, 17101,
3872 17113, 17125, 17137, 17149, 17161, 17173, 17185, 17197, 17209, 17221,
3873 17233, 17245, 17257, 17269, 17281, 17289, 17297, 17309, 17317, 17325,
3874 17333, 17345, 17357, 17365, 17373, 17381, 17389, 17397, 17413, 17421,
3875 17429, 17437, 17445, 17453, 17461, 17469, 17477, 17489, 17505, 17513,
3876 17521, 17529, 17537, 17545, 17553, 17561, 17573, 17585, 17597, 17609,
3877 17617, 17625, 17633, 17641, 17649, 17657, 17665, 17673, 17681, 17689,
3878 17701, 17713, 17721, 17733, 17745, 17757, 17765, 17777, 17789, 17805,
3879 17813, 17825, 17837, 17849, 17861, 17881, 17905, 17913, 17921, 17929,
3880 17937, 17945, 17953, 17961, 17969, 17977, 17985, 17993, 18001, 18009,
3881 18017, 18025, 18033, 18041, 18049, 18065, 18073, 18081, 18089, 18105,
3882 18117, 18125, 18133, 18141, 18149, 18157, 18165, 18173, 18181, 18189,
3883 18197, 18209, 18217, 18225, 18237, 18249, 18257, 18273, 18285, 18293,
3884 18301, 18309, 18317, 18329, 18341, 18349, 18357, 18365, 18373, 18381,
3885 18389, 18397, 18405, 18413, 18425, 18437, 18449, 18461, 18473, 18485,
3886 18497, 18509, 18521, 18533, 18545, 18557, 18569, 18581, 18593, 18605,
3887 18617, 18629, 18641, 18653, 18665, 18677, 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, 18688, 18688, 18688, 18688,
3902 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688, 18688,
3903 18688, 18688, 18688, 18688, 18688, 18688, 18689, 18693, 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, 18696, 18696, 18696,
3912 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3913 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, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3924 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696, 18696,
3925 18696, 18696, 18697, 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, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3937 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700, 18700,
3938 18700, 18700, 18701, 18705, 18709, 18712, 18712, 18712, 18713, 18717,
3939 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, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3948 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720, 18720,
3949 18720, 18720, 18721, 18725, 18729, 18733, 18736, 18736, 18736, 18736,
3950 18736, 18736, 18736, 18736, 18736, 18737, 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, 18740, 18740, 18740,
3964 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740, 18740,
3965 18740, 18740, 18740, 18740, 18740, 18740, 18740},
3966 {18740, 18744, 18748, 18752, 18756, 18760, 18764, 18768, 18772, 18776,
3967 18780, 18784, 18788, 18792, 18796, 18800, 18804, 18808, 18812, 18816,
3968 18820, 18824, 18828, 18832, 18836, 18840, 18844, 18848, 18852, 18856,
3969 18860, 18864, 18868, 18872, 18876, 18880, 18884, 18888, 18892, 18896,
3970 18900, 18904, 18908, 18912, 18916, 18920, 18924, 18928, 18932, 18936,
3971 18940, 18944, 18948, 18952, 18956, 18960, 18964, 18968, 18972, 18976,
3972 18980, 18984, 18988, 18992, 18996, 19000, 19004, 19008, 19012, 19016,
3973 19020, 19024, 19028, 19032, 19036, 19040, 19044, 19048, 19052, 19056,
3974 19060, 19064, 19068, 19072, 19076, 19080, 19084, 19088, 19092, 19096,
3975 19100, 19104, 19108, 19112, 19116, 19120, 19124, 19128, 19132, 19136,
3976 19140, 19144, 19148, 19152, 19156, 19160, 19164, 19168, 19172, 19176,
3977 19180, 19184, 19188, 19192, 19196, 19200, 19204, 19208, 19212, 19216,
3978 19220, 19224, 19228, 19232, 19236, 19240, 19244, 19248, 19252, 19256,
3979 19260, 19264, 19268, 19272, 19276, 19280, 19284, 19288, 19292, 19296,
3980 19300, 19304, 19308, 19312, 19316, 19320, 19324, 19328, 19332, 19336,
3981 19340, 19344, 19348, 19352, 19356, 19360, 19364, 19368, 19372, 19376,
3982 19380, 19384, 19388, 19392, 19396, 19400, 19404, 19408, 19412, 19416,
3983 19420, 19424, 19428, 19432, 19436, 19440, 19444, 19448, 19452, 19456,
3984 19460, 19464, 19468, 19472, 19476, 19480, 19484, 19488, 19492, 19496,
3985 19500, 19504, 19508, 19512, 19516, 19520, 19524, 19528, 19532, 19536,
3986 19540, 19544, 19548, 19552, 19556, 19560, 19564, 19568, 19572, 19576,
3987 19580, 19584, 19588, 19592, 19596, 19600, 19604, 19608, 19612, 19616,
3988 19620, 19624, 19628, 19632, 19636, 19640, 19644, 19648, 19652, 19656,
3989 19660, 19664, 19668, 19672, 19676, 19680, 19684, 19688, 19692, 19696,
3990 19700, 19704, 19708, 19712, 19716, 19720, 19724, 19728, 19732, 19736,
3991 19740, 19744, 19748, 19752, 19756, 19760, 19764},
3992 {19764, 19768, 19772, 19776, 19780, 19784, 19788, 19792, 19796, 19800,
3993 19804, 19808, 19812, 19816, 19820, 19820, 19820, 19824, 19824, 19828,
3994 19828, 19828, 19832, 19836, 19840, 19844, 19848, 19852, 19856, 19860,
3995 19864, 19868, 19868, 19872, 19872, 19876, 19876, 19876, 19880, 19884,
3996 19884, 19884, 19884, 19888, 19892, 19896, 19900, 19904, 19908, 19912,
3997 19916, 19920, 19924, 19928, 19932, 19936, 19940, 19944, 19948, 19952,
3998 19956, 19960, 19964, 19968, 19972, 19976, 19980, 19984, 19988, 19992,
3999 19996, 20000, 20004, 20008, 20012, 20016, 20020, 20024, 20028, 20032,
4000 20036, 20040, 20044, 20048, 20052, 20056, 20060, 20064, 20068, 20072,
4001 20076, 20080, 20084, 20088, 20092, 20096, 20100, 20104, 20108, 20112,
4002 20116, 20120, 20124, 20128, 20132, 20136, 20140, 20144, 20148, 20152,
4003 20156, 20156, 20156, 20160, 20164, 20168, 20172, 20176, 20180, 20184,
4004 20188, 20192, 20196, 20200, 20204, 20208, 20212, 20216, 20220, 20224,
4005 20228, 20232, 20236, 20240, 20244, 20248, 20252, 20256, 20260, 20264,
4006 20268, 20272, 20276, 20280, 20284, 20288, 20292, 20296, 20300, 20304,
4007 20308, 20312, 20316, 20320, 20324, 20328, 20332, 20336, 20340, 20344,
4008 20348, 20352, 20356, 20360, 20364, 20368, 20372, 20376, 20380, 20384,
4009 20388, 20392, 20396, 20400, 20404, 20408, 20412, 20416, 20420, 20424,
4010 20428, 20432, 20436, 20440, 20444, 20448, 20452, 20456, 20460, 20464,
4011 20468, 20472, 20476, 20480, 20484, 20488, 20492, 20496, 20500, 20504,
4012 20508, 20512, 20516, 20520, 20524, 20528, 20532, 20536, 20540, 20544,
4013 20548, 20552, 20556, 20560, 20564, 20568, 20572, 20576, 20580, 20580,
4014 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,
4015 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,
4016 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580, 20580,
4017 20580, 20580, 20580, 20580, 20580, 20580, 20581},
4018 {20581, 20589, 20597, 20605, 20617, 20629, 20637, 20644, 20644, 20644,
4019 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20644, 20645,
4020 20653, 20661, 20669, 20677, 20684, 20684, 20684, 20684, 20684, 20684,
4021 20692, 20692, 20701, 20705, 20709, 20713, 20717, 20721, 20725, 20729,
4022 20733, 20737, 20740, 20748, 20756, 20768, 20780, 20788, 20796, 20804,
4023 20812, 20820, 20828, 20836, 20844, 20852, 20852, 20860, 20868, 20876,
4024 20884, 20892, 20892, 20900, 20900, 20908, 20916, 20916, 20924, 20932,
4025 20932, 20940, 20948, 20956, 20964, 20972, 20980, 20988, 20996, 21005,
4026 21013, 21017, 21021, 21025, 21029, 21033, 21037, 21041, 21045, 21049,
4027 21053, 21057, 21061, 21065, 21069, 21073, 21077, 21081, 21085, 21089,
4028 21093, 21097, 21101, 21105, 21109, 21113, 21117, 21121, 21125, 21129,
4029 21133, 21137, 21141, 21145, 21149, 21153, 21157, 21161, 21165, 21169,
4030 21173, 21177, 21181, 21185, 21189, 21193, 21197, 21201, 21205, 21209,
4031 21213, 21217, 21221, 21225, 21229, 21233, 21237, 21241, 21245, 21249,
4032 21253, 21257, 21261, 21265, 21269, 21273, 21277, 21281, 21285, 21289,
4033 21293, 21297, 21301, 21305, 21309, 21313, 21317, 21321, 21325, 21329,
4034 21333, 21337, 21341, 21345, 21349, 21357, 21365, 21369, 21373, 21377,
4035 21381, 21385, 21389, 21393, 21397, 21401, 21405, 21413, 21420, 21420,
4036 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,
4037 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,
4038 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420, 21420,
4039 21420, 21421, 21425, 21429, 21433, 21437, 21441, 21445, 21449, 21453,
4040 21457, 21461, 21469, 21473, 21477, 21481, 21485, 21489, 21493, 21497,
4041 21501, 21505, 21509, 21513, 21517, 21529, 21541, 21553, 21565, 21577,
4042 21589, 21601, 21613, 21625, 21637, 21649, 21661, 21673, 21685, 21697,
4043 21709, 21721, 21733, 21737, 21741, 21745, 21749},
4044 {21749, 21761, 21773, 21785, 21797, 21809, 21817, 21825, 21833, 21841,
4045 21849, 21857, 21865, 21873, 21881, 21889, 21897, 21905, 21913, 21921,
4046 21929, 21937, 21945, 21953, 21961, 21969, 21977, 21985, 21993, 22001,
4047 22009, 22017, 22025, 22033, 22041, 22049, 22057, 22065, 22073, 22081,
4048 22089, 22097, 22105, 22113, 22121, 22129, 22137, 22145, 22153, 22161,
4049 22169, 22177, 22185, 22193, 22201, 22209, 22217, 22225, 22233, 22241,
4050 22249, 22257, 22265, 22273, 22281, 22289, 22297, 22305, 22313, 22321,
4051 22329, 22337, 22345, 22353, 22361, 22369, 22377, 22385, 22393, 22401,
4052 22409, 22417, 22425, 22433, 22441, 22449, 22457, 22465, 22473, 22481,
4053 22489, 22497, 22505, 22513, 22521, 22533, 22545, 22557, 22569, 22581,
4054 22593, 22605, 22617, 22629, 22641, 22653, 22665, 22673, 22681, 22689,
4055 22697, 22705, 22713, 22721, 22729, 22737, 22745, 22753, 22761, 22769,
4056 22777, 22785, 22793, 22801, 22809, 22817, 22825, 22833, 22841, 22849,
4057 22857, 22865, 22873, 22881, 22889, 22897, 22905, 22913, 22921, 22929,
4058 22937, 22945, 22953, 22961, 22969, 22977, 22985, 22993, 23001, 23009,
4059 23017, 23025, 23037, 23049, 23061, 23073, 23085, 23093, 23101, 23109,
4060 23117, 23125, 23133, 23141, 23149, 23157, 23165, 23173, 23181, 23189,
4061 23197, 23205, 23213, 23221, 23229, 23237, 23245, 23253, 23261, 23269,
4062 23277, 23285, 23293, 23301, 23309, 23317, 23325, 23333, 23341, 23349,
4063 23357, 23365, 23373, 23381, 23389, 23397, 23405, 23413, 23421, 23429,
4064 23437, 23445, 23453, 23461, 23469, 23477, 23485, 23493, 23501, 23509,
4065 23517, 23525, 23533, 23541, 23549, 23557, 23565, 23573, 23581, 23589,
4066 23597, 23605, 23613, 23621, 23633, 23645, 23653, 23661, 23669, 23677,
4067 23685, 23693, 23701, 23709, 23717, 23725, 23733, 23741, 23749, 23757,
4068 23765, 23773, 23781, 23793, 23805, 23817, 23825, 23833, 23841, 23849,
4069 23857, 23865, 23873, 23881, 23889, 23897, 23905},
4070 {23905, 23913, 23921, 23929, 23937, 23945, 23953, 23961, 23969, 23977,
4071 23985, 23993, 24001, 24009, 24017, 24025, 24033, 24041, 24049, 24057,
4072 24065, 24073, 24081, 24089, 24097, 24105, 24113, 24121, 24129, 24137,
4073 24145, 24153, 24161, 24169, 24177, 24185, 24193, 24201, 24209, 24217,
4074 24225, 24233, 24241, 24249, 24257, 24265, 24273, 24281, 24289, 24297,
4075 24305, 24313, 24321, 24329, 24337, 24345, 24353, 24361, 24369, 24377,
4076 24385, 24393, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400,
4077 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400, 24400,
4078 24401, 24413, 24425, 24437, 24449, 24461, 24473, 24485, 24497, 24509,
4079 24521, 24533, 24545, 24557, 24569, 24581, 24593, 24605, 24617, 24629,
4080 24641, 24653, 24665, 24677, 24689, 24701, 24713, 24725, 24737, 24749,
4081 24761, 24773, 24785, 24797, 24809, 24821, 24833, 24845, 24857, 24869,
4082 24881, 24893, 24905, 24917, 24929, 24941, 24953, 24965, 24977, 24989,
4083 25001, 25013, 25025, 25037, 25049, 25061, 25073, 25085, 25097, 25109,
4084 25121, 25133, 25145, 25157, 25168, 25168, 25169, 25181, 25193, 25205,
4085 25217, 25229, 25241, 25253, 25265, 25277, 25289, 25301, 25313, 25325,
4086 25337, 25349, 25361, 25373, 25385, 25397, 25409, 25421, 25433, 25445,
4087 25457, 25469, 25481, 25493, 25505, 25517, 25529, 25541, 25553, 25565,
4088 25577, 25589, 25601, 25613, 25625, 25637, 25649, 25661, 25673, 25685,
4089 25697, 25709, 25721, 25733, 25745, 25757, 25769, 25781, 25793, 25805,
4090 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4091 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4092 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4093 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816, 25816,
4094 25817, 25829, 25841, 25857, 25873, 25889, 25905, 25921, 25937, 25953,
4095 25965, 26037, 26069, 26084, 26084, 26084, 26084},
4096 {26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084, 26084,
4097 26084, 26084, 26084, 26084, 26084, 26084, 26085, 26089, 26093, 26097,
4098 26101, 26105, 26109, 26113, 26117, 26121, 26132, 26132, 26132, 26132,
4099 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132,
4100 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26132, 26133, 26141,
4101 26145, 26149, 26153, 26157, 26161, 26165, 26169, 26173, 26177, 26181,
4102 26185, 26189, 26193, 26197, 26201, 26205, 26209, 26213, 26217, 26220,
4103 26220, 26221, 26225, 26229, 26237, 26245, 26253, 26261, 26265, 26269,
4104 26273, 26277, 26281, 26284, 26285, 26289, 26293, 26297, 26301, 26305,
4105 26309, 26313, 26317, 26321, 26325, 26329, 26333, 26337, 26341, 26345,
4106 26349, 26353, 26357, 26360, 26361, 26365, 26369, 26373, 26376, 26376,
4107 26376, 26376, 26377, 26385, 26393, 26400, 26401, 26408, 26409, 26417,
4108 26425, 26433, 26441, 26449, 26457, 26465, 26473, 26481, 26489, 26493,
4109 26501, 26509, 26517, 26525, 26533, 26541, 26549, 26557, 26565, 26573,
4110 26581, 26589, 26593, 26597, 26601, 26605, 26609, 26613, 26617, 26621,
4111 26625, 26629, 26633, 26637, 26641, 26645, 26649, 26653, 26657, 26661,
4112 26665, 26669, 26673, 26677, 26681, 26685, 26689, 26693, 26697, 26701,
4113 26705, 26709, 26713, 26717, 26721, 26725, 26729, 26733, 26737, 26741,
4114 26745, 26749, 26753, 26757, 26761, 26765, 26769, 26773, 26777, 26781,
4115 26785, 26789, 26793, 26797, 26801, 26805, 26809, 26813, 26817, 26821,
4116 26825, 26829, 26833, 26837, 26841, 26845, 26849, 26853, 26857, 26861,
4117 26865, 26869, 26873, 26877, 26881, 26885, 26889, 26893, 26897, 26901,
4118 26905, 26909, 26913, 26917, 26921, 26925, 26929, 26933, 26937, 26941,
4119 26945, 26949, 26953, 26957, 26961, 26965, 26969, 26973, 26977, 26981,
4120 26985, 26989, 26993, 26997, 27001, 27005, 27017, 27029, 27041, 27053,
4121 27065, 27077, 27085, 27092, 27092, 27092, 27092},
4122 {27092, 27093, 27097, 27101, 27105, 27109, 27113, 27117, 27121, 27125,
4123 27129, 27133, 27137, 27141, 27145, 27149, 27153, 27157, 27161, 27165,
4124 27169, 27173, 27177, 27181, 27185, 27189, 27193, 27197, 27201, 27205,
4125 27209, 27213, 27217, 27221, 27225, 27229, 27233, 27237, 27241, 27245,
4126 27249, 27253, 27257, 27261, 27265, 27269, 27273, 27277, 27281, 27285,
4127 27289, 27293, 27297, 27301, 27305, 27309, 27313, 27317, 27321, 27325,
4128 27329, 27333, 27337, 27341, 27345, 27349, 27353, 27357, 27361, 27365,
4129 27369, 27373, 27377, 27381, 27385, 27389, 27393, 27397, 27401, 27405,
4130 27409, 27413, 27417, 27421, 27425, 27429, 27433, 27437, 27441, 27445,
4131 27449, 27453, 27457, 27461, 27465, 27469, 27473, 27477, 27481, 27485,
4132 27489, 27493, 27497, 27501, 27505, 27509, 27513, 27517, 27521, 27525,
4133 27529, 27533, 27537, 27541, 27545, 27549, 27553, 27557, 27561, 27565,
4134 27569, 27573, 27577, 27581, 27585, 27589, 27593, 27597, 27601, 27605,
4135 27609, 27613, 27617, 27621, 27625, 27629, 27633, 27637, 27641, 27645,
4136 27649, 27653, 27657, 27661, 27665, 27669, 27673, 27677, 27681, 27685,
4137 27689, 27693, 27697, 27701, 27705, 27709, 27713, 27717, 27721, 27725,
4138 27729, 27733, 27737, 27741, 27745, 27749, 27753, 27757, 27761, 27765,
4139 27769, 27773, 27777, 27781, 27785, 27789, 27793, 27797, 27801, 27805,
4140 27809, 27813, 27817, 27821, 27825, 27829, 27833, 27837, 27841, 27845,
4141 27849, 27852, 27852, 27852, 27853, 27857, 27861, 27865, 27869, 27873,
4142 27876, 27876, 27877, 27881, 27885, 27889, 27893, 27897, 27900, 27900,
4143 27901, 27905, 27909, 27913, 27917, 27921, 27924, 27924, 27925, 27929,
4144 27933, 27936, 27936, 27936, 27937, 27941, 27945, 27949, 27957, 27961,
4145 27965, 27968, 27969, 27973, 27977, 27981, 27985, 27989, 27993, 27996,
4146 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4147 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, 27996,
4159 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996,
4160 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27996, 27997,
4161 28001, 28005, 28009, 28013, 28016, 28017, 28021, 28025, 28029, 28033,
4162 28037, 28041, 28045, 28049, 28053, 28057, 28061, 28065, 28069, 28073,
4163 28077, 28081, 28085, 28089, 28093, 28097, 28101, 28105, 28109, 28113,
4164 28117, 28121, 28125, 28129, 28133, 28137, 28141, 28145, 28149, 28153,
4165 28157, 28161, 28165, 28169, 28173, 28177, 28181, 28184, 28185, 28189,
4166 28193, 28197, 28201, 28205, 28209, 28213, 28217, 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, 28220, 28220, 28220,
4172 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4173 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, 28220, 28220, 28220, 28220, 28220,
4188 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220, 28220,
4189 28220, 28220, 28220, 28220, 28220, 28228, 28228, 28236, 28236, 28236,
4190 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236, 28236,
4191 28236, 28236, 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, 28244, 28244, 28244,
4198 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4199 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, 28244, 28244, 28244,
4203 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28244,
4204 28244, 28244, 28244, 28244, 28244, 28244, 28244, 28252, 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, 28260, 28260, 28260,
4224 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4225 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, 28260, 28260, 28260, 28260,
4232 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260, 28260,
4233 28260, 28260, 28260, 28260, 28260, 28260, 28268, 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, 28276, 28276, 28276,
4250 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4251 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, 28276, 28276,
4269 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276,
4270 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28276, 28284, 28292,
4271 28292, 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, 28300, 28300, 28300,
4276 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4277 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, 28300, 28300, 28300,
4295 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28300,
4296 28300, 28300, 28300, 28300, 28300, 28300, 28300, 28308, 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, 28316, 28316, 28316,
4302 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4303 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, 28316, 28316, 28316,
4308 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316, 28316,
4309 28316, 28316, 28316, 28316, 28316, 28316, 28316, 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, 28324, 28324, 28324,
4328 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4329 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, 28324, 28324, 28324, 28324, 28324,
4338 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324, 28324,
4339 28324, 28324, 28324, 28324, 28324, 28332, 28340, 28352, 28364, 28376,
4340 28388, 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, 28400, 28400,
4347 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400,
4348 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28400, 28408, 28416,
4349 28428, 28440, 28452, 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, 28464, 28464, 28464,
4354 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4355 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, 28464, 28464, 28464, 28464,
4380 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464, 28464,
4381 28464, 28464, 28464, 28464, 28464, 28464, 28465},
4382 {28465, 28469, 28473, 28477, 28481, 28485, 28489, 28493, 28497, 28501,
4383 28505, 28509, 28513, 28517, 28521, 28525, 28529, 28533, 28537, 28541,
4384 28545, 28549, 28553, 28557, 28561, 28565, 28569, 28573, 28577, 28581,
4385 28585, 28589, 28593, 28597, 28601, 28605, 28609, 28613, 28617, 28621,
4386 28625, 28629, 28633, 28637, 28641, 28645, 28649, 28653, 28657, 28661,
4387 28665, 28669, 28673, 28677, 28681, 28685, 28689, 28693, 28697, 28701,
4388 28705, 28709, 28713, 28717, 28721, 28725, 28729, 28733, 28737, 28741,
4389 28745, 28749, 28753, 28757, 28761, 28765, 28769, 28773, 28777, 28781,
4390 28785, 28789, 28793, 28797, 28801, 28804, 28805, 28809, 28813, 28817,
4391 28821, 28825, 28829, 28833, 28837, 28841, 28845, 28849, 28853, 28857,
4392 28861, 28865, 28869, 28873, 28877, 28881, 28885, 28889, 28893, 28897,
4393 28901, 28905, 28909, 28913, 28917, 28921, 28925, 28929, 28933, 28937,
4394 28941, 28945, 28949, 28953, 28957, 28961, 28965, 28969, 28973, 28977,
4395 28981, 28985, 28989, 28993, 28997, 29001, 29005, 29009, 29013, 29017,
4396 29021, 29025, 29029, 29033, 29037, 29041, 29045, 29049, 29053, 29057,
4397 29061, 29065, 29069, 29073, 29077, 29081, 29085, 29088, 29089, 29093,
4398 29096, 29096, 29097, 29100, 29100, 29101, 29105, 29108, 29108, 29109,
4399 29113, 29117, 29121, 29124, 29125, 29129, 29133, 29137, 29141, 29145,
4400 29149, 29153, 29157, 29161, 29165, 29169, 29172, 29173, 29176, 29177,
4401 29181, 29185, 29189, 29193, 29197, 29201, 29204, 29205, 29209, 29213,
4402 29217, 29221, 29225, 29229, 29233, 29237, 29241, 29245, 29249, 29253,
4403 29257, 29261, 29265, 29269, 29273, 29277, 29281, 29285, 29289, 29293,
4404 29297, 29301, 29305, 29309, 29313, 29317, 29321, 29325, 29329, 29333,
4405 29337, 29341, 29345, 29349, 29353, 29357, 29361, 29365, 29369, 29373,
4406 29377, 29381, 29385, 29389, 29393, 29397, 29401, 29405, 29409, 29413,
4407 29417, 29421, 29425, 29429, 29433, 29437, 29441},
4408 {29441, 29445, 29449, 29453, 29457, 29461, 29464, 29465, 29469, 29473,
4409 29477, 29480, 29480, 29481, 29485, 29489, 29493, 29497, 29501, 29505,
4410 29509, 29512, 29513, 29517, 29521, 29525, 29529, 29533, 29537, 29540,
4411 29541, 29545, 29549, 29553, 29557, 29561, 29565, 29569, 29573, 29577,
4412 29581, 29585, 29589, 29593, 29597, 29601, 29605, 29609, 29613, 29617,
4413 29621, 29625, 29629, 29633, 29637, 29641, 29645, 29649, 29652, 29653,
4414 29657, 29661, 29665, 29668, 29669, 29673, 29677, 29681, 29685, 29688,
4415 29689, 29692, 29692, 29692, 29693, 29697, 29701, 29705, 29709, 29713,
4416 29717, 29720, 29721, 29725, 29729, 29733, 29737, 29741, 29745, 29749,
4417 29753, 29757, 29761, 29765, 29769, 29773, 29777, 29781, 29785, 29789,
4418 29793, 29797, 29801, 29805, 29809, 29813, 29817, 29821, 29825, 29829,
4419 29833, 29837, 29841, 29845, 29849, 29853, 29857, 29861, 29865, 29869,
4420 29873, 29877, 29881, 29885, 29889, 29893, 29897, 29901, 29905, 29909,
4421 29913, 29917, 29921, 29925, 29929, 29933, 29937, 29941, 29945, 29949,
4422 29953, 29957, 29961, 29965, 29969, 29973, 29977, 29981, 29985, 29989,
4423 29993, 29997, 30001, 30005, 30009, 30013, 30017, 30021, 30025, 30029,
4424 30033, 30037, 30041, 30045, 30049, 30053, 30057, 30061, 30065, 30069,
4425 30073, 30077, 30081, 30085, 30089, 30093, 30097, 30101, 30105, 30109,
4426 30113, 30117, 30121, 30125, 30129, 30133, 30137, 30141, 30145, 30149,
4427 30153, 30157, 30161, 30165, 30169, 30173, 30177, 30181, 30185, 30189,
4428 30193, 30197, 30201, 30205, 30209, 30213, 30217, 30221, 30225, 30229,
4429 30233, 30237, 30241, 30245, 30249, 30253, 30257, 30261, 30265, 30269,
4430 30273, 30277, 30281, 30285, 30289, 30293, 30297, 30301, 30305, 30309,
4431 30313, 30317, 30321, 30325, 30329, 30333, 30337, 30341, 30345, 30349,
4432 30353, 30357, 30361, 30365, 30369, 30373, 30377, 30381, 30385, 30389,
4433 30393, 30397, 30401, 30405, 30409, 30413, 30417},
4434 {30417, 30421, 30425, 30429, 30433, 30437, 30441, 30445, 30449, 30453,
4435 30457, 30461, 30465, 30469, 30473, 30477, 30481, 30485, 30489, 30493,
4436 30497, 30501, 30505, 30509, 30513, 30517, 30521, 30525, 30529, 30533,
4437 30537, 30541, 30545, 30549, 30553, 30557, 30561, 30565, 30569, 30573,
4438 30577, 30581, 30585, 30589, 30593, 30597, 30601, 30605, 30609, 30613,
4439 30617, 30621, 30625, 30629, 30633, 30637, 30641, 30645, 30649, 30653,
4440 30657, 30661, 30665, 30669, 30673, 30677, 30681, 30685, 30689, 30693,
4441 30697, 30701, 30705, 30709, 30713, 30717, 30721, 30725, 30729, 30733,
4442 30737, 30741, 30745, 30749, 30753, 30757, 30761, 30765, 30769, 30773,
4443 30777, 30781, 30785, 30789, 30793, 30797, 30801, 30805, 30809, 30813,
4444 30817, 30821, 30825, 30829, 30833, 30837, 30841, 30845, 30849, 30853,
4445 30857, 30861, 30865, 30869, 30873, 30877, 30881, 30885, 30889, 30893,
4446 30897, 30901, 30905, 30909, 30913, 30917, 30921, 30925, 30929, 30933,
4447 30937, 30941, 30945, 30949, 30953, 30957, 30961, 30965, 30969, 30973,
4448 30977, 30981, 30985, 30989, 30993, 30997, 31001, 31005, 31009, 31013,
4449 31017, 31021, 31025, 31029, 31033, 31037, 31041, 31045, 31049, 31053,
4450 31057, 31061, 31065, 31069, 31073, 31077, 31080, 31080, 31081, 31085,
4451 31089, 31093, 31097, 31101, 31105, 31109, 31113, 31117, 31121, 31125,
4452 31129, 31133, 31137, 31141, 31145, 31149, 31153, 31157, 31161, 31165,
4453 31169, 31173, 31177, 31181, 31185, 31189, 31193, 31197, 31201, 31205,
4454 31209, 31213, 31217, 31221, 31225, 31229, 31233, 31237, 31241, 31245,
4455 31249, 31253, 31257, 31261, 31265, 31269, 31273, 31277, 31281, 31285,
4456 31289, 31293, 31297, 31301, 31305, 31309, 31313, 31317, 31321, 31325,
4457 31329, 31333, 31337, 31341, 31345, 31349, 31353, 31357, 31361, 31365,
4458 31369, 31373, 31377, 31381, 31385, 31389, 31393, 31397, 31401, 31405,
4459 31409, 31413, 31417, 31421, 31425, 31429, 31433},
4460 {31433, 31437, 31441, 31445, 31449, 31453, 31457, 31461, 31465, 31469,
4461 31473, 31477, 31481, 31485, 31489, 31493, 31497, 31501, 31505, 31509,
4462 31513, 31517, 31521, 31525, 31529, 31533, 31537, 31541, 31545, 31549,
4463 31553, 31557, 31561, 31565, 31569, 31573, 31577, 31581, 31585, 31589,
4464 31593, 31597, 31601, 31605, 31609, 31613, 31617, 31621, 31625, 31629,
4465 31633, 31637, 31641, 31645, 31649, 31653, 31657, 31661, 31665, 31669,
4466 31673, 31677, 31681, 31685, 31689, 31693, 31697, 31701, 31705, 31709,
4467 31713, 31717, 31721, 31725, 31729, 31733, 31737, 31741, 31745, 31749,
4468 31753, 31757, 31761, 31765, 31769, 31773, 31777, 31781, 31785, 31789,
4469 31793, 31797, 31801, 31805, 31809, 31813, 31817, 31821, 31825, 31829,
4470 31833, 31837, 31841, 31845, 31849, 31853, 31857, 31861, 31865, 31869,
4471 31873, 31877, 31881, 31885, 31889, 31893, 31897, 31901, 31905, 31909,
4472 31913, 31917, 31921, 31925, 31929, 31933, 31937, 31941, 31945, 31949,
4473 31953, 31957, 31961, 31965, 31969, 31973, 31977, 31981, 31985, 31989,
4474 31993, 31997, 32001, 32005, 32009, 32013, 32017, 32021, 32025, 32029,
4475 32033, 32037, 32041, 32045, 32049, 32053, 32057, 32061, 32065, 32069,
4476 32073, 32077, 32081, 32085, 32089, 32093, 32097, 32101, 32105, 32109,
4477 32113, 32117, 32121, 32125, 32129, 32133, 32137, 32141, 32145, 32149,
4478 32153, 32157, 32161, 32165, 32169, 32173, 32177, 32181, 32185, 32189,
4479 32193, 32197, 32201, 32205, 32209, 32213, 32217, 32221, 32225, 32229,
4480 32233, 32237, 32241, 32245, 32248, 32248, 32249, 32253, 32257, 32261,
4481 32265, 32269, 32273, 32277, 32281, 32285, 32289, 32293, 32297, 32301,
4482 32305, 32309, 32313, 32317, 32321, 32325, 32329, 32333, 32337, 32341,
4483 32345, 32349, 32353, 32357, 32361, 32365, 32369, 32373, 32377, 32381,
4484 32385, 32389, 32393, 32397, 32401, 32405, 32409, 32413, 32417, 32421,
4485 32425, 32429, 32433, 32437, 32441, 32445, 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, 32448, 32448,
4489 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448,
4490 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32448, 32449, 32453,
4491 32457, 32461, 32465, 32469, 32473, 32477, 32481, 32485, 32489, 32493,
4492 32497, 32501, 32505, 32509, 32513, 32517, 32521, 32525, 32529, 32533,
4493 32537, 32541, 32545, 32549, 32553, 32557, 32561, 32565, 32569, 32573,
4494 32577, 32581, 32585, 32589, 32593, 32597, 32601, 32605, 32609, 32613,
4495 32617, 32621, 32625, 32629, 32633, 32637, 32641, 32645, 32649, 32653,
4496 32657, 32661, 32665, 32669, 32673, 32677, 32681, 32685, 32689, 32693,
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, 32696, 32696, 32696,
4510 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4511 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, 32696, 32696, 32696, 32696,
4536 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696, 32696,
4537 32696, 32696, 32696, 32696, 32696, 32696, 32697},
4538 {32697, 32701, 32705, 32709, 32712, 32713, 32717, 32721, 32725, 32729,
4539 32733, 32737, 32741, 32745, 32749, 32753, 32757, 32761, 32765, 32769,
4540 32773, 32777, 32781, 32785, 32789, 32793, 32797, 32801, 32805, 32809,
4541 32813, 32817, 32820, 32821, 32825, 32828, 32829, 32832, 32832, 32833,
4542 32836, 32837, 32841, 32845, 32849, 32853, 32857, 32861, 32865, 32869,
4543 32873, 32876, 32877, 32881, 32885, 32889, 32892, 32893, 32896, 32897,
4544 32900, 32900, 32900, 32900, 32900, 32900, 32901, 32904, 32904, 32904,
4545 32904, 32905, 32908, 32909, 32912, 32913, 32916, 32917, 32921, 32925,
4546 32928, 32929, 32933, 32936, 32937, 32940, 32940, 32941, 32944, 32945,
4547 32948, 32949, 32952, 32953, 32956, 32957, 32960, 32961, 32965, 32968,
4548 32969, 32972, 32972, 32973, 32977, 32981, 32985, 32988, 32989, 32993,
4549 32997, 33001, 33005, 33009, 33013, 33016, 33017, 33021, 33025, 33029,
4550 33032, 33033, 33037, 33041, 33045, 33048, 33049, 33052, 33053, 33057,
4551 33061, 33065, 33069, 33073, 33077, 33081, 33085, 33089, 33092, 33093,
4552 33097, 33101, 33105, 33109, 33113, 33117, 33121, 33125, 33129, 33133,
4553 33137, 33141, 33145, 33149, 33153, 33157, 33160, 33160, 33160, 33160,
4554 33160, 33161, 33165, 33169, 33172, 33173, 33177, 33181, 33185, 33189,
4555 33192, 33193, 33197, 33201, 33205, 33209, 33213, 33217, 33221, 33225,
4556 33229, 33233, 33237, 33241, 33245, 33249, 33253, 33257, 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, 33260, 33260, 33260,
4562 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4563 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, 33260, 33260, 33260, 33260,
4588 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260, 33260,
4589 33260, 33260, 33260, 33260, 33260, 33260, 33261},
4590 {33261, 33269, 33277, 33285, 33293, 33301, 33309, 33317, 33325, 33333,
4591 33341, 33348, 33348, 33348, 33348, 33348, 33349, 33361, 33373, 33385,
4592 33397, 33409, 33421, 33433, 33445, 33457, 33469, 33481, 33493, 33505,
4593 33517, 33529, 33541, 33553, 33565, 33577, 33589, 33601, 33613, 33625,
4594 33637, 33649, 33661, 33673, 33677, 33681, 33689, 33696, 33697, 33701,
4595 33705, 33709, 33713, 33717, 33721, 33725, 33729, 33733, 33737, 33741,
4596 33745, 33749, 33753, 33757, 33761, 33765, 33769, 33773, 33777, 33781,
4597 33785, 33789, 33793, 33797, 33801, 33809, 33817, 33825, 33833, 33845,
4598 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852,
4599 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852, 33852,
4600 33852, 33852, 33852, 33852, 33852, 33852, 33853, 33861, 33869, 33876,
4601 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,
4602 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,
4603 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876, 33876,
4604 33876, 33876, 33876, 33876, 33877, 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, 33884, 33884, 33884, 33884,
4614 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884, 33884,
4615 33884, 33884, 33884, 33884, 33884, 33884, 33885},
4616 {33885, 33893, 33901, 33904, 33904, 33904, 33904, 33904, 33904, 33904,
4617 33904, 33904, 33904, 33904, 33904, 33904, 33905, 33909, 33913, 33917,
4618 33925, 33929, 33933, 33937, 33941, 33945, 33949, 33953, 33957, 33961,
4619 33965, 33969, 33973, 33977, 33981, 33985, 33989, 33993, 33997, 34001,
4620 34005, 34009, 34013, 34017, 34021, 34025, 34029, 34033, 34037, 34041,
4621 34045, 34049, 34053, 34057, 34061, 34065, 34069, 34073, 34077, 34081,
4622 34084, 34084, 34084, 34084, 34085, 34097, 34109, 34121, 34133, 34145,
4623 34157, 34169, 34181, 34192, 34192, 34192, 34192, 34192, 34192, 34192,
4624 34193, 34197, 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, 34200, 34200, 34200,
4640 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4641 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 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4665 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200, 34200,
4666 34201, 34205, 34209, 34213, 34217, 34221, 34225, 34229, 34233, 34237,
4667 34240, 34240, 34240, 34240, 34240, 34240, 34240},
4668 {34240, 34244, 34248, 34252, 34256, 34260, 34264, 34268, 34272, 34276,
4669 34280, 34284, 34288, 34292, 34296, 34300, 34304, 34308, 34312, 34316,
4670 34320, 34324, 34328, 34332, 34336, 34340, 34344, 34348, 34352, 34356,
4671 34360, 34364, 34368, 34372, 34376, 34380, 34384, 34388, 34392, 34396,
4672 34400, 34404, 34408, 34412, 34416, 34420, 34424, 34428, 34432, 34436,
4673 34440, 34444, 34448, 34452, 34456, 34460, 34464, 34468, 34472, 34476,
4674 34480, 34484, 34488, 34492, 34496, 34500, 34504, 34508, 34512, 34516,
4675 34520, 34524, 34528, 34532, 34536, 34540, 34544, 34548, 34552, 34556,
4676 34560, 34564, 34568, 34572, 34576, 34580, 34584, 34588, 34592, 34596,
4677 34600, 34604, 34608, 34612, 34616, 34620, 34624, 34628, 34632, 34636,
4678 34640, 34644, 34648, 34652, 34656, 34660, 34664, 34668, 34672, 34676,
4679 34680, 34684, 34688, 34692, 34696, 34700, 34704, 34708, 34712, 34716,
4680 34720, 34724, 34728, 34732, 34736, 34740, 34744, 34748, 34752, 34756,
4681 34760, 34764, 34768, 34772, 34776, 34780, 34784, 34788, 34792, 34796,
4682 34800, 34804, 34808, 34812, 34816, 34820, 34824, 34828, 34832, 34836,
4683 34840, 34844, 34848, 34852, 34856, 34860, 34864, 34868, 34872, 34876,
4684 34880, 34884, 34888, 34892, 34896, 34900, 34904, 34908, 34912, 34916,
4685 34920, 34924, 34928, 34932, 34936, 34940, 34944, 34948, 34952, 34956,
4686 34960, 34964, 34968, 34972, 34976, 34980, 34984, 34988, 34992, 34996,
4687 35000, 35004, 35008, 35012, 35016, 35020, 35024, 35028, 35032, 35036,
4688 35040, 35044, 35048, 35052, 35056, 35060, 35064, 35068, 35072, 35076,
4689 35080, 35084, 35088, 35092, 35096, 35100, 35104, 35108, 35112, 35116,
4690 35120, 35124, 35128, 35132, 35136, 35140, 35144, 35148, 35152, 35156,
4691 35160, 35164, 35168, 35172, 35176, 35180, 35184, 35188, 35192, 35196,
4692 35200, 35204, 35208, 35212, 35216, 35220, 35224, 35228, 35232, 35236,
4693 35240, 35244, 35248, 35252, 35256, 35260, 35264},
4694 {35264, 35268, 35272, 35276, 35280, 35284, 35288, 35292, 35296, 35300,
4695 35304, 35308, 35312, 35316, 35320, 35324, 35328, 35332, 35336, 35340,
4696 35344, 35348, 35352, 35356, 35360, 35364, 35368, 35372, 35376, 35380,
4697 35384, 35388, 35392, 35396, 35400, 35404, 35408, 35412, 35416, 35420,
4698 35424, 35428, 35432, 35436, 35440, 35444, 35448, 35452, 35456, 35460,
4699 35464, 35468, 35472, 35476, 35480, 35484, 35488, 35492, 35496, 35500,
4700 35504, 35508, 35512, 35516, 35520, 35524, 35528, 35532, 35536, 35540,
4701 35544, 35548, 35552, 35556, 35560, 35564, 35568, 35572, 35576, 35580,
4702 35584, 35588, 35592, 35596, 35600, 35604, 35608, 35612, 35616, 35620,
4703 35624, 35628, 35632, 35636, 35640, 35644, 35648, 35652, 35656, 35660,
4704 35664, 35668, 35672, 35676, 35680, 35684, 35688, 35692, 35696, 35700,
4705 35704, 35708, 35712, 35716, 35720, 35724, 35728, 35732, 35736, 35740,
4706 35744, 35748, 35752, 35756, 35760, 35764, 35768, 35772, 35776, 35780,
4707 35784, 35788, 35792, 35796, 35800, 35804, 35808, 35812, 35816, 35820,
4708 35824, 35828, 35832, 35836, 35840, 35844, 35848, 35852, 35856, 35860,
4709 35864, 35868, 35872, 35876, 35880, 35884, 35888, 35892, 35896, 35900,
4710 35904, 35908, 35912, 35916, 35920, 35924, 35928, 35932, 35936, 35940,
4711 35944, 35948, 35952, 35956, 35960, 35964, 35968, 35972, 35976, 35980,
4712 35984, 35988, 35992, 35996, 36000, 36004, 36008, 36012, 36016, 36020,
4713 36024, 36028, 36032, 36036, 36040, 36044, 36048, 36052, 36056, 36060,
4714 36064, 36068, 36072, 36076, 36080, 36084, 36088, 36092, 36096, 36100,
4715 36104, 36108, 36112, 36116, 36120, 36124, 36128, 36132, 36136, 36140,
4716 36144, 36148, 36152, 36156, 36160, 36164, 36168, 36172, 36176, 36180,
4717 36184, 36188, 36192, 36196, 36200, 36204, 36208, 36212, 36216, 36220,
4718 36224, 36228, 36232, 36236, 36240, 36244, 36248, 36252, 36256, 36260,
4719 36264, 36268, 36272, 36276, 36280, 36284, 36288},
4720 {36288, 36292, 36296, 36300, 36304, 36308, 36312, 36316, 36320, 36324,
4721 36328, 36332, 36336, 36340, 36344, 36348, 36352, 36356, 36360, 36364,
4722 36368, 36372, 36376, 36380, 36384, 36388, 36392, 36396, 36400, 36404,
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, 36408, 36408, 36408,
4744 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408, 36408,
4745 36408, 36408, 36408, 36408, 36408, 36408, 36408}};
4746 const char32_t decomposition_data[9102] = {
4747 0, 32, 32, 776, 97, 32, 772, 50, 51,
4748 32, 769, 956, 32, 807, 49, 111, 49, 8260,
4749 52, 49, 8260, 50, 51, 8260, 52, 65, 768,
4750 65, 769, 65, 770, 65, 771, 65, 776, 65,
4751 778, 67, 807, 69, 768, 69, 769, 69, 770,
4752 69, 776, 73, 768, 73, 769, 73, 770, 73,
4753 776, 78, 771, 79, 768, 79, 769, 79, 770,
4754 79, 771, 79, 776, 85, 768, 85, 769, 85,
4755 770, 85, 776, 89, 769, 97, 768, 97, 769,
4756 97, 770, 97, 771, 97, 776, 97, 778, 99,
4757 807, 101, 768, 101, 769, 101, 770, 101, 776,
4758 105, 768, 105, 769, 105, 770, 105, 776, 110,
4759 771, 111, 768, 111, 769, 111, 770, 111, 771,
4760 111, 776, 117, 768, 117, 769, 117, 770, 117,
4761 776, 121, 769, 121, 776, 65, 772, 97, 772,
4762 65, 774, 97, 774, 65, 808, 97, 808, 67,
4763 769, 99, 769, 67, 770, 99, 770, 67, 775,
4764 99, 775, 67, 780, 99, 780, 68, 780, 100,
4765 780, 69, 772, 101, 772, 69, 774, 101, 774,
4766 69, 775, 101, 775, 69, 808, 101, 808, 69,
4767 780, 101, 780, 71, 770, 103, 770, 71, 774,
4768 103, 774, 71, 775, 103, 775, 71, 807, 103,
4769 807, 72, 770, 104, 770, 73, 771, 105, 771,
4770 73, 772, 105, 772, 73, 774, 105, 774, 73,
4771 808, 105, 808, 73, 775, 73, 74, 105, 106,
4772 74, 770, 106, 770, 75, 807, 107, 807, 76,
4773 769, 108, 769, 76, 807, 108, 807, 76, 780,
4774 108, 780, 76, 183, 108, 183, 78, 769, 110,
4775 769, 78, 807, 110, 807, 78, 780, 110, 780,
4776 700, 110, 79, 772, 111, 772, 79, 774, 111,
4777 774, 79, 779, 111, 779, 82, 769, 114, 769,
4778 82, 807, 114, 807, 82, 780, 114, 780, 83,
4779 769, 115, 769, 83, 770, 115, 770, 83, 807,
4780 115, 807, 83, 780, 115, 780, 84, 807, 116,
4781 807, 84, 780, 116, 780, 85, 771, 117, 771,
4782 85, 772, 117, 772, 85, 774, 117, 774, 85,
4783 778, 117, 778, 85, 779, 117, 779, 85, 808,
4784 117, 808, 87, 770, 119, 770, 89, 770, 121,
4785 770, 89, 776, 90, 769, 122, 769, 90, 775,
4786 122, 775, 90, 780, 122, 780, 115, 79, 795,
4787 111, 795, 85, 795, 117, 795, 68, 90, 780,
4788 68, 122, 780, 100, 122, 780, 76, 74, 76,
4789 106, 108, 106, 78, 74, 78, 106, 110, 106,
4790 65, 780, 97, 780, 73, 780, 105, 780, 79,
4791 780, 111, 780, 85, 780, 117, 780, 85, 776,
4792 772, 117, 776, 772, 85, 776, 769, 117, 776,
4793 769, 85, 776, 780, 117, 776, 780, 85, 776,
4794 768, 117, 776, 768, 65, 776, 772, 97, 776,
4795 772, 65, 775, 772, 97, 775, 772, 198, 772,
4796 230, 772, 71, 780, 103, 780, 75, 780, 107,
4797 780, 79, 808, 111, 808, 79, 808, 772, 111,
4798 808, 772, 439, 780, 658, 780, 106, 780, 68,
4799 90, 68, 122, 100, 122, 71, 769, 103, 769,
4800 78, 768, 110, 768, 65, 778, 769, 97, 778,
4801 769, 198, 769, 230, 769, 216, 769, 248, 769,
4802 65, 783, 97, 783, 65, 785, 97, 785, 69,
4803 783, 101, 783, 69, 785, 101, 785, 73, 783,
4804 105, 783, 73, 785, 105, 785, 79, 783, 111,
4805 783, 79, 785, 111, 785, 82, 783, 114, 783,
4806 82, 785, 114, 785, 85, 783, 117, 783, 85,
4807 785, 117, 785, 83, 806, 115, 806, 84, 806,
4808 116, 806, 72, 780, 104, 780, 65, 775, 97,
4809 775, 69, 807, 101, 807, 79, 776, 772, 111,
4810 776, 772, 79, 771, 772, 111, 771, 772, 79,
4811 775, 111, 775, 79, 775, 772, 111, 775, 772,
4812 89, 772, 121, 772, 104, 614, 106, 114, 633,
4813 635, 641, 119, 121, 32, 774, 32, 775, 32,
4814 778, 32, 808, 32, 771, 32, 779, 611, 108,
4815 115, 120, 661, 768, 769, 787, 776, 769, 697,
4816 32, 837, 59, 32, 769, 168, 769, 913, 769,
4817 183, 917, 769, 919, 769, 921, 769, 927, 769,
4818 933, 769, 937, 769, 953, 776, 769, 921, 776,
4819 933, 776, 945, 769, 949, 769, 951, 769, 953,
4820 769, 965, 776, 769, 953, 776, 965, 776, 959,
4821 769, 965, 769, 969, 769, 946, 952, 933, 978,
4822 769, 978, 776, 966, 960, 954, 961, 962, 920,
4823 949, 931, 1045, 768, 1045, 776, 1043, 769, 1030,
4824 776, 1050, 769, 1048, 768, 1059, 774, 1048, 774,
4825 1080, 774, 1077, 768, 1077, 776, 1075, 769, 1110,
4826 776, 1082, 769, 1080, 768, 1091, 774, 1140, 783,
4827 1141, 783, 1046, 774, 1078, 774, 1040, 774, 1072,
4828 774, 1040, 776, 1072, 776, 1045, 774, 1077, 774,
4829 1240, 776, 1241, 776, 1046, 776, 1078, 776, 1047,
4830 776, 1079, 776, 1048, 772, 1080, 772, 1048, 776,
4831 1080, 776, 1054, 776, 1086, 776, 1256, 776, 1257,
4832 776, 1069, 776, 1101, 776, 1059, 772, 1091, 772,
4833 1059, 776, 1091, 776, 1059, 779, 1091, 779, 1063,
4834 776, 1095, 776, 1067, 776, 1099, 776, 1381, 1410,
4835 1575, 1619, 1575, 1620, 1608, 1620, 1575, 1621, 1610,
4836 1620, 1575, 1652, 1608, 1652, 1735, 1652, 1610, 1652,
4837 1749, 1620, 1729, 1620, 1746, 1620, 2344, 2364, 2352,
4838 2364, 2355, 2364, 2325, 2364, 2326, 2364, 2327, 2364,
4839 2332, 2364, 2337, 2364, 2338, 2364, 2347, 2364, 2351,
4840 2364, 2503, 2494, 2503, 2519, 2465, 2492, 2466, 2492,
4841 2479, 2492, 2610, 2620, 2616, 2620, 2582, 2620, 2583,
4842 2620, 2588, 2620, 2603, 2620, 2887, 2902, 2887, 2878,
4843 2887, 2903, 2849, 2876, 2850, 2876, 2962, 3031, 3014,
4844 3006, 3015, 3006, 3014, 3031, 3142, 3158, 3263, 3285,
4845 3270, 3285, 3270, 3286, 3270, 3266, 3270, 3266, 3285,
4846 3398, 3390, 3399, 3390, 3398, 3415, 3545, 3530, 3545,
4847 3535, 3545, 3535, 3530, 3545, 3551, 3661, 3634, 3789,
4848 3762, 3755, 3737, 3755, 3745, 3851, 3906, 4023, 3916,
4849 4023, 3921, 4023, 3926, 4023, 3931, 4023, 3904, 4021,
4850 3953, 3954, 3953, 3956, 4018, 3968, 4018, 3953, 3968,
4851 4019, 3968, 4019, 3953, 3968, 3953, 3968, 3986, 4023,
4852 3996, 4023, 4001, 4023, 4006, 4023, 4011, 4023, 3984,
4853 4021, 4133, 4142, 4316, 6917, 6965, 6919, 6965, 6921,
4854 6965, 6923, 6965, 6925, 6965, 6929, 6965, 6970, 6965,
4855 6972, 6965, 6974, 6965, 6975, 6965, 6978, 6965, 65,
4856 198, 66, 68, 69, 398, 71, 72, 73, 74,
4857 75, 76, 77, 78, 79, 546, 80, 82, 84,
4858 85, 87, 97, 592, 593, 7426, 98, 100, 101,
4859 601, 603, 604, 103, 107, 109, 331, 111, 596,
4860 7446, 7447, 112, 116, 117, 7453, 623, 118, 7461,
4861 946, 947, 948, 966, 967, 105, 114, 117, 118,
4862 946, 947, 961, 966, 967, 1085, 594, 99, 597,
4863 240, 604, 102, 607, 609, 613, 616, 617, 618,
4864 7547, 669, 621, 7557, 671, 625, 624, 626, 627,
4865 628, 629, 632, 642, 643, 427, 649, 650, 7452,
4866 651, 652, 122, 656, 657, 658, 952, 65, 805,
4867 97, 805, 66, 775, 98, 775, 66, 803, 98,
4868 803, 66, 817, 98, 817, 67, 807, 769, 99,
4869 807, 769, 68, 775, 100, 775, 68, 803, 100,
4870 803, 68, 817, 100, 817, 68, 807, 100, 807,
4871 68, 813, 100, 813, 69, 772, 768, 101, 772,
4872 768, 69, 772, 769, 101, 772, 769, 69, 813,
4873 101, 813, 69, 816, 101, 816, 69, 807, 774,
4874 101, 807, 774, 70, 775, 102, 775, 71, 772,
4875 103, 772, 72, 775, 104, 775, 72, 803, 104,
4876 803, 72, 776, 104, 776, 72, 807, 104, 807,
4877 72, 814, 104, 814, 73, 816, 105, 816, 73,
4878 776, 769, 105, 776, 769, 75, 769, 107, 769,
4879 75, 803, 107, 803, 75, 817, 107, 817, 76,
4880 803, 108, 803, 76, 803, 772, 108, 803, 772,
4881 76, 817, 108, 817, 76, 813, 108, 813, 77,
4882 769, 109, 769, 77, 775, 109, 775, 77, 803,
4883 109, 803, 78, 775, 110, 775, 78, 803, 110,
4884 803, 78, 817, 110, 817, 78, 813, 110, 813,
4885 79, 771, 769, 111, 771, 769, 79, 771, 776,
4886 111, 771, 776, 79, 772, 768, 111, 772, 768,
4887 79, 772, 769, 111, 772, 769, 80, 769, 112,
4888 769, 80, 775, 112, 775, 82, 775, 114, 775,
4889 82, 803, 114, 803, 82, 803, 772, 114, 803,
4890 772, 82, 817, 114, 817, 83, 775, 115, 775,
4891 83, 803, 115, 803, 83, 769, 775, 115, 769,
4892 775, 83, 780, 775, 115, 780, 775, 83, 803,
4893 775, 115, 803, 775, 84, 775, 116, 775, 84,
4894 803, 116, 803, 84, 817, 116, 817, 84, 813,
4895 116, 813, 85, 804, 117, 804, 85, 816, 117,
4896 816, 85, 813, 117, 813, 85, 771, 769, 117,
4897 771, 769, 85, 772, 776, 117, 772, 776, 86,
4898 771, 118, 771, 86, 803, 118, 803, 87, 768,
4899 119, 768, 87, 769, 119, 769, 87, 776, 119,
4900 776, 87, 775, 119, 775, 87, 803, 119, 803,
4901 88, 775, 120, 775, 88, 776, 120, 776, 89,
4902 775, 121, 775, 90, 770, 122, 770, 90, 803,
4903 122, 803, 90, 817, 122, 817, 104, 817, 116,
4904 776, 119, 778, 121, 778, 97, 702, 383, 775,
4905 65, 803, 97, 803, 65, 777, 97, 777, 65,
4906 770, 769, 97, 770, 769, 65, 770, 768, 97,
4907 770, 768, 65, 770, 777, 97, 770, 777, 65,
4908 770, 771, 97, 770, 771, 65, 803, 770, 97,
4909 803, 770, 65, 774, 769, 97, 774, 769, 65,
4910 774, 768, 97, 774, 768, 65, 774, 777, 97,
4911 774, 777, 65, 774, 771, 97, 774, 771, 65,
4912 803, 774, 97, 803, 774, 69, 803, 101, 803,
4913 69, 777, 101, 777, 69, 771, 101, 771, 69,
4914 770, 769, 101, 770, 769, 69, 770, 768, 101,
4915 770, 768, 69, 770, 777, 101, 770, 777, 69,
4916 770, 771, 101, 770, 771, 69, 803, 770, 101,
4917 803, 770, 73, 777, 105, 777, 73, 803, 105,
4918 803, 79, 803, 111, 803, 79, 777, 111, 777,
4919 79, 770, 769, 111, 770, 769, 79, 770, 768,
4920 111, 770, 768, 79, 770, 777, 111, 770, 777,
4921 79, 770, 771, 111, 770, 771, 79, 803, 770,
4922 111, 803, 770, 79, 795, 769, 111, 795, 769,
4923 79, 795, 768, 111, 795, 768, 79, 795, 777,
4924 111, 795, 777, 79, 795, 771, 111, 795, 771,
4925 79, 795, 803, 111, 795, 803, 85, 803, 117,
4926 803, 85, 777, 117, 777, 85, 795, 769, 117,
4927 795, 769, 85, 795, 768, 117, 795, 768, 85,
4928 795, 777, 117, 795, 777, 85, 795, 771, 117,
4929 795, 771, 85, 795, 803, 117, 795, 803, 89,
4930 768, 121, 768, 89, 803, 121, 803, 89, 777,
4931 121, 777, 89, 771, 121, 771, 945, 787, 945,
4932 788, 945, 787, 768, 945, 788, 768, 945, 787,
4933 769, 945, 788, 769, 945, 787, 834, 945, 788,
4934 834, 913, 787, 913, 788, 913, 787, 768, 913,
4935 788, 768, 913, 787, 769, 913, 788, 769, 913,
4936 787, 834, 913, 788, 834, 949, 787, 949, 788,
4937 949, 787, 768, 949, 788, 768, 949, 787, 769,
4938 949, 788, 769, 917, 787, 917, 788, 917, 787,
4939 768, 917, 788, 768, 917, 787, 769, 917, 788,
4940 769, 951, 787, 951, 788, 951, 787, 768, 951,
4941 788, 768, 951, 787, 769, 951, 788, 769, 951,
4942 787, 834, 951, 788, 834, 919, 787, 919, 788,
4943 919, 787, 768, 919, 788, 768, 919, 787, 769,
4944 919, 788, 769, 919, 787, 834, 919, 788, 834,
4945 953, 787, 953, 788, 953, 787, 768, 953, 788,
4946 768, 953, 787, 769, 953, 788, 769, 953, 787,
4947 834, 953, 788, 834, 921, 787, 921, 788, 921,
4948 787, 768, 921, 788, 768, 921, 787, 769, 921,
4949 788, 769, 921, 787, 834, 921, 788, 834, 959,
4950 787, 959, 788, 959, 787, 768, 959, 788, 768,
4951 959, 787, 769, 959, 788, 769, 927, 787, 927,
4952 788, 927, 787, 768, 927, 788, 768, 927, 787,
4953 769, 927, 788, 769, 965, 787, 965, 788, 965,
4954 787, 768, 965, 788, 768, 965, 787, 769, 965,
4955 788, 769, 965, 787, 834, 965, 788, 834, 933,
4956 788, 933, 788, 768, 933, 788, 769, 933, 788,
4957 834, 969, 787, 969, 788, 969, 787, 768, 969,
4958 788, 768, 969, 787, 769, 969, 788, 769, 969,
4959 787, 834, 969, 788, 834, 937, 787, 937, 788,
4960 937, 787, 768, 937, 788, 768, 937, 787, 769,
4961 937, 788, 769, 937, 787, 834, 937, 788, 834,
4962 945, 768, 945, 769, 949, 768, 949, 769, 951,
4963 768, 951, 769, 953, 768, 953, 769, 959, 768,
4964 959, 769, 965, 768, 965, 769, 969, 768, 969,
4965 769, 945, 787, 837, 945, 788, 837, 945, 787,
4966 768, 837, 945, 788, 768, 837, 945, 787, 769,
4967 837, 945, 788, 769, 837, 945, 787, 834, 837,
4968 945, 788, 834, 837, 913, 787, 837, 913, 788,
4969 837, 913, 787, 768, 837, 913, 788, 768, 837,
4970 913, 787, 769, 837, 913, 788, 769, 837, 913,
4971 787, 834, 837, 913, 788, 834, 837, 951, 787,
4972 837, 951, 788, 837, 951, 787, 768, 837, 951,
4973 788, 768, 837, 951, 787, 769, 837, 951, 788,
4974 769, 837, 951, 787, 834, 837, 951, 788, 834,
4975 837, 919, 787, 837, 919, 788, 837, 919, 787,
4976 768, 837, 919, 788, 768, 837, 919, 787, 769,
4977 837, 919, 788, 769, 837, 919, 787, 834, 837,
4978 919, 788, 834, 837, 969, 787, 837, 969, 788,
4979 837, 969, 787, 768, 837, 969, 788, 768, 837,
4980 969, 787, 769, 837, 969, 788, 769, 837, 969,
4981 787, 834, 837, 969, 788, 834, 837, 937, 787,
4982 837, 937, 788, 837, 937, 787, 768, 837, 937,
4983 788, 768, 837, 937, 787, 769, 837, 937, 788,
4984 769, 837, 937, 787, 834, 837, 937, 788, 834,
4985 837, 945, 774, 945, 772, 945, 768, 837, 945,
4986 837, 945, 769, 837, 945, 834, 945, 834, 837,
4987 913, 774, 913, 772, 913, 768, 913, 769, 913,
4988 837, 32, 787, 953, 32, 787, 32, 834, 168,
4989 834, 951, 768, 837, 951, 837, 951, 769, 837,
4990 951, 834, 951, 834, 837, 917, 768, 917, 769,
4991 919, 768, 919, 769, 919, 837, 8127, 768, 8127,
4992 769, 8127, 834, 953, 774, 953, 772, 953, 776,
4993 768, 953, 776, 769, 953, 834, 953, 776, 834,
4994 921, 774, 921, 772, 921, 768, 921, 769, 8190,
4995 768, 8190, 769, 8190, 834, 965, 774, 965, 772,
4996 965, 776, 768, 965, 776, 769, 961, 787, 961,
4997 788, 965, 834, 965, 776, 834, 933, 774, 933,
4998 772, 933, 768, 933, 769, 929, 788, 168, 768,
4999 168, 769, 96, 969, 768, 837, 969, 837, 969,
5000 769, 837, 969, 834, 969, 834, 837, 927, 768,
5001 927, 769, 937, 768, 937, 769, 937, 837, 180,
5002 32, 788, 8194, 8195, 32, 32, 32, 32, 32,
5003 32, 32, 32, 32, 8208, 32, 819, 46, 46,
5004 46, 46, 46, 46, 32, 8242, 8242, 8242, 8242,
5005 8242, 8245, 8245, 8245, 8245, 8245, 33, 33, 32,
5006 773, 63, 63, 63, 33, 33, 63, 8242, 8242,
5007 8242, 8242, 32, 48, 105, 52, 53, 54, 55,
5008 56, 57, 43, 8722, 61, 40, 41, 110, 48,
5009 49, 50, 51, 52, 53, 54, 55, 56, 57,
5010 43, 8722, 61, 40, 41, 97, 101, 111, 120,
5011 601, 104, 107, 108, 109, 110, 112, 115, 116,
5012 82, 115, 97, 47, 99, 97, 47, 115, 67,
5013 176, 67, 99, 47, 111, 99, 47, 117, 400,
5014 176, 70, 103, 72, 72, 72, 104, 295, 73,
5015 73, 76, 108, 78, 78, 111, 80, 81, 82,
5016 82, 82, 83, 77, 84, 69, 76, 84, 77,
5017 90, 937, 90, 75, 65, 778, 66, 67, 101,
5018 69, 70, 77, 111, 1488, 1489, 1490, 1491, 105,
5019 70, 65, 88, 960, 947, 915, 928, 8721, 68,
5020 100, 101, 105, 106, 49, 8260, 55, 49, 8260,
5021 57, 49, 8260, 49, 48, 49, 8260, 51, 50,
5022 8260, 51, 49, 8260, 53, 50, 8260, 53, 51,
5023 8260, 53, 52, 8260, 53, 49, 8260, 54, 53,
5024 8260, 54, 49, 8260, 56, 51, 8260, 56, 53,
5025 8260, 56, 55, 8260, 56, 49, 8260, 73, 73,
5026 73, 73, 73, 73, 73, 86, 86, 86, 73,
5027 86, 73, 73, 86, 73, 73, 73, 73, 88,
5028 88, 88, 73, 88, 73, 73, 76, 67, 68,
5029 77, 105, 105, 105, 105, 105, 105, 105, 118,
5030 118, 118, 105, 118, 105, 105, 118, 105, 105,
5031 105, 105, 120, 120, 120, 105, 120, 105, 105,
5032 108, 99, 100, 109, 48, 8260, 51, 8592, 824,
5033 8594, 824, 8596, 824, 8656, 824, 8660, 824, 8658,
5034 824, 8707, 824, 8712, 824, 8715, 824, 8739, 824,
5035 8741, 824, 8747, 8747, 8747, 8747, 8747, 8750, 8750,
5036 8750, 8750, 8750, 8764, 824, 8771, 824, 8773, 824,
5037 8776, 824, 61, 824, 8801, 824, 8781, 824, 60,
5038 824, 62, 824, 8804, 824, 8805, 824, 8818, 824,
5039 8819, 824, 8822, 824, 8823, 824, 8826, 824, 8827,
5040 824, 8834, 824, 8835, 824, 8838, 824, 8839, 824,
5041 8866, 824, 8872, 824, 8873, 824, 8875, 824, 8828,
5042 824, 8829, 824, 8849, 824, 8850, 824, 8882, 824,
5043 8883, 824, 8884, 824, 8885, 824, 12296, 12297, 49,
5044 50, 51, 52, 53, 54, 55, 56, 57, 49,
5045 48, 49, 49, 49, 50, 49, 51, 49, 52,
5046 49, 53, 49, 54, 49, 55, 49, 56, 49,
5047 57, 50, 48, 40, 49, 41, 40, 50, 41,
5048 40, 51, 41, 40, 52, 41, 40, 53, 41,
5049 40, 54, 41, 40, 55, 41, 40, 56, 41,
5050 40, 57, 41, 40, 49, 48, 41, 40, 49,
5051 49, 41, 40, 49, 50, 41, 40, 49, 51,
5052 41, 40, 49, 52, 41, 40, 49, 53, 41,
5053 40, 49, 54, 41, 40, 49, 55, 41, 40,
5054 49, 56, 41, 40, 49, 57, 41, 40, 50,
5055 48, 41, 49, 46, 50, 46, 51, 46, 52,
5056 46, 53, 46, 54, 46, 55, 46, 56, 46,
5057 57, 46, 49, 48, 46, 49, 49, 46, 49,
5058 50, 46, 49, 51, 46, 49, 52, 46, 49,
5059 53, 46, 49, 54, 46, 49, 55, 46, 49,
5060 56, 46, 49, 57, 46, 50, 48, 46, 40,
5061 97, 41, 40, 98, 41, 40, 99, 41, 40,
5062 100, 41, 40, 101, 41, 40, 102, 41, 40,
5063 103, 41, 40, 104, 41, 40, 105, 41, 40,
5064 106, 41, 40, 107, 41, 40, 108, 41, 40,
5065 109, 41, 40, 110, 41, 40, 111, 41, 40,
5066 112, 41, 40, 113, 41, 40, 114, 41, 40,
5067 115, 41, 40, 116, 41, 40, 117, 41, 40,
5068 118, 41, 40, 119, 41, 40, 120, 41, 40,
5069 121, 41, 40, 122, 41, 65, 66, 67, 68,
5070 69, 70, 71, 72, 73, 74, 75, 76, 77,
5071 78, 79, 80, 81, 82, 83, 84, 85, 86,
5072 87, 88, 89, 90, 97, 98, 99, 100, 101,
5073 102, 103, 104, 105, 106, 107, 108, 109, 110,
5074 111, 112, 113, 114, 115, 116, 117, 118, 119,
5075 120, 121, 122, 48, 8747, 8747, 8747, 8747, 58,
5076 58, 61, 61, 61, 61, 61, 61, 10973, 824,
5077 106, 86, 11617, 27597, 40863, 19968, 20008, 20022, 20031,
5078 20057, 20101, 20108, 20128, 20154, 20799, 20837, 20843, 20866,
5079 20886, 20907, 20960, 20981, 20992, 21147, 21241, 21269, 21274,
5080 21304, 21313, 21340, 21353, 21378, 21430, 21448, 21475, 22231,
5081 22303, 22763, 22786, 22794, 22805, 22823, 22899, 23376, 23424,
5082 23544, 23567, 23586, 23608, 23662, 23665, 24027, 24037, 24049,
5083 24062, 24178, 24186, 24191, 24308, 24318, 24331, 24339, 24400,
5084 24417, 24435, 24515, 25096, 25142, 25163, 25903, 25908, 25991,
5085 26007, 26020, 26041, 26080, 26085, 26352, 26376, 26408, 27424,
5086 27490, 27513, 27571, 27595, 27604, 27611, 27663, 27668, 27700,
5087 28779, 29226, 29238, 29243, 29247, 29255, 29273, 29275, 29356,
5088 29572, 29577, 29916, 29926, 29976, 29983, 29992, 30000, 30091,
5089 30098, 30326, 30333, 30382, 30399, 30446, 30683, 30690, 30707,
5090 31034, 31160, 31166, 31348, 31435, 31481, 31859, 31992, 32566,
5091 32593, 32650, 32701, 32769, 32780, 32786, 32819, 32895, 32905,
5092 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390, 33394,
5093 33400, 34381, 34411, 34880, 34892, 34915, 35198, 35211, 35282,
5094 35328, 35895, 35910, 35925, 35960, 35997, 36196, 36208, 36275,
5095 36523, 36554, 36763, 36784, 36789, 37009, 37193, 37318, 37324,
5096 37329, 38263, 38272, 38428, 38582, 38585, 38632, 38737, 38750,
5097 38754, 38761, 38859, 38893, 38899, 38913, 39080, 39131, 39135,
5098 39318, 39321, 39340, 39592, 39640, 39647, 39717, 39727, 39730,
5099 39740, 39770, 40165, 40565, 40575, 40613, 40635, 40643, 40653,
5100 40657, 40697, 40701, 40718, 40723, 40736, 40763, 40778, 40786,
5101 40845, 40860, 40864, 32, 12306, 21313, 21316, 21317, 12363,
5102 12441, 12365, 12441, 12367, 12441, 12369, 12441, 12371, 12441,
5103 12373, 12441, 12375, 12441, 12377, 12441, 12379, 12441, 12381,
5104 12441, 12383, 12441, 12385, 12441, 12388, 12441, 12390, 12441,
5105 12392, 12441, 12399, 12441, 12399, 12442, 12402, 12441, 12402,
5106 12442, 12405, 12441, 12405, 12442, 12408, 12441, 12408, 12442,
5107 12411, 12441, 12411, 12442, 12358, 12441, 32, 12441, 32,
5108 12442, 12445, 12441, 12424, 12426, 12459, 12441, 12461, 12441,
5109 12463, 12441, 12465, 12441, 12467, 12441, 12469, 12441, 12471,
5110 12441, 12473, 12441, 12475, 12441, 12477, 12441, 12479, 12441,
5111 12481, 12441, 12484, 12441, 12486, 12441, 12488, 12441, 12495,
5112 12441, 12495, 12442, 12498, 12441, 12498, 12442, 12501, 12441,
5113 12501, 12442, 12504, 12441, 12504, 12442, 12507, 12441, 12507,
5114 12442, 12454, 12441, 12527, 12441, 12528, 12441, 12529, 12441,
5115 12530, 12441, 12541, 12441, 12467, 12488, 4352, 4353, 4522,
5116 4354, 4524, 4525, 4355, 4356, 4357, 4528, 4529, 4530,
5117 4531, 4532, 4533, 4378, 4358, 4359, 4360, 4385, 4361,
5118 4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370,
5119 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457,
5120 4458, 4459, 4460, 4461, 4462, 4463, 4464, 4465, 4466,
5121 4467, 4468, 4469, 4448, 4372, 4373, 4551, 4552, 4556,
5122 4558, 4563, 4567, 4569, 4380, 4573, 4575, 4381, 4382,
5123 4384, 4386, 4387, 4391, 4393, 4395, 4396, 4397, 4398,
5124 4399, 4402, 4406, 4416, 4423, 4428, 4593, 4594, 4439,
5125 4440, 4441, 4484, 4485, 4488, 4497, 4498, 4500, 4510,
5126 4513, 19968, 20108, 19977, 22235, 19978, 20013, 19979, 30002,
5127 20057, 19993, 19969, 22825, 22320, 20154, 40, 4352, 41,
5128 40, 4354, 41, 40, 4355, 41, 40, 4357, 41,
5129 40, 4358, 41, 40, 4359, 41, 40, 4361, 41,
5130 40, 4363, 41, 40, 4364, 41, 40, 4366, 41,
5131 40, 4367, 41, 40, 4368, 41, 40, 4369, 41,
5132 40, 4370, 41, 40, 4352, 4449, 41, 40, 4354,
5133 4449, 41, 40, 4355, 4449, 41, 40, 4357, 4449,
5134 41, 40, 4358, 4449, 41, 40, 4359, 4449, 41,
5135 40, 4361, 4449, 41, 40, 4363, 4449, 41, 40,
5136 4364, 4449, 41, 40, 4366, 4449, 41, 40, 4367,
5137 4449, 41, 40, 4368, 4449, 41, 40, 4369, 4449,
5138 41, 40, 4370, 4449, 41, 40, 4364, 4462, 41,
5139 40, 4363, 4457, 4364, 4453, 4523, 41, 40, 4363,
5140 4457, 4370, 4462, 41, 40, 19968, 41, 40, 20108,
5141 41, 40, 19977, 41, 40, 22235, 41, 40, 20116,
5142 41, 40, 20845, 41, 40, 19971, 41, 40, 20843,
5143 41, 40, 20061, 41, 40, 21313, 41, 40, 26376,
5144 41, 40, 28779, 41, 40, 27700, 41, 40, 26408,
5145 41, 40, 37329, 41, 40, 22303, 41, 40, 26085,
5146 41, 40, 26666, 41, 40, 26377, 41, 40, 31038,
5147 41, 40, 21517, 41, 40, 29305, 41, 40, 36001,
5148 41, 40, 31069, 41, 40, 21172, 41, 40, 20195,
5149 41, 40, 21628, 41, 40, 23398, 41, 40, 30435,
5150 41, 40, 20225, 41, 40, 36039, 41, 40, 21332,
5151 41, 40, 31085, 41, 40, 20241, 41, 40, 33258,
5152 41, 40, 33267, 41, 21839, 24188, 25991, 31631, 80,
5153 84, 69, 50, 49, 50, 50, 50, 51, 50,
5154 52, 50, 53, 50, 54, 50, 55, 50, 56,
5155 50, 57, 51, 48, 51, 49, 51, 50, 51,
5156 51, 51, 52, 51, 53, 4352, 4354, 4355, 4357,
5157 4358, 4359, 4361, 4363, 4364, 4366, 4367, 4368, 4369,
5158 4370, 4352, 4449, 4354, 4449, 4355, 4449, 4357, 4449,
5159 4358, 4449, 4359, 4449, 4361, 4449, 4363, 4449, 4364,
5160 4449, 4366, 4449, 4367, 4449, 4368, 4449, 4369, 4449,
5161 4370, 4449, 4366, 4449, 4535, 4352, 4457, 4364, 4462,
5162 4363, 4468, 4363, 4462, 19968, 20108, 19977, 22235, 20116,
5163 20845, 19971, 20843, 20061, 21313, 26376, 28779, 27700, 26408,
5164 37329, 22303, 26085, 26666, 26377, 31038, 21517, 29305, 36001,
5165 31069, 21172, 31192, 30007, 22899, 36969, 20778, 21360, 27880,
5166 38917, 20241, 20889, 27491, 19978, 20013, 19979, 24038, 21491,
5167 21307, 23447, 23398, 30435, 20225, 36039, 21332, 22812, 51,
5168 54, 51, 55, 51, 56, 51, 57, 52, 48,
5169 52, 49, 52, 50, 52, 51, 52, 52, 52,
5170 53, 52, 54, 52, 55, 52, 56, 52, 57,
5171 53, 48, 49, 26376, 50, 26376, 51, 26376, 52,
5172 26376, 53, 26376, 54, 26376, 55, 26376, 56, 26376,
5173 57, 26376, 49, 48, 26376, 49, 49, 26376, 49,
5174 50, 26376, 72, 103, 101, 114, 103, 101, 86,
5175 76, 84, 68, 12450, 12452, 12454, 12456, 12458, 12459,
5176 12461, 12463, 12465, 12467, 12469, 12471, 12473, 12475, 12477,
5177 12479, 12481, 12484, 12486, 12488, 12490, 12491, 12492, 12493,
5178 12494, 12495, 12498, 12501, 12504, 12507, 12510, 12511, 12512,
5179 12513, 12514, 12516, 12518, 12520, 12521, 12522, 12523, 12524,
5180 12525, 12527, 12528, 12529, 12530, 20196, 21644, 12450, 12495,
5181 12442, 12540, 12488, 12450, 12523, 12501, 12449, 12450, 12531,
5182 12504, 12442, 12450, 12450, 12540, 12523, 12452, 12491, 12531,
5183 12463, 12441, 12452, 12531, 12481, 12454, 12457, 12531, 12456,
5184 12473, 12463, 12540, 12488, 12441, 12456, 12540, 12459, 12540,
5185 12458, 12531, 12473, 12458, 12540, 12512, 12459, 12452, 12522,
5186 12459, 12521, 12483, 12488, 12459, 12525, 12522, 12540, 12459,
5187 12441, 12525, 12531, 12459, 12441, 12531, 12510, 12461, 12441,
5188 12459, 12441, 12461, 12441, 12491, 12540, 12461, 12517, 12522,
5189 12540, 12461, 12441, 12523, 12479, 12441, 12540, 12461, 12525,
5190 12461, 12525, 12463, 12441, 12521, 12512, 12461, 12525, 12513,
5191 12540, 12488, 12523, 12461, 12525, 12527, 12483, 12488, 12463,
5192 12441, 12521, 12512, 12463, 12441, 12521, 12512, 12488, 12531,
5193 12463, 12523, 12475, 12441, 12452, 12525, 12463, 12525, 12540,
5194 12493, 12465, 12540, 12473, 12467, 12523, 12490, 12467, 12540,
5195 12507, 12442, 12469, 12452, 12463, 12523, 12469, 12531, 12481,
5196 12540, 12512, 12471, 12522, 12531, 12463, 12441, 12475, 12531,
5197 12481, 12475, 12531, 12488, 12479, 12441, 12540, 12473, 12486,
5198 12441, 12471, 12488, 12441, 12523, 12488, 12531, 12490, 12494,
5199 12494, 12483, 12488, 12495, 12452, 12484, 12495, 12442, 12540,
5200 12475, 12531, 12488, 12495, 12442, 12540, 12484, 12495, 12441,
5201 12540, 12524, 12523, 12498, 12442, 12450, 12473, 12488, 12523,
5202 12498, 12442, 12463, 12523, 12498, 12442, 12467, 12498, 12441,
5203 12523, 12501, 12449, 12521, 12483, 12488, 12441, 12501, 12451,
5204 12540, 12488, 12501, 12441, 12483, 12471, 12455, 12523, 12501,
5205 12521, 12531, 12504, 12463, 12479, 12540, 12523, 12504, 12442,
5206 12477, 12504, 12442, 12491, 12498, 12504, 12523, 12484, 12504,
5207 12442, 12531, 12473, 12504, 12442, 12540, 12471, 12441, 12504,
5208 12441, 12540, 12479, 12507, 12442, 12452, 12531, 12488, 12507,
5209 12441, 12523, 12488, 12507, 12531, 12507, 12442, 12531, 12488,
5210 12441, 12507, 12540, 12523, 12507, 12540, 12531, 12510, 12452,
5211 12463, 12525, 12510, 12452, 12523, 12510, 12483, 12495, 12510,
5212 12523, 12463, 12510, 12531, 12471, 12519, 12531, 12511, 12463,
5213 12525, 12531, 12511, 12522, 12511, 12522, 12495, 12441, 12540,
5214 12523, 12513, 12459, 12441, 12513, 12459, 12441, 12488, 12531,
5215 12513, 12540, 12488, 12523, 12516, 12540, 12488, 12441, 12516,
5216 12540, 12523, 12518, 12450, 12531, 12522, 12483, 12488, 12523,
5217 12522, 12521, 12523, 12498, 12442, 12540, 12523, 12540, 12501,
5218 12441, 12523, 12524, 12512, 12524, 12531, 12488, 12465, 12441,
5219 12531, 12527, 12483, 12488, 48, 28857, 49, 28857, 50,
5220 28857, 51, 28857, 52, 28857, 53, 28857, 54, 28857,
5221 55, 28857, 56, 28857, 57, 28857, 49, 48, 28857,
5222 49, 49, 28857, 49, 50, 28857, 49, 51, 28857,
5223 49, 52, 28857, 49, 53, 28857, 49, 54, 28857,
5224 49, 55, 28857, 49, 56, 28857, 49, 57, 28857,
5225 50, 48, 28857, 50, 49, 28857, 50, 50, 28857,
5226 50, 51, 28857, 50, 52, 28857, 104, 80, 97,
5227 100, 97, 65, 85, 98, 97, 114, 111, 86,
5228 112, 99, 100, 109, 100, 109, 50, 100, 109,
5229 51, 73, 85, 24179, 25104, 26157, 21644, 22823, 27491,
5230 26126, 27835, 26666, 24335, 20250, 31038, 112, 65, 110,
5231 65, 956, 65, 109, 65, 107, 65, 75, 66,
5232 77, 66, 71, 66, 99, 97, 108, 107, 99,
5233 97, 108, 112, 70, 110, 70, 956, 70, 956,
5234 103, 109, 103, 107, 103, 72, 122, 107, 72,
5235 122, 77, 72, 122, 71, 72, 122, 84, 72,
5236 122, 956, 108, 109, 108, 100, 108, 107, 108,
5237 102, 109, 110, 109, 956, 109, 109, 109, 99,
5238 109, 107, 109, 109, 109, 50, 99, 109, 50,
5239 109, 50, 107, 109, 50, 109, 109, 51, 99,
5240 109, 51, 109, 51, 107, 109, 51, 109, 8725,
5241 115, 109, 8725, 115, 50, 80, 97, 107, 80,
5242 97, 77, 80, 97, 71, 80, 97, 114, 97,
5243 100, 114, 97, 100, 8725, 115, 114, 97, 100,
5244 8725, 115, 50, 112, 115, 110, 115, 956, 115,
5245 109, 115, 112, 86, 110, 86, 956, 86, 109,
5246 86, 107, 86, 77, 86, 112, 87, 110, 87,
5247 956, 87, 109, 87, 107, 87, 77, 87, 107,
5248 937, 77, 937, 97, 46, 109, 46, 66, 113,
5249 99, 99, 99, 100, 67, 8725, 107, 103, 67,
5250 111, 46, 100, 66, 71, 121, 104, 97, 72,
5251 80, 105, 110, 75, 75, 75, 77, 107, 116,
5252 108, 109, 108, 110, 108, 111, 103, 108, 120,
5253 109, 98, 109, 105, 108, 109, 111, 108, 80,
5254 72, 112, 46, 109, 46, 80, 80, 77, 80,
5255 82, 115, 114, 83, 118, 87, 98, 86, 8725,
5256 109, 65, 8725, 109, 49, 26085, 50, 26085, 51,
5257 26085, 52, 26085, 53, 26085, 54, 26085, 55, 26085,
5258 56, 26085, 57, 26085, 49, 48, 26085, 49, 49,
5259 26085, 49, 50, 26085, 49, 51, 26085, 49, 52,
5260 26085, 49, 53, 26085, 49, 54, 26085, 49, 55,
5261 26085, 49, 56, 26085, 49, 57, 26085, 50, 48,
5262 26085, 50, 49, 26085, 50, 50, 26085, 50, 51,
5263 26085, 50, 52, 26085, 50, 53, 26085, 50, 54,
5264 26085, 50, 55, 26085, 50, 56, 26085, 50, 57,
5265 26085, 51, 48, 26085, 51, 49, 26085, 103, 97,
5266 108, 1098, 1100, 42863, 67, 70, 81, 294, 339,
5267 42791, 43831, 619, 43858, 653, 35912, 26356, 36554, 36040,
5268 28369, 20018, 21477, 40860, 40860, 22865, 37329, 21895, 22856,
5269 25078, 30313, 32645, 34367, 34746, 35064, 37007, 27138, 27931,
5270 28889, 29662, 33853, 37226, 39409, 20098, 21365, 27396, 29211,
5271 34349, 40478, 23888, 28651, 34253, 35172, 25289, 33240, 34847,
5272 24266, 26391, 28010, 29436, 37070, 20358, 20919, 21214, 25796,
5273 27347, 29200, 30439, 32769, 34310, 34396, 36335, 38706, 39791,
5274 40442, 30860, 31103, 32160, 33737, 37636, 40575, 35542, 22751,
5275 24324, 31840, 32894, 29282, 30922, 36034, 38647, 22744, 23650,
5276 27155, 28122, 28431, 32047, 32311, 38475, 21202, 32907, 20956,
5277 20940, 31260, 32190, 33777, 38517, 35712, 25295, 27138, 35582,
5278 20025, 23527, 24594, 29575, 30064, 21271, 30971, 20415, 24489,
5279 19981, 27852, 25976, 32034, 21443, 22622, 30465, 33865, 35498,
5280 27578, 36784, 27784, 25342, 33509, 25504, 30053, 20142, 20841,
5281 20937, 26753, 31975, 33391, 35538, 37327, 21237, 21570, 22899,
5282 24300, 26053, 28670, 31018, 38317, 39530, 40599, 40654, 21147,
5283 26310, 27511, 36706, 24180, 24976, 25088, 25754, 28451, 29001,
5284 29833, 31178, 32244, 32879, 36646, 34030, 36899, 37706, 21015,
5285 21155, 21693, 28872, 35010, 35498, 24265, 24565, 25467, 27566,
5286 31806, 29557, 20196, 22265, 23527, 23994, 24604, 29618, 29801,
5287 32666, 32838, 37428, 38646, 38728, 38936, 20363, 31150, 37300,
5288 38584, 24801, 20102, 20698, 23534, 23615, 26009, 27138, 29134,
5289 30274, 34044, 36988, 40845, 26248, 38446, 21129, 26491, 26611,
5290 27969, 28316, 29705, 30041, 30827, 32016, 39006, 20845, 25134,
5291 38520, 20523, 23833, 28138, 36650, 24459, 24900, 26647, 29575,
5292 38534, 21033, 21519, 23653, 26131, 26446, 26792, 27877, 29702,
5293 30178, 32633, 35023, 35041, 37324, 38626, 21311, 28346, 21533,
5294 29136, 29848, 34298, 38563, 40023, 40607, 26519, 28107, 33256,
5295 31435, 31520, 31890, 29376, 28825, 35672, 20160, 33590, 21050,
5296 20999, 24230, 25299, 31958, 23429, 27934, 26292, 36667, 34892,
5297 38477, 35211, 24275, 20800, 21952, 22618, 26228, 20958, 29482,
5298 30410, 31036, 31070, 31077, 31119, 38742, 31934, 32701, 34322,
5299 35576, 36920, 37117, 39151, 39164, 39208, 40372, 37086, 38583,
5300 20398, 20711, 20813, 21193, 21220, 21329, 21917, 22022, 22120,
5301 22592, 22696, 23652, 23662, 24724, 24936, 24974, 25074, 25935,
5302 26082, 26257, 26757, 28023, 28186, 28450, 29038, 29227, 29730,
5303 30865, 31038, 31049, 31048, 31056, 31062, 31069, 31117, 31118,
5304 31296, 31361, 31680, 32244, 32265, 32321, 32626, 32773, 33261,
5305 33401, 33401, 33879, 35088, 35222, 35585, 35641, 36051, 36104,
5306 36790, 36920, 38627, 38911, 38971, 24693, 148206, 33304, 20006,
5307 20917, 20840, 20352, 20805, 20864, 21191, 21242, 21917, 21845,
5308 21913, 21986, 22618, 22707, 22852, 22868, 23138, 23336, 24274,
5309 24281, 24425, 24493, 24792, 24910, 24840, 24974, 24928, 25074,
5310 25140, 25540, 25628, 25682, 25942, 26228, 26391, 26395, 26454,
5311 27513, 27578, 27969, 28379, 28363, 28450, 28702, 29038, 30631,
5312 29237, 29359, 29482, 29809, 29958, 30011, 30237, 30239, 30410,
5313 30427, 30452, 30538, 30528, 30924, 31409, 31680, 31867, 32091,
5314 32244, 32574, 32773, 33618, 33775, 34681, 35137, 35206, 35222,
5315 35519, 35576, 35531, 35585, 35582, 35565, 35641, 35722, 36104,
5316 36664, 36978, 37273, 37494, 38524, 38627, 38742, 38875, 38911,
5317 38923, 38971, 39698, 40860, 141386, 141380, 144341, 15261, 16408,
5318 16441, 152137, 154832, 163539, 40771, 40846, 102, 102, 102,
5319 105, 102, 108, 102, 102, 105, 102, 102, 108,
5320 115, 116, 115, 116, 1396, 1398, 1396, 1381, 1396,
5321 1387, 1406, 1398, 1396, 1389, 1497, 1460, 1522, 1463,
5322 1506, 1488, 1491, 1492, 1499, 1500, 1501, 1512, 1514,
5323 43, 1513, 1473, 1513, 1474, 1513, 1468, 1473, 1513,
5324 1468, 1474, 1488, 1463, 1488, 1464, 1488, 1468, 1489,
5325 1468, 1490, 1468, 1491, 1468, 1492, 1468, 1493, 1468,
5326 1494, 1468, 1496, 1468, 1497, 1468, 1498, 1468, 1499,
5327 1468, 1500, 1468, 1502, 1468, 1504, 1468, 1505, 1468,
5328 1507, 1468, 1508, 1468, 1510, 1468, 1511, 1468, 1512,
5329 1468, 1513, 1468, 1514, 1468, 1493, 1465, 1489, 1471,
5330 1499, 1471, 1508, 1471, 1488, 1500, 1649, 1649, 1659,
5331 1659, 1659, 1659, 1662, 1662, 1662, 1662, 1664, 1664,
5332 1664, 1664, 1658, 1658, 1658, 1658, 1663, 1663, 1663,
5333 1663, 1657, 1657, 1657, 1657, 1700, 1700, 1700, 1700,
5334 1702, 1702, 1702, 1702, 1668, 1668, 1668, 1668, 1667,
5335 1667, 1667, 1667, 1670, 1670, 1670, 1670, 1671, 1671,
5336 1671, 1671, 1677, 1677, 1676, 1676, 1678, 1678, 1672,
5337 1672, 1688, 1688, 1681, 1681, 1705, 1705, 1705, 1705,
5338 1711, 1711, 1711, 1711, 1715, 1715, 1715, 1715, 1713,
5339 1713, 1713, 1713, 1722, 1722, 1723, 1723, 1723, 1723,
5340 1749, 1620, 1749, 1620, 1729, 1729, 1729, 1729, 1726,
5341 1726, 1726, 1726, 1746, 1746, 1746, 1620, 1746, 1620,
5342 1709, 1709, 1709, 1709, 1735, 1735, 1734, 1734, 1736,
5343 1736, 1735, 1652, 1739, 1739, 1733, 1733, 1737, 1737,
5344 1744, 1744, 1744, 1744, 1609, 1609, 1610, 1620, 1575,
5345 1610, 1620, 1575, 1610, 1620, 1749, 1610, 1620, 1749,
5346 1610, 1620, 1608, 1610, 1620, 1608, 1610, 1620, 1735,
5347 1610, 1620, 1735, 1610, 1620, 1734, 1610, 1620, 1734,
5348 1610, 1620, 1736, 1610, 1620, 1736, 1610, 1620, 1744,
5349 1610, 1620, 1744, 1610, 1620, 1744, 1610, 1620, 1609,
5350 1610, 1620, 1609, 1610, 1620, 1609, 1740, 1740, 1740,
5351 1740, 1610, 1620, 1580, 1610, 1620, 1581, 1610, 1620,
5352 1605, 1610, 1620, 1609, 1610, 1620, 1610, 1576, 1580,
5353 1576, 1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576,
5354 1610, 1578, 1580, 1578, 1581, 1578, 1582, 1578, 1605,
5355 1578, 1609, 1578, 1610, 1579, 1580, 1579, 1605, 1579,
5356 1609, 1579, 1610, 1580, 1581, 1580, 1605, 1581, 1580,
5357 1581, 1605, 1582, 1580, 1582, 1581, 1582, 1605, 1587,
5358 1580, 1587, 1581, 1587, 1582, 1587, 1605, 1589, 1581,
5359 1589, 1605, 1590, 1580, 1590, 1581, 1590, 1582, 1590,
5360 1605, 1591, 1581, 1591, 1605, 1592, 1605, 1593, 1580,
5361 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601,
5362 1581, 1601, 1582, 1601, 1605, 1601, 1609, 1601, 1610,
5363 1602, 1581, 1602, 1605, 1602, 1609, 1602, 1610, 1603,
5364 1575, 1603, 1580, 1603, 1581, 1603, 1582, 1603, 1604,
5365 1603, 1605, 1603, 1609, 1603, 1610, 1604, 1580, 1604,
5366 1581, 1604, 1582, 1604, 1605, 1604, 1609, 1604, 1610,
5367 1605, 1580, 1605, 1581, 1605, 1582, 1605, 1605, 1605,
5368 1609, 1605, 1610, 1606, 1580, 1606, 1581, 1606, 1582,
5369 1606, 1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607,
5370 1605, 1607, 1609, 1607, 1610, 1610, 1580, 1610, 1581,
5371 1610, 1582, 1610, 1605, 1610, 1609, 1610, 1610, 1584,
5372 1648, 1585, 1648, 1609, 1648, 32, 1612, 1617, 32,
5373 1613, 1617, 32, 1614, 1617, 32, 1615, 1617, 32,
5374 1616, 1617, 32, 1617, 1648, 1610, 1620, 1585, 1610,
5375 1620, 1586, 1610, 1620, 1605, 1610, 1620, 1606, 1610,
5376 1620, 1609, 1610, 1620, 1610, 1576, 1585, 1576, 1586,
5377 1576, 1605, 1576, 1606, 1576, 1609, 1576, 1610, 1578,
5378 1585, 1578, 1586, 1578, 1605, 1578, 1606, 1578, 1609,
5379 1578, 1610, 1579, 1585, 1579, 1586, 1579, 1605, 1579,
5380 1606, 1579, 1609, 1579, 1610, 1601, 1609, 1601, 1610,
5381 1602, 1609, 1602, 1610, 1603, 1575, 1603, 1604, 1603,
5382 1605, 1603, 1609, 1603, 1610, 1604, 1605, 1604, 1609,
5383 1604, 1610, 1605, 1575, 1605, 1605, 1606, 1585, 1606,
5384 1586, 1606, 1605, 1606, 1606, 1606, 1609, 1606, 1610,
5385 1609, 1648, 1610, 1585, 1610, 1586, 1610, 1605, 1610,
5386 1606, 1610, 1609, 1610, 1610, 1610, 1620, 1580, 1610,
5387 1620, 1581, 1610, 1620, 1582, 1610, 1620, 1605, 1610,
5388 1620, 1607, 1576, 1580, 1576, 1581, 1576, 1582, 1576,
5389 1605, 1576, 1607, 1578, 1580, 1578, 1581, 1578, 1582,
5390 1578, 1605, 1578, 1607, 1579, 1605, 1580, 1581, 1580,
5391 1605, 1581, 1580, 1581, 1605, 1582, 1580, 1582, 1605,
5392 1587, 1580, 1587, 1581, 1587, 1582, 1587, 1605, 1589,
5393 1581, 1589, 1582, 1589, 1605, 1590, 1580, 1590, 1581,
5394 1590, 1582, 1590, 1605, 1591, 1581, 1592, 1605, 1593,
5395 1580, 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580,
5396 1601, 1581, 1601, 1582, 1601, 1605, 1602, 1581, 1602,
5397 1605, 1603, 1580, 1603, 1581, 1603, 1582, 1603, 1604,
5398 1603, 1605, 1604, 1580, 1604, 1581, 1604, 1582, 1604,
5399 1605, 1604, 1607, 1605, 1580, 1605, 1581, 1605, 1582,
5400 1605, 1605, 1606, 1580, 1606, 1581, 1606, 1582, 1606,
5401 1605, 1606, 1607, 1607, 1580, 1607, 1605, 1607, 1648,
5402 1610, 1580, 1610, 1581, 1610, 1582, 1610, 1605, 1610,
5403 1607, 1610, 1620, 1605, 1610, 1620, 1607, 1576, 1605,
5404 1576, 1607, 1578, 1605, 1578, 1607, 1579, 1605, 1579,
5405 1607, 1587, 1605, 1587, 1607, 1588, 1605, 1588, 1607,
5406 1603, 1604, 1603, 1605, 1604, 1605, 1606, 1605, 1606,
5407 1607, 1610, 1605, 1610, 1607, 1600, 1614, 1617, 1600,
5408 1615, 1617, 1600, 1616, 1617, 1591, 1609, 1591, 1610,
5409 1593, 1609, 1593, 1610, 1594, 1609, 1594, 1610, 1587,
5410 1609, 1587, 1610, 1588, 1609, 1588, 1610, 1581, 1609,
5411 1581, 1610, 1580, 1609, 1580, 1610, 1582, 1609, 1582,
5412 1610, 1589, 1609, 1589, 1610, 1590, 1609, 1590, 1610,
5413 1588, 1580, 1588, 1581, 1588, 1582, 1588, 1605, 1588,
5414 1585, 1587, 1585, 1589, 1585, 1590, 1585, 1591, 1609,
5415 1591, 1610, 1593, 1609, 1593, 1610, 1594, 1609, 1594,
5416 1610, 1587, 1609, 1587, 1610, 1588, 1609, 1588, 1610,
5417 1581, 1609, 1581, 1610, 1580, 1609, 1580, 1610, 1582,
5418 1609, 1582, 1610, 1589, 1609, 1589, 1610, 1590, 1609,
5419 1590, 1610, 1588, 1580, 1588, 1581, 1588, 1582, 1588,
5420 1605, 1588, 1585, 1587, 1585, 1589, 1585, 1590, 1585,
5421 1588, 1580, 1588, 1581, 1588, 1582, 1588, 1605, 1587,
5422 1607, 1588, 1607, 1591, 1605, 1587, 1580, 1587, 1581,
5423 1587, 1582, 1588, 1580, 1588, 1581, 1588, 1582, 1591,
5424 1605, 1592, 1605, 1575, 1611, 1575, 1611, 1578, 1580,
5425 1605, 1578, 1581, 1580, 1578, 1581, 1580, 1578, 1581,
5426 1605, 1578, 1582, 1605, 1578, 1605, 1580, 1578, 1605,
5427 1581, 1578, 1605, 1582, 1580, 1605, 1581, 1580, 1605,
5428 1581, 1581, 1605, 1610, 1581, 1605, 1609, 1587, 1581,
5429 1580, 1587, 1580, 1581, 1587, 1580, 1609, 1587, 1605,
5430 1581, 1587, 1605, 1581, 1587, 1605, 1580, 1587, 1605,
5431 1605, 1587, 1605, 1605, 1589, 1581, 1581, 1589, 1581,
5432 1581, 1589, 1605, 1605, 1588, 1581, 1605, 1588, 1581,
5433 1605, 1588, 1580, 1610, 1588, 1605, 1582, 1588, 1605,
5434 1582, 1588, 1605, 1605, 1588, 1605, 1605, 1590, 1581,
5435 1609, 1590, 1582, 1605, 1590, 1582, 1605, 1591, 1605,
5436 1581, 1591, 1605, 1581, 1591, 1605, 1605, 1591, 1605,
5437 1610, 1593, 1580, 1605, 1593, 1605, 1605, 1593, 1605,
5438 1605, 1593, 1605, 1609, 1594, 1605, 1605, 1594, 1605,
5439 1610, 1594, 1605, 1609, 1601, 1582, 1605, 1601, 1582,
5440 1605, 1602, 1605, 1581, 1602, 1605, 1605, 1604, 1581,
5441 1605, 1604, 1581, 1610, 1604, 1581, 1609, 1604, 1580,
5442 1580, 1604, 1580, 1580, 1604, 1582, 1605, 1604, 1582,
5443 1605, 1604, 1605, 1581, 1604, 1605, 1581, 1605, 1581,
5444 1580, 1605, 1581, 1605, 1605, 1581, 1610, 1605, 1580,
5445 1581, 1605, 1580, 1605, 1605, 1582, 1580, 1605, 1582,
5446 1605, 1605, 1580, 1582, 1607, 1605, 1580, 1607, 1605,
5447 1605, 1606, 1581, 1605, 1606, 1581, 1609, 1606, 1580,
5448 1605, 1606, 1580, 1605, 1606, 1580, 1609, 1606, 1605,
5449 1610, 1606, 1605, 1609, 1610, 1605, 1605, 1610, 1605,
5450 1605, 1576, 1582, 1610, 1578, 1580, 1610, 1578, 1580,
5451 1609, 1578, 1582, 1610, 1578, 1582, 1609, 1578, 1605,
5452 1610, 1578, 1605, 1609, 1580, 1605, 1610, 1580, 1581,
5453 1609, 1580, 1605, 1609, 1587, 1582, 1609, 1589, 1581,
5454 1610, 1588, 1581, 1610, 1590, 1581, 1610, 1604, 1580,
5455 1610, 1604, 1605, 1610, 1610, 1581, 1610, 1610, 1580,
5456 1610, 1610, 1605, 1610, 1605, 1605, 1610, 1602, 1605,
5457 1610, 1606, 1581, 1610, 1602, 1605, 1581, 1604, 1581,
5458 1605, 1593, 1605, 1610, 1603, 1605, 1610, 1606, 1580,
5459 1581, 1605, 1582, 1610, 1604, 1580, 1605, 1603, 1605,
5460 1605, 1604, 1580, 1605, 1606, 1580, 1581, 1580, 1581,
5461 1610, 1581, 1580, 1610, 1605, 1580, 1610, 1601, 1605,
5462 1610, 1576, 1581, 1610, 1603, 1605, 1605, 1593, 1580,
5463 1605, 1589, 1605, 1605, 1587, 1582, 1610, 1606, 1580,
5464 1610, 1589, 1604, 1746, 1602, 1604, 1746, 1575, 1604,
5465 1604, 1607, 1575, 1603, 1576, 1585, 1605, 1581, 1605,
5466 1583, 1589, 1604, 1593, 1605, 1585, 1587, 1608, 1604,
5467 1593, 1604, 1610, 1607, 1608, 1587, 1604, 1605, 1589,
5468 1604, 1609, 1589, 1604, 1609, 32, 1575, 1604, 1604,
5469 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587,
5470 1604, 1605, 1580, 1604, 32, 1580, 1604, 1575, 1604,
5471 1607, 1585, 1740, 1575, 1604, 44, 12289, 12290, 58,
5472 59, 33, 63, 12310, 12311, 46, 46, 46, 46,
5473 46, 8212, 8211, 95, 95, 40, 41, 123, 125,
5474 12308, 12309, 12304, 12305, 12298, 12299, 12296, 12297, 12300,
5475 12301, 12302, 12303, 91, 93, 32, 773, 32, 773,
5476 32, 773, 32, 773, 95, 95, 95, 44, 12289,
5477 46, 59, 58, 63, 33, 8212, 40, 41, 123,
5478 125, 12308, 12309, 35, 38, 42, 43, 45, 60,
5479 62, 61, 92, 36, 37, 64, 32, 1611, 1600,
5480 1611, 32, 1612, 32, 1613, 32, 1614, 1600, 1614,
5481 32, 1615, 1600, 1615, 32, 1616, 1600, 1616, 32,
5482 1617, 1600, 1617, 32, 1618, 1600, 1618, 1569, 1575,
5483 1619, 1575, 1619, 1575, 1620, 1575, 1620, 1608, 1620,
5484 1608, 1620, 1575, 1621, 1575, 1621, 1610, 1620, 1610,
5485 1620, 1610, 1620, 1610, 1620, 1575, 1575, 1576, 1576,
5486 1576, 1576, 1577, 1577, 1578, 1578, 1578, 1578, 1579,
5487 1579, 1579, 1579, 1580, 1580, 1580, 1580, 1581, 1581,
5488 1581, 1581, 1582, 1582, 1582, 1582, 1583, 1583, 1584,
5489 1584, 1585, 1585, 1586, 1586, 1587, 1587, 1587, 1587,
5490 1588, 1588, 1588, 1588, 1589, 1589, 1589, 1589, 1590,
5491 1590, 1590, 1590, 1591, 1591, 1591, 1591, 1592, 1592,
5492 1592, 1592, 1593, 1593, 1593, 1593, 1594, 1594, 1594,
5493 1594, 1601, 1601, 1601, 1601, 1602, 1602, 1602, 1602,
5494 1603, 1603, 1603, 1603, 1604, 1604, 1604, 1604, 1605,
5495 1605, 1605, 1605, 1606, 1606, 1606, 1606, 1607, 1607,
5496 1607, 1607, 1608, 1608, 1609, 1609, 1610, 1610, 1610,
5497 1610, 1604, 1575, 1619, 1604, 1575, 1619, 1604, 1575,
5498 1620, 1604, 1575, 1620, 1604, 1575, 1621, 1604, 1575,
5499 1621, 1604, 1575, 1604, 1575, 33, 34, 35, 36,
5500 37, 38, 39, 40, 41, 42, 43, 44, 45,
5501 46, 47, 48, 49, 50, 51, 52, 53, 54,
5502 55, 56, 57, 58, 59, 60, 61, 62, 63,
5503 64, 65, 66, 67, 68, 69, 70, 71, 72,
5504 73, 74, 75, 76, 77, 78, 79, 80, 81,
5505 82, 83, 84, 85, 86, 87, 88, 89, 90,
5506 91, 92, 93, 94, 95, 96, 97, 98, 99,
5507 100, 101, 102, 103, 104, 105, 106, 107, 108,
5508 109, 110, 111, 112, 113, 114, 115, 116, 117,
5509 118, 119, 120, 121, 122, 123, 124, 125, 126,
5510 10629, 10630, 12290, 12300, 12301, 12289, 12539, 12530, 12449,
5511 12451, 12453, 12455, 12457, 12515, 12517, 12519, 12483, 12540,
5512 12450, 12452, 12454, 12456, 12458, 12459, 12461, 12463, 12465,
5513 12467, 12469, 12471, 12473, 12475, 12477, 12479, 12481, 12484,
5514 12486, 12488, 12490, 12491, 12492, 12493, 12494, 12495, 12498,
5515 12501, 12504, 12507, 12510, 12511, 12512, 12513, 12514, 12516,
5516 12518, 12520, 12521, 12522, 12523, 12524, 12525, 12527, 12531,
5517 12441, 12442, 4448, 4352, 4353, 4522, 4354, 4524, 4525,
5518 4355, 4356, 4357, 4528, 4529, 4530, 4531, 4532, 4533,
5519 4378, 4358, 4359, 4360, 4385, 4361, 4362, 4363, 4364,
5520 4365, 4366, 4367, 4368, 4369, 4370, 4449, 4450, 4451,
5521 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460,
5522 4461, 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469,
5523 162, 163, 172, 32, 772, 166, 165, 8361, 9474,
5524 8592, 8593, 8594, 8595, 9632, 9675, 720, 721, 230,
5525 665, 595, 675, 43878, 677, 676, 598, 599, 7569,
5526 600, 606, 681, 612, 610, 608, 667, 295, 668,
5527 615, 644, 682, 683, 620, 122628, 42894, 622, 122629,
5528 654, 122630, 248, 630, 631, 113, 634, 122632, 637,
5529 638, 640, 680, 678, 43879, 679, 648, 11377, 655,
5530 673, 674, 664, 448, 449, 450, 122634, 122654, 69785,
5531 69818, 69787, 69818, 69797, 69818, 69937, 69927, 69938, 69927,
5532 70471, 70462, 70471, 70487, 70841, 70842, 70841, 70832, 70841,
5533 70845, 71096, 71087, 71097, 71087, 71989, 71984, 119127, 119141,
5534 119128, 119141, 119128, 119141, 119150, 119128, 119141, 119151, 119128,
5535 119141, 119152, 119128, 119141, 119153, 119128, 119141, 119154, 119225,
5536 119141, 119226, 119141, 119225, 119141, 119150, 119226, 119141, 119150,
5537 119225, 119141, 119151, 119226, 119141, 119151, 65, 66, 67,
5538 68, 69, 70, 71, 72, 73, 74, 75, 76,
5539 77, 78, 79, 80, 81, 82, 83, 84, 85,
5540 86, 87, 88, 89, 90, 97, 98, 99, 100,
5541 101, 102, 103, 104, 105, 106, 107, 108, 109,
5542 110, 111, 112, 113, 114, 115, 116, 117, 118,
5543 119, 120, 121, 122, 65, 66, 67, 68, 69,
5544 70, 71, 72, 73, 74, 75, 76, 77, 78,
5545 79, 80, 81, 82, 83, 84, 85, 86, 87,
5546 88, 89, 90, 97, 98, 99, 100, 101, 102,
5547 103, 105, 106, 107, 108, 109, 110, 111, 112,
5548 113, 114, 115, 116, 117, 118, 119, 120, 121,
5549 122, 65, 66, 67, 68, 69, 70, 71, 72,
5550 73, 74, 75, 76, 77, 78, 79, 80, 81,
5551 82, 83, 84, 85, 86, 87, 88, 89, 90,
5552 97, 98, 99, 100, 101, 102, 103, 104, 105,
5553 106, 107, 108, 109, 110, 111, 112, 113, 114,
5554 115, 116, 117, 118, 119, 120, 121, 122, 65,
5555 67, 68, 71, 74, 75, 78, 79, 80, 81,
5556 83, 84, 85, 86, 87, 88, 89, 90, 97,
5557 98, 99, 100, 102, 104, 105, 106, 107, 108,
5558 109, 110, 112, 113, 114, 115, 116, 117, 118,
5559 119, 120, 121, 122, 65, 66, 67, 68, 69,
5560 70, 71, 72, 73, 74, 75, 76, 77, 78,
5561 79, 80, 81, 82, 83, 84, 85, 86, 87,
5562 88, 89, 90, 97, 98, 99, 100, 101, 102,
5563 103, 104, 105, 106, 107, 108, 109, 110, 111,
5564 112, 113, 114, 115, 116, 117, 118, 119, 120,
5565 121, 122, 65, 66, 68, 69, 70, 71, 74,
5566 75, 76, 77, 78, 79, 80, 81, 83, 84,
5567 85, 86, 87, 88, 89, 97, 98, 99, 100,
5568 101, 102, 103, 104, 105, 106, 107, 108, 109,
5569 110, 111, 112, 113, 114, 115, 116, 117, 118,
5570 119, 120, 121, 122, 65, 66, 68, 69, 70,
5571 71, 73, 74, 75, 76, 77, 79, 83, 84,
5572 85, 86, 87, 88, 89, 97, 98, 99, 100,
5573 101, 102, 103, 104, 105, 106, 107, 108, 109,
5574 110, 111, 112, 113, 114, 115, 116, 117, 118,
5575 119, 120, 121, 122, 65, 66, 67, 68, 69,
5576 70, 71, 72, 73, 74, 75, 76, 77, 78,
5577 79, 80, 81, 82, 83, 84, 85, 86, 87,
5578 88, 89, 90, 97, 98, 99, 100, 101, 102,
5579 103, 104, 105, 106, 107, 108, 109, 110, 111,
5580 112, 113, 114, 115, 116, 117, 118, 119, 120,
5581 121, 122, 65, 66, 67, 68, 69, 70, 71,
5582 72, 73, 74, 75, 76, 77, 78, 79, 80,
5583 81, 82, 83, 84, 85, 86, 87, 88, 89,
5584 90, 97, 98, 99, 100, 101, 102, 103, 104,
5585 105, 106, 107, 108, 109, 110, 111, 112, 113,
5586 114, 115, 116, 117, 118, 119, 120, 121, 122,
5587 65, 66, 67, 68, 69, 70, 71, 72, 73,
5588 74, 75, 76, 77, 78, 79, 80, 81, 82,
5589 83, 84, 85, 86, 87, 88, 89, 90, 97,
5590 98, 99, 100, 101, 102, 103, 104, 105, 106,
5591 107, 108, 109, 110, 111, 112, 113, 114, 115,
5592 116, 117, 118, 119, 120, 121, 122, 65, 66,
5593 67, 68, 69, 70, 71, 72, 73, 74, 75,
5594 76, 77, 78, 79, 80, 81, 82, 83, 84,
5595 85, 86, 87, 88, 89, 90, 97, 98, 99,
5596 100, 101, 102, 103, 104, 105, 106, 107, 108,
5597 109, 110, 111, 112, 113, 114, 115, 116, 117,
5598 118, 119, 120, 121, 122, 65, 66, 67, 68,
5599 69, 70, 71, 72, 73, 74, 75, 76, 77,
5600 78, 79, 80, 81, 82, 83, 84, 85, 86,
5601 87, 88, 89, 90, 97, 98, 99, 100, 101,
5602 102, 103, 104, 105, 106, 107, 108, 109, 110,
5603 111, 112, 113, 114, 115, 116, 117, 118, 119,
5604 120, 121, 122, 65, 66, 67, 68, 69, 70,
5605 71, 72, 73, 74, 75, 76, 77, 78, 79,
5606 80, 81, 82, 83, 84, 85, 86, 87, 88,
5607 89, 90, 97, 98, 99, 100, 101, 102, 103,
5608 104, 105, 106, 107, 108, 109, 110, 111, 112,
5609 113, 114, 115, 116, 117, 118, 119, 120, 121,
5610 122, 305, 567, 913, 914, 915, 916, 917, 918,
5611 919, 920, 921, 922, 923, 924, 925, 926, 927,
5612 928, 929, 920, 931, 932, 933, 934, 935, 936,
5613 937, 8711, 945, 946, 947, 948, 949, 950, 951,
5614 952, 953, 954, 955, 956, 957, 958, 959, 960,
5615 961, 962, 963, 964, 965, 966, 967, 968, 969,
5616 8706, 949, 952, 954, 966, 961, 960, 913, 914,
5617 915, 916, 917, 918, 919, 920, 921, 922, 923,
5618 924, 925, 926, 927, 928, 929, 920, 931, 932,
5619 933, 934, 935, 936, 937, 8711, 945, 946, 947,
5620 948, 949, 950, 951, 952, 953, 954, 955, 956,
5621 957, 958, 959, 960, 961, 962, 963, 964, 965,
5622 966, 967, 968, 969, 8706, 949, 952, 954, 966,
5623 961, 960, 913, 914, 915, 916, 917, 918, 919,
5624 920, 921, 922, 923, 924, 925, 926, 927, 928,
5625 929, 920, 931, 932, 933, 934, 935, 936, 937,
5626 8711, 945, 946, 947, 948, 949, 950, 951, 952,
5627 953, 954, 955, 956, 957, 958, 959, 960, 961,
5628 962, 963, 964, 965, 966, 967, 968, 969, 8706,
5629 949, 952, 954, 966, 961, 960, 913, 914, 915,
5630 916, 917, 918, 919, 920, 921, 922, 923, 924,
5631 925, 926, 927, 928, 929, 920, 931, 932, 933,
5632 934, 935, 936, 937, 8711, 945, 946, 947, 948,
5633 949, 950, 951, 952, 953, 954, 955, 956, 957,
5634 958, 959, 960, 961, 962, 963, 964, 965, 966,
5635 967, 968, 969, 8706, 949, 952, 954, 966, 961,
5636 960, 913, 914, 915, 916, 917, 918, 919, 920,
5637 921, 922, 923, 924, 925, 926, 927, 928, 929,
5638 920, 931, 932, 933, 934, 935, 936, 937, 8711,
5639 945, 946, 947, 948, 949, 950, 951, 952, 953,
5640 954, 955, 956, 957, 958, 959, 960, 961, 962,
5641 963, 964, 965, 966, 967, 968, 969, 8706, 949,
5642 952, 954, 966, 961, 960, 988, 989, 48, 49,
5643 50, 51, 52, 53, 54, 55, 56, 57, 48,
5644 49, 50, 51, 52, 53, 54, 55, 56, 57,
5645 48, 49, 50, 51, 52, 53, 54, 55, 56,
5646 57, 48, 49, 50, 51, 52, 53, 54, 55,
5647 56, 57, 48, 49, 50, 51, 52, 53, 54,
5648 55, 56, 57, 1072, 1073, 1074, 1075, 1076, 1077,
5649 1078, 1079, 1080, 1082, 1083, 1084, 1086, 1087, 1088,
5650 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1099,
5651 1101, 1102, 42633, 1241, 1110, 1112, 1257, 1199, 1231,
5652 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080,
5653 1082, 1083, 1086, 1087, 1089, 1091, 1092, 1093, 1094,
5654 1095, 1096, 1098, 1099, 1169, 1110, 1109, 1119, 1195,
5655 42577, 1201, 1575, 1576, 1580, 1583, 1608, 1586, 1581,
5656 1591, 1610, 1603, 1604, 1605, 1606, 1587, 1593, 1601,
5657 1589, 1602, 1585, 1588, 1578, 1579, 1582, 1584, 1590,
5658 1592, 1594, 1646, 1722, 1697, 1647, 1576, 1580, 1607,
5659 1581, 1610, 1603, 1604, 1605, 1606, 1587, 1593, 1601,
5660 1589, 1602, 1588, 1578, 1579, 1582, 1590, 1594, 1580,
5661 1581, 1610, 1604, 1606, 1587, 1593, 1589, 1602, 1588,
5662 1582, 1590, 1594, 1722, 1647, 1576, 1580, 1607, 1581,
5663 1591, 1610, 1603, 1605, 1606, 1587, 1593, 1601, 1589,
5664 1602, 1588, 1578, 1579, 1582, 1590, 1592, 1594, 1646,
5665 1697, 1575, 1576, 1580, 1583, 1607, 1608, 1586, 1581,
5666 1591, 1610, 1604, 1605, 1606, 1587, 1593, 1601, 1589,
5667 1602, 1585, 1588, 1578, 1579, 1582, 1584, 1590, 1592,
5668 1594, 1576, 1580, 1583, 1608, 1586, 1581, 1591, 1610,
5669 1604, 1605, 1606, 1587, 1593, 1601, 1589, 1602, 1585,
5670 1588, 1578, 1579, 1582, 1584, 1590, 1592, 1594, 48,
5671 46, 48, 44, 49, 44, 50, 44, 51, 44,
5672 52, 44, 53, 44, 54, 44, 55, 44, 56,
5673 44, 57, 44, 40, 65, 41, 40, 66, 41,
5674 40, 67, 41, 40, 68, 41, 40, 69, 41,
5675 40, 70, 41, 40, 71, 41, 40, 72, 41,
5676 40, 73, 41, 40, 74, 41, 40, 75, 41,
5677 40, 76, 41, 40, 77, 41, 40, 78, 41,
5678 40, 79, 41, 40, 80, 41, 40, 81, 41,
5679 40, 82, 41, 40, 83, 41, 40, 84, 41,
5680 40, 85, 41, 40, 86, 41, 40, 87, 41,
5681 40, 88, 41, 40, 89, 41, 40, 90, 41,
5682 12308, 83, 12309, 67, 82, 67, 68, 87, 90,
5683 65, 66, 67, 68, 69, 70, 71, 72, 73,
5684 74, 75, 76, 77, 78, 79, 80, 81, 82,
5685 83, 84, 85, 86, 87, 88, 89, 90, 72,
5686 86, 77, 86, 83, 68, 83, 83, 80, 80,
5687 86, 87, 67, 77, 67, 77, 68, 77, 82,
5688 68, 74, 12411, 12363, 12467, 12467, 12469, 25163, 23383,
5689 21452, 12486, 12441, 20108, 22810, 35299, 22825, 20132, 26144,
5690 28961, 26009, 21069, 24460, 20877, 26032, 21021, 32066, 29983,
5691 36009, 22768, 21561, 28436, 25237, 25429, 19968, 19977, 36938,
5692 24038, 20013, 21491, 25351, 36208, 25171, 31105, 31354, 21512,
5693 28288, 26377, 26376, 30003, 21106, 21942, 37197, 12308, 26412,
5694 12309, 12308, 19977, 12309, 12308, 20108, 12309, 12308, 23433,
5695 12309, 12308, 28857, 12309, 12308, 25171, 12309, 12308, 30423,
5696 12309, 12308, 21213, 12309, 12308, 25943, 12309, 24471, 21487,
5697 48, 49, 50, 51, 52, 53, 54, 55, 56,
5698 57, 20029, 20024, 20033, 131362, 20320, 20398, 20411, 20482,
5699 20602, 20633, 20711, 20687, 13470, 132666, 20813, 20820, 20836,
5700 20855, 132380, 13497, 20839, 20877, 132427, 20887, 20900, 20172,
5701 20908, 20917, 168415, 20981, 20995, 13535, 21051, 21062, 21106,
5702 21111, 13589, 21191, 21193, 21220, 21242, 21253, 21254, 21271,
5703 21321, 21329, 21338, 21363, 21373, 21375, 21375, 21375, 133676,
5704 28784, 21450, 21471, 133987, 21483, 21489, 21510, 21662, 21560,
5705 21576, 21608, 21666, 21750, 21776, 21843, 21859, 21892, 21892,
5706 21913, 21931, 21939, 21954, 22294, 22022, 22295, 22097, 22132,
5707 20999, 22766, 22478, 22516, 22541, 22411, 22578, 22577, 22700,
5708 136420, 22770, 22775, 22790, 22810, 22818, 22882, 136872, 136938,
5709 23020, 23067, 23079, 23000, 23142, 14062, 14076, 23304, 23358,
5710 23358, 137672, 23491, 23512, 23527, 23539, 138008, 23551, 23558,
5711 24403, 23586, 14209, 23648, 23662, 23744, 23693, 138724, 23875,
5712 138726, 23918, 23915, 23932, 24033, 24034, 14383, 24061, 24104,
5713 24125, 24169, 14434, 139651, 14460, 24240, 24243, 24246, 24266,
5714 172946, 24318, 140081, 140081, 33281, 24354, 24354, 14535, 144056,
5715 156122, 24418, 24427, 14563, 24474, 24525, 24535, 24569, 24705,
5716 14650, 14620, 24724, 141012, 24775, 24904, 24908, 24910, 24908,
5717 24954, 24974, 25010, 24996, 25007, 25054, 25074, 25078, 25104,
5718 25115, 25181, 25265, 25300, 25424, 142092, 25405, 25340, 25448,
5719 25475, 25572, 142321, 25634, 25541, 25513, 14894, 25705, 25726,
5720 25757, 25719, 14956, 25935, 25964, 143370, 26083, 26360, 26185,
5721 15129, 26257, 15112, 15076, 20882, 20885, 26368, 26268, 32941,
5722 17369, 26391, 26395, 26401, 26462, 26451, 144323, 15177, 26618,
5723 26501, 26706, 26757, 144493, 26766, 26655, 26900, 15261, 26946,
5724 27043, 27114, 27304, 145059, 27355, 15384, 27425, 145575, 27476,
5725 15438, 27506, 27551, 27578, 27579, 146061, 138507, 146170, 27726,
5726 146620, 27839, 27853, 27751, 27926, 27966, 28023, 27969, 28009,
5727 28024, 28037, 146718, 27956, 28207, 28270, 15667, 28363, 28359,
5728 147153, 28153, 28526, 147294, 147342, 28614, 28729, 28702, 28699,
5729 15766, 28746, 28797, 28791, 28845, 132389, 28997, 148067, 29084,
5730 148395, 29224, 29237, 29264, 149000, 29312, 29333, 149301, 149524,
5731 29562, 29579, 16044, 29605, 16056, 16056, 29767, 29788, 29809,
5732 29829, 29898, 16155, 29988, 150582, 30014, 150674, 30064, 139679,
5733 30224, 151457, 151480, 151620, 16380, 16392, 30452, 151795, 151794,
5734 151833, 151859, 30494, 30495, 30495, 30538, 16441, 30603, 16454,
5735 16534, 152605, 30798, 30860, 30924, 16611, 153126, 31062, 153242,
5736 153285, 31119, 31211, 16687, 31296, 31306, 31311, 153980, 154279,
5737 154279, 31470, 16898, 154539, 31686, 31689, 16935, 154752, 31954,
5738 17056, 31976, 31971, 32000, 155526, 32099, 17153, 32199, 32258,
5739 32325, 17204, 156200, 156231, 17241, 156377, 32634, 156478, 32661,
5740 32762, 32773, 156890, 156963, 32864, 157096, 32880, 144223, 17365,
5741 32946, 33027, 17419, 33086, 23221, 157607, 157621, 144275, 144284,
5742 33281, 33284, 36766, 17515, 33425, 33419, 33437, 21171, 33457,
5743 33459, 33469, 33510, 158524, 33509, 33565, 33635, 33709, 33571,
5744 33725, 33767, 33879, 33619, 33738, 33740, 33756, 158774, 159083,
5745 158933, 17707, 34033, 34035, 34070, 160714, 34148, 159532, 17757,
5746 17761, 159665, 159954, 17771, 34384, 34396, 34407, 34409, 34473,
5747 34440, 34574, 34530, 34681, 34600, 34667, 34694, 17879, 34785,
5748 34817, 17913, 34912, 34915, 161383, 35031, 35038, 17973, 35066,
5749 13499, 161966, 162150, 18110, 18119, 35488, 35565, 35722, 35925,
5750 162984, 36011, 36033, 36123, 36215, 163631, 133124, 36299, 36284,
5751 36336, 133342, 36564, 36664, 165330, 165357, 37012, 37105, 37137,
5752 165678, 37147, 37432, 37591, 37592, 37500, 37881, 37909, 166906,
5753 38283, 18837, 38327, 167287, 18918, 38595, 23986, 38691, 168261,
5754 168474, 19054, 19062, 38880, 168970, 19122, 169110, 38923, 38923,
5755 38953, 169398, 39138, 19251, 39209, 39335, 39362, 39422, 19406,
5756 170800, 39698, 40000, 40189, 19662, 19693, 40295, 172238, 19704,
5757 172293, 172558, 172689, 40635, 19798, 40697, 40702, 40709, 40719,
5758 40726, 40763, 173568};
5759
5760 const uint8_t canonical_combining_class_index[4352] = {
5761 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0,
5762 15, 0, 0, 0, 16, 17, 18, 19, 20, 21, 22, 0, 0, 23, 0, 0, 0, 0, 0,
5763 0, 0, 0, 0, 0, 0, 24, 25, 0, 0, 26, 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, 0, 0, 0, 0, 0,
5768 0, 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, 27, 0, 28, 29, 30,
5770 31, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5773 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5774 0, 0, 0, 0, 32, 0, 0, 33, 0, 0, 34, 35, 36, 0, 0, 0, 0, 0, 0,
5775 37, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 52,
5776 53, 0, 54, 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, 0, 0, 0, 0, 0, 0, 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, 55, 56, 0, 0, 0, 57, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5783 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5784 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5785 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 0, 0,
5786 0, 0, 0, 0, 0, 61, 56, 62, 0, 63, 0, 0, 0, 64, 65, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5989 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5990 0};
5991 const uint8_t canonical_combining_class_block[67][256] = {
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, 0, 0, 0, 0, 0, 0, 0, 0,
6001 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6002 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6003 {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6004 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220,
6005 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220,
6006 220, 220, 220, 220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 220, 220,
6007 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230,
6008 230, 230, 220, 220, 0, 230, 230, 230, 220, 220, 220, 220, 230, 232, 220,
6009 220, 230, 233, 234, 234, 233, 234, 234, 233, 230, 230, 230, 230, 230, 230,
6010 230, 230, 230, 230, 230, 230, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6019 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6020 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, 0,
6025 0, 0, 0, 0, 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, 230,
6027 230, 230, 230, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0,
6031 0, 0, 0, 0, 0, 0, 0, 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},
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, 0, 0, 0, 0, 0,
6041 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6042 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 230, 230, 230, 230,
6043 220, 230, 230, 230, 222, 220, 230, 230, 230, 230, 230, 230, 220, 220, 220,
6044 220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230, 10, 11, 12, 13,
6045 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25,
6046 0, 230, 220, 0, 18, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6049 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6050 0},
6051 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6052 0, 230, 230, 230, 230, 230, 230, 230, 230, 30, 31, 32, 0, 0, 0,
6053 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6054 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6055 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6056 27, 28, 29, 30, 31, 32, 33, 34, 230, 230, 220, 220, 230, 230, 230,
6057 230, 230, 220, 230, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6058 0, 0, 0, 0, 0, 0, 0, 35, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6064 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6065 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230, 230,
6066 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, 230, 220, 0, 0,
6067 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6068 0},
6069 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6070 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6071 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6072 0, 0, 0, 230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220,
6073 220, 230, 220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230,
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, 0, 0, 0, 0, 0,
6083 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6084 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230,
6085 230, 230, 220, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0,
6086 0},
6087 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6088 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 230, 230, 230,
6089 230, 230, 230, 230, 230, 230, 0, 230, 230, 230, 0, 230, 230, 230, 230,
6090 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6091 0, 0, 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, 220,
6093 220, 220, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6096 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6097 0, 0, 230, 220, 220, 220, 230, 230, 230, 230, 0, 0, 0, 0, 0,
6098 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6099 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6100 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 220, 220, 220,
6101 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6102 230, 0, 220, 230, 230, 220, 230, 230, 220, 230, 230, 230, 220, 220, 220,
6103 27, 28, 29, 230, 230, 230, 220, 230, 230, 220, 220, 230, 230, 230, 230,
6104 230},
6105 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0,
6108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 230, 220, 230, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6112 0, 0, 0, 0, 0, 0, 0, 0, 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6114 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6115 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, 230, 0},
6117 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6118 0, 0, 0, 0, 0, 0, 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6120 0, 0, 0, 0, 0, 9, 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, 0, 0, 0, 0,
6123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 7, 0, 0, 0,
6125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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},
6128 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6129 0, 0, 0, 0, 0, 0, 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6131 0, 0, 0, 0, 0, 9, 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, 0, 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, 9, 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},
6139 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6140 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6142 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 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, 0, 0, 0, 0,
6145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 7, 0, 0, 0,
6147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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},
6150 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6151 0, 0, 0, 0, 0, 0, 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6153 0, 0, 0, 0, 0, 9, 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, 0, 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, 9, 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, 0, 0, 0, 0, 0, 0,
6160 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6163 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6164 0, 0, 103, 103, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6165 107, 107, 107, 107, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6171 0, 0, 0, 0, 118, 118, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6172 0, 0, 122, 122, 122, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6175 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, 0, 220, 220, 0, 0, 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, 220, 0, 220, 0, 216, 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, 0, 0, 0, 0, 0, 0, 0,
6182 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6183 0, 0, 0, 0, 0, 0, 0, 0, 129, 130, 0, 132, 0, 0, 0,
6184 0, 0, 130, 130, 130, 130, 0, 0, 130, 0, 230, 230, 9, 0, 230,
6185 230, 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, 0, 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, 220, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6192 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6193 0},
6194 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 7, 0, 9, 9, 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, 0, 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, 220, 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, 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, 0, 0,
6204 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, 0, 0, 0, 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, 230, 230, 230, 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, 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, 0, 0,
6216 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6217 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 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, 9, 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, 0, 0, 0, 0, 0, 0,
6224 0, 0, 0, 0, 0, 0, 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, 0, 0, 9, 0, 0, 0, 0, 0,
6226 0, 0, 0, 0, 0, 230, 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},
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, 0, 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, 228, 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, 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, 0, 0,
6238 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, 0, 0, 0, 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, 222, 230, 220, 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, 0, 0, 0, 0, 0, 0, 0, 0,
6249 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6250 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 230, 220, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6257 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,
6258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230,
6259 230, 230, 230, 230, 230, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0,
6260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6262 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230,
6263 230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 0, 220, 220, 230, 230,
6264 220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 230, 230, 0, 0, 0,
6265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6266 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6267 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6268 0},
6269 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
6272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
6273 0, 0, 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, 230, 220, 230, 230, 230, 230, 230,
6275 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6276 0, 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, 9,
6278 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6280 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6281 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0,
6282 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, 0, 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, 7, 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, 0, 0,
6295 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6296 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230,
6297 230, 0, 1, 220, 220, 220, 220, 220, 230, 230, 220, 220, 220, 220, 230,
6298 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 220, 0, 0,
6299 0, 0, 0, 0, 230, 0, 0, 0, 230, 230, 0, 0, 0, 0, 0,
6300 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, 0, 0, 0,
6312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 220,
6314 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 234, 214, 220, 202, 230,
6315 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6316 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6317 230, 230, 230, 230, 230, 230, 232, 228, 228, 220, 218, 230, 233, 220, 230,
6318 220},
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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6332 230, 230, 1, 1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 0, 0, 0,
6333 0, 230, 0, 0, 0, 1, 1, 230, 220, 230, 1, 1, 220, 220, 220, 220,
6334 230, 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, 0, 0, 0,
6344 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 230, 230, 230,
6346 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, 0, 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, 9, 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, 0,
6360 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6361 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,
6362 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6363 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6364 230},
6365 {0, 0, 0, 0, 0, 0, 0, 0, 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, 218, 228, 232, 222, 224, 224, 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, 0, 0, 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, 8, 8, 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, 0, 0, 0, 0,
6376 0, 0, 0, 0, 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, 0,
6383 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6384 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,
6385 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0,
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, 230, 230,
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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6392 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6393 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6394 {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0,
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, 9,
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, 0, 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, 0,
6407 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6408 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230,
6409 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
6410 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6411 0},
6412 {0, 0, 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, 0, 0, 0, 0, 220,
6414 220, 220, 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, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
6421 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0,
6423 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6432 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6433 0, 0, 0, 0, 0, 230, 0, 230, 230, 220, 0, 0, 230, 230, 0, 0, 0, 0, 0,
6434 230, 230, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6435 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9,
6437 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, 0, 0, 0,
6446 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 0, 0,
6448 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, 26, 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, 0, 0, 0, 0, 0, 0, 0, 0,
6458 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0},
6460 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6461 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6462 0, 0, 230, 230, 230, 230, 230, 230, 230, 220, 220, 220, 220, 220, 220,
6463 220, 230, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6476 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6477 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 220, 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, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,
6498 0, 0, 0, 0, 0, 0, 0, 0, 220, 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},
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, 0, 0, 0, 0, 0, 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, 230, 230, 230, 230, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0,
6510 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6511 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, 220, 0, 230, 0, 0, 0, 0,
6513 0, 0, 0, 0, 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, 230, 1, 220, 0,
6515 0, 0, 0, 9, 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, 0, 0, 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, 0, 0, 0, 0,
6523 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6524 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 230, 230, 230, 230, 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, 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},
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, 0, 0, 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, 230, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6547 0, 0, 0, 0, 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, 220, 220, 220},
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, 0, 0,
6551 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 220, 220,
6553 230, 230, 230, 220, 230, 220, 220, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6554 0, 0, 0, 0, 0, 0, 0, 0, 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, 230, 220, 230, 220, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6562 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6563 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, 0, 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, 0, 0, 0, 0, 0, 0, 9, 0,
6567 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6568 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
6569 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 7, 0, 0, 0, 0, 0,
6572 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6573 0, 0, 0, 0, 0, 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},
6575 {230, 230, 230, 0, 0, 0, 0, 0, 0, 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6578 0, 0, 0, 0, 0, 0, 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, 7, 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, 0, 0, 0, 0, 0, 0,
6582 0, 0, 0, 0, 0, 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, 9, 0, 0, 0, 0, 0,
6584 0, 0, 0, 0, 7, 0, 0, 0, 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,
6586 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6587 {0, 0, 0, 0, 0, 0, 0, 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, 9, 7, 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, 0, 0, 0, 0, 0, 0, 0,
6595 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 7, 9, 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, 0, 0, 0, 0, 0,
6600 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6601 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0,
6602 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0,
6603 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6604 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0,
6605 230, 230, 230, 230, 230, 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,
6613 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, 0, 0, 0, 0, 0, 0,
6615 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6616 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 7, 0,
6617 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 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, 0, 0, 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, 9, 7, 0, 0, 0, 0, 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},
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, 0,
6631 0, 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, 9,
6633 7, 0, 0, 0, 0, 0, 0, 0, 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},
6636 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 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, 0, 0, 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, 9, 7, 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, 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},
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, 9, 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, 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},
6658 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 7, 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, 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},
6669 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 0, 0, 0, 0, 7, 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, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,
6678 0, 0, 0, 0, 0, 0, 0, 0, 9, 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},
6680 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
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, 0, 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, 9, 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, 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},
6691 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 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, 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},
6702 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 7, 0, 9, 9, 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, 0, 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, 9, 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, 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},
6713 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 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, 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},
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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0,
6734 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6735 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 230, 230, 230, 230, 230, 230, 230, 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, 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,
6747 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 6, 6, 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, 0, 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, 1, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6775 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6776 0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216,
6777 216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220,
6778 220, 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0, 0, 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, 230, 230, 230, 230, 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,
6785 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 0, 0, 0, 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 230, 230, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0,
6796 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6797 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6798 {230, 230, 230, 230, 230, 230, 230, 0, 230, 230, 230, 230, 230, 230, 230,
6799 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230, 230, 230,
6800 230, 230, 230, 230, 0, 230, 230, 0, 230, 230, 230, 230, 230, 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, 0, 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, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6814 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6815 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, 0, 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, 230, 0,
6824 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6825 0, 0, 0, 0, 0, 0, 0, 0, 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, 230, 230, 230, 230, 0, 0,
6827 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, 0, 0, 0, 0, 0, 0,
6837 0, 0, 0, 0, 0, 0, 0, 0, 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, 232, 232, 220, 230, 0, 0,
6839 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, 0, 0, 0, 0, 0, 0, 0, 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, 220, 220, 220, 220, 220, 220, 220, 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},
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, 0, 0, 0, 0, 0, 0, 0, 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, 230, 230, 230, 230, 230, 230, 7, 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, 0, 0, 0, 0,
6864 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6865 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
6866
6867 const uint8_t composition_index[4352] = {
6868 0, 1, 2, 3, 4, 5, 6, 5, 5, 7, 5, 8, 9, 10, 5, 5, 11, 5, 5, 5, 5, 5,
6869 5, 5, 5, 5, 5, 12, 5, 5, 13, 14, 5, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6870 5, 5, 5, 5, 17, 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, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 18, 19, 5, 20, 21, 22, 5, 5, 5, 23, 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, 5, 5, 5, 5,
7064 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
7065 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
7066 const uint16_t composition_block[67][257] = {
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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
7070 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
7071 1, 3, 5, 7, 7, 7, 39, 45, 55, 67, 101, 103, 117, 131, 161,
7072 163, 173, 185, 191, 209, 241, 245, 245, 261, 275, 289, 327, 331, 343, 347,
7073 365, 377, 377, 377, 377, 377, 377, 377, 409, 415, 425, 437, 471, 473, 487,
7074 503, 531, 535, 545, 557, 563, 581, 613, 617, 617, 633, 647, 663, 701, 705,
7075 719, 723, 743, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,
7076 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,
7077 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755,
7078 755, 755, 755, 755, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
7079 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
7080 769, 769, 771, 773, 777, 779, 779, 779, 787, 787, 787, 787, 787, 789, 789,
7081 789, 789, 789, 797, 803, 805, 805, 807, 807, 807, 807, 815, 815, 815, 815,
7082 815, 815, 823, 823, 825, 827, 831, 833, 833, 833, 841, 841, 841, 841, 841,
7083 843, 843, 843, 843, 843, 851, 857, 859, 859, 861, 861, 861, 861, 869, 869,
7084 869, 869},
7085 {869, 869, 869, 877, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885,
7086 885, 885, 885, 885, 889, 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, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7089 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893,
7090 893, 893, 897, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901,
7091 901, 903, 905, 905, 905, 905, 905, 907, 909, 909, 909, 909, 909, 909, 909,
7092 911, 913, 915, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, 917,
7093 917, 917, 917, 917, 917, 917, 917, 917, 919, 919, 919, 919, 919, 919, 919,
7094 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919,
7095 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 929, 939, 939, 939,
7096 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, 949, 959, 959, 959,
7097 959, 959, 959, 959, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,
7098 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,
7099 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961,
7100 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 963, 965, 965, 965, 965,
7101 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,
7102 965, 965},
7103 {965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,
7104 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,
7105 965, 965, 965, 965, 965, 965, 965, 965, 965, 967, 969, 971, 973, 973, 973,
7106 973, 973, 975, 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, 977, 977, 977,
7111 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977,
7112 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 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, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7119 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7120 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, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7132 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
7133 979, 979, 993, 993, 993, 993, 1001, 1001, 1011, 1011, 1025, 1025,
7134 1025, 1025, 1025, 1025, 1033, 1033, 1035, 1035, 1035, 1035, 1047, 1047,
7135 1047, 1047, 1057, 1057, 1057, 1059, 1059, 1061, 1061, 1061, 1077, 1077,
7136 1077, 1077, 1085, 1085, 1097, 1097, 1113, 1113, 1113, 1113, 1113, 1113,
7137 1121, 1121, 1125, 1125, 1125, 1125, 1141, 1141, 1141, 1141, 1153, 1159,
7138 1165, 1165, 1165, 1167, 1167, 1167, 1167, 1171, 1171, 1171, 1171, 1171,
7139 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
7140 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
7141 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171,
7142 1171, 1171, 1171, 1171, 1171},
7143 {1171, 1171, 1171, 1171, 1171, 1171, 1171, 1173, 1173, 1173, 1173, 1173,
7144 1173, 1173, 1173, 1173, 1173, 1177, 1177, 1177, 1179, 1179, 1185, 1189,
7145 1191, 1199, 1199, 1201, 1201, 1201, 1201, 1203, 1203, 1203, 1203, 1203,
7146 1211, 1211, 1211, 1211, 1213, 1213, 1213, 1213, 1215, 1215, 1217, 1217,
7147 1217, 1221, 1221, 1221, 1223, 1223, 1229, 1233, 1235, 1243, 1243, 1245,
7148 1245, 1245, 1245, 1247, 1247, 1247, 1247, 1247, 1255, 1255, 1255, 1255,
7149 1257, 1257, 1257, 1257, 1259, 1259, 1261, 1261, 1261, 1261, 1261, 1261,
7150 1261, 1261, 1261, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263,
7151 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263,
7152 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1265, 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, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7160 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
7161 1267, 1269, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271,
7162 1271, 1271, 1271, 1271, 1271, 1273, 1275, 1275, 1275, 1275, 1275, 1275,
7163 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7164 1275, 1275, 1275, 1275, 1275},
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, 0, 0, 0, 0, 0, 0, 0,
7174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7175 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
7176 {1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7177 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7178 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
7179 1275, 1275, 1275, 1275, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
7180 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
7181 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
7182 1281, 1283, 1283, 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, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7191 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
7192 1285, 1285, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
7193 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1289, 1289, 1289, 1291, 1291,
7194 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7195 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7196 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7197 1291, 1291, 1291, 1291, 1291},
7198 {1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7199 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7200 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
7201 1291, 1291, 1291, 1291, 1291, 1293, 1293, 1293, 1293, 1293, 1293, 1293,
7202 1293, 1295, 1295, 1295, 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, 1297, 1297, 1297, 1297,
7213 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297,
7214 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 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, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7218 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7219 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 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
7225 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301,
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, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7231 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
7232 1307, 1307, 1307, 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, 1309, 1309, 1309, 1309, 1309,
7235 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
7236 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1313, 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, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7240 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7241 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, 1315,
7246 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315,
7247 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 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 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7257 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317,
7258 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1325, 1325, 1325, 1325, 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, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7262 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7263 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, 1327,
7268 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327,
7269 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1331,
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, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7281 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333,
7282 1333, 1333, 1339, 1339, 1339, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7283 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7284 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7285 1341, 1341, 1341, 1341, 1341},
7286 {1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7287 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7288 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
7289 1341, 1341, 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, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7306 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
7307 1343, 1343, 1343, 1343, 1343},
7308 {1343, 1343, 1343, 1343, 1343, 1343, 1345, 1345, 1347, 1347, 1349, 1349,
7309 1351, 1351, 1353, 1353, 1353, 1353, 1355, 1355, 1355, 1355, 1355, 1355,
7310 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355,
7311 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355,
7312 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1357,
7313 1357, 1359, 1359, 1361, 1363, 1363, 1363, 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, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7328 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7329 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, 1365, 1365, 1365, 1365, 1365,
7333 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365,
7334 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1367, 1369, 1369, 1369, 1369,
7335 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369,
7336 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369,
7337 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1371, 1373, 1373, 1373, 1373,
7338 1373, 1373, 1373, 1375, 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, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7342 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377,
7343 1377, 1377, 1377, 1377, 1377, 1381, 1385, 1385, 1385, 1385, 1385, 1385,
7344 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
7345 1385, 1385, 1385, 1385, 1385, 1387, 1389, 1389, 1389, 1389, 1389, 1389,
7346 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389,
7347 1389, 1391, 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, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7350 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393,
7351 1393, 1393, 1393, 1393, 1393},
7352 {1393, 1401, 1409, 1411, 1413, 1415, 1417, 1419, 1421, 1429, 1437, 1439,
7353 1441, 1443, 1445, 1447, 1449, 1453, 1457, 1457, 1457, 1457, 1457, 1457,
7354 1457, 1461, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1473, 1481, 1483,
7355 1485, 1487, 1489, 1491, 1493, 1501, 1509, 1511, 1513, 1515, 1517, 1519,
7356 1521, 1527, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1539, 1545, 1545,
7357 1545, 1545, 1545, 1545, 1545, 1549, 1553, 1553, 1553, 1553, 1553, 1553,
7358 1553, 1557, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1567, 1573, 1573,
7359 1573, 1573, 1573, 1573, 1573, 1573, 1579, 1579, 1579, 1579, 1579, 1579,
7360 1579, 1587, 1595, 1597, 1599, 1601, 1603, 1605, 1607, 1615, 1623, 1625,
7361 1627, 1629, 1631, 1633, 1635, 1637, 1637, 1637, 1637, 1639, 1639, 1639,
7362 1639, 1639, 1639, 1639, 1639, 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, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7366 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
7367 1641, 1641, 1641, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643,
7368 1649, 1649, 1649, 1649, 1649, 1649, 1649, 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, 1651, 1651, 1651, 1651, 1651,
7371 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651,
7372 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1653, 1653, 1653, 1653, 1653,
7373 1653, 1653, 1653, 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, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7385 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
7386 1659, 1661, 1661, 1663, 1663, 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, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7390 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665,
7391 1665, 1665, 1665, 1665, 1665, 1667, 1667, 1669, 1669, 1671, 1671, 1671,
7392 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
7393 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
7394 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
7395 1671, 1671, 1671, 1671, 1671},
7396 {1671, 1671, 1671, 1671, 1673, 1673, 1673, 1673, 1673, 1675, 1675, 1675,
7397 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
7398 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
7399 1679, 1679, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
7400 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
7401 1681, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1685, 1685, 1687, 1687,
7402 1687, 1689, 1689, 1689, 1689, 1689, 1691, 1691, 1691, 1691, 1691, 1691,
7403 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691,
7404 1691, 1691, 1693, 1693, 1693, 1695, 1697, 1697, 1697, 1697, 1697, 1697,
7405 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1699, 1701, 1701, 1701, 1703,
7406 1705, 1705, 1705, 1707, 1709, 1711, 1713, 1713, 1713, 1713, 1713, 1715,
7407 1717, 1717, 1717, 1719, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721,
7408 1721, 1721, 1723, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725,
7409 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1727, 1727, 1727, 1727, 1727,
7410 1727, 1729, 1731, 1731, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1735,
7411 1737, 1739, 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, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7416 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7417 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, 1741,
7422 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
7423 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1743,
7424 1743, 1743, 1743, 1743, 1745, 1745, 1747, 1747, 1749, 1749, 1751, 1751,
7425 1753, 1753, 1755, 1755, 1757, 1757, 1759, 1759, 1761, 1761, 1763, 1763,
7426 1765, 1765, 1767, 1767, 1767, 1769, 1769, 1771, 1771, 1773, 1773, 1773,
7427 1773, 1773, 1773, 1773, 1777, 1777, 1777, 1781, 1781, 1781, 1785, 1785,
7428 1785, 1789, 1789, 1789, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,
7429 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,
7430 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793,
7431 1793, 1793, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1797,
7432 1797, 1797, 1797, 1797, 1799, 1799, 1801, 1801, 1803, 1803, 1805, 1805,
7433 1807, 1807, 1809, 1809, 1811, 1811, 1813, 1813, 1815, 1815, 1817, 1817,
7434 1819, 1819, 1821, 1821, 1821, 1823, 1823, 1825, 1825, 1827, 1827, 1827,
7435 1827, 1827, 1827, 1827, 1831, 1831, 1831, 1835, 1835, 1835, 1839, 1839,
7436 1839, 1843, 1843, 1843, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
7437 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
7438 1849, 1851, 1853, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855,
7439 1855, 1855, 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, 1857, 1857,
7451 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857,
7452 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1859, 1859,
7453 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 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, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7460 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7461 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, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7465 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
7466 1863, 1863, 1865, 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, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7482 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7483 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 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
7489 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867,
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, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7504 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7505 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, 1871, 1871, 1871, 1871, 1871, 1871,
7520 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871,
7521 1871, 1871, 1871, 1871, 1871, 1871, 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, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7526 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7527 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, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7542 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
7543 1877, 1877, 1877, 1877, 1877, 1879, 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, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7548 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7549 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, 1881, 1881, 1881, 1881, 1881, 1881,
7553 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881,
7554 1881, 1881, 1881, 1881, 1881, 1881, 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, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7570 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883,
7571 1883, 1883, 1883, 1883, 1883}};
7572 const char32_t composition_data[1883] = {
7573 0, 824, 8814, 824, 8800, 824, 8815, 768, 192, 769, 193,
7574 770, 194, 771, 195, 772, 256, 774, 258, 775, 550, 776,
7575 196, 777, 7842, 778, 197, 780, 461, 783, 512, 785, 514,
7576 803, 7840, 805, 7680, 808, 260, 775, 7682, 803, 7684, 817,
7577 7686, 769, 262, 770, 264, 775, 266, 780, 268, 807, 199,
7578 775, 7690, 780, 270, 803, 7692, 807, 7696, 813, 7698, 817,
7579 7694, 768, 200, 769, 201, 770, 202, 771, 7868, 772, 274,
7580 774, 276, 775, 278, 776, 203, 777, 7866, 780, 282, 783,
7581 516, 785, 518, 803, 7864, 807, 552, 808, 280, 813, 7704,
7582 816, 7706, 775, 7710, 769, 500, 770, 284, 772, 7712, 774,
7583 286, 775, 288, 780, 486, 807, 290, 770, 292, 775, 7714,
7584 776, 7718, 780, 542, 803, 7716, 807, 7720, 814, 7722, 768,
7585 204, 769, 205, 770, 206, 771, 296, 772, 298, 774, 300,
7586 775, 304, 776, 207, 777, 7880, 780, 463, 783, 520, 785,
7587 522, 803, 7882, 808, 302, 816, 7724, 770, 308, 769, 7728,
7588 780, 488, 803, 7730, 807, 310, 817, 7732, 769, 313, 780,
7589 317, 803, 7734, 807, 315, 813, 7740, 817, 7738, 769, 7742,
7590 775, 7744, 803, 7746, 768, 504, 769, 323, 771, 209, 775,
7591 7748, 780, 327, 803, 7750, 807, 325, 813, 7754, 817, 7752,
7592 768, 210, 769, 211, 770, 212, 771, 213, 772, 332, 774,
7593 334, 775, 558, 776, 214, 777, 7886, 779, 336, 780, 465,
7594 783, 524, 785, 526, 795, 416, 803, 7884, 808, 490, 769,
7595 7764, 775, 7766, 769, 340, 775, 7768, 780, 344, 783, 528,
7596 785, 530, 803, 7770, 807, 342, 817, 7774, 769, 346, 770,
7597 348, 775, 7776, 780, 352, 803, 7778, 806, 536, 807, 350,
7598 775, 7786, 780, 356, 803, 7788, 806, 538, 807, 354, 813,
7599 7792, 817, 7790, 768, 217, 769, 218, 770, 219, 771, 360,
7600 772, 362, 774, 364, 776, 220, 777, 7910, 778, 366, 779,
7601 368, 780, 467, 783, 532, 785, 534, 795, 431, 803, 7908,
7602 804, 7794, 808, 370, 813, 7798, 816, 7796, 771, 7804, 803,
7603 7806, 768, 7808, 769, 7810, 770, 372, 775, 7814, 776, 7812,
7604 803, 7816, 775, 7818, 776, 7820, 768, 7922, 769, 221, 770,
7605 374, 771, 7928, 772, 562, 775, 7822, 776, 376, 777, 7926,
7606 803, 7924, 769, 377, 770, 7824, 775, 379, 780, 381, 803,
7607 7826, 817, 7828, 768, 224, 769, 225, 770, 226, 771, 227,
7608 772, 257, 774, 259, 775, 551, 776, 228, 777, 7843, 778,
7609 229, 780, 462, 783, 513, 785, 515, 803, 7841, 805, 7681,
7610 808, 261, 775, 7683, 803, 7685, 817, 7687, 769, 263, 770,
7611 265, 775, 267, 780, 269, 807, 231, 775, 7691, 780, 271,
7612 803, 7693, 807, 7697, 813, 7699, 817, 7695, 768, 232, 769,
7613 233, 770, 234, 771, 7869, 772, 275, 774, 277, 775, 279,
7614 776, 235, 777, 7867, 780, 283, 783, 517, 785, 519, 803,
7615 7865, 807, 553, 808, 281, 813, 7705, 816, 7707, 775, 7711,
7616 769, 501, 770, 285, 772, 7713, 774, 287, 775, 289, 780,
7617 487, 807, 291, 770, 293, 775, 7715, 776, 7719, 780, 543,
7618 803, 7717, 807, 7721, 814, 7723, 817, 7830, 768, 236, 769,
7619 237, 770, 238, 771, 297, 772, 299, 774, 301, 776, 239,
7620 777, 7881, 780, 464, 783, 521, 785, 523, 803, 7883, 808,
7621 303, 816, 7725, 770, 309, 780, 496, 769, 7729, 780, 489,
7622 803, 7731, 807, 311, 817, 7733, 769, 314, 780, 318, 803,
7623 7735, 807, 316, 813, 7741, 817, 7739, 769, 7743, 775, 7745,
7624 803, 7747, 768, 505, 769, 324, 771, 241, 775, 7749, 780,
7625 328, 803, 7751, 807, 326, 813, 7755, 817, 7753, 768, 242,
7626 769, 243, 770, 244, 771, 245, 772, 333, 774, 335, 775,
7627 559, 776, 246, 777, 7887, 779, 337, 780, 466, 783, 525,
7628 785, 527, 795, 417, 803, 7885, 808, 491, 769, 7765, 775,
7629 7767, 769, 341, 775, 7769, 780, 345, 783, 529, 785, 531,
7630 803, 7771, 807, 343, 817, 7775, 769, 347, 770, 349, 775,
7631 7777, 780, 353, 803, 7779, 806, 537, 807, 351, 775, 7787,
7632 776, 7831, 780, 357, 803, 7789, 806, 539, 807, 355, 813,
7633 7793, 817, 7791, 768, 249, 769, 250, 770, 251, 771, 361,
7634 772, 363, 774, 365, 776, 252, 777, 7911, 778, 367, 779,
7635 369, 780, 468, 783, 533, 785, 535, 795, 432, 803, 7909,
7636 804, 7795, 808, 371, 813, 7799, 816, 7797, 771, 7805, 803,
7637 7807, 768, 7809, 769, 7811, 770, 373, 775, 7815, 776, 7813,
7638 778, 7832, 803, 7817, 775, 7819, 776, 7821, 768, 7923, 769,
7639 253, 770, 375, 771, 7929, 772, 563, 775, 7823, 776, 255,
7640 777, 7927, 778, 7833, 803, 7925, 769, 378, 770, 7825, 775,
7641 380, 780, 382, 803, 7827, 817, 7829, 768, 8173, 769, 901,
7642 834, 8129, 768, 7846, 769, 7844, 771, 7850, 777, 7848, 772,
7643 478, 769, 506, 769, 508, 772, 482, 769, 7688, 768, 7872,
7644 769, 7870, 771, 7876, 777, 7874, 769, 7726, 768, 7890, 769,
7645 7888, 771, 7894, 777, 7892, 769, 7756, 772, 556, 776, 7758,
7646 772, 554, 769, 510, 768, 475, 769, 471, 772, 469, 780,
7647 473, 768, 7847, 769, 7845, 771, 7851, 777, 7849, 772, 479,
7648 769, 507, 769, 509, 772, 483, 769, 7689, 768, 7873, 769,
7649 7871, 771, 7877, 777, 7875, 769, 7727, 768, 7891, 769, 7889,
7650 771, 7895, 777, 7893, 769, 7757, 772, 557, 776, 7759, 772,
7651 555, 769, 511, 768, 476, 769, 472, 772, 470, 780, 474,
7652 768, 7856, 769, 7854, 771, 7860, 777, 7858, 768, 7857, 769,
7653 7855, 771, 7861, 777, 7859, 768, 7700, 769, 7702, 768, 7701,
7654 769, 7703, 768, 7760, 769, 7762, 768, 7761, 769, 7763, 775,
7655 7780, 775, 7781, 775, 7782, 775, 7783, 769, 7800, 769, 7801,
7656 776, 7802, 776, 7803, 775, 7835, 768, 7900, 769, 7898, 771,
7657 7904, 777, 7902, 803, 7906, 768, 7901, 769, 7899, 771, 7905,
7658 777, 7903, 803, 7907, 768, 7914, 769, 7912, 771, 7918, 777,
7659 7916, 803, 7920, 768, 7915, 769, 7913, 771, 7919, 777, 7917,
7660 803, 7921, 780, 494, 772, 492, 772, 493, 772, 480, 772,
7661 481, 774, 7708, 774, 7709, 772, 560, 772, 561, 780, 495,
7662 768, 8122, 769, 902, 772, 8121, 774, 8120, 787, 7944, 788,
7663 7945, 837, 8124, 768, 8136, 769, 904, 787, 7960, 788, 7961,
7664 768, 8138, 769, 905, 787, 7976, 788, 7977, 837, 8140, 768,
7665 8154, 769, 906, 772, 8153, 774, 8152, 776, 938, 787, 7992,
7666 788, 7993, 768, 8184, 769, 908, 787, 8008, 788, 8009, 788,
7667 8172, 768, 8170, 769, 910, 772, 8169, 774, 8168, 776, 939,
7668 788, 8025, 768, 8186, 769, 911, 787, 8040, 788, 8041, 837,
7669 8188, 837, 8116, 837, 8132, 768, 8048, 769, 940, 772, 8113,
7670 774, 8112, 787, 7936, 788, 7937, 834, 8118, 837, 8115, 768,
7671 8050, 769, 941, 787, 7952, 788, 7953, 768, 8052, 769, 942,
7672 787, 7968, 788, 7969, 834, 8134, 837, 8131, 768, 8054, 769,
7673 943, 772, 8145, 774, 8144, 776, 970, 787, 7984, 788, 7985,
7674 834, 8150, 768, 8056, 769, 972, 787, 8000, 788, 8001, 787,
7675 8164, 788, 8165, 768, 8058, 769, 973, 772, 8161, 774, 8160,
7676 776, 971, 787, 8016, 788, 8017, 834, 8166, 768, 8060, 769,
7677 974, 787, 8032, 788, 8033, 834, 8182, 837, 8179, 768, 8146,
7678 769, 912, 834, 8151, 768, 8162, 769, 944, 834, 8167, 837,
7679 8180, 769, 979, 776, 980, 776, 1031, 774, 1232, 776, 1234,
7680 769, 1027, 768, 1024, 774, 1238, 776, 1025, 774, 1217, 776,
7681 1244, 776, 1246, 768, 1037, 772, 1250, 774, 1049, 776, 1252,
7682 769, 1036, 776, 1254, 772, 1262, 774, 1038, 776, 1264, 779,
7683 1266, 776, 1268, 776, 1272, 776, 1260, 774, 1233, 776, 1235,
7684 769, 1107, 768, 1104, 774, 1239, 776, 1105, 774, 1218, 776,
7685 1245, 776, 1247, 768, 1117, 772, 1251, 774, 1081, 776, 1253,
7686 769, 1116, 776, 1255, 772, 1263, 774, 1118, 776, 1265, 779,
7687 1267, 776, 1269, 776, 1273, 776, 1261, 776, 1111, 783, 1142,
7688 783, 1143, 776, 1242, 776, 1243, 776, 1258, 776, 1259, 1619,
7689 1570, 1620, 1571, 1621, 1573, 1620, 1572, 1620, 1574, 1620, 1730,
7690 1620, 1747, 1620, 1728, 2364, 2345, 2364, 2353, 2364, 2356, 2494,
7691 2507, 2519, 2508, 2878, 2891, 2902, 2888, 2903, 2892, 3031, 2964,
7692 3006, 3018, 3031, 3020, 3006, 3019, 3158, 3144, 3285, 3264, 3266,
7693 3274, 3285, 3271, 3286, 3272, 3285, 3275, 3390, 3402, 3415, 3404,
7694 3390, 3403, 3530, 3546, 3535, 3548, 3551, 3550, 3530, 3549, 4142,
7695 4134, 6965, 6918, 6965, 6920, 6965, 6922, 6965, 6924, 6965, 6926,
7696 6965, 6930, 6965, 6971, 6965, 6973, 6965, 6976, 6965, 6977, 6965,
7697 6979, 772, 7736, 772, 7737, 772, 7772, 772, 7773, 775, 7784,
7698 775, 7785, 770, 7852, 774, 7862, 770, 7853, 774, 7863, 770,
7699 7878, 770, 7879, 770, 7896, 770, 7897, 768, 7938, 769, 7940,
7700 834, 7942, 837, 8064, 768, 7939, 769, 7941, 834, 7943, 837,
7701 8065, 837, 8066, 837, 8067, 837, 8068, 837, 8069, 837, 8070,
7702 837, 8071, 768, 7946, 769, 7948, 834, 7950, 837, 8072, 768,
7703 7947, 769, 7949, 834, 7951, 837, 8073, 837, 8074, 837, 8075,
7704 837, 8076, 837, 8077, 837, 8078, 837, 8079, 768, 7954, 769,
7705 7956, 768, 7955, 769, 7957, 768, 7962, 769, 7964, 768, 7963,
7706 769, 7965, 768, 7970, 769, 7972, 834, 7974, 837, 8080, 768,
7707 7971, 769, 7973, 834, 7975, 837, 8081, 837, 8082, 837, 8083,
7708 837, 8084, 837, 8085, 837, 8086, 837, 8087, 768, 7978, 769,
7709 7980, 834, 7982, 837, 8088, 768, 7979, 769, 7981, 834, 7983,
7710 837, 8089, 837, 8090, 837, 8091, 837, 8092, 837, 8093, 837,
7711 8094, 837, 8095, 768, 7986, 769, 7988, 834, 7990, 768, 7987,
7712 769, 7989, 834, 7991, 768, 7994, 769, 7996, 834, 7998, 768,
7713 7995, 769, 7997, 834, 7999, 768, 8002, 769, 8004, 768, 8003,
7714 769, 8005, 768, 8010, 769, 8012, 768, 8011, 769, 8013, 768,
7715 8018, 769, 8020, 834, 8022, 768, 8019, 769, 8021, 834, 8023,
7716 768, 8027, 769, 8029, 834, 8031, 768, 8034, 769, 8036, 834,
7717 8038, 837, 8096, 768, 8035, 769, 8037, 834, 8039, 837, 8097,
7718 837, 8098, 837, 8099, 837, 8100, 837, 8101, 837, 8102, 837,
7719 8103, 768, 8042, 769, 8044, 834, 8046, 837, 8104, 768, 8043,
7720 769, 8045, 834, 8047, 837, 8105, 837, 8106, 837, 8107, 837,
7721 8108, 837, 8109, 837, 8110, 837, 8111, 837, 8114, 837, 8130,
7722 837, 8178, 837, 8119, 768, 8141, 769, 8142, 834, 8143, 837,
7723 8135, 837, 8183, 768, 8157, 769, 8158, 834, 8159, 824, 8602,
7724 824, 8603, 824, 8622, 824, 8653, 824, 8655, 824, 8654, 824,
7725 8708, 824, 8713, 824, 8716, 824, 8740, 824, 8742, 824, 8769,
7726 824, 8772, 824, 8775, 824, 8777, 824, 8813, 824, 8802, 824,
7727 8816, 824, 8817, 824, 8820, 824, 8821, 824, 8824, 824, 8825,
7728 824, 8832, 824, 8833, 824, 8928, 824, 8929, 824, 8836, 824,
7729 8837, 824, 8840, 824, 8841, 824, 8930, 824, 8931, 824, 8876,
7730 824, 8877, 824, 8878, 824, 8879, 824, 8938, 824, 8939, 824,
7731 8940, 824, 8941, 12441, 12436, 12441, 12364, 12441, 12366, 12441, 12368,
7732 12441, 12370, 12441, 12372, 12441, 12374, 12441, 12376, 12441, 12378, 12441,
7733 12380, 12441, 12382, 12441, 12384, 12441, 12386, 12441, 12389, 12441, 12391,
7734 12441, 12393, 12441, 12400, 12442, 12401, 12441, 12403, 12442, 12404, 12441,
7735 12406, 12442, 12407, 12441, 12409, 12442, 12410, 12441, 12412, 12442, 12413,
7736 12441, 12446, 12441, 12532, 12441, 12460, 12441, 12462, 12441, 12464, 12441,
7737 12466, 12441, 12468, 12441, 12470, 12441, 12472, 12441, 12474, 12441, 12476,
7738 12441, 12478, 12441, 12480, 12441, 12482, 12441, 12485, 12441, 12487, 12441,
7739 12489, 12441, 12496, 12442, 12497, 12441, 12499, 12442, 12500, 12441, 12502,
7740 12442, 12503, 12441, 12505, 12442, 12506, 12441, 12508, 12442, 12509, 12441,
7741 12535, 12441, 12536, 12441, 12537, 12441, 12538, 12441, 12542, 69818, 69786,
7742 69818, 69788, 69818, 69803, 69927, 69934, 69927, 69935, 70462, 70475, 70487,
7743 70476, 70832, 70844, 70842, 70843, 70845, 70846, 71087, 71098, 71087, 71099,
7744 71984, 71992};
7745
7746 } // namespace ada::idna
7747 #endif // ADA_IDNA_NORMALIZATION_TABLES_H
7748 /* end file src/normalization_tables.cpp */
7749
7750 namespace ada::idna {
7751
7752 // See
7753 // https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/impl_norm.h#L467
7754 constexpr char32_t hangul_sbase = 0xAC00;
7755 constexpr char32_t hangul_tbase = 0x11A7;
7756 constexpr char32_t hangul_vbase = 0x1161;
7757 constexpr char32_t hangul_lbase = 0x1100;
7758 constexpr char32_t hangul_lcount = 19;
7759 constexpr char32_t hangul_vcount = 21;
7760 constexpr char32_t hangul_tcount = 28;
7761 constexpr char32_t hangul_ncount = hangul_vcount * hangul_tcount;
7762 constexpr char32_t hangul_scount =
7763 hangul_lcount * hangul_vcount * hangul_tcount;
7764
compute_decomposition_length(const std::u32string_view input)7765 std::pair<bool, size_t> compute_decomposition_length(
7766 const std::u32string_view input) noexcept {
7767 bool decomposition_needed{false};
7768 size_t additional_elements{0};
7769 for (char32_t current_character : input) {
7770 size_t decomposition_length{0};
7771
7772 if (current_character >= hangul_sbase &&
7773 current_character < hangul_sbase + hangul_scount) {
7774 decomposition_length = 2;
7775 if ((current_character - hangul_sbase) % hangul_tcount) {
7776 decomposition_length = 3;
7777 }
7778 } else if (current_character < 0x110000) {
7779 const uint8_t di = decomposition_index[current_character >> 8];
7780 const uint16_t* const decomposition =
7781 decomposition_block[di] + (current_character % 256);
7782 decomposition_length = (decomposition[1] >> 2) - (decomposition[0] >> 2);
7783 if ((decomposition_length > 0) && (decomposition[0] & 1)) {
7784 decomposition_length = 0;
7785 }
7786 }
7787 if (decomposition_length != 0) {
7788 decomposition_needed = true;
7789 additional_elements += decomposition_length - 1;
7790 }
7791 }
7792 return {decomposition_needed, additional_elements};
7793 }
7794
decompose(std::u32string & input,size_t additional_elements)7795 void decompose(std::u32string& input, size_t additional_elements) {
7796 input.resize(input.size() + additional_elements);
7797 for (size_t descending_idx = input.size(),
7798 input_count = descending_idx - additional_elements;
7799 input_count--;) {
7800 if (input[input_count] >= hangul_sbase &&
7801 input[input_count] < hangul_sbase + hangul_scount) {
7802 // Hangul decomposition.
7803 char32_t s_index = input[input_count] - hangul_sbase;
7804 if (s_index % hangul_tcount != 0) {
7805 input[--descending_idx] = hangul_tbase + s_index % hangul_tcount;
7806 }
7807 input[--descending_idx] =
7808 hangul_vbase + (s_index % hangul_ncount) / hangul_tcount;
7809 input[--descending_idx] = hangul_lbase + s_index / hangul_ncount;
7810 } else if (input[input_count] < 0x110000) {
7811 // Check decomposition_data.
7812 const uint16_t* decomposition =
7813 decomposition_block[decomposition_index[input[input_count] >> 8]] +
7814 (input[input_count] % 256);
7815 uint16_t decomposition_length =
7816 (decomposition[1] >> 2) - (decomposition[0] >> 2);
7817 if (decomposition_length > 0 && (decomposition[0] & 1)) {
7818 decomposition_length = 0;
7819 }
7820 if (decomposition_length > 0) {
7821 // Non-recursive decomposition.
7822 while (decomposition_length-- > 0) {
7823 input[--descending_idx] = decomposition_data[(decomposition[0] >> 2) +
7824 decomposition_length];
7825 }
7826 } else {
7827 // No decomposition.
7828 input[--descending_idx] = input[input_count];
7829 }
7830 } else {
7831 // Non-Unicode character.
7832 input[--descending_idx] = input[input_count];
7833 }
7834 }
7835 }
7836
get_ccc(char32_t c)7837 uint8_t get_ccc(char32_t c) noexcept {
7838 return c < 0x110000 ? canonical_combining_class_block
7839 [canonical_combining_class_index[c >> 8]][c % 256]
7840 : 0;
7841 }
7842
sort_marks(std::u32string & input)7843 void sort_marks(std::u32string& input) {
7844 for (size_t idx = 1; idx < input.size(); idx++) {
7845 uint8_t ccc = get_ccc(input[idx]);
7846 if (ccc == 0) {
7847 continue;
7848 } // Skip non-combining characters.
7849 auto current_character = input[idx];
7850 size_t back_idx = idx;
7851 while (back_idx != 0 && get_ccc(input[back_idx - 1]) > ccc) {
7852 input[back_idx] = input[back_idx - 1];
7853 back_idx--;
7854 }
7855 input[back_idx] = current_character;
7856 }
7857 }
7858
decompose_nfc(std::u32string & input)7859 void decompose_nfc(std::u32string& input) {
7860 /**
7861 * Decompose the domain_name string to Unicode Normalization Form C.
7862 * @see https://www.unicode.org/reports/tr46/#ProcessingStepDecompose
7863 */
7864 auto [decomposition_needed, additional_elements] =
7865 compute_decomposition_length(input);
7866 if (decomposition_needed) {
7867 decompose(input, additional_elements);
7868 }
7869 sort_marks(input);
7870 }
7871
compose(std::u32string & input)7872 void compose(std::u32string& input) {
7873 /**
7874 * Compose the domain_name string to Unicode Normalization Form C.
7875 * @see https://www.unicode.org/reports/tr46/#ProcessingStepCompose
7876 */
7877 size_t input_count{0};
7878 size_t composition_count{0};
7879 for (; input_count < input.size(); input_count++, composition_count++) {
7880 input[composition_count] = input[input_count];
7881 if (input[input_count] >= hangul_lbase &&
7882 input[input_count] < hangul_lbase + hangul_lcount) {
7883 if (input_count + 1 < input.size() &&
7884 input[input_count + 1] >= hangul_vbase &&
7885 input[input_count + 1] < hangul_vbase + hangul_vcount) {
7886 input[composition_count] =
7887 hangul_sbase +
7888 ((input[input_count] - hangul_lbase) * hangul_vcount +
7889 input[input_count + 1] - hangul_vbase) *
7890 hangul_tcount;
7891 input_count++;
7892 if (input_count + 1 < input.size() &&
7893 input[input_count + 1] > hangul_tbase &&
7894 input[input_count + 1] < hangul_tbase + hangul_tcount) {
7895 input[composition_count] += input[++input_count] - hangul_tbase;
7896 }
7897 }
7898 } else if (input[input_count] >= hangul_sbase &&
7899 input[input_count] < hangul_sbase + hangul_scount) {
7900 if ((input[input_count] - hangul_sbase) % hangul_tcount &&
7901 input_count + 1 < input.size() &&
7902 input[input_count + 1] > hangul_tbase &&
7903 input[input_count + 1] < hangul_tbase + hangul_tcount) {
7904 input[composition_count] += input[++input_count] - hangul_tbase;
7905 }
7906 } else if (input[input_count] < 0x110000) {
7907 const uint16_t* composition =
7908 &composition_block[composition_index[input[input_count] >> 8]]
7909 [input[input_count] % 256];
7910 size_t initial_composition_count = composition_count;
7911 for (int32_t previous_ccc = -1; input_count + 1 < input.size();
7912 input_count++) {
7913 uint8_t ccc = get_ccc(input[input_count + 1]);
7914
7915 if (composition[1] != composition[0] && previous_ccc < ccc) {
7916 // Try finding a composition.
7917 uint16_t left = composition[0];
7918 uint16_t right = composition[1];
7919 while (left + 2 < right) {
7920 // mean without overflow
7921 uint16_t middle = left + (((right - left) >> 1) & ~1);
7922 if (composition_data[middle] <= input[input_count + 1]) {
7923 left = middle;
7924 }
7925 if (composition_data[middle] >= input[input_count + 1]) {
7926 right = middle;
7927 }
7928 }
7929 if (composition_data[left] == input[input_count + 1]) {
7930 input[initial_composition_count] = composition_data[left + 1];
7931 composition =
7932 &composition_block
7933 [composition_index[composition_data[left + 1] >> 8]]
7934 [composition_data[left + 1] % 256];
7935 continue;
7936 }
7937 }
7938
7939 if (ccc == 0) {
7940 break;
7941 } // Not a combining character.
7942 previous_ccc = ccc;
7943 input[++composition_count] = input[input_count + 1];
7944 }
7945 }
7946 }
7947
7948 if (composition_count < input_count) {
7949 input.resize(composition_count);
7950 }
7951 }
7952
normalize(std::u32string & input)7953 void normalize(std::u32string& input) {
7954 /**
7955 * Normalize the domain_name string to Unicode Normalization Form C.
7956 * @see https://www.unicode.org/reports/tr46/#ProcessingStepNormalize
7957 */
7958 decompose_nfc(input);
7959 compose(input);
7960 }
7961
7962 } // namespace ada::idna
7963 /* end file src/normalization.cpp */
7964 /* begin file src/punycode.cpp */
7965
7966 #include <cstdint>
7967
7968 namespace ada::idna {
7969
7970 constexpr int32_t base = 36;
7971 constexpr int32_t tmin = 1;
7972 constexpr int32_t tmax = 26;
7973 constexpr int32_t skew = 38;
7974 constexpr int32_t damp = 700;
7975 constexpr int32_t initial_bias = 72;
7976 constexpr uint32_t initial_n = 128;
7977
char_to_digit_value(char value)7978 static constexpr int32_t char_to_digit_value(char value) {
7979 if (value >= 'a' && value <= 'z') return value - 'a';
7980 if (value >= '0' && value <= '9') return value - '0' + 26;
7981 return -1;
7982 }
7983
digit_to_char(int32_t digit)7984 static constexpr char digit_to_char(int32_t digit) {
7985 return digit < 26 ? char(digit + 97) : char(digit + 22);
7986 }
7987
adapt(int32_t d,int32_t n,bool firsttime)7988 static constexpr int32_t adapt(int32_t d, int32_t n, bool firsttime) {
7989 if (firsttime) {
7990 d = d / damp;
7991 } else {
7992 d = d / 2;
7993 }
7994 d += d / n;
7995 int32_t k = 0;
7996 while (d > ((base - tmin) * tmax) / 2) {
7997 d /= base - tmin;
7998 k += base;
7999 }
8000 return k + (((base - tmin + 1) * d) / (d + skew));
8001 }
8002
punycode_to_utf32(std::string_view input,std::u32string & out)8003 bool punycode_to_utf32(std::string_view input, std::u32string &out) {
8004 int32_t written_out{0};
8005 out.reserve(out.size() + input.size());
8006 uint32_t n = initial_n;
8007 int32_t i = 0;
8008 int32_t bias = initial_bias;
8009 // grab ascii content
8010 size_t end_of_ascii = input.find_last_of('-');
8011 if (end_of_ascii != std::string_view::npos) {
8012 for (uint8_t c : input.substr(0, end_of_ascii)) {
8013 if (c >= 0x80) {
8014 return false;
8015 }
8016 out.push_back(c);
8017 written_out++;
8018 }
8019 input.remove_prefix(end_of_ascii + 1);
8020 }
8021 while (!input.empty()) {
8022 int32_t oldi = i;
8023 int32_t w = 1;
8024 for (int32_t k = base;; k += base) {
8025 if (input.empty()) {
8026 return false;
8027 }
8028 uint8_t code_point = input.front();
8029 input.remove_prefix(1);
8030 int32_t digit = char_to_digit_value(code_point);
8031 if (digit < 0) {
8032 return false;
8033 }
8034 if (digit > (0x7fffffff - i) / w) {
8035 return false;
8036 }
8037 i = i + digit * w;
8038 int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
8039 if (digit < t) {
8040 break;
8041 }
8042 if (w > 0x7fffffff / (base - t)) {
8043 return false;
8044 }
8045 w = w * (base - t);
8046 }
8047 bias = adapt(i - oldi, written_out + 1, oldi == 0);
8048 if (i / (written_out + 1) > int32_t(0x7fffffff - n)) {
8049 return false;
8050 }
8051 n = n + i / (written_out + 1);
8052 i = i % (written_out + 1);
8053 if (n < 0x80) {
8054 return false;
8055 }
8056 out.insert(out.begin() + i, n);
8057 written_out++;
8058 ++i;
8059 }
8060
8061 return true;
8062 }
8063
verify_punycode(std::string_view input)8064 bool verify_punycode(std::string_view input) {
8065 size_t written_out{0};
8066 uint32_t n = initial_n;
8067 int32_t i = 0;
8068 int32_t bias = initial_bias;
8069 // grab ascii content
8070 size_t end_of_ascii = input.find_last_of('-');
8071 if (end_of_ascii != std::string_view::npos) {
8072 for (uint8_t c : input.substr(0, end_of_ascii)) {
8073 if (c >= 0x80) {
8074 return false;
8075 }
8076 written_out++;
8077 }
8078 input.remove_prefix(end_of_ascii + 1);
8079 }
8080 while (!input.empty()) {
8081 int32_t oldi = i;
8082 int32_t w = 1;
8083 for (int32_t k = base;; k += base) {
8084 if (input.empty()) {
8085 return false;
8086 }
8087 uint8_t code_point = input.front();
8088 input.remove_prefix(1);
8089 int32_t digit = char_to_digit_value(code_point);
8090 if (digit < 0) {
8091 return false;
8092 }
8093 if (digit > (0x7fffffff - i) / w) {
8094 return false;
8095 }
8096 i = i + digit * w;
8097 int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
8098 if (digit < t) {
8099 break;
8100 }
8101 if (w > 0x7fffffff / (base - t)) {
8102 return false;
8103 }
8104 w = w * (base - t);
8105 }
8106 bias = adapt(i - oldi, int32_t(written_out + 1), oldi == 0);
8107 if (i / (written_out + 1) > 0x7fffffff - n) {
8108 return false;
8109 }
8110 n = n + i / int32_t(written_out + 1);
8111 i = i % int32_t(written_out + 1);
8112 if (n < 0x80) {
8113 return false;
8114 }
8115 written_out++;
8116 ++i;
8117 }
8118
8119 return true;
8120 }
8121
utf32_to_punycode(std::u32string_view input,std::string & out)8122 bool utf32_to_punycode(std::u32string_view input, std::string &out) {
8123 out.reserve(input.size() + out.size());
8124 uint32_t n = initial_n;
8125 int32_t d = 0;
8126 int32_t bias = initial_bias;
8127 size_t h = 0;
8128 // first push the ascii content
8129 for (uint32_t c : input) {
8130 if (c < 0x80) {
8131 ++h;
8132 out.push_back(char(c));
8133 }
8134 if (c > 0x10ffff || (c >= 0xd880 && c < 0xe000)) {
8135 return false;
8136 }
8137 }
8138 size_t b = h;
8139 if (b > 0) {
8140 out.push_back('-');
8141 }
8142 while (h < input.size()) {
8143 uint32_t m = 0x10FFFF;
8144 for (auto code_point : input) {
8145 if (code_point >= n && code_point < m) m = code_point;
8146 }
8147
8148 if ((m - n) > (0x7fffffff - d) / (h + 1)) {
8149 return false;
8150 }
8151 d = d + int32_t((m - n) * (h + 1));
8152 n = m;
8153 for (auto c : input) {
8154 if (c < n) {
8155 if (d == 0x7fffffff) {
8156 return false;
8157 }
8158 ++d;
8159 }
8160 if (c == n) {
8161 int32_t q = d;
8162 for (int32_t k = base;; k += base) {
8163 int32_t t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
8164
8165 if (q < t) {
8166 break;
8167 }
8168 out.push_back(digit_to_char(t + ((q - t) % (base - t))));
8169 q = (q - t) / (base - t);
8170 }
8171 out.push_back(digit_to_char(q));
8172 bias = adapt(d, int32_t(h + 1), h == b);
8173 d = 0;
8174 ++h;
8175 }
8176 }
8177 ++d;
8178 ++n;
8179 }
8180 return true;
8181 }
8182
8183 } // namespace ada::idna
8184 /* end file src/punycode.cpp */
8185 /* begin file src/validity.cpp */
8186 #include <algorithm>
8187 #include <string_view>
8188
8189 namespace ada::idna {
8190
8191 enum direction : uint8_t {
8192 NONE,
8193 BN,
8194 CS,
8195 ES,
8196 ON,
8197 EN,
8198 L,
8199 R,
8200 NSM,
8201 AL,
8202 AN,
8203 ET,
8204 WS,
8205 RLO,
8206 LRO,
8207 PDF,
8208 RLE,
8209 RLI,
8210 FSI,
8211 PDI,
8212 LRI,
8213 B,
8214 S,
8215 LRE
8216 };
8217
8218 struct directions {
8219 uint32_t start_code;
8220 uint32_t final_code;
8221 direction direct;
8222 };
8223
8224 static directions dir_table[] = {
8225 {0x0, 0x8, direction::BN}, {0x9, 0x9, direction::S},
8226 {0xa, 0xa, direction::B}, {0xb, 0xb, direction::S},
8227 {0xc, 0xc, direction::WS}, {0xd, 0xd, direction::B},
8228 {0xe, 0x1b, direction::BN}, {0x1c, 0x1e, direction::B},
8229 {0x1f, 0x1f, direction::S}, {0x20, 0x20, direction::WS},
8230 {0x21, 0x22, direction::ON}, {0x23, 0x25, direction::ET},
8231 {0x26, 0x2a, direction::ON}, {0x2b, 0x2b, direction::ES},
8232 {0x2c, 0x2c, direction::CS}, {0x2d, 0x2d, direction::ES},
8233 {0x2e, 0x2f, direction::CS}, {0x30, 0x39, direction::EN},
8234 {0x3a, 0x3a, direction::CS}, {0x3b, 0x40, direction::ON},
8235 {0x41, 0x5a, direction::L}, {0x5b, 0x60, direction::ON},
8236 {0x61, 0x7a, direction::L}, {0x7b, 0x7e, direction::ON},
8237 {0x7f, 0x84, direction::BN}, {0x85, 0x85, direction::B},
8238 {0x86, 0x9f, direction::BN}, {0xa0, 0xa0, direction::CS},
8239 {0xa1, 0xa1, direction::ON}, {0xa2, 0xa5, direction::ET},
8240 {0xa6, 0xa9, direction::ON}, {0xaa, 0xaa, direction::L},
8241 {0xab, 0xac, direction::ON}, {0xad, 0xad, direction::BN},
8242 {0xae, 0xaf, direction::ON}, {0xb0, 0xb1, direction::ET},
8243 {0xb2, 0xb3, direction::EN}, {0xb4, 0xb4, direction::ON},
8244 {0xb5, 0xb5, direction::L}, {0xb6, 0xb8, direction::ON},
8245 {0xb9, 0xb9, direction::EN}, {0xba, 0xba, direction::L},
8246 {0xbb, 0xbf, direction::ON}, {0xc0, 0xd6, direction::L},
8247 {0xd7, 0xd7, direction::ON}, {0xd8, 0xf6, direction::L},
8248 {0xf7, 0xf7, direction::ON}, {0xf8, 0x2b8, direction::L},
8249 {0x2b9, 0x2ba, direction::ON}, {0x2bb, 0x2c1, direction::L},
8250 {0x2c2, 0x2cf, direction::ON}, {0x2d0, 0x2d1, direction::L},
8251 {0x2d2, 0x2df, direction::ON}, {0x2e0, 0x2e4, direction::L},
8252 {0x2e5, 0x2ed, direction::ON}, {0x2ee, 0x2ee, direction::L},
8253 {0x2ef, 0x2ff, direction::ON}, {0x300, 0x36f, direction::NSM},
8254 {0x370, 0x373, direction::L}, {0x374, 0x375, direction::ON},
8255 {0x376, 0x377, direction::L}, {0x37a, 0x37d, direction::L},
8256 {0x37e, 0x37e, direction::ON}, {0x37f, 0x37f, direction::L},
8257 {0x384, 0x385, direction::ON}, {0x386, 0x386, direction::L},
8258 {0x387, 0x387, direction::ON}, {0x388, 0x38a, direction::L},
8259 {0x38c, 0x38c, direction::L}, {0x38e, 0x3a1, direction::L},
8260 {0x3a3, 0x3f5, direction::L}, {0x3f6, 0x3f6, direction::ON},
8261 {0x3f7, 0x482, direction::L}, {0x483, 0x489, direction::NSM},
8262 {0x48a, 0x52f, direction::L}, {0x531, 0x556, direction::L},
8263 {0x559, 0x589, direction::L}, {0x58a, 0x58a, direction::ON},
8264 {0x58d, 0x58e, direction::ON}, {0x58f, 0x58f, direction::ET},
8265 {0x591, 0x5bd, direction::NSM}, {0x5be, 0x5be, direction::R},
8266 {0x5bf, 0x5bf, direction::NSM}, {0x5c0, 0x5c0, direction::R},
8267 {0x5c1, 0x5c2, direction::NSM}, {0x5c3, 0x5c3, direction::R},
8268 {0x5c4, 0x5c5, direction::NSM}, {0x5c6, 0x5c6, direction::R},
8269 {0x5c7, 0x5c7, direction::NSM}, {0x5d0, 0x5ea, direction::R},
8270 {0x5ef, 0x5f4, direction::R}, {0x600, 0x605, direction::AN},
8271 {0x606, 0x607, direction::ON}, {0x608, 0x608, direction::AL},
8272 {0x609, 0x60a, direction::ET}, {0x60b, 0x60b, direction::AL},
8273 {0x60c, 0x60c, direction::CS}, {0x60d, 0x60d, direction::AL},
8274 {0x60e, 0x60f, direction::ON}, {0x610, 0x61a, direction::NSM},
8275 {0x61b, 0x61c, direction::AL}, {0x61e, 0x64a, direction::AL},
8276 {0x64b, 0x65f, direction::NSM}, {0x660, 0x669, direction::AN},
8277 {0x66a, 0x66a, direction::ET}, {0x66b, 0x66c, direction::AN},
8278 {0x66d, 0x66f, direction::AL}, {0x670, 0x670, direction::NSM},
8279 {0x671, 0x6d5, direction::AL}, {0x6d6, 0x6dc, direction::NSM},
8280 {0x6dd, 0x6dd, direction::AN}, {0x6de, 0x6de, direction::ON},
8281 {0x6df, 0x6e4, direction::NSM}, {0x6e5, 0x6e6, direction::AL},
8282 {0x6e7, 0x6e8, direction::NSM}, {0x6e9, 0x6e9, direction::ON},
8283 {0x6ea, 0x6ed, direction::NSM}, {0x6ee, 0x6ef, direction::AL},
8284 {0x6f0, 0x6f9, direction::EN}, {0x6fa, 0x70d, direction::AL},
8285 {0x70f, 0x710, direction::AL}, {0x711, 0x711, direction::NSM},
8286 {0x712, 0x72f, direction::AL}, {0x730, 0x74a, direction::NSM},
8287 {0x74d, 0x7a5, direction::AL}, {0x7a6, 0x7b0, direction::NSM},
8288 {0x7b1, 0x7b1, direction::AL}, {0x7c0, 0x7ea, direction::R},
8289 {0x7eb, 0x7f3, direction::NSM}, {0x7f4, 0x7f5, direction::R},
8290 {0x7f6, 0x7f9, direction::ON}, {0x7fa, 0x7fa, direction::R},
8291 {0x7fd, 0x7fd, direction::NSM}, {0x7fe, 0x815, direction::R},
8292 {0x816, 0x819, direction::NSM}, {0x81a, 0x81a, direction::R},
8293 {0x81b, 0x823, direction::NSM}, {0x824, 0x824, direction::R},
8294 {0x825, 0x827, direction::NSM}, {0x828, 0x828, direction::R},
8295 {0x829, 0x82d, direction::NSM}, {0x830, 0x83e, direction::R},
8296 {0x840, 0x858, direction::R}, {0x859, 0x85b, direction::NSM},
8297 {0x85e, 0x85e, direction::R}, {0x860, 0x86a, direction::AL},
8298 {0x8a0, 0x8b4, direction::AL}, {0x8b6, 0x8c7, direction::AL},
8299 {0x8d3, 0x8e1, direction::NSM}, {0x8e2, 0x8e2, direction::AN},
8300 {0x8e3, 0x902, direction::NSM}, {0x903, 0x939, direction::L},
8301 {0x93a, 0x93a, direction::NSM}, {0x93b, 0x93b, direction::L},
8302 {0x93c, 0x93c, direction::NSM}, {0x93d, 0x940, direction::L},
8303 {0x941, 0x948, direction::NSM}, {0x949, 0x94c, direction::L},
8304 {0x94d, 0x94d, direction::NSM}, {0x94e, 0x950, direction::L},
8305 {0x951, 0x957, direction::NSM}, {0x958, 0x961, direction::L},
8306 {0x962, 0x963, direction::NSM}, {0x964, 0x980, direction::L},
8307 {0x981, 0x981, direction::NSM}, {0x982, 0x983, direction::L},
8308 {0x985, 0x98c, direction::L}, {0x98f, 0x990, direction::L},
8309 {0x993, 0x9a8, direction::L}, {0x9aa, 0x9b0, direction::L},
8310 {0x9b2, 0x9b2, direction::L}, {0x9b6, 0x9b9, direction::L},
8311 {0x9bc, 0x9bc, direction::NSM}, {0x9bd, 0x9c0, direction::L},
8312 {0x9c1, 0x9c4, direction::NSM}, {0x9c7, 0x9c8, direction::L},
8313 {0x9cb, 0x9cc, direction::L}, {0x9cd, 0x9cd, direction::NSM},
8314 {0x9ce, 0x9ce, direction::L}, {0x9d7, 0x9d7, direction::L},
8315 {0x9dc, 0x9dd, direction::L}, {0x9df, 0x9e1, direction::L},
8316 {0x9e2, 0x9e3, direction::NSM}, {0x9e6, 0x9f1, direction::L},
8317 {0x9f2, 0x9f3, direction::ET}, {0x9f4, 0x9fa, direction::L},
8318 {0x9fb, 0x9fb, direction::ET}, {0x9fc, 0x9fd, direction::L},
8319 {0x9fe, 0x9fe, direction::NSM}, {0xa01, 0xa02, direction::NSM},
8320 {0xa03, 0xa03, direction::L}, {0xa05, 0xa0a, direction::L},
8321 {0xa0f, 0xa10, direction::L}, {0xa13, 0xa28, direction::L},
8322 {0xa2a, 0xa30, direction::L}, {0xa32, 0xa33, direction::L},
8323 {0xa35, 0xa36, direction::L}, {0xa38, 0xa39, direction::L},
8324 {0xa3c, 0xa3c, direction::NSM}, {0xa3e, 0xa40, direction::L},
8325 {0xa41, 0xa42, direction::NSM}, {0xa47, 0xa48, direction::NSM},
8326 {0xa4b, 0xa4d, direction::NSM}, {0xa51, 0xa51, direction::NSM},
8327 {0xa59, 0xa5c, direction::L}, {0xa5e, 0xa5e, direction::L},
8328 {0xa66, 0xa6f, direction::L}, {0xa70, 0xa71, direction::NSM},
8329 {0xa72, 0xa74, direction::L}, {0xa75, 0xa75, direction::NSM},
8330 {0xa76, 0xa76, direction::L}, {0xa81, 0xa82, direction::NSM},
8331 {0xa83, 0xa83, direction::L}, {0xa85, 0xa8d, direction::L},
8332 {0xa8f, 0xa91, direction::L}, {0xa93, 0xaa8, direction::L},
8333 {0xaaa, 0xab0, direction::L}, {0xab2, 0xab3, direction::L},
8334 {0xab5, 0xab9, direction::L}, {0xabc, 0xabc, direction::NSM},
8335 {0xabd, 0xac0, direction::L}, {0xac1, 0xac5, direction::NSM},
8336 {0xac7, 0xac8, direction::NSM}, {0xac9, 0xac9, direction::L},
8337 {0xacb, 0xacc, direction::L}, {0xacd, 0xacd, direction::NSM},
8338 {0xad0, 0xad0, direction::L}, {0xae0, 0xae1, direction::L},
8339 {0xae2, 0xae3, direction::NSM}, {0xae6, 0xaf0, direction::L},
8340 {0xaf1, 0xaf1, direction::ET}, {0xaf9, 0xaf9, direction::L},
8341 {0xafa, 0xaff, direction::NSM}, {0xb01, 0xb01, direction::NSM},
8342 {0xb02, 0xb03, direction::L}, {0xb05, 0xb0c, direction::L},
8343 {0xb0f, 0xb10, direction::L}, {0xb13, 0xb28, direction::L},
8344 {0xb2a, 0xb30, direction::L}, {0xb32, 0xb33, direction::L},
8345 {0xb35, 0xb39, direction::L}, {0xb3c, 0xb3c, direction::NSM},
8346 {0xb3d, 0xb3e, direction::L}, {0xb3f, 0xb3f, direction::NSM},
8347 {0xb40, 0xb40, direction::L}, {0xb41, 0xb44, direction::NSM},
8348 {0xb47, 0xb48, direction::L}, {0xb4b, 0xb4c, direction::L},
8349 {0xb4d, 0xb4d, direction::NSM}, {0xb55, 0xb56, direction::NSM},
8350 {0xb57, 0xb57, direction::L}, {0xb5c, 0xb5d, direction::L},
8351 {0xb5f, 0xb61, direction::L}, {0xb62, 0xb63, direction::NSM},
8352 {0xb66, 0xb77, direction::L}, {0xb82, 0xb82, direction::NSM},
8353 {0xb83, 0xb83, direction::L}, {0xb85, 0xb8a, direction::L},
8354 {0xb8e, 0xb90, direction::L}, {0xb92, 0xb95, direction::L},
8355 {0xb99, 0xb9a, direction::L}, {0xb9c, 0xb9c, direction::L},
8356 {0xb9e, 0xb9f, direction::L}, {0xba3, 0xba4, direction::L},
8357 {0xba8, 0xbaa, direction::L}, {0xbae, 0xbb9, direction::L},
8358 {0xbbe, 0xbbf, direction::L}, {0xbc0, 0xbc0, direction::NSM},
8359 {0xbc1, 0xbc2, direction::L}, {0xbc6, 0xbc8, direction::L},
8360 {0xbca, 0xbcc, direction::L}, {0xbcd, 0xbcd, direction::NSM},
8361 {0xbd0, 0xbd0, direction::L}, {0xbd7, 0xbd7, direction::L},
8362 {0xbe6, 0xbf2, direction::L}, {0xbf3, 0xbf8, direction::ON},
8363 {0xbf9, 0xbf9, direction::ET}, {0xbfa, 0xbfa, direction::ON},
8364 {0xc00, 0xc00, direction::NSM}, {0xc01, 0xc03, direction::L},
8365 {0xc04, 0xc04, direction::NSM}, {0xc05, 0xc0c, direction::L},
8366 {0xc0e, 0xc10, direction::L}, {0xc12, 0xc28, direction::L},
8367 {0xc2a, 0xc39, direction::L}, {0xc3d, 0xc3d, direction::L},
8368 {0xc3e, 0xc40, direction::NSM}, {0xc41, 0xc44, direction::L},
8369 {0xc46, 0xc48, direction::NSM}, {0xc4a, 0xc4d, direction::NSM},
8370 {0xc55, 0xc56, direction::NSM}, {0xc58, 0xc5a, direction::L},
8371 {0xc60, 0xc61, direction::L}, {0xc62, 0xc63, direction::NSM},
8372 {0xc66, 0xc6f, direction::L}, {0xc77, 0xc77, direction::L},
8373 {0xc78, 0xc7e, direction::ON}, {0xc7f, 0xc80, direction::L},
8374 {0xc81, 0xc81, direction::NSM}, {0xc82, 0xc8c, direction::L},
8375 {0xc8e, 0xc90, direction::L}, {0xc92, 0xca8, direction::L},
8376 {0xcaa, 0xcb3, direction::L}, {0xcb5, 0xcb9, direction::L},
8377 {0xcbc, 0xcbc, direction::NSM}, {0xcbd, 0xcc4, direction::L},
8378 {0xcc6, 0xcc8, direction::L}, {0xcca, 0xccb, direction::L},
8379 {0xccc, 0xccd, direction::NSM}, {0xcd5, 0xcd6, direction::L},
8380 {0xcde, 0xcde, direction::L}, {0xce0, 0xce1, direction::L},
8381 {0xce2, 0xce3, direction::NSM}, {0xce6, 0xcef, direction::L},
8382 {0xcf1, 0xcf2, direction::L}, {0xd00, 0xd01, direction::NSM},
8383 {0xd02, 0xd0c, direction::L}, {0xd0e, 0xd10, direction::L},
8384 {0xd12, 0xd3a, direction::L}, {0xd3b, 0xd3c, direction::NSM},
8385 {0xd3d, 0xd40, direction::L}, {0xd41, 0xd44, direction::NSM},
8386 {0xd46, 0xd48, direction::L}, {0xd4a, 0xd4c, direction::L},
8387 {0xd4d, 0xd4d, direction::NSM}, {0xd4e, 0xd4f, direction::L},
8388 {0xd54, 0xd61, direction::L}, {0xd62, 0xd63, direction::NSM},
8389 {0xd66, 0xd7f, direction::L}, {0xd81, 0xd81, direction::NSM},
8390 {0xd82, 0xd83, direction::L}, {0xd85, 0xd96, direction::L},
8391 {0xd9a, 0xdb1, direction::L}, {0xdb3, 0xdbb, direction::L},
8392 {0xdbd, 0xdbd, direction::L}, {0xdc0, 0xdc6, direction::L},
8393 {0xdca, 0xdca, direction::NSM}, {0xdcf, 0xdd1, direction::L},
8394 {0xdd2, 0xdd4, direction::NSM}, {0xdd6, 0xdd6, direction::NSM},
8395 {0xdd8, 0xddf, direction::L}, {0xde6, 0xdef, direction::L},
8396 {0xdf2, 0xdf4, direction::L}, {0xe01, 0xe30, direction::L},
8397 {0xe31, 0xe31, direction::NSM}, {0xe32, 0xe33, direction::L},
8398 {0xe34, 0xe3a, direction::NSM}, {0xe3f, 0xe3f, direction::ET},
8399 {0xe40, 0xe46, direction::L}, {0xe47, 0xe4e, direction::NSM},
8400 {0xe4f, 0xe5b, direction::L}, {0xe81, 0xe82, direction::L},
8401 {0xe84, 0xe84, direction::L}, {0xe86, 0xe8a, direction::L},
8402 {0xe8c, 0xea3, direction::L}, {0xea5, 0xea5, direction::L},
8403 {0xea7, 0xeb0, direction::L}, {0xeb1, 0xeb1, direction::NSM},
8404 {0xeb2, 0xeb3, direction::L}, {0xeb4, 0xebc, direction::NSM},
8405 {0xebd, 0xebd, direction::L}, {0xec0, 0xec4, direction::L},
8406 {0xec6, 0xec6, direction::L}, {0xec8, 0xecd, direction::NSM},
8407 {0xed0, 0xed9, direction::L}, {0xedc, 0xedf, direction::L},
8408 {0xf00, 0xf17, direction::L}, {0xf18, 0xf19, direction::NSM},
8409 {0xf1a, 0xf34, direction::L}, {0xf35, 0xf35, direction::NSM},
8410 {0xf36, 0xf36, direction::L}, {0xf37, 0xf37, direction::NSM},
8411 {0xf38, 0xf38, direction::L}, {0xf39, 0xf39, direction::NSM},
8412 {0xf3a, 0xf3d, direction::ON}, {0xf3e, 0xf47, direction::L},
8413 {0xf49, 0xf6c, direction::L}, {0xf71, 0xf7e, direction::NSM},
8414 {0xf7f, 0xf7f, direction::L}, {0xf80, 0xf84, direction::NSM},
8415 {0xf85, 0xf85, direction::L}, {0xf86, 0xf87, direction::NSM},
8416 {0xf88, 0xf8c, direction::L}, {0xf8d, 0xf97, direction::NSM},
8417 {0xf99, 0xfbc, direction::NSM}, {0xfbe, 0xfc5, direction::L},
8418 {0xfc6, 0xfc6, direction::NSM}, {0xfc7, 0xfcc, direction::L},
8419 {0xfce, 0xfda, direction::L}, {0x1000, 0x102c, direction::L},
8420 {0x102d, 0x1030, direction::NSM}, {0x1031, 0x1031, direction::L},
8421 {0x1032, 0x1037, direction::NSM}, {0x1038, 0x1038, direction::L},
8422 {0x1039, 0x103a, direction::NSM}, {0x103b, 0x103c, direction::L},
8423 {0x103d, 0x103e, direction::NSM}, {0x103f, 0x1057, direction::L},
8424 {0x1058, 0x1059, direction::NSM}, {0x105a, 0x105d, direction::L},
8425 {0x105e, 0x1060, direction::NSM}, {0x1061, 0x1070, direction::L},
8426 {0x1071, 0x1074, direction::NSM}, {0x1075, 0x1081, direction::L},
8427 {0x1082, 0x1082, direction::NSM}, {0x1083, 0x1084, direction::L},
8428 {0x1085, 0x1086, direction::NSM}, {0x1087, 0x108c, direction::L},
8429 {0x108d, 0x108d, direction::NSM}, {0x108e, 0x109c, direction::L},
8430 {0x109d, 0x109d, direction::NSM}, {0x109e, 0x10c5, direction::L},
8431 {0x10c7, 0x10c7, direction::L}, {0x10cd, 0x10cd, direction::L},
8432 {0x10d0, 0x1248, direction::L}, {0x124a, 0x124d, direction::L},
8433 {0x1250, 0x1256, direction::L}, {0x1258, 0x1258, direction::L},
8434 {0x125a, 0x125d, direction::L}, {0x1260, 0x1288, direction::L},
8435 {0x128a, 0x128d, direction::L}, {0x1290, 0x12b0, direction::L},
8436 {0x12b2, 0x12b5, direction::L}, {0x12b8, 0x12be, direction::L},
8437 {0x12c0, 0x12c0, direction::L}, {0x12c2, 0x12c5, direction::L},
8438 {0x12c8, 0x12d6, direction::L}, {0x12d8, 0x1310, direction::L},
8439 {0x1312, 0x1315, direction::L}, {0x1318, 0x135a, direction::L},
8440 {0x135d, 0x135f, direction::NSM}, {0x1360, 0x137c, direction::L},
8441 {0x1380, 0x138f, direction::L}, {0x1390, 0x1399, direction::ON},
8442 {0x13a0, 0x13f5, direction::L}, {0x13f8, 0x13fd, direction::L},
8443 {0x1400, 0x1400, direction::ON}, {0x1401, 0x167f, direction::L},
8444 {0x1680, 0x1680, direction::WS}, {0x1681, 0x169a, direction::L},
8445 {0x169b, 0x169c, direction::ON}, {0x16a0, 0x16f8, direction::L},
8446 {0x1700, 0x170c, direction::L}, {0x170e, 0x1711, direction::L},
8447 {0x1712, 0x1714, direction::NSM}, {0x1720, 0x1731, direction::L},
8448 {0x1732, 0x1734, direction::NSM}, {0x1735, 0x1736, direction::L},
8449 {0x1740, 0x1751, direction::L}, {0x1752, 0x1753, direction::NSM},
8450 {0x1760, 0x176c, direction::L}, {0x176e, 0x1770, direction::L},
8451 {0x1772, 0x1773, direction::NSM}, {0x1780, 0x17b3, direction::L},
8452 {0x17b4, 0x17b5, direction::NSM}, {0x17b6, 0x17b6, direction::L},
8453 {0x17b7, 0x17bd, direction::NSM}, {0x17be, 0x17c5, direction::L},
8454 {0x17c6, 0x17c6, direction::NSM}, {0x17c7, 0x17c8, direction::L},
8455 {0x17c9, 0x17d3, direction::NSM}, {0x17d4, 0x17da, direction::L},
8456 {0x17db, 0x17db, direction::ET}, {0x17dc, 0x17dc, direction::L},
8457 {0x17dd, 0x17dd, direction::NSM}, {0x17e0, 0x17e9, direction::L},
8458 {0x17f0, 0x17f9, direction::ON}, {0x1800, 0x180a, direction::ON},
8459 {0x180b, 0x180d, direction::NSM}, {0x180e, 0x180e, direction::BN},
8460 {0x1810, 0x1819, direction::L}, {0x1820, 0x1878, direction::L},
8461 {0x1880, 0x1884, direction::L}, {0x1885, 0x1886, direction::NSM},
8462 {0x1887, 0x18a8, direction::L}, {0x18a9, 0x18a9, direction::NSM},
8463 {0x18aa, 0x18aa, direction::L}, {0x18b0, 0x18f5, direction::L},
8464 {0x1900, 0x191e, direction::L}, {0x1920, 0x1922, direction::NSM},
8465 {0x1923, 0x1926, direction::L}, {0x1927, 0x1928, direction::NSM},
8466 {0x1929, 0x192b, direction::L}, {0x1930, 0x1931, direction::L},
8467 {0x1932, 0x1932, direction::NSM}, {0x1933, 0x1938, direction::L},
8468 {0x1939, 0x193b, direction::NSM}, {0x1940, 0x1940, direction::ON},
8469 {0x1944, 0x1945, direction::ON}, {0x1946, 0x196d, direction::L},
8470 {0x1970, 0x1974, direction::L}, {0x1980, 0x19ab, direction::L},
8471 {0x19b0, 0x19c9, direction::L}, {0x19d0, 0x19da, direction::L},
8472 {0x19de, 0x19ff, direction::ON}, {0x1a00, 0x1a16, direction::L},
8473 {0x1a17, 0x1a18, direction::NSM}, {0x1a19, 0x1a1a, direction::L},
8474 {0x1a1b, 0x1a1b, direction::NSM}, {0x1a1e, 0x1a55, direction::L},
8475 {0x1a56, 0x1a56, direction::NSM}, {0x1a57, 0x1a57, direction::L},
8476 {0x1a58, 0x1a5e, direction::NSM}, {0x1a60, 0x1a60, direction::NSM},
8477 {0x1a61, 0x1a61, direction::L}, {0x1a62, 0x1a62, direction::NSM},
8478 {0x1a63, 0x1a64, direction::L}, {0x1a65, 0x1a6c, direction::NSM},
8479 {0x1a6d, 0x1a72, direction::L}, {0x1a73, 0x1a7c, direction::NSM},
8480 {0x1a7f, 0x1a7f, direction::NSM}, {0x1a80, 0x1a89, direction::L},
8481 {0x1a90, 0x1a99, direction::L}, {0x1aa0, 0x1aad, direction::L},
8482 {0x1ab0, 0x1ac0, direction::NSM}, {0x1b00, 0x1b03, direction::NSM},
8483 {0x1b04, 0x1b33, direction::L}, {0x1b34, 0x1b34, direction::NSM},
8484 {0x1b35, 0x1b35, direction::L}, {0x1b36, 0x1b3a, direction::NSM},
8485 {0x1b3b, 0x1b3b, direction::L}, {0x1b3c, 0x1b3c, direction::NSM},
8486 {0x1b3d, 0x1b41, direction::L}, {0x1b42, 0x1b42, direction::NSM},
8487 {0x1b43, 0x1b4b, direction::L}, {0x1b50, 0x1b6a, direction::L},
8488 {0x1b6b, 0x1b73, direction::NSM}, {0x1b74, 0x1b7c, direction::L},
8489 {0x1b80, 0x1b81, direction::NSM}, {0x1b82, 0x1ba1, direction::L},
8490 {0x1ba2, 0x1ba5, direction::NSM}, {0x1ba6, 0x1ba7, direction::L},
8491 {0x1ba8, 0x1ba9, direction::NSM}, {0x1baa, 0x1baa, direction::L},
8492 {0x1bab, 0x1bad, direction::NSM}, {0x1bae, 0x1be5, direction::L},
8493 {0x1be6, 0x1be6, direction::NSM}, {0x1be7, 0x1be7, direction::L},
8494 {0x1be8, 0x1be9, direction::NSM}, {0x1bea, 0x1bec, direction::L},
8495 {0x1bed, 0x1bed, direction::NSM}, {0x1bee, 0x1bee, direction::L},
8496 {0x1bef, 0x1bf1, direction::NSM}, {0x1bf2, 0x1bf3, direction::L},
8497 {0x1bfc, 0x1c2b, direction::L}, {0x1c2c, 0x1c33, direction::NSM},
8498 {0x1c34, 0x1c35, direction::L}, {0x1c36, 0x1c37, direction::NSM},
8499 {0x1c3b, 0x1c49, direction::L}, {0x1c4d, 0x1c88, direction::L},
8500 {0x1c90, 0x1cba, direction::L}, {0x1cbd, 0x1cc7, direction::L},
8501 {0x1cd0, 0x1cd2, direction::NSM}, {0x1cd3, 0x1cd3, direction::L},
8502 {0x1cd4, 0x1ce0, direction::NSM}, {0x1ce1, 0x1ce1, direction::L},
8503 {0x1ce2, 0x1ce8, direction::NSM}, {0x1ce9, 0x1cec, direction::L},
8504 {0x1ced, 0x1ced, direction::NSM}, {0x1cee, 0x1cf3, direction::L},
8505 {0x1cf4, 0x1cf4, direction::NSM}, {0x1cf5, 0x1cf7, direction::L},
8506 {0x1cf8, 0x1cf9, direction::NSM}, {0x1cfa, 0x1cfa, direction::L},
8507 {0x1d00, 0x1dbf, direction::L}, {0x1dc0, 0x1df9, direction::NSM},
8508 {0x1dfb, 0x1dff, direction::NSM}, {0x1e00, 0x1f15, direction::L},
8509 {0x1f18, 0x1f1d, direction::L}, {0x1f20, 0x1f45, direction::L},
8510 {0x1f48, 0x1f4d, direction::L}, {0x1f50, 0x1f57, direction::L},
8511 {0x1f59, 0x1f59, direction::L}, {0x1f5b, 0x1f5b, direction::L},
8512 {0x1f5d, 0x1f5d, direction::L}, {0x1f5f, 0x1f7d, direction::L},
8513 {0x1f80, 0x1fb4, direction::L}, {0x1fb6, 0x1fbc, direction::L},
8514 {0x1fbd, 0x1fbd, direction::ON}, {0x1fbe, 0x1fbe, direction::L},
8515 {0x1fbf, 0x1fc1, direction::ON}, {0x1fc2, 0x1fc4, direction::L},
8516 {0x1fc6, 0x1fcc, direction::L}, {0x1fcd, 0x1fcf, direction::ON},
8517 {0x1fd0, 0x1fd3, direction::L}, {0x1fd6, 0x1fdb, direction::L},
8518 {0x1fdd, 0x1fdf, direction::ON}, {0x1fe0, 0x1fec, direction::L},
8519 {0x1fed, 0x1fef, direction::ON}, {0x1ff2, 0x1ff4, direction::L},
8520 {0x1ff6, 0x1ffc, direction::L}, {0x1ffd, 0x1ffe, direction::ON},
8521 {0x2000, 0x200a, direction::WS}, {0x200b, 0x200d, direction::BN},
8522 {0x200e, 0x200e, direction::L}, {0x200f, 0x200f, direction::R},
8523 {0x2010, 0x2027, direction::ON}, {0x2028, 0x2028, direction::WS},
8524 {0x2029, 0x2029, direction::B}, {0x202a, 0x202a, direction::LRE},
8525 {0x202b, 0x202b, direction::RLE}, {0x202c, 0x202c, direction::PDF},
8526 {0x202d, 0x202d, direction::LRO}, {0x202e, 0x202e, direction::RLO},
8527 {0x202f, 0x202f, direction::CS}, {0x2030, 0x2034, direction::ET},
8528 {0x2035, 0x2043, direction::ON}, {0x2044, 0x2044, direction::CS},
8529 {0x2045, 0x205e, direction::ON}, {0x205f, 0x205f, direction::WS},
8530 {0x2060, 0x2064, direction::BN}, {0x2066, 0x2066, direction::LRI},
8531 {0x2067, 0x2067, direction::RLI}, {0x2068, 0x2068, direction::FSI},
8532 {0x2069, 0x2069, direction::PDI}, {0x206a, 0x206f, direction::BN},
8533 {0x2070, 0x2070, direction::EN}, {0x2071, 0x2071, direction::L},
8534 {0x2074, 0x2079, direction::EN}, {0x207a, 0x207b, direction::ES},
8535 {0x207c, 0x207e, direction::ON}, {0x207f, 0x207f, direction::L},
8536 {0x2080, 0x2089, direction::EN}, {0x208a, 0x208b, direction::ES},
8537 {0x208c, 0x208e, direction::ON}, {0x2090, 0x209c, direction::L},
8538 {0x20a0, 0x20bf, direction::ET}, {0x20d0, 0x20f0, direction::NSM},
8539 {0x2100, 0x2101, direction::ON}, {0x2102, 0x2102, direction::L},
8540 {0x2103, 0x2106, direction::ON}, {0x2107, 0x2107, direction::L},
8541 {0x2108, 0x2109, direction::ON}, {0x210a, 0x2113, direction::L},
8542 {0x2114, 0x2114, direction::ON}, {0x2115, 0x2115, direction::L},
8543 {0x2116, 0x2118, direction::ON}, {0x2119, 0x211d, direction::L},
8544 {0x211e, 0x2123, direction::ON}, {0x2124, 0x2124, direction::L},
8545 {0x2125, 0x2125, direction::ON}, {0x2126, 0x2126, direction::L},
8546 {0x2127, 0x2127, direction::ON}, {0x2128, 0x2128, direction::L},
8547 {0x2129, 0x2129, direction::ON}, {0x212a, 0x212d, direction::L},
8548 {0x212e, 0x212e, direction::ET}, {0x212f, 0x2139, direction::L},
8549 {0x213a, 0x213b, direction::ON}, {0x213c, 0x213f, direction::L},
8550 {0x2140, 0x2144, direction::ON}, {0x2145, 0x2149, direction::L},
8551 {0x214a, 0x214d, direction::ON}, {0x214e, 0x214f, direction::L},
8552 {0x2150, 0x215f, direction::ON}, {0x2160, 0x2188, direction::L},
8553 {0x2189, 0x218b, direction::ON}, {0x2190, 0x2211, direction::ON},
8554 {0x2212, 0x2212, direction::ES}, {0x2213, 0x2213, direction::ET},
8555 {0x2214, 0x2335, direction::ON}, {0x2336, 0x237a, direction::L},
8556 {0x237b, 0x2394, direction::ON}, {0x2395, 0x2395, direction::L},
8557 {0x2396, 0x2426, direction::ON}, {0x2440, 0x244a, direction::ON},
8558 {0x2460, 0x2487, direction::ON}, {0x2488, 0x249b, direction::EN},
8559 {0x249c, 0x24e9, direction::L}, {0x24ea, 0x26ab, direction::ON},
8560 {0x26ac, 0x26ac, direction::L}, {0x26ad, 0x27ff, direction::ON},
8561 {0x2800, 0x28ff, direction::L}, {0x2900, 0x2b73, direction::ON},
8562 {0x2b76, 0x2b95, direction::ON}, {0x2b97, 0x2bff, direction::ON},
8563 {0x2c00, 0x2c2e, direction::L}, {0x2c30, 0x2c5e, direction::L},
8564 {0x2c60, 0x2ce4, direction::L}, {0x2ce5, 0x2cea, direction::ON},
8565 {0x2ceb, 0x2cee, direction::L}, {0x2cef, 0x2cf1, direction::NSM},
8566 {0x2cf2, 0x2cf3, direction::L}, {0x2cf9, 0x2cff, direction::ON},
8567 {0x2d00, 0x2d25, direction::L}, {0x2d27, 0x2d27, direction::L},
8568 {0x2d2d, 0x2d2d, direction::L}, {0x2d30, 0x2d67, direction::L},
8569 {0x2d6f, 0x2d70, direction::L}, {0x2d7f, 0x2d7f, direction::NSM},
8570 {0x2d80, 0x2d96, direction::L}, {0x2da0, 0x2da6, direction::L},
8571 {0x2da8, 0x2dae, direction::L}, {0x2db0, 0x2db6, direction::L},
8572 {0x2db8, 0x2dbe, direction::L}, {0x2dc0, 0x2dc6, direction::L},
8573 {0x2dc8, 0x2dce, direction::L}, {0x2dd0, 0x2dd6, direction::L},
8574 {0x2dd8, 0x2dde, direction::L}, {0x2de0, 0x2dff, direction::NSM},
8575 {0x2e00, 0x2e52, direction::ON}, {0x2e80, 0x2e99, direction::ON},
8576 {0x2e9b, 0x2ef3, direction::ON}, {0x2f00, 0x2fd5, direction::ON},
8577 {0x2ff0, 0x2ffb, direction::ON}, {0x3000, 0x3000, direction::WS},
8578 {0x3001, 0x3004, direction::ON}, {0x3005, 0x3007, direction::L},
8579 {0x3008, 0x3020, direction::ON}, {0x3021, 0x3029, direction::L},
8580 {0x302a, 0x302d, direction::NSM}, {0x302e, 0x302f, direction::L},
8581 {0x3030, 0x3030, direction::ON}, {0x3031, 0x3035, direction::L},
8582 {0x3036, 0x3037, direction::ON}, {0x3038, 0x303c, direction::L},
8583 {0x303d, 0x303f, direction::ON}, {0x3041, 0x3096, direction::L},
8584 {0x3099, 0x309a, direction::NSM}, {0x309b, 0x309c, direction::ON},
8585 {0x309d, 0x309f, direction::L}, {0x30a0, 0x30a0, direction::ON},
8586 {0x30a1, 0x30fa, direction::L}, {0x30fb, 0x30fb, direction::ON},
8587 {0x30fc, 0x30ff, direction::L}, {0x3105, 0x312f, direction::L},
8588 {0x3131, 0x318e, direction::L}, {0x3190, 0x31bf, direction::L},
8589 {0x31c0, 0x31e3, direction::ON}, {0x31f0, 0x321c, direction::L},
8590 {0x321d, 0x321e, direction::ON}, {0x3220, 0x324f, direction::L},
8591 {0x3250, 0x325f, direction::ON}, {0x3260, 0x327b, direction::L},
8592 {0x327c, 0x327e, direction::ON}, {0x327f, 0x32b0, direction::L},
8593 {0x32b1, 0x32bf, direction::ON}, {0x32c0, 0x32cb, direction::L},
8594 {0x32cc, 0x32cf, direction::ON}, {0x32d0, 0x3376, direction::L},
8595 {0x3377, 0x337a, direction::ON}, {0x337b, 0x33dd, direction::L},
8596 {0x33de, 0x33df, direction::ON}, {0x33e0, 0x33fe, direction::L},
8597 {0x33ff, 0x33ff, direction::ON}, {0x3400, 0x4dbf, direction::L},
8598 {0x4dc0, 0x4dff, direction::ON}, {0x4e00, 0x9ffc, direction::L},
8599 {0xa000, 0xa48c, direction::L}, {0xa490, 0xa4c6, direction::ON},
8600 {0xa4d0, 0xa60c, direction::L}, {0xa60d, 0xa60f, direction::ON},
8601 {0xa610, 0xa62b, direction::L}, {0xa640, 0xa66e, direction::L},
8602 {0xa66f, 0xa672, direction::NSM}, {0xa673, 0xa673, direction::ON},
8603 {0xa674, 0xa67d, direction::NSM}, {0xa67e, 0xa67f, direction::ON},
8604 {0xa680, 0xa69d, direction::L}, {0xa69e, 0xa69f, direction::NSM},
8605 {0xa6a0, 0xa6ef, direction::L}, {0xa6f0, 0xa6f1, direction::NSM},
8606 {0xa6f2, 0xa6f7, direction::L}, {0xa700, 0xa721, direction::ON},
8607 {0xa722, 0xa787, direction::L}, {0xa788, 0xa788, direction::ON},
8608 {0xa789, 0xa7bf, direction::L}, {0xa7c2, 0xa7ca, direction::L},
8609 {0xa7f5, 0xa801, direction::L}, {0xa802, 0xa802, direction::NSM},
8610 {0xa803, 0xa805, direction::L}, {0xa806, 0xa806, direction::NSM},
8611 {0xa807, 0xa80a, direction::L}, {0xa80b, 0xa80b, direction::NSM},
8612 {0xa80c, 0xa824, direction::L}, {0xa825, 0xa826, direction::NSM},
8613 {0xa827, 0xa827, direction::L}, {0xa828, 0xa82b, direction::ON},
8614 {0xa82c, 0xa82c, direction::NSM}, {0xa830, 0xa837, direction::L},
8615 {0xa838, 0xa839, direction::ET}, {0xa840, 0xa873, direction::L},
8616 {0xa874, 0xa877, direction::ON}, {0xa880, 0xa8c3, direction::L},
8617 {0xa8c4, 0xa8c5, direction::NSM}, {0xa8ce, 0xa8d9, direction::L},
8618 {0xa8e0, 0xa8f1, direction::NSM}, {0xa8f2, 0xa8fe, direction::L},
8619 {0xa8ff, 0xa8ff, direction::NSM}, {0xa900, 0xa925, direction::L},
8620 {0xa926, 0xa92d, direction::NSM}, {0xa92e, 0xa946, direction::L},
8621 {0xa947, 0xa951, direction::NSM}, {0xa952, 0xa953, direction::L},
8622 {0xa95f, 0xa97c, direction::L}, {0xa980, 0xa982, direction::NSM},
8623 {0xa983, 0xa9b2, direction::L}, {0xa9b3, 0xa9b3, direction::NSM},
8624 {0xa9b4, 0xa9b5, direction::L}, {0xa9b6, 0xa9b9, direction::NSM},
8625 {0xa9ba, 0xa9bb, direction::L}, {0xa9bc, 0xa9bd, direction::NSM},
8626 {0xa9be, 0xa9cd, direction::L}, {0xa9cf, 0xa9d9, direction::L},
8627 {0xa9de, 0xa9e4, direction::L}, {0xa9e5, 0xa9e5, direction::NSM},
8628 {0xa9e6, 0xa9fe, direction::L}, {0xaa00, 0xaa28, direction::L},
8629 {0xaa29, 0xaa2e, direction::NSM}, {0xaa2f, 0xaa30, direction::L},
8630 {0xaa31, 0xaa32, direction::NSM}, {0xaa33, 0xaa34, direction::L},
8631 {0xaa35, 0xaa36, direction::NSM}, {0xaa40, 0xaa42, direction::L},
8632 {0xaa43, 0xaa43, direction::NSM}, {0xaa44, 0xaa4b, direction::L},
8633 {0xaa4c, 0xaa4c, direction::NSM}, {0xaa4d, 0xaa4d, direction::L},
8634 {0xaa50, 0xaa59, direction::L}, {0xaa5c, 0xaa7b, direction::L},
8635 {0xaa7c, 0xaa7c, direction::NSM}, {0xaa7d, 0xaaaf, direction::L},
8636 {0xaab0, 0xaab0, direction::NSM}, {0xaab1, 0xaab1, direction::L},
8637 {0xaab2, 0xaab4, direction::NSM}, {0xaab5, 0xaab6, direction::L},
8638 {0xaab7, 0xaab8, direction::NSM}, {0xaab9, 0xaabd, direction::L},
8639 {0xaabe, 0xaabf, direction::NSM}, {0xaac0, 0xaac0, direction::L},
8640 {0xaac1, 0xaac1, direction::NSM}, {0xaac2, 0xaac2, direction::L},
8641 {0xaadb, 0xaaeb, direction::L}, {0xaaec, 0xaaed, direction::NSM},
8642 {0xaaee, 0xaaf5, direction::L}, {0xaaf6, 0xaaf6, direction::NSM},
8643 {0xab01, 0xab06, direction::L}, {0xab09, 0xab0e, direction::L},
8644 {0xab11, 0xab16, direction::L}, {0xab20, 0xab26, direction::L},
8645 {0xab28, 0xab2e, direction::L}, {0xab30, 0xab69, direction::L},
8646 {0xab6a, 0xab6b, direction::ON}, {0xab70, 0xabe4, direction::L},
8647 {0xabe5, 0xabe5, direction::NSM}, {0xabe6, 0xabe7, direction::L},
8648 {0xabe8, 0xabe8, direction::NSM}, {0xabe9, 0xabec, direction::L},
8649 {0xabed, 0xabed, direction::NSM}, {0xabf0, 0xabf9, direction::L},
8650 {0xac00, 0xd7a3, direction::L}, {0xd7b0, 0xd7c6, direction::L},
8651 {0xd7cb, 0xd7fb, direction::L}, {0xd800, 0xfa6d, direction::L},
8652 {0xfa70, 0xfad9, direction::L}, {0xfb00, 0xfb06, direction::L},
8653 {0xfb13, 0xfb17, direction::L}, {0xfb1d, 0xfb1d, direction::R},
8654 {0xfb1e, 0xfb1e, direction::NSM}, {0xfb1f, 0xfb28, direction::R},
8655 {0xfb29, 0xfb29, direction::ES}, {0xfb2a, 0xfb36, direction::R},
8656 {0xfb38, 0xfb3c, direction::R}, {0xfb3e, 0xfb3e, direction::R},
8657 {0xfb40, 0xfb41, direction::R}, {0xfb43, 0xfb44, direction::R},
8658 {0xfb46, 0xfb4f, direction::R}, {0xfb50, 0xfbc1, direction::AL},
8659 {0xfbd3, 0xfd3d, direction::AL}, {0xfd3e, 0xfd3f, direction::ON},
8660 {0xfd50, 0xfd8f, direction::AL}, {0xfd92, 0xfdc7, direction::AL},
8661 {0xfdf0, 0xfdfc, direction::AL}, {0xfdfd, 0xfdfd, direction::ON},
8662 {0xfe00, 0xfe0f, direction::NSM}, {0xfe10, 0xfe19, direction::ON},
8663 {0xfe20, 0xfe2f, direction::NSM}, {0xfe30, 0xfe4f, direction::ON},
8664 {0xfe50, 0xfe50, direction::CS}, {0xfe51, 0xfe51, direction::ON},
8665 {0xfe52, 0xfe52, direction::CS}, {0xfe54, 0xfe54, direction::ON},
8666 {0xfe55, 0xfe55, direction::CS}, {0xfe56, 0xfe5e, direction::ON},
8667 {0xfe5f, 0xfe5f, direction::ET}, {0xfe60, 0xfe61, direction::ON},
8668 {0xfe62, 0xfe63, direction::ES}, {0xfe64, 0xfe66, direction::ON},
8669 {0xfe68, 0xfe68, direction::ON}, {0xfe69, 0xfe6a, direction::ET},
8670 {0xfe6b, 0xfe6b, direction::ON}, {0xfe70, 0xfe74, direction::AL},
8671 {0xfe76, 0xfefc, direction::AL}, {0xfeff, 0xfeff, direction::BN},
8672 {0xff01, 0xff02, direction::ON}, {0xff03, 0xff05, direction::ET},
8673 {0xff06, 0xff0a, direction::ON}, {0xff0b, 0xff0b, direction::ES},
8674 {0xff0c, 0xff0c, direction::CS}, {0xff0d, 0xff0d, direction::ES},
8675 {0xff0e, 0xff0f, direction::CS}, {0xff10, 0xff19, direction::EN},
8676 {0xff1a, 0xff1a, direction::CS}, {0xff1b, 0xff20, direction::ON},
8677 {0xff21, 0xff3a, direction::L}, {0xff3b, 0xff40, direction::ON},
8678 {0xff41, 0xff5a, direction::L}, {0xff5b, 0xff65, direction::ON},
8679 {0xff66, 0xffbe, direction::L}, {0xffc2, 0xffc7, direction::L},
8680 {0xffca, 0xffcf, direction::L}, {0xffd2, 0xffd7, direction::L},
8681 {0xffda, 0xffdc, direction::L}, {0xffe0, 0xffe1, direction::ET},
8682 {0xffe2, 0xffe4, direction::ON}, {0xffe5, 0xffe6, direction::ET},
8683 {0xffe8, 0xffee, direction::ON}, {0xfff9, 0xfffd, direction::ON},
8684 {0x10000, 0x1000b, direction::L}, {0x1000d, 0x10026, direction::L},
8685 {0x10028, 0x1003a, direction::L}, {0x1003c, 0x1003d, direction::L},
8686 {0x1003f, 0x1004d, direction::L}, {0x10050, 0x1005d, direction::L},
8687 {0x10080, 0x100fa, direction::L}, {0x10100, 0x10100, direction::L},
8688 {0x10101, 0x10101, direction::ON}, {0x10102, 0x10102, direction::L},
8689 {0x10107, 0x10133, direction::L}, {0x10137, 0x1013f, direction::L},
8690 {0x10140, 0x1018c, direction::ON}, {0x1018d, 0x1018e, direction::L},
8691 {0x10190, 0x1019c, direction::ON}, {0x101a0, 0x101a0, direction::ON},
8692 {0x101d0, 0x101fc, direction::L}, {0x101fd, 0x101fd, direction::NSM},
8693 {0x10280, 0x1029c, direction::L}, {0x102a0, 0x102d0, direction::L},
8694 {0x102e0, 0x102e0, direction::NSM}, {0x102e1, 0x102fb, direction::EN},
8695 {0x10300, 0x10323, direction::L}, {0x1032d, 0x1034a, direction::L},
8696 {0x10350, 0x10375, direction::L}, {0x10376, 0x1037a, direction::NSM},
8697 {0x10380, 0x1039d, direction::L}, {0x1039f, 0x103c3, direction::L},
8698 {0x103c8, 0x103d5, direction::L}, {0x10400, 0x1049d, direction::L},
8699 {0x104a0, 0x104a9, direction::L}, {0x104b0, 0x104d3, direction::L},
8700 {0x104d8, 0x104fb, direction::L}, {0x10500, 0x10527, direction::L},
8701 {0x10530, 0x10563, direction::L}, {0x1056f, 0x1056f, direction::L},
8702 {0x10600, 0x10736, direction::L}, {0x10740, 0x10755, direction::L},
8703 {0x10760, 0x10767, direction::L}, {0x10800, 0x10805, direction::R},
8704 {0x10808, 0x10808, direction::R}, {0x1080a, 0x10835, direction::R},
8705 {0x10837, 0x10838, direction::R}, {0x1083c, 0x1083c, direction::R},
8706 {0x1083f, 0x10855, direction::R}, {0x10857, 0x1089e, direction::R},
8707 {0x108a7, 0x108af, direction::R}, {0x108e0, 0x108f2, direction::R},
8708 {0x108f4, 0x108f5, direction::R}, {0x108fb, 0x1091b, direction::R},
8709 {0x1091f, 0x1091f, direction::ON}, {0x10920, 0x10939, direction::R},
8710 {0x1093f, 0x1093f, direction::R}, {0x10980, 0x109b7, direction::R},
8711 {0x109bc, 0x109cf, direction::R}, {0x109d2, 0x10a00, direction::R},
8712 {0x10a01, 0x10a03, direction::NSM}, {0x10a05, 0x10a06, direction::NSM},
8713 {0x10a0c, 0x10a0f, direction::NSM}, {0x10a10, 0x10a13, direction::R},
8714 {0x10a15, 0x10a17, direction::R}, {0x10a19, 0x10a35, direction::R},
8715 {0x10a38, 0x10a3a, direction::NSM}, {0x10a3f, 0x10a3f, direction::NSM},
8716 {0x10a40, 0x10a48, direction::R}, {0x10a50, 0x10a58, direction::R},
8717 {0x10a60, 0x10a9f, direction::R}, {0x10ac0, 0x10ae4, direction::R},
8718 {0x10ae5, 0x10ae6, direction::NSM}, {0x10aeb, 0x10af6, direction::R},
8719 {0x10b00, 0x10b35, direction::R}, {0x10b39, 0x10b3f, direction::ON},
8720 {0x10b40, 0x10b55, direction::R}, {0x10b58, 0x10b72, direction::R},
8721 {0x10b78, 0x10b91, direction::R}, {0x10b99, 0x10b9c, direction::R},
8722 {0x10ba9, 0x10baf, direction::R}, {0x10c00, 0x10c48, direction::R},
8723 {0x10c80, 0x10cb2, direction::R}, {0x10cc0, 0x10cf2, direction::R},
8724 {0x10cfa, 0x10cff, direction::R}, {0x10d00, 0x10d23, direction::AL},
8725 {0x10d24, 0x10d27, direction::NSM}, {0x10d30, 0x10d39, direction::AN},
8726 {0x10e60, 0x10e7e, direction::AN}, {0x10e80, 0x10ea9, direction::R},
8727 {0x10eab, 0x10eac, direction::NSM}, {0x10ead, 0x10ead, direction::R},
8728 {0x10eb0, 0x10eb1, direction::R}, {0x10f00, 0x10f27, direction::R},
8729 {0x10f30, 0x10f45, direction::AL}, {0x10f46, 0x10f50, direction::NSM},
8730 {0x10f51, 0x10f59, direction::AL}, {0x10fb0, 0x10fcb, direction::R},
8731 {0x10fe0, 0x10ff6, direction::R}, {0x11000, 0x11000, direction::L},
8732 {0x11001, 0x11001, direction::NSM}, {0x11002, 0x11037, direction::L},
8733 {0x11038, 0x11046, direction::NSM}, {0x11047, 0x1104d, direction::L},
8734 {0x11052, 0x11065, direction::ON}, {0x11066, 0x1106f, direction::L},
8735 {0x1107f, 0x11081, direction::NSM}, {0x11082, 0x110b2, direction::L},
8736 {0x110b3, 0x110b6, direction::NSM}, {0x110b7, 0x110b8, direction::L},
8737 {0x110b9, 0x110ba, direction::NSM}, {0x110bb, 0x110c1, direction::L},
8738 {0x110cd, 0x110cd, direction::L}, {0x110d0, 0x110e8, direction::L},
8739 {0x110f0, 0x110f9, direction::L}, {0x11100, 0x11102, direction::NSM},
8740 {0x11103, 0x11126, direction::L}, {0x11127, 0x1112b, direction::NSM},
8741 {0x1112c, 0x1112c, direction::L}, {0x1112d, 0x11134, direction::NSM},
8742 {0x11136, 0x11147, direction::L}, {0x11150, 0x11172, direction::L},
8743 {0x11173, 0x11173, direction::NSM}, {0x11174, 0x11176, direction::L},
8744 {0x11180, 0x11181, direction::NSM}, {0x11182, 0x111b5, direction::L},
8745 {0x111b6, 0x111be, direction::NSM}, {0x111bf, 0x111c8, direction::L},
8746 {0x111c9, 0x111cc, direction::NSM}, {0x111cd, 0x111ce, direction::L},
8747 {0x111cf, 0x111cf, direction::NSM}, {0x111d0, 0x111df, direction::L},
8748 {0x111e1, 0x111f4, direction::L}, {0x11200, 0x11211, direction::L},
8749 {0x11213, 0x1122e, direction::L}, {0x1122f, 0x11231, direction::NSM},
8750 {0x11232, 0x11233, direction::L}, {0x11234, 0x11234, direction::NSM},
8751 {0x11235, 0x11235, direction::L}, {0x11236, 0x11237, direction::NSM},
8752 {0x11238, 0x1123d, direction::L}, {0x1123e, 0x1123e, direction::NSM},
8753 {0x11280, 0x11286, direction::L}, {0x11288, 0x11288, direction::L},
8754 {0x1128a, 0x1128d, direction::L}, {0x1128f, 0x1129d, direction::L},
8755 {0x1129f, 0x112a9, direction::L}, {0x112b0, 0x112de, direction::L},
8756 {0x112df, 0x112df, direction::NSM}, {0x112e0, 0x112e2, direction::L},
8757 {0x112e3, 0x112ea, direction::NSM}, {0x112f0, 0x112f9, direction::L},
8758 {0x11300, 0x11301, direction::NSM}, {0x11302, 0x11303, direction::L},
8759 {0x11305, 0x1130c, direction::L}, {0x1130f, 0x11310, direction::L},
8760 {0x11313, 0x11328, direction::L}, {0x1132a, 0x11330, direction::L},
8761 {0x11332, 0x11333, direction::L}, {0x11335, 0x11339, direction::L},
8762 {0x1133b, 0x1133c, direction::NSM}, {0x1133d, 0x1133f, direction::L},
8763 {0x11340, 0x11340, direction::NSM}, {0x11341, 0x11344, direction::L},
8764 {0x11347, 0x11348, direction::L}, {0x1134b, 0x1134d, direction::L},
8765 {0x11350, 0x11350, direction::L}, {0x11357, 0x11357, direction::L},
8766 {0x1135d, 0x11363, direction::L}, {0x11366, 0x1136c, direction::NSM},
8767 {0x11370, 0x11374, direction::NSM}, {0x11400, 0x11437, direction::L},
8768 {0x11438, 0x1143f, direction::NSM}, {0x11440, 0x11441, direction::L},
8769 {0x11442, 0x11444, direction::NSM}, {0x11445, 0x11445, direction::L},
8770 {0x11446, 0x11446, direction::NSM}, {0x11447, 0x1145b, direction::L},
8771 {0x1145d, 0x1145d, direction::L}, {0x1145e, 0x1145e, direction::NSM},
8772 {0x1145f, 0x11461, direction::L}, {0x11480, 0x114b2, direction::L},
8773 {0x114b3, 0x114b8, direction::NSM}, {0x114b9, 0x114b9, direction::L},
8774 {0x114ba, 0x114ba, direction::NSM}, {0x114bb, 0x114be, direction::L},
8775 {0x114bf, 0x114c0, direction::NSM}, {0x114c1, 0x114c1, direction::L},
8776 {0x114c2, 0x114c3, direction::NSM}, {0x114c4, 0x114c7, direction::L},
8777 {0x114d0, 0x114d9, direction::L}, {0x11580, 0x115b1, direction::L},
8778 {0x115b2, 0x115b5, direction::NSM}, {0x115b8, 0x115bb, direction::L},
8779 {0x115bc, 0x115bd, direction::NSM}, {0x115be, 0x115be, direction::L},
8780 {0x115bf, 0x115c0, direction::NSM}, {0x115c1, 0x115db, direction::L},
8781 {0x115dc, 0x115dd, direction::NSM}, {0x11600, 0x11632, direction::L},
8782 {0x11633, 0x1163a, direction::NSM}, {0x1163b, 0x1163c, direction::L},
8783 {0x1163d, 0x1163d, direction::NSM}, {0x1163e, 0x1163e, direction::L},
8784 {0x1163f, 0x11640, direction::NSM}, {0x11641, 0x11644, direction::L},
8785 {0x11650, 0x11659, direction::L}, {0x11660, 0x1166c, direction::ON},
8786 {0x11680, 0x116aa, direction::L}, {0x116ab, 0x116ab, direction::NSM},
8787 {0x116ac, 0x116ac, direction::L}, {0x116ad, 0x116ad, direction::NSM},
8788 {0x116ae, 0x116af, direction::L}, {0x116b0, 0x116b5, direction::NSM},
8789 {0x116b6, 0x116b6, direction::L}, {0x116b7, 0x116b7, direction::NSM},
8790 {0x116b8, 0x116b8, direction::L}, {0x116c0, 0x116c9, direction::L},
8791 {0x11700, 0x1171a, direction::L}, {0x1171d, 0x1171f, direction::NSM},
8792 {0x11720, 0x11721, direction::L}, {0x11722, 0x11725, direction::NSM},
8793 {0x11726, 0x11726, direction::L}, {0x11727, 0x1172b, direction::NSM},
8794 {0x11730, 0x1173f, direction::L}, {0x11800, 0x1182e, direction::L},
8795 {0x1182f, 0x11837, direction::NSM}, {0x11838, 0x11838, direction::L},
8796 {0x11839, 0x1183a, direction::NSM}, {0x1183b, 0x1183b, direction::L},
8797 {0x118a0, 0x118f2, direction::L}, {0x118ff, 0x11906, direction::L},
8798 {0x11909, 0x11909, direction::L}, {0x1190c, 0x11913, direction::L},
8799 {0x11915, 0x11916, direction::L}, {0x11918, 0x11935, direction::L},
8800 {0x11937, 0x11938, direction::L}, {0x1193b, 0x1193c, direction::NSM},
8801 {0x1193d, 0x1193d, direction::L}, {0x1193e, 0x1193e, direction::NSM},
8802 {0x1193f, 0x11942, direction::L}, {0x11943, 0x11943, direction::NSM},
8803 {0x11944, 0x11946, direction::L}, {0x11950, 0x11959, direction::L},
8804 {0x119a0, 0x119a7, direction::L}, {0x119aa, 0x119d3, direction::L},
8805 {0x119d4, 0x119d7, direction::NSM}, {0x119da, 0x119db, direction::NSM},
8806 {0x119dc, 0x119df, direction::L}, {0x119e0, 0x119e0, direction::NSM},
8807 {0x119e1, 0x119e4, direction::L}, {0x11a00, 0x11a00, direction::L},
8808 {0x11a01, 0x11a06, direction::NSM}, {0x11a07, 0x11a08, direction::L},
8809 {0x11a09, 0x11a0a, direction::NSM}, {0x11a0b, 0x11a32, direction::L},
8810 {0x11a33, 0x11a38, direction::NSM}, {0x11a39, 0x11a3a, direction::L},
8811 {0x11a3b, 0x11a3e, direction::NSM}, {0x11a3f, 0x11a46, direction::L},
8812 {0x11a47, 0x11a47, direction::NSM}, {0x11a50, 0x11a50, direction::L},
8813 {0x11a51, 0x11a56, direction::NSM}, {0x11a57, 0x11a58, direction::L},
8814 {0x11a59, 0x11a5b, direction::NSM}, {0x11a5c, 0x11a89, direction::L},
8815 {0x11a8a, 0x11a96, direction::NSM}, {0x11a97, 0x11a97, direction::L},
8816 {0x11a98, 0x11a99, direction::NSM}, {0x11a9a, 0x11aa2, direction::L},
8817 {0x11ac0, 0x11af8, direction::L}, {0x11c00, 0x11c08, direction::L},
8818 {0x11c0a, 0x11c2f, direction::L}, {0x11c30, 0x11c36, direction::NSM},
8819 {0x11c38, 0x11c3d, direction::NSM}, {0x11c3e, 0x11c45, direction::L},
8820 {0x11c50, 0x11c6c, direction::L}, {0x11c70, 0x11c8f, direction::L},
8821 {0x11c92, 0x11ca7, direction::NSM}, {0x11ca9, 0x11ca9, direction::L},
8822 {0x11caa, 0x11cb0, direction::NSM}, {0x11cb1, 0x11cb1, direction::L},
8823 {0x11cb2, 0x11cb3, direction::NSM}, {0x11cb4, 0x11cb4, direction::L},
8824 {0x11cb5, 0x11cb6, direction::NSM}, {0x11d00, 0x11d06, direction::L},
8825 {0x11d08, 0x11d09, direction::L}, {0x11d0b, 0x11d30, direction::L},
8826 {0x11d31, 0x11d36, direction::NSM}, {0x11d3a, 0x11d3a, direction::NSM},
8827 {0x11d3c, 0x11d3d, direction::NSM}, {0x11d3f, 0x11d45, direction::NSM},
8828 {0x11d46, 0x11d46, direction::L}, {0x11d47, 0x11d47, direction::NSM},
8829 {0x11d50, 0x11d59, direction::L}, {0x11d60, 0x11d65, direction::L},
8830 {0x11d67, 0x11d68, direction::L}, {0x11d6a, 0x11d8e, direction::L},
8831 {0x11d90, 0x11d91, direction::NSM}, {0x11d93, 0x11d94, direction::L},
8832 {0x11d95, 0x11d95, direction::NSM}, {0x11d96, 0x11d96, direction::L},
8833 {0x11d97, 0x11d97, direction::NSM}, {0x11d98, 0x11d98, direction::L},
8834 {0x11da0, 0x11da9, direction::L}, {0x11ee0, 0x11ef2, direction::L},
8835 {0x11ef3, 0x11ef4, direction::NSM}, {0x11ef5, 0x11ef8, direction::L},
8836 {0x11fb0, 0x11fb0, direction::L}, {0x11fc0, 0x11fd4, direction::L},
8837 {0x11fd5, 0x11fdc, direction::ON}, {0x11fdd, 0x11fe0, direction::ET},
8838 {0x11fe1, 0x11ff1, direction::ON}, {0x11fff, 0x12399, direction::L},
8839 {0x12400, 0x1246e, direction::L}, {0x12470, 0x12474, direction::L},
8840 {0x12480, 0x12543, direction::L}, {0x13000, 0x1342e, direction::L},
8841 {0x13430, 0x13438, direction::L}, {0x14400, 0x14646, direction::L},
8842 {0x16800, 0x16a38, direction::L}, {0x16a40, 0x16a5e, direction::L},
8843 {0x16a60, 0x16a69, direction::L}, {0x16a6e, 0x16a6f, direction::L},
8844 {0x16ad0, 0x16aed, direction::L}, {0x16af0, 0x16af4, direction::NSM},
8845 {0x16af5, 0x16af5, direction::L}, {0x16b00, 0x16b2f, direction::L},
8846 {0x16b30, 0x16b36, direction::NSM}, {0x16b37, 0x16b45, direction::L},
8847 {0x16b50, 0x16b59, direction::L}, {0x16b5b, 0x16b61, direction::L},
8848 {0x16b63, 0x16b77, direction::L}, {0x16b7d, 0x16b8f, direction::L},
8849 {0x16e40, 0x16e9a, direction::L}, {0x16f00, 0x16f4a, direction::L},
8850 {0x16f4f, 0x16f4f, direction::NSM}, {0x16f50, 0x16f87, direction::L},
8851 {0x16f8f, 0x16f92, direction::NSM}, {0x16f93, 0x16f9f, direction::L},
8852 {0x16fe0, 0x16fe1, direction::L}, {0x16fe2, 0x16fe2, direction::ON},
8853 {0x16fe3, 0x16fe3, direction::L}, {0x16fe4, 0x16fe4, direction::NSM},
8854 {0x16ff0, 0x16ff1, direction::L}, {0x17000, 0x187f7, direction::L},
8855 {0x18800, 0x18cd5, direction::L}, {0x18d00, 0x18d08, direction::L},
8856 {0x1b000, 0x1b11e, direction::L}, {0x1b150, 0x1b152, direction::L},
8857 {0x1b164, 0x1b167, direction::L}, {0x1b170, 0x1b2fb, direction::L},
8858 {0x1bc00, 0x1bc6a, direction::L}, {0x1bc70, 0x1bc7c, direction::L},
8859 {0x1bc80, 0x1bc88, direction::L}, {0x1bc90, 0x1bc99, direction::L},
8860 {0x1bc9c, 0x1bc9c, direction::L}, {0x1bc9d, 0x1bc9e, direction::NSM},
8861 {0x1bc9f, 0x1bc9f, direction::L}, {0x1bca0, 0x1bca3, direction::BN},
8862 {0x1d000, 0x1d0f5, direction::L}, {0x1d100, 0x1d126, direction::L},
8863 {0x1d129, 0x1d166, direction::L}, {0x1d167, 0x1d169, direction::NSM},
8864 {0x1d16a, 0x1d172, direction::L}, {0x1d173, 0x1d17a, direction::BN},
8865 {0x1d17b, 0x1d182, direction::NSM}, {0x1d183, 0x1d184, direction::L},
8866 {0x1d185, 0x1d18b, direction::NSM}, {0x1d18c, 0x1d1a9, direction::L},
8867 {0x1d1aa, 0x1d1ad, direction::NSM}, {0x1d1ae, 0x1d1e8, direction::L},
8868 {0x1d200, 0x1d241, direction::ON}, {0x1d242, 0x1d244, direction::NSM},
8869 {0x1d245, 0x1d245, direction::ON}, {0x1d2e0, 0x1d2f3, direction::L},
8870 {0x1d300, 0x1d356, direction::ON}, {0x1d360, 0x1d378, direction::L},
8871 {0x1d400, 0x1d454, direction::L}, {0x1d456, 0x1d49c, direction::L},
8872 {0x1d49e, 0x1d49f, direction::L}, {0x1d4a2, 0x1d4a2, direction::L},
8873 {0x1d4a5, 0x1d4a6, direction::L}, {0x1d4a9, 0x1d4ac, direction::L},
8874 {0x1d4ae, 0x1d4b9, direction::L}, {0x1d4bb, 0x1d4bb, direction::L},
8875 {0x1d4bd, 0x1d4c3, direction::L}, {0x1d4c5, 0x1d505, direction::L},
8876 {0x1d507, 0x1d50a, direction::L}, {0x1d50d, 0x1d514, direction::L},
8877 {0x1d516, 0x1d51c, direction::L}, {0x1d51e, 0x1d539, direction::L},
8878 {0x1d53b, 0x1d53e, direction::L}, {0x1d540, 0x1d544, direction::L},
8879 {0x1d546, 0x1d546, direction::L}, {0x1d54a, 0x1d550, direction::L},
8880 {0x1d552, 0x1d6a5, direction::L}, {0x1d6a8, 0x1d6da, direction::L},
8881 {0x1d6db, 0x1d6db, direction::ON}, {0x1d6dc, 0x1d714, direction::L},
8882 {0x1d715, 0x1d715, direction::ON}, {0x1d716, 0x1d74e, direction::L},
8883 {0x1d74f, 0x1d74f, direction::ON}, {0x1d750, 0x1d788, direction::L},
8884 {0x1d789, 0x1d789, direction::ON}, {0x1d78a, 0x1d7c2, direction::L},
8885 {0x1d7c3, 0x1d7c3, direction::ON}, {0x1d7c4, 0x1d7cb, direction::L},
8886 {0x1d7ce, 0x1d7ff, direction::EN}, {0x1d800, 0x1d9ff, direction::L},
8887 {0x1da00, 0x1da36, direction::NSM}, {0x1da37, 0x1da3a, direction::L},
8888 {0x1da3b, 0x1da6c, direction::NSM}, {0x1da6d, 0x1da74, direction::L},
8889 {0x1da75, 0x1da75, direction::NSM}, {0x1da76, 0x1da83, direction::L},
8890 {0x1da84, 0x1da84, direction::NSM}, {0x1da85, 0x1da8b, direction::L},
8891 {0x1da9b, 0x1da9f, direction::NSM}, {0x1daa1, 0x1daaf, direction::NSM},
8892 {0x1e000, 0x1e006, direction::NSM}, {0x1e008, 0x1e018, direction::NSM},
8893 {0x1e01b, 0x1e021, direction::NSM}, {0x1e023, 0x1e024, direction::NSM},
8894 {0x1e026, 0x1e02a, direction::NSM}, {0x1e100, 0x1e12c, direction::L},
8895 {0x1e130, 0x1e136, direction::NSM}, {0x1e137, 0x1e13d, direction::L},
8896 {0x1e140, 0x1e149, direction::L}, {0x1e14e, 0x1e14f, direction::L},
8897 {0x1e2c0, 0x1e2eb, direction::L}, {0x1e2ec, 0x1e2ef, direction::NSM},
8898 {0x1e2f0, 0x1e2f9, direction::L}, {0x1e2ff, 0x1e2ff, direction::ET},
8899 {0x1e800, 0x1e8c4, direction::R}, {0x1e8c7, 0x1e8cf, direction::R},
8900 {0x1e8d0, 0x1e8d6, direction::NSM}, {0x1e900, 0x1e943, direction::R},
8901 {0x1e944, 0x1e94a, direction::NSM}, {0x1e94b, 0x1e94b, direction::R},
8902 {0x1e950, 0x1e959, direction::R}, {0x1e95e, 0x1e95f, direction::R},
8903 {0x1ec71, 0x1ecb4, direction::AL}, {0x1ed01, 0x1ed3d, direction::AL},
8904 {0x1ee00, 0x1ee03, direction::AL}, {0x1ee05, 0x1ee1f, direction::AL},
8905 {0x1ee21, 0x1ee22, direction::AL}, {0x1ee24, 0x1ee24, direction::AL},
8906 {0x1ee27, 0x1ee27, direction::AL}, {0x1ee29, 0x1ee32, direction::AL},
8907 {0x1ee34, 0x1ee37, direction::AL}, {0x1ee39, 0x1ee39, direction::AL},
8908 {0x1ee3b, 0x1ee3b, direction::AL}, {0x1ee42, 0x1ee42, direction::AL},
8909 {0x1ee47, 0x1ee47, direction::AL}, {0x1ee49, 0x1ee49, direction::AL},
8910 {0x1ee4b, 0x1ee4b, direction::AL}, {0x1ee4d, 0x1ee4f, direction::AL},
8911 {0x1ee51, 0x1ee52, direction::AL}, {0x1ee54, 0x1ee54, direction::AL},
8912 {0x1ee57, 0x1ee57, direction::AL}, {0x1ee59, 0x1ee59, direction::AL},
8913 {0x1ee5b, 0x1ee5b, direction::AL}, {0x1ee5d, 0x1ee5d, direction::AL},
8914 {0x1ee5f, 0x1ee5f, direction::AL}, {0x1ee61, 0x1ee62, direction::AL},
8915 {0x1ee64, 0x1ee64, direction::AL}, {0x1ee67, 0x1ee6a, direction::AL},
8916 {0x1ee6c, 0x1ee72, direction::AL}, {0x1ee74, 0x1ee77, direction::AL},
8917 {0x1ee79, 0x1ee7c, direction::AL}, {0x1ee7e, 0x1ee7e, direction::AL},
8918 {0x1ee80, 0x1ee89, direction::AL}, {0x1ee8b, 0x1ee9b, direction::AL},
8919 {0x1eea1, 0x1eea3, direction::AL}, {0x1eea5, 0x1eea9, direction::AL},
8920 {0x1eeab, 0x1eebb, direction::AL}, {0x1eef0, 0x1eef1, direction::ON},
8921 {0x1f000, 0x1f02b, direction::ON}, {0x1f030, 0x1f093, direction::ON},
8922 {0x1f0a0, 0x1f0ae, direction::ON}, {0x1f0b1, 0x1f0bf, direction::ON},
8923 {0x1f0c1, 0x1f0cf, direction::ON}, {0x1f0d1, 0x1f0f5, direction::ON},
8924 {0x1f100, 0x1f10a, direction::EN}, {0x1f10b, 0x1f10f, direction::ON},
8925 {0x1f110, 0x1f12e, direction::L}, {0x1f12f, 0x1f12f, direction::ON},
8926 {0x1f130, 0x1f169, direction::L}, {0x1f16a, 0x1f16f, direction::ON},
8927 {0x1f170, 0x1f1ac, direction::L}, {0x1f1ad, 0x1f1ad, direction::ON},
8928 {0x1f1e6, 0x1f202, direction::L}, {0x1f210, 0x1f23b, direction::L},
8929 {0x1f240, 0x1f248, direction::L}, {0x1f250, 0x1f251, direction::L},
8930 {0x1f260, 0x1f265, direction::ON}, {0x1f300, 0x1f6d7, direction::ON},
8931 {0x1f6e0, 0x1f6ec, direction::ON}, {0x1f6f0, 0x1f6fc, direction::ON},
8932 {0x1f700, 0x1f773, direction::ON}, {0x1f780, 0x1f7d8, direction::ON},
8933 {0x1f7e0, 0x1f7eb, direction::ON}, {0x1f800, 0x1f80b, direction::ON},
8934 {0x1f810, 0x1f847, direction::ON}, {0x1f850, 0x1f859, direction::ON},
8935 {0x1f860, 0x1f887, direction::ON}, {0x1f890, 0x1f8ad, direction::ON},
8936 {0x1f8b0, 0x1f8b1, direction::ON}, {0x1f900, 0x1f978, direction::ON},
8937 {0x1f97a, 0x1f9cb, direction::ON}, {0x1f9cd, 0x1fa53, direction::ON},
8938 {0x1fa60, 0x1fa6d, direction::ON}, {0x1fa70, 0x1fa74, direction::ON},
8939 {0x1fa78, 0x1fa7a, direction::ON}, {0x1fa80, 0x1fa86, direction::ON},
8940 {0x1fa90, 0x1faa8, direction::ON}, {0x1fab0, 0x1fab6, direction::ON},
8941 {0x1fac0, 0x1fac2, direction::ON}, {0x1fad0, 0x1fad6, direction::ON},
8942 {0x1fb00, 0x1fb92, direction::ON}, {0x1fb94, 0x1fbca, direction::ON},
8943 {0x1fbf0, 0x1fbf9, direction::EN}, {0x20000, 0x2a6dd, direction::L},
8944 {0x2a700, 0x2b734, direction::L}, {0x2b740, 0x2b81d, direction::L},
8945 {0x2b820, 0x2cea1, direction::L}, {0x2ceb0, 0x2ebe0, direction::L},
8946 {0x2f800, 0x2fa1d, direction::L}, {0x30000, 0x3134a, direction::L},
8947 {0xe0001, 0xe0001, direction::BN}, {0xe0020, 0xe007f, direction::BN},
8948 {0xe0100, 0xe01ef, direction::NSM}, {0xf0000, 0xffffd, direction::L},
8949 {0x100000, 0x10fffd, direction::L}};
8950
8951 // CheckJoiners and CheckBidi are true for URL specification.
8952
find_direction(uint32_t code_point)8953 inline static direction find_direction(uint32_t code_point) noexcept {
8954 auto it = std::lower_bound(
8955 std::begin(dir_table), std::end(dir_table), code_point,
8956 [](const directions& d, uint32_t c) { return d.final_code < c; });
8957
8958 // next check is almost surely in vain, but we use it for safety.
8959 if (it == std::end(dir_table)) {
8960 return direction::NONE;
8961 }
8962 // We have that d.final_code >= c.
8963 if (code_point >= it->start_code) {
8964 return it->direct;
8965 }
8966 return direction::NONE;
8967 }
8968
find_last_not_of_nsm(const std::u32string_view label)8969 inline static size_t find_last_not_of_nsm(
8970 const std::u32string_view label) noexcept {
8971 for (int i = label.size() - 1; i >= 0; i--)
8972 if (find_direction(label[i]) != direction::NSM) return i;
8973
8974 return std::u32string_view::npos;
8975 }
8976
8977 // An RTL label is a label that contains at least one character of type R, AL,
8978 // or AN. https://www.rfc-editor.org/rfc/rfc5893#section-2
is_rtl_label(const std::u32string_view label)8979 inline static bool is_rtl_label(const std::u32string_view label) noexcept {
8980 const size_t mask =
8981 (1u << direction::R) | (1u << direction::AL) | (1u << direction::AN);
8982
8983 size_t directions = 0;
8984 for (size_t i = 0; i < label.size(); i++) {
8985 directions |= 1u << find_direction(label[i]);
8986 }
8987 return (directions & mask) != 0;
8988 }
8989
is_label_valid(const std::u32string_view label)8990 bool is_label_valid(const std::u32string_view label) {
8991 if (label.empty()) {
8992 return true;
8993 }
8994
8995 ///////////////
8996 // We have a normalization step which ensures that we are in NFC.
8997 // If we receive punycode, we normalize and check that the normalized
8998 // version matches the original.
8999 // --------------------------------------
9000 // The label must be in Unicode Normalization Form NFC.
9001
9002 // Current URL standard indicatest that CheckHyphens is set to false.
9003 // ---------------------------------------
9004 // If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character
9005 // in both the third and fourth positions. If CheckHyphens, the label must
9006 // neither begin nor end with a U+002D HYPHEN-MINUS character.
9007
9008 // This is not necessary because we segment the
9009 // labels by '.'.
9010 // ---------------------------------------
9011 // The label must not contain a U+002E ( . ) FULL STOP.
9012 // if (label.find('.') != std::string_view::npos) return false;
9013
9014 // The label must not begin with a combining mark, that is:
9015 // General_Category=Mark.
9016 constexpr static uint32_t combining[] = {
9017 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, 0x307,
9018 0x308, 0x309, 0x30a, 0x30b, 0x30c, 0x30d, 0x30e, 0x30f,
9019 0x310, 0x311, 0x312, 0x313, 0x314, 0x315, 0x316, 0x317,
9020 0x318, 0x319, 0x31a, 0x31b, 0x31c, 0x31d, 0x31e, 0x31f,
9021 0x320, 0x321, 0x322, 0x323, 0x324, 0x325, 0x326, 0x327,
9022 0x328, 0x329, 0x32a, 0x32b, 0x32c, 0x32d, 0x32e, 0x32f,
9023 0x330, 0x331, 0x332, 0x333, 0x334, 0x335, 0x336, 0x337,
9024 0x338, 0x339, 0x33a, 0x33b, 0x33c, 0x33d, 0x33e, 0x33f,
9025 0x340, 0x341, 0x342, 0x343, 0x344, 0x345, 0x346, 0x347,
9026 0x348, 0x349, 0x34a, 0x34b, 0x34c, 0x34d, 0x34e, 0x34f,
9027 0x350, 0x351, 0x352, 0x353, 0x354, 0x355, 0x356, 0x357,
9028 0x358, 0x359, 0x35a, 0x35b, 0x35c, 0x35d, 0x35e, 0x35f,
9029 0x360, 0x361, 0x362, 0x363, 0x364, 0x365, 0x366, 0x367,
9030 0x368, 0x369, 0x36a, 0x36b, 0x36c, 0x36d, 0x36e, 0x36f,
9031 0x483, 0x484, 0x485, 0x486, 0x487, 0x488, 0x489, 0x591,
9032 0x592, 0x593, 0x594, 0x595, 0x596, 0x597, 0x598, 0x599,
9033 0x59a, 0x59b, 0x59c, 0x59d, 0x59e, 0x59f, 0x5a0, 0x5a1,
9034 0x5a2, 0x5a3, 0x5a4, 0x5a5, 0x5a6, 0x5a7, 0x5a8, 0x5a9,
9035 0x5aa, 0x5ab, 0x5ac, 0x5ad, 0x5ae, 0x5af, 0x5b0, 0x5b1,
9036 0x5b2, 0x5b3, 0x5b4, 0x5b5, 0x5b6, 0x5b7, 0x5b8, 0x5b9,
9037 0x5ba, 0x5bb, 0x5bc, 0x5bd, 0x5bf, 0x5c1, 0x5c2, 0x5c4,
9038 0x5c5, 0x5c7, 0x610, 0x611, 0x612, 0x613, 0x614, 0x615,
9039 0x616, 0x617, 0x618, 0x619, 0x61a, 0x64b, 0x64c, 0x64d,
9040 0x64e, 0x64f, 0x650, 0x651, 0x652, 0x653, 0x654, 0x655,
9041 0x656, 0x657, 0x658, 0x659, 0x65a, 0x65b, 0x65c, 0x65d,
9042 0x65e, 0x65f, 0x670, 0x6d6, 0x6d7, 0x6d8, 0x6d9, 0x6da,
9043 0x6db, 0x6dc, 0x6df, 0x6e0, 0x6e1, 0x6e2, 0x6e3, 0x6e4,
9044 0x6e7, 0x6e8, 0x6ea, 0x6eb, 0x6ec, 0x6ed, 0x711, 0x730,
9045 0x731, 0x732, 0x733, 0x734, 0x735, 0x736, 0x737, 0x738,
9046 0x739, 0x73a, 0x73b, 0x73c, 0x73d, 0x73e, 0x73f, 0x740,
9047 0x741, 0x742, 0x743, 0x744, 0x745, 0x746, 0x747, 0x748,
9048 0x749, 0x74a, 0x7a6, 0x7a7, 0x7a8, 0x7a9, 0x7aa, 0x7ab,
9049 0x7ac, 0x7ad, 0x7ae, 0x7af, 0x7b0, 0x7eb, 0x7ec, 0x7ed,
9050 0x7ee, 0x7ef, 0x7f0, 0x7f1, 0x7f2, 0x7f3, 0x7fd, 0x816,
9051 0x817, 0x818, 0x819, 0x81b, 0x81c, 0x81d, 0x81e, 0x81f,
9052 0x820, 0x821, 0x822, 0x823, 0x825, 0x826, 0x827, 0x829,
9053 0x82a, 0x82b, 0x82c, 0x82d, 0x859, 0x85a, 0x85b, 0x8d3,
9054 0x8d4, 0x8d5, 0x8d6, 0x8d7, 0x8d8, 0x8d9, 0x8da, 0x8db,
9055 0x8dc, 0x8dd, 0x8de, 0x8df, 0x8e0, 0x8e1, 0x8e3, 0x8e4,
9056 0x8e5, 0x8e6, 0x8e7, 0x8e8, 0x8e9, 0x8ea, 0x8eb, 0x8ec,
9057 0x8ed, 0x8ee, 0x8ef, 0x8f0, 0x8f1, 0x8f2, 0x8f3, 0x8f4,
9058 0x8f5, 0x8f6, 0x8f7, 0x8f8, 0x8f9, 0x8fa, 0x8fb, 0x8fc,
9059 0x8fd, 0x8fe, 0x8ff, 0x900, 0x901, 0x902, 0x903, 0x93a,
9060 0x93b, 0x93c, 0x93e, 0x93f, 0x940, 0x941, 0x942, 0x943,
9061 0x944, 0x945, 0x946, 0x947, 0x948, 0x949, 0x94a, 0x94b,
9062 0x94c, 0x94d, 0x94e, 0x94f, 0x951, 0x952, 0x953, 0x954,
9063 0x955, 0x956, 0x957, 0x962, 0x963, 0x981, 0x982, 0x983,
9064 0x9bc, 0x9be, 0x9bf, 0x9c0, 0x9c1, 0x9c2, 0x9c3, 0x9c4,
9065 0x9c7, 0x9c8, 0x9cb, 0x9cc, 0x9cd, 0x9d7, 0x9e2, 0x9e3,
9066 0x9fe, 0xa01, 0xa02, 0xa03, 0xa3c, 0xa3e, 0xa3f, 0xa40,
9067 0xa41, 0xa42, 0xa47, 0xa48, 0xa4b, 0xa4c, 0xa4d, 0xa51,
9068 0xa70, 0xa71, 0xa75, 0xa81, 0xa82, 0xa83, 0xabc, 0xabe,
9069 0xabf, 0xac0, 0xac1, 0xac2, 0xac3, 0xac4, 0xac5, 0xac7,
9070 0xac8, 0xac9, 0xacb, 0xacc, 0xacd, 0xae2, 0xae3, 0xafa,
9071 0xafb, 0xafc, 0xafd, 0xafe, 0xaff, 0xb01, 0xb02, 0xb03,
9072 0xb3c, 0xb3e, 0xb3f, 0xb40, 0xb41, 0xb42, 0xb43, 0xb44,
9073 0xb47, 0xb48, 0xb4b, 0xb4c, 0xb4d, 0xb55, 0xb56, 0xb57,
9074 0xb62, 0xb63, 0xb82, 0xbbe, 0xbbf, 0xbc0, 0xbc1, 0xbc2,
9075 0xbc6, 0xbc7, 0xbc8, 0xbca, 0xbcb, 0xbcc, 0xbcd, 0xbd7,
9076 0xc00, 0xc01, 0xc02, 0xc03, 0xc04, 0xc3e, 0xc3f, 0xc40,
9077 0xc41, 0xc42, 0xc43, 0xc44, 0xc46, 0xc47, 0xc48, 0xc4a,
9078 0xc4b, 0xc4c, 0xc4d, 0xc55, 0xc56, 0xc62, 0xc63, 0xc81,
9079 0xc82, 0xc83, 0xcbc, 0xcbe, 0xcbf, 0xcc0, 0xcc1, 0xcc2,
9080 0xcc3, 0xcc4, 0xcc6, 0xcc7, 0xcc8, 0xcca, 0xccb, 0xccc,
9081 0xccd, 0xcd5, 0xcd6, 0xce2, 0xce3, 0xd00, 0xd01, 0xd02,
9082 0xd03, 0xd3b, 0xd3c, 0xd3e, 0xd3f, 0xd40, 0xd41, 0xd42,
9083 0xd43, 0xd44, 0xd46, 0xd47, 0xd48, 0xd4a, 0xd4b, 0xd4c,
9084 0xd4d, 0xd57, 0xd62, 0xd63, 0xd81, 0xd82, 0xd83, 0xdca,
9085 0xdcf, 0xdd0, 0xdd1, 0xdd2, 0xdd3, 0xdd4, 0xdd6, 0xdd8,
9086 0xdd9, 0xdda, 0xddb, 0xddc, 0xddd, 0xdde, 0xddf, 0xdf2,
9087 0xdf3, 0xe31, 0xe34, 0xe35, 0xe36, 0xe37, 0xe38, 0xe39,
9088 0xe3a, 0xe47, 0xe48, 0xe49, 0xe4a, 0xe4b, 0xe4c, 0xe4d,
9089 0xe4e, 0xeb1, 0xeb4, 0xeb5, 0xeb6, 0xeb7, 0xeb8, 0xeb9,
9090 0xeba, 0xebb, 0xebc, 0xec8, 0xec9, 0xeca, 0xecb, 0xecc,
9091 0xecd, 0xf18, 0xf19, 0xf35, 0xf37, 0xf39, 0xf3e, 0xf3f,
9092 0xf71, 0xf72, 0xf73, 0xf74, 0xf75, 0xf76, 0xf77, 0xf78,
9093 0xf79, 0xf7a, 0xf7b, 0xf7c, 0xf7d, 0xf7e, 0xf7f, 0xf80,
9094 0xf81, 0xf82, 0xf83, 0xf84, 0xf86, 0xf87, 0xf8d, 0xf8e,
9095 0xf8f, 0xf90, 0xf91, 0xf92, 0xf93, 0xf94, 0xf95, 0xf96,
9096 0xf97, 0xf99, 0xf9a, 0xf9b, 0xf9c, 0xf9d, 0xf9e, 0xf9f,
9097 0xfa0, 0xfa1, 0xfa2, 0xfa3, 0xfa4, 0xfa5, 0xfa6, 0xfa7,
9098 0xfa8, 0xfa9, 0xfaa, 0xfab, 0xfac, 0xfad, 0xfae, 0xfaf,
9099 0xfb0, 0xfb1, 0xfb2, 0xfb3, 0xfb4, 0xfb5, 0xfb6, 0xfb7,
9100 0xfb8, 0xfb9, 0xfba, 0xfbb, 0xfbc, 0xfc6, 0x102b, 0x102c,
9101 0x102d, 0x102e, 0x102f, 0x1030, 0x1031, 0x1032, 0x1033, 0x1034,
9102 0x1035, 0x1036, 0x1037, 0x1038, 0x1039, 0x103a, 0x103b, 0x103c,
9103 0x103d, 0x103e, 0x1056, 0x1057, 0x1058, 0x1059, 0x105e, 0x105f,
9104 0x1060, 0x1062, 0x1063, 0x1064, 0x1067, 0x1068, 0x1069, 0x106a,
9105 0x106b, 0x106c, 0x106d, 0x1071, 0x1072, 0x1073, 0x1074, 0x1082,
9106 0x1083, 0x1084, 0x1085, 0x1086, 0x1087, 0x1088, 0x1089, 0x108a,
9107 0x108b, 0x108c, 0x108d, 0x108f, 0x109a, 0x109b, 0x109c, 0x109d,
9108 0x135d, 0x135e, 0x135f, 0x1712, 0x1713, 0x1714, 0x1732, 0x1733,
9109 0x1734, 0x1752, 0x1753, 0x1772, 0x1773, 0x17b4, 0x17b5, 0x17b6,
9110 0x17b7, 0x17b8, 0x17b9, 0x17ba, 0x17bb, 0x17bc, 0x17bd, 0x17be,
9111 0x17bf, 0x17c0, 0x17c1, 0x17c2, 0x17c3, 0x17c4, 0x17c5, 0x17c6,
9112 0x17c7, 0x17c8, 0x17c9, 0x17ca, 0x17cb, 0x17cc, 0x17cd, 0x17ce,
9113 0x17cf, 0x17d0, 0x17d1, 0x17d2, 0x17d3, 0x17dd, 0x180b, 0x180c,
9114 0x180d, 0x1885, 0x1886, 0x18a9, 0x1920, 0x1921, 0x1922, 0x1923,
9115 0x1924, 0x1925, 0x1926, 0x1927, 0x1928, 0x1929, 0x192a, 0x192b,
9116 0x1930, 0x1931, 0x1932, 0x1933, 0x1934, 0x1935, 0x1936, 0x1937,
9117 0x1938, 0x1939, 0x193a, 0x193b, 0x1a17, 0x1a18, 0x1a19, 0x1a1a,
9118 0x1a1b, 0x1a55, 0x1a56, 0x1a57, 0x1a58, 0x1a59, 0x1a5a, 0x1a5b,
9119 0x1a5c, 0x1a5d, 0x1a5e, 0x1a60, 0x1a61, 0x1a62, 0x1a63, 0x1a64,
9120 0x1a65, 0x1a66, 0x1a67, 0x1a68, 0x1a69, 0x1a6a, 0x1a6b, 0x1a6c,
9121 0x1a6d, 0x1a6e, 0x1a6f, 0x1a70, 0x1a71, 0x1a72, 0x1a73, 0x1a74,
9122 0x1a75, 0x1a76, 0x1a77, 0x1a78, 0x1a79, 0x1a7a, 0x1a7b, 0x1a7c,
9123 0x1a7f, 0x1ab0, 0x1ab1, 0x1ab2, 0x1ab3, 0x1ab4, 0x1ab5, 0x1ab6,
9124 0x1ab7, 0x1ab8, 0x1ab9, 0x1aba, 0x1abb, 0x1abc, 0x1abd, 0x1abe,
9125 0x1abf, 0x1ac0, 0x1b00, 0x1b01, 0x1b02, 0x1b03, 0x1b04, 0x1b34,
9126 0x1b35, 0x1b36, 0x1b37, 0x1b38, 0x1b39, 0x1b3a, 0x1b3b, 0x1b3c,
9127 0x1b3d, 0x1b3e, 0x1b3f, 0x1b40, 0x1b41, 0x1b42, 0x1b43, 0x1b44,
9128 0x1b6b, 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b70, 0x1b71, 0x1b72,
9129 0x1b73, 0x1b80, 0x1b81, 0x1b82, 0x1ba1, 0x1ba2, 0x1ba3, 0x1ba4,
9130 0x1ba5, 0x1ba6, 0x1ba7, 0x1ba8, 0x1ba9, 0x1baa, 0x1bab, 0x1bac,
9131 0x1bad, 0x1be6, 0x1be7, 0x1be8, 0x1be9, 0x1bea, 0x1beb, 0x1bec,
9132 0x1bed, 0x1bee, 0x1bef, 0x1bf0, 0x1bf1, 0x1bf2, 0x1bf3, 0x1c24,
9133 0x1c25, 0x1c26, 0x1c27, 0x1c28, 0x1c29, 0x1c2a, 0x1c2b, 0x1c2c,
9134 0x1c2d, 0x1c2e, 0x1c2f, 0x1c30, 0x1c31, 0x1c32, 0x1c33, 0x1c34,
9135 0x1c35, 0x1c36, 0x1c37, 0x1cd0, 0x1cd1, 0x1cd2, 0x1cd4, 0x1cd5,
9136 0x1cd6, 0x1cd7, 0x1cd8, 0x1cd9, 0x1cda, 0x1cdb, 0x1cdc, 0x1cdd,
9137 0x1cde, 0x1cdf, 0x1ce0, 0x1ce1, 0x1ce2, 0x1ce3, 0x1ce4, 0x1ce5,
9138 0x1ce6, 0x1ce7, 0x1ce8, 0x1ced, 0x1cf4, 0x1cf7, 0x1cf8, 0x1cf9,
9139 0x1dc0, 0x1dc1, 0x1dc2, 0x1dc3, 0x1dc4, 0x1dc5, 0x1dc6, 0x1dc7,
9140 0x1dc8, 0x1dc9, 0x1dca, 0x1dcb, 0x1dcc, 0x1dcd, 0x1dce, 0x1dcf,
9141 0x1dd0, 0x1dd1, 0x1dd2, 0x1dd3, 0x1dd4, 0x1dd5, 0x1dd6, 0x1dd7,
9142 0x1dd8, 0x1dd9, 0x1dda, 0x1ddb, 0x1ddc, 0x1ddd, 0x1dde, 0x1ddf,
9143 0x1de0, 0x1de1, 0x1de2, 0x1de3, 0x1de4, 0x1de5, 0x1de6, 0x1de7,
9144 0x1de8, 0x1de9, 0x1dea, 0x1deb, 0x1dec, 0x1ded, 0x1dee, 0x1def,
9145 0x1df0, 0x1df1, 0x1df2, 0x1df3, 0x1df4, 0x1df5, 0x1df6, 0x1df7,
9146 0x1df8, 0x1df9, 0x1dfb, 0x1dfc, 0x1dfd, 0x1dfe, 0x1dff, 0x20d0,
9147 0x20d1, 0x20d2, 0x20d3, 0x20d4, 0x20d5, 0x20d6, 0x20d7, 0x20d8,
9148 0x20d9, 0x20da, 0x20db, 0x20dc, 0x20dd, 0x20de, 0x20df, 0x20e0,
9149 0x20e1, 0x20e2, 0x20e3, 0x20e4, 0x20e5, 0x20e6, 0x20e7, 0x20e8,
9150 0x20e9, 0x20ea, 0x20eb, 0x20ec, 0x20ed, 0x20ee, 0x20ef, 0x20f0,
9151 0x2cef, 0x2cf0, 0x2cf1, 0x2d7f, 0x2de0, 0x2de1, 0x2de2, 0x2de3,
9152 0x2de4, 0x2de5, 0x2de6, 0x2de7, 0x2de8, 0x2de9, 0x2dea, 0x2deb,
9153 0x2dec, 0x2ded, 0x2dee, 0x2def, 0x2df0, 0x2df1, 0x2df2, 0x2df3,
9154 0x2df4, 0x2df5, 0x2df6, 0x2df7, 0x2df8, 0x2df9, 0x2dfa, 0x2dfb,
9155 0x2dfc, 0x2dfd, 0x2dfe, 0x2dff, 0x302a, 0x302b, 0x302c, 0x302d,
9156 0x302e, 0x302f, 0x3099, 0x309a, 0xa66f, 0xa670, 0xa671, 0xa672,
9157 0xa674, 0xa675, 0xa676, 0xa677, 0xa678, 0xa679, 0xa67a, 0xa67b,
9158 0xa67c, 0xa67d, 0xa69e, 0xa69f, 0xa6f0, 0xa6f1, 0xa802, 0xa806,
9159 0xa80b, 0xa823, 0xa824, 0xa825, 0xa826, 0xa827, 0xa82c, 0xa880,
9160 0xa881, 0xa8b4, 0xa8b5, 0xa8b6, 0xa8b7, 0xa8b8, 0xa8b9, 0xa8ba,
9161 0xa8bb, 0xa8bc, 0xa8bd, 0xa8be, 0xa8bf, 0xa8c0, 0xa8c1, 0xa8c2,
9162 0xa8c3, 0xa8c4, 0xa8c5, 0xa8e0, 0xa8e1, 0xa8e2, 0xa8e3, 0xa8e4,
9163 0xa8e5, 0xa8e6, 0xa8e7, 0xa8e8, 0xa8e9, 0xa8ea, 0xa8eb, 0xa8ec,
9164 0xa8ed, 0xa8ee, 0xa8ef, 0xa8f0, 0xa8f1, 0xa8ff, 0xa926, 0xa927,
9165 0xa928, 0xa929, 0xa92a, 0xa92b, 0xa92c, 0xa92d, 0xa947, 0xa948,
9166 0xa949, 0xa94a, 0xa94b, 0xa94c, 0xa94d, 0xa94e, 0xa94f, 0xa950,
9167 0xa951, 0xa952, 0xa953, 0xa980, 0xa981, 0xa982, 0xa983, 0xa9b3,
9168 0xa9b4, 0xa9b5, 0xa9b6, 0xa9b7, 0xa9b8, 0xa9b9, 0xa9ba, 0xa9bb,
9169 0xa9bc, 0xa9bd, 0xa9be, 0xa9bf, 0xa9c0, 0xa9e5, 0xaa29, 0xaa2a,
9170 0xaa2b, 0xaa2c, 0xaa2d, 0xaa2e, 0xaa2f, 0xaa30, 0xaa31, 0xaa32,
9171 0xaa33, 0xaa34, 0xaa35, 0xaa36, 0xaa43, 0xaa4c, 0xaa4d, 0xaa7b,
9172 0xaa7c, 0xaa7d, 0xaab0, 0xaab2, 0xaab3, 0xaab4, 0xaab7, 0xaab8,
9173 0xaabe, 0xaabf, 0xaac1, 0xaaeb, 0xaaec, 0xaaed, 0xaaee, 0xaaef,
9174 0xaaf5, 0xaaf6, 0xabe3, 0xabe4, 0xabe5, 0xabe6, 0xabe7, 0xabe8,
9175 0xabe9, 0xabea, 0xabec, 0xabed, 0xfb1e, 0xfe00, 0xfe01, 0xfe02,
9176 0xfe03, 0xfe04, 0xfe05, 0xfe06, 0xfe07, 0xfe08, 0xfe09, 0xfe0a,
9177 0xfe0b, 0xfe0c, 0xfe0d, 0xfe0e, 0xfe0f, 0xfe20, 0xfe21, 0xfe22,
9178 0xfe23, 0xfe24, 0xfe25, 0xfe26, 0xfe27, 0xfe28, 0xfe29, 0xfe2a,
9179 0xfe2b, 0xfe2c, 0xfe2d, 0xfe2e, 0xfe2f, 0x101fd, 0x102e0, 0x10376,
9180 0x10377, 0x10378, 0x10379, 0x1037a, 0x10a01, 0x10a02, 0x10a03, 0x10a05,
9181 0x10a06, 0x10a0c, 0x10a0d, 0x10a0e, 0x10a0f, 0x10a38, 0x10a39, 0x10a3a,
9182 0x10a3f, 0x10ae5, 0x10ae6, 0x10d24, 0x10d25, 0x10d26, 0x10d27, 0x10eab,
9183 0x10eac, 0x10f46, 0x10f47, 0x10f48, 0x10f49, 0x10f4a, 0x10f4b, 0x10f4c,
9184 0x10f4d, 0x10f4e, 0x10f4f, 0x10f50, 0x11000, 0x11001, 0x11002, 0x11038,
9185 0x11039, 0x1103a, 0x1103b, 0x1103c, 0x1103d, 0x1103e, 0x1103f, 0x11040,
9186 0x11041, 0x11042, 0x11043, 0x11044, 0x11045, 0x11046, 0x1107f, 0x11080,
9187 0x11081, 0x11082, 0x110b0, 0x110b1, 0x110b2, 0x110b3, 0x110b4, 0x110b5,
9188 0x110b6, 0x110b7, 0x110b8, 0x110b9, 0x110ba, 0x11100, 0x11101, 0x11102,
9189 0x11127, 0x11128, 0x11129, 0x1112a, 0x1112b, 0x1112c, 0x1112d, 0x1112e,
9190 0x1112f, 0x11130, 0x11131, 0x11132, 0x11133, 0x11134, 0x11145, 0x11146,
9191 0x11173, 0x11180, 0x11181, 0x11182, 0x111b3, 0x111b4, 0x111b5, 0x111b6,
9192 0x111b7, 0x111b8, 0x111b9, 0x111ba, 0x111bb, 0x111bc, 0x111bd, 0x111be,
9193 0x111bf, 0x111c0, 0x111c9, 0x111ca, 0x111cb, 0x111cc, 0x111ce, 0x111cf,
9194 0x1122c, 0x1122d, 0x1122e, 0x1122f, 0x11230, 0x11231, 0x11232, 0x11233,
9195 0x11234, 0x11235, 0x11236, 0x11237, 0x1123e, 0x112df, 0x112e0, 0x112e1,
9196 0x112e2, 0x112e3, 0x112e4, 0x112e5, 0x112e6, 0x112e7, 0x112e8, 0x112e9,
9197 0x112ea, 0x11300, 0x11301, 0x11302, 0x11303, 0x1133b, 0x1133c, 0x1133e,
9198 0x1133f, 0x11340, 0x11341, 0x11342, 0x11343, 0x11344, 0x11347, 0x11348,
9199 0x1134b, 0x1134c, 0x1134d, 0x11357, 0x11362, 0x11363, 0x11366, 0x11367,
9200 0x11368, 0x11369, 0x1136a, 0x1136b, 0x1136c, 0x11370, 0x11371, 0x11372,
9201 0x11373, 0x11374, 0x11435, 0x11436, 0x11437, 0x11438, 0x11439, 0x1143a,
9202 0x1143b, 0x1143c, 0x1143d, 0x1143e, 0x1143f, 0x11440, 0x11441, 0x11442,
9203 0x11443, 0x11444, 0x11445, 0x11446, 0x1145e, 0x114b0, 0x114b1, 0x114b2,
9204 0x114b3, 0x114b4, 0x114b5, 0x114b6, 0x114b7, 0x114b8, 0x114b9, 0x114ba,
9205 0x114bb, 0x114bc, 0x114bd, 0x114be, 0x114bf, 0x114c0, 0x114c1, 0x114c2,
9206 0x114c3, 0x115af, 0x115b0, 0x115b1, 0x115b2, 0x115b3, 0x115b4, 0x115b5,
9207 0x115b8, 0x115b9, 0x115ba, 0x115bb, 0x115bc, 0x115bd, 0x115be, 0x115bf,
9208 0x115c0, 0x115dc, 0x115dd, 0x11630, 0x11631, 0x11632, 0x11633, 0x11634,
9209 0x11635, 0x11636, 0x11637, 0x11638, 0x11639, 0x1163a, 0x1163b, 0x1163c,
9210 0x1163d, 0x1163e, 0x1163f, 0x11640, 0x116ab, 0x116ac, 0x116ad, 0x116ae,
9211 0x116af, 0x116b0, 0x116b1, 0x116b2, 0x116b3, 0x116b4, 0x116b5, 0x116b6,
9212 0x116b7, 0x1171d, 0x1171e, 0x1171f, 0x11720, 0x11721, 0x11722, 0x11723,
9213 0x11724, 0x11725, 0x11726, 0x11727, 0x11728, 0x11729, 0x1172a, 0x1172b,
9214 0x1182c, 0x1182d, 0x1182e, 0x1182f, 0x11830, 0x11831, 0x11832, 0x11833,
9215 0x11834, 0x11835, 0x11836, 0x11837, 0x11838, 0x11839, 0x1183a, 0x11930,
9216 0x11931, 0x11932, 0x11933, 0x11934, 0x11935, 0x11937, 0x11938, 0x1193b,
9217 0x1193c, 0x1193d, 0x1193e, 0x11940, 0x11942, 0x11943, 0x119d1, 0x119d2,
9218 0x119d3, 0x119d4, 0x119d5, 0x119d6, 0x119d7, 0x119da, 0x119db, 0x119dc,
9219 0x119dd, 0x119de, 0x119df, 0x119e0, 0x119e4, 0x11a01, 0x11a02, 0x11a03,
9220 0x11a04, 0x11a05, 0x11a06, 0x11a07, 0x11a08, 0x11a09, 0x11a0a, 0x11a33,
9221 0x11a34, 0x11a35, 0x11a36, 0x11a37, 0x11a38, 0x11a39, 0x11a3b, 0x11a3c,
9222 0x11a3d, 0x11a3e, 0x11a47, 0x11a51, 0x11a52, 0x11a53, 0x11a54, 0x11a55,
9223 0x11a56, 0x11a57, 0x11a58, 0x11a59, 0x11a5a, 0x11a5b, 0x11a8a, 0x11a8b,
9224 0x11a8c, 0x11a8d, 0x11a8e, 0x11a8f, 0x11a90, 0x11a91, 0x11a92, 0x11a93,
9225 0x11a94, 0x11a95, 0x11a96, 0x11a97, 0x11a98, 0x11a99, 0x11c2f, 0x11c30,
9226 0x11c31, 0x11c32, 0x11c33, 0x11c34, 0x11c35, 0x11c36, 0x11c38, 0x11c39,
9227 0x11c3a, 0x11c3b, 0x11c3c, 0x11c3d, 0x11c3e, 0x11c3f, 0x11c92, 0x11c93,
9228 0x11c94, 0x11c95, 0x11c96, 0x11c97, 0x11c98, 0x11c99, 0x11c9a, 0x11c9b,
9229 0x11c9c, 0x11c9d, 0x11c9e, 0x11c9f, 0x11ca0, 0x11ca1, 0x11ca2, 0x11ca3,
9230 0x11ca4, 0x11ca5, 0x11ca6, 0x11ca7, 0x11ca9, 0x11caa, 0x11cab, 0x11cac,
9231 0x11cad, 0x11cae, 0x11caf, 0x11cb0, 0x11cb1, 0x11cb2, 0x11cb3, 0x11cb4,
9232 0x11cb5, 0x11cb6, 0x11d31, 0x11d32, 0x11d33, 0x11d34, 0x11d35, 0x11d36,
9233 0x11d3a, 0x11d3c, 0x11d3d, 0x11d3f, 0x11d40, 0x11d41, 0x11d42, 0x11d43,
9234 0x11d44, 0x11d45, 0x11d47, 0x11d8a, 0x11d8b, 0x11d8c, 0x11d8d, 0x11d8e,
9235 0x11d90, 0x11d91, 0x11d93, 0x11d94, 0x11d95, 0x11d96, 0x11d97, 0x11ef3,
9236 0x11ef4, 0x11ef5, 0x11ef6, 0x16af0, 0x16af1, 0x16af2, 0x16af3, 0x16af4,
9237 0x16b30, 0x16b31, 0x16b32, 0x16b33, 0x16b34, 0x16b35, 0x16b36, 0x16f4f,
9238 0x16f51, 0x16f52, 0x16f53, 0x16f54, 0x16f55, 0x16f56, 0x16f57, 0x16f58,
9239 0x16f59, 0x16f5a, 0x16f5b, 0x16f5c, 0x16f5d, 0x16f5e, 0x16f5f, 0x16f60,
9240 0x16f61, 0x16f62, 0x16f63, 0x16f64, 0x16f65, 0x16f66, 0x16f67, 0x16f68,
9241 0x16f69, 0x16f6a, 0x16f6b, 0x16f6c, 0x16f6d, 0x16f6e, 0x16f6f, 0x16f70,
9242 0x16f71, 0x16f72, 0x16f73, 0x16f74, 0x16f75, 0x16f76, 0x16f77, 0x16f78,
9243 0x16f79, 0x16f7a, 0x16f7b, 0x16f7c, 0x16f7d, 0x16f7e, 0x16f7f, 0x16f80,
9244 0x16f81, 0x16f82, 0x16f83, 0x16f84, 0x16f85, 0x16f86, 0x16f87, 0x16f8f,
9245 0x16f90, 0x16f91, 0x16f92, 0x16fe4, 0x16ff0, 0x16ff1, 0x1bc9d, 0x1bc9e,
9246 0x1d165, 0x1d166, 0x1d167, 0x1d168, 0x1d169, 0x1d16d, 0x1d16e, 0x1d16f,
9247 0x1d170, 0x1d171, 0x1d172, 0x1d17b, 0x1d17c, 0x1d17d, 0x1d17e, 0x1d17f,
9248 0x1d180, 0x1d181, 0x1d182, 0x1d185, 0x1d186, 0x1d187, 0x1d188, 0x1d189,
9249 0x1d18a, 0x1d18b, 0x1d1aa, 0x1d1ab, 0x1d1ac, 0x1d1ad, 0x1d242, 0x1d243,
9250 0x1d244, 0x1da00, 0x1da01, 0x1da02, 0x1da03, 0x1da04, 0x1da05, 0x1da06,
9251 0x1da07, 0x1da08, 0x1da09, 0x1da0a, 0x1da0b, 0x1da0c, 0x1da0d, 0x1da0e,
9252 0x1da0f, 0x1da10, 0x1da11, 0x1da12, 0x1da13, 0x1da14, 0x1da15, 0x1da16,
9253 0x1da17, 0x1da18, 0x1da19, 0x1da1a, 0x1da1b, 0x1da1c, 0x1da1d, 0x1da1e,
9254 0x1da1f, 0x1da20, 0x1da21, 0x1da22, 0x1da23, 0x1da24, 0x1da25, 0x1da26,
9255 0x1da27, 0x1da28, 0x1da29, 0x1da2a, 0x1da2b, 0x1da2c, 0x1da2d, 0x1da2e,
9256 0x1da2f, 0x1da30, 0x1da31, 0x1da32, 0x1da33, 0x1da34, 0x1da35, 0x1da36,
9257 0x1da3b, 0x1da3c, 0x1da3d, 0x1da3e, 0x1da3f, 0x1da40, 0x1da41, 0x1da42,
9258 0x1da43, 0x1da44, 0x1da45, 0x1da46, 0x1da47, 0x1da48, 0x1da49, 0x1da4a,
9259 0x1da4b, 0x1da4c, 0x1da4d, 0x1da4e, 0x1da4f, 0x1da50, 0x1da51, 0x1da52,
9260 0x1da53, 0x1da54, 0x1da55, 0x1da56, 0x1da57, 0x1da58, 0x1da59, 0x1da5a,
9261 0x1da5b, 0x1da5c, 0x1da5d, 0x1da5e, 0x1da5f, 0x1da60, 0x1da61, 0x1da62,
9262 0x1da63, 0x1da64, 0x1da65, 0x1da66, 0x1da67, 0x1da68, 0x1da69, 0x1da6a,
9263 0x1da6b, 0x1da6c, 0x1da75, 0x1da84, 0x1da9b, 0x1da9c, 0x1da9d, 0x1da9e,
9264 0x1da9f, 0x1daa1, 0x1daa2, 0x1daa3, 0x1daa4, 0x1daa5, 0x1daa6, 0x1daa7,
9265 0x1daa8, 0x1daa9, 0x1daaa, 0x1daab, 0x1daac, 0x1daad, 0x1daae, 0x1daaf,
9266 0x1e000, 0x1e001, 0x1e002, 0x1e003, 0x1e004, 0x1e005, 0x1e006, 0x1e008,
9267 0x1e009, 0x1e00a, 0x1e00b, 0x1e00c, 0x1e00d, 0x1e00e, 0x1e00f, 0x1e010,
9268 0x1e011, 0x1e012, 0x1e013, 0x1e014, 0x1e015, 0x1e016, 0x1e017, 0x1e018,
9269 0x1e01b, 0x1e01c, 0x1e01d, 0x1e01e, 0x1e01f, 0x1e020, 0x1e021, 0x1e023,
9270 0x1e024, 0x1e026, 0x1e027, 0x1e028, 0x1e029, 0x1e02a, 0x1e130, 0x1e131,
9271 0x1e132, 0x1e133, 0x1e134, 0x1e135, 0x1e136, 0x1e2ec, 0x1e2ed, 0x1e2ee,
9272 0x1e2ef, 0x1e8d0, 0x1e8d1, 0x1e8d2, 0x1e8d3, 0x1e8d4, 0x1e8d5, 0x1e8d6,
9273 0x1e944, 0x1e945, 0x1e946, 0x1e947, 0x1e948, 0x1e949, 0x1e94a, 0xe0100,
9274 0xe0101, 0xe0102, 0xe0103, 0xe0104, 0xe0105, 0xe0106, 0xe0107, 0xe0108,
9275 0xe0109, 0xe010a, 0xe010b, 0xe010c, 0xe010d, 0xe010e, 0xe010f, 0xe0110,
9276 0xe0111, 0xe0112, 0xe0113, 0xe0114, 0xe0115, 0xe0116, 0xe0117, 0xe0118,
9277 0xe0119, 0xe011a, 0xe011b, 0xe011c, 0xe011d, 0xe011e, 0xe011f, 0xe0120,
9278 0xe0121, 0xe0122, 0xe0123, 0xe0124, 0xe0125, 0xe0126, 0xe0127, 0xe0128,
9279 0xe0129, 0xe012a, 0xe012b, 0xe012c, 0xe012d, 0xe012e, 0xe012f, 0xe0130,
9280 0xe0131, 0xe0132, 0xe0133, 0xe0134, 0xe0135, 0xe0136, 0xe0137, 0xe0138,
9281 0xe0139, 0xe013a, 0xe013b, 0xe013c, 0xe013d, 0xe013e, 0xe013f, 0xe0140,
9282 0xe0141, 0xe0142, 0xe0143, 0xe0144, 0xe0145, 0xe0146, 0xe0147, 0xe0148,
9283 0xe0149, 0xe014a, 0xe014b, 0xe014c, 0xe014d, 0xe014e, 0xe014f, 0xe0150,
9284 0xe0151, 0xe0152, 0xe0153, 0xe0154, 0xe0155, 0xe0156, 0xe0157, 0xe0158,
9285 0xe0159, 0xe015a, 0xe015b, 0xe015c, 0xe015d, 0xe015e, 0xe015f, 0xe0160,
9286 0xe0161, 0xe0162, 0xe0163, 0xe0164, 0xe0165, 0xe0166, 0xe0167, 0xe0168,
9287 0xe0169, 0xe016a, 0xe016b, 0xe016c, 0xe016d, 0xe016e, 0xe016f, 0xe0170,
9288 0xe0171, 0xe0172, 0xe0173, 0xe0174, 0xe0175, 0xe0176, 0xe0177, 0xe0178,
9289 0xe0179, 0xe017a, 0xe017b, 0xe017c, 0xe017d, 0xe017e, 0xe017f, 0xe0180,
9290 0xe0181, 0xe0182, 0xe0183, 0xe0184, 0xe0185, 0xe0186, 0xe0187, 0xe0188,
9291 0xe0189, 0xe018a, 0xe018b, 0xe018c, 0xe018d, 0xe018e, 0xe018f, 0xe0190,
9292 0xe0191, 0xe0192, 0xe0193, 0xe0194, 0xe0195, 0xe0196, 0xe0197, 0xe0198,
9293 0xe0199, 0xe019a, 0xe019b, 0xe019c, 0xe019d, 0xe019e, 0xe019f, 0xe01a0,
9294 0xe01a1, 0xe01a2, 0xe01a3, 0xe01a4, 0xe01a5, 0xe01a6, 0xe01a7, 0xe01a8,
9295 0xe01a9, 0xe01aa, 0xe01ab, 0xe01ac, 0xe01ad, 0xe01ae, 0xe01af, 0xe01b0,
9296 0xe01b1, 0xe01b2, 0xe01b3, 0xe01b4, 0xe01b5, 0xe01b6, 0xe01b7, 0xe01b8,
9297 0xe01b9, 0xe01ba, 0xe01bb, 0xe01bc, 0xe01bd, 0xe01be, 0xe01bf, 0xe01c0,
9298 0xe01c1, 0xe01c2, 0xe01c3, 0xe01c4, 0xe01c5, 0xe01c6, 0xe01c7, 0xe01c8,
9299 0xe01c9, 0xe01ca, 0xe01cb, 0xe01cc, 0xe01cd, 0xe01ce, 0xe01cf, 0xe01d0,
9300 0xe01d1, 0xe01d2, 0xe01d3, 0xe01d4, 0xe01d5, 0xe01d6, 0xe01d7, 0xe01d8,
9301 0xe01d9, 0xe01da, 0xe01db, 0xe01dc, 0xe01dd, 0xe01de, 0xe01df, 0xe01e0,
9302 0xe01e1, 0xe01e2, 0xe01e3, 0xe01e4, 0xe01e5, 0xe01e6, 0xe01e7, 0xe01e8,
9303 0xe01e9, 0xe01ea, 0xe01eb, 0xe01ec, 0xe01ed, 0xe01ee, 0xe01ef};
9304 if (std::binary_search(std::begin(combining), std::end(combining),
9305 label.front())) {
9306 return false;
9307 }
9308 // We verify this next step as part of the mapping:
9309 // ---------------------------------------------
9310 // Each code point in the label must only have certain status values
9311 // according to Section 5, IDNA Mapping Table:
9312 // - For Transitional Processing, each value must be valid.
9313 // - For Nontransitional Processing, each value must be either valid or
9314 // deviation.
9315
9316 // If CheckJoiners, the label must satisfy the ContextJ rules from Appendix
9317 // A, in The Unicode Code Points and Internationalized Domain Names for
9318 // Applications (IDNA) [IDNA2008].
9319 constexpr static uint32_t virama[] = {
9320 0x094D, 0x09CD, 0x0A4D, 0x0ACD, 0x0B4D, 0x0BCD, 0x0C4D, 0x0CCD,
9321 0x0D3B, 0x0D3C, 0x0D4D, 0x0DCA, 0x0E3A, 0x0EBA, 0x0F84, 0x1039,
9322 0x103A, 0x1714, 0x1734, 0x17D2, 0x1A60, 0x1B44, 0x1BAA, 0x1BAB,
9323 0x1BF2, 0x1BF3, 0x2D7F, 0xA806, 0xA82C, 0xA8C4, 0xA953, 0xA9C0,
9324 0xAAF6, 0xABED, 0x10A3F, 0x11046, 0x1107F, 0x110B9, 0x11133, 0x11134,
9325 0x111C0, 0x11235, 0x112EA, 0x1134D, 0x11442, 0x114C2, 0x115BF, 0x1163F,
9326 0x116B6, 0x1172B, 0x11839, 0x1193D, 0x1193E, 0x119E0, 0x11A34, 0x11A47,
9327 0x11A99, 0x11C3F, 0x11D44, 0x11D45, 0x11D97};
9328 constexpr static uint32_t R[] = {
9329 0x622, 0x623, 0x624, 0x625, 0x627, 0x629, 0x62f, 0x630, 0x631,
9330 0x632, 0x648, 0x671, 0x672, 0x673, 0x675, 0x676, 0x677, 0x688,
9331 0x689, 0x68a, 0x68b, 0x68c, 0x68d, 0x68e, 0x68f, 0x690, 0x691,
9332 0x692, 0x693, 0x694, 0x695, 0x696, 0x697, 0x698, 0x699, 0x6c0,
9333 0x6c3, 0x6c4, 0x6c5, 0x6c6, 0x6c7, 0x6c8, 0x6c9, 0x6ca, 0x6cb,
9334 0x6cd, 0x6cf, 0x6d2, 0x6d3, 0x6d5, 0x6ee, 0x6ef, 0x710, 0x715,
9335 0x716, 0x717, 0x718, 0x719, 0x71e, 0x728, 0x72a, 0x72c, 0x72f,
9336 0x74d, 0x759, 0x75a, 0x75b, 0x854, 0x8aa, 0x8ab, 0x8ac};
9337 constexpr static uint32_t L[] = {0xa872};
9338 constexpr static uint32_t D[] = {
9339 0x620, 0x626, 0x628, 0x62a, 0x62b, 0x62c, 0x62d, 0x62e, 0x633,
9340 0x634, 0x635, 0x636, 0x637, 0x638, 0x639, 0x63a, 0x63b, 0x63c,
9341 0x63d, 0x63e, 0x63f, 0x641, 0x642, 0x643, 0x644, 0x645, 0x646,
9342 0x647, 0x649, 0x64a, 0x66e, 0x66f, 0x678, 0x679, 0x67a, 0x67b,
9343 0x67c, 0x67d, 0x67e, 0x67f, 0x680, 0x681, 0x682, 0x683, 0x684,
9344 0x685, 0x686, 0x687, 0x69a, 0x69b, 0x69c, 0x69d, 0x69e, 0x69f,
9345 0x6a0, 0x6a1, 0x6a2, 0x6a3, 0x6a4, 0x6a5, 0x6a6, 0x6a7, 0x6a8,
9346 0x6a9, 0x6aa, 0x6ab, 0x6ac, 0x6ad, 0x6ae, 0x6af, 0x6b0, 0x6b1,
9347 0x6b2, 0x6b3, 0x6b4, 0x6b5, 0x6b6, 0x6b7, 0x6b8, 0x6b9, 0x6ba,
9348 0x6bb, 0x6bc, 0x6bd, 0x6be, 0x6bf, 0x6c1, 0x6c2, 0x6cc, 0x6ce,
9349 0x6d0, 0x6d1, 0x6fa, 0x6fb, 0x6fc, 0x6ff, 0x712, 0x713, 0x714,
9350 0x71a, 0x71b, 0x71c, 0x71d, 0x71f, 0x720, 0x721, 0x722, 0x723,
9351 0x724, 0x725, 0x726, 0x727, 0x729, 0x72b, 0x72d, 0x72e, 0x74e,
9352 0x74f, 0x750, 0x751, 0x752, 0x753, 0x754, 0x755, 0x756, 0x757,
9353 0x758, 0x75c, 0x75d, 0x75e, 0x75f, 0x760, 0x761, 0x762, 0x763,
9354 0x764, 0x765, 0x766, 0x850, 0x851, 0x852, 0x853, 0x855, 0x8a0,
9355 0x8a2, 0x8a3, 0x8a4, 0x8a5, 0x8a6, 0x8a7, 0x8a8, 0x8a9, 0x1807,
9356 0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827, 0x1828,
9357 0x1829, 0x182a, 0x182b, 0x182c, 0x182d, 0x182e, 0x182f, 0x1830, 0x1831,
9358 0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837, 0x1838, 0x1839, 0x183a,
9359 0x183b, 0x183c, 0x183d, 0x183e, 0x183f, 0x1840, 0x1841, 0x1842, 0x1843,
9360 0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x184a, 0x184b, 0x184c,
9361 0x184d, 0x184e, 0x184f, 0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855,
9362 0x1856, 0x1857, 0x1858, 0x1859, 0x185a, 0x185b, 0x185c, 0x185d, 0x185e,
9363 0x185f, 0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867,
9364 0x1868, 0x1869, 0x186a, 0x186b, 0x186c, 0x186d, 0x186e, 0x186f, 0x1870,
9365 0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877, 0x1887, 0x1888,
9366 0x1889, 0x188a, 0x188b, 0x188c, 0x188d, 0x188e, 0x188f, 0x1890, 0x1891,
9367 0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897, 0x1898, 0x1899, 0x189a,
9368 0x189b, 0x189c, 0x189d, 0x189e, 0x189f, 0x18a0, 0x18a1, 0x18a2, 0x18a3,
9369 0x18a4, 0x18a5, 0x18a6, 0x18a7, 0x18a8, 0x18aa, 0xa840, 0xa841, 0xa842,
9370 0xa843, 0xa844, 0xa845, 0xa846, 0xa847, 0xa848, 0xa849, 0xa84a, 0xa84b,
9371 0xa84c, 0xa84d, 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa853, 0xa854,
9372 0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c, 0xa85d,
9373 0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864, 0xa865, 0xa866,
9374 0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c, 0xa86d, 0xa86e, 0xa86f,
9375 0xa870, 0xa871};
9376
9377 for (size_t i = 0; i < label.size(); i++) {
9378 uint32_t c = label[i];
9379 if (c == 0x200c) {
9380 if (i > 0) {
9381 if (std::binary_search(std::begin(virama), std::end(virama),
9382 label[i - 1])) {
9383 return true;
9384 }
9385 }
9386 if ((i == 0) || (i + 1 >= label.size())) {
9387 return false;
9388 }
9389 // we go backward looking for L or D
9390 auto is_l_or_d = [](uint32_t code) {
9391 return std::binary_search(std::begin(L), std::end(L), code) ||
9392 std::binary_search(std::begin(D), std::end(D), code);
9393 };
9394 auto is_r_or_d = [](uint32_t code) {
9395 return std::binary_search(std::begin(R), std::end(R), code) ||
9396 std::binary_search(std::begin(D), std::end(D), code);
9397 };
9398 std::u32string_view before = label.substr(0, i);
9399 std::u32string_view after = label.substr(i + 1);
9400 return (std::find_if(before.begin(), before.end(), is_l_or_d) !=
9401 before.end()) &&
9402 (std::find_if(after.begin(), after.end(), is_r_or_d) !=
9403 after.end());
9404 } else if (c == 0x200d) {
9405 if (i > 0) {
9406 if (std::binary_search(std::begin(virama), std::end(virama),
9407 label[i - 1])) {
9408 return true;
9409 }
9410 }
9411 return false;
9412 }
9413 }
9414
9415 // If CheckBidi, and if the domain name is a Bidi domain name, then the label
9416 // must satisfy all six of the numbered conditions in [IDNA2008] RFC 5893,
9417 // Section 2.
9418
9419 // The following rule, consisting of six conditions, applies to labels
9420 // in Bidi domain names. The requirements that this rule satisfies are
9421 // described in Section 3. All of the conditions must be satisfied for
9422 // the rule to be satisfied.
9423 //
9424 // 1. The first character must be a character with Bidi property L, R,
9425 // or AL. If it has the R or AL property, it is an RTL label; if it
9426 // has the L property, it is an LTR label.
9427 //
9428 // 2. In an RTL label, only characters with the Bidi properties R, AL,
9429 // AN, EN, ES, CS, ET, ON, BN, or NSM are allowed.
9430 //
9431 // 3. In an RTL label, the end of the label must be a character with
9432 // Bidi property R, AL, EN, or AN, followed by zero or more
9433 // characters with Bidi property NSM.
9434 //
9435 // 4. In an RTL label, if an EN is present, no AN may be present, and
9436 // vice versa.
9437 //
9438 // 5. In an LTR label, only characters with the Bidi properties L, EN,
9439 // ES, CS, ET, ON, BN, or NSM are allowed.
9440 //
9441 // 6. In an LTR label, the end of the label must be a character with
9442 // Bidi property L or EN, followed by zero or more characters with
9443 // Bidi property NSM.
9444
9445 size_t last_non_nsm_char = find_last_not_of_nsm(label);
9446 if (last_non_nsm_char == std::u32string_view::npos) {
9447 return false;
9448 }
9449
9450 // A "Bidi domain name" is a domain name that contains at least one RTL label.
9451 // The following rule, consisting of six conditions, applies to labels in Bidi
9452 // domain names.
9453 if (is_rtl_label(label)) {
9454 // The first character must be a character with Bidi property L, R,
9455 // or AL. If it has the R or AL property, it is an RTL label; if it
9456 // has the L property, it is an LTR label.
9457
9458 if (find_direction(label[0]) == direction::L) {
9459 // Eval as LTR
9460
9461 // In an LTR label, only characters with the Bidi properties L, EN,
9462 // ES, CS, ET, ON, BN, or NSM are allowed.
9463 for (size_t i = 0; i < last_non_nsm_char; i++) {
9464 const direction d = find_direction(label[i]);
9465 if (!(d == direction::L || d == direction::EN || d == direction::ES ||
9466 d == direction::CS || d == direction::ET || d == direction::ON ||
9467 d == direction::BN || d == direction::NSM)) {
9468 return false;
9469 }
9470
9471 if ((i == last_non_nsm_char) &&
9472 !(d == direction::L || d == direction::EN)) {
9473 return false;
9474 }
9475 }
9476
9477 return true;
9478
9479 } else {
9480 // Eval as RTL
9481
9482 bool has_an = false;
9483 bool has_en = false;
9484 for (size_t i = 0; i <= last_non_nsm_char; i++) {
9485 const direction d = find_direction(label[i]);
9486
9487 // In an RTL label, if an EN is present, no AN may be present, and vice
9488 // versa.
9489 if ((d == direction::EN && ((has_en = true) && has_an)) ||
9490 (d == direction::AN && ((has_an = true) && has_en))) {
9491 return false;
9492 }
9493
9494 if (!(d == direction::R || d == direction::AL || d == direction::AN ||
9495 d == direction::EN || d == direction::ES || d == direction::CS ||
9496 d == direction::ET || d == direction::ON || d == direction::BN ||
9497 d == direction::NSM)) {
9498 return false;
9499 }
9500
9501 if (i == last_non_nsm_char &&
9502 !(d == direction::R || d == direction::AL || d == direction::AN ||
9503 d == direction::EN)) {
9504 return false;
9505 }
9506 }
9507
9508 return true;
9509 }
9510 }
9511
9512 return true;
9513 }
9514
9515 } // namespace ada::idna
9516 /* end file src/validity.cpp */
9517 /* begin file src/to_ascii.cpp */
9518
9519 #include <algorithm>
9520 #include <cstdint>
9521
9522
9523 namespace ada::idna {
9524
begins_with(std::u32string_view view,std::u32string_view prefix)9525 bool begins_with(std::u32string_view view, std::u32string_view prefix) {
9526 if (view.size() < prefix.size()) {
9527 return false;
9528 }
9529 // constexpr as of C++20
9530 return std::equal(prefix.begin(), prefix.end(), view.begin());
9531 }
9532
begins_with(std::string_view view,std::string_view prefix)9533 bool begins_with(std::string_view view, std::string_view prefix) {
9534 if (view.size() < prefix.size()) {
9535 return false;
9536 }
9537 // constexpr as of C++20
9538 return std::equal(prefix.begin(), prefix.end(), view.begin());
9539 }
9540
is_ascii(std::u32string_view view)9541 bool constexpr is_ascii(std::u32string_view view) {
9542 for (uint32_t c : view) {
9543 if (c >= 0x80) {
9544 return false;
9545 }
9546 }
9547 return true;
9548 }
9549
is_ascii(std::string_view view)9550 bool constexpr is_ascii(std::string_view view) {
9551 for (uint8_t c : view) {
9552 if (c >= 0x80) {
9553 return false;
9554 }
9555 }
9556 return true;
9557 }
9558
9559 constexpr static uint8_t is_forbidden_domain_code_point_table[] = {
9560 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9561 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
9562 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
9563 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
9564 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9565 0, 0, 0, 0, 1, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1,
9568 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9569 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
9570 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
9571
9572 static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
9573
is_forbidden_domain_code_point(const char c)9574 inline bool is_forbidden_domain_code_point(const char c) noexcept {
9575 return is_forbidden_domain_code_point_table[uint8_t(c)];
9576 }
9577
contains_forbidden_domain_code_point(std::string_view view)9578 bool contains_forbidden_domain_code_point(std::string_view view) {
9579 return (
9580 std::any_of(view.begin(), view.end(), is_forbidden_domain_code_point));
9581 }
9582
9583 // We return "" on error.
from_ascii_to_ascii(std::string_view ut8_string)9584 static std::string from_ascii_to_ascii(std::string_view ut8_string) {
9585 static const std::string error = "";
9586 // copy and map
9587 // we could be more efficient by avoiding the copy when unnecessary.
9588 std::string mapped_string = std::string(ut8_string);
9589 ascii_map(mapped_string.data(), mapped_string.size());
9590 std::string out;
9591 size_t label_start = 0;
9592
9593 while (label_start != mapped_string.size()) {
9594 size_t loc_dot = mapped_string.find('.', label_start);
9595 bool is_last_label = (loc_dot == std::string_view::npos);
9596 size_t label_size = is_last_label ? mapped_string.size() - label_start
9597 : loc_dot - label_start;
9598 size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;
9599 std::string_view label_view(mapped_string.data() + label_start, label_size);
9600 label_start += label_size_with_dot;
9601 if (label_size == 0) {
9602 // empty label? Nothing to do.
9603 } else if (begins_with(label_view, "xn--")) {
9604 // The xn-- part is the expensive game.
9605 out.append(label_view);
9606 std::string_view puny_segment_ascii(
9607 out.data() + out.size() - label_view.size() + 4,
9608 label_view.size() - 4);
9609 std::u32string tmp_buffer;
9610 bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);
9611 if (!is_ok) {
9612 return error;
9613 }
9614 std::u32string post_map = ada::idna::map(tmp_buffer);
9615 if (tmp_buffer != post_map) {
9616 return error;
9617 }
9618 std::u32string pre_normal = post_map;
9619 normalize(post_map);
9620 if (post_map != pre_normal) {
9621 return error;
9622 }
9623 if (post_map.empty()) {
9624 return error;
9625 }
9626 if (!is_label_valid(post_map)) {
9627 return error;
9628 }
9629 } else {
9630 out.append(label_view);
9631 }
9632 if (!is_last_label) {
9633 out.push_back('.');
9634 }
9635 }
9636 return out;
9637 }
9638
9639 // We return "" on error.
to_ascii(std::string_view ut8_string)9640 std::string to_ascii(std::string_view ut8_string) {
9641 if (is_ascii(ut8_string)) {
9642 return from_ascii_to_ascii(ut8_string);
9643 }
9644 static const std::string error = "";
9645 // We convert to UTF-32
9646 size_t utf32_length =
9647 ada::idna::utf32_length_from_utf8(ut8_string.data(), ut8_string.size());
9648 std::u32string utf32(utf32_length, '\0');
9649 size_t actual_utf32_length = ada::idna::utf8_to_utf32(
9650 ut8_string.data(), ut8_string.size(), utf32.data());
9651 if (actual_utf32_length == 0) {
9652 return error;
9653 }
9654 // mapping
9655 utf32 = ada::idna::map(utf32);
9656 normalize(utf32);
9657 std::string out;
9658 size_t label_start = 0;
9659
9660 while (label_start != utf32.size()) {
9661 size_t loc_dot = utf32.find('.', label_start);
9662 bool is_last_label = (loc_dot == std::string_view::npos);
9663 size_t label_size =
9664 is_last_label ? utf32.size() - label_start : loc_dot - label_start;
9665 size_t label_size_with_dot = is_last_label ? label_size : label_size + 1;
9666 std::u32string_view label_view(utf32.data() + label_start, label_size);
9667 label_start += label_size_with_dot;
9668 if (label_size == 0) {
9669 // empty label? Nothing to do.
9670 } else if (begins_with(label_view, U"xn--")) {
9671 // we do not need to check, e.g., Xn-- because mapping goes to lower case
9672 for (char32_t c : label_view) {
9673 if (c >= 0x80) {
9674 return error;
9675 }
9676 out += (unsigned char)(c);
9677 }
9678 std::string_view puny_segment_ascii(
9679 out.data() + out.size() - label_view.size() + 4,
9680 label_view.size() - 4);
9681 std::u32string tmp_buffer;
9682 bool is_ok = ada::idna::punycode_to_utf32(puny_segment_ascii, tmp_buffer);
9683 if (!is_ok) {
9684 return error;
9685 }
9686 std::u32string post_map = ada::idna::map(tmp_buffer);
9687 if (tmp_buffer != post_map) {
9688 return error;
9689 }
9690 std::u32string pre_normal = post_map;
9691 normalize(post_map);
9692 if (post_map != pre_normal) {
9693 return error;
9694 }
9695 if (post_map.empty()) {
9696 return error;
9697 }
9698 if (!is_label_valid(post_map)) {
9699 return error;
9700 }
9701 } else {
9702 // The fast path here is an ascii label.
9703 if (is_ascii(label_view)) {
9704 // no validation needed.
9705 for (char32_t c : label_view) {
9706 out += (unsigned char)(c);
9707 }
9708 } else {
9709 // slow path.
9710 // first check validity.
9711 if (!is_label_valid(label_view)) {
9712 return error;
9713 }
9714 // It is valid! So now we must encode it as punycode...
9715 out.append("xn--");
9716 bool is_ok = ada::idna::utf32_to_punycode(label_view, out);
9717 if (!is_ok) {
9718 return error;
9719 }
9720 }
9721 }
9722 if (!is_last_label) {
9723 out.push_back('.');
9724 }
9725 }
9726 return out;
9727 }
9728 } // namespace ada::idna
9729 /* end file src/to_ascii.cpp */
9730 /* begin file src/to_unicode.cpp */
9731
9732 #include <algorithm>
9733 #include <string>
9734
9735
9736 namespace ada::idna {
to_unicode(std::string_view input)9737 std::string to_unicode(std::string_view input) {
9738 std::string output;
9739 output.reserve(input.size());
9740
9741 size_t label_start = 0;
9742 while (label_start < input.size()) {
9743 size_t loc_dot = input.find('.', label_start);
9744 bool is_last_label = (loc_dot == std::string_view::npos);
9745 size_t label_size =
9746 is_last_label ? input.size() - label_start : loc_dot - label_start;
9747 auto label_view = std::string_view(input.data() + label_start, label_size);
9748
9749 if (ada::idna::begins_with(label_view, "xn--") &&
9750 ada::idna::is_ascii(label_view)) {
9751 label_view.remove_prefix(4);
9752 if (ada::idna::verify_punycode(label_view)) {
9753 std::u32string tmp_buffer;
9754 if (ada::idna::punycode_to_utf32(label_view, tmp_buffer)) {
9755 auto utf8_size = ada::idna::utf8_length_from_utf32(tmp_buffer.data(),
9756 tmp_buffer.size());
9757 std::string final_utf8(utf8_size, '\0');
9758 ada::idna::utf32_to_utf8(tmp_buffer.data(), tmp_buffer.size(),
9759 final_utf8.data());
9760 output.append(final_utf8);
9761 } else {
9762 // ToUnicode never fails. If any step fails, then the original input
9763 // sequence is returned immediately in that step.
9764 output.append(
9765 std::string_view(input.data() + label_start, label_size));
9766 }
9767 } else {
9768 output.append(std::string_view(input.data() + label_start, label_size));
9769 }
9770 } else {
9771 output.append(label_view);
9772 }
9773
9774 if (!is_last_label) {
9775 output.push_back('.');
9776 }
9777
9778 label_start += label_size + 1;
9779 }
9780
9781 return output;
9782 }
9783 } // namespace ada::idna
9784 /* end file src/to_unicode.cpp */
9785 /* end file src/idna.cpp */
9786 /* end file src/ada_idna.cpp */
9787 ADA_POP_DISABLE_WARNINGS
9788
9789 #include <algorithm>
9790 #if ADA_NEON
9791 #include <arm_neon.h>
9792 #elif ADA_SSE2
9793 #include <emmintrin.h>
9794 #endif
9795
9796 namespace ada::unicode {
9797
broadcast(uint8_t v)9798 constexpr uint64_t broadcast(uint8_t v) noexcept {
9799 return 0x101010101010101ull * v;
9800 }
9801
to_lower_ascii(char * input,size_t length)9802 constexpr bool to_lower_ascii(char* input, size_t length) noexcept {
9803 uint64_t broadcast_80 = broadcast(0x80);
9804 uint64_t broadcast_Ap = broadcast(128 - 'A');
9805 uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
9806 uint64_t non_ascii = 0;
9807 size_t i = 0;
9808
9809 for (; i + 7 < length; i += 8) {
9810 uint64_t word{};
9811 memcpy(&word, input + i, sizeof(word));
9812 non_ascii |= (word & broadcast_80);
9813 word ^=
9814 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
9815 memcpy(input + i, &word, sizeof(word));
9816 }
9817 if (i < length) {
9818 uint64_t word{};
9819 memcpy(&word, input + i, length - i);
9820 non_ascii |= (word & broadcast_80);
9821 word ^=
9822 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
9823 memcpy(input + i, &word, length - i);
9824 }
9825 return non_ascii == 0;
9826 }
9827 #if ADA_NEON
has_tabs_or_newline(std::string_view user_input)9828 ada_really_inline bool has_tabs_or_newline(
9829 std::string_view user_input) noexcept {
9830 // first check for short strings in which case we do it naively.
9831 if (user_input.size() < 16) { // slow path
9832 for (size_t i = 0; i < user_input.size(); i++) {
9833 if (user_input[i] == '\r' || user_input[i] == '\n' ||
9834 user_input[i] == '\t') {
9835 return true;
9836 }
9837 }
9838 return false;
9839 }
9840 // fast path for long strings (expected to be common)
9841 size_t i = 0;
9842 const uint8x16_t mask1 = vmovq_n_u8('\r');
9843 const uint8x16_t mask2 = vmovq_n_u8('\n');
9844 const uint8x16_t mask3 = vmovq_n_u8('\t');
9845 uint8x16_t running{0};
9846 for (; i + 15 < user_input.size(); i += 16) {
9847 uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i);
9848 running = vorrq_u8(vorrq_u8(running, vorrq_u8(vceqq_u8(word, mask1),
9849 vceqq_u8(word, mask2))),
9850 vceqq_u8(word, mask3));
9851 }
9852 if (i < user_input.size()) {
9853 uint8x16_t word =
9854 vld1q_u8((const uint8_t*)user_input.data() + user_input.length() - 16);
9855 running = vorrq_u8(vorrq_u8(running, vorrq_u8(vceqq_u8(word, mask1),
9856 vceqq_u8(word, mask2))),
9857 vceqq_u8(word, mask3));
9858 }
9859 return vmaxvq_u8(running) != 0;
9860 }
9861 #elif ADA_SSE2
has_tabs_or_newline(std::string_view user_input)9862 ada_really_inline bool has_tabs_or_newline(
9863 std::string_view user_input) noexcept {
9864 // first check for short strings in which case we do it naively.
9865 if (user_input.size() < 16) { // slow path
9866 for (size_t i = 0; i < user_input.size(); i++) {
9867 if (user_input[i] == '\r' || user_input[i] == '\n' ||
9868 user_input[i] == '\t') {
9869 return true;
9870 }
9871 }
9872 return false;
9873 }
9874 // fast path for long strings (expected to be common)
9875 size_t i = 0;
9876 const __m128i mask1 = _mm_set1_epi8('\r');
9877 const __m128i mask2 = _mm_set1_epi8('\n');
9878 const __m128i mask3 = _mm_set1_epi8('\t');
9879 __m128i running{0};
9880 for (; i + 15 < user_input.size(); i += 16) {
9881 __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));
9882 running = _mm_or_si128(
9883 _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
9884 _mm_cmpeq_epi8(word, mask2))),
9885 _mm_cmpeq_epi8(word, mask3));
9886 }
9887 if (i < user_input.size()) {
9888 __m128i word = _mm_loadu_si128(
9889 (const __m128i*)(user_input.data() + user_input.length() - 16));
9890 running = _mm_or_si128(
9891 _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
9892 _mm_cmpeq_epi8(word, mask2))),
9893 _mm_cmpeq_epi8(word, mask3));
9894 }
9895 return _mm_movemask_epi8(running) != 0;
9896 }
9897 #else
has_tabs_or_newline(std::string_view user_input)9898 ada_really_inline bool has_tabs_or_newline(
9899 std::string_view user_input) noexcept {
9900 auto has_zero_byte = [](uint64_t v) {
9901 return ((v - 0x0101010101010101) & ~(v)&0x8080808080808080);
9902 };
9903 size_t i = 0;
9904 uint64_t mask1 = broadcast('\r');
9905 uint64_t mask2 = broadcast('\n');
9906 uint64_t mask3 = broadcast('\t');
9907 uint64_t running{0};
9908 for (; i + 7 < user_input.size(); i += 8) {
9909 uint64_t word{};
9910 memcpy(&word, user_input.data() + i, sizeof(word));
9911 uint64_t xor1 = word ^ mask1;
9912 uint64_t xor2 = word ^ mask2;
9913 uint64_t xor3 = word ^ mask3;
9914 running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
9915 }
9916 if (i < user_input.size()) {
9917 uint64_t word{};
9918 memcpy(&word, user_input.data() + i, user_input.size() - i);
9919 uint64_t xor1 = word ^ mask1;
9920 uint64_t xor2 = word ^ mask2;
9921 uint64_t xor3 = word ^ mask3;
9922 running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
9923 }
9924 return running;
9925 }
9926 #endif
9927
9928 // A forbidden host code point is U+0000 NULL, U+0009 TAB, U+000A LF, U+000D CR,
9929 // U+0020 SPACE, U+0023 (#), U+002F (/), U+003A (:), U+003C (<), U+003E (>),
9930 // U+003F (?), U+0040 (@), U+005B ([), U+005C (\), U+005D (]), U+005E (^), or
9931 // U+007C (|).
9932 constexpr static std::array<uint8_t, 256> is_forbidden_host_code_point_table =
__anon4ddc785e0902() 9933 []() constexpr {
9934 std::array<uint8_t, 256> result{};
9935 for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
9936 '>', '?', '@', '[', '\\', ']', '^', '|'}) {
9937 result[c] = true;
9938 }
9939 return result;
9940 }();
9941
is_forbidden_host_code_point(const char c)9942 ada_really_inline constexpr bool is_forbidden_host_code_point(
9943 const char c) noexcept {
9944 return is_forbidden_host_code_point_table[uint8_t(c)];
9945 }
9946
9947 constexpr static std::array<uint8_t, 256> is_forbidden_domain_code_point_table =
__anon4ddc785e0a02() 9948 []() constexpr {
9949 std::array<uint8_t, 256> result{};
9950 for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
9951 '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
9952 result[c] = true;
9953 }
9954 for (uint8_t c = 0; c <= 32; c++) {
9955 result[c] = true;
9956 }
9957 for (size_t c = 127; c < 255; c++) {
9958 result[c] = true;
9959 }
9960 return result;
9961 }();
9962
9963 static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
9964
is_forbidden_domain_code_point(const char c)9965 ada_really_inline constexpr bool is_forbidden_domain_code_point(
9966 const char c) noexcept {
9967 return is_forbidden_domain_code_point_table[uint8_t(c)];
9968 }
9969
contains_forbidden_domain_code_point(const char * input,size_t length)9970 ada_really_inline constexpr bool contains_forbidden_domain_code_point(
9971 const char* input, size_t length) noexcept {
9972 size_t i = 0;
9973 uint8_t accumulator{};
9974 for (; i + 4 <= length; i += 4) {
9975 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
9976 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 1])];
9977 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 2])];
9978 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 3])];
9979 }
9980 for (; i < length; i++) {
9981 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
9982 }
9983 return accumulator;
9984 }
9985
9986 constexpr static std::array<uint8_t, 256>
__anon4ddc785e0b02() 9987 is_forbidden_domain_code_point_table_or_upper = []() constexpr {
9988 std::array<uint8_t, 256> result{};
9989 for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
9990 '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
9991 result[c] = 1;
9992 }
9993 for (uint8_t c = 'A'; c <= 'Z'; c++) {
9994 result[c] = 2;
9995 }
9996 for (uint8_t c = 0; c <= 32; c++) {
9997 result[c] = 1;
9998 }
9999 for (size_t c = 127; c < 255; c++) {
10000 result[c] = 1;
10001 }
10002 return result;
10003 }();
10004
10005 ada_really_inline constexpr uint8_t
contains_forbidden_domain_code_point_or_upper(const char * input,size_t length)10006 contains_forbidden_domain_code_point_or_upper(const char* input,
10007 size_t length) noexcept {
10008 size_t i = 0;
10009 uint8_t accumulator{};
10010 for (; i + 4 <= length; i += 4) {
10011 accumulator |=
10012 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
10013 accumulator |=
10014 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 1])];
10015 accumulator |=
10016 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 2])];
10017 accumulator |=
10018 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 3])];
10019 }
10020 for (; i < length; i++) {
10021 accumulator |=
10022 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i])];
10023 }
10024 return accumulator;
10025 }
10026
10027 // std::isalnum(c) || c == '+' || c == '-' || c == '.') is true for
__anon4ddc785e0c02() 10028 constexpr static std::array<bool, 256> is_alnum_plus_table = []() constexpr {
10029 std::array<bool, 256> result{};
10030 for (size_t c = 0; c < 256; c++) {
10031 if (c >= '0' && c <= '9') {
10032 result[c] = true;
10033 } else if (c >= 'a' && c <= 'z') {
10034 result[c] = true;
10035 } else if (c >= 'A' && c <= 'Z') {
10036 result[c] = true;
10037 } else if (c == '+' || c == '-' || c == '.') {
10038 result[c] = true;
10039 }
10040 }
10041 return result;
10042 }();
10043
is_alnum_plus(const char c)10044 ada_really_inline constexpr bool is_alnum_plus(const char c) noexcept {
10045 return is_alnum_plus_table[uint8_t(c)];
10046 // A table is almost surely much faster than the
10047 // following under most compilers: return
10048 // return (std::isalnum(c) || c == '+' || c == '-' || c == '.');
10049 }
10050
is_ascii_hex_digit(const char c)10051 ada_really_inline constexpr bool is_ascii_hex_digit(const char c) noexcept {
10052 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
10053 (c >= 'a' && c <= 'f');
10054 }
10055
is_c0_control_or_space(const char c)10056 ada_really_inline constexpr bool is_c0_control_or_space(const char c) noexcept {
10057 return (unsigned char)c <= ' ';
10058 }
10059
is_ascii_tab_or_newline(const char c)10060 ada_really_inline constexpr bool is_ascii_tab_or_newline(
10061 const char c) noexcept {
10062 return c == '\t' || c == '\n' || c == '\r';
10063 }
10064
10065 constexpr std::string_view table_is_double_dot_path_segment[] = {
10066 "..", "%2e.", ".%2e", "%2e%2e"};
10067
is_double_dot_path_segment(std::string_view input)10068 ada_really_inline ada_constexpr bool is_double_dot_path_segment(
10069 std::string_view input) noexcept {
10070 // This will catch most cases:
10071 // The length must be 2,4 or 6.
10072 // We divide by two and require
10073 // that the result be between 1 and 3 inclusively.
10074 uint64_t half_length = uint64_t(input.size()) / 2;
10075 if (half_length - 1 > 2) {
10076 return false;
10077 }
10078 // We have a string of length 2, 4 or 6.
10079 // We now check the first character:
10080 if ((input[0] != '.') && (input[0] != '%')) {
10081 return false;
10082 }
10083 // We are unlikely the get beyond this point.
10084 int hash_value = (input.size() + (unsigned)(input[0])) & 3;
10085 const std::string_view target = table_is_double_dot_path_segment[hash_value];
10086 if (target.size() != input.size()) {
10087 return false;
10088 }
10089 // We almost never get here.
10090 // Optimizing the rest is relatively unimportant.
10091 auto prefix_equal_unsafe = [](std::string_view a, std::string_view b) {
10092 uint16_t A, B;
10093 memcpy(&A, a.data(), sizeof(A));
10094 memcpy(&B, b.data(), sizeof(B));
10095 return A == B;
10096 };
10097 if (!prefix_equal_unsafe(input, target)) {
10098 return false;
10099 }
10100 for (size_t i = 2; i < input.size(); i++) {
10101 char c = input[i];
10102 if ((uint8_t((c | 0x20) - 0x61) <= 25 ? (c | 0x20) : c) != target[i]) {
10103 return false;
10104 }
10105 }
10106 return true;
10107 // The above code might be a bit better than the code below. Compilers
10108 // are not stupid and may use the fact that these strings have length 2,4 and
10109 // 6 and other tricks.
10110 // return input == ".." ||
10111 // input == ".%2e" || input == ".%2E" ||
10112 // input == "%2e." || input == "%2E." ||
10113 // input == "%2e%2e" || input == "%2E%2E" || input == "%2E%2e" || input ==
10114 // "%2e%2E";
10115 }
10116
is_single_dot_path_segment(std::string_view input)10117 ada_really_inline constexpr bool is_single_dot_path_segment(
10118 std::string_view input) noexcept {
10119 return input == "." || input == "%2e" || input == "%2E";
10120 }
10121
is_lowercase_hex(const char c)10122 ada_really_inline constexpr bool is_lowercase_hex(const char c) noexcept {
10123 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
10124 }
10125
10126 constexpr static char hex_to_binary_table[] = {
10127 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11,
10128 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
convert_hex_to_binary(const char c)10130 unsigned constexpr convert_hex_to_binary(const char c) noexcept {
10131 return hex_to_binary_table[c - '0'];
10132 }
10133
percent_decode(const std::string_view input,size_t first_percent)10134 std::string percent_decode(const std::string_view input, size_t first_percent) {
10135 // next line is for safety only, we expect users to avoid calling
10136 // percent_decode when first_percent is outside the range.
10137 if (first_percent == std::string_view::npos) {
10138 return std::string(input);
10139 }
10140 std::string dest;
10141 dest.reserve(input.length());
10142 dest.append(input.substr(0, first_percent));
10143 const char* pointer = input.data() + first_percent;
10144 const char* end = input.data() + input.size();
10145 // Optimization opportunity: if the following code gets
10146 // called often, it can be optimized quite a bit.
10147 while (pointer < end) {
10148 const char ch = pointer[0];
10149 size_t remaining = end - pointer - 1;
10150 if (ch != '%' || remaining < 2 ||
10151 ( // ch == '%' && // It is unnecessary to check that ch == '%'.
10152 (!is_ascii_hex_digit(pointer[1]) ||
10153 !is_ascii_hex_digit(pointer[2])))) {
10154 dest += ch;
10155 pointer++;
10156 continue;
10157 } else {
10158 unsigned a = convert_hex_to_binary(pointer[1]);
10159 unsigned b = convert_hex_to_binary(pointer[2]);
10160 char c = static_cast<char>(a * 16 + b);
10161 dest += c;
10162 pointer += 3;
10163 }
10164 }
10165 return dest;
10166 }
10167
percent_encode(const std::string_view input,const uint8_t character_set[])10168 std::string percent_encode(const std::string_view input,
10169 const uint8_t character_set[]) {
10170 auto pointer =
10171 std::find_if(input.begin(), input.end(), [character_set](const char c) {
10172 return character_sets::bit_at(character_set, c);
10173 });
10174 // Optimization: Don't iterate if percent encode is not required
10175 if (pointer == input.end()) {
10176 return std::string(input);
10177 }
10178
10179 std::string result;
10180 result.reserve(input.length()); // in the worst case, percent encoding might
10181 // produce 3 characters.
10182 result.append(input.substr(0, std::distance(input.begin(), pointer)));
10183
10184 for (; pointer != input.end(); pointer++) {
10185 if (character_sets::bit_at(character_set, *pointer)) {
10186 result.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
10187 } else {
10188 result += *pointer;
10189 }
10190 }
10191
10192 return result;
10193 }
10194
10195 template <bool append>
percent_encode(const std::string_view input,const uint8_t character_set[],std::string & out)10196 bool percent_encode(const std::string_view input, const uint8_t character_set[],
10197 std::string& out) {
10198 ada_log("percent_encode ", input, " to output string while ",
10199 append ? "appending" : "overwriting");
10200 auto pointer =
10201 std::find_if(input.begin(), input.end(), [character_set](const char c) {
10202 return character_sets::bit_at(character_set, c);
10203 });
10204 ada_log("percent_encode done checking, moved to ",
10205 std::distance(input.begin(), pointer));
10206
10207 // Optimization: Don't iterate if percent encode is not required
10208 if (pointer == input.end()) {
10209 ada_log("percent_encode encoding not needed.");
10210 return false;
10211 }
10212 if (!append) {
10213 out.clear();
10214 }
10215 ada_log("percent_encode appending ", std::distance(input.begin(), pointer),
10216 " bytes");
10217 out.append(input.data(), std::distance(input.begin(), pointer));
10218 ada_log("percent_encode processing ", std::distance(pointer, input.end()),
10219 " bytes");
10220 for (; pointer != input.end(); pointer++) {
10221 if (character_sets::bit_at(character_set, *pointer)) {
10222 out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
10223 } else {
10224 out += *pointer;
10225 }
10226 }
10227 return true;
10228 }
10229
to_ascii(std::optional<std::string> & out,const std::string_view plain,size_t first_percent)10230 bool to_ascii(std::optional<std::string>& out, const std::string_view plain,
10231 size_t first_percent) {
10232 std::string percent_decoded_buffer;
10233 std::string_view input = plain;
10234 if (first_percent != std::string_view::npos) {
10235 percent_decoded_buffer = unicode::percent_decode(plain, first_percent);
10236 input = percent_decoded_buffer;
10237 }
10238 // input is a non-empty UTF-8 string, must be percent decoded
10239 std::string idna_ascii = ada::idna::to_ascii(input);
10240 if (idna_ascii.empty() || contains_forbidden_domain_code_point(
10241 idna_ascii.data(), idna_ascii.size())) {
10242 return false;
10243 }
10244 out = std::move(idna_ascii);
10245 return true;
10246 }
10247
percent_encode(const std::string_view input,const uint8_t character_set[],size_t index)10248 std::string percent_encode(const std::string_view input,
10249 const uint8_t character_set[], size_t index) {
10250 std::string out;
10251 out.append(input.data(), index);
10252 auto pointer = input.begin() + index;
10253 for (; pointer != input.end(); pointer++) {
10254 if (character_sets::bit_at(character_set, *pointer)) {
10255 out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
10256 } else {
10257 out += *pointer;
10258 }
10259 }
10260 return out;
10261 }
10262
to_unicode(std::string_view input)10263 std::string to_unicode(std::string_view input) {
10264 return ada::idna::to_unicode(input);
10265 }
10266
10267 } // namespace ada::unicode
10268 /* end file src/unicode.cpp */
10269 /* begin file src/serializers.cpp */
10270
10271 #include <array>
10272 #include <string>
10273
10274 namespace ada::serializers {
10275
find_longest_sequence_of_ipv6_pieces(const std::array<uint16_t,8> & address,size_t & compress,size_t & compress_length)10276 void find_longest_sequence_of_ipv6_pieces(
10277 const std::array<uint16_t, 8>& address, size_t& compress,
10278 size_t& compress_length) noexcept {
10279 for (size_t i = 0; i < 8; i++) {
10280 if (address[i] == 0) {
10281 size_t next = i + 1;
10282 while (next != 8 && address[next] == 0) ++next;
10283 const size_t count = next - i;
10284 if (compress_length < count) {
10285 compress_length = count;
10286 compress = i;
10287 if (next == 8) break;
10288 i = next;
10289 }
10290 }
10291 }
10292 }
10293
ipv6(const std::array<uint16_t,8> & address)10294 std::string ipv6(const std::array<uint16_t, 8>& address) noexcept {
10295 size_t compress_length = 0; // The length of a long sequence of zeros.
10296 size_t compress = 0; // The start of a long sequence of zeros.
10297 find_longest_sequence_of_ipv6_pieces(address, compress, compress_length);
10298
10299 if (compress_length <= 1) {
10300 // Optimization opportunity: Find a faster way then snprintf for imploding
10301 // and return here.
10302 compress = compress_length = 8;
10303 }
10304
10305 std::string output(4 * 8 + 7 + 2, '\0');
10306 size_t piece_index = 0;
10307 char* point = output.data();
10308 char* point_end = output.data() + output.size();
10309 *point++ = '[';
10310 while (true) {
10311 if (piece_index == compress) {
10312 *point++ = ':';
10313 // If we skip a value initially, we need to write '::', otherwise
10314 // a single ':' will do since it follows a previous ':'.
10315 if (piece_index == 0) {
10316 *point++ = ':';
10317 }
10318 piece_index += compress_length;
10319 if (piece_index == 8) {
10320 break;
10321 }
10322 }
10323 point = std::to_chars(point, point_end, address[piece_index], 16).ptr;
10324 piece_index++;
10325 if (piece_index == 8) {
10326 break;
10327 }
10328 *point++ = ':';
10329 }
10330 *point++ = ']';
10331 output.resize(point - output.data());
10332 return output;
10333 }
10334
ipv4(const uint64_t address)10335 std::string ipv4(const uint64_t address) noexcept {
10336 std::string output(15, '\0');
10337 char* point = output.data();
10338 char* point_end = output.data() + output.size();
10339 point = std::to_chars(point, point_end, uint8_t(address >> 24)).ptr;
10340 for (int i = 2; i >= 0; i--) {
10341 *point++ = '.';
10342 point = std::to_chars(point, point_end, uint8_t(address >> (i * 8))).ptr;
10343 }
10344 output.resize(point - output.data());
10345 return output;
10346 }
10347
10348 } // namespace ada::serializers
10349 /* end file src/serializers.cpp */
10350 /* begin file src/implementation.cpp */
10351 #include <string_view>
10352
10353
10354 namespace ada {
10355
10356 template <class result_type>
parse(std::string_view input,const result_type * base_url)10357 ada_warn_unused tl::expected<result_type, ada::errors> parse(
10358 std::string_view input, const result_type* base_url) {
10359 result_type u = ada::parser::parse_url<result_type>(input, base_url);
10360 if (!u.is_valid) {
10361 return tl::unexpected(errors::generic_error);
10362 }
10363 return u;
10364 }
10365
10366 template ada::result<url> parse<url>(std::string_view input,
10367 const url* base_url = nullptr);
10368 template ada::result<url_aggregator> parse<url_aggregator>(
10369 std::string_view input, const url_aggregator* base_url = nullptr);
10370
href_from_file(std::string_view input)10371 std::string href_from_file(std::string_view input) {
10372 // This is going to be much faster than constructing a URL.
10373 std::string tmp_buffer;
10374 std::string_view internal_input;
10375 if (unicode::has_tabs_or_newline(input)) {
10376 tmp_buffer = input;
10377 helpers::remove_ascii_tab_or_newline(tmp_buffer);
10378 internal_input = tmp_buffer;
10379 } else {
10380 internal_input = input;
10381 }
10382 std::string path;
10383 if (internal_input.empty()) {
10384 path = "/";
10385 } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
10386 helpers::parse_prepared_path(internal_input.substr(1),
10387 ada::scheme::type::FILE, path);
10388 } else {
10389 helpers::parse_prepared_path(internal_input, ada::scheme::type::FILE, path);
10390 }
10391 return "file://" + path;
10392 }
10393
can_parse(std::string_view input,const std::string_view * base_input)10394 bool can_parse(std::string_view input, const std::string_view* base_input) {
10395 ada::result<ada::url_aggregator> base;
10396 ada::url_aggregator* base_pointer = nullptr;
10397 if (base_input != nullptr) {
10398 base = ada::parse<url_aggregator>(*base_input);
10399 if (!base) {
10400 return false;
10401 }
10402 base_pointer = &base.value();
10403 }
10404 return ada::parse<url_aggregator>(input, base_pointer).has_value();
10405 }
10406
to_string(ada::encoding_type type)10407 ada_warn_unused std::string to_string(ada::encoding_type type) {
10408 switch (type) {
10409 case ada::encoding_type::UTF8:
10410 return "UTF-8";
10411 case ada::encoding_type::UTF_16LE:
10412 return "UTF-16LE";
10413 case ada::encoding_type::UTF_16BE:
10414 return "UTF-16BE";
10415 default:
10416 unreachable();
10417 }
10418 }
10419
10420 } // namespace ada
10421 /* end file src/implementation.cpp */
10422 /* begin file src/helpers.cpp */
10423
10424 #include <algorithm>
10425 #include <charconv>
10426 #include <cstring>
10427 #include <sstream>
10428
10429 namespace ada::helpers {
10430
10431 template <typename out_iter>
encode_json(std::string_view view,out_iter out)10432 void encode_json(std::string_view view, out_iter out) {
10433 // trivial implementation. could be faster.
10434 const char* hexvalues =
10435 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
10436 for (uint8_t c : view) {
10437 if (c == '\\') {
10438 *out++ = '\\';
10439 *out++ = '\\';
10440 } else if (c == '"') {
10441 *out++ = '\\';
10442 *out++ = '"';
10443 } else if (c <= 0x1f) {
10444 *out++ = '\\';
10445 *out++ = 'u';
10446 *out++ = '0';
10447 *out++ = '0';
10448 *out++ = hexvalues[2 * c];
10449 *out++ = hexvalues[2 * c + 1];
10450 } else {
10451 *out++ = c;
10452 }
10453 }
10454 }
10455
get_state(ada::state s)10456 ada_unused std::string get_state(ada::state s) {
10457 switch (s) {
10458 case ada::state::AUTHORITY:
10459 return "Authority";
10460 case ada::state::SCHEME_START:
10461 return "Scheme Start";
10462 case ada::state::SCHEME:
10463 return "Scheme";
10464 case ada::state::HOST:
10465 return "Host";
10466 case ada::state::NO_SCHEME:
10467 return "No Scheme";
10468 case ada::state::FRAGMENT:
10469 return "Fragment";
10470 case ada::state::RELATIVE_SCHEME:
10471 return "Relative Scheme";
10472 case ada::state::RELATIVE_SLASH:
10473 return "Relative Slash";
10474 case ada::state::FILE:
10475 return "File";
10476 case ada::state::FILE_HOST:
10477 return "File Host";
10478 case ada::state::FILE_SLASH:
10479 return "File Slash";
10480 case ada::state::PATH_OR_AUTHORITY:
10481 return "Path or Authority";
10482 case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES:
10483 return "Special Authority Ignore Slashes";
10484 case ada::state::SPECIAL_AUTHORITY_SLASHES:
10485 return "Special Authority Slashes";
10486 case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY:
10487 return "Special Relative or Authority";
10488 case ada::state::QUERY:
10489 return "Query";
10490 case ada::state::PATH:
10491 return "Path";
10492 case ada::state::PATH_START:
10493 return "Path Start";
10494 case ada::state::OPAQUE_PATH:
10495 return "Opaque Path";
10496 case ada::state::PORT:
10497 return "Port";
10498 default:
10499 return "unknown state";
10500 }
10501 }
10502
prune_hash(std::string_view & input)10503 ada_really_inline std::optional<std::string_view> prune_hash(
10504 std::string_view& input) noexcept {
10505 // compiles down to 20--30 instructions including a class to memchr (C
10506 // function). this function should be quite fast.
10507 size_t location_of_first = input.find('#');
10508 if (location_of_first == std::string_view::npos) {
10509 return std::nullopt;
10510 }
10511 std::string_view hash = input;
10512 hash.remove_prefix(location_of_first + 1);
10513 input.remove_suffix(input.size() - location_of_first);
10514 return hash;
10515 }
10516
shorten_path(std::string & path,ada::scheme::type type)10517 ada_really_inline bool shorten_path(std::string& path,
10518 ada::scheme::type type) noexcept {
10519 size_t first_delimiter = path.find_first_of('/', 1);
10520
10521 // Let path be url's path.
10522 // If url's scheme is "file", path's size is 1, and path[0] is a normalized
10523 // Windows drive letter, then return.
10524 if (type == ada::scheme::type::FILE &&
10525 first_delimiter == std::string_view::npos && !path.empty()) {
10526 if (checkers::is_normalized_windows_drive_letter(
10527 helpers::substring(path, 1))) {
10528 return false;
10529 }
10530 }
10531
10532 // Remove path's last item, if any.
10533 size_t last_delimiter = path.rfind('/');
10534 if (last_delimiter != std::string::npos) {
10535 path.erase(last_delimiter);
10536 return true;
10537 }
10538
10539 return false;
10540 }
10541
shorten_path(std::string_view & path,ada::scheme::type type)10542 ada_really_inline bool shorten_path(std::string_view& path,
10543 ada::scheme::type type) noexcept {
10544 size_t first_delimiter = path.find_first_of('/', 1);
10545
10546 // Let path be url's path.
10547 // If url's scheme is "file", path's size is 1, and path[0] is a normalized
10548 // Windows drive letter, then return.
10549 if (type == ada::scheme::type::FILE &&
10550 first_delimiter == std::string_view::npos && !path.empty()) {
10551 if (checkers::is_normalized_windows_drive_letter(
10552 helpers::substring(path, 1))) {
10553 return false;
10554 }
10555 }
10556
10557 // Remove path's last item, if any.
10558 if (!path.empty()) {
10559 size_t slash_loc = path.rfind('/');
10560 if (slash_loc != std::string_view::npos) {
10561 path.remove_suffix(path.size() - slash_loc);
10562 return true;
10563 }
10564 }
10565
10566 return false;
10567 }
10568
remove_ascii_tab_or_newline(std::string & input)10569 ada_really_inline void remove_ascii_tab_or_newline(
10570 std::string& input) noexcept {
10571 // if this ever becomes a performance issue, we could use an approach similar
10572 // to has_tabs_or_newline
10573 input.erase(std::remove_if(input.begin(), input.end(),
10574 [](char c) {
10575 return ada::unicode::is_ascii_tab_or_newline(c);
10576 }),
10577 input.end());
10578 }
10579
substring(std::string_view input,size_t pos)10580 ada_really_inline std::string_view substring(std::string_view input,
10581 size_t pos) noexcept {
10582 ADA_ASSERT_TRUE(pos <= input.size());
10583 // The following is safer but unneeded if we have the above line:
10584 // return pos > input.size() ? std::string_view() : input.substr(pos);
10585 return input.substr(pos);
10586 }
10587
resize(std::string_view & input,size_t pos)10588 ada_really_inline void resize(std::string_view& input, size_t pos) noexcept {
10589 ADA_ASSERT_TRUE(pos <= input.size());
10590 input.remove_suffix(input.size() - pos);
10591 }
10592
10593 // computes the number of trailing zeroes
10594 // this is a private inline function only defined in this source file.
trailing_zeroes(uint32_t input_num)10595 ada_really_inline int trailing_zeroes(uint32_t input_num) noexcept {
10596 #ifdef ADA_REGULAR_VISUAL_STUDIO
10597 unsigned long ret;
10598 // Search the mask data from least significant bit (LSB)
10599 // to the most significant bit (MSB) for a set bit (1).
10600 _BitScanForward(&ret, input_num);
10601 return (int)ret;
10602 #else // ADA_REGULAR_VISUAL_STUDIO
10603 return __builtin_ctzl(input_num);
10604 #endif // ADA_REGULAR_VISUAL_STUDIO
10605 }
10606
10607 // starting at index location, this finds the next location of a character
10608 // :, /, \\, ? or [. If none is found, view.size() is returned.
10609 // For use within get_host_delimiter_location.
10610 #if ADA_NEON
10611 // The ada_make_uint8x16_t macro is necessary because Visual Studio does not
10612 // support direct initialization of uint8x16_t. See
10613 // https://developercommunity.visualstudio.com/t/error-C2078:-too-many-initializers-whe/402911?q=backend+neon
10614 #ifndef ada_make_uint8x16_t
10615 #define ada_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \
10616 x13, x14, x15, x16) \
10617 ([=]() { \
10618 static uint8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \
10619 x9, x10, x11, x12, x13, x14, x15, x16}; \
10620 return vld1q_u8(array); \
10621 }())
10622 #endif
10623
find_next_host_delimiter_special(std::string_view view,size_t location)10624 ada_really_inline size_t find_next_host_delimiter_special(
10625 std::string_view view, size_t location) noexcept {
10626 // first check for short strings in which case we do it naively.
10627 if (view.size() - location < 16) { // slow path
10628 for (size_t i = location; i < view.size(); i++) {
10629 if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
10630 view[i] == '?' || view[i] == '[') {
10631 return i;
10632 }
10633 }
10634 return size_t(view.size());
10635 }
10636 auto to_bitmask = [](uint8x16_t input) -> uint16_t {
10637 uint8x16_t bit_mask =
10638 ada_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x01,
10639 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
10640 uint8x16_t minput = vandq_u8(input, bit_mask);
10641 uint8x16_t tmp = vpaddq_u8(minput, minput);
10642 tmp = vpaddq_u8(tmp, tmp);
10643 tmp = vpaddq_u8(tmp, tmp);
10644 return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0);
10645 };
10646
10647 // fast path for long strings (expected to be common)
10648 size_t i = location;
10649 uint8x16_t low_mask =
10650 ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10651 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x03);
10652 uint8x16_t high_mask =
10653 ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
10654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
10655 uint8x16_t fmask = vmovq_n_u8(0xf);
10656 uint8x16_t zero{0};
10657 for (; i + 15 < view.size(); i += 16) {
10658 uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
10659 uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
10660 uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
10661 uint8x16_t classify = vandq_u8(lowpart, highpart);
10662 if (vmaxvq_u8(classify) != 0) {
10663 uint8x16_t is_zero = vceqq_u8(classify, zero);
10664 uint16_t is_non_zero = ~to_bitmask(is_zero);
10665 return i + trailing_zeroes(is_non_zero);
10666 }
10667 }
10668
10669 if (i < view.size()) {
10670 uint8x16_t word =
10671 vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
10672 uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
10673 uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
10674 uint8x16_t classify = vandq_u8(lowpart, highpart);
10675 if (vmaxvq_u8(classify) != 0) {
10676 uint8x16_t is_zero = vceqq_u8(classify, zero);
10677 uint16_t is_non_zero = ~to_bitmask(is_zero);
10678 return view.length() - 16 + trailing_zeroes(is_non_zero);
10679 }
10680 }
10681 return size_t(view.size());
10682 }
10683 #elif ADA_SSE2
find_next_host_delimiter_special(std::string_view view,size_t location)10684 ada_really_inline size_t find_next_host_delimiter_special(
10685 std::string_view view, size_t location) noexcept {
10686 // first check for short strings in which case we do it naively.
10687 if (view.size() - location < 16) { // slow path
10688 for (size_t i = location; i < view.size(); i++) {
10689 if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
10690 view[i] == '?' || view[i] == '[') {
10691 return i;
10692 }
10693 }
10694 return size_t(view.size());
10695 }
10696 // fast path for long strings (expected to be common)
10697 size_t i = location;
10698 const __m128i mask1 = _mm_set1_epi8(':');
10699 const __m128i mask2 = _mm_set1_epi8('/');
10700 const __m128i mask3 = _mm_set1_epi8('\\');
10701 const __m128i mask4 = _mm_set1_epi8('?');
10702 const __m128i mask5 = _mm_set1_epi8('[');
10703
10704 for (; i + 15 < view.size(); i += 16) {
10705 __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
10706 __m128i m1 = _mm_cmpeq_epi8(word, mask1);
10707 __m128i m2 = _mm_cmpeq_epi8(word, mask2);
10708 __m128i m3 = _mm_cmpeq_epi8(word, mask3);
10709 __m128i m4 = _mm_cmpeq_epi8(word, mask4);
10710 __m128i m5 = _mm_cmpeq_epi8(word, mask5);
10711 __m128i m = _mm_or_si128(
10712 _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
10713 int mask = _mm_movemask_epi8(m);
10714 if (mask != 0) {
10715 return i + trailing_zeroes(mask);
10716 }
10717 }
10718 if (i < view.size()) {
10719 __m128i word =
10720 _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
10721 __m128i m1 = _mm_cmpeq_epi8(word, mask1);
10722 __m128i m2 = _mm_cmpeq_epi8(word, mask2);
10723 __m128i m3 = _mm_cmpeq_epi8(word, mask3);
10724 __m128i m4 = _mm_cmpeq_epi8(word, mask4);
10725 __m128i m5 = _mm_cmpeq_epi8(word, mask5);
10726 __m128i m = _mm_or_si128(
10727 _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
10728 int mask = _mm_movemask_epi8(m);
10729 if (mask != 0) {
10730 return view.length() - 16 + trailing_zeroes(mask);
10731 }
10732 }
10733 return size_t(view.length());
10734 }
10735 #else
10736 // : / [ \\ ?
10737 static constexpr std::array<uint8_t, 256> special_host_delimiters =
__anon4ddc785e1202() 10738 []() constexpr {
10739 std::array<uint8_t, 256> result{};
10740 for (int i : {':', '/', '[', '\\', '?'}) {
10741 result[i] = 1;
10742 }
10743 return result;
10744 }();
10745 // credit: @the-moisrex recommended a table-based approach
find_next_host_delimiter_special(std::string_view view,size_t location)10746 ada_really_inline size_t find_next_host_delimiter_special(
10747 std::string_view view, size_t location) noexcept {
10748 auto const str = view.substr(location);
10749 for (auto pos = str.begin(); pos != str.end(); ++pos) {
10750 if (special_host_delimiters[(uint8_t)*pos]) {
10751 return pos - str.begin() + location;
10752 }
10753 }
10754 return size_t(view.size());
10755 }
10756 #endif
10757
10758 // starting at index location, this finds the next location of a character
10759 // :, /, ? or [. If none is found, view.size() is returned.
10760 // For use within get_host_delimiter_location.
10761 #if ADA_NEON
find_next_host_delimiter(std::string_view view,size_t location)10762 ada_really_inline size_t find_next_host_delimiter(std::string_view view,
10763 size_t location) noexcept {
10764 // first check for short strings in which case we do it naively.
10765 if (view.size() - location < 16) { // slow path
10766 for (size_t i = location; i < view.size(); i++) {
10767 if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
10768 view[i] == '[') {
10769 return i;
10770 }
10771 }
10772 return size_t(view.size());
10773 }
10774 auto to_bitmask = [](uint8x16_t input) -> uint16_t {
10775 uint8x16_t bit_mask =
10776 ada_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x01,
10777 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
10778 uint8x16_t minput = vandq_u8(input, bit_mask);
10779 uint8x16_t tmp = vpaddq_u8(minput, minput);
10780 tmp = vpaddq_u8(tmp, tmp);
10781 tmp = vpaddq_u8(tmp, tmp);
10782 return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0);
10783 };
10784
10785 // fast path for long strings (expected to be common)
10786 size_t i = location;
10787 uint8x16_t low_mask =
10788 ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10789 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x03);
10790 uint8x16_t high_mask =
10791 ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
10792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
10793 uint8x16_t fmask = vmovq_n_u8(0xf);
10794 uint8x16_t zero{0};
10795 for (; i + 15 < view.size(); i += 16) {
10796 uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
10797 uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
10798 uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
10799 uint8x16_t classify = vandq_u8(lowpart, highpart);
10800 if (vmaxvq_u8(classify) != 0) {
10801 uint8x16_t is_zero = vceqq_u8(classify, zero);
10802 uint16_t is_non_zero = ~to_bitmask(is_zero);
10803 return i + trailing_zeroes(is_non_zero);
10804 }
10805 }
10806
10807 if (i < view.size()) {
10808 uint8x16_t word =
10809 vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
10810 uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
10811 uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
10812 uint8x16_t classify = vandq_u8(lowpart, highpart);
10813 if (vmaxvq_u8(classify) != 0) {
10814 uint8x16_t is_zero = vceqq_u8(classify, zero);
10815 uint16_t is_non_zero = ~to_bitmask(is_zero);
10816 return view.length() - 16 + trailing_zeroes(is_non_zero);
10817 }
10818 }
10819 return size_t(view.size());
10820 }
10821 #elif ADA_SSE2
find_next_host_delimiter(std::string_view view,size_t location)10822 ada_really_inline size_t find_next_host_delimiter(std::string_view view,
10823 size_t location) noexcept {
10824 // first check for short strings in which case we do it naively.
10825 if (view.size() - location < 16) { // slow path
10826 for (size_t i = location; i < view.size(); i++) {
10827 if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
10828 view[i] == '[') {
10829 return i;
10830 }
10831 }
10832 return size_t(view.size());
10833 }
10834 // fast path for long strings (expected to be common)
10835 size_t i = location;
10836 const __m128i mask1 = _mm_set1_epi8(':');
10837 const __m128i mask2 = _mm_set1_epi8('/');
10838 const __m128i mask4 = _mm_set1_epi8('?');
10839 const __m128i mask5 = _mm_set1_epi8('[');
10840
10841 for (; i + 15 < view.size(); i += 16) {
10842 __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
10843 __m128i m1 = _mm_cmpeq_epi8(word, mask1);
10844 __m128i m2 = _mm_cmpeq_epi8(word, mask2);
10845 __m128i m4 = _mm_cmpeq_epi8(word, mask4);
10846 __m128i m5 = _mm_cmpeq_epi8(word, mask5);
10847 __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
10848 int mask = _mm_movemask_epi8(m);
10849 if (mask != 0) {
10850 return i + trailing_zeroes(mask);
10851 }
10852 }
10853 if (i < view.size()) {
10854 __m128i word =
10855 _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
10856 __m128i m1 = _mm_cmpeq_epi8(word, mask1);
10857 __m128i m2 = _mm_cmpeq_epi8(word, mask2);
10858 __m128i m4 = _mm_cmpeq_epi8(word, mask4);
10859 __m128i m5 = _mm_cmpeq_epi8(word, mask5);
10860 __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
10861 int mask = _mm_movemask_epi8(m);
10862 if (mask != 0) {
10863 return view.length() - 16 + trailing_zeroes(mask);
10864 }
10865 }
10866 return size_t(view.length());
10867 }
10868 #else
10869 // : / [ ?
__anon4ddc785e1402() 10870 static constexpr std::array<uint8_t, 256> host_delimiters = []() constexpr {
10871 std::array<uint8_t, 256> result{};
10872 for (int i : {':', '/', '?', '['}) {
10873 result[i] = 1;
10874 }
10875 return result;
10876 }();
10877 // credit: @the-moisrex recommended a table-based approach
find_next_host_delimiter(std::string_view view,size_t location)10878 ada_really_inline size_t find_next_host_delimiter(std::string_view view,
10879 size_t location) noexcept {
10880 auto const str = view.substr(location);
10881 for (auto pos = str.begin(); pos != str.end(); ++pos) {
10882 if (host_delimiters[(uint8_t)*pos]) {
10883 return pos - str.begin() + location;
10884 }
10885 }
10886 return size_t(view.size());
10887 }
10888 #endif
10889
get_host_delimiter_location(const bool is_special,std::string_view & view)10890 ada_really_inline std::pair<size_t, bool> get_host_delimiter_location(
10891 const bool is_special, std::string_view& view) noexcept {
10892 /**
10893 * The spec at https://url.spec.whatwg.org/#hostname-state expects us to
10894 * compute a variable called insideBrackets but this variable is only used
10895 * once, to check whether a ':' character was found outside brackets. Exact
10896 * text: "Otherwise, if c is U+003A (:) and insideBrackets is false, then:".
10897 * It is conceptually simpler and arguably more efficient to just return a
10898 * Boolean indicating whether ':' was found outside brackets.
10899 */
10900 const size_t view_size = view.size();
10901 size_t location = 0;
10902 bool found_colon = false;
10903 /**
10904 * Performance analysis:
10905 *
10906 * We are basically seeking the end of the hostname which can be indicated
10907 * by the end of the view, or by one of the characters ':', '/', '?', '\\'
10908 * (where '\\' is only applicable for special URLs). However, these must
10909 * appear outside a bracket range. E.g., if you have [something?]fd: then the
10910 * '?' does not count.
10911 *
10912 * So we can skip ahead to the next delimiter, as long as we include '[' in
10913 * the set of delimiters, and that we handle it first.
10914 *
10915 * So the trick is to have a fast function that locates the next delimiter.
10916 * Unless we find '[', then it only needs to be called once! Ideally, such a
10917 * function would be provided by the C++ standard library, but it seems that
10918 * find_first_of is not very fast, so we are forced to roll our own.
10919 *
10920 * We do not break into two loops for speed, but for clarity.
10921 */
10922 if (is_special) {
10923 // We move to the next delimiter.
10924 location = find_next_host_delimiter_special(view, location);
10925 // Unless we find '[' then we are going only going to have to call
10926 // find_next_host_delimiter_special once.
10927 for (; location < view_size;
10928 location = find_next_host_delimiter_special(view, location)) {
10929 if (view[location] == '[') {
10930 location = view.find(']', location);
10931 if (location == std::string_view::npos) {
10932 // performance: view.find might get translated to a memchr, which
10933 // has no notion of std::string_view::npos, so the code does not
10934 // reflect the assembly.
10935 location = view_size;
10936 break;
10937 }
10938 } else {
10939 found_colon = view[location] == ':';
10940 break;
10941 }
10942 }
10943 } else {
10944 // We move to the next delimiter.
10945 location = find_next_host_delimiter(view, location);
10946 // Unless we find '[' then we are going only going to have to call
10947 // find_next_host_delimiter_special once.
10948 for (; location < view_size;
10949 location = find_next_host_delimiter(view, location)) {
10950 if (view[location] == '[') {
10951 location = view.find(']', location);
10952 if (location == std::string_view::npos) {
10953 // performance: view.find might get translated to a memchr, which
10954 // has no notion of std::string_view::npos, so the code does not
10955 // reflect the assembly.
10956 location = view_size;
10957 break;
10958 }
10959 } else {
10960 found_colon = view[location] == ':';
10961 break;
10962 }
10963 }
10964 }
10965 // performance: remove_suffix may translate into a single instruction.
10966 view.remove_suffix(view_size - location);
10967 return {location, found_colon};
10968 }
10969
trim_c0_whitespace(std::string_view & input)10970 ada_really_inline void trim_c0_whitespace(std::string_view& input) noexcept {
10971 while (!input.empty() &&
10972 ada::unicode::is_c0_control_or_space(input.front())) {
10973 input.remove_prefix(1);
10974 }
10975 while (!input.empty() && ada::unicode::is_c0_control_or_space(input.back())) {
10976 input.remove_suffix(1);
10977 }
10978 }
10979
parse_prepared_path(std::string_view input,ada::scheme::type type,std::string & path)10980 ada_really_inline void parse_prepared_path(std::string_view input,
10981 ada::scheme::type type,
10982 std::string& path) {
10983 ada_log("parse_prepared_path ", input);
10984 uint8_t accumulator = checkers::path_signature(input);
10985 // Let us first detect a trivial case.
10986 // If it is special, we check that we have no dot, no %, no \ and no
10987 // character needing percent encoding. Otherwise, we check that we have no %,
10988 // no dot, and no character needing percent encoding.
10989 constexpr uint8_t need_encoding = 1;
10990 constexpr uint8_t backslash_char = 2;
10991 constexpr uint8_t dot_char = 4;
10992 constexpr uint8_t percent_char = 8;
10993 bool special = type != ada::scheme::NOT_SPECIAL;
10994 bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
10995 checkers::is_windows_drive_letter(input));
10996 bool trivial_path =
10997 (special ? (accumulator == 0)
10998 : ((accumulator & (need_encoding | dot_char | percent_char)) ==
10999 0)) &&
11000 (!may_need_slow_file_handling);
11001 if (accumulator == dot_char && !may_need_slow_file_handling) {
11002 // '4' means that we have at least one dot, but nothing that requires
11003 // percent encoding or decoding. The only part that is not trivial is
11004 // that we may have single dots and double dots path segments.
11005 // If we have such segments, then we either have a path that begins
11006 // with '.' (easy to check), or we have the sequence './'.
11007 // Note: input cannot be empty, it must at least contain one character ('.')
11008 // Note: we know that '\' is not present.
11009 if (input[0] != '.') {
11010 size_t slashdot = input.find("/.");
11011 if (slashdot == std::string_view::npos) { // common case
11012 trivial_path = true;
11013 } else { // uncommon
11014 // only three cases matter: /./, /.. or a final /
11015 trivial_path =
11016 !(slashdot + 2 == input.size() || input[slashdot + 2] == '.' ||
11017 input[slashdot + 2] == '/');
11018 }
11019 }
11020 }
11021 if (trivial_path) {
11022 ada_log("parse_path trivial");
11023 path += '/';
11024 path += input;
11025 return;
11026 }
11027 // We are going to need to look a bit at the path, but let us see if we can
11028 // ignore percent encoding *and* backslashes *and* percent characters.
11029 // Except for the trivial case, this is likely to capture 99% of paths out
11030 // there.
11031 bool fast_path =
11032 (special &&
11033 (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
11034 (type != ada::scheme::type::FILE);
11035 if (fast_path) {
11036 ada_log("parse_prepared_path fast");
11037 // Here we don't need to worry about \ or percent encoding.
11038 // We also do not have a file protocol. We might have dots, however,
11039 // but dots must as appear as '.', and they cannot be encoded because
11040 // the symbol '%' is not present.
11041 size_t previous_location = 0; // We start at 0.
11042 do {
11043 size_t new_location = input.find('/', previous_location);
11044 // std::string_view path_view = input;
11045 // We process the last segment separately:
11046 if (new_location == std::string_view::npos) {
11047 std::string_view path_view = input.substr(previous_location);
11048 if (path_view == "..") { // The path ends with ..
11049 // e.g., if you receive ".." with an empty path, you go to "/".
11050 if (path.empty()) {
11051 path = '/';
11052 return;
11053 }
11054 // Fast case where we have nothing to do:
11055 if (path.back() == '/') {
11056 return;
11057 }
11058 // If you have the path "/joe/myfriend",
11059 // then you delete 'myfriend'.
11060 path.resize(path.rfind('/') + 1);
11061 return;
11062 }
11063 path += '/';
11064 if (path_view != ".") {
11065 path.append(path_view);
11066 }
11067 return;
11068 } else {
11069 // This is a non-final segment.
11070 std::string_view path_view =
11071 input.substr(previous_location, new_location - previous_location);
11072 previous_location = new_location + 1;
11073 if (path_view == "..") {
11074 size_t last_delimiter = path.rfind('/');
11075 if (last_delimiter != std::string::npos) {
11076 path.erase(last_delimiter);
11077 }
11078 } else if (path_view != ".") {
11079 path += '/';
11080 path.append(path_view);
11081 }
11082 }
11083 } while (true);
11084 } else {
11085 ada_log("parse_path slow");
11086 // we have reached the general case
11087 bool needs_percent_encoding = (accumulator & 1);
11088 std::string path_buffer_tmp;
11089 do {
11090 size_t location = (special && (accumulator & 2))
11091 ? input.find_first_of("/\\")
11092 : input.find('/');
11093 std::string_view path_view = input;
11094 if (location != std::string_view::npos) {
11095 path_view.remove_suffix(path_view.size() - location);
11096 input.remove_prefix(location + 1);
11097 }
11098 // path_buffer is either path_view or it might point at a percent encoded
11099 // temporary file.
11100 std::string_view path_buffer =
11101 (needs_percent_encoding &&
11102 ada::unicode::percent_encode<false>(
11103 path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
11104 ? path_buffer_tmp
11105 : path_view;
11106 if (unicode::is_double_dot_path_segment(path_buffer)) {
11107 if ((helpers::shorten_path(path, type) || special) &&
11108 location == std::string_view::npos) {
11109 path += '/';
11110 }
11111 } else if (unicode::is_single_dot_path_segment(path_buffer) &&
11112 (location == std::string_view::npos)) {
11113 path += '/';
11114 }
11115 // Otherwise, if path_buffer is not a single-dot path segment, then:
11116 else if (!unicode::is_single_dot_path_segment(path_buffer)) {
11117 // If url's scheme is "file", url's path is empty, and path_buffer is a
11118 // Windows drive letter, then replace the second code point in
11119 // path_buffer with U+003A (:).
11120 if (type == ada::scheme::type::FILE && path.empty() &&
11121 checkers::is_windows_drive_letter(path_buffer)) {
11122 path += '/';
11123 path += path_buffer[0];
11124 path += ':';
11125 path_buffer.remove_prefix(2);
11126 path.append(path_buffer);
11127 } else {
11128 // Append path_buffer to url's path.
11129 path += '/';
11130 path.append(path_buffer);
11131 }
11132 }
11133 if (location == std::string_view::npos) {
11134 return;
11135 }
11136 } while (true);
11137 }
11138 }
11139
overlaps(std::string_view input1,const std::string & input2)11140 bool overlaps(std::string_view input1, const std::string& input2) noexcept {
11141 ada_log("helpers::overlaps check if string_view '", input1, "' [",
11142 input1.size(), " bytes] is part of string '", input2, "' [",
11143 input2.size(), " bytes]");
11144 return !input1.empty() && !input2.empty() && input1.data() >= input2.data() &&
11145 input1.data() < input2.data() + input2.size();
11146 }
11147
11148 template <class url_type>
strip_trailing_spaces_from_opaque_path(url_type & url)11149 ada_really_inline void strip_trailing_spaces_from_opaque_path(
11150 url_type& url) noexcept {
11151 ada_log("helpers::strip_trailing_spaces_from_opaque_path");
11152 if (!url.has_opaque_path) return;
11153 if (url.has_hash()) return;
11154 if (url.has_search()) return;
11155
11156 auto path = std::string(url.get_pathname());
11157 while (!path.empty() && path.back() == ' ') {
11158 path.resize(path.size() - 1);
11159 }
11160 url.update_base_pathname(path);
11161 }
11162
11163 // @ / \\ ?
11164 static constexpr std::array<uint8_t, 256> authority_delimiter_special =
__anon4ddc785e1502() 11165 []() constexpr {
11166 std::array<uint8_t, 256> result{};
11167 for (int i : {'@', '/', '\\', '?'}) {
11168 result[i] = 1;
11169 }
11170 return result;
11171 }();
11172 // credit: @the-moisrex recommended a table-based approach
11173 ada_really_inline size_t
find_authority_delimiter_special(std::string_view view)11174 find_authority_delimiter_special(std::string_view view) noexcept {
11175 // performance note: we might be able to gain further performance
11176 // with SIMD instrinsics.
11177 for (auto pos = view.begin(); pos != view.end(); ++pos) {
11178 if (authority_delimiter_special[(uint8_t)*pos]) {
11179 return pos - view.begin();
11180 }
11181 }
11182 return size_t(view.size());
11183 }
11184
11185 // @ / ?
__anon4ddc785e1602() 11186 static constexpr std::array<uint8_t, 256> authority_delimiter = []() constexpr {
11187 std::array<uint8_t, 256> result{};
11188 for (int i : {'@', '/', '?'}) {
11189 result[i] = 1;
11190 }
11191 return result;
11192 }();
11193 // credit: @the-moisrex recommended a table-based approach
11194 ada_really_inline size_t
find_authority_delimiter(std::string_view view)11195 find_authority_delimiter(std::string_view view) noexcept {
11196 // performance note: we might be able to gain further performance
11197 // with SIMD instrinsics.
11198 for (auto pos = view.begin(); pos != view.end(); ++pos) {
11199 if (authority_delimiter[(uint8_t)*pos]) {
11200 return pos - view.begin();
11201 }
11202 }
11203 return size_t(view.size());
11204 }
11205
11206 } // namespace ada::helpers
11207
11208 namespace ada {
to_string(ada::state state)11209 ada_warn_unused std::string to_string(ada::state state) {
11210 return ada::helpers::get_state(state);
11211 }
11212 #undef ada_make_uint8x16_t
11213 } // namespace ada
11214 /* end file src/helpers.cpp */
11215 /* begin file src/url.cpp */
11216
11217 #include <numeric>
11218 #include <algorithm>
11219 #include <string>
11220
11221 namespace ada {
11222
parse_opaque_host(std::string_view input)11223 bool url::parse_opaque_host(std::string_view input) {
11224 ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
11225 if (std::any_of(input.begin(), input.end(),
11226 ada::unicode::is_forbidden_host_code_point)) {
11227 return is_valid = false;
11228 }
11229
11230 // Return the result of running UTF-8 percent-encode on input using the C0
11231 // control percent-encode set.
11232 host = ada::unicode::percent_encode(
11233 input, ada::character_sets::C0_CONTROL_PERCENT_ENCODE);
11234 return true;
11235 }
11236
parse_ipv4(std::string_view input)11237 bool url::parse_ipv4(std::string_view input) {
11238 ada_log("parse_ipv4 ", input, " [", input.size(), " bytes]");
11239 if (input.back() == '.') {
11240 input.remove_suffix(1);
11241 }
11242 size_t digit_count{0};
11243 int pure_decimal_count = 0; // entries that are decimal
11244 std::string_view original_input =
11245 input; // we might use this if pure_decimal_count == 4.
11246 uint64_t ipv4{0};
11247 // we could unroll for better performance?
11248 for (; (digit_count < 4) && !(input.empty()); digit_count++) {
11249 uint32_t
11250 segment_result{}; // If any number exceeds 32 bits, we have an error.
11251 bool is_hex = checkers::has_hex_prefix(input);
11252 if (is_hex && ((input.length() == 2) ||
11253 ((input.length() > 2) && (input[2] == '.')))) {
11254 // special case
11255 segment_result = 0;
11256 input.remove_prefix(2);
11257 } else {
11258 std::from_chars_result r;
11259 if (is_hex) {
11260 r = std::from_chars(input.data() + 2, input.data() + input.size(),
11261 segment_result, 16);
11262 } else if ((input.length() >= 2) && input[0] == '0' &&
11263 checkers::is_digit(input[1])) {
11264 r = std::from_chars(input.data() + 1, input.data() + input.size(),
11265 segment_result, 8);
11266 } else {
11267 pure_decimal_count++;
11268 r = std::from_chars(input.data(), input.data() + input.size(),
11269 segment_result, 10);
11270 }
11271 if (r.ec != std::errc()) {
11272 return is_valid = false;
11273 }
11274 input.remove_prefix(r.ptr - input.data());
11275 }
11276 if (input.empty()) {
11277 // We have the last value.
11278 // At this stage, ipv4 contains digit_count*8 bits.
11279 // So we have 32-digit_count*8 bits left.
11280 if (segment_result >= (uint64_t(1) << (32 - digit_count * 8))) {
11281 return is_valid = false;
11282 }
11283 ipv4 <<= (32 - digit_count * 8);
11284 ipv4 |= segment_result;
11285 goto final;
11286 } else {
11287 // There is more, so that the value must no be larger than 255
11288 // and we must have a '.'.
11289 if ((segment_result > 255) || (input[0] != '.')) {
11290 return is_valid = false;
11291 }
11292 ipv4 <<= 8;
11293 ipv4 |= segment_result;
11294 input.remove_prefix(1); // remove '.'
11295 }
11296 }
11297 if ((digit_count != 4) || (!input.empty())) {
11298 return is_valid = false;
11299 }
11300 final:
11301 // We could also check r.ptr to see where the parsing ended.
11302 if (pure_decimal_count == 4) {
11303 host = original_input; // The original input was already all decimal and we
11304 // validated it.
11305 } else {
11306 host = ada::serializers::ipv4(ipv4); // We have to reserialize the address.
11307 }
11308 host_type = IPV4;
11309 return true;
11310 }
11311
parse_ipv6(std::string_view input)11312 bool url::parse_ipv6(std::string_view input) {
11313 ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
11314
11315 if (input.empty()) {
11316 return is_valid = false;
11317 }
11318 // Let address be a new IPv6 address whose IPv6 pieces are all 0.
11319 std::array<uint16_t, 8> address{};
11320
11321 // Let pieceIndex be 0.
11322 int piece_index = 0;
11323
11324 // Let compress be null.
11325 std::optional<int> compress{};
11326
11327 // Let pointer be a pointer for input.
11328 std::string_view::iterator pointer = input.begin();
11329
11330 // If c is U+003A (:), then:
11331 if (input[0] == ':') {
11332 // If remaining does not start with U+003A (:), validation error, return
11333 // failure.
11334 if (input.size() == 1 || input[1] != ':') {
11335 ada_log("parse_ipv6 starts with : but the rest does not start with :");
11336 return is_valid = false;
11337 }
11338
11339 // Increase pointer by 2.
11340 pointer += 2;
11341
11342 // Increase pieceIndex by 1 and then set compress to pieceIndex.
11343 compress = ++piece_index;
11344 }
11345
11346 // While c is not the EOF code point:
11347 while (pointer != input.end()) {
11348 // If pieceIndex is 8, validation error, return failure.
11349 if (piece_index == 8) {
11350 ada_log("parse_ipv6 piece_index == 8");
11351 return is_valid = false;
11352 }
11353
11354 // If c is U+003A (:), then:
11355 if (*pointer == ':') {
11356 // If compress is non-null, validation error, return failure.
11357 if (compress.has_value()) {
11358 ada_log("parse_ipv6 compress is non-null");
11359 return is_valid = false;
11360 }
11361
11362 // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and
11363 // then continue.
11364 pointer++;
11365 compress = ++piece_index;
11366 continue;
11367 }
11368
11369 // Let value and length be 0.
11370 uint16_t value = 0, length = 0;
11371
11372 // While length is less than 4 and c is an ASCII hex digit,
11373 // set value to value times 0x10 + c interpreted as hexadecimal number, and
11374 // increase pointer and length by 1.
11375 while (length < 4 && pointer != input.end() &&
11376 unicode::is_ascii_hex_digit(*pointer)) {
11377 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
11378 value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));
11379 pointer++;
11380 length++;
11381 }
11382
11383 // If c is U+002E (.), then:
11384 if (pointer != input.end() && *pointer == '.') {
11385 // If length is 0, validation error, return failure.
11386 if (length == 0) {
11387 ada_log("parse_ipv6 length is 0");
11388 return is_valid = false;
11389 }
11390
11391 // Decrease pointer by length.
11392 pointer -= length;
11393
11394 // If pieceIndex is greater than 6, validation error, return failure.
11395 if (piece_index > 6) {
11396 ada_log("parse_ipv6 piece_index > 6");
11397 return is_valid = false;
11398 }
11399
11400 // Let numbersSeen be 0.
11401 int numbers_seen = 0;
11402
11403 // While c is not the EOF code point:
11404 while (pointer != input.end()) {
11405 // Let ipv4Piece be null.
11406 std::optional<uint16_t> ipv4_piece{};
11407
11408 // If numbersSeen is greater than 0, then:
11409 if (numbers_seen > 0) {
11410 // If c is a U+002E (.) and numbersSeen is less than 4, then increase
11411 // pointer by 1.
11412 if (*pointer == '.' && numbers_seen < 4) {
11413 pointer++;
11414 }
11415 // Otherwise, validation error, return failure.
11416 else {
11417 ada_log("parse_ipv6 Otherwise, validation error, return failure");
11418 return is_valid = false;
11419 }
11420 }
11421
11422 // If c is not an ASCII digit, validation error, return failure.
11423 if (pointer == input.end() || !checkers::is_digit(*pointer)) {
11424 ada_log(
11425 "parse_ipv6 If c is not an ASCII digit, validation error, return "
11426 "failure");
11427 return is_valid = false;
11428 }
11429
11430 // While c is an ASCII digit:
11431 while (pointer != input.end() && checkers::is_digit(*pointer)) {
11432 // Let number be c interpreted as decimal number.
11433 int number = *pointer - '0';
11434
11435 // If ipv4Piece is null, then set ipv4Piece to number.
11436 if (!ipv4_piece.has_value()) {
11437 ipv4_piece = number;
11438 }
11439 // Otherwise, if ipv4Piece is 0, validation error, return failure.
11440 else if (ipv4_piece == 0) {
11441 ada_log("parse_ipv6 if ipv4Piece is 0, validation error");
11442 return is_valid = false;
11443 }
11444 // Otherwise, set ipv4Piece to ipv4Piece times 10 + number.
11445 else {
11446 ipv4_piece = *ipv4_piece * 10 + number;
11447 }
11448
11449 // If ipv4Piece is greater than 255, validation error, return failure.
11450 if (ipv4_piece > 255) {
11451 ada_log("parse_ipv6 ipv4_piece > 255");
11452 return is_valid = false;
11453 }
11454
11455 // Increase pointer by 1.
11456 pointer++;
11457 }
11458
11459 // Set address[pieceIndex] to address[pieceIndex] times 0x100 +
11460 // ipv4Piece.
11461 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
11462 address[piece_index] =
11463 uint16_t(address[piece_index] * 0x100 + *ipv4_piece);
11464
11465 // Increase numbersSeen by 1.
11466 numbers_seen++;
11467
11468 // If numbersSeen is 2 or 4, then increase pieceIndex by 1.
11469 if (numbers_seen == 2 || numbers_seen == 4) {
11470 piece_index++;
11471 }
11472 }
11473
11474 // If numbersSeen is not 4, validation error, return failure.
11475 if (numbers_seen != 4) {
11476 return is_valid = false;
11477 }
11478
11479 // Break.
11480 break;
11481 }
11482 // Otherwise, if c is U+003A (:):
11483 else if ((pointer != input.end()) && (*pointer == ':')) {
11484 // Increase pointer by 1.
11485 pointer++;
11486
11487 // If c is the EOF code point, validation error, return failure.
11488 if (pointer == input.end()) {
11489 ada_log(
11490 "parse_ipv6 If c is the EOF code point, validation error, return "
11491 "failure");
11492 return is_valid = false;
11493 }
11494 }
11495 // Otherwise, if c is not the EOF code point, validation error, return
11496 // failure.
11497 else if (pointer != input.end()) {
11498 ada_log(
11499 "parse_ipv6 Otherwise, if c is not the EOF code point, validation "
11500 "error, return failure");
11501 return is_valid = false;
11502 }
11503
11504 // Set address[pieceIndex] to value.
11505 address[piece_index] = value;
11506
11507 // Increase pieceIndex by 1.
11508 piece_index++;
11509 }
11510
11511 // If compress is non-null, then:
11512 if (compress.has_value()) {
11513 // Let swaps be pieceIndex - compress.
11514 int swaps = piece_index - *compress;
11515
11516 // Set pieceIndex to 7.
11517 piece_index = 7;
11518
11519 // While pieceIndex is not 0 and swaps is greater than 0,
11520 // swap address[pieceIndex] with address[compress + swaps - 1], and then
11521 // decrease both pieceIndex and swaps by 1.
11522 while (piece_index != 0 && swaps > 0) {
11523 std::swap(address[piece_index], address[*compress + swaps - 1]);
11524 piece_index--;
11525 swaps--;
11526 }
11527 }
11528 // Otherwise, if compress is null and pieceIndex is not 8, validation error,
11529 // return failure.
11530 else if (piece_index != 8) {
11531 ada_log(
11532 "parse_ipv6 if compress is null and pieceIndex is not 8, validation "
11533 "error, return failure");
11534 return is_valid = false;
11535 }
11536 host = ada::serializers::ipv6(address);
11537 ada_log("parse_ipv6 ", *host);
11538 host_type = IPV6;
11539 return true;
11540 }
11541
11542 template <bool has_state_override>
parse_scheme(const std::string_view input)11543 ada_really_inline bool url::parse_scheme(const std::string_view input) {
11544 auto parsed_type = ada::scheme::get_scheme_type(input);
11545 bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
11546 /**
11547 * In the common case, we will immediately recognize a special scheme (e.g.,
11548 *http, https), in which case, we can go really fast.
11549 **/
11550 if (is_input_special) { // fast path!!!
11551 if (has_state_override) {
11552 // If url's scheme is not a special scheme and buffer is a special scheme,
11553 // then return.
11554 if (is_special() != is_input_special) {
11555 return true;
11556 }
11557
11558 // If url includes credentials or has a non-null port, and buffer is
11559 // "file", then return.
11560 if ((has_credentials() || port.has_value()) &&
11561 parsed_type == ada::scheme::type::FILE) {
11562 return true;
11563 }
11564
11565 // If url's scheme is "file" and its host is an empty host, then return.
11566 // An empty host is the empty string.
11567 if (type == ada::scheme::type::FILE && host.has_value() &&
11568 host.value().empty()) {
11569 return true;
11570 }
11571 }
11572
11573 type = parsed_type;
11574
11575 if (has_state_override) {
11576 // This is uncommon.
11577 uint16_t urls_scheme_port = get_special_port();
11578
11579 if (urls_scheme_port) {
11580 // If url's port is url's scheme's default port, then set url's port to
11581 // null.
11582 if (port.has_value() && *port == urls_scheme_port) {
11583 port = std::nullopt;
11584 }
11585 }
11586 }
11587 } else { // slow path
11588 std::string _buffer = std::string(input);
11589 // Next function is only valid if the input is ASCII and returns false
11590 // otherwise, but it seems that we always have ascii content so we do not
11591 // need to check the return value.
11592 // bool is_ascii =
11593 unicode::to_lower_ascii(_buffer.data(), _buffer.size());
11594
11595 if (has_state_override) {
11596 // If url's scheme is a special scheme and buffer is not a special scheme,
11597 // then return. If url's scheme is not a special scheme and buffer is a
11598 // special scheme, then return.
11599 if (is_special() != ada::scheme::is_special(_buffer)) {
11600 return true;
11601 }
11602
11603 // If url includes credentials or has a non-null port, and buffer is
11604 // "file", then return.
11605 if ((has_credentials() || port.has_value()) && _buffer == "file") {
11606 return true;
11607 }
11608
11609 // If url's scheme is "file" and its host is an empty host, then return.
11610 // An empty host is the empty string.
11611 if (type == ada::scheme::type::FILE && host.has_value() &&
11612 host.value().empty()) {
11613 return true;
11614 }
11615 }
11616
11617 set_scheme(std::move(_buffer));
11618
11619 if (has_state_override) {
11620 // This is uncommon.
11621 uint16_t urls_scheme_port = get_special_port();
11622
11623 if (urls_scheme_port) {
11624 // If url's port is url's scheme's default port, then set url's port to
11625 // null.
11626 if (port.has_value() && *port == urls_scheme_port) {
11627 port = std::nullopt;
11628 }
11629 }
11630 }
11631 }
11632
11633 return true;
11634 }
11635
parse_host(std::string_view input)11636 ada_really_inline bool url::parse_host(std::string_view input) {
11637 ada_log("parse_host ", input, " [", input.size(), " bytes]");
11638 if (input.empty()) {
11639 return is_valid = false;
11640 } // technically unnecessary.
11641 // If input starts with U+005B ([), then:
11642 if (input[0] == '[') {
11643 // If input does not end with U+005D (]), validation error, return failure.
11644 if (input.back() != ']') {
11645 return is_valid = false;
11646 }
11647 ada_log("parse_host ipv6");
11648
11649 // Return the result of IPv6 parsing input with its leading U+005B ([) and
11650 // trailing U+005D (]) removed.
11651 input.remove_prefix(1);
11652 input.remove_suffix(1);
11653 return parse_ipv6(input);
11654 }
11655
11656 // If isNotSpecial is true, then return the result of opaque-host parsing
11657 // input.
11658 if (!is_special()) {
11659 return parse_opaque_host(input);
11660 }
11661 // Let domain be the result of running UTF-8 decode without BOM on the
11662 // percent-decoding of input. Let asciiDomain be the result of running domain
11663 // to ASCII with domain and false. The most common case is an ASCII input, in
11664 // which case we do not need to call the expensive 'to_ascii' if a few
11665 // conditions are met: no '%' and no 'xn-' subsequence.
11666 std::string buffer = std::string(input);
11667 // This next function checks that the result is ascii, but we are going to
11668 // to check anyhow with is_forbidden.
11669 // bool is_ascii =
11670 unicode::to_lower_ascii(buffer.data(), buffer.size());
11671 bool is_forbidden = unicode::contains_forbidden_domain_code_point(
11672 buffer.data(), buffer.size());
11673 if (is_forbidden == 0 && buffer.find("xn-") == std::string_view::npos) {
11674 // fast path
11675 host = std::move(buffer);
11676 if (checkers::is_ipv4(host.value())) {
11677 ada_log("parse_host fast path ipv4");
11678 return parse_ipv4(host.value());
11679 }
11680 ada_log("parse_host fast path ", *host);
11681 return true;
11682 }
11683 ada_log("parse_host calling to_ascii");
11684 is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
11685 if (!is_valid) {
11686 ada_log("parse_host to_ascii returns false");
11687 return is_valid = false;
11688 }
11689 ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
11690 " bytes]");
11691
11692 if (std::any_of(host.value().begin(), host.value().end(),
11693 ada::unicode::is_forbidden_domain_code_point)) {
11694 host = std::nullopt;
11695 return is_valid = false;
11696 }
11697
11698 // If asciiDomain ends in a number, then return the result of IPv4 parsing
11699 // asciiDomain.
11700 if (checkers::is_ipv4(host.value())) {
11701 ada_log("parse_host got ipv4 ", *host);
11702 return parse_ipv4(host.value());
11703 }
11704
11705 return true;
11706 }
11707
parse_path(std::string_view input)11708 ada_really_inline void url::parse_path(std::string_view input) {
11709 ada_log("parse_path ", input);
11710 std::string tmp_buffer;
11711 std::string_view internal_input;
11712 if (unicode::has_tabs_or_newline(input)) {
11713 tmp_buffer = input;
11714 // Optimization opportunity: Instead of copying and then pruning, we could
11715 // just directly build the string from user_input.
11716 helpers::remove_ascii_tab_or_newline(tmp_buffer);
11717 internal_input = tmp_buffer;
11718 } else {
11719 internal_input = input;
11720 }
11721
11722 // If url is special, then:
11723 if (is_special()) {
11724 if (internal_input.empty()) {
11725 path = "/";
11726 } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
11727 helpers::parse_prepared_path(internal_input.substr(1), type, path);
11728 return;
11729 } else {
11730 helpers::parse_prepared_path(internal_input, type, path);
11731 return;
11732 }
11733 } else if (!internal_input.empty()) {
11734 if (internal_input[0] == '/') {
11735 helpers::parse_prepared_path(internal_input.substr(1), type, path);
11736 return;
11737 } else {
11738 helpers::parse_prepared_path(internal_input, type, path);
11739 return;
11740 }
11741 } else {
11742 if (!host.has_value()) {
11743 path = "/";
11744 }
11745 }
11746 }
11747
to_string() const11748 [[nodiscard]] std::string url::to_string() const {
11749 if (!is_valid) {
11750 return "null";
11751 }
11752 std::string answer;
11753 auto back = std::back_insert_iterator(answer);
11754 answer.append("{\n");
11755 answer.append("\t\"protocol\":\"");
11756 helpers::encode_json(get_protocol(), back);
11757 answer.append("\",\n");
11758 if (has_credentials()) {
11759 answer.append("\t\"username\":\"");
11760 helpers::encode_json(username, back);
11761 answer.append("\",\n");
11762 answer.append("\t\"password\":\"");
11763 helpers::encode_json(password, back);
11764 answer.append("\",\n");
11765 }
11766 if (host.has_value()) {
11767 answer.append("\t\"host\":\"");
11768 helpers::encode_json(host.value(), back);
11769 answer.append("\",\n");
11770 }
11771 if (port.has_value()) {
11772 answer.append("\t\"port\":\"");
11773 answer.append(std::to_string(port.value()));
11774 answer.append("\",\n");
11775 }
11776 answer.append("\t\"path\":\"");
11777 helpers::encode_json(path, back);
11778 answer.append("\",\n");
11779 answer.append("\t\"opaque path\":");
11780 answer.append((has_opaque_path ? "true" : "false"));
11781 if (has_search()) {
11782 answer.append(",\n");
11783 answer.append("\t\"query\":\"");
11784 helpers::encode_json(query.value(), back);
11785 answer.append("\"");
11786 }
11787 if (hash.has_value()) {
11788 answer.append(",\n");
11789 answer.append("\t\"hash\":\"");
11790 helpers::encode_json(hash.value(), back);
11791 answer.append("\"");
11792 }
11793 answer.append("\n}");
11794 return answer;
11795 }
11796
has_valid_domain() const11797 [[nodiscard]] bool url::has_valid_domain() const noexcept {
11798 if (!host.has_value()) {
11799 return false;
11800 }
11801 return checkers::verify_dns_length(host.value());
11802 }
11803
11804 } // namespace ada
11805 /* end file src/url.cpp */
11806 /* begin file src/url-getters.cpp */
11807 /**
11808 * @file url-getters.cpp
11809 * Includes all the getters of `ada::url`
11810 */
11811
11812 #include <algorithm>
11813 #include <string>
11814
11815 namespace ada {
get_origin() const11816 [[nodiscard]] std::string url::get_origin() const noexcept {
11817 if (is_special()) {
11818 // Return a new opaque origin.
11819 if (type == scheme::FILE) {
11820 return "null";
11821 }
11822 return ada::helpers::concat(get_protocol(), "//", get_host());
11823 }
11824
11825 if (non_special_scheme == "blob") {
11826 if (!path.empty()) {
11827 auto result = ada::parse<ada::url>(path);
11828 if (result &&
11829 (result->type == scheme::HTTP || result->type == scheme::HTTPS)) {
11830 // If pathURL's scheme is not "http" and not "https", then return a
11831 // new opaque origin.
11832 return ada::helpers::concat(result->get_protocol(), "//",
11833 result->get_host());
11834 }
11835 }
11836 }
11837
11838 // Return a new opaque origin.
11839 return "null";
11840 }
11841
get_protocol() const11842 [[nodiscard]] std::string url::get_protocol() const noexcept {
11843 if (is_special()) {
11844 return helpers::concat(ada::scheme::details::is_special_list[type], ":");
11845 }
11846 // We only move the 'scheme' if it is non-special.
11847 return helpers::concat(non_special_scheme, ":");
11848 }
11849
get_host() const11850 [[nodiscard]] std::string url::get_host() const noexcept {
11851 // If url's host is null, then return the empty string.
11852 // If url's port is null, return url's host, serialized.
11853 // Return url's host, serialized, followed by U+003A (:) and url's port,
11854 // serialized.
11855 if (!host.has_value()) {
11856 return "";
11857 }
11858 if (port.has_value()) {
11859 return host.value() + ":" + get_port();
11860 }
11861 return host.value();
11862 }
11863
get_hostname() const11864 [[nodiscard]] std::string url::get_hostname() const noexcept {
11865 return host.value_or("");
11866 }
11867
get_pathname() const11868 [[nodiscard]] std::string_view url::get_pathname() const noexcept {
11869 return path;
11870 }
11871
get_search() const11872 [[nodiscard]] std::string url::get_search() const noexcept {
11873 // If this's URL's query is either null or the empty string, then return the
11874 // empty string. Return U+003F (?), followed by this's URL's query.
11875 return (!query.has_value() || (query.value().empty())) ? ""
11876 : "?" + query.value();
11877 }
11878
get_username() const11879 [[nodiscard]] const std::string& url::get_username() const noexcept {
11880 return username;
11881 }
11882
get_password() const11883 [[nodiscard]] const std::string& url::get_password() const noexcept {
11884 return password;
11885 }
11886
get_port() const11887 [[nodiscard]] std::string url::get_port() const noexcept {
11888 return port.has_value() ? std::to_string(port.value()) : "";
11889 }
11890
get_hash() const11891 [[nodiscard]] std::string url::get_hash() const noexcept {
11892 // If this's URL's fragment is either null or the empty string, then return
11893 // the empty string. Return U+0023 (#), followed by this's URL's fragment.
11894 return (!hash.has_value() || (hash.value().empty())) ? ""
11895 : "#" + hash.value();
11896 }
11897
11898 } // namespace ada
11899 /* end file src/url-getters.cpp */
11900 /* begin file src/url-setters.cpp */
11901 /**
11902 * @file url-setters.cpp
11903 * Includes all the setters of `ada::url`
11904 */
11905
11906 #include <optional>
11907 #include <string>
11908
11909 namespace ada {
11910
11911 template <bool override_hostname>
set_host_or_hostname(const std::string_view input)11912 bool url::set_host_or_hostname(const std::string_view input) {
11913 if (has_opaque_path) {
11914 return false;
11915 }
11916
11917 std::optional<std::string> previous_host = host;
11918 std::optional<uint16_t> previous_port = port;
11919
11920 size_t host_end_pos = input.find('#');
11921 std::string _host(input.data(), host_end_pos != std::string_view::npos
11922 ? host_end_pos
11923 : input.size());
11924 helpers::remove_ascii_tab_or_newline(_host);
11925 std::string_view new_host(_host);
11926
11927 // If url's scheme is "file", then set state to file host state, instead of
11928 // host state.
11929 if (type != ada::scheme::type::FILE) {
11930 std::string_view host_view(_host.data(), _host.length());
11931 auto [location, found_colon] =
11932 helpers::get_host_delimiter_location(is_special(), host_view);
11933
11934 // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
11935 // Note: the 'found_colon' value is true if and only if a colon was
11936 // encountered while not inside brackets.
11937 if (found_colon) {
11938 if (override_hostname) {
11939 return false;
11940 }
11941 std::string_view buffer = new_host.substr(location + 1);
11942 if (!buffer.empty()) {
11943 set_port(buffer);
11944 }
11945 }
11946 // If url is special and host_view is the empty string, validation error,
11947 // return failure. Otherwise, if state override is given, host_view is the
11948 // empty string, and either url includes credentials or url's port is
11949 // non-null, return.
11950 else if (host_view.empty() &&
11951 (is_special() || has_credentials() || port.has_value())) {
11952 return false;
11953 }
11954
11955 // Let host be the result of host parsing host_view with url is not special.
11956 if (host_view.empty() && !is_special()) {
11957 host = "";
11958 return true;
11959 }
11960
11961 bool succeeded = parse_host(host_view);
11962 if (!succeeded) {
11963 host = previous_host;
11964 update_base_port(previous_port);
11965 }
11966 return succeeded;
11967 }
11968
11969 size_t location = new_host.find_first_of("/\\?");
11970 if (location != std::string_view::npos) {
11971 new_host.remove_suffix(new_host.length() - location);
11972 }
11973
11974 if (new_host.empty()) {
11975 // Set url's host to the empty string.
11976 host = "";
11977 } else {
11978 // Let host be the result of host parsing buffer with url is not special.
11979 if (!parse_host(new_host)) {
11980 host = previous_host;
11981 update_base_port(previous_port);
11982 return false;
11983 }
11984
11985 // If host is "localhost", then set host to the empty string.
11986 if (host.has_value() && host.value() == "localhost") {
11987 host = "";
11988 }
11989 }
11990 return true;
11991 }
11992
set_host(const std::string_view input)11993 bool url::set_host(const std::string_view input) {
11994 return set_host_or_hostname<false>(input);
11995 }
11996
set_hostname(const std::string_view input)11997 bool url::set_hostname(const std::string_view input) {
11998 return set_host_or_hostname<true>(input);
11999 }
12000
set_username(const std::string_view input)12001 bool url::set_username(const std::string_view input) {
12002 if (cannot_have_credentials_or_port()) {
12003 return false;
12004 }
12005 username = ada::unicode::percent_encode(
12006 input, character_sets::USERINFO_PERCENT_ENCODE);
12007 return true;
12008 }
12009
set_password(const std::string_view input)12010 bool url::set_password(const std::string_view input) {
12011 if (cannot_have_credentials_or_port()) {
12012 return false;
12013 }
12014 password = ada::unicode::percent_encode(
12015 input, character_sets::USERINFO_PERCENT_ENCODE);
12016 return true;
12017 }
12018
set_port(const std::string_view input)12019 bool url::set_port(const std::string_view input) {
12020 if (cannot_have_credentials_or_port()) {
12021 return false;
12022 }
12023 std::string trimmed(input);
12024 helpers::remove_ascii_tab_or_newline(trimmed);
12025 if (trimmed.empty()) {
12026 port = std::nullopt;
12027 return true;
12028 }
12029 // Input should not start with control characters.
12030 if (ada::unicode::is_c0_control_or_space(trimmed.front())) {
12031 return false;
12032 }
12033 // Input should contain at least one ascii digit.
12034 if (input.find_first_of("0123456789") == std::string_view::npos) {
12035 return false;
12036 }
12037
12038 // Revert changes if parse_port fails.
12039 std::optional<uint16_t> previous_port = port;
12040 parse_port(trimmed);
12041 if (is_valid) {
12042 return true;
12043 }
12044 port = previous_port;
12045 is_valid = true;
12046 return false;
12047 }
12048
set_hash(const std::string_view input)12049 void url::set_hash(const std::string_view input) {
12050 if (input.empty()) {
12051 hash = std::nullopt;
12052 helpers::strip_trailing_spaces_from_opaque_path(*this);
12053 return;
12054 }
12055
12056 std::string new_value;
12057 new_value = input[0] == '#' ? input.substr(1) : input;
12058 helpers::remove_ascii_tab_or_newline(new_value);
12059 hash = unicode::percent_encode(new_value,
12060 ada::character_sets::FRAGMENT_PERCENT_ENCODE);
12061 return;
12062 }
12063
set_search(const std::string_view input)12064 void url::set_search(const std::string_view input) {
12065 if (input.empty()) {
12066 query = std::nullopt;
12067 helpers::strip_trailing_spaces_from_opaque_path(*this);
12068 return;
12069 }
12070
12071 std::string new_value;
12072 new_value = input[0] == '?' ? input.substr(1) : input;
12073 helpers::remove_ascii_tab_or_newline(new_value);
12074
12075 auto query_percent_encode_set =
12076 is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
12077 : ada::character_sets::QUERY_PERCENT_ENCODE;
12078
12079 query = ada::unicode::percent_encode(std::string_view(new_value),
12080 query_percent_encode_set);
12081 }
12082
set_pathname(const std::string_view input)12083 bool url::set_pathname(const std::string_view input) {
12084 if (has_opaque_path) {
12085 return false;
12086 }
12087 path = "";
12088 parse_path(input);
12089 return true;
12090 }
12091
set_protocol(const std::string_view input)12092 bool url::set_protocol(const std::string_view input) {
12093 std::string view(input);
12094 helpers::remove_ascii_tab_or_newline(view);
12095 if (view.empty()) {
12096 return true;
12097 }
12098
12099 // Schemes should start with alpha values.
12100 if (!checkers::is_alpha(view[0])) {
12101 return false;
12102 }
12103
12104 view.append(":");
12105
12106 std::string::iterator pointer =
12107 std::find_if_not(view.begin(), view.end(), unicode::is_alnum_plus);
12108
12109 if (pointer != view.end() && *pointer == ':') {
12110 return parse_scheme<true>(
12111 std::string_view(view.data(), pointer - view.begin()));
12112 }
12113 return false;
12114 }
12115
set_href(const std::string_view input)12116 bool url::set_href(const std::string_view input) {
12117 ada::result<ada::url> out = ada::parse<ada::url>(input);
12118
12119 if (out) {
12120 username = out->username;
12121 password = out->password;
12122 host = out->host;
12123 port = out->port;
12124 path = out->path;
12125 query = out->query;
12126 hash = out->hash;
12127 type = out->type;
12128 non_special_scheme = out->non_special_scheme;
12129 has_opaque_path = out->has_opaque_path;
12130 }
12131
12132 return out.has_value();
12133 }
12134
12135 } // namespace ada
12136 /* end file src/url-setters.cpp */
12137 /* begin file src/parser.cpp */
12138
12139 #include <numeric>
12140 #include <limits>
12141
12142 namespace ada::parser {
12143
12144 template <class result_type>
parse_url(std::string_view user_input,const result_type * base_url)12145 result_type parse_url(std::string_view user_input,
12146 const result_type* base_url) {
12147 // We can specialize the implementation per type.
12148 // Important: result_type_is_ada_url is evaluated at *compile time*. This
12149 // means that doing if constexpr(result_type_is_ada_url) { something } else {
12150 // something else } is free (at runtime). This means that ada::url_aggregator
12151 // and ada::url **do not have to support the exact same API**.
12152 constexpr bool result_type_is_ada_url =
12153 std::is_same<ada::url, result_type>::value;
12154 constexpr bool result_type_is_ada_url_aggregator =
12155 std::is_same<ada::url_aggregator, result_type>::value;
12156 static_assert(result_type_is_ada_url ||
12157 result_type_is_ada_url_aggregator); // We don't support
12158 // anything else for now.
12159
12160 ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(),
12161 " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),
12162 ")");
12163
12164 ada::state state = ada::state::SCHEME_START;
12165 result_type url{};
12166
12167 // We refuse to parse URL strings that exceed 4GB. Such strings are almost
12168 // surely the result of a bug or are otherwise a security concern.
12169 if (user_input.size() > std::numeric_limits<uint32_t>::max()) {
12170 url.is_valid = false;
12171 }
12172 // Going forward, user_input.size() is in [0,
12173 // std::numeric_limits<uint32_t>::max). If we are provided with an invalid
12174 // base, or the optional_url was invalid, we must return.
12175 if (base_url != nullptr) {
12176 url.is_valid &= base_url->is_valid;
12177 }
12178 if (!url.is_valid) {
12179 return url;
12180 }
12181 if constexpr (result_type_is_ada_url_aggregator) {
12182 // Most of the time, we just need user_input.size().
12183 // In some instances, we may need a bit more.
12184 ///////////////////////////
12185 // This is *very* important. This line should *not* be removed
12186 // hastily. There are principled reasons why reserve is important
12187 // for performance. If you have a benchmark with small inputs,
12188 // it may not matter, but in other instances, it could.
12189 ////
12190 // This rounds up to the next power of two.
12191 // We know that user_input.size() is in [0,
12192 // std::numeric_limits<uint32_t>::max).
12193 uint32_t reserve_capacity =
12194 (0xFFFFFFFF >>
12195 helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +
12196 1;
12197 url.reserve(reserve_capacity);
12198 //
12199 //
12200 //
12201 }
12202 std::string tmp_buffer;
12203 std::string_view internal_input;
12204 if (unicode::has_tabs_or_newline(user_input)) {
12205 tmp_buffer = user_input;
12206 // Optimization opportunity: Instead of copying and then pruning, we could
12207 // just directly build the string from user_input.
12208 helpers::remove_ascii_tab_or_newline(tmp_buffer);
12209 internal_input = tmp_buffer;
12210 } else {
12211 internal_input = user_input;
12212 }
12213
12214 // Leading and trailing control characters are uncommon and easy to deal with
12215 // (no performance concern).
12216 std::string_view url_data = internal_input;
12217 helpers::trim_c0_whitespace(url_data);
12218
12219 // Optimization opportunity. Most websites do not have fragment.
12220 std::optional<std::string_view> fragment = helpers::prune_hash(url_data);
12221 // We add it last so that an implementation like ada::url_aggregator
12222 // can append it last to its internal buffer, thus improving performance.
12223
12224 // Here url_data no longer has its fragment.
12225 // We are going to access the data from url_data (it is immutable).
12226 // At any given time, we are pointing at byte 'input_position' in url_data.
12227 // The input_position variable should range from 0 to input_size.
12228 // It is illegal to access url_data at input_size.
12229 size_t input_position = 0;
12230 const size_t input_size = url_data.size();
12231 // Keep running the following state machine by switching on state.
12232 // If after a run pointer points to the EOF code point, go to the next step.
12233 // Otherwise, increase pointer by 1 and continue with the state machine.
12234 // We never decrement input_position.
12235 while (input_position <= input_size) {
12236 ada_log("In parsing at ", input_position, " out of ", input_size,
12237 " in state ", ada::to_string(state));
12238 switch (state) {
12239 case ada::state::SCHEME_START: {
12240 ada_log("SCHEME_START ", helpers::substring(url_data, input_position));
12241 // If c is an ASCII alpha, append c, lowercased, to buffer, and set
12242 // state to scheme state.
12243 if ((input_position != input_size) &&
12244 checkers::is_alpha(url_data[input_position])) {
12245 state = ada::state::SCHEME;
12246 input_position++;
12247 } else {
12248 // Otherwise, if state override is not given, set state to no scheme
12249 // state and decrease pointer by 1.
12250 state = ada::state::NO_SCHEME;
12251 }
12252 break;
12253 }
12254 case ada::state::SCHEME: {
12255 ada_log("SCHEME ", helpers::substring(url_data, input_position));
12256 // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),
12257 // append c, lowercased, to buffer.
12258 while ((input_position != input_size) &&
12259 (ada::unicode::is_alnum_plus(url_data[input_position]))) {
12260 input_position++;
12261 }
12262 // Otherwise, if c is U+003A (:), then:
12263 if ((input_position != input_size) &&
12264 (url_data[input_position] == ':')) {
12265 ada_log("SCHEME the scheme should be ",
12266 url_data.substr(0, input_position));
12267 if constexpr (result_type_is_ada_url) {
12268 if (!url.parse_scheme(url_data.substr(0, input_position))) {
12269 return url;
12270 }
12271 } else {
12272 // we pass the colon along instead of painfully adding it back.
12273 if (!url.parse_scheme_with_colon(
12274 url_data.substr(0, input_position + 1))) {
12275 return url;
12276 }
12277 }
12278 ada_log("SCHEME the scheme is ", url.get_protocol());
12279
12280 // If url's scheme is "file", then:
12281 if (url.type == ada::scheme::type::FILE) {
12282 // Set state to file state.
12283 state = ada::state::FILE;
12284 }
12285 // Otherwise, if url is special, base is non-null, and base's scheme
12286 // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url
12287 // != nullptr is false.
12288 else if (url.is_special() && base_url != nullptr &&
12289 base_url->type == url.type) {
12290 // Set state to special relative or authority state.
12291 state = ada::state::SPECIAL_RELATIVE_OR_AUTHORITY;
12292 }
12293 // Otherwise, if url is special, set state to special authority
12294 // slashes state.
12295 else if (url.is_special()) {
12296 state = ada::state::SPECIAL_AUTHORITY_SLASHES;
12297 }
12298 // Otherwise, if remaining starts with an U+002F (/), set state to
12299 // path or authority state and increase pointer by 1.
12300 else if (input_position + 1 < input_size &&
12301 url_data[input_position + 1] == '/') {
12302 state = ada::state::PATH_OR_AUTHORITY;
12303 input_position++;
12304 }
12305 // Otherwise, set url's path to the empty string and set state to
12306 // opaque path state.
12307 else {
12308 state = ada::state::OPAQUE_PATH;
12309 }
12310 }
12311 // Otherwise, if state override is not given, set buffer to the empty
12312 // string, state to no scheme state, and start over (from the first code
12313 // point in input).
12314 else {
12315 state = ada::state::NO_SCHEME;
12316 input_position = 0;
12317 break;
12318 }
12319 input_position++;
12320 break;
12321 }
12322 case ada::state::NO_SCHEME: {
12323 ada_log("NO_SCHEME ", helpers::substring(url_data, input_position));
12324 // If base is null, or base has an opaque path and c is not U+0023 (#),
12325 // validation error, return failure.
12326 if (base_url == nullptr ||
12327 (base_url->has_opaque_path && !fragment.has_value())) {
12328 ada_log("NO_SCHEME validation error");
12329 url.is_valid = false;
12330 return url;
12331 }
12332 // Otherwise, if base has an opaque path and c is U+0023 (#),
12333 // set url's scheme to base's scheme, url's path to base's path, url's
12334 // query to base's query, and set state to fragment state.
12335 else if (base_url->has_opaque_path && fragment.has_value() &&
12336 input_position == input_size) {
12337 ada_log("NO_SCHEME opaque base with fragment");
12338 url.copy_scheme(*base_url);
12339 url.has_opaque_path = base_url->has_opaque_path;
12340
12341 if constexpr (result_type_is_ada_url) {
12342 url.path = base_url->path;
12343 url.query = base_url->query;
12344 } else {
12345 url.update_base_pathname(base_url->get_pathname());
12346 url.update_base_search(base_url->get_search());
12347 }
12348 url.update_unencoded_base_hash(*fragment);
12349 return url;
12350 }
12351 // Otherwise, if base's scheme is not "file", set state to relative
12352 // state and decrease pointer by 1.
12353 else if (base_url->type != ada::scheme::type::FILE) {
12354 ada_log("NO_SCHEME non-file relative path");
12355 state = ada::state::RELATIVE_SCHEME;
12356 }
12357 // Otherwise, set state to file state and decrease pointer by 1.
12358 else {
12359 ada_log("NO_SCHEME file base type");
12360 state = ada::state::FILE;
12361 }
12362 break;
12363 }
12364 case ada::state::AUTHORITY: {
12365 ada_log("AUTHORITY ", helpers::substring(url_data, input_position));
12366 // most URLs have no @. Having no @ tells us that we don't have to worry
12367 // about AUTHORITY. Of course, we could have @ and still not have to
12368 // worry about AUTHORITY.
12369 // TODO: Instead of just collecting a bool, collect the location of the
12370 // '@' and do something useful with it.
12371 // TODO: We could do various processing early on, using a single pass
12372 // over the string to collect information about it, e.g., telling us
12373 // whether there is a @ and if so, where (or how many).
12374 const bool contains_ampersand =
12375 (url_data.find('@', input_position) != std::string_view::npos);
12376
12377 if (!contains_ampersand) {
12378 state = ada::state::HOST;
12379 break;
12380 }
12381 bool at_sign_seen{false};
12382 bool password_token_seen{false};
12383 /**
12384 * We expect something of the sort...
12385 * https://user:pass@example.com:1234/foo/bar?baz#quux
12386 * --------^
12387 */
12388 do {
12389 std::string_view view = helpers::substring(url_data, input_position);
12390 // The delimiters are @, /, ? \\.
12391 size_t location =
12392 url.is_special() ? helpers::find_authority_delimiter_special(view)
12393 : helpers::find_authority_delimiter(view);
12394 std::string_view authority_view(view.data(), location);
12395 size_t end_of_authority = input_position + authority_view.size();
12396 // If c is U+0040 (@), then:
12397 if ((end_of_authority != input_size) &&
12398 (url_data[end_of_authority] == '@')) {
12399 // If atSignSeen is true, then prepend "%40" to buffer.
12400 if (at_sign_seen) {
12401 if (password_token_seen) {
12402 if constexpr (result_type_is_ada_url) {
12403 url.password += "%40";
12404 } else {
12405 url.append_base_password("%40");
12406 }
12407 } else {
12408 if constexpr (result_type_is_ada_url) {
12409 url.username += "%40";
12410 } else {
12411 url.append_base_username("%40");
12412 }
12413 }
12414 }
12415
12416 at_sign_seen = true;
12417
12418 if (!password_token_seen) {
12419 size_t password_token_location = authority_view.find(':');
12420 password_token_seen =
12421 password_token_location != std::string_view::npos;
12422
12423 if (!password_token_seen) {
12424 if constexpr (result_type_is_ada_url) {
12425 url.username += unicode::percent_encode(
12426 authority_view, character_sets::USERINFO_PERCENT_ENCODE);
12427 } else {
12428 url.append_base_username(unicode::percent_encode(
12429 authority_view, character_sets::USERINFO_PERCENT_ENCODE));
12430 }
12431 } else {
12432 if constexpr (result_type_is_ada_url) {
12433 url.username += unicode::percent_encode(
12434 authority_view.substr(0, password_token_location),
12435 character_sets::USERINFO_PERCENT_ENCODE);
12436 url.password += unicode::percent_encode(
12437 authority_view.substr(password_token_location + 1),
12438 character_sets::USERINFO_PERCENT_ENCODE);
12439 } else {
12440 url.append_base_username(unicode::percent_encode(
12441 authority_view.substr(0, password_token_location),
12442 character_sets::USERINFO_PERCENT_ENCODE));
12443 url.append_base_password(unicode::percent_encode(
12444 authority_view.substr(password_token_location + 1),
12445 character_sets::USERINFO_PERCENT_ENCODE));
12446 }
12447 }
12448 } else {
12449 if constexpr (result_type_is_ada_url) {
12450 url.password += unicode::percent_encode(
12451 authority_view, character_sets::USERINFO_PERCENT_ENCODE);
12452 } else {
12453 url.append_base_password(unicode::percent_encode(
12454 authority_view, character_sets::USERINFO_PERCENT_ENCODE));
12455 }
12456 }
12457 }
12458 // Otherwise, if one of the following is true:
12459 // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
12460 // - url is special and c is U+005C (\)
12461 else if (end_of_authority == input_size ||
12462 url_data[end_of_authority] == '/' ||
12463 url_data[end_of_authority] == '?' ||
12464 (url.is_special() && url_data[end_of_authority] == '\\')) {
12465 // If atSignSeen is true and authority_view is the empty string,
12466 // validation error, return failure.
12467 if (at_sign_seen && authority_view.empty()) {
12468 url.is_valid = false;
12469 return url;
12470 }
12471 state = ada::state::HOST;
12472 break;
12473 }
12474 if (end_of_authority == input_size) {
12475 if (fragment.has_value()) {
12476 url.update_unencoded_base_hash(*fragment);
12477 }
12478 return url;
12479 }
12480 input_position = end_of_authority + 1;
12481 } while (true);
12482
12483 break;
12484 }
12485 case ada::state::SPECIAL_RELATIVE_OR_AUTHORITY: {
12486 ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ",
12487 helpers::substring(url_data, input_position));
12488
12489 // If c is U+002F (/) and remaining starts with U+002F (/),
12490 // then set state to special authority ignore slashes state and increase
12491 // pointer by 1.
12492 std::string_view view = helpers::substring(url_data, input_position);
12493 if (ada::checkers::begins_with(view, "//")) {
12494 state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
12495 input_position += 2;
12496 } else {
12497 // Otherwise, validation error, set state to relative state and
12498 // decrease pointer by 1.
12499 state = ada::state::RELATIVE_SCHEME;
12500 }
12501
12502 break;
12503 }
12504 case ada::state::PATH_OR_AUTHORITY: {
12505 ada_log("PATH_OR_AUTHORITY ",
12506 helpers::substring(url_data, input_position));
12507
12508 // If c is U+002F (/), then set state to authority state.
12509 if ((input_position != input_size) &&
12510 (url_data[input_position] == '/')) {
12511 state = ada::state::AUTHORITY;
12512 input_position++;
12513 } else {
12514 // Otherwise, set state to path state, and decrease pointer by 1.
12515 state = ada::state::PATH;
12516 }
12517
12518 break;
12519 }
12520 case ada::state::RELATIVE_SCHEME: {
12521 ada_log("RELATIVE_SCHEME ",
12522 helpers::substring(url_data, input_position));
12523
12524 // Set url's scheme to base's scheme.
12525 url.copy_scheme(*base_url);
12526
12527 // If c is U+002F (/), then set state to relative slash state.
12528 if ((input_position != input_size) &&
12529 (url_data[input_position] == '/')) {
12530 ada_log(
12531 "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "
12532 "slash state");
12533 state = ada::state::RELATIVE_SLASH;
12534 } else if (url.is_special() && (input_position != input_size) &&
12535 (url_data[input_position] == '\\')) {
12536 // Otherwise, if url is special and c is U+005C (\), validation error,
12537 // set state to relative slash state.
12538 ada_log(
12539 "RELATIVE_SCHEME if url is special and c is U+005C, validation "
12540 "error, set state to relative slash state");
12541 state = ada::state::RELATIVE_SLASH;
12542 } else {
12543 ada_log("RELATIVE_SCHEME otherwise");
12544 // Set url's username to base's username, url's password to base's
12545 // password, url's host to base's host, url's port to base's port,
12546 // url's path to a clone of base's path, and url's query to base's
12547 // query.
12548 if constexpr (result_type_is_ada_url) {
12549 url.username = base_url->username;
12550 url.password = base_url->password;
12551 url.host = base_url->host;
12552 url.port = base_url->port;
12553 // cloning the base path includes cloning the has_opaque_path flag
12554 url.has_opaque_path = base_url->has_opaque_path;
12555 url.path = base_url->path;
12556 url.query = base_url->query;
12557 } else {
12558 url.update_base_authority(base_url->get_href(),
12559 base_url->get_components());
12560 // TODO: Get rid of set_hostname and replace it with
12561 // update_base_hostname
12562 url.set_hostname(base_url->get_hostname());
12563 url.update_base_port(base_url->retrieve_base_port());
12564 // cloning the base path includes cloning the has_opaque_path flag
12565 url.has_opaque_path = base_url->has_opaque_path;
12566 url.update_base_pathname(base_url->get_pathname());
12567 url.update_base_search(base_url->get_search());
12568 }
12569
12570 url.has_opaque_path = base_url->has_opaque_path;
12571
12572 // If c is U+003F (?), then set url's query to the empty string, and
12573 // state to query state.
12574 if ((input_position != input_size) &&
12575 (url_data[input_position] == '?')) {
12576 state = ada::state::QUERY;
12577 }
12578 // Otherwise, if c is not the EOF code point:
12579 else if (input_position != input_size) {
12580 // Set url's query to null.
12581 url.clear_search();
12582 if constexpr (result_type_is_ada_url) {
12583 // Shorten url's path.
12584 helpers::shorten_path(url.path, url.type);
12585 } else {
12586 std::string_view path = url.get_pathname();
12587 if (helpers::shorten_path(path, url.type)) {
12588 url.update_base_pathname(std::string(path));
12589 }
12590 }
12591 // Set state to path state and decrease pointer by 1.
12592 state = ada::state::PATH;
12593 break;
12594 }
12595 }
12596 input_position++;
12597 break;
12598 }
12599 case ada::state::RELATIVE_SLASH: {
12600 ada_log("RELATIVE_SLASH ",
12601 helpers::substring(url_data, input_position));
12602
12603 // If url is special and c is U+002F (/) or U+005C (\), then:
12604 if (url.is_special() && (input_position != input_size) &&
12605 (url_data[input_position] == '/' ||
12606 url_data[input_position] == '\\')) {
12607 // Set state to special authority ignore slashes state.
12608 state = ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES;
12609 }
12610 // Otherwise, if c is U+002F (/), then set state to authority state.
12611 else if ((input_position != input_size) &&
12612 (url_data[input_position] == '/')) {
12613 state = ada::state::AUTHORITY;
12614 }
12615 // Otherwise, set
12616 // - url's username to base's username,
12617 // - url's password to base's password,
12618 // - url's host to base's host,
12619 // - url's port to base's port,
12620 // - state to path state, and then, decrease pointer by 1.
12621 else {
12622 if constexpr (result_type_is_ada_url) {
12623 url.username = base_url->username;
12624 url.password = base_url->password;
12625 url.host = base_url->host;
12626 url.port = base_url->port;
12627 } else {
12628 url.update_base_authority(base_url->get_href(),
12629 base_url->get_components());
12630 // TODO: Get rid of set_hostname and replace it with
12631 // update_base_hostname
12632 url.set_hostname(base_url->get_hostname());
12633 url.update_base_port(base_url->retrieve_base_port());
12634 }
12635 state = ada::state::PATH;
12636 break;
12637 }
12638
12639 input_position++;
12640 break;
12641 }
12642 case ada::state::SPECIAL_AUTHORITY_SLASHES: {
12643 ada_log("SPECIAL_AUTHORITY_SLASHES ",
12644 helpers::substring(url_data, input_position));
12645
12646 // If c is U+002F (/) and remaining starts with U+002F (/),
12647 // then set state to special authority ignore slashes state and increase
12648 // pointer by 1.
12649 std::string_view view = helpers::substring(url_data, input_position);
12650 if (ada::checkers::begins_with(view, "//")) {
12651 input_position += 2;
12652 }
12653
12654 [[fallthrough]];
12655 }
12656 case ada::state::SPECIAL_AUTHORITY_IGNORE_SLASHES: {
12657 ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ",
12658 helpers::substring(url_data, input_position));
12659
12660 // If c is neither U+002F (/) nor U+005C (\), then set state to
12661 // authority state and decrease pointer by 1.
12662 while ((input_position != input_size) &&
12663 ((url_data[input_position] == '/') ||
12664 (url_data[input_position] == '\\'))) {
12665 input_position++;
12666 }
12667 state = ada::state::AUTHORITY;
12668
12669 break;
12670 }
12671 case ada::state::QUERY: {
12672 ada_log("QUERY ", helpers::substring(url_data, input_position));
12673 // Let queryPercentEncodeSet be the special-query percent-encode set if
12674 // url is special; otherwise the query percent-encode set.
12675 const uint8_t* query_percent_encode_set =
12676 url.is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
12677 : ada::character_sets::QUERY_PERCENT_ENCODE;
12678
12679 // Percent-encode after encoding, with encoding, buffer, and
12680 // queryPercentEncodeSet, and append the result to url's query.
12681 url.update_base_search(helpers::substring(url_data, input_position),
12682 query_percent_encode_set);
12683 ada_log("QUERY update_base_search completed ");
12684 if (fragment.has_value()) {
12685 url.update_unencoded_base_hash(*fragment);
12686 }
12687 return url;
12688 }
12689 case ada::state::HOST: {
12690 ada_log("HOST ", helpers::substring(url_data, input_position));
12691
12692 std::string_view host_view =
12693 helpers::substring(url_data, input_position);
12694 auto [location, found_colon] =
12695 helpers::get_host_delimiter_location(url.is_special(), host_view);
12696 input_position = (location != std::string_view::npos)
12697 ? input_position + location
12698 : input_size;
12699 // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
12700 // Note: the 'found_colon' value is true if and only if a colon was
12701 // encountered while not inside brackets.
12702 if (found_colon) {
12703 // If buffer is the empty string, validation error, return failure.
12704 // Let host be the result of host parsing buffer with url is not
12705 // special.
12706 ada_log("HOST parsing ", host_view);
12707 if (!url.parse_host(host_view)) {
12708 return url;
12709 }
12710 ada_log("HOST parsing results in ", url.get_hostname());
12711 // Set url's host to host, buffer to the empty string, and state to
12712 // port state.
12713 state = ada::state::PORT;
12714 input_position++;
12715 }
12716 // Otherwise, if one of the following is true:
12717 // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
12718 // - url is special and c is U+005C (\)
12719 // The get_host_delimiter_location function either brings us to
12720 // the colon outside of the bracket, or to one of those characters.
12721 else {
12722 // If url is special and host_view is the empty string, validation
12723 // error, return failure.
12724 if (url.is_special() && host_view.empty()) {
12725 url.is_valid = false;
12726 return url;
12727 }
12728 ada_log("HOST parsing ", host_view, " href=", url.get_href());
12729 // Let host be the result of host parsing host_view with url is not
12730 // special.
12731 if (host_view.empty()) {
12732 url.update_base_hostname("");
12733 } else if (!url.parse_host(host_view)) {
12734 return url;
12735 }
12736 ada_log("HOST parsing results in ", url.get_hostname(),
12737 " href=", url.get_href());
12738
12739 // Set url's host to host, and state to path start state.
12740 state = ada::state::PATH_START;
12741 }
12742
12743 break;
12744 }
12745 case ada::state::OPAQUE_PATH: {
12746 ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position));
12747 std::string_view view = helpers::substring(url_data, input_position);
12748 // If c is U+003F (?), then set url's query to the empty string and
12749 // state to query state.
12750 size_t location = view.find('?');
12751 if (location != std::string_view::npos) {
12752 view.remove_suffix(view.size() - location);
12753 state = ada::state::QUERY;
12754 input_position += location + 1;
12755 } else {
12756 input_position = input_size + 1;
12757 }
12758 url.has_opaque_path = true;
12759 // This is a really unlikely scenario in real world. We should not seek
12760 // to optimize it.
12761 url.update_base_pathname(unicode::percent_encode(
12762 view, character_sets::C0_CONTROL_PERCENT_ENCODE));
12763 break;
12764 }
12765 case ada::state::PORT: {
12766 ada_log("PORT ", helpers::substring(url_data, input_position));
12767 std::string_view port_view =
12768 helpers::substring(url_data, input_position);
12769 size_t consumed_bytes = url.parse_port(port_view, true);
12770 input_position += consumed_bytes;
12771 if (!url.is_valid) {
12772 return url;
12773 }
12774 state = state::PATH_START;
12775 [[fallthrough]];
12776 }
12777 case ada::state::PATH_START: {
12778 ada_log("PATH_START ", helpers::substring(url_data, input_position));
12779
12780 // If url is special, then:
12781 if (url.is_special()) {
12782 // Set state to path state.
12783 state = ada::state::PATH;
12784
12785 // Optimization: Avoiding going into PATH state improves the
12786 // performance of urls ending with /.
12787 if (input_position == input_size) {
12788 url.update_base_pathname("/");
12789 if (fragment.has_value()) {
12790 url.update_unencoded_base_hash(*fragment);
12791 }
12792 return url;
12793 }
12794 // If c is neither U+002F (/) nor U+005C (\), then decrease pointer
12795 // by 1. We know that (input_position == input_size) is impossible
12796 // here, because of the previous if-check.
12797 if ((url_data[input_position] != '/') &&
12798 (url_data[input_position] != '\\')) {
12799 break;
12800 }
12801 }
12802 // Otherwise, if state override is not given and c is U+003F (?),
12803 // set url's query to the empty string and state to query state.
12804 else if ((input_position != input_size) &&
12805 (url_data[input_position] == '?')) {
12806 state = ada::state::QUERY;
12807 }
12808 // Otherwise, if c is not the EOF code point:
12809 else if (input_position != input_size) {
12810 // Set state to path state.
12811 state = ada::state::PATH;
12812
12813 // If c is not U+002F (/), then decrease pointer by 1.
12814 if (url_data[input_position] != '/') {
12815 break;
12816 }
12817 }
12818
12819 input_position++;
12820 break;
12821 }
12822 case ada::state::PATH: {
12823 std::string_view view = helpers::substring(url_data, input_position);
12824 ada_log("PATH ", helpers::substring(url_data, input_position));
12825
12826 // Most time, we do not need percent encoding.
12827 // Furthermore, we can immediately locate the '?'.
12828 size_t locofquestionmark = view.find('?');
12829 if (locofquestionmark != std::string_view::npos) {
12830 state = ada::state::QUERY;
12831 view.remove_suffix(view.size() - locofquestionmark);
12832 input_position += locofquestionmark + 1;
12833 } else {
12834 input_position = input_size + 1;
12835 }
12836 if constexpr (result_type_is_ada_url) {
12837 helpers::parse_prepared_path(view, url.type, url.path);
12838 } else {
12839 url.consume_prepared_path(view);
12840 ADA_ASSERT_TRUE(url.validate());
12841 }
12842 break;
12843 }
12844 case ada::state::FILE_SLASH: {
12845 ada_log("FILE_SLASH ", helpers::substring(url_data, input_position));
12846
12847 // If c is U+002F (/) or U+005C (\), then:
12848 if ((input_position != input_size) &&
12849 (url_data[input_position] == '/' ||
12850 url_data[input_position] == '\\')) {
12851 ada_log("FILE_SLASH c is U+002F or U+005C");
12852 // Set state to file host state.
12853 state = ada::state::FILE_HOST;
12854 input_position++;
12855 } else {
12856 ada_log("FILE_SLASH otherwise");
12857 // If base is non-null and base's scheme is "file", then:
12858 // Note: it is unsafe to do base_url->scheme unless you know that
12859 // base_url_has_value() is true.
12860 if (base_url != nullptr &&
12861 base_url->type == ada::scheme::type::FILE) {
12862 // Set url's host to base's host.
12863 if constexpr (result_type_is_ada_url) {
12864 url.host = base_url->host;
12865 } else {
12866 // TODO: Optimization opportunity.
12867 url.set_host(base_url->get_host());
12868 }
12869 // If the code point substring from pointer to the end of input does
12870 // not start with a Windows drive letter and base's path[0] is a
12871 // normalized Windows drive letter, then append base's path[0] to
12872 // url's path.
12873 if (!base_url->get_pathname().empty()) {
12874 if (!checkers::is_windows_drive_letter(
12875 helpers::substring(url_data, input_position))) {
12876 std::string_view first_base_url_path =
12877 base_url->get_pathname().substr(1);
12878 size_t loc = first_base_url_path.find('/');
12879 if (loc != std::string_view::npos) {
12880 helpers::resize(first_base_url_path, loc);
12881 }
12882 if (checkers::is_normalized_windows_drive_letter(
12883 first_base_url_path)) {
12884 if constexpr (result_type_is_ada_url) {
12885 url.path += '/';
12886 url.path += first_base_url_path;
12887 } else {
12888 url.append_base_pathname(
12889 helpers::concat("/", first_base_url_path));
12890 }
12891 }
12892 }
12893 }
12894 }
12895
12896 // Set state to path state, and decrease pointer by 1.
12897 state = ada::state::PATH;
12898 }
12899
12900 break;
12901 }
12902 case ada::state::FILE_HOST: {
12903 std::string_view view = helpers::substring(url_data, input_position);
12904 ada_log("FILE_HOST ", helpers::substring(url_data, input_position));
12905
12906 size_t location = view.find_first_of("/\\?");
12907 std::string_view file_host_buffer(
12908 view.data(),
12909 (location != std::string_view::npos) ? location : view.size());
12910
12911 if (checkers::is_windows_drive_letter(file_host_buffer)) {
12912 state = ada::state::PATH;
12913 } else if (file_host_buffer.empty()) {
12914 // Set url's host to the empty string.
12915 if constexpr (result_type_is_ada_url) {
12916 url.host = "";
12917 } else {
12918 url.update_base_hostname("");
12919 }
12920 // Set state to path start state.
12921 state = ada::state::PATH_START;
12922 } else {
12923 size_t consumed_bytes = file_host_buffer.size();
12924 input_position += consumed_bytes;
12925 // Let host be the result of host parsing buffer with url is not
12926 // special.
12927 if (!url.parse_host(file_host_buffer)) {
12928 return url;
12929 }
12930
12931 if constexpr (result_type_is_ada_url) {
12932 // If host is "localhost", then set host to the empty string.
12933 if (url.host.has_value() && url.host.value() == "localhost") {
12934 url.host = "";
12935 }
12936 } else {
12937 if (url.get_hostname() == "localhost") {
12938 url.update_base_hostname("");
12939 }
12940 }
12941
12942 // Set buffer to the empty string and state to path start state.
12943 state = ada::state::PATH_START;
12944 }
12945
12946 break;
12947 }
12948 case ada::state::FILE: {
12949 ada_log("FILE ", helpers::substring(url_data, input_position));
12950 std::string_view file_view =
12951 helpers::substring(url_data, input_position);
12952
12953 url.set_protocol_as_file();
12954 if constexpr (result_type_is_ada_url) {
12955 // Set url's host to the empty string.
12956 url.host = "";
12957 } else {
12958 url.update_base_hostname("");
12959 }
12960 // If c is U+002F (/) or U+005C (\), then:
12961 if (input_position != input_size &&
12962 (url_data[input_position] == '/' ||
12963 url_data[input_position] == '\\')) {
12964 ada_log("FILE c is U+002F or U+005C");
12965 // Set state to file slash state.
12966 state = ada::state::FILE_SLASH;
12967 }
12968 // Otherwise, if base is non-null and base's scheme is "file":
12969 else if (base_url != nullptr &&
12970 base_url->type == ada::scheme::type::FILE) {
12971 // Set url's host to base's host, url's path to a clone of base's
12972 // path, and url's query to base's query.
12973 ada_log("FILE base non-null");
12974 if constexpr (result_type_is_ada_url) {
12975 url.host = base_url->host;
12976 url.path = base_url->path;
12977 url.query = base_url->query;
12978 } else {
12979 // TODO: Get rid of set_hostname and replace it with
12980 // update_base_hostname
12981 url.set_hostname(base_url->get_hostname());
12982 url.update_base_pathname(base_url->get_pathname());
12983 url.update_base_search(base_url->get_search());
12984 }
12985 url.has_opaque_path = base_url->has_opaque_path;
12986
12987 // If c is U+003F (?), then set url's query to the empty string and
12988 // state to query state.
12989 if (input_position != input_size && url_data[input_position] == '?') {
12990 state = ada::state::QUERY;
12991 }
12992 // Otherwise, if c is not the EOF code point:
12993 else if (input_position != input_size) {
12994 // Set url's query to null.
12995 url.clear_search();
12996 // If the code point substring from pointer to the end of input does
12997 // not start with a Windows drive letter, then shorten url's path.
12998 if (!checkers::is_windows_drive_letter(file_view)) {
12999 if constexpr (result_type_is_ada_url) {
13000 helpers::shorten_path(url.path, url.type);
13001 } else {
13002 std::string_view path = url.get_pathname();
13003 if (helpers::shorten_path(path, url.type)) {
13004 url.update_base_pathname(std::string(path));
13005 }
13006 }
13007 }
13008 // Otherwise:
13009 else {
13010 // Set url's path to an empty list.
13011 url.clear_pathname();
13012 url.has_opaque_path = true;
13013 }
13014
13015 // Set state to path state and decrease pointer by 1.
13016 state = ada::state::PATH;
13017 break;
13018 }
13019 }
13020 // Otherwise, set state to path state, and decrease pointer by 1.
13021 else {
13022 ada_log("FILE go to path");
13023 state = ada::state::PATH;
13024 break;
13025 }
13026
13027 input_position++;
13028 break;
13029 }
13030 default:
13031 ada::unreachable();
13032 }
13033 }
13034 if (fragment.has_value()) {
13035 url.update_unencoded_base_hash(*fragment);
13036 }
13037 return url;
13038 }
13039
13040 template url parse_url<url>(std::string_view user_input,
13041 const url* base_url = nullptr);
13042 template url_aggregator parse_url<url_aggregator>(
13043 std::string_view user_input, const url_aggregator* base_url = nullptr);
13044
13045 } // namespace ada::parser
13046 /* end file src/parser.cpp */
13047 /* begin file src/url_components.cpp */
13048
13049 #include <numeric>
13050 #include <string>
13051
13052 namespace ada {
13053
check_offset_consistency() const13054 [[nodiscard]] bool url_components::check_offset_consistency() const noexcept {
13055 /**
13056 * https://user:pass@example.com:1234/foo/bar?baz#quux
13057 * | | | | ^^^^| | |
13058 * | | | | | | | `----- hash_start
13059 * | | | | | | `--------- search_start
13060 * | | | | | `----------------- pathname_start
13061 * | | | | `--------------------- port
13062 * | | | `----------------------- host_end
13063 * | | `---------------------------------- host_start
13064 * | `--------------------------------------- username_end
13065 * `--------------------------------------------- protocol_end
13066 */
13067 // These conditions can be made more strict.
13068 uint32_t index = 0;
13069
13070 if (protocol_end == url_components::omitted) {
13071 return false;
13072 }
13073 if (protocol_end < index) {
13074 return false;
13075 }
13076 index = protocol_end;
13077
13078 if (username_end == url_components::omitted) {
13079 return false;
13080 }
13081 if (username_end < index) {
13082 return false;
13083 }
13084 index = username_end;
13085
13086 if (host_start == url_components::omitted) {
13087 return false;
13088 }
13089 if (host_start < index) {
13090 return false;
13091 }
13092 index = host_start;
13093
13094 if (port != url_components::omitted) {
13095 if (port > 0xffff) {
13096 return false;
13097 }
13098 uint32_t port_length = helpers::fast_digit_count(port) + 1;
13099 if (index + port_length < index) {
13100 return false;
13101 }
13102 index += port_length;
13103 }
13104
13105 if (pathname_start == url_components::omitted) {
13106 return false;
13107 }
13108 if (pathname_start < index) {
13109 return false;
13110 }
13111 index = pathname_start;
13112
13113 if (search_start != url_components::omitted) {
13114 if (search_start < index) {
13115 return false;
13116 }
13117 index = search_start;
13118 }
13119
13120 if (hash_start != url_components::omitted) {
13121 if (hash_start < index) {
13122 return false;
13123 }
13124 index = hash_start;
13125 }
13126
13127 return true;
13128 }
13129
to_string() const13130 [[nodiscard]] std::string url_components::to_string() const {
13131 std::string answer;
13132 auto back = std::back_insert_iterator(answer);
13133 answer.append("{\n");
13134
13135 answer.append("\t\"protocol_end\":\"");
13136 helpers::encode_json(std::to_string(protocol_end), back);
13137 answer.append("\",\n");
13138
13139 answer.append("\t\"username_end\":\"");
13140 helpers::encode_json(std::to_string(username_end), back);
13141 answer.append("\",\n");
13142
13143 answer.append("\t\"host_start\":\"");
13144 helpers::encode_json(std::to_string(host_start), back);
13145 answer.append("\",\n");
13146
13147 answer.append("\t\"host_end\":\"");
13148 helpers::encode_json(std::to_string(host_end), back);
13149 answer.append("\",\n");
13150
13151 answer.append("\t\"port\":\"");
13152 helpers::encode_json(std::to_string(port), back);
13153 answer.append("\",\n");
13154
13155 answer.append("\t\"pathname_start\":\"");
13156 helpers::encode_json(std::to_string(pathname_start), back);
13157 answer.append("\",\n");
13158
13159 answer.append("\t\"search_start\":\"");
13160 helpers::encode_json(std::to_string(search_start), back);
13161 answer.append("\",\n");
13162
13163 answer.append("\t\"hash_start\":\"");
13164 helpers::encode_json(std::to_string(hash_start), back);
13165 answer.append("\",\n");
13166
13167 answer.append("\n}");
13168 return answer;
13169 }
13170
13171 } // namespace ada
13172 /* end file src/url_components.cpp */
13173 /* begin file src/url_aggregator.cpp */
13174
13175 #include <string>
13176 #include <string_view>
13177
13178 namespace ada {
13179 template <bool has_state_override>
parse_scheme_with_colon(const std::string_view input_with_colon)13180 [[nodiscard]] ada_really_inline bool url_aggregator::parse_scheme_with_colon(
13181 const std::string_view input_with_colon) {
13182 ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon);
13183 ADA_ASSERT_TRUE(validate());
13184 ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));
13185 std::string_view input{input_with_colon};
13186 input.remove_suffix(1);
13187 auto parsed_type = ada::scheme::get_scheme_type(input);
13188 bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
13189 /**
13190 * In the common case, we will immediately recognize a special scheme (e.g.,
13191 *http, https), in which case, we can go really fast.
13192 **/
13193 if (is_input_special) { // fast path!!!
13194 if (has_state_override) {
13195 // If url's scheme is not a special scheme and buffer is a special scheme,
13196 // then return.
13197 if (is_special() != is_input_special) {
13198 return true;
13199 }
13200
13201 // If url includes credentials or has a non-null port, and buffer is
13202 // "file", then return.
13203 if ((has_credentials() || components.port != url_components::omitted) &&
13204 parsed_type == ada::scheme::type::FILE) {
13205 return true;
13206 }
13207
13208 // If url's scheme is "file" and its host is an empty host, then return.
13209 // An empty host is the empty string.
13210 if (type == ada::scheme::type::FILE &&
13211 components.host_start == components.host_end) {
13212 return true;
13213 }
13214 }
13215
13216 type = parsed_type;
13217 set_scheme_from_view_with_colon(input_with_colon);
13218
13219 if (has_state_override) {
13220 // This is uncommon.
13221 uint16_t urls_scheme_port = get_special_port();
13222
13223 // If url's port is url's scheme's default port, then set url's port to
13224 // null.
13225 if (components.port == urls_scheme_port) {
13226 clear_port();
13227 }
13228 }
13229 } else { // slow path
13230 std::string _buffer = std::string(input);
13231 // Next function is only valid if the input is ASCII and returns false
13232 // otherwise, but it seems that we always have ascii content so we do not
13233 // need to check the return value.
13234 unicode::to_lower_ascii(_buffer.data(), _buffer.size());
13235
13236 if (has_state_override) {
13237 // If url's scheme is a special scheme and buffer is not a special scheme,
13238 // then return. If url's scheme is not a special scheme and buffer is a
13239 // special scheme, then return.
13240 if (is_special() != ada::scheme::is_special(_buffer)) {
13241 return true;
13242 }
13243
13244 // If url includes credentials or has a non-null port, and buffer is
13245 // "file", then return.
13246 if ((has_credentials() || components.port != url_components::omitted) &&
13247 _buffer == "file") {
13248 return true;
13249 }
13250
13251 // If url's scheme is "file" and its host is an empty host, then return.
13252 // An empty host is the empty string.
13253 if (type == ada::scheme::type::FILE &&
13254 components.host_start == components.host_end) {
13255 return true;
13256 }
13257 }
13258
13259 set_scheme(_buffer);
13260
13261 if (has_state_override) {
13262 // This is uncommon.
13263 uint16_t urls_scheme_port = get_special_port();
13264
13265 // If url's port is url's scheme's default port, then set url's port to
13266 // null.
13267 if (components.port == urls_scheme_port) {
13268 clear_port();
13269 }
13270 }
13271 }
13272 ADA_ASSERT_TRUE(validate());
13273 return true;
13274 }
13275
copy_scheme(const url_aggregator & u)13276 inline void url_aggregator::copy_scheme(const url_aggregator& u) noexcept {
13277 ada_log("url_aggregator::copy_scheme ", u.buffer);
13278 ADA_ASSERT_TRUE(validate());
13279 // next line could overflow but unsigned arithmetic has well-defined
13280 // overflows.
13281 uint32_t new_difference = u.components.protocol_end - components.protocol_end;
13282 type = u.type;
13283 buffer.erase(0, components.protocol_end);
13284 buffer.insert(0, u.get_protocol());
13285 components.protocol_end = u.components.protocol_end;
13286
13287 // No need to update the components
13288 if (new_difference == 0) {
13289 return;
13290 }
13291
13292 // Update the rest of the components.
13293 components.username_end += new_difference;
13294 components.host_start += new_difference;
13295 components.host_end += new_difference;
13296 components.pathname_start += new_difference;
13297 if (components.search_start != url_components::omitted) {
13298 components.search_start += new_difference;
13299 }
13300 if (components.hash_start != url_components::omitted) {
13301 components.hash_start += new_difference;
13302 }
13303 ADA_ASSERT_TRUE(validate());
13304 }
13305
set_scheme_from_view_with_colon(std::string_view new_scheme_with_colon)13306 inline void url_aggregator::set_scheme_from_view_with_colon(
13307 std::string_view new_scheme_with_colon) noexcept {
13308 ada_log("url_aggregator::set_scheme_from_view_with_colon ",
13309 new_scheme_with_colon);
13310 ADA_ASSERT_TRUE(validate());
13311 ADA_ASSERT_TRUE(!new_scheme_with_colon.empty() &&
13312 new_scheme_with_colon.back() == ':');
13313 // next line could overflow but unsigned arithmetic has well-defined
13314 // overflows.
13315 uint32_t new_difference =
13316 uint32_t(new_scheme_with_colon.size()) - components.protocol_end;
13317
13318 if (buffer.empty()) {
13319 buffer.append(new_scheme_with_colon);
13320 } else {
13321 buffer.erase(0, components.protocol_end);
13322 buffer.insert(0, new_scheme_with_colon);
13323 }
13324 components.protocol_end += new_difference;
13325
13326 // Update the rest of the components.
13327 components.username_end += new_difference;
13328 components.host_start += new_difference;
13329 components.host_end += new_difference;
13330 components.pathname_start += new_difference;
13331 if (components.search_start != url_components::omitted) {
13332 components.search_start += new_difference;
13333 }
13334 if (components.hash_start != url_components::omitted) {
13335 components.hash_start += new_difference;
13336 }
13337 ADA_ASSERT_TRUE(validate());
13338 }
13339
set_scheme(std::string_view new_scheme)13340 inline void url_aggregator::set_scheme(std::string_view new_scheme) noexcept {
13341 ada_log("url_aggregator::set_scheme ", new_scheme);
13342 ADA_ASSERT_TRUE(validate());
13343 ADA_ASSERT_TRUE(new_scheme.empty() || new_scheme.back() != ':');
13344 // next line could overflow but unsigned arithmetic has well-defined
13345 // overflows.
13346 uint32_t new_difference =
13347 uint32_t(new_scheme.size()) - components.protocol_end + 1;
13348
13349 type = ada::scheme::get_scheme_type(new_scheme);
13350 if (buffer.empty()) {
13351 buffer.append(helpers::concat(new_scheme, ":"));
13352 } else {
13353 buffer.erase(0, components.protocol_end);
13354 buffer.insert(0, helpers::concat(new_scheme, ":"));
13355 }
13356 components.protocol_end = uint32_t(new_scheme.size() + 1);
13357
13358 // Update the rest of the components.
13359 components.username_end += new_difference;
13360 components.host_start += new_difference;
13361 components.host_end += new_difference;
13362 components.pathname_start += new_difference;
13363 if (components.search_start != url_components::omitted) {
13364 components.search_start += new_difference;
13365 }
13366 if (components.hash_start != url_components::omitted) {
13367 components.hash_start += new_difference;
13368 }
13369 ADA_ASSERT_TRUE(validate());
13370 }
13371
set_protocol(const std::string_view input)13372 bool url_aggregator::set_protocol(const std::string_view input) {
13373 ada_log("url_aggregator::set_protocol ", input);
13374 ADA_ASSERT_TRUE(validate());
13375 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13376 std::string view(input);
13377 helpers::remove_ascii_tab_or_newline(view);
13378 if (view.empty()) {
13379 return true;
13380 }
13381
13382 // Schemes should start with alpha values.
13383 if (!checkers::is_alpha(view[0])) {
13384 return false;
13385 }
13386
13387 view.append(":");
13388
13389 std::string::iterator pointer =
13390 std::find_if_not(view.begin(), view.end(), unicode::is_alnum_plus);
13391
13392 if (pointer != view.end() && *pointer == ':') {
13393 return parse_scheme_with_colon<true>(
13394 std::string_view(view.data(), pointer - view.begin() + 1));
13395 }
13396 return false;
13397 }
13398
set_username(const std::string_view input)13399 bool url_aggregator::set_username(const std::string_view input) {
13400 ada_log("url_aggregator::set_username '", input, "' ");
13401 ADA_ASSERT_TRUE(validate());
13402 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13403 if (cannot_have_credentials_or_port()) {
13404 return false;
13405 }
13406 size_t idx = ada::unicode::percent_encode_index(
13407 input, character_sets::USERINFO_PERCENT_ENCODE);
13408 if (idx == input.size()) {
13409 update_base_username(input);
13410 } else {
13411 // We only create a temporary string if we have to!
13412 update_base_username(ada::unicode::percent_encode(
13413 input, character_sets::USERINFO_PERCENT_ENCODE, idx));
13414 }
13415 ADA_ASSERT_TRUE(validate());
13416 return true;
13417 }
13418
set_password(const std::string_view input)13419 bool url_aggregator::set_password(const std::string_view input) {
13420 ada_log("url_aggregator::set_password '", input, "'");
13421 ADA_ASSERT_TRUE(validate());
13422 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13423 if (cannot_have_credentials_or_port()) {
13424 return false;
13425 }
13426 size_t idx = ada::unicode::percent_encode_index(
13427 input, character_sets::USERINFO_PERCENT_ENCODE);
13428 if (idx == input.size()) {
13429 update_base_password(input);
13430 } else {
13431 // We only create a temporary string if we have to!
13432 update_base_password(ada::unicode::percent_encode(
13433 input, character_sets::USERINFO_PERCENT_ENCODE, idx));
13434 }
13435 ADA_ASSERT_TRUE(validate());
13436 return true;
13437 }
13438
set_port(const std::string_view input)13439 bool url_aggregator::set_port(const std::string_view input) {
13440 ada_log("url_aggregator::set_port ", input);
13441 ADA_ASSERT_TRUE(validate());
13442 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13443 if (cannot_have_credentials_or_port()) {
13444 return false;
13445 }
13446 std::string trimmed(input);
13447 helpers::remove_ascii_tab_or_newline(trimmed);
13448 if (trimmed.empty()) {
13449 clear_port();
13450 return true;
13451 }
13452 // Input should not start with control characters.
13453 if (ada::unicode::is_c0_control_or_space(trimmed.front())) {
13454 return false;
13455 }
13456 // Input should contain at least one ascii digit.
13457 if (input.find_first_of("0123456789") == std::string_view::npos) {
13458 return false;
13459 }
13460
13461 // Revert changes if parse_port fails.
13462 uint32_t previous_port = components.port;
13463 parse_port(trimmed);
13464 if (is_valid) {
13465 return true;
13466 }
13467 update_base_port(previous_port);
13468 is_valid = true;
13469 ADA_ASSERT_TRUE(validate());
13470 return false;
13471 }
13472
set_pathname(const std::string_view input)13473 bool url_aggregator::set_pathname(const std::string_view input) {
13474 ada_log("url_aggregator::set_pathname ", input);
13475 ADA_ASSERT_TRUE(validate());
13476 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13477 if (has_opaque_path) {
13478 return false;
13479 }
13480 clear_pathname();
13481 parse_path(input);
13482 if (checkers::begins_with(input, "//") && !has_authority() &&
13483 !has_dash_dot()) {
13484 buffer.insert(components.pathname_start, "/.");
13485 components.pathname_start += 2;
13486 }
13487 ADA_ASSERT_TRUE(validate());
13488 return true;
13489 }
13490
parse_path(std::string_view input)13491 ada_really_inline void url_aggregator::parse_path(std::string_view input) {
13492 ada_log("url_aggregator::parse_path ", input);
13493 ADA_ASSERT_TRUE(validate());
13494 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13495 std::string tmp_buffer;
13496 std::string_view internal_input;
13497 if (unicode::has_tabs_or_newline(input)) {
13498 tmp_buffer = input;
13499 // Optimization opportunity: Instead of copying and then pruning, we could
13500 // just directly build the string from user_input.
13501 helpers::remove_ascii_tab_or_newline(tmp_buffer);
13502 internal_input = tmp_buffer;
13503 } else {
13504 internal_input = input;
13505 }
13506
13507 // If url is special, then:
13508 if (is_special()) {
13509 if (internal_input.empty()) {
13510 update_base_pathname("/");
13511 } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
13512 consume_prepared_path(internal_input.substr(1));
13513 } else {
13514 consume_prepared_path(internal_input);
13515 }
13516 } else if (!internal_input.empty()) {
13517 if (internal_input[0] == '/') {
13518 consume_prepared_path(internal_input.substr(1));
13519 } else {
13520 consume_prepared_path(internal_input);
13521 }
13522 } else {
13523 // Non-special URLs with an empty host can have their paths erased
13524 // Path-only URLs cannot have their paths erased
13525 if (components.host_start == components.host_end && !has_authority()) {
13526 update_base_pathname("/");
13527 }
13528 }
13529 ADA_ASSERT_TRUE(validate());
13530 }
13531
set_search(const std::string_view input)13532 void url_aggregator::set_search(const std::string_view input) {
13533 ada_log("url_aggregator::set_search ", input);
13534 ADA_ASSERT_TRUE(validate());
13535 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13536 if (input.empty()) {
13537 clear_search();
13538 helpers::strip_trailing_spaces_from_opaque_path(*this);
13539 return;
13540 }
13541
13542 std::string new_value;
13543 new_value = input[0] == '?' ? input.substr(1) : input;
13544 helpers::remove_ascii_tab_or_newline(new_value);
13545
13546 auto query_percent_encode_set =
13547 is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
13548 : ada::character_sets::QUERY_PERCENT_ENCODE;
13549
13550 update_base_search(new_value, query_percent_encode_set);
13551 ADA_ASSERT_TRUE(validate());
13552 }
13553
set_hash(const std::string_view input)13554 void url_aggregator::set_hash(const std::string_view input) {
13555 ada_log("url_aggregator::set_hash ", input);
13556 ADA_ASSERT_TRUE(validate());
13557 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13558 if (input.empty()) {
13559 if (components.hash_start != url_components::omitted) {
13560 buffer.resize(components.hash_start);
13561 components.hash_start = url_components::omitted;
13562 }
13563 helpers::strip_trailing_spaces_from_opaque_path(*this);
13564 return;
13565 }
13566
13567 std::string new_value;
13568 new_value = input[0] == '#' ? input.substr(1) : input;
13569 helpers::remove_ascii_tab_or_newline(new_value);
13570 update_unencoded_base_hash(new_value);
13571 ADA_ASSERT_TRUE(validate());
13572 }
13573
set_href(const std::string_view input)13574 bool url_aggregator::set_href(const std::string_view input) {
13575 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13576 ada_log("url_aggregator::set_href ", input, " [", input.size(), " bytes]");
13577 ada::result<url_aggregator> out = ada::parse<url_aggregator>(input);
13578 ada_log("url_aggregator::set_href, success :", out.has_value());
13579
13580 if (out) {
13581 ada_log("url_aggregator::set_href, parsed ", out->to_string());
13582 // TODO: Figure out why the following line puts test to never finish.
13583 *this = *out;
13584 }
13585
13586 return out.has_value();
13587 }
13588
parse_host(std::string_view input)13589 ada_really_inline bool url_aggregator::parse_host(std::string_view input) {
13590 ada_log("url_aggregator:parse_host \"", input, "\" [", input.size(),
13591 " bytes]");
13592 ADA_ASSERT_TRUE(validate());
13593 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13594 if (input.empty()) {
13595 return is_valid = false;
13596 } // technically unnecessary.
13597 // If input starts with U+005B ([), then:
13598 if (input[0] == '[') {
13599 // If input does not end with U+005D (]), validation error, return failure.
13600 if (input.back() != ']') {
13601 return is_valid = false;
13602 }
13603 ada_log("parse_host ipv6");
13604
13605 // Return the result of IPv6 parsing input with its leading U+005B ([) and
13606 // trailing U+005D (]) removed.
13607 input.remove_prefix(1);
13608 input.remove_suffix(1);
13609 return parse_ipv6(input);
13610 }
13611
13612 // If isNotSpecial is true, then return the result of opaque-host parsing
13613 // input.
13614 if (!is_special()) {
13615 return parse_opaque_host(input);
13616 }
13617 // Let domain be the result of running UTF-8 decode without BOM on the
13618 // percent-decoding of input. Let asciiDomain be the result of running domain
13619 // to ASCII with domain and false. The most common case is an ASCII input, in
13620 // which case we do not need to call the expensive 'to_ascii' if a few
13621 // conditions are met: no '%' and no 'xn-' subsequence.
13622
13623 // Often, the input does not contain any forbidden code points, and no upper
13624 // case ASCII letter, then we can just copy it to the buffer. We want to
13625 // optimize for such a common case.
13626 uint8_t is_forbidden_or_upper =
13627 unicode::contains_forbidden_domain_code_point_or_upper(input.data(),
13628 input.size());
13629 // Minor optimization opportunity:
13630 // contains_forbidden_domain_code_point_or_upper could be extend to check for
13631 // the presence of characters that cannot appear in the ipv4 address and we
13632 // could also check whether x and n and - are present, and so we could skip
13633 // some of the checks below. However, the gains are likely to be small, and
13634 // the code would be more complex.
13635 if (is_forbidden_or_upper == 0 &&
13636 input.find("xn-") == std::string_view::npos) {
13637 // fast path
13638 update_base_hostname(input);
13639 if (checkers::is_ipv4(get_hostname())) {
13640 ada_log("parse_host fast path ipv4");
13641 return parse_ipv4(get_hostname(), true);
13642 }
13643 ada_log("parse_host fast path ", get_hostname());
13644 return true;
13645 }
13646 // We have encountered at least one forbidden code point or the input contains
13647 // 'xn-' (case insensitive), so we need to call 'to_ascii' to perform the full
13648 // conversion.
13649
13650 ada_log("parse_host calling to_ascii");
13651 std::optional<std::string> host = std::string(get_hostname());
13652 is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
13653 if (!is_valid) {
13654 ada_log("parse_host to_ascii returns false");
13655 return is_valid = false;
13656 }
13657 ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
13658 " bytes]");
13659
13660 if (std::any_of(host.value().begin(), host.value().end(),
13661 ada::unicode::is_forbidden_domain_code_point)) {
13662 return is_valid = false;
13663 }
13664
13665 // If asciiDomain ends in a number, then return the result of IPv4 parsing
13666 // asciiDomain.
13667 if (checkers::is_ipv4(host.value())) {
13668 ada_log("parse_host got ipv4 ", *host);
13669 return parse_ipv4(host.value(), false);
13670 }
13671
13672 update_base_hostname(host.value());
13673 ADA_ASSERT_TRUE(validate());
13674 return true;
13675 }
13676
13677 template <bool override_hostname>
set_host_or_hostname(const std::string_view input)13678 bool url_aggregator::set_host_or_hostname(const std::string_view input) {
13679 ada_log("url_aggregator::set_host_or_hostname ", input);
13680 ADA_ASSERT_TRUE(validate());
13681 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13682 if (has_opaque_path) {
13683 return false;
13684 }
13685
13686 std::string previous_host = std::string(get_hostname());
13687 uint32_t previous_port = components.port;
13688
13689 size_t host_end_pos = input.find('#');
13690 std::string _host(input.data(), host_end_pos != std::string_view::npos
13691 ? host_end_pos
13692 : input.size());
13693 helpers::remove_ascii_tab_or_newline(_host);
13694 std::string_view new_host(_host);
13695
13696 // If url's scheme is "file", then set state to file host state, instead of
13697 // host state.
13698 if (type != ada::scheme::type::FILE) {
13699 std::string_view host_view(_host.data(), _host.length());
13700 auto [location, found_colon] =
13701 helpers::get_host_delimiter_location(is_special(), host_view);
13702
13703 // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
13704 // Note: the 'found_colon' value is true if and only if a colon was
13705 // encountered while not inside brackets.
13706 if (found_colon) {
13707 if (override_hostname) {
13708 return false;
13709 }
13710 std::string_view sub_buffer = new_host.substr(location + 1);
13711 if (!sub_buffer.empty()) {
13712 set_port(sub_buffer);
13713 }
13714 }
13715 // If url is special and host_view is the empty string, validation error,
13716 // return failure. Otherwise, if state override is given, host_view is the
13717 // empty string, and either url includes credentials or url's port is
13718 // non-null, return.
13719 else if (host_view.empty() &&
13720 (is_special() || has_credentials() || has_port())) {
13721 return false;
13722 }
13723
13724 // Let host be the result of host parsing host_view with url is not special.
13725 if (host_view.empty() && !is_special()) {
13726 if (has_hostname()) {
13727 clear_hostname(); // easy!
13728 } else if (has_dash_dot()) {
13729 add_authority_slashes_if_needed();
13730 delete_dash_dot();
13731 }
13732 return true;
13733 }
13734
13735 bool succeeded = parse_host(host_view);
13736 if (!succeeded) {
13737 update_base_hostname(previous_host);
13738 update_base_port(previous_port);
13739 } else if (has_dash_dot()) {
13740 // Should remove dash_dot from pathname
13741 delete_dash_dot();
13742 }
13743 return succeeded;
13744 }
13745
13746 size_t location = new_host.find_first_of("/\\?");
13747 if (location != std::string_view::npos) {
13748 new_host.remove_suffix(new_host.length() - location);
13749 }
13750
13751 if (new_host.empty()) {
13752 // Set url's host to the empty string.
13753 clear_hostname();
13754 } else {
13755 // Let host be the result of host parsing buffer with url is not special.
13756 if (!parse_host(new_host)) {
13757 update_base_hostname(previous_host);
13758 update_base_port(previous_port);
13759 return false;
13760 }
13761
13762 // If host is "localhost", then set host to the empty string.
13763 if (helpers::substring(buffer, components.host_start,
13764 components.host_end) == "localhost") {
13765 clear_hostname();
13766 }
13767 }
13768 ADA_ASSERT_TRUE(validate());
13769 return true;
13770 }
13771
set_host(const std::string_view input)13772 bool url_aggregator::set_host(const std::string_view input) {
13773 ada_log("url_aggregator::set_host '", input, "'");
13774 ADA_ASSERT_TRUE(validate());
13775 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13776 return set_host_or_hostname<false>(input);
13777 }
13778
set_hostname(const std::string_view input)13779 bool url_aggregator::set_hostname(const std::string_view input) {
13780 ada_log("url_aggregator::set_hostname '", input, "'");
13781 ADA_ASSERT_TRUE(validate());
13782 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13783 return set_host_or_hostname<true>(input);
13784 }
13785
get_origin() const13786 [[nodiscard]] std::string url_aggregator::get_origin() const noexcept {
13787 ada_log("url_aggregator::get_origin");
13788 if (is_special()) {
13789 // Return a new opaque origin.
13790 if (type == scheme::FILE) {
13791 return "null";
13792 }
13793
13794 return helpers::concat(get_protocol(), "//", get_host());
13795 }
13796
13797 if (get_protocol() == "blob:") {
13798 std::string_view path = get_pathname();
13799 if (!path.empty()) {
13800 auto out = ada::parse<ada::url_aggregator>(path);
13801 if (out && (out->type == scheme::HTTP || out->type == scheme::HTTPS)) {
13802 // If pathURL's scheme is not "http" and not "https", then return a
13803 // new opaque origin.
13804 return helpers::concat(out->get_protocol(), "//", out->get_host());
13805 }
13806 }
13807 }
13808
13809 // Return a new opaque origin.
13810 return "null";
13811 }
13812
get_username() const13813 [[nodiscard]] std::string_view url_aggregator::get_username() const noexcept {
13814 ada_log("url_aggregator::get_username");
13815 if (has_non_empty_username()) {
13816 return helpers::substring(buffer, components.protocol_end + 2,
13817 components.username_end);
13818 }
13819 return "";
13820 }
13821
get_password() const13822 [[nodiscard]] std::string_view url_aggregator::get_password() const noexcept {
13823 ada_log("url_aggregator::get_password");
13824 if (has_non_empty_password()) {
13825 return helpers::substring(buffer, components.username_end + 1,
13826 components.host_start);
13827 }
13828 return "";
13829 }
13830
get_port() const13831 [[nodiscard]] std::string_view url_aggregator::get_port() const noexcept {
13832 ada_log("url_aggregator::get_port");
13833 if (components.port == url_components::omitted) {
13834 return "";
13835 }
13836 return helpers::substring(buffer, components.host_end + 1,
13837 components.pathname_start);
13838 }
13839
get_hash() const13840 [[nodiscard]] std::string_view url_aggregator::get_hash() const noexcept {
13841 ada_log("url_aggregator::get_hash");
13842 // If this's URL's fragment is either null or the empty string, then return
13843 // the empty string. Return U+0023 (#), followed by this's URL's fragment.
13844 if (components.hash_start == url_components::omitted) {
13845 return "";
13846 }
13847 if (buffer.size() - components.hash_start <= 1) {
13848 return "";
13849 }
13850 return helpers::substring(buffer, components.hash_start);
13851 }
13852
get_host() const13853 [[nodiscard]] std::string_view url_aggregator::get_host() const noexcept {
13854 ada_log("url_aggregator::get_host");
13855 // Technically, we should check if there is a hostname, but
13856 // the code below works even if there isn't.
13857 // if(!has_hostname()) { return ""; }
13858 size_t start = components.host_start;
13859 if (components.host_end > components.host_start &&
13860 buffer[components.host_start] == '@') {
13861 start++;
13862 }
13863 // if we have an empty host, then the space between components.host_end and
13864 // components.pathname_start may be occupied by /.
13865 if (start == components.host_end) {
13866 return std::string_view();
13867 }
13868 return helpers::substring(buffer, start, components.pathname_start);
13869 }
13870
get_hostname() const13871 [[nodiscard]] std::string_view url_aggregator::get_hostname() const noexcept {
13872 ada_log("url_aggregator::get_hostname");
13873 // Technically, we should check if there is a hostname, but
13874 // the code below works even if there isn't.
13875 // if(!has_hostname()) { return ""; }
13876 size_t start = components.host_start;
13877 // So host_start is not where the host begins.
13878 if (components.host_end > components.host_start &&
13879 buffer[components.host_start] == '@') {
13880 start++;
13881 }
13882 return helpers::substring(buffer, start, components.host_end);
13883 }
13884
get_pathname() const13885 [[nodiscard]] std::string_view url_aggregator::get_pathname() const noexcept {
13886 ada_log("url_aggregator::get_pathname pathname_start = ",
13887 components.pathname_start, " buffer.size() = ", buffer.size(),
13888 " components.search_start = ", components.search_start,
13889 " components.hash_start = ", components.hash_start);
13890 uint32_t ending_index = uint32_t(buffer.size());
13891 if (components.search_start != url_components::omitted) {
13892 ending_index = components.search_start;
13893 } else if (components.hash_start != url_components::omitted) {
13894 ending_index = components.hash_start;
13895 }
13896 return helpers::substring(buffer, components.pathname_start, ending_index);
13897 }
13898
get_search() const13899 [[nodiscard]] std::string_view url_aggregator::get_search() const noexcept {
13900 ada_log("url_aggregator::get_search");
13901 // If this's URL's query is either null or the empty string, then return the
13902 // empty string. Return U+003F (?), followed by this's URL's query.
13903 if (components.search_start == url_components::omitted) {
13904 return "";
13905 }
13906 uint32_t ending_index = uint32_t(buffer.size());
13907 if (components.hash_start != url_components::omitted) {
13908 ending_index = components.hash_start;
13909 }
13910 if (ending_index - components.search_start <= 1) {
13911 return "";
13912 }
13913 return helpers::substring(buffer, components.search_start, ending_index);
13914 }
13915
get_protocol() const13916 [[nodiscard]] std::string_view url_aggregator::get_protocol() const noexcept {
13917 ada_log("url_aggregator::get_protocol");
13918 return helpers::substring(buffer, 0, components.protocol_end);
13919 }
13920
to_string() const13921 [[nodiscard]] std::string ada::url_aggregator::to_string() const {
13922 ada_log("url_aggregator::to_string buffer:", buffer, " [", buffer.size(),
13923 " bytes]");
13924 if (!is_valid) {
13925 return "null";
13926 }
13927
13928 std::string answer;
13929 auto back = std::back_insert_iterator(answer);
13930 answer.append("{\n");
13931
13932 answer.append("\t\"buffer\":\"");
13933 helpers::encode_json(buffer, back);
13934 answer.append("\",\n");
13935
13936 answer.append("\t\"protocol\":\"");
13937 helpers::encode_json(get_protocol(), back);
13938 answer.append("\",\n");
13939
13940 if (has_credentials()) {
13941 answer.append("\t\"username\":\"");
13942 helpers::encode_json(get_username(), back);
13943 answer.append("\",\n");
13944 answer.append("\t\"password\":\"");
13945 helpers::encode_json(get_password(), back);
13946 answer.append("\",\n");
13947 }
13948
13949 answer.append("\t\"host\":\"");
13950 helpers::encode_json(get_host(), back);
13951 answer.append("\",\n");
13952
13953 answer.append("\t\"path\":\"");
13954 helpers::encode_json(get_pathname(), back);
13955 answer.append("\",\n");
13956 answer.append("\t\"opaque path\":");
13957 answer.append((has_opaque_path ? "true" : "false"));
13958 answer.append(",\n");
13959
13960 if (components.search_start != url_components::omitted) {
13961 answer.append("\t\"query\":\"");
13962 helpers::encode_json(get_search(), back);
13963 answer.append("\",\n");
13964 }
13965 if (components.hash_start != url_components::omitted) {
13966 answer.append("\t\"fragment\":\"");
13967 helpers::encode_json(get_hash(), back);
13968 answer.append("\",\n");
13969 }
13970
13971 auto convert_offset_to_string = [](uint32_t offset) -> std::string {
13972 if (offset == url_components::omitted) {
13973 return "null";
13974 } else {
13975 return std::to_string(offset);
13976 }
13977 };
13978
13979 answer.append("\t\"protocol_end\":");
13980 answer.append(convert_offset_to_string(components.protocol_end));
13981 answer.append(",\n");
13982
13983 answer.append("\t\"username_end\":");
13984 answer.append(convert_offset_to_string(components.username_end));
13985 answer.append(",\n");
13986
13987 answer.append("\t\"host_start\":");
13988 answer.append(convert_offset_to_string(components.host_start));
13989 answer.append(",\n");
13990
13991 answer.append("\t\"host_end\":");
13992 answer.append(convert_offset_to_string(components.host_end));
13993 answer.append(",\n");
13994
13995 answer.append("\t\"port\":");
13996 answer.append(convert_offset_to_string(components.port));
13997 answer.append(",\n");
13998
13999 answer.append("\t\"pathname_start\":");
14000 answer.append(convert_offset_to_string(components.pathname_start));
14001 answer.append(",\n");
14002
14003 answer.append("\t\"search_start\":");
14004 answer.append(convert_offset_to_string(components.search_start));
14005 answer.append(",\n");
14006
14007 answer.append("\t\"hash_start\":");
14008 answer.append(convert_offset_to_string(components.hash_start));
14009 answer.append("\n}");
14010
14011 return answer;
14012 }
14013
has_valid_domain() const14014 [[nodiscard]] bool url_aggregator::has_valid_domain() const noexcept {
14015 if (components.host_start == components.host_end) {
14016 return false;
14017 }
14018 return checkers::verify_dns_length(get_hostname());
14019 }
14020
parse_ipv4(std::string_view input,bool in_place)14021 bool url_aggregator::parse_ipv4(std::string_view input, bool in_place) {
14022 ada_log("parse_ipv4 ", input, " [", input.size(),
14023 " bytes], overlaps with buffer: ",
14024 helpers::overlaps(input, buffer) ? "yes" : "no");
14025 ADA_ASSERT_TRUE(validate());
14026 const bool trailing_dot = (input.back() == '.');
14027 if (trailing_dot) {
14028 input.remove_suffix(1);
14029 }
14030 size_t digit_count{0};
14031 int pure_decimal_count = 0; // entries that are decimal
14032 uint64_t ipv4{0};
14033 // we could unroll for better performance?
14034 for (; (digit_count < 4) && !(input.empty()); digit_count++) {
14035 uint32_t
14036 segment_result{}; // If any number exceeds 32 bits, we have an error.
14037 bool is_hex = checkers::has_hex_prefix(input);
14038 if (is_hex && ((input.length() == 2) ||
14039 ((input.length() > 2) && (input[2] == '.')))) {
14040 // special case
14041 segment_result = 0;
14042 input.remove_prefix(2);
14043 } else {
14044 std::from_chars_result r;
14045 if (is_hex) {
14046 ada_log("parse_ipv4 trying to parse hex number");
14047 r = std::from_chars(input.data() + 2, input.data() + input.size(),
14048 segment_result, 16);
14049 } else if ((input.length() >= 2) && input[0] == '0' &&
14050 checkers::is_digit(input[1])) {
14051 ada_log("parse_ipv4 trying to parse octal number");
14052 r = std::from_chars(input.data() + 1, input.data() + input.size(),
14053 segment_result, 8);
14054 } else {
14055 ada_log("parse_ipv4 trying to parse decimal number");
14056 pure_decimal_count++;
14057 r = std::from_chars(input.data(), input.data() + input.size(),
14058 segment_result, 10);
14059 }
14060 if (r.ec != std::errc()) {
14061 ada_log("parse_ipv4 parsing failed");
14062 return is_valid = false;
14063 }
14064 ada_log("parse_ipv4 parsed ", segment_result);
14065 input.remove_prefix(r.ptr - input.data());
14066 }
14067 if (input.empty()) {
14068 // We have the last value.
14069 // At this stage, ipv4 contains digit_count*8 bits.
14070 // So we have 32-digit_count*8 bits left.
14071 if (segment_result >= (uint64_t(1) << (32 - digit_count * 8))) {
14072 return is_valid = false;
14073 }
14074 ipv4 <<= (32 - digit_count * 8);
14075 ipv4 |= segment_result;
14076 goto final;
14077 } else {
14078 // There is more, so that the value must no be larger than 255
14079 // and we must have a '.'.
14080 if ((segment_result > 255) || (input[0] != '.')) {
14081 return is_valid = false;
14082 }
14083 ipv4 <<= 8;
14084 ipv4 |= segment_result;
14085 input.remove_prefix(1); // remove '.'
14086 }
14087 }
14088 if ((digit_count != 4) || (!input.empty())) {
14089 ada_log("parse_ipv4 found invalid (more than 4 numbers or empty) ");
14090 return is_valid = false;
14091 }
14092 final:
14093 ada_log("url_aggregator::parse_ipv4 completed ", get_href(),
14094 " host: ", get_host());
14095
14096 // We could also check r.ptr to see where the parsing ended.
14097 if (in_place && pure_decimal_count == 4 && !trailing_dot) {
14098 ada_log(
14099 "url_aggregator::parse_ipv4 completed and was already correct in the "
14100 "buffer");
14101 // The original input was already all decimal and we validated it. So we
14102 // don't need to do anything.
14103 } else {
14104 ada_log("url_aggregator::parse_ipv4 completed and we need to update it");
14105 // Optimization opportunity: Get rid of unnecessary string return in ipv4
14106 // serializer.
14107 // TODO: This is likely a bug because it goes back update_base_hostname, not
14108 // what we want to do.
14109 update_base_hostname(
14110 ada::serializers::ipv4(ipv4)); // We have to reserialize the address.
14111 }
14112 host_type = IPV4;
14113 ADA_ASSERT_TRUE(validate());
14114 return true;
14115 }
14116
parse_ipv6(std::string_view input)14117 bool url_aggregator::parse_ipv6(std::string_view input) {
14118 // TODO: Implement in_place optimization: we know that input points
14119 // in the buffer, so we can just check whether the buffer is already
14120 // well formatted.
14121 // TODO: Find a way to merge parse_ipv6 with url.cpp implementation.
14122 ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
14123 ADA_ASSERT_TRUE(validate());
14124 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14125 if (input.empty()) {
14126 return is_valid = false;
14127 }
14128 // Let address be a new IPv6 address whose IPv6 pieces are all 0.
14129 std::array<uint16_t, 8> address{};
14130
14131 // Let pieceIndex be 0.
14132 int piece_index = 0;
14133
14134 // Let compress be null.
14135 std::optional<int> compress{};
14136
14137 // Let pointer be a pointer for input.
14138 std::string_view::iterator pointer = input.begin();
14139
14140 // If c is U+003A (:), then:
14141 if (input[0] == ':') {
14142 // If remaining does not start with U+003A (:), validation error, return
14143 // failure.
14144 if (input.size() == 1 || input[1] != ':') {
14145 ada_log("parse_ipv6 starts with : but the rest does not start with :");
14146 return is_valid = false;
14147 }
14148
14149 // Increase pointer by 2.
14150 pointer += 2;
14151
14152 // Increase pieceIndex by 1 and then set compress to pieceIndex.
14153 compress = ++piece_index;
14154 }
14155
14156 // While c is not the EOF code point:
14157 while (pointer != input.end()) {
14158 // If pieceIndex is 8, validation error, return failure.
14159 if (piece_index == 8) {
14160 ada_log("parse_ipv6 piece_index == 8");
14161 return is_valid = false;
14162 }
14163
14164 // If c is U+003A (:), then:
14165 if (*pointer == ':') {
14166 // If compress is non-null, validation error, return failure.
14167 if (compress.has_value()) {
14168 ada_log("parse_ipv6 compress is non-null");
14169 return is_valid = false;
14170 }
14171
14172 // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and
14173 // then continue.
14174 pointer++;
14175 compress = ++piece_index;
14176 continue;
14177 }
14178
14179 // Let value and length be 0.
14180 uint16_t value = 0, length = 0;
14181
14182 // While length is less than 4 and c is an ASCII hex digit,
14183 // set value to value times 0x10 + c interpreted as hexadecimal number, and
14184 // increase pointer and length by 1.
14185 while (length < 4 && pointer != input.end() &&
14186 unicode::is_ascii_hex_digit(*pointer)) {
14187 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
14188 value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));
14189 pointer++;
14190 length++;
14191 }
14192
14193 // If c is U+002E (.), then:
14194 if (pointer != input.end() && *pointer == '.') {
14195 // If length is 0, validation error, return failure.
14196 if (length == 0) {
14197 ada_log("parse_ipv6 length is 0");
14198 return is_valid = false;
14199 }
14200
14201 // Decrease pointer by length.
14202 pointer -= length;
14203
14204 // If pieceIndex is greater than 6, validation error, return failure.
14205 if (piece_index > 6) {
14206 ada_log("parse_ipv6 piece_index > 6");
14207 return is_valid = false;
14208 }
14209
14210 // Let numbersSeen be 0.
14211 int numbers_seen = 0;
14212
14213 // While c is not the EOF code point:
14214 while (pointer != input.end()) {
14215 // Let ipv4Piece be null.
14216 std::optional<uint16_t> ipv4_piece{};
14217
14218 // If numbersSeen is greater than 0, then:
14219 if (numbers_seen > 0) {
14220 // If c is a U+002E (.) and numbersSeen is less than 4, then increase
14221 // pointer by 1.
14222 if (*pointer == '.' && numbers_seen < 4) {
14223 pointer++;
14224 } else {
14225 // Otherwise, validation error, return failure.
14226 ada_log("parse_ipv6 Otherwise, validation error, return failure");
14227 return is_valid = false;
14228 }
14229 }
14230
14231 // If c is not an ASCII digit, validation error, return failure.
14232 if (pointer == input.end() || !checkers::is_digit(*pointer)) {
14233 ada_log(
14234 "parse_ipv6 If c is not an ASCII digit, validation error, return "
14235 "failure");
14236 return is_valid = false;
14237 }
14238
14239 // While c is an ASCII digit:
14240 while (pointer != input.end() && checkers::is_digit(*pointer)) {
14241 // Let number be c interpreted as decimal number.
14242 int number = *pointer - '0';
14243
14244 // If ipv4Piece is null, then set ipv4Piece to number.
14245 if (!ipv4_piece.has_value()) {
14246 ipv4_piece = number;
14247 }
14248 // Otherwise, if ipv4Piece is 0, validation error, return failure.
14249 else if (ipv4_piece == 0) {
14250 ada_log("parse_ipv6 if ipv4Piece is 0, validation error");
14251 return is_valid = false;
14252 }
14253 // Otherwise, set ipv4Piece to ipv4Piece times 10 + number.
14254 else {
14255 ipv4_piece = *ipv4_piece * 10 + number;
14256 }
14257
14258 // If ipv4Piece is greater than 255, validation error, return failure.
14259 if (ipv4_piece > 255) {
14260 ada_log("parse_ipv6 ipv4_piece > 255");
14261 return is_valid = false;
14262 }
14263
14264 // Increase pointer by 1.
14265 pointer++;
14266 }
14267
14268 // Set address[pieceIndex] to address[pieceIndex] times 0x100 +
14269 // ipv4Piece.
14270 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
14271 address[piece_index] =
14272 uint16_t(address[piece_index] * 0x100 + *ipv4_piece);
14273
14274 // Increase numbersSeen by 1.
14275 numbers_seen++;
14276
14277 // If numbersSeen is 2 or 4, then increase pieceIndex by 1.
14278 if (numbers_seen == 2 || numbers_seen == 4) {
14279 piece_index++;
14280 }
14281 }
14282
14283 // If numbersSeen is not 4, validation error, return failure.
14284 if (numbers_seen != 4) {
14285 return is_valid = false;
14286 }
14287
14288 // Break.
14289 break;
14290 }
14291 // Otherwise, if c is U+003A (:):
14292 else if ((pointer != input.end()) && (*pointer == ':')) {
14293 // Increase pointer by 1.
14294 pointer++;
14295
14296 // If c is the EOF code point, validation error, return failure.
14297 if (pointer == input.end()) {
14298 ada_log(
14299 "parse_ipv6 If c is the EOF code point, validation error, return "
14300 "failure");
14301 return is_valid = false;
14302 }
14303 }
14304 // Otherwise, if c is not the EOF code point, validation error, return
14305 // failure.
14306 else if (pointer != input.end()) {
14307 ada_log(
14308 "parse_ipv6 Otherwise, if c is not the EOF code point, validation "
14309 "error, return failure");
14310 return is_valid = false;
14311 }
14312
14313 // Set address[pieceIndex] to value.
14314 address[piece_index] = value;
14315
14316 // Increase pieceIndex by 1.
14317 piece_index++;
14318 }
14319
14320 // If compress is non-null, then:
14321 if (compress.has_value()) {
14322 // Let swaps be pieceIndex - compress.
14323 int swaps = piece_index - *compress;
14324
14325 // Set pieceIndex to 7.
14326 piece_index = 7;
14327
14328 // While pieceIndex is not 0 and swaps is greater than 0,
14329 // swap address[pieceIndex] with address[compress + swaps - 1], and then
14330 // decrease both pieceIndex and swaps by 1.
14331 while (piece_index != 0 && swaps > 0) {
14332 std::swap(address[piece_index], address[*compress + swaps - 1]);
14333 piece_index--;
14334 swaps--;
14335 }
14336 }
14337 // Otherwise, if compress is null and pieceIndex is not 8, validation error,
14338 // return failure.
14339 else if (piece_index != 8) {
14340 ada_log(
14341 "parse_ipv6 if compress is null and pieceIndex is not 8, validation "
14342 "error, return failure");
14343 return is_valid = false;
14344 }
14345 // TODO: Optimization opportunity: Get rid of unnecessary string creation.
14346 // TODO: This is likely a bug because it goes back update_base_hostname, not
14347 // what we want to do.
14348 update_base_hostname(ada::serializers::ipv6(address));
14349 ada_log("parse_ipv6 ", get_hostname());
14350 ADA_ASSERT_TRUE(validate());
14351 host_type = IPV6;
14352 return true;
14353 }
14354
parse_opaque_host(std::string_view input)14355 bool url_aggregator::parse_opaque_host(std::string_view input) {
14356 ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
14357 ADA_ASSERT_TRUE(validate());
14358 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14359 if (std::any_of(input.begin(), input.end(),
14360 ada::unicode::is_forbidden_host_code_point)) {
14361 return is_valid = false;
14362 }
14363
14364 // Return the result of running UTF-8 percent-encode on input using the C0
14365 // control percent-encode set.
14366 size_t idx = ada::unicode::percent_encode_index(
14367 input, character_sets::C0_CONTROL_PERCENT_ENCODE);
14368 if (idx == input.size()) {
14369 update_base_hostname(input);
14370 } else {
14371 // We only create a temporary string if we need to.
14372 update_base_hostname(ada::unicode::percent_encode(
14373 input, character_sets::C0_CONTROL_PERCENT_ENCODE, idx));
14374 }
14375 ADA_ASSERT_TRUE(validate());
14376 return true;
14377 }
14378
to_diagram() const14379 [[nodiscard]] std::string url_aggregator::to_diagram() const {
14380 if (!is_valid) {
14381 return "invalid";
14382 }
14383 std::string answer;
14384 answer.append(buffer);
14385 answer.append(" [");
14386 answer.append(std::to_string(buffer.size()));
14387 answer.append(" bytes]");
14388 answer.append("\n");
14389 // first line
14390 std::string line1;
14391 line1.resize(buffer.size(), ' ');
14392 if (components.hash_start != url_components::omitted) {
14393 line1[components.hash_start] = '|';
14394 }
14395 if (components.search_start != url_components::omitted) {
14396 line1[components.search_start] = '|';
14397 }
14398 if (components.pathname_start != buffer.size()) {
14399 line1[components.pathname_start] = '|';
14400 }
14401 if (components.host_end != buffer.size()) {
14402 line1[components.host_end] = '|';
14403 }
14404 if (components.host_start != buffer.size()) {
14405 line1[components.host_start] = '|';
14406 }
14407 if (components.username_end != buffer.size()) {
14408 line1[components.username_end] = '|';
14409 }
14410 if (components.protocol_end != buffer.size()) {
14411 line1[components.protocol_end] = '|';
14412 }
14413 answer.append(line1);
14414 answer.append("\n");
14415
14416 std::string line2 = line1;
14417 if (components.hash_start != url_components::omitted) {
14418 line2[components.hash_start] = '`';
14419 line1[components.hash_start] = ' ';
14420
14421 for (size_t i = components.hash_start + 1; i < line2.size(); i++) {
14422 line2[i] = '-';
14423 }
14424 line2.append(" hash_start");
14425 answer.append(line2);
14426 answer.append("\n");
14427 }
14428
14429 std::string line3 = line1;
14430 if (components.search_start != url_components::omitted) {
14431 line3[components.search_start] = '`';
14432 line1[components.search_start] = ' ';
14433
14434 for (size_t i = components.search_start + 1; i < line3.size(); i++) {
14435 line3[i] = '-';
14436 }
14437 line3.append(" search_start ");
14438 line3.append(std::to_string(components.search_start));
14439 answer.append(line3);
14440 answer.append("\n");
14441 }
14442
14443 std::string line4 = line1;
14444 if (components.pathname_start != buffer.size()) {
14445 line4[components.pathname_start] = '`';
14446 line1[components.pathname_start] = ' ';
14447 for (size_t i = components.pathname_start + 1; i < line4.size(); i++) {
14448 line4[i] = '-';
14449 }
14450 line4.append(" pathname_start ");
14451 line4.append(std::to_string(components.pathname_start));
14452 answer.append(line4);
14453 answer.append("\n");
14454 }
14455
14456 std::string line5 = line1;
14457 if (components.host_end != buffer.size()) {
14458 line5[components.host_end] = '`';
14459 line1[components.host_end] = ' ';
14460
14461 for (size_t i = components.host_end + 1; i < line5.size(); i++) {
14462 line5[i] = '-';
14463 }
14464 line5.append(" host_end ");
14465 line5.append(std::to_string(components.host_end));
14466 answer.append(line5);
14467 answer.append("\n");
14468 }
14469
14470 std::string line6 = line1;
14471 if (components.host_start != buffer.size()) {
14472 line6[components.host_start] = '`';
14473 line1[components.host_start] = ' ';
14474
14475 for (size_t i = components.host_start + 1; i < line6.size(); i++) {
14476 line6[i] = '-';
14477 }
14478 line6.append(" host_start ");
14479 line6.append(std::to_string(components.host_start));
14480 answer.append(line6);
14481 answer.append("\n");
14482 }
14483
14484 std::string line7 = line1;
14485 if (components.username_end != buffer.size()) {
14486 line7[components.username_end] = '`';
14487 line1[components.username_end] = ' ';
14488
14489 for (size_t i = components.username_end + 1; i < line7.size(); i++) {
14490 line7[i] = '-';
14491 }
14492 line7.append(" username_end ");
14493 line7.append(std::to_string(components.username_end));
14494 answer.append(line7);
14495 answer.append("\n");
14496 }
14497
14498 std::string line8 = line1;
14499 if (components.protocol_end != buffer.size()) {
14500 line8[components.protocol_end] = '`';
14501 line1[components.protocol_end] = ' ';
14502
14503 for (size_t i = components.protocol_end + 1; i < line8.size(); i++) {
14504 line8[i] = '-';
14505 }
14506 line8.append(" protocol_end ");
14507 line8.append(std::to_string(components.protocol_end));
14508 answer.append(line8);
14509 answer.append("\n");
14510 }
14511
14512 if (components.hash_start == url_components::omitted) {
14513 answer.append("note: hash omitted\n");
14514 }
14515 if (components.search_start == url_components::omitted) {
14516 answer.append("note: search omitted\n");
14517 }
14518 if (components.protocol_end > buffer.size()) {
14519 answer.append("warning: protocol_end overflows\n");
14520 }
14521 if (components.username_end > buffer.size()) {
14522 answer.append("warning: username_end overflows\n");
14523 }
14524 if (components.host_start > buffer.size()) {
14525 answer.append("warning: host_start overflows\n");
14526 }
14527 if (components.host_end > buffer.size()) {
14528 answer.append("warning: host_end overflows\n");
14529 }
14530 if (components.pathname_start > buffer.size()) {
14531 answer.append("warning: pathname_start overflows\n");
14532 }
14533 return answer;
14534 }
14535
validate() const14536 [[nodiscard]] bool url_aggregator::validate() const noexcept {
14537 if (!is_valid) {
14538 return true;
14539 }
14540 if (!components.check_offset_consistency()) {
14541 ada_log("url_aggregator::validate inconsistent components \n",
14542 to_diagram());
14543 return false;
14544 }
14545 // We have a credible components struct, but let us investivate more
14546 // carefully:
14547 /**
14548 * https://user:pass@example.com:1234/foo/bar?baz#quux
14549 * | | | | ^^^^| | |
14550 * | | | | | | | `----- hash_start
14551 * | | | | | | `--------- search_start
14552 * | | | | | `----------------- pathname_start
14553 * | | | | `--------------------- port
14554 * | | | `----------------------- host_end
14555 * | | `---------------------------------- host_start
14556 * | `--------------------------------------- username_end
14557 * `--------------------------------------------- protocol_end
14558 */
14559 if (components.protocol_end == url_components::omitted) {
14560 ada_log("url_aggregator::validate omitted protocol_end \n", to_diagram());
14561 return false;
14562 }
14563 if (components.username_end == url_components::omitted) {
14564 ada_log("url_aggregator::validate omitted username_end \n", to_diagram());
14565 return false;
14566 }
14567 if (components.host_start == url_components::omitted) {
14568 ada_log("url_aggregator::validate omitted host_start \n", to_diagram());
14569 return false;
14570 }
14571 if (components.host_end == url_components::omitted) {
14572 ada_log("url_aggregator::validate omitted host_end \n", to_diagram());
14573 return false;
14574 }
14575 if (components.pathname_start == url_components::omitted) {
14576 ada_log("url_aggregator::validate omitted pathname_start \n", to_diagram());
14577 return false;
14578 }
14579
14580 if (components.protocol_end > buffer.size()) {
14581 ada_log("url_aggregator::validate protocol_end overflow \n", to_diagram());
14582 return false;
14583 }
14584 if (components.username_end > buffer.size()) {
14585 ada_log("url_aggregator::validate username_end overflow \n", to_diagram());
14586 return false;
14587 }
14588 if (components.host_start > buffer.size()) {
14589 ada_log("url_aggregator::validate host_start overflow \n", to_diagram());
14590 return false;
14591 }
14592 if (components.host_end > buffer.size()) {
14593 ada_log("url_aggregator::validate host_end overflow \n", to_diagram());
14594 return false;
14595 }
14596 if (components.pathname_start > buffer.size()) {
14597 ada_log("url_aggregator::validate pathname_start overflow \n",
14598 to_diagram());
14599 return false;
14600 }
14601
14602 if (components.protocol_end > 0) {
14603 if (buffer[components.protocol_end - 1] != ':') {
14604 ada_log(
14605 "url_aggregator::validate missing : at the end of the protocol \n",
14606 to_diagram());
14607 return false;
14608 }
14609 }
14610
14611 if (components.username_end != buffer.size() &&
14612 components.username_end > components.protocol_end + 2) {
14613 if (buffer[components.username_end] != ':' &&
14614 buffer[components.username_end] != '@') {
14615 ada_log(
14616 "url_aggregator::validate missing : or @ at the end of the username "
14617 "\n",
14618 to_diagram());
14619 return false;
14620 }
14621 }
14622
14623 if (components.host_start != buffer.size()) {
14624 if (components.host_start > components.username_end) {
14625 if (buffer[components.host_start] != '@') {
14626 ada_log(
14627 "url_aggregator::validate missing @ at the end of the password \n",
14628 to_diagram());
14629 return false;
14630 }
14631 } else if (components.host_start == components.username_end &&
14632 components.host_end > components.host_start) {
14633 if (components.host_start == components.protocol_end + 2) {
14634 if (buffer[components.protocol_end] != '/' ||
14635 buffer[components.protocol_end + 1] != '/') {
14636 ada_log(
14637 "url_aggregator::validate missing // between protocol and host "
14638 "\n",
14639 to_diagram());
14640 return false;
14641 }
14642 } else {
14643 if (components.host_start > components.protocol_end &&
14644 buffer[components.host_start] != '@') {
14645 ada_log(
14646 "url_aggregator::validate missing @ at the end of the username "
14647 "\n",
14648 to_diagram());
14649 return false;
14650 }
14651 }
14652 } else {
14653 if (components.host_end != components.host_start) {
14654 ada_log("url_aggregator::validate expected omitted host \n",
14655 to_diagram());
14656 return false;
14657 }
14658 }
14659 }
14660 if (components.host_end != buffer.size() &&
14661 components.pathname_start > components.host_end) {
14662 if (components.pathname_start == components.host_end + 2 &&
14663 buffer[components.host_end] == '/' &&
14664 buffer[components.host_end + 1] == '.') {
14665 if (components.pathname_start + 1 >= buffer.size() ||
14666 buffer[components.pathname_start] != '/' ||
14667 buffer[components.pathname_start + 1] != '/') {
14668 ada_log(
14669 "url_aggregator::validate expected the path to begin with // \n",
14670 to_diagram());
14671 return false;
14672 }
14673 } else if (buffer[components.host_end] != ':') {
14674 ada_log("url_aggregator::validate missing : at the port \n",
14675 to_diagram());
14676 return false;
14677 }
14678 }
14679 if (components.pathname_start != buffer.size() &&
14680 components.pathname_start < components.search_start &&
14681 components.pathname_start < components.hash_start && !has_opaque_path) {
14682 if (buffer[components.pathname_start] != '/') {
14683 ada_log("url_aggregator::validate missing / at the path \n",
14684 to_diagram());
14685 return false;
14686 }
14687 }
14688 if (components.search_start != url_components::omitted) {
14689 if (buffer[components.search_start] != '?') {
14690 ada_log("url_aggregator::validate missing ? at the search \n",
14691 to_diagram());
14692 return false;
14693 }
14694 }
14695 if (components.hash_start != url_components::omitted) {
14696 if (buffer[components.hash_start] != '#') {
14697 ada_log("url_aggregator::validate missing # at the hash \n",
14698 to_diagram());
14699 return false;
14700 }
14701 }
14702
14703 return true;
14704 }
14705
delete_dash_dot()14706 void url_aggregator::delete_dash_dot() {
14707 ada_log("url_aggregator::delete_dash_dot");
14708 ADA_ASSERT_TRUE(validate());
14709 ADA_ASSERT_TRUE(has_dash_dot());
14710 buffer.erase(components.host_end, 2);
14711 components.pathname_start -= 2;
14712 if (components.search_start != url_components::omitted) {
14713 components.search_start -= 2;
14714 }
14715 if (components.hash_start != url_components::omitted) {
14716 components.hash_start -= 2;
14717 }
14718 ADA_ASSERT_TRUE(validate());
14719 ADA_ASSERT_TRUE(!has_dash_dot());
14720 }
14721
consume_prepared_path(std::string_view input)14722 inline void url_aggregator::consume_prepared_path(std::string_view input) {
14723 ada_log("url_aggregator::consume_prepared_path ", input);
14724 /***
14725 * This is largely duplicated code from helpers::parse_prepared_path, which is
14726 * unfortunate. This particular function is nearly identical, except that it
14727 * is a method on url_aggregator. The idea is that the trivial path (which is
14728 * very common) merely appends to the buffer. This is the same trivial path as
14729 * with helpers::parse_prepared_path, except that we have the additional check
14730 * for is_at_path(). Otherwise, we grab a copy of the current path and we
14731 * modify it, and then insert it back into the buffer.
14732 */
14733 uint8_t accumulator = checkers::path_signature(input);
14734 // Let us first detect a trivial case.
14735 // If it is special, we check that we have no dot, no %, no \ and no
14736 // character needing percent encoding. Otherwise, we check that we have no %,
14737 // no dot, and no character needing percent encoding.
14738 constexpr uint8_t need_encoding = 1;
14739 constexpr uint8_t backslash_char = 2;
14740 constexpr uint8_t dot_char = 4;
14741 constexpr uint8_t percent_char = 8;
14742 bool special = type != ada::scheme::NOT_SPECIAL;
14743 bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
14744 checkers::is_windows_drive_letter(input));
14745 bool trivial_path =
14746 (special ? (accumulator == 0)
14747 : ((accumulator & (need_encoding | dot_char | percent_char)) ==
14748 0)) &&
14749 (!may_need_slow_file_handling);
14750 if (accumulator == dot_char && !may_need_slow_file_handling) {
14751 // '4' means that we have at least one dot, but nothing that requires
14752 // percent encoding or decoding. The only part that is not trivial is
14753 // that we may have single dots and double dots path segments.
14754 // If we have such segments, then we either have a path that begins
14755 // with '.' (easy to check), or we have the sequence './'.
14756 // Note: input cannot be empty, it must at least contain one character ('.')
14757 // Note: we know that '\' is not present.
14758 if (input[0] != '.') {
14759 size_t slashdot = input.find("/.");
14760 if (slashdot == std::string_view::npos) { // common case
14761 trivial_path = true;
14762 } else { // uncommon
14763 // only three cases matter: /./, /.. or a final /
14764 trivial_path =
14765 !(slashdot + 2 == input.size() || input[slashdot + 2] == '.' ||
14766 input[slashdot + 2] == '/');
14767 }
14768 }
14769 }
14770 if (trivial_path && is_at_path()) {
14771 ada_log("parse_path trivial");
14772 buffer += '/';
14773 buffer += input;
14774 return;
14775 }
14776 std::string path = std::string(get_pathname());
14777 // We are going to need to look a bit at the path, but let us see if we can
14778 // ignore percent encoding *and* backslashes *and* percent characters.
14779 // Except for the trivial case, this is likely to capture 99% of paths out
14780 // there.
14781 bool fast_path =
14782 (special &&
14783 (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
14784 (type != ada::scheme::type::FILE);
14785 if (fast_path) {
14786 ada_log("parse_prepared_path fast");
14787 // Here we don't need to worry about \ or percent encoding.
14788 // We also do not have a file protocol. We might have dots, however,
14789 // but dots must as appear as '.', and they cannot be encoded because
14790 // the symbol '%' is not present.
14791 size_t previous_location = 0; // We start at 0.
14792 do {
14793 size_t new_location = input.find('/', previous_location);
14794 // std::string_view path_view = input;
14795 // We process the last segment separately:
14796 if (new_location == std::string_view::npos) {
14797 std::string_view path_view = input.substr(previous_location);
14798 if (path_view == "..") { // The path ends with ..
14799 // e.g., if you receive ".." with an empty path, you go to "/".
14800 if (path.empty()) {
14801 path = '/';
14802 update_base_pathname(path);
14803 return;
14804 }
14805 // Fast case where we have nothing to do:
14806 if (path.back() == '/') {
14807 update_base_pathname(path);
14808 return;
14809 }
14810 // If you have the path "/joe/myfriend",
14811 // then you delete 'myfriend'.
14812 path.resize(path.rfind('/') + 1);
14813 update_base_pathname(path);
14814 return;
14815 }
14816 path += '/';
14817 if (path_view != ".") {
14818 path.append(path_view);
14819 }
14820 update_base_pathname(path);
14821 return;
14822 } else {
14823 // This is a non-final segment.
14824 std::string_view path_view =
14825 input.substr(previous_location, new_location - previous_location);
14826 previous_location = new_location + 1;
14827 if (path_view == "..") {
14828 size_t last_delimiter = path.rfind('/');
14829 if (last_delimiter != std::string::npos) {
14830 path.erase(last_delimiter);
14831 }
14832 } else if (path_view != ".") {
14833 path += '/';
14834 path.append(path_view);
14835 }
14836 }
14837 } while (true);
14838 } else {
14839 ada_log("parse_path slow");
14840 // we have reached the general case
14841 bool needs_percent_encoding = (accumulator & 1);
14842 std::string path_buffer_tmp;
14843 do {
14844 size_t location = (special && (accumulator & 2))
14845 ? input.find_first_of("/\\")
14846 : input.find('/');
14847 std::string_view path_view = input;
14848 if (location != std::string_view::npos) {
14849 path_view.remove_suffix(path_view.size() - location);
14850 input.remove_prefix(location + 1);
14851 }
14852 // path_buffer is either path_view or it might point at a percent encoded
14853 // temporary string.
14854 std::string_view path_buffer =
14855 (needs_percent_encoding &&
14856 ada::unicode::percent_encode<false>(
14857 path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
14858 ? path_buffer_tmp
14859 : path_view;
14860 if (unicode::is_double_dot_path_segment(path_buffer)) {
14861 if ((helpers::shorten_path(path, type) || special) &&
14862 location == std::string_view::npos) {
14863 path += '/';
14864 }
14865 } else if (unicode::is_single_dot_path_segment(path_buffer) &&
14866 (location == std::string_view::npos)) {
14867 path += '/';
14868 }
14869 // Otherwise, if path_buffer is not a single-dot path segment, then:
14870 else if (!unicode::is_single_dot_path_segment(path_buffer)) {
14871 // If url's scheme is "file", url's path is empty, and path_buffer is a
14872 // Windows drive letter, then replace the second code point in
14873 // path_buffer with U+003A (:).
14874 if (type == ada::scheme::type::FILE && path.empty() &&
14875 checkers::is_windows_drive_letter(path_buffer)) {
14876 path += '/';
14877 path += path_buffer[0];
14878 path += ':';
14879 path_buffer.remove_prefix(2);
14880 path.append(path_buffer);
14881 } else {
14882 // Append path_buffer to url's path.
14883 path += '/';
14884 path.append(path_buffer);
14885 }
14886 }
14887 if (location == std::string_view::npos) {
14888 update_base_pathname(path);
14889 return;
14890 }
14891 } while (true);
14892 }
14893 }
14894 } // namespace ada
14895 /* end file src/url_aggregator.cpp */
14896 /* begin file src/ada_c.cpp */
14897
get_instance(void * result)14898 ada::result<ada::url_aggregator>& get_instance(void* result) noexcept {
14899 return *(ada::result<ada::url_aggregator>*)result;
14900 }
14901
14902 extern "C" {
14903 typedef void* ada_url;
14904 typedef void* ada_url_search_params;
14905 typedef void* ada_strings;
14906 typedef void* ada_url_search_params_keys_iter;
14907 typedef void* ada_url_search_params_values_iter;
14908 typedef void* ada_url_search_params_entries_iter;
14909
14910 struct ada_string {
14911 const char* data;
14912 size_t length;
14913 };
14914
14915 struct ada_owned_string {
14916 const char* data;
14917 size_t length;
14918 };
14919
14920 struct ada_string_pair {
14921 ada_string key;
14922 ada_string value;
14923 };
14924
ada_string_create(const char * data,size_t length)14925 ada_string ada_string_create(const char* data, size_t length) {
14926 ada_string out{};
14927 out.data = data;
14928 out.length = length;
14929 return out;
14930 }
14931
14932 struct ada_url_components {
14933 /*
14934 * By using 32-bit integers, we implicitly assume that the URL string
14935 * cannot exceed 4 GB.
14936 *
14937 * https://user:pass@example.com:1234/foo/bar?baz#quux
14938 * | | | | ^^^^| | |
14939 * | | | | | | | `----- hash_start
14940 * | | | | | | `--------- search_start
14941 * | | | | | `----------------- pathname_start
14942 * | | | | `--------------------- port
14943 * | | | `----------------------- host_end
14944 * | | `---------------------------------- host_start
14945 * | `--------------------------------------- username_end
14946 * `--------------------------------------------- protocol_end
14947 */
14948 uint32_t protocol_end;
14949 /**
14950 * Username end is not `omitted` by default (-1) to make username and password
14951 * getters less costly to implement.
14952 */
14953 uint32_t username_end;
14954 uint32_t host_start;
14955 uint32_t host_end;
14956 uint32_t port;
14957 uint32_t pathname_start;
14958 uint32_t search_start;
14959 uint32_t hash_start;
14960 };
14961
ada_parse(const char * input,size_t length)14962 ada_url ada_parse(const char* input, size_t length) noexcept {
14963 return new ada::result<ada::url_aggregator>(
14964 ada::parse<ada::url_aggregator>(std::string_view(input, length)));
14965 }
14966
ada_parse_with_base(const char * input,size_t input_length,const char * base,size_t base_length)14967 ada_url ada_parse_with_base(const char* input, size_t input_length,
14968 const char* base, size_t base_length) noexcept {
14969 auto base_out =
14970 ada::parse<ada::url_aggregator>(std::string_view(base, base_length));
14971
14972 if (!base_out) {
14973 return new ada::result<ada::url_aggregator>(base_out);
14974 }
14975
14976 return new ada::result<ada::url_aggregator>(ada::parse<ada::url_aggregator>(
14977 std::string_view(input, input_length), &base_out.value()));
14978 }
14979
ada_can_parse(const char * input,size_t length)14980 bool ada_can_parse(const char* input, size_t length) noexcept {
14981 return ada::can_parse(std::string_view(input, length));
14982 }
14983
ada_can_parse_with_base(const char * input,size_t input_length,const char * base,size_t base_length)14984 bool ada_can_parse_with_base(const char* input, size_t input_length,
14985 const char* base, size_t base_length) noexcept {
14986 auto base_view = std::string_view(base, base_length);
14987 return ada::can_parse(std::string_view(input, input_length), &base_view);
14988 }
14989
ada_free(ada_url result)14990 void ada_free(ada_url result) noexcept {
14991 ada::result<ada::url_aggregator>* r =
14992 (ada::result<ada::url_aggregator>*)result;
14993 delete r;
14994 }
14995
ada_copy(ada_url input)14996 ada_url ada_copy(ada_url input) noexcept {
14997 ada::result<ada::url_aggregator>& r = get_instance(input);
14998 return new ada::result<ada::url_aggregator>(r);
14999 }
15000
ada_is_valid(ada_url result)15001 bool ada_is_valid(ada_url result) noexcept {
15002 ada::result<ada::url_aggregator>& r = get_instance(result);
15003 return r.has_value();
15004 }
15005
15006 // caller must free the result with ada_free_owned_string
ada_get_origin(ada_url result)15007 ada_owned_string ada_get_origin(ada_url result) noexcept {
15008 ada::result<ada::url_aggregator>& r = get_instance(result);
15009 ada_owned_string owned;
15010 if (!r) {
15011 owned.data = nullptr;
15012 owned.length = 0;
15013 return owned;
15014 }
15015 std::string out = r->get_origin();
15016 owned.length = out.size();
15017 owned.data = new char[owned.length];
15018 memcpy((void*)owned.data, out.data(), owned.length);
15019 return owned;
15020 }
15021
ada_free_owned_string(ada_owned_string owned)15022 void ada_free_owned_string(ada_owned_string owned) noexcept {
15023 delete[] owned.data;
15024 owned.data = nullptr;
15025 owned.length = 0;
15026 }
15027
ada_get_href(ada_url result)15028 ada_string ada_get_href(ada_url result) noexcept {
15029 ada::result<ada::url_aggregator>& r = get_instance(result);
15030 if (!r) {
15031 return ada_string_create(NULL, 0);
15032 }
15033 std::string_view out = r->get_href();
15034 return ada_string_create(out.data(), out.length());
15035 }
15036
ada_get_username(ada_url result)15037 ada_string ada_get_username(ada_url result) noexcept {
15038 ada::result<ada::url_aggregator>& r = get_instance(result);
15039 if (!r) {
15040 return ada_string_create(NULL, 0);
15041 }
15042 std::string_view out = r->get_username();
15043 return ada_string_create(out.data(), out.length());
15044 }
15045
ada_get_password(ada_url result)15046 ada_string ada_get_password(ada_url result) noexcept {
15047 ada::result<ada::url_aggregator>& r = get_instance(result);
15048 if (!r) {
15049 return ada_string_create(NULL, 0);
15050 }
15051 std::string_view out = r->get_password();
15052 return ada_string_create(out.data(), out.length());
15053 }
15054
ada_get_port(ada_url result)15055 ada_string ada_get_port(ada_url result) noexcept {
15056 ada::result<ada::url_aggregator>& r = get_instance(result);
15057 if (!r) {
15058 return ada_string_create(NULL, 0);
15059 }
15060 std::string_view out = r->get_port();
15061 return ada_string_create(out.data(), out.length());
15062 }
15063
ada_get_hash(ada_url result)15064 ada_string ada_get_hash(ada_url result) noexcept {
15065 ada::result<ada::url_aggregator>& r = get_instance(result);
15066 if (!r) {
15067 return ada_string_create(NULL, 0);
15068 }
15069 std::string_view out = r->get_hash();
15070 return ada_string_create(out.data(), out.length());
15071 }
15072
ada_get_host(ada_url result)15073 ada_string ada_get_host(ada_url result) noexcept {
15074 ada::result<ada::url_aggregator>& r = get_instance(result);
15075 if (!r) {
15076 return ada_string_create(NULL, 0);
15077 }
15078 std::string_view out = r->get_host();
15079 return ada_string_create(out.data(), out.length());
15080 }
15081
ada_get_hostname(ada_url result)15082 ada_string ada_get_hostname(ada_url result) noexcept {
15083 ada::result<ada::url_aggregator>& r = get_instance(result);
15084 if (!r) {
15085 return ada_string_create(NULL, 0);
15086 }
15087 std::string_view out = r->get_hostname();
15088 return ada_string_create(out.data(), out.length());
15089 }
15090
ada_get_pathname(ada_url result)15091 ada_string ada_get_pathname(ada_url result) noexcept {
15092 ada::result<ada::url_aggregator>& r = get_instance(result);
15093 if (!r) {
15094 return ada_string_create(NULL, 0);
15095 }
15096 std::string_view out = r->get_pathname();
15097 return ada_string_create(out.data(), out.length());
15098 }
15099
ada_get_search(ada_url result)15100 ada_string ada_get_search(ada_url result) noexcept {
15101 ada::result<ada::url_aggregator>& r = get_instance(result);
15102 if (!r) {
15103 return ada_string_create(NULL, 0);
15104 }
15105 std::string_view out = r->get_search();
15106 return ada_string_create(out.data(), out.length());
15107 }
15108
ada_get_protocol(ada_url result)15109 ada_string ada_get_protocol(ada_url result) noexcept {
15110 ada::result<ada::url_aggregator>& r = get_instance(result);
15111 if (!r) {
15112 return ada_string_create(NULL, 0);
15113 }
15114 std::string_view out = r->get_protocol();
15115 return ada_string_create(out.data(), out.length());
15116 }
15117
ada_get_host_type(ada_url result)15118 uint8_t ada_get_host_type(ada_url result) noexcept {
15119 ada::result<ada::url_aggregator>& r = get_instance(result);
15120 if (!r) {
15121 return 0;
15122 }
15123 return r->host_type;
15124 }
15125
ada_get_scheme_type(ada_url result)15126 uint8_t ada_get_scheme_type(ada_url result) noexcept {
15127 ada::result<ada::url_aggregator>& r = get_instance(result);
15128 if (!r) {
15129 return 0;
15130 }
15131 return r->type;
15132 }
15133
ada_set_href(ada_url result,const char * input,size_t length)15134 bool ada_set_href(ada_url result, const char* input, size_t length) noexcept {
15135 ada::result<ada::url_aggregator>& r = get_instance(result);
15136 if (!r) {
15137 return false;
15138 }
15139 return r->set_href(std::string_view(input, length));
15140 }
15141
ada_set_host(ada_url result,const char * input,size_t length)15142 bool ada_set_host(ada_url result, const char* input, size_t length) noexcept {
15143 ada::result<ada::url_aggregator>& r = get_instance(result);
15144 if (!r) {
15145 return false;
15146 }
15147 return r->set_host(std::string_view(input, length));
15148 }
15149
ada_set_hostname(ada_url result,const char * input,size_t length)15150 bool ada_set_hostname(ada_url result, const char* input,
15151 size_t length) noexcept {
15152 ada::result<ada::url_aggregator>& r = get_instance(result);
15153 if (!r) {
15154 return false;
15155 }
15156 return r->set_hostname(std::string_view(input, length));
15157 }
15158
ada_set_protocol(ada_url result,const char * input,size_t length)15159 bool ada_set_protocol(ada_url result, const char* input,
15160 size_t length) noexcept {
15161 ada::result<ada::url_aggregator>& r = get_instance(result);
15162 if (!r) {
15163 return false;
15164 }
15165 return r->set_protocol(std::string_view(input, length));
15166 }
15167
ada_set_username(ada_url result,const char * input,size_t length)15168 bool ada_set_username(ada_url result, const char* input,
15169 size_t length) noexcept {
15170 ada::result<ada::url_aggregator>& r = get_instance(result);
15171 if (!r) {
15172 return false;
15173 }
15174 return r->set_username(std::string_view(input, length));
15175 }
15176
ada_set_password(ada_url result,const char * input,size_t length)15177 bool ada_set_password(ada_url result, const char* input,
15178 size_t length) noexcept {
15179 ada::result<ada::url_aggregator>& r = get_instance(result);
15180 if (!r) {
15181 return false;
15182 }
15183 return r->set_password(std::string_view(input, length));
15184 }
15185
ada_set_port(ada_url result,const char * input,size_t length)15186 bool ada_set_port(ada_url result, const char* input, size_t length) noexcept {
15187 ada::result<ada::url_aggregator>& r = get_instance(result);
15188 if (!r) {
15189 return false;
15190 }
15191 return r->set_port(std::string_view(input, length));
15192 }
15193
ada_set_pathname(ada_url result,const char * input,size_t length)15194 bool ada_set_pathname(ada_url result, const char* input,
15195 size_t length) noexcept {
15196 ada::result<ada::url_aggregator>& r = get_instance(result);
15197 if (!r) {
15198 return false;
15199 }
15200 return r->set_pathname(std::string_view(input, length));
15201 }
15202
15203 /**
15204 * Update the search/query of the URL.
15205 *
15206 * If a URL has `?` as the search value, passing empty string to this function
15207 * does not remove the attribute. If you need to remove it, please use
15208 * `ada_clear_search` method.
15209 */
ada_set_search(ada_url result,const char * input,size_t length)15210 void ada_set_search(ada_url result, const char* input, size_t length) noexcept {
15211 ada::result<ada::url_aggregator>& r = get_instance(result);
15212 if (r) {
15213 r->set_search(std::string_view(input, length));
15214 }
15215 }
15216
15217 /**
15218 * Update the hash/fragment of the URL.
15219 *
15220 * If a URL has `#` as the hash value, passing empty string to this function
15221 * does not remove the attribute. If you need to remove it, please use
15222 * `ada_clear_hash` method.
15223 */
ada_set_hash(ada_url result,const char * input,size_t length)15224 void ada_set_hash(ada_url result, const char* input, size_t length) noexcept {
15225 ada::result<ada::url_aggregator>& r = get_instance(result);
15226 if (r) {
15227 r->set_hash(std::string_view(input, length));
15228 }
15229 }
15230
ada_clear_port(ada_url result)15231 void ada_clear_port(ada_url result) noexcept {
15232 ada::result<ada::url_aggregator>& r = get_instance(result);
15233 if (r) {
15234 r->clear_port();
15235 }
15236 }
15237
15238 /**
15239 * Removes the hash of the URL.
15240 *
15241 * Despite `ada_set_hash` method, this function allows the complete
15242 * removal of the hash attribute, even if it has a value of `#`.
15243 */
ada_clear_hash(ada_url result)15244 void ada_clear_hash(ada_url result) noexcept {
15245 ada::result<ada::url_aggregator>& r = get_instance(result);
15246 if (r) {
15247 r->clear_hash();
15248 }
15249 }
15250
15251 /**
15252 * Removes the search of the URL.
15253 *
15254 * Despite `ada_set_search` method, this function allows the complete
15255 * removal of the search attribute, even if it has a value of `?`.
15256 */
ada_clear_search(ada_url result)15257 void ada_clear_search(ada_url result) noexcept {
15258 ada::result<ada::url_aggregator>& r = get_instance(result);
15259 if (r) {
15260 r->clear_search();
15261 }
15262 }
15263
ada_has_credentials(ada_url result)15264 bool ada_has_credentials(ada_url result) noexcept {
15265 ada::result<ada::url_aggregator>& r = get_instance(result);
15266 if (!r) {
15267 return false;
15268 }
15269 return r->has_credentials();
15270 }
15271
ada_has_empty_hostname(ada_url result)15272 bool ada_has_empty_hostname(ada_url result) noexcept {
15273 ada::result<ada::url_aggregator>& r = get_instance(result);
15274 if (!r) {
15275 return false;
15276 }
15277 return r->has_empty_hostname();
15278 }
15279
ada_has_hostname(ada_url result)15280 bool ada_has_hostname(ada_url result) noexcept {
15281 ada::result<ada::url_aggregator>& r = get_instance(result);
15282 if (!r) {
15283 return false;
15284 }
15285 return r->has_hostname();
15286 }
15287
ada_has_non_empty_username(ada_url result)15288 bool ada_has_non_empty_username(ada_url result) noexcept {
15289 ada::result<ada::url_aggregator>& r = get_instance(result);
15290 if (!r) {
15291 return false;
15292 }
15293 return r->has_non_empty_username();
15294 }
15295
ada_has_non_empty_password(ada_url result)15296 bool ada_has_non_empty_password(ada_url result) noexcept {
15297 ada::result<ada::url_aggregator>& r = get_instance(result);
15298 if (!r) {
15299 return false;
15300 }
15301 return r->has_non_empty_password();
15302 }
15303
ada_has_port(ada_url result)15304 bool ada_has_port(ada_url result) noexcept {
15305 ada::result<ada::url_aggregator>& r = get_instance(result);
15306 if (!r) {
15307 return false;
15308 }
15309 return r->has_port();
15310 }
15311
ada_has_password(ada_url result)15312 bool ada_has_password(ada_url result) noexcept {
15313 ada::result<ada::url_aggregator>& r = get_instance(result);
15314 if (!r) {
15315 return false;
15316 }
15317 return r->has_password();
15318 }
15319
ada_has_hash(ada_url result)15320 bool ada_has_hash(ada_url result) noexcept {
15321 ada::result<ada::url_aggregator>& r = get_instance(result);
15322 if (!r) {
15323 return false;
15324 }
15325 return r->has_hash();
15326 }
15327
ada_has_search(ada_url result)15328 bool ada_has_search(ada_url result) noexcept {
15329 ada::result<ada::url_aggregator>& r = get_instance(result);
15330 if (!r) {
15331 return false;
15332 }
15333 return r->has_search();
15334 }
15335
15336 // returns a pointer to the internal url_aggregator::url_components
ada_get_components(ada_url result)15337 const ada_url_components* ada_get_components(ada_url result) noexcept {
15338 static_assert(sizeof(ada_url_components) == sizeof(ada::url_components));
15339 ada::result<ada::url_aggregator>& r = get_instance(result);
15340 if (!r) {
15341 return nullptr;
15342 }
15343 return reinterpret_cast<const ada_url_components*>(&r->get_components());
15344 }
15345
ada_idna_to_unicode(const char * input,size_t length)15346 ada_owned_string ada_idna_to_unicode(const char* input, size_t length) {
15347 std::string out = ada::idna::to_unicode(std::string_view(input, length));
15348 ada_owned_string owned{};
15349 owned.length = out.length();
15350 owned.data = new char[owned.length];
15351 memcpy((void*)owned.data, out.data(), owned.length);
15352 return owned;
15353 }
15354
ada_idna_to_ascii(const char * input,size_t length)15355 ada_owned_string ada_idna_to_ascii(const char* input, size_t length) {
15356 std::string out = ada::idna::to_ascii(std::string_view(input, length));
15357 ada_owned_string owned{};
15358 owned.length = out.size();
15359 owned.data = new char[owned.length];
15360 memcpy((void*)owned.data, out.data(), owned.length);
15361 return owned;
15362 }
15363
ada_parse_search_params(const char * input,size_t length)15364 ada_url_search_params ada_parse_search_params(const char* input,
15365 size_t length) {
15366 return new ada::result<ada::url_search_params>(
15367 ada::url_search_params(std::string_view(input, length)));
15368 }
15369
ada_free_search_params(ada_url_search_params result)15370 void ada_free_search_params(ada_url_search_params result) {
15371 ada::result<ada::url_search_params>* r =
15372 (ada::result<ada::url_search_params>*)result;
15373 delete r;
15374 }
15375
ada_search_params_to_string(ada_url_search_params result)15376 ada_owned_string ada_search_params_to_string(ada_url_search_params result) {
15377 ada::result<ada::url_search_params>& r =
15378 *(ada::result<ada::url_search_params>*)result;
15379 if (!r) return ada_owned_string{NULL, 0};
15380 std::string out = r->to_string();
15381 ada_owned_string owned{};
15382 owned.length = out.size();
15383 owned.data = new char[owned.length];
15384 memcpy((void*)owned.data, out.data(), owned.length);
15385 return owned;
15386 }
15387
ada_search_params_size(ada_url_search_params result)15388 size_t ada_search_params_size(ada_url_search_params result) {
15389 ada::result<ada::url_search_params>& r =
15390 *(ada::result<ada::url_search_params>*)result;
15391 if (!r) return 0;
15392 return r->size();
15393 }
15394
ada_search_params_sort(ada_url_search_params result)15395 void ada_search_params_sort(ada_url_search_params result) {
15396 ada::result<ada::url_search_params>& r =
15397 *(ada::result<ada::url_search_params>*)result;
15398 if (r) r->sort();
15399 }
15400
ada_search_params_append(ada_url_search_params result,const char * key,size_t key_length,const char * value,size_t value_length)15401 void ada_search_params_append(ada_url_search_params result, const char* key,
15402 size_t key_length, const char* value,
15403 size_t value_length) {
15404 ada::result<ada::url_search_params>& r =
15405 *(ada::result<ada::url_search_params>*)result;
15406 if (r) {
15407 r->append(std::string_view(key, key_length),
15408 std::string_view(value, value_length));
15409 }
15410 }
15411
ada_search_params_set(ada_url_search_params result,const char * key,size_t key_length,const char * value,size_t value_length)15412 void ada_search_params_set(ada_url_search_params result, const char* key,
15413 size_t key_length, const char* value,
15414 size_t value_length) {
15415 ada::result<ada::url_search_params>& r =
15416 *(ada::result<ada::url_search_params>*)result;
15417 if (r) {
15418 r->set(std::string_view(key, key_length),
15419 std::string_view(value, value_length));
15420 }
15421 }
15422
ada_search_params_remove(ada_url_search_params result,const char * key,size_t key_length)15423 void ada_search_params_remove(ada_url_search_params result, const char* key,
15424 size_t key_length) {
15425 ada::result<ada::url_search_params>& r =
15426 *(ada::result<ada::url_search_params>*)result;
15427 if (r) {
15428 r->remove(std::string_view(key, key_length));
15429 }
15430 }
15431
ada_search_params_remove_value(ada_url_search_params result,const char * key,size_t key_length,const char * value,size_t value_length)15432 void ada_search_params_remove_value(ada_url_search_params result,
15433 const char* key, size_t key_length,
15434 const char* value, size_t value_length) {
15435 ada::result<ada::url_search_params>& r =
15436 *(ada::result<ada::url_search_params>*)result;
15437 if (r) {
15438 r->remove(std::string_view(key, key_length),
15439 std::string_view(value, value_length));
15440 }
15441 }
15442
ada_search_params_has(ada_url_search_params result,const char * key,size_t key_length)15443 bool ada_search_params_has(ada_url_search_params result, const char* key,
15444 size_t key_length) {
15445 ada::result<ada::url_search_params>& r =
15446 *(ada::result<ada::url_search_params>*)result;
15447 if (!r) return false;
15448 return r->has(std::string_view(key, key_length));
15449 }
15450
ada_search_params_has_value(ada_url_search_params result,const char * key,size_t key_length,const char * value,size_t value_length)15451 bool ada_search_params_has_value(ada_url_search_params result, const char* key,
15452 size_t key_length, const char* value,
15453 size_t value_length) {
15454 ada::result<ada::url_search_params>& r =
15455 *(ada::result<ada::url_search_params>*)result;
15456 if (!r) return false;
15457 return r->has(std::string_view(key, key_length),
15458 std::string_view(value, value_length));
15459 }
15460
ada_search_params_get(ada_url_search_params result,const char * key,size_t key_length)15461 ada_string ada_search_params_get(ada_url_search_params result, const char* key,
15462 size_t key_length) {
15463 ada::result<ada::url_search_params>& r =
15464 *(ada::result<ada::url_search_params>*)result;
15465 if (!r) return ada_string_create(NULL, 0);
15466 auto found = r->get(std::string_view(key, key_length));
15467 if (!found.has_value()) return ada_string_create(NULL, 0);
15468 return ada_string_create(found->data(), found->length());
15469 }
15470
ada_search_params_get_all(ada_url_search_params result,const char * key,size_t key_length)15471 ada_strings ada_search_params_get_all(ada_url_search_params result,
15472 const char* key, size_t key_length) {
15473 ada::result<ada::url_search_params>& r =
15474 *(ada::result<ada::url_search_params>*)result;
15475 if (!r) {
15476 return new ada::result<std::vector<std::string>>(
15477 std::vector<std::string>());
15478 }
15479 return new ada::result<std::vector<std::string>>(
15480 r->get_all(std::string_view(key, key_length)));
15481 }
15482
ada_search_params_get_keys(ada_url_search_params result)15483 ada_url_search_params_keys_iter ada_search_params_get_keys(
15484 ada_url_search_params result) {
15485 ada::result<ada::url_search_params>& r =
15486 *(ada::result<ada::url_search_params>*)result;
15487 if (!r) {
15488 return new ada::result<ada::url_search_params_keys_iter>(
15489 ada::url_search_params_keys_iter());
15490 }
15491 return new ada::result<ada::url_search_params_keys_iter>(r->get_keys());
15492 }
15493
ada_search_params_get_values(ada_url_search_params result)15494 ada_url_search_params_values_iter ada_search_params_get_values(
15495 ada_url_search_params result) {
15496 ada::result<ada::url_search_params>& r =
15497 *(ada::result<ada::url_search_params>*)result;
15498 if (!r) {
15499 return new ada::result<ada::url_search_params_values_iter>(
15500 ada::url_search_params_values_iter());
15501 }
15502 return new ada::result<ada::url_search_params_values_iter>(r->get_values());
15503 }
15504
ada_search_params_get_entries(ada_url_search_params result)15505 ada_url_search_params_entries_iter ada_search_params_get_entries(
15506 ada_url_search_params result) {
15507 ada::result<ada::url_search_params>& r =
15508 *(ada::result<ada::url_search_params>*)result;
15509 if (!r) {
15510 return new ada::result<ada::url_search_params_entries_iter>(
15511 ada::url_search_params_entries_iter());
15512 }
15513 return new ada::result<ada::url_search_params_entries_iter>(r->get_entries());
15514 }
15515
ada_free_strings(ada_strings result)15516 void ada_free_strings(ada_strings result) {
15517 ada::result<std::vector<std::string>>* r =
15518 (ada::result<std::vector<std::string>>*)result;
15519 delete r;
15520 }
15521
ada_strings_size(ada_strings result)15522 size_t ada_strings_size(ada_strings result) {
15523 ada::result<std::vector<std::string>>* r =
15524 (ada::result<std::vector<std::string>>*)result;
15525 if (!r) return 0;
15526 return (*r)->size();
15527 }
15528
ada_strings_get(ada_strings result,size_t index)15529 ada_string ada_strings_get(ada_strings result, size_t index) {
15530 ada::result<std::vector<std::string>>* r =
15531 (ada::result<std::vector<std::string>>*)result;
15532 if (!r) return ada_string_create(NULL, 0);
15533 std::string_view view = (*r)->at(index);
15534 return ada_string_create(view.data(), view.length());
15535 }
15536
ada_free_search_params_keys_iter(ada_url_search_params_keys_iter result)15537 void ada_free_search_params_keys_iter(ada_url_search_params_keys_iter result) {
15538 ada::result<ada::url_search_params_keys_iter>* r =
15539 (ada::result<ada::url_search_params_keys_iter>*)result;
15540 delete r;
15541 }
15542
ada_search_params_keys_iter_next(ada_url_search_params_keys_iter result)15543 ada_string ada_search_params_keys_iter_next(
15544 ada_url_search_params_keys_iter result) {
15545 ada::result<ada::url_search_params_keys_iter>* r =
15546 (ada::result<ada::url_search_params_keys_iter>*)result;
15547 if (!r) return ada_string_create(NULL, 0);
15548 auto next = (*r)->next();
15549 if (!next.has_value()) return ada_string_create(NULL, 0);
15550 return ada_string_create(next->data(), next->length());
15551 }
15552
ada_search_params_keys_iter_has_next(ada_url_search_params_keys_iter result)15553 bool ada_search_params_keys_iter_has_next(
15554 ada_url_search_params_keys_iter result) {
15555 ada::result<ada::url_search_params_keys_iter>* r =
15556 (ada::result<ada::url_search_params_keys_iter>*)result;
15557 if (!r) return false;
15558 return (*r)->has_next();
15559 }
15560
ada_free_search_params_values_iter(ada_url_search_params_values_iter result)15561 void ada_free_search_params_values_iter(
15562 ada_url_search_params_values_iter result) {
15563 ada::result<ada::url_search_params_values_iter>* r =
15564 (ada::result<ada::url_search_params_values_iter>*)result;
15565 delete r;
15566 }
15567
ada_search_params_values_iter_next(ada_url_search_params_values_iter result)15568 ada_string ada_search_params_values_iter_next(
15569 ada_url_search_params_values_iter result) {
15570 ada::result<ada::url_search_params_values_iter>* r =
15571 (ada::result<ada::url_search_params_values_iter>*)result;
15572 if (!r) return ada_string_create(NULL, 0);
15573 auto next = (*r)->next();
15574 if (!next.has_value()) return ada_string_create(NULL, 0);
15575 return ada_string_create(next->data(), next->length());
15576 }
15577
ada_search_params_values_iter_has_next(ada_url_search_params_values_iter result)15578 bool ada_search_params_values_iter_has_next(
15579 ada_url_search_params_values_iter result) {
15580 ada::result<ada::url_search_params_values_iter>* r =
15581 (ada::result<ada::url_search_params_values_iter>*)result;
15582 if (!r) return false;
15583 return (*r)->has_next();
15584 }
15585
ada_free_search_params_entries_iter(ada_url_search_params_entries_iter result)15586 void ada_free_search_params_entries_iter(
15587 ada_url_search_params_entries_iter result) {
15588 ada::result<ada::url_search_params_entries_iter>* r =
15589 (ada::result<ada::url_search_params_entries_iter>*)result;
15590 delete r;
15591 }
15592
ada_search_params_entries_iter_next(ada_url_search_params_entries_iter result)15593 ada_string_pair ada_search_params_entries_iter_next(
15594 ada_url_search_params_entries_iter result) {
15595 ada::result<ada::url_search_params_entries_iter>* r =
15596 (ada::result<ada::url_search_params_entries_iter>*)result;
15597 if (!r) return {ada_string_create(NULL, 0), ada_string_create(NULL, 0)};
15598 auto next = (*r)->next();
15599 if (!next.has_value())
15600 return {ada_string_create(NULL, 0), ada_string_create(NULL, 0)};
15601 return ada_string_pair{
15602 ada_string_create(next->first.data(), next->first.length()),
15603 ada_string_create(next->second.data(), next->second.length())};
15604 }
15605
ada_search_params_entries_iter_has_next(ada_url_search_params_entries_iter result)15606 bool ada_search_params_entries_iter_has_next(
15607 ada_url_search_params_entries_iter result) {
15608 ada::result<ada::url_search_params_entries_iter>* r =
15609 (ada::result<ada::url_search_params_entries_iter>*)result;
15610 if (!r) return false;
15611 return (*r)->has_next();
15612 }
15613
15614 } // extern "C"
15615 /* end file src/ada_c.cpp */
15616 /* end file src/ada.cpp */
15617