Commit e895ced6 by Mohan Maiya Committed by Commit Bot

Vulkan: Add OES_shader_image_atomic support

Add support for shader builtins and enable the extension. Bug: angleproject:3578 Tests: dEQP-GLES31.functional.*image_atomic* Change-Id: Idd45b2ee62efe1474c6c5947c77da64ff2221bf6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2505540 Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 4c5630d0
......@@ -26,7 +26,7 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 235
#define ANGLE_SH_VERSION 236
enum ShShaderSpec
{
......@@ -407,7 +407,7 @@ struct ShBuiltInResources
int EXT_texture_cube_map_array;
int EXT_shadow_samplers;
int OES_shader_multisample_interpolation;
int OES_shader_image_atomic;
// Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
// with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
// EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
......
......@@ -357,6 +357,14 @@ struct FeaturesVk : FeatureSetBase
"and has the shaderFloat16 feature",
&members, "http://anglebug.com/4551"};
// Whether the VkDevice supports the VK_EXT_shader_atomic_flat extension and has the
// shaderImageFloat32Atomics feature
Feature supportsShaderImageFloat32Atomics = {
"shaderImageFloat32Atomics", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_EXT_shader_atomic_float extension and has the "
"shaderImageFloat32Atomics feature.",
&members, "http://anglebug.com/3578"};
// Some devices don't meet the limits required to perform mipmap generation using the built-in
// compute shader. On some other devices, VK_IMAGE_USAGE_STORAGE_BIT is detrimental to
// performance, making this solution impractical.
......
{
"src/compiler/translator/ImmutableString_ESSL_autogen.cpp":
"98168ea2a1d9bfa290c7e72e299955f8",
"bab94ae93917a40dd2f3184be08a4933",
"src/compiler/translator/ImmutableString_autogen.cpp":
"663daecf68294fa141be288ceb7f75f0",
"fa74ff3796c28e14bb617749987c94f8",
"src/compiler/translator/ParseContext_ESSL_autogen.h":
"b33dad2b5b23cc4a48b0a8183c536c21",
"fb36d587618dabfd828d7d5f645fa2e5",
"src/compiler/translator/ParseContext_complete_autogen.h":
"6113be5f4ebd8789901ef48a611a1e03",
"2db8d7d0efd13afdd4b971c89f785f7e",
"src/compiler/translator/SymbolTable_ESSL_autogen.cpp":
"96a8712eba5ae5245af83b082cbd5219",
"6a4ad24f5d85a39e797226cc9416df1d",
"src/compiler/translator/SymbolTable_autogen.cpp":
"51bdcd32bb37a2a1bbffa154f7427694",
"0ea25cc0c63638efa3f38923e796008b",
"src/compiler/translator/SymbolTable_autogen.h":
"2d8bed6ff5debc6546199a2add316a66",
"src/compiler/translator/builtin_function_declarations.txt":
"bd195be52e11bb993aa757acb3770b85",
"dfc73c66a0efbdc7543ed7a6fbd3f00c",
"src/compiler/translator/builtin_variables.json":
"98d347a6ed181eca3d89bfd73193d787",
"src/compiler/translator/gen_builtin_symbols.py":
"a538e53475983ae9643afd5b36056347",
"src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h":
"ad4b5fafc78f98b2bf0ff1f0516d6f4b",
"359670b3327789b173bb961e3c66a19f",
"src/compiler/translator/tree_util/BuiltIn_complete_autogen.h":
"7429fd6b4be0c23aba95fbbc66a40ad9",
"2ec6e29190e01f1731b3e3a18d6f0684",
"src/tests/compiler_tests/ImmutableString_test_ESSL_autogen.cpp":
"ade4d08598c35df6eb3a67a9eb45bad8",
"90bfc0010975c358a3a8d6336f9afb01",
"src/tests/compiler_tests/ImmutableString_test_autogen.cpp":
"424a9c61841fa9b5613fb94210272c30"
"7994b8d74b3f497da8e7b031a7f83e3d"
}
\ No newline at end of file
......@@ -1091,6 +1091,7 @@ void TCompiler::setResourceString()
<< ":EXT_texture_cube_map_array:" << mResources.EXT_texture_cube_map_array
<< ":EXT_shadow_samplers:" << mResources.EXT_shadow_samplers
<< ":OES_shader_multisample_interpolation:" << mResources.OES_shader_multisample_interpolation
<< ":OES_shader_image_atomic:" << mResources.OES_shader_image_atomic
<< ":MinProgramTextureGatherOffset:" << mResources.MinProgramTextureGatherOffset
<< ":MaxProgramTextureGatherOffset:" << mResources.MaxProgramTextureGatherOffset
<< ":MaxImageUnits:" << mResources.MaxImageUnits
......
......@@ -36,6 +36,7 @@
OP(OES_EGL_image_external) \
OP(OES_EGL_image_external_essl3) \
OP(OES_shader_multisample_interpolation) \
OP(OES_shader_image_atomic) \
OP(OES_standard_derivatives) \
OP(OES_texture_3D) \
OP(OES_texture_cube_map_array) \
......
......@@ -42,6 +42,7 @@ enum class TExtension : uint8_t
OES_EGL_image_external,
OES_EGL_image_external_essl3,
OES_shader_multisample_interpolation,
OES_shader_image_atomic,
OES_standard_derivatives,
OES_texture_3D,
OES_texture_cube_map_array,
......
......@@ -24,129 +24,220 @@ std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str)
namespace
{
constexpr int mangledkT1[] = {1106, 604, 1081, 1073, 268, 909, 330, 1205, 93, 649,
1076, 1741, 178, 280, 718, 568, 1291, 1500, 200, 912,
656, 66, 1686, 281, 1191, 743, 708, 1486, 1716, 611,
693, 1452, 670, 1815, 1027, 639, 1170};
constexpr int mangledkT2[] = {234, 1220, 1447, 1660, 623, 489, 1356, 724, 1027, 1265,
552, 1361, 1696, 1334, 590, 859, 1703, 1035, 1647, 1001,
338, 662, 1306, 781, 337, 522, 1058, 822, 1177, 971,
614, 1251, 633, 159, 252, 503, 619};
constexpr int mangledkT1[] = {2708, 3175, 2064, 1771, 3131, 2903, 517, 1297, 3189, 309,
838, 1744, 2254, 1706, 1110, 2931, 629, 816, 164, 3014,
2541, 2243, 739, 611, 2611, 2519, 1809, 413, 707, 2461,
538, 796, 1466, 2213, 2296, 214, 896};
constexpr int mangledkT2[] = {843, 1097, 1828, 808, 2705, 2200, 604, 1069, 539, 814,
271, 2974, 1418, 2712, 2658, 443, 2745, 191, 3063, 2471,
3137, 1509, 692, 2747, 2848, 1058, 2208, 687, 2182, 232,
3071, 3160, 317, 3107, 776, 3070, 3194};
constexpr int mangledkG[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 1350, 0, 980, 715, 0, 0, 600,
0, 0, 0, 694, 0, 0, 1151, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
376, 1549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 349, 161,
0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 1701, 1243, 0, 212, 0,
0, 0, 0, 0, 853, 0, 649, 799, 0, 0, 0, 1218, 0, 0, 0, 0,
0, 579, 0, 0, 0, 1043, 0, 0, 645, 0, 0, 323, 0, 1451, 0, 1428,
886, 0, 0, 0, 1801, 475, 0, 0, 0, 533, 0, 0, 0, 0, 92, 1218,
299, 0, 0, 0, 0, 0, 241, 120, 129, 163, 0, 0, 0, 0, 974, 0,
0, 0, 0, 1559, 793, 1295, 0, 52, 0, 0, 0, 0, 115, 0, 0, 1804,
207, 43, 0, 874, 1672, 173, 145, 1066, 1320, 88, 0, 1548, 0, 445, 0, 0,
213, 0, 1652, 1808, 0, 837, 0, 0, 144, 367, 1, 0, 0, 0, 1213, 765,
0, 0, 256, 0, 0, 1070, 0, 592, 0, 0, 0, 979, 1009, 0, 315, 0,
138, 1056, 330, 987, 0, 0, 0, 1535, 0, 161, 0, 0, 0, 0, 736, 0,
1256, 0, 1710, 0, 1805, 0, 922, 1811, 1183, 0, 0, 524, 0, 0, 1357, 0,
1011, 0, 1077, 0, 0, 0, 0, 0, 883, 850, 1506, 0, 47, 0, 0, 0,
0, 0, 1436, 1000, 0, 959, 0, 367, 895, 0, 0, 1508, 998, 0, 0, 0,
0, 1571, 1413, 0, 1010, 0, 835, 0, 0, 0, 0, 1418, 0, 1693, 460, 0,
0, 1333, 1786, 0, 0, 0, 0, 0, 789, 328, 0, 0, 0, 1259, 1299, 571,
0, 0, 1682, 923, 809, 0, 784, 1249, 0, 982, 0, 118, 972, 330, 0, 234,
0, 0, 820, 461, 1266, 0, 0, 1128, 453, 415, 1657, 658, 1560, 0, 130, 698,
1522, 911, 553, 0, 782, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1019, 526, 676, 0, 335, 1513, 0, 457, 722, 0, 1645, 0, 1243,
0, 81, 0, 0, 1811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0,
0, 0, 160, 654, 0, 142, 0, 364, 0, 92, 1089, 827, 1408, 1477, 0, 0,
527, 0, 0, 0, 164, 0, 0, 1342, 0, 837, 1549, 0, 0, 0, 609, 0,
0, 232, 0, 0, 876, 0, 1427, 233, 547, 417, 276, 0, 0, 0, 0, 0,
777, 1483, 0, 0, 0, 0, 0, 1307, 472, 1394, 1494, 660, 662, 940, 0, 0,
496, 0, 0, 887, 1084, 0, 0, 1033, 80, 749, 0, 1109, 744, 631, 1786, 0,
1765, 0, 0, 0, 788, 0, 0, 559, 0, 752, 473, 0, 886, 1111, 0, 0,
1521, 0, 0, 825, 0, 0, 0, 0, 324, 0, 243, 1623, 0, 565, 0, 0,
0, 80, 0, 0, 674, 0, 0, 1451, 0, 582, 0, 0, 520, 814, 0, 530,
0, 878, 572, 0, 0, 304, 0, 1013, 0, 1426, 326, 1371, 818, 25, 0, 8,
0, 0, 494, 1656, 436, 0, 0, 1270, 0, 207, 0, 669, 0, 0, 8, 1759,
994, 1510, 0, 1038, 373, 0, 1105, 0, 1229, 649, 520, 0, 767, 1203, 1407, 206,
211, 268, 0, 0, 96, 0, 1410, 0, 0, 0, 0, 1597, 0, 0, 0, 476,
0, 0, 0, 0, 0, 922, 218, 36, 0, 887, 0, 0, 453, 236, 0, 1508,
0, 0, 0, 0, 175, 0, 467, 540, 685, 620, 1472, 0, 1336, 0, 1796, 0,
0, 1151, 0, 567, 776, 0, 0, 0, 1607, 1055, 203, 0, 1427, 901, 0, 174,
710, 147, 866, 1508, 0, 1342, 86, 1040, 0, 1583, 489, 530, 0, 0, 689, 105,
0, 825, 679, 1736, 1387, 1721, 0, 0, 0, 367, 875, 1446, 12, 0, 0, 1082,
0, 0, 0, 408, 0, 0, 0, 0, 0, 0, 558, 0, 0, 1160, 216, 892,
104, 0, 0, 0, 105, 765, 18, 0, 0, 0, 0, 525, 0, 0, 818, 0,
0, 932, 0, 269, 0, 251, 542, 0, 0, 879, 0, 0, 0, 0, 0, 0,
0, 931, 0, 0, 0, 0, 759, 228, 0, 437, 1502, 1412, 0, 1283, 893, 0,
0, 0, 1290, 1208, 0, 0, 769, 0, 917, 336, 475, 807, 12, 0, 130, 0,
0, 1703, 0, 0, 139, 654, 0, 0, 0, 251, 298, 0, 1772, 0, 692, 0,
661, 0, 0, 376, 1388, 238, 1628, 83, 0, 0, 619, 791, 651, 0, 783, 644,
831, 0, 547, 1235, 835, 929, 0, 1762, 1803, 0, 1118, 1365, 658, 26, 562, 0,
313, 881, 977, 0, 0, 295, 845, 887, 958, 0, 675, 813, 0, 1546, 1186, 0,
0, 1816, 0, 1010, 633, 563, 697, 29, 1002, 1806, 1221, 0, 1014, 621, 0, 427,
0, 0, 463, 1271, 0, 252, 556, 212, 255, 589, 551, 442, 1112, 0, 0, 0,
25, 591, 240, 0, 0, 881, 1145, 0, 0, 190, 0, 0, 0, 0, 0, 1161,
1728, 1328, 344, 0, 97, 1386, 23, 144, 0, 902, 575, 407, 1488, 0, 723, 0,
0, 0, 810, 0, 0, 0, 1515, 974, 0, 0, 0, 1294, 983, 370, 1544, 1328,
114, 898, 1576, 0, 1393, 1542, 1406, 341, 0, 0, 0, 157, 0, 172, 175, 685,
1448, 0, 0, 1009, 916, 302, 334, 1378, 0, 274, 0, 0, 728, 783, 59, 65,
0, 476, 32, 0, 0, 0, 0, 1288, 1249, 0, 0, 1474, 792, 0, 1696, 0,
360, 0, 0, 0, 1730, 0, 0, 0, 1237, 181, 1513, 1783, 43, 0, 0, 1768,
0, 167, 6, 1352, 0, 908, 229, 967, 0, 0, 0, 0, 0, 0, 297, 0,
0, 1167, 1097, 832, 0, 0, 1359, 1553, 653, 436, 0, 0, 1271, 1002, 0, 1114,
0, 0, 0, 0, 0, 1771, 0, 0, 269, 700, 0, 0, 0, 576, 1134, 726,
832, 0, 925, 421, 438, 308, 344, 0, 539, 0, 0, 622, 522, 1146, 0, 199,
1434, 0, 558, 481, 938, 1662, 706, 365, 0, 0, 0, 1774, 545, 0, 0, 0,
611, 0, 0, 0, 0, 0, 518, 0, 1183, 836, 0, 1580, 101, 1494, 1319, 865,
127, 767, 612, 618, 1311, 1034, 0, 7, 1347, 467, 712, 433, 185, 0, 1432, 0,
1627, 861, 0, 1008, 0, 1608, 947, 462, 0, 848, 0, 0, 1765, 0, 854, 533,
0, 721, 578, 0, 175, 1276, 839, 1753, 340, 0, 151, 269, 1253, 1630, 67, 0,
0, 1773, 88, 0, 1271, 1116, 62, 0, 0, 794, 1142, 898, 0, 0, 237, 194,
0, 843, 362, 0, 0, 594, 1623, 0, 118, 1617, 438, 221, 0, 0, 371, 608,
832, 1810, 466, 867, 1722, 0, 0, 0, 1441, 804, 0, 705, 357, 455, 348, 512,
1730, 0, 0, 534, 0, 691, 0, 1493, 0, 1150, 209, 1435, 1007, 805, 851, 12,
751, 0, 0, 0, 826, 367, 1008, 0, 739, 0, 632, 956, 339, 523, 98, 1716,
1555, 1324, 288, 685, 0, 1024, 179, 0, 0, 0, 0, 944, 0, 380, 0, 1503,
910, 6, 0, 0, 0, 1407, 1535, 0, 813, 0, 635, 0, 580, 0, 560, 0,
557, 1737, 1469, 0, 428, 1220, 499, 0, 895, 602, 1562, 315, 223, 0, 0, 475,
1072, 1723, 670, 25, 1692, 1701, 1272, 0, 0, 342, 917, 0, 216, 834, 1394, 0,
1742, 1639, 0, 534, 0, 1681, 0, 874, 0, 228, 301, 0, 1407, 872, 0, 987,
0, 680, 1679, 0, 1290, 613, 461, 147, 589, 146, 598, 1556, 0, 0, 1556, 313,
267, 0, 62, 1142, 0, 0, 159, 55, 1115, 0, 0, 1522, 1195, 1084, 0, 333,
593, 91, 0, 1066, 270, 627, 203, 1142, 1174, 271, 127, 164, 1402, 0, 0, 37,
1218, 361, 338, 1218, 712, 0, 349, 1015, 1515, 1543, 1531, 1563, 763, 281, 0, 235,
361, 277, 0, 1007, 0, 0, 568, 950, 910, 981, 1764, 0, 327, 0, 78, 0,
0, 982, 36, 0, 0, 837, 1078, 901, 1551, 1485, 113, 0, 1591, 0, 0, 702,
0, 12, 310, 1507, 7, 0, 1332, 272, 0, 1358, 1632, 0, 1712, 658, 0, 1493,
305, 0, 317, 1173, 716, 1654, 0, 402, 250, 0, 0, 796, 0, 868, 1143, 1782,
770, 0, 216, 1237, 640, 0, 321, 0, 609, 0, 0, 0, 0, 1256, 0, 0,
0, 0, 0, 767, 857, 1760, 1764, 470, 961, 0, 430, 1409, 652, 1702, 925, 501,
0, 0, 562, 0, 1322, 0, 0, 1413, 8, 0, 0, 1653, 536, 257, 16, 0,
0, 1061, 1787, 0, 392, 1345, 0, 0, 1527, 693, 844, 708, 0, 0, 0, 0,
0, 237, 290, 0, 0, 0, 0, 165, 281, 1419, 1460, 627, 1776, 1150, 38, 0,
0, 0, 568, 810, 131, 38, 399, 0, 0, 0, 0, 869, 322, 145, 0, 566,
83, 0, 0, 1303, 1206, 1159, 1395, 570, 810, 0, 0, 195, 389, 244, 0, 0,
447, 0, 1741, 1136, 76, 0, 586, 1049, 0, 781, 0, 742, 1746, 148, 0, 0,
669, 0, 0, 0, 936, 31, 0, 1288, 1442, 45, 598, 828, 1186, 215, 1230, 0,
688, 1273, 54, 0, 0, 441, 1652, 892, 0, 1648, 434, 1032, 1010, 16, 1593, 0,
0, 0, 1599, 784, 1714, 0, 0, 0, 123, 1431, 0, 508, 0, 960, 0, 0,
1561, 623, 0, 0, 670, 1292, 80, 672, 783, 11, 318, 547, 678, 0, 863, 1248,
254, 786, 0, 322, 326, 459, 900, 0, 95, 193, 1720, 381, 1587, 0, 0, 0,
266, 179, 0, 0, 258, 642, 411, 1067, 0, 0, 961, 0, 0, 1281, 1355, 426,
583, 0, 0, 112, 0, 549, 1388, 303, 390, 85, 1484, 1771, 0, 133, 0, 433,
1352, 376, 1260, 677, 0, 1630, 0, 555, 1603, 0, 661, 1528, 0, 1195, 288, 307,
150, 340, 1428, 410, 184, 0, 0, 820, 1528, 93, 280, 0, 78, 978, 0, 1631,
0, 1036, 681, 0, 1667, 109, 0, 883, 0, 101, 862, 0, 771, 110, 1290, 928,
75, 0, 696, 1232, 875, 0, 1414, 324, 237, 0, 379, 1151, 1724, 0, 76, 0,
70, 275, 39, 1058, 120, 746, 0, 1003, 83, 422, 875, 0, 616, 32, 0, 0,
0, 0, 753, 655, 0, 811, 0, 0, 185, 107, 0, 897, 0, 850, 976, 809,
0, 0, 0, 0, 1687, 511, 0, 736, 560, 1470, 1027, 1722, 992, 498, 0, 1370,
659, 0, 841, 648, 537, 561, 823, 666, 485, 926, 0, 754, 580, 728, 0, 0,
899, 0, 835, 0, 0, 771, 0, 6, 0, 664, 943, 0, 882, 58, 0, 1364,
752, 0, 0, 706, 0, 1014, 0, 0, 0, 697, 0, 0, 715, 358, 999, 0,
1106, 297, 0, 0, 0, 890, 1657, 977, 876, 407, 1249, 319, 877, 261, 0, 0,
0, 1341, 1249, 348, 1154, 0, 263, 55, 0, 0, 681, 0, 1668, 1385, 831, 1210,
356, 455, 1643, 674, 1378, 148, 0, 0, 0};
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1252, 0, 2012, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2176, 0, 1948,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1546, 0, 1019, 0, 0,
0, 50, 1098, 0, 0, 0, 0, 0, 0, 0, 1435, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 215, 0, 0, 2969, 0, 27, 0, 0, 0, 0, 0,
0, 0, 278, 0, 1107, 0, 0, 675, 0, 2734, 0, 2651, 2084, 746, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1327,
283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2970, 1142, 0, 0, 0, 1714, 0, 0, 0, 0, 0, 3096, 0, 1048, 0,
0, 0, 0, 0, 0, 0, 0, 2732, 0, 0, 0, 0, 2163, 0, 2866, 3243,
0, 0, 311, 0, 0, 0, 0, 3117, 432, 0, 0, 1865, 0, 2701, 0, 0,
2104, 0, 0, 0, 0, 321, 65, 0, 0, 0, 0, 0, 0, 2405, 0, 126,
728, 0, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1419, 0, 0, 0,
42, 0, 369, 2470, 0, 1361, 0, 222, 0, 1344, 2987, 0, 0, 0, 2228, 0,
1369, 809, 0, 210, 828, 0, 0, 0, 3024, 1105, 0, 0, 843, 0, 0, 0,
1373, 0, 0, 0, 0, 0, 0, 0, 1630, 0, 156, 0, 0, 0, 0, 0,
0, 966, 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,
1886, 0, 3125, 0, 3192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 961, 0,
0, 0, 0, 0, 0, 0, 0, 2736, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2750, 0,
0, 1180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 972, 3114, 1062, 2333,
0, 0, 0, 0, 0, 0, 0, 0, 2354, 2075, 0, 1221, 236, 0, 0, 0,
1142, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1397, 0, 0, 0, 716, 0, 0, 3022, 706, 0, 0, 0,
175, 1550, 0, 1061, 0, 0, 3264, 756, 0, 0, 0, 0, 0, 0, 2979, 0,
21, 0, 1016, 1209, 0, 0, 0, 0, 3150, 952, 0, 110, 0, 0, 3155, 2893,
0, 0, 2541, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0,
0, 2773, 0, 2395, 0, 3221, 0, 0, 0, 0, 916, 844, 2203, 0, 495, 0,
0, 0, 0, 0, 484, 0, 0, 0, 122, 0, 1700, 0, 0, 0, 781, 2394,
0, 0, 0, 0, 0, 2904, 0, 0, 293, 712, 0, 0, 0, 0, 143, 0,
1503, 0, 2489, 0, 0, 1392, 0, 3030, 0, 0, 1853, 879, 0, 0, 0, 0,
0, 2392, 0, 1859, 0, 790, 0, 0, 0, 0, 0, 1356, 599, 2922, 1316, 635,
210, 0, 1024, 0, 0, 2026, 627, 0, 1745, 833, 0, 1181, 74, 3160, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 542, 0, 0, 0, 0, 0, 863,
1394, 0, 0, 0, 0, 0, 674, 64, 0, 0, 0, 0, 0, 2555, 0, 3176,
0, 0, 0, 0, 0, 2840, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0,
328, 0, 519, 1179, 391, 297, 0, 872, 0, 521, 3069, 0, 0, 0, 0, 3010,
0, 0, 281, 0, 2870, 0, 0, 1919, 0, 0, 0, 345, 0, 0, 0, 1006,
588, 2977, 0, 1371, 312, 0, 2414, 0, 0, 0, 1150, 0, 1635, 0, 0, 0,
1999, 0, 0, 2703, 886, 1009, 0, 0, 436, 0, 2256, 0, 0, 0, 0, 0,
619, 0, 0, 0, 0, 0, 0, 573, 0, 243, 485, 2737, 0, 0, 687, 0,
0, 0, 0, 0, 1764, 2247, 0, 0, 260, 2375, 3161, 246, 2104, 122, 0, 0,
1818, 3042, 0, 0, 0, 0, 2605, 0, 0, 1073, 0, 0, 0, 2580, 0, 0,
0, 47, 0, 0, 3133, 1264, 0, 0, 1333, 0, 219, 0, 45, 0, 342, 0,
0, 1422, 1574, 0, 0, 0, 0, 0, 0, 0, 1112, 0, 0, 0, 0, 590,
517, 2919, 744, 0, 0, 0, 282, 0, 0, 2789, 2565, 1328, 0, 1435, 0, 0,
0, 371, 1712, 0, 0, 0, 2911, 0, 0, 825, 0, 0, 0, 992, 3150, 43,
91, 0, 0, 0, 192, 399, 0, 0, 3159, 553, 1089, 811, 1128, 0, 0, 1127,
0, 3200, 0, 0, 0, 1105, 2375, 825, 1249, 0, 107, 1446, 0, 0, 184, 0,
1226, 0, 1862, 2530, 1437, 0, 1317, 746, 2922, 0, 0, 849, 0, 3054, 836, 0,
0, 0, 0, 830, 0, 0, 863, 0, 0, 0, 135, 0, 0, 0, 123, 625,
910, 2974, 0, 0, 0, 0, 1967, 0, 1348, 0, 771, 2506, 78, 540, 864, 117,
0, 0, 440, 0, 0, 733, 0, 2463, 1236, 0, 0, 3057, 0, 0, 1396, 0,
1577, 0, 0, 0, 2094, 0, 0, 1331, 0, 0, 677, 0, 1345, 2659, 1924, 596,
0, 0, 0, 0, 0, 1314, 0, 62, 1483, 0, 2142, 159, 1129, 902, 219, 0,
1187, 2199, 0, 0, 0, 0, 0, 699, 0, 40, 0, 891, 3268, 0, 2960, 0,
0, 2670, 0, 0, 173, 0, 634, 2084, 0, 0, 265, 0, 0, 0, 0, 2972,
636, 0, 0, 0, 0, 1360, 0, 1168, 0, 2901, 2878, 0, 1094, 0, 0, 2124,
0, 0, 260, 0, 0, 0, 274, 0, 0, 0, 0, 0, 480, 840, 0, 0,
840, 936, 0, 176, 0, 3033, 0, 0, 88, 0, 1439, 0, 2390, 0, 0, 2978,
0, 574, 251, 1415, 2591, 0, 2791, 448, 210, 2256, 0, 661, 0, 0, 33, 3254,
1096, 0, 2736, 0, 0, 0, 1926, 0, 0, 2913, 2100, 0, 1400, 1185, 0, 290,
0, 3171, 0, 0, 0, 0, 3135, 2823, 0, 126, 0, 2761, 0, 0, 0, 1763,
0, 829, 2045, 0, 0, 0, 0, 1261, 0, 662, 0, 900, 2749, 602, 383, 0,
290, 0, 0, 0, 0, 0, 2145, 2172, 2238, 8, 2954, 0, 0, 584, 499, 1240,
0, 0, 287, 1072, 1041, 0, 2153, 3216, 0, 0, 0, 0, 0, 0, 0, 247,
1062, 2960, 0, 692, 2929, 1105, 0, 0, 0, 1533, 80, 2044, 2052, 0, 0, 1512,
3010, 1180, 0, 0, 0, 106, 0, 438, 2090, 0, 0, 2501, 0, 0, 0, 1508,
38, 0, 0, 0, 1008, 0, 376, 0, 3175, 300, 682, 46, 1088, 0, 744, 172,
119, 0, 0, 0, 371, 0, 1434, 0, 0, 0, 1344, 0, 681, 0, 0, 379,
0, 278, 3116, 0, 573, 1237, 0, 1253, 0, 844, 0, 95, 233, 526, 0, 0,
508, 172, 0, 778, 0, 0, 0, 0, 475, 2885, 0, 0, 0, 0, 0, 0,
0, 1318, 0, 1042, 214, 1552, 786, 0, 2, 457, 1617, 945, 1730, 0, 249, 1144,
0, 2220, 0, 0, 0, 0, 1543, 3142, 0, 0, 0, 0, 0, 0, 0, 56,
0, 0, 330, 2817, 0, 0, 2763, 129, 0, 0, 0, 0, 0, 1465, 0, 140,
0, 0, 3140, 0, 0, 380, 901, 0, 0, 1442, 671, 0, 3265, 738, 2361, 0,
115, 0, 481, 0, 315, 0, 0, 823, 472, 1406, 1485, 250, 0, 920, 1273, 0,
0, 1303, 0, 9, 2897, 0, 0, 3231, 1711, 0, 0, 2513, 0, 106, 0, 0,
1087, 839, 1470, 3214, 714, 0, 1511, 0, 3212, 0, 0, 354, 0, 1575, 0, 0,
0, 1824, 0, 2823, 2710, 3065, 716, 0, 2577, 0, 1109, 0, 0, 1023, 0, 1224,
0, 30, 151, 0, 2624, 0, 0, 0, 923, 1030, 0, 1212, 0, 98, 0, 1580,
0, 224, 0, 0, 111, 1725, 2310, 0, 0, 2984, 0, 1033, 0, 0, 857, 617,
671, 3172, 2603, 1216, 0, 0, 0, 0, 0, 0, 451, 1470, 1276, 2933, 0, 72,
0, 0, 0, 1494, 58, 1939, 39, 0, 0, 1320, 0, 0, 1174, 0, 259, 0,
0, 2700, 0, 0, 948, 388, 921, 0, 0, 0, 0, 0, 1239, 0, 955, 0,
0, 185, 0, 0, 1192, 0, 0, 2192, 0, 1056, 0, 1207, 834, 515, 0, 0,
0, 0, 1027, 1054, 0, 0, 1635, 0, 38, 773, 225, 248, 2922, 110, 1406, 2710,
1469, 0, 0, 0, 0, 3026, 2894, 1033, 1067, 0, 764, 2329, 0, 231, 1370, 2168,
0, 0, 1341, 0, 1250, 612, 1077, 168, 40, 0, 229, 0, 2974, 1414, 0, 0,
2719, 2101, 61, 2485, 45, 0, 0, 0, 1092, 0, 0, 0, 652, 0, 2252, 629,
3258, 0, 0, 3072, 0, 0, 1064, 1054, 0, 0, 0, 1246, 0, 1001, 402, 0,
235, 566, 248, 465, 2088, 1495, 0, 1218, 1306, 2515, 1330, 0, 0, 0, 0, 2860,
0, 1022, 0, 0, 0, 0, 0, 1018, 0, 0, 0, 1865, 2963, 0, 2365, 0,
0, 2182, 751, 969, 0, 1244, 1288, 3080, 0, 0, 1094, 0, 0, 3104, 0, 0,
0, 0, 295, 0, 0, 753, 0, 0, 1302, 0, 0, 1434, 0, 0, 0, 204,
0, 1138, 1193, 314, 1541, 792, 0, 0, 0, 0, 1314, 0, 0, 55, 0, 0,
2290, 454, 0, 0, 138, 402, 0, 1955, 0, 0, 0, 1682, 623, 1749, 0, 0,
1426, 0, 943, 0, 0, 0, 3136, 0, 0, 0, 0, 426, 861, 556, 817, 0,
0, 0, 0, 776, 2517, 1285, 0, 0, 817, 1471, 1312, 0, 0, 421, 870, 0,
32, 1551, 1761, 0, 143, 3206, 2033, 1104, 0, 0, 2572, 1228, 0, 1236, 894, 0,
0, 495, 1333, 3202, 1354, 619, 0, 215, 2702, 2026, 0, 3033, 491, 0, 2572, 187,
2934, 0, 82, 1195, 0, 406, 2013, 0, 2731, 2520, 0, 0, 306, 276, 1545, 85,
0, 244, 1352, 0, 390, 3134, 1691, 66, 911, 0, 1325, 0, 364, 764, 1020, 2515,
0, 3146, 0, 0, 223, 2553, 3079, 0, 75, 0, 269, 516, 0, 2693, 0, 390,
0, 0, 0, 0, 173, 0, 0, 0, 4, 1450, 762, 0, 1139, 0, 848, 0,
68, 1388, 1755, 989, 320, 1475, 0, 0, 0, 851, 0, 1166, 1100, 0, 990, 0,
805, 0, 1624, 0, 575, 520, 0, 0, 215, 0, 535, 0, 142, 0, 0, 0,
0, 396, 129, 144, 761, 1363, 0, 0, 594, 276, 482, 0, 0, 0, 0, 71,
0, 0, 684, 0, 0, 302, 0, 3072, 0, 0, 0, 1887, 2793, 0, 0, 0,
458, 0, 0, 0, 1018, 691, 0, 0, 3073, 0, 28, 434, 3089, 706, 2701, 220,
1101, 0, 226, 135, 3095, 0, 0, 590, 2849, 784, 349, 471, 0, 2534, 0, 0,
0, 0, 2385, 0, 77, 2714, 2099, 1336, 2144, 870, 438, 0, 0, 0, 2567, 979,
1274, 487, 0, 0, 1682, 0, 0, 0, 9, 51, 0, 0, 0, 635, 0, 0,
0, 0, 0, 0, 0, 459, 153, 720, 318, 0, 0, 79, 1536, 1226, 0, 0,
3030, 3000, 0, 632, 1050, 1112, 1344, 2409, 0, 858, 1019, 898, 0, 0, 880, 958,
0, 2926, 3171, 469, 0, 0, 423, 2183, 0, 1699, 310, 304, 393, 2645, 1061, 0,
0, 0, 0, 65, 0, 2370, 2746, 0, 0, 3126, 0, 1026, 0, 0, 649, 227,
351, 832, 944, 2033, 670, 0, 196, 642, 1047, 0, 1770, 0, 123, 2567, 688, 0,
800, 138, 452, 1332, 31, 1093, 910, 2630, 0, 0, 674, 0, 2633, 0, 234, 634,
3159, 1046, 8, 0, 0, 2435, 0, 585, 1198, 472, 0, 0, 471, 3129, 534, 0,
0, 805, 1558, 0, 0, 3226, 476, 0, 291, 0, 0, 0, 0, 0, 1433, 0,
380, 3230, 816, 0, 1462, 366, 0, 0, 1342, 427, 1407, 219, 0, 1067, 0, 2302,
0, 0, 745, 3266, 0, 0, 0, 1161, 0, 2022, 0, 2199, 2236, 0, 0, 20,
0, 1854, 1103, 1234, 655, 1371, 0, 1348, 382, 0, 2999, 1029, 1959, 1184, 149, 1503,
0, 0, 0, 2503, 3223, 0, 0, 602, 0, 102, 0, 726, 0, 109, 0, 2714,
1529, 0, 0, 2647, 1037, 0, 2837, 0, 0, 224, 245, 335, 0, 1228, 318, 0,
230, 1556, 0, 0, 156, 783, 0, 1818, 2414, 1094, 0, 2966, 52, 246, 1250, 0,
530, 1082, 1994, 644, 0, 0, 885, 0, 0, 0, 0, 0, 1020, 416, 0, 584,
0, 2647, 2663, 868, 723, 2933, 1099, 0, 1606, 0, 258, 44, 73, 0, 621, 0,
0, 137, 3168, 1859, 2700, 0, 0, 348, 0, 1556, 0, 0, 1051, 0, 0, 2626,
1386, 0, 2134, 0, 0, 0, 1177, 36, 197, 0, 0, 2102, 0, 0, 4, 1738,
153, 1891, 0, 907, 109, 0, 0, 0, 1124, 1156, 0, 0, 0, 462, 2434, 879,
373, 0, 1064, 37, 0, 2617, 0, 0, 0, 0, 0, 0, 0, 492, 2197, 799,
0, 659, 1001, 1609, 1275, 1550, 0, 0, 0, 0, 258, 0, 0, 1455, 0, 0,
627, 1950, 527, 0, 1433, 823, 0, 650, 3090, 820, 322, 0, 872, 0, 3164, 1442,
0, 0, 0, 0, 1654, 0, 0, 2920, 0, 527, 0, 113, 691, 0, 0, 1376,
1213, 0, 985, 0, 696, 0, 2365, 139, 0, 1497, 0, 0, 0, 689, 0, 0,
885, 0, 0, 0, 276, 818, 2543, 0, 0, 157, 0, 0, 3151, 1286, 1908, 0,
0, 0, 1759, 816, 0, 0, 1682, 182, 0, 1078, 0, 1215, 1408, 2164, 975, 293,
2458, 0, 1274, 0, 1544, 0, 2890, 0, 0, 516, 0, 0, 0, 0, 0, 0,
285, 0, 22, 433, 347, 621, 0, 0, 2788, 0, 0, 183, 0, 0, 111, 528,
354, 0, 182, 192, 0, 166, 0, 1019, 2014, 456, 1035, 0, 0, 0, 687, 0,
108, 2492, 1993, 186, 87, 0, 1254, 861, 137, 2731, 0, 0, 0, 368, 0, 1130,
0, 2835, 2931, 1807, 88, 0, 0, 0, 153, 0, 2288, 3063, 0, 777, 1223, 565,
1178, 3008, 0, 0, 159, 506, 885, 0, 1563, 0, 0, 1244, 1150, 2545, 963, 1447,
2844, 883, 1204, 0, 490, 1310, 522, 2397, 208, 146, 0, 0, 2112, 1526, 2095, 0,
534, 0, 1337, 88, 1486, 694, 39, 688, 0, 0, 2162, 0, 0, 0, 2477, 1423,
13, 0, 1291, 0, 0, 0, 2019, 2218, 688, 2849, 1243, 0, 0, 468, 0, 313,
0, 1392, 2178, 0, 16, 126, 0, 990, 0, 0, 0, 1854, 3264, 909, 1456, 938,
0, 0, 0, 0, 3, 2382, 0, 2837, 270, 2725, 1335, 0, 0, 679, 832, 374,
0, 1221, 2883, 0, 1537, 0, 1684, 47, 0, 1271, 2050, 1410, 0, 754, 1117, 2066,
310, 702, 0, 2719, 788, 0, 2673, 0, 2700, 0, 379, 3241, 35, 100, 581, 0,
2942, 134, 497, 0, 0, 0, 627, 1127, 326, 1753, 0, 0, 0, 1520, 0, 1475,
0, 146, 648, 1794, 0, 5, 0, 1125, 2477, 1167, 2199, 0, 750, 1696, 18, 130,
0, 1378, 400, 0, 1512, 236, 0, 1437, 962, 0, 576, 2717, 1356, 2306, 0, 950,
279, 0, 1086, 2723, 512, 0, 0, 3067, 0, 0, 2947, 457, 181, 0, 0, 0,
2847, 542, 3115, 1332, 0, 1988, 984, 0, 544, 785, 70, 0, 2336, 1499, 0, 0,
1716, 647, 0, 697, 0, 0, 0, 289, 1036, 0, 571, 2722, 752, 0, 2780, 0,
0, 580, 609, 1053, 0, 0, 0, 0, 0, 2550, 1065, 0, 0, 3069, 497, 0,
0, 606, 0, 25, 1481, 61, 328, 0, 2393, 461, 557, 381, 408, 1122, 121, 378,
1126, 905, 0, 1413, 139, 1656, 555, 48, 0, 0, 0, 49, 0, 3196, 0, 1041,
333, 338, 525, 2661, 0, 3225, 1168, 602, 1519, 0, 0, 1555, 1973, 405, 0, 0,
0, 0, 292, 1087, 1175, 961, 772, 1208, 0, 0, 460, 0, 0, 1257, 0, 631,
1133, 0, 845, 1905, 1340, 3017, 3061, 1469, 474, 2846, 486, 1571, 0, 0, 1755, 0,
0, 2587, 825, 1524, 0, 1406, 0, 711, 0, 3102, 1958, 901, 0, 838, 496, 3250,
2905, 500, 0, 0, 2018, 0, 0, 0, 0, 3088, 0, 0, 790, 1073, 2148, 0,
744, 1103, 0, 0, 0, 3027, 0, 710, 1870, 0, 2695, 0, 2523, 0, 685, 2346,
0, 582, 1428, 0, 0, 1325, 1977, 1256, 0, 598, 1197, 0, 0, 0, 707, 0,
1404, 0, 1387, 0, 1028, 0, 649, 1696, 105, 464, 1305, 0, 0, 0, 0, 2893,
1682, 1097, 0, 0, 1405, 1264, 1173, 1753, 0, 0, 0, 0, 0, 0, 0, 2398,
0, 0, 589, 1295, 249, 0, 1288, 0, 0, 0, 0, 0, 71, 918, 0, 911,
0, 2615, 1271, 0, 36, 1236, 955, 1017, 2982, 475, 1572, 154, 827, 0, 1338, 1307,
0, 359, 2587, 1262, 1021, 1273, 0, 1873, 0, 89, 658, 0, 3260, 844, 646, 0,
0, 1363, 1826, 0, 1425, 0, 0, 0, 0, 444, 833, 520, 52, 872, 531, 0,
439, 2322, 2133, 483, 2504, 0, 587, 2874, 0, 23, 3197, 410, 0, 1266, 750, 0,
0, 0, 262, 1081, 2884, 0, 0, 1645, 983, 2380, 957, 0, 0, 3008, 1145, 0,
0, 3083, 1553, 0, 0, 0, 224, 0, 812, 0, 0, 0, 0, 0, 0, 3251,
301, 46, 10, 0, 0, 0, 2568, 139, 474, 0, 72, 775, 280, 0, 0, 0,
124, 0, 1079, 1160, 551, 2609, 1275, 0, 0, 0, 0, 1144, 0, 0, 207, 0,
0, 38, 0, 601, 1539, 0, 3003, 1454, 2786, 3023, 0, 722, 2794, 1037, 815, 1188,
0, 0, 0, 925, 1841, 538, 92, 0, 0, 1247, 3035, 0, 1296, 524, 1383, 2516,
0, 76, 2061, 323, 0, 0, 0, 1199, 0, 1278, 0, 530, 185, 1119, 695, 1986,
1343, 1449, 0, 133, 24, 0, 0, 455, 0, 1325, 453, 1567, 0, 1253, 0, 0,
1369, 0, 1224, 1437, 750, 0, 549, 9, 532, 913, 902, 697, 1558, 0, 2752, 353,
386, 1098, 663, 2782, 0, 427, 3232, 25, 2989, 1293, 1028, 2316, 0, 0, 3256, 1553,
0, 150, 1371, 0, 980, 0, 873, 2980, 1260, 192, 2033, 924, 96, 0, 1189, 0,
2984, 0, 1062, 1304, 0, 0, 370, 1980, 1888, 0, 3185, 0, 1012, 564, 0, 421,
0, 391, 0, 953, 696, 0, 1046, 0, 2037, 1971, 1616, 1561, 946, 200, 0, 0,
2846, 2624, 19, 0, 0, 0, 0, 729, 0, 0, 0, 2458, 561, 533, 0, 1224,
709, 980, 0, 0, 997, 2075, 0, 0, 847, 0, 0, 889, 186, 1477, 2225, 0,
1278, 3155, 1164, 2270, 0, 522, 0, 2917, 1491, 648, 856, 1194, 0, 0, 1063, 678,
0, 1964, 0, 324, 0, 611, 138, 356, 0, 1042, 0, 1534, 1571, 0, 0, 640,
103, 1349, 0, 0, 0, 40, 0, 1439, 0, 2794, 755, 164, 1416, 1263, 2459, 0,
2099, 36, 0, 450, 2017, 0, 303, 511, 862, 2706, 2803, 2784, 7, 363, 2932, 1219,
1487, 1086, 665, 3202, 428, 0, 0, 2670, 1468, 0, 2400, 0, 312, 0, 713, 0,
657, 3076, 0, 1447, 0, 0, 2035, 2, 0, 892, 0, 0, 1953, 802, 0, 2473,
899, 739, 0, 0, 3153, 0, 0, 0, 175, 355, 1214, 0, 0, 0, 0, 0,
1046, 1328, 0, 813, 0, 0, 2260, 2092, 1144, 158, 3233, 1380, 1244, 0, 192, 393,
951, 2709, 0, 1051, 0};
int MangledHashG(const char *key, const int *T)
{
......@@ -155,7 +246,7 @@ int MangledHashG(const char *key, const int *T)
for (int i = 0; key[i] != '\0'; i++)
{
sum += T[i] * key[i];
sum %= 1817;
sum %= 3269;
}
return mangledkG[sum];
}
......@@ -165,30 +256,29 @@ int MangledPerfectHash(const char *key)
if (strlen(key) > 37)
return 0;
return (MangledHashG(key, mangledkT1) + MangledHashG(key, mangledkT2)) % 1817;
return (MangledHashG(key, mangledkT1) + MangledHashG(key, mangledkT2)) % 3269;
}
constexpr int unmangledkT1[] = {15, 233, 194, 259, 187, 65, 109, 198, 165, 206, 74, 164, 172,
198, 48, 141, 242, 152, 35, 96, 14, 179, 6, 42, 13, 35};
constexpr int unmangledkT2[] = {122, 165, 120, 12, 62, 286, 77, 258, 188, 149, 38, 244, 167,
106, 184, 260, 202, 267, 80, 149, 176, 79, 68, 194, 277, 268};
constexpr int unmangledkT1[] = {154, 95, 278, 6, 35, 255, 255, 225, 266, 107, 238, 214, 59,
198, 267, 139, 100, 265, 109, 264, 131, 194, 214, 44, 182, 215};
constexpr int unmangledkT2[] = {5, 249, 205, 267, 173, 112, 278, 212, 74, 228, 266, 117, 51,
32, 189, 252, 56, 269, 171, 211, 27, 253, 18, 16, 129, 107};
constexpr int unmangledkG[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
269, 0, 61, 0, 0, 0, 0, 0, 0, 0, 14, 7, 0, 0, 0, 0, 0, 0,
0, 0, 49, 0, 0, 20, 0, 104, 197, 0, 0, 125, 0, 0, 33, 95, 144, 0,
127, 7, 0, 194, 43, 114, 0, 0, 111, 216, 0, 101, 0, 94, 40, 156, 0, 129,
15, 0, 0, 0, 0, 134, 45, 0, 0, 17, 261, 53, 85, 77, 0, 0, 265, 37,
18, 0, 0, 0, 204, 171, 13, 242, 0, 0, 249, 0, 53, 67, 0, 215, 237, 105,
0, 255, 0, 0, 45, 0, 236, 0, 127, 0, 222, 133, 281, 63, 227, 19, 0, 0,
0, 0, 0, 129, 15, 75, 248, 0, 0, 0, 0, 0, 0, 95, 0, 0, 44, 0,
126, 142, 18, 0, 9, 137, 21, 133, 118, 284, 105, 0, 89, 261, 10, 4, 0, 6,
65, 236, 81, 32, 75, 0, 0, 121, 0, 109, 145, 0, 0, 0, 0, 148, 0, 34,
0, 0, 245, 58, 123, 31, 13, 0, 0, 94, 124, 126, 0, 180, 0, 51, 280, 241,
0, 106, 0, 71, 125, 132, 0, 206, 192, 59, 24, 0, 0, 232, 0, 202, 8, 36,
0, 119, 143, 255, 0, 0, 212, 57, 0, 0, 0, 109, 243, 47, 0, 145, 0, 90,
0, 49, 0, 70, 228, 262, 26, 97, 27, 0, 0, 122, 206, 115, 0, 173, 0, 111,
0, 88, 38, 214, 139, 13, 0, 61, 0, 62, 96, 0, 43, 46, 243, 0, 174, 261,
22, 0, 93, 0, 43, 74, 117, 80, 193, 43, 26, 0, 266, 0, 19, 156, 0, 39};
0, 0, 0, 0, 259, 157, 231, 0, 81, 131, 0, 271, 0, 0, 0, 111, 0, 0, 55,
75, 47, 73, 70, 0, 0, 242, 83, 0, 0, 198, 127, 8, 82, 100, 23, 0, 100, 0,
216, 123, 55, 242, 215, 0, 0, 0, 56, 0, 0, 0, 0, 34, 104, 0, 16, 149, 0,
0, 160, 30, 0, 0, 0, 0, 0, 0, 96, 277, 76, 82, 234, 0, 0, 120, 8, 28,
0, 173, 100, 97, 0, 0, 215, 0, 0, 78, 0, 67, 253, 0, 6, 35, 139, 241, 271,
29, 254, 0, 9, 0, 209, 36, 219, 266, 28, 0, 27, 24, 221, 45, 109, 219, 0, 13,
0, 90, 0, 188, 0, 0, 116, 78, 0, 75, 42, 146, 0, 0, 0, 0, 25, 0, 0,
163, 0, 0, 0, 141, 222, 255, 0, 0, 86, 99, 0, 124, 157, 260, 259, 0, 142, 159,
0, 23, 0, 0, 5, 67, 190, 0, 0, 202, 54, 0, 0, 34, 1, 103, 87, 51, 0,
0, 0, 10, 0, 25, 154, 161, 143, 0, 61, 0, 255, 239, 27, 126, 7, 162, 66, 0,
103, 144, 192, 0, 45, 83, 0, 46, 0, 0, 63, 110, 215, 130, 271, 21, 217, 0, 0,
0, 251, 0, 18, 15, 0, 0, 0, 266, 115, 0, 55, 137, 189, 0, 89, 142, 0, 0,
60, 96, 0, 0, 0, 137, 92, 227, 58, 70, 0, 159, 21, 38, 198, 105, 0, 72, 53,
0, 66, 30, 100, 113, 239, 0, 0, 0, 51, 0, 0, 0, 264, 0, 0, 0, 0, 0,
166, 25, 0, 135, 9, 167, 278, 0, 117, 0, 92, 0, 76};
int UnmangledHashG(const char *key, const int *T)
{
......@@ -197,7 +287,7 @@ int UnmangledHashG(const char *key, const int *T)
for (int i = 0; key[i] != '\0'; i++)
{
sum += T[i] * key[i];
sum %= 288;
sum %= 279;
}
return unmangledkG[sum];
}
......@@ -207,7 +297,7 @@ int UnmangledPerfectHash(const char *key)
if (strlen(key) > 26)
return 0;
return (UnmangledHashG(key, unmangledkT1) + UnmangledHashG(key, unmangledkT2)) % 288;
return (UnmangledHashG(key, unmangledkT1) + UnmangledHashG(key, unmangledkT2)) % 279;
}
} // namespace
......
......@@ -34,284 +34,284 @@ constexpr int mangledkT2[] = {3974, 952, 3020, 19, 962, 3302, 1369, 968, 24
1157, 2004, 4019, 4114, 1201, 3022, 2477};
constexpr int mangledkG[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 4415, 0, 0, 1692, 0, 0, 0, 0, 0, 0, 4425, 0,
0, 0, 0, 0, 0, 0, 4034, 1669, 0, 0, 0, 0, 2799, 0, 0, 0,
0, 2968, 0, 294, 0, 3468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 908, 0, 0, 0, 0, 0, 0, 2400, 0, 2142, 0, 0, 0, 0, 0,
0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 857, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 4415, 0, 0, 1691, 0, 0, 0, 0, 0, 0, 4425, 0,
0, 0, 0, 0, 0, 0, 4035, 1669, 0, 0, 0, 0, 2801, 0, 0, 0,
0, 2968, 0, 294, 0, 3469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 909, 0, 0, 0, 0, 0, 0, 2401, 0, 2142, 0, 0, 0, 0, 0,
0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 858, 0, 0, 0, 0, 0,
0, 1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1876, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 640, 810, 0, 3416, 0,
0, 3688, 0, 0, 3802, 4332, 0, 0, 2261, 0, 0, 0, 1719, 0, 0, 0,
0, 0, 1386, 0, 1507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 356, 0, 0, 0, 0, 0, 0, 432, 0, 0, 0, 1198, 0,
0, 0, 0, 0, 2445, 0, 0, 222, 0, 0, 3859, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3598, 918, 0, 0, 0, 0, 0, 0, 1694, 0, 0, 0,
0, 0, 1161, 0, 0, 0, 0, 0, 381, 0, 222, 0, 3810, 0, 1466, 3945,
0, 3178, 0, 0, 331, 60, 0, 0, 0, 605, 679, 0, 3566, 0, 0, 0,
438, 0, 3807, 0, 0, 0, 1331, 0, 0, 0, 945, 0, 0, 0, 3384, 2673,
0, 0, 0, 4287, 4141, 455, 0, 4098, 0, 0, 0, 0, 0, 0, 685, 1248,
4248, 0, 0, 0, 0, 0, 0, 0, 0, 1704, 0, 0, 0, 0, 204, 0,
0, 3604, 1783, 889, 0, 0, 0, 533, 841, 0, 0, 0, 722, 2641, 0, 0,
0, 3828, 1320, 700, 4165, 0, 2297, 1239, 0, 2147, 0, 0, 0, 0, 0, 75,
0, 0, 0, 2019, 0, 0, 0, 0, 0, 1980, 0, 0, 0, 0, 75, 0,
0, 0, 578, 1657, 0, 0, 0, 0, 2823, 240, 0, 0, 29, 0, 0, 1252,
0, 2306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1198, 3986, 0, 0, 0,
0, 0, 1984, 0, 0, 0, 1929, 3657, 0, 0, 0, 0, 1516, 0, 0, 593,
0, 0, 0, 0, 0, 0, 0, 0, 478, 0, 883, 0, 0, 0, 0, 0,
1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1100, 0, 0, 0, 0,
3867, 559, 0, 0, 0, 0, 4302, 0, 0, 0, 0, 780, 0, 0, 1982, 0,
0, 0, 4234, 0, 0, 0, 0, 0, 0, 0, 2296, 0, 0, 0, 659, 0,
0, 3233, 0, 0, 0, 0, 0, 0, 0, 322, 393, 4384, 1087, 520, 0, 1156,
1940, 0, 0, 0, 662, 866, 3748, 0, 958, 1862, 0, 409, 0, 0, 0, 1528,
0, 0, 0, 0, 0, 0, 0, 3561, 0, 210, 0, 604, 3750, 869, 0, 859,
786, 0, 0, 3852, 0, 0, 0, 0, 667, 4364, 1550, 1783, 0, 0, 0, 0,
0, 209, 0, 4182, 4421, 0, 0, 0, 0, 1394, 0, 0, 0, 1002, 0, 0,
0, 0, 0, 0, 1081, 0, 0, 0, 0, 0, 0, 3533, 0, 0, 0, 0,
507, 2504, 0, 0, 0, 0, 0, 0, 0, 1709, 806, 1351, 209, 0, 813, 0,
0, 0, 0, 0, 0, 0, 0, 0, 655, 0, 0, 0, 0, 0, 0, 4319,
0, 0, 111, 656, 0, 255, 0, 0, 315, 4070, 3520, 0, 0, 0, 0, 0,
0, 0, 0, 3079, 967, 1823, 1486, 0, 434, 0, 0, 3856, 0, 0, 4252, 2293,
0, 0, 0, 0, 0, 0, 1117, 0, 0, 1022, 0, 2050, 4188, 0, 3664, 0,
0, 0, 801, 0, 0, 0, 0, 0, 0, 0, 2511, 0, 0, 0, 0, 69,
360, 0, 873, 0, 0, 0, 0, 4049, 4196, 0, 0, 0, 2160, 506, 0, 1160,
1876, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 640, 811, 0, 3417, 0,
0, 3687, 0, 0, 3802, 4331, 0, 0, 2261, 0, 0, 0, 1718, 0, 0, 0,
0, 0, 1387, 0, 1507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 431, 0, 0, 0, 1199, 0,
0, 0, 0, 0, 2446, 0, 0, 218, 0, 0, 3861, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3600, 919, 0, 0, 0, 0, 0, 0, 1694, 0, 0, 0,
0, 0, 1161, 0, 0, 0, 0, 0, 381, 0, 221, 0, 3810, 0, 1467, 3945,
0, 3178, 0, 0, 331, 61, 0, 0, 0, 606, 680, 0, 3568, 0, 0, 0,
437, 0, 3806, 0, 0, 0, 1330, 0, 0, 0, 945, 0, 0, 0, 3384, 2674,
0, 0, 0, 4287, 4141, 454, 0, 4099, 0, 0, 0, 0, 0, 0, 684, 1247,
4248, 0, 0, 0, 0, 0, 0, 0, 0, 1705, 0, 0, 0, 0, 204, 0,
0, 3605, 1783, 889, 0, 0, 0, 533, 841, 0, 0, 0, 722, 2641, 0, 0,
0, 3827, 1320, 701, 4165, 0, 2297, 1239, 0, 2147, 0, 0, 0, 0, 0, 74,
0, 0, 0, 2019, 0, 0, 0, 0, 0, 1982, 0, 0, 0, 0, 75, 0,
0, 0, 578, 1658, 0, 0, 0, 0, 2822, 240, 0, 0, 27, 0, 0, 1251,
0, 2305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1199, 3986, 0, 0, 0,
0, 0, 1984, 0, 0, 0, 1930, 3656, 0, 0, 0, 0, 1516, 0, 0, 593,
0, 0, 0, 0, 0, 0, 0, 0, 478, 0, 882, 0, 0, 0, 0, 0,
1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1101, 0, 0, 0, 0,
3866, 559, 0, 0, 0, 0, 4302, 0, 0, 0, 0, 780, 0, 0, 1982, 0,
0, 0, 4234, 0, 0, 0, 0, 0, 0, 0, 2297, 0, 0, 0, 659, 0,
0, 3233, 0, 0, 0, 0, 0, 0, 0, 321, 393, 4385, 1088, 520, 0, 1157,
1939, 0, 0, 0, 662, 865, 3747, 0, 959, 1862, 0, 408, 0, 0, 0, 1528,
0, 0, 0, 0, 0, 0, 0, 3562, 0, 210, 0, 604, 3749, 869, 0, 859,
787, 0, 0, 3851, 0, 0, 0, 0, 2430, 4363, 1549, 1784, 0, 0, 0, 0,
0, 208, 0, 4183, 4422, 0, 0, 0, 0, 1393, 0, 0, 0, 1002, 0, 0,
0, 0, 0, 0, 1081, 0, 0, 0, 0, 0, 0, 3531, 0, 0, 0, 0,
507, 2505, 0, 0, 0, 0, 0, 0, 0, 1709, 806, 1352, 209, 0, 813, 0,
0, 0, 0, 0, 0, 0, 0, 0, 653, 0, 0, 0, 0, 0, 0, 4320,
0, 0, 111, 655, 0, 256, 0, 0, 315, 4069, 3518, 0, 0, 0, 0, 0,
0, 0, 0, 3080, 968, 1823, 1486, 0, 432, 0, 0, 3856, 0, 0, 4251, 2293,
0, 0, 0, 0, 0, 0, 1118, 0, 0, 1023, 0, 2048, 4190, 0, 3663, 0,
0, 0, 802, 0, 0, 0, 0, 0, 0, 0, 2511, 0, 0, 0, 0, 70,
359, 0, 872, 0, 0, 0, 0, 1357, 4197, 0, 0, 0, 2161, 509, 0, 1160,
0, 0, 0, 0, 0, 1966, 57, 0, 0, 4399, 0, 3118, 0, 0, 3220, 0,
36, 0, 1406, 0, 0, 0, 692, 0, 0, 1501, 0, 0, 4442, 0, 1161, 0,
35, 0, 1408, 0, 0, 0, 693, 0, 0, 1501, 0, 0, 4442, 0, 1162, 0,
660, 0, 0, 0, 0, 0, 1589, 0, 0, 0, 0, 0, 0, 847, 0, 0,
0, 536, 0, 1851, 0, 0, 0, 0, 3951, 4010, 0, 0, 1443, 0, 0, 0,
235, 0, 0, 1930, 2635, 0, 1948, 2125, 0, 631, 0, 0, 1625, 0, 0, 4132,
0, 0, 2700, 1001, 0, 0, 947, 2543, 1489, 0, 4346, 0, 0, 150, 0, 0,
2828, 0, 0, 0, 0, 0, 0, 278, 4192, 756, 0, 3986, 0, 0, 380, 0,
1812, 0, 3423, 0, 0, 0, 182, 0, 0, 0, 814, 0, 304, 4449, 0, 646,
0, 0, 95, 0, 0, 1125, 0, 0, 0, 0, 0, 3814, 0, 0, 2261, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 3776, 0, 0, 2770, 0, 0, 0,
782, 3419, 0, 4001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 986, 0,
1770, 758, 0, 0, 0, 0, 1084, 0, 343, 0, 0, 0, 0, 0, 0, 1935,
0, 0, 1532, 535, 0, 0, 0, 0, 0, 0, 1205, 3609, 0, 0, 0, 0,
0, 1031, 0, 0, 2709, 0, 4085, 0, 3679, 0, 0, 0, 514, 0, 4211, 0,
0, 357, 0, 0, 0, 0, 1866, 0, 2116, 0, 0, 0, 0, 2538, 0, 4146,
0, 0, 0, 0, 0, 1774, 1203, 4192, 0, 37, 0, 0, 4239, 1431, 0, 0,
0, 2085, 3360, 313, 1258, 3044, 1013, 0, 0, 0, 2550, 0, 937, 0, 0, 0,
0, 4097, 0, 0, 0, 2627, 1961, 0, 0, 0, 3686, 3390, 0, 0, 324, 0,
0, 0, 0, 1933, 0, 670, 0, 338, 0, 0, 0, 0, 1111, 0, 0, 0,
0, 1483, 0, 320, 0, 1248, 0, 924, 0, 0, 0, 0, 1072, 0, 0, 0,
0, 4238, 3207, 0, 396, 0, 0, 0, 84, 0, 1418, 127, 0, 1372, 0, 0,
0, 0, 0, 711, 0, 2598, 2053, 4314, 0, 2707, 568, 0, 0, 1248, 0, 0,
1186, 0, 0, 3899, 1893, 0, 0, 0, 1498, 591, 2018, 551, 2649, 911, 0, 2537,
0, 0, 0, 3434, 0, 0, 0, 0, 2339, 0, 0, 461, 0, 0, 0, 0,
0, 4013, 0, 3289, 647, 0, 0, 0, 466, 230, 0, 1544, 0, 1576, 0, 0,
0, 3249, 0, 0, 699, 0, 0, 3515, 0, 0, 0, 0, 0, 653, 0, 2703,
0, 0, 0, 2215, 0, 2015, 0, 0, 0, 0, 0, 0, 0, 0, 1307, 663,
0, 178, 0, 0, 0, 0, 2717, 927, 358, 0, 4142, 1093, 3580, 0, 467, 0,
0, 0, 0, 933, 590, 85, 3482, 1580, 3629, 0, 0, 0, 0, 0, 0, 3354,
0, 0, 165, 0, 0, 3413, 1429, 0, 0, 4427, 0, 0, 0, 0, 328, 0,
0, 0, 0, 0, 857, 0, 0, 751, 0, 0, 4389, 446, 0, 0, 1645, 0,
0, 0, 0, 0, 0, 0, 3076, 0, 0, 1571, 472, 1588, 0, 0, 0, 17,
0, 653, 816, 3016, 400, 0, 0, 0, 0, 0, 0, 4005, 0, 0, 1981, 2016,
0, 934, 0, 0, 0, 0, 0, 0, 4100, 644, 1623, 0, 0, 91, 2506, 0,
1312, 0, 2364, 0, 0, 327, 0, 0, 0, 264, 0, 3166, 3276, 4163, 1593, 0,
0, 733, 0, 0, 0, 4089, 0, 3221, 1135, 0, 0, 0, 0, 867, 2968, 1781,
0, 0, 4039, 2959, 0, 3500, 0, 3383, 1150, 2820, 268, 802, 132, 0, 0, 0,
3176, 0, 1651, 3802, 0, 0, 0, 0, 0, 2732, 0, 0, 0, 150, 0, 0,
1117, 3687, 0, 696, 2045, 0, 814, 0, 0, 0, 0, 3981, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 278, 2734, 0, 686, 853, 349, 0, 575, 2143, 0,
0, 0, 3275, 0, 3086, 0, 0, 0, 0, 563, 1960, 0, 0, 0, 4128, 311,
2688, 4370, 348, 1881, 1648, 1442, 0, 4229, 1609, 0, 0, 387, 2765, 0, 956, 0,
0, 3301, 2280, 812, 0, 0, 66, 0, 0, 0, 0, 0, 0, 3084, 203, 0,
708, 0, 235, 176, 0, 0, 0, 0, 2513, 1450, 0, 3215, 0, 0, 0, 1514,
1008, 1860, 0, 3610, 906, 0, 0, 0, 158, 0, 153, 719, 0, 1185, 396, 256,
0, 0, 517, 4240, 2401, 2210, 0, 4057, 0, 0, 1262, 0, 0, 0, 701, 604,
0, 0, 136, 0, 0, 2102, 3714, 0, 826, 2267, 344, 0, 0, 4015, 0, 3959,
1358, 0, 354, 0, 0, 598, 0, 0, 0, 0, 294, 3552, 0, 1276, 0, 0,
0, 0, 140, 0, 0, 4114, 0, 0, 0, 1945, 0, 3229, 0, 973, 102, 1382,
0, 0, 1012, 3534, 4384, 1312, 124, 2647, 0, 2014, 0, 1867, 0, 0, 3712, 99,
515, 0, 0, 166, 858, 0, 0, 0, 0, 3900, 3591, 0, 0, 0, 0, 0,
0, 0, 1972, 0, 1653, 4379, 1975, 0, 948, 0, 0, 1553, 0, 0, 0, 0,
144, 1095, 1404, 315, 0, 0, 0, 0, 1666, 0, 1042, 0, 2900, 1356, 0, 0,
0, 0, 0, 860, 0, 0, 0, 957, 1889, 0, 0, 0, 0, 3925, 0, 0,
2819, 0, 2639, 0, 0, 2583, 0, 0, 805, 1852, 0, 0, 0, 4051, 0, 3569,
0, 0, 0, 0, 0, 0, 0, 0, 885, 0, 1526, 0, 847, 0, 532, 0,
1212, 3983, 1204, 1023, 664, 1264, 2772, 0, 0, 72, 0, 1553, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2702, 2088, 811, 339, 0, 2050, 3888, 115, 72,
0, 0, 0, 1749, 1278, 232, 1112, 0, 0, 0, 0, 1421, 369, 589, 0, 0,
0, 0, 0, 3945, 0, 192, 0, 1500, 2057, 0, 3093, 0, 0, 253, 686, 0,
0, 0, 1847, 0, 0, 0, 0, 1529, 0, 222, 0, 0, 1290, 1153, 0, 0,
0, 1423, 0, 0, 91, 1760, 0, 3482, 174, 3016, 0, 0, 0, 2091, 0, 1082,
0, 1332, 2071, 573, 1651, 1903, 0, 0, 358, 3933, 999, 0, 0, 0, 0, 134,
4134, 0, 0, 0, 288, 0, 0, 0, 464, 0, 890, 408, 2369, 978, 0, 2495,
3640, 0, 0, 0, 0, 1013, 1171, 1937, 2472, 0, 0, 0, 84, 518, 0, 1452,
1596, 0, 1521, 0, 3416, 0, 1555, 0, 1997, 4117, 1537, 3658, 0, 0, 444, 451,
2039, 835, 3930, 0, 4098, 1127, 0, 500, 0, 0, 0, 249, 0, 0, 4088, 2388,
629, 0, 801, 0, 0, 1568, 771, 0, 948, 0, 140, 0, 0, 1806, 1568, 0,
0, 2031, 1755, 0, 0, 2075, 0, 2829, 0, 0, 0, 0, 854, 1779, 0, 1021,
2947, 0, 22, 0, 668, 1835, 105, 0, 0, 110, 1656, 1229, 0, 0, 0, 0,
3191, 406, 0, 752, 971, 0, 2872, 73, 0, 4399, 2629, 0, 1194, 399, 0, 949,
0, 429, 0, 4344, 2988, 0, 1480, 3077, 0, 3808, 0, 0, 0, 455, 0, 1267,
0, 0, 0, 1642, 1885, 0, 391, 1478, 1476, 0, 0, 906, 433, 0, 556, 0,
0, 3782, 0, 2578, 2017, 4024, 0, 0, 0, 570, 2699, 1749, 0, 0, 0, 2651,
1491, 0, 0, 0, 0, 905, 0, 0, 488, 1274, 0, 310, 437, 4202, 3962, 0,
255, 2234, 2841, 0, 0, 0, 1666, 263, 1319, 0, 2742, 4376, 0, 0, 1651, 0,
109, 0, 0, 0, 0, 777, 0, 0, 2423, 4124, 0, 1814, 0, 1951, 0, 0,
0, 923, 4000, 0, 1108, 201, 0, 1719, 1045, 230, 0, 1359, 102, 0, 0, 0,
105, 0, 872, 675, 0, 1685, 0, 0, 44, 0, 798, 554, 0, 239, 0, 0,
0, 0, 881, 2691, 0, 4223, 0, 845, 0, 0, 2051, 0, 0, 0, 0, 4292,
0, 1618, 125, 4436, 1169, 491, 0, 0, 3102, 0, 0, 1043, 1499, 1290, 0, 0,
0, 278, 0, 0, 1599, 0, 0, 0, 0, 0, 0, 0, 2903, 0, 0, 0,
0, 683, 471, 0, 742, 3005, 0, 0, 1851, 1386, 1159, 1494, 1859, 0, 3499, 4049,
581, 0, 0, 227, 1737, 0, 0, 0, 354, 0, 3818, 0, 4093, 0, 0, 1895,
0, 1866, 1629, 0, 696, 0, 0, 1811, 0, 0, 0, 0, 0, 0, 0, 3866,
753, 0, 0, 1902, 0, 0, 404, 830, 0, 1268, 0, 0, 0, 0, 2689, 0,
0, 0, 0, 0, 0, 1274, 0, 0, 1799, 968, 0, 0, 0, 471, 465, 110,
0, 0, 4410, 0, 2883, 3928, 724, 0, 0, 0, 1270, 2067, 2790, 1810, 0, 0,
0, 0, 97, 0, 867, 1424, 1558, 1665, 1393, 0, 939, 692, 0, 0, 290, 803,
0, 0, 1839, 0, 3826, 0, 1040, 0, 0, 0, 0, 0, 0, 0, 0, 3660,
1943, 0, 0, 958, 1505, 4211, 238, 0, 0, 0, 119, 0, 0, 0, 407, 0,
0, 0, 0, 3009, 1972, 1308, 0, 775, 0, 3397, 0, 532, 0, 0, 0, 0,
0, 0, 0, 0, 0, 786, 0, 0, 2087, 0, 0, 0, 1648, 0, 0, 841,
3232, 1828, 0, 334, 3195, 0, 13, 0, 779, 0, 1004, 1147, 0, 513, 3955, 0,
0, 154, 567, 0, 0, 0, 1905, 0, 0, 949, 1022, 0, 2350, 1139, 0, 870,
218, 291, 0, 1859, 3041, 708, 1500, 4198, 2385, 0, 0, 2040, 0, 276, 708, 3508,
0, 0, 3047, 0, 0, 183, 219, 1024, 0, 4272, 3737, 0, 2220, 0, 1223, 1984,
4319, 374, 0, 0, 0, 0, 0, 944, 2350, 496, 0, 1757, 0, 0, 0, 425,
2723, 0, 0, 0, 771, 0, 0, 1184, 960, 3976, 0, 0, 0, 0, 0, 0,
935, 0, 1339, 2161, 1198, 0, 0, 0, 0, 109, 850, 0, 0, 0, 0, 541,
2149, 415, 0, 3874, 208, 0, 1655, 495, 1902, 0, 0, 2135, 0, 0, 0, 640,
3196, 0, 0, 0, 3486, 0, 234, 0, 0, 0, 1377, 0, 0, 723, 107, 954,
0, 0, 3310, 0, 3588, 419, 0, 4015, 1633, 2624, 0, 1128, 0, 1348, 2147, 0,
0, 3078, 2173, 1650, 0, 0, 505, 0, 0, 2215, 0, 3567, 1278, 3671, 526, 1355,
0, 1077, 507, 345, 0, 695, 0, 160, 0, 1867, 1923, 0, 528, 0, 0, 555,
0, 0, 0, 0, 2207, 0, 0, 1838, 0, 0, 0, 0, 0, 1923, 1492, 0,
1738, 1336, 0, 903, 0, 691, 1268, 0, 1946, 0, 393, 0, 0, 13, 0, 0,
866, 2299, 1334, 0, 0, 0, 727, 2446, 3227, 3237, 667, 0, 0, 0, 1279, 2776,
0, 0, 0, 434, 4302, 2397, 4103, 671, 1657, 0, 0, 4023, 0, 0, 0, 0,
3357, 0, 0, 1009, 0, 0, 0, 0, 1660, 3425, 0, 0, 0, 616, 372, 0,
1705, 4365, 998, 276, 0, 0, 963, 0, 0, 794, 4047, 1750, 1406, 0, 54, 1751,
0, 0, 0, 0, 0, 0, 0, 0, 739, 0, 649, 0, 0, 0, 3990, 0,
3272, 0, 0, 0, 0, 0, 0, 0, 3295, 0, 1428, 0, 0, 812, 0, 351,
0, 3835, 0, 1564, 0, 0, 1058, 2305, 3303, 1938, 0, 923, 378, 3177, 0, 0,
1468, 0, 286, 0, 3064, 1370, 0, 675, 1708, 0, 0, 1203, 0, 0, 0, 0,
376, 0, 346, 983, 2009, 0, 3790, 27, 247, 821, 0, 836, 1905, 575, 561, 1806,
0, 107, 0, 1466, 0, 0, 1154, 87, 0, 2077, 0, 0, 838, 731, 289, 0,
0, 0, 2114, 3726, 1066, 2248, 1546, 1000, 0, 0, 550, 3065, 1987, 0, 0, 0,
0, 202, 0, 1788, 0, 981, 0, 3628, 881, 3968, 1358, 639, 4323, 0, 0, 0,
613, 751, 0, 0, 3915, 326, 4034, 452, 1688, 4105, 4054, 0, 0, 795, 755, 3427,
0, 4057, 0, 0, 0, 512, 3446, 0, 0, 0, 2624, 0, 3564, 1334, 0, 1244,
2280, 301, 0, 0, 946, 0, 0, 0, 3406, 0, 0, 0, 4298, 0, 0, 1612,
311, 1739, 0, 492, 3070, 0, 221, 3974, 1171, 898, 0, 1212, 0, 0, 1075, 2752,
582, 0, 4030, 297, 0, 0, 3208, 0, 2012, 0, 408, 459, 101, 0, 0, 0,
0, 318, 463, 4380, 0, 243, 0, 1065, 3614, 3654, 2871, 3545, 0, 0, 585, 903,
274, 0, 1457, 0, 0, 4057, 692, 15, 0, 1008, 4196, 0, 0, 0, 524, 0,
0, 0, 0, 845, 203, 1783, 2118, 0, 672, 2269, 0, 0, 1907, 0, 0, 4417,
0, 3798, 455, 0, 195, 0, 929, 4167, 480, 744, 4217, 0, 0, 3705, 2915, 2273,
1062, 677, 0, 4420, 2325, 0, 0, 0, 1178, 1725, 0, 0, 3730, 0, 38, 4270,
1585, 0, 1925, 3912, 0, 0, 0, 0, 0, 0, 4274, 0, 824, 0, 970, 0,
0, 0, 0, 1928, 298, 0, 735, 0, 0, 10, 2811, 850, 0, 2730, 1321, 4050,
3210, 0, 4321, 786, 346, 2109, 0, 0, 1919, 0, 0, 1661, 280, 174, 518, 3704,
3169, 0, 0, 3433, 3344, 3829, 3866, 0, 195, 1421, 0, 0, 2369, 483, 1717, 0,
0, 0, 0, 0, 0, 0, 594, 420, 0, 829, 0, 248, 1449, 4229, 0, 190,
0, 3538, 4358, 3070, 0, 1222, 33, 0, 0, 16, 355, 0, 361, 606, 297, 0,
1158, 1532, 0, 486, 0, 0, 0, 60, 749, 462, 861, 0, 4407, 463, 0, 0,
849, 218, 0, 0, 0, 1061, 1411, 0, 1275, 45, 0, 0, 0, 86, 670, 861,
569, 1206, 0, 0, 0, 0, 1367, 162, 352, 2631, 689, 1288, 0, 383, 0, 0,
0, 0, 1901, 1817, 532, 1743, 438, 0, 3197, 0, 1134, 4398, 0, 0, 0, 1458,
499, 253, 1313, 3691, 515, 0, 1730, 0, 1513, 691, 1126, 257, 0, 534, 0, 302,
0, 0, 0, 0, 0, 1192, 50, 0, 314, 0, 0, 332, 4102, 265, 0, 1207,
0, 2236, 0, 0, 0, 916, 0, 0, 2083, 2924, 543, 2492, 3603, 762, 423, 0,
1293, 3453, 0, 2499, 0, 1700, 0, 0, 812, 1928, 1279, 2631, 436, 1423, 0, 0,
1200, 0, 0, 1338, 67, 1873, 4153, 4268, 4239, 0, 1705, 0, 0, 0, 523, 0,
0, 2026, 986, 291, 176, 1381, 1033, 518, 0, 0, 1611, 4312, 3213, 0, 0, 952,
0, 0, 541, 818, 0, 0, 1348, 0, 0, 525, 0, 1457, 0, 1408, 3698, 823,
0, 1883, 546, 4103, 1013, 700, 1048, 1166, 840, 0, 3918, 1405, 0, 2137, 1292, 0,
0, 0, 697, 1168, 45, 0, 579, 0, 3506, 0, 4195, 2147, 0, 0, 228, 519,
0, 0, 4271, 0, 28, 0, 581, 1070, 1434, 0, 268, 0, 0, 408, 3320, 64,
1411, 730, 1394, 0, 0, 2114, 1306, 0, 0, 236, 0, 0, 3602, 4029, 0, 0,
716, 0, 2457, 0, 3916, 4440, 2554, 3643, 0, 628, 1356, 1373, 1008, 0, 0, 3023,
1346, 230, 0, 0, 1991, 430, 100, 0, 0, 0, 0, 1766, 0, 0, 3902, 0,
236, 3880, 0, 1921, 0, 2200, 0, 4411, 0, 1006, 3899, 0, 0, 282, 0, 1362,
1017, 0, 0, 1191, 4441, 0, 0, 1279, 741, 2104, 1910, 0, 0, 394, 1719, 0,
969, 0, 0, 0, 0, 4028, 0, 4148, 94, 3451, 131, 2735, 1448, 0, 228, 3911,
0, 0, 713, 0, 0, 2154, 314, 382, 3165, 157, 1849, 0, 3496, 3767, 179, 0,
0, 0, 912, 0, 0, 0, 3280, 1766, 2680, 4277, 591, 0, 4043, 3673, 3883, 0,
1562, 421, 1388, 4120, 4153, 4200, 0, 3910, 95, 3477, 242, 0, 0, 256, 1298, 459,
0, 0, 0, 0, 0, 4255, 0, 0, 440, 0, 0, 1967, 735, 2878, 0, 163,
0, 2812, 3015, 2070, 0, 0, 0, 0, 294, 1999, 1933, 4131, 1509, 2149, 0, 0,
1969, 792, 2383, 2594, 985, 1628, 0, 48, 0, 0, 0, 0, 9, 0, 1126, 49,
0, 0, 51, 0, 1013, 0, 1350, 0, 2061, 2487, 1716, 1425, 0, 3255, 970, 1752,
0, 4326, 0, 639, 0, 1347, 2053, 3757, 1295, 1818, 1805, 0, 0, 0, 4319, 2090,
0, 0, 2321, 0, 0, 3823, 193, 3422, 0, 2160, 0, 1106, 1630, 25, 0, 0,
0, 0, 1436, 3023, 1003, 0, 2324, 0, 0, 682, 1022, 1760, 0, 1894, 16, 778,
1559, 244, 1004, 0, 492, 2069, 4421, 1315, 3755, 764, 0, 0, 29, 0, 466, 1511,
412, 0, 0, 0, 570, 0, 0, 0, 2074, 1627, 0, 0, 2037, 0, 539, 832,
1953, 0, 0, 639, 650, 900, 462, 1215, 0, 1073, 0, 0, 1006, 0, 0, 0,
0, 3391, 1988, 0, 831, 1710, 0, 0, 3855, 2597, 959, 3987, 0, 4209, 0, 772,
0, 0, 4415, 2725, 0, 0, 2165, 771, 0, 0, 2181, 431, 4129, 1508, 48, 790,
3068, 0, 4308, 1596, 0, 0, 857, 0, 823, 3595, 2052, 3140, 0, 4377, 0, 194,
414, 0, 0, 1050, 963, 1533, 0, 0, 1265, 3491, 0, 0, 0, 828, 1504, 0,
1895, 0, 648, 833, 2963, 37, 3225, 1426, 3700, 1202, 1929, 1301, 2167, 0, 992, 1771,
106, 0, 842, 0, 1151, 0, 0, 0, 1605, 0, 1533, 0, 709, 96, 658, 2045,
2865, 618, 0, 3439, 0, 4312, 2084, 371, 0, 1961, 141, 0, 0, 0, 1552, 0,
0, 0, 3073, 0, 1381, 1098, 1423, 0, 2743, 0, 45, 3082, 62, 3153, 0, 3754,
3949, 2255, 808, 0, 0, 1791, 0, 2956, 1335, 152, 0, 1695, 2180, 335, 0, 502,
895, 3490, 0, 924, 441, 465, 0, 0, 3206, 3577, 407, 2564, 2165, 4008, 734, 1520,
765, 0, 0, 586, 0, 1024, 0, 1345, 1, 0, 139, 1355, 1884, 4337, 916, 1410,
0, 0, 0, 75, 0, 1201, 4196, 1720, 1178, 0, 3223, 1724, 785, 0, 0, 44,
0, 1285, 0, 145, 0, 4040, 0, 0, 0, 909, 0, 0, 277, 1485, 1494, 3994,
0, 0, 363, 952, 582, 2391, 1748, 951, 0, 0, 799, 0, 0, 3674, 7, 884,
2132, 0, 498, 702, 0, 0, 0, 1527, 0, 0, 0, 558, 3174, 0, 2887, 20,
0, 863, 0, 1542, 1194, 0, 0, 0, 1530, 0, 1426, 3370, 1183, 1888, 0, 0,
0, 1880, 0, 0, 0, 0, 1373, 0, 0, 3925, 0, 0, 609, 3556, 886, 512,
0, 1443, 1158, 0, 1601, 0, 496, 0, 0, 0, 0, 3981, 316, 0, 3998, 608,
1375, 4451, 2447, 334, 0, 615, 1540, 3032, 3997, 0, 4214, 1469, 0, 1136, 925, 1311,
0, 1763, 0, 2334, 645, 0, 942, 0, 2473, 0, 1213, 1635, 0, 0, 82, 4374,
1992, 207, 292, 1172, 0, 2020, 0, 1194, 0, 540, 0, 641, 0, 0, 0, 1653,
4302, 4209, 1076, 0, 4000, 0, 700, 3918, 3318, 3817, 750, 2117, 3307, 0, 3891, 1426,
3664, 2485, 0, 14, 0, 0, 0, 2064, 0, 0, 0, 0, 1040, 0, 2024, 856,
0, 1671, 879, 684, 683, 0, 846, 0, 1964, 3882, 0, 2652, 0, 0, 0, 3343,
3567, 1574, 0, 1079, 1180, 1637, 482, 0, 2037, 265, 0, 1412, 0, 2269, 1228, 0,
314, 297, 0, 2, 512, 0, 1097, 1346, 0, 4166, 0, 0, 0, 0, 0, 0,
1372, 368, 1293, 0, 0, 0, 2844, 571, 1965, 4451, 1206, 1894, 1973, 2267, 0, 1272,
0, 1584, 1144, 0, 2292, 1717, 3713, 1000, 0, 0, 1007, 834, 346, 1993, 1329, 4270,
2874, 2333, 0, 0, 950, 0, 0, 0, 0, 3963, 1195, 1830, 1537, 3866, 808, 1958,
0, 0, 4321, 0, 0, 0, 2289, 1032, 1592, 0, 340, 444, 3595, 3437, 424, 1916,
0, 12, 181, 1544, 2175, 0, 1535, 1624, 0, 0, 1211, 0, 0, 4223, 0, 0,
618, 2131, 0, 430, 1002, 666, 2643, 2023, 0, 1845, 632, 1055, 1251, 0, 468, 4018,
0, 0, 0, 0, 4173, 1951, 1641, 1372, 0, 0, 0, 4294, 1219, 113, 0, 418,
652, 98, 1014, 4403, 0, 1294, 0, 1339, 3942, 0, 542, 3493, 75, 919, 404, 329,
0, 1438, 300, 956, 0, 0, 602, 373, 0, 4302, 2585, 23, 1959, 293, 3629, 1485,
1241, 0, 0, 0, 1109, 0, 533, 0, 1842, 772, 0, 879, 1239, 0, 1545, 0,
0, 0, 159, 112, 730, 0, 0, 0, 1284, 126, 2537, 2421, 0, 1076, 656, 862,
3395, 3538, 399, 859, 1477, 0, 3064, 0, 0, 1873, 0, 1187, 39, 3292, 397, 0,
0, 1097, 1548, 0, 0, 0, 3, 4273, 3348, 1906, 518, 1258, 1309, 167, 753, 330,
0, 2196, 777, 3060, 0, 1447, 810, 0, 983, 0, 0, 1386, 1266, 0, 0, 0,
1429, 1565, 1976, 3102, 0, 0, 0, 3726, 0, 2404, 0, 0, 3509, 2114, 0, 1146,
0, 1704, 0, 0, 74, 0, 3847, 0, 0, 0, 0, 822, 3349, 4291, 977, 1393,
1631, 0, 4271, 1276, 0, 0, 0, 2093, 774, 0, 3926, 900, 0, 3714, 0, 0,
1582, 0, 1741, 4024, 748, 2962, 1208, 0, 0, 1440, 941, 2827, 0, 797, 2566, 4276,
252, 2841, 3771, 0, 1222, 0, 0, 1900, 0, 3581, 1281, 1111, 0, 1261, 122, 116,
380, 537, 1615, 2427, 1559, 1101, 2474, 1722, 0, 902, 0, 3891, 468, 3629, 338, 0,
887, 4365, 676, 1438, 838, 119, 0, 940, 0, 1869, 353, 1742, 0, 1479, 0, 3561,
0, 1483, 3730, 0, 3009, 0, 0, 0, 1887, 161, 635, 0, 3015, 0, 4170, 0,
0, 946, 0, 118, 1617, 0, 0, 2563, 170, 458, 0, 1046, 1107, 1879, 504, 0,
2102, 0, 1144, 2340, 364, 0, 0, 0, 39, 0, 2062, 282, 0, 744, 4329, 0,
98, 1996, 0, 2710, 1761, 0, 1424, 3704, 0, 0, 0, 0, 1356, 4382, 3326, 0,
0, 3027, 499, 2275, 0, 3230, 0, 922, 0, 0, 4362, 4025, 869, 0, 0, 0,
1528, 0, 2906, 915, 0, 0, 4270, 1210, 0, 1802, 0, 0, 2894, 1825, 873, 1052,
1322, 1833, 360, 0, 1586, 1732, 0, 1071, 0, 0, 0, 942, 1379, 0, 3870, 4429,
3155, 1312, 2013, 0, 4231, 1316, 335, 637, 2071, 19, 4384, 0, 832, 0, 3, 0,
0, 0, 1650, 4307, 0, 1869, 0, 0, 4114, 1016, 317, 0, 0, 1842, 0, 1377,
577, 0, 0, 4442, 80, 3850, 0, 1643, 4385, 3916, 1747, 0, 1664, 0, 1216, 367,
0, 0, 937, 0, 207, 2033, 0, 413, 655, 632, 433, 0, 0, 933, 0, 36,
4005, 0, 0, 1536, 342, 0, 0, 667, 363, 117, 4353, 0, 0, 0, 249, 104,
1553, 1547, 19, 0, 493, 1351, 1917, 1691, 0, 1347, 0, 380, 757, 0, 0, 0,
0, 0, 1415, 0, 1644, 0, 0, 241, 3884, 2487, 1276, 0, 0, 714, 0, 1468,
0, 145, 1965, 0, 1115, 0, 2624, 0, 878, 2183, 1566, 1770, 850, 699, 0, 0,
2283, 535, 0, 584, 0, 2002, 242, 0, 3766, 1093, 2006, 0, 0, 0, 4207, 3761,
4353, 1045, 310, 3707, 0, 1252, 1283, 0, 0, 3089, 337, 2235, 161, 4231, 0, 422,
5, 694, 1718, 0, 1853, 1475, 191, 1297, 0, 0, 2917, 4064, 0, 0, 1088, 0,
0, 1309, 2035, 4328, 34, 0, 0, 1853, 0, 4389, 1250, 0, 1094, 1677, 1125, 1034,
1048, 773, 2533, 769, 15, 343, 3631, 768, 539, 0, 1909, 672, 0, 460, 1732, 0,
4192, 0, 1434, 1388, 2036, 0, 0, 2293, 0, 0, 919, 0, 1137, 1125, 0, 0,
0, 1454, 0, 1987, 0, 1289, 77};
0, 536, 0, 1852, 0, 0, 0, 0, 3950, 4010, 0, 0, 1443, 0, 0, 0,
235, 0, 0, 1930, 2636, 0, 1948, 2125, 0, 631, 0, 0, 1626, 0, 0, 4130,
0, 0, 2700, 1002, 0, 0, 948, 2542, 1493, 0, 4345, 0, 0, 151, 0, 0,
2828, 0, 0, 0, 0, 0, 0, 278, 4191, 756, 0, 3986, 0, 0, 380, 0,
1810, 0, 3423, 0, 0, 0, 183, 0, 0, 0, 813, 0, 304, 4453, 0, 647,
0, 0, 96, 0, 0, 1125, 0, 0, 0, 0, 0, 3813, 0, 0, 2261, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 3774, 0, 0, 2771, 0, 0, 0,
784, 3419, 0, 4000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 986, 0,
3, 4422, 0, 0, 0, 0, 1085, 0, 2105, 0, 0, 0, 0, 0, 0, 1935,
0, 0, 1532, 536, 0, 0, 0, 0, 0, 0, 1204, 3610, 0, 0, 0, 0,
0, 1032, 0, 0, 2706, 0, 4084, 0, 3679, 0, 0, 0, 515, 0, 4210, 0,
0, 357, 0, 0, 0, 0, 1868, 0, 2116, 0, 0, 0, 0, 2537, 0, 4146,
0, 0, 0, 0, 0, 1774, 1202, 4192, 0, 38, 0, 0, 4239, 1431, 0, 0,
0, 2086, 3359, 313, 1257, 3045, 1014, 0, 0, 0, 2549, 0, 938, 0, 0, 0,
0, 4095, 0, 0, 0, 2625, 1961, 0, 0, 0, 3687, 3390, 0, 0, 325, 0,
0, 0, 0, 1933, 0, 667, 0, 338, 0, 0, 0, 0, 1111, 0, 0, 0,
0, 1483, 0, 320, 0, 1248, 0, 925, 0, 0, 0, 0, 1074, 0, 0, 0,
0, 4239, 3207, 0, 396, 0, 0, 0, 85, 0, 1418, 127, 0, 1372, 0, 0,
0, 0, 0, 710, 0, 2599, 2053, 4316, 0, 2708, 570, 0, 0, 1248, 0, 0,
1187, 0, 0, 3899, 1895, 0, 0, 0, 1498, 594, 2018, 553, 2649, 911, 0, 2538,
0, 0, 0, 3433, 0, 0, 0, 0, 2340, 0, 0, 461, 0, 0, 0, 0,
0, 4014, 0, 3287, 647, 0, 0, 0, 466, 229, 0, 1544, 0, 1576, 0, 0,
0, 3251, 0, 0, 698, 0, 0, 3516, 0, 0, 0, 0, 0, 653, 0, 2703,
0, 0, 0, 2212, 0, 2015, 0, 0, 0, 0, 0, 0, 0, 0, 1307, 663,
0, 179, 0, 0, 0, 0, 2717, 929, 358, 0, 4142, 1092, 3578, 0, 3160, 0,
0, 0, 0, 932, 590, 85, 3483, 1580, 3628, 0, 0, 0, 0, 0, 0, 3354,
0, 0, 166, 0, 0, 3413, 1430, 0, 0, 4427, 0, 0, 0, 0, 328, 0,
0, 0, 0, 0, 856, 0, 0, 4415, 0, 0, 4389, 446, 0, 0, 1645, 0,
0, 0, 0, 0, 0, 0, 3077, 0, 0, 1571, 472, 1588, 0, 0, 0, 17,
0, 653, 815, 3015, 400, 0, 0, 0, 0, 0, 0, 4004, 0, 0, 1981, 2016,
0, 935, 0, 0, 0, 0, 0, 0, 4100, 644, 1623, 0, 0, 91, 2507, 0,
1311, 0, 2364, 0, 0, 327, 0, 0, 0, 264, 0, 3167, 3276, 4162, 1591, 0,
0, 736, 0, 0, 0, 4089, 0, 3221, 1136, 0, 0, 0, 0, 867, 2968, 1781,
0, 0, 4040, 2958, 0, 3499, 0, 3382, 1149, 2819, 266, 802, 133, 0, 0, 0,
3176, 0, 1650, 3802, 0, 0, 0, 0, 0, 2732, 0, 0, 0, 151, 0, 0,
1117, 3687, 0, 696, 2046, 0, 814, 0, 0, 0, 0, 3982, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 279, 2735, 0, 689, 853, 349, 0, 574, 2143, 0,
0, 0, 3275, 0, 3086, 0, 0, 0, 0, 562, 1960, 0, 0, 0, 4129, 312,
2687, 4370, 347, 1881, 1648, 1442, 0, 4226, 1609, 0, 0, 386, 2767, 0, 956, 0,
0, 3301, 2280, 812, 0, 0, 66, 0, 0, 0, 0, 0, 0, 3085, 203, 0,
709, 0, 235, 177, 0, 0, 0, 0, 2512, 1450, 0, 3215, 0, 0, 0, 1514,
1008, 1860, 0, 3610, 908, 0, 0, 0, 158, 0, 153, 719, 0, 1184, 397, 256,
0, 0, 517, 4241, 2402, 2208, 0, 4057, 0, 0, 1261, 0, 0, 0, 701, 604,
0, 0, 135, 0, 0, 2102, 3714, 0, 826, 2268, 344, 0, 0, 4015, 0, 3958,
1357, 0, 354, 0, 0, 598, 0, 0, 0, 0, 294, 3554, 0, 1277, 0, 0,
0, 0, 141, 0, 0, 4115, 0, 0, 0, 1945, 0, 3230, 0, 972, 101, 1382,
0, 0, 1014, 3534, 4383, 1312, 125, 2647, 0, 2014, 0, 1866, 0, 0, 3715, 99,
515, 0, 0, 167, 2621, 0, 0, 0, 0, 3900, 3592, 0, 0, 0, 0, 0,
0, 0, 1972, 0, 1653, 4378, 1975, 0, 950, 0, 0, 1553, 0, 0, 0, 0,
145, 1093, 1404, 314, 0, 0, 0, 0, 1668, 0, 1042, 0, 2900, 1355, 0, 0,
0, 0, 0, 858, 0, 0, 0, 958, 1889, 0, 0, 0, 0, 3924, 0, 0,
2819, 0, 2638, 0, 0, 2585, 0, 0, 807, 1852, 0, 0, 0, 4051, 0, 3570,
0, 0, 0, 0, 0, 0, 0, 0, 883, 0, 1526, 0, 847, 0, 532, 0,
1214, 3981, 1205, 1023, 664, 1264, 2773, 0, 0, 73, 0, 1555, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2701, 2088, 811, 339, 0, 2050, 3888, 4133, 73,
0, 0, 0, 1749, 1278, 232, 1113, 0, 0, 0, 0, 1423, 369, 589, 0, 0,
0, 0, 0, 3947, 0, 192, 0, 1500, 2058, 0, 3093, 0, 0, 253, 686, 0,
0, 0, 1847, 0, 0, 0, 0, 1531, 0, 222, 0, 0, 1291, 1154, 0, 0,
0, 1422, 0, 0, 92, 1761, 0, 3482, 175, 3016, 0, 0, 0, 2091, 0, 1083,
0, 1331, 2074, 573, 1650, 1903, 0, 0, 358, 3934, 1000, 0, 0, 0, 0, 135,
4136, 0, 0, 0, 288, 0, 0, 0, 464, 0, 890, 408, 2370, 979, 0, 2494,
3640, 0, 0, 0, 0, 1013, 1172, 1937, 2471, 0, 0, 0, 84, 519, 0, 1452,
1596, 0, 1521, 0, 3417, 0, 1555, 0, 1997, 4116, 1537, 3657, 0, 0, 445, 451,
2039, 835, 3931, 0, 4100, 1128, 0, 501, 0, 0, 0, 248, 0, 0, 4088, 2388,
629, 0, 801, 0, 0, 1568, 771, 0, 949, 0, 140, 0, 0, 1806, 1568, 0,
0, 2030, 1755, 0, 0, 2075, 0, 2829, 0, 0, 0, 0, 854, 1779, 0, 1022,
2947, 0, 2714, 0, 668, 1835, 106, 0, 0, 111, 1656, 1230, 0, 0, 0, 0,
3187, 406, 0, 752, 972, 0, 2872, 73, 0, 4400, 2630, 0, 1194, 399, 0, 948,
0, 429, 0, 4344, 2988, 0, 1482, 3078, 0, 3811, 0, 0, 0, 453, 0, 1268,
0, 0, 0, 1643, 1883, 0, 391, 1478, 1476, 0, 0, 907, 432, 0, 556, 0,
0, 3783, 0, 2575, 2017, 4024, 0, 0, 0, 570, 2698, 1749, 0, 0, 0, 2650,
1490, 0, 0, 0, 0, 906, 0, 0, 488, 1274, 0, 310, 436, 4202, 3961, 0,
255, 2232, 2841, 0, 0, 0, 1666, 262, 1320, 0, 2744, 4376, 0, 0, 1651, 0,
110, 0, 0, 0, 0, 775, 0, 0, 2425, 4122, 0, 1814, 0, 1951, 0, 0,
0, 924, 3999, 0, 1109, 202, 0, 1719, 1045, 230, 0, 1359, 102, 0, 0, 0,
542, 0, 872, 676, 0, 1685, 0, 0, 44, 0, 798, 553, 0, 239, 0, 0,
0, 0, 881, 2692, 0, 4224, 0, 3537, 0, 0, 2051, 0, 0, 0, 0, 4291,
0, 1617, 126, 4440, 1170, 491, 0, 0, 3101, 0, 0, 1044, 1499, 1290, 0, 0,
0, 278, 0, 0, 1600, 0, 0, 0, 0, 0, 0, 0, 2903, 0, 0, 0,
0, 684, 472, 0, 742, 3004, 0, 0, 1851, 1386, 1160, 1494, 1859, 0, 3500, 4048,
581, 0, 0, 226, 1737, 0, 0, 0, 354, 0, 3818, 0, 4092, 0, 0, 1895,
0, 1866, 1629, 0, 696, 0, 0, 1811, 0, 0, 0, 0, 0, 0, 0, 3865,
753, 0, 0, 1902, 0, 0, 403, 831, 0, 1269, 0, 0, 0, 0, 2689, 0,
0, 0, 0, 0, 0, 1275, 0, 0, 1799, 968, 0, 0, 0, 471, 466, 109,
0, 0, 4410, 0, 2886, 3928, 725, 0, 0, 0, 1271, 2067, 2790, 1810, 0, 0,
0, 0, 98, 0, 867, 1424, 1558, 1665, 1393, 0, 940, 692, 0, 0, 290, 803,
0, 0, 1839, 0, 3825, 0, 1040, 0, 0, 0, 0, 0, 0, 0, 0, 3660,
1943, 0, 0, 959, 1505, 4212, 238, 0, 0, 0, 119, 0, 0, 0, 407, 0,
0, 0, 0, 3009, 1974, 1309, 0, 775, 0, 3398, 0, 532, 0, 0, 0, 0,
0, 0, 0, 0, 0, 785, 0, 0, 2087, 0, 0, 0, 1647, 0, 0, 840,
3232, 1827, 0, 336, 3195, 0, 12, 0, 778, 0, 1004, 1148, 0, 513, 3952, 0,
0, 155, 567, 0, 0, 0, 1905, 0, 0, 950, 1021, 0, 2350, 1140, 0, 870,
218, 291, 0, 1859, 3042, 708, 1500, 4199, 2385, 0, 0, 2040, 0, 276, 710, 3508,
0, 0, 3049, 0, 0, 183, 219, 1025, 0, 4272, 3738, 0, 2222, 0, 1224, 1984,
4319, 374, 0, 0, 0, 0, 0, 945, 2352, 496, 0, 1759, 0, 0, 0, 425,
2723, 0, 0, 0, 771, 0, 0, 1185, 961, 3977, 0, 0, 0, 0, 0, 0,
934, 0, 1340, 2162, 1199, 0, 0, 0, 0, 110, 851, 0, 0, 0, 0, 540,
2149, 415, 0, 3873, 208, 0, 1655, 495, 1902, 0, 0, 2135, 0, 0, 0, 639,
3197, 0, 0, 0, 3487, 0, 234, 0, 0, 0, 1378, 0, 0, 723, 107, 955,
0, 0, 3313, 0, 3589, 419, 0, 4015, 1633, 2623, 0, 1129, 0, 1347, 2147, 0,
0, 3079, 2172, 1649, 0, 0, 505, 0, 0, 2215, 0, 3567, 1279, 3671, 526, 1356,
0, 1078, 507, 347, 0, 695, 0, 162, 0, 1867, 1923, 0, 530, 0, 0, 555,
0, 0, 0, 0, 2208, 0, 0, 1838, 0, 0, 0, 0, 0, 1924, 1492, 0,
1738, 1337, 0, 3595, 0, 690, 1269, 0, 1946, 0, 395, 0, 0, 13, 0, 0,
866, 2298, 1771, 0, 0, 0, 728, 2447, 3227, 3237, 667, 0, 0, 0, 1279, 2780,
0, 0, 0, 435, 4301, 2397, 4103, 672, 1657, 0, 0, 4024, 0, 0, 0, 0,
3357, 0, 0, 1010, 0, 0, 0, 0, 1660, 3424, 0, 0, 0, 616, 371, 0,
1705, 4365, 999, 275, 0, 0, 963, 0, 0, 794, 4047, 1749, 1406, 0, 55, 1751,
0, 0, 0, 0, 0, 0, 0, 0, 739, 0, 649, 0, 0, 0, 3989, 0,
3272, 0, 0, 0, 0, 0, 0, 0, 3295, 0, 1427, 0, 0, 811, 0, 351,
0, 3834, 0, 1564, 0, 0, 1059, 2743, 3304, 1938, 0, 923, 378, 3177, 0, 0,
1470, 0, 286, 0, 3065, 1371, 0, 675, 1708, 0, 0, 1203, 0, 0, 0, 0,
376, 0, 345, 983, 2009, 0, 3788, 27, 247, 822, 0, 835, 1903, 575, 561, 1806,
0, 107, 0, 1466, 0, 0, 1155, 85, 0, 2077, 0, 0, 838, 731, 289, 0,
0, 0, 2114, 3728, 1067, 2248, 1546, 1000, 0, 0, 550, 3066, 1987, 0, 0, 0,
0, 202, 0, 1788, 0, 981, 0, 3628, 882, 3969, 1795, 639, 4323, 0, 0, 0,
614, 751, 0, 0, 3917, 326, 4035, 452, 1688, 4105, 4053, 0, 0, 797, 755, 3429,
0, 4058, 0, 0, 0, 512, 3446, 0, 0, 0, 2624, 0, 3564, 1335, 0, 1245,
2282, 301, 0, 0, 945, 0, 0, 0, 3408, 0, 0, 0, 4298, 0, 0, 1612,
312, 1740, 0, 491, 3070, 0, 222, 3974, 1172, 898, 0, 1213, 0, 0, 1076, 2750,
582, 0, 4030, 297, 0, 0, 3209, 0, 2012, 0, 409, 459, 102, 0, 0, 0,
0, 318, 3156, 4381, 0, 243, 0, 1066, 3613, 3654, 2871, 3545, 0, 0, 585, 904,
274, 0, 1457, 0, 0, 4058, 693, 15, 0, 1009, 4195, 0, 0, 0, 524, 0,
0, 0, 0, 844, 203, 1782, 2118, 0, 672, 2269, 0, 0, 1905, 0, 0, 4417,
0, 3797, 454, 0, 195, 0, 930, 4168, 480, 743, 4217, 0, 0, 3706, 2915, 2273,
1063, 677, 0, 4420, 2326, 0, 0, 0, 1179, 1725, 0, 0, 3730, 0, 39, 4270,
1585, 0, 1925, 3912, 0, 0, 0, 0, 0, 0, 4274, 0, 824, 0, 971, 0,
0, 0, 0, 1928, 298, 0, 734, 0, 0, 10, 2811, 850, 0, 2731, 1322, 4050,
2774, 0, 4322, 786, 346, 2108, 0, 0, 1920, 0, 0, 1660, 280, 174, 518, 3704,
3169, 0, 0, 3434, 3345, 3828, 3865, 0, 196, 1421, 0, 0, 2368, 483, 1716, 0,
0, 0, 0, 0, 0, 0, 593, 420, 0, 829, 0, 248, 1450, 4228, 0, 190,
0, 3538, 4358, 3070, 0, 1222, 33, 0, 0, 16, 355, 0, 364, 606, 297, 0,
1159, 1532, 0, 486, 0, 0, 0, 60, 749, 463, 861, 0, 4408, 463, 0, 0,
849, 218, 0, 0, 0, 1062, 1411, 0, 1276, 45, 0, 0, 0, 87, 669, 861,
570, 1206, 0, 0, 0, 0, 1367, 163, 353, 2631, 688, 1288, 0, 383, 0, 0,
0, 0, 1901, 1817, 532, 1743, 438, 0, 3196, 0, 1135, 3962, 0, 0, 0, 1458,
500, 253, 1314, 3690, 519, 0, 1729, 0, 1513, 692, 1127, 257, 0, 534, 0, 302,
0, 0, 0, 0, 0, 1193, 50, 0, 314, 0, 0, 332, 4102, 265, 0, 1208,
0, 2236, 0, 0, 0, 917, 0, 0, 2083, 2924, 543, 2492, 3603, 762, 423, 0,
1293, 3452, 0, 2499, 0, 1700, 0, 0, 812, 1928, 1280, 2631, 436, 1422, 0, 0,
1201, 0, 0, 1339, 68, 1872, 4153, 4268, 4238, 0, 1704, 0, 0, 0, 523, 0,
0, 2026, 987, 292, 177, 1381, 1034, 518, 0, 0, 1611, 4312, 3213, 0, 0, 952,
0, 0, 541, 818, 0, 0, 1349, 0, 0, 525, 0, 1459, 0, 1408, 3696, 823,
0, 1883, 109, 4102, 1011, 700, 1049, 1167, 840, 0, 3919, 1405, 0, 2137, 1293, 0,
0, 0, 698, 1169, 45, 0, 578, 0, 3507, 0, 4197, 379, 0, 0, 228, 519,
0, 0, 4270, 0, 28, 0, 581, 1071, 1434, 0, 267, 0, 0, 408, 2883, 64,
1411, 730, 1394, 0, 0, 2112, 1307, 0, 0, 236, 0, 0, 3601, 4029, 0, 0,
716, 0, 2456, 0, 3915, 4440, 2555, 3643, 0, 628, 1357, 1373, 1008, 0, 0, 3022,
1346, 230, 0, 0, 1991, 432, 101, 0, 0, 0, 0, 1767, 0, 0, 3903, 0,
236, 3881, 0, 1921, 0, 2200, 0, 4411, 0, 1007, 3900, 0, 0, 282, 0, 1362,
1018, 0, 0, 1191, 4441, 0, 0, 1280, 741, 2106, 1910, 0, 0, 394, 1720, 0,
970, 0, 0, 0, 0, 4025, 0, 4150, 95, 3451, 132, 2737, 1448, 0, 230, 3911,
0, 0, 713, 0, 0, 2156, 314, 382, 3165, 158, 1849, 0, 3498, 4204, 179, 0,
0, 0, 913, 0, 0, 0, 3279, 1766, 2680, 4279, 591, 0, 4045, 3673, 3881, 0,
1562, 421, 1387, 4121, 4154, 4200, 0, 3912, 97, 3476, 242, 0, 0, 258, 1299, 460,
0, 0, 0, 0, 0, 4257, 0, 0, 440, 0, 0, 1967, 736, 2881, 0, 164,
0, 2813, 3015, 2070, 0, 0, 0, 0, 294, 1999, 1933, 4131, 1509, 2148, 0, 0,
1969, 1583, 2383, 2596, 986, 1628, 0, 49, 0, 0, 0, 0, 9, 0, 1127, 49,
0, 0, 52, 0, 1012, 0, 1351, 0, 2061, 2487, 1716, 1424, 0, 3255, 967, 1752,
0, 4326, 0, 639, 0, 1348, 2053, 3758, 1296, 1818, 1805, 0, 0, 0, 4321, 2091,
0, 0, 2320, 0, 0, 3821, 193, 3423, 0, 2160, 0, 1107, 1631, 25, 0, 0,
0, 0, 1436, 3024, 1003, 0, 2325, 0, 0, 683, 1023, 1760, 0, 1894, 16, 780,
1558, 244, 1005, 0, 492, 2069, 1020, 1315, 3756, 764, 0, 0, 30, 0, 467, 1511,
414, 0, 0, 0, 570, 0, 0, 0, 2072, 1627, 0, 0, 2037, 0, 539, 832,
899, 0, 0, 638, 651, 901, 462, 1216, 0, 1074, 0, 0, 1006, 0, 0, 0,
0, 3390, 1987, 0, 831, 1710, 0, 0, 3856, 2599, 960, 3988, 0, 4209, 0, 771,
0, 0, 4415, 2729, 0, 0, 2165, 772, 0, 0, 2181, 431, 4130, 1508, 48, 790,
3068, 0, 4306, 1596, 0, 0, 859, 0, 823, 3596, 2052, 3141, 0, 4377, 0, 194,
414, 0, 0, 1051, 964, 1532, 0, 0, 1266, 3492, 0, 0, 0, 829, 1504, 0,
1895, 0, 648, 831, 2964, 37, 3224, 1426, 3699, 1203, 1929, 1302, 2167, 0, 993, 1771,
106, 0, 842, 0, 1152, 0, 0, 0, 1605, 0, 1533, 0, 709, 96, 658, 2045,
2865, 618, 0, 3439, 0, 4312, 2084, 371, 0, 1961, 142, 0, 0, 0, 1552, 0,
0, 0, 3070, 0, 1381, 1099, 1423, 0, 2743, 0, 46, 3081, 62, 3152, 0, 1067,
3948, 2254, 808, 0, 0, 1791, 0, 2956, 1336, 153, 0, 1695, 2180, 335, 0, 502,
896, 3491, 0, 925, 441, 464, 0, 0, 3206, 3577, 408, 2565, 2166, 4007, 734, 1520,
766, 0, 0, 586, 0, 1025, 0, 1346, 2, 0, 140, 1355, 1884, 4337, 916, 1411,
0, 0, 0, 76, 0, 1202, 4196, 1720, 1176, 0, 3222, 1724, 785, 0, 0, 45,
0, 1286, 0, 144, 0, 4040, 0, 0, 0, 910, 0, 0, 277, 1484, 1494, 3994,
0, 0, 364, 953, 582, 623, 1748, 952, 0, 0, 799, 0, 0, 3675, 7, 884,
2132, 0, 497, 703, 0, 0, 0, 1527, 0, 0, 0, 558, 3175, 0, 2886, 20,
0, 863, 0, 1542, 1194, 0, 0, 0, 1530, 0, 1426, 3370, 1184, 1888, 0, 0,
0, 1879, 0, 0, 0, 0, 1373, 0, 0, 3925, 0, 0, 609, 3556, 886, 512,
0, 1443, 1158, 0, 1601, 0, 496, 0, 0, 0, 0, 3980, 316, 0, 3999, 608,
1375, 4451, 2447, 334, 0, 614, 1540, 3033, 3997, 0, 4215, 1469, 0, 1137, 925, 1312,
0, 1765, 0, 2335, 645, 0, 943, 0, 2472, 0, 1214, 1635, 0, 0, 83, 4375,
1993, 207, 291, 1175, 0, 2020, 0, 1194, 0, 540, 0, 641, 0, 0, 0, 1652,
4302, 4210, 1077, 0, 4000, 0, 700, 3918, 3319, 3820, 750, 2117, 3307, 0, 3891, 1427,
3662, 2483, 0, 14, 0, 0, 0, 2064, 0, 0, 0, 0, 1040, 0, 2024, 857,
0, 1671, 879, 684, 682, 0, 846, 0, 1964, 3883, 0, 2651, 0, 0, 0, 3344,
3567, 1574, 0, 1079, 1181, 1637, 482, 0, 2037, 265, 0, 1412, 0, 2269, 1227, 0,
315, 297, 0, 2, 512, 0, 1097, 1347, 0, 4166, 0, 0, 0, 0, 0, 0,
1372, 368, 1293, 0, 0, 0, 2843, 571, 1965, 4451, 1207, 1894, 1973, 2267, 0, 1274,
0, 1584, 1144, 0, 2289, 1717, 3714, 1001, 0, 0, 1008, 834, 346, 1993, 1330, 4271,
2874, 2332, 0, 0, 951, 0, 0, 0, 0, 3962, 1194, 1830, 1537, 3864, 807, 1958,
0, 0, 4321, 0, 0, 0, 2290, 1033, 1590, 0, 340, 444, 3595, 3436, 425, 1916,
0, 12, 182, 1544, 2176, 0, 1535, 1624, 0, 0, 1212, 0, 0, 4223, 0, 0,
614, 2131, 0, 430, 1003, 667, 2642, 2027, 0, 1845, 631, 1056, 1252, 0, 468, 4019,
0, 0, 0, 0, 1481, 1951, 3403, 1374, 0, 0, 0, 4294, 1220, 114, 0, 418,
651, 98, 1015, 4403, 0, 1295, 0, 1338, 3941, 0, 542, 3496, 75, 916, 404, 329,
0, 1438, 300, 957, 0, 0, 602, 373, 0, 2540, 2585, 23, 1959, 293, 3627, 1485,
1242, 0, 0, 0, 1108, 0, 533, 0, 1842, 772, 0, 879, 1240, 0, 1545, 0,
0, 0, 159, 111, 731, 0, 0, 0, 1284, 127, 2538, 2422, 0, 1077, 657, 862,
3393, 3538, 398, 859, 1477, 0, 3066, 0, 0, 1873, 0, 1188, 39, 3293, 397, 0,
0, 1098, 1549, 0, 0, 0, 6, 4275, 3349, 1906, 518, 1259, 1310, 167, 754, 329,
0, 2196, 778, 3061, 0, 1447, 811, 0, 984, 0, 0, 1386, 1267, 0, 0, 0,
1429, 1565, 1976, 3102, 0, 0, 0, 3727, 0, 2404, 0, 0, 3510, 2113, 0, 1147,
0, 1704, 0, 0, 75, 0, 3848, 0, 0, 0, 0, 822, 3353, 4291, 978, 1393,
1631, 0, 4272, 1276, 0, 0, 0, 2093, 774, 0, 3925, 901, 0, 3714, 0, 0,
1582, 0, 1742, 4026, 748, 2962, 1209, 0, 0, 1440, 940, 2826, 0, 797, 2567, 4275,
252, 2842, 3771, 0, 1223, 0, 0, 1900, 0, 3580, 1282, 1112, 0, 1261, 123, 117,
381, 537, 1615, 2429, 1559, 1102, 2475, 1722, 0, 903, 0, 3890, 466, 3629, 338, 0,
887, 4365, 676, 1438, 837, 120, 0, 941, 0, 1869, 353, 1742, 0, 1479, 0, 3562,
0, 1483, 3730, 0, 3009, 0, 0, 0, 1887, 161, 635, 0, 3014, 0, 4170, 0,
0, 947, 0, 119, 1617, 0, 0, 2562, 169, 458, 0, 1047, 1108, 1879, 504, 0,
2102, 0, 1144, 2339, 364, 0, 0, 0, 40, 0, 2062, 283, 0, 745, 4330, 0,
99, 1996, 0, 2711, 1765, 0, 1424, 3705, 0, 0, 0, 0, 1358, 4383, 3326, 0,
0, 3030, 499, 2276, 0, 3230, 0, 923, 0, 0, 4362, 4025, 871, 0, 0, 0,
1529, 0, 2906, 916, 0, 0, 4269, 1211, 0, 1802, 0, 0, 2895, 1825, 873, 1053,
1322, 1833, 360, 0, 1586, 1730, 0, 1072, 0, 0, 0, 943, 1379, 0, 3869, 4429,
3154, 1312, 2013, 0, 4232, 1317, 336, 637, 2071, 16, 4384, 0, 832, 0, 3, 0,
0, 0, 1650, 4308, 0, 1869, 0, 0, 4115, 1017, 316, 0, 0, 1843, 0, 1378,
577, 0, 0, 4440, 81, 3849, 0, 1644, 4385, 3917, 1747, 0, 1664, 0, 1217, 367,
0, 0, 2700, 0, 208, 2033, 0, 413, 656, 632, 433, 0, 0, 934, 0, 37,
4004, 0, 0, 1536, 342, 0, 0, 666, 363, 118, 4353, 0, 0, 0, 249, 105,
1553, 1547, 19, 0, 493, 1350, 1917, 1691, 0, 1349, 0, 380, 756, 0, 0, 0,
0, 0, 1415, 0, 1643, 0, 0, 241, 3884, 2489, 1276, 0, 0, 717, 0, 1468,
0, 146, 1965, 0, 1116, 0, 2624, 0, 878, 2182, 1566, 1770, 850, 699, 0, 0,
1846, 535, 0, 584, 0, 2002, 244, 0, 3769, 1094, 2006, 0, 0, 0, 4207, 3761,
4353, 1046, 310, 3707, 0, 1253, 1284, 0, 0, 3085, 337, 2234, 162, 4231, 0, 422,
5, 694, 1721, 0, 1853, 1474, 191, 1298, 0, 0, 2918, 4065, 0, 0, 1089, 0,
0, 1310, 2035, 4324, 34, 0, 0, 1853, 0, 4390, 1251, 0, 1095, 1677, 1126, 1035,
1048, 773, 2534, 767, 16, 343, 3632, 768, 538, 0, 1909, 672, 0, 461, 1732, 0,
4193, 0, 1434, 1387, 2036, 0, 0, 2293, 0, 0, 920, 0, 1138, 1125, 0, 0,
0, 1453, 0, 1990, 0, 1289, 76};
int MangledHashG(const char *key, const int *T)
{
......
......@@ -133,6 +133,10 @@ void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavi
{
extBehavior[TExtension::OES_shader_multisample_interpolation] = EBhUndefined;
}
if (resources.OES_shader_image_atomic)
{
extBehavior[TExtension::OES_shader_image_atomic] = EBhUndefined;
}
}
void ResetExtensionBehavior(const ShBuiltInResources &resources,
......
......@@ -6105,6 +6105,21 @@ void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *
GetImageArgumentToken(imageNode));
}
}
else if (BuiltInGroup::isImageAtomic(func))
{
if (memoryQualifier.readonly)
{
error(imageNode->getLine(),
"'imageAtomic' cannot be used with images qualified as 'readonly'",
GetImageArgumentToken(imageNode));
}
if (memoryQualifier.writeonly)
{
error(imageNode->getLine(),
"'imageAtomic' cannot be used with images qualified as 'writeonly'",
GetImageArgumentToken(imageNode));
}
}
}
}
......
......@@ -21,72 +21,77 @@ namespace BuiltInGroup
bool isTextureOffsetNoBias(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3110 && id <= 3179;
return id >= 3671 && id <= 3740;
}
bool isTextureOffsetBias(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3180 && id <= 3199;
return id >= 3741 && id <= 3760;
}
bool isTextureGatherOffsetsComp(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3237 && id <= 3249;
return id >= 3798 && id <= 3810;
}
bool isTextureGatherOffsetsNoComp(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3250 && id <= 3265;
return id >= 3811 && id <= 3826;
}
bool isTextureGatherOffsets(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3237 && id <= 3265;
return id >= 3798 && id <= 3826;
}
bool isTextureGatherOffsetComp(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3266 && id <= 3271;
return id >= 3827 && id <= 3832;
}
bool isTextureGatherOffsetNoComp(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3272 && id <= 3279;
return id >= 3833 && id <= 3840;
}
bool isTextureGatherOffset(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3266 && id <= 3279;
return id >= 3827 && id <= 3840;
}
bool isTextureGather(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3213 && id <= 3279;
return id >= 3774 && id <= 3840;
}
bool isInterpolationFS(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3292 && id <= 3315;
return id >= 3853 && id <= 3876;
}
bool isAtomicMemory(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3320 && id <= 3337;
return id >= 3881 && id <= 3898;
}
bool isImageLoad(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3368 && id <= 3382;
return id >= 3929 && id <= 3943;
}
bool isImageAtomic(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3944 && id <= 4522;
}
bool isImageStore(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3383 && id <= 3397;
return id >= 4523 && id <= 4537;
}
bool isImage(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 3338 && id <= 3397;
return id >= 3899 && id <= 4537;
}
} // namespace BuiltInGroup
......
......@@ -76,17 +76,22 @@ bool isAtomicMemory(const TFunction *func)
bool isImageLoad(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 2142 && id <= 2174;
return id >= 1578 && id <= 1613;
}
bool isImageAtomic(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 1614 && id <= 2735;
}
bool isImageStore(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 2175 && id <= 2207;
return id >= 2736 && id <= 2768;
}
bool isImage(const TFunction *func)
{
int id = func->uniqueId().get();
return id >= 1506 && id <= 2207;
return id >= 1506 && id <= 2768;
}
} // namespace BuiltInGroup
......
......@@ -180,8 +180,8 @@ void InitBuiltInResources(ShBuiltInResources *resources)
resources->EXT_texture_cube_map_array = 0;
resources->EXT_shadow_samplers = 0;
resources->OES_shader_multisample_interpolation = 0;
resources->NV_draw_buffers = 0;
resources->NV_draw_buffers = 0;
resources->OES_shader_image_atomic = 0;
resources->MaxClipDistances = 0;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1087,26 +1087,46 @@ GROUP BEGIN Image {"queryFunction": true}
DEFAULT METADATA {"glsl_level": "GLSL4_5_BUILTINS", "op": "CallBuiltInFunction"}
int imageSamples(readonly writeonly gimage2DMS);
int imageSamples(readonly writeonly gimage2DMSArray);
DEFAULT METADATA {"glsl_level": "GLSL4_2_BUILTINS", "op": "CallBuiltInFunction"}
uint imageAtomicAdd(IMAGE_PARAMS, uint);
int imageAtomicAdd(IMAGE_PARAMS, int);
uint imageAtomicMin(IMAGE_PARAMS, uint);
int imageAtomicMin(IMAGE_PARAMS, int);
uint imageAtomicMax(IMAGE_PARAMS, uint);
int imageAtomicMax(IMAGE_PARAMS, int);
uint imageAtomicAnd(IMAGE_PARAMS, uint);
int imageAtomicAnd(IMAGE_PARAMS, int);
uint imageAtomicOr(IMAGE_PARAMS, uint);
int imageAtomicOr(IMAGE_PARAMS, int);
uint imageAtomicXor(IMAGE_PARAMS, uint);
int imageAtomicXor(IMAGE_PARAMS, int);
uint imageAtomicExchange(IMAGE_PARAMS, uint);
int imageAtomicExchange(IMAGE_PARAMS, int);
DEFAULT METADATA {"glsl_level": "GLSL4_5_BUILTINS", "op": "CallBuiltInFunction"}
int imageAtomicExchange(IMAGE_PARAMS, float);
DEFAULT METADATA {"glsl_level": "GLSL4_2_BUILTINS", "op": "CallBuiltInFunction"}
uint imageAtomicCompSwap(IMAGE_PARAMS, uint, uint);
int imageAtomicCompSwap(IMAGE_PARAMS, int, int);
GROUP BEGIN Atomic {"queryFunction": true}
DEFAULT METADATA {"glsl_level": "GLSL4_2_BUILTINS", "op": "CallBuiltInFunction"}
uint imageAtomicAdd(IMAGE_PARAMS, uint);
int imageAtomicAdd(IMAGE_PARAMS, int);
uint imageAtomicMin(IMAGE_PARAMS, uint);
int imageAtomicMin(IMAGE_PARAMS, int);
uint imageAtomicMax(IMAGE_PARAMS, uint);
int imageAtomicMax(IMAGE_PARAMS, int);
uint imageAtomicAnd(IMAGE_PARAMS, uint);
int imageAtomicAnd(IMAGE_PARAMS, int);
uint imageAtomicOr(IMAGE_PARAMS, uint);
int imageAtomicOr(IMAGE_PARAMS, int);
uint imageAtomicXor(IMAGE_PARAMS, uint);
int imageAtomicXor(IMAGE_PARAMS, int);
uint imageAtomicExchange(IMAGE_PARAMS, uint);
int imageAtomicExchange(IMAGE_PARAMS, int);
DEFAULT METADATA {"glsl_level": "GLSL4_5_BUILTINS", "op": "CallBuiltInFunction"}
int imageAtomicExchange(IMAGE_PARAMS, float);
DEFAULT METADATA {"glsl_level": "GLSL4_2_BUILTINS", "op": "CallBuiltInFunction"}
uint imageAtomicCompSwap(IMAGE_PARAMS, uint, uint);
int imageAtomicCompSwap(IMAGE_PARAMS, int, int);
DEFAULT METADATA {"essl_level": "ESSL3_1_BUILTINS", "op": "CallBuiltInFunction", "essl_extension": "OES_shader_image_atomic", "suffix": "Ext"}
uint imageAtomicAdd(readonly writeonly IMAGE_PARAMS, uint);
int imageAtomicAdd(readonly writeonly IMAGE_PARAMS, int);
uint imageAtomicMin(readonly writeonly IMAGE_PARAMS, uint);
int imageAtomicMin(readonly writeonly IMAGE_PARAMS, int);
uint imageAtomicMax(readonly writeonly IMAGE_PARAMS, uint);
int imageAtomicMax(readonly writeonly IMAGE_PARAMS, int);
uint imageAtomicAnd(readonly writeonly IMAGE_PARAMS, uint);
int imageAtomicAnd(readonly writeonly IMAGE_PARAMS, int);
uint imageAtomicOr(readonly writeonly IMAGE_PARAMS, uint);
int imageAtomicOr(readonly writeonly IMAGE_PARAMS, int);
uint imageAtomicXor(readonly writeonly IMAGE_PARAMS, uint);
int imageAtomicXor(readonly writeonly IMAGE_PARAMS, int);
uint imageAtomicExchange(readonly writeonly IMAGE_PARAMS, uint);
int imageAtomicExchange(readonly writeonly IMAGE_PARAMS, int);
int imageAtomicExchange(readonly writeonly IMAGE_PARAMS, float);
uint imageAtomicCompSwap(readonly writeonly IMAGE_PARAMS, uint, uint);
int imageAtomicCompSwap(readonly writeonly IMAGE_PARAMS, int, int);
GROUP END Atomic
GROUP END Image
GROUP BEGIN Noise
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1037,6 +1037,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_OES_texture_stencil8"] = enableableExtension(&Extensions::stencilIndex8);
map["GL_OES_sample_shading"] = enableableExtension(&Extensions::sampleShadingOES);
map["GL_OES_shader_multisample_interpolation"] = enableableExtension(&Extensions::multisampleInterpolationOES);
map["GL_OES_shader_image_atomic"] = enableableExtension(&Extensions::shaderImageAtomicOES);
map["GL_NV_robustness_video_memory_purge"] = esOnlyExtension(&Extensions::robustnessVideoMemoryPurgeNV);
map["GL_ANGLE_get_tex_level_parameter"] = enableableExtension(&Extensions::getTexLevelParameterANGLE);
// GLES1 extensions
......
......@@ -657,6 +657,9 @@ struct Extensions
// OES_shader_multisample_interpolation
bool multisampleInterpolationOES = false;
// GL_OES_shader_image_atomic
bool shaderImageAtomicOES = false;
// GL_NV_robustness_video_memory_purge
bool robustnessVideoMemoryPurgeNV = false;
......
......@@ -112,6 +112,7 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Disp
mResources.APPLE_clip_distance = extensions.clipDistanceAPPLE;
// OES_shader_multisample_interpolation
mResources.OES_shader_multisample_interpolation = extensions.multisampleInterpolationOES;
mResources.OES_shader_image_atomic = extensions.shaderImageAtomicOES;
// TODO: use shader precision caps to determine if high precision is supported?
mResources.FragmentPrecisionHigh = 1;
mResources.EXT_frag_depth = extensions.fragDepth;
......
......@@ -961,6 +961,10 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt
mShaderFloat16Int8Features.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;
mShaderAtomicFloatFeature = {};
mShaderAtomicFloatFeature.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT;
mDepthStencilResolveProperties = {};
mDepthStencilResolveProperties.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
......@@ -1036,6 +1040,12 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt
vk::AddToPNextChain(&deviceFeatures, &mShaderFloat16Int8Features);
}
// Query shader atomic float features
if (ExtensionFound(VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME, deviceExtensionNames))
{
vk::AddToPNextChain(&deviceFeatures, &mShaderAtomicFloatFeature);
}
// Query depth/stencil resolve properties
if (ExtensionFound(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, deviceExtensionNames))
{
......@@ -1080,6 +1090,7 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt
mSubgroupProperties.pNext = nullptr;
mExternalMemoryHostProperties.pNext = nullptr;
mShaderFloat16Int8Features.pNext = nullptr;
mShaderAtomicFloatFeature.pNext = nullptr;
mDepthStencilResolveProperties.pNext = nullptr;
mSamplerYcbcrConversionFeatures.pNext = nullptr;
}
......@@ -1431,6 +1442,12 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
vk::AddToPNextChain(&createInfo, &mShaderFloat16Int8Features);
}
if (getFeatures().supportsShaderImageFloat32Atomics.enabled)
{
enabledDeviceExtensions.push_back(VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME);
vk::AddToPNextChain(&createInfo, &mShaderAtomicFloatFeature);
}
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.flags = 0;
createInfo.queueCreateInfoCount = 1;
......@@ -1925,6 +1942,9 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderFloat16,
mShaderFloat16Int8Features.shaderFloat16 == VK_TRUE);
ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderImageFloat32Atomics,
mShaderAtomicFloatFeature.shaderImageFloat32Atomics == VK_TRUE);
// The compute shader used to generate mipmaps uses a 256-wide workgroup. This path is only
// enabled on devices that meet this minimum requirement. Furthermore,
// VK_IMAGE_USAGE_STORAGE_BIT is detrimental to performance on many platforms, on which this
......
......@@ -356,6 +356,7 @@ class RendererVk : angle::NonCopyable
VkPhysicalDeviceSubgroupProperties mSubgroupProperties;
VkPhysicalDeviceExternalMemoryHostPropertiesEXT mExternalMemoryHostProperties;
VkPhysicalDeviceShaderFloat16Int8FeaturesKHR mShaderFloat16Int8Features;
VkPhysicalDeviceShaderAtomicFloatFeaturesEXT mShaderAtomicFloatFeature;
VkPhysicalDeviceDepthStencilResolvePropertiesKHR mDepthStencilResolveProperties;
VkExternalFenceProperties mExternalFenceProperties;
VkExternalSemaphoreProperties mExternalSemaphoreProperties;
......
......@@ -368,6 +368,11 @@ void RendererVk::ensureCapsInitialized() const
mNativeExtensions.multisampleInterpolationOES =
supportSampleRateShading && (mNativeCaps.maxInterpolationOffset >= 0.5);
mNativeExtensions.shaderImageAtomicOES =
((mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics == VK_TRUE) &&
(mPhysicalDeviceFeatures.fragmentStoresAndAtomics == VK_TRUE) &&
getFeatures().supportsShaderImageFloat32Atomics.enabled);
// https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s02.html
mNativeCaps.maxElementIndex = std::numeric_limits<GLuint>::max() - 1;
mNativeCaps.max3DTextureSize = LimitToInt(limitsVk.maxImageDimension3D);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment