Ada 2.9.2
Fast spec-compliant URL parser
Loading...
Searching...
No Matches
ada.cpp
Go to the documentation of this file.
1/* auto-generated on 2024-10-06 13:37:32.540028. Do not edit! */
2/* begin file src/ada.cpp */
3#include "ada.h"
4/* begin file src/checkers.cpp */
5
6#include <algorithm>
7
8namespace ada::checkers {
9
10ada_really_inline ada_constexpr bool is_ipv4(std::string_view view) noexcept {
11 // The string is not empty and does not contain upper case ASCII characters.
12 //
13 // Optimization. To be considered as a possible ipv4, the string must end
14 // with 'x' or a lowercase hex character.
15 // Most of the time, this will be false so this simple check will save a lot
16 // of effort.
17 char last_char = view.back();
18 // If the address ends with a dot, we need to prune it (special case).
19 if (last_char == '.') {
20 view.remove_suffix(1);
21 if (view.empty()) {
22 return false;
23 }
24 last_char = view.back();
25 }
26 bool possible_ipv4 = (last_char >= '0' && last_char <= '9') ||
27 (last_char >= 'a' && last_char <= 'f') ||
28 last_char == 'x';
29 if (!possible_ipv4) {
30 return false;
31 }
32 // From the last character, find the last dot.
33 size_t last_dot = view.rfind('.');
34 if (last_dot != std::string_view::npos) {
35 // We have at least one dot.
36 view = view.substr(last_dot + 1);
37 }
41 if (std::all_of(view.begin(), view.end(), ada::checkers::is_digit)) {
42 return true;
43 }
44 // It could be hex (0x), but not if there is a single character.
45 if (view.size() == 1) {
46 return false;
47 }
48 // It must start with 0x.
49 if (!std::equal(view.begin(), view.begin() + 2, "0x")) {
50 return false;
51 }
52 // We must allow "0x".
53 if (view.size() == 2) {
54 return true;
55 }
56 // We have 0x followed by some characters, we need to check that they are
57 // hexadecimals.
58 return std::all_of(view.begin() + 2, view.end(),
59 ada::unicode::is_lowercase_hex);
60}
61
62// for use with path_signature, we include all characters that need percent
63// encoding.
64static constexpr std::array<uint8_t, 256> path_signature_table =
65 []() constexpr {
66 std::array<uint8_t, 256> result{};
67 for (size_t i = 0; i < 256; i++) {
68 if (i <= 0x20 || i == 0x22 || i == 0x23 || i == 0x3c || i == 0x3e ||
69 i == 0x3f || i == 0x60 || i == 0x7b || i == 0x7d || 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
84ada_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
109ada_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
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
144namespace ada::idna {
145
146size_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
243size_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
256size_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
265size_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
335namespace ada::idna {
336
337const 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};
719const 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
2729namespace 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.
2733uint32_t find_range_index(uint32_t key) {
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.
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
2755bool 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
2779void 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.
2805std::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
2868namespace ada::idna {
2869
2870const 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
3102const 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}};
4746const 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
5760const 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};
5991const 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
6867const 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};
7066const 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}};
7572const 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
7750namespace ada::idna {
7751
7752// See
7753// https://github.com/uni-algo/uni-algo/blob/c612968c5ed3ace39bde4c894c24286c5f2c7fe2/include/uni_algo/impl/impl_norm.h#L467
7754constexpr char32_t hangul_sbase = 0xAC00;
7755constexpr char32_t hangul_tbase = 0x11A7;
7756constexpr char32_t hangul_vbase = 0x1161;
7757constexpr char32_t hangul_lbase = 0x1100;
7758constexpr char32_t hangul_lcount = 19;
7759constexpr char32_t hangul_vcount = 21;
7760constexpr char32_t hangul_tcount = 28;
7762constexpr char32_t hangul_scount =
7764
7765std::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
7795void 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] =
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
7837uint8_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
7843void 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
7859void decompose_nfc(std::u32string& input) {
7864 auto [decomposition_needed, additional_elements] =
7866 if (decomposition_needed) {
7867 decompose(input, additional_elements);
7868 }
7869 sort_marks(input);
7870}
7871
7872void compose(std::u32string& input) {
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) *
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 =
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
7953void normalize(std::u32string& input) {
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
7968namespace ada::idna {
7969
7970constexpr int32_t base = 36;
7971constexpr int32_t tmin = 1;
7972constexpr int32_t tmax = 26;
7973constexpr int32_t skew = 38;
7974constexpr int32_t damp = 700;
7975constexpr int32_t initial_bias = 72;
7976constexpr uint32_t initial_n = 128;
7977
7978static 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
7984static constexpr char digit_to_char(int32_t digit) {
7985 return digit < 26 ? char(digit + 97) : char(digit + 22);
7986}
7987
7988static 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
8003bool 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
8064bool 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
8122bool 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
8189namespace ada::idna {
8190
8217
8218struct directions {
8219 uint32_t start_code;
8220 uint32_t final_code;
8222};
8223
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
8953inline 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
8969inline 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
8979inline 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
8990bool is_label_valid(const std::u32string_view label) {
8991 if (label.empty()) {
8992 return true;
8993 }
8994
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
9523namespace ada::idna {
9524
9525bool 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
9533bool 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
9541bool 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
9550bool 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
9559constexpr 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
9572static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
9573
9574inline bool is_forbidden_domain_code_point(const char c) noexcept {
9575 return is_forbidden_domain_code_point_table[uint8_t(c)];
9576}
9577
9578bool 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.
9584static 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.
9640std::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
9736namespace ada::idna {
9737std::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 */
9788
9789#include <algorithm>
9790#if ADA_NEON
9791#include <arm_neon.h>
9792#elif ADA_SSE2
9793#include <emmintrin.h>
9794#endif
9795
9796namespace ada::unicode {
9797
9798constexpr bool is_tabs_or_newline(char c) noexcept {
9799 return c == '\r' || c == '\n' || c == '\t';
9800}
9801
9802constexpr uint64_t broadcast(uint8_t v) noexcept {
9803 return 0x101010101010101ull * v;
9804}
9805
9806constexpr bool to_lower_ascii(char* input, size_t length) noexcept {
9807 uint64_t broadcast_80 = broadcast(0x80);
9808 uint64_t broadcast_Ap = broadcast(128 - 'A');
9809 uint64_t broadcast_Zp = broadcast(128 - 'Z' - 1);
9810 uint64_t non_ascii = 0;
9811 size_t i = 0;
9812
9813 for (; i + 7 < length; i += 8) {
9814 uint64_t word{};
9815 memcpy(&word, input + i, sizeof(word));
9816 non_ascii |= (word & broadcast_80);
9817 word ^=
9818 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
9819 memcpy(input + i, &word, sizeof(word));
9820 }
9821 if (i < length) {
9822 uint64_t word{};
9823 memcpy(&word, input + i, length - i);
9824 non_ascii |= (word & broadcast_80);
9825 word ^=
9826 (((word + broadcast_Ap) ^ (word + broadcast_Zp)) & broadcast_80) >> 2;
9827 memcpy(input + i, &word, length - i);
9828 }
9829 return non_ascii == 0;
9830}
9831#if ADA_NEON
9832ada_really_inline bool has_tabs_or_newline(
9833 std::string_view user_input) noexcept {
9834 // first check for short strings in which case we do it naively.
9835 if (user_input.size() < 16) { // slow path
9836 return std::any_of(user_input.begin(), user_input.end(),
9838 }
9839 // fast path for long strings (expected to be common)
9840 size_t i = 0;
9853 static uint8_t rnt_array[16] = {1, 0, 0, 0, 0, 0, 0, 0,
9854 0, 9, 10, 0, 0, 13, 0, 0};
9855 const uint8x16_t rnt = vld1q_u8(rnt_array);
9856 // m['0xd', '0xa', '0x9']
9857 uint8x16_t running{0};
9858 for (; i + 15 < user_input.size(); i += 16) {
9859 uint8x16_t word = vld1q_u8((const uint8_t*)user_input.data() + i);
9860
9861 running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word));
9862 }
9863 if (i < user_input.size()) {
9864 uint8x16_t word =
9865 vld1q_u8((const uint8_t*)user_input.data() + user_input.length() - 16);
9866 running = vorrq_u8(running, vceqq_u8(vqtbl1q_u8(rnt, word), word));
9867 }
9868 return vmaxvq_u32(vreinterpretq_u32_u8(running)) != 0;
9869}
9870#elif ADA_SSE2
9871ada_really_inline bool has_tabs_or_newline(
9872 std::string_view user_input) noexcept {
9873 // first check for short strings in which case we do it naively.
9874 if (user_input.size() < 16) { // slow path
9875 return std::any_of(user_input.begin(), user_input.end(),
9877 }
9878 // fast path for long strings (expected to be common)
9879 size_t i = 0;
9880 const __m128i mask1 = _mm_set1_epi8('\r');
9881 const __m128i mask2 = _mm_set1_epi8('\n');
9882 const __m128i mask3 = _mm_set1_epi8('\t');
9883 // If we supported SSSE3, we could use the algorithm that we use for NEON.
9884 __m128i running{0};
9885 for (; i + 15 < user_input.size(); i += 16) {
9886 __m128i word = _mm_loadu_si128((const __m128i*)(user_input.data() + i));
9887 running = _mm_or_si128(
9888 _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
9889 _mm_cmpeq_epi8(word, mask2))),
9890 _mm_cmpeq_epi8(word, mask3));
9891 }
9892 if (i < user_input.size()) {
9893 __m128i word = _mm_loadu_si128(
9894 (const __m128i*)(user_input.data() + user_input.length() - 16));
9895 running = _mm_or_si128(
9896 _mm_or_si128(running, _mm_or_si128(_mm_cmpeq_epi8(word, mask1),
9897 _mm_cmpeq_epi8(word, mask2))),
9898 _mm_cmpeq_epi8(word, mask3));
9899 }
9900 return _mm_movemask_epi8(running) != 0;
9901}
9902#else
9903ada_really_inline bool has_tabs_or_newline(
9904 std::string_view user_input) noexcept {
9905 auto has_zero_byte = [](uint64_t v) {
9906 return ((v - 0x0101010101010101) & ~(v) & 0x8080808080808080);
9907 };
9908 size_t i = 0;
9909 uint64_t mask1 = broadcast('\r');
9910 uint64_t mask2 = broadcast('\n');
9911 uint64_t mask3 = broadcast('\t');
9912 uint64_t running{0};
9913 for (; i + 7 < user_input.size(); i += 8) {
9914 uint64_t word{};
9915 memcpy(&word, user_input.data() + i, sizeof(word));
9916 uint64_t xor1 = word ^ mask1;
9917 uint64_t xor2 = word ^ mask2;
9918 uint64_t xor3 = word ^ mask3;
9919 running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
9920 }
9921 if (i < user_input.size()) {
9922 uint64_t word{};
9923 memcpy(&word, user_input.data() + i, user_input.size() - i);
9924 uint64_t xor1 = word ^ mask1;
9925 uint64_t xor2 = word ^ mask2;
9926 uint64_t xor3 = word ^ mask3;
9927 running |= has_zero_byte(xor1) | has_zero_byte(xor2) | has_zero_byte(xor3);
9928 }
9929 return running;
9930}
9931#endif
9932
9933// A forbidden host code point is U+0000 NULL, U+0009 TAB, U+000A LF, U+000D CR,
9934// U+0020 SPACE, U+0023 (#), U+002F (/), U+003A (:), U+003C (<), U+003E (>),
9935// U+003F (?), U+0040 (@), U+005B ([), U+005C (\‍), U+005D (]), U+005E (^), or
9936// U+007C (|).
9937constexpr static std::array<uint8_t, 256> is_forbidden_host_code_point_table =
9938 []() constexpr {
9939 std::array<uint8_t, 256> result{};
9940 for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
9941 '>', '?', '@', '[', '\\', ']', '^', '|'}) {
9942 result[c] = true;
9943 }
9944 return result;
9945 }();
9946
9947ada_really_inline constexpr bool is_forbidden_host_code_point(
9948 const char c) noexcept {
9949 return is_forbidden_host_code_point_table[uint8_t(c)];
9950}
9951
9952constexpr static std::array<uint8_t, 256> is_forbidden_domain_code_point_table =
9953 []() constexpr {
9954 std::array<uint8_t, 256> result{};
9955 for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
9956 '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
9957 result[c] = true;
9958 }
9959 for (uint8_t c = 0; c <= 32; c++) {
9960 result[c] = true;
9961 }
9962 for (size_t c = 127; c < 255; c++) {
9963 result[c] = true;
9964 }
9965 return result;
9966 }();
9967
9968static_assert(sizeof(is_forbidden_domain_code_point_table) == 256);
9969
9970ada_really_inline constexpr bool is_forbidden_domain_code_point(
9971 const char c) noexcept {
9972 return is_forbidden_domain_code_point_table[uint8_t(c)];
9973}
9974
9975ada_really_inline constexpr bool contains_forbidden_domain_code_point(
9976 const char* input, size_t length) noexcept {
9977 size_t i = 0;
9978 uint8_t accumulator{};
9979 for (; i + 4 <= length; i += 4) {
9980 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
9981 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 1])];
9982 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 2])];
9983 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i + 3])];
9984 }
9985 for (; i < length; i++) {
9986 accumulator |= is_forbidden_domain_code_point_table[uint8_t(input[i])];
9987 }
9988 return accumulator;
9989}
9990
9991constexpr static std::array<uint8_t, 256>
9993 std::array<uint8_t, 256> result{};
9994 for (uint8_t c : {'\0', '\x09', '\x0a', '\x0d', ' ', '#', '/', ':', '<',
9995 '>', '?', '@', '[', '\\', ']', '^', '|', '%'}) {
9996 result[c] = 1;
9997 }
9998 for (uint8_t c = 'A'; c <= 'Z'; c++) {
9999 result[c] = 2;
10000 }
10001 for (uint8_t c = 0; c <= 32; c++) {
10002 result[c] = 1;
10003 }
10004 for (size_t c = 127; c < 255; c++) {
10005 result[c] = 1;
10006 }
10007 return result;
10008 }();
10009
10010ada_really_inline constexpr uint8_t
10011contains_forbidden_domain_code_point_or_upper(const char* input,
10012 size_t length) noexcept {
10013 size_t i = 0;
10014 uint8_t accumulator{};
10015 for (; i + 4 <= length; i += 4) {
10016 accumulator |=
10018 accumulator |=
10019 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 1])];
10020 accumulator |=
10021 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 2])];
10022 accumulator |=
10023 is_forbidden_domain_code_point_table_or_upper[uint8_t(input[i + 3])];
10024 }
10025 for (; i < length; i++) {
10026 accumulator |=
10028 }
10029 return accumulator;
10030}
10031
10032// std::isalnum(c) || c == '+' || c == '-' || c == '.') is true for
10033constexpr static std::array<bool, 256> is_alnum_plus_table = []() constexpr {
10034 std::array<bool, 256> result{};
10035 for (size_t c = 0; c < 256; c++) {
10036 result[c] = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
10037 (c >= 'A' && c <= 'Z') || c == '+' || c == '-' || c == '.';
10038 }
10039 return result;
10040}();
10041
10042ada_really_inline constexpr bool is_alnum_plus(const char c) noexcept {
10043 return is_alnum_plus_table[uint8_t(c)];
10044 // A table is almost surely much faster than the
10045 // following under most compilers: return
10046 // return (std::isalnum(c) || c == '+' || c == '-' || c == '.');
10047}
10048
10049ada_really_inline constexpr bool is_ascii_hex_digit(const char c) noexcept {
10050 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
10051 (c >= 'a' && c <= 'f');
10052}
10053
10054ada_really_inline constexpr bool is_c0_control_or_space(const char c) noexcept {
10055 return (unsigned char)c <= ' ';
10056}
10057
10058ada_really_inline constexpr bool is_ascii_tab_or_newline(
10059 const char c) noexcept {
10060 return c == '\t' || c == '\n' || c == '\r';
10061}
10062
10063constexpr std::string_view table_is_double_dot_path_segment[] = {
10064 "..", "%2e.", ".%2e", "%2e%2e"};
10065
10066ada_really_inline ada_constexpr bool is_double_dot_path_segment(
10067 std::string_view input) noexcept {
10068 // This will catch most cases:
10069 // The length must be 2,4 or 6.
10070 // We divide by two and require
10071 // that the result be between 1 and 3 inclusively.
10072 uint64_t half_length = uint64_t(input.size()) / 2;
10073 if (half_length - 1 > 2) {
10074 return false;
10075 }
10076 // We have a string of length 2, 4 or 6.
10077 // We now check the first character:
10078 if ((input[0] != '.') && (input[0] != '%')) {
10079 return false;
10080 }
10081 // We are unlikely the get beyond this point.
10082 int hash_value = (input.size() + (unsigned)(input[0])) & 3;
10083 const std::string_view target = table_is_double_dot_path_segment[hash_value];
10084 if (target.size() != input.size()) {
10085 return false;
10086 }
10087 // We almost never get here.
10088 // Optimizing the rest is relatively unimportant.
10089 auto prefix_equal_unsafe = [](std::string_view a, std::string_view b) {
10090 uint16_t A, B;
10091 memcpy(&A, a.data(), sizeof(A));
10092 memcpy(&B, b.data(), sizeof(B));
10093 return A == B;
10094 };
10095 if (!prefix_equal_unsafe(input, target)) {
10096 return false;
10097 }
10098 for (size_t i = 2; i < input.size(); i++) {
10099 char c = input[i];
10100 if ((uint8_t((c | 0x20) - 0x61) <= 25 ? (c | 0x20) : c) != target[i]) {
10101 return false;
10102 }
10103 }
10104 return true;
10105 // The above code might be a bit better than the code below. Compilers
10106 // are not stupid and may use the fact that these strings have length 2,4 and
10107 // 6 and other tricks.
10108 // return input == ".." ||
10109 // input == ".%2e" || input == ".%2E" ||
10110 // input == "%2e." || input == "%2E." ||
10111 // input == "%2e%2e" || input == "%2E%2E" || input == "%2E%2e" || input ==
10112 // "%2e%2E";
10113}
10114
10115ada_really_inline constexpr bool is_single_dot_path_segment(
10116 std::string_view input) noexcept {
10117 return input == "." || input == "%2e" || input == "%2E";
10118}
10119
10120ada_really_inline constexpr bool is_lowercase_hex(const char c) noexcept {
10121 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
10122}
10123
10124constexpr static char hex_to_binary_table[] = {
10125 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11,
10126 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
10128unsigned constexpr convert_hex_to_binary(const char c) noexcept {
10129 return hex_to_binary_table[c - '0'];
10130}
10131
10132std::string percent_decode(const std::string_view input, size_t first_percent) {
10133 // next line is for safety only, we expect users to avoid calling
10134 // percent_decode when first_percent is outside the range.
10135 if (first_percent == std::string_view::npos) {
10136 return std::string(input);
10137 }
10138 std::string dest;
10139 dest.reserve(input.length());
10140 dest.append(input.substr(0, first_percent));
10141 const char* pointer = input.data() + first_percent;
10142 const char* end = input.data() + input.size();
10143 // Optimization opportunity: if the following code gets
10144 // called often, it can be optimized quite a bit.
10145 while (pointer < end) {
10146 const char ch = pointer[0];
10147 size_t remaining = end - pointer - 1;
10148 if (ch != '%' || remaining < 2 ||
10149 ( // ch == '%' && // It is unnecessary to check that ch == '%'.
10150 (!is_ascii_hex_digit(pointer[1]) ||
10151 !is_ascii_hex_digit(pointer[2])))) {
10152 dest += ch;
10153 pointer++;
10154 continue;
10155 } else {
10156 unsigned a = convert_hex_to_binary(pointer[1]);
10157 unsigned b = convert_hex_to_binary(pointer[2]);
10158 char c = static_cast<char>(a * 16 + b);
10159 dest += c;
10160 pointer += 3;
10161 }
10162 }
10163 return dest;
10164}
10165
10166std::string percent_encode(const std::string_view input,
10167 const uint8_t character_set[]) {
10168 auto pointer =
10169 std::find_if(input.begin(), input.end(), [character_set](const char c) {
10170 return character_sets::bit_at(character_set, c);
10171 });
10172 // Optimization: Don't iterate if percent encode is not required
10173 if (pointer == input.end()) {
10174 return std::string(input);
10175 }
10176
10177 std::string result;
10178 result.reserve(input.length()); // in the worst case, percent encoding might
10179 // produce 3 characters.
10180 result.append(input.substr(0, std::distance(input.begin(), pointer)));
10181
10182 for (; pointer != input.end(); pointer++) {
10183 if (character_sets::bit_at(character_set, *pointer)) {
10184 result.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
10185 } else {
10186 result += *pointer;
10187 }
10188 }
10189
10190 return result;
10191}
10192
10193template <bool append>
10194bool percent_encode(const std::string_view input, const uint8_t character_set[],
10195 std::string& out) {
10196 ada_log("percent_encode ", input, " to output string while ",
10197 append ? "appending" : "overwriting");
10198 auto pointer =
10199 std::find_if(input.begin(), input.end(), [character_set](const char c) {
10200 return character_sets::bit_at(character_set, c);
10201 });
10202 ada_log("percent_encode done checking, moved to ",
10203 std::distance(input.begin(), pointer));
10204
10205 // Optimization: Don't iterate if percent encode is not required
10206 if (pointer == input.end()) {
10207 ada_log("percent_encode encoding not needed.");
10208 return false;
10209 }
10210 if (!append) {
10211 out.clear();
10212 }
10213 ada_log("percent_encode appending ", std::distance(input.begin(), pointer),
10214 " bytes");
10215 out.append(input.data(), std::distance(input.begin(), pointer));
10216 ada_log("percent_encode processing ", std::distance(pointer, input.end()),
10217 " bytes");
10218 for (; pointer != input.end(); pointer++) {
10219 if (character_sets::bit_at(character_set, *pointer)) {
10220 out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
10221 } else {
10222 out += *pointer;
10223 }
10224 }
10225 return true;
10226}
10227
10228bool to_ascii(std::optional<std::string>& out, const std::string_view plain,
10229 size_t first_percent) {
10230 std::string percent_decoded_buffer;
10231 std::string_view input = plain;
10232 if (first_percent != std::string_view::npos) {
10233 percent_decoded_buffer = unicode::percent_decode(plain, first_percent);
10234 input = percent_decoded_buffer;
10235 }
10236 // input is a non-empty UTF-8 string, must be percent decoded
10237 std::string idna_ascii = ada::idna::to_ascii(input);
10238 if (idna_ascii.empty() || contains_forbidden_domain_code_point(
10239 idna_ascii.data(), idna_ascii.size())) {
10240 return false;
10241 }
10242 out = std::move(idna_ascii);
10243 return true;
10244}
10245
10246std::string percent_encode(const std::string_view input,
10247 const uint8_t character_set[], size_t index) {
10248 std::string out;
10249 out.append(input.data(), index);
10250 auto pointer = input.begin() + index;
10251 for (; pointer != input.end(); pointer++) {
10252 if (character_sets::bit_at(character_set, *pointer)) {
10253 out.append(character_sets::hex + uint8_t(*pointer) * 4, 3);
10254 } else {
10255 out += *pointer;
10256 }
10257 }
10258 return out;
10259}
10260
10261} // namespace ada::unicode
10262/* end file src/unicode.cpp */
10263/* begin file src/serializers.cpp */
10264
10265#include <array>
10266#include <string>
10267
10268namespace ada::serializers {
10269
10271 const std::array<uint16_t, 8>& address, size_t& compress,
10272 size_t& compress_length) noexcept {
10273 for (size_t i = 0; i < 8; i++) {
10274 if (address[i] == 0) {
10275 size_t next = i + 1;
10276 while (next != 8 && address[next] == 0) ++next;
10277 const size_t count = next - i;
10278 if (compress_length < count) {
10279 compress_length = count;
10280 compress = i;
10281 if (next == 8) break;
10282 i = next;
10283 }
10284 }
10285 }
10286}
10287
10288std::string ipv6(const std::array<uint16_t, 8>& address) noexcept {
10289 size_t compress_length = 0; // The length of a long sequence of zeros.
10290 size_t compress = 0; // The start of a long sequence of zeros.
10291 find_longest_sequence_of_ipv6_pieces(address, compress, compress_length);
10292
10293 if (compress_length <= 1) {
10294 // Optimization opportunity: Find a faster way then snprintf for imploding
10295 // and return here.
10296 compress = compress_length = 8;
10297 }
10298
10299 std::string output(4 * 8 + 7 + 2, '\0');
10300 size_t piece_index = 0;
10301 char* point = output.data();
10302 char* point_end = output.data() + output.size();
10303 *point++ = '[';
10304 while (true) {
10305 if (piece_index == compress) {
10306 *point++ = ':';
10307 // If we skip a value initially, we need to write '::', otherwise
10308 // a single ':' will do since it follows a previous ':'.
10309 if (piece_index == 0) {
10310 *point++ = ':';
10311 }
10312 piece_index += compress_length;
10313 if (piece_index == 8) {
10314 break;
10315 }
10316 }
10317 point = std::to_chars(point, point_end, address[piece_index], 16).ptr;
10318 piece_index++;
10319 if (piece_index == 8) {
10320 break;
10321 }
10322 *point++ = ':';
10323 }
10324 *point++ = ']';
10325 output.resize(point - output.data());
10326 return output;
10327}
10328
10329std::string ipv4(const uint64_t address) noexcept {
10330 std::string output(15, '\0');
10331 char* point = output.data();
10332 char* point_end = output.data() + output.size();
10333 point = std::to_chars(point, point_end, uint8_t(address >> 24)).ptr;
10334 for (int i = 2; i >= 0; i--) {
10335 *point++ = '.';
10336 point = std::to_chars(point, point_end, uint8_t(address >> (i * 8))).ptr;
10337 }
10338 output.resize(point - output.data());
10339 return output;
10340}
10341
10342} // namespace ada::serializers
10343/* end file src/serializers.cpp */
10344/* begin file src/implementation.cpp */
10345#include <string_view>
10346
10347
10348namespace ada {
10349
10350template <class result_type>
10352 std::string_view input, const result_type* base_url) {
10353 result_type u =
10355 if (!u.is_valid) {
10357 }
10358 return u;
10359}
10360
10361template ada::result<url> parse<url>(std::string_view input,
10362 const url* base_url = nullptr);
10364 std::string_view input, const url_aggregator* base_url = nullptr);
10365
10366std::string href_from_file(std::string_view input) {
10367 // This is going to be much faster than constructing a URL.
10368 std::string tmp_buffer;
10369 std::string_view internal_input;
10370 if (unicode::has_tabs_or_newline(input)) {
10371 tmp_buffer = input;
10372 helpers::remove_ascii_tab_or_newline(tmp_buffer);
10373 internal_input = tmp_buffer;
10374 } else {
10375 internal_input = input;
10376 }
10377 std::string path;
10378 if (internal_input.empty()) {
10379 path = "/";
10380 } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
10381 helpers::parse_prepared_path(internal_input.substr(1),
10382 ada::scheme::type::FILE, path);
10383 } else {
10384 helpers::parse_prepared_path(internal_input, ada::scheme::type::FILE, path);
10385 }
10386 return "file://" + path;
10387}
10388
10389bool can_parse(std::string_view input, const std::string_view* base_input) {
10390 ada::url_aggregator base_aggregator;
10391 ada::url_aggregator* base_pointer = nullptr;
10392
10393 if (base_input != nullptr) {
10395 *base_input, nullptr);
10396 if (!base_aggregator.is_valid) {
10397 return false;
10398 }
10399 base_pointer = &base_aggregator;
10400 }
10401
10404 base_pointer);
10405 return result.is_valid;
10406}
10407
10409 switch (type) {
10411 return "UTF-8";
10413 return "UTF-16LE";
10415 return "UTF-16BE";
10416 default:
10417 unreachable();
10418 }
10419}
10420
10421} // namespace ada
10422/* end file src/implementation.cpp */
10423/* begin file src/helpers.cpp */
10424
10425#include <algorithm>
10426#include <charconv>
10427#include <cstring>
10428#include <sstream>
10429
10430namespace ada::helpers {
10431
10432template <typename out_iter>
10433void encode_json(std::string_view view, out_iter out) {
10434 // trivial implementation. could be faster.
10435 const char* hexvalues =
10436 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
10437 for (uint8_t c : view) {
10438 if (c == '\\') {
10439 *out++ = '\\';
10440 *out++ = '\\';
10441 } else if (c == '"') {
10442 *out++ = '\\';
10443 *out++ = '"';
10444 } else if (c <= 0x1f) {
10445 *out++ = '\\';
10446 *out++ = 'u';
10447 *out++ = '0';
10448 *out++ = '0';
10449 *out++ = hexvalues[2 * c];
10450 *out++ = hexvalues[2 * c + 1];
10451 } else {
10452 *out++ = c;
10453 }
10454 }
10455}
10456
10458 switch (s) {
10460 return "Authority";
10462 return "Scheme Start";
10463 case ada::state::SCHEME:
10464 return "Scheme";
10465 case ada::state::HOST:
10466 return "Host";
10468 return "No Scheme";
10470 return "Fragment";
10472 return "Relative Scheme";
10474 return "Relative Slash";
10475 case ada::state::FILE:
10476 return "File";
10478 return "File Host";
10480 return "File Slash";
10482 return "Path or Authority";
10484 return "Special Authority Ignore Slashes";
10486 return "Special Authority Slashes";
10488 return "Special Relative or Authority";
10489 case ada::state::QUERY:
10490 return "Query";
10491 case ada::state::PATH:
10492 return "Path";
10494 return "Path Start";
10496 return "Opaque Path";
10497 case ada::state::PORT:
10498 return "Port";
10499 default:
10500 return "unknown state";
10501 }
10502}
10503
10504ada_really_inline std::optional<std::string_view> prune_hash(
10505 std::string_view& input) noexcept {
10506 // compiles down to 20--30 instructions including a class to memchr (C
10507 // function). this function should be quite fast.
10508 size_t location_of_first = input.find('#');
10509 if (location_of_first == std::string_view::npos) {
10510 return std::nullopt;
10511 }
10512 std::string_view hash = input;
10513 hash.remove_prefix(location_of_first + 1);
10514 input.remove_suffix(input.size() - location_of_first);
10515 return hash;
10516}
10517
10518ada_really_inline bool shorten_path(std::string& path,
10519 ada::scheme::type type) noexcept {
10520 size_t first_delimiter = path.find_first_of('/', 1);
10521
10522 // Let path be url's path.
10523 // If url's scheme is "file", path's size is 1, and path[0] is a normalized
10524 // Windows drive letter, then return.
10525 if (type == ada::scheme::type::FILE &&
10526 first_delimiter == std::string_view::npos && !path.empty()) {
10527 if (checkers::is_normalized_windows_drive_letter(
10528 helpers::substring(path, 1))) {
10529 return false;
10530 }
10531 }
10532
10533 // Remove path's last item, if any.
10534 size_t last_delimiter = path.rfind('/');
10535 if (last_delimiter != std::string::npos) {
10536 path.erase(last_delimiter);
10537 return true;
10538 }
10539
10540 return false;
10541}
10542
10543ada_really_inline bool shorten_path(std::string_view& path,
10544 ada::scheme::type type) noexcept {
10545 size_t first_delimiter = path.find_first_of('/', 1);
10546
10547 // Let path be url's path.
10548 // If url's scheme is "file", path's size is 1, and path[0] is a normalized
10549 // Windows drive letter, then return.
10550 if (type == ada::scheme::type::FILE &&
10551 first_delimiter == std::string_view::npos && !path.empty()) {
10552 if (checkers::is_normalized_windows_drive_letter(
10553 helpers::substring(path, 1))) {
10554 return false;
10555 }
10556 }
10557
10558 // Remove path's last item, if any.
10559 if (!path.empty()) {
10560 size_t slash_loc = path.rfind('/');
10561 if (slash_loc != std::string_view::npos) {
10562 path.remove_suffix(path.size() - slash_loc);
10563 return true;
10564 }
10565 }
10566
10567 return false;
10568}
10569
10570ada_really_inline void remove_ascii_tab_or_newline(
10571 std::string& input) noexcept {
10572 // if this ever becomes a performance issue, we could use an approach similar
10573 // to has_tabs_or_newline
10574 input.erase(std::remove_if(input.begin(), input.end(),
10575 [](char c) {
10576 return ada::unicode::is_ascii_tab_or_newline(c);
10577 }),
10578 input.end());
10579}
10580
10581ada_really_inline std::string_view substring(std::string_view input,
10582 size_t pos) noexcept {
10583 ADA_ASSERT_TRUE(pos <= input.size());
10584 // The following is safer but unneeded if we have the above line:
10585 // return pos > input.size() ? std::string_view() : input.substr(pos);
10586 return input.substr(pos);
10587}
10588
10589ada_really_inline void resize(std::string_view& input, size_t pos) noexcept {
10590 ADA_ASSERT_TRUE(pos <= input.size());
10591 input.remove_suffix(input.size() - pos);
10592}
10593
10594// computes the number of trailing zeroes
10595// this is a private inline function only defined in this source file.
10596ada_really_inline int trailing_zeroes(uint32_t input_num) noexcept {
10597#ifdef ADA_REGULAR_VISUAL_STUDIO
10598 unsigned long ret;
10599 // Search the mask data from least significant bit (LSB)
10600 // to the most significant bit (MSB) for a set bit (1).
10601 _BitScanForward(&ret, input_num);
10602 return (int)ret;
10603#else // ADA_REGULAR_VISUAL_STUDIO
10604 return __builtin_ctzl(input_num);
10605#endif // ADA_REGULAR_VISUAL_STUDIO
10606}
10607
10608// starting at index location, this finds the next location of a character
10609// :, /, \\, ? or [. If none is found, view.size() is returned.
10610// For use within get_host_delimiter_location.
10611#if ADA_NEON
10612// The ada_make_uint8x16_t macro is necessary because Visual Studio does not
10613// support direct initialization of uint8x16_t. See
10614// https://developercommunity.visualstudio.com/t/error-C2078:-too-many-initializers-whe/402911?q=backend+neon
10615#ifndef ada_make_uint8x16_t
10616#define ada_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \
10617 x13, x14, x15, x16) \
10618 ([=]() { \
10619 static uint8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \
10620 x9, x10, x11, x12, x13, x14, x15, x16}; \
10621 return vld1q_u8(array); \
10622 }())
10623#endif
10624
10625ada_really_inline size_t find_next_host_delimiter_special(
10626 std::string_view view, size_t location) noexcept {
10627 // first check for short strings in which case we do it naively.
10628 if (view.size() - location < 16) { // slow path
10629 for (size_t i = location; i < view.size(); i++) {
10630 if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
10631 view[i] == '?' || view[i] == '[') {
10632 return i;
10633 }
10634 }
10635 return size_t(view.size());
10636 }
10637 auto to_bitmask = [](uint8x16_t input) -> uint16_t {
10638 uint8x16_t bit_mask =
10639 ada_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x01,
10640 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
10641 uint8x16_t minput = vandq_u8(input, bit_mask);
10642 uint8x16_t tmp = vpaddq_u8(minput, minput);
10643 tmp = vpaddq_u8(tmp, tmp);
10644 tmp = vpaddq_u8(tmp, tmp);
10645 return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0);
10646 };
10647
10648 // fast path for long strings (expected to be common)
10649 size_t i = location;
10650 uint8x16_t low_mask =
10651 ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10652 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x03);
10653 uint8x16_t high_mask =
10654 ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
10655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
10656 uint8x16_t fmask = vmovq_n_u8(0xf);
10657 uint8x16_t zero{0};
10658 for (; i + 15 < view.size(); i += 16) {
10659 uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
10660 uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
10661 uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
10662 uint8x16_t classify = vandq_u8(lowpart, highpart);
10663 if (vmaxvq_u32(vreinterpretq_u32_u8(classify)) != 0) {
10664 uint8x16_t is_zero = vceqq_u8(classify, zero);
10665 uint16_t is_non_zero = ~to_bitmask(is_zero);
10666 return i + trailing_zeroes(is_non_zero);
10667 }
10668 }
10669
10670 if (i < view.size()) {
10671 uint8x16_t word =
10672 vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
10673 uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
10674 uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
10675 uint8x16_t classify = vandq_u8(lowpart, highpart);
10676 if (vmaxvq_u32(vreinterpretq_u32_u8(classify)) != 0) {
10677 uint8x16_t is_zero = vceqq_u8(classify, zero);
10678 uint16_t is_non_zero = ~to_bitmask(is_zero);
10679 return view.length() - 16 + trailing_zeroes(is_non_zero);
10680 }
10681 }
10682 return size_t(view.size());
10683}
10684#elif ADA_SSE2
10686 std::string_view view, size_t location) noexcept {
10687 // first check for short strings in which case we do it naively.
10688 if (view.size() - location < 16) { // slow path
10689 for (size_t i = location; i < view.size(); i++) {
10690 if (view[i] == ':' || view[i] == '/' || view[i] == '\\' ||
10691 view[i] == '?' || view[i] == '[') {
10692 return i;
10693 }
10694 }
10695 return size_t(view.size());
10696 }
10697 // fast path for long strings (expected to be common)
10698 size_t i = location;
10699 const __m128i mask1 = _mm_set1_epi8(':');
10700 const __m128i mask2 = _mm_set1_epi8('/');
10701 const __m128i mask3 = _mm_set1_epi8('\\');
10702 const __m128i mask4 = _mm_set1_epi8('?');
10703 const __m128i mask5 = _mm_set1_epi8('[');
10704
10705 for (; i + 15 < view.size(); i += 16) {
10706 __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
10707 __m128i m1 = _mm_cmpeq_epi8(word, mask1);
10708 __m128i m2 = _mm_cmpeq_epi8(word, mask2);
10709 __m128i m3 = _mm_cmpeq_epi8(word, mask3);
10710 __m128i m4 = _mm_cmpeq_epi8(word, mask4);
10711 __m128i m5 = _mm_cmpeq_epi8(word, mask5);
10712 __m128i m = _mm_or_si128(
10713 _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
10714 int mask = _mm_movemask_epi8(m);
10715 if (mask != 0) {
10716 return i + trailing_zeroes(mask);
10717 }
10718 }
10719 if (i < view.size()) {
10720 __m128i word =
10721 _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
10722 __m128i m1 = _mm_cmpeq_epi8(word, mask1);
10723 __m128i m2 = _mm_cmpeq_epi8(word, mask2);
10724 __m128i m3 = _mm_cmpeq_epi8(word, mask3);
10725 __m128i m4 = _mm_cmpeq_epi8(word, mask4);
10726 __m128i m5 = _mm_cmpeq_epi8(word, mask5);
10727 __m128i m = _mm_or_si128(
10728 _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m3, m4)), m5);
10729 int mask = _mm_movemask_epi8(m);
10730 if (mask != 0) {
10731 return view.length() - 16 + trailing_zeroes(mask);
10732 }
10733 }
10734 return size_t(view.length());
10735}
10736#else
10737// : / [ \\ ?
10738static constexpr std::array<uint8_t, 256> special_host_delimiters =
10739 []() constexpr {
10740 std::array<uint8_t, 256> result{};
10741 for (int i : {':', '/', '[', '\\', '?'}) {
10742 result[i] = 1;
10743 }
10744 return result;
10745 }();
10746// credit: @the-moisrex recommended a table-based approach
10748 std::string_view view, size_t location) noexcept {
10749 auto const str = view.substr(location);
10750 for (auto pos = str.begin(); pos != str.end(); ++pos) {
10751 if (special_host_delimiters[(uint8_t)*pos]) {
10752 return pos - str.begin() + location;
10753 }
10754 }
10755 return size_t(view.size());
10756}
10757#endif
10758
10759// starting at index location, this finds the next location of a character
10760// :, /, ? or [. If none is found, view.size() is returned.
10761// For use within get_host_delimiter_location.
10762#if ADA_NEON
10763ada_really_inline size_t find_next_host_delimiter(std::string_view view,
10764 size_t location) noexcept {
10765 // first check for short strings in which case we do it naively.
10766 if (view.size() - location < 16) { // slow path
10767 for (size_t i = location; i < view.size(); i++) {
10768 if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
10769 view[i] == '[') {
10770 return i;
10771 }
10772 }
10773 return size_t(view.size());
10774 }
10775 auto to_bitmask = [](uint8x16_t input) -> uint16_t {
10776 uint8x16_t bit_mask =
10777 ada_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x01,
10778 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
10779 uint8x16_t minput = vandq_u8(input, bit_mask);
10780 uint8x16_t tmp = vpaddq_u8(minput, minput);
10781 tmp = vpaddq_u8(tmp, tmp);
10782 tmp = vpaddq_u8(tmp, tmp);
10783 return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0);
10784 };
10785
10786 // fast path for long strings (expected to be common)
10787 size_t i = location;
10788 uint8x16_t low_mask =
10789 ada_make_uint8x16_t(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10790 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x03);
10791 uint8x16_t high_mask =
10792 ada_make_uint8x16_t(0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
10793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
10794 uint8x16_t fmask = vmovq_n_u8(0xf);
10795 uint8x16_t zero{0};
10796 for (; i + 15 < view.size(); i += 16) {
10797 uint8x16_t word = vld1q_u8((const uint8_t*)view.data() + i);
10798 uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
10799 uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
10800 uint8x16_t classify = vandq_u8(lowpart, highpart);
10801 if (vmaxvq_u32(vreinterpretq_u32_u8(classify)) != 0) {
10802 uint8x16_t is_zero = vceqq_u8(classify, zero);
10803 uint16_t is_non_zero = ~to_bitmask(is_zero);
10804 return i + trailing_zeroes(is_non_zero);
10805 }
10806 }
10807
10808 if (i < view.size()) {
10809 uint8x16_t word =
10810 vld1q_u8((const uint8_t*)view.data() + view.length() - 16);
10811 uint8x16_t lowpart = vqtbl1q_u8(low_mask, vandq_u8(word, fmask));
10812 uint8x16_t highpart = vqtbl1q_u8(high_mask, vshrq_n_u8(word, 4));
10813 uint8x16_t classify = vandq_u8(lowpart, highpart);
10814 if (vmaxvq_u32(vreinterpretq_u32_u8(classify)) != 0) {
10815 uint8x16_t is_zero = vceqq_u8(classify, zero);
10816 uint16_t is_non_zero = ~to_bitmask(is_zero);
10817 return view.length() - 16 + trailing_zeroes(is_non_zero);
10818 }
10819 }
10820 return size_t(view.size());
10821}
10822#elif ADA_SSE2
10823ada_really_inline size_t find_next_host_delimiter(std::string_view view,
10824 size_t location) noexcept {
10825 // first check for short strings in which case we do it naively.
10826 if (view.size() - location < 16) { // slow path
10827 for (size_t i = location; i < view.size(); i++) {
10828 if (view[i] == ':' || view[i] == '/' || view[i] == '?' ||
10829 view[i] == '[') {
10830 return i;
10831 }
10832 }
10833 return size_t(view.size());
10834 }
10835 // fast path for long strings (expected to be common)
10836 size_t i = location;
10837 const __m128i mask1 = _mm_set1_epi8(':');
10838 const __m128i mask2 = _mm_set1_epi8('/');
10839 const __m128i mask4 = _mm_set1_epi8('?');
10840 const __m128i mask5 = _mm_set1_epi8('[');
10841
10842 for (; i + 15 < view.size(); i += 16) {
10843 __m128i word = _mm_loadu_si128((const __m128i*)(view.data() + i));
10844 __m128i m1 = _mm_cmpeq_epi8(word, mask1);
10845 __m128i m2 = _mm_cmpeq_epi8(word, mask2);
10846 __m128i m4 = _mm_cmpeq_epi8(word, mask4);
10847 __m128i m5 = _mm_cmpeq_epi8(word, mask5);
10848 __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
10849 int mask = _mm_movemask_epi8(m);
10850 if (mask != 0) {
10851 return i + trailing_zeroes(mask);
10852 }
10853 }
10854 if (i < view.size()) {
10855 __m128i word =
10856 _mm_loadu_si128((const __m128i*)(view.data() + view.length() - 16));
10857 __m128i m1 = _mm_cmpeq_epi8(word, mask1);
10858 __m128i m2 = _mm_cmpeq_epi8(word, mask2);
10859 __m128i m4 = _mm_cmpeq_epi8(word, mask4);
10860 __m128i m5 = _mm_cmpeq_epi8(word, mask5);
10861 __m128i m = _mm_or_si128(_mm_or_si128(m1, m2), _mm_or_si128(m4, m5));
10862 int mask = _mm_movemask_epi8(m);
10863 if (mask != 0) {
10864 return view.length() - 16 + trailing_zeroes(mask);
10865 }
10866 }
10867 return size_t(view.length());
10868}
10869#else
10870// : / [ ?
10871static constexpr std::array<uint8_t, 256> host_delimiters = []() constexpr {
10872 std::array<uint8_t, 256> result{};
10873 for (int i : {':', '/', '?', '['}) {
10874 result[i] = 1;
10875 }
10876 return result;
10877}();
10878// credit: @the-moisrex recommended a table-based approach
10879ada_really_inline size_t find_next_host_delimiter(std::string_view view,
10880 size_t location) noexcept {
10881 auto const str = view.substr(location);
10882 for (auto pos = str.begin(); pos != str.end(); ++pos) {
10883 if (host_delimiters[(uint8_t)*pos]) {
10884 return pos - str.begin() + location;
10885 }
10886 }
10887 return size_t(view.size());
10888}
10889#endif
10890
10891ada_really_inline std::pair<size_t, bool> get_host_delimiter_location(
10892 const bool is_special, std::string_view& view) noexcept {
10901 const size_t view_size = view.size();
10902 size_t location = 0;
10903 bool found_colon = false;
10923 if (is_special) {
10924 // We move to the next delimiter.
10925 location = find_next_host_delimiter_special(view, location);
10926 // Unless we find '[' then we are going only going to have to call
10927 // find_next_host_delimiter_special once.
10928 for (; location < view_size;
10929 location = find_next_host_delimiter_special(view, location)) {
10930 if (view[location] == '[') {
10931 location = view.find(']', location);
10932 if (location == std::string_view::npos) {
10933 // performance: view.find might get translated to a memchr, which
10934 // has no notion of std::string_view::npos, so the code does not
10935 // reflect the assembly.
10936 location = view_size;
10937 break;
10938 }
10939 } else {
10940 found_colon = view[location] == ':';
10941 break;
10942 }
10943 }
10944 } else {
10945 // We move to the next delimiter.
10946 location = find_next_host_delimiter(view, location);
10947 // Unless we find '[' then we are going only going to have to call
10948 // find_next_host_delimiter_special once.
10949 for (; location < view_size;
10950 location = find_next_host_delimiter(view, location)) {
10951 if (view[location] == '[') {
10952 location = view.find(']', location);
10953 if (location == std::string_view::npos) {
10954 // performance: view.find might get translated to a memchr, which
10955 // has no notion of std::string_view::npos, so the code does not
10956 // reflect the assembly.
10957 location = view_size;
10958 break;
10959 }
10960 } else {
10961 found_colon = view[location] == ':';
10962 break;
10963 }
10964 }
10965 }
10966 // performance: remove_suffix may translate into a single instruction.
10967 view.remove_suffix(view_size - location);
10968 return {location, found_colon};
10969}
10970
10971ada_really_inline void trim_c0_whitespace(std::string_view& input) noexcept {
10972 while (!input.empty() &&
10973 ada::unicode::is_c0_control_or_space(input.front())) {
10974 input.remove_prefix(1);
10975 }
10976 while (!input.empty() && ada::unicode::is_c0_control_or_space(input.back())) {
10977 input.remove_suffix(1);
10978 }
10979}
10980
10981ada_really_inline void parse_prepared_path(std::string_view input,
10982 ada::scheme::type type,
10983 std::string& path) {
10984 ada_log("parse_prepared_path ", input);
10985 uint8_t accumulator = checkers::path_signature(input);
10986 // Let us first detect a trivial case.
10987 // If it is special, we check that we have no dot, no %, no \ and no
10988 // character needing percent encoding. Otherwise, we check that we have no %,
10989 // no dot, and no character needing percent encoding.
10990 constexpr uint8_t need_encoding = 1;
10991 constexpr uint8_t backslash_char = 2;
10992 constexpr uint8_t dot_char = 4;
10993 constexpr uint8_t percent_char = 8;
10994 bool special = type != ada::scheme::NOT_SPECIAL;
10995 bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
10996 checkers::is_windows_drive_letter(input));
10997 bool trivial_path =
10998 (special ? (accumulator == 0)
10999 : ((accumulator & (need_encoding | dot_char | percent_char)) ==
11000 0)) &&
11001 (!may_need_slow_file_handling);
11002 if (accumulator == dot_char && !may_need_slow_file_handling) {
11003 // '4' means that we have at least one dot, but nothing that requires
11004 // percent encoding or decoding. The only part that is not trivial is
11005 // that we may have single dots and double dots path segments.
11006 // If we have such segments, then we either have a path that begins
11007 // with '.' (easy to check), or we have the sequence './'.
11008 // Note: input cannot be empty, it must at least contain one character ('.')
11009 // Note: we know that '\' is not present.
11010 if (input[0] != '.') {
11011 size_t slashdot = input.find("/.");
11012 if (slashdot == std::string_view::npos) { // common case
11013 trivial_path = true;
11014 } else { // uncommon
11015 // only three cases matter: /./, /.. or a final /
11016 trivial_path =
11017 !(slashdot + 2 == input.size() || input[slashdot + 2] == '.' ||
11018 input[slashdot + 2] == '/');
11019 }
11020 }
11021 }
11022 if (trivial_path) {
11023 ada_log("parse_path trivial");
11024 path += '/';
11025 path += input;
11026 return;
11027 }
11028 // We are going to need to look a bit at the path, but let us see if we can
11029 // ignore percent encoding *and* backslashes *and* percent characters.
11030 // Except for the trivial case, this is likely to capture 99% of paths out
11031 // there.
11032 bool fast_path =
11033 (special &&
11034 (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
11035 (type != ada::scheme::type::FILE);
11036 if (fast_path) {
11037 ada_log("parse_prepared_path fast");
11038 // Here we don't need to worry about \ or percent encoding.
11039 // We also do not have a file protocol. We might have dots, however,
11040 // but dots must as appear as '.', and they cannot be encoded because
11041 // the symbol '%' is not present.
11042 size_t previous_location = 0; // We start at 0.
11043 do {
11044 size_t new_location = input.find('/', previous_location);
11045 // std::string_view path_view = input;
11046 // We process the last segment separately:
11047 if (new_location == std::string_view::npos) {
11048 std::string_view path_view = input.substr(previous_location);
11049 if (path_view == "..") { // The path ends with ..
11050 // e.g., if you receive ".." with an empty path, you go to "/".
11051 if (path.empty()) {
11052 path = '/';
11053 return;
11054 }
11055 // Fast case where we have nothing to do:
11056 if (path.back() == '/') {
11057 return;
11058 }
11059 // If you have the path "/joe/myfriend",
11060 // then you delete 'myfriend'.
11061 path.resize(path.rfind('/') + 1);
11062 return;
11063 }
11064 path += '/';
11065 if (path_view != ".") {
11066 path.append(path_view);
11067 }
11068 return;
11069 } else {
11070 // This is a non-final segment.
11071 std::string_view path_view =
11072 input.substr(previous_location, new_location - previous_location);
11073 previous_location = new_location + 1;
11074 if (path_view == "..") {
11075 size_t last_delimiter = path.rfind('/');
11076 if (last_delimiter != std::string::npos) {
11077 path.erase(last_delimiter);
11078 }
11079 } else if (path_view != ".") {
11080 path += '/';
11081 path.append(path_view);
11082 }
11083 }
11084 } while (true);
11085 } else {
11086 ada_log("parse_path slow");
11087 // we have reached the general case
11088 bool needs_percent_encoding = (accumulator & 1);
11089 std::string path_buffer_tmp;
11090 do {
11091 size_t location = (special && (accumulator & 2))
11092 ? input.find_first_of("/\\")
11093 : input.find('/');
11094 std::string_view path_view = input;
11095 if (location != std::string_view::npos) {
11096 path_view.remove_suffix(path_view.size() - location);
11097 input.remove_prefix(location + 1);
11098 }
11099 // path_buffer is either path_view or it might point at a percent encoded
11100 // temporary file.
11101 std::string_view path_buffer =
11102 (needs_percent_encoding &&
11103 ada::unicode::percent_encode<false>(
11104 path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
11105 ? path_buffer_tmp
11106 : path_view;
11107 if (unicode::is_double_dot_path_segment(path_buffer)) {
11108 if ((helpers::shorten_path(path, type) || special) &&
11109 location == std::string_view::npos) {
11110 path += '/';
11111 }
11112 } else if (unicode::is_single_dot_path_segment(path_buffer) &&
11113 (location == std::string_view::npos)) {
11114 path += '/';
11115 }
11116 // Otherwise, if path_buffer is not a single-dot path segment, then:
11117 else if (!unicode::is_single_dot_path_segment(path_buffer)) {
11118 // If url's scheme is "file", url's path is empty, and path_buffer is a
11119 // Windows drive letter, then replace the second code point in
11120 // path_buffer with U+003A (:).
11121 if (type == ada::scheme::type::FILE && path.empty() &&
11122 checkers::is_windows_drive_letter(path_buffer)) {
11123 path += '/';
11124 path += path_buffer[0];
11125 path += ':';
11126 path_buffer.remove_prefix(2);
11127 path.append(path_buffer);
11128 } else {
11129 // Append path_buffer to url's path.
11130 path += '/';
11131 path.append(path_buffer);
11132 }
11133 }
11134 if (location == std::string_view::npos) {
11135 return;
11136 }
11137 } while (true);
11138 }
11139}
11140
11141bool overlaps(std::string_view input1, const std::string& input2) noexcept {
11142 ada_log("helpers::overlaps check if string_view '", input1, "' [",
11143 input1.size(), " bytes] is part of string '", input2, "' [",
11144 input2.size(), " bytes]");
11145 return !input1.empty() && !input2.empty() && input1.data() >= input2.data() &&
11146 input1.data() < input2.data() + input2.size();
11147}
11148
11149template <class url_type>
11150ada_really_inline void strip_trailing_spaces_from_opaque_path(
11151 url_type& url) noexcept {
11152 ada_log("helpers::strip_trailing_spaces_from_opaque_path");
11153 if (!url.has_opaque_path) return;
11154 if (url.has_hash()) return;
11155 if (url.has_search()) return;
11156
11157 auto path = std::string(url.get_pathname());
11158 while (!path.empty() && path.back() == ' ') {
11159 path.resize(path.size() - 1);
11160 }
11161 url.update_base_pathname(path);
11162}
11163
11164// @ / \\ ?
11165static constexpr std::array<uint8_t, 256> authority_delimiter_special =
11166 []() constexpr {
11167 std::array<uint8_t, 256> result{};
11168 for (uint8_t i : {'@', '/', '\\', '?'}) {
11169 result[i] = 1;
11170 }
11171 return result;
11172 }();
11173// credit: @the-moisrex recommended a table-based approach
11174ada_really_inline size_t
11175find_authority_delimiter_special(std::string_view view) noexcept {
11176 // performance note: we might be able to gain further performance
11177 // with SIMD instrinsics.
11178 for (auto pos = view.begin(); pos != view.end(); ++pos) {
11179 if (authority_delimiter_special[(uint8_t)*pos]) {
11180 return pos - view.begin();
11181 }
11182 }
11183 return size_t(view.size());
11184}
11185
11186// @ / ?
11187static constexpr std::array<uint8_t, 256> authority_delimiter = []() constexpr {
11188 std::array<uint8_t, 256> result{};
11189 for (uint8_t i : {'@', '/', '?'}) {
11190 result[i] = 1;
11191 }
11192 return result;
11193}();
11194// credit: @the-moisrex recommended a table-based approach
11195ada_really_inline size_t
11196find_authority_delimiter(std::string_view view) noexcept {
11197 // performance note: we might be able to gain further performance
11198 // with SIMD instrinsics.
11199 for (auto pos = view.begin(); pos != view.end(); ++pos) {
11200 if (authority_delimiter[(uint8_t)*pos]) {
11201 return pos - view.begin();
11202 }
11203 }
11204 return size_t(view.size());
11205}
11206
11207} // namespace ada::helpers
11208
11209namespace ada {
11213#undef ada_make_uint8x16_t
11214} // namespace ada
11215/* end file src/helpers.cpp */
11216/* begin file src/url.cpp */
11217
11218#include <numeric>
11219#include <algorithm>
11220#include <string>
11221
11222namespace ada {
11223
11224bool url::parse_opaque_host(std::string_view input) {
11225 ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
11226 if (std::any_of(input.begin(), input.end(),
11227 ada::unicode::is_forbidden_host_code_point)) {
11228 return is_valid = false;
11229 }
11230
11231 // Return the result of running UTF-8 percent-encode on input using the C0
11232 // control percent-encode set.
11233 host = ada::unicode::percent_encode(
11235 return true;
11236}
11237
11238bool url::parse_ipv4(std::string_view input) {
11239 ada_log("parse_ipv4 ", input, " [", input.size(), " bytes]");
11240 if (input.back() == '.') {
11241 input.remove_suffix(1);
11242 }
11243 size_t digit_count{0};
11244 int pure_decimal_count = 0; // entries that are decimal
11245 std::string_view original_input =
11246 input; // we might use this if pure_decimal_count == 4.
11247 uint64_t ipv4{0};
11248 // we could unroll for better performance?
11249 for (; (digit_count < 4) && !(input.empty()); digit_count++) {
11250 uint32_t
11251 segment_result{}; // If any number exceeds 32 bits, we have an error.
11252 bool is_hex = checkers::has_hex_prefix(input);
11253 if (is_hex && ((input.length() == 2) ||
11254 ((input.length() > 2) && (input[2] == '.')))) {
11255 // special case
11256 segment_result = 0;
11257 input.remove_prefix(2);
11258 } else {
11259 std::from_chars_result r{};
11260 if (is_hex) {
11261 r = std::from_chars(input.data() + 2, input.data() + input.size(),
11262 segment_result, 16);
11263 } else if ((input.length() >= 2) && input[0] == '0' &&
11264 checkers::is_digit(input[1])) {
11265 r = std::from_chars(input.data() + 1, input.data() + input.size(),
11266 segment_result, 8);
11267 } else {
11268 pure_decimal_count++;
11269 r = std::from_chars(input.data(), input.data() + input.size(),
11270 segment_result, 10);
11271 }
11272 if (r.ec != std::errc()) {
11273 return is_valid = false;
11274 }
11275 input.remove_prefix(r.ptr - input.data());
11276 }
11277 if (input.empty()) {
11278 // We have the last value.
11279 // At this stage, ipv4 contains digit_count*8 bits.
11280 // So we have 32-digit_count*8 bits left.
11281 if (segment_result >= (uint64_t(1) << (32 - digit_count * 8))) {
11282 return is_valid = false;
11283 }
11284 ipv4 <<= (32 - digit_count * 8);
11285 ipv4 |= segment_result;
11286 goto final;
11287 } else {
11288 // There is more, so that the value must no be larger than 255
11289 // and we must have a '.'.
11290 if ((segment_result > 255) || (input[0] != '.')) {
11291 return is_valid = false;
11292 }
11293 ipv4 <<= 8;
11294 ipv4 |= segment_result;
11295 input.remove_prefix(1); // remove '.'
11296 }
11297 }
11298 if ((digit_count != 4) || (!input.empty())) {
11299 return is_valid = false;
11300 }
11301final:
11302 // We could also check r.ptr to see where the parsing ended.
11303 if (pure_decimal_count == 4) {
11304 host = original_input; // The original input was already all decimal and we
11305 // validated it.
11306 } else {
11307 host = ada::serializers::ipv4(ipv4); // We have to reserialize the address.
11308 }
11309 host_type = IPV4;
11310 return true;
11311}
11312
11313bool url::parse_ipv6(std::string_view input) {
11314 ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
11315
11316 if (input.empty()) {
11317 return is_valid = false;
11318 }
11319 // Let address be a new IPv6 address whose IPv6 pieces are all 0.
11320 std::array<uint16_t, 8> address{};
11321
11322 // Let pieceIndex be 0.
11323 int piece_index = 0;
11324
11325 // Let compress be null.
11326 std::optional<int> compress{};
11327
11328 // Let pointer be a pointer for input.
11329 std::string_view::iterator pointer = input.begin();
11330
11331 // If c is U+003A (:), then:
11332 if (input[0] == ':') {
11333 // If remaining does not start with U+003A (:), validation error, return
11334 // failure.
11335 if (input.size() == 1 || input[1] != ':') {
11336 ada_log("parse_ipv6 starts with : but the rest does not start with :");
11337 return is_valid = false;
11338 }
11339
11340 // Increase pointer by 2.
11341 pointer += 2;
11342
11343 // Increase pieceIndex by 1 and then set compress to pieceIndex.
11344 compress = ++piece_index;
11345 }
11346
11347 // While c is not the EOF code point:
11348 while (pointer != input.end()) {
11349 // If pieceIndex is 8, validation error, return failure.
11350 if (piece_index == 8) {
11351 ada_log("parse_ipv6 piece_index == 8");
11352 return is_valid = false;
11353 }
11354
11355 // If c is U+003A (:), then:
11356 if (*pointer == ':') {
11357 // If compress is non-null, validation error, return failure.
11358 if (compress.has_value()) {
11359 ada_log("parse_ipv6 compress is non-null");
11360 return is_valid = false;
11361 }
11362
11363 // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and
11364 // then continue.
11365 pointer++;
11366 compress = ++piece_index;
11367 continue;
11368 }
11369
11370 // Let value and length be 0.
11371 uint16_t value = 0, length = 0;
11372
11373 // While length is less than 4 and c is an ASCII hex digit,
11374 // set value to value times 0x10 + c interpreted as hexadecimal number, and
11375 // increase pointer and length by 1.
11376 while (length < 4 && pointer != input.end() &&
11377 unicode::is_ascii_hex_digit(*pointer)) {
11378 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
11379 value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));
11380 pointer++;
11381 length++;
11382 }
11383
11384 // If c is U+002E (.), then:
11385 if (pointer != input.end() && *pointer == '.') {
11386 // If length is 0, validation error, return failure.
11387 if (length == 0) {
11388 ada_log("parse_ipv6 length is 0");
11389 return is_valid = false;
11390 }
11391
11392 // Decrease pointer by length.
11393 pointer -= length;
11394
11395 // If pieceIndex is greater than 6, validation error, return failure.
11396 if (piece_index > 6) {
11397 ada_log("parse_ipv6 piece_index > 6");
11398 return is_valid = false;
11399 }
11400
11401 // Let numbersSeen be 0.
11402 int numbers_seen = 0;
11403
11404 // While c is not the EOF code point:
11405 while (pointer != input.end()) {
11406 // Let ipv4Piece be null.
11407 std::optional<uint16_t> ipv4_piece{};
11408
11409 // If numbersSeen is greater than 0, then:
11410 if (numbers_seen > 0) {
11411 // If c is a U+002E (.) and numbersSeen is less than 4, then increase
11412 // pointer by 1.
11413 if (*pointer == '.' && numbers_seen < 4) {
11414 pointer++;
11415 }
11416 // Otherwise, validation error, return failure.
11417 else {
11418 ada_log("parse_ipv6 Otherwise, validation error, return failure");
11419 return is_valid = false;
11420 }
11421 }
11422
11423 // If c is not an ASCII digit, validation error, return failure.
11424 if (pointer == input.end() || !checkers::is_digit(*pointer)) {
11425 ada_log(
11426 "parse_ipv6 If c is not an ASCII digit, validation error, return "
11427 "failure");
11428 return is_valid = false;
11429 }
11430
11431 // While c is an ASCII digit:
11432 while (pointer != input.end() && checkers::is_digit(*pointer)) {
11433 // Let number be c interpreted as decimal number.
11434 int number = *pointer - '0';
11435
11436 // If ipv4Piece is null, then set ipv4Piece to number.
11437 if (!ipv4_piece.has_value()) {
11438 ipv4_piece = number;
11439 }
11440 // Otherwise, if ipv4Piece is 0, validation error, return failure.
11441 else if (ipv4_piece == 0) {
11442 ada_log("parse_ipv6 if ipv4Piece is 0, validation error");
11443 return is_valid = false;
11444 }
11445 // Otherwise, set ipv4Piece to ipv4Piece times 10 + number.
11446 else {
11447 ipv4_piece = *ipv4_piece * 10 + number;
11448 }
11449
11450 // If ipv4Piece is greater than 255, validation error, return failure.
11451 if (ipv4_piece > 255) {
11452 ada_log("parse_ipv6 ipv4_piece > 255");
11453 return is_valid = false;
11454 }
11455
11456 // Increase pointer by 1.
11457 pointer++;
11458 }
11459
11460 // Set address[pieceIndex] to address[pieceIndex] times 0x100 +
11461 // ipv4Piece.
11462 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
11463 address[piece_index] =
11464 uint16_t(address[piece_index] * 0x100 + *ipv4_piece);
11465
11466 // Increase numbersSeen by 1.
11467 numbers_seen++;
11468
11469 // If numbersSeen is 2 or 4, then increase pieceIndex by 1.
11470 if (numbers_seen == 2 || numbers_seen == 4) {
11471 piece_index++;
11472 }
11473 }
11474
11475 // If numbersSeen is not 4, validation error, return failure.
11476 if (numbers_seen != 4) {
11477 return is_valid = false;
11478 }
11479
11480 // Break.
11481 break;
11482 }
11483 // Otherwise, if c is U+003A (:):
11484 else if ((pointer != input.end()) && (*pointer == ':')) {
11485 // Increase pointer by 1.
11486 pointer++;
11487
11488 // If c is the EOF code point, validation error, return failure.
11489 if (pointer == input.end()) {
11490 ada_log(
11491 "parse_ipv6 If c is the EOF code point, validation error, return "
11492 "failure");
11493 return is_valid = false;
11494 }
11495 }
11496 // Otherwise, if c is not the EOF code point, validation error, return
11497 // failure.
11498 else if (pointer != input.end()) {
11499 ada_log(
11500 "parse_ipv6 Otherwise, if c is not the EOF code point, validation "
11501 "error, return failure");
11502 return is_valid = false;
11503 }
11504
11505 // Set address[pieceIndex] to value.
11506 address[piece_index] = value;
11507
11508 // Increase pieceIndex by 1.
11509 piece_index++;
11510 }
11511
11512 // If compress is non-null, then:
11513 if (compress.has_value()) {
11514 // Let swaps be pieceIndex - compress.
11515 int swaps = piece_index - *compress;
11516
11517 // Set pieceIndex to 7.
11518 piece_index = 7;
11519
11520 // While pieceIndex is not 0 and swaps is greater than 0,
11521 // swap address[pieceIndex] with address[compress + swaps - 1], and then
11522 // decrease both pieceIndex and swaps by 1.
11523 while (piece_index != 0 && swaps > 0) {
11524 std::swap(address[piece_index], address[*compress + swaps - 1]);
11525 piece_index--;
11526 swaps--;
11527 }
11528 }
11529 // Otherwise, if compress is null and pieceIndex is not 8, validation error,
11530 // return failure.
11531 else if (piece_index != 8) {
11532 ada_log(
11533 "parse_ipv6 if compress is null and pieceIndex is not 8, validation "
11534 "error, return failure");
11535 return is_valid = false;
11536 }
11537 host = ada::serializers::ipv6(address);
11538 ada_log("parse_ipv6 ", *host);
11539 host_type = IPV6;
11540 return true;
11541}
11542
11543template <bool has_state_override>
11544ada_really_inline bool url::parse_scheme(const std::string_view input) {
11545 auto parsed_type = ada::scheme::get_scheme_type(input);
11546 bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
11551 if (is_input_special) { // fast path!!!
11552 if (has_state_override) {
11553 // If url's scheme is not a special scheme and buffer is a special scheme,
11554 // then return.
11555 if (is_special() != is_input_special) {
11556 return false;
11557 }
11558
11559 // If url includes credentials or has a non-null port, and buffer is
11560 // "file", then return.
11561 if ((has_credentials() || port.has_value()) &&
11562 parsed_type == ada::scheme::type::FILE) {
11563 return false;
11564 }
11565
11566 // If url's scheme is "file" and its host is an empty host, then return.
11567 // An empty host is the empty string.
11568 if (type == ada::scheme::type::FILE && host.has_value() &&
11569 host.value().empty()) {
11570 return false;
11571 }
11572 }
11573
11574 type = parsed_type;
11575
11576 if (has_state_override) {
11577 // This is uncommon.
11578 uint16_t urls_scheme_port = get_special_port();
11579
11580 if (urls_scheme_port) {
11581 // If url's port is url's scheme's default port, then set url's port to
11582 // null.
11583 if (port.has_value() && *port == urls_scheme_port) {
11584 port = std::nullopt;
11585 }
11586 }
11587 }
11588 } else { // slow path
11589 std::string _buffer(input);
11590 // Next function is only valid if the input is ASCII and returns false
11591 // otherwise, but it seems that we always have ascii content so we do not
11592 // need to check the return value.
11593 // bool is_ascii =
11594 unicode::to_lower_ascii(_buffer.data(), _buffer.size());
11595
11596 if (has_state_override) {
11597 // If url's scheme is a special scheme and buffer is not a special scheme,
11598 // then return. If url's scheme is not a special scheme and buffer is a
11599 // special scheme, then return.
11600 if (is_special() != ada::scheme::is_special(_buffer)) {
11601 return true;
11602 }
11603
11604 // If url includes credentials or has a non-null port, and buffer is
11605 // "file", then return.
11606 if ((has_credentials() || port.has_value()) && _buffer == "file") {
11607 return true;
11608 }
11609
11610 // If url's scheme is "file" and its host is an empty host, then return.
11611 // An empty host is the empty string.
11612 if (type == ada::scheme::type::FILE && host.has_value() &&
11613 host.value().empty()) {
11614 return true;
11615 }
11616 }
11617
11618 set_scheme(std::move(_buffer));
11619
11620 if (has_state_override) {
11621 // This is uncommon.
11622 uint16_t urls_scheme_port = get_special_port();
11623
11624 if (urls_scheme_port) {
11625 // If url's port is url's scheme's default port, then set url's port to
11626 // null.
11627 if (port.has_value() && *port == urls_scheme_port) {
11628 port = std::nullopt;
11629 }
11630 }
11631 }
11632 }
11633
11634 return true;
11635}
11636
11637ada_really_inline bool url::parse_host(std::string_view input) {
11638 ada_log("parse_host ", input, " [", input.size(), " bytes]");
11639 if (input.empty()) {
11640 return is_valid = false;
11641 } // technically unnecessary.
11642 // If input starts with U+005B ([), then:
11643 if (input[0] == '[') {
11644 // If input does not end with U+005D (]), validation error, return failure.
11645 if (input.back() != ']') {
11646 return is_valid = false;
11647 }
11648 ada_log("parse_host ipv6");
11649
11650 // Return the result of IPv6 parsing input with its leading U+005B ([) and
11651 // trailing U+005D (]) removed.
11652 input.remove_prefix(1);
11653 input.remove_suffix(1);
11654 return parse_ipv6(input);
11655 }
11656
11657 // If isNotSpecial is true, then return the result of opaque-host parsing
11658 // input.
11659 if (!is_special()) {
11660 return parse_opaque_host(input);
11661 }
11662 // Let domain be the result of running UTF-8 decode without BOM on the
11663 // percent-decoding of input. Let asciiDomain be the result of running domain
11664 // to ASCII with domain and false. The most common case is an ASCII input, in
11665 // which case we do not need to call the expensive 'to_ascii' if a few
11666 // conditions are met: no '%' and no 'xn-' subsequence.
11667 std::string buffer = std::string(input);
11668 // This next function checks that the result is ascii, but we are going to
11669 // to check anyhow with is_forbidden.
11670 // bool is_ascii =
11671 unicode::to_lower_ascii(buffer.data(), buffer.size());
11672 bool is_forbidden = unicode::contains_forbidden_domain_code_point(
11673 buffer.data(), buffer.size());
11674 if (is_forbidden == 0 && buffer.find("xn-") == std::string_view::npos) {
11675 // fast path
11676 host = std::move(buffer);
11677 if (checkers::is_ipv4(host.value())) {
11678 ada_log("parse_host fast path ipv4");
11679 return parse_ipv4(host.value());
11680 }
11681 ada_log("parse_host fast path ", *host);
11682 return true;
11683 }
11684 ada_log("parse_host calling to_ascii");
11685 is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
11686 if (!is_valid) {
11687 ada_log("parse_host to_ascii returns false");
11688 return is_valid = false;
11689 }
11690 ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
11691 " bytes]");
11692
11693 if (std::any_of(host.value().begin(), host.value().end(),
11694 ada::unicode::is_forbidden_domain_code_point)) {
11695 host = std::nullopt;
11696 return is_valid = false;
11697 }
11698
11699 // If asciiDomain ends in a number, then return the result of IPv4 parsing
11700 // asciiDomain.
11701 if (checkers::is_ipv4(host.value())) {
11702 ada_log("parse_host got ipv4 ", *host);
11703 return parse_ipv4(host.value());
11704 }
11705
11706 return true;
11707}
11708
11709ada_really_inline void url::parse_path(std::string_view input) {
11710 ada_log("parse_path ", input);
11711 std::string tmp_buffer;
11712 std::string_view internal_input;
11713 if (unicode::has_tabs_or_newline(input)) {
11714 tmp_buffer = input;
11715 // Optimization opportunity: Instead of copying and then pruning, we could
11716 // just directly build the string from user_input.
11717 helpers::remove_ascii_tab_or_newline(tmp_buffer);
11718 internal_input = tmp_buffer;
11719 } else {
11720 internal_input = input;
11721 }
11722
11723 // If url is special, then:
11724 if (is_special()) {
11725 if (internal_input.empty()) {
11726 path = "/";
11727 } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
11728 helpers::parse_prepared_path(internal_input.substr(1), type, path);
11729 return;
11730 } else {
11731 helpers::parse_prepared_path(internal_input, type, path);
11732 return;
11733 }
11734 } else if (!internal_input.empty()) {
11735 if (internal_input[0] == '/') {
11736 helpers::parse_prepared_path(internal_input.substr(1), type, path);
11737 return;
11738 } else {
11739 helpers::parse_prepared_path(internal_input, type, path);
11740 return;
11741 }
11742 } else {
11743 if (!host.has_value()) {
11744 path = "/";
11745 }
11746 }
11747}
11748
11749[[nodiscard]] std::string url::to_string() const {
11750 if (!is_valid) {
11751 return "null";
11752 }
11753 std::string answer;
11754 auto back = std::back_insert_iterator(answer);
11755 answer.append("{\n");
11756 answer.append("\t\"protocol\":\"");
11757 helpers::encode_json(get_protocol(), back);
11758 answer.append("\",\n");
11759 if (has_credentials()) {
11760 answer.append("\t\"username\":\"");
11761 helpers::encode_json(username, back);
11762 answer.append("\",\n");
11763 answer.append("\t\"password\":\"");
11764 helpers::encode_json(password, back);
11765 answer.append("\",\n");
11766 }
11767 if (host.has_value()) {
11768 answer.append("\t\"host\":\"");
11769 helpers::encode_json(host.value(), back);
11770 answer.append("\",\n");
11771 }
11772 if (port.has_value()) {
11773 answer.append("\t\"port\":\"");
11774 answer.append(std::to_string(port.value()));
11775 answer.append("\",\n");
11776 }
11777 answer.append("\t\"path\":\"");
11778 helpers::encode_json(path, back);
11779 answer.append("\",\n");
11780 answer.append("\t\"opaque path\":");
11781 answer.append((has_opaque_path ? "true" : "false"));
11782 if (has_search()) {
11783 answer.append(",\n");
11784 answer.append("\t\"query\":\"");
11785 helpers::encode_json(query.value(), back);
11786 answer.append("\"");
11787 }
11788 if (hash.has_value()) {
11789 answer.append(",\n");
11790 answer.append("\t\"hash\":\"");
11791 helpers::encode_json(hash.value(), back);
11792 answer.append("\"");
11793 }
11794 answer.append("\n}");
11795 return answer;
11796}
11797
11798[[nodiscard]] bool url::has_valid_domain() const noexcept {
11799 if (!host.has_value()) {
11800 return false;
11801 }
11802 return checkers::verify_dns_length(host.value());
11803}
11804
11805} // namespace ada
11806/* end file src/url.cpp */
11807/* begin file src/url-getters.cpp */
11813#include <string>
11814
11815namespace ada {
11816[[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
11842[[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
11850[[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
11864[[nodiscard]] std::string url::get_hostname() const noexcept {
11865 return host.value_or("");
11866}
11867
11868[[nodiscard]] std::string_view url::get_pathname() const noexcept {
11869 return path;
11870}
11871
11872[[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
11879[[nodiscard]] const std::string& url::get_username() const noexcept {
11880 return username;
11881}
11882
11883[[nodiscard]] const std::string& url::get_password() const noexcept {
11884 return password;
11885}
11886
11887[[nodiscard]] std::string url::get_port() const noexcept {
11888 return port.has_value() ? std::to_string(port.value()) : "";
11889}
11890
11891[[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 */
11906#include <optional>
11907#include <string>
11908
11909namespace ada {
11910
11911template <bool override_hostname>
11912bool 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
11993bool url::set_host(const std::string_view input) {
11994 return set_host_or_hostname<false>(input);
11995}
11996
11997bool url::set_hostname(const std::string_view input) {
11998 return set_host_or_hostname<true>(input);
11999}
12000
12001bool 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
12010bool 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
12019bool 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
12049void 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,
12061}
12062
12063void url::set_search(const std::string_view input) {
12064 if (input.empty()) {
12065 query = std::nullopt;
12066 helpers::strip_trailing_spaces_from_opaque_path(*this);
12067 return;
12068 }
12069
12070 std::string new_value;
12071 new_value = input[0] == '?' ? input.substr(1) : input;
12072 helpers::remove_ascii_tab_or_newline(new_value);
12073
12074 auto query_percent_encode_set =
12077
12078 query = ada::unicode::percent_encode(std::string_view(new_value),
12079 query_percent_encode_set);
12080}
12081
12082bool url::set_pathname(const std::string_view input) {
12083 if (has_opaque_path) {
12084 return false;
12085 }
12086 path = "";
12087 parse_path(input);
12088 return true;
12089}
12090
12091bool url::set_protocol(const std::string_view input) {
12092 std::string view(input);
12093 helpers::remove_ascii_tab_or_newline(view);
12094 if (view.empty()) {
12095 return true;
12096 }
12097
12098 // Schemes should start with alpha values.
12099 if (!checkers::is_alpha(view[0])) {
12100 return false;
12101 }
12102
12103 view.append(":");
12104
12105 std::string::iterator pointer =
12106 std::find_if_not(view.begin(), view.end(), unicode::is_alnum_plus);
12107
12108 if (pointer != view.end() && *pointer == ':') {
12109 return parse_scheme<true>(
12110 std::string_view(view.data(), pointer - view.begin()));
12111 }
12112 return false;
12113}
12114
12115bool url::set_href(const std::string_view input) {
12117
12118 if (out) {
12119 username = out->username;
12120 password = out->password;
12121 host = out->host;
12122 port = out->port;
12123 path = out->path;
12124 query = out->query;
12125 hash = out->hash;
12126 type = out->type;
12127 non_special_scheme = out->non_special_scheme;
12128 has_opaque_path = out->has_opaque_path;
12129 }
12130
12131 return out.has_value();
12132}
12133
12134} // namespace ada
12135/* end file src/url-setters.cpp */
12136/* begin file src/parser.cpp */
12137
12138#include <limits>
12139
12140
12141namespace ada::parser {
12142
12143template <class result_type, bool store_values>
12144result_type parse_url_impl(std::string_view user_input,
12145 const result_type* base_url) {
12146 // We can specialize the implementation per type.
12147 // Important: result_type_is_ada_url is evaluated at *compile time*. This
12148 // means that doing if constexpr(result_type_is_ada_url) { something } else {
12149 // something else } is free (at runtime). This means that ada::url_aggregator
12150 // and ada::url **do not have to support the exact same API**.
12151 constexpr bool result_type_is_ada_url =
12152 std::is_same<ada::url, result_type>::value;
12153 constexpr bool result_type_is_ada_url_aggregator =
12154 std::is_same<ada::url_aggregator, result_type>::value;
12155 static_assert(result_type_is_ada_url ||
12156 result_type_is_ada_url_aggregator); // We don't support
12157 // anything else for now.
12158
12159 ada_log("ada::parser::parse_url('", user_input, "' [", user_input.size(),
12160 " bytes],", (base_url != nullptr ? base_url->to_string() : "null"),
12161 ")");
12162
12164 result_type url{};
12165
12166 // We refuse to parse URL strings that exceed 4GB. Such strings are almost
12167 // surely the result of a bug or are otherwise a security concern.
12168 if (user_input.size() > std::numeric_limits<uint32_t>::max()) {
12169 url.is_valid = false;
12170 }
12171 // Going forward, user_input.size() is in [0,
12172 // std::numeric_limits<uint32_t>::max). If we are provided with an invalid
12173 // base, or the optional_url was invalid, we must return.
12174 if (base_url != nullptr) {
12175 url.is_valid &= base_url->is_valid;
12176 }
12177 if (!url.is_valid) {
12178 return url;
12179 }
12180 if constexpr (result_type_is_ada_url_aggregator && store_values) {
12181 // Most of the time, we just need user_input.size().
12182 // In some instances, we may need a bit more.
12184 // This is *very* important. This line should *not* be removed
12185 // hastily. There are principled reasons why reserve is important
12186 // for performance. If you have a benchmark with small inputs,
12187 // it may not matter, but in other instances, it could.
12189 // This rounds up to the next power of two.
12190 // We know that user_input.size() is in [0,
12191 // std::numeric_limits<uint32_t>::max).
12192 uint32_t reserve_capacity =
12193 (0xFFFFFFFF >>
12194 helpers::leading_zeroes(uint32_t(1 | user_input.size()))) +
12195 1;
12196 url.reserve(reserve_capacity);
12197 }
12198 std::string tmp_buffer;
12199 std::string_view internal_input;
12200 if (unicode::has_tabs_or_newline(user_input)) {
12201 tmp_buffer = user_input;
12202 // Optimization opportunity: Instead of copying and then pruning, we could
12203 // just directly build the string from user_input.
12204 helpers::remove_ascii_tab_or_newline(tmp_buffer);
12205 internal_input = tmp_buffer;
12206 } else {
12207 internal_input = user_input;
12208 }
12209
12210 // Leading and trailing control characters are uncommon and easy to deal with
12211 // (no performance concern).
12212 std::string_view url_data = internal_input;
12213 helpers::trim_c0_whitespace(url_data);
12214
12215 // Optimization opportunity. Most websites do not have fragment.
12216 std::optional<std::string_view> fragment = helpers::prune_hash(url_data);
12217 // We add it last so that an implementation like ada::url_aggregator
12218 // can append it last to its internal buffer, thus improving performance.
12219
12220 // Here url_data no longer has its fragment.
12221 // We are going to access the data from url_data (it is immutable).
12222 // At any given time, we are pointing at byte 'input_position' in url_data.
12223 // The input_position variable should range from 0 to input_size.
12224 // It is illegal to access url_data at input_size.
12225 size_t input_position = 0;
12226 const size_t input_size = url_data.size();
12227 // Keep running the following state machine by switching on state.
12228 // If after a run pointer points to the EOF code point, go to the next step.
12229 // Otherwise, increase pointer by 1 and continue with the state machine.
12230 // We never decrement input_position.
12231 while (input_position <= input_size) {
12232 ada_log("In parsing at ", input_position, " out of ", input_size,
12233 " in state ", ada::to_string(state));
12234 switch (state) {
12236 ada_log("SCHEME_START ", helpers::substring(url_data, input_position));
12237 // If c is an ASCII alpha, append c, lowercased, to buffer, and set
12238 // state to scheme state.
12239 if ((input_position != input_size) &&
12240 checkers::is_alpha(url_data[input_position])) {
12242 input_position++;
12243 } else {
12244 // Otherwise, if state override is not given, set state to no scheme
12245 // state and decrease pointer by 1.
12247 }
12248 break;
12249 }
12250 case ada::state::SCHEME: {
12251 ada_log("SCHEME ", helpers::substring(url_data, input_position));
12252 // If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E (.),
12253 // append c, lowercased, to buffer.
12254 while ((input_position != input_size) &&
12255 (ada::unicode::is_alnum_plus(url_data[input_position]))) {
12256 input_position++;
12257 }
12258 // Otherwise, if c is U+003A (:), then:
12259 if ((input_position != input_size) &&
12260 (url_data[input_position] == ':')) {
12261 ada_log("SCHEME the scheme should be ",
12262 url_data.substr(0, input_position));
12263 if constexpr (result_type_is_ada_url) {
12264 if (!url.parse_scheme(url_data.substr(0, input_position))) {
12265 return url;
12266 }
12267 } else {
12268 // we pass the colon along instead of painfully adding it back.
12269 if (!url.parse_scheme_with_colon(
12270 url_data.substr(0, input_position + 1))) {
12271 return url;
12272 }
12273 }
12274 ada_log("SCHEME the scheme is ", url.get_protocol());
12275
12276 // If url's scheme is "file", then:
12277 if (url.type == ada::scheme::type::FILE) {
12278 // Set state to file state.
12280 }
12281 // Otherwise, if url is special, base is non-null, and base's scheme
12282 // is url's scheme: Note: Doing base_url->scheme is unsafe if base_url
12283 // != nullptr is false.
12284 else if (url.is_special() && base_url != nullptr &&
12285 base_url->type == url.type) {
12286 // Set state to special relative or authority state.
12288 }
12289 // Otherwise, if url is special, set state to special authority
12290 // slashes state.
12291 else if (url.is_special()) {
12293 }
12294 // Otherwise, if remaining starts with an U+002F (/), set state to
12295 // path or authority state and increase pointer by 1.
12296 else if (input_position + 1 < input_size &&
12297 url_data[input_position + 1] == '/') {
12299 input_position++;
12300 }
12301 // Otherwise, set url's path to the empty string and set state to
12302 // opaque path state.
12303 else {
12305 }
12306 }
12307 // Otherwise, if state override is not given, set buffer to the empty
12308 // string, state to no scheme state, and start over (from the first code
12309 // point in input).
12310 else {
12312 input_position = 0;
12313 break;
12314 }
12315 input_position++;
12316 break;
12317 }
12318 case ada::state::NO_SCHEME: {
12319 ada_log("NO_SCHEME ", helpers::substring(url_data, input_position));
12320 // If base is null, or base has an opaque path and c is not U+0023 (#),
12321 // validation error, return failure.
12322 if (base_url == nullptr ||
12323 (base_url->has_opaque_path && !fragment.has_value())) {
12324 ada_log("NO_SCHEME validation error");
12325 url.is_valid = false;
12326 return url;
12327 }
12328 // Otherwise, if base has an opaque path and c is U+0023 (#),
12329 // set url's scheme to base's scheme, url's path to base's path, url's
12330 // query to base's query, and set state to fragment state.
12331 else if (base_url->has_opaque_path && fragment.has_value() &&
12332 input_position == input_size) {
12333 ada_log("NO_SCHEME opaque base with fragment");
12334 url.copy_scheme(*base_url);
12335 url.has_opaque_path = base_url->has_opaque_path;
12336
12337 if constexpr (result_type_is_ada_url) {
12338 url.path = base_url->path;
12339 url.query = base_url->query;
12340 } else {
12341 url.update_base_pathname(base_url->get_pathname());
12342 url.update_base_search(base_url->get_search());
12343 }
12344 url.update_unencoded_base_hash(*fragment);
12345 return url;
12346 }
12347 // Otherwise, if base's scheme is not "file", set state to relative
12348 // state and decrease pointer by 1.
12349 else if (base_url->type != ada::scheme::type::FILE) {
12350 ada_log("NO_SCHEME non-file relative path");
12352 }
12353 // Otherwise, set state to file state and decrease pointer by 1.
12354 else {
12355 ada_log("NO_SCHEME file base type");
12357 }
12358 break;
12359 }
12360 case ada::state::AUTHORITY: {
12361 ada_log("AUTHORITY ", helpers::substring(url_data, input_position));
12362 // most URLs have no @. Having no @ tells us that we don't have to worry
12363 // about AUTHORITY. Of course, we could have @ and still not have to
12364 // worry about AUTHORITY.
12365 // TODO: Instead of just collecting a bool, collect the location of the
12366 // '@' and do something useful with it.
12367 // TODO: We could do various processing early on, using a single pass
12368 // over the string to collect information about it, e.g., telling us
12369 // whether there is a @ and if so, where (or how many).
12370 const bool contains_ampersand =
12371 (url_data.find('@', input_position) != std::string_view::npos);
12372
12373 if (!contains_ampersand) {
12375 break;
12376 }
12377 bool at_sign_seen{false};
12378 bool password_token_seen{false};
12384 do {
12385 std::string_view view = helpers::substring(url_data, input_position);
12386 // The delimiters are @, /, ? \\.
12387 size_t location =
12388 url.is_special() ? helpers::find_authority_delimiter_special(view)
12389 : helpers::find_authority_delimiter(view);
12390 std::string_view authority_view(view.data(), location);
12391 size_t end_of_authority = input_position + authority_view.size();
12392 // If c is U+0040 (@), then:
12393 if ((end_of_authority != input_size) &&
12394 (url_data[end_of_authority] == '@')) {
12395 // If atSignSeen is true, then prepend "%40" to buffer.
12396 if (at_sign_seen) {
12397 if (password_token_seen) {
12398 if constexpr (result_type_is_ada_url) {
12399 url.password += "%40";
12400 } else {
12401 url.append_base_password("%40");
12402 }
12403 } else {
12404 if constexpr (result_type_is_ada_url) {
12405 url.username += "%40";
12406 } else {
12407 url.append_base_username("%40");
12408 }
12409 }
12410 }
12411
12412 at_sign_seen = true;
12413
12414 if (!password_token_seen) {
12415 size_t password_token_location = authority_view.find(':');
12416 password_token_seen =
12417 password_token_location != std::string_view::npos;
12418
12419 if constexpr (store_values) {
12420 if (!password_token_seen) {
12421 if constexpr (result_type_is_ada_url) {
12422 url.username += unicode::percent_encode(
12423 authority_view,
12424 character_sets::USERINFO_PERCENT_ENCODE);
12425 } else {
12426 url.append_base_username(unicode::percent_encode(
12427 authority_view,
12428 character_sets::USERINFO_PERCENT_ENCODE));
12429 }
12430 } else {
12431 if constexpr (result_type_is_ada_url) {
12432 url.username += unicode::percent_encode(
12433 authority_view.substr(0, password_token_location),
12434 character_sets::USERINFO_PERCENT_ENCODE);
12435 url.password += unicode::percent_encode(
12436 authority_view.substr(password_token_location + 1),
12437 character_sets::USERINFO_PERCENT_ENCODE);
12438 } else {
12439 url.append_base_username(unicode::percent_encode(
12440 authority_view.substr(0, password_token_location),
12441 character_sets::USERINFO_PERCENT_ENCODE));
12442 url.append_base_password(unicode::percent_encode(
12443 authority_view.substr(password_token_location + 1),
12444 character_sets::USERINFO_PERCENT_ENCODE));
12445 }
12446 }
12447 }
12448 } else if constexpr (store_values) {
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 }
12472 break;
12473 }
12474 if (end_of_authority == input_size) {
12475 if constexpr (store_values) {
12476 if (fragment.has_value()) {
12477 url.update_unencoded_base_hash(*fragment);
12478 }
12479 }
12480 return url;
12481 }
12482 input_position = end_of_authority + 1;
12483 } while (true);
12484
12485 break;
12486 }
12488 ada_log("SPECIAL_RELATIVE_OR_AUTHORITY ",
12489 helpers::substring(url_data, input_position));
12490
12491 // If c is U+002F (/) and remaining starts with U+002F (/),
12492 // then set state to special authority ignore slashes state and increase
12493 // pointer by 1.
12494 std::string_view view = helpers::substring(url_data, input_position);
12495 if (ada::checkers::begins_with(view, "//")) {
12497 input_position += 2;
12498 } else {
12499 // Otherwise, validation error, set state to relative state and
12500 // decrease pointer by 1.
12502 }
12503
12504 break;
12505 }
12507 ada_log("PATH_OR_AUTHORITY ",
12508 helpers::substring(url_data, input_position));
12509
12510 // If c is U+002F (/), then set state to authority state.
12511 if ((input_position != input_size) &&
12512 (url_data[input_position] == '/')) {
12514 input_position++;
12515 } else {
12516 // Otherwise, set state to path state, and decrease pointer by 1.
12518 }
12519
12520 break;
12521 }
12523 ada_log("RELATIVE_SCHEME ",
12524 helpers::substring(url_data, input_position));
12525
12526 // Set url's scheme to base's scheme.
12527 url.copy_scheme(*base_url);
12528
12529 // If c is U+002F (/), then set state to relative slash state.
12530 if ((input_position != input_size) &&
12531 (url_data[input_position] == '/')) {
12532 ada_log(
12533 "RELATIVE_SCHEME if c is U+002F (/), then set state to relative "
12534 "slash state");
12536 } else if (url.is_special() && (input_position != input_size) &&
12537 (url_data[input_position] == '\\')) {
12538 // Otherwise, if url is special and c is U+005C (\‍), validation error,
12539 // set state to relative slash state.
12540 ada_log(
12541 "RELATIVE_SCHEME if url is special and c is U+005C, validation "
12542 "error, set state to relative slash state");
12544 } else {
12545 ada_log("RELATIVE_SCHEME otherwise");
12546 // Set url's username to base's username, url's password to base's
12547 // password, url's host to base's host, url's port to base's port,
12548 // url's path to a clone of base's path, and url's query to base's
12549 // query.
12550 if constexpr (result_type_is_ada_url) {
12551 url.username = base_url->username;
12552 url.password = base_url->password;
12553 url.host = base_url->host;
12554 url.port = base_url->port;
12555 // cloning the base path includes cloning the has_opaque_path flag
12556 url.has_opaque_path = base_url->has_opaque_path;
12557 url.path = base_url->path;
12558 url.query = base_url->query;
12559 } else {
12560 url.update_base_authority(base_url->get_href(),
12561 base_url->get_components());
12562 // TODO: Get rid of set_hostname and replace it with
12563 // update_base_hostname
12564 url.set_hostname(base_url->get_hostname());
12565 url.update_base_port(base_url->retrieve_base_port());
12566 // cloning the base path includes cloning the has_opaque_path flag
12567 url.has_opaque_path = base_url->has_opaque_path;
12568 url.update_base_pathname(base_url->get_pathname());
12569 url.update_base_search(base_url->get_search());
12570 }
12571
12572 url.has_opaque_path = base_url->has_opaque_path;
12573
12574 // If c is U+003F (?), then set url's query to the empty string, and
12575 // state to query state.
12576 if ((input_position != input_size) &&
12577 (url_data[input_position] == '?')) {
12579 }
12580 // Otherwise, if c is not the EOF code point:
12581 else if (input_position != input_size) {
12582 // Set url's query to null.
12583 url.clear_search();
12584 if constexpr (result_type_is_ada_url) {
12585 // Shorten url's path.
12586 helpers::shorten_path(url.path, url.type);
12587 } else {
12588 std::string_view path = url.get_pathname();
12589 if (helpers::shorten_path(path, url.type)) {
12590 url.update_base_pathname(std::string(path));
12591 }
12592 }
12593 // Set state to path state and decrease pointer by 1.
12595 break;
12596 }
12597 }
12598 input_position++;
12599 break;
12600 }
12602 ada_log("RELATIVE_SLASH ",
12603 helpers::substring(url_data, input_position));
12604
12605 // If url is special and c is U+002F (/) or U+005C (\‍), then:
12606 if (url.is_special() && (input_position != input_size) &&
12607 (url_data[input_position] == '/' ||
12608 url_data[input_position] == '\\')) {
12609 // Set state to special authority ignore slashes state.
12611 }
12612 // Otherwise, if c is U+002F (/), then set state to authority state.
12613 else if ((input_position != input_size) &&
12614 (url_data[input_position] == '/')) {
12616 }
12617 // Otherwise, set
12618 // - url's username to base's username,
12619 // - url's password to base's password,
12620 // - url's host to base's host,
12621 // - url's port to base's port,
12622 // - state to path state, and then, decrease pointer by 1.
12623 else {
12624 if constexpr (result_type_is_ada_url) {
12625 url.username = base_url->username;
12626 url.password = base_url->password;
12627 url.host = base_url->host;
12628 url.port = base_url->port;
12629 } else {
12630 url.update_base_authority(base_url->get_href(),
12631 base_url->get_components());
12632 // TODO: Get rid of set_hostname and replace it with
12633 // update_base_hostname
12634 url.set_hostname(base_url->get_hostname());
12635 url.update_base_port(base_url->retrieve_base_port());
12636 }
12638 break;
12639 }
12640
12641 input_position++;
12642 break;
12643 }
12645 ada_log("SPECIAL_AUTHORITY_SLASHES ",
12646 helpers::substring(url_data, input_position));
12647
12648 // If c is U+002F (/) and remaining starts with U+002F (/),
12649 // then set state to special authority ignore slashes state and increase
12650 // pointer by 1.
12651 std::string_view view = helpers::substring(url_data, input_position);
12652 if (ada::checkers::begins_with(view, "//")) {
12653 input_position += 2;
12654 }
12655
12656 [[fallthrough]];
12657 }
12659 ada_log("SPECIAL_AUTHORITY_IGNORE_SLASHES ",
12660 helpers::substring(url_data, input_position));
12661
12662 // If c is neither U+002F (/) nor U+005C (\‍), then set state to
12663 // authority state and decrease pointer by 1.
12664 while ((input_position != input_size) &&
12665 ((url_data[input_position] == '/') ||
12666 (url_data[input_position] == '\\'))) {
12667 input_position++;
12668 }
12670
12671 break;
12672 }
12673 case ada::state::QUERY: {
12674 ada_log("QUERY ", helpers::substring(url_data, input_position));
12675 if constexpr (store_values) {
12676 // Let queryPercentEncodeSet be the special-query percent-encode set
12677 // if url is special; otherwise the query percent-encode set.
12678 const uint8_t* query_percent_encode_set =
12679 url.is_special()
12682
12683 // Percent-encode after encoding, with encoding, buffer, and
12684 // queryPercentEncodeSet, and append the result to url's query.
12685 url.update_base_search(helpers::substring(url_data, input_position),
12686 query_percent_encode_set);
12687 ada_log("QUERY update_base_search completed ");
12688 if (fragment.has_value()) {
12689 url.update_unencoded_base_hash(*fragment);
12690 }
12691 }
12692 return url;
12693 }
12694 case ada::state::HOST: {
12695 ada_log("HOST ", helpers::substring(url_data, input_position));
12696
12697 std::string_view host_view =
12698 helpers::substring(url_data, input_position);
12699 auto [location, found_colon] =
12700 helpers::get_host_delimiter_location(url.is_special(), host_view);
12701 input_position = (location != std::string_view::npos)
12702 ? input_position + location
12703 : input_size;
12704 // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
12705 // Note: the 'found_colon' value is true if and only if a colon was
12706 // encountered while not inside brackets.
12707 if (found_colon) {
12708 // If buffer is the empty string, validation error, return failure.
12709 // Let host be the result of host parsing buffer with url is not
12710 // special.
12711 ada_log("HOST parsing ", host_view);
12712 if (!url.parse_host(host_view)) {
12713 return url;
12714 }
12715 ada_log("HOST parsing results in ", url.get_hostname());
12716 // Set url's host to host, buffer to the empty string, and state to
12717 // port state.
12719 input_position++;
12720 }
12721 // Otherwise, if one of the following is true:
12722 // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
12723 // - url is special and c is U+005C (\‍)
12724 // The get_host_delimiter_location function either brings us to
12725 // the colon outside of the bracket, or to one of those characters.
12726 else {
12727 // If url is special and host_view is the empty string, validation
12728 // error, return failure.
12729 if (url.is_special() && host_view.empty()) {
12730 url.is_valid = false;
12731 return url;
12732 }
12733 ada_log("HOST parsing ", host_view, " href=", url.get_href());
12734 // Let host be the result of host parsing host_view with url is not
12735 // special.
12736 if (host_view.empty()) {
12737 url.update_base_hostname("");
12738 } else if (!url.parse_host(host_view)) {
12739 return url;
12740 }
12741 ada_log("HOST parsing results in ", url.get_hostname(),
12742 " href=", url.get_href());
12743
12744 // Set url's host to host, and state to path start state.
12746 }
12747
12748 break;
12749 }
12751 ada_log("OPAQUE_PATH ", helpers::substring(url_data, input_position));
12752 std::string_view view = helpers::substring(url_data, input_position);
12753 // If c is U+003F (?), then set url's query to the empty string and
12754 // state to query state.
12755 size_t location = view.find('?');
12756 if (location != std::string_view::npos) {
12757 view.remove_suffix(view.size() - location);
12759 input_position += location + 1;
12760 } else {
12761 input_position = input_size + 1;
12762 }
12763 url.has_opaque_path = true;
12764 // This is a really unlikely scenario in real world. We should not seek
12765 // to optimize it.
12766 url.update_base_pathname(unicode::percent_encode(
12767 view, character_sets::C0_CONTROL_PERCENT_ENCODE));
12768 break;
12769 }
12770 case ada::state::PORT: {
12771 ada_log("PORT ", helpers::substring(url_data, input_position));
12772 std::string_view port_view =
12773 helpers::substring(url_data, input_position);
12774 size_t consumed_bytes = url.parse_port(port_view, true);
12775 input_position += consumed_bytes;
12776 if (!url.is_valid) {
12777 return url;
12778 }
12779 state = state::PATH_START;
12780 [[fallthrough]];
12781 }
12783 ada_log("PATH_START ", helpers::substring(url_data, input_position));
12784
12785 // If url is special, then:
12786 if (url.is_special()) {
12787 // Set state to path state.
12789
12790 // Optimization: Avoiding going into PATH state improves the
12791 // performance of urls ending with /.
12792 if (input_position == input_size) {
12793 if constexpr (store_values) {
12794 url.update_base_pathname("/");
12795 if (fragment.has_value()) {
12796 url.update_unencoded_base_hash(*fragment);
12797 }
12798 }
12799 return url;
12800 }
12801 // If c is neither U+002F (/) nor U+005C (\‍), then decrease pointer
12802 // by 1. We know that (input_position == input_size) is impossible
12803 // here, because of the previous if-check.
12804 if ((url_data[input_position] != '/') &&
12805 (url_data[input_position] != '\\')) {
12806 break;
12807 }
12808 }
12809 // Otherwise, if state override is not given and c is U+003F (?),
12810 // set url's query to the empty string and state to query state.
12811 else if ((input_position != input_size) &&
12812 (url_data[input_position] == '?')) {
12814 }
12815 // Otherwise, if c is not the EOF code point:
12816 else if (input_position != input_size) {
12817 // Set state to path state.
12819
12820 // If c is not U+002F (/), then decrease pointer by 1.
12821 if (url_data[input_position] != '/') {
12822 break;
12823 }
12824 }
12825
12826 input_position++;
12827 break;
12828 }
12829 case ada::state::PATH: {
12830 std::string_view view = helpers::substring(url_data, input_position);
12831 ada_log("PATH ", helpers::substring(url_data, input_position));
12832
12833 // Most time, we do not need percent encoding.
12834 // Furthermore, we can immediately locate the '?'.
12835 size_t locofquestionmark = view.find('?');
12836 if (locofquestionmark != std::string_view::npos) {
12838 view.remove_suffix(view.size() - locofquestionmark);
12839 input_position += locofquestionmark + 1;
12840 } else {
12841 input_position = input_size + 1;
12842 }
12843 if constexpr (store_values) {
12844 if constexpr (result_type_is_ada_url) {
12845 helpers::parse_prepared_path(view, url.type, url.path);
12846 } else {
12847 url.consume_prepared_path(view);
12848 ADA_ASSERT_TRUE(url.validate());
12849 }
12850 }
12851 break;
12852 }
12854 ada_log("FILE_SLASH ", helpers::substring(url_data, input_position));
12855
12856 // If c is U+002F (/) or U+005C (\‍), then:
12857 if ((input_position != input_size) &&
12858 (url_data[input_position] == '/' ||
12859 url_data[input_position] == '\\')) {
12860 ada_log("FILE_SLASH c is U+002F or U+005C");
12861 // Set state to file host state.
12863 input_position++;
12864 } else {
12865 ada_log("FILE_SLASH otherwise");
12866 // If base is non-null and base's scheme is "file", then:
12867 // Note: it is unsafe to do base_url->scheme unless you know that
12868 // base_url_has_value() is true.
12869 if (base_url != nullptr &&
12870 base_url->type == ada::scheme::type::FILE) {
12871 // Set url's host to base's host.
12872 if constexpr (result_type_is_ada_url) {
12873 url.host = base_url->host;
12874 } else {
12875 // TODO: Optimization opportunity.
12876 url.set_host(base_url->get_host());
12877 }
12878 // If the code point substring from pointer to the end of input does
12879 // not start with a Windows drive letter and base's path[0] is a
12880 // normalized Windows drive letter, then append base's path[0] to
12881 // url's path.
12882 if (!base_url->get_pathname().empty()) {
12883 if (!checkers::is_windows_drive_letter(
12884 helpers::substring(url_data, input_position))) {
12885 std::string_view first_base_url_path =
12886 base_url->get_pathname().substr(1);
12887 size_t loc = first_base_url_path.find('/');
12888 if (loc != std::string_view::npos) {
12889 helpers::resize(first_base_url_path, loc);
12890 }
12891 if (checkers::is_normalized_windows_drive_letter(
12892 first_base_url_path)) {
12893 if constexpr (result_type_is_ada_url) {
12894 url.path += '/';
12895 url.path += first_base_url_path;
12896 } else {
12897 url.append_base_pathname(
12898 helpers::concat("/", first_base_url_path));
12899 }
12900 }
12901 }
12902 }
12903 }
12904
12905 // Set state to path state, and decrease pointer by 1.
12907 }
12908
12909 break;
12910 }
12911 case ada::state::FILE_HOST: {
12912 std::string_view view = helpers::substring(url_data, input_position);
12913 ada_log("FILE_HOST ", helpers::substring(url_data, input_position));
12914
12915 size_t location = view.find_first_of("/\\?");
12916 std::string_view file_host_buffer(
12917 view.data(),
12918 (location != std::string_view::npos) ? location : view.size());
12919
12920 if (checkers::is_windows_drive_letter(file_host_buffer)) {
12922 } else if (file_host_buffer.empty()) {
12923 // Set url's host to the empty string.
12924 if constexpr (result_type_is_ada_url) {
12925 url.host = "";
12926 } else {
12927 url.update_base_hostname("");
12928 }
12929 // Set state to path start state.
12931 } else {
12932 size_t consumed_bytes = file_host_buffer.size();
12933 input_position += consumed_bytes;
12934 // Let host be the result of host parsing buffer with url is not
12935 // special.
12936 if (!url.parse_host(file_host_buffer)) {
12937 return url;
12938 }
12939
12940 if constexpr (result_type_is_ada_url) {
12941 // If host is "localhost", then set host to the empty string.
12942 if (url.host.has_value() && url.host.value() == "localhost") {
12943 url.host = "";
12944 }
12945 } else {
12946 if (url.get_hostname() == "localhost") {
12947 url.update_base_hostname("");
12948 }
12949 }
12950
12951 // Set buffer to the empty string and state to path start state.
12953 }
12954
12955 break;
12956 }
12957 case ada::state::FILE: {
12958 ada_log("FILE ", helpers::substring(url_data, input_position));
12959 std::string_view file_view =
12960 helpers::substring(url_data, input_position);
12961
12962 url.set_protocol_as_file();
12963 if constexpr (result_type_is_ada_url) {
12964 // Set url's host to the empty string.
12965 url.host = "";
12966 } else {
12967 url.update_base_hostname("");
12968 }
12969 // If c is U+002F (/) or U+005C (\‍), then:
12970 if (input_position != input_size &&
12971 (url_data[input_position] == '/' ||
12972 url_data[input_position] == '\\')) {
12973 ada_log("FILE c is U+002F or U+005C");
12974 // Set state to file slash state.
12976 }
12977 // Otherwise, if base is non-null and base's scheme is "file":
12978 else if (base_url != nullptr &&
12979 base_url->type == ada::scheme::type::FILE) {
12980 // Set url's host to base's host, url's path to a clone of base's
12981 // path, and url's query to base's query.
12982 ada_log("FILE base non-null");
12983 if constexpr (result_type_is_ada_url) {
12984 url.host = base_url->host;
12985 url.path = base_url->path;
12986 url.query = base_url->query;
12987 } else {
12988 // TODO: Get rid of set_hostname and replace it with
12989 // update_base_hostname
12990 url.set_hostname(base_url->get_hostname());
12991 url.update_base_pathname(base_url->get_pathname());
12992 url.update_base_search(base_url->get_search());
12993 }
12994 url.has_opaque_path = base_url->has_opaque_path;
12995
12996 // If c is U+003F (?), then set url's query to the empty string and
12997 // state to query state.
12998 if (input_position != input_size && url_data[input_position] == '?') {
13000 }
13001 // Otherwise, if c is not the EOF code point:
13002 else if (input_position != input_size) {
13003 // Set url's query to null.
13004 url.clear_search();
13005 // If the code point substring from pointer to the end of input does
13006 // not start with a Windows drive letter, then shorten url's path.
13007 if (!checkers::is_windows_drive_letter(file_view)) {
13008 if constexpr (result_type_is_ada_url) {
13009 helpers::shorten_path(url.path, url.type);
13010 } else {
13011 std::string_view path = url.get_pathname();
13012 if (helpers::shorten_path(path, url.type)) {
13013 url.update_base_pathname(std::string(path));
13014 }
13015 }
13016 }
13017 // Otherwise:
13018 else {
13019 // Set url's path to an empty list.
13020 url.clear_pathname();
13021 url.has_opaque_path = true;
13022 }
13023
13024 // Set state to path state and decrease pointer by 1.
13026 break;
13027 }
13028 }
13029 // Otherwise, set state to path state, and decrease pointer by 1.
13030 else {
13031 ada_log("FILE go to path");
13033 break;
13034 }
13035
13036 input_position++;
13037 break;
13038 }
13039 default:
13041 }
13042 }
13043 if constexpr (store_values) {
13044 if (fragment.has_value()) {
13045 url.update_unencoded_base_hash(*fragment);
13046 }
13047 }
13048 return url;
13049}
13050
13051template url parse_url_impl(std::string_view user_input,
13052 const url* base_url = nullptr);
13054 std::string_view user_input, const url_aggregator* base_url = nullptr);
13055
13056template <class result_type>
13057result_type parse_url(std::string_view user_input,
13058 const result_type* base_url) {
13059 return parse_url_impl<result_type, true>(user_input, base_url);
13060}
13061
13062template url parse_url<url>(std::string_view user_input,
13063 const url* base_url = nullptr);
13064template url_aggregator parse_url<url_aggregator>(
13065 std::string_view user_input, const url_aggregator* base_url = nullptr);
13066} // namespace ada::parser
13067/* end file src/parser.cpp */
13068/* begin file src/url_components.cpp */
13069
13070#include <numeric>
13071#include <string>
13072
13073namespace ada {
13074
13075[[nodiscard]] bool url_components::check_offset_consistency() const noexcept {
13088 // These conditions can be made more strict.
13089 uint32_t index = 0;
13090
13091 if (protocol_end == url_components::omitted) {
13092 return false;
13093 }
13094 if (protocol_end < index) {
13095 return false;
13096 }
13097 index = protocol_end;
13098
13099 if (username_end == url_components::omitted) {
13100 return false;
13101 }
13102 if (username_end < index) {
13103 return false;
13104 }
13105 index = username_end;
13106
13107 if (host_start == url_components::omitted) {
13108 return false;
13109 }
13110 if (host_start < index) {
13111 return false;
13112 }
13113 index = host_start;
13114
13115 if (port != url_components::omitted) {
13116 if (port > 0xffff) {
13117 return false;
13118 }
13119 uint32_t port_length = helpers::fast_digit_count(port) + 1;
13120 if (index + port_length < index) {
13121 return false;
13122 }
13123 index += port_length;
13124 }
13125
13126 if (pathname_start == url_components::omitted) {
13127 return false;
13128 }
13129 if (pathname_start < index) {
13130 return false;
13131 }
13132 index = pathname_start;
13133
13134 if (search_start != url_components::omitted) {
13135 if (search_start < index) {
13136 return false;
13137 }
13138 index = search_start;
13139 }
13140
13141 if (hash_start != url_components::omitted) {
13142 if (hash_start < index) {
13143 return false;
13144 }
13145 }
13146
13147 return true;
13148}
13149
13150[[nodiscard]] std::string url_components::to_string() const {
13151 std::string answer;
13152 auto back = std::back_insert_iterator(answer);
13153 answer.append("{\n");
13154
13155 answer.append("\t\"protocol_end\":\"");
13156 helpers::encode_json(std::to_string(protocol_end), back);
13157 answer.append("\",\n");
13158
13159 answer.append("\t\"username_end\":\"");
13160 helpers::encode_json(std::to_string(username_end), back);
13161 answer.append("\",\n");
13162
13163 answer.append("\t\"host_start\":\"");
13164 helpers::encode_json(std::to_string(host_start), back);
13165 answer.append("\",\n");
13166
13167 answer.append("\t\"host_end\":\"");
13168 helpers::encode_json(std::to_string(host_end), back);
13169 answer.append("\",\n");
13170
13171 answer.append("\t\"port\":\"");
13172 helpers::encode_json(std::to_string(port), back);
13173 answer.append("\",\n");
13174
13175 answer.append("\t\"pathname_start\":\"");
13176 helpers::encode_json(std::to_string(pathname_start), back);
13177 answer.append("\",\n");
13178
13179 answer.append("\t\"search_start\":\"");
13180 helpers::encode_json(std::to_string(search_start), back);
13181 answer.append("\",\n");
13182
13183 answer.append("\t\"hash_start\":\"");
13184 helpers::encode_json(std::to_string(hash_start), back);
13185 answer.append("\",\n");
13186
13187 answer.append("\n}");
13188 return answer;
13189}
13190
13191} // namespace ada
13192/* end file src/url_components.cpp */
13193/* begin file src/url_aggregator.cpp */
13194
13195#include <string>
13196#include <string_view>
13197
13198namespace ada {
13199template <bool has_state_override>
13200[[nodiscard]] ada_really_inline bool url_aggregator::parse_scheme_with_colon(
13201 const std::string_view input_with_colon) {
13202 ada_log("url_aggregator::parse_scheme_with_colon ", input_with_colon);
13203 ADA_ASSERT_TRUE(validate());
13204 ADA_ASSERT_TRUE(!helpers::overlaps(input_with_colon, buffer));
13205 std::string_view input{input_with_colon};
13206 input.remove_suffix(1);
13207 auto parsed_type = ada::scheme::get_scheme_type(input);
13208 bool is_input_special = (parsed_type != ada::scheme::NOT_SPECIAL);
13213 if (is_input_special) { // fast path!!!
13214 if (has_state_override) {
13215 // If url's scheme is not a special scheme and buffer is a special scheme,
13216 // then return.
13217 if (is_special() != is_input_special) {
13218 return false;
13219 }
13220
13221 // If url includes credentials or has a non-null port, and buffer is
13222 // "file", then return.
13223 if ((has_credentials() || components.port != url_components::omitted) &&
13224 parsed_type == ada::scheme::type::FILE) {
13225 return false;
13226 }
13227
13228 // If url's scheme is "file" and its host is an empty host, then return.
13229 // An empty host is the empty string.
13230 if (type == ada::scheme::type::FILE &&
13231 components.host_start == components.host_end) {
13232 return false;
13233 }
13234 }
13235
13236 type = parsed_type;
13237 set_scheme_from_view_with_colon(input_with_colon);
13238
13239 if (has_state_override) {
13240 // This is uncommon.
13241 uint16_t urls_scheme_port = get_special_port();
13242
13243 // If url's port is url's scheme's default port, then set url's port to
13244 // null.
13245 if (components.port == urls_scheme_port) {
13246 clear_port();
13247 }
13248 }
13249 } else { // slow path
13250 std::string _buffer(input);
13251 // Next function is only valid if the input is ASCII and returns false
13252 // otherwise, but it seems that we always have ascii content so we do not
13253 // need to check the return value.
13254 unicode::to_lower_ascii(_buffer.data(), _buffer.size());
13255
13256 if (has_state_override) {
13257 // If url's scheme is a special scheme and buffer is not a special scheme,
13258 // then return. If url's scheme is not a special scheme and buffer is a
13259 // special scheme, then return.
13260 if (is_special() != ada::scheme::is_special(_buffer)) {
13261 return true;
13262 }
13263
13264 // If url includes credentials or has a non-null port, and buffer is
13265 // "file", then return.
13266 if ((has_credentials() || components.port != url_components::omitted) &&
13267 _buffer == "file") {
13268 return true;
13269 }
13270
13271 // If url's scheme is "file" and its host is an empty host, then return.
13272 // An empty host is the empty string.
13273 if (type == ada::scheme::type::FILE &&
13274 components.host_start == components.host_end) {
13275 return true;
13276 }
13277 }
13278
13279 set_scheme(_buffer);
13280
13281 if (has_state_override) {
13282 // This is uncommon.
13283 uint16_t urls_scheme_port = get_special_port();
13284
13285 // If url's port is url's scheme's default port, then set url's port to
13286 // null.
13287 if (components.port == urls_scheme_port) {
13288 clear_port();
13289 }
13290 }
13291 }
13292 ADA_ASSERT_TRUE(validate());
13293 return true;
13294}
13295
13296inline void url_aggregator::copy_scheme(const url_aggregator& u) noexcept {
13297 ada_log("url_aggregator::copy_scheme ", u.buffer);
13298 ADA_ASSERT_TRUE(validate());
13299 // next line could overflow but unsigned arithmetic has well-defined
13300 // overflows.
13301 uint32_t new_difference = u.components.protocol_end - components.protocol_end;
13302 type = u.type;
13303 buffer.erase(0, components.protocol_end);
13304 buffer.insert(0, u.get_protocol());
13305 components.protocol_end = u.components.protocol_end;
13306
13307 // No need to update the components
13308 if (new_difference == 0) {
13309 return;
13310 }
13311
13312 // Update the rest of the components.
13313 components.username_end += new_difference;
13314 components.host_start += new_difference;
13315 components.host_end += new_difference;
13316 components.pathname_start += new_difference;
13317 if (components.search_start != url_components::omitted) {
13318 components.search_start += new_difference;
13319 }
13320 if (components.hash_start != url_components::omitted) {
13321 components.hash_start += new_difference;
13322 }
13323 ADA_ASSERT_TRUE(validate());
13324}
13325
13326inline void url_aggregator::set_scheme_from_view_with_colon(
13327 std::string_view new_scheme_with_colon) noexcept {
13328 ada_log("url_aggregator::set_scheme_from_view_with_colon ",
13329 new_scheme_with_colon);
13330 ADA_ASSERT_TRUE(validate());
13331 ADA_ASSERT_TRUE(!new_scheme_with_colon.empty() &&
13332 new_scheme_with_colon.back() == ':');
13333 // next line could overflow but unsigned arithmetic has well-defined
13334 // overflows.
13335 uint32_t new_difference =
13336 uint32_t(new_scheme_with_colon.size()) - components.protocol_end;
13337
13338 if (buffer.empty()) {
13339 buffer.append(new_scheme_with_colon);
13340 } else {
13341 buffer.erase(0, components.protocol_end);
13342 buffer.insert(0, new_scheme_with_colon);
13343 }
13344 components.protocol_end += new_difference;
13345
13346 // Update the rest of the components.
13347 components.username_end += new_difference;
13348 components.host_start += new_difference;
13349 components.host_end += new_difference;
13350 components.pathname_start += new_difference;
13351 if (components.search_start != url_components::omitted) {
13352 components.search_start += new_difference;
13353 }
13354 if (components.hash_start != url_components::omitted) {
13355 components.hash_start += new_difference;
13356 }
13357 ADA_ASSERT_TRUE(validate());
13358}
13359
13360inline void url_aggregator::set_scheme(std::string_view new_scheme) noexcept {
13361 ada_log("url_aggregator::set_scheme ", new_scheme);
13362 ADA_ASSERT_TRUE(validate());
13363 ADA_ASSERT_TRUE(new_scheme.empty() || new_scheme.back() != ':');
13364 // next line could overflow but unsigned arithmetic has well-defined
13365 // overflows.
13366 uint32_t new_difference =
13367 uint32_t(new_scheme.size()) - components.protocol_end + 1;
13368
13369 type = ada::scheme::get_scheme_type(new_scheme);
13370 if (buffer.empty()) {
13371 buffer.append(helpers::concat(new_scheme, ":"));
13372 } else {
13373 buffer.erase(0, components.protocol_end);
13374 buffer.insert(0, helpers::concat(new_scheme, ":"));
13375 }
13376 components.protocol_end = uint32_t(new_scheme.size() + 1);
13377
13378 // Update the rest of the components.
13379 components.username_end += new_difference;
13380 components.host_start += new_difference;
13381 components.host_end += new_difference;
13382 components.pathname_start += new_difference;
13383 if (components.search_start != url_components::omitted) {
13384 components.search_start += new_difference;
13385 }
13386 if (components.hash_start != url_components::omitted) {
13387 components.hash_start += new_difference;
13388 }
13389 ADA_ASSERT_TRUE(validate());
13390}
13391
13392bool url_aggregator::set_protocol(const std::string_view input) {
13393 ada_log("url_aggregator::set_protocol ", input);
13394 ADA_ASSERT_TRUE(validate());
13395 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13396 std::string view(input);
13397 helpers::remove_ascii_tab_or_newline(view);
13398 if (view.empty()) {
13399 return true;
13400 }
13401
13402 // Schemes should start with alpha values.
13403 if (!checkers::is_alpha(view[0])) {
13404 return false;
13405 }
13406
13407 view.append(":");
13408
13409 std::string::iterator pointer =
13410 std::find_if_not(view.begin(), view.end(), unicode::is_alnum_plus);
13411
13412 if (pointer != view.end() && *pointer == ':') {
13413 return parse_scheme_with_colon<true>(
13414 std::string_view(view.data(), pointer - view.begin() + 1));
13415 }
13416 return false;
13417}
13418
13419bool url_aggregator::set_username(const std::string_view input) {
13420 ada_log("url_aggregator::set_username '", 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 }
13427 input, character_sets::USERINFO_PERCENT_ENCODE);
13428 if (idx == input.size()) {
13429 update_base_username(input);
13430 } else {
13431 // We only create a temporary string if we have to!
13432 update_base_username(ada::unicode::percent_encode(
13433 input, character_sets::USERINFO_PERCENT_ENCODE, idx));
13434 }
13435 ADA_ASSERT_TRUE(validate());
13436 return true;
13437}
13438
13439bool url_aggregator::set_password(const std::string_view input) {
13440 ada_log("url_aggregator::set_password '", 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 }
13447 input, character_sets::USERINFO_PERCENT_ENCODE);
13448 if (idx == input.size()) {
13449 update_base_password(input);
13450 } else {
13451 // We only create a temporary string if we have to!
13452 update_base_password(ada::unicode::percent_encode(
13453 input, character_sets::USERINFO_PERCENT_ENCODE, idx));
13454 }
13455 ADA_ASSERT_TRUE(validate());
13456 return true;
13457}
13458
13459bool url_aggregator::set_port(const std::string_view input) {
13460 ada_log("url_aggregator::set_port ", input);
13461 ADA_ASSERT_TRUE(validate());
13462 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13463 if (cannot_have_credentials_or_port()) {
13464 return false;
13465 }
13466 std::string trimmed(input);
13467 helpers::remove_ascii_tab_or_newline(trimmed);
13468 if (trimmed.empty()) {
13469 clear_port();
13470 return true;
13471 }
13472 // Input should not start with control characters.
13473 if (ada::unicode::is_c0_control_or_space(trimmed.front())) {
13474 return false;
13475 }
13476 // Input should contain at least one ascii digit.
13477 if (input.find_first_of("0123456789") == std::string_view::npos) {
13478 return false;
13479 }
13480
13481 // Revert changes if parse_port fails.
13482 uint32_t previous_port = components.port;
13483 parse_port(trimmed);
13484 if (is_valid) {
13485 return true;
13486 }
13487 update_base_port(previous_port);
13488 is_valid = true;
13489 ADA_ASSERT_TRUE(validate());
13490 return false;
13491}
13492
13493bool url_aggregator::set_pathname(const std::string_view input) {
13494 ada_log("url_aggregator::set_pathname ", input);
13495 ADA_ASSERT_TRUE(validate());
13496 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13497 if (has_opaque_path) {
13498 return false;
13499 }
13500 clear_pathname();
13501 parse_path(input);
13502 if (checkers::begins_with(get_pathname(), "//") && !has_authority() &&
13503 !has_dash_dot()) {
13504 buffer.insert(components.pathname_start, "/.");
13505 components.pathname_start += 2;
13506 }
13507 ADA_ASSERT_TRUE(validate());
13508 return true;
13509}
13510
13511ada_really_inline void url_aggregator::parse_path(std::string_view input) {
13512 ada_log("url_aggregator::parse_path ", input);
13513 ADA_ASSERT_TRUE(validate());
13514 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13515 std::string tmp_buffer;
13516 std::string_view internal_input;
13517 if (unicode::has_tabs_or_newline(input)) {
13518 tmp_buffer = input;
13519 // Optimization opportunity: Instead of copying and then pruning, we could
13520 // just directly build the string from user_input.
13521 helpers::remove_ascii_tab_or_newline(tmp_buffer);
13522 internal_input = tmp_buffer;
13523 } else {
13524 internal_input = input;
13525 }
13526
13527 // If url is special, then:
13528 if (is_special()) {
13529 if (internal_input.empty()) {
13530 update_base_pathname("/");
13531 } else if ((internal_input[0] == '/') || (internal_input[0] == '\\')) {
13532 consume_prepared_path(internal_input.substr(1));
13533 } else {
13534 consume_prepared_path(internal_input);
13535 }
13536 } else if (!internal_input.empty()) {
13537 if (internal_input[0] == '/') {
13538 consume_prepared_path(internal_input.substr(1));
13539 } else {
13540 consume_prepared_path(internal_input);
13541 }
13542 } else {
13543 // Non-special URLs with an empty host can have their paths erased
13544 // Path-only URLs cannot have their paths erased
13545 if (components.host_start == components.host_end && !has_authority()) {
13546 update_base_pathname("/");
13547 }
13548 }
13549 ADA_ASSERT_TRUE(validate());
13550}
13551
13552void url_aggregator::set_search(const std::string_view input) {
13553 ada_log("url_aggregator::set_search ", input);
13554 ADA_ASSERT_TRUE(validate());
13555 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13556 if (input.empty()) {
13557 clear_search();
13558 helpers::strip_trailing_spaces_from_opaque_path(*this);
13559 return;
13560 }
13561
13562 std::string new_value;
13563 new_value = input[0] == '?' ? input.substr(1) : input;
13564 helpers::remove_ascii_tab_or_newline(new_value);
13565
13566 auto query_percent_encode_set =
13569
13570 update_base_search(new_value, query_percent_encode_set);
13571 ADA_ASSERT_TRUE(validate());
13572}
13573
13574void url_aggregator::set_hash(const std::string_view input) {
13575 ada_log("url_aggregator::set_hash ", input);
13576 ADA_ASSERT_TRUE(validate());
13577 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13578 if (input.empty()) {
13579 if (components.hash_start != url_components::omitted) {
13580 buffer.resize(components.hash_start);
13581 components.hash_start = url_components::omitted;
13582 }
13583 helpers::strip_trailing_spaces_from_opaque_path(*this);
13584 return;
13585 }
13586
13587 std::string new_value;
13588 new_value = input[0] == '#' ? input.substr(1) : input;
13589 helpers::remove_ascii_tab_or_newline(new_value);
13590 update_unencoded_base_hash(new_value);
13591 ADA_ASSERT_TRUE(validate());
13592}
13593
13594bool url_aggregator::set_href(const std::string_view input) {
13595 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13596 ada_log("url_aggregator::set_href ", input, " [", input.size(), " bytes]");
13598 ada_log("url_aggregator::set_href, success :", out.has_value());
13599
13600 if (out) {
13601 ada_log("url_aggregator::set_href, parsed ", out->to_string());
13602 // TODO: Figure out why the following line puts test to never finish.
13603 *this = *out;
13604 }
13605
13606 return out.has_value();
13607}
13608
13609ada_really_inline bool url_aggregator::parse_host(std::string_view input) {
13610 ada_log("url_aggregator:parse_host \"", input, "\" [", input.size(),
13611 " bytes]");
13612 ADA_ASSERT_TRUE(validate());
13613 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13614 if (input.empty()) {
13615 return is_valid = false;
13616 } // technically unnecessary.
13617 // If input starts with U+005B ([), then:
13618 if (input[0] == '[') {
13619 // If input does not end with U+005D (]), validation error, return failure.
13620 if (input.back() != ']') {
13621 return is_valid = false;
13622 }
13623 ada_log("parse_host ipv6");
13624
13625 // Return the result of IPv6 parsing input with its leading U+005B ([) and
13626 // trailing U+005D (]) removed.
13627 input.remove_prefix(1);
13628 input.remove_suffix(1);
13629 return parse_ipv6(input);
13630 }
13631
13632 // If isNotSpecial is true, then return the result of opaque-host parsing
13633 // input.
13634 if (!is_special()) {
13635 return parse_opaque_host(input);
13636 }
13637 // Let domain be the result of running UTF-8 decode without BOM on the
13638 // percent-decoding of input. Let asciiDomain be the result of running domain
13639 // to ASCII with domain and false. The most common case is an ASCII input, in
13640 // which case we do not need to call the expensive 'to_ascii' if a few
13641 // conditions are met: no '%' and no 'xn-' subsequence.
13642
13643 // Often, the input does not contain any forbidden code points, and no upper
13644 // case ASCII letter, then we can just copy it to the buffer. We want to
13645 // optimize for such a common case.
13646 uint8_t is_forbidden_or_upper =
13647 unicode::contains_forbidden_domain_code_point_or_upper(input.data(),
13648 input.size());
13649 // Minor optimization opportunity:
13650 // contains_forbidden_domain_code_point_or_upper could be extend to check for
13651 // the presence of characters that cannot appear in the ipv4 address and we
13652 // could also check whether x and n and - are present, and so we could skip
13653 // some of the checks below. However, the gains are likely to be small, and
13654 // the code would be more complex.
13655 if (is_forbidden_or_upper == 0 &&
13656 input.find("xn-") == std::string_view::npos) {
13657 // fast path
13658 update_base_hostname(input);
13659 if (checkers::is_ipv4(get_hostname())) {
13660 ada_log("parse_host fast path ipv4");
13661 return parse_ipv4(get_hostname(), true);
13662 }
13663 ada_log("parse_host fast path ", get_hostname());
13664 return true;
13665 }
13666 // We have encountered at least one forbidden code point or the input contains
13667 // 'xn-' (case insensitive), so we need to call 'to_ascii' to perform the full
13668 // conversion.
13669
13670 ada_log("parse_host calling to_ascii");
13671 std::optional<std::string> host = std::string(get_hostname());
13672 is_valid = ada::unicode::to_ascii(host, input, input.find('%'));
13673 if (!is_valid) {
13674 ada_log("parse_host to_ascii returns false");
13675 return is_valid = false;
13676 }
13677 ada_log("parse_host to_ascii succeeded ", *host, " [", host->size(),
13678 " bytes]");
13679
13680 if (std::any_of(host.value().begin(), host.value().end(),
13681 ada::unicode::is_forbidden_domain_code_point)) {
13682 return is_valid = false;
13683 }
13684
13685 // If asciiDomain ends in a number, then return the result of IPv4 parsing
13686 // asciiDomain.
13687 if (checkers::is_ipv4(host.value())) {
13688 ada_log("parse_host got ipv4 ", *host);
13689 return parse_ipv4(host.value(), false);
13690 }
13691
13692 update_base_hostname(host.value());
13693 ADA_ASSERT_TRUE(validate());
13694 return true;
13695}
13696
13697template <bool override_hostname>
13698bool url_aggregator::set_host_or_hostname(const std::string_view input) {
13699 ada_log("url_aggregator::set_host_or_hostname ", input);
13700 ADA_ASSERT_TRUE(validate());
13701 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13702 if (has_opaque_path) {
13703 return false;
13704 }
13705
13706 std::string previous_host(get_hostname());
13707 uint32_t previous_port = components.port;
13708
13709 size_t host_end_pos = input.find('#');
13710 std::string _host(input.data(), host_end_pos != std::string_view::npos
13711 ? host_end_pos
13712 : input.size());
13713 helpers::remove_ascii_tab_or_newline(_host);
13714 std::string_view new_host(_host);
13715
13716 // If url's scheme is "file", then set state to file host state, instead of
13717 // host state.
13718 if (type != ada::scheme::type::FILE) {
13719 std::string_view host_view(_host.data(), _host.length());
13720 auto [location, found_colon] =
13721 helpers::get_host_delimiter_location(is_special(), host_view);
13722
13723 // Otherwise, if c is U+003A (:) and insideBrackets is false, then:
13724 // Note: the 'found_colon' value is true if and only if a colon was
13725 // encountered while not inside brackets.
13726 if (found_colon) {
13727 if (override_hostname) {
13728 return false;
13729 }
13730 std::string_view sub_buffer = new_host.substr(location + 1);
13731 if (!sub_buffer.empty()) {
13732 set_port(sub_buffer);
13733 }
13734 }
13735 // If url is special and host_view is the empty string, validation error,
13736 // return failure. Otherwise, if state override is given, host_view is the
13737 // empty string, and either url includes credentials or url's port is
13738 // non-null, return.
13739 else if (host_view.empty() &&
13740 (is_special() || has_credentials() || has_port())) {
13741 return false;
13742 }
13743
13744 // Let host be the result of host parsing host_view with url is not special.
13745 if (host_view.empty() && !is_special()) {
13746 if (has_hostname()) {
13747 clear_hostname(); // easy!
13748 } else if (has_dash_dot()) {
13749 add_authority_slashes_if_needed();
13750 delete_dash_dot();
13751 }
13752 return true;
13753 }
13754
13755 bool succeeded = parse_host(host_view);
13756 if (!succeeded) {
13757 update_base_hostname(previous_host);
13758 update_base_port(previous_port);
13759 } else if (has_dash_dot()) {
13760 // Should remove dash_dot from pathname
13761 delete_dash_dot();
13762 }
13763 return succeeded;
13764 }
13765
13766 size_t location = new_host.find_first_of("/\\?");
13767 if (location != std::string_view::npos) {
13768 new_host.remove_suffix(new_host.length() - location);
13769 }
13770
13771 if (new_host.empty()) {
13772 // Set url's host to the empty string.
13773 clear_hostname();
13774 } else {
13775 // Let host be the result of host parsing buffer with url is not special.
13776 if (!parse_host(new_host)) {
13777 update_base_hostname(previous_host);
13778 update_base_port(previous_port);
13779 return false;
13780 }
13781
13782 // If host is "localhost", then set host to the empty string.
13783 if (helpers::substring(buffer, components.host_start,
13784 components.host_end) == "localhost") {
13785 clear_hostname();
13786 }
13787 }
13788 ADA_ASSERT_TRUE(validate());
13789 return true;
13790}
13791
13792bool url_aggregator::set_host(const std::string_view input) {
13793 ada_log("url_aggregator::set_host '", input, "'");
13794 ADA_ASSERT_TRUE(validate());
13795 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13796 return set_host_or_hostname<false>(input);
13797}
13798
13799bool url_aggregator::set_hostname(const std::string_view input) {
13800 ada_log("url_aggregator::set_hostname '", input, "'");
13801 ADA_ASSERT_TRUE(validate());
13802 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
13803 return set_host_or_hostname<true>(input);
13804}
13805
13806[[nodiscard]] std::string url_aggregator::get_origin() const noexcept {
13807 ada_log("url_aggregator::get_origin");
13808 if (is_special()) {
13809 // Return a new opaque origin.
13810 if (type == scheme::FILE) {
13811 return "null";
13812 }
13813
13814 return helpers::concat(get_protocol(), "//", get_host());
13815 }
13816
13817 if (get_protocol() == "blob:") {
13818 std::string_view path = get_pathname();
13819 if (!path.empty()) {
13820 auto out = ada::parse<ada::url_aggregator>(path);
13821 if (out && (out->type == scheme::HTTP || out->type == scheme::HTTPS)) {
13822 // If pathURL's scheme is not "http" and not "https", then return a
13823 // new opaque origin.
13824 return helpers::concat(out->get_protocol(), "//", out->get_host());
13825 }
13826 }
13827 }
13828
13829 // Return a new opaque origin.
13830 return "null";
13831}
13832
13833[[nodiscard]] std::string_view url_aggregator::get_username() const noexcept
13835 ada_log("url_aggregator::get_username");
13836 if (has_non_empty_username()) {
13837 return helpers::substring(buffer, components.protocol_end + 2,
13838 components.username_end);
13839 }
13840 return "";
13841}
13842
13843[[nodiscard]] std::string_view url_aggregator::get_password() const noexcept
13845 ada_log("url_aggregator::get_password");
13846 if (has_non_empty_password()) {
13847 return helpers::substring(buffer, components.username_end + 1,
13848 components.host_start);
13849 }
13850 return "";
13851}
13852
13853[[nodiscard]] std::string_view url_aggregator::get_port() const noexcept
13855 ada_log("url_aggregator::get_port");
13856 if (components.port == url_components::omitted) {
13857 return "";
13858 }
13859 return helpers::substring(buffer, components.host_end + 1,
13860 components.pathname_start);
13861}
13862
13863[[nodiscard]] std::string_view url_aggregator::get_hash() const noexcept
13865 ada_log("url_aggregator::get_hash");
13866 // If this's URL's fragment is either null or the empty string, then return
13867 // the empty string. Return U+0023 (#), followed by this's URL's fragment.
13868 if (components.hash_start == url_components::omitted) {
13869 return "";
13870 }
13871 if (buffer.size() - components.hash_start <= 1) {
13872 return "";
13873 }
13874 return helpers::substring(buffer, components.hash_start);
13875}
13876
13877[[nodiscard]] std::string_view url_aggregator::get_host() const noexcept
13879 ada_log("url_aggregator::get_host");
13880 // Technically, we should check if there is a hostname, but
13881 // the code below works even if there isn't.
13882 // if(!has_hostname()) { return ""; }
13883 size_t start = components.host_start;
13884 if (components.host_end > components.host_start &&
13885 buffer[components.host_start] == '@') {
13886 start++;
13887 }
13888 // if we have an empty host, then the space between components.host_end and
13889 // components.pathname_start may be occupied by /.
13890 if (start == components.host_end) {
13891 return {};
13892 }
13893 return helpers::substring(buffer, start, components.pathname_start);
13894}
13895
13896[[nodiscard]] std::string_view url_aggregator::get_hostname() const noexcept
13898 ada_log("url_aggregator::get_hostname");
13899 // Technically, we should check if there is a hostname, but
13900 // the code below works even if there isn't.
13901 // if(!has_hostname()) { return ""; }
13902 size_t start = components.host_start;
13903 // So host_start is not where the host begins.
13904 if (components.host_end > components.host_start &&
13905 buffer[components.host_start] == '@') {
13906 start++;
13907 }
13908 return helpers::substring(buffer, start, components.host_end);
13909}
13910
13911[[nodiscard]] std::string_view url_aggregator::get_pathname() const noexcept
13913 ada_log("url_aggregator::get_pathname pathname_start = ",
13914 components.pathname_start, " buffer.size() = ", buffer.size(),
13915 " components.search_start = ", components.search_start,
13916 " components.hash_start = ", components.hash_start);
13917 auto ending_index = uint32_t(buffer.size());
13918 if (components.search_start != url_components::omitted) {
13919 ending_index = components.search_start;
13920 } else if (components.hash_start != url_components::omitted) {
13921 ending_index = components.hash_start;
13922 }
13923 return helpers::substring(buffer, components.pathname_start, ending_index);
13924}
13925
13926[[nodiscard]] std::string_view url_aggregator::get_search() const noexcept
13928 ada_log("url_aggregator::get_search");
13929 // If this's URL's query is either null or the empty string, then return the
13930 // empty string. Return U+003F (?), followed by this's URL's query.
13931 if (components.search_start == url_components::omitted) {
13932 return "";
13933 }
13934 auto ending_index = uint32_t(buffer.size());
13935 if (components.hash_start != url_components::omitted) {
13936 ending_index = components.hash_start;
13937 }
13938 if (ending_index - components.search_start <= 1) {
13939 return "";
13940 }
13941 return helpers::substring(buffer, components.search_start, ending_index);
13942}
13943
13944[[nodiscard]] std::string_view url_aggregator::get_protocol() const noexcept
13946 ada_log("url_aggregator::get_protocol");
13947 return helpers::substring(buffer, 0, components.protocol_end);
13948}
13949
13950[[nodiscard]] std::string ada::url_aggregator::to_string() const {
13951 ada_log("url_aggregator::to_string buffer:", buffer, " [", buffer.size(),
13952 " bytes]");
13953 if (!is_valid) {
13954 return "null";
13955 }
13956
13957 std::string answer;
13958 auto back = std::back_insert_iterator(answer);
13959 answer.append("{\n");
13960
13961 answer.append("\t\"buffer\":\"");
13962 helpers::encode_json(buffer, back);
13963 answer.append("\",\n");
13964
13965 answer.append("\t\"protocol\":\"");
13966 helpers::encode_json(get_protocol(), back);
13967 answer.append("\",\n");
13968
13969 if (has_credentials()) {
13970 answer.append("\t\"username\":\"");
13971 helpers::encode_json(get_username(), back);
13972 answer.append("\",\n");
13973 answer.append("\t\"password\":\"");
13974 helpers::encode_json(get_password(), back);
13975 answer.append("\",\n");
13976 }
13977
13978 answer.append("\t\"host\":\"");
13979 helpers::encode_json(get_host(), back);
13980 answer.append("\",\n");
13981
13982 answer.append("\t\"path\":\"");
13983 helpers::encode_json(get_pathname(), back);
13984 answer.append("\",\n");
13985 answer.append("\t\"opaque path\":");
13986 answer.append((has_opaque_path ? "true" : "false"));
13987 answer.append(",\n");
13988
13989 if (components.search_start != url_components::omitted) {
13990 answer.append("\t\"query\":\"");
13991 helpers::encode_json(get_search(), back);
13992 answer.append("\",\n");
13993 }
13994 if (components.hash_start != url_components::omitted) {
13995 answer.append("\t\"fragment\":\"");
13996 helpers::encode_json(get_hash(), back);
13997 answer.append("\",\n");
13998 }
13999
14000 auto convert_offset_to_string = [](uint32_t offset) -> std::string {
14001 if (offset == url_components::omitted) {
14002 return "null";
14003 } else {
14004 return std::to_string(offset);
14005 }
14006 };
14007
14008 answer.append("\t\"protocol_end\":");
14009 answer.append(convert_offset_to_string(components.protocol_end));
14010 answer.append(",\n");
14011
14012 answer.append("\t\"username_end\":");
14013 answer.append(convert_offset_to_string(components.username_end));
14014 answer.append(",\n");
14015
14016 answer.append("\t\"host_start\":");
14017 answer.append(convert_offset_to_string(components.host_start));
14018 answer.append(",\n");
14019
14020 answer.append("\t\"host_end\":");
14021 answer.append(convert_offset_to_string(components.host_end));
14022 answer.append(",\n");
14023
14024 answer.append("\t\"port\":");
14025 answer.append(convert_offset_to_string(components.port));
14026 answer.append(",\n");
14027
14028 answer.append("\t\"pathname_start\":");
14029 answer.append(convert_offset_to_string(components.pathname_start));
14030 answer.append(",\n");
14031
14032 answer.append("\t\"search_start\":");
14033 answer.append(convert_offset_to_string(components.search_start));
14034 answer.append(",\n");
14035
14036 answer.append("\t\"hash_start\":");
14037 answer.append(convert_offset_to_string(components.hash_start));
14038 answer.append("\n}");
14039
14040 return answer;
14041}
14042
14043[[nodiscard]] bool url_aggregator::has_valid_domain() const noexcept {
14044 if (components.host_start == components.host_end) {
14045 return false;
14046 }
14047 return checkers::verify_dns_length(get_hostname());
14048}
14049
14050bool url_aggregator::parse_ipv4(std::string_view input, bool in_place) {
14051 ada_log("parse_ipv4 ", input, " [", input.size(),
14052 " bytes], overlaps with buffer: ",
14053 helpers::overlaps(input, buffer) ? "yes" : "no");
14055 const bool trailing_dot = (input.back() == '.');
14056 if (trailing_dot) {
14057 input.remove_suffix(1);
14058 }
14059 size_t digit_count{0};
14060 int pure_decimal_count = 0; // entries that are decimal
14061 uint64_t ipv4{0};
14062 // we could unroll for better performance?
14063 for (; (digit_count < 4) && !(input.empty()); digit_count++) {
14064 uint32_t
14065 segment_result{}; // If any number exceeds 32 bits, we have an error.
14066 bool is_hex = checkers::has_hex_prefix(input);
14067 if (is_hex && ((input.length() == 2) ||
14068 ((input.length() > 2) && (input[2] == '.')))) {
14069 // special case
14070 segment_result = 0;
14071 input.remove_prefix(2);
14072 } else {
14073 std::from_chars_result r{};
14074 if (is_hex) {
14075 ada_log("parse_ipv4 trying to parse hex number");
14076 r = std::from_chars(input.data() + 2, input.data() + input.size(),
14077 segment_result, 16);
14078 } else if ((input.length() >= 2) && input[0] == '0' &&
14079 checkers::is_digit(input[1])) {
14080 ada_log("parse_ipv4 trying to parse octal number");
14081 r = std::from_chars(input.data() + 1, input.data() + input.size(),
14082 segment_result, 8);
14083 } else {
14084 ada_log("parse_ipv4 trying to parse decimal number");
14085 pure_decimal_count++;
14086 r = std::from_chars(input.data(), input.data() + input.size(),
14087 segment_result, 10);
14088 }
14089 if (r.ec != std::errc()) {
14090 ada_log("parse_ipv4 parsing failed");
14091 return is_valid = false;
14092 }
14093 ada_log("parse_ipv4 parsed ", segment_result);
14094 input.remove_prefix(r.ptr - input.data());
14095 }
14096 if (input.empty()) {
14097 // We have the last value.
14098 // At this stage, ipv4 contains digit_count*8 bits.
14099 // So we have 32-digit_count*8 bits left.
14100 if (segment_result >= (uint64_t(1) << (32 - digit_count * 8))) {
14101 return is_valid = false;
14102 }
14103 ipv4 <<= (32 - digit_count * 8);
14104 ipv4 |= segment_result;
14105 goto final;
14106 } else {
14107 // There is more, so that the value must no be larger than 255
14108 // and we must have a '.'.
14109 if ((segment_result > 255) || (input[0] != '.')) {
14110 return is_valid = false;
14111 }
14112 ipv4 <<= 8;
14113 ipv4 |= segment_result;
14114 input.remove_prefix(1); // remove '.'
14115 }
14116 }
14117 if ((digit_count != 4) || (!input.empty())) {
14118 ada_log("parse_ipv4 found invalid (more than 4 numbers or empty) ");
14119 return is_valid = false;
14120 }
14121final:
14122 ada_log("url_aggregator::parse_ipv4 completed ", get_href(),
14123 " host: ", get_host());
14124
14125 // We could also check r.ptr to see where the parsing ended.
14126 if (in_place && pure_decimal_count == 4 && !trailing_dot) {
14127 ada_log(
14128 "url_aggregator::parse_ipv4 completed and was already correct in the "
14129 "buffer");
14130 // The original input was already all decimal and we validated it. So we
14131 // don't need to do anything.
14132 } else {
14133 ada_log("url_aggregator::parse_ipv4 completed and we need to update it");
14134 // Optimization opportunity: Get rid of unnecessary string return in ipv4
14135 // serializer.
14136 // TODO: This is likely a bug because it goes back update_base_hostname, not
14137 // what we want to do.
14138 update_base_hostname(
14139 ada::serializers::ipv4(ipv4)); // We have to reserialize the address.
14140 }
14141 host_type = IPV4;
14143 return true;
14144}
14145
14146bool url_aggregator::parse_ipv6(std::string_view input) {
14147 // TODO: Implement in_place optimization: we know that input points
14148 // in the buffer, so we can just check whether the buffer is already
14149 // well formatted.
14150 // TODO: Find a way to merge parse_ipv6 with url.cpp implementation.
14151 ada_log("parse_ipv6 ", input, " [", input.size(), " bytes]");
14153 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14154 if (input.empty()) {
14155 return is_valid = false;
14156 }
14157 // Let address be a new IPv6 address whose IPv6 pieces are all 0.
14158 std::array<uint16_t, 8> address{};
14159
14160 // Let pieceIndex be 0.
14161 int piece_index = 0;
14162
14163 // Let compress be null.
14164 std::optional<int> compress{};
14165
14166 // Let pointer be a pointer for input.
14167 std::string_view::iterator pointer = input.begin();
14168
14169 // If c is U+003A (:), then:
14170 if (input[0] == ':') {
14171 // If remaining does not start with U+003A (:), validation error, return
14172 // failure.
14173 if (input.size() == 1 || input[1] != ':') {
14174 ada_log("parse_ipv6 starts with : but the rest does not start with :");
14175 return is_valid = false;
14176 }
14177
14178 // Increase pointer by 2.
14179 pointer += 2;
14180
14181 // Increase pieceIndex by 1 and then set compress to pieceIndex.
14182 compress = ++piece_index;
14183 }
14184
14185 // While c is not the EOF code point:
14186 while (pointer != input.end()) {
14187 // If pieceIndex is 8, validation error, return failure.
14188 if (piece_index == 8) {
14189 ada_log("parse_ipv6 piece_index == 8");
14190 return is_valid = false;
14191 }
14192
14193 // If c is U+003A (:), then:
14194 if (*pointer == ':') {
14195 // If compress is non-null, validation error, return failure.
14196 if (compress.has_value()) {
14197 ada_log("parse_ipv6 compress is non-null");
14198 return is_valid = false;
14199 }
14200
14201 // Increase pointer and pieceIndex by 1, set compress to pieceIndex, and
14202 // then continue.
14203 pointer++;
14204 compress = ++piece_index;
14205 continue;
14206 }
14207
14208 // Let value and length be 0.
14209 uint16_t value = 0, length = 0;
14210
14211 // While length is less than 4 and c is an ASCII hex digit,
14212 // set value to value times 0x10 + c interpreted as hexadecimal number, and
14213 // increase pointer and length by 1.
14214 while (length < 4 && pointer != input.end() &&
14215 unicode::is_ascii_hex_digit(*pointer)) {
14216 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
14217 value = uint16_t(value * 0x10 + unicode::convert_hex_to_binary(*pointer));
14218 pointer++;
14219 length++;
14220 }
14221
14222 // If c is U+002E (.), then:
14223 if (pointer != input.end() && *pointer == '.') {
14224 // If length is 0, validation error, return failure.
14225 if (length == 0) {
14226 ada_log("parse_ipv6 length is 0");
14227 return is_valid = false;
14228 }
14229
14230 // Decrease pointer by length.
14231 pointer -= length;
14232
14233 // If pieceIndex is greater than 6, validation error, return failure.
14234 if (piece_index > 6) {
14235 ada_log("parse_ipv6 piece_index > 6");
14236 return is_valid = false;
14237 }
14238
14239 // Let numbersSeen be 0.
14240 int numbers_seen = 0;
14241
14242 // While c is not the EOF code point:
14243 while (pointer != input.end()) {
14244 // Let ipv4Piece be null.
14245 std::optional<uint16_t> ipv4_piece{};
14246
14247 // If numbersSeen is greater than 0, then:
14248 if (numbers_seen > 0) {
14249 // If c is a U+002E (.) and numbersSeen is less than 4, then increase
14250 // pointer by 1.
14251 if (*pointer == '.' && numbers_seen < 4) {
14252 pointer++;
14253 } else {
14254 // Otherwise, validation error, return failure.
14255 ada_log("parse_ipv6 Otherwise, validation error, return failure");
14256 return is_valid = false;
14257 }
14258 }
14259
14260 // If c is not an ASCII digit, validation error, return failure.
14261 if (pointer == input.end() || !checkers::is_digit(*pointer)) {
14262 ada_log(
14263 "parse_ipv6 If c is not an ASCII digit, validation error, return "
14264 "failure");
14265 return is_valid = false;
14266 }
14267
14268 // While c is an ASCII digit:
14269 while (pointer != input.end() && checkers::is_digit(*pointer)) {
14270 // Let number be c interpreted as decimal number.
14271 int number = *pointer - '0';
14272
14273 // If ipv4Piece is null, then set ipv4Piece to number.
14274 if (!ipv4_piece.has_value()) {
14275 ipv4_piece = number;
14276 }
14277 // Otherwise, if ipv4Piece is 0, validation error, return failure.
14278 else if (ipv4_piece == 0) {
14279 ada_log("parse_ipv6 if ipv4Piece is 0, validation error");
14280 return is_valid = false;
14281 }
14282 // Otherwise, set ipv4Piece to ipv4Piece times 10 + number.
14283 else {
14284 ipv4_piece = *ipv4_piece * 10 + number;
14285 }
14286
14287 // If ipv4Piece is greater than 255, validation error, return failure.
14288 if (ipv4_piece > 255) {
14289 ada_log("parse_ipv6 ipv4_piece > 255");
14290 return is_valid = false;
14291 }
14292
14293 // Increase pointer by 1.
14294 pointer++;
14295 }
14296
14297 // Set address[pieceIndex] to address[pieceIndex] times 0x100 +
14298 // ipv4Piece.
14299 // https://stackoverflow.com/questions/39060852/why-does-the-addition-of-two-shorts-return-an-int
14300 address[piece_index] =
14301 uint16_t(address[piece_index] * 0x100 + *ipv4_piece);
14302
14303 // Increase numbersSeen by 1.
14304 numbers_seen++;
14305
14306 // If numbersSeen is 2 or 4, then increase pieceIndex by 1.
14307 if (numbers_seen == 2 || numbers_seen == 4) {
14308 piece_index++;
14309 }
14310 }
14311
14312 // If numbersSeen is not 4, validation error, return failure.
14313 if (numbers_seen != 4) {
14314 return is_valid = false;
14315 }
14316
14317 // Break.
14318 break;
14319 }
14320 // Otherwise, if c is U+003A (:):
14321 else if ((pointer != input.end()) && (*pointer == ':')) {
14322 // Increase pointer by 1.
14323 pointer++;
14324
14325 // If c is the EOF code point, validation error, return failure.
14326 if (pointer == input.end()) {
14327 ada_log(
14328 "parse_ipv6 If c is the EOF code point, validation error, return "
14329 "failure");
14330 return is_valid = false;
14331 }
14332 }
14333 // Otherwise, if c is not the EOF code point, validation error, return
14334 // failure.
14335 else if (pointer != input.end()) {
14336 ada_log(
14337 "parse_ipv6 Otherwise, if c is not the EOF code point, validation "
14338 "error, return failure");
14339 return is_valid = false;
14340 }
14341
14342 // Set address[pieceIndex] to value.
14343 address[piece_index] = value;
14344
14345 // Increase pieceIndex by 1.
14346 piece_index++;
14347 }
14348
14349 // If compress is non-null, then:
14350 if (compress.has_value()) {
14351 // Let swaps be pieceIndex - compress.
14352 int swaps = piece_index - *compress;
14353
14354 // Set pieceIndex to 7.
14355 piece_index = 7;
14356
14357 // While pieceIndex is not 0 and swaps is greater than 0,
14358 // swap address[pieceIndex] with address[compress + swaps - 1], and then
14359 // decrease both pieceIndex and swaps by 1.
14360 while (piece_index != 0 && swaps > 0) {
14361 std::swap(address[piece_index], address[*compress + swaps - 1]);
14362 piece_index--;
14363 swaps--;
14364 }
14365 }
14366 // Otherwise, if compress is null and pieceIndex is not 8, validation error,
14367 // return failure.
14368 else if (piece_index != 8) {
14369 ada_log(
14370 "parse_ipv6 if compress is null and pieceIndex is not 8, validation "
14371 "error, return failure");
14372 return is_valid = false;
14373 }
14374 // TODO: Optimization opportunity: Get rid of unnecessary string creation.
14375 // TODO: This is likely a bug because it goes back update_base_hostname, not
14376 // what we want to do.
14377 update_base_hostname(ada::serializers::ipv6(address));
14378 ada_log("parse_ipv6 ", get_hostname());
14380 host_type = IPV6;
14381 return true;
14382}
14383
14384bool url_aggregator::parse_opaque_host(std::string_view input) {
14385 ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]");
14387 ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
14388 if (std::any_of(input.begin(), input.end(),
14389 ada::unicode::is_forbidden_host_code_point)) {
14390 return is_valid = false;
14391 }
14392
14393 // Return the result of running UTF-8 percent-encode on input using the C0
14394 // control percent-encode set.
14397 if (idx == input.size()) {
14398 update_base_hostname(input);
14399 } else {
14400 // We only create a temporary string if we need to.
14401 update_base_hostname(ada::unicode::percent_encode(
14403 }
14405 return true;
14406}
14407
14408[[nodiscard]] std::string url_aggregator::to_diagram() const {
14409 if (!is_valid) {
14410 return "invalid";
14411 }
14412 std::string answer;
14413 answer.append(buffer);
14414 answer.append(" [");
14415 answer.append(std::to_string(buffer.size()));
14416 answer.append(" bytes]");
14417 answer.append("\n");
14418 // first line
14419 std::string line1;
14420 line1.resize(buffer.size(), ' ');
14421 if (components.hash_start != url_components::omitted) {
14422 line1[components.hash_start] = '|';
14423 }
14424 if (components.search_start != url_components::omitted) {
14425 line1[components.search_start] = '|';
14426 }
14427 if (components.pathname_start != buffer.size()) {
14428 line1[components.pathname_start] = '|';
14429 }
14430 if (components.host_end != buffer.size()) {
14431 line1[components.host_end] = '|';
14432 }
14433 if (components.host_start != buffer.size()) {
14434 line1[components.host_start] = '|';
14435 }
14436 if (components.username_end != buffer.size()) {
14437 line1[components.username_end] = '|';
14438 }
14439 if (components.protocol_end != buffer.size()) {
14440 line1[components.protocol_end] = '|';
14441 }
14442 answer.append(line1);
14443 answer.append("\n");
14444
14445 std::string line2 = line1;
14446 if (components.hash_start != url_components::omitted) {
14447 line2[components.hash_start] = '`';
14448 line1[components.hash_start] = ' ';
14449
14450 for (size_t i = components.hash_start + 1; i < line2.size(); i++) {
14451 line2[i] = '-';
14452 }
14453 line2.append(" hash_start");
14454 answer.append(line2);
14455 answer.append("\n");
14456 }
14457
14458 std::string line3 = line1;
14459 if (components.search_start != url_components::omitted) {
14460 line3[components.search_start] = '`';
14461 line1[components.search_start] = ' ';
14462
14463 for (size_t i = components.search_start + 1; i < line3.size(); i++) {
14464 line3[i] = '-';
14465 }
14466 line3.append(" search_start ");
14467 line3.append(std::to_string(components.search_start));
14468 answer.append(line3);
14469 answer.append("\n");
14470 }
14471
14472 std::string line4 = line1;
14473 if (components.pathname_start != buffer.size()) {
14474 line4[components.pathname_start] = '`';
14475 line1[components.pathname_start] = ' ';
14476 for (size_t i = components.pathname_start + 1; i < line4.size(); i++) {
14477 line4[i] = '-';
14478 }
14479 line4.append(" pathname_start ");
14480 line4.append(std::to_string(components.pathname_start));
14481 answer.append(line4);
14482 answer.append("\n");
14483 }
14484
14485 std::string line5 = line1;
14486 if (components.host_end != buffer.size()) {
14487 line5[components.host_end] = '`';
14488 line1[components.host_end] = ' ';
14489
14490 for (size_t i = components.host_end + 1; i < line5.size(); i++) {
14491 line5[i] = '-';
14492 }
14493 line5.append(" host_end ");
14494 line5.append(std::to_string(components.host_end));
14495 answer.append(line5);
14496 answer.append("\n");
14497 }
14498
14499 std::string line6 = line1;
14500 if (components.host_start != buffer.size()) {
14501 line6[components.host_start] = '`';
14502 line1[components.host_start] = ' ';
14503
14504 for (size_t i = components.host_start + 1; i < line6.size(); i++) {
14505 line6[i] = '-';
14506 }
14507 line6.append(" host_start ");
14508 line6.append(std::to_string(components.host_start));
14509 answer.append(line6);
14510 answer.append("\n");
14511 }
14512
14513 std::string line7 = line1;
14514 if (components.username_end != buffer.size()) {
14515 line7[components.username_end] = '`';
14516 line1[components.username_end] = ' ';
14517
14518 for (size_t i = components.username_end + 1; i < line7.size(); i++) {
14519 line7[i] = '-';
14520 }
14521 line7.append(" username_end ");
14522 line7.append(std::to_string(components.username_end));
14523 answer.append(line7);
14524 answer.append("\n");
14525 }
14526
14527 std::string line8 = line1;
14528 if (components.protocol_end != buffer.size()) {
14529 line8[components.protocol_end] = '`';
14530 line1[components.protocol_end] = ' ';
14531
14532 for (size_t i = components.protocol_end + 1; i < line8.size(); i++) {
14533 line8[i] = '-';
14534 }
14535 line8.append(" protocol_end ");
14536 line8.append(std::to_string(components.protocol_end));
14537 answer.append(line8);
14538 answer.append("\n");
14539 }
14540
14541 if (components.hash_start == url_components::omitted) {
14542 answer.append("note: hash omitted\n");
14543 }
14544 if (components.search_start == url_components::omitted) {
14545 answer.append("note: search omitted\n");
14546 }
14547 if (components.protocol_end > buffer.size()) {
14548 answer.append("warning: protocol_end overflows\n");
14549 }
14550 if (components.username_end > buffer.size()) {
14551 answer.append("warning: username_end overflows\n");
14552 }
14553 if (components.host_start > buffer.size()) {
14554 answer.append("warning: host_start overflows\n");
14555 }
14556 if (components.host_end > buffer.size()) {
14557 answer.append("warning: host_end overflows\n");
14558 }
14559 if (components.pathname_start > buffer.size()) {
14560 answer.append("warning: pathname_start overflows\n");
14561 }
14562 return answer;
14563}
14564
14565[[nodiscard]] bool url_aggregator::validate() const noexcept {
14566 if (!is_valid) {
14567 return true;
14568 }
14569 if (!components.check_offset_consistency()) {
14570 ada_log("url_aggregator::validate inconsistent components \n",
14571 to_diagram());
14572 return false;
14573 }
14574 // We have a credible components struct, but let us investivate more
14575 // carefully:
14588 if (components.protocol_end == url_components::omitted) {
14589 ada_log("url_aggregator::validate omitted protocol_end \n", to_diagram());
14590 return false;
14591 }
14592 if (components.username_end == url_components::omitted) {
14593 ada_log("url_aggregator::validate omitted username_end \n", to_diagram());
14594 return false;
14595 }
14596 if (components.host_start == url_components::omitted) {
14597 ada_log("url_aggregator::validate omitted host_start \n", to_diagram());
14598 return false;
14599 }
14600 if (components.host_end == url_components::omitted) {
14601 ada_log("url_aggregator::validate omitted host_end \n", to_diagram());
14602 return false;
14603 }
14604 if (components.pathname_start == url_components::omitted) {
14605 ada_log("url_aggregator::validate omitted pathname_start \n", to_diagram());
14606 return false;
14607 }
14608
14609 if (components.protocol_end > buffer.size()) {
14610 ada_log("url_aggregator::validate protocol_end overflow \n", to_diagram());
14611 return false;
14612 }
14613 if (components.username_end > buffer.size()) {
14614 ada_log("url_aggregator::validate username_end overflow \n", to_diagram());
14615 return false;
14616 }
14617 if (components.host_start > buffer.size()) {
14618 ada_log("url_aggregator::validate host_start overflow \n", to_diagram());
14619 return false;
14620 }
14621 if (components.host_end > buffer.size()) {
14622 ada_log("url_aggregator::validate host_end overflow \n", to_diagram());
14623 return false;
14624 }
14625 if (components.pathname_start > buffer.size()) {
14626 ada_log("url_aggregator::validate pathname_start overflow \n",
14627 to_diagram());
14628 return false;
14629 }
14630
14631 if (components.protocol_end > 0) {
14632 if (buffer[components.protocol_end - 1] != ':') {
14633 ada_log(
14634 "url_aggregator::validate missing : at the end of the protocol \n",
14635 to_diagram());
14636 return false;
14637 }
14638 }
14639
14640 if (components.username_end != buffer.size() &&
14641 components.username_end > components.protocol_end + 2) {
14642 if (buffer[components.username_end] != ':' &&
14643 buffer[components.username_end] != '@') {
14644 ada_log(
14645 "url_aggregator::validate missing : or @ at the end of the username "
14646 "\n",
14647 to_diagram());
14648 return false;
14649 }
14650 }
14651
14652 if (components.host_start != buffer.size()) {
14653 if (components.host_start > components.username_end) {
14654 if (buffer[components.host_start] != '@') {
14655 ada_log(
14656 "url_aggregator::validate missing @ at the end of the password \n",
14657 to_diagram());
14658 return false;
14659 }
14660 } else if (components.host_start == components.username_end &&
14661 components.host_end > components.host_start) {
14662 if (components.host_start == components.protocol_end + 2) {
14663 if (buffer[components.protocol_end] != '/' ||
14664 buffer[components.protocol_end + 1] != '/') {
14665 ada_log(
14666 "url_aggregator::validate missing // between protocol and host "
14667 "\n",
14668 to_diagram());
14669 return false;
14670 }
14671 } else {
14672 if (components.host_start > components.protocol_end &&
14673 buffer[components.host_start] != '@') {
14674 ada_log(
14675 "url_aggregator::validate missing @ at the end of the username "
14676 "\n",
14677 to_diagram());
14678 return false;
14679 }
14680 }
14681 } else {
14682 if (components.host_end != components.host_start) {
14683 ada_log("url_aggregator::validate expected omitted host \n",
14684 to_diagram());
14685 return false;
14686 }
14687 }
14688 }
14689 if (components.host_end != buffer.size() &&
14690 components.pathname_start > components.host_end) {
14691 if (components.pathname_start == components.host_end + 2 &&
14692 buffer[components.host_end] == '/' &&
14693 buffer[components.host_end + 1] == '.') {
14694 if (components.pathname_start + 1 >= buffer.size() ||
14695 buffer[components.pathname_start] != '/' ||
14696 buffer[components.pathname_start + 1] != '/') {
14697 ada_log(
14698 "url_aggregator::validate expected the path to begin with // \n",
14699 to_diagram());
14700 return false;
14701 }
14702 } else if (buffer[components.host_end] != ':') {
14703 ada_log("url_aggregator::validate missing : at the port \n",
14704 to_diagram());
14705 return false;
14706 }
14707 }
14708 if (components.pathname_start != buffer.size() &&
14709 components.pathname_start < components.search_start &&
14710 components.pathname_start < components.hash_start && !has_opaque_path) {
14711 if (buffer[components.pathname_start] != '/') {
14712 ada_log("url_aggregator::validate missing / at the path \n",
14713 to_diagram());
14714 return false;
14715 }
14716 }
14717 if (components.search_start != url_components::omitted) {
14718 if (buffer[components.search_start] != '?') {
14719 ada_log("url_aggregator::validate missing ? at the search \n",
14720 to_diagram());
14721 return false;
14722 }
14723 }
14724 if (components.hash_start != url_components::omitted) {
14725 if (buffer[components.hash_start] != '#') {
14726 ada_log("url_aggregator::validate missing # at the hash \n",
14727 to_diagram());
14728 return false;
14729 }
14730 }
14731
14732 return true;
14733}
14734
14735void url_aggregator::delete_dash_dot() {
14736 ada_log("url_aggregator::delete_dash_dot");
14738 ADA_ASSERT_TRUE(has_dash_dot());
14739 buffer.erase(components.host_end, 2);
14740 components.pathname_start -= 2;
14741 if (components.search_start != url_components::omitted) {
14742 components.search_start -= 2;
14743 }
14744 if (components.hash_start != url_components::omitted) {
14745 components.hash_start -= 2;
14746 }
14748 ADA_ASSERT_TRUE(!has_dash_dot());
14749}
14750
14751inline void url_aggregator::consume_prepared_path(std::string_view input) {
14752 ada_log("url_aggregator::consume_prepared_path ", input);
14753
14762 uint8_t accumulator = checkers::path_signature(input);
14763 // Let us first detect a trivial case.
14764 // If it is special, we check that we have no dot, no %, no \ and no
14765 // character needing percent encoding. Otherwise, we check that we have no %,
14766 // no dot, and no character needing percent encoding.
14767 constexpr uint8_t need_encoding = 1;
14768 constexpr uint8_t backslash_char = 2;
14769 constexpr uint8_t dot_char = 4;
14770 constexpr uint8_t percent_char = 8;
14771 bool special = type != ada::scheme::NOT_SPECIAL;
14772 bool may_need_slow_file_handling = (type == ada::scheme::type::FILE &&
14774 bool trivial_path =
14775 (special ? (accumulator == 0)
14776 : ((accumulator & (need_encoding | dot_char | percent_char)) ==
14777 0)) &&
14778 (!may_need_slow_file_handling);
14779 if (accumulator == dot_char && !may_need_slow_file_handling) {
14780 // '4' means that we have at least one dot, but nothing that requires
14781 // percent encoding or decoding. The only part that is not trivial is
14782 // that we may have single dots and double dots path segments.
14783 // If we have such segments, then we either have a path that begins
14784 // with '.' (easy to check), or we have the sequence './'.
14785 // Note: input cannot be empty, it must at least contain one character ('.')
14786 // Note: we know that '\' is not present.
14787 if (input[0] != '.') {
14788 size_t slashdot = input.find("/.");
14789 if (slashdot == std::string_view::npos) { // common case
14790 trivial_path = true;
14791 } else { // uncommon
14792 // only three cases matter: /./, /.. or a final /
14793 trivial_path =
14794 !(slashdot + 2 == input.size() || input[slashdot + 2] == '.' ||
14795 input[slashdot + 2] == '/');
14796 }
14797 }
14798 }
14799 if (trivial_path && is_at_path()) {
14800 ada_log("parse_path trivial");
14801 buffer += '/';
14802 buffer += input;
14803 return;
14804 }
14805 std::string path = std::string(get_pathname());
14806 // We are going to need to look a bit at the path, but let us see if we can
14807 // ignore percent encoding *and* backslashes *and* percent characters.
14808 // Except for the trivial case, this is likely to capture 99% of paths out
14809 // there.
14810 bool fast_path =
14811 (special &&
14812 (accumulator & (need_encoding | backslash_char | percent_char)) == 0) &&
14813 (type != ada::scheme::type::FILE);
14814 if (fast_path) {
14815 ada_log("parse_prepared_path fast");
14816 // Here we don't need to worry about \ or percent encoding.
14817 // We also do not have a file protocol. We might have dots, however,
14818 // but dots must as appear as '.', and they cannot be encoded because
14819 // the symbol '%' is not present.
14820 size_t previous_location = 0; // We start at 0.
14821 do {
14822 size_t new_location = input.find('/', previous_location);
14823 // std::string_view path_view = input;
14824 // We process the last segment separately:
14825 if (new_location == std::string_view::npos) {
14826 std::string_view path_view = input.substr(previous_location);
14827 if (path_view == "..") { // The path ends with ..
14828 // e.g., if you receive ".." with an empty path, you go to "/".
14829 if (path.empty()) {
14830 path = '/';
14831 update_base_pathname(path);
14832 return;
14833 }
14834 // Fast case where we have nothing to do:
14835 if (path.back() == '/') {
14836 update_base_pathname(path);
14837 return;
14838 }
14839 // If you have the path "/joe/myfriend",
14840 // then you delete 'myfriend'.
14841 path.resize(path.rfind('/') + 1);
14842 update_base_pathname(path);
14843 return;
14844 }
14845 path += '/';
14846 if (path_view != ".") {
14847 path.append(path_view);
14848 }
14849 update_base_pathname(path);
14850 return;
14851 } else {
14852 // This is a non-final segment.
14853 std::string_view path_view =
14854 input.substr(previous_location, new_location - previous_location);
14855 previous_location = new_location + 1;
14856 if (path_view == "..") {
14857 size_t last_delimiter = path.rfind('/');
14858 if (last_delimiter != std::string::npos) {
14859 path.erase(last_delimiter);
14860 }
14861 } else if (path_view != ".") {
14862 path += '/';
14863 path.append(path_view);
14864 }
14865 }
14866 } while (true);
14867 } else {
14868 ada_log("parse_path slow");
14869 // we have reached the general case
14870 bool needs_percent_encoding = (accumulator & 1);
14871 std::string path_buffer_tmp;
14872 do {
14873 size_t location = (special && (accumulator & 2))
14874 ? input.find_first_of("/\\")
14875 : input.find('/');
14876 std::string_view path_view = input;
14877 if (location != std::string_view::npos) {
14878 path_view.remove_suffix(path_view.size() - location);
14879 input.remove_prefix(location + 1);
14880 }
14881 // path_buffer is either path_view or it might point at a percent encoded
14882 // temporary string.
14883 std::string_view path_buffer =
14884 (needs_percent_encoding &&
14885 ada::unicode::percent_encode<false>(
14886 path_view, character_sets::PATH_PERCENT_ENCODE, path_buffer_tmp))
14887 ? path_buffer_tmp
14888 : path_view;
14889 if (unicode::is_double_dot_path_segment(path_buffer)) {
14890 if ((helpers::shorten_path(path, type) || special) &&
14891 location == std::string_view::npos) {
14892 path += '/';
14893 }
14894 } else if (unicode::is_single_dot_path_segment(path_buffer) &&
14895 (location == std::string_view::npos)) {
14896 path += '/';
14897 }
14898 // Otherwise, if path_buffer is not a single-dot path segment, then:
14899 else if (!unicode::is_single_dot_path_segment(path_buffer)) {
14900 // If url's scheme is "file", url's path is empty, and path_buffer is a
14901 // Windows drive letter, then replace the second code point in
14902 // path_buffer with U+003A (:).
14903 if (type == ada::scheme::type::FILE && path.empty() &&
14904 checkers::is_windows_drive_letter(path_buffer)) {
14905 path += '/';
14906 path += path_buffer[0];
14907 path += ':';
14908 path_buffer.remove_prefix(2);
14909 path.append(path_buffer);
14910 } else {
14911 // Append path_buffer to url's path.
14912 path += '/';
14913 path.append(path_buffer);
14914 }
14915 }
14916 if (location == std::string_view::npos) {
14917 update_base_pathname(path);
14918 return;
14919 }
14920 } while (true);
14921 }
14922}
14923} // namespace ada
14924/* end file src/url_aggregator.cpp */
14925/* begin file src/ada_c.cpp */
14926
14930
14931extern "C" {
14932typedef void* ada_url;
14934typedef void* ada_strings;
14938
14939struct ada_string {
14940 const char* data;
14941 size_t length;
14942};
14943
14944struct ada_owned_string {
14945 const char* data;
14946 size_t length;
14947};
14948
14949struct ada_string_pair {
14950 ada_string key;
14951 ada_string value;
14952};
14953
14954ada_string ada_string_create(const char* data, size_t length) {
14955 ada_string out{};
14956 out.data = data;
14957 out.length = length;
14958 return out;
14959}
14960
14961struct ada_url_components {
14962 /*
14963 * By using 32-bit integers, we implicitly assume that the URL string
14964 * cannot exceed 4 GB.
14965 *
14966 * https://user:pass@example.com:1234/foo/bar?baz#quux
14967 * | | | | ^^^^| | |
14968 * | | | | | | | `----- hash_start
14969 * | | | | | | `--------- search_start
14970 * | | | | | `----------------- pathname_start
14971 * | | | | `--------------------- port
14972 * | | | `----------------------- host_end
14973 * | | `---------------------------------- host_start
14974 * | `--------------------------------------- username_end
14975 * `--------------------------------------------- protocol_end
14976 */
14977 uint32_t protocol_end;
14982 uint32_t username_end;
14983 uint32_t host_start;
14984 uint32_t host_end;
14985 uint32_t port;
14986 uint32_t pathname_start;
14987 uint32_t search_start;
14988 uint32_t hash_start;
14989};
14990
14991ada_url ada_parse(const char* input, size_t length) noexcept {
14993 ada::parse<ada::url_aggregator>(std::string_view(input, length)));
14994}
14995
14996ada_url ada_parse_with_base(const char* input, size_t input_length,
14997 const char* base, size_t base_length) noexcept {
14998 auto base_out =
14999 ada::parse<ada::url_aggregator>(std::string_view(base, base_length));
15000
15001 if (!base_out) {
15002 return new ada::result<ada::url_aggregator>(base_out);
15003 }
15004
15006 std::string_view(input, input_length), &base_out.value()));
15007}
15008
15009bool ada_can_parse(const char* input, size_t length) noexcept {
15010 return ada::can_parse(std::string_view(input, length));
15011}
15012
15013bool ada_can_parse_with_base(const char* input, size_t input_length,
15014 const char* base, size_t base_length) noexcept {
15015 std::string_view base_view(base, base_length);
15016 return ada::can_parse(std::string_view(input, input_length), &base_view);
15017}
15018
15019void ada_free(ada_url result) noexcept {
15021 delete r;
15022}
15023
15024ada_url ada_copy(ada_url input) noexcept {
15027}
15028
15031 return r.has_value();
15032}
15033
15034// caller must free the result with ada_free_owned_string
15037 ada_owned_string owned{};
15038 if (!r) {
15039 owned.data = nullptr;
15040 owned.length = 0;
15041 return owned;
15042 }
15043 std::string out = r->get_origin();
15044 owned.length = out.size();
15045 owned.data = new char[owned.length];
15046 memcpy((void*)owned.data, out.data(), owned.length);
15047 return owned;
15048}
15049
15051 delete[] owned.data;
15052}
15053
15056 if (!r) {
15057 return ada_string_create(nullptr, 0);
15058 }
15059 std::string_view out = r->get_href();
15060 return ada_string_create(out.data(), out.length());
15061}
15062
15065 if (!r) {
15066 return ada_string_create(nullptr, 0);
15067 }
15068 std::string_view out = r->get_username();
15069 return ada_string_create(out.data(), out.length());
15070}
15071
15074 if (!r) {
15075 return ada_string_create(nullptr, 0);
15076 }
15077 std::string_view out = r->get_password();
15078 return ada_string_create(out.data(), out.length());
15079}
15080
15083 if (!r) {
15084 return ada_string_create(nullptr, 0);
15085 }
15086 std::string_view out = r->get_port();
15087 return ada_string_create(out.data(), out.length());
15088}
15089
15092 if (!r) {
15093 return ada_string_create(nullptr, 0);
15094 }
15095 std::string_view out = r->get_hash();
15096 return ada_string_create(out.data(), out.length());
15097}
15098
15101 if (!r) {
15102 return ada_string_create(nullptr, 0);
15103 }
15104 std::string_view out = r->get_host();
15105 return ada_string_create(out.data(), out.length());
15106}
15107
15110 if (!r) {
15111 return ada_string_create(nullptr, 0);
15112 }
15113 std::string_view out = r->get_hostname();
15114 return ada_string_create(out.data(), out.length());
15115}
15116
15119 if (!r) {
15120 return ada_string_create(nullptr, 0);
15121 }
15122 std::string_view out = r->get_pathname();
15123 return ada_string_create(out.data(), out.length());
15124}
15125
15128 if (!r) {
15129 return ada_string_create(nullptr, 0);
15130 }
15131 std::string_view out = r->get_search();
15132 return ada_string_create(out.data(), out.length());
15133}
15134
15137 if (!r) {
15138 return ada_string_create(nullptr, 0);
15139 }
15140 std::string_view out = r->get_protocol();
15141 return ada_string_create(out.data(), out.length());
15142}
15143
15146 if (!r) {
15147 return 0;
15148 }
15149 return r->host_type;
15150}
15151
15154 if (!r) {
15155 return 0;
15156 }
15157 return r->type;
15158}
15159
15160bool ada_set_href(ada_url result, const char* input, size_t length) noexcept {
15162 if (!r) {
15163 return false;
15164 }
15165 return r->set_href(std::string_view(input, length));
15166}
15167
15168bool ada_set_host(ada_url result, const char* input, size_t length) noexcept {
15170 if (!r) {
15171 return false;
15172 }
15173 return r->set_host(std::string_view(input, length));
15174}
15175
15176bool ada_set_hostname(ada_url result, const char* input,
15177 size_t length) noexcept {
15179 if (!r) {
15180 return false;
15181 }
15182 return r->set_hostname(std::string_view(input, length));
15183}
15184
15185bool ada_set_protocol(ada_url result, const char* input,
15186 size_t length) noexcept {
15188 if (!r) {
15189 return false;
15190 }
15191 return r->set_protocol(std::string_view(input, length));
15192}
15193
15194bool ada_set_username(ada_url result, const char* input,
15195 size_t length) noexcept {
15197 if (!r) {
15198 return false;
15199 }
15200 return r->set_username(std::string_view(input, length));
15201}
15202
15203bool ada_set_password(ada_url result, const char* input,
15204 size_t length) noexcept {
15206 if (!r) {
15207 return false;
15208 }
15209 return r->set_password(std::string_view(input, length));
15210}
15211
15212bool ada_set_port(ada_url result, const char* input, size_t length) noexcept {
15214 if (!r) {
15215 return false;
15216 }
15217 return r->set_port(std::string_view(input, length));
15218}
15219
15220bool ada_set_pathname(ada_url result, const char* input,
15221 size_t length) noexcept {
15223 if (!r) {
15224 return false;
15225 }
15226 return r->set_pathname(std::string_view(input, length));
15227}
15228
15236void ada_set_search(ada_url result, const char* input, size_t length) noexcept {
15238 if (r) {
15239 r->set_search(std::string_view(input, length));
15240 }
15241}
15242
15250void ada_set_hash(ada_url result, const char* input, size_t length) noexcept {
15252 if (r) {
15253 r->set_hash(std::string_view(input, length));
15254 }
15255}
15256
15259 if (r) {
15260 r->clear_port();
15261 }
15262}
15263
15272 if (r) {
15273 r->clear_hash();
15274 }
15275}
15276
15285 if (r) {
15286 r->clear_search();
15287 }
15288}
15289
15292 if (!r) {
15293 return false;
15294 }
15295 return r->has_credentials();
15296}
15297
15300 if (!r) {
15301 return false;
15302 }
15303 return r->has_empty_hostname();
15304}
15305
15308 if (!r) {
15309 return false;
15310 }
15311 return r->has_hostname();
15312}
15313
15316 if (!r) {
15317 return false;
15318 }
15319 return r->has_non_empty_username();
15320}
15321
15324 if (!r) {
15325 return false;
15326 }
15327 return r->has_non_empty_password();
15328}
15329
15332 if (!r) {
15333 return false;
15334 }
15335 return r->has_port();
15336}
15337
15340 if (!r) {
15341 return false;
15342 }
15343 return r->has_password();
15344}
15345
15348 if (!r) {
15349 return false;
15350 }
15351 return r->has_hash();
15352}
15353
15356 if (!r) {
15357 return false;
15358 }
15359 return r->has_search();
15360}
15361
15362// returns a pointer to the internal url_aggregator::url_components
15364 static_assert(sizeof(ada_url_components) == sizeof(ada::url_components));
15366 if (!r) {
15367 return nullptr;
15368 }
15369 return reinterpret_cast<const ada_url_components*>(&r->get_components());
15370}
15371
15372ada_owned_string ada_idna_to_unicode(const char* input, size_t length) {
15373 std::string out = ada::idna::to_unicode(std::string_view(input, length));
15374 ada_owned_string owned{};
15375 owned.length = out.length();
15376 owned.data = new char[owned.length];
15377 memcpy((void*)owned.data, out.data(), owned.length);
15378 return owned;
15379}
15380
15381ada_owned_string ada_idna_to_ascii(const char* input, size_t length) {
15382 std::string out = ada::idna::to_ascii(std::string_view(input, length));
15383 ada_owned_string owned{};
15384 owned.length = out.size();
15385 owned.data = new char[owned.length];
15386 memcpy((void*)owned.data, out.data(), owned.length);
15387 return owned;
15388}
15389
15391 size_t length) {
15393 ada::url_search_params(std::string_view(input, length)));
15394}
15395
15400
15404 if (!r) return ada_owned_string{nullptr, 0};
15405 std::string out = r->to_string();
15406 ada_owned_string owned{};
15407 owned.length = out.size();
15408 owned.data = new char[owned.length];
15409 memcpy((void*)owned.data, out.data(), owned.length);
15410 return owned;
15411}
15412
15416 if (!r) {
15417 return 0;
15418 }
15419 return r->size();
15420}
15421
15429
15431 size_t length) {
15434 if (r) {
15435 r->reset(std::string_view(input, length));
15436 }
15437}
15438
15440 size_t key_length, const char* value,
15441 size_t value_length) {
15444 if (r) {
15445 r->append(std::string_view(key, key_length),
15446 std::string_view(value, value_length));
15447 }
15448}
15449
15451 size_t key_length, const char* value,
15452 size_t value_length) {
15455 if (r) {
15456 r->set(std::string_view(key, key_length),
15457 std::string_view(value, value_length));
15458 }
15459}
15460
15462 size_t key_length) {
15465 if (r) {
15466 r->remove(std::string_view(key, key_length));
15467 }
15468}
15469
15471 const char* key, size_t key_length,
15472 const char* value, size_t value_length) {
15475 if (r) {
15476 r->remove(std::string_view(key, key_length),
15477 std::string_view(value, value_length));
15478 }
15479}
15480
15482 size_t key_length) {
15485 if (!r) {
15486 return false;
15487 }
15488 return r->has(std::string_view(key, key_length));
15489}
15490
15492 size_t key_length, const char* value,
15493 size_t value_length) {
15496 if (!r) {
15497 return false;
15498 }
15499 return r->has(std::string_view(key, key_length),
15500 std::string_view(value, value_length));
15501}
15502
15504 size_t key_length) {
15507 if (!r) {
15508 return ada_string_create(nullptr, 0);
15509 }
15510 auto found = r->get(std::string_view(key, key_length));
15511 if (!found.has_value()) {
15512 return ada_string_create(nullptr, 0);
15513 }
15514 return ada_string_create(found->data(), found->length());
15515}
15516
15518 const char* key, size_t key_length) {
15521 if (!r) {
15523 std::vector<std::string>());
15524 }
15526 r->get_all(std::string_view(key, key_length)));
15527}
15528
15539
15550
15561
15564 delete r;
15565}
15566
15569 if (!r) {
15570 return 0;
15571 }
15572 return (*r)->size();
15573}
15574
15577 if (!r) {
15578 return ada_string_create(nullptr, 0);
15579 }
15580 std::string_view view = (*r)->at(index);
15581 return ada_string_create(view.data(), view.length());
15582}
15583
15588
15592 if (!r) {
15593 return ada_string_create(nullptr, 0);
15594 }
15595 auto next = (*r)->next();
15596 if (!next.has_value()) {
15597 return ada_string_create(nullptr, 0);
15598 }
15599 return ada_string_create(next->data(), next->length());
15600}
15601
15605 if (!r) {
15606 return false;
15607 }
15608 return (*r)->has_next();
15609}
15610
15616
15620 if (!r) {
15621 return ada_string_create(nullptr, 0);
15622 }
15623 auto next = (*r)->next();
15624 if (!next.has_value()) {
15625 return ada_string_create(nullptr, 0);
15626 }
15627 return ada_string_create(next->data(), next->length());
15628}
15629
15633 if (!r) {
15634 return false;
15635 }
15636 return (*r)->has_next();
15637}
15638
15644
15648 if (!r) return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)};
15649 auto next = (*r)->next();
15650 if (!next.has_value()) {
15651 return {ada_string_create(nullptr, 0), ada_string_create(nullptr, 0)};
15652 }
15653 return ada_string_pair{
15654 ada_string_create(next->first.data(), next->first.length()),
15655 ada_string_create(next->second.data(), next->second.length())};
15656}
15657
15661 if (!r) {
15662 return false;
15663 }
15664 return (*r)->has_next();
15665}
15666
15667} // extern "C"
15668/* end file src/ada_c.cpp */
15669/* end file src/ada.cpp */
constexpr bool has_value() const noexcept
Definition ada.h:3923
#define ADA_ASSERT_TRUE(COND)
#define ada_constexpr
#define ada_unused
Definition common_defs.h:87
#define ADA_PUSH_DISABLE_ALL_WARNINGS
#define ada_lifetime_bound
#define ADA_POP_DISABLE_WARNINGS
#define ada_warn_unused
Definition common_defs.h:88
#define ada_really_inline
Definition common_defs.h:84
ada_url_search_params ada_parse_search_params(const char *input, size_t length)
Definition ada.cpp:15390
ada_string ada_get_hash(ada_url result)
Definition ada.cpp:15090
bool ada_set_port(ada_url result, const char *input, size_t length)
Definition ada.cpp:15212
ada_strings ada_search_params_get_all(ada_url_search_params result, const char *key, size_t key_length)
Definition ada.cpp:15517
void ada_clear_search(ada_url result)
Definition ada.cpp:15283
void ada_free_search_params_entries_iter(ada_url_search_params_entries_iter result)
Definition ada.cpp:15639
bool ada_set_host(ada_url result, const char *input, size_t length)
Definition ada.cpp:15168
bool ada_has_password(ada_url result)
Definition ada.cpp:15338
bool ada_search_params_keys_iter_has_next(ada_url_search_params_keys_iter result)
Definition ada.cpp:15602
ada_string ada_search_params_values_iter_next(ada_url_search_params_values_iter result)
Definition ada.cpp:15617
void ada_free_search_params_keys_iter(ada_url_search_params_keys_iter result)
Definition ada.cpp:15584
ada_string ada_get_pathname(ada_url result)
Definition ada.cpp:15117
const ada_url_components * ada_get_components(ada_url result)
Definition ada.cpp:15363
bool ada_search_params_has_value(ada_url_search_params result, const char *key, size_t key_length, const char *value, size_t value_length)
Definition ada.cpp:15491
bool ada_has_empty_hostname(ada_url result)
Definition ada.cpp:15298
void ada_free_strings(ada_strings result)
Definition ada.cpp:15562
void ada_search_params_append(ada_url_search_params result, const char *key, size_t key_length, const char *value, size_t value_length)
Definition ada.cpp:15439
bool ada_has_non_empty_password(ada_url result)
Definition ada.cpp:15322
bool ada_set_password(ada_url result, const char *input, size_t length)
Definition ada.cpp:15203
ada_url_search_params_entries_iter ada_search_params_get_entries(ada_url_search_params result)
Definition ada.cpp:15551
void * ada_url_search_params_entries_iter
Definition ada_c.h:125
ada_string ada_get_hostname(ada_url result)
Definition ada.cpp:15108
bool ada_can_parse_with_base(const char *input, size_t input_length, const char *base, size_t base_length)
Definition ada.cpp:15013
ada_string ada_search_params_get(ada_url_search_params result, const char *key, size_t key_length)
Definition ada.cpp:15503
uint8_t ada_get_host_type(ada_url result)
Definition ada.cpp:15144
ada_string ada_get_password(ada_url result)
Definition ada.cpp:15072
void * ada_strings
Definition ada_c.h:116
void ada_search_params_sort(ada_url_search_params result)
Definition ada.cpp:15422
ada_owned_string ada_idna_to_unicode(const char *input, size_t length)
Definition ada.cpp:15372
void ada_search_params_remove_value(ada_url_search_params result, const char *key, size_t key_length, const char *value, size_t value_length)
Definition ada.cpp:15470
bool ada_set_hostname(ada_url result, const char *input, size_t length)
Definition ada.cpp:15176
ada_url ada_parse_with_base(const char *input, size_t input_length, const char *base, size_t base_length)
Definition ada.cpp:14996
void ada_free_search_params(ada_url_search_params result)
Definition ada.cpp:15396
ada_string ada_get_port(ada_url result)
Definition ada.cpp:15081
bool ada_set_pathname(ada_url result, const char *input, size_t length)
Definition ada.cpp:15220
ada_string ada_get_host(ada_url result)
Definition ada.cpp:15099
void * ada_url_search_params
Definition ada_c.h:113
ada_url ada_parse(const char *input, size_t length)
Definition ada.cpp:14991
bool ada_has_port(ada_url result)
Definition ada.cpp:15330
void ada_clear_hash(ada_url result)
Definition ada.cpp:15270
void ada_free_owned_string(ada_owned_string owned)
Definition ada.cpp:15050
ada_owned_string ada_search_params_to_string(ada_url_search_params result)
Definition ada.cpp:15401
ada_string ada_strings_get(ada_strings result, size_t index)
Definition ada.cpp:15575
bool ada_set_href(ada_url result, const char *input, size_t length)
Definition ada.cpp:15160
void ada_free(ada_url result)
Definition ada.cpp:15019
void * ada_url
Definition ada_c.h:39
bool ada_search_params_entries_iter_has_next(ada_url_search_params_entries_iter result)
Definition ada.cpp:15658
size_t ada_search_params_size(ada_url_search_params result)
Definition ada.cpp:15413
ada_owned_string ada_get_origin(ada_url result)
Definition ada.cpp:15035
ada_string ada_get_protocol(ada_url result)
Definition ada.cpp:15135
void ada_free_search_params_values_iter(ada_url_search_params_values_iter result)
Definition ada.cpp:15611
bool ada_set_username(ada_url result, const char *input, size_t length)
Definition ada.cpp:15194
ada_string ada_get_username(ada_url result)
Definition ada.cpp:15063
uint8_t ada_get_scheme_type(ada_url result)
Definition ada.cpp:15152
ada_string ada_search_params_keys_iter_next(ada_url_search_params_keys_iter result)
Definition ada.cpp:15589
ada_string_pair ada_search_params_entries_iter_next(ada_url_search_params_entries_iter result)
Definition ada.cpp:15645
void ada_clear_port(ada_url result)
Definition ada.cpp:15257
bool ada_is_valid(ada_url result)
Definition ada.cpp:15029
ada_url_search_params_keys_iter ada_search_params_get_keys(ada_url_search_params result)
Definition ada.cpp:15529
ada_owned_string ada_idna_to_ascii(const char *input, size_t length)
Definition ada.cpp:15381
void ada_set_search(ada_url result, const char *input, size_t length)
Definition ada.cpp:15236
void * ada_url_search_params_keys_iter
Definition ada_c.h:117
bool ada_search_params_values_iter_has_next(ada_url_search_params_values_iter result)
Definition ada.cpp:15630
void ada_search_params_set(ada_url_search_params result, const char *key, size_t key_length, const char *value, size_t value_length)
Definition ada.cpp:15450
ada_string ada_get_href(ada_url result)
Definition ada.cpp:15054
bool ada_set_protocol(ada_url result, const char *input, size_t length)
Definition ada.cpp:15185
size_t ada_strings_size(ada_strings result)
Definition ada.cpp:15567
ada_url_search_params_values_iter ada_search_params_get_values(ada_url_search_params result)
Definition ada.cpp:15540
bool ada_has_hash(ada_url result)
Definition ada.cpp:15346
bool ada_search_params_has(ada_url_search_params result, const char *key, size_t key_length)
Definition ada.cpp:15481
bool ada_has_hostname(ada_url result)
Definition ada.cpp:15306
bool ada_has_credentials(ada_url result)
Definition ada.cpp:15290
void * ada_url_search_params_values_iter
Definition ada_c.h:118
bool ada_can_parse(const char *input, size_t length)
Definition ada.cpp:15009
ada_string ada_get_search(ada_url result)
Definition ada.cpp:15126
void ada_search_params_reset(ada_url_search_params result, const char *input, size_t length)
Definition ada.cpp:15430
void ada_search_params_remove(ada_url_search_params result, const char *key, size_t key_length)
Definition ada.cpp:15461
bool ada_has_non_empty_username(ada_url result)
Definition ada.cpp:15314
bool ada_has_search(ada_url result)
Definition ada.cpp:15354
ada_url ada_copy(ada_url input)
Definition ada.cpp:15024
void ada_set_hash(ada_url result, const char *input, size_t length)
Definition ada.cpp:15250
constexpr uint8_t C0_CONTROL_PERCENT_ENCODE[32]
constexpr uint8_t FRAGMENT_PERCENT_ENCODE[32]
constexpr uint8_t PATH_PERCENT_ENCODE[32]
constexpr uint8_t SPECIAL_QUERY_PERCENT_ENCODE[32]
constexpr char hex[1024]
constexpr uint8_t QUERY_PERCENT_ENCODE[32]
ada_really_inline bool bit_at(const uint8_t a[], const uint8_t i)
Includes the definitions for validation functions.
constexpr bool is_windows_drive_letter(std::string_view input) noexcept
static constexpr std::array< uint8_t, 256 > path_signature_table
Definition ada.cpp:64
bool has_hex_prefix(std::string_view input)
constexpr bool is_digit(char x) noexcept
ada_really_inline bool begins_with(std::string_view view, std::string_view prefix)
Includes the definitions for helper functions.
ada_really_inline size_t find_next_host_delimiter(std::string_view view, size_t location) noexcept
Definition ada.cpp:10879
static constexpr std::array< uint8_t, 256 > authority_delimiter_special
Definition ada.cpp:11165
static constexpr std::array< uint8_t, 256 > host_delimiters
Definition ada.cpp:10871
ada_really_inline size_t find_next_host_delimiter_special(std::string_view view, size_t location) noexcept
Definition ada.cpp:10747
ada_unused std::string get_state(ada::state s)
Definition ada.cpp:10457
static constexpr std::array< uint8_t, 256 > authority_delimiter
Definition ada.cpp:11187
static constexpr std::array< uint8_t, 256 > special_host_delimiters
Definition ada.cpp:10738
ada_really_inline int trailing_zeroes(uint32_t input_num) noexcept
Definition ada.cpp:10596
const uint32_t table[8000][2]
Definition ada.cpp:719
void compose(std::u32string &input)
Definition ada.cpp:7872
constexpr char32_t hangul_tcount
Definition ada.cpp:7760
constexpr int32_t base
Definition ada.cpp:7970
void ascii_map(char *input, size_t length)
Definition ada.cpp:2779
void decompose(std::u32string &input, size_t additional_elements)
Definition ada.cpp:7795
static bool is_rtl_label(const std::u32string_view label) noexcept
Definition ada.cpp:8979
uint32_t find_range_index(uint32_t key)
Definition ada.cpp:2733
static constexpr char digit_to_char(int32_t digit)
Definition ada.cpp:7984
static constexpr int32_t adapt(int32_t d, int32_t n, bool firsttime)
Definition ada.cpp:7988
void decompose_nfc(std::u32string &input)
Definition ada.cpp:7859
bool punycode_to_utf32(std::string_view input, std::u32string &out)
Definition ada.cpp:8003
constexpr char32_t hangul_ncount
Definition ada.cpp:7761
size_t utf32_length_from_utf8(const char *buf, size_t len)
Definition ada.cpp:256
constexpr int32_t tmin
Definition ada.cpp:7971
size_t utf32_to_utf8(const char32_t *buf, size_t len, char *utf8_output)
Definition ada.cpp:265
const uint16_t composition_block[67][257]
Definition ada.cpp:7066
constexpr char32_t hangul_lbase
Definition ada.cpp:7757
const uint8_t canonical_combining_class_index[4352]
Definition ada.cpp:5760
void sort_marks(std::u32string &input)
Definition ada.cpp:7843
static constexpr uint8_t is_forbidden_domain_code_point_table[]
Definition ada.cpp:9559
bool constexpr is_ascii(std::u32string_view view)
Definition ada.cpp:9541
void normalize(std::u32string &input)
Definition ada.cpp:7953
constexpr char32_t hangul_lcount
Definition ada.cpp:7758
constexpr char32_t hangul_scount
Definition ada.cpp:7762
static direction find_direction(uint32_t code_point) noexcept
Definition ada.cpp:8953
bool utf32_to_punycode(std::u32string_view input, std::string &out)
Definition ada.cpp:8122
static directions dir_table[]
Definition ada.cpp:8224
constexpr char32_t hangul_sbase
Definition ada.cpp:7754
const uint8_t composition_index[4352]
Definition ada.cpp:6867
const uint32_t mappings[5164]
Definition ada.cpp:337
std::string to_ascii(std::string_view ut8_string)
Definition ada.cpp:9640
std::string to_unicode(std::string_view input)
Definition ada.cpp:9737
constexpr char32_t hangul_vbase
Definition ada.cpp:7756
uint8_t get_ccc(char32_t c) noexcept
Definition ada.cpp:7837
static std::string from_ascii_to_ascii(std::string_view ut8_string)
Definition ada.cpp:9584
const char32_t decomposition_data[9102]
Definition ada.cpp:4746
const uint8_t canonical_combining_class_block[67][256]
Definition ada.cpp:5991
static size_t find_last_not_of_nsm(const std::u32string_view label) noexcept
Definition ada.cpp:8969
constexpr int32_t damp
Definition ada.cpp:7974
bool is_forbidden_domain_code_point(const char c) noexcept
Definition ada.cpp:9574
constexpr int32_t skew
Definition ada.cpp:7973
bool begins_with(std::u32string_view view, std::u32string_view prefix)
Definition ada.cpp:9525
constexpr uint32_t initial_n
Definition ada.cpp:7976
const char32_t composition_data[1883]
Definition ada.cpp:7572
size_t utf8_length_from_utf32(const char32_t *buf, size_t len)
Definition ada.cpp:243
bool is_label_valid(std::u32string_view label)
Definition ada.cpp:8990
static constexpr int32_t char_to_digit_value(char value)
Definition ada.cpp:7978
std::pair< bool, size_t > compute_decomposition_length(const std::u32string_view input) noexcept
Definition ada.cpp:7765
bool ascii_has_upper_case(char *input, size_t length)
Definition ada.cpp:2755
bool contains_forbidden_domain_code_point(std::string_view ascii_string)
Definition ada.cpp:9578
std::u32string map(std::u32string_view input)
Definition ada.cpp:2805
constexpr int32_t initial_bias
Definition ada.cpp:7975
constexpr int32_t tmax
Definition ada.cpp:7972
constexpr char32_t hangul_vcount
Definition ada.cpp:7759
constexpr char32_t hangul_tbase
Definition ada.cpp:7755
size_t utf8_to_utf32(const char *buf, size_t len, char32_t *utf32_output)
Definition ada.cpp:146
const uint16_t decomposition_block[67][257]
Definition ada.cpp:3102
const uint8_t decomposition_index[4352]
Definition ada.cpp:2870
bool verify_punycode(std::string_view input)
Definition ada.cpp:8064
Includes the definitions for supported parsers.
result_type parse_url(std::string_view user_input, const result_type *base_url=nullptr)
Definition ada.cpp:13057
result_type parse_url_impl(std::string_view user_input, const result_type *base_url=nullptr)
Definition ada.cpp:12144
constexpr std::string_view is_special_list[]
Definition scheme-inl.h:19
constexpr ada::scheme::type get_scheme_type(std::string_view scheme) noexcept
Definition scheme-inl.h:72
@ NOT_SPECIAL
Definition scheme.h:32
constexpr uint16_t get_special_port(std::string_view scheme) noexcept
Definition scheme-inl.h:57
Includes the definitions for URL serializers.
std::string ipv6(const std::array< uint16_t, 8 > &address) noexcept
Definition ada.cpp:10288
void find_longest_sequence_of_ipv6_pieces(const std::array< uint16_t, 8 > &address, size_t &compress, size_t &compress_length) noexcept
Definition ada.cpp:10270
std::string ipv4(uint64_t address) noexcept
Definition ada.cpp:10329
Includes the declarations for unicode operations.
static constexpr std::array< uint8_t, 256 > is_forbidden_domain_code_point_table
Definition ada.cpp:9952
static constexpr std::array< uint8_t, 256 > is_forbidden_domain_code_point_table_or_upper
Definition ada.cpp:9992
ada_really_inline size_t percent_encode_index(const std::string_view input, const uint8_t character_set[])
Definition unicode-inl.h:19
static constexpr char hex_to_binary_table[]
Definition ada.cpp:10124
constexpr uint64_t broadcast(uint8_t v) noexcept
Definition ada.cpp:9802
constexpr bool is_tabs_or_newline(char c) noexcept
Definition ada.cpp:9798
static constexpr std::array< uint8_t, 256 > is_forbidden_host_code_point_table
Definition ada.cpp:9937
static constexpr std::array< bool, 256 > is_alnum_plus_table
Definition ada.cpp:10033
constexpr std::string_view table_is_double_dot_path_segment[]
Definition ada.cpp:10063
Definition ada_idna.h:13
bool can_parse(std::string_view input, const std::string_view *base_input=nullptr)
Definition ada.cpp:10389
template ada::result< url > parse< url >(std::string_view input, const url *base_url)
std::string href_from_file(std::string_view path)
Definition ada.cpp:10366
ada_warn_unused std::string to_string(encoding_type type)
Definition ada.cpp:10408
@ IPV4
Definition url_base.h:27
@ IPV6
Definition url_base.h:32
state
Definition state.h:17
@ SPECIAL_RELATIVE_OR_AUTHORITY
@ SPECIAL_AUTHORITY_SLASHES
@ SPECIAL_AUTHORITY_IGNORE_SLASHES
template ada::result< url_aggregator > parse< url_aggregator >(std::string_view input, const url_aggregator *base_url)
encoding_type
void unreachable()
tl::expected< result_type, ada::errors > result
ada_warn_unused ada::result< result_type > parse(std::string_view input, const result_type *base_url=nullptr)
Definition ada.cpp:10351
ada_string ada_string_create(const char *data, size_t length)
Definition ada.cpp:14954
ada::result< ada::url_aggregator > & get_instance(void *result) noexcept
Definition ada.cpp:14927
Includes all definitions for Ada.
#define ada_log(...)
Definition ada.h:1166
uint32_t final_code
Definition ada.cpp:8220
uint32_t start_code
Definition ada.cpp:8219
Lightweight URL struct.
Definition ada.h:4825
std::string_view get_hostname() const noexcept ada_lifetime_bound
Definition ada.cpp:13896
ada_really_inline bool has_credentials() const noexcept
std::string to_string() const override
Definition ada.cpp:13950
std::string_view get_pathname() const noexcept ada_lifetime_bound
Definition ada.cpp:13911
std::string_view get_hash() const noexcept ada_lifetime_bound
Definition ada.cpp:13863
std::string to_diagram() const
Definition ada.cpp:14408
bool validate() const noexcept
Definition ada.cpp:14565
std::string_view get_search() const noexcept ada_lifetime_bound
Definition ada.cpp:13926
bool has_valid_domain() const noexcept override
Definition ada.cpp:14043
std::string_view get_protocol() const noexcept ada_lifetime_bound
Definition ada.cpp:13944
std::string_view get_password() const noexcept ada_lifetime_bound
Definition ada.cpp:13843
std::string_view get_href() const noexcept ada_lifetime_bound
std::string_view get_host() const noexcept ada_lifetime_bound
Definition ada.cpp:13877
std::string_view get_username() const noexcept ada_lifetime_bound
Definition ada.cpp:13833
ada_really_inline bool is_special() const noexcept
url_host_type host_type
Definition url_base.h:60
bool is_valid
Definition url_base.h:50
bool has_opaque_path
Definition url_base.h:55
URL Component representations using offsets.
Definition ada.h:1369
bool check_offset_consistency() const noexcept
Definition ada.cpp:13075
static constexpr uint32_t omitted
Generic URL struct reliant on std::string instantiation.
Definition ada.h:5276
bool set_hostname(std::string_view input)
Definition ada.cpp:11997
bool set_host(std::string_view input)
Definition ada.cpp:11993
std::string_view get_pathname() const noexcept
Definition ada.cpp:11868
ada_really_inline std::string get_href() const noexcept
Definition url-inl.h:183
std::string get_hostname() const noexcept
Definition ada.cpp:11864
std::string get_protocol() const noexcept
Definition ada.cpp:11842
size_t length
Definition ada_c.h:25
const char * data
Definition ada_c.h:18