diff options
87 files changed, 4077 insertions, 2540 deletions
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index de9936d96b..cdc59a4596 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -71,16 +71,6 @@ Comment: The Android Open Source Project Copyright: 2002, Google Inc. License: Apache-2.0 -Files: ./platform/android/power_android.cpp - ./platform/osx/power_osx.cpp - ./platform/windows/power_windows.cpp - ./platform/x11/power_x11.cpp -Comment: Simple DirectMedia Layer -Copyright: 1997-2017, Sam Lantinga - 2007-2020, Juan Linietsky, Ariel Manzur. - 2014-2020, Godot Engine contributors. -License: Expat and Zlib - Files: ./scene/animation/tween_interpolaters.cpp Comment: Penner Easing Copyright: 2001, Robert Penner diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 9413772f84..d7614c5a82 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -587,18 +587,6 @@ bool _OS::is_vsync_via_compositor_enabled() const { return OS::get_singleton()->is_vsync_via_compositor_enabled(); } -_OS::PowerState _OS::get_power_state() { - return _OS::PowerState(OS::get_singleton()->get_power_state()); -} - -int _OS::get_power_seconds_left() { - return OS::get_singleton()->get_power_seconds_left(); -} - -int _OS::get_power_percent_left() { - return OS::get_singleton()->get_power_percent_left(); -} - bool _OS::has_feature(const String &p_feature) const { return OS::get_singleton()->has_feature(p_feature); @@ -1348,10 +1336,6 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("has_feature", "tag_name"), &_OS::has_feature); - ClassDB::bind_method(D_METHOD("get_power_state"), &_OS::get_power_state); - ClassDB::bind_method(D_METHOD("get_power_seconds_left"), &_OS::get_power_seconds_left); - ClassDB::bind_method(D_METHOD("get_power_percent_left"), &_OS::get_power_percent_left); - ClassDB::bind_method(D_METHOD("request_permission", "name"), &_OS::request_permission); ClassDB::bind_method(D_METHOD("request_permissions"), &_OS::request_permissions); ClassDB::bind_method(D_METHOD("get_granted_permissions"), &_OS::get_granted_permissions); @@ -1439,12 +1423,6 @@ void _OS::_bind_methods() { BIND_ENUM_CONSTANT(SYSTEM_DIR_MUSIC); BIND_ENUM_CONSTANT(SYSTEM_DIR_PICTURES); BIND_ENUM_CONSTANT(SYSTEM_DIR_RINGTONES); - - BIND_ENUM_CONSTANT(POWERSTATE_UNKNOWN); - BIND_ENUM_CONSTANT(POWERSTATE_ON_BATTERY); - BIND_ENUM_CONSTANT(POWERSTATE_NO_BATTERY); - BIND_ENUM_CONSTANT(POWERSTATE_CHARGING); - BIND_ENUM_CONSTANT(POWERSTATE_CHARGED); } _OS::_OS() { diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 18bb1408e3..39bed791d0 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -105,14 +105,6 @@ public: VIDEO_DRIVER_VULKAN, }; - enum PowerState { - POWERSTATE_UNKNOWN, // Cannot determine power status. - POWERSTATE_ON_BATTERY, // Not plugged in, running on the battery. - POWERSTATE_NO_BATTERY, // Plugged in, no battery available. - POWERSTATE_CHARGING, // Plugged in, charging battery. - POWERSTATE_CHARGED // Plugged in, battery charged. - }; - enum Weekday { DAY_SUNDAY, DAY_MONDAY, @@ -346,10 +338,6 @@ public: void set_vsync_via_compositor(bool p_enable); bool is_vsync_via_compositor_enabled() const; - PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); - bool has_feature(const String &p_feature) const; bool request_permission(const String &p_name); @@ -362,7 +350,6 @@ public: }; VARIANT_ENUM_CAST(_OS::VideoDriver); -VARIANT_ENUM_CAST(_OS::PowerState); VARIANT_ENUM_CAST(_OS::Weekday); VARIANT_ENUM_CAST(_OS::Month); VARIANT_ENUM_CAST(_OS::SystemDir); diff --git a/core/os/os.cpp b/core/os/os.cpp index 13be4a5c37..d1b6ccab54 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -586,16 +586,6 @@ bool OS::is_vsync_via_compositor_enabled() const { return _vsync_via_compositor; } -OS::PowerState OS::get_power_state() { - return POWERSTATE_UNKNOWN; -} -int OS::get_power_seconds_left() { - return -1; -} -int OS::get_power_percent_left() { - return -1; -} - void OS::set_has_server_feature_callback(HasServerFeatureCallback p_callback) { has_server_feature_callback = p_callback; diff --git a/core/os/os.h b/core/os/os.h index 1bb910cb0d..e4661e4583 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -78,14 +78,6 @@ public: typedef void (*ImeCallback)(void *p_inp, String p_text, Point2 p_selection); typedef bool (*HasServerFeatureCallback)(const String &p_feature); - enum PowerState { - POWERSTATE_UNKNOWN, /**< cannot determine power status */ - POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */ - POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */ - POWERSTATE_CHARGING, /**< Plugged in, charging battery */ - POWERSTATE_CHARGED /**< Plugged in, battery charged */ - }; - enum RenderThreadMode { RENDER_THREAD_UNSAFE, @@ -517,10 +509,6 @@ public: void set_vsync_via_compositor(bool p_enable); bool is_vsync_via_compositor_enabled() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual void force_process_input(){}; bool has_feature(const String &p_feature); @@ -542,6 +530,4 @@ public: virtual ~OS(); }; -VARIANT_ENUM_CAST(OS::PowerState); - #endif diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index b3b77b0b26..d361ea83e6 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -280,30 +280,6 @@ Returns the name of the host OS. Possible values are: [code]"Android"[/code], [code]"Haiku"[/code], [code]"iOS"[/code], [code]"HTML5"[/code], [code]"OSX"[/code], [code]"Server"[/code], [code]"Windows"[/code], [code]"UWP"[/code], [code]"X11"[/code]. </description> </method> - <method name="get_power_percent_left"> - <return type="int"> - </return> - <description> - Returns the amount of battery left in the device as a percentage. Returns [code]-1[/code] if power state is unknown. - [b]Note:[/b] This method is implemented on Linux, macOS and Windows. - </description> - </method> - <method name="get_power_seconds_left"> - <return type="int"> - </return> - <description> - Returns an estimate of the time left in seconds before the device runs out of battery. Returns [code]-1[/code] if power state is unknown. - [b]Note:[/b] This method is implemented on Linux, macOS and Windows. - </description> - </method> - <method name="get_power_state"> - <return type="int" enum="OS.PowerState"> - </return> - <description> - Returns the current state of the device regarding battery and power. See [enum PowerState] constants. - [b]Note:[/b] This method is implemented on Linux, macOS and Windows. - </description> - </method> <method name="get_process_id" qualifiers="const"> <return type="int"> </return> @@ -1081,20 +1057,5 @@ <constant name="SYSTEM_DIR_RINGTONES" value="7" enum="SystemDir"> Ringtones directory path. </constant> - <constant name="POWERSTATE_UNKNOWN" value="0" enum="PowerState"> - Unknown powerstate. - </constant> - <constant name="POWERSTATE_ON_BATTERY" value="1" enum="PowerState"> - Unplugged, running on battery. - </constant> - <constant name="POWERSTATE_NO_BATTERY" value="2" enum="PowerState"> - Plugged in, no battery available. - </constant> - <constant name="POWERSTATE_CHARGING" value="3" enum="PowerState"> - Plugged in, battery charging. - </constant> - <constant name="POWERSTATE_CHARGED" value="4" enum="PowerState"> - Plugged in, battery fully charged. - </constant> </constants> </class> diff --git a/drivers/spirv-reflect/SCsub b/drivers/spirv-reflect/SCsub index f6b40ac433..8ff27da114 100644 --- a/drivers/spirv-reflect/SCsub +++ b/drivers/spirv-reflect/SCsub @@ -3,12 +3,13 @@ Import('env') env_spirv_reflect = env.Clone() +env_spirv_reflect.disable_warnings() thirdparty_dir = "#thirdparty/spirv-reflect/" thirdparty_sources = [ "spirv_reflect.c" ] - + thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_spirv_reflect.add_source_files(env.drivers_sources, thirdparty_sources) diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 4582f1c2c1..1eb6f204f2 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1997,8 +1997,8 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p //create view - ERR_FAIL_INDEX_V(p_mipmap, src_texture->mipmaps, RID()); - ERR_FAIL_INDEX_V(p_layer, src_texture->layers, RID()); + ERR_FAIL_UNSIGNED_INDEX_V(p_mipmap, src_texture->mipmaps, RID()); + ERR_FAIL_UNSIGNED_INDEX_V(p_layer, src_texture->layers, RID()); Texture texture = *src_texture; get_image_format_required_size(texture.format, texture.width, texture.height, texture.depth, p_mipmap + 1, &texture.width, &texture.height); @@ -6940,15 +6940,15 @@ uint64_t RenderingDeviceVulkan::get_captured_timestamps_frame() const { } uint64_t RenderingDeviceVulkan::get_captured_timestamp_gpu_time(uint32_t p_index) const { - ERR_FAIL_INDEX_V(p_index, frames[frame].timestamp_result_count, 0); + ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, 0); return frames[frame].timestamp_result_values[p_index] * limits.timestampPeriod; } uint64_t RenderingDeviceVulkan::get_captured_timestamp_cpu_time(uint32_t p_index) const { - ERR_FAIL_INDEX_V(p_index, frames[frame].timestamp_result_count, 0); + ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, 0); return frames[frame].timestamp_cpu_result_values[p_index]; } String RenderingDeviceVulkan::get_captured_timestamp_name(uint32_t p_index) const { - ERR_FAIL_INDEX_V(p_index, frames[frame].timestamp_result_count, String()); + ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, String()); return frames[frame].timestamp_result_names[p_index]; } diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 068c0fd9d2..ca488fc3a3 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -1344,6 +1344,7 @@ Error VulkanContext::swap_buffers() { /*swapchainCount*/ 0, /*pSwapchain*/ NULL, /*pImageIndices*/ NULL, + /*pResults*/ NULL, }; VkSwapchainKHR *pSwapchains = (VkSwapchainKHR *)alloca(sizeof(VkSwapchainKHR *) * windows.size()); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index f3da1b59b2..e898bc54dd 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -517,6 +517,11 @@ void FindReplaceBar::_replace_text_entered(const String &p_text) { if (selection_only->is_pressed() && text_edit->is_selection_active()) { _replace_all(); _hide_bar(); + } else if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { + _replace(); + search_prev(); + } else { + _replace(); } } diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 22a16ac65a..0ade4c5c80 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -50,7 +50,7 @@ void EditorHelp::_init_colors() { text_color = get_color("default_color", "RichTextLabel"); headline_color = get_color("headline_color", "EditorHelp"); base_type_color = title_color.linear_interpolate(text_color, 0.5); - comment_color = text_color * Color(1, 1, 1, 0.4); + comment_color = text_color * Color(1, 1, 1, 0.6); symbol_color = comment_color; value_color = text_color * Color(1, 1, 1, 0.6); qualifier_color = text_color * Color(1, 1, 1, 0.8); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index f88b071515..baee7abb32 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -6406,6 +6406,8 @@ EditorNode::EditorNode() { video_driver->set_focus_mode(Control::FOCUS_NONE); video_driver->connect("item_selected", this, "_video_driver_selected"); video_driver->add_font_override("font", gui_base->get_font("bold", "EditorFonts")); + // TODO re-enable when GLES2 is ported + video_driver->set_disabled(true); right_menu_hb->add_child(video_driver); String video_drivers = ProjectSettings::get_singleton()->get_custom_property_info()["rendering/quality/driver/driver_name"].hint_string; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index f43aefc944..50e3408037 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -90,9 +90,6 @@ Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float Ref<ImageTexture> icon = memnew(ImageTexture); Ref<Image> img = memnew(Image); - // dumb gizmo check - bool is_gizmo = String(editor_icons_names[p_index]).begins_with("Gizmo"); - // Upsample icon generation only if the editor scale isn't an integer multiplier. // Generating upsampled icons is slower, and the benefit is hardly visible // with integer editor scales. diff --git a/editor/editor_visual_profiler.cpp b/editor/editor_visual_profiler.cpp index 3f3da7c4a5..1b68a89181 100644 --- a/editor/editor_visual_profiler.cpp +++ b/editor/editor_visual_profiler.cpp @@ -113,12 +113,6 @@ void EditorVisualProfiler::clear() { seeking = false; } -static String _get_percent_txt(float p_value, float p_total) { - if (p_total == 0) - p_total = 0.00001; - return String::num((p_value / p_total) * 100, 1) + "%"; -} - String EditorVisualProfiler::_get_time_as_text(float p_time) { int dmode = display_mode->get_selected(); @@ -126,7 +120,7 @@ String EditorVisualProfiler::_get_time_as_text(float p_time) { if (dmode == DISPLAY_FRAME_TIME) { return rtos(p_time) + "ms"; } else if (dmode == DISPLAY_FRAME_PERCENT) { - return String::num(p_time * 100 / graph_limit, 2) + "%"; //_get_percent_txt(p_time, m.frame_time); + return String::num(p_time * 100 / graph_limit, 2) + "%"; } return "err"; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 7d59b8e20d..d9bccc35f4 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -2710,10 +2710,10 @@ VisualShaderEditor::VisualShaderEditor() { // TEXTURES - add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubeMap", TTR("Perform the cubic texture lookup."), -1, -1)); + add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1)); texture_node_option_idx = add_options.size(); add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, -1)); - add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubeMapUniform", TTR("Cubic texture uniform lookup."), -1, -1)); + add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1)); add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, -1)); add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, -1, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 0c22db075d..a1032130f8 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -885,7 +885,7 @@ public: rs_button->set_pressed(true); rvb->add_child(rs_button); l = memnew(Label); - l->set_text(TTR("- Higher visual quality\n- More accurate API, which produces very fast code\n- Some features not implemented yet — work in progress\n- Incompatible with older hardware\n- Not recommended for web and mobile games")); + l->set_text(TTR("- Higher visual quality\n- More accurate API, which produces very fast code\n- Some features not implemented yet - work in progress\n- Incompatible with older hardware\n- Not recommended for web and mobile games")); l->set_modulate(Color(1, 1, 1, 0.7)); rvb->add_child(l); diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp index 1e0f3c6425..941a6771bf 100644 --- a/main/tests/test_shader_lang.cpp +++ b/main/tests/test_shader_lang.cpp @@ -207,6 +207,9 @@ static String dump_node_code(SL::Node *p_node, int p_level) { case SL::Node::TYPE_ARRAY_DECLARATION: { // FIXME: Implement } break; + case SL::Node::TYPE_ARRAY_CONSTRUCT: { + // FIXME: Implement + } break; case SL::Node::TYPE_CONSTANT: { SL::ConstantNode *cnode = (SL::ConstantNode *)p_node; return get_constant_text(cnode->datatype, cnode->values); diff --git a/modules/assimp/import_utils.h b/modules/assimp/import_utils.h index 0eb055956b..d037efce21 100644 --- a/modules/assimp/import_utils.h +++ b/modules/assimp/import_utils.h @@ -320,10 +320,10 @@ public: static void set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<ImageTexture> texture) { ERR_FAIL_COND(texture.is_null()); ERR_FAIL_COND(map_mode == NULL); - aiTextureMapMode tex_mode = map_mode[0]; - // FIXME: Commented out during Vulkan port. /* + aiTextureMapMode tex_mode = map_mode[0]; + int32_t flags = Texture2D::FLAGS_DEFAULT; if (tex_mode == aiTextureMapMode_Wrap) { //Default diff --git a/modules/basis_universal/SCsub b/modules/basis_universal/SCsub index 3e179762a5..d7342358d7 100644 --- a/modules/basis_universal/SCsub +++ b/modules/basis_universal/SCsub @@ -28,7 +28,11 @@ tool_sources = [ tool_sources = [thirdparty_dir + file for file in tool_sources] transcoder_sources = [thirdparty_dir + "transcoder/basisu_transcoder.cpp"] -env_basisu.Append(CPPPATH=[thirdparty_dir, thirdparty_dir + "transcoder"]) +# Treat Basis headers as system headers to avoid raising warnings. Not supported on MSVC. +if not env.msvc: + env_basisu.Append(CPPFLAGS=['-isystem', Dir(thirdparty_dir).path, '-isystem', Dir(thirdparty_dir + "transcoder").path]) +else: + env_basisu.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "transcoder"]) if env['target'] == "debug": env_basisu.Append(CPPFLAGS=["-DBASISU_DEVEL_MESSAGES=1", "-DBASISD_ENABLE_DEBUG_FLAGS=1"]) diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp index 4071f3477a..f5ae424b56 100644 --- a/modules/basis_universal/register_types.cpp +++ b/modules/basis_universal/register_types.cpp @@ -91,7 +91,7 @@ static PoolVector<uint8_t> basis_universal_packer(const Ref<Image> &p_image, Ima //params.m_quality_level = 0; //params.m_disable_hierarchical_endpoint_codebooks = true; //params.m_no_selector_rdo = true; - params.m_no_auto_global_sel_pal = true; + params.m_auto_global_sel_pal = false; basisu::job_pool jpool(OS::get_singleton()->get_processor_count()); params.m_pJob_pool = &jpool; @@ -170,13 +170,13 @@ static Ref<Image> basis_universal_unpacker(const PoolVector<uint8_t> &p_buffer) case BASIS_DECOMPRESS_RG: { if (VS::get_singleton()->has_os_feature("rgtc")) { - format = basist::cTFBC5; // get this from renderer + format = basist::transcoder_texture_format::cTFBC5; // get this from renderer imgfmt = Image::FORMAT_RGTC_RG; } else if (VS::get_singleton()->has_os_feature("etc2")) { //unfortunately, basis universal does not support // ERR_FAIL_V(image); //unimplemented here - //format = basist::cTFETC1; // get this from renderer + //format = basist::transcoder_texture_format::cTFETC1; // get this from renderer //imgfmt = Image::FORMAT_RGTC_RG; } else { //decompress @@ -184,47 +184,47 @@ static Ref<Image> basis_universal_unpacker(const PoolVector<uint8_t> &p_buffer) } break; case BASIS_DECOMPRESS_RGB: { if (VS::get_singleton()->has_os_feature("bptc")) { - format = basist::cTFBC7_M6_OPAQUE_ONLY; // get this from renderer + format = basist::transcoder_texture_format::cTFBC7_M6_OPAQUE_ONLY; // get this from renderer imgfmt = Image::FORMAT_BPTC_RGBA; } else if (VS::get_singleton()->has_os_feature("s3tc")) { - format = basist::cTFBC1; // get this from renderer + format = basist::transcoder_texture_format::cTFBC1; // get this from renderer imgfmt = Image::FORMAT_DXT1; } else if (VS::get_singleton()->has_os_feature("etc")) { - format = basist::cTFETC1; // get this from renderer + format = basist::transcoder_texture_format::cTFETC1; // get this from renderer imgfmt = Image::FORMAT_ETC; } else { - format = basist::cTFBGR565; // get this from renderer + format = basist::transcoder_texture_format::cTFBGR565; // get this from renderer imgfmt = Image::FORMAT_RGB565; } } break; case BASIS_DECOMPRESS_RGBA: { if (VS::get_singleton()->has_os_feature("bptc")) { - format = basist::cTFBC7_M5; // get this from renderer + format = basist::transcoder_texture_format::cTFBC7_M5; // get this from renderer imgfmt = Image::FORMAT_BPTC_RGBA; } else if (VS::get_singleton()->has_os_feature("s3tc")) { - format = basist::cTFBC3; // get this from renderer + format = basist::transcoder_texture_format::cTFBC3; // get this from renderer imgfmt = Image::FORMAT_DXT5; } else if (VS::get_singleton()->has_os_feature("etc2")) { - format = basist::cTFETC2; // get this from renderer + format = basist::transcoder_texture_format::cTFETC2; // get this from renderer imgfmt = Image::FORMAT_ETC2_RGBA8; } else { //gles2 most likely - format = basist::cTFRGBA4444; // get this from renderer + format = basist::transcoder_texture_format::cTFRGBA4444; // get this from renderer imgfmt = Image::FORMAT_RGBA4444; } } break; case BASIS_DECOMPRESS_RG_AS_RA: { if (VS::get_singleton()->has_os_feature("s3tc")) { - format = basist::cTFBC3; // get this from renderer + format = basist::transcoder_texture_format::cTFBC3; // get this from renderer imgfmt = Image::FORMAT_DXT5_RA_AS_RG; } else if (VS::get_singleton()->has_os_feature("etc2")) { - format = basist::cTFETC2; // get this from renderer + format = basist::transcoder_texture_format::cTFETC2; // get this from renderer imgfmt = Image::FORMAT_ETC2_RGBA8; } else { //gles2 most likely, bad for normalmaps, nothing to do about this. - format = basist::cTFRGBA32; + format = basist::transcoder_texture_format::cTFRGBA32; imgfmt = Image::FORMAT_RGBA8; } } break; diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/arvr/arvr_interface_gdnative.cpp index 7c791a3108..a033c2b7f9 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp +++ b/modules/gdnative/arvr/arvr_interface_gdnative.cpp @@ -277,7 +277,9 @@ godot_transform GDAPI godot_arvr_get_reference_frame() { void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) { // blits out our texture as is, handy for preview display of one of the eyes that is already rendered with lens distortion on an external HMD ARVRInterface::Eyes eye = (ARVRInterface::Eyes)p_eye; +#if 0 RID *render_target = (RID *)p_render_target; +#endif Rect2 screen_rect = *(Rect2 *)p_rect; if (eye == ARVRInterface::EYE_LEFT) { @@ -297,9 +299,12 @@ void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_re godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) { // In order to send off our textures to display on our hardware we need the opengl texture ID instead of the render target RID // This is a handy function to expose that. +#if 0 RID *render_target = (RID *)p_render_target; RID eye_texture = VSG::storage->render_target_get_texture(*render_target); +#endif + #ifndef _MSC_VER #warning need to obtain this ID again #endif diff --git a/platform/android/SCsub b/platform/android/SCsub index 3ff5b8278a..fd2a774c71 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -18,7 +18,6 @@ android_files = [ 'java_class_wrapper.cpp', 'java_godot_wrapper.cpp', 'java_godot_io_wrapper.cpp', - #'power_android.cpp' ] env_android = env.Clone() diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 642b045f5b..952bc3d28f 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -385,7 +385,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { ea->device_lock->unlock(); } - uint64_t sleep = OS::get_singleton()->get_power_state() == OS::POWERSTATE_ON_BATTERY ? 1000 : 100; + uint64_t sleep = 200; uint64_t wait = 3000000; uint64_t time = OS::get_singleton()->get_ticks_usec(); while (OS::get_singleton()->get_ticks_usec() - time < wait) { diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index e86e373630..15e3ac48c7 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -152,8 +152,6 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int input = memnew(InputDefault); input->set_fallback_mapping(godot_java->get_input_fallback_mapping()); - //power_manager = memnew(PowerAndroid); - return OK; } diff --git a/platform/android/os_android.h b/platform/android/os_android.h index c2f9a0992f..ec6ffe5438 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -37,7 +37,6 @@ #include "core/os/main_loop.h" #include "drivers/unix/os_unix.h" #include "main/input_default.h" -//#include "power_android.h" #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" @@ -93,8 +92,6 @@ private: GodotJavaWrapper *godot_java; GodotIOJavaWrapper *godot_io_java; - //PowerAndroid *power_manager_func; - int video_driver_index; public: diff --git a/platform/android/power_android.cpp b/platform/android/power_android.cpp deleted file mode 100644 index b0a90312e5..0000000000 --- a/platform/android/power_android.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/*************************************************************************/ -/* power_android.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -/* -Adapted from corresponding SDL 2.0 code. -*/ - -/* - Simple DirectMedia Layer - Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "power_android.h" - -#include "core/error_macros.h" - -static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) { - if (refholder->m_env) { - JNIEnv *env = refholder->m_env; - (*env)->PopLocalFrame(env, NULL); - --s_active; - } -} - -static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func) { - struct LocalReferenceHolder refholder; - refholder.m_env = NULL; - refholder.m_func = func; - return refholder; -} - -static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env) { - const int capacity = 16; - if ((*env)->PushLocalFrame(env, capacity) < 0) { - return false; - } - ++s_active; - refholder->m_env = env; - return true; -} - -static SDL_bool LocalReferenceHolder_IsActive(void) { - return s_active > 0; -} - -ANativeWindow *Android_JNI_GetNativeWindow(void) { - ANativeWindow *anw; - jobject s; - JNIEnv *env = Android_JNI_GetEnv(); - - s = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetNativeSurface); - anw = ANativeWindow_fromSurface(env, s); - (*env)->DeleteLocalRef(env, s); - - return anw; -} - -/* - * CODE CHUNK IMPORTED FROM SDL 2.0 - * returns 0 on success or -1 on error (others undefined then) - * returns truthy or falsy value in plugged, charged and battery - * returns the value in seconds and percent or -1 if not available - */ -int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent) { - env = Android_JNI_GetEnv(); - refs = LocalReferenceHolder_Setup(__FUNCTION__); - - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); - context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); - action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); - cls = (*env)->FindClass(env, "android/content/IntentFilter"); - mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); - filter = (*env)->NewObject(env, cls, mid, action); - (*env)->DeleteLocalRef(env, action); - mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); - intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); - (*env)->DeleteLocalRef(env, filter); - cls = (*env)->GetObjectClass(env, intent); - imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); -// Watch out for C89 scoping rules because of the macro -#define GET_INT_EXTRA(var, key) \ - int var; \ - iname = (*env)->NewStringUTF(env, key); \ - var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ - (*env)->DeleteLocalRef(env, iname); - bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); -// Watch out for C89 scoping rules because of the macro -#define GET_BOOL_EXTRA(var, key) \ - int var; \ - bname = (*env)->NewStringUTF(env, key); \ - var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ - (*env)->DeleteLocalRef(env, bname); - if (plugged) { - // Watch out for C89 scoping rules because of the macro - GET_INT_EXTRA(plug, "plugged") // == BatteryManager.EXTRA_PLUGGED (API 5) - if (plug == -1) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - // 1 == BatteryManager.BATTERY_PLUGGED_AC - // 2 == BatteryManager.BATTERY_PLUGGED_USB - *plugged = (0 < plug) ? 1 : 0; - } - if (charged) { - // Watch out for C89 scoping rules because of the macro - GET_INT_EXTRA(status, "status") // == BatteryManager.EXTRA_STATUS (API 5) - if (status == -1) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - // 5 == BatteryManager.BATTERY_STATUS_FULL - *charged = (status == 5) ? 1 : 0; - } - if (battery) { - GET_BOOL_EXTRA(present, "present") // == BatteryManager.EXTRA_PRESENT (API 5) - *battery = present ? 1 : 0; - } - if (seconds) { - *seconds = -1; // not possible - } - if (percent) { - int level; - int scale; - // Watch out for C89 scoping rules because of the macro - { - GET_INT_EXTRA(level_temp, "level") // == BatteryManager.EXTRA_LEVEL (API 5) - level = level_temp; - } - // Watch out for C89 scoping rules because of the macro - { - GET_INT_EXTRA(scale_temp, "scale") // == BatteryManager.EXTRA_SCALE (API 5) - scale = scale_temp; - } - if ((level == -1) || (scale == -1)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - *percent = level * 100 / scale; - } - (*env)->DeleteLocalRef(env, intent); - LocalReferenceHolder_Cleanup(&refs); - - return 0; -} - -bool PowerAndroid::GetPowerInfo_Android() { - int battery; - int plugged; - int charged; - - if (Android_JNI_GetPowerInfo(&plugged, &charged, &battery, &this->nsecs_left, &this->percent_left) != -1) { - if (plugged) { - if (charged) { - this->power_state = OS::POWERSTATE_CHARGED; - } else if (battery) { - this->power_state = OS::POWERSTATE_CHARGING; - } else { - this->power_state = OS::POWERSTATE_NO_BATTERY; - this->nsecs_left = -1; - this->percent_left = -1; - } - } else { - this->power_state = OS::POWERSTATE_ON_BATTERY; - } - } else { - this->power_state = OS::POWERSTATE_UNKNOWN; - this->nsecs_left = -1; - this->percent_left = -1; - } - - return true; -} - -OS::PowerState PowerAndroid::get_power_state() { - if (GetPowerInfo_Android()) { - return power_state; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerAndroid::get_power_seconds_left() { - if (GetPowerInfo_Android()) { - return nsecs_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} - -int PowerAndroid::get_power_percent_left() { - if (GetPowerInfo_Android()) { - return percent_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} - -PowerAndroid::PowerAndroid() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerAndroid::~PowerAndroid() { -} diff --git a/platform/android/power_android.h b/platform/android/power_android.h deleted file mode 100644 index 9f77f3fc6b..0000000000 --- a/platform/android/power_android.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************/ -/* power_android.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef POWER_ANDROID_H -#define POWER_ANDROID_H - -#include "core/os/os.h" - -#include <android/native_window_jni.h> - -class PowerAndroid { - - struct LocalReferenceHolder { - JNIEnv *m_env; - const char *m_func; - }; - -private: - static struct LocalReferenceHolder refs; - static JNIEnv *env; - static jmethodID mid; - static jobject context; - static jstring action; - static jclass cls; - static jobject filter; - static jobject intent; - static jstring iname; - static jmethodID imid; - static jstring bname; - static jmethodID bmid; - - int nsecs_left; - int percent_left; - OS::PowerState power_state; - - bool GetPowerInfo_Android(); - bool UpdatePowerInfo(); - -public: - static int s_active; - - PowerAndroid(); - virtual ~PowerAndroid(); - static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env); - static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func); - static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder); - - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; - -#endif // POWER_ANDROID_H diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 2e4bb2ff26..a082ba53f9 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -360,18 +360,3 @@ String OS_Haiku::get_cache_path() const { return get_config_path(); } } - -OS::PowerState OS_Haiku::get_power_state() { - WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; -} - -int OS_Haiku::get_power_seconds_left() { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; -} - -int OS_Haiku::get_power_percent_left() { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; -} diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index c99147198d..fc8cb77a91 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -113,10 +113,6 @@ public: virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const; virtual String get_executable_path() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual bool _check_internal_feature_support(const String &p_feature); virtual String get_config_path() const; diff --git a/platform/iphone/power_iphone.cpp b/platform/iphone/power_iphone.cpp deleted file mode 100644 index 36bac8da38..0000000000 --- a/platform/iphone/power_iphone.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************/ -/* power_iphone.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "power_iphone.h" - -bool PowerIphone::UpdatePowerInfo() { - return false; -} - -OS::PowerState PowerIphone::get_power_state() { - if (UpdatePowerInfo()) { - return power_state; - } else { - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerIphone::get_power_seconds_left() { - if (UpdatePowerInfo()) { - return nsecs_left; - } else { - return -1; - } -} - -int PowerIphone::get_power_percent_left() { - if (UpdatePowerInfo()) { - return percent_left; - } else { - return -1; - } -} - -PowerIphone::PowerIphone() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { - // TODO Auto-generated constructor stub -} - -PowerIphone::~PowerIphone() { - // TODO Auto-generated destructor stub -} diff --git a/platform/iphone/power_iphone.h b/platform/iphone/power_iphone.h deleted file mode 100644 index 47a4508509..0000000000 --- a/platform/iphone/power_iphone.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************/ -/* power_iphone.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef POWER_IPHONE_H -#define POWER_IPHONE_H - -#include <os/os.h> - -class PowerIphone { -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; - - bool UpdatePowerInfo(); - -public: - PowerIphone(); - virtual ~PowerIphone(); - - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; - -#endif // POWER_IPHONE_H diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index d22e53e7ea..8ba2b39c85 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -1244,24 +1244,6 @@ String OS_JavaScript::get_resource_dir() const { return "/"; } -OS::PowerState OS_JavaScript::get_power_state() { - - WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; -} - -int OS_JavaScript::get_power_seconds_left() { - - WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1"); - return -1; -} - -int OS_JavaScript::get_power_percent_left() { - - WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1"); - return -1; -} - void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags) { OS_JavaScript *os = get_singleton(); diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 65a18830ed..5319ea121c 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -160,10 +160,6 @@ public: virtual String get_resource_dir() const; virtual String get_user_data_dir() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - void set_idb_available(bool p_idb_available); virtual bool is_userfs_persistent() const; diff --git a/platform/osx/SCsub b/platform/osx/SCsub index 09f213cb0e..d764ac4b50 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -12,7 +12,6 @@ files = [ 'semaphore_osx.cpp', 'dir_access_osx.mm', 'joypad_osx.cpp', - 'power_osx.cpp', 'vulkan_context_osx.mm', 'context_gl_osx.mm' ] diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index bfd13be43a..75a56bd82c 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -40,7 +40,6 @@ #include "drivers/unix/os_unix.h" #include "joypad_osx.h" #include "main/input_default.h" -#include "power_osx.h" #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual/visual_server_wrap_mt.h" @@ -147,8 +146,6 @@ public: Size2 min_size; Size2 max_size; - PowerOSX *power_manager; - CrashHandler crash_handler; float _mouse_scale(float p_scale) { @@ -304,10 +301,6 @@ public: virtual String get_unique_id() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual bool _check_internal_feature_support(const String &p_feature); virtual void _set_use_vsync(bool p_enable); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 87ab8b3420..ca29c95f57 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -1628,8 +1628,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a input = memnew(InputDefault); joypad_osx = memnew(JoypadOSX); - power_manager = memnew(PowerOSX); - _ensure_user_data_dir(); restore_rect = Rect2(get_window_position(), get_window_size()); @@ -2973,18 +2971,6 @@ String OS_OSX::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } -OS::PowerState OS_OSX::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_OSX::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_OSX::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - Error OS_OSX::move_to_trash(const String &p_path) { NSFileManager *fm = [NSFileManager defaultManager]; NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())]; diff --git a/platform/osx/power_osx.cpp b/platform/osx/power_osx.cpp deleted file mode 100644 index 6d7667c5e8..0000000000 --- a/platform/osx/power_osx.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/*************************************************************************/ -/* power_osx.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -/* -Adapted from corresponding SDL 2.0 code. -*/ - -/* - Simple DirectMedia Layer - Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "power_osx.h" - -#include <CoreFoundation/CoreFoundation.h> -#include <IOKit/ps/IOPSKeys.h> -#include <IOKit/ps/IOPowerSources.h> - -// CODE CHUNK IMPORTED FROM SDL 2.0 - -/* CoreFoundation is so verbose... */ -#define STRMATCH(a, b) (CFStringCompare(a, b, 0) == kCFCompareEqualTo) -#define GETVAL(k, v) \ - CFDictionaryGetValueIfPresent(dict, CFSTR(k), (const void **)v) - -/* Note that AC power sources also include a laptop battery it is charging. */ -void PowerOSX::checkps(CFDictionaryRef dict, bool *have_ac, bool *have_battery, bool *charging) { - CFStringRef strval; /* don't CFRelease() this. */ - CFBooleanRef bval; - CFNumberRef numval; - bool charge = false; - bool choose = false; - bool is_ac = false; - int secs = -1; - int maxpct = -1; - int pct = -1; - - if ((GETVAL(kIOPSIsPresentKey, &bval)) && (bval == kCFBooleanFalse)) { - return; /* nothing to see here. */ - } - - if (!GETVAL(kIOPSPowerSourceStateKey, &strval)) { - return; - } - - if (STRMATCH(strval, CFSTR(kIOPSACPowerValue))) { - is_ac = *have_ac = true; - } else if (!STRMATCH(strval, CFSTR(kIOPSBatteryPowerValue))) { - return; /* not a battery? */ - } - - if ((GETVAL(kIOPSIsChargingKey, &bval)) && (bval == kCFBooleanTrue)) { - charge = true; - } - - if (GETVAL(kIOPSMaxCapacityKey, &numval)) { - SInt32 val = -1; - CFNumberGetValue(numval, kCFNumberSInt32Type, &val); - if (val > 0) { - *have_battery = true; - maxpct = (int)val; - } - } - - if (GETVAL(kIOPSMaxCapacityKey, &numval)) { - SInt32 val = -1; - CFNumberGetValue(numval, kCFNumberSInt32Type, &val); - if (val > 0) { - *have_battery = true; - maxpct = (int)val; - } - } - - if (GETVAL(kIOPSTimeToEmptyKey, &numval)) { - SInt32 val = -1; - CFNumberGetValue(numval, kCFNumberSInt32Type, &val); - - /* Mac OS X reports 0 minutes until empty if you're plugged in. :( */ - if ((val == 0) && (is_ac)) { - val = -1; /* !!! FIXME: calc from timeToFull and capacity? */ - } - - secs = (int)val; - if (secs > 0) { - secs *= 60; /* value is in minutes, so convert to seconds. */ - } - } - - if (GETVAL(kIOPSCurrentCapacityKey, &numval)) { - SInt32 val = -1; - CFNumberGetValue(numval, kCFNumberSInt32Type, &val); - pct = (int)val; - } - - if ((pct > 0) && (maxpct > 0)) { - pct = (int)((((double)pct) / ((double)maxpct)) * 100.0); - } - - if (pct > 100) { - pct = 100; - } - - /* - * We pick the battery that claims to have the most minutes left. - * (failing a report of minutes, we'll take the highest percent.) - */ - if ((secs < 0) && (nsecs_left < 0)) { - if ((pct < 0) && (percent_left < 0)) { - choose = true; /* at least we know there's a battery. */ - } - if (pct > percent_left) { - choose = true; - } - } else if (secs > nsecs_left) { - choose = true; - } - - if (choose) { - nsecs_left = secs; - percent_left = pct; - *charging = charge; - } -} - -#undef GETVAL -#undef STRMATCH - -// CODE CHUNK IMPORTED FROM SDL 2.0 -bool PowerOSX::GetPowerInfo_MacOSX() { - CFTypeRef blob = IOPSCopyPowerSourcesInfo(); - - nsecs_left = -1; - percent_left = -1; - power_state = OS::POWERSTATE_UNKNOWN; - - if (blob != NULL) { - CFArrayRef list = IOPSCopyPowerSourcesList(blob); - if (list != NULL) { - /* don't CFRelease() the list items, or dictionaries! */ - bool have_ac = false; - bool have_battery = false; - bool charging = false; - const CFIndex total = CFArrayGetCount(list); - CFIndex i; - for (i = 0; i < total; i++) { - CFTypeRef ps = (CFTypeRef)CFArrayGetValueAtIndex(list, i); - CFDictionaryRef dict = IOPSGetPowerSourceDescription(blob, ps); - if (dict != NULL) { - checkps(dict, &have_ac, &have_battery, &charging); - } - } - - if (!have_battery) { - power_state = OS::POWERSTATE_NO_BATTERY; - } else if (charging) { - power_state = OS::POWERSTATE_CHARGING; - } else if (have_ac) { - power_state = OS::POWERSTATE_CHARGED; - } else { - power_state = OS::POWERSTATE_ON_BATTERY; - } - - CFRelease(list); - } - CFRelease(blob); - } - - return true; /* always the definitive answer on Mac OS X. */ -} - -bool PowerOSX::UpdatePowerInfo() { - if (GetPowerInfo_MacOSX()) { - return true; - } - return false; -} - -OS::PowerState PowerOSX::get_power_state() { - if (UpdatePowerInfo()) { - return power_state; - } else { - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerOSX::get_power_seconds_left() { - if (UpdatePowerInfo()) { - return nsecs_left; - } else { - return -1; - } -} - -int PowerOSX::get_power_percent_left() { - if (UpdatePowerInfo()) { - return percent_left; - } else { - return -1; - } -} - -PowerOSX::PowerOSX() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerOSX::~PowerOSX() { -} diff --git a/platform/osx/power_osx.h b/platform/osx/power_osx.h deleted file mode 100644 index 6f9b213439..0000000000 --- a/platform/osx/power_osx.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************/ -/* power_osx.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef POWER_OSX_H -#define POWER_OSX_H - -#include "core/os/file_access.h" -#include "core/os/os.h" -#include "dir_access_osx.h" - -#include <CoreFoundation/CoreFoundation.h> - -class PowerOSX { - -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; - void checkps(CFDictionaryRef dict, bool *have_ac, bool *have_battery, bool *charging); - bool GetPowerInfo_MacOSX(/*PowerState * state, int *seconds, int *percent*/); - bool UpdatePowerInfo(); - -public: - PowerOSX(); - virtual ~PowerOSX(); - - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; - -#endif // POWER_OSX_H diff --git a/platform/server/SCsub b/platform/server/SCsub index f977275595..e8538f03a6 100644 --- a/platform/server/SCsub +++ b/platform/server/SCsub @@ -10,10 +10,8 @@ common_server = [\ if sys.platform == "darwin": common_server.append("#platform/osx/crash_handler_osx.mm") - common_server.append("#platform/osx/power_osx.cpp") common_server.append("#platform/osx/semaphore_osx.cpp") else: common_server.append("#platform/x11/crash_handler_x11.cpp") - common_server.append("#platform/x11/power_x11.cpp") prog = env.add_program('#bin/godot_server', ['godot_server.cpp'] + common_server) diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp index 498fd01b5e..c0a4813596 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -92,12 +92,6 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int input = memnew(InputDefault); -#ifdef __APPLE__ - power_manager = memnew(PowerOSX); -#else - power_manager = memnew(PowerX11); -#endif - _ensure_user_data_dir(); resource_loader_dummy.instance(); @@ -117,8 +111,6 @@ void OS_Server::finalize() { memdelete(input); - memdelete(power_manager); - ResourceLoader::remove_resource_format_loader(resource_loader_dummy); resource_loader_dummy.unref(); @@ -198,18 +190,6 @@ String OS_Server::get_name() const { void OS_Server::move_window_to_foreground() { } -OS::PowerState OS_Server::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_Server::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_Server::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - bool OS_Server::_check_internal_feature_support(const String &p_feature) { return p_feature == "pc"; } diff --git a/platform/server/os_server.h b/platform/server/os_server.h index 46ca9cb6d1..7584293722 100644 --- a/platform/server/os_server.h +++ b/platform/server/os_server.h @@ -36,11 +36,9 @@ #include "main/input_default.h" #ifdef __APPLE__ #include "platform/osx/crash_handler_osx.h" -#include "platform/osx/power_osx.h" #include "platform/osx/semaphore_osx.h" #else #include "platform/x11/crash_handler_x11.h" -#include "platform/x11/power_x11.h" #endif #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" @@ -63,12 +61,6 @@ class OS_Server : public OS_Unix { InputDefault *input; -#ifdef __APPLE__ - PowerOSX *power_manager; -#else - PowerX11 *power_manager; -#endif - CrashHandler crash_handler; int video_driver_index; @@ -112,9 +104,6 @@ public: void run(); - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); virtual bool _check_internal_feature_support(const String &p_feature); virtual String get_config_path() const; diff --git a/platform/uwp/SCsub b/platform/uwp/SCsub index c14290f0c4..620d8c3c3a 100644 --- a/platform/uwp/SCsub +++ b/platform/uwp/SCsub @@ -7,7 +7,6 @@ files = [ '#platform/windows/key_mapping_windows.cpp', '#platform/windows/windows_terminal_logger.cpp', 'joypad_uwp.cpp', - 'power_uwp.cpp', 'context_egl_uwp.cpp', 'app.cpp', 'os_uwp.cpp', diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 9748c1ef9f..3cd7a02a94 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -271,8 +271,6 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a AudioDriverManager::initialize(p_audio_driver); - power_manager = memnew(PowerUWP); - managed_object->update_clipboard(); Clipboard::ContentChanged += ref new EventHandler<Platform::Object ^>(managed_object, &ManagedType::on_clipboard_changed); @@ -854,18 +852,6 @@ bool OS_UWP::_check_internal_feature_support(const String &p_feature) { return p_feature == "pc"; } -OS::PowerState OS_UWP::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_UWP::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_UWP::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - OS_UWP::OS_UWP() { key_event_pos = 0; diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index fb43ab382e..32b899c0da 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -39,7 +39,6 @@ #include "drivers/xaudio2/audio_driver_xaudio2.h" #include "joypad_uwp.h" #include "main/input_default.h" -#include "power_uwp.h" #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" @@ -102,8 +101,6 @@ private: AudioDriverXAudio2 audio_driver; - PowerUWP *power_manager; - MouseMode mouse_mode; bool alt_mem; bool gr_mem; @@ -254,10 +251,6 @@ public: void input_event(const Ref<InputEvent> &p_event); - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - void queue_key_event(KeyEvent &p_event); OS_UWP(); diff --git a/platform/uwp/power_uwp.cpp b/platform/uwp/power_uwp.cpp deleted file mode 100644 index c6b4359392..0000000000 --- a/platform/uwp/power_uwp.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************/ -/* power_uwp.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "power_uwp.h" - -PowerUWP::PowerUWP() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerUWP::~PowerUWP() { -} - -bool PowerUWP::UpdatePowerInfo() { - // TODO, WinRT: Battery info is available on at least one WinRT platform (Windows Phone 8). Implement UpdatePowerInfo as appropriate. */ - /* Notes from SDL: - - the Win32 function, GetSystemPowerStatus, is not available for use on WinRT - - Windows Phone 8 has a 'Battery' class, which is documented as available for C++ - - More info on WP8's Battery class can be found at http://msdn.microsoft.com/library/windowsphone/develop/jj207231 - */ - return false; -} - -OS::PowerState PowerUWP::get_power_state() { - if (UpdatePowerInfo()) { - return power_state; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerUWP::get_power_seconds_left() { - if (UpdatePowerInfo()) { - return nsecs_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} - -int PowerUWP::get_power_percent_left() { - if (UpdatePowerInfo()) { - return percent_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} diff --git a/platform/uwp/power_uwp.h b/platform/uwp/power_uwp.h deleted file mode 100644 index 5e28cf65e5..0000000000 --- a/platform/uwp/power_uwp.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************/ -/* power_uwp.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef POWER_UWP_H -#define POWER_UWP_H - -#include "core/os/dir_access.h" -#include "core/os/file_access.h" -#include "core/os/os.h" - -class PowerUWP { - -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; - - bool UpdatePowerInfo(); - -public: - PowerUWP(); - virtual ~PowerUWP(); - - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; - -#endif // POWER_UWP_H diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 6f01460025..8e94c7b35d 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -12,7 +12,6 @@ common_win = [ "os_windows.cpp", "key_mapping_windows.cpp", "joypad_windows.cpp", - "power_windows.cpp", "windows_terminal_logger.cpp", "vulkan_context_win.cpp", "context_gl_windows.cpp" diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 133dc9004d..cdcdf65e21 100755 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1492,8 +1492,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int input = memnew(InputDefault); joypad = memnew(JoypadWindows(input, &hWnd)); - power_manager = memnew(PowerWindows); - AudioDriverManager::initialize(p_audio_driver); TRACKMOUSEEVENT tme; @@ -3334,18 +3332,6 @@ void OS_Windows::_set_use_vsync(bool p_enable) { #endif } -OS::PowerState OS_Windows::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_Windows::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_Windows::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - bool OS_Windows::_check_internal_feature_support(const String &p_feature) { return p_feature == "pc"; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 89b67f8d91..6c3769c98c 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -40,7 +40,6 @@ #include "drivers/winmidi/midi_driver_winmidi.h" #include "key_mapping_windows.h" #include "main/input_default.h" -#include "power_windows.h" #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" @@ -239,8 +238,6 @@ class OS_Windows : public OS { JoypadWindows *joypad; Map<int, Vector2> touch_state; - PowerWindows *power_manager; - int video_driver_index; #ifdef WASAPI_ENABLED AudioDriverWASAPI driver_wasapi; @@ -433,10 +430,6 @@ public: virtual void _set_use_vsync(bool p_enable); //virtual bool is_vsync_enabled() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual bool _check_internal_feature_support(const String &p_feature); void disable_crash_handler(); diff --git a/platform/windows/power_windows.cpp b/platform/windows/power_windows.cpp deleted file mode 100644 index aea06da413..0000000000 --- a/platform/windows/power_windows.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************/ -/* power_windows.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -/* -Adapted from corresponding SDL 2.0 code. -*/ - -/* - Simple DirectMedia Layer - Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "power_windows.h" - -// CODE CHUNK IMPORTED FROM SDL 2.0 - -bool PowerWindows::GetPowerInfo_Windows() { - SYSTEM_POWER_STATUS status; - bool need_details = FALSE; - - /* This API should exist back to Win95. */ - if (!GetSystemPowerStatus(&status)) { - /* !!! FIXME: push GetLastError() into GetError() */ - power_state = OS::POWERSTATE_UNKNOWN; - } else if (status.BatteryFlag == 0xFF) { /* unknown state */ - power_state = OS::POWERSTATE_UNKNOWN; - } else if (status.BatteryFlag & (1 << 7)) { /* no battery */ - power_state = OS::POWERSTATE_NO_BATTERY; - } else if (status.BatteryFlag & (1 << 3)) { /* charging */ - power_state = OS::POWERSTATE_CHARGING; - need_details = TRUE; - } else if (status.ACLineStatus == 1) { - power_state = OS::POWERSTATE_CHARGED; /* on AC, not charging. */ - need_details = TRUE; - } else { - power_state = OS::POWERSTATE_ON_BATTERY; /* not on AC. */ - need_details = TRUE; - } - - percent_left = -1; - nsecs_left = -1; - if (need_details) { - const int pct = (int)status.BatteryLifePercent; - const int secs = (int)status.BatteryLifeTime; - - if (pct != 255) { /* 255 == unknown */ - percent_left = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ - } - if (secs != (int)0xFFFFFFFF) { /* ((DWORD)-1) == unknown */ - nsecs_left = secs; - } - } - - return TRUE; /* always the definitive answer on Windows. */ -} - -OS::PowerState PowerWindows::get_power_state() { - if (GetPowerInfo_Windows()) { - return power_state; - } else { - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerWindows::get_power_seconds_left() { - if (GetPowerInfo_Windows()) { - return nsecs_left; - } else { - return -1; - } -} - -int PowerWindows::get_power_percent_left() { - if (GetPowerInfo_Windows()) { - return percent_left; - } else { - return -1; - } -} - -PowerWindows::PowerWindows() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerWindows::~PowerWindows() { -} diff --git a/platform/windows/power_windows.h b/platform/windows/power_windows.h deleted file mode 100644 index 80d86a12c5..0000000000 --- a/platform/windows/power_windows.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************/ -/* power_windows.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef POWER_WINDOWS_H -#define POWER_WINDOWS_H - -#include "core/os/dir_access.h" -#include "core/os/file_access.h" -#include "core/os/os.h" - -#include <windows.h> - -class PowerWindows { - -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; - - bool GetPowerInfo_Windows(); - -public: - PowerWindows(); - virtual ~PowerWindows(); - - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; - -#endif // POWER_WINDOWS_H diff --git a/platform/x11/SCsub b/platform/x11/SCsub index 9027c244be..2268e4cc3d 100644 --- a/platform/x11/SCsub +++ b/platform/x11/SCsub @@ -12,7 +12,6 @@ common_x11 = [ "os_x11.cpp", "key_mapping_x11.cpp", "joypad_linux.cpp", - "power_x11.cpp", "detect_prime.cpp" ] diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 1fd91ec3c1..26170a8335 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -659,8 +659,6 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a #endif _ensure_user_data_dir(); - power_manager = memnew(PowerX11); - if (p_desired.layered) { set_window_per_pixel_transparency_enabled(true); } @@ -870,8 +868,6 @@ void OS_X11::finalize() { visual_server->finish(); memdelete(visual_server); - memdelete(power_manager); - #if defined(OPENGL_ENABLED) if (video_driver_index == VIDEO_DRIVER_GLES2) { @@ -3389,18 +3385,6 @@ void OS_X11::set_context(int p_context) { } } -OS::PowerState OS_X11::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_X11::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_X11::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - void OS_X11::disable_crash_handler() { crash_handler.disable(); } diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index fd8a981763..55d24d64a3 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -39,7 +39,6 @@ #include "drivers/unix/os_unix.h" #include "joypad_linux.h" #include "main/input_default.h" -#include "power_x11.h" #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" @@ -200,8 +199,6 @@ class OS_X11 : public OS_Unix { AudioDriverPulseAudio driver_pulseaudio; #endif - PowerX11 *power_manager; - bool layered_window; CrashHandler crash_handler; @@ -323,10 +320,6 @@ public: virtual void _set_use_vsync(bool p_enable); //virtual bool is_vsync_enabled() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual bool _check_internal_feature_support(const String &p_feature); virtual void force_process_input(); diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp deleted file mode 100644 index 5ac5e8e87b..0000000000 --- a/platform/x11/power_x11.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/*************************************************************************/ -/* power_x11.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -/* -Adapted from corresponding SDL 2.0 code. -*/ - -/* - Simple DirectMedia Layer - Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "power_x11.h" - -#include <stdio.h> -#include <unistd.h> - -#include "core/error_macros.h" -#include <dirent.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> - -// CODE CHUNK IMPORTED FROM SDL 2.0 - -static const char *proc_apm_path = "/proc/apm"; -static const char *proc_acpi_battery_path = "/proc/acpi/battery"; -static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter"; -static const char *sys_class_power_supply_path = "/sys/class/power_supply"; - -FileAccessRef PowerX11::open_power_file(const char *base, const char *node, const char *key) { - String path = String(base) + String("/") + String(node) + String("/") + String(key); - FileAccessRef f = FileAccess::open(path, FileAccess::READ); - return f; -} - -bool PowerX11::read_power_file(const char *base, const char *node, const char *key, char *buf, size_t buflen) { - ssize_t br = 0; - FileAccessRef fd = open_power_file(base, node, key); - if (!fd) { - return false; - } - br = fd->get_buffer(reinterpret_cast<uint8_t *>(buf), buflen - 1); - fd->close(); - if (br < 0) { - return false; - } - buf[br] = '\0'; // null-terminate the string - return true; -} - -bool PowerX11::make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) { - char *ptr = *_ptr; - - while (*ptr == ' ') { - ptr++; /* skip whitespace. */ - } - - if (*ptr == '\0') { - return false; /* EOF. */ - } - - *_key = ptr; - - while ((*ptr != ':') && (*ptr != '\0')) { - ptr++; - } - - if (*ptr == '\0') { - return false; /* (unexpected) EOF. */ - } - - *(ptr++) = '\0'; /* terminate the key. */ - - while (*ptr == ' ') { - ptr++; /* skip whitespace. */ - } - - if (*ptr == '\0') { - return false; /* (unexpected) EOF. */ - } - - *_val = ptr; - - while ((*ptr != '\n') && (*ptr != '\0')) { - ptr++; - } - - if (*ptr != '\0') { - *(ptr++) = '\0'; /* terminate the value. */ - } - - *_ptr = ptr; /* store for next time. */ - return true; -} - -void PowerX11::check_proc_acpi_battery(const char *node, bool *have_battery, bool *charging) { - const char *base = proc_acpi_battery_path; - char info[1024]; - char state[1024]; - char *ptr = NULL; - char *key = NULL; - char *val = NULL; - bool charge = false; - bool choose = false; - int maximum = -1; - int remaining = -1; - int secs = -1; - int pct = -1; - - if (!read_power_file(base, node, "state", state, sizeof(state))) { - return; - } else { - if (!read_power_file(base, node, "info", info, sizeof(info))) - return; - } - - ptr = &state[0]; - while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (String(key) == "present") { - if (String(val) == "yes") { - *have_battery = true; - } - } else if (String(key) == "charging state") { - /* !!! FIXME: what exactly _does_ charging/discharging mean? */ - if (String(val) == "charging/discharging") { - charge = true; - } else if (String(val) == "charging") { - charge = true; - } - } else if (String(key) == "remaining capacity") { - String sval = val; - const int cvt = sval.to_int(); - remaining = cvt; - } - } - - ptr = &info[0]; - while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (String(key) == "design capacity") { - String sval = val; - const int cvt = sval.to_int(); - maximum = cvt; - } - } - - if ((maximum >= 0) && (remaining >= 0)) { - pct = (int)((((float)remaining) / ((float)maximum)) * 100.0f); - if (pct < 0) { - pct = 0; - } else if (pct > 100) { - pct = 100; - } - } - - /* !!! FIXME: calculate (secs). */ - - /* - * We pick the battery that claims to have the most minutes left. - * (failing a report of minutes, we'll take the highest percent.) - */ - // -- GODOT start -- - //if ((secs < 0) && (this->nsecs_left < 0)) { - if (this->nsecs_left < 0) { - // -- GODOT end -- - if ((pct < 0) && (this->percent_left < 0)) { - choose = true; /* at least we know there's a battery. */ - } - if (pct > this->percent_left) { - choose = true; - } - } else if (secs > this->nsecs_left) { - choose = true; - } - - if (choose) { - this->nsecs_left = secs; - this->percent_left = pct; - *charging = charge; - } -} - -void PowerX11::check_proc_acpi_ac_adapter(const char *node, bool *have_ac) { - const char *base = proc_acpi_ac_adapter_path; - char state[256]; - char *ptr = NULL; - char *key = NULL; - char *val = NULL; - - if (!read_power_file(base, node, "state", state, sizeof(state))) { - return; - } - - ptr = &state[0]; - while (make_proc_acpi_key_val(&ptr, &key, &val)) { - String skey = key; - if (skey == "state") { - String sval = val; - if (sval == "on-line") { - *have_ac = true; - } - } - } -} - -bool PowerX11::GetPowerInfo_Linux_proc_acpi() { - String node; - DirAccess *dirp = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - bool have_battery = false; - bool have_ac = false; - bool charging = false; - - this->nsecs_left = -1; - this->percent_left = -1; - this->power_state = OS::POWERSTATE_UNKNOWN; - - dirp->change_dir(proc_acpi_battery_path); - Error err = dirp->list_dir_begin(); - - if (err != OK) { - return false; /* can't use this interface. */ - } else { - node = dirp->get_next(); - while (node != "") { - check_proc_acpi_battery(node.utf8().get_data(), &have_battery, &charging /*, seconds, percent*/); - node = dirp->get_next(); - } - } - dirp->change_dir(proc_acpi_ac_adapter_path); - err = dirp->list_dir_begin(); - if (err != OK) { - return false; /* can't use this interface. */ - } else { - node = dirp->get_next(); - while (node != "") { - check_proc_acpi_ac_adapter(node.utf8().get_data(), &have_ac); - node = dirp->get_next(); - } - } - - if (!have_battery) { - this->power_state = OS::POWERSTATE_NO_BATTERY; - } else if (charging) { - this->power_state = OS::POWERSTATE_CHARGING; - } else if (have_ac) { - this->power_state = OS::POWERSTATE_CHARGED; - } else { - this->power_state = OS::POWERSTATE_ON_BATTERY; - } - - memdelete(dirp); - return true; /* definitive answer. */ -} - -bool PowerX11::next_string(char **_ptr, char **_str) { - char *ptr = *_ptr; - char *str = *_str; - - while (*ptr == ' ') { /* skip any spaces... */ - ptr++; - } - - if (*ptr == '\0') { - return false; - } - - str = ptr; - while ((*ptr != ' ') && (*ptr != '\n') && (*ptr != '\0')) - ptr++; - - if (*ptr != '\0') - *(ptr++) = '\0'; - - *_str = str; - *_ptr = ptr; - return true; -} - -bool PowerX11::int_string(char *str, int *val) { - String sval = str; - *val = sval.to_int(); - return (*str != '\0'); -} - -/* http://lxr.linux.no/linux+v2.6.29/drivers/char/apm-emulation.c */ -bool PowerX11::GetPowerInfo_Linux_proc_apm() { - bool need_details = false; - int ac_status = 0; - int battery_status = 0; - int battery_flag = 0; - int battery_percent = 0; - int battery_time = 0; - FileAccessRef fd = FileAccess::open(proc_apm_path, FileAccess::READ); - char buf[128]; - char *ptr = &buf[0]; - char *str = NULL; - ssize_t br; - - if (!fd) { - return false; /* can't use this interface. */ - } - - br = fd->get_buffer(reinterpret_cast<uint8_t *>(buf), sizeof(buf) - 1); - fd->close(); - - if (br < 0) { - return false; - } - - buf[br] = '\0'; /* null-terminate the string. */ - if (!next_string(&ptr, &str)) { /* driver version */ - return false; - } - if (!next_string(&ptr, &str)) { /* BIOS version */ - return false; - } - if (!next_string(&ptr, &str)) { /* APM flags */ - return false; - } - - if (!next_string(&ptr, &str)) { /* AC line status */ - return false; - } else if (!int_string(str, &ac_status)) { - return false; - } - - if (!next_string(&ptr, &str)) { /* battery status */ - return false; - } else if (!int_string(str, &battery_status)) { - return false; - } - if (!next_string(&ptr, &str)) { /* battery flag */ - return false; - } else if (!int_string(str, &battery_flag)) { - return false; - } - if (!next_string(&ptr, &str)) { /* remaining battery life percent */ - return false; - } - String sstr = str; - if (sstr[sstr.length() - 1] == '%') { - sstr[sstr.length() - 1] = '\0'; - } - if (!int_string(str, &battery_percent)) { - return false; - } - - if (!next_string(&ptr, &str)) { /* remaining battery life time */ - return false; - } else if (!int_string(str, &battery_time)) { - return false; - } - - if (!next_string(&ptr, &str)) { /* remaining battery life time units */ - return false; - } else if (String(str) == "min") { - battery_time *= 60; - } - - if (battery_flag == 0xFF) { /* unknown state */ - this->power_state = OS::POWERSTATE_UNKNOWN; - } else if (battery_flag & (1 << 7)) { /* no battery */ - this->power_state = OS::POWERSTATE_NO_BATTERY; - } else if (battery_flag & (1 << 3)) { /* charging */ - this->power_state = OS::POWERSTATE_CHARGING; - need_details = true; - } else if (ac_status == 1) { - this->power_state = OS::POWERSTATE_CHARGED; /* on AC, not charging. */ - need_details = true; - } else { - this->power_state = OS::POWERSTATE_ON_BATTERY; - need_details = true; - } - - this->percent_left = -1; - this->nsecs_left = -1; - if (need_details) { - const int pct = battery_percent; - const int secs = battery_time; - - if (pct >= 0) { /* -1 == unknown */ - this->percent_left = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ - } - if (secs >= 0) { /* -1 == unknown */ - this->nsecs_left = secs; - } - } - - return true; -} - -/* !!! FIXME: implement d-bus queries to org.freedesktop.UPower. */ - -bool PowerX11::GetPowerInfo_Linux_sys_class_power_supply(/*PowerState *state, int *seconds, int *percent*/) { - const char *base = sys_class_power_supply_path; - String name; - - DirAccess *dirp = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - dirp->change_dir(base); - Error err = dirp->list_dir_begin(); - - if (err != OK) { - return false; - } - - this->power_state = OS::POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */ - this->nsecs_left = -1; - this->percent_left = -1; - - name = dirp->get_next(); - - while (name != "") { - bool choose = false; - char str[64]; - OS::PowerState st; - int secs; - int pct; - - if ((name == ".") || (name == "..")) { - name = dirp->get_next(); - continue; //skip these, of course. - } else { - if (!read_power_file(base, name.utf8().get_data(), "type", str, sizeof(str))) { - name = dirp->get_next(); - continue; // Don't know _what_ we're looking at. Give up on it. - } else { - if (String(str) != "Battery\n") { - name = dirp->get_next(); - continue; // we don't care about UPS and such. - } - } - } - - /* some drivers don't offer this, so if it's not explicitly reported assume it's present. */ - if (read_power_file(base, name.utf8().get_data(), "present", str, sizeof(str)) && (String(str) == "0\n")) { - st = OS::POWERSTATE_NO_BATTERY; - } else if (!read_power_file(base, name.utf8().get_data(), "status", str, sizeof(str))) { - st = OS::POWERSTATE_UNKNOWN; /* uh oh */ - } else if (String(str) == "Charging\n") { - st = OS::POWERSTATE_CHARGING; - } else if (String(str) == "Discharging\n") { - st = OS::POWERSTATE_ON_BATTERY; - } else if ((String(str) == "Full\n") || (String(str) == "Not charging\n")) { - st = OS::POWERSTATE_CHARGED; - } else { - st = OS::POWERSTATE_UNKNOWN; /* uh oh */ - } - - if (!read_power_file(base, name.utf8().get_data(), "capacity", str, sizeof(str))) { - pct = -1; - } else { - pct = String(str).to_int(); - pct = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ - } - - if (!read_power_file(base, name.utf8().get_data(), "time_to_empty_now", str, sizeof(str))) { - secs = -1; - } else { - secs = String(str).to_int(); - secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */ - } - - /* - * We pick the battery that claims to have the most minutes left. - * (failing a report of minutes, we'll take the highest percent.) - */ - if ((secs < 0) && (this->nsecs_left < 0)) { - if ((pct < 0) && (this->percent_left < 0)) { - choose = true; /* at least we know there's a battery. */ - } else if (pct > this->percent_left) { - choose = true; - } - } else if (secs > this->nsecs_left) { - choose = true; - } - - if (choose) { - this->nsecs_left = secs; - this->percent_left = pct; - this->power_state = st; - } - - name = dirp->get_next(); - } - - memdelete(dirp); - return true; /* don't look any further*/ -} - -bool PowerX11::UpdatePowerInfo() { - if (GetPowerInfo_Linux_sys_class_power_supply()) { // try method 1 - return true; - } - if (GetPowerInfo_Linux_proc_acpi()) { // try further - return true; - } - if (GetPowerInfo_Linux_proc_apm()) { // try even further - return true; - } - return false; -} - -PowerX11::PowerX11() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerX11::~PowerX11() { -} - -OS::PowerState PowerX11::get_power_state() { - if (UpdatePowerInfo()) { - return power_state; - } else { - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerX11::get_power_seconds_left() { - if (UpdatePowerInfo()) { - return nsecs_left; - } else { - return -1; - } -} - -int PowerX11::get_power_percent_left() { - if (UpdatePowerInfo()) { - return percent_left; - } else { - return -1; - } -} diff --git a/platform/x11/power_x11.h b/platform/x11/power_x11.h deleted file mode 100644 index 76f20c68e8..0000000000 --- a/platform/x11/power_x11.h +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************/ -/* power_x11.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef POWER_X11_H -#define POWER_X11_H - -#include "core/os/dir_access.h" -#include "core/os/file_access.h" -#include "core/os/os.h" - -class PowerX11 { - -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; - - FileAccessRef open_power_file(const char *base, const char *node, const char *key); - bool read_power_file(const char *base, const char *node, const char *key, char *buf, size_t buflen); - bool make_proc_acpi_key_val(char **_ptr, char **_key, char **_val); - void check_proc_acpi_battery(const char *node, bool *have_battery, bool *charging); - void check_proc_acpi_ac_adapter(const char *node, bool *have_ac); - bool GetPowerInfo_Linux_proc_acpi(); - bool next_string(char **_ptr, char **_str); - bool int_string(char *str, int *val); - bool GetPowerInfo_Linux_proc_apm(); - bool GetPowerInfo_Linux_sys_class_power_supply(); - bool UpdatePowerInfo(); - -public: - PowerX11(); - virtual ~PowerX11(); - - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; - -#endif // POWER_X11_H diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index c40cdb4720..21b2bede05 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -363,8 +363,11 @@ void NavigationPolygon::_bind_methods() { NavigationPolygon::NavigationPolygon() : rect_cache_dirty(true), - navmesh_generation(NULL) { - navmesh_generation = Mutex::create(); + navmesh_generation(Mutex::create()) { +} + +NavigationPolygon::~NavigationPolygon() { + memdelete(navmesh_generation); } void NavigationPolygonInstance::set_enabled(bool p_enabled) { diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h index 92cfc8f5e6..8d3d8543c4 100644 --- a/scene/2d/navigation_polygon.h +++ b/scene/2d/navigation_polygon.h @@ -91,6 +91,7 @@ public: Ref<NavigationMesh> get_mesh(); NavigationPolygon(); + ~NavigationPolygon(); }; class Navigation2D; diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 4d7054726d..7cf26ab974 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -1087,7 +1087,7 @@ PoolVector<uint8_t> Voxelizer::get_sdf_3d_image() const { if (d == 0) { w[i] = 0; } else { - w[i] = CLAMP(d, 0, 254) + 1; + w[i] = MIN(d, 254) + 1; } } } diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 01e3c4c930..6e2fe01834 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -423,6 +423,7 @@ void BaseMaterial3D::_update_shader() { case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: texfilter_str = "filter_linear_mipmap"; break; case TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC: texfilter_str = "filter_nearest_mipmap_aniso"; break; case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: texfilter_str = "filter_linear_mipmap_aniso"; break; + case TEXTURE_FILTER_MAX: break; // Internal value, skip. } if (flags[FLAG_USE_TEXTURE_REPEAT]) { diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 72c9a7f913..08d2104f94 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -1080,8 +1080,8 @@ public: const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c); xf = transform->xform; found_xform = true; - - } //passthrough + FALLTHROUGH; + } default: { c = c->next; continue; diff --git a/servers/visual/rasterizer_rd/light_cluster_builder.cpp b/servers/visual/rasterizer_rd/light_cluster_builder.cpp index 5fe734e82d..78011c22cc 100644 --- a/servers/visual/rasterizer_rd/light_cluster_builder.cpp +++ b/servers/visual/rasterizer_rd/light_cluster_builder.cpp @@ -112,8 +112,8 @@ void LightClusterBuilder::bake_cluster() { int sx = MAX(0, from_x); int sy = MAX(0, from_y); - int dx = MIN(width - 1, to_x); - int dy = MIN(height - 1, to_y); + int dx = MIN((int)width - 1, to_x); + int dy = MIN((int)height - 1, to_y); //print_line(itos(j) + " - " + Vector2i(sx, sy) + " -> " + Vector2i(dx, dy)); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index f029cddc79..e3c3cdf0bf 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp @@ -1409,7 +1409,7 @@ void RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_r } if (p_reflection_probe_cull_count) { - RD::get_singleton()->buffer_update(scene_state.reflection_buffer, 0, MIN(scene_state.max_reflections, p_reflection_probe_cull_count) * sizeof(ReflectionData), scene_state.reflections, true); + RD::get_singleton()->buffer_update(scene_state.reflection_buffer, 0, MIN(scene_state.max_reflections, (unsigned int)p_reflection_probe_cull_count) * sizeof(ReflectionData), scene_state.reflections, true); } } @@ -1566,10 +1566,10 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.attenuation_energy[0] = Math::make_half_float(storage->light_get_param(base, VS::LIGHT_PARAM_ATTENUATION)); light_data.attenuation_energy[1] = Math::make_half_float(sign * storage->light_get_param(base, VS::LIGHT_PARAM_ENERGY) * Math_PI); - light_data.color_specular[0] = CLAMP(uint32_t(linear_col.r * 255), 0, 255); - light_data.color_specular[1] = CLAMP(uint32_t(linear_col.g * 255), 0, 255); - light_data.color_specular[2] = CLAMP(uint32_t(linear_col.b * 255), 0, 255); - light_data.color_specular[3] = CLAMP(uint32_t(storage->light_get_param(base, VS::LIGHT_PARAM_SPECULAR) * 255), 0, 255); + light_data.color_specular[0] = MIN(uint32_t(linear_col.r * 255), 255); + light_data.color_specular[1] = MIN(uint32_t(linear_col.g * 255), 255); + light_data.color_specular[2] = MIN(uint32_t(linear_col.b * 255), 255); + light_data.color_specular[3] = MIN(uint32_t(storage->light_get_param(base, VS::LIGHT_PARAM_SPECULAR) * 255), 255); float radius = MAX(0.001, storage->light_get_param(base, VS::LIGHT_PARAM_RANGE)); light_data.inv_radius = 1.0 / radius; @@ -1595,9 +1595,9 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig Color shadow_color = storage->light_get_shadow_color(base); bool has_shadow = p_using_shadows && storage->light_has_shadow(base); - light_data.shadow_color_enabled[0] = CLAMP(uint32_t(shadow_color.r * 255), 0, 255); - light_data.shadow_color_enabled[1] = CLAMP(uint32_t(shadow_color.g * 255), 0, 255); - light_data.shadow_color_enabled[2] = CLAMP(uint32_t(shadow_color.b * 255), 0, 255); + light_data.shadow_color_enabled[0] = MIN(uint32_t(shadow_color.r * 255), 255); + light_data.shadow_color_enabled[1] = MIN(uint32_t(shadow_color.g * 255), 255); + light_data.shadow_color_enabled[2] = MIN(uint32_t(shadow_color.b * 255), 255); light_data.shadow_color_enabled[3] = has_shadow ? 255 : 0; light_data.atlas_rect[0] = 0; @@ -1821,7 +1821,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor case VS::ENV_BG_SKY: { RID sky = environment_get_sky(p_environment); if (sky.is_valid()) { - radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, radiance_uniform_set, RADIANCE_UNIFORM_SET); + radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, default_shader_rd, RADIANCE_UNIFORM_SET); draw_sky = true; } } break; @@ -2690,6 +2690,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag } RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() { + directional_shadow_atlas_set_size(0); + //clear base uniform set if still valid if (view_dependant_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(view_dependant_uniform_set)) { RD::get_singleton()->free(view_dependant_uniform_set); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp index e95b7c0b2a..317ffb994f 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp @@ -3125,8 +3125,6 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { } RasterizerSceneRD::~RasterizerSceneRD() { - directional_shadow_atlas_set_size(0); - for (Map<Vector2i, ShadowMap>::Element *E = shadow_maps.front(); E; E = E->next()) { RD::get_singleton()->free(E->get().depth); } diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp index c92400c188..4a3960be1c 100644 --- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp @@ -1958,7 +1958,7 @@ VS::BlendShapeMode RasterizerStorageRD::mesh_get_blend_shape_mode(RID p_mesh) co void RasterizerStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector<uint8_t> &p_data) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); - ERR_FAIL_INDEX((uint32_t)p_surface, mesh->surface_count); + ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); ERR_FAIL_COND(p_data.size() == 0); uint64_t data_size = p_data.size(); PoolVector<uint8_t>::Read r = p_data.read(); @@ -1969,7 +1969,7 @@ void RasterizerStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, void RasterizerStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); - ERR_FAIL_INDEX((uint32_t)p_surface, mesh->surface_count); + ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); mesh->surfaces[p_surface]->material = p_material; mesh->instance_dependency.instance_notify_changed(false, true); @@ -1978,7 +1978,7 @@ void RasterizerStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, R RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RID()); - ERR_FAIL_INDEX_V((uint32_t)p_surface, mesh->surface_count, RID()); + ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RID()); return mesh->surfaces[p_surface]->material; } @@ -1987,7 +1987,7 @@ VS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface) Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, VS::SurfaceData()); - ERR_FAIL_INDEX_V((uint32_t)p_surface, mesh->surface_count, VS::SurfaceData()); + ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, VS::SurfaceData()); Mesh::Surface &s = *mesh->surfaces[p_surface]; @@ -2468,7 +2468,7 @@ void RasterizerStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_inde uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE; #ifdef DEBUG_ENABLED uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; - ERR_FAIL_INDEX(region_index, data_cache_dirty_region_count); //bug + ERR_FAIL_UNSIGNED_INDEX(region_index, data_cache_dirty_region_count); //bug #endif if (!multimesh->data_cache_dirty_regions[region_index]) { multimesh->data_cache_dirty_regions[p_index] = true; @@ -3581,7 +3581,7 @@ void RasterizerStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_t uint32_t cell_count = p_octree_cells.size() / 32; - ERR_FAIL_COND(p_data_cells.size() != cell_count * 16); //see that data size matches + ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches gi_probe->cell_count = cell_count; gi_probe->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells); diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h index 7ab8b904ad..055737d65d 100644 --- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h @@ -657,7 +657,7 @@ public: _FORCE_INLINE_ VS::PrimitiveType mesh_surface_get_primitive(RID p_mesh, uint32_t p_surface_index) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, VS::PRIMITIVE_MAX); - ERR_FAIL_INDEX_V(p_surface_index, mesh->surface_count, VS::PRIMITIVE_MAX); + ERR_FAIL_UNSIGNED_INDEX_V(p_surface_index, mesh->surface_count, VS::PRIMITIVE_MAX); return mesh->surfaces[p_surface_index]->primitive; } @@ -665,7 +665,7 @@ public: _FORCE_INLINE_ void mesh_surface_get_arrays_and_format(RID p_mesh, uint32_t p_surface_index, uint32_t p_input_mask, RID &r_vertex_array_rd, RID &r_index_array_rd, RD::VertexFormatID &r_vertex_format) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); - ERR_FAIL_INDEX(p_surface_index, mesh->surface_count); + ERR_FAIL_UNSIGNED_INDEX(p_surface_index, mesh->surface_count); Mesh::Surface *s = mesh->surfaces[p_surface_index]; diff --git a/servers/visual/rendering_device.cpp b/servers/visual/rendering_device.cpp index dab936d9a9..d7c88d5671 100644 --- a/servers/visual/rendering_device.cpp +++ b/servers/visual/rendering_device.cpp @@ -60,9 +60,5 @@ PoolVector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_st } RenderingDevice::RenderingDevice() { - - ShaderCompileFunction compile_function; - ShaderCacheFunction cache_function; - singleton = this; } diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 6166489302..734abd7365 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -2708,31 +2708,43 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform pi.hint = PROPERTY_HINT_RESOURCE_TYPE; pi.hint_string = "CubeMap"; } break; + case ShaderLanguage::TYPE_STRUCT: { + // FIXME: Implement this. + } break; } return pi; } uint32_t ShaderLanguage::get_type_size(DataType p_type) { switch (p_type) { + case TYPE_VOID: + return 0; case TYPE_BOOL: case TYPE_INT: case TYPE_UINT: - case TYPE_FLOAT: return 4; + case TYPE_FLOAT: + return 4; case TYPE_BVEC2: case TYPE_IVEC2: case TYPE_UVEC2: - case TYPE_VEC2: return 8; + case TYPE_VEC2: + return 8; case TYPE_BVEC3: case TYPE_IVEC3: case TYPE_UVEC3: - case TYPE_VEC3: return 12; + case TYPE_VEC3: + return 12; case TYPE_BVEC4: case TYPE_IVEC4: case TYPE_UVEC4: - case TYPE_VEC4: return 16; - case TYPE_MAT2: return 8; - case TYPE_MAT3: return 12; - case TYPE_MAT4: return 16; + case TYPE_VEC4: + return 16; + case TYPE_MAT2: + return 8; + case TYPE_MAT3: + return 12; + case TYPE_MAT4: + return 16; case TYPE_SAMPLER2D: case TYPE_ISAMPLER2D: case TYPE_USAMPLER2D: @@ -2742,7 +2754,11 @@ uint32_t ShaderLanguage::get_type_size(DataType p_type) { case TYPE_SAMPLER3D: case TYPE_ISAMPLER3D: case TYPE_USAMPLER3D: - case TYPE_SAMPLERCUBE: return 4; //not really, but useful for indices + case TYPE_SAMPLERCUBE: + return 4; //not really, but useful for indices + case TYPE_STRUCT: + // FIXME: Implement. + return 0; } return 0; } @@ -6273,6 +6289,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } + if (qualifier == ARGUMENT_QUALIFIER_OUT || qualifier == ARGUMENT_QUALIFIER_INOUT) { + if (is_sampler_type(get_token_datatype(tk.type))) { + _set_error("Opaque types cannot be output parameters."); + return ERR_PARSE_ERROR; + } + } + if (is_struct) { ptype = TYPE_STRUCT; } else { diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 6599b9a2d2..b27c01cccc 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -139,7 +139,7 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) { uint64_t base_cpu = VSG::storage->get_captured_timestamp_cpu_time(0); uint64_t base_gpu = VSG::storage->get_captured_timestamp_gpu_time(0); - for (int i = 0; i < VSG::storage->get_captured_timestamps_count(); i++) { + for (uint32_t i = 0; i < VSG::storage->get_captured_timestamps_count(); i++) { uint64_t time_cpu = VSG::storage->get_captured_timestamp_cpu_time(i) - base_cpu; uint64_t time_gpu = VSG::storage->get_captured_timestamp_gpu_time(i) - base_gpu; new_profile.write[i].gpu_msec = float(time_gpu / 1000) / 1000.0; diff --git a/thirdparty/README.md b/thirdparty/README.md index f77f573221..934d719ca6 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -16,7 +16,7 @@ Subcategories (`###` level) where needed are separated by a single empty line. ## basis_universal - Upstream: https://github.com/BinomialLLC/basis_universal -- Version: git (6afb2fc, 2019) +- Version: git (895ee8e, 2020) - License: Apache 2.0 Files extracted from upstream source: diff --git a/thirdparty/basis_universal/basisu_backend.cpp b/thirdparty/basis_universal/basisu_backend.cpp index ef1a5c378a..3a689e58d7 100644 --- a/thirdparty/basis_universal/basisu_backend.cpp +++ b/thirdparty/basis_universal/basisu_backend.cpp @@ -597,7 +597,7 @@ namespace basisu const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y; gpu_image gi; - gi.init(cETC1, width, height); + gi.init(texture_format::cETC1, width, height); for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) { diff --git a/thirdparty/basis_universal/basisu_basis_file.cpp b/thirdparty/basis_universal/basisu_basis_file.cpp index 81e0be3b78..3e6b1906b9 100644 --- a/thirdparty/basis_universal/basisu_basis_file.cpp +++ b/thirdparty/basis_universal/basisu_basis_file.cpp @@ -32,7 +32,7 @@ namespace basisu for (uint32_t i = 0; i < encoder_output.m_slice_desc.size(); i++) m_header.m_total_images = maximum<uint32_t>(m_header.m_total_images, encoder_output.m_slice_desc[i].m_source_file_index + 1); - m_header.m_format = basist::cETC1; + m_header.m_format = 0;// basist::block_format::cETC1; m_header.m_flags = 0; if (encoder_output.m_etc1s) diff --git a/thirdparty/basis_universal/basisu_comp.cpp b/thirdparty/basis_universal/basisu_comp.cpp index b6765884bc..1e4679311c 100644 --- a/thirdparty/basis_universal/basisu_comp.cpp +++ b/thirdparty/basis_universal/basisu_comp.cpp @@ -57,7 +57,7 @@ namespace basisu PRINT_BOOL_VALUE(m_debug); PRINT_BOOL_VALUE(m_debug_images); PRINT_BOOL_VALUE(m_global_sel_pal); - PRINT_BOOL_VALUE(m_no_auto_global_sel_pal); + PRINT_BOOL_VALUE(m_auto_global_sel_pal); PRINT_BOOL_VALUE(m_compression_level); PRINT_BOOL_VALUE(m_no_hybrid_sel_cb); PRINT_BOOL_VALUE(m_perceptual); @@ -774,7 +774,7 @@ namespace basisu } m_auto_global_sel_pal = false; - if (!m_params.m_global_sel_pal && !m_params.m_no_auto_global_sel_pal) + if (!m_params.m_global_sel_pal && m_params.m_auto_global_sel_pal) { const float bits_per_selector_cluster = 31.0f; double selector_codebook_bpp_est = (bits_per_selector_cluster * selector_clusters) / total_texels; @@ -860,7 +860,7 @@ namespace basisu const uint32_t width = num_blocks_x * 4; const uint32_t height = num_blocks_y * 4; - m_frontend_output_textures[i].init(cETC1, width, height); + m_frontend_output_textures[i].init(texture_format::cETC1, width, height); for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) @@ -875,7 +875,7 @@ namespace basisu } #endif - m_best_etc1s_images[i].init(cETC1, width, height); + m_best_etc1s_images[i].init(texture_format::cETC1, width, height); for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) memcpy(m_best_etc1s_images[i].get_block_ptr(block_x, block_y, 0), &m_frontend.get_etc1s_block(slice_desc.m_first_block_index + block_x + block_y * num_blocks_x), sizeof(etc_block)); @@ -970,12 +970,12 @@ namespace basisu for (uint32_t i = 0; i < m_slice_descs.size(); i++) { gpu_image decoded_texture; - decoded_texture.init(cETC1, m_slice_descs[i].m_width, m_slice_descs[i].m_height); + decoded_texture.init(texture_format::cETC1, m_slice_descs[i].m_width, m_slice_descs[i].m_height); tm.start(); if (!decoder.transcode_slice(&comp_data[0], (uint32_t)comp_data.size(), i, - reinterpret_cast<etc_block *>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, basist::cETC1, 8)) + reinterpret_cast<etc_block *>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, basist::block_format::cETC1, 8)) { error_printf("Transcoding failed to ETC1 on slice %u!\n", i); return false; @@ -1008,12 +1008,12 @@ namespace basisu for (uint32_t i = 0; i < m_slice_descs.size(); i++) { gpu_image decoded_texture; - decoded_texture.init(cBC1, m_slice_descs[i].m_width, m_slice_descs[i].m_height); + decoded_texture.init(texture_format::cBC1, m_slice_descs[i].m_width, m_slice_descs[i].m_height); tm.start(); if (!decoder.transcode_slice(&comp_data[0], (uint32_t)comp_data.size(), i, - reinterpret_cast<etc_block *>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, basist::cBC1, 8)) + reinterpret_cast<etc_block *>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, basist::block_format::cBC1, 8)) { error_printf("Transcoding failed to BC1 on slice %u!\n", i); return false; @@ -1066,9 +1066,7 @@ namespace basisu { const uint8_vec &comp_data = m_basis_file.get_compressed_data(); - std::string basis_filename(m_params.m_out_filename); - string_remove_extension(basis_filename); - basis_filename += ".basis"; + const std::string& basis_filename = m_params.m_out_filename; if (!write_vec_to_file(basis_filename.c_str(), comp_data)) { diff --git a/thirdparty/basis_universal/basisu_comp.h b/thirdparty/basis_universal/basisu_comp.h index affbbd9632..1c201ddbed 100644 --- a/thirdparty/basis_universal/basisu_comp.h +++ b/thirdparty/basis_universal/basisu_comp.h @@ -207,7 +207,7 @@ namespace basisu m_debug.clear(); m_debug_images.clear(); m_global_sel_pal.clear(); - m_no_auto_global_sel_pal.clear(); + m_auto_global_sel_pal.clear(); m_no_hybrid_sel_cb.clear(); m_perceptual.clear(); m_no_selector_rdo.clear(); @@ -279,7 +279,7 @@ namespace basisu param<int> m_compression_level; bool_param<false> m_global_sel_pal; - bool_param<false> m_no_auto_global_sel_pal; + bool_param<false> m_auto_global_sel_pal; // Frontend/backend codec parameters bool_param<false> m_no_hybrid_sel_cb; diff --git a/thirdparty/basis_universal/basisu_enc.h b/thirdparty/basis_universal/basisu_enc.h index e0ebfa3c03..c2b9133045 100644 --- a/thirdparty/basis_universal/basisu_enc.h +++ b/thirdparty/basis_universal/basisu_enc.h @@ -1070,7 +1070,7 @@ namespace basisu assert(node.is_leaf()); var_heap.delete_top(); - + if (node.m_training_vecs.size() > 1) { if (split_node(node_index, var_heap, l_children, r_children)) @@ -1197,11 +1197,11 @@ namespace basisu } if ((l_child.m_var > 0.0f) && (l_child.m_training_vecs.size() > 1)) - var_heap.add_heap(l_child_index, l_var); - + var_heap.add_heap(l_child_index, l_child.m_var); + if ((r_child.m_var > 0.0f) && (r_child.m_training_vecs.size() > 1)) - var_heap.add_heap(r_child_index, r_var); - + var_heap.add_heap(r_child_index, r_child.m_var); + return true; } diff --git a/thirdparty/basis_universal/basisu_frontend.cpp b/thirdparty/basis_universal/basisu_frontend.cpp index 06a8eb4e87..6f7a9bf889 100644 --- a/thirdparty/basis_universal/basisu_frontend.cpp +++ b/thirdparty/basis_universal/basisu_frontend.cpp @@ -343,6 +343,7 @@ namespace basisu cur_blk.set_block_color5_etc1s(get_endpoint_cluster_unscaled_color(endpoint_cluster_index, false)); cur_blk.set_inten_tables_etc1s(get_endpoint_cluster_inten_table(endpoint_cluster_index, false)); cur_blk.set_raw_selector_bits(get_selector_cluster_selector_bits(old_selector_cluster_index).get_raw_selector_bits()); + cur_blk.set_flip_bit(true); const uint64_t cur_err = cur_blk.evaluate_etc1_error(get_source_pixel_block(block_index).get_ptr(), m_params.m_perceptual); @@ -2385,7 +2386,7 @@ namespace basisu void basisu_frontend::dump_debug_image(const char *pFilename, uint32_t first_block, uint32_t num_blocks_x, uint32_t num_blocks_y, bool output_blocks) { gpu_image g; - g.init(cETC1, num_blocks_x * 4, num_blocks_y * 4); + g.init(texture_format::cETC1, num_blocks_x * 4, num_blocks_y * 4); for (uint32_t y = 0; y < num_blocks_y; y++) { diff --git a/thirdparty/basis_universal/basisu_gpu_texture.cpp b/thirdparty/basis_universal/basisu_gpu_texture.cpp index d1d1018163..117668c5e2 100644 --- a/thirdparty/basis_universal/basisu_gpu_texture.cpp +++ b/thirdparty/basis_universal/basisu_gpu_texture.cpp @@ -596,33 +596,375 @@ namespace basisu return true; } + + struct fxt1_block + { + union + { + struct + { + uint64_t m_t00 : 2; + uint64_t m_t01 : 2; + uint64_t m_t02 : 2; + uint64_t m_t03 : 2; + uint64_t m_t04 : 2; + uint64_t m_t05 : 2; + uint64_t m_t06 : 2; + uint64_t m_t07 : 2; + uint64_t m_t08 : 2; + uint64_t m_t09 : 2; + uint64_t m_t10 : 2; + uint64_t m_t11 : 2; + uint64_t m_t12 : 2; + uint64_t m_t13 : 2; + uint64_t m_t14 : 2; + uint64_t m_t15 : 2; + uint64_t m_t16 : 2; + uint64_t m_t17 : 2; + uint64_t m_t18 : 2; + uint64_t m_t19 : 2; + uint64_t m_t20 : 2; + uint64_t m_t21 : 2; + uint64_t m_t22 : 2; + uint64_t m_t23 : 2; + uint64_t m_t24 : 2; + uint64_t m_t25 : 2; + uint64_t m_t26 : 2; + uint64_t m_t27 : 2; + uint64_t m_t28 : 2; + uint64_t m_t29 : 2; + uint64_t m_t30 : 2; + uint64_t m_t31 : 2; + } m_lo; + uint64_t m_lo_bits; + uint8_t m_sels[8]; + }; + + union + { + struct + { +#ifdef BASISU_USE_ORIGINAL_3DFX_FXT1_ENCODING + // This is the format that 3DFX's DECOMP.EXE tool expects, which I'm assuming is what the actual 3DFX hardware wanted. + // Unfortunately, color0/color1 and color2/color3 are flipped relative to the official OpenGL extension and Intel's documentation! + uint64_t m_b1 : 5; + uint64_t m_g1 : 5; + uint64_t m_r1 : 5; + uint64_t m_b0 : 5; + uint64_t m_g0 : 5; + uint64_t m_r0 : 5; + uint64_t m_b3 : 5; + uint64_t m_g3 : 5; + uint64_t m_r3 : 5; + uint64_t m_b2 : 5; + uint64_t m_g2 : 5; + uint64_t m_r2 : 5; +#else + // Intel's encoding, and the encoding in the OpenGL FXT1 spec. + uint64_t m_b0 : 5; + uint64_t m_g0 : 5; + uint64_t m_r0 : 5; + uint64_t m_b1 : 5; + uint64_t m_g1 : 5; + uint64_t m_r1 : 5; + uint64_t m_b2 : 5; + uint64_t m_g2 : 5; + uint64_t m_r2 : 5; + uint64_t m_b3 : 5; + uint64_t m_g3 : 5; + uint64_t m_r3 : 5; +#endif + uint64_t m_alpha : 1; + uint64_t m_glsb : 2; + uint64_t m_mode : 1; + } m_hi; + + uint64_t m_hi_bits; + }; + }; + + static color_rgba expand_565(const color_rgba& c) + { + return color_rgba((c.r << 3) | (c.r >> 2), (c.g << 2) | (c.g >> 4), (c.b << 3) | (c.b >> 2), 255); + } + + // We only support CC_MIXED non-alpha blocks here because that's the only mode the transcoder uses at the moment. + bool unpack_fxt1(const void *p, color_rgba *pPixels) + { + const fxt1_block* pBlock = static_cast<const fxt1_block*>(p); + + if (pBlock->m_hi.m_mode == 0) + return false; + if (pBlock->m_hi.m_alpha == 1) + return false; + + color_rgba colors[4]; + + colors[0].r = pBlock->m_hi.m_r0; + colors[0].g = (uint8_t)((pBlock->m_hi.m_g0 << 1) | ((pBlock->m_lo.m_t00 >> 1) ^ (pBlock->m_hi.m_glsb & 1))); + colors[0].b = pBlock->m_hi.m_b0; + colors[0].a = 255; + + colors[1].r = pBlock->m_hi.m_r1; + colors[1].g = (uint8_t)((pBlock->m_hi.m_g1 << 1) | (pBlock->m_hi.m_glsb & 1)); + colors[1].b = pBlock->m_hi.m_b1; + colors[1].a = 255; + + colors[2].r = pBlock->m_hi.m_r2; + colors[2].g = (uint8_t)((pBlock->m_hi.m_g2 << 1) | ((pBlock->m_lo.m_t16 >> 1) ^ (pBlock->m_hi.m_glsb >> 1))); + colors[2].b = pBlock->m_hi.m_b2; + colors[2].a = 255; + + colors[3].r = pBlock->m_hi.m_r3; + colors[3].g = (uint8_t)((pBlock->m_hi.m_g3 << 1) | (pBlock->m_hi.m_glsb >> 1)); + colors[3].b = pBlock->m_hi.m_b3; + colors[3].a = 255; + + for (uint32_t i = 0; i < 4; i++) + colors[i] = expand_565(colors[i]); + + color_rgba block0_colors[4]; + block0_colors[0] = colors[0]; + block0_colors[1] = color_rgba((colors[0].r * 2 + colors[1].r + 1) / 3, (colors[0].g * 2 + colors[1].g + 1) / 3, (colors[0].b * 2 + colors[1].b + 1) / 3, 255); + block0_colors[2] = color_rgba((colors[1].r * 2 + colors[0].r + 1) / 3, (colors[1].g * 2 + colors[0].g + 1) / 3, (colors[1].b * 2 + colors[0].b + 1) / 3, 255); + block0_colors[3] = colors[1]; + + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t sel = (pBlock->m_sels[i >> 2] >> ((i & 3) * 2)) & 3; + + const uint32_t x = i & 3; + const uint32_t y = i >> 2; + pPixels[x + y * 8] = block0_colors[sel]; + } + + color_rgba block1_colors[4]; + block1_colors[0] = colors[2]; + block1_colors[1] = color_rgba((colors[2].r * 2 + colors[3].r + 1) / 3, (colors[2].g * 2 + colors[3].g + 1) / 3, (colors[2].b * 2 + colors[3].b + 1) / 3, 255); + block1_colors[2] = color_rgba((colors[3].r * 2 + colors[2].r + 1) / 3, (colors[3].g * 2 + colors[2].g + 1) / 3, (colors[3].b * 2 + colors[2].b + 1) / 3, 255); + block1_colors[3] = colors[3]; + + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t sel = (pBlock->m_sels[4 + (i >> 2)] >> ((i & 3) * 2)) & 3; + + const uint32_t x = i & 3; + const uint32_t y = i >> 2; + pPixels[4 + x + y * 8] = block1_colors[sel]; + } + + return true; + } + + struct pvrtc2_block + { + uint8_t m_modulation[4]; + + union + { + union + { + // Opaque mode: RGB colora=554 and colorb=555 + struct + { + uint32_t m_mod_flag : 1; + uint32_t m_blue_a : 4; + uint32_t m_green_a : 5; + uint32_t m_red_a : 5; + uint32_t m_hard_flag : 1; + uint32_t m_blue_b : 5; + uint32_t m_green_b : 5; + uint32_t m_red_b : 5; + uint32_t m_opaque_flag : 1; + + } m_opaque_color_data; + + // Transparent mode: RGBA colora=4433 and colorb=4443 + struct + { + uint32_t m_mod_flag : 1; + uint32_t m_blue_a : 3; + uint32_t m_green_a : 4; + uint32_t m_red_a : 4; + uint32_t m_alpha_a : 3; + uint32_t m_hard_flag : 1; + uint32_t m_blue_b : 4; + uint32_t m_green_b : 4; + uint32_t m_red_b : 4; + uint32_t m_alpha_b : 3; + uint32_t m_opaque_flag : 1; + + } m_trans_color_data; + }; + + uint32_t m_color_data_bits; + }; + }; + + static color_rgba convert_rgb_555_to_888(const color_rgba& col) + { + return color_rgba((col[0] << 3) | (col[0] >> 2), (col[1] << 3) | (col[1] >> 2), (col[2] << 3) | (col[2] >> 2), 255); + } + + static color_rgba convert_rgba_5554_to_8888(const color_rgba& col) + { + return color_rgba((col[0] << 3) | (col[0] >> 2), (col[1] << 3) | (col[1] >> 2), (col[2] << 3) | (col[2] >> 2), (col[3] << 4) | col[3]); + } + + // PVRTC2 is currently limited to only what our transcoder outputs (non-interpolated, hard_flag=1 modulation=0). In this mode, PVRTC2 looks much like BC1/ATC. + bool unpack_pvrtc2(const void *p, color_rgba *pPixels) + { + const pvrtc2_block* pBlock = static_cast<const pvrtc2_block*>(p); + + if ((!pBlock->m_opaque_color_data.m_hard_flag) || (pBlock->m_opaque_color_data.m_mod_flag)) + { + // This mode isn't supported by the transcoder, so we aren't bothering with it here. + return false; + } + + color_rgba colors[4]; + + if (pBlock->m_opaque_color_data.m_opaque_flag) + { + // colora=554 + color_rgba color_a(pBlock->m_opaque_color_data.m_red_a, pBlock->m_opaque_color_data.m_green_a, (pBlock->m_opaque_color_data.m_blue_a << 1) | (pBlock->m_opaque_color_data.m_blue_a >> 3), 255); + + // colora=555 + color_rgba color_b(pBlock->m_opaque_color_data.m_red_b, pBlock->m_opaque_color_data.m_green_b, pBlock->m_opaque_color_data.m_blue_b, 255); + + colors[0] = convert_rgb_555_to_888(color_a); + colors[3] = convert_rgb_555_to_888(color_b); + + colors[1].set((colors[0].r * 5 + colors[3].r * 3) / 8, (colors[0].g * 5 + colors[3].g * 3) / 8, (colors[0].b * 5 + colors[3].b * 3) / 8, 255); + colors[2].set((colors[0].r * 3 + colors[3].r * 5) / 8, (colors[0].g * 3 + colors[3].g * 5) / 8, (colors[0].b * 3 + colors[3].b * 5) / 8, 255); + } + else + { + // colora=4433 + color_rgba color_a( + (pBlock->m_trans_color_data.m_red_a << 1) | (pBlock->m_trans_color_data.m_red_a >> 3), + (pBlock->m_trans_color_data.m_green_a << 1) | (pBlock->m_trans_color_data.m_green_a >> 3), + (pBlock->m_trans_color_data.m_blue_a << 2) | (pBlock->m_trans_color_data.m_blue_a >> 1), + pBlock->m_trans_color_data.m_alpha_a << 1); + + //colorb=4443 + color_rgba color_b( + (pBlock->m_trans_color_data.m_red_b << 1) | (pBlock->m_trans_color_data.m_red_b >> 3), + (pBlock->m_trans_color_data.m_green_b << 1) | (pBlock->m_trans_color_data.m_green_b >> 3), + (pBlock->m_trans_color_data.m_blue_b << 1) | (pBlock->m_trans_color_data.m_blue_b >> 3), + (pBlock->m_trans_color_data.m_alpha_b << 1) | 1); + + colors[0] = convert_rgba_5554_to_8888(color_a); + colors[3] = convert_rgba_5554_to_8888(color_b); + } + + colors[1].set((colors[0].r * 5 + colors[3].r * 3) / 8, (colors[0].g * 5 + colors[3].g * 3) / 8, (colors[0].b * 5 + colors[3].b * 3) / 8, (colors[0].a * 5 + colors[3].a * 3) / 8); + colors[2].set((colors[0].r * 3 + colors[3].r * 5) / 8, (colors[0].g * 3 + colors[3].g * 5) / 8, (colors[0].b * 3 + colors[3].b * 5) / 8, (colors[0].a * 3 + colors[3].a * 5) / 8); + + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t sel = (pBlock->m_modulation[i >> 2] >> ((i & 3) * 2)) & 3; + pPixels[i] = colors[sel]; + } + + return true; + } + + struct etc2_eac_r11 + { + uint64_t m_base : 8; + uint64_t m_table : 4; + uint64_t m_mul : 4; + uint64_t m_sels_0 : 8; + uint64_t m_sels_1 : 8; + uint64_t m_sels_2 : 8; + uint64_t m_sels_3 : 8; + uint64_t m_sels_4 : 8; + uint64_t m_sels_5 : 8; + + uint64_t get_sels() const + { + return ((uint64_t)m_sels_0 << 40U) | ((uint64_t)m_sels_1 << 32U) | ((uint64_t)m_sels_2 << 24U) | ((uint64_t)m_sels_3 << 16U) | ((uint64_t)m_sels_4 << 8U) | m_sels_5; + } + + void set_sels(uint64_t v) + { + m_sels_0 = (v >> 40U) & 0xFF; + m_sels_1 = (v >> 32U) & 0xFF; + m_sels_2 = (v >> 24U) & 0xFF; + m_sels_3 = (v >> 16U) & 0xFF; + m_sels_4 = (v >> 8U) & 0xFF; + m_sels_5 = v & 0xFF; + } + }; + + struct etc2_eac_rg11 + { + etc2_eac_r11 m_c[2]; + }; + + static void unpack_etc2_eac_r(const etc2_eac_r11* p, color_rgba* pPixels, uint32_t c) + { + const uint64_t sels = p->get_sels(); + + const int base = (int)p->m_base * 8 + 4; + const int mul = p->m_mul ? ((int)p->m_mul * 8) : 1; + const int table = (int)p->m_table; + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t shift = 45 - ((y + x * 4) * 3); + + const uint32_t sel = (uint32_t)((sels >> shift) & 7); + + int val = base + g_etc2_eac_tables[table][sel] * mul; + val = clamp<int>(val, 0, 2047); + + // Convert to 8-bits with rounding + pPixels[x + y * 4].m_comps[c] = static_cast<uint8_t>((val * 255 + 1024) / 2047); + + } // x + } // y + } + + void unpack_etc2_eac_rg(const void* p, color_rgba* pPixels) + { + for (uint32_t c = 0; c < 2; c++) + { + const etc2_eac_r11* pBlock = &static_cast<const etc2_eac_rg11*>(p)->m_c[c]; + + unpack_etc2_eac_r(pBlock, pPixels, c); + } + } // Unpacks to RGBA, R, RG, or A bool unpack_block(texture_format fmt, const void* pBlock, color_rgba* pPixels) { switch (fmt) { - case cBC1: + case texture_format::cBC1: { unpack_bc1(pBlock, pPixels, true); break; } - case cBC3: + case texture_format::cBC3: { return unpack_bc3(pBlock, pPixels); } - case cBC4: + case texture_format::cBC4: { // Unpack to R unpack_bc4(pBlock, &pPixels[0].r, sizeof(color_rgba)); break; } - case cBC5: + case texture_format::cBC5: { unpack_bc5(pBlock, pPixels); break; } - case cBC7: + case texture_format::cBC7: { // We only support modes 5 and 6. if (!unpack_bc7_mode5(pBlock, pPixels)) @@ -634,42 +976,62 @@ namespace basisu break; } // Full ETC2 color blocks (planar/T/H modes) is currently unsupported in basisu, but we do support ETC2 with alpha (using ETC1 for color) - case cETC2_RGB: - case cETC1: - case cETC1S: + case texture_format::cETC2_RGB: + case texture_format::cETC1: + case texture_format::cETC1S: { return unpack_etc1(*static_cast<const etc_block*>(pBlock), pPixels); } - case cETC2_RGBA: + case texture_format::cETC2_RGBA: { if (!unpack_etc1(static_cast<const etc_block*>(pBlock)[1], pPixels)) return false; unpack_etc2_eac(pBlock, pPixels); break; } - case cETC2_ALPHA: + case texture_format::cETC2_ALPHA: { // Unpack to A unpack_etc2_eac(pBlock, pPixels); break; } - case cASTC4x4: + case texture_format::cASTC4x4: { const bool astc_srgb = false; basisu_astc::astc::decompress(reinterpret_cast<uint8_t*>(pPixels), static_cast<const uint8_t*>(pBlock), astc_srgb, 4, 4); break; } - case cATC_RGB: + case texture_format::cATC_RGB: { unpack_atc(pBlock, pPixels); break; } - case cATC_RGBA_INTERPOLATED_ALPHA: + case texture_format::cATC_RGBA_INTERPOLATED_ALPHA: { unpack_atc(static_cast<const uint8_t*>(pBlock) + 8, pPixels); unpack_bc4(pBlock, &pPixels[0].a, sizeof(color_rgba)); break; } + case texture_format::cFXT1_RGB: + { + unpack_fxt1(pBlock, pPixels); + break; + } + case texture_format::cPVRTC2_4_RGBA: + { + unpack_pvrtc2(pBlock, pPixels); + break; + } + case texture_format::cETC2_R11_EAC: + { + unpack_etc2_eac_r(static_cast<const etc2_eac_r11 *>(pBlock), pPixels, 0); + break; + } + case texture_format::cETC2_RG11_EAC: + { + unpack_etc2_eac_rg(pBlock, pPixels); + break; + } default: { assert(0); @@ -680,7 +1042,7 @@ namespace basisu return true; } - bool gpu_image::unpack(image& img, bool pvrtc_wrap_addressing) const + bool gpu_image::unpack(image& img) const { img.resize(get_pixel_width(), get_pixel_height()); img.set_all(g_black_color); @@ -688,9 +1050,9 @@ namespace basisu if (!img.get_width() || !img.get_height()) return true; - if ((m_fmt == cPVRTC1_4_RGB) || (m_fmt == cPVRTC1_4_RGBA)) + if ((m_fmt == texture_format::cPVRTC1_4_RGB) || (m_fmt == texture_format::cPVRTC1_4_RGBA)) { - pvrtc4_image pi(m_width, m_height, pvrtc_wrap_addressing); + pvrtc4_image pi(m_width, m_height); if (get_total_blocks() != pi.get_total_blocks()) return false; @@ -704,6 +1066,7 @@ namespace basisu return true; } + assert((m_block_width <= cMaxBlockSize) && (m_block_height <= cMaxBlockSize)); color_rgba pixels[cMaxBlockSize * cMaxBlockSize]; for (uint32_t i = 0; i < cMaxBlockSize * cMaxBlockSize; i++) pixels[i] = g_black_color; @@ -751,7 +1114,12 @@ namespace basisu KTX_COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0, KTX_ATC_RGB_AMD = 0x8C92, - KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD = 0x87EE + KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD = 0x87EE, + KTX_COMPRESSED_RGB_FXT1_3DFX = 0x86B0, + KTX_COMPRESSED_RGBA_FXT1_3DFX = 0x86B1, + KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG = 0x9138, + KTX_COMPRESSED_R11_EAC = 0x9270, + KTX_COMPRESSED_RG11_EAC = 0x9272 }; struct ktx_header @@ -784,7 +1152,7 @@ namespace basisu } uint32_t width = 0, height = 0, total_levels = 0; - basisu::texture_format fmt = cInvalidTextureFormat; + basisu::texture_format fmt = texture_format::cInvalidTextureFormat; if (cubemap_flag) { @@ -851,80 +1219,103 @@ namespace basisu switch (fmt) { - case cBC1: + case texture_format::cBC1: { internal_fmt = KTX_COMPRESSED_RGB_S3TC_DXT1_EXT; break; } - case cBC3: + case texture_format::cBC3: { internal_fmt = KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT; base_internal_fmt = KTX_RGBA; break; } - case cBC4: + case texture_format::cBC4: { internal_fmt = KTX_COMPRESSED_RED_RGTC1_EXT;// KTX_COMPRESSED_LUMINANCE_LATC1_EXT; base_internal_fmt = KTX_RED; break; } - case cBC5: + case texture_format::cBC5: { internal_fmt = KTX_COMPRESSED_RED_GREEN_RGTC2_EXT; base_internal_fmt = KTX_RG; break; } - case cETC1: - case cETC1S: + case texture_format::cETC1: + case texture_format::cETC1S: { internal_fmt = KTX_ETC1_RGB8_OES; break; } - case cETC2_RGB: + case texture_format::cETC2_RGB: { internal_fmt = KTX_COMPRESSED_RGB8_ETC2; break; } - case cETC2_RGBA: + case texture_format::cETC2_RGBA: { internal_fmt = KTX_COMPRESSED_RGBA8_ETC2_EAC; base_internal_fmt = KTX_RGBA; break; } - case cBC7: + case texture_format::cBC7: { internal_fmt = KTX_COMPRESSED_RGBA_BPTC_UNORM; base_internal_fmt = KTX_RGBA; break; } - case cPVRTC1_4_RGB: + case texture_format::cPVRTC1_4_RGB: { internal_fmt = KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; break; } - case cPVRTC1_4_RGBA: + case texture_format::cPVRTC1_4_RGBA: { internal_fmt = KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; base_internal_fmt = KTX_RGBA; break; } - case cASTC4x4: + case texture_format::cASTC4x4: { internal_fmt = KTX_COMPRESSED_RGBA_ASTC_4x4_KHR; base_internal_fmt = KTX_RGBA; break; } - case cATC_RGB: + case texture_format::cATC_RGB: { internal_fmt = KTX_ATC_RGB_AMD; break; } - case cATC_RGBA_INTERPOLATED_ALPHA: + case texture_format::cATC_RGBA_INTERPOLATED_ALPHA: { internal_fmt = KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD; base_internal_fmt = KTX_RGBA; break; } + case texture_format::cETC2_R11_EAC: + { + internal_fmt = KTX_COMPRESSED_R11_EAC; + base_internal_fmt = KTX_RED; + break; + } + case texture_format::cETC2_RG11_EAC: + { + internal_fmt = KTX_COMPRESSED_RG11_EAC; + base_internal_fmt = KTX_RG; + break; + } + case texture_format::cFXT1_RGB: + { + internal_fmt = KTX_COMPRESSED_RGB_FXT1_3DFX; + break; + } + case texture_format::cPVRTC2_4_RGBA: + { + internal_fmt = KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG; + base_internal_fmt = KTX_RGBA; + break; + } default: { // TODO @@ -1024,5 +1415,37 @@ namespace basisu return write_compressed_texture_file(pFilename, v, false); } + const uint32_t OUT_FILE_MAGIC = 'TEXC'; + struct out_file_header + { + packed_uint<4> m_magic; + packed_uint<4> m_pad; + packed_uint<4> m_width; + packed_uint<4> m_height; + }; + + // As no modern tool supports FXT1 format .KTX files, let's write .OUT files and make sure 3DFX's original tools shipped in 1999 can decode our encoded output. + bool write_3dfx_out_file(const char* pFilename, const gpu_image& gi) + { + out_file_header hdr; + hdr.m_magic = OUT_FILE_MAGIC; + hdr.m_pad = 0; + hdr.m_width = gi.get_blocks_x() * 8; + hdr.m_height = gi.get_blocks_y() * 4; + + FILE* pFile = nullptr; +#ifdef _WIN32 + fopen_s(&pFile, pFilename, "wb"); +#else + pFile = fopen(pFilename, "wb"); +#endif + if (!pFile) + return false; + + fwrite(&hdr, sizeof(hdr), 1, pFile); + fwrite(gi.get_ptr(), gi.get_size_in_bytes(), 1, pFile); + + return fclose(pFile) != EOF; + } } // basisu diff --git a/thirdparty/basis_universal/basisu_gpu_texture.h b/thirdparty/basis_universal/basisu_gpu_texture.h index 9b18116737..8a49757ca7 100644 --- a/thirdparty/basis_universal/basisu_gpu_texture.h +++ b/thirdparty/basis_universal/basisu_gpu_texture.h @@ -37,7 +37,7 @@ namespace basisu void clear() { - m_fmt = cInvalidTextureFormat; + m_fmt = texture_format::cInvalidTextureFormat; m_width = 0; m_height = 0; m_block_width = 0; @@ -101,7 +101,7 @@ namespace basisu m_blocks.resize(m_blocks_x * m_blocks_y * m_qwords_per_block); } - bool unpack(image& img, bool pvrtc_wrap_addressing = true) const; + bool unpack(image& img) const; void override_dimensions(uint32_t w, uint32_t h) { @@ -132,6 +132,7 @@ namespace basisu bool write_compressed_texture_file(const char *pFilename, const gpu_image &g); + bool write_3dfx_out_file(const char* pFilename, const gpu_image& gi); // GPU texture block unpacking void unpack_etc2_eac(const void *pBlock_bits, color_rgba *pPixels); @@ -142,6 +143,9 @@ namespace basisu bool unpack_bc7_mode6(const void *pBlock_bits, color_rgba *pPixels); bool unpack_bc7_mode5(const void* pBlock_bits, color_rgba* pPixels); void unpack_atc(const void* pBlock_bits, color_rgba* pPixels); + bool unpack_fxt1(const void* p, color_rgba* pPixels); + bool unpack_pvrtc2(const void* p, color_rgba* pPixels); + void unpack_etc2_eac_rg(const void* p, color_rgba* pPixels); // unpack_block() is only capable of unpacking texture data created by the transcoder. // For some texture formats (like BC7, or ETC2) it's not a complete implementation. diff --git a/thirdparty/basis_universal/basisu_pvrtc1_4.cpp b/thirdparty/basis_universal/basisu_pvrtc1_4.cpp index 5a732b2ceb..f0122fcb6c 100644 --- a/thirdparty/basis_universal/basisu_pvrtc1_4.cpp +++ b/thirdparty/basis_universal/basisu_pvrtc1_4.cpp @@ -193,21 +193,12 @@ namespace basisu int block_x1 = block_x0 + 1; int block_y0 = (static_cast<int>(y) - 2) >> 2; int block_y1 = block_y0 + 1; - if (m_wrap_addressing) - { - block_x0 = posmod(block_x0, m_block_width); - block_x1 = posmod(block_x1, m_block_width); - block_y0 = posmod(block_y0, m_block_height); - block_y1 = posmod(block_y1, m_block_height); - } - else - { - block_x0 = clamp<int>(block_x0, 0, m_block_width - 1); - block_x1 = clamp<int>(block_x1, 0, m_block_width - 1); - block_y0 = clamp<int>(block_y0, 0, m_block_height - 1); - block_y1 = clamp<int>(block_y1, 0, m_block_height - 1); - } - + + block_x0 = posmod(block_x0, m_block_width); + block_x1 = posmod(block_x1, m_block_width); + block_y0 = posmod(block_y0, m_block_height); + block_y1 = posmod(block_y1, m_block_height); + pColors[0] = interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0)); pColors[3] = interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1)); @@ -240,21 +231,12 @@ namespace basisu int block_x1 = block_x0 + 1; int block_y0 = (static_cast<int>(y) - 2) >> 2; int block_y1 = block_y0 + 1; - if (m_wrap_addressing) - { - block_x0 = posmod(block_x0, m_block_width); - block_x1 = posmod(block_x1, m_block_width); - block_y0 = posmod(block_y0, m_block_height); - block_y1 = posmod(block_y1, m_block_height); - } - else - { - block_x0 = clamp<int>(block_x0, 0, m_block_width - 1); - block_x1 = clamp<int>(block_x1, 0, m_block_width - 1); - block_y0 = clamp<int>(block_y0, 0, m_block_height - 1); - block_y1 = clamp<int>(block_y1, 0, m_block_height - 1); - } - + + block_x0 = posmod(block_x0, m_block_width); + block_x1 = posmod(block_x1, m_block_width); + block_y0 = posmod(block_y0, m_block_height); + block_y1 = posmod(block_y1, m_block_height); + if (get_block_uses_transparent_modulation(x >> 2, y >> 2)) { if (m == 0) diff --git a/thirdparty/basis_universal/basisu_pvrtc1_4.h b/thirdparty/basis_universal/basisu_pvrtc1_4.h index 71c4fba1d8..80b4413351 100644 --- a/thirdparty/basis_universal/basisu_pvrtc1_4.h +++ b/thirdparty/basis_universal/basisu_pvrtc1_4.h @@ -168,15 +168,14 @@ namespace basisu { public: inline pvrtc4_image() : - m_width(0), m_height(0), m_block_width(0), m_block_height(0), m_wrap_addressing(false), m_uses_alpha(false) + m_width(0), m_height(0), m_block_width(0), m_block_height(0), m_uses_alpha(false) { } - inline pvrtc4_image(uint32_t width, uint32_t height, bool wrap_addressing = false) : - m_width(0), m_height(0), m_block_width(0), m_block_height(0), m_wrap_addressing(false), m_uses_alpha(false) + inline pvrtc4_image(uint32_t width, uint32_t height) : + m_width(0), m_height(0), m_block_width(0), m_block_height(0), m_uses_alpha(false) { resize(width, height); - set_wrap_addressing(wrap_addressing); } inline void clear() @@ -187,7 +186,6 @@ namespace basisu m_block_height = 0; m_blocks.clear(); m_uses_alpha = false; - m_wrap_addressing = false; } inline void resize(uint32_t width, uint32_t height) @@ -218,9 +216,6 @@ namespace basisu inline bool get_uses_alpha() const { return m_uses_alpha; } inline void set_uses_alpha(bool uses_alpha) { m_uses_alpha = uses_alpha; } - inline void set_wrap_addressing(bool wrapping) { m_wrap_addressing = wrapping; } - inline bool get_wrap_addressing() const { return m_wrap_addressing; } - inline bool are_blocks_equal(const pvrtc4_image& rhs) const { return m_blocks == rhs.m_blocks; @@ -298,24 +293,24 @@ namespace basisu dst(x, y) = get_pixel(block_x * 4 + x, block_y * 4 + y); } - inline int wrap_or_clamp_x(int x) const + inline int wrap_x(int x) const { - return m_wrap_addressing ? posmod(x, m_width) : clamp<int>(x, 0, m_width - 1); + return posmod(x, m_width); } - inline int wrap_or_clamp_y(int y) const + inline int wrap_y(int y) const { - return m_wrap_addressing ? posmod(y, m_height) : clamp<int>(y, 0, m_height - 1); + return posmod(y, m_height); } - inline int wrap_or_clamp_block_x(int bx) const + inline int wrap_block_x(int bx) const { - return m_wrap_addressing ? posmod(bx, m_block_width) : clamp<int>(bx, 0, m_block_width - 1); + return posmod(bx, m_block_width); } - inline int wrap_or_clamp_block_y(int by) const + inline int wrap_block_y(int by) const { - return m_wrap_addressing ? posmod(by, m_block_height) : clamp<int>(by, 0, m_block_height - 1); + return posmod(by, m_block_height); } inline vec2F get_interpolation_factors(uint32_t x, uint32_t y) const @@ -362,7 +357,6 @@ namespace basisu pvrtc4_block_vector2D m_blocks; uint32_t m_block_width, m_block_height; - bool m_wrap_addressing; bool m_uses_alpha; }; diff --git a/thirdparty/basis_universal/basisu_tool.cpp b/thirdparty/basis_universal/basisu_tool.cpp index 92ff6e9c6f..8172a8c5cc 100644 --- a/thirdparty/basis_universal/basisu_tool.cpp +++ b/thirdparty/basis_universal/basisu_tool.cpp @@ -27,7 +27,7 @@ using namespace basisu; -#define BASISU_TOOL_VERSION "1.09.00" +#define BASISU_TOOL_VERSION "1.10.00" enum tool_mode { @@ -35,7 +35,8 @@ enum tool_mode cCompress, cValidate, cUnpack, - cCompare + cCompare, + cVersion, }; static void print_usage() @@ -47,6 +48,7 @@ static void print_usage() " -unpack: Use transcoder to unpack .basis file to one or more .ktx/.png files\n" " -validate: Validate and display information about a .basis file\n" " -compare: Compare two PNG images specified with -file, output PSNR and SSIM statistics and RGB/A delta images\n" + " -version: Print basisu version and exit\n" "Unless an explicit mode is specified, if one or more files have the .basis extension this tool defaults to unpack mode.\n" "\n" "Important: By default, the compressor assumes the input is in the sRGB colorspace (like photos/albedo textures).\n" @@ -82,7 +84,7 @@ static void print_usage() " -normal_map: Tunes codec parameters for better quality on normal maps (linear colorspace metrics, linear mipmap filtering, no selector RDO, no sRGB)\n" " -no_alpha: Always output non-alpha basis files, even if one or more inputs has alpha\n" " -force_alpha: Always output alpha basis files, even if no inputs has alpha\n" - " -seperate_rg_to_color_alpha: Seperate input R and G channels to RGB and A (for tangent space XY normal maps)\n" + " -separate_rg_to_color_alpha: Separate input R and G channels to RGB and A (for tangent space XY normal maps)\n" " -no_multithreading: Disable multithreading\n" " -no_ktx: Disable KTX writing when unpacking (faster)\n" " -etc1_only: Only unpack to ETC1, skipping the other texture formats during -unpack\n" @@ -108,7 +110,7 @@ static void print_usage() "\n" "Hierarchical virtual selector codebook options:\n" " -global_sel_pal: Always use vitual selector palettes (instead of custom palettes), slightly smaller files, but lower quality, slower encoding\n" - " -no_auto_global_sel_pal: Don't automatically use virtual selector palettes on small images\n" + " -auto_global_sel_pal: Automatically use virtual selector palettes on small images for slightly smaller files (defaults to off for faster encoding time)\n" " -no_hybrid_sel_cb: Don't automatically use hybrid virtual selector codebooks (for higher quality, only active when -global_sel_pal is specified)\n" " -global_pal_bits X: Set virtual selector codebook palette bits, range is [0,12], default is 8, higher is slower/better quality\n" " -global_mod_bits X: Set virtual selector codebook modifier bits, range is [0,15], defualt is 8, higher is slower/better quality\n" @@ -216,6 +218,8 @@ static bool load_listing_file(const std::string &f, std::vector<std::string> &fi class command_line_params { + BASISU_NO_EQUALS_OR_COPY_CONSTRUCT(command_line_params); + public: command_line_params() : m_mode(cDefault), @@ -248,6 +252,8 @@ public: m_mode = cUnpack; else if (strcasecmp(pArg, "-validate") == 0) m_mode = cValidate; + else if (strcasecmp(pArg, "-version") == 0) + m_mode = cVersion; else if (strcasecmp(pArg, "-compare_ssim") == 0) m_compare_ssim = true; else if (strcasecmp(pArg, "-file") == 0) @@ -347,7 +353,8 @@ public: m_comp_params.m_check_for_alpha = false; else if (strcasecmp(pArg, "-force_alpha") == 0) m_comp_params.m_force_alpha = true; - else if (strcasecmp(pArg, "-seperate_rg_to_color_alpha") == 0) + else if ((strcasecmp(pArg, "-separate_rg_to_color_alpha") == 0) || + (strcasecmp(pArg, "-seperate_rg_to_color_alpha") == 0)) // was mispelled for a while - whoops! m_comp_params.m_seperate_rg_to_color_alpha = true; else if (strcasecmp(pArg, "-no_multithreading") == 0) { @@ -407,7 +414,9 @@ public: else if (strcasecmp(pArg, "-global_sel_pal") == 0) m_comp_params.m_global_sel_pal = true; else if (strcasecmp(pArg, "-no_auto_global_sel_pal") == 0) - m_comp_params.m_no_auto_global_sel_pal = true; + m_comp_params.m_auto_global_sel_pal = false; + else if (strcasecmp(pArg, "-auto_global_sel_pal") == 0) + m_comp_params.m_auto_global_sel_pal = true; else if (strcasecmp(pArg, "-global_pal_bits") == 0) { REMAINING_ARGS_CHECK(1); @@ -942,14 +951,14 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl printf("start_transcoding time: %3.3f ms\n", tm.get_elapsed_ms()); - std::vector< gpu_image_vec > gpu_images[basist::cTFTotalTextureFormats]; + std::vector< gpu_image_vec > gpu_images[(int)basist::transcoder_texture_format::cTFTotalTextureFormats]; int first_format = 0; - int last_format = basist::cTFTotalBlockTextureFormats; + int last_format = (int)basist::transcoder_texture_format::cTFTotalTextureFormats; if (opts.m_etc1_only) { - first_format = basist::cTFETC1; + first_format = (int)basist::transcoder_texture_format::cTFETC1_RGB; last_format = first_format + 1; } @@ -957,15 +966,23 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl { basist::transcoder_texture_format tex_fmt = static_cast<basist::transcoder_texture_format>(format_iter); - gpu_images[tex_fmt].resize(fileinfo.m_total_images); + if (basist::basis_transcoder_format_is_uncompressed(tex_fmt)) + continue; + + gpu_images[(int)tex_fmt].resize(fileinfo.m_total_images); for (uint32_t image_index = 0; image_index < fileinfo.m_total_images; image_index++) - gpu_images[tex_fmt][image_index].resize(fileinfo.m_image_mipmap_levels[image_index]); + gpu_images[(int)tex_fmt][image_index].resize(fileinfo.m_image_mipmap_levels[image_index]); } // Now transcode the file to all supported texture formats and save mipmapped KTX files for (int format_iter = first_format; format_iter < last_format; format_iter++) { + const basist::transcoder_texture_format transcoder_tex_fmt = static_cast<basist::transcoder_texture_format>(format_iter); + + if (basist::basis_transcoder_format_is_uncompressed(transcoder_tex_fmt)) + continue; + for (uint32_t image_index = 0; image_index < fileinfo.m_total_images; image_index++) { for (uint32_t level_index = 0; level_index < fileinfo.m_image_mipmap_levels[image_index]; level_index++) @@ -977,10 +994,8 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl error_printf("Failed retrieving image level information (%u %u)!\n", image_index, level_index); return false; } - - const basist::transcoder_texture_format transcoder_tex_fmt = static_cast<basist::transcoder_texture_format>(format_iter); - - if ((transcoder_tex_fmt == basist::cTFPVRTC1_4_RGB) || (transcoder_tex_fmt == basist::cTFPVRTC1_4_RGBA)) + + if ((transcoder_tex_fmt == basist::transcoder_texture_format::cTFPVRTC1_4_RGB) || (transcoder_tex_fmt == basist::transcoder_texture_format::cTFPVRTC1_4_RGBA)) { if (!is_pow2(level_info.m_width) || !is_pow2(level_info.m_height)) { @@ -995,52 +1010,24 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl basisu::texture_format tex_fmt = basis_get_basisu_texture_format(transcoder_tex_fmt); - gpu_image& gi = gpu_images[transcoder_tex_fmt][image_index][level_index]; + gpu_image& gi = gpu_images[(int)transcoder_tex_fmt][image_index][level_index]; gi.init(tex_fmt, level_info.m_orig_width, level_info.m_orig_height); // Fill the buffer with psuedo-random bytes, to help more visibly detect cases where the transcoder fails to write to part of the output. fill_buffer_with_random_bytes(gi.get_ptr(), gi.get_size_in_bytes()); - tm.start(); -#if 1 - if (!dec.transcode_image_level(&basis_data[0], (uint32_t)basis_data.size(), image_index, level_index, gi.get_ptr(), gi.get_total_blocks(), transcoder_tex_fmt, 0)) - { - error_printf("Failed transcoding image level (%u %u %u)!\n", image_index, level_index, format_iter); - return false; - } - - double total_transcode_time = tm.get_elapsed_ms(); -#else - // quick and dirty row pitch parameter test, to be moved into a unit test - uint8_vec temp; - uint32_t block_pitch_to_test = level_info.m_num_blocks_x; - if ((transcoder_tex_fmt != basist::cTFPVRTC1_4_RGB) || (transcoder_tex_fmt != basist::cTFPVRTC1_4_RGBA)) - block_pitch_to_test += 5; - - temp.resize(level_info.m_num_blocks_y * block_pitch_to_test * gi.get_bytes_per_block()); - fill_buffer_with_random_bytes(&temp[0], temp.size()); + uint32_t decode_flags = 0; tm.start(); - - if (!dec.transcode_image_level(&basis_data[0], (uint32_t)basis_data.size(), image_index, level_index, &temp[0], (uint32_t)(temp.size() / gi.get_bytes_per_block()), transcoder_tex_fmt, 0, block_pitch_to_test)) + + if (!dec.transcode_image_level(&basis_data[0], (uint32_t)basis_data.size(), image_index, level_index, gi.get_ptr(), gi.get_total_blocks(), transcoder_tex_fmt, decode_flags)) { error_printf("Failed transcoding image level (%u %u %u)!\n", image_index, level_index, format_iter); return false; } + double total_transcode_time = tm.get_elapsed_ms(); - if ((transcoder_tex_fmt == basist::cTFPVRTC1_4_RGB) || (transcoder_tex_fmt == basist::cTFPVRTC1_4_RGBA)) - { - assert(temp.size() == gi.get_size_in_bytes()); - memcpy(gi.get_ptr(), &temp[0], gi.get_size_in_bytes()); - } - else - { - for (uint32_t y = 0; y < level_info.m_num_blocks_y; y++) - memcpy(gi.get_block_ptr(0, y), &temp[y * block_pitch_to_test * gi.get_bytes_per_block()], gi.get_row_pitch_in_bytes()); - } -#endif - printf("Transcode of image %u level %u res %ux%u format %s succeeded in %3.3f ms\n", image_index, level_index, level_info.m_orig_width, level_info.m_orig_height, basist::basis_get_format_name(transcoder_tex_fmt), total_transcode_time); } // format_iter @@ -1057,6 +1044,9 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl { const basist::transcoder_texture_format transcoder_tex_fmt = static_cast<basist::transcoder_texture_format>(format_iter); + if (basist::basis_transcoder_format_is_uncompressed(transcoder_tex_fmt)) + continue; + if ((!opts.m_no_ktx) && (fileinfo.m_tex_type == basist::cBASISTexTypeCubemapArray)) { // No KTX tool that we know of supports cubemap arrays, so write individual cubemap files. @@ -1132,6 +1122,21 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl } printf("Wrote PNG file \"%s\"\n", rgb_filename.c_str()); + if (transcoder_tex_fmt == basist::transcoder_texture_format::cTFFXT1_RGB) + { + std::string out_filename; + if (gi.size() > 1) + out_filename = base_filename + string_format("_unpacked_rgb_%s_%u_%04u.out", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index); + else + out_filename = base_filename + string_format("_unpacked_rgb_%s_%04u.out", basist::basis_get_format_name(transcoder_tex_fmt), image_index); + if (!write_3dfx_out_file(out_filename.c_str(), gi[level_index])) + { + error_printf("Failed writing to OUT file \"%s\"\n", out_filename.c_str()); + return false; + } + printf("Wrote .OUT file \"%s\"\n", out_filename.c_str()); + } + if (basis_transcoder_format_has_alpha(transcoder_tex_fmt)) { std::string a_filename; @@ -1160,7 +1165,7 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl { for (uint32_t level_index = 0; level_index < fileinfo.m_image_mipmap_levels[image_index]; level_index++) { - const basist::transcoder_texture_format transcoder_tex_fmt = basist::cTFRGBA32; + const basist::transcoder_texture_format transcoder_tex_fmt = basist::transcoder_texture_format::cTFRGBA32; basist::basisu_image_level_info level_info; @@ -1210,7 +1215,7 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl { for (uint32_t level_index = 0; level_index < fileinfo.m_image_mipmap_levels[image_index]; level_index++) { - const basist::transcoder_texture_format transcoder_tex_fmt = basist::cTFRGB565; + const basist::transcoder_texture_format transcoder_tex_fmt = basist::transcoder_texture_format::cTFRGB565; basist::basisu_image_level_info level_info; @@ -1258,14 +1263,6 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl } printf("Wrote PNG file \"%s\"\n", rgb_filename.c_str()); - std::string a_filename(base_filename + string_format("_unpacked_a_%s_%u_%04u.png", basist::basis_get_format_name(transcoder_tex_fmt), level_index, image_index)); - if (!save_png(a_filename, img, cImageSaveGrayscale, 3)) - { - error_printf("Failed writing to PNG file \"%s\"\n", a_filename.c_str()); - return false; - } - printf("Wrote PNG file \"%s\"\n", a_filename.c_str()); - } // level_index } // image_index @@ -1274,7 +1271,7 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl { for (uint32_t level_index = 0; level_index < fileinfo.m_image_mipmap_levels[image_index]; level_index++) { - const basist::transcoder_texture_format transcoder_tex_fmt = basist::cTFRGBA4444; + const basist::transcoder_texture_format transcoder_tex_fmt = basist::transcoder_texture_format::cTFRGBA4444; basist::basisu_image_level_info level_info; @@ -1515,6 +1512,9 @@ static int main_internal(int argc, const char **argv) case cCompare: status = compare_mode(opts); break; + case cVersion: + status = true; // We printed the version at the beginning of main_internal + break; default: assert(0); break; diff --git a/thirdparty/basis_universal/transcoder/basisu.h b/thirdparty/basis_universal/transcoder/basisu.h index 58b74df376..25600a69bf 100644 --- a/thirdparty/basis_universal/transcoder/basisu.h +++ b/thirdparty/basis_universal/transcoder/basisu.h @@ -301,7 +301,7 @@ namespace basisu // GPU texture formats - enum texture_format + enum class texture_format { cInvalidTextureFormat = -1, @@ -321,6 +321,10 @@ namespace basisu cPVRTC1_4_RGBA, cATC_RGB, cATC_RGBA_INTERPOLATED_ALPHA, + cFXT1_RGB, + cPVRTC2_4_RGBA, + cETC2_R11_EAC, + cETC2_RG11_EAC, // Uncompressed/raw pixels cRGBA32, @@ -334,17 +338,19 @@ namespace basisu { switch (fmt) { - case cETC1: - case cETC1S: - case cETC2_RGB: - case cETC2_ALPHA: - case cBC1: - case cBC4: - case cPVRTC1_4_RGB: - case cPVRTC1_4_RGBA: - case cATC_RGB: + case texture_format::cETC1: + case texture_format::cETC1S: + case texture_format::cETC2_RGB: + case texture_format::cETC2_ALPHA: + case texture_format::cBC1: + case texture_format::cBC4: + case texture_format::cPVRTC1_4_RGB: + case texture_format::cPVRTC1_4_RGBA: + case texture_format::cATC_RGB: + case texture_format::cPVRTC2_4_RGBA: + case texture_format::cETC2_R11_EAC: return 8; - case cRGBA32: + case texture_format::cRGBA32: return sizeof(uint32_t) * 16; default: break; @@ -360,6 +366,13 @@ namespace basisu inline uint32_t get_block_width(texture_format fmt) { BASISU_NOTE_UNUSED(fmt); + switch (fmt) + { + case texture_format::cFXT1_RGB: + return 8; + default: + break; + } return 4; } diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp index 08a4661dfa..d15b6013d9 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp @@ -71,6 +71,11 @@ #define BASISD_SUPPORT_ATC 1 #endif +// Support for ETC2 EAC R11 and ETC2 EAC RG11 +#ifndef BASISD_SUPPORT_ETC2_EAC_RG11 +#define BASISD_SUPPORT_ETC2_EAC_RG11 1 +#endif + // If BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY is 1, opaque blocks will be transcoded to ASTC at slightly higher quality (higher than BC1), but the transcoder tables will be 2x as large. // This impacts grayscale and grayscale+alpha textures the most. #ifndef BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY @@ -83,12 +88,33 @@ #endif #endif -#define BASISD_WRITE_NEW_BC7_TABLES 0 -#define BASISD_WRITE_NEW_BC7_MODE5_TABLES 0 -#define BASISD_WRITE_NEW_DXT1_TABLES 0 -#define BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES 0 -#define BASISD_WRITE_NEW_ASTC_TABLES 0 -#define BASISD_WRITE_NEW_ATC_TABLES 0 +#ifndef BASISD_SUPPORT_FXT1 +#define BASISD_SUPPORT_FXT1 1 +#endif + +#ifndef BASISD_SUPPORT_PVRTC2 +#define BASISD_SUPPORT_PVRTC2 1 +#endif + +#if BASISD_SUPPORT_PVRTC2 +#if !BASISD_SUPPORT_ATC +#error BASISD_SUPPORT_ATC must be 1 if BASISD_SUPPORT_PVRTC2 is 1 +#endif +#endif + +#if BASISD_SUPPORT_ATC +#if !BASISD_SUPPORT_DXT5A +#error BASISD_SUPPORT_DXT5A must be 1 if BASISD_SUPPORT_ATC is 1 +#endif +#endif + +#define BASISD_WRITE_NEW_BC7_TABLES 0 +#define BASISD_WRITE_NEW_BC7_MODE5_TABLES 0 +#define BASISD_WRITE_NEW_DXT1_TABLES 0 +#define BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES 0 +#define BASISD_WRITE_NEW_ASTC_TABLES 0 +#define BASISD_WRITE_NEW_ATC_TABLES 0 +#define BASISD_WRITE_NEW_ETC2_EAC_R11_TABLES 0 #ifndef BASISD_ENABLE_DEBUG_FLAGS #define BASISD_ENABLE_DEBUG_FLAGS 0 @@ -120,7 +146,9 @@ namespace basisu namespace basist { +#if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY #include "basisu_transcoder_tables_bc7_m6.inc" +#endif #if BASISD_ENABLE_DEBUG_FLAGS static uint32_t g_debug_flags = 0; @@ -1240,20 +1268,8 @@ namespace basist } #endif -#if BASISD_SUPPORT_ETC2_EAC_A8 - enum - { - cEAC_A8_BYTES_PER_BLOCK = 8, - cEAC_A8_SELECTOR_BYTES = 6, - cEAC_A8_SELECTOR_BITS = 3, - cEAC_RGBA8_BYTES_PER_BLOCK = 16, - cEAC_RGBA8_RGB_OFFSET = 8, - cEAC_RGBA8_A_OFFSET = 0, - cEAC_A8_MIN_VALUE_SELECTOR = 3, - cEAC_A8_MAX_VALUE_SELECTOR = 7 - }; - - static const int8_t g_eac_a8_modifier_table[16][8] = +#if BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_ETC2_EAC_RG11 + static const int8_t g_eac_modifier_table[16][8] = { { -3, -6, -9, -15, 2, 5, 8, 14 }, { -3, -7, -10, -13, 2, 6, 9, 12 }, @@ -1274,7 +1290,8 @@ namespace basist { -3, -5, -7, -9, 2, 4, 6, 8 } }; - struct eac_a8_block + // Used by ETC2 EAC A8 and ETC2 EAC R11/RG11. + struct eac_block { uint16_t m_base : 8; @@ -1327,6 +1344,28 @@ namespace basist } }; + static const dxt_selector_range s_etc2_eac_selector_ranges[] = + { + { 0, 3 }, + + { 1, 3 }, + { 0, 2 }, + + { 1, 2 }, + }; + + const uint32_t NUM_ETC2_EAC_SELECTOR_RANGES = sizeof(s_etc2_eac_selector_ranges) / sizeof(s_etc2_eac_selector_ranges[0]); + + struct etc1_g_to_eac_conversion + { + uint8_t m_base; + uint8_t m_table_mul; // mul*16+table + uint16_t m_trans; // translates ETC1 selectors to ETC2_EAC_A8 + }; +#endif // BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_ETC2_EAC_RG11 + +#if BASISD_SUPPORT_ETC2_EAC_A8 + #if BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES struct pack_eac_a8_results { @@ -1360,7 +1399,7 @@ namespace basist uint32_t best_s = 0; for (uint32_t s = 0; s < 8; s++) { - int v = (int)multiplier * g_eac_a8_modifier_table[table][s] + (int)base_color; + int v = (int)multiplier * g_eac_modifier_table[table][s] + (int)base_color; if (v < 0) v = 0; else if (v > 255) @@ -1398,32 +1437,13 @@ namespace basist return best_err; } -#endif - - static const dxt_selector_range s_etc2_eac_a8_selector_ranges[] = - { - { 0, 3 }, - - { 1, 3 }, - { 0, 2 }, - - { 1, 2 }, - }; - - const uint32_t NUM_ETC2_EAC_A8_SELECTOR_RANGES = sizeof(s_etc2_eac_a8_selector_ranges) / sizeof(s_etc2_eac_a8_selector_ranges[0]); - - struct etc1_g_to_etc2_a8_conversion - { - uint8_t m_base; - uint8_t m_table_mul; // mul*16+table - uint16_t m_trans; // translates ETC1 selectors to ETC2_EAC_A8 - }; - +#endif // BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES + static #if !BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES const #endif - etc1_g_to_etc2_a8_conversion s_etc1_g_to_etc2_a8[32 * 8][NUM_ETC2_EAC_A8_SELECTOR_RANGES] = + etc1_g_to_eac_conversion s_etc1_g_to_etc2_a8[32 * 8][NUM_ETC2_EAC_SELECTOR_RANGES] = { { { 0,1,3328 },{ 0,1,3328 },{ 0,1,256 },{ 0,1,256 } }, { { 0,226,3936 },{ 0,226,3936 },{ 0,81,488 },{ 0,81,488 } }, @@ -1682,7 +1702,7 @@ namespace basist { { 168,40,4075 },{ 80,15,4080 },{ 168,40,491 },{ 80,15,496 } }, { { 144,8,4082 },{ 88,15,4080 },{ 144,8,498 },{ 88,15,496 } } }; -#endif +#endif // BASISD_SUPPORT_ETC2_EAC_A8 #if BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES static void create_etc2_eac_a8_conversion_table() @@ -1698,10 +1718,10 @@ namespace basist fprintf(pFile, "{"); - for (uint32_t sel_range = 0; sel_range < NUM_ETC2_EAC_A8_SELECTOR_RANGES; sel_range++) + for (uint32_t sel_range = 0; sel_range < NUM_ETC2_EAC_SELECTOR_RANGES; sel_range++) { - const uint32_t low_selector = s_etc2_eac_a8_selector_ranges[sel_range].m_low; - const uint32_t high_selector = s_etc2_eac_a8_selector_ranges[sel_range].m_high; + const uint32_t low_selector = s_etc2_eac_selector_ranges[sel_range].m_low; + const uint32_t high_selector = s_etc2_eac_selector_ranges[sel_range].m_high; // We have a ETC1 base color and intensity, and a used selector range from low_selector-high_selector. // Now find the best ETC2 EAC A8 base/table/multiplier that fits these colors. @@ -1714,7 +1734,7 @@ namespace basist pack_eac_a8_results pack_results; pack_eac_a8_exhaustive(pack_results, pixels, num_pixels); - etc1_g_to_etc2_a8_conversion& c = s_etc1_g_to_etc2_a8[base + inten * 32][sel_range]; + etc1_g_to_eac_conversion& c = s_etc1_g_to_etc2_a8[base + inten * 32][sel_range]; c.m_base = pack_results.m_base; c.m_table_mul = pack_results.m_table * 16 + pack_results.m_multiplier; @@ -1731,7 +1751,7 @@ namespace basist } fprintf(pFile, "{%u,%u,%u}", c.m_base, c.m_table_mul, c.m_trans); - if (sel_range < (NUM_ETC2_EAC_A8_SELECTOR_RANGES - 1)) + if (sel_range < (NUM_ETC2_EAC_SELECTOR_RANGES - 1)) fprintf(pFile, ","); } @@ -1743,6 +1763,138 @@ namespace basist } #endif +#if BASISD_WRITE_NEW_ETC2_EAC_R11_TABLES + struct pack_eac_r11_results + { + uint32_t m_base; + uint32_t m_table; + uint32_t m_multiplier; + std::vector<uint8_t> m_selectors; + std::vector<uint8_t> m_selectors_temp; + }; + + static uint64_t pack_eac_r11_exhaustive(pack_eac_r11_results& results, const uint8_t* pPixels, uint32_t num_pixels) + { + results.m_selectors.resize(num_pixels); + results.m_selectors_temp.resize(num_pixels); + + uint64_t best_err = UINT64_MAX; + + for (uint32_t base_color = 0; base_color < 256; base_color++) + { + for (uint32_t multiplier = 0; multiplier < 16; multiplier++) + { + for (uint32_t table = 0; table < 16; table++) + { + uint64_t total_err = 0; + + for (uint32_t i = 0; i < num_pixels; i++) + { + // Convert 8-bit input to 11-bits + const int a = (pPixels[i] * 2047 + 128) / 255; + + uint32_t best_s_err = UINT32_MAX; + uint32_t best_s = 0; + for (uint32_t s = 0; s < 8; s++) + { + int v = (int)(multiplier ? (multiplier * 8) : 1) * g_eac_modifier_table[table][s] + (int)base_color * 8 + 4; + if (v < 0) + v = 0; + else if (v > 2047) + v = 2047; + + uint32_t err = abs(a - v); + if (err < best_s_err) + { + best_s_err = err; + best_s = s; + } + } + + results.m_selectors_temp[i] = static_cast<uint8_t>(best_s); + + total_err += best_s_err * best_s_err; + if (total_err >= best_err) + break; + } + + if (total_err < best_err) + { + best_err = total_err; + results.m_base = base_color; + results.m_multiplier = multiplier; + results.m_table = table; + results.m_selectors.swap(results.m_selectors_temp); + } + + } // table + + } // multiplier + + } // base_color + + return best_err; + } + + static void create_etc2_eac_r11_conversion_table() + { + FILE* pFile = nullptr; + fopen_s(&pFile, "basisu_decoder_tables_etc2_eac_r11.inc", "w"); + + for (uint32_t inten = 0; inten < 8; inten++) + { + for (uint32_t base = 0; base < 32; base++) + { + color32 block_colors[4]; + decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(base, base, base, 255), false), inten); + + fprintf(pFile, "{"); + + for (uint32_t sel_range = 0; sel_range < NUM_ETC2_EAC_SELECTOR_RANGES; sel_range++) + { + const uint32_t low_selector = s_etc2_eac_selector_ranges[sel_range].m_low; + const uint32_t high_selector = s_etc2_eac_selector_ranges[sel_range].m_high; + + // We have a ETC1 base color and intensity, and a used selector range from low_selector-high_selector. + // Now find the best ETC2 EAC R11 base/table/multiplier that fits these colors. + + uint8_t pixels[4]; + uint32_t num_pixels = 0; + for (uint32_t s = low_selector; s <= high_selector; s++) + pixels[num_pixels++] = block_colors[s].g; + + pack_eac_r11_results pack_results; + pack_eac_r11_exhaustive(pack_results, pixels, num_pixels); + + etc1_g_to_eac_conversion c; + + c.m_base = (uint8_t)pack_results.m_base; + c.m_table_mul = (uint8_t)(pack_results.m_table * 16 + pack_results.m_multiplier); + c.m_trans = 0; + + for (uint32_t s = 0; s < 4; s++) + { + if ((s < low_selector) || (s > high_selector)) + continue; + + uint32_t etc2_selector = pack_results.m_selectors[s - low_selector]; + + c.m_trans |= (etc2_selector << (s * 3)); + } + + fprintf(pFile, "{%u,%u,%u}", c.m_base, c.m_table_mul, c.m_trans); + if (sel_range < (NUM_ETC2_EAC_SELECTOR_RANGES - 1)) + fprintf(pFile, ","); + } + + fprintf(pFile, "},\n"); + } + } + + fclose(pFile); + } +#endif // BASISD_WRITE_NEW_ETC2_EAC_R11_TABLES + #if BASISD_WRITE_NEW_ASTC_TABLES static void create_etc1_to_astc_conversion_table_0_47(); static void create_etc1_to_astc_conversion_table_0_255(); @@ -1769,6 +1921,10 @@ namespace basist static void transcoder_init_atc(); #endif +#if BASISD_SUPPORT_PVRTC2 + static void transcoder_init_pvrtc2(); +#endif + // Library global initialization. Requires ~9 milliseconds when compiled and executed natively on a Core i7 2.2 GHz. // If this is too slow, these computed tables can easilky be moved to be compiled in. void basisu_transcoder_init() @@ -1814,6 +1970,11 @@ namespace basist exit(0); #endif +#if BASISD_WRITE_NEW_ETC2_EAC_R11_TABLES + create_etc2_eac_r11_conversion_table(); + exit(0); +#endif + #if BASISD_SUPPORT_DXT1 uint8_t bc1_expand5[32]; for (int i = 0; i < 32; i++) @@ -1881,7 +2042,11 @@ namespace basist #if BASISD_SUPPORT_ATC transcoder_init_atc(); -#endif +#endif + +#if BASISD_SUPPORT_PVRTC2 + transcoder_init_pvrtc2(); +#endif s_initialized = true; } @@ -2101,6 +2266,176 @@ namespace basist #endif #endif +#if BASISD_SUPPORT_FXT1 + struct fxt1_block + { + union + { + struct + { + uint64_t m_t00 : 2; + uint64_t m_t01 : 2; + uint64_t m_t02 : 2; + uint64_t m_t03 : 2; + uint64_t m_t04 : 2; + uint64_t m_t05 : 2; + uint64_t m_t06 : 2; + uint64_t m_t07 : 2; + uint64_t m_t08 : 2; + uint64_t m_t09 : 2; + uint64_t m_t10 : 2; + uint64_t m_t11 : 2; + uint64_t m_t12 : 2; + uint64_t m_t13 : 2; + uint64_t m_t14 : 2; + uint64_t m_t15 : 2; + uint64_t m_t16 : 2; + uint64_t m_t17 : 2; + uint64_t m_t18 : 2; + uint64_t m_t19 : 2; + uint64_t m_t20 : 2; + uint64_t m_t21 : 2; + uint64_t m_t22 : 2; + uint64_t m_t23 : 2; + uint64_t m_t24 : 2; + uint64_t m_t25 : 2; + uint64_t m_t26 : 2; + uint64_t m_t27 : 2; + uint64_t m_t28 : 2; + uint64_t m_t29 : 2; + uint64_t m_t30 : 2; + uint64_t m_t31 : 2; + } m_lo; + uint64_t m_lo_bits; + uint8_t m_sels[8]; + }; + union + { + struct + { +#ifdef BASISU_USE_ORIGINAL_3DFX_FXT1_ENCODING + uint64_t m_b1 : 5; + uint64_t m_g1 : 5; + uint64_t m_r1 : 5; + uint64_t m_b0 : 5; + uint64_t m_g0 : 5; + uint64_t m_r0 : 5; + uint64_t m_b3 : 5; + uint64_t m_g3 : 5; + uint64_t m_r3 : 5; + uint64_t m_b2 : 5; + uint64_t m_g2 : 5; + uint64_t m_r2 : 5; +#else + uint64_t m_b0 : 5; + uint64_t m_g0 : 5; + uint64_t m_r0 : 5; + uint64_t m_b1 : 5; + uint64_t m_g1 : 5; + uint64_t m_r1 : 5; + uint64_t m_b2 : 5; + uint64_t m_g2 : 5; + uint64_t m_r2 : 5; + uint64_t m_b3 : 5; + uint64_t m_g3 : 5; + uint64_t m_r3 : 5; +#endif + uint64_t m_alpha : 1; + uint64_t m_glsb : 2; + uint64_t m_mode : 1; + } m_hi; + uint64_t m_hi_bits; + }; + }; + + static uint8_t conv_dxt1_to_fxt1_sels(uint32_t sels) + { + static uint8_t s_conv_table[16] = { 0, 3, 1, 2, 12, 15, 13, 14, 4, 7, 5, 6, 8, 11, 9, 10 }; + return s_conv_table[sels & 15] | (s_conv_table[sels >> 4] << 4); + } + + static void convert_etc1s_to_fxt1(void *pDst, const endpoint *pEndpoints, const selector *pSelectors, uint32_t fxt1_subblock) + { + fxt1_block* pBlock = static_cast<fxt1_block*>(pDst); + + // CC_MIXED is basically DXT1 with different encoding tricks. + // So transcode ETC1S to DXT1, then transcode that to FXT1 which is easy and nearly lossless. + // (It's not completely lossless because FXT1 rounds in its color lerps while DXT1 doesn't, but it should be good enough.) + dxt1_block blk; + convert_etc1s_to_dxt1(&blk, pEndpoints, pSelectors, false); + + const uint32_t l = blk.get_low_color(); + const uint32_t h = blk.get_high_color(); + + color32 color0((l >> 11) & 31, (l >> 5) & 63, l & 31, 255); + color32 color1((h >> 11) & 31, (h >> 5) & 63, h & 31, 255); + + uint32_t g0 = color0.g & 1; + uint32_t g1 = color1.g & 1; + + color0.g >>= 1; + color1.g >>= 1; + + blk.m_selectors[0] = conv_dxt1_to_fxt1_sels(blk.m_selectors[0]); + blk.m_selectors[1] = conv_dxt1_to_fxt1_sels(blk.m_selectors[1]); + blk.m_selectors[2] = conv_dxt1_to_fxt1_sels(blk.m_selectors[2]); + blk.m_selectors[3] = conv_dxt1_to_fxt1_sels(blk.m_selectors[3]); + + if ((blk.get_selector(0, 0) >> 1) != (g0 ^ g1)) + { + std::swap(color0, color1); + std::swap(g0, g1); + + blk.m_selectors[0] ^= 0xFF; + blk.m_selectors[1] ^= 0xFF; + blk.m_selectors[2] ^= 0xFF; + blk.m_selectors[3] ^= 0xFF; + } + + if (fxt1_subblock == 0) + { + pBlock->m_hi.m_mode = 1; + pBlock->m_hi.m_alpha = 0; + pBlock->m_hi.m_glsb = g1 | (g1 << 1); + pBlock->m_hi.m_r0 = color0.r; + pBlock->m_hi.m_g0 = color0.g; + pBlock->m_hi.m_b0 = color0.b; + pBlock->m_hi.m_r1 = color1.r; + pBlock->m_hi.m_g1 = color1.g; + pBlock->m_hi.m_b1 = color1.b; + pBlock->m_hi.m_r2 = color0.r; + pBlock->m_hi.m_g2 = color0.g; + pBlock->m_hi.m_b2 = color0.b; + pBlock->m_hi.m_r3 = color1.r; + pBlock->m_hi.m_g3 = color1.g; + pBlock->m_hi.m_b3 = color1.b; + pBlock->m_sels[0] = blk.m_selectors[0]; + pBlock->m_sels[1] = blk.m_selectors[1]; + pBlock->m_sels[2] = blk.m_selectors[2]; + pBlock->m_sels[3] = blk.m_selectors[3]; + + static const uint8_t s_border_dup[4] = { 0, 85, 170, 255 }; + pBlock->m_sels[4] = s_border_dup[blk.m_selectors[0] >> 6]; + pBlock->m_sels[5] = s_border_dup[blk.m_selectors[1] >> 6]; + pBlock->m_sels[6] = s_border_dup[blk.m_selectors[2] >> 6]; + pBlock->m_sels[7] = s_border_dup[blk.m_selectors[3] >> 6]; + } + else + { + pBlock->m_hi.m_glsb = (pBlock->m_hi.m_glsb & 1) | (g1 << 1); + pBlock->m_hi.m_r2 = color0.r; + pBlock->m_hi.m_g2 = color0.g; + pBlock->m_hi.m_b2 = color0.b; + pBlock->m_hi.m_r3 = color1.r; + pBlock->m_hi.m_g3 = color1.g; + pBlock->m_hi.m_b3 = color1.b; + pBlock->m_sels[4] = blk.m_selectors[0]; + pBlock->m_sels[5] = blk.m_selectors[1]; + pBlock->m_sels[6] = blk.m_selectors[2]; + pBlock->m_sels[7] = blk.m_selectors[3]; + } + } +#endif // BASISD_SUPPORT_FXT1 #if BASISD_SUPPORT_DXT5A static dxt_selector_range s_dxt5a_selector_ranges[] = { @@ -3069,7 +3404,7 @@ namespace basist } // TODO: Support decoding a non-pow2 ETC1S texture into the next larger pow2 PVRTC texture. - static void fixup_pvrtc1_4_modulation_rgb(const decoder_etc_block* pETC_Blocks, const uint32_t* pPVRTC_endpoints, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool pvrtc_wrap_addressing) + static void fixup_pvrtc1_4_modulation_rgb(const decoder_etc_block* pETC_Blocks, const uint32_t* pPVRTC_endpoints, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y) { const uint32_t x_mask = num_blocks_x - 1; const uint32_t y_mask = num_blocks_y - 1; @@ -3090,7 +3425,7 @@ namespace basist for (int ey = 0; ey < 3; ey++) { - int by = y + ey - 1; if (!pvrtc_wrap_addressing) by = basisu::clamp<int>(by, 0, y_mask); + int by = y + ey - 1; const uint32_t* pE = &pPVRTC_endpoints[(by & y_mask) * num_blocks_x]; @@ -3098,7 +3433,7 @@ namespace basist for (int ex = 0; ex < 3; ex++) { - int bx = 0 + ex - 1; if (!pvrtc_wrap_addressing) bx = basisu::clamp<int>(bx, 0, x_mask); + int bx = 0 + ex - 1; const uint32_t e = pE[bx & x_mask]; @@ -3144,8 +3479,6 @@ namespace basist { const uint32_t ex = 2; int bx = x + ex - 1; - if (!pvrtc_wrap_addressing) - bx = basisu::clamp<int>(bx, 0, x_mask); bx &= x_mask; #define DO_ROW(ey) \ @@ -3251,7 +3584,7 @@ namespace basist static void fixup_pvrtc1_4_modulation_rgba( const decoder_etc_block* pETC_Blocks, const uint32_t* pPVRTC_endpoints, - void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool pvrtc_wrap_addressing, void *pAlpha_blocks, + void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, void *pAlpha_blocks, const endpoint* pEndpoints, const selector* pSelectors) { const uint32_t x_mask = num_blocks_x - 1; @@ -3273,7 +3606,7 @@ namespace basist for (int ey = 0; ey < 3; ey++) { - int by = y + ey - 1; if (!pvrtc_wrap_addressing) by = basisu::clamp<int>(by, 0, y_mask); + int by = y + ey - 1; const uint32_t* pE = &pPVRTC_endpoints[(by & y_mask) * num_blocks_x]; @@ -3281,7 +3614,7 @@ namespace basist for (int ex = 0; ex < 3; ex++) { - int bx = 0 + ex - 1; if (!pvrtc_wrap_addressing) bx = basisu::clamp<int>(bx, 0, x_mask); + int bx = 0 + ex - 1; const uint32_t e = pE[bx & x_mask]; @@ -3341,8 +3674,6 @@ namespace basist { const uint32_t ex = 2; int bx = x + ex - 1; - if (!pvrtc_wrap_addressing) - bx = basisu::clamp<int>(bx, 0, x_mask); bx &= x_mask; #define DO_ROW(ey) \ @@ -4361,7 +4692,7 @@ namespace basist #endif // BASISD_SUPPORT_BC7_MODE5 #if BASISD_SUPPORT_ETC2_EAC_A8 - static void convert_etc1s_to_etc2_eac_a8(eac_a8_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector) + static void convert_etc1s_to_etc2_eac_a8(eac_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector) { const uint32_t low_selector = pSelector->m_lo_selector; const uint32_t high_selector = pSelector->m_hi_selector; @@ -4388,13 +4719,13 @@ namespace basist } uint32_t selector_range_table = 0; - for (selector_range_table = 0; selector_range_table < NUM_ETC2_EAC_A8_SELECTOR_RANGES; selector_range_table++) - if ((low_selector == s_etc2_eac_a8_selector_ranges[selector_range_table].m_low) && (high_selector == s_etc2_eac_a8_selector_ranges[selector_range_table].m_high)) + for (selector_range_table = 0; selector_range_table < NUM_ETC2_EAC_SELECTOR_RANGES; selector_range_table++) + if ((low_selector == s_etc2_eac_selector_ranges[selector_range_table].m_low) && (high_selector == s_etc2_eac_selector_ranges[selector_range_table].m_high)) break; - if (selector_range_table >= NUM_ETC2_EAC_A8_SELECTOR_RANGES) + if (selector_range_table >= NUM_ETC2_EAC_SELECTOR_RANGES) selector_range_table = 0; - const etc1_g_to_etc2_a8_conversion* pTable_entry = &s_etc1_g_to_etc2_a8[base_color.r + inten_table * 32][selector_range_table]; + const etc1_g_to_eac_conversion* pTable_entry = &s_etc1_g_to_etc2_a8[base_color.r + inten_table * 32][selector_range_table]; pDst_block->m_base = pTable_entry->m_base; pDst_block->m_table = pTable_entry->m_table_mul >> 4; @@ -4419,6 +4750,325 @@ namespace basist } #endif // BASISD_SUPPORT_ETC2_EAC_A8 +#if BASISD_SUPPORT_ETC2_EAC_RG11 + static const etc1_g_to_eac_conversion s_etc1_g_to_etc2_r11[32 * 8][NUM_ETC2_EAC_SELECTOR_RANGES] = + { + {{0,1,3328},{0,1,3328},{0,16,457},{0,16,456}}, + {{0,226,3936},{0,226,3936},{0,17,424},{8,0,472}}, + {{6,178,4012},{6,178,4008},{0,146,501},{16,0,472}}, + {{14,178,4012},{14,178,4008},{8,146,501},{24,0,472}}, + {{23,178,4012},{23,178,4008},{17,146,501},{33,0,472}}, + {{31,178,4012},{31,178,4008},{25,146,501},{41,0,472}}, + {{39,178,4012},{39,178,4008},{33,146,501},{49,0,472}}, + {{47,178,4012},{47,178,4008},{41,146,501},{27,228,496}}, + {{56,178,4012},{56,178,4008},{50,146,501},{36,228,496}}, + {{64,178,4012},{64,178,4008},{58,146,501},{44,228,496}}, + {{72,178,4012},{72,178,4008},{66,146,501},{52,228,496}}, + {{80,178,4012},{80,178,4008},{74,146,501},{60,228,496}}, + {{89,178,4012},{89,178,4008},{83,146,501},{69,228,496}}, + {{97,178,4012},{97,178,4008},{91,146,501},{77,228,496}}, + {{105,178,4012},{105,178,4008},{99,146,501},{85,228,496}}, + {{113,178,4012},{113,178,4008},{107,146,501},{93,228,496}}, + {{122,178,4012},{122,178,4008},{116,146,501},{102,228,496}}, + {{130,178,4012},{130,178,4008},{124,146,501},{110,228,496}}, + {{138,178,4012},{138,178,4008},{132,146,501},{118,228,496}}, + {{146,178,4012},{146,178,4008},{140,146,501},{126,228,496}}, + {{155,178,4012},{155,178,4008},{149,146,501},{135,228,496}}, + {{163,178,4012},{163,178,4008},{157,146,501},{143,228,496}}, + {{171,178,4012},{171,178,4008},{165,146,501},{151,228,496}}, + {{179,178,4012},{179,178,4008},{173,146,501},{159,228,496}}, + {{188,178,4012},{188,178,4008},{182,146,501},{168,228,496}}, + {{196,178,4012},{196,178,4008},{190,146,501},{176,228,496}}, + {{204,178,4012},{204,178,4008},{198,146,501},{184,228,496}}, + {{212,178,4012},{212,178,4008},{206,146,501},{192,228,496}}, + {{221,178,4012},{221,178,4008},{215,146,501},{201,228,496}}, + {{229,178,4012},{229,178,4008},{223,146,501},{209,228,496}}, + {{235,66,4012},{221,100,4008},{231,146,501},{217,228,496}}, + {{211,102,4085},{254,32,4040},{211,102,501},{254,32,456}}, + {{0,2,3328},{0,2,3328},{0,1,320},{0,1,320}}, + {{7,162,3905},{7,162,3904},{0,17,480},{0,17,480}}, + {{15,162,3906},{15,162,3904},{1,117,352},{1,117,352}}, + {{23,162,3906},{23,162,3904},{5,34,500},{4,53,424}}, + {{32,162,3906},{32,162,3904},{14,34,500},{3,69,424}}, + {{40,162,3906},{40,162,3904},{22,34,500},{1,133,496}}, + {{48,162,3906},{48,162,3904},{30,34,500},{4,85,496}}, + {{56,162,3906},{56,162,3904},{38,34,500},{12,85,496}}, + {{65,162,3906},{65,162,3904},{47,34,500},{1,106,424}}, + {{73,162,3906},{73,162,3904},{55,34,500},{9,106,424}}, + {{81,162,3906},{81,162,3904},{63,34,500},{7,234,496}}, + {{89,162,3906},{89,162,3904},{71,34,500},{15,234,496}}, + {{98,162,3906},{98,162,3904},{80,34,500},{24,234,496}}, + {{106,162,3906},{106,162,3904},{88,34,500},{32,234,496}}, + {{114,162,3906},{114,162,3904},{96,34,500},{40,234,496}}, + {{122,162,3906},{122,162,3904},{104,34,500},{48,234,496}}, + {{131,162,3906},{131,162,3904},{113,34,500},{57,234,496}}, + {{139,162,3906},{139,162,3904},{121,34,500},{65,234,496}}, + {{147,162,3906},{147,162,3904},{129,34,500},{73,234,496}}, + {{155,162,3906},{155,162,3904},{137,34,500},{81,234,496}}, + {{164,162,3906},{164,162,3904},{146,34,500},{90,234,496}}, + {{172,162,3906},{172,162,3904},{154,34,500},{98,234,496}}, + {{180,162,3906},{180,162,3904},{162,34,500},{106,234,496}}, + {{188,162,3906},{188,162,3904},{170,34,500},{114,234,496}}, + {{197,162,3906},{197,162,3904},{179,34,500},{123,234,496}}, + {{205,162,3906},{205,162,3904},{187,34,500},{131,234,496}}, + {{213,162,3906},{213,162,3904},{195,34,500},{139,234,496}}, + {{221,162,3906},{221,162,3904},{203,34,500},{147,234,496}}, + {{230,162,3906},{230,162,3904},{212,34,500},{156,234,496}}, + {{238,162,3906},{174,106,4008},{220,34,500},{164,234,496}}, + {{240,178,4001},{182,106,4008},{228,34,500},{172,234,496}}, + {{166,108,4085},{115,31,4080},{166,108,501},{115,31,496}}, + {{1,68,3328},{1,68,3328},{0,1,384},{0,1,384}}, + {{1,51,3968},{1,51,3968},{0,2,384},{0,2,384}}, + {{21,18,3851},{21,18,3848},{1,50,488},{1,50,488}}, + {{26,195,3851},{29,18,3848},{0,67,488},{0,67,488}}, + {{35,195,3851},{38,18,3848},{12,115,488},{0,3,496}}, + {{43,195,3851},{46,18,3848},{20,115,488},{2,6,424}}, + {{51,195,3851},{54,18,3848},{36,66,482},{4,22,424}}, + {{59,195,3851},{62,18,3848},{44,66,482},{3,73,424}}, + {{68,195,3851},{71,18,3848},{53,66,482},{3,22,496}}, + {{76,195,3851},{79,18,3848},{61,66,482},{2,137,496}}, + {{84,195,3851},{87,18,3848},{69,66,482},{1,89,496}}, + {{92,195,3851},{95,18,3848},{77,66,482},{9,89,496}}, + {{101,195,3851},{104,18,3848},{86,66,482},{18,89,496}}, + {{109,195,3851},{112,18,3848},{94,66,482},{26,89,496}}, + {{117,195,3851},{120,18,3848},{102,66,482},{34,89,496}}, + {{125,195,3851},{128,18,3848},{110,66,482},{42,89,496}}, + {{134,195,3851},{137,18,3848},{119,66,482},{51,89,496}}, + {{141,195,3907},{145,18,3848},{127,66,482},{59,89,496}}, + {{149,195,3907},{153,18,3848},{135,66,482},{67,89,496}}, + {{157,195,3907},{161,18,3848},{143,66,482},{75,89,496}}, + {{166,195,3907},{170,18,3848},{152,66,482},{84,89,496}}, + {{174,195,3907},{178,18,3848},{160,66,482},{92,89,496}}, + {{182,195,3907},{186,18,3848},{168,66,482},{100,89,496}}, + {{190,195,3907},{194,18,3848},{176,66,482},{108,89,496}}, + {{199,195,3907},{203,18,3848},{185,66,482},{117,89,496}}, + {{207,195,3907},{211,18,3848},{193,66,482},{125,89,496}}, + {{215,195,3907},{219,18,3848},{201,66,482},{133,89,496}}, + {{223,195,3907},{227,18,3848},{209,66,482},{141,89,496}}, + {{232,195,3907},{168,89,4008},{218,66,482},{150,89,496}}, + {{236,18,3907},{176,89,4008},{226,66,482},{158,89,496}}, + {{158,90,4085},{103,31,4080},{158,90,501},{103,31,496}}, + {{166,90,4085},{111,31,4080},{166,90,501},{111,31,496}}, + {{0,70,3328},{0,70,3328},{0,17,448},{0,17,448}}, + {{0,117,3904},{0,117,3904},{0,35,384},{0,35,384}}, + {{13,165,3905},{13,165,3904},{2,211,480},{2,211,480}}, + {{21,165,3906},{21,165,3904},{1,51,488},{1,51,488}}, + {{30,165,3906},{30,165,3904},{7,61,352},{7,61,352}}, + {{38,165,3906},{38,165,3904},{2,125,352},{2,125,352}}, + {{46,165,3906},{46,165,3904},{1,37,500},{10,125,352}}, + {{54,165,3906},{54,165,3904},{9,37,500},{5,61,424}}, + {{63,165,3906},{63,165,3904},{18,37,500},{1,189,424}}, + {{71,165,3906},{71,165,3904},{26,37,500},{9,189,424}}, + {{79,165,3906},{79,165,3904},{34,37,500},{4,77,424}}, + {{87,165,3906},{87,165,3904},{42,37,500},{12,77,424}}, + {{96,165,3906},{96,165,3904},{51,37,500},{8,93,424}}, + {{104,165,3906},{104,165,3904},{59,37,500},{3,141,496}}, + {{112,165,3906},{112,165,3904},{68,37,500},{11,141,496}}, + {{120,165,3906},{120,165,3904},{76,37,500},{6,93,496}}, + {{129,165,3906},{129,165,3904},{85,37,500},{15,93,496}}, + {{70,254,4012},{137,165,3904},{93,37,500},{23,93,496}}, + {{145,165,3906},{145,165,3904},{101,37,500},{31,93,496}}, + {{86,254,4012},{153,165,3904},{109,37,500},{39,93,496}}, + {{163,165,3906},{162,165,3904},{118,37,500},{48,93,496}}, + {{171,165,3906},{170,165,3904},{126,37,500},{56,93,496}}, + {{179,165,3906},{178,165,3904},{134,37,500},{64,93,496}}, + {{187,165,3906},{187,165,3904},{142,37,500},{72,93,496}}, + {{196,165,3906},{196,165,3904},{151,37,500},{81,93,496}}, + {{204,165,3906},{204,165,3904},{159,37,500},{89,93,496}}, + {{212,165,3906},{136,77,4008},{167,37,500},{97,93,496}}, + {{220,165,3906},{131,93,4008},{175,37,500},{105,93,496}}, + {{214,181,4001},{140,93,4008},{184,37,500},{114,93,496}}, + {{222,181,4001},{148,93,4008},{192,37,500},{122,93,496}}, + {{115,95,4085},{99,31,4080},{115,95,501},{99,31,496}}, + {{123,95,4085},{107,31,4080},{123,95,501},{107,31,496}}, + {{0,102,3840},{0,102,3840},{0,18,384},{0,18,384}}, + {{5,167,3904},{5,167,3904},{0,13,256},{0,13,256}}, + {{4,54,3968},{4,54,3968},{1,67,448},{1,67,448}}, + {{30,198,3850},{30,198,3848},{0,3,480},{0,3,480}}, + {{39,198,3850},{39,198,3848},{3,52,488},{3,52,488}}, + {{47,198,3851},{47,198,3848},{3,4,488},{3,4,488}}, + {{55,198,3851},{55,198,3848},{1,70,488},{1,70,488}}, + {{53,167,3906},{63,198,3848},{3,22,488},{3,22,488}}, + {{62,167,3906},{72,198,3848},{24,118,488},{0,6,496}}, + {{70,167,3906},{80,198,3848},{32,118,488},{2,89,488}}, + {{78,167,3906},{88,198,3848},{40,118,488},{1,73,496}}, + {{86,167,3906},{96,198,3848},{48,118,488},{0,28,424}}, + {{95,167,3906},{105,198,3848},{57,118,488},{9,28,424}}, + {{103,167,3906},{113,198,3848},{65,118,488},{5,108,496}}, + {{111,167,3906},{121,198,3848},{73,118,488},{13,108,496}}, + {{119,167,3906},{129,198,3848},{81,118,488},{21,108,496}}, + {{128,167,3906},{138,198,3848},{90,118,488},{6,28,496}}, + {{136,167,3906},{146,198,3848},{98,118,488},{14,28,496}}, + {{145,167,3906},{154,198,3848},{106,118,488},{22,28,496}}, + {{153,167,3906},{162,198,3848},{114,118,488},{30,28,496}}, + {{162,167,3906},{171,198,3848},{123,118,488},{39,28,496}}, + {{170,167,3906},{179,198,3848},{131,118,488},{47,28,496}}, + {{178,167,3906},{187,198,3848},{139,118,488},{55,28,496}}, + {{186,167,3906},{195,198,3848},{147,118,488},{63,28,496}}, + {{194,167,3906},{120,12,4008},{156,118,488},{72,28,496}}, + {{206,198,3907},{116,28,4008},{164,118,488},{80,28,496}}, + {{214,198,3907},{124,28,4008},{172,118,488},{88,28,496}}, + {{222,198,3395},{132,28,4008},{180,118,488},{96,28,496}}, + {{207,134,4001},{141,28,4008},{189,118,488},{105,28,496}}, + {{95,30,4085},{86,31,4080},{95,30,501},{86,31,496}}, + {{103,30,4085},{94,31,4080},{103,30,501},{94,31,496}}, + {{111,30,4085},{102,31,4080},{111,30,501},{102,31,496}}, + {{0,104,3840},{0,104,3840},{0,18,448},{0,18,448}}, + {{4,39,3904},{4,39,3904},{0,4,384},{0,4,384}}, + {{0,56,3968},{0,56,3968},{0,84,448},{0,84,448}}, + {{6,110,3328},{6,110,3328},{0,20,448},{0,20,448}}, + {{41,200,3850},{41,200,3848},{1,4,480},{1,4,480}}, + {{49,200,3850},{49,200,3848},{1,8,416},{1,8,416}}, + {{57,200,3851},{57,200,3848},{1,38,488},{1,38,488}}, + {{65,200,3851},{65,200,3848},{1,120,488},{1,120,488}}, + {{74,200,3851},{74,200,3848},{2,72,488},{2,72,488}}, + {{68,6,3907},{82,200,3848},{2,24,488},{2,24,488}}, + {{77,6,3907},{90,200,3848},{26,120,488},{10,24,488}}, + {{97,63,3330},{98,200,3848},{34,120,488},{2,8,496}}, + {{106,63,3330},{107,200,3848},{43,120,488},{3,92,488}}, + {{114,63,3330},{115,200,3848},{51,120,488},{11,92,488}}, + {{122,63,3330},{123,200,3848},{59,120,488},{7,76,496}}, + {{130,63,3330},{131,200,3848},{67,120,488},{15,76,496}}, + {{139,63,3330},{140,200,3848},{76,120,488},{24,76,496}}, + {{147,63,3330},{148,200,3848},{84,120,488},{32,76,496}}, + {{155,63,3330},{156,200,3848},{92,120,488},{40,76,496}}, + {{164,63,3330},{164,200,3848},{100,120,488},{48,76,496}}, + {{173,63,3330},{173,200,3848},{109,120,488},{57,76,496}}, + {{184,6,3851},{181,200,3848},{117,120,488},{65,76,496}}, + {{192,6,3851},{133,28,3936},{125,120,488},{73,76,496}}, + {{189,200,3907},{141,28,3936},{133,120,488},{81,76,496}}, + {{198,200,3907},{138,108,4000},{142,120,488},{90,76,496}}, + {{206,200,3907},{146,108,4000},{150,120,488},{98,76,496}}, + {{214,200,3395},{154,108,4000},{158,120,488},{106,76,496}}, + {{190,136,4001},{162,108,4000},{166,120,488},{114,76,496}}, + {{123,30,4076},{87,15,4080},{123,30,492},{87,15,496}}, + {{117,110,4084},{80,31,4080},{117,110,500},{80,31,496}}, + {{125,110,4084},{88,31,4080},{125,110,500},{88,31,496}}, + {{133,110,4084},{96,31,4080},{133,110,500},{96,31,496}}, + {{9,56,3904},{9,56,3904},{0,67,448},{0,67,448}}, + {{1,8,3904},{1,8,3904},{1,84,448},{1,84,448}}, + {{1,124,3904},{1,124,3904},{0,39,384},{0,39,384}}, + {{9,124,3904},{9,124,3904},{1,4,448},{1,4,448}}, + {{6,76,3904},{6,76,3904},{0,70,448},{0,70,448}}, + {{62,6,3859},{62,6,3856},{2,38,480},{2,38,480}}, + {{70,6,3859},{70,6,3856},{5,43,416},{5,43,416}}, + {{78,6,3859},{78,6,3856},{2,11,416},{2,11,416}}, + {{87,6,3859},{87,6,3856},{0,171,488},{0,171,488}}, + {{67,8,3906},{95,6,3856},{8,171,488},{8,171,488}}, + {{75,8,3907},{103,6,3856},{5,123,488},{5,123,488}}, + {{83,8,3907},{111,6,3856},{2,75,488},{2,75,488}}, + {{92,8,3907},{120,6,3856},{0,27,488},{0,27,488}}, + {{100,8,3907},{128,6,3856},{8,27,488},{8,27,488}}, + {{120,106,3843},{136,6,3856},{99,6,387},{16,27,488}}, + {{128,106,3843},{144,6,3856},{107,6,387},{2,11,496}}, + {{137,106,3843},{153,6,3856},{117,6,387},{11,11,496}}, + {{145,106,3843},{161,6,3856},{125,6,387},{19,11,496}}, + {{163,8,3851},{137,43,3904},{133,6,387},{27,11,496}}, + {{171,8,3851},{145,43,3904},{141,6,387},{35,11,496}}, + {{180,8,3851},{110,11,4000},{150,6,387},{44,11,496}}, + {{188,8,3851},{118,11,4000},{158,6,387},{52,11,496}}, + {{172,72,3907},{126,11,4000},{166,6,387},{60,11,496}}, + {{174,6,3971},{134,11,4000},{174,6,387},{68,11,496}}, + {{183,6,3971},{143,11,4000},{183,6,387},{77,11,496}}, + {{191,6,3971},{151,11,4000},{191,6,387},{85,11,496}}, + {{199,6,3971},{159,11,4000},{199,6,387},{93,11,496}}, + {{92,12,4084},{69,15,4080},{92,12,500},{69,15,496}}, + {{101,12,4084},{78,15,4080},{101,12,500},{78,15,496}}, + {{110,12,4084},{86,15,4080},{110,12,500},{86,15,496}}, + {{118,12,4084},{79,31,4080},{118,12,500},{79,31,496}}, + {{126,12,4084},{87,31,4080},{126,12,500},{87,31,496}}, + {{71,8,3602},{71,8,3600},{2,21,384},{2,21,384}}, + {{79,8,3611},{79,8,3608},{0,69,448},{0,69,448}}, + {{87,8,3611},{87,8,3608},{0,23,384},{0,23,384}}, + {{95,8,3611},{95,8,3608},{1,5,448},{1,5,448}}, + {{104,8,3611},{104,8,3608},{0,88,448},{0,88,448}}, + {{112,8,3611},{112,8,3608},{0,72,448},{0,72,448}}, + {{120,8,3611},{121,8,3608},{36,21,458},{36,21,456}}, + {{133,47,3091},{129,8,3608},{44,21,458},{44,21,456}}, + {{142,47,3091},{138,8,3608},{53,21,459},{53,21,456}}, + {{98,12,3850},{98,12,3848},{61,21,459},{61,21,456}}, + {{106,12,3850},{106,12,3848},{10,92,480},{69,21,456}}, + {{114,12,3851},{114,12,3848},{18,92,480},{77,21,456}}, + {{123,12,3851},{123,12,3848},{3,44,488},{86,21,456}}, + {{95,12,3906},{95,12,3904},{11,44,488},{94,21,456}}, + {{103,12,3906},{103,12,3904},{19,44,488},{102,21,456}}, + {{111,12,3907},{111,12,3904},{27,44,489},{110,21,456}}, + {{120,12,3907},{120,12,3904},{36,44,489},{119,21,456}}, + {{128,12,3907},{128,12,3904},{44,44,489},{127,21,456}}, + {{136,12,3907},{136,12,3904},{52,44,489},{135,21,456}}, + {{144,12,3907},{144,12,3904},{60,44,490},{144,21,456}}, + {{153,12,3907},{153,12,3904},{69,44,490},{153,21,456}}, + {{161,12,3395},{149,188,3968},{77,44,490},{161,21,456}}, + {{169,12,3395},{199,21,3928},{85,44,490},{169,21,456}}, + {{113,95,4001},{202,69,3992},{125,8,483},{177,21,456}}, + {{122,95,4001},{201,21,3984},{134,8,483},{186,21,456}}, + {{143,8,4067},{209,21,3984},{142,8,483},{194,21,456}}, + {{151,8,4067},{47,15,4080},{151,8,483},{47,15,496}}, + {{159,8,4067},{55,15,4080},{159,8,483},{55,15,496}}, + {{168,8,4067},{64,15,4080},{168,8,483},{64,15,496}}, + {{160,40,4075},{72,15,4080},{160,40,491},{72,15,496}}, + {{168,40,4075},{80,15,4080},{168,40,491},{80,15,496}}, + {{144,8,4082},{88,15,4080},{144,8,498},{88,15,496}}, + }; + + static void convert_etc1s_to_etc2_eac_r11(eac_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector) + { + const uint32_t low_selector = pSelector->m_lo_selector; + const uint32_t high_selector = pSelector->m_hi_selector; + + const color32& base_color = pEndpoints->m_color5; + const uint32_t inten_table = pEndpoints->m_inten5; + + if (low_selector == high_selector) + { + uint32_t r; + decoder_etc_block::get_block_color5_r(base_color, inten_table, low_selector, r); + + // Constant alpha block + // Select table 13, use selector 4 (0), set multiplier to 1 and base color r + pDst_block->m_base = r; + pDst_block->m_table = 13; + pDst_block->m_multiplier = 1; + + // selectors are all 4's + static const uint8_t s_etc2_eac_r11_sel4[6] = { 0x92, 0x49, 0x24, 0x92, 0x49, 0x24 }; + memcpy(pDst_block->m_selectors, s_etc2_eac_r11_sel4, sizeof(s_etc2_eac_r11_sel4)); + + return; + } + + uint32_t selector_range_table = 0; + for (selector_range_table = 0; selector_range_table < NUM_ETC2_EAC_SELECTOR_RANGES; selector_range_table++) + if ((low_selector == s_etc2_eac_selector_ranges[selector_range_table].m_low) && (high_selector == s_etc2_eac_selector_ranges[selector_range_table].m_high)) + break; + if (selector_range_table >= NUM_ETC2_EAC_SELECTOR_RANGES) + selector_range_table = 0; + + const etc1_g_to_eac_conversion* pTable_entry = &s_etc1_g_to_etc2_r11[base_color.r + inten_table * 32][selector_range_table]; + + pDst_block->m_base = pTable_entry->m_base; + pDst_block->m_table = pTable_entry->m_table_mul >> 4; + pDst_block->m_multiplier = pTable_entry->m_table_mul & 15; + + uint64_t selector_bits = 0; + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + uint32_t s = pSelector->get_selector(x, y); + + uint32_t ds = (pTable_entry->m_trans >> (s * 3)) & 7; + + const uint32_t dst_ofs = 45 - (y + x * 4) * 3; + selector_bits |= (static_cast<uint64_t>(ds) << dst_ofs); + } + } + + pDst_block->set_selector_bits(selector_bits); + } +#endif // BASISD_SUPPORT_ETC2_EAC_RG11 + // ASTC struct etc1_to_astc_solution { @@ -5563,6 +6213,7 @@ namespace basist #endif #if BASISD_SUPPORT_ATC + // ATC and PVRTC2 both use these tables. struct etc1s_to_atc_solution { uint8_t m_lo; @@ -5600,6 +6251,16 @@ namespace basist }; const uint32_t ATC_IDENTITY_SELECTOR_MAPPING_INDEX = 6; +#if BASISD_SUPPORT_PVRTC2 + static const etc1s_to_atc_solution g_etc1s_to_pvrtc2_45[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = { +#include "basisu_transcoder_tables_pvrtc2_45.inc" + }; + + static const etc1s_to_atc_solution g_etc1s_to_pvrtc2_alpha_33[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = { +#include "basisu_transcoder_tables_pvrtc2_alpha_33.inc" + }; +#endif + static const etc1s_to_atc_solution g_etc1s_to_atc_55[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = { #include "basisu_transcoder_tables_atc_55.inc" }; @@ -5613,8 +6274,8 @@ namespace basist uint8_t m_lo; uint8_t m_hi; }; - static atc_match_entry g_atc_match55_equals_1[256], g_atc_match56_equals_1[256]; // selector 1 - static atc_match_entry g_atc_match5[256], g_atc_match6[256]; + static atc_match_entry g_pvrtc2_match45_equals_1[256], g_atc_match55_equals_1[256], g_atc_match56_equals_1[256]; // selector 1 + static atc_match_entry g_pvrtc2_match4[256], g_atc_match5[256], g_atc_match6[256]; static void prepare_atc_single_color_table(atc_match_entry* pTable, int size0, int size1, int sel) { @@ -5624,7 +6285,12 @@ namespace basist for (int lo = 0; lo < size0; lo++) { int lo_e = lo; - if (size0 == 32) + if (size0 == 16) + { + lo_e = (lo_e << 1) | (lo_e >> 3); + lo_e = (lo_e << 3) | (lo_e >> 2); + } + else if (size0 == 32) lo_e = (lo_e << 3) | (lo_e >> 2); else lo_e = (lo_e << 2) | (lo_e >> 4); @@ -5632,7 +6298,13 @@ namespace basist for (int hi = 0; hi < size1; hi++) { int hi_e = hi; - if (size1 == 32) + if (size1 == 16) + { + // This is only for PVRTC2 - expand to 5 then 8 + hi_e = (hi_e << 1) | (hi_e >> 3); + hi_e = (hi_e << 3) | (hi_e >> 2); + } + else if (size1 == 32) hi_e = (hi_e << 3) | (hi_e >> 2); else hi_e = (hi_e << 2) | (hi_e >> 4); @@ -5667,9 +6339,11 @@ namespace basist static void transcoder_init_atc() { - prepare_atc_single_color_table(g_atc_match55_equals_1, 32, 32, 1); - prepare_atc_single_color_table(g_atc_match56_equals_1, 32, 64, 1); + prepare_atc_single_color_table(g_pvrtc2_match45_equals_1, 16, 32, 1); + prepare_atc_single_color_table(g_atc_match55_equals_1, 32, 32, 1); + prepare_atc_single_color_table(g_atc_match56_equals_1, 32, 64, 1); + prepare_atc_single_color_table(g_pvrtc2_match4, 1, 16, 3); prepare_atc_single_color_table(g_atc_match5, 1, 32, 3); prepare_atc_single_color_table(g_atc_match6, 1, 64, 3); @@ -5813,6 +6487,7 @@ namespace basist #if BASISD_WRITE_NEW_ATC_TABLES static void create_etc1s_to_atc_conversion_tables() { + // ATC 55 FILE* pFile = nullptr; fopen_s(&pFile, "basisu_transcoder_tables_atc_55.inc", "w"); @@ -5887,6 +6562,7 @@ namespace basist fclose(pFile); pFile = nullptr; + // ATC 56 fopen_s(&pFile, "basisu_transcoder_tables_atc_56.inc", "w"); n = 0; @@ -5958,11 +6634,1140 @@ namespace basist } // inten fclose(pFile); + + // PVRTC2 45 + fopen_s(&pFile, "basisu_transcoder_tables_pvrtc2_45.inc", "w"); + + n = 0; + + for (int inten = 0; inten < 8; inten++) + { + for (uint32_t g = 0; g < 32; g++) + { + color32 block_colors[4]; + decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten); + + for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++) + { + const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low; + const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high; + + for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++) + { + uint32_t best_lo = 0; + uint32_t best_hi = 0; + uint64_t best_err = UINT64_MAX; + + for (uint32_t hi = 0; hi <= 31; hi++) + { + for (uint32_t lo = 0; lo <= 15; lo++) + { + uint32_t colors[4]; + + colors[0] = (lo << 1) | (lo >> 3); + colors[0] = (colors[0] << 3) | (colors[0] >> 2); + + colors[3] = (hi << 3) | (hi >> 2); + + colors[1] = (colors[0] * 5 + colors[3] * 3) / 8; + colors[2] = (colors[3] * 5 + colors[0] * 3) / 8; + + uint64_t total_err = 0; + + for (uint32_t s = low_selector; s <= high_selector; s++) + { + int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]]; + + int err_scale = 1; + // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor + // the low/high selectors which are clamping to either 0 or 255. + if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3))) + err_scale = 5; + + total_err += (err * err) * err_scale; + } + + if (total_err < best_err) + { + best_err = total_err; + best_lo = lo; + best_hi = hi; + } + } + } + + //assert(best_err <= 0xFFFF); + best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF); + + fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err); + n++; + if ((n & 31) == 31) + fprintf(pFile, "\n"); + } // m + } // sr + } // g + } // inten + + fclose(pFile); + +#if 0 + // PVRTC2 34 + fopen_s(&pFile, "basisu_transcoder_tables_pvrtc2_34.inc", "w"); + + n = 0; + + for (int inten = 0; inten < 8; inten++) + { + for (uint32_t g = 0; g < 32; g++) + { + color32 block_colors[4]; + decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten); + + for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++) + { + const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low; + const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high; + + for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++) + { + uint32_t best_lo = 0; + uint32_t best_hi = 0; + uint64_t best_err = UINT64_MAX; + + for (uint32_t hi = 0; hi <= 15; hi++) + { + for (uint32_t lo = 0; lo <= 7; lo++) + { + uint32_t colors[4]; + + colors[0] = (lo << 2) | (lo >> 1); + colors[0] = (colors[0] << 3) | (colors[0] >> 2); + + colors[3] = (hi << 1) | (hi >> 3); + colors[3] = (colors[3] << 3) | (colors[3] >> 2); + + colors[1] = (colors[0] * 5 + colors[3] * 3) / 8; + colors[2] = (colors[3] * 5 + colors[0] * 3) / 8; + + uint64_t total_err = 0; + + for (uint32_t s = low_selector; s <= high_selector; s++) + { + int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]]; + + int err_scale = 1; + // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor + // the low/high selectors which are clamping to either 0 or 255. + if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3))) + err_scale = 5; + + total_err += (err * err) * err_scale; + } + + if (total_err < best_err) + { + best_err = total_err; + best_lo = lo; + best_hi = hi; + } + } + } + + //assert(best_err <= 0xFFFF); + best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF); + + fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err); + n++; + if ((n & 31) == 31) + fprintf(pFile, "\n"); + } // m + } // sr + } // g + } // inten + + fclose(pFile); +#endif +#if 0 + // PVRTC2 44 + fopen_s(&pFile, "basisu_transcoder_tables_pvrtc2_44.inc", "w"); + + n = 0; + + for (int inten = 0; inten < 8; inten++) + { + for (uint32_t g = 0; g < 32; g++) + { + color32 block_colors[4]; + decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten); + + for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++) + { + const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low; + const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high; + + for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++) + { + uint32_t best_lo = 0; + uint32_t best_hi = 0; + uint64_t best_err = UINT64_MAX; + + for (uint32_t hi = 0; hi <= 15; hi++) + { + for (uint32_t lo = 0; lo <= 15; lo++) + { + uint32_t colors[4]; + + colors[0] = (lo << 1) | (lo >> 3); + colors[0] = (colors[0] << 3) | (colors[0] >> 2); + + colors[3] = (hi << 1) | (hi >> 3); + colors[3] = (colors[3] << 3) | (colors[3] >> 2); + + colors[1] = (colors[0] * 5 + colors[3] * 3) / 8; + colors[2] = (colors[3] * 5 + colors[0] * 3) / 8; + + uint64_t total_err = 0; + + for (uint32_t s = low_selector; s <= high_selector; s++) + { + int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]]; + + int err_scale = 1; + // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor + // the low/high selectors which are clamping to either 0 or 255. + if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3))) + err_scale = 5; + + total_err += (err * err) * err_scale; + } + + if (total_err < best_err) + { + best_err = total_err; + best_lo = lo; + best_hi = hi; + } + } + } + + //assert(best_err <= 0xFFFF); + best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF); + + fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err); + n++; + if ((n & 31) == 31) + fprintf(pFile, "\n"); + } // m + } // sr + } // g + } // inten + + fclose(pFile); +#endif + + // PVRTC2 alpha 33 + fopen_s(&pFile, "basisu_transcoder_tables_pvrtc2_alpha_33.inc", "w"); + + n = 0; + + for (int inten = 0; inten < 8; inten++) + { + for (uint32_t g = 0; g < 32; g++) + { + color32 block_colors[4]; + decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten); + + for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++) + { + const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low; + const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high; + + for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++) + { + uint32_t best_lo = 0; + uint32_t best_hi = 0; + uint64_t best_err = UINT64_MAX; + + for (uint32_t hi = 0; hi <= 7; hi++) + { + for (uint32_t lo = 0; lo <= 7; lo++) + { + uint32_t colors[4]; + + colors[0] = (lo << 1); + colors[0] = (colors[0] << 4) | colors[0]; + + colors[3] = (hi << 1) | 1; + colors[3] = (colors[3] << 4) | colors[3]; + + colors[1] = (colors[0] * 5 + colors[3] * 3) / 8; + colors[2] = (colors[3] * 5 + colors[0] * 3) / 8; + + uint64_t total_err = 0; + + for (uint32_t s = low_selector; s <= high_selector; s++) + { + int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]]; + + int err_scale = 1; + // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor + // the low/high selectors which are clamping to either 0 or 255. + if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3))) + err_scale = 5; + + total_err += (err * err) * err_scale; + } + + if (total_err < best_err) + { + best_err = total_err; + best_lo = lo; + best_hi = hi; + } + } + } + + //assert(best_err <= 0xFFFF); + best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF); + + fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err); + n++; + if ((n & 31) == 31) + fprintf(pFile, "\n"); + } // m + } // sr + } // g + } // inten + + fclose(pFile); } #endif // BASISD_WRITE_NEW_ATC_TABLES #endif // BASISD_SUPPORT_ATC +#if BASISD_SUPPORT_PVRTC2 + struct pvrtc2_block + { + uint8_t m_modulation[4]; + + union + { + union + { + // Opaque mode: RGB colora=554 and colorb=555 + struct + { + uint32_t m_mod_flag : 1; + uint32_t m_blue_a : 4; + uint32_t m_green_a : 5; + uint32_t m_red_a : 5; + uint32_t m_hard_flag : 1; + uint32_t m_blue_b : 5; + uint32_t m_green_b : 5; + uint32_t m_red_b : 5; + uint32_t m_opaque_flag : 1; + + } m_opaque_color_data; + + // Transparent mode: RGBA colora=4433 and colorb=4443 + struct + { + uint32_t m_mod_flag : 1; + uint32_t m_blue_a : 3; + uint32_t m_green_a : 4; + uint32_t m_red_a : 4; + uint32_t m_alpha_a : 3; + uint32_t m_hard_flag : 1; + uint32_t m_blue_b : 4; + uint32_t m_green_b : 4; + uint32_t m_red_b : 4; + uint32_t m_alpha_b : 3; + uint32_t m_opaque_flag : 1; + + } m_trans_color_data; + }; + + uint32_t m_color_data_bits; + }; + + // 554 + void set_low_color(uint32_t r, uint32_t g, uint32_t b) + { + assert((r < 32) && (g < 32) && (b < 16)); + m_opaque_color_data.m_red_a = r; + m_opaque_color_data.m_green_a = g; + m_opaque_color_data.m_blue_a = b; + } + + // 555 + void set_high_color(uint32_t r, uint32_t g, uint32_t b) + { + assert((r < 32) && (g < 32) && (b < 32)); + m_opaque_color_data.m_red_b = r; + m_opaque_color_data.m_green_b = g; + m_opaque_color_data.m_blue_b = b; + } + + // 4433 + void set_trans_low_color(uint32_t r, uint32_t g, uint32_t b, uint32_t a) + { + assert((r < 16) && (g < 16) && (b < 8) && (a < 8)); + m_trans_color_data.m_red_a = r; + m_trans_color_data.m_green_a = g; + m_trans_color_data.m_blue_a = b; + m_trans_color_data.m_alpha_a = a; + } + + // 4443 + void set_trans_high_color(uint32_t r, uint32_t g, uint32_t b, uint32_t a) + { + assert((r < 16) && (g < 16) && (b < 16) && (a < 8)); + m_trans_color_data.m_red_b = r; + m_trans_color_data.m_green_b = g; + m_trans_color_data.m_blue_b = b; + m_trans_color_data.m_alpha_b = a; + } + }; + + static struct + { + uint8_t m_l, m_h; + } g_pvrtc2_trans_match34[256]; + + static struct + { + uint8_t m_l, m_h; + } g_pvrtc2_trans_match44[256]; + + static struct + { + uint8_t m_l, m_h; + } g_pvrtc2_alpha_match33[256]; + + static struct + { + uint8_t m_l, m_h; + } g_pvrtc2_alpha_match33_0[256]; + + static struct + { + uint8_t m_l, m_h; + } g_pvrtc2_alpha_match33_3[256]; + + // PVRTC2 can be forced to look like a slightly weaker variant of ATC/BC1, so that's what we do here for simplicity. + static void convert_etc1s_to_pvrtc2_rgb(void* pDst, const endpoint* pEndpoints, const selector* pSelector) + { + pvrtc2_block* pBlock = static_cast<pvrtc2_block*>(pDst); + + pBlock->m_opaque_color_data.m_hard_flag = 1; + pBlock->m_opaque_color_data.m_mod_flag = 0; + pBlock->m_opaque_color_data.m_opaque_flag = 1; + + const uint32_t low_selector = pSelector->m_lo_selector; + const uint32_t high_selector = pSelector->m_hi_selector; + + const color32& base_color = pEndpoints->m_color5; + const uint32_t inten_table = pEndpoints->m_inten5; + + if (low_selector == high_selector) + { + uint32_t r, g, b; + decoder_etc_block::get_block_color5(base_color, inten_table, low_selector, r, g, b); + + pBlock->set_low_color(g_atc_match55_equals_1[r].m_lo, g_atc_match55_equals_1[g].m_lo, g_pvrtc2_match45_equals_1[b].m_lo); + pBlock->set_high_color(g_atc_match55_equals_1[r].m_hi, g_atc_match55_equals_1[g].m_hi, g_pvrtc2_match45_equals_1[b].m_hi); + + pBlock->m_modulation[0] = 0x55; + pBlock->m_modulation[1] = 0x55; + pBlock->m_modulation[2] = 0x55; + pBlock->m_modulation[3] = 0x55; + + return; + } + else if ((inten_table >= 7) && (pSelector->m_num_unique_selectors == 2) && (pSelector->m_lo_selector == 0) && (pSelector->m_hi_selector == 3)) + { + color32 block_colors[4]; + decoder_etc_block::get_block_colors5(block_colors, base_color, inten_table); + + const uint32_t r0 = block_colors[0].r; + const uint32_t g0 = block_colors[0].g; + const uint32_t b0 = block_colors[0].b; + + const uint32_t r1 = block_colors[3].r; + const uint32_t g1 = block_colors[3].g; + const uint32_t b1 = block_colors[3].b; + + pBlock->set_low_color(g_atc_match5[r0].m_hi, g_atc_match5[g0].m_hi, g_pvrtc2_match4[b0].m_hi); + pBlock->set_high_color(g_atc_match5[r1].m_hi, g_atc_match5[g1].m_hi, g_atc_match5[b1].m_hi); + + pBlock->m_modulation[0] = pSelector->m_selectors[0]; + pBlock->m_modulation[1] = pSelector->m_selectors[1]; + pBlock->m_modulation[2] = pSelector->m_selectors[2]; + pBlock->m_modulation[3] = pSelector->m_selectors[3]; + + return; + } + + const uint32_t selector_range_table = g_etc1s_to_atc_selector_range_index[low_selector][high_selector]; + + //[32][8][RANGES][MAPPING] + const etc1s_to_atc_solution* pTable_r = &g_etc1s_to_atc_55[(inten_table * 32 + base_color.r) * (NUM_ETC1S_TO_ATC_SELECTOR_RANGES * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS]; + const etc1s_to_atc_solution* pTable_g = &g_etc1s_to_atc_55[(inten_table * 32 + base_color.g) * (NUM_ETC1S_TO_ATC_SELECTOR_RANGES * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS]; + const etc1s_to_atc_solution* pTable_b = &g_etc1s_to_pvrtc2_45[(inten_table * 32 + base_color.b) * (NUM_ETC1S_TO_ATC_SELECTOR_RANGES * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS]; + + uint32_t best_err = UINT_MAX; + uint32_t best_mapping = 0; + + assert(NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS == 10); +#define DO_ITER(m) { uint32_t total_err = pTable_r[m].m_err + pTable_g[m].m_err + pTable_b[m].m_err; if (total_err < best_err) { best_err = total_err; best_mapping = m; } } + DO_ITER(0); DO_ITER(1); DO_ITER(2); DO_ITER(3); DO_ITER(4); + DO_ITER(5); DO_ITER(6); DO_ITER(7); DO_ITER(8); DO_ITER(9); +#undef DO_ITER + + pBlock->set_low_color(pTable_r[best_mapping].m_lo, pTable_g[best_mapping].m_lo, pTable_b[best_mapping].m_lo); + pBlock->set_high_color(pTable_r[best_mapping].m_hi, pTable_g[best_mapping].m_hi, pTable_b[best_mapping].m_hi); + + if (ATC_IDENTITY_SELECTOR_MAPPING_INDEX == best_mapping) + { + pBlock->m_modulation[0] = pSelector->m_selectors[0]; + pBlock->m_modulation[1] = pSelector->m_selectors[1]; + pBlock->m_modulation[2] = pSelector->m_selectors[2]; + pBlock->m_modulation[3] = pSelector->m_selectors[3]; + } + else + { + // TODO: We could make this faster using several precomputed 256 entry tables, like ETC1S->BC1 does. + const uint8_t* pSelectors_xlat = &g_etc1s_to_atc_selector_mappings[best_mapping][0]; + + const uint32_t sel_bits0 = pSelector->m_selectors[0]; + const uint32_t sel_bits1 = pSelector->m_selectors[1]; + const uint32_t sel_bits2 = pSelector->m_selectors[2]; + const uint32_t sel_bits3 = pSelector->m_selectors[3]; + + uint32_t sels0 = 0, sels1 = 0, sels2 = 0, sels3 = 0; + +#define DO_X(x) { \ + const uint32_t x_shift = (x) * 2; \ + sels0 |= (pSelectors_xlat[(sel_bits0 >> x_shift) & 3] << x_shift); \ + sels1 |= (pSelectors_xlat[(sel_bits1 >> x_shift) & 3] << x_shift); \ + sels2 |= (pSelectors_xlat[(sel_bits2 >> x_shift) & 3] << x_shift); \ + sels3 |= (pSelectors_xlat[(sel_bits3 >> x_shift) & 3] << x_shift); } + + DO_X(0); + DO_X(1); + DO_X(2); + DO_X(3); +#undef DO_X + + pBlock->m_modulation[0] = (uint8_t)sels0; + pBlock->m_modulation[1] = (uint8_t)sels1; + pBlock->m_modulation[2] = (uint8_t)sels2; + pBlock->m_modulation[3] = (uint8_t)sels3; + } + } + + typedef struct { float c[4]; } vec4F; + + static inline int32_t clampi(int32_t value, int32_t low, int32_t high) { if (value < low) value = low; else if (value > high) value = high; return value; } + static inline float clampf(float value, float low, float high) { if (value < low) value = low; else if (value > high) value = high; return value; } + static inline float saturate(float value) { return clampf(value, 0, 1.0f); } + static inline vec4F* vec4F_set_scalar(vec4F* pV, float x) { pV->c[0] = x; pV->c[1] = x; pV->c[2] = x; pV->c[3] = x; return pV; } + static inline vec4F* vec4F_set(vec4F* pV, float x, float y, float z, float w) { pV->c[0] = x; pV->c[1] = y; pV->c[2] = z; pV->c[3] = w; return pV; } + static inline vec4F* vec4F_saturate_in_place(vec4F* pV) { pV->c[0] = saturate(pV->c[0]); pV->c[1] = saturate(pV->c[1]); pV->c[2] = saturate(pV->c[2]); pV->c[3] = saturate(pV->c[3]); return pV; } + static inline vec4F vec4F_saturate(const vec4F* pV) { vec4F res; res.c[0] = saturate(pV->c[0]); res.c[1] = saturate(pV->c[1]); res.c[2] = saturate(pV->c[2]); res.c[3] = saturate(pV->c[3]); return res; } + static inline vec4F vec4F_from_color(const color32* pC) { vec4F res; vec4F_set(&res, pC->c[0], pC->c[1], pC->c[2], pC->c[3]); return res; } + static inline vec4F vec4F_add(const vec4F* pLHS, const vec4F* pRHS) { vec4F res; vec4F_set(&res, pLHS->c[0] + pRHS->c[0], pLHS->c[1] + pRHS->c[1], pLHS->c[2] + pRHS->c[2], pLHS->c[3] + pRHS->c[3]); return res; } + static inline vec4F vec4F_sub(const vec4F* pLHS, const vec4F* pRHS) { vec4F res; vec4F_set(&res, pLHS->c[0] - pRHS->c[0], pLHS->c[1] - pRHS->c[1], pLHS->c[2] - pRHS->c[2], pLHS->c[3] - pRHS->c[3]); return res; } + static inline float vec4F_dot(const vec4F* pLHS, const vec4F* pRHS) { return pLHS->c[0] * pRHS->c[0] + pLHS->c[1] * pRHS->c[1] + pLHS->c[2] * pRHS->c[2] + pLHS->c[3] * pRHS->c[3]; } + static inline vec4F vec4F_mul(const vec4F* pLHS, float s) { vec4F res; vec4F_set(&res, pLHS->c[0] * s, pLHS->c[1] * s, pLHS->c[2] * s, pLHS->c[3] * s); return res; } + static inline vec4F* vec4F_normalize_in_place(vec4F* pV) { float s = pV->c[0] * pV->c[0] + pV->c[1] * pV->c[1] + pV->c[2] * pV->c[2] + pV->c[3] * pV->c[3]; if (s != 0.0f) { s = 1.0f / sqrtf(s); pV->c[0] *= s; pV->c[1] *= s; pV->c[2] *= s; pV->c[3] *= s; } return pV; } + + static color32 convert_rgba_5554_to_8888(const color32& col) + { + return color32((col[0] << 3) | (col[0] >> 2), (col[1] << 3) | (col[1] >> 2), (col[2] << 3) | (col[2] >> 2), (col[3] << 4) | col[3]); + } + + static inline int sq(int x) { return x * x; } + + // PVRTC2 is a slightly borked format for alpha: In Non-Interpolated mode, the way AlphaB8 is exanded from 4 to 8 bits means it can never be 0. + // This is actually very bad, because on 100% transparent blocks which have non-trivial color pixels, part of the color channel will leak into alpha! + // And there's nothing straightforward we can do because using the other modes is too expensive/complex. I can see why Apple didn't adopt it. + static void convert_etc1s_to_pvrtc2_rgba(void* pDst, const endpoint* pEndpoints, const selector* pSelector, const endpoint* pEndpoint_codebook, const selector* pSelector_codebook) + { + pvrtc2_block* pBlock = static_cast<pvrtc2_block*>(pDst); + + const endpoint& alpha_endpoint = pEndpoint_codebook[((uint16_t*)pBlock)[0]]; + const selector& alpha_selectors = pSelector_codebook[((uint16_t*)pBlock)[1]]; + + pBlock->m_opaque_color_data.m_hard_flag = 1; + pBlock->m_opaque_color_data.m_mod_flag = 0; + pBlock->m_opaque_color_data.m_opaque_flag = 0; + + const int num_unique_alpha_selectors = alpha_selectors.m_num_unique_selectors; + + const color32& alpha_base_color = alpha_endpoint.m_color5; + const uint32_t alpha_inten_table = alpha_endpoint.m_inten5; + + int constant_alpha_val = -1; + + int alpha_block_colors[4]; + decoder_etc_block::get_block_colors5_g(alpha_block_colors, alpha_base_color, alpha_inten_table); + + if (num_unique_alpha_selectors == 1) + { + constant_alpha_val = alpha_block_colors[alpha_selectors.m_lo_selector]; + } + else + { + constant_alpha_val = alpha_block_colors[alpha_selectors.m_lo_selector]; + + for (uint32_t i = alpha_selectors.m_lo_selector + 1; i <= alpha_selectors.m_hi_selector; i++) + { + if (constant_alpha_val != alpha_block_colors[i]) + { + constant_alpha_val = -1; + break; + } + } + } + + if (constant_alpha_val >= 250) + { + // It's opaque enough, so don't bother trying to encode it as an alpha block. + convert_etc1s_to_pvrtc2_rgb(pDst, pEndpoints, pSelector); + return; + } + + const color32& base_color = pEndpoints->m_color5; + const uint32_t inten_table = pEndpoints->m_inten5; + + const uint32_t low_selector = pSelector->m_lo_selector; + const uint32_t high_selector = pSelector->m_hi_selector; + + const int num_unique_color_selectors = pSelector->m_num_unique_selectors; + + // We need to reencode the block at the pixel level, unfortunately, from two ETC1S planes. + // Do 4D incremental PCA, project all pixels to this hyperline, then quantize to packed endpoints and compute the modulation values. + const int br = (base_color.r << 3) | (base_color.r >> 2); + const int bg = (base_color.g << 3) | (base_color.g >> 2); + const int bb = (base_color.b << 3) | (base_color.b >> 2); + + color32 block_cols[4]; + for (uint32_t i = 0; i < 4; i++) + { + const int ci = g_etc1_inten_tables[inten_table][i]; + block_cols[i].set_clamped(br + ci, bg + ci, bb + ci, alpha_block_colors[i]); + } + + bool solid_color_block = true; + if (num_unique_color_selectors > 1) + { + for (uint32_t i = low_selector + 1; i <= high_selector; i++) + { + if ((block_cols[low_selector].r != block_cols[i].r) || (block_cols[low_selector].g != block_cols[i].g) || (block_cols[low_selector].b != block_cols[i].b)) + { + solid_color_block = false; + break; + } + } + } + + if ((solid_color_block) && (constant_alpha_val >= 0)) + { + // Constant color/alpha block. + // This is more complex than it may seem because of the way color and alpha are packed in PVRTC2. We need to evaluate mod0, mod1 and mod3 encodings to find the best one. + uint32_t r, g, b; + decoder_etc_block::get_block_color5(base_color, inten_table, low_selector, r, g, b); + + // Mod 0 + uint32_t lr0 = (r * 15 + 128) / 255, lg0 = (g * 15 + 128) / 255, lb0 = (b * 7 + 128) / 255; + uint32_t la0 = g_pvrtc2_alpha_match33_0[constant_alpha_val].m_l; + + uint32_t cr0 = (lr0 << 1) | (lr0 >> 3); + uint32_t cg0 = (lg0 << 1) | (lg0 >> 3); + uint32_t cb0 = (lb0 << 2) | (lb0 >> 1); + uint32_t ca0 = (la0 << 1); + + cr0 = (cr0 << 3) | (cr0 >> 2); + cg0 = (cg0 << 3) | (cg0 >> 2); + cb0 = (cb0 << 3) | (cb0 >> 2); + ca0 = (ca0 << 4) | ca0; + + uint32_t err0 = sq(cr0 - r) + sq(cg0 - g) + sq(cb0 - b) + sq(ca0 - constant_alpha_val) * 2; + + // If the alpha is < 3 or so we're kinda screwed. It's better to have some RGB error than it is to turn a 100% transparent area slightly opaque. + if ((err0 == 0) || (constant_alpha_val < 3)) + { + pBlock->set_trans_low_color(lr0, lg0, lb0, la0); + pBlock->set_trans_high_color(0, 0, 0, 0); + + pBlock->m_modulation[0] = 0; + pBlock->m_modulation[1] = 0; + pBlock->m_modulation[2] = 0; + pBlock->m_modulation[3] = 0; + return; + } + + // Mod 3 + uint32_t lr3 = (r * 15 + 128) / 255, lg3 = (g * 15 + 128) / 255, lb3 = (b * 15 + 128) / 255; + uint32_t la3 = g_pvrtc2_alpha_match33_3[constant_alpha_val].m_l; + + uint32_t cr3 = (lr3 << 1) | (lr3 >> 3); + uint32_t cg3 = (lg3 << 1) | (lg3 >> 3); + uint32_t cb3 = (lb3 << 1) | (lb3 >> 3); + uint32_t ca3 = (la3 << 1) | 1; + + cr3 = (cr3 << 3) | (cr3 >> 2); + cg3 = (cg3 << 3) | (cg3 >> 2); + cb3 = (cb3 << 3) | (cb3 >> 2); + ca3 = (ca3 << 4) | ca3; + + uint32_t err3 = sq(cr3 - r) + sq(cg3 - g) + sq(cb3 - b) + sq(ca3 - constant_alpha_val) * 2; + + // Mod 1 + uint32_t lr1 = g_pvrtc2_trans_match44[r].m_l, lg1 = g_pvrtc2_trans_match44[g].m_l, lb1 = g_pvrtc2_trans_match34[b].m_l; + uint32_t hr1 = g_pvrtc2_trans_match44[r].m_h, hg1 = g_pvrtc2_trans_match44[g].m_h, hb1 = g_pvrtc2_trans_match34[b].m_h; + uint32_t la1 = g_pvrtc2_alpha_match33[constant_alpha_val].m_l, ha1 = g_pvrtc2_alpha_match33[constant_alpha_val].m_h; + + uint32_t clr1 = (lr1 << 1) | (lr1 >> 3); + uint32_t clg1 = (lg1 << 1) | (lg1 >> 3); + uint32_t clb1 = (lb1 << 2) | (lb1 >> 1); + uint32_t cla1 = (la1 << 1); + + clr1 = (clr1 << 3) | (clr1 >> 2); + clg1 = (clg1 << 3) | (clg1 >> 2); + clb1 = (clb1 << 3) | (clb1 >> 2); + cla1 = (cla1 << 4) | cla1; + + uint32_t chr1 = (hr1 << 1) | (hr1 >> 3); + uint32_t chg1 = (hg1 << 1) | (hg1 >> 3); + uint32_t chb1 = (hb1 << 1) | (hb1 >> 3); + uint32_t cha1 = (ha1 << 1) | 1; + + chr1 = (chr1 << 3) | (chr1 >> 2); + chg1 = (chg1 << 3) | (chg1 >> 2); + chb1 = (chb1 << 3) | (chb1 >> 2); + cha1 = (cha1 << 4) | cha1; + + uint32_t r1 = (clr1 * 5 + chr1 * 3) / 8; + uint32_t g1 = (clg1 * 5 + chg1 * 3) / 8; + uint32_t b1 = (clb1 * 5 + chb1 * 3) / 8; + uint32_t a1 = (cla1 * 5 + cha1 * 3) / 8; + + uint32_t err1 = sq(r1 - r) + sq(g1 - g) + sq(b1 - b) + sq(a1 - constant_alpha_val) * 2; + + if ((err1 < err0) && (err1 < err3)) + { + pBlock->set_trans_low_color(lr1, lg1, lb1, la1); + pBlock->set_trans_high_color(hr1, hg1, hb1, ha1); + + pBlock->m_modulation[0] = 0x55; + pBlock->m_modulation[1] = 0x55; + pBlock->m_modulation[2] = 0x55; + pBlock->m_modulation[3] = 0x55; + } + else if (err0 < err3) + { + pBlock->set_trans_low_color(lr0, lg0, lb0, la0); + pBlock->set_trans_high_color(0, 0, 0, 0); + + pBlock->m_modulation[0] = 0; + pBlock->m_modulation[1] = 0; + pBlock->m_modulation[2] = 0; + pBlock->m_modulation[3] = 0; + } + else + { + pBlock->set_trans_low_color(0, 0, 0, 0); + pBlock->set_trans_high_color(lr3, lg3, lb3, la3); + + pBlock->m_modulation[0] = 0xFF; + pBlock->m_modulation[1] = 0xFF; + pBlock->m_modulation[2] = 0xFF; + pBlock->m_modulation[3] = 0xFF; + } + + return; + } + + // It's a complex block with non-solid color and/or alpha pixels. + vec4F minColor, maxColor; + + if (solid_color_block) + { + // It's a solid color block. + uint32_t low_a = block_cols[alpha_selectors.m_lo_selector].a; + uint32_t high_a = block_cols[alpha_selectors.m_hi_selector].a; + + const float S = 1.0f / 255.0f; + vec4F_set(&minColor, block_cols[low_selector].r * S, block_cols[low_selector].g * S, block_cols[low_selector].b * S, low_a * S); + vec4F_set(&maxColor, block_cols[low_selector].r * S, block_cols[low_selector].g * S, block_cols[low_selector].b * S, high_a * S); + } + else if (constant_alpha_val >= 0) + { + // It's a solid alpha block. + const float S = 1.0f / 255.0f; + vec4F_set(&minColor, block_cols[low_selector].r * S, block_cols[low_selector].g * S, block_cols[low_selector].b * S, constant_alpha_val * S); + vec4F_set(&maxColor, block_cols[high_selector].r * S, block_cols[high_selector].g * S, block_cols[high_selector].b * S, constant_alpha_val * S); + } + // See if any of the block colors got clamped - if so the principle axis got distorted (it's no longer just the ETC1S luma axis). + // To keep quality up we need to use full 4D PCA in this case. + else if ((block_cols[low_selector].c[0] == 0) || (block_cols[high_selector].c[0] == 255) || + (block_cols[low_selector].c[1] == 0) || (block_cols[high_selector].c[1] == 255) || + (block_cols[low_selector].c[2] == 0) || (block_cols[high_selector].c[2] == 255) || + (block_cols[alpha_selectors.m_lo_selector].c[3] == 0) || (block_cols[alpha_selectors.m_hi_selector].c[3] == 255)) + { + // Find principle component of RGBA colors treated as 4D vectors. + color32 pixels[16]; + + uint32_t sum_r = 0, sum_g = 0, sum_b = 0, sum_a = 0; + for (uint32_t i = 0; i < 16; i++) + { + color32 rgb(block_cols[pSelector->get_selector(i & 3, i >> 2)]); + uint32_t a = block_cols[alpha_selectors.get_selector(i & 3, i >> 2)].a; + + pixels[i].set(rgb.r, rgb.g, rgb.b, a); + + sum_r += rgb.r; + sum_g += rgb.g; + sum_b += rgb.b; + sum_a += a; + } + + vec4F meanColor; + vec4F_set(&meanColor, (float)sum_r, (float)sum_g, (float)sum_b, (float)sum_a); + vec4F meanColorScaled = vec4F_mul(&meanColor, 1.0f / 16.0f); + + meanColor = vec4F_mul(&meanColor, 1.0f / (float)(16.0f * 255.0f)); + vec4F_saturate_in_place(&meanColor); + + vec4F axis; + vec4F_set_scalar(&axis, 0.0f); + // Why this incremental method? Because it's stable and predictable. Covar+power method can require a lot of iterations to converge in 4D. + for (uint32_t i = 0; i < 16; i++) + { + vec4F color = vec4F_from_color(&pixels[i]); + color = vec4F_sub(&color, &meanColorScaled); + vec4F a = vec4F_mul(&color, color.c[0]); + vec4F b = vec4F_mul(&color, color.c[1]); + vec4F c = vec4F_mul(&color, color.c[2]); + vec4F d = vec4F_mul(&color, color.c[3]); + vec4F n = i ? axis : color; + vec4F_normalize_in_place(&n); + axis.c[0] += vec4F_dot(&a, &n); + axis.c[1] += vec4F_dot(&b, &n); + axis.c[2] += vec4F_dot(&c, &n); + axis.c[3] += vec4F_dot(&d, &n); + } + + vec4F_normalize_in_place(&axis); + + if (vec4F_dot(&axis, &axis) < .5f) + vec4F_set_scalar(&axis, .5f); + + float l = 1e+9f, h = -1e+9f; + + for (uint32_t i = 0; i < 16; i++) + { + vec4F color = vec4F_from_color(&pixels[i]); + + vec4F q = vec4F_sub(&color, &meanColorScaled); + float d = vec4F_dot(&q, &axis); + + l = basisu::minimum(l, d); + h = basisu::maximum(h, d); + } + + l *= (1.0f / 255.0f); + h *= (1.0f / 255.0f); + + vec4F b0 = vec4F_mul(&axis, l); + vec4F b1 = vec4F_mul(&axis, h); + vec4F c0 = vec4F_add(&meanColor, &b0); + vec4F c1 = vec4F_add(&meanColor, &b1); + minColor = vec4F_saturate(&c0); + maxColor = vec4F_saturate(&c1); + if (minColor.c[3] > maxColor.c[3]) + std::swap(minColor, maxColor); + } + else + { + // We know the RGB axis is luma, because it's an ETC1S block and none of the block colors got clamped. So we only need to use 2D PCA. + // We project each LA vector onto two 2D lines with axes (1,1) and (1,-1) and find the largest projection to determine if axis A is flipped relative to L. + uint32_t block_cols_l[4], block_cols_a[4]; + for (uint32_t i = 0; i < 4; i++) + { + block_cols_l[i] = block_cols[i].r + block_cols[i].g + block_cols[i].b; + block_cols_a[i] = block_cols[i].a * 3; + } + + int p0_min = INT_MAX, p0_max = INT_MIN; + int p1_min = INT_MAX, p1_max = INT_MIN; + for (uint32_t y = 0; y < 4; y++) + { + const uint32_t cs = pSelector->m_selectors[y]; + const uint32_t as = alpha_selectors.m_selectors[y]; + + { + const int l = block_cols_l[cs & 3]; + const int a = block_cols_a[as & 3]; + const int p0 = l + a; p0_min = basisu::minimum(p0_min, p0); p0_max = basisu::maximum(p0_max, p0); + const int p1 = l - a; p1_min = basisu::minimum(p1_min, p1); p1_max = basisu::maximum(p1_max, p1); + } + { + const int l = block_cols_l[(cs >> 2) & 3]; + const int a = block_cols_a[(as >> 2) & 3]; + const int p0 = l + a; p0_min = basisu::minimum(p0_min, p0); p0_max = basisu::maximum(p0_max, p0); + const int p1 = l - a; p1_min = basisu::minimum(p1_min, p1); p1_max = basisu::maximum(p1_max, p1); + } + { + const int l = block_cols_l[(cs >> 4) & 3]; + const int a = block_cols_a[(as >> 4) & 3]; + const int p0 = l + a; p0_min = basisu::minimum(p0_min, p0); p0_max = basisu::maximum(p0_max, p0); + const int p1 = l - a; p1_min = basisu::minimum(p1_min, p1); p1_max = basisu::maximum(p1_max, p1); + } + { + const int l = block_cols_l[cs >> 6]; + const int a = block_cols_a[as >> 6]; + const int p0 = l + a; p0_min = basisu::minimum(p0_min, p0); p0_max = basisu::maximum(p0_max, p0); + const int p1 = l - a; p1_min = basisu::minimum(p1_min, p1); p1_max = basisu::maximum(p1_max, p1); + } + } + + int dist0 = p0_max - p0_min; + int dist1 = p1_max - p1_min; + + const float S = 1.0f / 255.0f; + + vec4F_set(&minColor, block_cols[low_selector].r * S, block_cols[low_selector].g * S, block_cols[low_selector].b * S, block_cols[alpha_selectors.m_lo_selector].a * S); + vec4F_set(&maxColor, block_cols[high_selector].r * S, block_cols[high_selector].g * S, block_cols[high_selector].b * S, block_cols[alpha_selectors.m_hi_selector].a * S); + + // See if the A component of the principle axis is flipped relative to L. If so, we need to flip either RGB or A bounds. + if (dist1 > dist0) + { + std::swap(minColor.c[0], maxColor.c[0]); + std::swap(minColor.c[1], maxColor.c[1]); + std::swap(minColor.c[2], maxColor.c[2]); + } + } + + // 4433 4443 + color32 trialMinColor, trialMaxColor; + + trialMinColor.set_clamped((int)(minColor.c[0] * 15.0f + .5f), (int)(minColor.c[1] * 15.0f + .5f), (int)(minColor.c[2] * 7.0f + .5f), (int)(minColor.c[3] * 7.0f + .5f)); + trialMaxColor.set_clamped((int)(maxColor.c[0] * 15.0f + .5f), (int)(maxColor.c[1] * 15.0f + .5f), (int)(maxColor.c[2] * 15.0f + .5f), (int)(maxColor.c[3] * 7.0f + .5f)); + + pBlock->set_trans_low_color(trialMinColor.r, trialMinColor.g, trialMinColor.b, trialMinColor.a); + pBlock->set_trans_high_color(trialMaxColor.r, trialMaxColor.g, trialMaxColor.b, trialMaxColor.a); + + color32 color_a((trialMinColor.r << 1) | (trialMinColor.r >> 3), (trialMinColor.g << 1) | (trialMinColor.g >> 3), (trialMinColor.b << 2) | (trialMinColor.b >> 1), trialMinColor.a << 1); + color32 color_b((trialMaxColor.r << 1) | (trialMaxColor.r >> 3), (trialMaxColor.g << 1) | (trialMaxColor.g >> 3), (trialMaxColor.b << 1) | (trialMaxColor.b >> 3), (trialMaxColor.a << 1) | 1); + + color32 color0(convert_rgba_5554_to_8888(color_a)); + color32 color3(convert_rgba_5554_to_8888(color_b)); + + const int lr = color0.r; + const int lg = color0.g; + const int lb = color0.b; + const int la = color0.a; + + const int axis_r = color3.r - lr; + const int axis_g = color3.g - lg; + const int axis_b = color3.b - lb; + const int axis_a = color3.a - la; + const int len_a = (axis_r * axis_r) + (axis_g * axis_g) + (axis_b * axis_b) + (axis_a * axis_a); + + const int thresh01 = (len_a * 3) / 16; + const int thresh12 = len_a >> 1; + const int thresh23 = (len_a * 13) / 16; + + if ((axis_r | axis_g | axis_b) == 0) + { + int ca_sel[4]; + + for (uint32_t i = 0; i < 4; i++) + { + int ca = (block_cols[i].a - la) * axis_a; + ca_sel[i] = (ca >= thresh23) + (ca >= thresh12) + (ca >= thresh01); + } + + for (uint32_t y = 0; y < 4; y++) + { + const uint32_t a_sels = alpha_selectors.m_selectors[y]; + + uint32_t sel = ca_sel[a_sels & 3] | (ca_sel[(a_sels >> 2) & 3] << 2) | (ca_sel[(a_sels >> 4) & 3] << 4) | (ca_sel[a_sels >> 6] << 6); + + pBlock->m_modulation[y] = (uint8_t)sel; + } + } + else + { + int cy[4], ca[4]; + + for (uint32_t i = 0; i < 4; i++) + { + cy[i] = (block_cols[i].r - lr) * axis_r + (block_cols[i].g - lg) * axis_g + (block_cols[i].b - lb) * axis_b; + ca[i] = (block_cols[i].a - la) * axis_a; + } + + for (uint32_t y = 0; y < 4; y++) + { + const uint32_t c_sels = pSelector->m_selectors[y]; + const uint32_t a_sels = alpha_selectors.m_selectors[y]; + + const int d0 = cy[c_sels & 3] + ca[a_sels & 3]; + const int d1 = cy[(c_sels >> 2) & 3] + ca[(a_sels >> 2) & 3]; + const int d2 = cy[(c_sels >> 4) & 3] + ca[(a_sels >> 4) & 3]; + const int d3 = cy[c_sels >> 6] + ca[a_sels >> 6]; + + uint32_t sel = ((d0 >= thresh23) + (d0 >= thresh12) + (d0 >= thresh01)) | + (((d1 >= thresh23) + (d1 >= thresh12) + (d1 >= thresh01)) << 2) | + (((d2 >= thresh23) + (d2 >= thresh12) + (d2 >= thresh01)) << 4) | + (((d3 >= thresh23) + (d3 >= thresh12) + (d3 >= thresh01)) << 6); + + pBlock->m_modulation[y] = (uint8_t)sel; + } + } + } + + static void transcoder_init_pvrtc2() + { + for (uint32_t v = 0; v < 256; v++) + { + int best_l = 0, best_h = 0, lowest_err = INT_MAX; + + for (uint32_t l = 0; l < 8; l++) + { + uint32_t le = (l << 1); + le = (le << 4) | le; + + for (uint32_t h = 0; h < 8; h++) + { + uint32_t he = (h << 1) | 1; + he = (he << 4) | he; + + uint32_t m = (le * 5 + he * 3) / 8; + + int err = labs((int)v - (int)m); + if (err < lowest_err) + { + lowest_err = err; + best_l = l; + best_h = h; + } + } + } + + g_pvrtc2_alpha_match33[v].m_l = (uint8_t)best_l; + g_pvrtc2_alpha_match33[v].m_h = (uint8_t)best_h; + } + + for (uint32_t v = 0; v < 256; v++) + { + int best_l = 0, best_h = 0, lowest_err = INT_MAX; + + for (uint32_t l = 0; l < 8; l++) + { + uint32_t le = (l << 1); + le = (le << 4) | le; + + int err = labs((int)v - (int)le); + if (err < lowest_err) + { + lowest_err = err; + best_l = l; + best_h = l; + } + } + + g_pvrtc2_alpha_match33_0[v].m_l = (uint8_t)best_l; + g_pvrtc2_alpha_match33_0[v].m_h = (uint8_t)best_h; + } + + for (uint32_t v = 0; v < 256; v++) + { + int best_l = 0, best_h = 0, lowest_err = INT_MAX; + + for (uint32_t h = 0; h < 8; h++) + { + uint32_t he = (h << 1) | 1; + he = (he << 4) | he; + + int err = labs((int)v - (int)he); + if (err < lowest_err) + { + lowest_err = err; + best_l = h; + best_h = h; + } + } + + g_pvrtc2_alpha_match33_3[v].m_l = (uint8_t)best_l; + g_pvrtc2_alpha_match33_3[v].m_h = (uint8_t)best_h; + } + + for (uint32_t v = 0; v < 256; v++) + { + int best_l = 0, best_h = 0, lowest_err = INT_MAX; + + for (uint32_t l = 0; l < 8; l++) + { + uint32_t le = (l << 2) | (l >> 1); + le = (le << 3) | (le >> 2); + + for (uint32_t h = 0; h < 16; h++) + { + uint32_t he = (h << 1) | (h >> 3); + he = (he << 3) | (he >> 2); + + uint32_t m = (le * 5 + he * 3) / 8; + + int err = labs((int)v - (int)m); + if (err < lowest_err) + { + lowest_err = err; + best_l = l; + best_h = h; + } + } + } + + g_pvrtc2_trans_match34[v].m_l = (uint8_t)best_l; + g_pvrtc2_trans_match34[v].m_h = (uint8_t)best_h; + } + + for (uint32_t v = 0; v < 256; v++) + { + int best_l = 0, best_h = 0, lowest_err = INT_MAX; + + for (uint32_t l = 0; l < 16; l++) + { + uint32_t le = (l << 1) | (l >> 3); + le = (le << 3) | (le >> 2); + + for (uint32_t h = 0; h < 16; h++) + { + uint32_t he = (h << 1) | (h >> 3); + he = (he << 3) | (he >> 2); + + uint32_t m = (le * 5 + he * 3) / 8; + + int err = labs((int)v - (int)m); + if (err < lowest_err) + { + lowest_err = err; + best_l = l; + best_h = h; + } + } + } + + g_pvrtc2_trans_match44[v].m_l = (uint8_t)best_l; + g_pvrtc2_trans_match44[v].m_h = (uint8_t)best_h; + } + } +#endif // BASISD_SUPPORT_PVRTC2 + basisu_lowlevel_transcoder::basisu_lowlevel_transcoder(const etc1_global_selector_codebook* pGlobal_sel_codebook) : m_pGlobal_sel_codebook(pGlobal_sel_codebook), m_selector_history_buf_size(0) @@ -6331,12 +8136,11 @@ namespace basist } bool basisu_lowlevel_transcoder::transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, - uint32_t output_block_or_pixel_stride_in_bytes, bool pvrtc_wrap_addressing, bool bc1_allow_threecolor_blocks, const basis_file_header& header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const basis_file_header& header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state* pState, bool transcode_alpha, void *pAlpha_blocks, uint32_t output_rows_in_pixels) { (void)transcode_alpha; (void)pAlpha_blocks; - (void)pvrtc_wrap_addressing; if (!pState) pState = &m_def_state; @@ -6349,7 +8153,12 @@ namespace basist if (basis_block_format_is_uncompressed(fmt)) output_row_pitch_in_blocks_or_pixels = slice_desc.m_orig_width; else - output_row_pitch_in_blocks_or_pixels = num_blocks_x; + { + if (fmt == block_format::cFXT1_RGB) + output_row_pitch_in_blocks_or_pixels = (slice_desc.m_orig_width + 7) / 8; + else + output_row_pitch_in_blocks_or_pixels = num_blocks_x; + } } if (basis_block_format_is_uncompressed(fmt)) @@ -6398,7 +8207,7 @@ namespace basist void* pPVRTC_work_mem = nullptr; uint32_t* pPVRTC_endpoints = nullptr; - if ((fmt == cPVRTC1_4_RGB) || (fmt == cPVRTC1_4_RGBA)) + if ((fmt == block_format::cPVRTC1_4_RGB) || (fmt == block_format::cPVRTC1_4_RGBA)) { pPVRTC_work_mem = malloc(num_blocks_x * num_blocks_y * (sizeof(decoder_etc_block) + sizeof(uint32_t))); if (!pPVRTC_work_mem) @@ -6608,7 +8417,7 @@ namespace basist (*pPrev_frame_indices)[block_x + block_y * num_blocks_x] = endpoint_index | (selector_index << 16); #if BASISD_ENABLE_DEBUG_FLAGS - if ((g_debug_flags & cDebugFlagVisCRs) && ((fmt == cETC1) || (fmt == cBC1))) + if ((g_debug_flags & cDebugFlagVisCRs) && ((fmt == block_format::cETC1) || (fmt == block_format::cBC1))) { if ((is_video) && (pred == 2)) { @@ -6624,7 +8433,7 @@ namespace basist switch (fmt) { - case cETC1: + case block_format::cETC1: { decoder_etc_block* pDst_block = reinterpret_cast<decoder_etc_block*>(static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes); @@ -6637,7 +8446,7 @@ namespace basist break; } - case cBC1: + case block_format::cBC1: { void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; @@ -6653,7 +8462,7 @@ namespace basist #endif break; } - case cBC4: + case block_format::cBC4: { #if BASISD_SUPPORT_DXT5A void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; @@ -6663,7 +8472,7 @@ namespace basist #endif break; } - case cPVRTC1_4_RGB: + case block_format::cPVRTC1_4_RGB: { #if BASISD_SUPPORT_PVRTC1 block.set_base5_color(decoder_etc_block::pack_color5(pEndpoints->m_color5, false)); @@ -6699,7 +8508,7 @@ namespace basist break; } - case cPVRTC1_4_RGBA: + case block_format::cPVRTC1_4_RGBA: { #if BASISD_SUPPORT_PVRTC1 assert(pAlpha_blocks); @@ -6750,7 +8559,7 @@ namespace basist break; } - case cBC7_M6_OPAQUE_ONLY: + case block_format::cBC7_M6_OPAQUE_ONLY: { #if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; @@ -6760,7 +8569,7 @@ namespace basist #endif break; } - case cBC7_M5_COLOR: + case block_format::cBC7_M5_COLOR: { #if BASISD_SUPPORT_BC7_MODE5 void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; @@ -6770,7 +8579,7 @@ namespace basist #endif break; } - case cBC7_M5_ALPHA: + case block_format::cBC7_M5_ALPHA: { #if BASISD_SUPPORT_BC7_MODE5 void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; @@ -6780,17 +8589,17 @@ namespace basist #endif break; } - case cETC2_EAC_A8: + case block_format::cETC2_EAC_A8: { #if BASISD_SUPPORT_ETC2_EAC_A8 void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; - convert_etc1s_to_etc2_eac_a8(static_cast<eac_a8_block*>(pDst_block), pEndpoints, pSelector); + convert_etc1s_to_etc2_eac_a8(static_cast<eac_block*>(pDst_block), pEndpoints, pSelector); #else assert(0); #endif break; } - case cASTC_4x4: + case block_format::cASTC_4x4: { #if BASISD_SUPPORT_ASTC void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; @@ -6800,7 +8609,7 @@ namespace basist #endif break; } - case cATC_RGB: + case block_format::cATC_RGB: { #if BASISD_SUPPORT_ATC void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; @@ -6810,14 +8619,48 @@ namespace basist #endif break; } - case cIndices: + case block_format::cFXT1_RGB: + { +#if BASISD_SUPPORT_FXT1 + const uint32_t fxt1_block_x = block_x >> 1; + const uint32_t fxt1_block_y = block_y; + const uint32_t fxt1_subblock = block_x & 1; + + void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (fxt1_block_x + fxt1_block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; + + convert_etc1s_to_fxt1(pDst_block, pEndpoints, pSelector, fxt1_subblock); +#else + assert(0); +#endif + break; + } + case block_format::cPVRTC2_4_RGB: + { +#if BASISD_SUPPORT_PVRTC2 + void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; + convert_etc1s_to_pvrtc2_rgb(pDst_block, pEndpoints, pSelector); +#endif + break; + } + case block_format::cPVRTC2_4_RGBA: + { +#if BASISD_SUPPORT_PVRTC2 + assert(transcode_alpha); + + void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; + + convert_etc1s_to_pvrtc2_rgba(pDst_block, pEndpoints, pSelector, &m_endpoints[0], &m_selectors[0]); +#endif + break; + } + case block_format::cIndices: { uint16_t* pDst_block = reinterpret_cast<uint16_t *>(static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes); pDst_block[0] = static_cast<uint16_t>(endpoint_index); pDst_block[1] = static_cast<uint16_t>(selector_index); break; } - case cA32: + case block_format::cA32: { assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t); @@ -6857,7 +8700,7 @@ namespace basist break; } - case cRGB32: + case block_format::cRGB32: { assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t); @@ -6886,7 +8729,7 @@ namespace basist break; } - case cRGBA32: + case block_format::cRGBA32: { assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t); @@ -6916,8 +8759,8 @@ namespace basist break; } - case cRGB565: - case cBGR565: + case block_format::cRGB565: + case block_format::cBGR565: { assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); @@ -6929,7 +8772,7 @@ namespace basist decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5); uint16_t packed_colors[4]; - if (fmt == cRGB565) + if (fmt == block_format::cRGB565) { for (uint32_t i = 0; i < 4; i++) packed_colors[i] = static_cast<uint16_t>(((colors[i].r >> 3) << 11) | ((colors[i].g >> 2) << 5) | (colors[i].b >> 3)); @@ -6952,7 +8795,7 @@ namespace basist break; } - case cRGBA4444_COLOR: + case block_format::cRGBA4444_COLOR: { assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); @@ -6983,7 +8826,7 @@ namespace basist break; } - case cRGBA4444_COLOR_OPAQUE: + case block_format::cRGBA4444_COLOR_OPAQUE: { assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); @@ -7010,7 +8853,7 @@ namespace basist break; } - case cRGBA4444_ALPHA: + case block_format::cRGBA4444_ALPHA: { assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); @@ -7037,6 +8880,16 @@ namespace basist break; } + case block_format::cETC2_EAC_R11: + { +#if BASISD_SUPPORT_ETC2_EAC_RG11 + void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; + convert_etc1s_to_etc2_eac_r11(static_cast<eac_block*>(pDst_block), pEndpoints, pSelector); +#else + assert(0); +#endif + break; + } default: { assert(0); @@ -7058,10 +8911,10 @@ namespace basist #if BASISD_SUPPORT_PVRTC1 // PVRTC post process - create per-pixel modulation values. - if (fmt == cPVRTC1_4_RGB) - fixup_pvrtc1_4_modulation_rgb((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pvrtc_wrap_addressing); - else if (fmt == cPVRTC1_4_RGBA) - fixup_pvrtc1_4_modulation_rgba((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pvrtc_wrap_addressing, pAlpha_blocks, &m_endpoints[0], &m_selectors[0]); + if (fmt == block_format::cPVRTC1_4_RGB) + fixup_pvrtc1_4_modulation_rgb((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y); + else if (fmt == block_format::cPVRTC1_4_RGBA) + fixup_pvrtc1_4_modulation_rgba((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pAlpha_blocks, &m_endpoints[0], &m_selectors[0]); #endif // BASISD_SUPPORT_PVRTC1 if (pPVRTC_work_mem) @@ -7612,7 +9465,7 @@ namespace basist const basis_slice_desc& slice_desc = reinterpret_cast<const basis_slice_desc*>(pDataU8 + pHeader->m_slice_desc_file_ofs)[slice_index]; - uint32_t total_blocks = slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y; + uint32_t total_4x4_blocks = slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y; if (basis_block_format_is_uncompressed(fmt)) { @@ -7630,18 +9483,30 @@ namespace basist return false; } } + else if (fmt == block_format::cFXT1_RGB) + { + const uint32_t num_blocks_fxt1_x = (slice_desc.m_orig_width + 7) / 8; + const uint32_t num_blocks_fxt1_y = (slice_desc.m_orig_height + 3) / 4; + const uint32_t total_blocks_fxt1 = num_blocks_fxt1_x * num_blocks_fxt1_y; + + if (output_blocks_buf_size_in_blocks_or_pixels < total_blocks_fxt1) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: output_blocks_buf_size_in_blocks_or_pixels < total_blocks_fxt1\n"); + return false; + } + } else { - if (output_blocks_buf_size_in_blocks_or_pixels < total_blocks) + if (output_blocks_buf_size_in_blocks_or_pixels < total_4x4_blocks) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: output_blocks_buf_size_in_blocks_or_pixels < total_blocks\n"); return false; } } - if (fmt != cETC1) + if (fmt != block_format::cETC1) { - if ((fmt == cPVRTC1_4_RGB) || (fmt == cPVRTC1_4_RGBA)) + if ((fmt == block_format::cPVRTC1_4_RGB) || (fmt == block_format::cPVRTC1_4_RGBA)) { if ((!basisu::is_pow2(slice_desc.m_num_blocks_x * 4)) || (!basisu::is_pow2(slice_desc.m_num_blocks_y * 4))) { @@ -7667,7 +9532,7 @@ namespace basist return m_lowlevel_decoder.transcode_slice(pOutput_blocks, slice_desc.m_num_blocks_x, slice_desc.m_num_blocks_y, pDataU8 + slice_desc.m_file_ofs, slice_desc.m_file_size, - fmt, output_block_or_pixel_stride_in_bytes, (decode_flags & cDecodeFlagsPVRTCWrapAddressing) != 0, (decode_flags & cDecodeFlagsBC1ForbidThreeColorBlocks) == 0, *pHeader, slice_desc, output_row_pitch_in_blocks_or_pixels, pState, + fmt, output_block_or_pixel_stride_in_bytes, (decode_flags & cDecodeFlagsBC1ForbidThreeColorBlocks) == 0, *pHeader, slice_desc, output_row_pitch_in_blocks_or_pixels, pState, (decode_flags & cDecodeFlagsOutputHasAlphaIndices) != 0, pAlpha_blocks, output_rows_in_pixels); } @@ -7731,11 +9596,11 @@ namespace basist if (!output_row_pitch_in_blocks_or_pixels) output_row_pitch_in_blocks_or_pixels = num_blocks_x; - - if (fmt == cETC2_EAC_A8) + + if ((fmt == block_format::cETC2_EAC_A8) || (fmt == block_format::cETC2_EAC_R11)) { #if BASISD_SUPPORT_ETC2_EAC_A8 - eac_a8_block blk; + eac_block blk; blk.m_base = 255; blk.m_multiplier = 1; blk.m_table = 13; @@ -7755,7 +9620,7 @@ namespace basist } #endif } - else if (fmt == cBC4) + else if (fmt == block_format::cBC4) { #if BASISD_SUPPORT_DXT5A dxt5a_block blk; @@ -7822,10 +9687,10 @@ namespace basist return false; } - if ((fmt == cTFPVRTC1_4_RGBA) && (!basis_file_has_alpha_slices)) + if ((fmt == transcoder_texture_format::cTFPVRTC1_4_RGBA) && (!basis_file_has_alpha_slices)) { // Switch to PVRTC1 RGB if the input doesn't have alpha. - fmt = cTFPVRTC1_4_RGB; + fmt = transcoder_texture_format::cTFPVRTC1_4_RGB; } if (pSlice_descs[slice_index].m_flags & cSliceDescFlagsIsAlphaData) @@ -7866,7 +9731,7 @@ namespace basist const uint32_t total_slice_blocks = pSlice_descs[slice_index].m_num_blocks_x * pSlice_descs[slice_index].m_num_blocks_y; - if (((fmt == cTFPVRTC1_4_RGB) || (fmt == cTFPVRTC1_4_RGBA)) && (output_blocks_buf_size_in_blocks_or_pixels > total_slice_blocks)) + if (((fmt == transcoder_texture_format::cTFPVRTC1_4_RGB) || (fmt == transcoder_texture_format::cTFPVRTC1_4_RGBA)) && (output_blocks_buf_size_in_blocks_or_pixels > total_slice_blocks)) { // The transcoder doesn't write beyond total_slice_blocks, so we need to clear the rest ourselves. // For GL usage, PVRTC1 4bpp image size is (max(width, 8)* max(height, 8) * 4 + 7) / 8. @@ -7876,21 +9741,21 @@ namespace basist switch (fmt) { - case cTFETC1: + case transcoder_texture_format::cTFETC1_RGB: { uint32_t slice_index_to_decode = slice_index; // If the caller wants us to transcode the mip level's alpha data, then use the next slice. if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) slice_index_to_decode++; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cETC1, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC1, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC1 failed\n"); } break; } - case cTFBC1: + case transcoder_texture_format::cTFBC1_RGB: { #if !BASISD_SUPPORT_DXT1 return false; @@ -7900,14 +9765,14 @@ namespace basist if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) slice_index_to_decode++; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC1, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC1, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC1 failed\n"); } break; } - case cTFBC4: + case transcoder_texture_format::cTFBC4_R: { #if !BASISD_SUPPORT_DXT5A return false; @@ -7917,14 +9782,14 @@ namespace basist if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) slice_index_to_decode++; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC4 failed\n"); } break; } - case cTFPVRTC1_4_RGB: + case transcoder_texture_format::cTFPVRTC1_4_RGB: { #if !BASISD_SUPPORT_PVRTC1 return false; @@ -7935,14 +9800,14 @@ namespace basist slice_index_to_decode++; // output_row_pitch_in_blocks_or_pixels is actually ignored because we're transcoding to PVRTC1. (Print a dev warning if it's != 0?) - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cPVRTC1_4_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to PVRTC1 4 RGB failed\n"); } break; } - case cTFPVRTC1_4_RGBA: + case transcoder_texture_format::cTFPVRTC1_4_RGBA: { #if !BASISD_SUPPORT_PVRTC1 return false; @@ -7953,7 +9818,7 @@ namespace basist std::vector<uint32_t> temp_block_indices(total_slice_blocks); // First transcode alpha data to temp buffer - status = transcode_slice(pData, data_size, slice_index + 1, &temp_block_indices[0], total_slice_blocks, cIndices, sizeof(uint32_t), decode_flags, pSlice_descs[slice_index].m_num_blocks_x, pState); + status = transcode_slice(pData, data_size, slice_index + 1, &temp_block_indices[0], total_slice_blocks, block_format::cIndices, sizeof(uint32_t), decode_flags, pSlice_descs[slice_index].m_num_blocks_x, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to PVRTC1 4 RGBA failed (0)\n"); @@ -7961,7 +9826,7 @@ namespace basist else { // output_row_pitch_in_blocks_or_pixels is actually ignored because we're transcoding to PVRTC1. (Print a dev warning if it's != 0?) - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cPVRTC1_4_RGBA, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState, &temp_block_indices[0]); + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGBA, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState, &temp_block_indices[0]); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to PVRTC1 4 RGBA failed (1)\n"); @@ -7970,7 +9835,7 @@ namespace basist break; } - case cTFBC7_M6_OPAQUE_ONLY: + case transcoder_texture_format::cTFBC7_M6_RGB: { #if !BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY return false; @@ -7980,50 +9845,54 @@ namespace basist if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) slice_index_to_decode++; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC7_M6_OPAQUE_ONLY, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7_M6_OPAQUE_ONLY, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC7 m6 opaque only failed\n"); } break; } - case cTFBC7_M5: + case transcoder_texture_format::cTFBC7_M5_RGBA: { #if !BASISD_SUPPORT_BC7_MODE5 return false; #else + assert(bytes_per_block == 16); + // First transcode the color slice. The cBC7_M5_COLOR transcoder will output opaque mode 5 blocks. - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC7_M5_COLOR, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7_M5_COLOR, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if ((status) && (basis_file_has_alpha_slices)) { // Now transcode the alpha slice. The cBC7_M5_ALPHA transcoder will now change the opaque mode 5 blocks to blocks with alpha. - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC7_M5_ALPHA, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7_M5_ALPHA, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); } break; #endif } - case cTFETC2: + case transcoder_texture_format::cTFETC2_RGBA: { #if !BASISD_SUPPORT_ETC2_EAC_A8 return false; #endif + assert(bytes_per_block == 16); + if (basis_file_has_alpha_slices) { // First decode the alpha data - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cETC2_EAC_A8, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_A8, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); } else { - write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cETC2_EAC_A8, 16, output_row_pitch_in_blocks_or_pixels); + write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_A8, 16, output_row_pitch_in_blocks_or_pixels); status = true; } if (status) { // Now decode the color data - status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cETC1, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC1, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2 RGB failed\n"); @@ -8035,7 +9904,7 @@ namespace basist } break; } - case cTFBC3: + case transcoder_texture_format::cTFBC3_RGBA: { #if !BASISD_SUPPORT_DXT1 return false; @@ -8043,21 +9912,23 @@ namespace basist #if !BASISD_SUPPORT_DXT5A return false; #endif + assert(bytes_per_block == 16); + // First decode the alpha data if (basis_file_has_alpha_slices) { - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); } else { - write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, output_row_pitch_in_blocks_or_pixels); + write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, output_row_pitch_in_blocks_or_pixels); status = true; } if (status) { // Now decode the color data. Forbid 3 color blocks, which aren't allowed in BC3. - status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cBC1, 16, decode_flags | cDecodeFlagsBC1ForbidThreeColorBlocks, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC1, 16, decode_flags | cDecodeFlagsBC1ForbidThreeColorBlocks, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC3 RGB failed\n"); @@ -8070,19 +9941,21 @@ namespace basist break; } - case cTFBC5: + case transcoder_texture_format::cTFBC5_RG: { #if !BASISD_SUPPORT_DXT5A return false; #endif + assert(bytes_per_block == 16); + // Decode the R data (actually the green channel of the color data slice in the basis file) - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (status) { if (basis_file_has_alpha_slices) { // Decode the G data (actually the green channel of the alpha data slice in the basis file) - status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC5 1 failed\n"); @@ -8090,7 +9963,7 @@ namespace basist } else { - write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, output_row_pitch_in_blocks_or_pixels); + write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, output_row_pitch_in_blocks_or_pixels); status = true; } } @@ -8100,15 +9973,17 @@ namespace basist } break; } - case cTFASTC_4x4: + case transcoder_texture_format::cTFASTC_4x4_RGBA: { #if !BASISD_SUPPORT_ASTC return false; #endif + assert(bytes_per_block == 16); + if (basis_file_has_alpha_slices) { // First decode the alpha data to the output (we're using the output texture as a temp buffer here). - status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cIndices, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cIndices, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to failed\n"); @@ -8117,15 +9992,15 @@ namespace basist { // Now decode the color data and transcode to ASTC. The transcoder function will read the alpha selector data from the output texture as it converts and // transcode both the alpha and color data at the same time to ASTC. - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cASTC_4x4, 16, decode_flags | cDecodeFlagsOutputHasAlphaIndices, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cASTC_4x4, 16, decode_flags | cDecodeFlagsOutputHasAlphaIndices, output_row_pitch_in_blocks_or_pixels, pState); } } else - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cASTC_4x4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cASTC_4x4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); break; } - case cTFATC_RGB: + case transcoder_texture_format::cTFATC_RGB: { #if !BASISD_SUPPORT_ATC return false; @@ -8135,14 +10010,14 @@ namespace basist if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) slice_index_to_decode++; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cATC_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cATC_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ATC_RGB failed\n"); } break; } - case cTFATC_RGBA_INTERPOLATED_ALPHA: + case transcoder_texture_format::cTFATC_RGBA: { #if !BASISD_SUPPORT_ATC return false; @@ -8150,20 +10025,22 @@ namespace basist #if !BASISD_SUPPORT_DXT5A return false; #endif + assert(bytes_per_block == 16); + // First decode the alpha data if (basis_file_has_alpha_slices) { - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); } else { - write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, output_row_pitch_in_blocks_or_pixels); + write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, output_row_pitch_in_blocks_or_pixels); status = true; } if (status) { - status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cATC_RGB, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cATC_RGB, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ATC RGB failed\n"); @@ -8173,22 +10050,67 @@ namespace basist { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ATC A failed\n"); } + break; + } + case transcoder_texture_format::cTFPVRTC2_4_RGB: + { +#if !BASISD_SUPPORT_PVRTC2 + return false; +#endif + uint32_t slice_index_to_decode = slice_index; + // If the caller wants us to transcode the mip level's alpha data, then use the next slice. + if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) + slice_index_to_decode++; + + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC2_4_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to cPVRTC2_4_RGB failed\n"); + } + break; + } + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + { +#if !BASISD_SUPPORT_PVRTC2 + return false; +#endif + if (basis_file_has_alpha_slices) + { + // First decode the alpha data to the output (we're using the output texture as a temp buffer here). + status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cIndices, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to failed\n"); + } + else + { + // Now decode the color data and transcode to PVRTC2 RGBA. + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC2_4_RGBA, bytes_per_block, decode_flags | cDecodeFlagsOutputHasAlphaIndices, output_row_pitch_in_blocks_or_pixels, pState); + } + } + else + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC2_4_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + + if (!status) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to cPVRTC2_4_RGBA failed\n"); + } break; } - case cTFRGBA32: + case transcoder_texture_format::cTFRGBA32: { // Raw 32bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory. // First decode the alpha data if (basis_file_has_alpha_slices) - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); else status = true; if (status) { - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? cRGB32 : cRGBA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? block_format::cRGB32 : block_format::cRGBA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA32 RGB failed\n"); @@ -8201,8 +10123,8 @@ namespace basist break; } - case cTFRGB565: - case cTFBGR565: + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: { // Raw 16bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory. @@ -8211,7 +10133,7 @@ namespace basist if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) slice_index_to_decode++; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, (fmt == cTFRGB565) ? cRGB565 : cBGR565, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, (fmt == transcoder_texture_format::cTFRGB565) ? block_format::cRGB565 : block_format::cBGR565, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGB565 RGB failed\n"); @@ -8219,19 +10141,19 @@ namespace basist break; } - case cTFRGBA4444: + case transcoder_texture_format::cTFRGBA4444: { // Raw 16bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory. // First decode the alpha data if (basis_file_has_alpha_slices) - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cRGBA4444_ALPHA, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cRGBA4444_ALPHA, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); else status = true; if (status) { - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? cRGBA4444_COLOR : cRGBA4444_COLOR_OPAQUE, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? block_format::cRGBA4444_COLOR : block_format::cRGBA4444_COLOR_OPAQUE, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); if (!status) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA4444 RGB failed\n"); @@ -8244,6 +10166,75 @@ namespace basist break; } + case transcoder_texture_format::cTFFXT1_RGB: + { +#if !BASISD_SUPPORT_FXT1 + return false; +#endif + uint32_t slice_index_to_decode = slice_index; + // If the caller wants us to transcode the mip level's alpha data, then use the next slice. + if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) + slice_index_to_decode++; + + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cFXT1_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to FXT1_RGB failed\n"); + } + break; + } + case transcoder_texture_format::cTFETC2_EAC_R11: + { +#if !BASISD_SUPPORT_ETC2_EAC_RG11 + return false; +#endif + uint32_t slice_index_to_decode = slice_index; + // If the caller wants us to transcode the mip level's alpha data, then use the next slice. + if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) + slice_index_to_decode++; + + status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2_EAC_R11 failed\n"); + } + + break; + } + case transcoder_texture_format::cTFETC2_EAC_RG11: + { +#if !BASISD_SUPPORT_ETC2_EAC_RG11 + return false; +#endif + assert(bytes_per_block == 16); + + if (basis_file_has_alpha_slices) + { + // First decode the alpha data to G + status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t *)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + } + else + { + write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, (uint8_t *)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, 16, output_row_pitch_in_blocks_or_pixels); + status = true; + } + + if (status) + { + // Now decode the color data to R + status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2_EAC_R11 R failed\n"); + } + } + else + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2_EAC_R11 G failed\n"); + } + + break; + } default: { assert(0); @@ -8259,26 +10250,31 @@ namespace basist { switch (fmt) { - case cTFETC1: - case cTFBC1: - case cTFBC4: - case cTFPVRTC1_4_RGB: - case cTFPVRTC1_4_RGBA: - case cTFATC_RGB: + case transcoder_texture_format::cTFETC1_RGB: + case transcoder_texture_format::cTFBC1_RGB: + case transcoder_texture_format::cTFBC4_R: + case transcoder_texture_format::cTFPVRTC1_4_RGB: + case transcoder_texture_format::cTFPVRTC1_4_RGBA: + case transcoder_texture_format::cTFATC_RGB: + case transcoder_texture_format::cTFPVRTC2_4_RGB: + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + case transcoder_texture_format::cTFETC2_EAC_R11: return 8; - case cTFBC7_M6_OPAQUE_ONLY: - case cTFBC7_M5: - case cTFETC2: - case cTFBC3: - case cTFBC5: - case cTFASTC_4x4: - case cTFATC_RGBA_INTERPOLATED_ALPHA: + case transcoder_texture_format::cTFBC7_M6_RGB: + case transcoder_texture_format::cTFBC7_M5_RGBA: + case transcoder_texture_format::cTFETC2_RGBA: + case transcoder_texture_format::cTFBC3_RGBA: + case transcoder_texture_format::cTFBC5_RG: + case transcoder_texture_format::cTFASTC_4x4_RGBA: + case transcoder_texture_format::cTFATC_RGBA: + case transcoder_texture_format::cTFFXT1_RGB: + case transcoder_texture_format::cTFETC2_EAC_RG11: return 16; - case cTFRGBA32: + case transcoder_texture_format::cTFRGBA32: return sizeof(uint32_t) * 16; - case cTFRGB565: - case cTFBGR565: - case cTFRGBA4444: + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: + case transcoder_texture_format::cTFRGBA4444: return sizeof(uint16_t) * 16; default: assert(0); @@ -8292,23 +10288,28 @@ namespace basist { switch (fmt) { - case cTFETC1: return "ETC1"; - case cTFBC1: return "BC1"; - case cTFBC4: return "BC4"; - case cTFPVRTC1_4_RGB: return "PVRTC1_4_RGB"; - case cTFPVRTC1_4_RGBA: return "PVRTC1_4_RGBA"; - case cTFBC7_M6_OPAQUE_ONLY: return "BC7_M6_OPAQUE_ONLY"; - case cTFBC7_M5: return "BC7_M5"; - case cTFETC2: return "ETC2"; - case cTFBC3: return "BC3"; - case cTFBC5: return "BC5"; - case cTFASTC_4x4: return "ASTC"; - case cTFATC_RGB: return "ATC_RGB"; - case cTFATC_RGBA_INTERPOLATED_ALPHA: return "ATC_RGBA_INTERPOLATED_ALPHA"; - case cTFRGBA32: return "RGBA32"; - case cTFRGB565: return "RGB565"; - case cTFBGR565: return "BGR565"; - case cTFRGBA4444: return "RGBA4444"; + case transcoder_texture_format::cTFETC1_RGB: return "ETC1_RGB"; + case transcoder_texture_format::cTFBC1_RGB: return "BC1_RGB"; + case transcoder_texture_format::cTFBC4_R: return "BC4_R"; + case transcoder_texture_format::cTFPVRTC1_4_RGB: return "PVRTC1_4_RGB"; + case transcoder_texture_format::cTFPVRTC1_4_RGBA: return "PVRTC1_4_RGBA"; + case transcoder_texture_format::cTFBC7_M6_RGB: return "BC7_M6_RGB"; + case transcoder_texture_format::cTFBC7_M5_RGBA: return "BC7_M5_RGBA"; + case transcoder_texture_format::cTFETC2_RGBA: return "ETC2_RGBA"; + case transcoder_texture_format::cTFBC3_RGBA: return "BC3_RGBA"; + case transcoder_texture_format::cTFBC5_RG: return "BC5_RG"; + case transcoder_texture_format::cTFASTC_4x4_RGBA: return "ASTC_RGBA"; + case transcoder_texture_format::cTFATC_RGB: return "ATC_RGB"; + case transcoder_texture_format::cTFATC_RGBA: return "ATC_RGBA"; + case transcoder_texture_format::cTFRGBA32: return "RGBA32"; + case transcoder_texture_format::cTFRGB565: return "RGB565"; + case transcoder_texture_format::cTFBGR565: return "BGR565"; + case transcoder_texture_format::cTFRGBA4444: return "RGBA4444"; + case transcoder_texture_format::cTFFXT1_RGB: return "FXT1_RGB"; + case transcoder_texture_format::cTFPVRTC2_4_RGB: return "PVRTC2_4_RGB"; + case transcoder_texture_format::cTFPVRTC2_4_RGBA: return "PVRTC2_4_RGBA"; + case transcoder_texture_format::cTFETC2_EAC_R11: return "ETC2_EAC_R11"; + case transcoder_texture_format::cTFETC2_EAC_RG11: return "ETC2_EAC_RG11"; default: assert(0); BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n"); @@ -8338,14 +10339,15 @@ namespace basist { switch (fmt) { - case cTFETC2: - case cTFBC3: - case cTFASTC_4x4: - case cTFBC7_M5: - case cTFPVRTC1_4_RGBA: - case cTFATC_RGBA_INTERPOLATED_ALPHA: - case cTFRGBA32: - case cTFRGBA4444: + case transcoder_texture_format::cTFETC2_RGBA: + case transcoder_texture_format::cTFBC3_RGBA: + case transcoder_texture_format::cTFASTC_4x4_RGBA: + case transcoder_texture_format::cTFBC7_M5_RGBA: + case transcoder_texture_format::cTFPVRTC1_4_RGBA: + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + case transcoder_texture_format::cTFATC_RGBA: + case transcoder_texture_format::cTFRGBA32: + case transcoder_texture_format::cTFRGBA4444: return true; default: break; @@ -8357,39 +10359,44 @@ namespace basist { switch (fmt) { - case cTFETC1: return basisu::cETC1; - case cTFBC1: return basisu::cBC1; - case cTFBC4: return basisu::cBC4; - case cTFPVRTC1_4_RGB: return basisu::cPVRTC1_4_RGB; - case cTFPVRTC1_4_RGBA: return basisu::cPVRTC1_4_RGBA; - case cTFBC7_M6_OPAQUE_ONLY: return basisu::cBC7; - case cTFBC7_M5: return basisu::cBC7; - case cTFETC2: return basisu::cETC2_RGBA; - case cTFBC3: return basisu::cBC3; - case cTFBC5: return basisu::cBC5; - case cTFASTC_4x4: return basisu::cASTC4x4; - case cTFATC_RGB: return basisu::cATC_RGB; - case cTFATC_RGBA_INTERPOLATED_ALPHA: return basisu::cATC_RGBA_INTERPOLATED_ALPHA; - case cTFRGBA32: return basisu::cRGBA32; - case cTFRGB565: return basisu::cRGB565; - case cTFBGR565: return basisu::cBGR565; - case cTFRGBA4444: return basisu::cRGBA4444; + case transcoder_texture_format::cTFETC1_RGB: return basisu::texture_format::cETC1; + case transcoder_texture_format::cTFBC1_RGB: return basisu::texture_format::cBC1; + case transcoder_texture_format::cTFBC4_R: return basisu::texture_format::cBC4; + case transcoder_texture_format::cTFPVRTC1_4_RGB: return basisu::texture_format::cPVRTC1_4_RGB; + case transcoder_texture_format::cTFPVRTC1_4_RGBA: return basisu::texture_format::cPVRTC1_4_RGBA; + case transcoder_texture_format::cTFBC7_M6_RGB: return basisu::texture_format::cBC7; + case transcoder_texture_format::cTFBC7_M5_RGBA: return basisu::texture_format::cBC7; + case transcoder_texture_format::cTFETC2_RGBA: return basisu::texture_format::cETC2_RGBA; + case transcoder_texture_format::cTFBC3_RGBA: return basisu::texture_format::cBC3; + case transcoder_texture_format::cTFBC5_RG: return basisu::texture_format::cBC5; + case transcoder_texture_format::cTFASTC_4x4_RGBA: return basisu::texture_format::cASTC4x4; + case transcoder_texture_format::cTFATC_RGB: return basisu::texture_format::cATC_RGB; + case transcoder_texture_format::cTFATC_RGBA: return basisu::texture_format::cATC_RGBA_INTERPOLATED_ALPHA; + case transcoder_texture_format::cTFRGBA32: return basisu::texture_format::cRGBA32; + case transcoder_texture_format::cTFRGB565: return basisu::texture_format::cRGB565; + case transcoder_texture_format::cTFBGR565: return basisu::texture_format::cBGR565; + case transcoder_texture_format::cTFRGBA4444: return basisu::texture_format::cRGBA4444; + case transcoder_texture_format::cTFFXT1_RGB: return basisu::texture_format::cFXT1_RGB; + case transcoder_texture_format::cTFPVRTC2_4_RGB: return basisu::texture_format::cPVRTC2_4_RGBA; + case transcoder_texture_format::cTFPVRTC2_4_RGBA: return basisu::texture_format::cPVRTC2_4_RGBA; + case transcoder_texture_format::cTFETC2_EAC_R11: return basisu::texture_format::cETC2_R11_EAC; + case transcoder_texture_format::cTFETC2_EAC_RG11: return basisu::texture_format::cETC2_RG11_EAC; default: assert(0); BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n"); break; } - return basisu::cInvalidTextureFormat; + return basisu::texture_format::cInvalidTextureFormat; } bool basis_transcoder_format_is_uncompressed(transcoder_texture_format tex_type) { switch (tex_type) { - case cTFRGBA32: - case cTFRGB565: - case cTFBGR565: - case cTFRGBA4444: + case transcoder_texture_format::cTFRGBA32: + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: + case transcoder_texture_format::cTFRGBA4444: return true; default: break; @@ -8401,14 +10408,14 @@ namespace basist { switch (tex_type) { - case cRGB32: - case cRGBA32: - case cA32: - case cRGB565: - case cBGR565: - case cRGBA4444_COLOR: - case cRGBA4444_ALPHA: - case cRGBA4444_COLOR_OPAQUE: + case block_format::cRGB32: + case block_format::cRGBA32: + case block_format::cA32: + case block_format::cRGB565: + case block_format::cBGR565: + case block_format::cRGBA4444_COLOR: + case block_format::cRGBA4444_ALPHA: + case block_format::cRGBA4444_COLOR_OPAQUE: return true; default: break; @@ -8420,17 +10427,106 @@ namespace basist { switch (fmt) { - case cTFRGBA32: + case transcoder_texture_format::cTFRGBA32: return sizeof(uint32_t); - case cTFRGB565: - case cTFBGR565: - case cTFRGBA4444: + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: + case transcoder_texture_format::cTFRGBA4444: return sizeof(uint16_t); default: break; } return 0; } + + uint32_t basis_get_block_width(transcoder_texture_format tex_type) + { + switch (tex_type) + { + case transcoder_texture_format::cTFFXT1_RGB: + return 8; + default: + break; + } + return 4; + } + + uint32_t basis_get_block_height(transcoder_texture_format tex_type) + { + (void)tex_type; + return 4; + } + + bool basis_is_format_supported(transcoder_texture_format tex_type) + { + switch (tex_type) + { + // ETC1 and uncompressed are always supported. + case transcoder_texture_format::cTFETC1_RGB: + case transcoder_texture_format::cTFRGBA32: + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: + case transcoder_texture_format::cTFRGBA4444: + return true; +#if BASISD_SUPPORT_DXT1 + case transcoder_texture_format::cTFBC1_RGB: + return true; +#endif +#if BASISD_SUPPORT_DXT5A + case transcoder_texture_format::cTFBC4_R: + case transcoder_texture_format::cTFBC5_RG: + return true; +#endif +#if BASISD_SUPPORT_DXT1 && BASISD_SUPPORT_DXT5A + case transcoder_texture_format::cTFBC3_RGBA: + return true; +#endif +#if BASISD_SUPPORT_PVRTC1 + case transcoder_texture_format::cTFPVRTC1_4_RGB: + case transcoder_texture_format::cTFPVRTC1_4_RGBA: + return true; +#endif +#if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY + case transcoder_texture_format::cTFBC7_M6_RGB: + return true; +#endif +#if BASISD_SUPPORT_BC7_MODE5 + case transcoder_texture_format::cTFBC7_M5_RGBA: + return true; +#endif +#if BASISD_SUPPORT_ETC2_EAC_A8 + case transcoder_texture_format::cTFETC2_RGBA: + return true; +#endif +#if BASISD_SUPPORT_ASTC + case transcoder_texture_format::cTFASTC_4x4_RGBA: + return true; +#endif +#if BASISD_SUPPORT_ATC + case transcoder_texture_format::cTFATC_RGB: + case transcoder_texture_format::cTFATC_RGBA: + return true; +#endif +#if BASISD_SUPPORT_FXT1 + case transcoder_texture_format::cTFFXT1_RGB: + return true; +#endif +#if BASISD_SUPPORT_PVRTC2 + case transcoder_texture_format::cTFPVRTC2_4_RGB: + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + return true; +#endif +#if BASISD_SUPPORT_ETC2_EAC_RG11 + case transcoder_texture_format::cTFETC2_EAC_R11: + case transcoder_texture_format::cTFETC2_EAC_RG11: + return true; +#endif + default: + break; + } + + return false; + } } // namespace basist diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder.h b/thirdparty/basis_universal/transcoder/basisu_transcoder.h index 877dee43b1..770c64122d 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder.h +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder.h @@ -31,42 +31,64 @@ namespace basist // fully opaque (255) alpha channel. // - The PVRTC1 texture formats only support power of 2 dimension .basis files, but this may be relaxed in a future version. // - The PVRTC1 transcoders are real-time encoders, so don't expect the highest quality. We may add a slower encoder with improved quality. - enum transcoder_texture_format + // - These enums must be kept in sync with Javascript code that calls the transcoder. + enum class transcoder_texture_format { // Compressed formats // ETC1-2 - cTFETC1, // Opaque only, returns RGB or alpha data if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified - cTFETC2, // Opaque+alpha, ETC2_EAC_A8 block followed by a ETC1 block, alpha channel will be opaque for opaque .basis files - - // BC1-5, BC7 - cTFBC1, // Opaque only, no punchthrough alpha support yet, transcodes alpha slice if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified - cTFBC3, // Opaque+alpha, BC4 followed by a BC1 block, alpha channel will be opaque for opaque .basis files - cTFBC4, // Red only, alpha slice is transcoded to output if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified - cTFBC5, // XY: Two BC4 blocks, X=R and Y=Alpha, .basis file should have alpha data (if not Y will be all 255's) - cTFBC7_M6_OPAQUE_ONLY, // Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified. Highest quality of all the non-ETC1 formats. - cTFBC7_M5, // Opaque+alpha, alpha channel will be opaque for opaque .basis files - - // PVRTC1 4bpp - cTFPVRTC1_4_RGB, // Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified, nearly lowest quality of any texture format. - cTFPVRTC1_4_RGBA, // Opaque+alpha, most useful for simple opacity maps. If .basis file doens't have alpha cTFPVRTC1_4_RGB will be used instead. Lowest quality of any supported texture format. - - // ASTC - cTFASTC_4x4, // Opaque+alpha, ASTC 4x4, alpha channel will be opaque for opaque .basis files. Transcoder uses RGB/RGBA/L/LA modes, void extent, and up to two ([0,47] and [0,255]) endpoint precisions. - - // ATC - cTFATC_RGB, // Opaque, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified. ATI ATC (GL_ATC_RGB_AMD) - cTFATC_RGBA_INTERPOLATED_ALPHA, // Opaque+alpha, alpha channel will be opaque for opaque .basis files. ATI ATC (ATC_RGBA_INTERPOLATED_ALPHA_AMD) - - cTFTotalBlockTextureFormats, - + cTFETC1_RGB = 0, // Opaque only, returns RGB or alpha data if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified + cTFETC2_RGBA = 1, // Opaque+alpha, ETC2_EAC_A8 block followed by a ETC1 block, alpha channel will be opaque for opaque .basis files + + // BC1-5, BC7 (desktop, some mobile devices) + cTFBC1_RGB = 2, // Opaque only, no punchthrough alpha support yet, transcodes alpha slice if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified + cTFBC3_RGBA = 3, // Opaque+alpha, BC4 followed by a BC1 block, alpha channel will be opaque for opaque .basis files + cTFBC4_R = 4, // Red only, alpha slice is transcoded to output if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified + cTFBC5_RG = 5, // XY: Two BC4 blocks, X=R and Y=Alpha, .basis file should have alpha data (if not Y will be all 255's) + cTFBC7_M6_RGB = 6, // Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified. Highest quality of all the non-ETC1 formats. + cTFBC7_M5_RGBA = 7, // Opaque+alpha, alpha channel will be opaque for opaque .basis files + + // PVRTC1 4bpp (mobile, PowerVR devices) + cTFPVRTC1_4_RGB = 8, // Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified, nearly lowest quality of any texture format. + cTFPVRTC1_4_RGBA = 9, // Opaque+alpha, most useful for simple opacity maps. If .basis file doens't have alpha cTFPVRTC1_4_RGB will be used instead. Lowest quality of any supported texture format. + + // ASTC (mobile, Intel devices, hopefully all desktop GPU's one day) + cTFASTC_4x4_RGBA = 10, // Opaque+alpha, ASTC 4x4, alpha channel will be opaque for opaque .basis files. Transcoder uses RGB/RGBA/L/LA modes, void extent, and up to two ([0,47] and [0,255]) endpoint precisions. + + // ATC (mobile, Adreno devices, this is a niche format) + cTFATC_RGB = 11, // Opaque, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified. ATI ATC (GL_ATC_RGB_AMD) + cTFATC_RGBA = 12, // Opaque+alpha, alpha channel will be opaque for opaque .basis files. ATI ATC (GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD) + + // FXT1 (desktop, Intel devices, this is a super obscure format) + cTFFXT1_RGB = 17, // Opaque only, uses exclusively CC_MIXED blocks. Notable for having a 8x4 block size. GL_3DFX_texture_compression_FXT1 is supported on Intel integrated GPU's (such as HD 630). + // Punch-through alpha is relatively easy to support, but full alpha is harder. This format is only here for completeness so opaque-only is fine for now. + // See the BASISU_USE_ORIGINAL_3DFX_FXT1_ENCODING macro in basisu_transcoder_internal.h. + + cTFPVRTC2_4_RGB = 18, // Opaque-only, almost BC1 quality, much faster to transcode and supports arbitrary texture dimensions (unlike PVRTC1 RGB). + cTFPVRTC2_4_RGBA = 19, // Opaque+alpha, slower to encode than cTFPVRTC2_4_RGB. Premultiplied alpha is highly recommended, otherwise the color channel can leak into the alpha channel on transparent blocks. + + cTFETC2_EAC_R11 = 20, // R only (ETC2 EAC R11 unsigned) + cTFETC2_EAC_RG11 = 21, // RG only (ETC2 EAC RG11 unsigned), R=opaque.r, G=alpha - for tangent space normal maps + // Uncompressed (raw pixel) formats - cTFRGBA32 = cTFTotalBlockTextureFormats, // 32bpp RGBA image stored in raster (not block) order in memory, R is first byte, A is last byte. - cTFRGB565, // 166pp RGB image stored in raster (not block) order in memory, R at bit position 11 - cTFBGR565, // 16bpp RGB image stored in raster (not block) order in memory, R at bit position 0 - cTFRGBA4444, // 16bpp RGBA image stored in raster (not block) order in memory, R at bit position 12, A at bit position 0 - - cTFTotalTextureFormats + cTFRGBA32 = 13, // 32bpp RGBA image stored in raster (not block) order in memory, R is first byte, A is last byte. + cTFRGB565 = 14, // 166pp RGB image stored in raster (not block) order in memory, R at bit position 11 + cTFBGR565 = 15, // 16bpp RGB image stored in raster (not block) order in memory, R at bit position 0 + cTFRGBA4444 = 16, // 16bpp RGBA image stored in raster (not block) order in memory, R at bit position 12, A at bit position 0 + + cTFTotalTextureFormats = 22, + + // Old enums for compatibility with code compiled against previous versions + cTFETC1 = cTFETC1_RGB, + cTFETC2 = cTFETC2_RGBA, + cTFBC1 = cTFBC1_RGB, + cTFBC3 = cTFBC3_RGBA, + cTFBC4 = cTFBC4_R, + cTFBC5 = cTFBC5_RG, + cTFBC7_M6_OPAQUE_ONLY = cTFBC7_M6_RGB, + cTFBC7_M5 = cTFBC7_M5_RGBA, + cTFASTC_4x4 = cTFASTC_4x4_RGBA, + cTFATC_RGBA_INTERPOLATED_ALPHA = cTFATC_RGBA, }; uint32_t basis_get_bytes_per_block(transcoder_texture_format fmt); @@ -74,10 +96,16 @@ namespace basist bool basis_transcoder_format_has_alpha(transcoder_texture_format fmt); basisu::texture_format basis_get_basisu_texture_format(transcoder_texture_format fmt); const char* basis_get_texture_type_name(basis_texture_type tex_type); + bool basis_transcoder_format_is_uncompressed(transcoder_texture_format tex_type); - bool basis_block_format_is_uncompressed(block_format tex_type); uint32_t basis_get_uncompressed_bytes_per_pixel(transcoder_texture_format fmt); + uint32_t basis_get_block_width(transcoder_texture_format tex_type); + uint32_t basis_get_block_height(transcoder_texture_format tex_type); + + // Returns true if the specified format was enabled at compile time. + bool basis_is_format_supported(transcoder_texture_format tex_type); + class basisu_transcoder; // This struct holds all state used during transcoding. For video, it needs to persist between image transcodes (it holds the previous frame). @@ -111,7 +139,7 @@ namespace basist bool decode_tables(const uint8_t *pTable_data, uint32_t table_data_size); bool transcode_slice(void *pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t *pImage_data, uint32_t image_data_size, block_format fmt, - uint32_t output_block_or_pixel_stride_in_bytes, bool wrap_addressing, bool bc1_allow_threecolor_blocks, const basis_file_header &header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels = 0, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const basis_file_header &header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state *pState = nullptr, bool astc_transcode_alpha = false, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0); private: @@ -276,9 +304,6 @@ namespace basist enum { - // PVRTC1: texture will use wrap addressing vs. clamp (most PVRTC viewer tools assume wrap addressing, so we default to wrap although that can cause edge artifacts) - cDecodeFlagsPVRTCWrapAddressing = 1, - // PVRTC1: decode non-pow2 ETC1S texture level to the next larger power of 2 (not implemented yet, but we're going to support it). Ignored if the slice's dimensions are already a power of 2. cDecodeFlagsPVRTCDecodeToNextPow2 = 2, @@ -292,7 +317,7 @@ namespace basist // The output buffer contains alpha endpoint/selector indices. // Used internally when decoding formats like ASTC that require both color and alpha data to be available when transcoding to the output format. - cDecodeFlagsOutputHasAlphaIndices = 16, + cDecodeFlagsOutputHasAlphaIndices = 16 }; // transcode_image_level() decodes a single mipmap level from the .basis file to any of the supported output texture formats. @@ -311,7 +336,7 @@ namespace basist uint32_t image_index, uint32_t level_index, void *pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, transcoder_texture_format fmt, - uint32_t decode_flags = cDecodeFlagsPVRTCWrapAddressing, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state *pState = nullptr, uint32_t output_rows_in_pixels = 0) const; + uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state *pState = nullptr, uint32_t output_rows_in_pixels = 0) const; // Finds the basis slice corresponding to the specified image/level/alpha params, or -1 if the slice can't be found. int find_slice(const void *pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, bool alpha_data) const; @@ -327,7 +352,7 @@ namespace basist // - basisu_transcoder_init() must have been called first to initialize the transcoder lookup tables before calling this function. bool transcode_slice(const void *pData, uint32_t data_size, uint32_t slice_index, void *pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, - block_format fmt, uint32_t output_block_stride_in_bytes, uint32_t decode_flags = cDecodeFlagsPVRTCWrapAddressing, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state * pState = nullptr, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0) const; + block_format fmt, uint32_t output_block_stride_in_bytes, uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state * pState = nullptr, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0) const; private: mutable basisu_lowlevel_transcoder m_lowlevel_decoder; diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_internal.h b/thirdparty/basis_universal/transcoder/basisu_transcoder_internal.h index ffa9b6fcae..a9c6823d92 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_internal.h +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_internal.h @@ -42,7 +42,7 @@ namespace basist { // Low-level formats directly supported by the transcoder (other supported texture formats are combinations of these low-level block formats). // You probably don't care about these enum's unless you are going pretty low-level and calling the transcoder to decode individual slices. - enum block_format + enum class block_format { cETC1, // ETC1S RGB cBC1, // DXT1 RGB @@ -57,6 +57,7 @@ namespace basist // data. If you use a sRGB ASTC format you'll get ~1 LSB of additional error, because of the different way ASTC decoders scale 8-bit endpoints to 16-bits during unpacking. cATC_RGB, cATC_RGBA_INTERPOLATED_ALPHA, + cFXT1_RGB, // Opaque-only, has oddball 8x4 pixel block size cIndices, // Used internally: Write 16-bit endpoint and selector indices directly to output (output block must be at least 32-bits) @@ -71,6 +72,11 @@ namespace basist cRGBA4444_ALPHA, cRGBA4444_COLOR_OPAQUE, + cPVRTC2_4_RGB, + cPVRTC2_4_RGBA, + + cETC2_EAC_R11, + cTotalBlockFormats }; @@ -624,6 +630,11 @@ namespace basist struct decoder_etc_block; + inline uint8_t clamp255(int32_t i) + { + return (uint8_t)((i & 0xFFFFFF00U) ? (~(i >> 31)) : i); + } + struct color32 { union @@ -647,6 +658,8 @@ namespace basist void set(uint32_t vr, uint32_t vg, uint32_t vb, uint32_t va) { c[0] = static_cast<uint8_t>(vr); c[1] = static_cast<uint8_t>(vg); c[2] = static_cast<uint8_t>(vb); c[3] = static_cast<uint8_t>(va); } + void set_clamped(int vr, int vg, int vb, int va) { c[0] = clamp255(vr); c[1] = clamp255(vg); c[2] = clamp255(vb); c[3] = clamp255(va); } + uint8_t operator[] (uint32_t idx) const { assert(idx < 4); return c[idx]; } uint8_t &operator[] (uint32_t idx) { assert(idx < 4); return c[idx]; } @@ -733,6 +746,8 @@ namespace basist } }; + bool basis_block_format_is_uncompressed(block_format tex_type); + } // namespace basist diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_45.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_45.inc new file mode 100644 index 0000000000..0bca0bbddc --- /dev/null +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_45.inc @@ -0,0 +1,481 @@ +{0,2,20},{0,1,10},{0,1,1},{0,1,9},{0,1,35},{0,1,27},{0,1,18},{0,1,61},{0,1,52},{0,0,68},{0,2,20},{0,1,10},{0,1,1},{0,1,9},{0,1,35},{0,1,27},{0,1,18},{0,1,61},{0,1,43},{0,1,61},{0,1,1},{0,1,1},{0,1,1},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,1,1}, +{0,1,1},{0,1,1},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,2,20},{0,1,10},{0,1,1},{0,1,9},{0,2,20},{0,1,18},{0,1,9},{0,1,36},{0,1,18},{0,1,36},{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,4,56},{0,3,38},{0,2,52}, +{0,2,36},{0,4,56},{0,3,35},{0,2,0},{0,2,52},{0,2,88},{0,1,78},{0,4,56},{0,3,38},{0,2,52},{0,2,36},{1,0,52},{0,3,35},{0,2,0},{0,2,52},{1,1,51},{0,2,52},{0,3,37},{0,3,37},{0,3,37},{0,2,36},{0,3,10},{0,2,0},{0,2,0},{0,1,5},{0,1,35},{0,1,14},{0,3,37},{0,3,37},{0,3,37},{0,2,36},{0,3,10}, +{0,2,0},{0,2,0},{0,1,5},{1,0,16},{0,1,5},{1,1,18},{0,3,2},{0,2,16},{0,2,0},{1,1,18},{2,0,20},{0,2,0},{0,2,36},{2,0,20},{0,2,36},{0,0,36},{0,0,36},{0,0,36},{0,0,36},{0,2,0},{0,2,0},{0,2,0},{0,1,1},{0,1,10},{0,1,10},{1,4,88},{1,3,78},{1,3,69},{1,3,77},{1,3,115},{0,4,88},{0,3,98}, +{0,3,101},{0,4,72},{0,3,38},{1,4,24},{1,3,14},{1,3,5},{1,3,13},{1,3,51},{0,4,24},{0,3,34},{0,3,37},{3,0,52},{0,3,37},{1,3,69},{1,3,69},{1,3,69},{1,2,72},{1,2,72},{1,2,72},{1,2,72},{1,2,72},{0,3,11},{0,2,24},{1,3,5},{1,3,5},{1,3,5},{1,2,8},{1,2,8},{1,2,8},{1,2,8},{1,2,8},{1,2,8}, +{1,2,8},{0,7,18},{1,3,10},{1,3,1},{0,3,9},{0,7,18},{1,3,18},{0,3,9},{0,3,36},{1,3,18},{0,3,36},{1,0,68},{1,0,68},{1,0,68},{1,0,68},{1,1,65},{1,1,65},{1,1,65},{0,3,65},{0,3,2},{0,3,2},{1,6,56},{1,5,38},{1,4,53},{1,4,37},{1,6,56},{1,5,35},{1,4,1},{1,4,66},{0,5,60},{0,4,70},{1,6,56}, +{1,5,38},{1,4,53},{1,4,37},{0,9,51},{1,5,35},{1,4,1},{0,4,54},{2,3,51},{0,4,54},{1,5,37},{1,5,37},{1,5,37},{1,4,36},{1,5,10},{1,4,0},{1,4,0},{1,3,5},{0,5,11},{1,3,14},{1,5,37},{1,5,37},{1,5,37},{1,4,36},{0,8,8},{1,4,0},{1,4,0},{1,3,5},{4,0,8},{1,3,5},{2,3,18},{1,5,2},{1,4,17}, +{1,4,1},{2,3,18},{4,1,18},{1,4,1},{0,4,50},{4,1,18},{0,4,50},{1,0,36},{1,0,36},{1,0,36},{1,0,36},{1,4,0},{1,4,0},{1,4,0},{1,3,1},{1,3,10},{1,3,10},{2,6,88},{2,5,78},{2,5,69},{2,5,77},{2,5,115},{2,5,107},{2,5,98},{1,5,117},{1,6,60},{1,5,36},{2,6,24},{2,5,14},{2,5,5},{2,5,13},{3,2,51}, +{1,6,35},{2,5,34},{1,5,36},{1,6,51},{1,5,36},{2,5,69},{2,5,69},{2,5,69},{2,4,72},{2,4,72},{2,4,72},{2,4,72},{2,4,72},{1,5,16},{1,5,36},{2,5,5},{2,5,5},{2,5,5},{2,4,8},{3,1,8},{2,4,8},{2,4,8},{2,4,8},{3,3,8},{2,4,8},{3,3,20},{2,5,10},{2,5,1},{2,5,9},{3,3,20},{2,5,18},{2,5,9}, +{0,5,36},{2,5,18},{0,5,36},{2,0,68},{2,0,68},{2,0,68},{2,0,68},{2,3,68},{2,3,68},{2,3,68},{2,4,68},{1,5,0},{1,5,0},{2,8,56},{2,7,38},{2,6,52},{2,6,36},{2,8,56},{2,7,35},{2,6,0},{2,6,52},{1,7,76},{1,6,70},{2,8,56},{2,7,38},{2,6,52},{2,6,36},{4,1,51},{2,7,35},{2,6,0},{1,6,45},{3,5,51}, +{1,6,45},{2,7,37},{2,7,37},{2,7,37},{2,6,36},{2,7,10},{2,6,0},{2,6,0},{2,5,5},{1,7,12},{2,5,14},{2,7,37},{2,7,37},{2,7,37},{2,6,36},{4,0,8},{2,6,0},{2,6,0},{2,5,5},{1,7,8},{2,5,5},{3,5,18},{2,7,2},{2,6,16},{2,6,0},{3,5,18},{0,9,18},{2,6,0},{0,6,36},{0,9,18},{0,6,36},{2,0,36}, +{2,0,36},{2,0,36},{2,0,36},{2,6,0},{2,6,0},{2,6,0},{2,5,1},{1,7,8},{1,7,8},{3,8,88},{3,7,78},{3,7,69},{3,7,77},{3,7,115},{2,8,88},{2,7,98},{2,7,101},{1,9,67},{2,7,38},{3,8,24},{3,7,14},{3,7,5},{3,7,13},{3,7,51},{2,8,24},{2,7,34},{2,7,37},{8,0,51},{2,7,37},{3,7,69},{3,7,69},{3,7,69}, +{3,6,72},{3,6,72},{3,6,72},{3,6,72},{3,6,72},{2,7,11},{2,6,24},{3,7,5},{3,7,5},{3,7,5},{3,6,8},{3,6,8},{3,6,8},{3,6,8},{3,6,8},{3,6,8},{3,6,8},{5,1,18},{3,7,10},{3,7,1},{2,7,9},{5,1,18},{3,7,18},{2,7,9},{0,7,36},{3,7,18},{0,7,36},{3,0,68},{3,0,68},{3,0,68},{3,0,68},{3,5,65}, +{3,5,65},{3,5,65},{2,7,65},{2,7,2},{2,7,2},{3,10,56},{3,9,38},{3,8,53},{3,8,37},{3,10,56},{3,9,35},{3,8,1},{3,8,66},{2,9,60},{2,8,70},{3,10,56},{3,9,38},{3,8,53},{3,8,37},{5,3,51},{3,9,35},{3,8,1},{2,8,54},{4,7,51},{2,8,54},{3,9,37},{3,9,37},{3,9,37},{3,8,36},{3,9,10},{3,8,0},{3,8,0}, +{3,7,5},{2,9,11},{3,7,14},{3,9,37},{3,9,37},{3,9,37},{3,8,36},{5,2,8},{3,8,0},{3,8,0},{3,7,5},{8,1,8},{3,7,5},{4,7,18},{3,9,2},{3,8,17},{3,8,1},{4,7,18},{8,2,18},{3,8,1},{0,8,50},{8,2,18},{0,8,50},{3,0,36},{3,0,36},{3,0,36},{3,0,36},{3,8,0},{3,8,0},{3,8,0},{3,7,1},{3,7,10}, +{3,7,10},{4,10,88},{4,9,78},{4,9,69},{4,9,77},{4,9,115},{4,9,107},{4,9,98},{3,9,117},{3,10,60},{3,9,36},{4,10,24},{4,9,14},{4,9,5},{4,9,13},{5,6,51},{3,10,35},{4,9,34},{3,9,36},{10,1,51},{3,9,36},{4,9,69},{4,9,69},{4,9,69},{4,8,72},{4,8,72},{4,8,72},{4,8,72},{4,8,72},{3,9,16},{3,9,36},{4,9,5}, +{4,9,5},{4,9,5},{4,8,8},{5,5,8},{4,8,8},{4,8,8},{4,8,8},{5,7,8},{4,8,8},{7,0,18},{4,9,10},{4,9,1},{4,9,9},{7,0,18},{4,9,18},{4,9,9},{0,9,36},{4,9,18},{0,9,36},{4,0,68},{4,0,68},{4,0,68},{4,0,68},{4,7,68},{4,7,68},{4,7,68},{4,8,68},{3,9,0},{3,9,0},{4,12,56},{4,11,38},{4,10,52}, +{4,10,36},{4,12,56},{4,11,35},{4,10,0},{4,10,52},{3,11,76},{3,10,70},{4,12,56},{4,11,38},{4,10,52},{4,10,36},{7,2,51},{4,11,35},{4,10,0},{3,10,45},{12,0,51},{3,10,45},{4,11,37},{4,11,37},{4,11,37},{4,10,36},{4,11,10},{4,10,0},{4,10,0},{4,9,5},{3,11,12},{4,9,14},{4,11,37},{4,11,37},{4,11,37},{4,10,36},{7,1,8}, +{4,10,0},{4,10,0},{4,9,5},{10,2,8},{4,9,5},{5,9,18},{4,11,2},{4,10,16},{4,10,0},{5,9,18},{10,3,18},{4,10,0},{0,10,36},{10,3,18},{0,10,36},{4,0,36},{4,0,36},{4,0,36},{4,0,36},{4,10,0},{4,10,0},{4,10,0},{4,9,1},{3,11,8},{3,11,8},{5,12,88},{5,11,78},{5,11,69},{5,11,77},{5,11,115},{4,12,88},{4,11,98}, +{4,11,101},{3,13,67},{4,11,38},{5,12,24},{5,11,14},{5,11,5},{5,11,13},{5,11,51},{4,12,24},{4,11,34},{4,11,37},{11,3,51},{4,11,37},{5,11,69},{5,11,69},{5,11,69},{5,10,72},{5,10,72},{5,10,72},{5,10,72},{5,10,72},{4,11,11},{4,10,24},{5,11,5},{5,11,5},{5,11,5},{5,10,8},{5,10,8},{5,10,8},{5,10,8},{5,10,8},{12,1,8}, +{5,10,8},{8,0,18},{5,11,10},{5,11,1},{4,11,9},{8,0,18},{12,2,18},{4,11,9},{0,11,36},{12,2,18},{0,11,36},{5,0,68},{5,0,68},{5,0,68},{5,0,68},{5,9,65},{5,9,65},{5,9,65},{4,11,65},{4,11,2},{4,11,2},{5,14,56},{5,13,38},{5,12,53},{5,12,37},{5,14,56},{5,13,35},{5,12,1},{5,12,66},{4,13,60},{4,12,70},{5,14,56}, +{5,13,38},{5,12,53},{5,12,37},{8,2,51},{5,13,35},{5,12,1},{4,12,54},{13,2,51},{4,12,54},{5,13,37},{5,13,37},{5,13,37},{5,12,36},{5,13,10},{5,12,0},{5,12,0},{5,11,5},{4,13,11},{5,11,14},{5,13,37},{5,13,37},{5,13,37},{5,12,36},{8,1,8},{5,12,0},{5,12,0},{5,11,5},{10,5,8},{5,11,5},{6,11,18},{5,13,2},{5,12,17}, +{5,12,1},{6,11,18},{15,0,18},{5,12,1},{0,12,50},{15,0,18},{0,12,50},{5,0,36},{5,0,36},{5,0,36},{5,0,36},{5,12,0},{5,12,0},{5,12,0},{5,11,1},{5,11,10},{5,11,10},{6,14,88},{6,13,78},{6,13,69},{6,13,77},{6,13,115},{6,13,107},{6,13,98},{5,13,117},{5,14,60},{5,13,36},{6,14,24},{6,13,14},{6,13,5},{6,13,13},{8,5,51}, +{5,14,35},{6,13,34},{5,13,36},{12,5,51},{5,13,36},{6,13,69},{6,13,69},{6,13,69},{6,12,72},{6,12,72},{6,12,72},{6,12,72},{6,12,72},{5,13,16},{5,13,36},{6,13,5},{6,13,5},{6,13,5},{6,12,8},{8,4,8},{6,12,8},{6,12,8},{6,12,8},{14,2,8},{6,12,8},{3,24,18},{6,13,10},{6,13,1},{6,13,9},{3,24,18},{14,3,18},{6,13,9}, +{0,13,36},{14,3,18},{0,13,36},{6,0,68},{6,0,68},{6,0,68},{6,0,68},{6,11,68},{6,11,68},{6,11,68},{6,12,68},{5,13,0},{5,13,0},{6,16,56},{6,15,38},{6,14,52},{6,14,36},{6,16,56},{6,15,35},{6,14,0},{6,14,52},{5,15,76},{5,14,70},{6,16,56},{6,15,38},{6,14,52},{6,14,36},{3,26,51},{6,15,35},{6,14,0},{5,14,45},{15,3,51}, +{5,14,45},{6,15,37},{6,15,37},{6,15,37},{6,14,36},{6,15,10},{6,14,0},{6,14,0},{6,13,5},{5,15,12},{6,13,14},{6,15,37},{6,15,37},{6,15,37},{6,14,36},{3,25,8},{6,14,0},{6,14,0},{6,13,5},{12,6,8},{6,13,5},{9,5,18},{6,15,2},{6,14,16},{6,14,0},{9,5,18},{12,7,18},{6,14,0},{0,14,36},{12,7,18},{0,14,36},{6,0,36}, +{6,0,36},{6,0,36},{6,0,36},{6,14,0},{6,14,0},{6,14,0},{6,13,1},{5,15,8},{5,15,8},{7,16,88},{7,15,78},{7,15,69},{7,15,77},{7,15,115},{6,16,88},{6,15,98},{6,15,101},{5,17,67},{6,15,38},{7,16,24},{7,15,14},{7,15,5},{7,15,13},{11,0,51},{6,16,24},{6,15,34},{6,15,37},{13,7,51},{6,15,37},{7,15,69},{7,15,69},{7,15,69}, +{7,14,72},{7,14,72},{7,14,72},{7,14,72},{7,14,72},{6,15,11},{6,14,24},{7,15,5},{7,15,5},{7,15,5},{7,14,8},{9,6,8},{7,14,8},{7,14,8},{7,14,8},{14,5,8},{7,14,8},{10,4,18},{7,15,10},{7,15,1},{6,15,9},{10,4,18},{14,6,18},{6,15,9},{0,15,36},{14,6,18},{0,15,36},{7,0,68},{7,0,68},{7,0,68},{7,0,68},{7,13,65}, +{7,13,65},{7,13,65},{6,15,65},{6,15,2},{6,15,2},{7,18,56},{7,17,38},{7,16,53},{7,16,37},{7,18,56},{7,17,35},{7,16,1},{7,16,66},{6,17,60},{6,16,70},{7,18,56},{7,17,38},{7,16,53},{7,16,37},{10,6,51},{7,17,35},{7,16,1},{6,16,54},{15,6,51},{6,16,54},{7,17,37},{7,17,37},{7,17,37},{7,16,36},{7,17,10},{7,16,0},{7,16,0}, +{7,15,5},{6,17,11},{7,15,14},{7,17,37},{7,17,37},{7,17,37},{7,16,36},{10,5,8},{7,16,0},{7,16,0},{7,15,5},{12,9,8},{7,15,5},{12,0,18},{7,17,2},{7,16,17},{7,16,1},{12,0,18},{12,10,18},{7,16,1},{0,16,50},{12,10,18},{0,16,50},{7,0,36},{7,0,36},{7,0,36},{7,0,36},{7,16,0},{7,16,0},{7,16,0},{7,15,1},{7,15,10}, +{7,15,10},{7,21,326},{7,19,322},{8,17,392},{7,17,322},{7,21,137},{7,18,116},{7,17,133},{7,17,117},{7,18,60},{7,17,36},{8,16,118},{8,16,134},{8,17,136},{8,17,136},{10,9,51},{7,18,35},{7,17,52},{7,17,36},{14,9,51},{7,17,36},{7,20,307},{7,20,307},{7,20,307},{7,18,307},{7,20,91},{7,18,91},{7,18,91},{7,16,110},{7,17,16},{7,17,36},{8,15,101}, +{8,15,101},{8,15,101},{8,16,101},{10,8,8},{7,18,10},{7,18,10},{7,16,29},{11,12,8},{7,16,29},{12,3,18},{7,19,16},{8,17,36},{7,17,16},{12,3,18},{11,13,18},{7,17,16},{0,17,36},{11,13,18},{0,17,36},{7,0,306},{7,0,306},{7,0,306},{7,0,306},{7,19,81},{7,19,81},{7,19,81},{7,17,81},{7,17,0},{7,17,0},{8,19,88},{8,18,78},{8,18,69}, +{8,18,77},{8,18,115},{8,18,107},{8,18,98},{8,17,136},{7,19,76},{7,18,70},{8,19,24},{8,18,14},{8,18,5},{8,18,13},{9,15,51},{8,18,43},{8,18,34},{7,18,45},{5,22,51},{7,18,45},{8,18,69},{8,18,69},{8,18,69},{8,17,72},{8,17,72},{8,17,72},{8,17,72},{8,17,72},{7,19,12},{7,18,70},{8,18,5},{8,18,5},{8,18,5},{8,17,8},{9,14,8}, +{8,17,8},{8,17,8},{8,17,8},{14,10,8},{8,17,8},{11,9,18},{8,18,10},{8,18,1},{8,18,9},{11,9,18},{14,11,18},{8,18,9},{0,18,36},{14,11,18},{0,18,36},{8,0,68},{8,0,68},{8,0,68},{8,0,68},{8,16,65},{8,16,65},{8,16,65},{8,17,68},{7,19,8},{7,19,8},{8,21,56},{8,20,38},{8,19,52},{8,19,36},{8,21,56},{8,20,35},{8,19,0}, +{8,19,52},{7,21,67},{8,18,78},{8,21,56},{8,20,38},{8,19,52},{8,19,36},{13,4,51},{8,20,35},{8,19,0},{8,19,52},{15,11,51},{8,19,52},{8,20,37},{8,20,37},{8,20,37},{8,19,36},{8,20,10},{8,19,0},{8,19,0},{8,18,5},{8,18,35},{8,18,14},{8,20,37},{8,20,37},{8,20,37},{8,19,36},{11,10,8},{8,19,0},{8,19,0},{8,18,5},{5,23,8}, +{8,18,5},{12,8,18},{8,20,2},{8,19,16},{8,19,0},{12,8,18},{11,16,18},{8,19,0},{0,19,36},{11,16,18},{0,19,36},{8,0,36},{8,0,36},{8,0,36},{8,0,36},{8,19,0},{8,19,0},{8,19,0},{8,18,1},{8,18,10},{8,18,10},{9,21,88},{9,20,78},{9,20,70},{9,20,78},{9,20,115},{8,21,88},{8,20,99},{8,20,115},{8,21,72},{8,20,52},{9,21,24}, +{9,20,14},{9,20,6},{9,20,14},{15,0,51},{8,21,24},{8,20,35},{8,20,51},{12,16,51},{8,20,51},{9,20,69},{9,20,69},{9,20,69},{9,19,72},{9,19,72},{9,19,72},{9,19,72},{9,19,72},{8,20,11},{8,19,24},{9,20,5},{9,20,5},{9,20,5},{9,19,8},{12,9,8},{9,19,8},{9,19,8},{9,19,8},{14,13,8},{9,19,8},{14,4,18},{9,20,10},{9,20,2}, +{8,20,10},{14,4,18},{14,14,18},{8,20,10},{0,20,50},{14,14,18},{0,20,50},{9,0,68},{9,0,68},{9,0,68},{9,0,68},{9,18,65},{9,18,65},{9,18,65},{8,20,65},{8,20,2},{8,20,2},{9,24,70},{9,22,58},{9,21,75},{9,21,51},{9,23,52},{9,22,25},{9,21,3},{9,21,46},{8,23,68},{8,21,70},{9,24,69},{9,22,57},{9,21,74},{9,21,50},{15,3,51}, +{9,22,24},{9,21,2},{8,21,45},{11,19,51},{8,21,45},{9,23,51},{9,23,51},{9,23,51},{9,21,51},{9,22,9},{9,21,3},{9,21,3},{9,20,9},{8,22,12},{9,20,12},{9,23,50},{9,23,50},{9,23,50},{9,21,50},{15,2,8},{9,21,2},{9,21,2},{9,20,8},{13,16,8},{9,20,8},{14,7,18},{9,22,8},{9,21,25},{9,21,1},{14,7,18},{13,17,18},{9,21,1}, +{0,21,36},{13,17,18},{0,21,36},{9,0,50},{9,0,50},{9,0,50},{9,0,50},{9,21,2},{9,21,2},{9,21,2},{9,20,5},{9,20,8},{9,20,8},{10,23,88},{10,22,78},{10,22,69},{10,22,77},{10,22,115},{10,22,107},{10,22,98},{9,22,117},{9,23,60},{9,22,36},{10,23,24},{10,22,14},{10,22,5},{10,22,13},{11,19,51},{9,23,35},{10,22,34},{9,22,36},{9,23,51}, +{9,22,36},{10,22,69},{10,22,69},{10,22,69},{10,21,72},{10,21,72},{10,21,72},{10,21,72},{10,21,72},{9,22,16},{9,22,36},{10,22,5},{10,22,5},{10,22,5},{10,21,8},{11,18,8},{10,21,8},{10,21,8},{10,21,8},{10,21,8},{10,21,8},{13,13,18},{10,22,10},{10,22,1},{10,22,9},{13,13,18},{15,16,18},{10,22,9},{0,22,36},{15,16,18},{0,22,36},{10,0,68}, +{10,0,68},{10,0,68},{10,0,68},{10,20,65},{10,20,65},{10,20,65},{10,21,68},{9,22,0},{9,22,0},{10,25,56},{10,24,38},{10,23,52},{10,23,36},{10,25,56},{10,24,35},{10,23,0},{10,23,52},{9,24,63},{9,23,70},{10,25,56},{10,24,38},{10,23,52},{10,23,36},{15,8,51},{10,24,35},{10,23,0},{9,23,45},{11,22,51},{9,23,45},{10,24,37},{10,24,37},{10,24,37}, +{10,23,36},{10,24,10},{10,23,0},{10,23,0},{10,22,5},{9,24,14},{10,22,14},{10,24,37},{10,24,37},{10,24,37},{10,23,36},{13,14,8},{10,23,0},{10,23,0},{10,22,5},{8,25,8},{10,22,5},{14,12,18},{10,24,2},{10,23,16},{10,23,0},{14,12,18},{13,20,18},{10,23,0},{0,23,36},{13,20,18},{0,23,36},{10,0,36},{10,0,36},{10,0,36},{10,0,36},{10,23,0}, +{10,23,0},{10,23,0},{10,22,1},{10,22,10},{10,22,10},{11,25,88},{11,24,78},{11,24,70},{11,24,78},{11,24,115},{10,25,88},{10,24,99},{10,24,115},{9,26,67},{10,24,52},{11,25,24},{11,24,14},{11,24,6},{11,24,14},{14,14,51},{10,25,24},{10,24,35},{10,24,51},{14,20,51},{10,24,51},{11,24,69},{11,24,69},{11,24,69},{11,23,72},{11,23,72},{11,23,72},{11,23,72}, +{11,23,72},{10,24,11},{10,23,24},{11,24,5},{11,24,5},{11,24,5},{11,23,8},{14,13,8},{11,23,8},{11,23,8},{11,23,8},{11,23,8},{11,23,8},{13,18,18},{11,24,10},{11,24,2},{10,24,10},{13,18,18},{11,24,18},{10,24,10},{0,24,50},{11,24,18},{0,24,50},{11,0,68},{11,0,68},{11,0,68},{11,0,68},{11,22,65},{11,22,65},{11,22,65},{10,24,65},{10,24,2}, +{10,24,2},{11,28,70},{11,26,58},{11,25,75},{11,25,51},{11,27,52},{11,26,25},{11,25,3},{11,25,46},{10,27,68},{10,25,70},{11,28,69},{11,26,57},{11,25,74},{11,25,50},{14,17,51},{11,26,24},{11,25,2},{10,25,45},{13,23,51},{10,25,45},{11,27,51},{11,27,51},{11,27,51},{11,25,51},{11,26,9},{11,25,3},{11,25,3},{11,24,9},{10,26,12},{11,24,12},{11,27,50}, +{11,27,50},{11,27,50},{11,25,50},{14,16,8},{11,25,2},{11,25,2},{11,24,8},{15,20,8},{11,24,8},{13,21,18},{11,26,8},{11,25,25},{11,25,1},{13,21,18},{15,21,18},{11,25,1},{0,25,36},{15,21,18},{0,25,36},{11,0,50},{11,0,50},{11,0,50},{11,0,50},{11,25,2},{11,25,2},{11,25,2},{11,24,5},{11,24,8},{11,24,8},{12,27,88},{12,26,78},{12,26,69}, +{12,26,77},{12,26,115},{12,26,107},{12,26,98},{11,26,117},{11,27,60},{11,26,36},{12,27,24},{12,26,14},{12,26,5},{12,26,13},{13,23,51},{11,27,35},{12,26,34},{11,26,36},{11,27,51},{11,26,36},{12,26,69},{12,26,69},{12,26,69},{12,25,72},{12,25,72},{12,25,72},{12,25,72},{12,25,72},{11,26,16},{11,26,36},{12,26,5},{12,26,5},{12,26,5},{12,25,8},{13,22,8}, +{12,25,8},{12,25,8},{12,25,8},{12,25,8},{12,25,8},{15,17,18},{12,26,10},{12,26,1},{12,26,9},{15,17,18},{12,26,18},{12,26,9},{0,26,36},{12,26,18},{0,26,36},{12,0,68},{12,0,68},{12,0,68},{12,0,68},{12,24,65},{12,24,65},{12,24,65},{12,25,68},{11,26,0},{11,26,0},{12,29,56},{12,28,38},{12,27,52},{12,27,36},{12,29,56},{12,28,35},{12,27,0}, +{12,27,52},{11,28,63},{11,27,70},{12,29,56},{12,28,38},{12,27,52},{12,27,36},{15,19,51},{12,28,35},{12,27,0},{11,27,45},{13,26,51},{11,27,45},{12,28,37},{12,28,37},{12,28,37},{12,27,36},{12,28,10},{12,27,0},{12,27,0},{12,26,5},{11,28,14},{12,26,14},{12,28,37},{12,28,37},{12,28,37},{12,27,36},{15,18,8},{12,27,0},{12,27,0},{12,26,5},{10,29,8}, +{12,26,5},{13,26,18},{12,28,2},{12,27,16},{12,27,0},{13,26,18},{15,24,18},{12,27,0},{0,27,36},{15,24,18},{0,27,36},{12,0,36},{12,0,36},{12,0,36},{12,0,36},{12,27,0},{12,27,0},{12,27,0},{12,26,1},{12,26,10},{12,26,10},{13,29,88},{13,28,78},{13,28,70},{13,28,78},{13,28,115},{12,29,88},{12,28,99},{12,28,115},{11,30,67},{12,28,52},{13,29,24}, +{13,28,14},{13,28,6},{13,28,14},{13,28,51},{12,29,24},{12,28,35},{12,28,51},{11,30,51},{12,28,51},{13,28,69},{13,28,69},{13,28,69},{13,27,72},{13,27,72},{13,27,72},{13,27,72},{13,27,72},{12,28,11},{12,27,24},{13,28,5},{13,28,5},{13,28,5},{13,27,8},{13,27,8},{13,27,8},{13,27,8},{13,27,8},{13,27,8},{13,27,8},{15,22,18},{13,28,10},{13,28,2}, +{12,28,10},{15,22,18},{13,28,18},{12,28,10},{0,28,50},{13,28,18},{0,28,50},{13,0,68},{13,0,68},{13,0,68},{13,0,68},{13,26,65},{13,26,65},{13,26,65},{12,28,65},{12,28,2},{12,28,2},{13,31,76},{13,30,58},{13,29,75},{13,29,51},{13,31,52},{13,30,25},{13,29,3},{13,29,46},{12,31,68},{12,29,70},{13,31,75},{13,30,57},{13,29,74},{13,29,50},{13,31,51}, +{13,30,24},{13,29,2},{12,29,45},{15,27,51},{12,29,45},{13,31,51},{13,31,51},{13,31,51},{13,29,51},{13,30,9},{13,29,3},{13,29,3},{13,28,9},{12,30,12},{13,28,12},{13,31,50},{13,31,50},{13,31,50},{13,29,50},{13,30,8},{13,29,2},{13,29,2},{13,28,8},{12,30,8},{13,28,8},{15,25,18},{13,30,8},{13,29,25},{13,29,1},{15,25,18},{12,31,18},{13,29,1}, +{0,29,36},{12,31,18},{0,29,36},{13,0,50},{13,0,50},{13,0,50},{13,0,50},{13,29,2},{13,29,2},{13,29,2},{13,28,5},{13,28,8},{13,28,8},{14,31,88},{14,30,78},{14,30,69},{14,30,77},{14,30,115},{14,30,107},{14,30,98},{13,30,117},{13,31,60},{13,30,36},{14,31,24},{14,30,14},{14,30,5},{14,30,13},{15,27,51},{13,31,35},{14,30,34},{13,30,36},{13,31,51}, +{13,30,36},{14,30,69},{14,30,69},{14,30,69},{14,29,72},{14,29,72},{14,29,72},{14,29,72},{14,29,72},{13,30,16},{13,30,36},{14,30,5},{14,30,5},{14,30,5},{14,29,8},{15,26,8},{14,29,8},{14,29,8},{14,29,8},{14,29,8},{14,29,8},{14,31,20},{14,30,10},{14,30,1},{14,30,9},{14,31,20},{14,30,18},{14,30,9},{0,30,36},{14,30,18},{0,30,36},{14,0,68}, +{14,0,68},{14,0,68},{14,0,68},{14,28,65},{14,28,65},{14,28,65},{14,29,68},{13,30,0},{13,30,0},{14,31,152},{14,31,88},{14,31,52},{14,31,36},{14,31,116},{14,31,36},{14,31,0},{14,31,52},{14,31,88},{13,31,70},{15,30,118},{14,31,88},{14,31,52},{14,31,36},{15,29,52},{14,31,36},{14,31,0},{13,31,45},{15,30,51},{13,31,45},{14,31,52},{14,31,52},{14,31,52}, +{14,31,36},{14,31,16},{14,31,0},{14,31,0},{14,30,5},{14,30,35},{14,30,14},{14,31,52},{14,31,52},{14,31,52},{14,31,36},{15,28,10},{14,31,0},{14,31,0},{14,30,5},{15,29,16},{14,30,5},{15,30,18},{15,30,34},{14,31,16},{14,31,0},{15,30,18},{15,30,26},{14,31,0},{0,31,36},{15,30,26},{0,31,36},{14,0,36},{14,0,36},{14,0,36},{14,0,36},{14,31,0}, +{14,31,0},{14,31,0},{14,30,1},{14,30,10},{14,30,10},{15,31,68},{15,31,68},{15,31,68},{15,31,68},{15,31,68},{15,31,68},{15,31,68},{15,31,68},{15,31,68},{14,31,20},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,68},{15,31,68},{15,31,68},{15,31,68},{15,31,68},{15,31,68},{15,31,68}, +{15,31,68},{14,31,56},{14,31,20},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{15,0,68},{15,0,68},{15,0,68},{15,0,68},{15,30,65},{15,30,65},{15,30,65},{15,31,68},{14,31,20}, +{14,31,20},{0,4,74},{0,3,20},{0,2,2},{0,2,26},{0,2,158},{0,2,110},{0,2,62},{0,1,115},{0,1,178},{0,1,124},{0,4,74},{0,3,20},{0,2,2},{0,2,26},{0,2,158},{0,2,110},{0,2,62},{0,1,115},{1,0,158},{0,1,115},{0,2,1},{0,2,1},{0,2,1},{0,1,0},{0,1,13},{0,1,9},{0,1,9},{0,0,25},{0,0,25},{0,0,25},{0,2,1}, +{0,2,1},{0,2,1},{0,1,0},{0,1,13},{0,1,9},{0,1,9},{0,0,25},{0,0,25},{0,0,25},{1,0,74},{0,3,20},{0,2,2},{0,2,26},{1,0,74},{1,1,72},{0,2,26},{0,1,90},{1,1,72},{0,1,90},{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,6,83},{0,5,13},{0,3,26}, +{0,3,14},{0,5,248},{0,3,140},{0,3,41},{0,2,139},{0,2,319},{0,2,175},{0,6,83},{0,5,13},{0,3,26},{0,3,14},{1,1,244},{0,3,140},{0,3,41},{0,2,139},{0,3,248},{0,2,139},{0,4,10},{0,4,10},{0,4,10},{0,3,13},{0,3,52},{0,2,18},{0,2,18},{0,1,29},{0,1,77},{0,1,38},{0,4,10},{0,4,10},{0,4,10},{0,3,13},{0,3,52}, +{0,2,18},{0,2,18},{0,1,29},{1,0,58},{0,1,29},{1,3,72},{0,5,4},{0,3,17},{0,3,5},{1,3,72},{3,0,74},{0,3,5},{0,2,90},{3,0,74},{0,2,90},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,1,0},{0,1,0},{0,1,0},{0,1,4},{0,0,9},{0,0,9},{0,9,193},{0,7,125},{0,4,202},{0,4,122},{0,7,244},{0,5,96},{0,4,2}, +{0,3,106},{0,4,395},{0,3,187},{1,6,99},{1,5,45},{1,4,26},{1,4,50},{1,4,243},{0,5,96},{0,4,2},{0,3,106},{2,2,243},{0,3,106},{0,7,121},{0,7,121},{0,7,121},{0,4,122},{0,5,52},{0,4,2},{0,4,2},{0,3,25},{0,3,133},{0,2,62},{1,4,26},{1,4,26},{1,4,26},{1,3,25},{1,2,50},{0,4,2},{0,4,2},{0,3,25},{1,2,50}, +{0,3,25},{0,9,72},{0,7,4},{1,4,1},{0,4,1},{0,9,72},{2,3,72},{0,4,1},{0,3,90},{2,3,72},{0,3,90},{0,0,121},{0,0,121},{0,0,121},{0,0,121},{0,4,1},{0,4,1},{0,4,1},{0,2,1},{0,2,37},{0,2,37},{1,8,164},{1,7,94},{1,5,106},{1,5,94},{0,10,292},{0,7,125},{0,5,81},{0,4,130},{0,6,364},{0,4,106},{1,8,83}, +{1,7,13},{1,5,25},{1,5,13},{3,0,243},{0,7,76},{0,5,32},{0,4,81},{5,0,243},{0,4,81},{1,6,91},{1,6,91},{1,6,91},{1,5,94},{0,8,99},{0,6,51},{0,6,51},{0,4,66},{0,4,107},{0,4,42},{1,6,10},{1,6,10},{1,6,10},{1,5,13},{0,8,50},{0,6,2},{0,6,2},{0,4,17},{4,0,50},{0,4,17},{3,2,74},{1,7,4},{1,5,16}, +{1,5,4},{3,2,74},{5,1,72},{1,5,4},{0,4,80},{5,1,72},{0,4,80},{1,0,90},{1,0,90},{1,0,90},{1,0,90},{0,6,50},{0,6,50},{0,6,50},{0,4,50},{0,3,20},{0,3,20},{1,11,218},{1,9,149},{1,7,242},{1,6,149},{1,10,248},{1,7,99},{1,6,5},{1,5,99},{0,7,308},{0,5,100},{2,8,99},{2,7,45},{2,6,27},{2,6,51},{3,3,243}, +{0,9,81},{1,6,5},{0,5,99},{4,3,243},{0,5,99},{1,9,145},{1,9,145},{1,9,145},{1,6,148},{1,8,52},{1,6,4},{1,6,4},{1,5,18},{0,6,72},{0,5,19},{2,6,26},{2,6,26},{2,6,26},{2,5,25},{3,1,50},{1,6,4},{1,6,4},{0,5,18},{3,3,50},{0,5,18},{4,1,72},{1,9,5},{2,6,2},{1,6,5},{4,1,72},{3,5,72},{1,6,5}, +{0,5,90},{3,5,72},{0,5,90},{1,0,144},{1,0,144},{1,0,144},{1,0,144},{1,6,0},{1,6,0},{1,6,0},{1,4,4},{0,6,8},{0,6,8},{2,10,164},{2,9,94},{2,7,107},{2,7,95},{1,12,307},{1,9,137},{1,7,115},{1,6,154},{0,9,253},{1,6,106},{2,10,83},{2,9,13},{2,7,26},{2,7,14},{4,2,243},{1,9,73},{2,7,41},{1,6,90},{6,2,243}, +{1,6,90},{2,8,91},{2,8,91},{2,8,91},{2,7,94},{1,10,116},{1,8,69},{1,8,69},{1,6,73},{0,8,50},{1,6,25},{2,8,10},{2,8,10},{2,8,10},{2,7,13},{4,0,50},{1,8,5},{1,8,5},{1,6,9},{1,7,50},{1,6,9},{3,7,72},{2,9,4},{2,7,17},{2,7,5},{3,7,72},{8,0,72},{2,7,5},{0,6,90},{8,0,72},{0,6,90},{2,0,90}, +{2,0,90},{2,0,90},{2,0,90},{1,9,65},{1,9,65},{1,9,65},{1,6,64},{0,7,10},{0,7,10},{2,13,194},{2,11,126},{2,8,203},{2,8,123},{2,11,245},{2,9,97},{2,8,3},{2,7,107},{0,11,249},{1,7,100},{3,10,99},{3,9,45},{3,8,26},{3,8,50},{3,8,243},{1,11,81},{2,8,2},{1,7,99},{4,6,243},{1,7,99},{2,11,122},{2,11,122},{2,11,122}, +{2,8,123},{2,9,53},{2,8,3},{2,8,3},{2,7,26},{1,8,62},{1,7,19},{3,8,26},{3,8,26},{3,8,26},{3,7,25},{3,6,50},{2,8,2},{2,8,2},{1,7,18},{3,6,50},{1,7,18},{5,3,72},{2,11,4},{3,8,1},{2,8,1},{5,3,72},{4,7,72},{2,8,1},{0,7,90},{4,7,72},{0,7,90},{2,0,122},{2,0,122},{2,0,122},{2,0,122},{2,8,2}, +{2,8,2},{2,8,2},{2,6,2},{1,7,10},{1,7,10},{3,12,164},{3,11,94},{3,9,106},{3,9,94},{2,14,292},{2,11,125},{2,9,81},{2,8,130},{1,11,253},{2,8,106},{3,12,83},{3,11,13},{3,9,25},{3,9,13},{5,4,243},{2,11,76},{2,9,32},{2,8,81},{9,1,243},{2,8,81},{3,10,91},{3,10,91},{3,10,91},{3,9,94},{2,12,99},{2,10,51},{2,10,51}, +{2,8,66},{1,10,50},{2,8,42},{3,10,10},{3,10,10},{3,10,10},{3,9,13},{5,2,50},{2,10,2},{2,10,2},{2,8,17},{8,1,50},{2,8,17},{1,19,72},{3,11,4},{3,9,16},{3,9,4},{1,19,72},{9,2,72},{3,9,4},{0,8,80},{9,2,72},{0,8,80},{3,0,90},{3,0,90},{3,0,90},{3,0,90},{2,10,50},{2,10,50},{2,10,50},{2,8,50},{1,9,9}, +{1,9,9},{3,15,218},{3,13,149},{3,11,242},{3,10,149},{3,14,248},{3,11,99},{3,10,5},{3,9,99},{1,13,244},{2,9,100},{4,12,99},{4,11,45},{4,10,27},{4,10,51},{5,7,243},{2,13,81},{3,10,5},{2,9,99},{6,7,243},{2,9,99},{3,13,145},{3,13,145},{3,13,145},{3,10,148},{3,12,52},{3,10,4},{3,10,4},{3,9,18},{1,12,56},{2,9,19},{4,10,26}, +{4,10,26},{4,10,26},{4,9,25},{5,5,50},{3,10,4},{3,10,4},{2,9,18},{5,7,50},{2,9,18},{7,2,72},{3,13,5},{4,10,2},{3,10,5},{7,2,72},{12,0,72},{3,10,5},{0,9,90},{12,0,72},{0,9,90},{3,0,144},{3,0,144},{3,0,144},{3,0,144},{3,10,0},{3,10,0},{3,10,0},{3,8,4},{2,10,8},{2,10,8},{4,14,164},{4,13,94},{4,11,107}, +{4,11,95},{3,16,307},{3,13,137},{3,11,115},{3,10,154},{2,13,253},{3,10,106},{4,14,83},{4,13,13},{4,11,26},{4,11,14},{7,3,243},{3,13,73},{4,11,41},{3,10,90},{11,2,243},{3,10,90},{4,12,91},{4,12,91},{4,12,91},{4,11,94},{3,14,116},{3,12,69},{3,12,69},{3,10,73},{2,12,50},{3,10,25},{4,12,10},{4,12,10},{4,12,10},{4,11,13},{7,1,50}, +{3,12,5},{3,12,5},{3,10,9},{10,2,50},{3,10,9},{5,11,72},{4,13,4},{4,11,17},{4,11,5},{5,11,72},{11,3,72},{4,11,5},{0,10,90},{11,3,72},{0,10,90},{4,0,90},{4,0,90},{4,0,90},{4,0,90},{3,13,65},{3,13,65},{3,13,65},{3,10,64},{2,11,10},{2,11,10},{4,17,194},{4,15,126},{4,12,203},{4,12,123},{4,15,245},{4,13,97},{4,12,3}, +{4,11,107},{2,15,249},{3,11,100},{5,14,99},{5,13,45},{5,12,26},{5,12,50},{5,12,243},{3,15,81},{4,12,2},{3,11,99},{13,1,243},{3,11,99},{4,15,122},{4,15,122},{4,15,122},{4,12,123},{4,13,53},{4,12,3},{4,12,3},{4,11,26},{3,12,62},{3,11,19},{5,12,26},{5,12,26},{5,12,26},{5,11,25},{5,10,50},{4,12,2},{4,12,2},{3,11,18},{12,1,50}, +{3,11,18},{8,2,72},{4,15,4},{5,12,1},{4,12,1},{8,2,72},{13,2,72},{4,12,1},{0,11,90},{13,2,72},{0,11,90},{4,0,122},{4,0,122},{4,0,122},{4,0,122},{4,12,2},{4,12,2},{4,12,2},{4,10,2},{3,11,10},{3,11,10},{5,16,164},{5,15,94},{5,13,106},{5,13,94},{4,18,292},{4,15,125},{4,13,81},{4,12,130},{3,15,253},{4,12,106},{5,16,83}, +{5,15,13},{5,13,25},{5,13,13},{8,3,243},{4,15,76},{4,13,32},{4,12,81},{11,5,243},{4,12,81},{5,14,91},{5,14,91},{5,14,91},{5,13,94},{4,16,99},{4,14,51},{4,14,51},{4,12,66},{3,14,50},{4,12,42},{5,14,10},{5,14,10},{5,14,10},{5,13,13},{8,1,50},{4,14,2},{4,14,2},{4,12,17},{10,5,50},{4,12,17},{3,23,72},{5,15,4},{5,13,16}, +{5,13,4},{3,23,72},{11,6,72},{5,13,4},{0,12,80},{11,6,72},{0,12,80},{5,0,90},{5,0,90},{5,0,90},{5,0,90},{4,14,50},{4,14,50},{4,14,50},{4,12,50},{3,13,9},{3,13,9},{5,19,218},{5,17,149},{5,15,242},{5,14,149},{5,18,248},{5,15,99},{5,14,5},{5,13,99},{3,17,244},{4,13,100},{6,16,99},{6,15,45},{6,14,27},{6,14,51},{8,6,243}, +{4,17,81},{5,14,5},{4,13,99},{15,2,243},{4,13,99},{5,17,145},{5,17,145},{5,17,145},{5,14,148},{5,16,52},{5,14,4},{5,14,4},{5,13,18},{3,16,56},{4,13,19},{6,14,26},{6,14,26},{6,14,26},{6,13,25},{8,4,50},{5,14,4},{5,14,4},{4,13,18},{14,2,50},{4,13,18},{3,26,72},{5,17,5},{6,14,2},{5,14,5},{3,26,72},{15,3,72},{5,14,5}, +{0,13,90},{15,3,72},{0,13,90},{5,0,144},{5,0,144},{5,0,144},{5,0,144},{5,14,0},{5,14,0},{5,14,0},{5,12,4},{4,14,8},{4,14,8},{6,18,164},{6,17,94},{6,15,107},{6,15,95},{5,20,307},{5,17,137},{5,15,115},{5,14,154},{4,17,253},{5,14,106},{6,18,83},{6,17,13},{6,15,26},{6,15,14},{5,20,243},{5,17,73},{6,15,41},{5,14,90},{13,6,243}, +{5,14,90},{6,16,91},{6,16,91},{6,16,91},{6,15,94},{5,18,116},{5,16,69},{5,16,69},{5,14,73},{4,16,50},{5,14,25},{6,16,10},{6,16,10},{6,16,10},{6,15,13},{3,25,50},{5,16,5},{5,16,5},{5,14,9},{12,6,50},{5,14,9},{11,0,72},{6,17,4},{6,15,17},{6,15,5},{11,0,72},{13,7,72},{6,15,5},{0,14,90},{13,7,72},{0,14,90},{6,0,90}, +{6,0,90},{6,0,90},{6,0,90},{5,17,65},{5,17,65},{5,17,65},{5,14,64},{4,15,10},{4,15,10},{6,21,194},{6,19,126},{6,16,203},{6,16,123},{6,19,245},{6,17,97},{6,16,3},{6,15,107},{4,19,249},{5,15,100},{7,18,99},{7,17,45},{7,16,26},{7,16,50},{11,1,243},{5,19,81},{6,16,2},{5,15,99},{15,5,243},{5,15,99},{6,19,122},{6,19,122},{6,19,122}, +{6,16,123},{6,17,53},{6,16,3},{6,16,3},{6,15,26},{5,16,62},{5,15,19},{7,16,26},{7,16,26},{7,16,26},{7,15,25},{9,6,50},{6,16,2},{6,16,2},{5,15,18},{14,5,50},{5,15,18},{10,6,72},{6,19,4},{7,16,1},{6,16,1},{10,6,72},{15,6,72},{6,16,1},{0,15,90},{15,6,72},{0,15,90},{6,0,122},{6,0,122},{6,0,122},{6,0,122},{6,16,2}, +{6,16,2},{6,16,2},{6,14,2},{5,15,10},{5,15,10},{7,20,164},{7,19,94},{7,17,106},{7,17,94},{6,22,292},{6,19,125},{6,17,81},{6,16,130},{5,19,253},{6,16,106},{7,20,83},{7,19,13},{7,17,25},{7,17,13},{10,7,243},{6,19,76},{6,17,32},{6,16,81},{13,9,243},{6,16,81},{7,18,91},{7,18,91},{7,18,91},{7,17,94},{6,20,99},{6,18,51},{6,18,51}, +{6,16,66},{5,18,50},{6,16,42},{7,18,10},{7,18,10},{7,18,10},{7,17,13},{10,5,50},{6,18,2},{6,18,2},{6,16,17},{12,9,50},{6,16,17},{12,2,72},{7,19,4},{7,17,16},{7,17,4},{12,2,72},{13,10,72},{7,17,4},{0,16,80},{13,10,72},{0,16,80},{7,0,90},{7,0,90},{7,0,90},{7,0,90},{6,18,50},{6,18,50},{6,18,50},{6,16,50},{5,17,9}, +{5,17,9},{7,23,218},{7,21,149},{7,19,242},{7,18,149},{7,22,248},{7,19,99},{7,18,5},{7,17,99},{5,21,244},{6,17,100},{7,23,218},{7,21,149},{8,18,206},{7,18,149},{13,0,243},{6,21,81},{7,18,5},{6,17,99},{5,21,243},{6,17,99},{7,21,145},{7,21,145},{7,21,145},{7,18,148},{7,20,52},{7,18,4},{7,18,4},{7,17,18},{5,20,56},{6,17,19},{7,21,145}, +{7,21,145},{7,21,145},{7,18,148},{10,8,50},{7,18,4},{7,18,4},{6,17,18},{11,12,50},{6,17,18},{9,15,72},{7,21,5},{8,18,37},{7,18,5},{9,15,72},{5,22,72},{7,18,5},{0,17,90},{5,22,72},{0,17,90},{7,0,144},{7,0,144},{7,0,144},{7,0,144},{7,18,0},{7,18,0},{7,18,0},{7,16,4},{6,18,8},{6,18,8},{8,21,388},{8,20,334},{8,19,316}, +{8,19,340},{7,24,307},{7,21,137},{7,19,115},{7,18,154},{6,21,253},{7,18,106},{8,21,99},{8,20,45},{8,19,27},{8,19,51},{8,19,243},{7,21,73},{7,19,51},{7,18,90},{15,10,243},{7,18,90},{8,19,315},{8,19,315},{8,19,315},{8,18,314},{7,22,116},{7,20,69},{7,20,69},{7,18,73},{6,20,50},{7,18,25},{8,19,26},{8,19,26},{8,19,26},{8,18,25},{9,14,50}, +{7,20,5},{7,20,5},{7,18,9},{14,10,50},{7,18,9},{13,4,72},{8,20,20},{8,19,2},{7,19,26},{13,4,72},{15,11,72},{7,19,26},{0,18,90},{15,11,72},{0,18,90},{8,0,314},{8,0,314},{8,0,314},{8,0,314},{7,21,65},{7,21,65},{7,21,65},{7,18,64},{6,19,10},{6,19,10},{8,23,164},{8,22,94},{8,20,106},{8,20,94},{8,22,329},{8,20,221},{8,20,121}, +{8,19,220},{6,23,249},{7,19,100},{8,23,83},{8,22,13},{8,20,25},{8,20,13},{13,5,243},{7,23,81},{8,20,40},{7,19,99},{12,15,243},{7,19,99},{8,21,91},{8,21,91},{8,21,91},{8,20,94},{8,20,133},{8,19,99},{8,19,99},{8,18,110},{7,20,62},{7,19,19},{8,21,10},{8,21,10},{8,21,10},{8,20,13},{11,10,50},{8,19,18},{8,19,18},{7,19,18},{5,23,50}, +{7,19,18},{15,0,72},{8,22,4},{8,20,16},{8,20,4},{15,0,72},{12,16,72},{8,20,4},{0,19,90},{12,16,72},{0,19,90},{8,0,90},{8,0,90},{8,0,90},{8,0,90},{8,18,81},{8,18,81},{8,18,81},{8,18,85},{7,19,10},{7,19,10},{8,26,194},{8,24,131},{8,21,203},{8,21,123},{8,24,245},{8,22,97},{8,21,3},{8,20,97},{7,23,253},{7,20,141},{9,23,99}, +{9,22,45},{9,21,26},{9,21,50},{15,1,243},{8,22,96},{8,21,2},{8,20,96},{15,13,243},{8,20,96},{8,24,122},{8,24,122},{8,24,122},{8,21,123},{8,22,53},{8,21,3},{8,21,3},{8,19,27},{7,22,50},{8,19,75},{9,21,26},{9,21,26},{9,21,26},{9,20,25},{12,9,50},{8,21,2},{8,21,2},{8,19,26},{14,13,50},{8,19,26},{14,6,72},{8,24,9},{9,21,1}, +{8,21,1},{14,6,72},{15,14,72},{8,21,1},{0,20,80},{15,14,72},{0,20,80},{8,0,122},{8,0,122},{8,0,122},{8,0,122},{8,21,2},{8,21,2},{8,21,2},{8,19,2},{7,21,9},{7,21,9},{9,26,154},{9,24,81},{9,22,106},{9,22,82},{9,24,307},{8,24,137},{9,22,91},{8,21,154},{7,25,244},{8,21,106},{9,26,90},{9,24,17},{9,22,42},{9,22,18},{15,4,243}, +{8,24,73},{9,22,27},{8,21,90},{9,22,243},{8,21,90},{9,24,81},{9,24,81},{9,24,81},{9,22,81},{9,22,114},{8,23,68},{8,23,68},{8,21,73},{7,24,56},{8,21,25},{9,24,17},{9,24,17},{9,24,17},{9,22,17},{15,2,50},{8,23,4},{8,23,4},{8,21,9},{13,16,50},{8,21,9},{11,19,72},{9,24,1},{9,22,26},{9,22,2},{11,19,72},{9,23,72},{9,22,2}, +{0,21,90},{9,23,72},{0,21,90},{9,0,80},{9,0,80},{9,0,80},{9,0,80},{9,20,65},{9,20,65},{9,20,65},{8,21,64},{8,21,16},{8,21,16},{9,28,216},{9,26,149},{9,23,245},{9,23,149},{9,27,248},{9,24,89},{9,23,5},{9,22,99},{7,27,260},{8,22,100},{10,25,99},{10,24,45},{10,23,27},{10,23,51},{10,23,243},{8,26,81},{9,23,5},{8,22,99},{11,21,243}, +{8,22,99},{9,26,145},{9,26,145},{9,26,145},{9,23,148},{9,25,52},{9,23,4},{9,23,4},{9,22,18},{8,23,72},{8,22,19},{10,23,26},{10,23,26},{10,23,26},{10,22,25},{11,18,50},{9,23,4},{9,23,4},{8,22,18},{10,21,50},{8,22,18},{15,8,72},{9,26,5},{10,23,2},{9,23,5},{15,8,72},{11,22,72},{9,23,5},{0,22,90},{11,22,72},{0,22,90},{9,0,144}, +{9,0,144},{9,0,144},{9,0,144},{9,23,0},{9,23,0},{9,23,0},{9,21,4},{8,23,8},{8,23,8},{10,27,164},{10,26,94},{10,24,106},{10,24,94},{9,29,307},{9,26,137},{9,24,105},{9,23,154},{8,26,253},{9,23,106},{10,27,83},{10,26,13},{10,24,25},{10,24,13},{15,9,243},{9,26,73},{10,24,40},{9,23,90},{14,19,243},{9,23,90},{10,25,91},{10,25,91},{10,25,91}, +{10,24,94},{9,27,116},{9,25,69},{9,25,69},{9,23,73},{8,25,50},{9,23,25},{10,25,10},{10,25,10},{10,25,10},{10,24,13},{13,14,50},{9,25,5},{9,25,5},{9,23,9},{8,25,50},{9,23,9},{14,14,72},{10,26,4},{10,24,16},{10,24,4},{14,14,72},{14,20,72},{10,24,4},{0,23,90},{14,20,72},{0,23,90},{10,0,90},{10,0,90},{10,0,90},{10,0,90},{9,26,65}, +{9,26,65},{9,26,65},{9,23,64},{8,24,9},{8,24,9},{10,30,194},{10,28,131},{10,25,203},{10,25,123},{10,28,245},{10,26,97},{10,25,3},{10,24,97},{8,28,252},{9,24,85},{11,27,99},{11,26,45},{11,25,26},{11,25,50},{14,15,243},{9,28,80},{10,25,2},{9,24,84},{12,23,243},{9,24,84},{10,28,122},{10,28,122},{10,28,122},{10,25,123},{10,26,53},{10,25,3},{10,25,3}, +{10,23,27},{9,25,62},{9,24,21},{11,25,26},{11,25,26},{11,25,26},{11,24,25},{14,13,50},{10,25,2},{10,25,2},{9,24,20},{11,23,50},{9,24,20},{13,20,72},{10,28,9},{11,25,1},{10,25,1},{13,20,72},{13,23,74},{10,25,1},{0,24,80},{13,23,74},{0,24,80},{10,0,122},{10,0,122},{10,0,122},{10,0,122},{10,25,2},{10,25,2},{10,25,2},{10,23,2},{9,24,5}, +{9,24,5},{11,30,154},{11,28,81},{11,26,106},{11,26,82},{11,28,307},{10,28,137},{11,26,91},{10,25,154},{9,28,260},{10,25,106},{11,30,90},{11,28,17},{11,26,42},{11,26,18},{14,18,243},{10,28,73},{11,26,27},{10,25,90},{11,26,243},{10,25,90},{11,28,81},{11,28,81},{11,28,81},{11,26,81},{11,26,114},{10,27,68},{10,27,68},{10,25,73},{9,27,53},{10,25,25},{11,28,17}, +{11,28,17},{11,28,17},{11,26,17},{14,16,50},{10,27,4},{10,27,4},{10,25,9},{15,20,50},{10,25,9},{13,23,72},{11,28,1},{11,26,26},{11,26,2},{13,23,72},{11,27,72},{11,26,2},{0,25,90},{11,27,72},{0,25,90},{11,0,80},{11,0,80},{11,0,80},{11,0,80},{11,24,65},{11,24,65},{11,24,65},{10,25,64},{10,25,16},{10,25,16},{11,31,248},{11,30,149},{11,27,245}, +{11,27,149},{11,31,248},{11,28,89},{11,27,5},{11,26,99},{9,30,244},{10,26,100},{12,29,99},{12,28,45},{12,27,27},{12,27,51},{12,27,243},{10,30,81},{11,27,5},{10,26,99},{13,25,243},{10,26,99},{11,30,145},{11,30,145},{11,30,145},{11,27,148},{11,29,52},{11,27,4},{11,27,4},{11,26,18},{9,29,56},{10,26,19},{12,27,26},{12,27,26},{12,27,26},{12,26,25},{13,22,50}, +{11,27,4},{11,27,4},{10,26,18},{12,25,50},{10,26,18},{15,19,72},{11,30,5},{12,27,2},{11,27,5},{15,19,72},{13,26,72},{11,27,5},{0,26,90},{13,26,72},{0,26,90},{11,0,144},{11,0,144},{11,0,144},{11,0,144},{11,27,0},{11,27,0},{11,27,0},{11,25,4},{10,27,8},{10,27,8},{12,31,164},{12,30,94},{12,28,106},{12,28,94},{12,30,329},{11,30,137},{11,28,105}, +{11,27,154},{10,30,253},{11,27,106},{12,31,83},{12,30,13},{12,28,25},{12,28,13},{14,23,243},{11,30,73},{12,28,40},{11,27,90},{11,29,243},{11,27,90},{12,29,91},{12,29,91},{12,29,91},{12,28,94},{11,31,116},{11,29,69},{11,29,69},{11,27,73},{10,29,50},{11,27,25},{12,29,10},{12,29,10},{12,29,10},{12,28,13},{15,18,50},{11,29,5},{11,29,5},{11,27,9},{10,29,50}, +{11,27,9},{13,28,72},{12,30,4},{12,28,16},{12,28,4},{13,28,72},{11,30,72},{12,28,4},{0,27,90},{11,30,72},{0,27,90},{12,0,90},{12,0,90},{12,0,90},{12,0,90},{11,30,65},{11,30,65},{11,30,65},{11,27,64},{10,28,9},{10,28,9},{12,31,356},{12,31,140},{12,29,203},{12,29,123},{12,31,284},{12,30,97},{12,29,3},{12,28,97},{10,31,287},{11,28,85},{13,31,99}, +{13,30,45},{13,29,26},{13,29,50},{13,29,243},{12,30,96},{12,29,2},{11,28,84},{14,27,243},{11,28,84},{12,31,131},{12,31,131},{12,31,131},{12,29,123},{12,30,53},{12,29,3},{12,29,3},{12,27,27},{11,29,62},{11,28,21},{13,29,26},{13,29,26},{13,29,26},{13,28,25},{13,27,50},{12,29,2},{12,29,2},{11,28,20},{13,27,50},{11,28,20},{15,24,72},{12,31,18},{13,29,1}, +{12,29,1},{15,24,72},{15,27,74},{12,29,1},{0,28,80},{15,27,74},{0,28,80},{12,0,122},{12,0,122},{12,0,122},{12,0,122},{12,29,2},{12,29,2},{12,29,2},{12,27,2},{11,28,5},{11,28,5},{13,31,280},{13,31,120},{13,30,106},{13,30,82},{13,31,328},{13,31,200},{13,30,91},{12,29,154},{12,31,344},{12,29,106},{13,31,216},{13,31,56},{13,30,42},{13,30,18},{15,25,244}, +{13,31,136},{13,30,27},{12,29,90},{13,30,243},{12,29,90},{13,31,84},{13,31,84},{13,31,84},{13,30,81},{13,30,114},{12,31,68},{12,31,68},{12,29,73},{11,31,53},{12,29,25},{13,31,20},{13,31,20},{13,31,20},{13,30,17},{13,30,50},{12,31,4},{12,31,4},{12,29,9},{12,30,50},{12,29,9},{15,27,72},{13,31,40},{13,30,26},{13,30,2},{15,27,72},{13,31,72},{13,30,2}, +{0,29,90},{13,31,72},{0,29,90},{13,0,80},{13,0,80},{13,0,80},{13,0,80},{13,28,65},{13,28,65},{13,28,65},{12,29,64},{12,29,16},{12,29,16},{14,31,415},{14,31,351},{13,31,244},{13,31,148},{14,31,511},{13,31,173},{13,31,4},{13,30,82},{13,31,381},{12,30,83},{14,31,126},{14,31,62},{14,31,26},{14,31,50},{14,31,222},{13,31,173},{13,31,4},{12,30,82},{14,30,221}, +{12,30,82},{13,31,244},{13,31,244},{13,31,244},{13,31,148},{13,31,100},{13,31,4},{13,31,4},{13,30,18},{12,31,72},{12,30,19},{14,31,26},{14,31,26},{14,31,26},{14,30,25},{15,26,50},{13,31,4},{13,31,4},{12,30,18},{14,29,50},{12,30,18},{15,29,61},{14,31,37},{14,31,1},{13,31,4},{15,29,61},{15,30,61},{13,31,4},{0,30,73},{15,30,61},{0,30,73},{13,0,144}, +{13,0,144},{13,0,144},{13,0,144},{13,31,0},{13,31,0},{13,31,0},{13,29,4},{12,31,8},{12,31,8},{14,31,239},{14,31,175},{14,31,139},{14,31,99},{14,31,239},{14,31,135},{14,31,99},{13,31,73},{13,31,285},{13,31,25},{14,31,158},{14,31,94},{14,31,58},{14,31,18},{15,29,94},{14,31,54},{14,31,18},{13,31,9},{15,30,93},{13,31,9},{14,31,139},{14,31,139},{14,31,139}, +{14,31,99},{14,31,139},{14,31,99},{14,31,99},{13,31,73},{13,31,116},{13,31,25},{14,31,58},{14,31,58},{14,31,58},{14,31,18},{15,28,52},{14,31,18},{14,31,18},{13,31,9},{15,29,58},{13,31,9},{15,30,9},{15,31,9},{15,31,9},{14,31,9},{15,30,9},{15,31,9},{14,31,9},{0,31,9},{15,31,9},{0,31,9},{14,0,90},{14,0,90},{14,0,90},{14,0,90},{14,30,81}, +{14,30,81},{14,30,81},{13,31,64},{13,31,16},{13,31,16},{15,31,314},{14,31,258},{14,31,222},{14,31,158},{14,31,226},{14,31,98},{14,31,62},{14,31,2},{14,31,122},{14,31,50},{15,31,25},{15,31,25},{15,31,25},{15,31,25},{15,30,22},{15,31,25},{15,31,25},{14,31,1},{15,31,25},{14,31,1},{14,31,222},{14,31,222},{14,31,222},{14,31,158},{14,31,126},{14,31,62},{14,31,62}, +{14,31,2},{14,31,86},{14,31,50},{15,31,25},{15,31,25},{15,31,25},{15,31,25},{15,30,13},{15,31,25},{15,31,25},{14,31,1},{15,30,25},{14,31,1},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{14,0,122},{14,0,122},{14,0,122},{14,0,122},{14,31,26},{14,31,26},{14,31,26},{14,31,2},{14,31,50}, +{14,31,50},{0,6,202},{0,5,52},{0,3,25},{0,3,61},{0,4,442},{0,3,313},{0,3,142},{0,2,318},{0,2,498},{0,2,354},{0,6,202},{0,5,52},{0,3,25},{0,3,61},{1,1,441},{0,3,313},{0,3,142},{0,2,318},{2,0,442},{0,2,318},{0,3,0},{0,3,0},{0,3,0},{0,2,1},{0,1,45},{0,1,25},{0,1,25},{0,1,26},{0,1,50},{0,1,35},{0,3,0}, +{0,3,0},{0,3,0},{0,2,1},{0,1,45},{0,1,25},{0,1,25},{0,1,26},{0,1,41},{0,1,26},{1,3,200},{0,5,52},{0,3,25},{0,3,61},{1,3,200},{3,0,202},{0,3,61},{0,2,218},{3,0,202},{0,2,218},{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,9,200},{0,7,20},{0,5,20}, +{0,4,25},{0,6,686},{0,5,433},{0,4,169},{0,3,443},{0,3,794},{0,3,524},{0,9,200},{0,7,20},{0,5,20},{0,4,25},{0,6,686},{0,5,433},{0,4,169},{0,3,443},{3,0,686},{0,3,443},{0,6,1},{0,6,1},{0,6,1},{0,3,4},{0,3,145},{0,2,85},{0,2,85},{0,2,101},{0,1,178},{0,1,115},{0,6,1},{0,6,1},{0,6,1},{0,3,4},{0,3,145}, +{0,2,85},{0,2,85},{0,2,101},{0,2,149},{0,2,101},{0,9,200},{0,7,20},{0,5,20},{0,4,25},{0,9,200},{2,3,200},{0,4,25},{0,3,218},{2,3,200},{0,3,218},{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,11,257},{0,9,54},{0,6,114},{0,5,65},{0,9,728},{0,6,371},{0,5,80}, +{0,4,377},{0,5,949},{0,4,521},{0,11,257},{0,9,54},{1,5,97},{0,5,65},{2,2,723},{0,6,371},{0,5,80},{0,4,377},{1,4,723},{0,4,377},{0,8,50},{0,8,50},{0,8,50},{0,5,49},{0,5,164},{0,4,50},{0,4,50},{0,3,65},{0,3,245},{0,2,126},{0,8,50},{0,8,50},{0,8,50},{0,5,49},{1,2,162},{0,4,50},{0,4,50},{0,3,65},{1,2,162}, +{0,3,65},{3,2,202},{0,9,5},{1,5,16},{0,5,16},{3,2,202},{5,1,200},{0,5,16},{0,4,208},{5,1,200},{0,4,208},{0,0,49},{0,0,49},{0,0,49},{0,0,49},{0,2,1},{0,2,1},{0,2,1},{0,1,4},{0,1,13},{0,1,13},{0,14,425},{0,11,234},{1,7,277},{0,7,245},{0,11,724},{0,8,289},{0,6,34},{0,5,308},{0,6,1087},{0,5,533},{1,11,201}, +{1,9,18},{1,7,21},{1,6,26},{1,8,723},{0,8,289},{0,6,34},{0,5,308},{4,2,723},{0,5,308},{0,11,225},{0,11,225},{0,11,225},{0,7,229},{0,8,162},{0,6,18},{0,6,18},{0,4,25},{0,4,338},{0,3,162},{1,8,2},{1,8,2},{1,8,2},{1,5,5},{0,8,162},{0,6,18},{0,6,18},{0,4,25},{4,0,162},{0,4,25},{3,4,200},{0,11,9},{1,7,20}, +{0,7,20},{3,4,200},{7,0,200},{0,7,20},{0,5,208},{7,0,200},{0,5,208},{0,0,225},{0,0,225},{0,0,225},{0,0,225},{0,5,0},{0,5,0},{0,5,0},{0,3,0},{0,2,61},{0,2,61},{1,14,410},{1,11,209},{1,8,288},{1,7,234},{0,14,739},{0,10,254},{0,8,33},{0,6,270},{0,8,1131},{0,6,450},{1,14,266},{1,11,65},{2,7,106},{1,7,90},{3,4,723}, +{0,10,238},{0,8,17},{0,6,254},{7,0,723},{0,6,254},{1,11,209},{1,11,209},{1,11,209},{1,7,209},{0,11,178},{0,8,17},{0,8,17},{0,5,18},{0,6,376},{0,5,123},{1,11,65},{1,11,65},{1,11,65},{1,7,65},{3,1,162},{0,8,1},{0,8,1},{0,5,2},{3,3,162},{0,5,2},{3,7,200},{1,11,1},{2,7,25},{0,8,17},{3,7,200},{8,0,200},{0,8,17}, +{0,6,218},{8,0,200},{0,6,218},{1,0,208},{1,0,208},{1,0,208},{1,0,208},{0,8,16},{0,8,16},{0,8,16},{0,5,17},{0,4,80},{0,4,80},{1,16,474},{1,13,276},{1,9,457},{1,9,292},{1,13,740},{1,10,298},{1,8,45},{1,7,315},{0,9,1013},{0,7,308},{2,13,201},{2,11,21},{2,9,21},{2,8,26},{5,0,723},{0,12,227},{1,8,29},{0,7,227},{5,4,723}, +{0,7,227},{1,13,272},{1,13,272},{1,13,272},{1,9,276},{1,10,180},{1,8,29},{1,8,29},{1,6,33},{0,8,306},{0,6,41},{2,10,2},{2,10,2},{2,10,2},{2,7,5},{4,0,162},{0,10,5},{0,10,5},{0,6,5},{1,7,162},{0,6,5},{5,3,200},{1,13,4},{2,9,20},{1,9,20},{5,3,200},{4,7,200},{1,9,20},{0,7,218},{4,7,200},{0,7,218},{1,0,272}, +{1,0,272},{1,0,272},{1,0,272},{1,7,17},{1,7,17},{1,7,17},{1,5,17},{0,6,40},{0,6,40},{2,15,426},{2,13,223},{2,10,283},{2,9,234},{1,16,739},{1,12,267},{1,10,33},{1,8,273},{0,11,913},{0,8,225},{2,15,257},{2,13,54},{3,9,97},{2,9,65},{4,6,723},{0,13,208},{1,10,17},{0,8,209},{3,8,723},{0,8,209},{2,12,219},{2,12,219},{2,12,219}, +{2,9,218},{1,13,180},{1,10,17},{1,10,17},{1,7,18},{0,9,229},{0,7,27},{2,12,50},{2,12,50},{2,12,50},{2,9,49},{3,6,162},{1,10,1},{1,10,1},{1,7,2},{3,6,162},{1,7,2},{1,19,200},{2,13,5},{3,9,16},{2,9,16},{1,19,200},{9,2,200},{2,9,16},{0,8,208},{9,2,200},{0,8,208},{2,0,218},{2,0,218},{2,0,218},{2,0,218},{1,10,16}, +{1,10,16},{1,10,16},{1,7,17},{0,8,17},{0,8,17},{2,18,450},{2,15,259},{2,11,410},{2,11,270},{2,15,749},{2,12,314},{2,10,59},{2,9,333},{0,13,868},{0,9,213},{3,15,201},{3,13,18},{3,11,21},{3,10,26},{6,2,723},{0,15,204},{2,10,34},{0,9,212},{8,3,723},{0,9,212},{2,15,250},{2,15,250},{2,15,250},{2,11,254},{2,12,187},{2,10,43},{2,10,43}, +{2,8,50},{0,11,189},{1,8,37},{3,12,2},{3,12,2},{3,12,2},{3,9,5},{5,2,162},{1,12,2},{1,12,2},{1,8,1},{8,1,162},{1,8,1},{5,8,200},{2,15,9},{3,11,20},{2,11,20},{5,8,200},{4,10,200},{2,11,20},{0,9,208},{4,10,200},{0,9,208},{2,0,250},{2,0,250},{2,0,250},{2,0,250},{2,9,25},{2,9,25},{2,9,25},{2,7,25},{0,9,5}, +{0,9,5},{3,18,410},{3,15,209},{3,12,288},{3,11,234},{2,18,739},{2,14,254},{2,12,33},{2,10,270},{0,15,804},{1,10,227},{3,18,266},{3,15,65},{4,11,106},{3,11,90},{5,8,723},{1,15,219},{2,12,17},{1,10,218},{4,10,723},{1,10,218},{3,15,209},{3,15,209},{3,15,209},{3,11,209},{2,15,178},{2,12,17},{2,12,17},{2,9,18},{0,13,171},{1,9,26},{3,15,65}, +{3,15,65},{3,15,65},{3,11,65},{5,5,162},{2,12,1},{2,12,1},{2,9,2},{5,7,162},{2,9,2},{5,11,200},{3,15,1},{4,11,25},{2,12,17},{5,11,200},{11,3,200},{2,12,17},{0,10,218},{11,3,200},{0,10,218},{3,0,208},{3,0,208},{3,0,208},{3,0,208},{2,12,16},{2,12,16},{2,12,16},{2,9,17},{1,10,9},{1,10,9},{3,20,474},{3,17,276},{3,13,457}, +{3,13,292},{3,17,740},{3,14,298},{3,12,45},{3,11,315},{0,16,747},{1,11,231},{4,17,201},{4,15,21},{4,13,21},{4,12,26},{7,4,723},{1,17,209},{3,12,29},{1,11,227},{9,5,723},{1,11,227},{3,17,272},{3,17,272},{3,17,272},{3,13,276},{3,14,180},{3,12,29},{3,12,29},{3,10,33},{0,15,171},{2,10,41},{4,14,2},{4,14,2},{4,14,2},{4,11,5},{7,1,162}, +{2,14,5},{2,14,5},{2,10,5},{10,2,162},{2,10,5},{8,2,200},{3,17,4},{4,13,20},{3,13,20},{8,2,200},{13,2,200},{3,13,20},{0,11,218},{13,2,200},{0,11,218},{3,0,272},{3,0,272},{3,0,272},{3,0,272},{3,11,17},{3,11,17},{3,11,17},{3,9,17},{1,12,8},{1,12,8},{4,19,426},{4,17,223},{4,14,283},{4,13,234},{3,20,739},{3,16,267},{3,14,33}, +{3,12,273},{0,18,727},{2,12,225},{4,19,257},{4,17,54},{5,13,97},{4,13,65},{6,10,723},{2,17,208},{3,14,17},{2,12,209},{12,3,723},{2,12,209},{4,16,219},{4,16,219},{4,16,219},{4,13,218},{3,17,180},{3,14,17},{3,14,17},{3,11,18},{1,15,171},{2,11,27},{4,16,50},{4,16,50},{4,16,50},{4,13,49},{5,10,162},{3,14,1},{3,14,1},{3,11,2},{12,1,162}, +{3,11,2},{3,23,200},{4,17,5},{5,13,16},{4,13,16},{3,23,200},{11,6,200},{4,13,16},{0,12,208},{11,6,200},{0,12,208},{4,0,218},{4,0,218},{4,0,218},{4,0,218},{3,14,16},{3,14,16},{3,14,16},{3,11,17},{1,13,10},{1,13,10},{4,22,450},{4,19,259},{4,15,410},{4,15,270},{4,19,749},{4,16,314},{4,14,59},{4,13,333},{1,18,747},{2,13,213},{5,19,201}, +{5,17,18},{5,15,21},{5,14,26},{9,1,723},{2,19,204},{4,14,34},{2,13,212},{15,1,723},{2,13,212},{4,19,250},{4,19,250},{4,19,250},{4,15,254},{4,16,187},{4,14,43},{4,14,43},{4,12,50},{1,16,174},{3,12,37},{5,16,2},{5,16,2},{5,16,2},{5,13,5},{8,1,162},{3,16,2},{3,16,2},{3,12,1},{10,5,162},{3,12,1},{9,4,200},{4,19,9},{5,15,20}, +{4,15,20},{9,4,200},{9,10,200},{4,15,20},{0,13,208},{9,10,200},{0,13,208},{4,0,250},{4,0,250},{4,0,250},{4,0,250},{4,13,25},{4,13,25},{4,13,25},{4,11,25},{2,13,5},{2,13,5},{5,22,410},{5,19,209},{5,16,288},{5,15,234},{4,22,739},{4,18,254},{4,16,33},{4,14,270},{1,20,724},{3,14,227},{5,22,266},{5,19,65},{6,15,106},{5,15,90},{9,4,723}, +{3,19,219},{4,16,17},{3,14,218},{9,10,723},{3,14,218},{5,19,209},{5,19,209},{5,19,209},{5,15,209},{4,19,178},{4,16,17},{4,16,17},{4,13,18},{2,17,171},{3,13,26},{5,19,65},{5,19,65},{5,19,65},{5,15,65},{8,4,162},{4,16,1},{4,16,1},{4,13,2},{14,2,162},{4,13,2},{11,0,200},{5,19,1},{6,15,25},{4,16,17},{11,0,200},{13,7,200},{4,16,17}, +{0,14,218},{13,7,200},{0,14,218},{5,0,208},{5,0,208},{5,0,208},{5,0,208},{4,16,16},{4,16,16},{4,16,16},{4,13,17},{3,14,9},{3,14,9},{5,24,474},{5,21,276},{5,17,457},{5,17,292},{5,21,740},{5,18,298},{5,16,45},{5,15,315},{1,22,740},{3,15,231},{6,21,201},{6,19,21},{6,17,21},{6,16,26},{10,3,723},{3,21,209},{5,16,29},{3,15,227},{11,9,723}, +{3,15,227},{5,21,272},{5,21,272},{5,21,272},{5,17,276},{5,18,180},{5,16,29},{5,16,29},{5,14,33},{2,19,171},{4,14,41},{6,18,2},{6,18,2},{6,18,2},{6,15,5},{3,25,162},{4,18,5},{4,18,5},{4,14,5},{12,6,162},{4,14,5},{10,6,200},{5,21,4},{6,17,20},{5,17,20},{10,6,200},{15,6,200},{5,17,20},{0,15,218},{15,6,200},{0,15,218},{5,0,272}, +{5,0,272},{5,0,272},{5,0,272},{5,15,17},{5,15,17},{5,15,17},{5,13,17},{3,16,8},{3,16,8},{6,23,426},{6,21,223},{6,18,283},{6,17,234},{5,24,739},{5,20,267},{5,18,33},{5,16,273},{2,22,727},{4,16,225},{6,23,257},{6,21,54},{7,17,97},{6,17,65},{9,9,723},{4,21,208},{5,18,17},{4,16,209},{14,7,723},{4,16,209},{6,20,219},{6,20,219},{6,20,219}, +{6,17,218},{5,21,180},{5,18,17},{5,18,17},{5,15,18},{3,19,171},{4,15,27},{6,20,50},{6,20,50},{6,20,50},{6,17,49},{9,6,162},{5,18,1},{5,18,1},{5,15,2},{14,5,162},{5,15,2},{12,2,200},{6,21,5},{7,17,16},{6,17,16},{12,2,200},{13,10,200},{6,17,16},{0,16,208},{13,10,200},{0,16,208},{6,0,218},{6,0,218},{6,0,218},{6,0,218},{5,18,16}, +{5,18,16},{5,18,16},{5,15,17},{3,17,10},{3,17,10},{6,26,450},{6,23,259},{6,19,410},{6,19,270},{6,23,749},{6,20,314},{6,18,59},{6,17,333},{3,22,747},{4,17,213},{7,23,201},{7,21,18},{7,19,21},{7,18,26},{11,5,723},{4,23,204},{6,18,34},{4,17,212},{12,11,723},{4,17,212},{6,23,250},{6,23,250},{6,23,250},{6,19,254},{6,20,187},{6,18,43},{6,18,43}, +{6,16,50},{3,20,174},{5,16,37},{7,20,2},{7,20,2},{7,20,2},{7,17,5},{10,5,162},{5,20,2},{5,20,2},{5,16,1},{12,9,162},{5,16,1},{11,8,200},{6,23,9},{7,19,20},{6,19,20},{11,8,200},{11,14,200},{6,19,20},{0,17,208},{11,14,200},{0,17,208},{6,0,250},{6,0,250},{6,0,250},{6,0,250},{6,17,25},{6,17,25},{6,17,25},{6,15,25},{4,17,5}, +{4,17,5},{7,26,410},{7,23,209},{7,20,288},{7,19,234},{6,26,739},{6,22,254},{6,20,33},{6,18,270},{3,24,724},{5,18,227},{7,26,266},{7,23,65},{7,20,144},{7,19,90},{11,8,723},{5,23,219},{6,20,17},{5,18,218},{11,14,723},{5,18,218},{7,23,209},{7,23,209},{7,23,209},{7,19,209},{6,23,178},{6,20,17},{6,20,17},{6,17,18},{4,21,171},{5,17,26},{7,23,65}, +{7,23,65},{7,23,65},{7,19,65},{10,8,162},{6,20,1},{6,20,1},{6,17,2},{11,12,162},{6,17,2},{13,4,200},{7,23,1},{8,19,50},{6,20,17},{13,4,200},{15,11,200},{6,20,17},{0,18,218},{15,11,200},{0,18,218},{7,0,208},{7,0,208},{7,0,208},{7,0,208},{6,20,16},{6,20,16},{6,20,16},{6,17,17},{5,18,9},{5,18,9},{7,28,474},{7,25,276},{7,21,457}, +{7,21,292},{7,25,740},{7,22,298},{7,20,45},{7,19,315},{3,26,740},{5,19,231},{8,23,283},{8,22,133},{8,20,97},{8,20,133},{12,7,723},{5,25,209},{7,20,29},{5,19,227},{13,13,723},{5,19,227},{7,25,272},{7,25,272},{7,25,272},{7,21,276},{7,22,180},{7,20,29},{7,20,29},{7,18,33},{4,23,171},{6,18,41},{8,20,81},{8,20,81},{8,20,81},{8,19,82},{9,14,162}, +{6,22,5},{6,22,5},{6,18,5},{14,10,162},{6,18,5},{15,0,200},{7,25,4},{8,20,16},{7,21,20},{15,0,200},{12,16,200},{7,21,20},{0,19,218},{12,16,200},{0,19,218},{7,0,272},{7,0,272},{7,0,272},{7,0,272},{7,19,17},{7,19,17},{7,19,17},{7,17,17},{5,20,8},{5,20,8},{8,26,642},{8,24,459},{8,22,462},{8,21,467},{7,28,739},{7,24,267},{7,22,33}, +{7,20,273},{4,26,727},{6,20,225},{8,26,201},{8,24,18},{8,22,21},{8,21,26},{14,3,723},{6,25,208},{7,22,17},{6,20,209},{11,17,723},{6,20,209},{8,23,443},{8,23,443},{8,23,443},{8,20,446},{7,25,180},{7,22,17},{7,22,17},{7,19,18},{5,23,171},{6,19,27},{8,23,2},{8,23,2},{8,23,2},{8,20,5},{11,10,162},{7,22,1},{7,22,1},{7,19,2},{5,23,162}, +{7,19,2},{14,6,200},{8,24,17},{8,22,20},{7,22,17},{14,6,200},{15,14,200},{7,22,17},{0,20,208},{15,14,200},{0,20,208},{8,0,442},{8,0,442},{8,0,442},{8,0,442},{7,22,16},{7,22,16},{7,22,16},{7,19,17},{5,21,10},{5,21,10},{8,28,420},{8,26,223},{8,23,283},{8,22,234},{7,31,872},{7,26,371},{7,23,201},{7,21,368},{5,26,747},{6,21,213},{8,28,251}, +{8,26,54},{9,22,97},{8,22,65},{13,9,723},{6,27,204},{7,23,57},{6,21,212},{14,15,723},{6,21,212},{8,25,219},{8,25,219},{8,25,219},{8,22,218},{7,27,308},{7,24,146},{7,24,146},{7,20,145},{5,24,174},{7,20,37},{8,25,50},{8,25,50},{8,25,50},{8,22,49},{12,9,162},{7,24,2},{7,24,2},{7,20,1},{14,13,162},{7,20,1},{13,12,200},{8,26,5},{9,22,16}, +{8,22,16},{13,12,200},{13,18,200},{8,22,16},{0,21,208},{13,18,200},{0,21,208},{8,0,218},{8,0,218},{8,0,218},{8,0,218},{7,24,145},{7,24,145},{7,24,145},{7,20,145},{6,21,5},{6,21,5},{8,31,474},{8,28,276},{9,24,425},{8,24,292},{8,28,740},{8,25,298},{8,23,61},{8,22,315},{5,28,724},{7,22,227},{9,28,200},{9,26,13},{9,24,25},{9,23,29},{13,12,723}, +{7,27,219},{8,23,45},{7,22,218},{13,18,723},{7,22,218},{8,28,272},{8,28,272},{8,28,272},{8,24,276},{8,25,180},{8,23,36},{8,23,36},{8,21,33},{6,25,171},{7,21,26},{9,25,0},{9,25,0},{9,25,0},{9,23,4},{15,2,162},{8,23,20},{8,23,20},{8,21,17},{13,16,162},{8,21,17},{15,8,200},{8,28,4},{9,24,25},{8,24,20},{15,8,200},{11,22,200},{8,24,20}, +{0,22,218},{11,22,200},{0,22,218},{8,0,272},{8,0,272},{8,0,272},{8,0,272},{8,22,17},{8,22,17},{8,22,17},{8,20,17},{7,22,9},{7,22,9},{9,31,410},{9,28,212},{9,25,288},{9,24,224},{8,31,739},{8,27,254},{8,25,33},{8,23,270},{5,30,740},{7,23,231},{9,31,266},{9,28,68},{10,24,97},{9,24,80},{14,11,723},{7,29,209},{8,25,17},{7,23,227},{15,17,723}, +{7,23,227},{9,27,212},{9,27,212},{9,27,212},{9,24,208},{8,28,180},{8,25,17},{8,25,17},{8,22,18},{6,27,171},{7,23,62},{9,27,68},{9,27,68},{9,27,68},{9,24,64},{11,18,162},{8,25,1},{8,25,1},{8,22,2},{10,21,162},{8,22,2},{14,14,200},{9,28,4},{10,24,16},{9,24,16},{14,14,200},{14,20,200},{9,24,16},{0,23,218},{14,20,200},{0,23,218},{9,0,208}, +{9,0,208},{9,0,208},{9,0,208},{8,25,16},{8,25,16},{8,25,16},{8,22,17},{7,24,8},{7,24,8},{9,31,570},{9,30,276},{9,26,457},{9,26,292},{9,30,740},{9,27,298},{9,25,45},{9,24,324},{6,30,727},{7,24,280},{10,30,201},{10,28,18},{10,26,21},{10,25,26},{13,17,723},{8,29,227},{9,25,29},{8,24,224},{13,21,723},{8,24,224},{9,30,272},{9,30,272},{9,30,272}, +{9,26,276},{9,27,180},{9,25,29},{9,25,29},{9,23,33},{7,27,171},{8,23,41},{10,27,2},{10,27,2},{10,27,2},{10,24,5},{13,14,162},{8,27,5},{8,27,5},{8,23,5},{8,25,162},{8,23,5},{13,20,200},{9,30,4},{10,26,20},{9,26,20},{13,20,200},{13,23,202},{9,26,20},{0,24,208},{13,23,202},{0,24,208},{9,0,272},{9,0,272},{9,0,272},{9,0,272},{9,24,17}, +{9,24,17},{9,24,17},{9,22,17},{7,25,10},{7,25,10},{10,31,468},{10,30,223},{10,27,283},{10,26,234},{9,31,835},{9,29,267},{9,27,33},{9,25,273},{7,30,747},{8,25,225},{11,29,283},{10,30,54},{11,26,97},{10,26,65},{15,13,723},{8,30,208},{9,27,17},{8,25,209},{11,25,723},{8,25,209},{10,29,219},{10,29,219},{10,29,219},{10,26,218},{9,30,180},{9,27,17},{9,27,17}, +{9,24,20},{7,28,174},{8,24,17},{10,29,50},{10,29,50},{10,29,50},{10,26,49},{14,13,162},{9,27,1},{9,27,1},{9,24,4},{11,23,162},{9,24,4},{15,16,200},{10,30,5},{11,26,16},{10,26,16},{15,16,200},{15,22,200},{10,26,16},{0,25,208},{15,22,200},{0,25,208},{10,0,218},{10,0,218},{10,0,218},{10,0,218},{9,27,16},{9,27,16},{9,27,16},{9,24,20},{8,24,17}, +{8,24,17},{11,31,632},{10,31,297},{11,28,425},{10,28,292},{10,31,804},{10,29,298},{10,27,61},{10,26,315},{7,31,823},{8,26,231},{11,31,232},{11,30,13},{11,28,25},{11,27,29},{15,16,723},{9,31,216},{10,27,45},{8,26,227},{15,22,723},{8,26,227},{10,31,288},{10,31,288},{10,31,288},{10,28,276},{10,29,180},{10,27,36},{10,27,36},{10,25,33},{7,30,189},{9,25,30},{11,29,0}, +{11,29,0},{11,29,0},{11,27,4},{14,16,162},{9,29,4},{9,29,4},{9,25,5},{15,20,162},{9,25,5},{15,19,200},{11,30,13},{11,28,25},{10,28,20},{15,19,200},{13,26,200},{10,28,20},{0,26,218},{13,26,200},{0,26,218},{10,0,272},{10,0,272},{10,0,272},{10,0,272},{10,26,17},{10,26,17},{10,26,17},{10,24,17},{8,27,5},{8,27,5},{11,31,696},{11,31,237},{11,29,288}, +{11,28,224},{11,31,888},{10,31,254},{10,29,33},{10,27,270},{8,31,824},{9,27,227},{12,31,283},{11,31,93},{12,28,97},{11,28,80},{13,25,723},{10,31,238},{10,29,17},{9,27,218},{12,27,723},{9,27,218},{11,31,212},{11,31,212},{11,31,212},{11,28,208},{10,31,196},{10,29,17},{10,29,17},{10,26,18},{8,30,171},{9,26,26},{11,31,68},{11,31,68},{11,31,68},{11,28,64},{13,22,162}, +{10,29,1},{10,29,1},{10,26,2},{12,25,162},{10,26,2},{13,28,200},{11,31,29},{12,28,16},{11,28,16},{13,28,200},{11,30,200},{11,28,16},{0,27,218},{11,30,200},{0,27,218},{11,0,208},{11,0,208},{11,0,208},{11,0,208},{10,29,16},{10,29,16},{10,29,16},{10,26,17},{9,27,9},{9,27,9},{12,31,804},{12,31,492},{11,30,457},{11,30,292},{11,31,1080},{11,31,298},{11,29,45}, +{11,28,324},{9,31,920},{9,28,218},{12,31,363},{12,31,51},{12,30,21},{12,29,26},{15,21,723},{11,31,282},{11,29,29},{9,28,217},{15,25,723},{9,28,217},{11,31,372},{11,31,372},{11,31,372},{11,30,276},{11,31,180},{11,29,29},{11,29,29},{11,27,33},{8,31,184},{10,27,41},{12,31,2},{12,31,2},{12,31,2},{12,28,5},{15,18,162},{10,31,5},{10,31,5},{10,27,5},{10,29,162}, +{10,27,5},{15,24,200},{12,31,50},{12,30,20},{11,30,20},{15,24,200},{15,27,202},{11,30,20},{0,28,208},{15,27,202},{0,28,208},{11,0,272},{11,0,272},{11,0,272},{11,0,272},{11,28,17},{11,28,17},{11,28,17},{11,26,17},{9,29,8},{9,29,8},{12,31,996},{12,31,492},{12,31,283},{12,30,234},{12,31,1068},{11,31,458},{11,31,33},{11,29,273},{10,31,999},{10,29,225},{13,31,379}, +{13,31,171},{13,30,97},{12,30,65},{14,27,723},{12,31,371},{11,31,17},{10,29,209},{13,29,723},{10,29,209},{12,31,267},{12,31,267},{12,31,267},{12,30,218},{12,30,333},{11,31,17},{11,31,17},{11,28,20},{9,31,212},{10,28,17},{13,30,81},{13,30,81},{13,30,81},{12,30,49},{13,27,162},{11,31,1},{11,31,1},{11,28,4},{13,27,162},{11,28,4},{15,27,202},{13,31,90},{13,30,16}, +{12,30,16},{15,27,202},{15,28,202},{12,30,16},{0,29,208},{15,28,202},{0,29,208},{12,0,218},{12,0,218},{12,0,218},{12,0,218},{11,31,16},{11,31,16},{11,31,16},{11,28,20},{9,30,10},{9,30,10},{13,31,877},{13,31,605},{13,31,436},{12,31,288},{13,31,1021},{12,31,397},{12,31,36},{12,30,210},{11,31,910},{10,30,126},{14,31,414},{13,31,205},{13,31,36},{13,31,4},{15,26,546}, +{13,31,317},{12,31,20},{10,30,122},{14,29,546},{10,30,122},{13,31,436},{13,31,436},{13,31,436},{12,31,288},{12,31,276},{12,31,36},{12,31,36},{12,29,33},{10,31,261},{11,29,30},{13,31,36},{13,31,36},{13,31,36},{13,31,4},{13,30,162},{12,31,20},{12,31,20},{11,29,5},{12,30,162},{11,29,5},{15,28,117},{14,31,61},{14,31,25},{13,31,4},{15,28,117},{14,31,117},{13,31,4}, +{0,30,113},{14,31,117},{0,30,113},{12,0,272},{12,0,272},{12,0,272},{12,0,272},{12,30,17},{12,30,17},{12,30,17},{12,28,17},{10,31,5},{10,31,5},{13,31,845},{13,31,573},{13,31,404},{13,31,244},{13,31,797},{13,31,365},{12,31,196},{12,30,82},{12,31,737},{11,31,58},{14,31,190},{14,31,126},{14,31,90},{14,31,82},{14,31,334},{13,31,221},{13,31,52},{11,31,49},{14,30,333}, +{11,31,49},{13,31,404},{13,31,404},{13,31,404},{13,31,244},{13,31,356},{12,31,196},{12,31,196},{12,30,18},{11,31,333},{11,30,26},{14,31,90},{14,31,90},{14,31,90},{14,31,82},{15,26,162},{13,31,52},{13,31,52},{12,30,2},{14,29,162},{12,30,2},{15,30,25},{15,30,41},{14,31,9},{14,31,1},{15,30,25},{15,30,29},{14,31,1},{0,31,49},{15,30,29},{0,31,49},{13,0,208}, +{13,0,208},{13,0,208},{13,0,208},{12,31,52},{12,31,52},{12,31,52},{12,30,17},{11,31,9},{11,31,9},{14,31,642},{14,31,578},{14,31,542},{13,31,441},{14,31,690},{13,31,370},{13,31,201},{13,31,32},{13,31,610},{12,31,40},{14,31,201},{14,31,137},{14,31,101},{14,31,37},{15,29,193},{14,31,121},{14,31,85},{12,31,4},{14,31,193},{12,31,4},{14,31,542},{14,31,542},{14,31,542}, +{13,31,441},{13,31,473},{13,31,201},{13,31,201},{13,31,32},{12,31,401},{12,31,40},{14,31,101},{14,31,101},{14,31,101},{14,31,37},{15,28,145},{14,31,85},{14,31,85},{12,31,4},{15,29,149},{12,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{13,0,272},{13,0,272},{13,0,272},{13,0,272},{13,31,32}, +{13,31,32},{13,31,32},{13,30,17},{12,31,40},{12,31,40},{14,31,418},{14,31,354},{14,31,318},{14,31,254},{14,31,370},{14,31,242},{14,31,206},{13,31,32},{13,31,418},{13,31,80},{15,31,81},{15,31,81},{15,31,81},{15,31,81},{15,30,54},{14,31,73},{14,31,37},{14,31,9},{15,30,66},{14,31,9},{14,31,318},{14,31,318},{14,31,318},{14,31,254},{14,31,270},{14,31,206},{14,31,206}, +{13,31,32},{13,31,249},{13,31,80},{15,31,81},{15,31,81},{15,31,81},{15,31,81},{15,29,45},{14,31,37},{14,31,37},{14,31,9},{15,30,41},{14,31,9},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{14,0,218},{14,0,218},{14,0,218},{14,0,218},{13,31,160},{13,31,160},{13,31,160},{13,31,32},{13,31,80}, +{13,31,80},{0,9,421},{0,7,113},{0,5,5},{0,4,130},{0,6,925},{0,5,658},{0,4,274},{0,3,670},{0,3,1039},{0,3,751},{0,9,421},{0,7,113},{0,5,5},{0,4,130},{0,6,925},{0,5,658},{0,4,274},{0,3,670},{3,0,925},{0,3,670},{0,4,1},{0,4,1},{0,4,1},{0,3,4},{0,2,85},{0,2,45},{0,2,45},{0,1,50},{0,1,98},{0,1,59},{0,4,1}, +{0,4,1},{0,4,1},{0,3,4},{0,2,85},{0,2,45},{0,2,45},{0,1,50},{1,0,85},{0,1,50},{1,6,421},{0,7,113},{0,5,5},{0,4,130},{1,6,421},{3,2,421},{0,4,130},{0,3,445},{3,2,421},{0,3,445},{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,12,425},{0,9,52},{0,6,10}, +{0,6,82},{0,8,1261},{0,6,805},{0,5,322},{0,4,833},{0,4,1445},{0,4,977},{0,12,425},{0,9,52},{0,6,10},{0,6,82},{0,8,1261},{0,6,805},{0,5,322},{0,4,833},{4,0,1261},{0,4,833},{0,7,0},{0,7,0},{0,7,0},{0,4,1},{0,3,225},{0,3,117},{0,3,117},{0,2,125},{0,2,257},{0,2,161},{0,7,0},{0,7,0},{0,7,0},{0,4,1},{1,0,221}, +{0,3,117},{0,3,117},{0,2,125},{1,1,221},{0,2,125},{3,2,421},{0,9,52},{0,6,10},{0,6,82},{3,2,421},{5,1,421},{0,6,82},{0,4,433},{5,1,421},{0,4,433},{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,14,430},{0,11,29},{0,7,74},{0,7,46},{0,10,1514},{0,8,874},{0,6,307}, +{0,5,917},{0,5,1814},{0,4,1074},{0,14,430},{0,11,29},{0,7,74},{0,7,46},{3,0,1514},{0,8,874},{0,6,307},{0,5,917},{5,0,1514},{0,5,917},{0,10,10},{0,10,10},{0,10,10},{0,6,10},{0,5,340},{0,5,160},{0,5,160},{0,3,169},{0,3,421},{0,3,250},{0,10,10},{0,10,10},{0,10,10},{0,6,10},{1,2,338},{0,5,160},{0,5,160},{0,3,169},{1,2,338}, +{0,3,169},{4,1,421},{0,11,20},{1,7,5},{0,7,37},{4,1,421},{7,0,421},{0,7,37},{0,5,433},{7,0,421},{0,5,433},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,1,0},{0,1,0},{0,1,0},{0,1,4},{0,0,9},{0,0,9},{0,17,542},{0,13,130},{0,9,285},{0,8,137},{0,12,1517},{0,9,737},{0,7,185},{0,6,794},{0,7,1982},{0,5,1062},{1,13,450}, +{1,11,77},{1,8,34},{1,7,122},{3,3,1517},{0,9,737},{0,7,185},{0,6,794},{2,5,1514},{0,6,794},{0,12,121},{0,12,121},{0,12,121},{0,7,125},{0,8,338},{0,6,98},{0,6,98},{0,4,97},{0,4,514},{0,4,241},{1,9,25},{1,9,25},{1,9,25},{1,6,26},{0,8,338},{0,6,98},{0,6,98},{0,4,97},{4,0,338},{0,4,97},{5,0,421},{0,13,9},{1,8,9}, +{0,8,16},{5,0,421},{8,0,421},{0,8,16},{0,6,433},{8,0,421},{0,6,433},{0,0,121},{0,0,121},{0,0,121},{0,0,121},{0,4,1},{0,4,1},{0,4,1},{0,2,1},{0,2,37},{0,2,37},{1,16,697},{1,13,297},{1,9,354},{1,9,309},{0,15,1517},{0,11,630},{0,9,50},{0,7,670},{0,8,2198},{0,6,1109},{1,16,441},{1,13,41},{1,9,98},{1,9,53},{4,2,1514}, +{0,11,630},{0,9,50},{0,7,670},{6,2,1514},{0,7,670},{1,12,273},{1,12,273},{1,12,273},{1,8,273},{0,11,338},{0,8,41},{0,8,41},{0,5,50},{0,6,680},{0,5,275},{1,12,17},{1,12,17},{1,12,17},{1,8,17},{3,1,338},{0,8,41},{0,8,41},{0,5,50},{3,3,338},{0,5,50},{6,0,421},{0,15,1},{2,9,5},{0,9,1},{6,0,421},{5,6,421},{0,9,1}, +{0,7,445},{5,6,421},{0,7,445},{1,0,272},{1,0,272},{1,0,272},{1,0,272},{0,7,1},{0,7,1},{0,7,1},{0,4,0},{0,3,106},{0,3,106},{1,19,821},{1,15,405},{1,11,570},{1,10,410},{0,18,1514},{0,13,577},{0,10,14},{0,8,602},{0,10,2462},{0,7,1175},{2,16,450},{2,13,77},{2,10,35},{2,10,107},{3,8,1514},{0,13,577},{0,10,14},{0,8,602},{4,6,1514}, +{0,8,602},{1,14,401},{1,14,401},{1,14,401},{1,9,404},{0,13,340},{0,10,13},{0,10,13},{0,6,29},{0,7,851},{0,6,353},{2,11,25},{2,11,25},{2,11,25},{2,8,26},{4,0,338},{0,10,13},{0,10,13},{0,6,29},{1,7,338},{0,6,29},{5,6,421},{1,15,5},{2,10,10},{0,10,10},{5,6,421},{10,1,421},{0,10,10},{0,8,433},{10,1,421},{0,8,433},{1,0,400}, +{1,0,400},{1,0,400},{1,0,400},{0,9,1},{0,9,1},{0,9,1},{0,6,4},{0,4,208},{0,4,208},{1,22,902},{1,17,485},{2,11,750},{1,11,482},{0,21,1566},{0,15,570},{0,11,95},{0,9,582},{0,11,2337},{0,9,933},{2,18,430},{2,15,29},{2,11,74},{2,11,46},{5,4,1514},{0,15,521},{0,11,46},{0,9,533},{9,1,1514},{0,9,533},{1,17,481},{1,17,481},{1,17,481}, +{1,11,481},{0,16,387},{0,12,51},{0,12,51},{0,7,75},{0,8,755},{0,7,222},{2,14,10},{2,14,10},{2,14,10},{2,10,10},{3,6,338},{0,12,2},{0,12,2},{0,7,26},{3,6,338},{0,7,26},{7,2,421},{1,17,4},{3,11,5},{1,11,1},{7,2,421},{12,0,421},{1,11,1},{0,9,433},{12,0,421},{0,9,433},{1,0,481},{1,0,481},{1,0,481},{1,0,481},{0,12,50}, +{0,12,50},{0,12,50},{0,7,50},{0,6,157},{0,6,157},{2,21,866},{2,17,454},{2,13,609},{2,12,461},{1,20,1515},{1,15,578},{1,12,19},{1,10,603},{0,13,2214},{0,10,707},{3,17,450},{3,15,77},{3,12,34},{3,11,122},{7,0,1514},{0,16,458},{1,12,18},{0,10,482},{4,9,1514},{0,10,482},{2,16,445},{2,16,445},{2,16,445},{2,11,449},{1,15,341},{1,12,19},{1,12,19}, +{1,8,26},{0,10,635},{0,8,106},{3,13,25},{3,13,25},{3,13,25},{3,10,26},{5,2,338},{0,14,2},{0,14,2},{0,9,20},{8,1,338},{0,9,20},{7,4,421},{2,17,9},{3,12,9},{1,12,9},{7,4,421},{11,3,421},{1,12,9},{0,10,433},{11,3,421},{0,10,433},{2,0,445},{2,0,445},{2,0,445},{2,0,445},{1,11,2},{1,11,2},{1,11,2},{1,7,10},{0,8,90}, +{0,8,90},{2,24,902},{2,19,482},{3,13,723},{2,13,482},{1,23,1578},{1,17,566},{1,14,117},{1,11,590},{0,15,2046},{0,11,535},{3,20,441},{3,17,41},{3,13,98},{3,13,53},{7,3,1514},{0,18,429},{2,13,50},{0,11,454},{11,2,1514},{0,11,454},{2,19,481},{2,19,481},{2,19,481},{2,13,481},{1,18,404},{1,14,68},{1,14,68},{1,10,89},{0,12,557},{0,10,49},{3,16,17}, +{3,16,17},{3,16,17},{3,12,17},{5,5,338},{1,14,4},{1,14,4},{0,10,13},{5,7,338},{0,10,13},{8,2,421},{2,19,1},{4,13,5},{2,13,1},{8,2,421},{14,1,421},{2,13,1},{0,11,445},{14,1,421},{0,11,445},{2,0,481},{2,0,481},{2,0,481},{2,0,481},{1,14,64},{1,14,64},{1,14,64},{1,9,65},{0,10,40},{0,10,40},{3,23,854},{3,19,438},{3,15,603}, +{3,14,443},{2,22,1515},{2,17,578},{2,14,15},{2,12,603},{0,16,1911},{0,12,458},{4,20,450},{4,17,77},{4,14,35},{4,14,107},{5,12,1514},{0,20,425},{2,14,14},{0,12,433},{13,1,1514},{0,12,433},{3,18,434},{3,18,434},{3,18,434},{3,13,437},{2,17,341},{2,14,14},{2,14,14},{2,10,30},{0,14,477},{0,11,35},{4,15,25},{4,15,25},{4,15,25},{4,12,26},{7,1,338}, +{1,16,5},{1,16,5},{1,11,10},{10,2,338},{1,11,10},{8,5,421},{3,19,5},{4,14,10},{2,14,10},{8,5,421},{12,5,421},{2,14,10},{0,12,433},{12,5,421},{0,12,433},{3,0,433},{3,0,433},{3,0,433},{3,0,433},{2,13,2},{2,13,2},{2,13,2},{2,10,5},{0,12,25},{0,12,25},{3,26,902},{3,21,485},{4,15,750},{3,15,482},{2,25,1566},{2,19,570},{2,15,95}, +{2,13,582},{0,18,1787},{0,13,442},{4,22,430},{4,19,29},{4,15,74},{4,15,46},{8,3,1514},{1,20,425},{2,15,46},{0,13,442},{11,5,1514},{0,13,442},{3,21,481},{3,21,481},{3,21,481},{3,15,481},{2,20,387},{2,16,51},{2,16,51},{2,11,75},{0,16,419},{1,12,69},{4,18,10},{4,18,10},{4,18,10},{4,14,10},{5,10,338},{2,16,2},{2,16,2},{1,12,20},{12,1,338}, +{1,12,20},{9,4,421},{3,21,4},{5,15,5},{3,15,1},{9,4,421},{15,3,421},{3,15,1},{0,13,433},{15,3,421},{0,13,433},{3,0,481},{3,0,481},{3,0,481},{3,0,481},{2,16,50},{2,16,50},{2,16,50},{2,11,50},{0,13,9},{0,13,9},{4,25,866},{4,21,454},{4,17,609},{4,16,461},{3,24,1515},{3,19,578},{3,16,19},{3,14,603},{0,20,1686},{1,14,458},{5,21,450}, +{5,19,77},{5,16,34},{5,15,122},{3,24,1514},{1,22,425},{3,16,18},{1,14,433},{14,3,1514},{1,14,433},{4,20,445},{4,20,445},{4,20,445},{4,15,449},{3,19,341},{3,16,19},{3,16,19},{3,12,26},{0,17,372},{1,13,45},{5,17,25},{5,17,25},{5,17,25},{5,14,26},{8,1,338},{2,18,2},{2,18,2},{2,13,20},{10,5,338},{2,13,20},{11,0,421},{4,21,9},{5,16,9}, +{3,16,9},{11,0,421},{13,7,421},{3,16,9},{0,14,433},{13,7,421},{0,14,433},{4,0,445},{4,0,445},{4,0,445},{4,0,445},{3,15,2},{3,15,2},{3,15,2},{3,11,10},{0,15,5},{0,15,5},{4,28,902},{4,23,482},{5,17,723},{4,17,482},{3,27,1578},{3,21,566},{3,18,117},{3,15,590},{0,22,1614},{1,15,462},{5,24,441},{5,21,41},{5,17,98},{5,17,53},{5,20,1514}, +{2,22,429},{4,17,50},{2,15,454},{13,6,1514},{2,15,454},{4,23,481},{4,23,481},{4,23,481},{4,17,481},{3,22,404},{3,18,68},{3,18,68},{3,14,89},{0,19,347},{2,14,49},{5,20,17},{5,20,17},{5,20,17},{5,16,17},{8,4,338},{3,18,4},{3,18,4},{2,14,13},{14,2,338},{2,14,13},{11,3,421},{4,23,1},{6,17,5},{4,17,1},{11,3,421},{15,6,421},{4,17,1}, +{0,15,445},{15,6,421},{0,15,445},{4,0,481},{4,0,481},{4,0,481},{4,0,481},{3,18,64},{3,18,64},{3,18,64},{3,13,65},{1,16,8},{1,16,8},{5,27,854},{5,23,438},{5,19,603},{5,18,443},{4,26,1515},{4,21,578},{4,18,15},{4,16,603},{0,23,1566},{2,16,458},{6,24,450},{6,21,77},{6,18,35},{6,18,107},{11,1,1514},{2,24,425},{4,18,14},{2,16,433},{15,5,1514}, +{2,16,433},{5,22,434},{5,22,434},{5,22,434},{5,17,437},{4,21,341},{4,18,14},{4,18,14},{4,14,30},{0,21,341},{2,15,35},{6,19,25},{6,19,25},{6,19,25},{6,16,26},{3,25,338},{3,20,5},{3,20,5},{3,15,10},{12,6,338},{3,15,10},{12,2,421},{5,23,5},{6,18,10},{4,18,10},{12,2,421},{14,9,421},{4,18,10},{0,16,433},{14,9,421},{0,16,433},{5,0,433}, +{5,0,433},{5,0,433},{5,0,433},{4,17,2},{4,17,2},{4,17,2},{4,14,5},{1,17,10},{1,17,10},{5,30,902},{5,25,485},{6,19,750},{5,19,482},{4,29,1566},{4,23,570},{4,19,95},{4,17,582},{0,25,1533},{2,17,442},{6,26,430},{6,23,29},{6,19,74},{6,19,46},{10,7,1514},{3,24,425},{4,19,46},{2,17,442},{13,9,1514},{2,17,442},{5,25,481},{5,25,481},{5,25,481}, +{5,19,481},{4,24,387},{4,20,51},{4,20,51},{4,15,75},{1,21,341},{3,16,69},{6,22,10},{6,22,10},{6,22,10},{6,18,10},{9,6,338},{4,20,2},{4,20,2},{3,16,20},{14,5,338},{3,16,20},{11,8,421},{5,25,4},{7,19,5},{5,19,1},{11,8,421},{11,14,421},{5,19,1},{0,17,433},{11,14,421},{0,17,433},{5,0,481},{5,0,481},{5,0,481},{5,0,481},{4,20,50}, +{4,20,50},{4,20,50},{4,15,50},{2,17,9},{2,17,9},{6,29,866},{6,25,454},{6,21,609},{6,20,461},{5,28,1515},{5,23,578},{5,20,19},{5,18,603},{0,27,1521},{3,18,458},{7,25,450},{7,23,77},{7,20,34},{7,19,122},{12,3,1514},{3,26,425},{5,20,18},{3,18,433},{11,13,1514},{3,18,433},{6,24,445},{6,24,445},{6,24,445},{6,19,449},{5,23,341},{5,20,19},{5,20,19}, +{5,16,26},{1,23,341},{3,17,45},{7,21,25},{7,21,25},{7,21,25},{7,18,26},{10,5,338},{4,22,2},{4,22,2},{4,17,20},{12,9,338},{4,17,20},{13,4,421},{6,25,9},{7,20,9},{5,20,9},{13,4,421},{15,11,421},{5,20,9},{0,18,433},{15,11,421},{0,18,433},{6,0,445},{6,0,445},{6,0,445},{6,0,445},{5,19,2},{5,19,2},{5,19,2},{5,15,10},{2,19,5}, +{2,19,5},{6,31,914},{6,27,482},{7,21,723},{6,21,482},{5,31,1578},{5,25,566},{5,22,117},{5,19,590},{1,27,1535},{3,19,462},{7,28,441},{7,25,41},{7,21,98},{7,21,53},{8,19,1514},{4,26,429},{6,21,50},{4,19,454},{15,10,1514},{4,19,454},{6,27,481},{6,27,481},{6,27,481},{6,21,481},{5,26,404},{5,22,68},{5,22,68},{5,18,89},{2,23,347},{4,18,49},{7,24,17}, +{7,24,17},{7,24,17},{7,20,17},{10,8,338},{5,22,4},{5,22,4},{4,18,13},{11,12,338},{4,18,13},{15,0,421},{6,27,1},{8,21,50},{6,21,1},{15,0,421},{13,15,421},{6,21,1},{0,19,445},{13,15,421},{0,19,445},{6,0,481},{6,0,481},{6,0,481},{6,0,481},{5,22,64},{5,22,64},{5,22,64},{5,17,65},{3,20,8},{3,20,8},{7,31,854},{7,27,438},{7,23,603}, +{7,22,443},{6,30,1515},{6,25,578},{6,22,15},{6,20,603},{1,29,1518},{4,20,458},{7,31,565},{7,27,149},{8,22,174},{7,22,154},{13,5,1514},{4,28,425},{6,22,14},{4,20,433},{12,15,1514},{4,20,433},{7,26,434},{7,26,434},{7,26,434},{7,21,437},{6,25,341},{6,22,14},{6,22,14},{6,18,30},{2,25,341},{4,19,35},{7,26,145},{7,26,145},{7,26,145},{7,21,148},{9,14,338}, +{5,24,5},{5,24,5},{5,19,10},{14,10,338},{5,19,10},{15,3,421},{7,27,5},{8,22,5},{6,22,10},{15,3,421},{15,14,421},{6,22,10},{0,20,433},{15,14,421},{0,20,433},{7,0,433},{7,0,433},{7,0,433},{7,0,433},{6,21,2},{6,21,2},{6,21,2},{6,18,5},{3,21,10},{3,21,10},{7,31,1046},{7,29,485},{7,24,770},{7,23,482},{7,29,1598},{6,27,570},{6,23,95}, +{6,21,582},{2,29,1533},{4,21,442},{8,28,450},{8,26,77},{8,23,35},{8,23,107},{15,1,1514},{5,28,425},{6,23,46},{4,21,442},{15,13,1514},{4,21,442},{7,29,481},{7,29,481},{7,29,481},{7,23,481},{6,28,387},{6,24,51},{6,24,51},{6,19,75},{3,25,341},{5,20,69},{8,24,25},{8,24,25},{8,24,25},{8,21,26},{11,10,338},{6,24,2},{6,24,2},{5,20,20},{5,23,338}, +{5,20,20},{13,12,421},{7,29,4},{8,23,10},{7,23,1},{13,12,421},{13,18,421},{7,23,1},{0,21,433},{13,18,421},{0,21,433},{7,0,481},{7,0,481},{7,0,481},{7,0,481},{6,24,50},{6,24,50},{6,24,50},{6,19,50},{4,21,9},{4,21,9},{8,31,1106},{8,28,714},{8,24,749},{8,24,734},{7,31,1542},{7,27,578},{7,24,19},{7,22,603},{2,31,1521},{5,22,458},{8,31,430}, +{8,28,38},{8,24,73},{8,24,58},{14,7,1514},{5,30,425},{7,24,18},{5,22,433},{13,17,1514},{5,22,433},{8,27,686},{8,27,686},{8,27,686},{8,23,686},{7,27,341},{7,24,19},{7,24,19},{7,20,26},{3,27,341},{5,21,45},{8,27,10},{8,27,10},{8,27,10},{8,23,10},{12,9,338},{6,26,2},{6,26,2},{6,21,20},{14,13,338},{6,21,20},{15,8,421},{7,31,20},{9,24,4}, +{7,24,9},{15,8,421},{15,17,421},{7,24,9},{0,22,433},{15,17,421},{0,22,433},{8,0,685},{8,0,685},{8,0,685},{8,0,685},{7,23,2},{7,23,2},{7,23,2},{7,19,10},{4,23,5},{4,23,5},{8,31,1034},{8,30,438},{8,26,603},{8,25,443},{8,30,1806},{7,29,566},{7,26,117},{7,23,590},{3,31,1535},{5,23,462},{9,31,437},{9,28,77},{9,25,33},{9,25,98},{10,23,1514}, +{6,30,429},{7,26,53},{6,23,454},{11,21,1514},{6,23,454},{8,29,434},{8,29,434},{8,29,434},{8,24,437},{7,30,404},{7,26,68},{7,26,68},{7,22,89},{4,27,347},{6,22,49},{9,26,17},{9,26,17},{9,26,17},{9,23,20},{15,2,338},{7,26,4},{7,26,4},{6,22,13},{13,16,338},{6,22,13},{15,11,421},{8,30,5},{9,25,17},{8,25,10},{15,11,421},{15,19,421},{8,25,10}, +{0,23,445},{15,19,421},{0,23,445},{8,0,433},{8,0,433},{8,0,433},{8,0,433},{7,26,64},{7,26,64},{7,26,64},{7,21,65},{5,24,8},{5,24,8},{9,31,1174},{8,31,506},{9,26,723},{8,26,482},{8,31,1643},{7,30,717},{8,26,131},{7,24,725},{4,31,1566},{6,24,458},{9,31,549},{9,30,41},{9,26,98},{9,26,53},{15,9,1514},{7,30,461},{8,26,50},{6,24,433},{14,19,1514}, +{6,24,433},{8,31,490},{8,31,490},{8,31,490},{8,26,481},{8,28,421},{8,25,122},{8,25,122},{8,22,131},{4,29,341},{6,23,35},{9,29,17},{9,29,17},{9,29,17},{9,25,17},{11,18,338},{7,28,5},{7,28,5},{7,23,10},{10,21,338},{7,23,10},{14,17,421},{9,30,25},{10,26,5},{8,26,1},{14,17,421},{13,23,421},{8,26,1},{0,24,433},{13,23,421},{0,24,433},{8,0,481}, +{8,0,481},{8,0,481},{8,0,481},{8,24,82},{8,24,82},{8,24,82},{8,21,81},{5,25,10},{5,25,10},{9,31,1334},{9,31,470},{9,28,597},{9,27,443},{9,31,1815},{8,30,578},{8,27,15},{8,25,603},{5,31,1638},{6,25,442},{10,31,506},{10,30,77},{10,27,35},{10,27,107},{14,15,1514},{7,31,506},{8,27,14},{6,25,442},{12,23,1514},{6,25,442},{9,31,434},{9,31,434},{9,31,434}, +{9,26,437},{8,30,341},{8,27,14},{8,27,14},{8,23,30},{5,29,341},{7,24,69},{10,28,25},{10,28,25},{10,28,25},{10,25,26},{13,14,338},{8,27,13},{8,27,13},{7,24,20},{8,25,338},{7,24,20},{15,16,421},{9,31,37},{10,27,10},{8,27,10},{15,16,421},{15,22,421},{8,27,10},{0,25,433},{15,22,421},{0,25,433},{9,0,433},{9,0,433},{9,0,433},{9,0,433},{8,26,2}, +{8,26,2},{8,26,2},{8,23,5},{6,25,9},{6,25,9},{10,31,1470},{10,31,735},{10,28,749},{9,28,481},{9,31,1895},{8,31,579},{8,28,89},{8,26,582},{6,31,1761},{7,26,458},{11,31,614},{10,31,59},{10,28,73},{10,28,58},{13,21,1514},{8,31,530},{8,28,40},{7,26,433},{15,21,1514},{7,26,433},{9,31,562},{9,31,562},{9,31,562},{9,28,481},{9,30,421},{8,29,51},{8,29,51}, +{8,24,65},{5,31,341},{7,25,45},{10,31,10},{10,31,10},{10,31,10},{10,27,10},{14,13,338},{8,29,2},{8,29,2},{8,24,16},{11,23,338},{8,24,16},{15,19,421},{10,31,50},{11,28,4},{9,28,0},{15,19,421},{13,26,421},{9,28,0},{0,26,433},{13,26,421},{0,26,433},{9,0,481},{9,0,481},{9,0,481},{9,0,481},{8,29,50},{8,29,50},{8,29,50},{8,24,49},{6,27,5}, +{6,27,5},{11,31,1838},{10,31,753},{10,30,603},{10,29,443},{10,31,2046},{9,31,629},{9,29,21},{9,27,589},{7,31,1935},{7,27,462},{11,31,749},{11,31,120},{11,29,33},{11,29,98},{12,27,1514},{9,31,629},{9,29,21},{7,27,461},{13,25,1514},{7,27,461},{10,31,497},{10,31,497},{10,31,497},{10,28,437},{9,31,388},{9,29,20},{9,29,20},{9,25,29},{6,31,347},{8,25,105},{11,30,17}, +{11,30,17},{11,30,17},{11,27,20},{14,16,338},{8,31,4},{8,31,4},{8,26,10},{15,20,338},{8,26,10},{14,25,421},{11,31,104},{11,29,17},{10,29,10},{14,25,421},{12,29,421},{10,29,10},{0,27,445},{12,29,421},{0,27,445},{10,0,433},{10,0,433},{10,0,433},{10,0,433},{9,28,1},{9,28,1},{9,28,1},{9,25,4},{7,28,8},{7,28,8},{11,31,1902},{11,31,1001},{11,30,723}, +{10,30,482},{11,31,2286},{10,31,782},{9,31,117},{9,28,578},{8,31,2118},{7,29,491},{12,31,770},{12,31,338},{11,30,98},{11,30,53},{14,23,1514},{10,31,701},{10,30,50},{8,28,442},{11,29,1514},{8,28,442},{11,31,677},{11,31,677},{11,31,677},{10,30,481},{10,31,437},{9,31,68},{9,31,68},{9,27,89},{7,31,379},{8,27,49},{11,31,52},{11,31,52},{11,31,52},{11,29,17},{13,22,338}, +{9,31,4},{9,31,4},{8,27,13},{12,25,338},{8,27,13},{15,24,421},{12,31,169},{12,30,5},{10,30,1},{15,24,421},{15,27,421},{10,30,1},{0,28,433},{15,27,421},{0,28,433},{10,0,481},{10,0,481},{10,0,481},{10,0,481},{9,31,64},{9,31,64},{9,31,64},{9,26,65},{7,29,10},{7,29,10},{12,31,2151},{11,31,1254},{11,31,629},{11,31,442},{11,31,2393},{10,31,975},{10,31,14}, +{10,29,570},{9,31,2241},{8,29,425},{13,31,931},{12,31,395},{12,31,34},{12,30,105},{13,29,1459},{11,31,778},{10,31,13},{8,29,400},{14,27,1459},{8,29,400},{11,31,629},{11,31,629},{11,31,629},{11,30,437},{10,31,581},{10,31,14},{10,31,14},{10,27,30},{8,31,477},{8,28,45},{12,31,34},{12,31,34},{12,31,34},{12,29,26},{15,18,338},{10,31,13},{10,31,13},{9,28,17},{10,29,338}, +{9,28,17},{15,27,394},{13,31,218},{12,31,9},{10,31,9},{15,27,394},{15,28,394},{10,31,9},{0,29,400},{15,28,394},{0,29,400},{11,0,433},{11,0,433},{11,0,433},{11,0,433},{10,30,2},{10,30,2},{10,30,2},{10,27,5},{8,29,25},{8,29,25},{12,31,1767},{12,31,1167},{12,31,806},{11,31,506},{12,31,1983},{11,31,747},{11,31,122},{10,29,346},{10,31,1836},{8,30,217},{13,31,611}, +{13,31,339},{12,31,130},{12,31,10},{15,24,1064},{12,31,587},{11,31,41},{8,30,217},{15,27,1067},{8,30,217},{12,31,806},{12,31,806},{12,31,806},{11,31,506},{11,31,581},{11,31,122},{11,31,122},{10,28,65},{9,31,557},{9,29,69},{12,31,130},{12,31,130},{12,31,130},{12,31,10},{13,27,338},{11,31,41},{11,31,41},{10,28,16},{13,27,338},{10,28,16},{14,31,200},{14,31,136},{13,31,1}, +{12,31,1},{14,31,200},{15,29,200},{12,31,1},{0,30,208},{15,29,200},{0,30,208},{11,0,481},{11,0,481},{11,0,481},{11,0,481},{11,30,82},{11,30,82},{11,30,82},{10,28,49},{8,30,9},{8,30,9},{13,31,1646},{12,31,1194},{12,31,833},{12,31,497},{12,31,1686},{12,31,750},{11,31,221},{11,30,122},{11,31,1541},{9,30,110},{14,31,542},{13,31,285},{13,31,116},{13,31,20},{15,26,722}, +{13,31,429},{12,31,100},{10,30,74},{14,29,722},{10,30,74},{12,31,833},{12,31,833},{12,31,833},{12,31,497},{12,31,725},{11,31,221},{11,31,221},{11,29,29},{10,31,632},{9,30,46},{13,31,116},{13,31,116},{13,31,116},{13,31,20},{13,30,338},{12,31,100},{12,31,100},{10,30,10},{12,30,338},{10,30,10},{15,29,61},{14,31,37},{14,31,1},{13,31,4},{15,29,61},{15,30,61},{13,31,4}, +{0,30,73},{15,30,61},{0,30,73},{12,0,433},{12,0,433},{12,0,433},{12,0,433},{11,31,25},{11,31,25},{11,31,25},{11,29,4},{9,31,17},{9,31,17},{13,31,1406},{13,31,1134},{13,31,965},{12,31,737},{13,31,1454},{12,31,702},{12,31,341},{11,31,89},{11,31,1381},{10,31,49},{14,31,318},{14,31,254},{14,31,218},{13,31,116},{14,31,510},{13,31,333},{13,31,164},{10,31,13},{14,30,509}, +{10,31,13},{13,31,965},{13,31,965},{13,31,965},{12,31,737},{12,31,869},{12,31,341},{12,31,341},{11,31,89},{11,31,756},{10,31,49},{14,31,218},{14,31,218},{14,31,218},{13,31,116},{15,26,338},{13,31,164},{13,31,164},{10,31,13},{14,29,338},{10,31,13},{15,30,9},{15,31,9},{15,31,9},{14,31,9},{15,30,9},{15,31,9},{14,31,9},{0,31,9},{15,31,9},{0,31,9},{12,0,481}, +{12,0,481},{12,0,481},{12,0,481},{12,31,85},{12,31,85},{12,31,85},{11,30,65},{10,31,40},{10,31,40},{13,31,1315},{13,31,1043},{13,31,874},{13,31,602},{13,31,1171},{13,31,627},{13,31,458},{12,31,5},{12,31,1087},{11,31,80},{14,31,225},{14,31,161},{14,31,125},{14,31,61},{15,29,297},{14,31,193},{14,31,157},{12,31,4},{14,31,297},{12,31,4},{13,31,874},{13,31,874},{13,31,874}, +{13,31,602},{13,31,730},{13,31,458},{13,31,458},{12,31,5},{11,31,705},{11,31,80},{14,31,125},{14,31,125},{14,31,125},{14,31,61},{14,31,221},{14,31,157},{14,31,157},{12,31,4},{15,29,221},{12,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{13,0,433},{13,0,433},{13,0,433},{13,0,433},{12,31,101}, +{12,31,101},{12,31,101},{12,31,5},{11,31,80},{11,31,80},{14,31,885},{14,31,821},{14,31,785},{13,31,650},{14,31,885},{13,31,483},{13,31,314},{13,31,81},{13,31,779},{11,31,144},{15,31,169},{14,31,145},{14,31,109},{14,31,45},{15,30,118},{14,31,81},{14,31,45},{13,31,0},{15,30,114},{13,31,0},{14,31,785},{14,31,785},{14,31,785},{13,31,650},{13,31,586},{13,31,314},{13,31,314}, +{13,31,81},{12,31,518},{11,31,144},{14,31,109},{14,31,109},{14,31,109},{14,31,45},{15,29,85},{14,31,45},{14,31,45},{13,31,0},{14,31,85},{13,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{13,0,481},{13,0,481},{13,0,481},{13,0,481},{13,31,145},{13,31,145},{13,31,145},{13,31,81},{11,31,144}, +{11,31,144},{0,13,884},{0,10,225},{0,7,18},{0,6,265},{0,9,1899},{0,7,1355},{0,6,589},{0,4,1354},{0,5,2124},{0,4,1498},{0,13,884},{0,10,225},{0,7,18},{0,6,265},{2,2,1896},{0,7,1355},{0,6,589},{0,4,1354},{1,4,1896},{0,4,1354},{0,6,0},{0,6,0},{0,6,0},{0,4,4},{0,3,162},{0,3,90},{0,3,90},{0,2,104},{0,2,200},{0,1,134},{0,6,0}, +{0,6,0},{0,6,0},{0,4,4},{0,3,162},{0,3,90},{0,3,90},{0,2,104},{0,2,164},{0,2,104},{3,3,882},{0,10,225},{0,7,18},{0,6,265},{3,3,882},{4,3,882},{0,6,265},{0,5,890},{4,3,882},{0,5,890},{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,15,884},{0,12,170},{0,8,8}, +{0,7,202},{0,10,2360},{0,8,1530},{0,7,643},{0,5,1579},{0,6,2684},{0,5,1804},{0,15,884},{0,12,170},{0,8,8},{0,7,202},{1,7,2355},{0,8,1530},{0,7,643},{0,5,1579},{1,5,2355},{0,5,1579},{0,9,1},{0,9,1},{0,9,1},{0,5,1},{0,4,340},{0,4,180},{0,4,180},{0,2,200},{0,2,392},{0,2,236},{0,9,1},{0,9,1},{0,9,1},{0,5,1},{1,1,338}, +{0,4,180},{0,4,180},{0,2,200},{2,0,340},{0,2,200},{4,2,882},{0,12,170},{0,8,8},{0,7,202},{4,2,882},{6,2,882},{0,7,202},{0,6,890},{6,2,882},{0,6,890},{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,18,882},{0,14,106},{0,10,52},{0,9,148},{0,12,2899},{0,9,1773},{0,8,725}, +{0,6,1854},{0,7,3348},{0,5,2124},{0,18,882},{0,14,106},{0,10,52},{0,9,148},{1,9,2899},{0,9,1773},{0,8,725},{0,6,1854},{6,0,2899},{0,6,1854},{0,11,1},{0,11,1},{0,11,1},{0,7,1},{0,6,580},{0,5,306},{0,5,306},{0,3,325},{0,3,667},{0,3,406},{0,11,1},{0,11,1},{0,11,1},{0,7,1},{1,2,580},{0,5,306},{0,5,306},{0,3,325},{2,1,578}, +{0,3,325},{3,8,882},{0,14,106},{1,9,13},{0,9,148},{3,8,882},{4,6,882},{0,9,148},{0,7,890},{4,6,882},{0,7,890},{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,21,920},{0,16,89},{0,11,153},{0,10,121},{0,14,3051},{0,11,1709},{0,9,557},{0,7,1795},{0,8,3651},{0,6,2174},{0,21,920}, +{0,16,89},{1,10,108},{0,10,121},{4,1,3048},{0,11,1709},{0,9,557},{0,7,1795},{3,5,3048},{0,7,1795},{0,14,37},{0,14,37},{0,14,37},{0,8,37},{0,8,648},{0,7,274},{0,7,274},{0,4,277},{0,4,824},{0,4,421},{0,14,37},{0,14,37},{0,14,37},{0,8,37},{0,8,648},{0,7,274},{0,7,274},{0,4,277},{4,0,648},{0,4,277},{5,4,882},{0,16,53},{1,10,8}, +{0,10,85},{5,4,882},{9,1,882},{0,10,85},{0,8,900},{9,1,882},{0,8,900},{0,0,36},{0,0,36},{0,0,36},{0,0,36},{0,2,0},{0,2,0},{0,2,0},{0,1,1},{0,1,10},{0,1,10},{0,23,1115},{0,18,242},{1,12,309},{0,11,259},{0,17,3051},{0,13,1579},{0,10,346},{0,8,1630},{0,9,3924},{0,7,2173},{1,20,885},{1,16,90},{1,12,53},{1,11,131},{4,4,3048}, +{0,13,1579},{0,10,346},{0,8,1630},{7,2,3048},{0,8,1630},{0,17,226},{0,17,226},{0,17,226},{0,10,225},{0,11,648},{0,9,169},{0,9,169},{0,5,200},{0,6,990},{0,5,425},{1,13,2},{1,13,2},{1,13,2},{1,9,2},{3,1,648},{0,9,169},{0,9,169},{0,5,200},{3,3,648},{0,5,200},{5,7,882},{0,18,17},{2,11,18},{0,11,34},{5,7,882},{6,7,882},{0,11,34}, +{0,9,890},{6,7,882},{0,9,890},{0,0,225},{0,0,225},{0,0,225},{0,0,225},{0,5,0},{0,5,0},{0,5,0},{0,3,0},{0,2,61},{0,2,61},{1,23,1187},{1,18,350},{1,13,422},{1,12,373},{0,20,3048},{0,15,1443},{0,12,204},{0,9,1483},{0,11,4212},{0,8,2174},{1,23,931},{1,18,94},{2,12,108},{1,12,117},{6,0,3048},{0,15,1443},{0,12,204},{0,9,1483},{5,6,3048}, +{0,9,1483},{1,16,305},{1,16,305},{1,16,305},{1,10,309},{0,13,650},{0,11,109},{0,11,109},{0,7,148},{0,7,1161},{0,6,473},{1,16,49},{1,16,49},{1,16,49},{1,10,53},{4,0,648},{0,11,109},{0,11,109},{0,7,148},{1,7,648},{0,7,148},{7,3,882},{0,20,8},{2,12,8},{0,12,8},{7,3,882},{11,2,882},{0,12,8},{0,10,890},{11,2,882},{0,10,890},{1,0,305}, +{1,0,305},{1,0,305},{1,0,305},{0,8,1},{0,8,1},{0,8,1},{0,5,4},{0,3,145},{0,3,145},{1,25,1365},{1,20,497},{1,14,713},{1,13,510},{0,23,3051},{0,16,1278},{0,13,86},{0,10,1354},{0,12,4609},{0,9,2228},{2,22,886},{2,18,110},{2,14,56},{2,13,152},{5,6,3048},{0,16,1278},{0,13,86},{0,10,1354},{10,1,3048},{0,10,1354},{1,19,482},{1,19,482},{1,19,482}, +{1,12,481},{0,16,648},{0,12,72},{0,12,72},{0,8,101},{0,8,1352},{0,7,557},{2,15,5},{2,15,5},{2,15,5},{2,11,5},{3,6,648},{0,12,72},{0,12,72},{0,8,101},{3,6,648},{0,8,101},{5,12,882},{0,21,10},{3,13,13},{0,13,5},{5,12,882},{13,1,882},{0,13,5},{0,11,890},{13,1,882},{0,11,890},{1,0,481},{1,0,481},{1,0,481},{1,0,481},{0,10,1}, +{0,10,1},{0,10,1},{0,6,1},{0,5,261},{0,5,261},{1,28,1667},{1,22,793},{1,15,1182},{1,14,793},{0,25,3048},{0,18,1170},{0,14,36},{0,11,1243},{0,14,5005},{0,10,2318},{2,25,920},{2,20,89},{3,14,108},{2,14,121},{7,2,3048},{0,18,1170},{0,14,36},{0,11,1243},{12,0,3048},{0,11,1243},{1,21,786},{1,21,786},{1,21,786},{1,14,789},{0,19,650},{0,14,32},{0,14,32}, +{0,9,50},{0,9,1619},{0,8,661},{2,18,37},{2,18,37},{2,18,37},{2,12,37},{5,2,648},{0,14,32},{0,14,32},{0,9,50},{8,1,648},{0,9,50},{8,3,882},{1,22,8},{3,14,8},{1,14,8},{8,3,882},{11,5,882},{1,14,8},{0,12,900},{11,5,882},{0,12,900},{1,0,785},{1,0,785},{1,0,785},{1,0,785},{0,13,1},{0,13,1},{0,13,1},{0,8,4},{0,6,405}, +{0,6,405},{2,27,1844},{2,22,971},{2,16,1186},{2,15,988},{0,28,3084},{0,20,1095},{0,16,77},{0,12,1159},{0,16,4945},{0,12,2084},{3,24,885},{3,20,90},{3,16,53},{3,15,131},{6,8,3048},{0,20,1059},{0,16,41},{0,12,1123},{4,12,3048},{0,12,1123},{2,21,955},{2,21,955},{2,21,955},{2,14,954},{0,22,686},{0,16,41},{0,16,41},{0,10,49},{0,11,1577},{0,9,545},{3,17,2}, +{3,17,2},{3,17,2},{3,13,2},{5,5,648},{0,16,5},{0,16,5},{0,10,13},{5,7,648},{0,10,13},{8,6,882},{1,24,9},{4,15,18},{1,15,13},{8,6,882},{15,2,882},{1,15,13},{0,13,890},{15,2,882},{0,13,890},{2,0,954},{2,0,954},{2,0,954},{2,0,954},{0,16,37},{0,16,37},{0,16,37},{0,9,40},{0,8,373},{0,8,373},{2,30,1772},{2,24,898},{2,17,1287}, +{2,16,898},{1,27,3055},{1,20,1143},{1,16,33},{1,13,1214},{0,17,4639},{0,13,1730},{3,27,931},{3,22,94},{4,16,108},{3,16,117},{5,14,3048},{0,21,996},{1,16,29},{0,13,1054},{14,1,3048},{0,13,1054},{2,23,891},{2,23,891},{2,23,891},{2,16,894},{1,21,652},{1,16,29},{1,16,29},{1,11,44},{0,13,1452},{0,11,365},{3,20,49},{3,20,49},{3,20,49},{3,14,53},{7,1,648}, +{0,18,1},{0,18,1},{0,11,4},{10,2,648},{0,11,4},{5,20,882},{2,24,8},{4,16,8},{2,16,8},{5,20,882},{13,6,882},{2,16,8},{0,14,890},{13,6,882},{0,14,890},{2,0,890},{2,0,890},{2,0,890},{2,0,890},{1,15,4},{1,15,4},{1,15,4},{1,10,5},{0,9,269},{0,9,269},{3,29,1838},{3,24,970},{3,18,1186},{3,17,983},{1,30,3084},{1,22,1095},{1,18,77}, +{1,14,1159},{0,19,4419},{0,14,1444},{4,26,886},{4,22,110},{4,18,56},{4,17,152},{8,5,3048},{0,23,936},{1,18,41},{0,14,1003},{12,5,3048},{0,14,1003},{3,23,955},{3,23,955},{3,23,955},{3,16,954},{1,23,692},{1,18,41},{1,18,41},{1,12,46},{0,15,1296},{0,12,235},{4,19,5},{4,19,5},{4,19,5},{4,15,5},{5,10,648},{1,18,5},{1,18,5},{0,12,10},{12,1,648}, +{0,12,10},{11,1,882},{2,25,10},{5,17,13},{2,17,5},{11,1,882},{15,5,882},{2,17,5},{0,15,890},{15,5,882},{0,15,890},{3,0,954},{3,0,954},{3,0,954},{3,0,954},{1,18,37},{1,18,37},{1,18,37},{1,11,40},{0,11,185},{0,11,185},{3,31,1790},{3,26,898},{3,19,1287},{3,18,898},{2,29,3057},{2,22,1179},{2,18,45},{1,15,1250},{0,20,4156},{0,15,1226},{4,29,920}, +{4,24,89},{5,18,108},{4,18,121},{3,26,3048},{0,25,909},{2,18,36},{0,15,970},{15,3,3048},{0,15,970},{3,25,891},{3,25,891},{3,25,891},{3,18,894},{2,23,659},{2,18,41},{2,18,41},{2,13,59},{0,16,1137},{0,13,137},{4,22,37},{4,22,37},{4,22,37},{4,16,37},{8,1,648},{1,20,2},{1,20,2},{1,13,1},{10,5,648},{1,13,1},{10,7,882},{3,26,8},{5,18,8}, +{3,18,8},{10,7,882},{13,9,882},{3,18,8},{0,16,900},{13,9,882},{0,16,900},{3,0,890},{3,0,890},{3,0,890},{3,0,890},{2,17,10},{2,17,10},{2,17,10},{2,12,13},{0,13,136},{0,13,136},{4,31,1844},{4,26,971},{4,20,1186},{4,19,988},{2,31,3111},{2,24,1095},{2,20,77},{2,16,1159},{0,22,3940},{0,16,1055},{5,28,885},{5,24,90},{5,20,53},{5,19,131},{5,22,3048}, +{0,27,886},{2,20,41},{0,17,926},{8,13,3048},{0,17,926},{4,25,955},{4,25,955},{4,25,955},{4,18,954},{2,26,686},{2,20,41},{2,20,41},{2,14,49},{0,18,1002},{0,15,110},{5,21,2},{5,21,2},{5,21,2},{5,17,2},{8,4,648},{2,20,5},{2,20,5},{2,14,13},{14,2,648},{2,14,13},{13,0,882},{3,28,9},{6,19,18},{3,19,13},{13,0,882},{5,21,882},{3,19,13}, +{0,17,890},{5,21,882},{0,17,890},{4,0,954},{4,0,954},{4,0,954},{4,0,954},{2,20,37},{2,20,37},{2,20,37},{2,13,40},{0,15,74},{0,15,74},{4,31,1972},{4,28,898},{4,21,1287},{4,20,898},{3,31,3055},{3,24,1143},{3,20,33},{3,17,1214},{0,23,3820},{0,18,963},{5,31,931},{5,26,94},{6,20,108},{5,20,117},{11,3,3048},{0,28,899},{3,20,29},{0,18,899},{11,11,3048}, +{0,18,899},{4,27,891},{4,27,891},{4,27,891},{4,20,894},{3,25,652},{3,20,29},{3,20,29},{3,15,44},{0,20,876},{0,16,102},{5,24,49},{5,24,49},{5,24,49},{5,18,53},{3,25,648},{2,22,1},{2,22,1},{2,15,4},{12,6,648},{2,15,4},{8,19,882},{4,28,8},{6,20,8},{4,20,8},{8,19,882},{15,10,882},{4,20,8},{0,18,890},{15,10,882},{0,18,890},{4,0,890}, +{4,0,890},{4,0,890},{4,0,890},{3,19,4},{3,19,4},{3,19,4},{3,14,5},{0,17,29},{0,17,29},{5,31,1964},{5,28,970},{5,22,1186},{5,21,983},{4,31,3172},{3,26,1095},{3,22,77},{3,18,1159},{0,25,3679},{0,19,899},{6,30,886},{6,26,110},{6,22,56},{6,21,152},{10,9,3048},{1,29,888},{3,22,41},{0,19,890},{14,9,3048},{0,19,890},{5,27,955},{5,27,955},{5,27,955}, +{5,20,954},{3,27,692},{3,22,41},{3,22,41},{3,16,46},{0,22,800},{1,16,98},{6,23,5},{6,23,5},{6,23,5},{6,19,5},{9,6,648},{3,22,5},{3,22,5},{2,16,10},{14,5,648},{2,16,10},{13,5,882},{4,29,10},{7,21,13},{4,21,5},{13,5,882},{12,15,882},{4,21,5},{0,19,890},{12,15,882},{0,19,890},{5,0,954},{5,0,954},{5,0,954},{5,0,954},{3,22,37}, +{3,22,37},{3,22,37},{3,15,40},{0,19,9},{0,19,9},{6,31,2264},{5,30,898},{5,23,1287},{5,22,898},{4,31,3204},{4,26,1179},{4,22,45},{3,19,1250},{0,27,3523},{0,20,908},{6,31,968},{6,28,89},{7,22,108},{6,22,121},{9,15,3048},{1,30,899},{4,22,36},{0,20,904},{5,22,3048},{0,20,904},{5,29,891},{5,29,891},{5,29,891},{5,22,894},{4,27,659},{4,22,41},{4,22,41}, +{4,17,59},{0,23,747},{1,18,102},{6,26,37},{6,26,37},{6,26,37},{6,20,37},{10,5,648},{3,24,2},{3,24,2},{3,17,1},{12,9,648},{3,17,1},{15,1,882},{5,30,8},{7,22,8},{5,22,8},{15,1,882},{15,13,882},{5,22,8},{0,20,900},{15,13,882},{0,20,900},{5,0,890},{5,0,890},{5,0,890},{5,0,890},{4,21,10},{4,21,10},{4,21,10},{4,16,13},{0,20,8}, +{0,20,8},{6,31,2228},{6,30,971},{6,24,1186},{6,23,988},{5,31,3256},{4,28,1095},{4,24,77},{4,20,1159},{0,29,3364},{1,21,894},{7,31,915},{7,28,90},{7,24,53},{7,23,131},{14,1,3048},{2,31,886},{4,24,41},{1,21,890},{10,17,3048},{1,21,890},{6,29,955},{6,29,955},{6,29,955},{6,22,954},{4,30,686},{4,24,41},{4,24,41},{4,18,49},{0,25,705},{2,19,110},{7,25,2}, +{7,25,2},{7,25,2},{7,21,2},{10,8,648},{4,24,5},{4,24,5},{4,18,13},{11,12,648},{4,18,13},{15,4,882},{6,30,17},{7,24,52},{5,23,13},{15,4,882},{9,22,882},{5,23,13},{0,21,890},{9,22,882},{0,21,890},{6,0,954},{6,0,954},{6,0,954},{6,0,954},{4,24,37},{4,24,37},{4,24,37},{4,17,40},{1,21,4},{1,21,4},{7,31,2444},{6,31,907},{6,25,1287}, +{6,24,898},{6,31,3436},{5,28,1143},{5,24,33},{5,21,1214},{0,31,3276},{1,22,908},{8,30,1208},{7,30,94},{7,25,166},{7,24,117},{13,7,3048},{3,31,906},{5,24,29},{1,22,899},{13,15,3048},{1,22,899},{6,31,891},{6,31,891},{6,31,891},{6,24,894},{5,29,652},{5,24,29},{5,24,29},{5,19,44},{0,27,665},{2,20,102},{7,28,49},{7,28,49},{7,28,49},{7,22,53},{9,14,648}, +{4,26,1},{4,26,1},{4,19,4},{14,10,648},{4,19,4},{10,23,882},{6,31,17},{8,24,13},{6,24,8},{10,23,882},{11,21,882},{6,24,8},{0,22,890},{11,21,882},{0,22,890},{6,0,890},{6,0,890},{6,0,890},{6,0,890},{5,23,4},{5,23,4},{5,23,4},{5,18,5},{1,23,4},{1,23,4},{7,31,2636},{7,31,991},{7,26,1186},{7,25,983},{6,31,3532},{5,30,1095},{5,26,77}, +{5,22,1159},{0,31,3340},{2,23,899},{8,31,1014},{7,31,262},{8,25,108},{7,25,254},{15,3,3048},{4,31,936},{5,26,41},{2,23,890},{11,19,3048},{2,23,890},{7,31,955},{7,31,955},{7,31,955},{7,24,954},{5,31,692},{5,26,41},{5,26,41},{5,20,46},{0,29,651},{3,20,98},{8,26,101},{8,26,101},{8,26,101},{8,22,101},{11,10,648},{5,26,5},{5,26,5},{4,20,10},{5,23,648}, +{4,20,10},{15,9,882},{7,31,37},{8,25,8},{6,25,5},{15,9,882},{14,19,882},{6,25,5},{0,23,890},{14,19,882},{0,23,890},{7,0,954},{7,0,954},{7,0,954},{7,0,954},{5,26,37},{5,26,37},{5,26,37},{5,19,40},{2,23,9},{2,23,9},{8,31,3110},{7,31,1135},{7,27,1287},{7,26,898},{7,31,3652},{6,30,1179},{6,26,45},{5,23,1250},{1,31,3492},{2,24,908},{8,31,1174}, +{8,31,110},{8,27,56},{8,26,152},{11,19,3048},{5,31,996},{6,26,36},{2,24,904},{9,23,3048},{2,24,904},{7,31,939},{7,31,939},{7,31,939},{7,26,894},{6,31,659},{6,26,41},{6,26,41},{6,21,59},{1,29,659},{3,22,102},{8,28,4},{8,28,4},{8,28,4},{8,24,8},{12,9,648},{5,28,2},{5,28,2},{5,21,1},{14,13,648},{5,21,1},{14,15,882},{8,31,106},{9,26,13}, +{7,26,8},{14,15,882},{12,23,882},{7,26,8},{0,24,900},{12,23,882},{0,24,900},{7,0,890},{7,0,890},{7,0,890},{7,0,890},{6,25,10},{6,25,10},{6,25,10},{6,20,13},{2,24,8},{2,24,8},{8,31,3038},{8,31,1470},{8,28,1391},{7,27,1137},{7,31,4120},{6,31,1146},{6,28,77},{6,24,1159},{3,31,3681},{3,25,894},{9,31,1205},{8,31,245},{9,27,99},{8,27,122},{10,25,3048}, +{6,31,1110},{6,28,41},{3,25,890},{12,21,3048},{3,25,890},{8,31,1274},{8,31,1274},{8,31,1274},{7,27,1128},{7,30,750},{6,28,41},{6,28,41},{6,22,49},{1,31,648},{4,23,110},{8,31,49},{8,31,49},{8,31,49},{8,25,53},{15,2,648},{6,28,5},{6,28,5},{6,22,13},{13,16,648},{6,22,13},{14,18,882},{9,31,164},{9,27,18},{7,27,13},{14,18,882},{11,26,882},{7,27,13}, +{0,25,890},{11,26,882},{0,25,890},{7,0,1124},{7,0,1124},{7,0,1124},{7,0,1124},{6,28,37},{6,28,37},{6,28,37},{6,21,40},{3,25,4},{3,25,4},{9,31,3454},{8,31,1502},{8,29,1186},{8,28,983},{8,31,4077},{7,31,1230},{7,28,33},{7,25,1214},{4,31,3820},{3,26,908},{10,31,1368},{9,31,261},{9,29,53},{9,28,126},{15,11,3048},{7,31,1226},{7,28,29},{3,26,899},{15,19,3048}, +{3,26,899},{8,31,1018},{8,31,1018},{8,31,1018},{8,27,954},{7,31,724},{7,28,29},{7,28,29},{7,23,44},{2,31,665},{4,24,102},{9,30,2},{9,30,2},{9,30,2},{9,26,2},{11,18,648},{6,30,1},{6,30,1},{6,23,4},{10,21,648},{6,23,4},{12,27,882},{10,31,225},{10,28,13},{7,28,20},{12,27,882},{13,25,882},{7,28,20},{0,26,890},{13,25,882},{0,26,890},{8,0,954}, +{8,0,954},{8,0,954},{8,0,954},{7,27,4},{7,27,4},{7,27,4},{7,22,5},{3,27,4},{3,27,4},{9,31,3614},{9,31,1886},{8,30,1287},{8,29,898},{8,31,4381},{7,31,1582},{7,30,77},{7,26,1159},{5,31,4036},{4,27,899},{10,31,1560},{10,31,405},{10,29,108},{9,29,117},{14,17,3048},{8,31,1444},{7,30,41},{4,27,890},{13,23,3048},{4,27,890},{8,31,1146},{8,31,1146},{8,31,1146}, +{8,29,894},{8,30,1011},{7,30,41},{7,30,41},{7,24,46},{3,31,705},{5,24,98},{9,31,85},{9,31,85},{9,31,85},{9,27,53},{13,14,648},{7,30,5},{7,30,5},{6,24,10},{8,25,648},{6,24,10},{14,23,882},{10,31,305},{10,29,8},{8,29,8},{14,23,882},{11,29,882},{8,29,8},{0,27,890},{11,29,882},{0,27,890},{8,0,890},{8,0,890},{8,0,890},{8,0,890},{7,30,37}, +{7,30,37},{7,30,37},{7,23,40},{4,27,9},{4,27,9},{10,31,4072},{9,31,2174},{9,31,1186},{9,30,983},{9,31,4545},{8,31,1725},{8,30,207},{7,27,1250},{6,31,4339},{4,28,908},{11,31,1656},{10,31,645},{10,31,56},{10,30,152},{13,23,3048},{8,31,1604},{7,31,77},{4,28,904},{11,27,3048},{4,28,904},{9,31,1150},{9,31,1150},{9,31,1150},{9,29,954},{8,31,841},{8,29,193},{8,29,193}, +{7,25,197},{4,31,747},{5,26,102},{10,31,20},{10,31,20},{10,31,20},{10,28,8},{14,13,648},{7,31,41},{7,31,41},{7,25,1},{11,23,648},{7,25,1},{13,29,882},{11,31,397},{11,30,13},{8,30,5},{13,29,882},{14,27,882},{8,30,5},{0,28,900},{14,27,882},{0,28,900},{9,0,954},{9,0,954},{9,0,954},{9,0,954},{8,27,122},{8,27,122},{8,27,122},{8,23,122},{4,28,8}, +{4,28,8},{10,31,4147},{10,31,2404},{9,31,1429},{9,31,901},{10,31,4627},{9,31,1938},{8,31,38},{8,28,1061},{7,31,4330},{5,29,789},{12,31,1701},{11,31,715},{11,31,90},{10,31,113},{15,19,2814},{10,31,1554},{8,31,34},{5,29,785},{13,26,2814},{5,29,785},{9,31,1429},{9,31,1429},{9,31,1429},{9,31,901},{9,31,1022},{8,31,38},{8,31,38},{8,26,44},{5,31,840},{6,27,110},{11,31,90}, +{11,31,90},{11,31,90},{10,29,53},{14,16,648},{8,31,34},{8,31,34},{7,26,20},{15,20,648},{7,26,20},{15,25,761},{12,31,425},{11,31,9},{9,31,1},{15,25,761},{12,31,761},{9,31,1},{0,29,785},{12,31,761},{0,29,785},{9,0,900},{9,0,900},{9,0,900},{9,0,900},{8,30,4},{8,30,4},{8,30,4},{8,25,5},{5,29,4},{5,29,4},{11,31,3735},{10,31,2356},{10,31,1395}, +{10,31,954},{10,31,4099},{9,31,1618},{9,31,174},{8,29,686},{7,31,3930},{6,29,510},{12,31,1285},{12,31,685},{11,31,122},{11,31,37},{13,27,2249},{10,31,1186},{9,31,74},{6,29,485},{13,27,2249},{6,29,485},{10,31,1395},{10,31,1395},{10,31,1395},{10,31,954},{9,31,1086},{9,31,174},{9,31,174},{8,27,49},{6,31,969},{6,28,102},{11,31,122},{11,31,122},{11,31,122},{11,30,2},{13,22,648}, +{9,31,74},{9,31,74},{8,27,13},{12,25,648},{8,27,13},{15,26,481},{13,31,269},{12,31,0},{10,31,0},{15,26,481},{15,28,481},{10,31,0},{0,29,481},{15,28,481},{0,29,481},{10,0,954},{10,0,954},{10,0,954},{10,0,954},{8,31,61},{8,31,61},{8,31,61},{8,26,40},{5,31,4},{5,31,4},{11,31,3399},{11,31,2260},{11,31,1635},{10,31,954},{11,31,3639},{10,31,1435},{9,31,238}, +{9,29,430},{8,31,3443},{6,30,314},{13,31,1121},{12,31,525},{12,31,164},{11,31,53},{13,29,1769},{11,31,918},{10,31,113},{7,30,290},{14,27,1769},{7,30,290},{11,31,1635},{11,31,1635},{11,31,1635},{10,31,954},{10,31,1251},{9,31,238},{9,31,238},{9,28,41},{7,31,1105},{7,28,98},{12,31,164},{12,31,164},{12,31,164},{11,31,53},{15,18,648},{10,31,113},{10,31,113},{8,28,1},{10,29,648}, +{8,28,1},{15,27,269},{13,31,173},{13,31,4},{11,31,4},{15,27,269},{14,30,265},{11,31,4},{0,30,289},{14,30,265},{0,30,289},{10,0,890},{10,0,890},{10,0,890},{10,0,890},{9,31,13},{9,31,13},{9,31,13},{9,27,5},{6,31,9},{6,31,9},{12,31,3157},{11,31,2308},{11,31,1683},{11,31,1054},{11,31,3303},{10,31,1339},{10,31,378},{9,30,213},{9,31,3103},{7,30,166},{13,31,801}, +{13,31,529},{12,31,260},{12,31,20},{15,24,1374},{12,31,777},{11,31,181},{8,30,117},{15,27,1377},{8,30,117},{11,31,1683},{11,31,1683},{11,31,1683},{11,31,1054},{10,31,1491},{10,31,378},{10,31,378},{9,29,46},{8,31,1331},{7,30,102},{12,31,260},{12,31,260},{12,31,260},{12,31,20},{13,27,648},{11,31,181},{11,31,181},{8,29,10},{13,27,648},{8,29,10},{15,28,117},{14,31,61},{14,31,25}, +{13,31,4},{15,28,117},{14,31,117},{13,31,4},{0,30,113},{14,31,117},{0,30,113},{11,0,954},{11,0,954},{11,0,954},{11,0,954},{10,31,122},{10,31,122},{10,31,122},{9,28,40},{7,31,29},{7,31,29},{12,31,2860},{12,31,2260},{12,31,1899},{11,31,1261},{12,31,2932},{11,31,1310},{11,31,685},{10,30,108},{10,31,2731},{7,31,173},{13,31,747},{13,31,475},{13,31,306},{13,31,130},{15,26,1032}, +{12,31,651},{12,31,290},{8,31,40},{14,29,1032},{8,31,40},{12,31,1899},{12,31,1899},{12,31,1899},{11,31,1261},{11,31,1620},{11,31,685},{11,31,685},{10,30,44},{9,31,1524},{8,30,134},{13,31,306},{13,31,306},{13,31,306},{13,31,130},{13,30,648},{12,31,290},{12,31,290},{9,30,5},{12,30,648},{9,30,5},{15,30,18},{15,30,34},{14,31,16},{14,31,0},{15,30,18},{15,30,26},{14,31,0}, +{0,31,36},{15,30,26},{0,31,36},{11,0,900},{11,0,900},{11,0,900},{11,0,900},{10,31,104},{10,31,104},{10,31,104},{10,29,5},{8,30,130},{8,30,130},{13,31,2732},{12,31,2276},{12,31,1915},{12,31,1315},{12,31,2660},{11,31,1414},{11,31,789},{10,31,45},{11,31,2487},{8,31,116},{14,31,524},{14,31,460},{14,31,424},{13,31,170},{14,31,776},{13,31,507},{13,31,338},{10,31,9},{14,30,771}, +{10,31,9},{12,31,1915},{12,31,1915},{12,31,1915},{12,31,1315},{12,31,1699},{11,31,789},{11,31,789},{10,31,45},{10,31,1546},{8,31,116},{14,31,424},{14,31,424},{14,31,424},{13,31,170},{15,26,580},{13,31,338},{13,31,338},{10,31,9},{14,29,580},{10,31,9},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{12,0,954}, +{12,0,954},{12,0,954},{12,0,954},{11,31,164},{11,31,164},{11,31,164},{10,30,40},{8,31,116},{8,31,116},{13,31,2156},{13,31,1884},{13,31,1715},{12,31,1251},{13,31,2132},{12,31,1108},{12,31,747},{11,31,5},{11,31,1927},{9,31,180},{14,31,300},{14,31,236},{14,31,200},{14,31,136},{15,28,451},{14,31,328},{13,31,194},{11,31,1},{15,29,456},{11,31,1},{13,31,1715},{13,31,1715},{13,31,1715}, +{12,31,1251},{12,31,1347},{12,31,747},{12,31,747},{11,31,5},{10,31,1242},{9,31,180},{14,31,200},{14,31,200},{14,31,200},{14,31,136},{15,27,338},{13,31,194},{13,31,194},{11,31,1},{13,31,338},{11,31,1},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{12,0,890},{12,0,890},{12,0,890},{12,0,890},{11,31,260}, +{11,31,260},{11,31,260},{11,31,5},{9,31,180},{9,31,180},{13,31,1836},{13,31,1564},{13,31,1395},{13,31,1123},{13,31,1620},{12,31,1012},{12,31,651},{11,31,85},{12,31,1564},{10,31,233},{14,31,204},{14,31,140},{14,31,104},{14,31,40},{15,29,216},{14,31,136},{14,31,100},{12,31,1},{14,31,216},{12,31,1},{13,31,1395},{13,31,1395},{13,31,1395},{13,31,1123},{13,31,1179},{12,31,651},{12,31,651}, +{11,31,85},{11,31,998},{10,31,233},{14,31,104},{14,31,104},{14,31,104},{14,31,40},{15,28,162},{14,31,100},{14,31,100},{12,31,1},{15,29,164},{12,31,1},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{13,0,954},{13,0,954},{13,0,954},{13,0,954},{12,31,290},{12,31,290},{12,31,290},{11,31,85},{10,31,233}, +{10,31,233},{0,17,1568},{0,14,442},{0,10,40},{0,8,485},{0,11,3379},{0,9,2369},{0,8,1061},{0,5,2435},{0,6,3760},{0,5,2660},{0,17,1568},{0,14,442},{0,10,40},{0,8,485},{1,8,3372},{0,9,2369},{0,8,1061},{0,5,2435},{5,1,3371},{0,5,2435},{0,8,0},{0,8,0},{0,8,0},{0,5,1},{0,4,288},{0,4,160},{0,4,160},{0,2,164},{0,2,332},{0,2,200},{0,8,0}, +{0,8,0},{0,8,0},{0,5,1},{0,4,288},{0,4,160},{0,4,160},{0,2,164},{2,0,288},{0,2,164},{3,7,1568},{0,14,442},{0,10,40},{0,8,485},{3,7,1568},{8,0,1568},{0,8,485},{0,6,1586},{8,0,1568},{0,6,1586},{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,20,1570},{0,16,325},{0,11,5}, +{0,9,392},{0,13,3968},{0,10,2630},{0,9,1121},{0,6,2710},{0,7,4484},{0,6,3034},{0,20,1570},{0,16,325},{0,11,5},{0,9,392},{1,10,3968},{0,10,2630},{0,9,1121},{0,6,2710},{5,2,3968},{0,6,2710},{0,11,1},{0,11,1},{0,11,1},{0,6,4},{0,5,514},{0,5,274},{0,5,274},{0,3,289},{0,3,595},{0,3,370},{0,11,1},{0,11,1},{0,11,1},{0,6,4},{1,2,512}, +{0,5,274},{0,5,274},{0,3,289},{1,2,512},{0,3,289},{5,3,1568},{0,16,325},{0,11,5},{0,9,392},{5,3,1568},{4,7,1568},{0,9,392},{0,7,1586},{4,7,1568},{0,7,1586},{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,22,1570},{0,17,225},{0,12,18},{0,11,292},{0,15,4652},{0,11,2945},{0,10,1217}, +{0,7,3035},{0,8,5283},{0,7,3476},{0,22,1570},{0,17,225},{0,12,18},{0,11,292},{2,8,4651},{0,11,2945},{0,10,1217},{0,7,3035},{5,3,4651},{0,7,3035},{0,13,0},{0,13,0},{0,13,0},{0,8,1},{0,7,802},{0,6,424},{0,6,424},{0,4,449},{0,3,931},{0,3,562},{0,13,0},{0,13,0},{0,13,0},{0,8,1},{2,0,800},{0,6,424},{0,6,424},{0,4,449},{0,4,800}, +{0,4,449},{1,19,1568},{0,17,225},{0,12,18},{0,11,292},{1,19,1568},{9,2,1568},{0,11,292},{0,8,1576},{9,2,1568},{0,8,1576},{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,25,1570},{0,19,149},{0,13,73},{0,12,194},{0,17,5424},{0,13,3368},{0,11,1349},{0,8,3449},{0,9,6213},{0,7,3956},{0,25,1570}, +{0,19,149},{0,13,73},{0,12,194},{5,0,5419},{0,13,3368},{0,11,1349},{0,8,3449},{5,4,5419},{0,8,3449},{0,16,1},{0,16,1},{0,16,1},{0,9,4},{0,8,1152},{0,7,610},{0,7,610},{0,4,625},{0,4,1328},{0,4,769},{0,16,1},{0,16,1},{0,16,1},{0,9,4},{0,8,1152},{0,7,610},{0,7,610},{0,4,625},{4,0,1152},{0,4,625},{5,8,1568},{0,19,149},{1,13,13}, +{0,12,194},{5,8,1568},{4,10,1568},{0,12,194},{0,9,1576},{4,10,1568},{0,9,1576},{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,28,1651},{0,21,155},{0,14,281},{0,13,198},{0,20,5424},{0,15,3099},{0,12,996},{0,9,3179},{0,10,6544},{0,8,3890},{1,24,1619},{0,21,155},{1,14,69},{0,13,198},{5,3,5419}, +{0,15,3099},{0,12,996},{0,9,3179},{4,7,5419},{0,9,3179},{0,19,82},{0,19,82},{0,19,82},{0,11,82},{0,11,1152},{0,9,445},{0,9,445},{0,6,505},{0,6,1494},{0,5,737},{1,15,50},{1,15,50},{1,15,50},{1,10,49},{3,1,1152},{0,9,445},{0,9,445},{0,6,505},{3,3,1152},{0,6,505},{5,11,1568},{0,21,74},{1,14,20},{0,13,117},{5,11,1568},{11,3,1568},{0,13,117}, +{0,10,1586},{11,3,1568},{0,10,1586},{0,0,81},{0,0,81},{0,0,81},{0,0,81},{0,3,0},{0,3,0},{0,3,0},{0,2,1},{0,1,25},{0,1,25},{1,27,1825},{0,23,323},{1,15,342},{0,14,361},{0,22,5420},{0,16,2834},{0,13,726},{0,10,2966},{0,11,6916},{0,9,3860},{1,27,1569},{1,21,131},{1,15,86},{1,14,181},{1,19,5419},{0,16,2834},{0,13,726},{0,10,2966},{9,2,5419}, +{0,10,2966},{1,18,257},{1,18,257},{1,18,257},{1,12,261},{0,13,1154},{0,11,337},{0,11,337},{0,7,388},{0,7,1665},{0,6,749},{1,18,1},{1,18,1},{1,18,1},{1,12,5},{4,0,1152},{0,11,337},{0,11,337},{0,7,388},{1,7,1152},{0,7,388},{8,2,1568},{0,23,34},{2,15,5},{0,14,72},{8,2,1568},{13,2,1568},{0,14,72},{0,11,1586},{13,2,1568},{0,11,1586},{1,0,257}, +{1,0,257},{1,0,257},{1,0,257},{0,6,1},{0,6,1},{0,6,1},{0,3,4},{0,2,85},{0,2,85},{1,30,1907},{1,23,411},{1,16,542},{1,15,454},{0,25,5424},{0,18,2630},{0,15,486},{0,11,2771},{0,13,7299},{0,11,3860},{2,26,1634},{1,23,155},{2,16,82},{1,15,198},{5,8,5419},{0,18,2630},{0,15,486},{0,11,2771},{4,10,5419},{0,11,2771},{1,21,338},{1,21,338},{1,21,338}, +{1,13,338},{0,16,1152},{0,13,274},{0,13,274},{0,8,305},{0,8,1856},{0,7,797},{2,17,64},{2,17,64},{2,17,64},{2,12,65},{3,6,1152},{0,13,274},{0,13,274},{0,8,305},{3,6,1152},{0,8,305},{3,23,1568},{0,25,17},{2,16,18},{0,15,45},{3,23,1568},{11,6,1568},{0,15,45},{0,12,1576},{11,6,1568},{0,12,1576},{1,0,337},{1,0,337},{1,0,337},{1,0,337},{0,8,1}, +{0,8,1},{0,8,1},{0,5,0},{0,4,169},{0,4,169},{1,31,2145},{1,25,590},{1,17,915},{1,16,619},{0,27,5420},{0,20,2424},{0,16,282},{0,12,2552},{0,15,7711},{0,11,3908},{2,29,1570},{2,23,149},{2,17,73},{2,16,194},{7,4,5419},{0,20,2424},{0,16,282},{0,12,2552},{9,5,5419},{0,12,2552},{1,23,546},{1,23,546},{1,23,546},{1,15,546},{0,19,1154},{0,15,194},{0,15,194}, +{0,9,218},{0,9,2123},{0,8,865},{2,20,1},{2,20,1},{2,20,1},{2,13,4},{5,2,1152},{0,15,194},{0,15,194},{0,9,218},{8,1,1152},{0,9,218},{9,4,1568},{0,27,5},{3,17,13},{0,16,26},{9,4,1568},{9,10,1568},{0,16,26},{0,13,1576},{9,10,1568},{0,13,1576},{1,0,545},{1,0,545},{1,0,545},{1,0,545},{0,11,0},{0,11,0},{0,11,0},{0,7,4},{0,5,289}, +{0,5,289},{2,31,2746},{1,27,945},{2,18,1370},{1,17,977},{0,30,5420},{0,22,2243},{0,17,145},{0,13,2386},{0,16,8161},{0,13,3986},{3,28,1619},{2,25,155},{3,18,69},{2,17,198},{8,2,5419},{0,22,2243},{0,17,145},{0,13,2386},{13,2,5419},{0,13,2386},{1,26,932},{1,26,932},{1,26,932},{1,16,936},{0,22,1154},{0,17,109},{0,17,109},{0,10,145},{0,11,2441},{0,9,1001},{3,19,50}, +{3,19,50},{3,19,50},{3,14,49},{5,5,1152},{0,17,109},{0,17,109},{0,10,145},{5,7,1152},{0,10,145},{11,0,1568},{0,29,10},{3,18,20},{0,18,8},{11,0,1568},{13,7,1568},{0,18,8},{0,14,1586},{13,7,1568},{0,14,1586},{1,0,932},{1,0,932},{1,0,932},{1,0,932},{0,14,1},{0,14,1},{0,14,1},{0,8,1},{0,6,468},{0,6,468},{2,31,3146},{2,27,1412},{2,19,1743}, +{1,19,1441},{0,31,5515},{0,23,2096},{0,19,69},{0,14,2251},{0,18,8669},{0,14,4100},{3,31,1569},{3,25,131},{3,19,86},{3,18,181},{3,23,5419},{0,23,2096},{0,19,69},{0,14,2251},{11,6,5419},{0,14,2251},{2,25,1379},{2,25,1379},{2,25,1379},{2,17,1379},{0,24,1152},{0,18,61},{0,18,61},{0,11,100},{0,12,2859},{0,10,1157},{3,22,1},{3,22,1},{3,22,1},{3,16,5},{7,1,1152}, +{0,18,61},{0,18,61},{0,11,100},{10,2,1152},{0,11,100},{10,6,1568},{1,29,2},{4,19,5},{0,19,5},{10,6,1568},{15,6,1568},{0,19,5},{0,15,1586},{15,6,1568},{0,15,1586},{2,0,1378},{2,0,1378},{2,0,1378},{2,0,1378},{0,16,1},{0,16,1},{0,16,1},{0,10,1},{0,8,657},{0,8,657},{2,31,3802},{2,29,1603},{2,21,2148},{2,19,1631},{1,31,5655},{0,25,2005},{0,20,31}, +{0,15,2138},{0,19,8963},{0,15,4070},{4,30,1634},{3,27,155},{4,20,82},{3,19,198},{9,4,5419},{0,25,2001},{0,20,27},{0,15,2134},{9,10,5419},{0,15,2134},{2,28,1587},{2,28,1587},{2,28,1587},{2,18,1590},{0,27,1158},{0,20,22},{0,20,22},{0,12,62},{0,14,3075},{0,11,1221},{4,21,64},{4,21,64},{4,21,64},{4,16,65},{5,10,1152},{0,20,18},{0,20,18},{0,12,58},{12,1,1152}, +{0,12,58},{12,2,1568},{1,31,10},{4,20,18},{0,20,18},{12,2,1568},{13,10,1568},{0,20,18},{0,16,1576},{13,10,1568},{0,16,1576},{2,0,1586},{2,0,1586},{2,0,1586},{2,0,1586},{0,19,4},{0,19,4},{0,19,4},{0,11,8},{0,9,769},{0,9,769},{3,31,3890},{2,31,1623},{3,21,2180},{2,20,1644},{1,31,5863},{0,27,1989},{1,21,109},{0,17,2117},{0,21,8560},{0,16,3545},{4,31,1640}, +{4,27,149},{4,21,73},{4,20,194},{10,3,5419},{0,27,1889},{0,21,49},{0,17,2017},{11,9,5419},{0,17,2017},{2,30,1619},{2,30,1619},{2,30,1619},{2,20,1619},{1,26,1188},{1,20,86},{1,20,86},{1,13,121},{0,16,2801},{0,13,949},{4,24,1},{4,24,1},{4,24,1},{4,17,4},{8,1,1152},{0,22,2},{0,22,2},{0,14,26},{10,5,1152},{0,14,26},{11,8,1568},{2,31,5},{5,21,13}, +{1,21,9},{11,8,1568},{11,14,1568},{1,21,9},{0,17,1576},{11,14,1568},{0,17,1576},{2,0,1618},{2,0,1618},{2,0,1618},{2,0,1618},{1,18,37},{1,18,37},{1,18,37},{1,12,37},{0,10,625},{0,10,625},{4,31,4308},{3,31,1589},{3,23,2160},{3,21,1621},{2,31,5895},{1,27,1999},{1,22,33},{1,18,2124},{0,23,8196},{0,17,3043},{5,31,1667},{4,29,155},{5,22,69},{4,21,198},{10,6,5419}, +{0,29,1772},{1,22,24},{0,18,1875},{15,6,5419},{0,18,1875},{3,30,1576},{3,30,1576},{3,30,1576},{3,20,1580},{1,29,1161},{1,22,29},{1,22,29},{1,15,58},{0,17,2529},{0,14,656},{5,23,50},{5,23,50},{5,23,50},{5,18,49},{8,4,1152},{0,24,1},{0,24,1},{0,15,1},{14,2,1152},{0,15,1},{13,4,1568},{3,31,13},{5,22,20},{2,22,8},{13,4,1568},{15,11,1568},{2,22,8}, +{0,18,1586},{15,11,1568},{0,18,1586},{3,0,1576},{3,0,1576},{3,0,1576},{3,0,1576},{1,21,10},{1,21,10},{1,21,10},{1,14,13},{0,12,520},{0,12,520},{4,31,4436},{3,31,1765},{4,23,2175},{3,23,1669},{3,31,6079},{1,29,1977},{2,23,105},{1,19,2107},{0,24,7969},{0,18,2675},{6,31,1832},{5,29,131},{5,23,86},{5,22,181},{12,2,5419},{0,30,1699},{1,23,62},{0,19,1782},{13,10,5419}, +{0,19,1782},{3,31,1665},{3,31,1665},{3,31,1665},{3,22,1640},{2,28,1188},{2,22,97},{2,22,97},{2,15,136},{0,19,2313},{0,15,474},{5,26,1},{5,26,1},{5,26,1},{5,20,5},{3,25,1152},{1,24,5},{1,24,5},{0,16,2},{12,6,1152},{0,16,2},{15,0,1568},{4,31,34},{6,23,5},{2,23,5},{15,0,1568},{12,16,1568},{2,23,5},{0,19,1586},{12,16,1568},{0,19,1586},{3,0,1640}, +{3,0,1640},{3,0,1640},{3,0,1640},{2,20,37},{2,20,37},{2,20,37},{2,14,37},{0,14,400},{0,14,400},{5,31,4740},{4,31,1716},{4,25,2148},{4,23,1631},{3,31,6351},{2,29,2005},{2,24,31},{2,19,2138},{0,26,7669},{0,19,2375},{6,31,1832},{5,31,155},{6,24,82},{5,23,198},{11,8,5419},{0,31,1712},{2,24,27},{0,20,1720},{11,14,5419},{0,20,1720},{4,31,1595},{4,31,1595},{4,31,1595}, +{4,22,1590},{2,31,1158},{2,24,22},{2,24,22},{2,16,62},{0,21,2091},{0,17,306},{6,25,64},{6,25,64},{6,25,64},{6,20,65},{9,6,1152},{1,26,1},{1,26,1},{1,17,5},{14,5,1152},{1,17,5},{14,6,1568},{5,31,74},{6,24,18},{2,24,18},{14,6,1568},{15,14,1568},{2,24,18},{0,20,1576},{15,14,1568},{0,20,1576},{4,0,1586},{4,0,1586},{4,0,1586},{4,0,1586},{2,23,4}, +{2,23,4},{2,23,4},{2,15,8},{0,16,277},{0,16,277},{5,31,5060},{5,31,1980},{5,25,2180},{4,24,1644},{4,31,6508},{2,31,1989},{3,25,109},{2,21,2117},{0,28,7364},{0,21,2098},{7,31,1952},{6,31,149},{6,25,73},{6,24,194},{12,7,5419},{1,31,1804},{2,25,49},{0,21,1657},{13,13,5419},{0,21,1657},{4,31,1739},{4,31,1739},{4,31,1739},{4,24,1619},{3,30,1188},{3,24,86},{3,24,86}, +{3,17,121},{0,22,1928},{0,18,194},{6,28,1},{6,28,1},{6,28,1},{6,21,4},{10,5,1152},{2,26,2},{2,26,2},{1,18,2},{12,9,1152},{1,18,2},{13,12,1568},{6,31,149},{7,25,13},{3,25,9},{13,12,1568},{13,18,1568},{3,25,9},{0,21,1576},{13,18,1568},{0,21,1576},{4,0,1618},{4,0,1618},{4,0,1618},{4,0,1618},{3,22,37},{3,22,37},{3,22,37},{3,16,37},{0,18,193}, +{0,18,193},{6,31,5316},{5,31,2160},{5,27,2160},{5,25,1621},{5,31,6800},{3,31,1999},{3,26,33},{3,22,2124},{0,29,7068},{0,22,1836},{7,31,2195},{7,31,270},{7,26,69},{6,25,198},{15,0,5419},{2,31,1970},{3,26,24},{0,22,1611},{12,16,5419},{0,22,1611},{5,31,1676},{5,31,1676},{5,31,1676},{5,24,1580},{3,31,1233},{3,26,29},{3,26,29},{3,19,58},{0,24,1798},{0,19,157},{7,27,50}, +{7,27,50},{7,27,50},{7,22,49},{10,8,1152},{2,28,1},{2,28,1},{2,19,1},{11,12,1152},{2,19,1},{15,8,1568},{7,31,221},{7,26,20},{4,26,8},{15,8,1568},{11,22,1568},{4,26,8},{0,22,1586},{11,22,1568},{0,22,1586},{5,0,1576},{5,0,1576},{5,0,1576},{5,0,1576},{3,25,10},{3,25,10},{3,25,10},{3,18,13},{0,20,106},{0,20,106},{6,31,5828},{6,31,2435},{6,27,2175}, +{5,27,1669},{5,31,7184},{4,31,2132},{4,27,105},{3,23,2107},{0,31,6820},{0,23,1690},{8,31,2306},{7,31,334},{7,27,86},{7,26,181},{14,6,5419},{4,31,2096},{3,27,62},{0,23,1590},{15,14,5419},{0,23,1590},{6,31,1859},{6,31,1859},{6,31,1859},{5,26,1640},{4,31,1220},{4,26,97},{4,26,97},{4,19,136},{0,26,1650},{0,21,161},{7,30,1},{7,30,1},{7,30,1},{7,24,5},{9,14,1152}, +{3,28,5},{3,28,5},{2,20,2},{14,10,1152},{2,20,2},{14,14,1568},{7,31,333},{8,27,40},{4,27,5},{14,14,1568},{14,20,1568},{4,27,5},{0,23,1586},{14,20,1568},{0,23,1586},{5,0,1640},{5,0,1640},{5,0,1640},{5,0,1640},{4,24,37},{4,24,37},{4,24,37},{4,18,37},{0,22,58},{0,22,58},{7,31,6036},{6,31,2835},{6,29,2148},{6,27,1631},{6,31,7316},{4,31,2228},{4,28,31}, +{4,23,2138},{0,31,6884},{0,24,1613},{8,31,2402},{8,31,666},{8,28,269},{7,27,198},{13,12,5419},{4,31,2224},{4,28,27},{0,24,1577},{13,18,5419},{0,24,1577},{6,31,1811},{6,31,1811},{6,31,1811},{6,26,1590},{5,31,1356},{4,28,22},{4,28,22},{4,20,62},{0,28,1508},{1,21,137},{7,31,106},{7,31,106},{7,31,106},{7,25,82},{11,10,1152},{3,30,1},{3,30,1},{3,21,5},{5,23,1152}, +{3,21,5},{13,20,1568},{8,31,410},{8,28,13},{4,28,18},{13,20,1568},{13,23,1570},{4,28,18},{0,24,1576},{13,23,1570},{0,24,1576},{6,0,1586},{6,0,1586},{6,0,1586},{6,0,1586},{4,27,4},{4,27,4},{4,27,4},{4,19,8},{0,24,37},{0,24,37},{7,31,6740},{7,31,3135},{7,29,2180},{6,28,1644},{7,31,7676},{5,31,2448},{5,29,109},{4,25,2117},{1,31,7196},{0,25,1593},{9,31,2594}, +{8,31,698},{8,29,82},{8,28,345},{14,11,5419},{5,31,2412},{4,29,49},{1,25,1580},{15,17,5419},{1,25,1580},{7,31,1979},{7,31,1979},{7,31,1979},{6,28,1619},{5,31,1388},{5,28,86},{5,28,86},{5,21,121},{0,30,1416},{1,23,161},{8,30,64},{8,30,64},{8,30,64},{8,25,65},{12,9,1152},{4,30,2},{4,30,2},{3,22,2},{14,13,1152},{3,22,2},{15,16,1568},{9,31,530},{8,29,18}, +{5,29,9},{15,16,1568},{15,22,1568},{5,29,9},{0,25,1576},{15,22,1568},{0,25,1576},{6,0,1618},{6,0,1618},{6,0,1618},{6,0,1618},{5,26,37},{5,26,37},{5,26,37},{5,20,37},{0,25,17},{0,25,17},{8,31,6906},{7,31,3909},{7,31,2160},{7,29,1621},{7,31,8144},{6,31,2902},{5,30,33},{5,26,2124},{2,31,7661},{1,26,1615},{9,31,2945},{9,31,1025},{8,30,86},{8,29,181},{14,14,5419}, +{7,31,2694},{5,30,24},{1,26,1590},{14,20,5419},{1,26,1590},{7,31,2060},{7,31,2060},{7,31,2060},{7,28,1580},{6,31,1476},{5,30,29},{5,30,29},{5,23,58},{0,31,1324},{2,23,157},{8,31,37},{8,31,37},{8,31,37},{8,27,5},{15,2,1152},{5,30,20},{5,30,20},{4,23,1},{13,16,1152},{4,23,1},{15,19,1568},{10,31,637},{9,30,5},{6,30,8},{15,19,1568},{13,26,1568},{6,30,8}, +{0,26,1586},{13,26,1568},{0,26,1586},{7,0,1576},{7,0,1576},{7,0,1576},{7,0,1576},{5,29,10},{5,29,10},{5,29,10},{5,22,13},{0,28,10},{0,28,10},{8,31,7386},{8,31,4250},{8,31,2490},{7,31,1669},{8,31,8461},{6,31,3350},{6,31,105},{5,27,2107},{4,31,8004},{1,27,1611},{10,31,3112},{9,31,1361},{9,31,69},{8,30,198},{13,20,5419},{7,31,2950},{5,31,62},{2,27,1590},{11,25,5420}, +{2,27,1590},{8,31,2486},{8,31,2486},{8,31,2486},{7,30,1640},{6,31,1700},{6,30,97},{6,30,97},{6,23,136},{1,31,1424},{2,25,161},{9,31,65},{9,31,65},{9,31,65},{9,27,49},{11,18,1152},{5,31,58},{5,31,58},{4,24,2},{10,21,1152},{4,24,2},{13,28,1568},{11,31,785},{9,31,20},{6,31,5},{13,28,1568},{11,30,1568},{6,31,5},{0,27,1586},{11,30,1568},{0,27,1586},{7,0,1640}, +{7,0,1640},{7,0,1640},{7,0,1640},{6,28,37},{6,28,37},{6,28,37},{6,22,37},{1,28,10},{1,28,10},{9,31,7014},{8,31,4230},{8,31,2294},{8,31,1846},{8,31,7865},{7,31,3114},{6,31,85},{6,27,1706},{4,31,7436},{2,28,1289},{11,31,2852},{10,31,1221},{9,31,145},{9,30,114},{13,22,4803},{8,31,2648},{6,31,81},{2,28,1253},{12,25,4803},{2,28,1253},{8,31,2294},{8,31,2294},{8,31,2294}, +{8,30,1811},{7,31,1740},{6,31,85},{6,31,85},{6,24,62},{2,31,1577},{3,25,137},{9,31,145},{9,31,145},{9,31,145},{9,29,5},{13,14,1152},{6,31,81},{6,31,81},{5,25,5},{8,25,1152},{5,25,5},{15,23,1250},{11,31,689},{10,31,4},{7,31,9},{15,23,1250},{11,31,1250},{7,31,9},{0,28,1252},{11,31,1250},{0,28,1252},{8,0,1810},{8,0,1810},{8,0,1810},{8,0,1810},{6,31,4}, +{6,31,4},{6,31,4},{6,23,8},{1,29,8},{1,29,8},{9,31,6534},{9,31,4134},{8,31,2486},{8,31,1590},{9,31,7237},{7,31,2970},{7,31,161},{6,28,1256},{5,31,6748},{2,29,949},{11,31,2340},{10,31,1125},{10,31,164},{9,31,97},{15,17,4056},{9,31,2244},{7,31,125},{3,28,909},{12,26,4056},{3,28,909},{8,31,2486},{8,31,2486},{8,31,2486},{8,31,1590},{7,31,2156},{7,31,161},{7,31,161}, +{7,25,121},{3,31,1729},{3,27,161},{10,31,164},{10,31,164},{10,31,164},{10,29,65},{14,13,1152},{7,31,125},{7,31,125},{5,26,2},{11,23,1152},{5,26,2},{13,31,882},{12,31,482},{11,31,0},{8,31,4},{13,31,882},{15,27,882},{8,31,4},{0,28,900},{15,27,882},{0,28,900},{8,0,1586},{8,0,1586},{8,0,1586},{8,0,1586},{7,30,37},{7,30,37},{7,30,37},{7,24,37},{1,31,16}, +{1,31,16},{10,31,6091},{9,31,4053},{9,31,2609},{8,31,1761},{9,31,6490},{8,31,2622},{7,31,458},{7,28,835},{6,31,6162},{3,29,598},{12,31,1989},{11,31,931},{11,31,306},{10,31,5},{15,19,3318},{10,31,1806},{8,31,202},{4,29,545},{13,26,3318},{4,29,545},{9,31,2609},{9,31,2609},{9,31,2609},{8,31,1761},{8,31,2086},{7,31,458},{7,31,458},{7,27,58},{4,31,1868},{4,27,157},{11,31,306}, +{11,31,306},{11,31,306},{10,31,5},{14,16,1152},{8,31,202},{8,31,202},{6,27,1},{15,20,1152},{6,27,1},{15,26,545},{13,31,313},{12,31,4},{10,31,4},{15,26,545},{14,29,545},{10,31,4},{0,29,545},{14,29,545},{0,29,545},{8,0,1640},{8,0,1640},{8,0,1640},{8,0,1640},{7,31,58},{7,31,58},{7,31,58},{7,26,13},{2,31,13},{2,31,13},{10,31,5723},{10,31,3980},{9,31,2945}, +{9,31,1745},{10,31,6083},{8,31,2494},{8,31,558},{7,29,558},{7,31,5674},{4,30,411},{12,31,1573},{11,31,963},{11,31,338},{11,31,49},{13,27,2753},{10,31,1438},{9,31,290},{5,29,341},{13,27,2753},{5,29,341},{9,31,2945},{9,31,2945},{9,31,2945},{9,31,1745},{9,31,2390},{8,31,558},{8,31,558},{7,28,147},{5,31,2064},{4,29,161},{11,31,338},{11,31,338},{11,31,338},{11,31,49},{13,22,1152}, +{9,31,290},{9,31,290},{6,28,2},{12,25,1152},{6,28,2},{15,27,313},{13,31,185},{13,31,16},{11,31,0},{15,27,313},{13,31,313},{11,31,0},{0,29,337},{13,31,313},{0,29,337},{9,0,1576},{9,0,1576},{9,0,1576},{9,0,1576},{8,31,197},{8,31,197},{8,31,197},{7,27,122},{3,31,25},{3,31,25},{11,31,5415},{10,31,3996},{10,31,3035},{10,31,2006},{10,31,5619},{9,31,2378},{8,31,814}, +{8,29,414},{7,31,5338},{5,30,251},{12,31,1413},{12,31,813},{12,31,452},{11,31,65},{13,29,2273},{11,31,1218},{10,31,365},{6,30,146},{14,27,2273},{6,30,146},{10,31,3035},{10,31,3035},{10,31,3035},{10,31,2006},{9,31,2518},{8,31,814},{8,31,814},{8,28,121},{6,31,2329},{5,29,137},{12,31,452},{12,31,452},{12,31,452},{11,31,65},{15,18,1152},{10,31,365},{10,31,365},{7,29,5},{10,29,1152}, +{7,29,5},{15,28,145},{14,31,85},{13,31,16},{12,31,4},{15,28,145},{15,29,149},{12,31,4},{0,30,145},{15,29,149},{0,30,145},{9,0,1640},{9,0,1640},{9,0,1640},{9,0,1640},{8,31,85},{8,31,85},{8,31,85},{8,27,37},{4,31,40},{4,31,40},{11,31,5143},{11,31,4004},{11,31,3379},{10,31,2070},{11,31,5287},{10,31,2431},{9,31,1062},{8,30,133},{8,31,5011},{5,31,161},{13,31,1161}, +{13,31,889},{12,31,548},{12,31,164},{15,24,1878},{11,31,1106},{11,31,481},{7,30,66},{15,27,1881},{7,30,66},{11,31,3379},{11,31,3379},{11,31,3379},{10,31,2070},{10,31,2835},{9,31,1062},{9,31,1062},{8,29,62},{7,31,2577},{5,31,161},{12,31,548},{12,31,548},{12,31,548},{12,31,164},{13,27,1152},{11,31,481},{11,31,481},{7,30,2},{13,27,1152},{7,30,2},{15,29,45},{14,31,37},{14,31,1}, +{14,31,9},{15,29,45},{15,30,41},{14,31,9},{0,30,65},{15,30,41},{0,30,65},{10,0,1586},{10,0,1586},{10,0,1586},{10,0,1586},{9,31,221},{9,31,221},{9,31,221},{8,28,8},{5,31,80},{5,31,80},{12,31,4948},{11,31,4157},{11,31,3532},{11,31,2393},{11,31,5008},{10,31,2422},{10,31,1461},{9,31,125},{9,31,4752},{6,31,157},{13,31,1107},{13,31,835},{13,31,666},{12,31,362},{15,26,1536}, +{12,31,1011},{12,31,650},{8,31,16},{14,29,1536},{8,31,16},{11,31,3532},{11,31,3532},{11,31,3532},{11,31,2393},{10,31,3204},{10,31,1461},{10,31,1461},{9,30,114},{8,31,2976},{6,31,157},{13,31,666},{13,31,666},{13,31,666},{12,31,362},{13,30,1152},{12,31,650},{12,31,650},{8,31,16},{12,30,1152},{8,31,16},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0}, +{0,31,0},{15,31,0},{0,31,0},{10,0,1640},{10,0,1640},{10,0,1640},{10,0,1640},{9,31,221},{9,31,221},{9,31,221},{9,29,25},{6,31,157},{6,31,157},{12,31,4212},{12,31,3612},{12,31,3251},{11,31,2201},{12,31,4212},{11,31,2154},{10,31,1301},{9,31,13},{10,31,3939},{7,31,233},{14,31,776},{13,31,659},{13,31,490},{13,31,218},{15,27,1067},{13,31,699},{12,31,442},{9,31,4},{13,31,1067}, +{9,31,4},{12,31,3251},{12,31,3251},{12,31,3251},{11,31,2201},{11,31,2668},{10,31,1301},{10,31,1301},{9,31,13},{8,31,2528},{7,31,233},{13,31,490},{13,31,490},{13,31,490},{13,31,218},{15,25,802},{12,31,442},{12,31,442},{9,31,4},{15,27,802},{9,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{11,0,1576}, +{11,0,1576},{11,0,1576},{11,0,1576},{10,31,340},{10,31,340},{10,31,340},{9,31,13},{7,31,233},{7,31,233},{12,31,3732},{12,31,3132},{12,31,2771},{12,31,2171},{12,31,3444},{11,31,1834},{11,31,1209},{10,31,37},{10,31,3219},{8,31,400},{14,31,456},{14,31,392},{14,31,356},{13,31,170},{14,31,684},{13,31,459},{13,31,290},{10,31,1},{14,30,683},{10,31,1},{12,31,2771},{12,31,2771},{12,31,2771}, +{12,31,2171},{11,31,2348},{11,31,1209},{11,31,1209},{10,31,37},{9,31,2156},{8,31,400},{14,31,356},{14,31,356},{14,31,356},{13,31,170},{15,26,512},{13,31,290},{13,31,290},{10,31,1},{14,29,512},{10,31,1},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{11,0,1640},{11,0,1640},{11,0,1640},{11,0,1640},{10,31,436}, +{10,31,436},{10,31,436},{10,31,37},{8,31,400},{8,31,400},{13,31,3172},{13,31,2900},{12,31,2547},{12,31,1947},{12,31,2932},{12,31,1732},{11,31,1145},{10,31,53},{11,31,2695},{8,31,464},{14,31,264},{14,31,200},{14,31,164},{14,31,100},{15,28,387},{14,31,268},{13,31,178},{11,31,1},{15,29,396},{11,31,1},{12,31,2547},{12,31,2547},{12,31,2547},{12,31,1947},{12,31,1971},{11,31,1145},{11,31,1145}, +{10,31,53},{10,31,1794},{8,31,464},{14,31,164},{14,31,164},{14,31,164},{14,31,100},{15,27,290},{13,31,178},{13,31,178},{11,31,1},{14,30,290},{11,31,1},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{12,0,1586},{12,0,1586},{12,0,1586},{12,0,1586},{11,31,520},{11,31,520},{11,31,520},{10,31,53},{8,31,464}, +{8,31,464},{0,23,2665},{0,18,680},{0,13,50},{0,11,785},{0,15,5885},{0,11,4118},{0,10,1800},{0,7,4202},{0,8,6546},{0,7,4643},{0,23,2665},{0,18,680},{0,13,50},{0,11,785},{3,5,5885},{0,11,4118},{0,10,1800},{0,7,4202},{0,9,5885},{0,7,4202},{0,11,0},{0,11,0},{0,11,0},{0,7,4},{0,5,549},{0,5,289},{0,5,289},{0,3,306},{0,3,630},{0,3,387},{0,11,0}, +{0,11,0},{0,11,0},{0,7,4},{1,2,545},{0,5,289},{0,5,289},{0,3,306},{2,1,545},{0,3,306},{6,3,2665},{0,18,680},{0,13,50},{0,11,785},{6,3,2665},{11,0,2665},{0,11,785},{0,8,2689},{11,0,2665},{0,8,2689},{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,25,2665},{0,20,521},{0,14,5}, +{0,12,625},{0,17,6669},{0,13,4529},{0,11,1890},{0,8,4610},{0,9,7494},{0,7,5171},{0,25,2665},{0,20,521},{0,14,5},{0,12,625},{3,7,6669},{0,13,4529},{0,11,1890},{0,8,4610},{8,0,6669},{0,8,4610},{0,13,1},{0,13,1},{0,13,1},{0,8,0},{0,7,841},{0,6,445},{0,6,445},{0,4,464},{0,3,982},{0,3,595},{0,13,1},{0,13,1},{0,13,1},{0,8,0},{2,0,841}, +{0,6,445},{0,6,445},{0,4,464},{1,3,841},{0,4,464},{7,2,2665},{0,20,521},{0,14,5},{0,12,625},{7,2,2665},{12,0,2665},{0,12,625},{0,9,2689},{12,0,2665},{0,9,2689},{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,28,2665},{0,22,405},{0,15,10},{0,13,514},{0,19,7541},{0,14,4934},{0,12,2042}, +{0,9,5045},{0,10,8546},{0,8,5682},{0,28,2665},{0,22,405},{0,15,10},{0,13,514},{5,2,7538},{0,14,4934},{0,12,2042},{0,9,5045},{8,1,7538},{0,9,5045},{0,16,0},{0,16,0},{0,16,0},{0,10,4},{0,8,1201},{0,7,637},{0,7,637},{0,4,656},{0,4,1385},{0,4,800},{0,16,0},{0,16,0},{0,16,0},{0,10,4},{1,5,1201},{0,7,637},{0,7,637},{0,4,656},{4,0,1201}, +{0,4,656},{6,8,2665},{0,22,405},{0,15,10},{0,13,514},{6,8,2665},{11,3,2665},{0,13,514},{0,10,2689},{11,3,2665},{0,10,2689},{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,30,2669},{0,23,313},{0,16,68},{0,15,410},{0,20,8498},{0,16,5330},{0,13,2210},{0,10,5530},{0,11,9702},{0,9,6270},{0,30,2669}, +{0,23,313},{0,16,68},{0,15,410},{4,7,8493},{0,16,5330},{0,13,2210},{0,10,5530},{8,2,8493},{0,10,5530},{0,19,1},{0,19,1},{0,19,1},{0,11,1},{0,9,1629},{0,8,832},{0,8,832},{0,5,881},{0,5,1874},{0,5,1106},{0,19,1},{0,19,1},{0,19,1},{0,11,1},{2,3,1625},{0,8,832},{0,8,832},{0,5,881},{4,1,1625},{0,5,881},{8,2,2665},{0,23,313},{1,16,8}, +{0,15,410},{8,2,2665},{14,1,2665},{0,15,410},{0,11,2689},{14,1,2665},{0,11,2689},{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,31,2777},{0,26,232},{0,17,197},{0,16,305},{0,22,9674},{0,17,5849},{0,14,2450},{0,10,6106},{0,12,11199},{0,10,7006},{0,31,2777},{0,26,232},{0,17,197},{0,16,305},{1,19,9669}, +{0,17,5849},{0,14,2450},{0,10,6106},{9,2,9669},{0,10,6106},{0,22,1},{0,22,1},{0,22,1},{0,13,0},{0,11,2178},{0,10,1125},{0,10,1125},{0,6,1189},{0,6,2520},{0,5,1475},{0,22,1},{0,22,1},{0,22,1},{0,13,0},{3,1,2178},{0,10,1125},{0,10,1125},{0,6,1189},{3,3,2178},{0,6,1189},{9,2,2665},{0,26,232},{1,17,17},{0,16,305},{9,2,2665},{13,4,2665},{0,16,305}, +{0,12,2689},{13,4,2665},{0,12,2689},{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},{1,31,3045},{0,28,217},{0,19,401},{0,17,282},{0,25,9670},{0,19,5529},{0,16,1970},{0,12,5738},{0,13,11589},{0,11,6898},{1,31,2789},{0,28,217},{1,18,146},{0,17,282},{5,8,9669},{0,19,5529},{0,16,1970},{0,12,5738},{4,10,9669}, +{0,12,5738},{0,24,64},{0,24,64},{0,24,64},{0,15,68},{0,13,2180},{0,11,949},{0,11,949},{0,7,1018},{0,7,2691},{0,6,1433},{1,21,64},{1,21,64},{1,21,64},{1,13,68},{4,0,2178},{0,11,949},{0,11,949},{0,7,1018},{1,7,2178},{0,7,1018},{10,1,2665},{0,28,153},{2,18,5},{0,17,218},{10,1,2665},{15,3,2665},{0,17,218},{0,13,2689},{15,3,2665},{0,13,2689},{0,0,64}, +{0,0,64},{0,0,64},{0,0,64},{0,3,1},{0,3,1},{0,3,1},{0,2,4},{0,1,18},{0,1,18},{1,31,3285},{0,29,341},{1,19,453},{0,18,405},{0,27,9674},{0,20,5170},{0,17,1546},{0,13,5429},{0,15,11993},{0,12,6819},{2,31,2966},{1,28,221},{1,19,197},{1,18,305},{7,4,9669},{0,20,5170},{0,17,1546},{0,13,5429},{9,5,9669},{0,13,5429},{0,27,257},{0,27,257},{0,27,257}, +{1,15,256},{0,16,2178},{0,13,832},{0,13,832},{0,8,881},{0,8,2882},{0,7,1427},{1,23,4},{1,23,4},{1,23,4},{1,15,0},{3,6,2178},{0,13,832},{0,13,832},{0,8,881},{3,6,2178},{0,8,881},{11,0,2665},{0,29,85},{2,19,10},{0,18,149},{11,0,2665},{13,7,2665},{0,18,149},{0,14,2689},{13,7,2665},{0,14,2689},{0,0,256},{0,0,256},{0,0,256},{0,0,256},{0,5,1}, +{0,5,1},{0,5,1},{0,3,1},{0,2,72},{0,2,72},{1,31,3909},{1,29,465},{1,21,676},{1,19,538},{0,30,9669},{0,22,4878},{0,18,1190},{0,14,5138},{0,16,12390},{0,13,6789},{2,31,2966},{1,29,209},{2,20,149},{1,19,282},{6,10,9669},{0,22,4878},{0,18,1190},{0,14,5138},{12,3,9669},{0,14,5138},{1,26,320},{1,26,320},{1,26,320},{1,16,324},{0,19,2180},{0,15,680},{0,15,680}, +{0,9,740},{0,9,3149},{0,8,1441},{1,26,64},{1,26,64},{1,26,64},{1,16,68},{5,2,2178},{0,15,680},{0,15,680},{0,9,740},{8,1,2178},{0,9,740},{11,3,2665},{0,31,41},{3,20,8},{0,19,98},{11,3,2665},{15,6,2665},{0,19,98},{0,15,2689},{15,6,2665},{0,15,2689},{1,0,320},{1,0,320},{1,0,320},{1,0,320},{0,8,0},{0,8,0},{0,8,0},{0,5,1},{0,4,160}, +{0,4,160},{2,31,4514},{1,31,630},{1,22,1110},{1,20,694},{0,31,9789},{0,23,4646},{0,20,849},{0,15,4826},{0,18,12955},{0,14,6798},{3,31,3101},{2,30,232},{2,21,197},{2,20,305},{3,23,9669},{0,23,4646},{0,20,849},{0,15,4826},{11,6,9669},{0,15,4826},{1,29,545},{1,29,545},{1,29,545},{1,18,546},{0,22,2180},{0,17,505},{0,17,505},{0,11,610},{0,11,3467},{0,10,1513},{2,26,1}, +{2,26,1},{2,26,1},{2,17,0},{5,5,2178},{0,17,505},{0,17,505},{0,11,610},{5,7,2178},{0,11,610},{11,6,2665},{1,31,85},{3,21,17},{0,20,65},{11,6,2665},{15,8,2665},{0,20,65},{0,16,2689},{15,8,2665},{0,16,2689},{1,0,545},{1,0,545},{1,0,545},{1,0,545},{0,11,0},{0,11,0},{0,11,0},{0,7,4},{0,5,289},{0,5,289},{2,31,5330},{1,31,1110},{2,23,1490}, +{1,21,979},{1,31,9981},{0,26,4406},{0,21,579},{0,16,4610},{0,19,13489},{0,15,6846},{3,31,3341},{2,31,226},{3,22,146},{2,21,282},{9,4,9669},{0,26,4406},{0,21,579},{0,16,4610},{9,10,9669},{0,16,4610},{1,31,885},{1,31,885},{1,31,885},{1,20,885},{0,24,2178},{0,19,389},{0,19,389},{0,12,464},{0,12,3885},{0,11,1603},{3,25,64},{3,25,64},{3,25,64},{3,17,68},{7,1,2178}, +{0,19,389},{0,19,389},{0,12,464},{10,2,2178},{0,12,464},{13,2,2665},{2,31,162},{4,22,5},{0,22,37},{13,2,2665},{12,13,2665},{0,22,37},{0,17,2689},{12,13,2665},{0,17,2689},{1,0,881},{1,0,881},{1,0,881},{1,0,881},{0,13,1},{0,13,1},{0,13,1},{0,8,0},{0,6,445},{0,6,445},{3,31,6366},{2,31,1635},{2,24,1886},{1,22,1410},{1,31,10381},{0,28,4146},{0,22,377}, +{0,17,4373},{0,20,14006},{0,16,6915},{4,31,3434},{3,31,242},{3,23,197},{3,22,305},{10,3,9669},{0,28,4146},{0,22,377},{0,17,4373},{11,9,9669},{0,17,4373},{2,31,1346},{2,31,1346},{2,31,1346},{2,20,1345},{0,27,2180},{0,21,274},{0,21,274},{0,13,353},{0,14,4269},{0,11,1763},{3,27,4},{3,27,4},{3,27,4},{3,19,0},{5,10,2178},{0,21,274},{0,21,274},{0,13,353},{12,1,2178}, +{0,13,353},{14,1,2665},{3,31,242},{4,23,10},{0,23,10},{14,1,2665},{15,11,2665},{0,23,10},{0,18,2689},{15,11,2665},{0,18,2689},{1,0,1345},{1,0,1345},{1,0,1345},{1,0,1345},{0,16,0},{0,16,0},{0,16,0},{0,10,4},{0,7,637},{0,7,637},{3,31,7374},{2,31,2339},{2,25,2441},{2,23,1763},{2,31,11019},{0,29,3909},{0,23,243},{0,18,4154},{0,22,14614},{0,17,7029},{5,31,3654}, +{4,31,394},{4,24,149},{3,23,282},{9,9,9669},{0,29,3909},{0,23,243},{0,18,4154},{14,7,9669},{0,18,4154},{2,31,1714},{2,31,1714},{2,31,1714},{2,22,1669},{0,29,2180},{0,23,194},{0,23,194},{0,14,260},{0,15,4686},{0,13,1937},{3,30,64},{3,30,64},{3,30,64},{3,20,68},{8,1,2178},{0,23,194},{0,23,194},{0,14,260},{10,5,2178},{0,14,260},{15,0,2665},{4,31,313},{5,24,8}, +{0,24,4},{15,0,2665},{13,15,2665},{0,24,4},{0,19,2689},{13,15,2665},{0,19,2689},{2,0,1665},{2,0,1665},{2,0,1665},{2,0,1665},{0,19,1},{0,19,1},{0,19,1},{0,11,1},{0,8,832},{0,8,832},{3,31,8967},{3,31,3510},{3,26,3255},{2,24,2243},{2,31,11766},{0,31,3686},{0,25,138},{0,19,3938},{0,23,15369},{0,18,7206},{5,31,3933},{4,31,457},{4,25,197},{4,24,305},{12,2,9669}, +{0,31,3686},{0,25,138},{0,19,3938},{13,10,9669},{0,19,3938},{2,31,2434},{2,31,2434},{2,31,2434},{2,23,2182},{0,31,2210},{0,25,137},{0,25,137},{0,15,181},{0,16,5157},{0,14,2163},{4,30,1},{4,30,1},{4,30,1},{4,21,0},{8,4,2178},{0,25,137},{0,25,137},{0,15,181},{14,2,2178},{0,15,181},{15,3,2665},{5,31,421},{5,25,17},{1,25,5},{15,3,2665},{12,18,2665},{1,25,5}, +{0,20,2689},{12,18,2665},{0,20,2689},{2,0,2178},{2,0,2178},{2,0,2178},{2,0,2178},{0,22,1},{0,22,1},{0,22,1},{0,13,0},{0,10,1125},{0,10,1125},{4,31,10234},{3,31,4421},{3,27,3739},{2,26,2742},{2,31,12773},{0,31,3719},{0,26,87},{0,20,3771},{0,25,16061},{0,19,7283},{6,31,4050},{5,31,629},{5,26,146},{4,25,282},{11,8,9669},{0,31,3718},{0,26,86},{0,20,3770},{11,14,9669}, +{0,20,3770},{3,31,3125},{3,31,3125},{3,31,3125},{2,25,2706},{1,31,2411},{0,26,86},{0,26,86},{0,16,129},{0,18,5544},{0,15,2318},{5,29,64},{5,29,64},{5,29,64},{5,21,68},{3,25,2178},{0,26,85},{0,26,85},{0,16,128},{12,6,2178},{0,16,128},{15,6,2665},{5,31,565},{6,26,5},{1,26,2},{15,6,2665},{14,17,2665},{1,26,2},{0,21,2689},{14,17,2665},{0,21,2689},{2,0,2705}, +{2,0,2705},{2,0,2705},{2,0,2705},{0,24,1},{0,24,1},{0,24,1},{0,15,5},{0,11,1348},{0,11,1348},{4,31,10874},{4,31,5018},{3,28,3750},{3,26,2754},{3,31,13045},{1,31,4003},{0,27,183},{0,21,3686},{0,27,15601},{0,20,6570},{7,31,4366},{5,31,965},{5,27,197},{5,26,305},{12,7,9669},{1,31,3954},{0,27,102},{0,21,3605},{13,13,9669},{0,21,3605},{3,31,3173},{3,31,3173},{3,31,3173}, +{3,25,2690},{1,31,2427},{0,28,113},{0,28,113},{0,17,170},{0,20,5170},{0,16,1856},{5,31,4},{5,31,4},{5,31,4},{5,23,0},{9,6,2178},{0,28,32},{0,28,32},{0,17,89},{14,5,2178},{0,17,89},{15,8,2665},{6,31,706},{6,27,10},{2,27,10},{15,8,2665},{12,21,2665},{2,27,10},{0,22,2689},{12,21,2665},{0,22,2689},{3,0,2689},{3,0,2689},{3,0,2689},{3,0,2689},{1,23,53}, +{1,23,53},{1,23,53},{1,15,49},{0,13,1217},{0,13,1217},{5,31,11278},{4,31,5402},{4,29,3753},{3,28,2745},{4,31,13566},{1,31,4403},{1,28,77},{0,22,3747},{0,28,15046},{0,21,5958},{7,31,4590},{6,31,1171},{6,28,149},{5,27,282},{14,3,9669},{2,31,4265},{1,28,76},{0,22,3458},{11,17,9669},{0,22,3458},{4,31,3377},{4,31,3377},{4,31,3377},{3,27,2706},{2,31,2532},{1,28,73},{1,28,73}, +{1,18,129},{0,21,4837},{0,17,1490},{6,31,82},{6,31,82},{6,31,82},{5,24,68},{10,5,2178},{0,30,8},{0,30,8},{0,19,49},{12,9,2178},{0,19,49},{15,11,2665},{7,31,850},{7,28,8},{2,28,4},{15,11,2665},{15,19,2665},{2,28,4},{0,23,2689},{15,19,2665},{0,23,2689},{3,0,2705},{3,0,2705},{3,0,2705},{3,0,2705},{1,26,1},{1,26,1},{1,26,1},{1,16,5},{0,14,1037}, +{0,14,1037},{6,31,11954},{5,31,6090},{4,30,3794},{4,28,2754},{5,31,14170},{2,31,4863},{2,29,187},{1,24,3689},{0,30,14558},{0,23,5274},{8,31,5030},{7,31,1556},{6,29,197},{6,28,305},{14,6,9669},{3,31,4594},{1,29,101},{0,24,3265},{15,14,9669},{0,24,3265},{4,31,3530},{4,31,3530},{4,31,3530},{4,27,2693},{2,31,2739},{1,30,134},{1,30,134},{1,19,197},{0,23,4506},{0,19,1109},{6,31,64}, +{6,31,64},{6,31,64},{6,25,0},{10,8,2178},{1,30,34},{1,30,34},{0,20,16},{11,12,2178},{0,20,16},{15,14,2665},{8,31,1053},{7,29,17},{3,29,5},{15,14,2665},{14,22,2665},{3,29,5},{0,24,2689},{14,22,2665},{0,24,2689},{4,0,2689},{4,0,2689},{4,0,2689},{4,0,2689},{2,26,50},{2,26,50},{2,26,50},{2,17,49},{0,16,818},{0,16,818},{6,31,12466},{5,31,6794},{5,31,3739}, +{4,30,2742},{5,31,14554},{3,31,5363},{2,30,87},{1,24,3737},{0,31,14190},{0,24,4785},{8,31,5158},{7,31,2036},{7,30,146},{6,29,282},{13,12,9669},{4,31,4806},{2,30,86},{0,25,3130},{13,18,9669},{0,25,3130},{5,31,3658},{5,31,3658},{5,31,3658},{4,29,2706},{3,31,2795},{2,30,86},{2,30,86},{2,20,129},{0,25,4315},{0,20,809},{7,31,100},{7,31,100},{7,31,100},{7,25,68},{9,14,2178}, +{1,31,68},{1,31,68},{0,21,1},{14,10,2178},{0,21,1},{13,23,2665},{9,31,1241},{8,30,50},{3,30,2},{13,23,2665},{11,27,2665},{3,30,2},{0,25,2689},{11,27,2665},{0,25,2689},{4,0,2705},{4,0,2705},{4,0,2705},{4,0,2705},{2,28,1},{2,28,1},{2,28,1},{2,19,5},{0,18,666},{0,18,666},{7,31,13094},{6,31,7445},{5,31,3915},{5,30,2754},{6,31,14998},{4,31,5926},{2,31,183}, +{2,25,3686},{0,31,14254},{0,25,4323},{9,31,5546},{8,31,2478},{7,31,197},{7,30,305},{14,11,9669},{5,31,5138},{2,31,102},{0,26,3013},{15,17,9669},{0,26,3013},{5,31,3914},{5,31,3914},{5,31,3914},{5,29,2690},{4,31,3042},{2,31,182},{2,31,182},{2,21,170},{0,27,4059},{0,21,597},{7,31,196},{7,31,196},{7,31,196},{7,27,0},{11,10,2178},{2,31,101},{2,31,101},{0,22,4},{5,23,2178}, +{0,22,4},{15,19,2665},{10,31,1384},{8,31,5},{4,31,10},{15,19,2665},{14,25,2665},{4,31,10},{0,26,2689},{14,25,2665},{0,26,2689},{5,0,2689},{5,0,2689},{5,0,2689},{5,0,2689},{3,27,53},{3,27,53},{3,27,53},{3,19,49},{0,20,505},{0,20,505},{7,31,12517},{6,31,7482},{6,31,4001},{5,31,2706},{6,31,14185},{4,31,5491},{3,31,154},{2,26,3124},{0,31,13437},{0,26,3306},{9,31,4949}, +{8,31,2261},{8,31,325},{7,30,192},{14,13,8712},{6,31,4686},{3,31,153},{0,27,2403},{11,23,8712},{0,27,2403},{6,31,4001},{6,31,4001},{6,31,4001},{5,31,2706},{4,31,3234},{3,31,154},{3,31,154},{3,22,129},{0,28,3762},{0,23,425},{8,31,325},{8,31,325},{8,31,325},{7,28,68},{12,9,2178},{3,31,153},{3,31,153},{1,23,1},{14,13,2178},{1,23,1},{13,27,2178},{10,31,1157},{9,31,16}, +{5,31,1},{13,27,2178},{13,27,2178},{5,31,1},{0,27,2178},{13,27,2178},{0,27,2178},{5,0,2705},{5,0,2705},{5,0,2705},{5,0,2705},{3,30,1},{3,30,1},{3,30,1},{3,20,5},{0,22,389},{0,22,389},{8,31,12034},{7,31,7195},{6,31,4370},{6,31,2693},{7,31,13066},{5,31,5014},{4,31,261},{3,27,2390},{1,31,12394},{0,27,2277},{10,31,4410},{9,31,2045},{8,31,289},{8,30,192},{14,15,7578}, +{7,31,4050},{4,31,212},{0,27,1701},{12,23,7578},{0,27,1701},{6,31,4370},{6,31,4370},{6,31,4370},{6,31,2693},{5,31,3429},{4,31,261},{4,31,261},{3,23,197},{0,30,3509},{0,24,306},{8,31,289},{8,31,289},{8,31,289},{8,28,68},{15,2,2178},{4,31,212},{4,31,212},{1,24,9},{13,16,2178},{1,24,9},{15,22,1625},{11,31,850},{9,31,25},{6,31,4},{15,22,1625},{13,28,1625},{6,31,4}, +{0,27,1665},{13,28,1625},{0,27,1665},{6,0,2689},{6,0,2689},{6,0,2689},{6,0,2689},{4,30,50},{4,30,50},{4,30,50},{4,21,49},{0,24,306},{0,24,306},{8,31,11042},{7,31,7259},{7,31,4450},{6,31,2805},{7,31,12298},{5,31,4742},{4,31,501},{4,27,1875},{2,31,11643},{0,28,1578},{10,31,3802},{9,31,1869},{9,31,425},{8,31,25},{13,20,6661},{7,31,3554},{5,31,292},{0,28,1217},{13,23,6662}, +{0,28,1217},{7,31,4450},{7,31,4450},{7,31,4450},{6,31,2805},{6,31,3714},{4,31,501},{4,31,501},{4,24,129},{0,31,3354},{0,25,244},{9,31,425},{9,31,425},{9,31,425},{8,30,0},{11,18,2178},{5,31,292},{5,31,292},{2,25,1},{10,21,2178},{2,25,1},{15,23,1201},{11,31,674},{10,31,9},{7,31,16},{15,23,1201},{12,30,1201},{7,31,16},{0,28,1201},{12,30,1201},{0,28,1201},{6,0,2705}, +{6,0,2705},{6,0,2705},{6,0,2705},{4,31,17},{4,31,17},{4,31,17},{4,23,5},{0,26,218},{0,26,218},{8,31,10434},{8,31,7186},{7,31,4898},{7,31,2833},{8,31,11595},{6,31,4462},{5,31,629},{4,28,1387},{3,31,10895},{0,28,1002},{11,31,3446},{10,31,1707},{9,31,505},{8,31,73},{13,22,5829},{8,31,3170},{6,31,405},{1,28,869},{12,25,5829},{1,28,869},{7,31,4898},{7,31,4898},{7,31,4898}, +{7,31,2833},{6,31,3906},{5,31,629},{5,31,629},{4,25,170},{0,31,3546},{0,27,228},{9,31,505},{9,31,505},{9,31,505},{9,30,68},{13,14,2178},{6,31,405},{6,31,405},{2,26,4},{8,25,2178},{2,26,4},{13,31,841},{12,31,461},{11,31,1},{8,31,9},{13,31,841},{15,27,841},{8,31,9},{0,28,865},{15,27,841},{0,28,865},{7,0,2689},{7,0,2689},{7,0,2689},{7,0,2689},{5,31,53}, +{5,31,53},{5,31,53},{5,23,49},{0,28,137},{0,28,137},{9,31,10014},{8,31,6962},{8,31,5026},{7,31,3105},{8,31,10683},{7,31,4354},{6,31,933},{5,28,1019},{4,31,10078},{0,29,630},{11,31,2934},{10,31,1611},{10,31,650},{9,31,25},{15,17,5082},{8,31,2786},{7,31,521},{1,29,546},{12,26,5082},{1,29,546},{8,31,5026},{8,31,5026},{8,31,5026},{7,31,3105},{7,31,4170},{6,31,933},{6,31,933}, +{5,26,129},{1,31,3814},{0,28,234},{10,31,650},{10,31,650},{10,31,650},{9,31,25},{14,13,2178},{7,31,521},{7,31,521},{3,27,1},{11,23,2178},{3,27,1},{15,26,545},{13,31,313},{12,31,4},{10,31,4},{15,26,545},{14,29,545},{10,31,4},{0,29,545},{14,29,545},{0,29,545},{7,0,2705},{7,0,2705},{7,0,2705},{7,0,2705},{5,31,101},{5,31,101},{5,31,101},{5,24,5},{0,29,85}, +{0,29,85},{9,31,9465},{9,31,7065},{8,31,5233},{8,31,3329},{8,31,10116},{7,31,4183},{6,31,1338},{5,29,645},{5,31,9447},{0,30,441},{11,31,2664},{11,31,1525},{10,31,848},{10,31,113},{15,19,4344},{9,31,2424},{8,31,724},{2,30,321},{13,26,4344},{2,30,321},{8,31,5233},{8,31,5233},{8,31,5233},{8,31,3329},{7,31,4629},{6,31,1338},{6,31,1338},{5,27,197},{2,31,4212},{1,29,213},{10,31,848}, +{10,31,848},{10,31,848},{10,31,113},{14,16,2178},{8,31,724},{8,31,724},{3,28,9},{15,20,2178},{3,28,9},{15,27,290},{13,31,178},{13,31,9},{11,31,1},{15,27,290},{14,30,290},{11,31,1},{0,29,320},{14,30,290},{0,29,320},{8,0,2929},{8,0,2929},{8,0,2929},{8,0,2929},{6,31,113},{6,31,113},{6,31,113},{6,25,49},{0,31,45},{0,31,45},{10,31,9329},{9,31,6985},{9,31,5541}, +{8,31,3473},{9,31,9496},{8,31,4420},{7,31,1630},{6,29,426},{5,31,9031},{1,30,301},{12,31,2275},{11,31,1557},{11,31,932},{10,31,225},{13,27,3779},{10,31,2086},{8,31,884},{3,30,129},{13,27,3779},{3,30,129},{9,31,5541},{9,31,5541},{9,31,5541},{8,31,3473},{8,31,4836},{7,31,1630},{7,31,1630},{6,28,129},{4,31,4442},{1,30,237},{11,31,932},{11,31,932},{11,31,932},{10,31,225},{13,22,2178}, +{8,31,884},{8,31,884},{4,29,1},{12,25,2178},{4,29,1},{15,28,130},{14,31,72},{13,31,25},{12,31,9},{15,28,130},{15,29,136},{12,31,9},{0,30,128},{15,29,136},{0,30,128},{8,0,2689},{8,0,2689},{8,0,2689},{8,0,2689},{6,31,257},{6,31,257},{6,31,257},{6,27,5},{1,31,89},{1,31,89},{10,31,8929},{10,31,7186},{9,31,5845},{9,31,3829},{9,31,9208},{8,31,4260},{7,31,2270}, +{6,30,245},{6,31,8708},{2,31,228},{12,31,2115},{12,31,1515},{12,31,1154},{11,31,353},{13,29,3299},{11,31,1938},{10,31,1013},{4,30,68},{14,27,3299},{4,30,68},{9,31,5845},{9,31,5845},{9,31,5845},{9,31,3829},{8,31,5124},{7,31,2270},{7,31,2270},{6,29,170},{4,31,4762},{2,31,228},{12,31,1154},{12,31,1154},{12,31,1154},{11,31,353},{15,18,2178},{10,31,1013},{10,31,1013},{4,30,4},{10,29,2178}, +{4,30,4},{15,30,34},{14,31,40},{14,31,4},{14,31,4},{15,30,34},{15,30,34},{14,31,4},{0,30,64},{15,30,34},{0,30,64},{8,0,2705},{8,0,2705},{8,0,2705},{8,0,2705},{7,31,245},{7,31,245},{7,31,245},{7,27,49},{2,31,164},{2,31,164},{11,31,8857},{10,31,7170},{10,31,6209},{9,31,4133},{10,31,8853},{8,31,4484},{8,31,2548},{7,31,170},{7,31,8388},{3,31,244},{13,31,1971}, +{12,31,1611},{12,31,1250},{11,31,625},{15,24,2904},{11,31,1826},{10,31,1157},{5,31,1},{15,27,2907},{5,31,1},{10,31,6209},{10,31,6209},{10,31,6209},{9,31,4133},{9,31,5460},{8,31,2548},{8,31,2548},{7,30,129},{5,31,5126},{3,31,244},{12,31,1250},{12,31,1250},{12,31,1250},{11,31,625},{13,27,2178},{10,31,1157},{10,31,1157},{5,31,1},{13,27,2178},{5,31,1},{15,31,0},{15,31,0},{15,31,0}, +{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{9,0,2689},{9,0,2689},{9,0,2689},{9,0,2689},{7,31,485},{7,31,485},{7,31,485},{7,28,5},{3,31,244},{3,31,244},{11,31,7705},{11,31,6566},{10,31,5633},{10,31,3890},{10,31,7737},{9,31,3874},{8,31,2386},{7,31,116},{7,31,7398},{4,31,317},{13,31,1458},{13,31,1186},{13,31,1017},{12,31,425},{15,25,2166}, +{12,31,1398},{11,31,850},{6,31,4},{12,31,2166},{6,31,4},{10,31,5633},{10,31,5633},{10,31,5633},{10,31,3890},{9,31,4830},{8,31,2386},{8,31,2386},{7,31,116},{6,31,4509},{4,31,317},{13,31,1017},{13,31,1017},{13,31,1017},{12,31,425},{15,22,1625},{11,31,850},{11,31,850},{6,31,4},{13,28,1625},{6,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0}, +{0,31,0},{15,31,0},{0,31,0},{9,0,2725},{9,0,2725},{9,0,2725},{9,0,2725},{8,31,450},{8,31,450},{8,31,450},{7,30,101},{4,31,317},{4,31,317},{11,31,6953},{11,31,5814},{11,31,5189},{10,31,3650},{11,31,6713},{10,31,3531},{9,31,2142},{8,31,74},{8,31,6397},{5,31,425},{13,31,1138},{13,31,866},{13,31,697},{12,31,361},{15,26,1601},{12,31,1046},{11,31,674},{7,31,16},{14,29,1601}, +{7,31,16},{11,31,5189},{11,31,5189},{11,31,5189},{10,31,3650},{10,31,4313},{9,31,2142},{9,31,2142},{8,31,74},{7,31,3981},{5,31,425},{13,31,697},{13,31,697},{13,31,697},{12,31,361},{15,23,1201},{11,31,674},{11,31,674},{7,31,16},{12,30,1201},{7,31,16},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{10,0,2689}, +{10,0,2689},{10,0,2689},{10,0,2689},{8,31,578},{8,31,578},{8,31,578},{8,30,49},{5,31,425},{5,31,425},{12,31,6211},{11,31,5318},{11,31,4693},{11,31,3554},{11,31,5833},{10,31,3067},{10,31,2106},{8,31,10},{9,31,5601},{6,31,580},{14,31,825},{13,31,674},{13,31,505},{13,31,233},{15,27,1122},{13,31,738},{12,31,461},{8,31,9},{13,31,1122},{8,31,9},{11,31,4693},{11,31,4693},{11,31,4693}, +{11,31,3554},{10,31,3849},{10,31,2106},{10,31,2106},{8,31,10},{7,31,3629},{6,31,580},{13,31,505},{13,31,505},{13,31,505},{13,31,233},{13,31,841},{12,31,461},{12,31,461},{8,31,9},{15,27,841},{8,31,9},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{10,0,2705},{10,0,2705},{10,0,2705},{10,0,2705},{9,31,666}, +{9,31,666},{9,31,666},{8,31,10},{6,31,580},{6,31,580},{12,31,5427},{12,31,4827},{11,31,4453},{11,31,3314},{12,31,5175},{10,31,2859},{10,31,1898},{9,31,74},{10,31,4842},{7,31,724},{14,31,489},{14,31,425},{14,31,389},{13,31,169},{14,31,729},{13,31,482},{13,31,313},{10,31,4},{14,30,726},{10,31,4},{11,31,4453},{11,31,4453},{11,31,4453},{11,31,3314},{11,31,3445},{10,31,1898},{10,31,1898}, +{9,31,74},{8,31,3213},{7,31,724},{14,31,389},{14,31,389},{14,31,389},{13,31,169},{15,26,545},{13,31,313},{13,31,313},{10,31,4},{14,29,545},{10,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{11,0,2689},{11,0,2689},{11,0,2689},{11,0,2689},{9,31,890},{9,31,890},{9,31,890},{9,31,74},{7,31,724}, +{7,31,724},{2,31,33740},{0,31,5184},{0,22,420},{0,21,4221},{1,31,46089},{0,29,24105},{0,21,8317},{0,18,24790},{0,21,63990},{0,16,38959},{1,31,9704},{0,30,2866},{0,21,389},{0,19,3229},{7,2,18065},{0,20,13257},{0,17,6153},{0,12,13481},{12,0,18065},{0,12,13481},{0,15,1},{0,15,1},{0,15,1},{0,9,1},{0,8,1105},{0,7,585},{0,7,585},{0,4,596},{0,4,1273},{0,4,740},{0,15,1}, +{0,15,1},{0,15,1},{0,9,1},{2,1,1105},{0,7,585},{0,7,585},{0,4,596},{4,0,1105},{0,4,596},{9,6,9248},{0,30,2866},{0,21,389},{0,19,3229},{9,6,9248},{14,5,9248},{0,19,3229},{0,14,9248},{14,5,9248},{0,14,9248},{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},{2,31,38380},{0,31,6720},{0,23,245}, +{0,22,3864},{2,31,50747},{0,31,24961},{0,22,8353},{0,19,25735},{0,22,65535},{0,17,41319},{1,31,10152},{0,31,2624},{0,23,229},{0,20,2980},{5,10,19334},{0,20,13769},{0,18,6243},{0,13,14116},{12,1,19334},{0,13,14116},{0,18,0},{0,18,0},{0,18,0},{0,11,1},{0,9,1513},{0,8,772},{0,8,772},{0,5,821},{0,5,1750},{0,4,1028},{0,18,0},{0,18,0},{0,18,0},{0,11,1},{1,6,1513}, +{0,8,772},{0,8,772},{0,5,821},{3,2,1513},{0,5,821},{10,5,9248},{0,31,2624},{0,23,229},{0,20,2980},{10,5,9248},{12,9,9248},{0,20,2980},{0,15,9248},{12,9,9248},{0,15,9248},{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},{2,31,43788},{0,31,9024},{0,24,126},{0,23,3525},{2,31,56155},{0,31,26241},{0,23,8425}, +{0,20,26793},{0,23,65535},{0,18,43819},{2,31,10787},{0,31,2624},{0,24,122},{0,21,2701},{8,0,20689},{0,22,14385},{0,19,6369},{0,13,14756},{12,2,20689},{0,13,14756},{0,21,1},{0,21,1},{0,21,1},{0,12,4},{0,10,1989},{0,9,1018},{0,9,1018},{0,6,1096},{0,5,2294},{0,5,1334},{0,21,1},{0,21,1},{0,21,1},{0,12,4},{1,7,1985},{0,9,1018},{0,9,1018},{0,6,1096},{1,5,1985}, +{0,6,1096},{12,1,9248},{0,31,2624},{0,24,122},{0,21,2701},{12,1,9248},{15,7,9248},{0,21,2701},{0,16,9250},{15,7,9248},{0,16,9250},{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},{2,31,49964},{1,31,11512},{0,25,41},{0,24,3109},{2,31,62331},{0,31,28289},{0,24,8585},{0,21,27848},{0,23,65535},{0,19,46459},{2,31,11395}, +{0,31,2880},{0,25,37},{0,22,2440},{8,2,22129},{0,23,15030},{0,20,6509},{0,14,15441},{13,2,22129},{0,14,15441},{0,23,1},{0,23,1},{0,23,1},{0,14,0},{0,12,2525},{0,10,1300},{0,10,1300},{0,6,1384},{0,6,2905},{0,6,1708},{0,23,1},{0,23,1},{0,23,1},{0,14,0},{3,2,2521},{0,10,1300},{0,10,1300},{0,6,1384},{5,1,2521},{0,6,1384},{11,7,9248},{0,31,2880},{0,25,37}, +{0,22,2440},{11,7,9248},{13,11,9248},{0,22,2440},{0,17,9250},{13,11,9248},{0,17,9250},{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},{3,31,57022},{1,31,15166},{0,26,20},{0,25,2804},{2,31,65535},{0,31,31511},{0,25,8733},{0,22,29095},{0,26,65535},{0,20,49444},{2,31,12385},{0,31,3474},{0,26,4},{0,23,2173},{8,4,23851}, +{0,23,15948},{0,21,6729},{0,15,16274},{14,2,23851},{0,15,16274},{0,26,0},{0,26,0},{0,26,0},{0,16,4},{0,13,3200},{0,11,1665},{0,11,1665},{0,7,1754},{0,7,3691},{0,6,2185},{0,26,0},{0,26,0},{0,26,0},{0,16,4},{1,10,3200},{0,11,1665},{0,11,1665},{0,7,1754},{5,2,3200},{0,7,1754},{11,10,9248},{1,31,3226},{0,26,4},{0,23,2173},{11,10,9248},{5,23,9248},{0,23,2173}, +{0,18,9248},{5,23,9248},{0,18,9248},{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},{3,31,63870},{1,31,19230},{0,27,45},{0,27,2520},{3,31,65535},{0,31,35191},{0,26,8925},{0,23,30250},{0,28,65535},{0,21,52374},{3,31,13449},{1,31,4026},{0,27,29},{0,24,1901},{3,24,25472},{0,26,16706},{0,22,6963},{0,16,17124},{14,3,25472}, +{0,16,17124},{0,29,1},{0,29,1},{0,29,1},{0,17,1},{0,14,3874},{0,13,2084},{0,13,2084},{0,8,2165},{0,8,4466},{0,7,2627},{0,29,1},{0,29,1},{0,29,1},{0,17,1},{4,1,3872},{0,13,2084},{0,13,2084},{0,8,2165},{3,5,3872},{0,8,2165},{12,9,9248},{2,31,3593},{0,27,29},{0,24,1901},{12,9,9248},{14,13,9248},{0,24,1901},{0,19,9248},{14,13,9248},{0,19,9248},{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},{3,31,65535},{1,31,24002},{0,28,109},{0,27,2268},{3,31,65535},{1,31,39095},{0,27,8825},{0,24,30825},{0,28,65535},{0,22,54996},{3,31,14345},{1,31,4766},{0,29,102},{0,26,1697},{3,26,26744},{0,28,17104},{0,23,6957},{0,17,17625},{15,3,26744},{0,17,17625},{0,31,5},{0,31,5},{0,31,5}, +{0,19,5},{0,16,4418},{0,14,2306},{0,14,2306},{0,9,2420},{0,8,5122},{0,8,2997},{0,31,5},{0,31,5},{0,31,5},{0,19,5},{3,6,4418},{0,14,2306},{0,14,2306},{0,9,2420},{3,6,4418},{0,9,2420},{14,5,9248},{4,31,3904},{1,28,1},{0,26,1693},{14,5,9248},{12,17,9248},{0,26,1693},{0,20,9250},{12,17,9248},{0,20,9250},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,1,1}, +{0,1,1},{0,1,1},{0,0,4},{0,0,4},{0,0,4},{3,31,65535},{1,31,29442},{0,29,330},{0,28,2105},{3,31,65535},{1,31,42151},{0,28,7781},{0,25,30108},{0,29,65535},{0,22,56388},{4,31,14976},{2,31,5434},{1,29,62},{0,27,1580},{11,0,26744},{0,29,16547},{0,24,6221},{0,18,17124},{13,7,26744},{0,18,17124},{0,31,181},{0,31,181},{0,31,181},{0,20,101},{0,19,4420},{0,16,2005},{0,16,2005}, +{0,10,2165},{0,9,5389},{0,9,2925},{1,31,37},{1,31,37},{1,31,37},{1,19,37},{5,2,4418},{0,16,2005},{0,16,2005},{0,10,2165},{8,1,4418},{0,10,2165},{13,11,9248},{4,31,4160},{1,29,26},{0,27,1480},{13,11,9248},{15,15,9248},{0,27,1480},{0,21,9250},{15,15,9248},{0,21,9250},{0,0,100},{0,0,100},{0,0,100},{0,0,100},{0,3,1},{0,3,1},{0,3,1},{0,2,0},{0,1,34}, +{0,1,34},{4,31,65535},{2,31,36070},{0,30,822},{0,30,2062},{3,31,65535},{1,31,46660},{0,29,6696},{0,26,29322},{0,31,65535},{0,23,58077},{4,31,15507},{3,31,6253},{1,31,109},{0,28,1646},{11,3,26744},{0,31,15992},{0,26,5346},{0,19,16582},{11,11,26744},{0,19,16582},{1,31,329},{1,31,329},{1,31,329},{1,21,266},{0,22,4420},{0,18,1737},{0,18,1737},{0,11,1898},{0,11,5707},{0,10,2885},{1,31,73}, +{1,31,73},{1,31,73},{1,21,10},{5,5,4418},{0,18,1737},{0,18,1737},{0,11,1898},{5,7,4418},{0,11,1898},{13,14,9248},{5,31,4570},{2,30,4},{0,28,1285},{13,14,9248},{8,25,9248},{0,28,1285},{0,22,9248},{8,25,9248},{0,22,9248},{1,0,265},{1,0,265},{1,0,265},{1,0,265},{0,6,1},{0,6,1},{0,6,1},{0,4,1},{0,3,97},{0,3,97},{4,31,65535},{2,31,40786},{0,31,1405}, +{0,30,2138},{4,31,65535},{1,31,49800},{0,30,5634},{0,27,27967},{0,31,65535},{0,24,58770},{5,31,15531},{3,31,6593},{2,31,61},{1,29,1533},{12,2,26259},{0,31,15284},{0,27,4514},{0,20,15812},{13,10,26259},{0,20,15812},{1,31,633},{1,31,633},{1,31,633},{1,22,381},{0,24,4418},{0,20,1480},{0,20,1480},{0,12,1640},{0,12,6125},{0,11,2891},{2,31,61},{2,31,61},{2,31,61},{2,21,37},{7,1,4418}, +{0,20,1480},{0,20,1480},{0,12,1640},{10,2,4418},{0,12,1640},{13,16,8978},{6,31,4777},{2,31,25},{0,29,1040},{13,16,8978},{15,18,8978},{0,29,1040},{0,23,8980},{15,18,8978},{0,23,8980},{1,0,377},{1,0,377},{1,0,377},{1,0,377},{0,9,0},{0,9,0},{0,9,0},{0,5,4},{0,4,193},{0,4,193},{4,31,65535},{2,31,40898},{1,31,2217},{0,31,2125},{4,31,65535},{1,31,47976},{0,30,4194}, +{0,27,24703},{0,31,65535},{0,24,56130},{5,31,14379},{4,31,6051},{2,31,173},{2,29,1284},{9,14,24371},{0,31,13716},{0,28,3402},{0,21,13989},{14,10,24371},{0,21,13989},{1,31,1193},{1,31,1193},{1,31,1193},{1,24,617},{0,27,4420},{0,22,1280},{0,22,1280},{0,13,1445},{0,14,6509},{0,12,2945},{2,31,173},{2,31,173},{2,31,173},{2,23,5},{5,10,4418},{0,22,1280},{0,22,1280},{0,13,1445},{12,1,4418}, +{0,13,1445},{14,14,7938},{7,31,4253},{3,31,9},{0,29,656},{14,14,7938},{14,20,7938},{0,29,656},{0,23,7956},{14,20,7938},{0,23,7956},{1,0,617},{1,0,617},{1,0,617},{1,0,617},{0,11,4},{0,11,4},{0,11,4},{0,7,0},{0,5,325},{0,5,325},{4,31,65535},{2,31,41266},{1,31,3033},{0,31,2333},{4,31,65535},{1,31,46408},{0,30,3010},{0,27,21695},{0,31,65535},{0,25,53636},{6,31,13140}, +{4,31,5571},{3,31,157},{2,29,932},{11,9,22568},{0,31,12404},{0,28,2474},{0,21,12245},{14,11,22568},{0,21,12245},{2,31,1630},{2,31,1630},{2,31,1630},{1,26,989},{0,29,4420},{0,23,1090},{0,23,1090},{0,14,1268},{0,15,6926},{0,13,3029},{3,31,157},{3,31,157},{3,31,157},{3,23,37},{8,1,4418},{0,23,1090},{0,23,1090},{0,14,1268},{10,5,4418},{0,14,1268},{15,12,6962},{7,31,3709},{4,31,1}, +{0,30,353},{15,12,6962},{13,22,6962},{0,30,353},{0,24,6970},{13,22,6962},{0,24,6970},{1,0,985},{1,0,985},{1,0,985},{1,0,985},{0,14,0},{0,14,0},{0,14,0},{0,8,4},{0,6,493},{0,6,493},{4,31,65535},{2,31,41986},{1,31,4257},{0,31,2873},{4,31,65535},{1,31,44950},{0,30,1984},{0,28,18569},{0,31,65535},{0,25,51026},{6,31,11934},{5,31,5125},{4,31,296},{3,29,706},{13,4,20642}, +{0,31,11234},{0,29,1634},{0,22,10422},{15,11,20642},{0,22,10422},{2,31,2350},{2,31,2350},{2,31,2350},{2,26,1450},{0,31,4450},{0,25,949},{0,25,949},{0,16,1096},{0,16,7397},{0,14,3171},{4,31,296},{4,31,296},{4,31,296},{3,25,10},{8,4,4418},{0,25,949},{0,25,949},{0,16,1096},{14,2,4418},{0,16,1096},{14,17,5941},{7,31,3250},{5,31,0},{0,30,128},{14,17,5941},{13,23,5941},{0,30,128}, +{0,24,5953},{13,23,5941},{0,24,5953},{2,0,1450},{2,0,1450},{2,0,1450},{2,0,1450},{0,17,0},{0,17,0},{0,17,0},{0,10,1},{0,8,697},{0,8,697},{4,31,65535},{2,31,42898},{1,31,5617},{1,31,3337},{4,31,65535},{1,31,43926},{0,31,1250},{0,28,15865},{0,31,65535},{0,25,48978},{7,31,10938},{5,31,4773},{4,31,360},{3,30,509},{12,9,19021},{1,31,10246},{0,30,1088},{0,23,8945},{14,13,19021}, +{0,23,8945},{2,31,3262},{2,31,3262},{2,31,3262},{2,28,1822},{1,31,4682},{0,28,776},{0,28,776},{0,17,925},{0,18,7893},{0,15,3333},{4,31,360},{4,31,360},{4,31,360},{4,25,37},{3,25,4418},{0,28,776},{0,28,776},{0,17,925},{12,6,4418},{0,17,925},{15,15,5101},{8,31,2777},{6,31,9},{0,31,25},{15,15,5101},{11,26,5101},{0,31,25},{0,25,5105},{11,26,5101},{0,25,5105},{2,0,1818}, +{2,0,1818},{2,0,1818},{2,0,1818},{0,20,1},{0,20,1},{0,20,1},{0,12,1},{0,9,925},{0,9,925},{4,31,65535},{2,31,44066},{1,31,7233},{1,31,3993},{4,31,65535},{2,31,43110},{0,31,738},{0,28,13417},{0,31,65535},{0,25,47186},{7,31,9978},{6,31,4467},{5,31,452},{4,30,357},{15,1,17485},{2,31,9441},{0,30,704},{0,24,7570},{15,13,17485},{0,24,7570},{3,31,4058},{3,31,4058},{3,31,4058}, +{2,29,2315},{1,31,4874},{0,29,610},{0,29,610},{0,18,772},{0,20,8427},{0,16,3497},{5,31,452},{5,31,452},{5,31,452},{4,27,5},{9,6,4418},{0,29,610},{0,29,610},{0,18,772},{14,5,4418},{0,18,772},{15,16,4325},{8,31,2377},{6,31,25},{0,31,9},{15,16,4325},{15,22,4325},{0,31,9},{0,25,4337},{15,22,4325},{0,25,4337},{2,0,2314},{2,0,2314},{2,0,2314},{2,0,2314},{0,22,1}, +{0,22,1},{0,22,1},{0,13,4},{0,10,1189},{0,10,1189},{5,31,65535},{3,31,45090},{1,31,9105},{1,31,4905},{4,31,65535},{2,31,42326},{0,31,482},{0,28,11225},{0,31,65535},{0,26,45590},{7,31,9274},{6,31,4179},{5,31,612},{4,30,245},{14,6,16034},{3,31,8633},{0,31,482},{0,24,6242},{15,14,16034},{0,24,6242},{3,31,5066},{3,31,5066},{3,31,5066},{2,31,2939},{1,31,5322},{0,31,482},{0,31,482}, +{0,19,637},{0,20,8939},{0,17,3725},{5,31,612},{5,31,612},{5,31,612},{5,27,37},{10,5,4418},{0,31,482},{0,31,482},{0,19,637},{12,9,4418},{0,19,637},{13,24,3613},{9,31,1973},{7,31,9},{2,31,1},{13,24,3613},{15,23,3613},{2,31,1},{0,26,3617},{15,23,3613},{0,26,3617},{2,0,2938},{2,0,2938},{2,0,2938},{2,0,2938},{0,25,1},{0,25,1},{0,25,1},{0,15,0},{0,11,1489}, +{0,11,1489},{5,31,65535},{3,31,46530},{1,31,11517},{1,31,6237},{4,31,65535},{2,31,41750},{0,31,500},{0,29,8976},{0,31,65535},{0,26,43934},{8,31,8225},{7,31,3853},{6,31,680},{5,30,109},{11,18,14504},{4,31,7667},{0,31,500},{0,25,4979},{10,21,14504},{0,25,4979},{3,31,6506},{3,31,6506},{3,31,6506},{3,31,3701},{2,31,6019},{0,31,500},{0,31,500},{0,20,520},{0,22,9629},{0,18,4035},{6,31,680}, +{6,31,680},{6,31,680},{5,29,10},{10,8,4418},{0,31,500},{0,31,500},{0,20,520},{11,12,4418},{0,20,520},{15,19,2888},{10,31,1537},{8,31,16},{3,31,4},{15,19,2888},{13,26,2888},{3,31,4},{0,26,2906},{13,26,2888},{0,26,2906},{3,0,3697},{3,0,3697},{3,0,3697},{3,0,3697},{0,28,1},{0,28,1},{0,28,1},{0,17,4},{0,11,1930},{0,11,1930},{5,31,65535},{3,31,48082},{1,31,13933}, +{1,31,7693},{4,31,65535},{2,31,41510},{0,31,788},{0,29,7120},{0,31,65535},{0,26,42734},{8,31,7409},{7,31,3693},{7,31,884},{6,30,116},{13,13,13235},{4,31,6899},{1,31,628},{0,25,3987},{15,16,13235},{0,25,3987},{4,31,7686},{4,31,7686},{4,31,7686},{3,31,4437},{2,31,6659},{0,31,788},{0,31,788},{0,21,421},{0,23,10286},{0,20,4305},{7,31,884},{7,31,884},{7,31,884},{6,29,37},{9,14,4418}, +{1,31,628},{1,31,628},{0,21,421},{14,10,4418},{0,21,421},{15,20,2312},{10,31,1217},{8,31,16},{4,31,9},{15,20,2312},{12,28,2312},{4,31,9},{0,27,2314},{12,28,2312},{0,27,2314},{3,0,4337},{3,0,4337},{3,0,4337},{3,0,4337},{0,30,1},{0,30,1},{0,30,1},{0,18,1},{0,13,2329},{0,13,2329},{5,31,65535},{3,31,49890},{2,31,16310},{1,31,9405},{4,31,65535},{2,31,41526},{0,31,1332}, +{0,29,5520},{0,31,65535},{0,26,41790},{8,31,6849},{8,31,3601},{7,31,980},{6,31,5},{15,8,12051},{5,31,6275},{2,31,801},{0,26,3066},{11,22,12051},{0,26,3066},{4,31,9062},{4,31,9062},{4,31,9062},{3,31,5429},{2,31,7555},{1,31,1172},{1,31,1172},{0,23,325},{0,23,11118},{0,20,4625},{7,31,980},{7,31,980},{7,31,980},{6,31,5},{11,10,4418},{2,31,801},{2,31,801},{0,23,325},{5,23,4418}, +{0,23,325},{13,28,1800},{11,31,949},{9,31,4},{6,31,1},{13,28,1800},{11,30,1800},{6,31,1},{0,27,1818},{11,30,1800},{0,27,1818},{3,0,5105},{3,0,5105},{3,0,5105},{3,0,5105},{0,31,36},{0,31,36},{0,31,36},{0,20,4},{0,15,2741},{0,15,2741},{5,31,65535},{3,31,51954},{2,31,18790},{1,31,11373},{5,31,65535},{2,31,41798},{0,31,2132},{0,29,4176},{0,31,65535},{0,27,41092},{9,31,6153}, +{8,31,3297},{7,31,1332},{7,31,37},{14,13,10952},{5,31,5763},{3,31,965},{0,27,2291},{11,23,10952},{0,27,2291},{4,31,10694},{4,31,10694},{4,31,10694},{4,31,6566},{3,31,8619},{1,31,1716},{1,31,1716},{0,24,221},{0,26,11876},{0,22,4989},{7,31,1332},{7,31,1332},{7,31,1332},{7,31,37},{12,9,4418},{3,31,965},{3,31,965},{0,24,221},{14,13,4418},{0,24,221},{14,26,1352},{11,31,725},{10,31,0}, +{7,31,1},{14,26,1352},{15,26,1352},{7,31,1},{0,28,1360},{15,26,1352},{0,28,1360},{3,0,6001},{3,0,6001},{3,0,6001},{3,0,6001},{0,31,196},{0,31,196},{0,31,196},{0,21,1},{0,16,3130},{0,16,3130},{5,31,65535},{3,31,54582},{2,31,21886},{1,31,13893},{5,31,65535},{2,31,42410},{0,31,3338},{0,30,2841},{0,31,65535},{0,27,40390},{9,31,5649},{9,31,3249},{8,31,1325},{7,31,109},{14,15,9818}, +{6,31,5258},{4,31,1108},{0,27,1589},{12,23,9818},{0,27,1589},{5,31,12376},{5,31,12376},{5,31,12376},{4,31,7844},{3,31,9861},{1,31,2634},{1,31,2634},{0,25,136},{0,28,12696},{0,23,5429},{8,31,1325},{8,31,1325},{8,31,1325},{7,31,109},{15,2,4418},{4,31,1108},{4,31,1108},{0,25,136},{13,16,4418},{0,25,136},{15,24,925},{12,31,505},{11,31,1},{8,31,1},{15,24,925},{15,27,925},{8,31,1}, +{0,28,937},{15,27,925},{0,28,937},{4,0,7060},{4,0,7060},{4,0,7060},{4,0,7060},{1,31,425},{1,31,425},{1,31,425},{0,23,0},{0,17,3665},{0,17,3665},{5,31,65535},{3,31,57190},{2,31,24910},{1,31,16405},{5,31,65535},{2,31,43226},{0,31,4682},{0,30,1833},{0,31,65535},{0,27,40038},{10,31,5202},{9,31,3073},{8,31,1565},{8,31,277},{13,20,8901},{7,31,4814},{5,31,1300},{0,28,1021},{13,23,8902}, +{0,28,1021},{5,31,14136},{5,31,14136},{5,31,14136},{4,31,9252},{3,31,11237},{2,31,3590},{2,31,3590},{0,26,85},{0,29,13491},{0,23,5925},{8,31,1565},{8,31,1565},{8,31,1565},{8,31,277},{11,18,4418},{5,31,1300},{5,31,1300},{0,26,85},{10,21,4418},{0,26,85},{15,25,617},{13,31,365},{12,31,16},{9,31,9},{15,25,617},{13,30,613},{9,31,9},{0,29,617},{13,30,613},{0,29,617},{4,0,7956}, +{4,0,7956},{4,0,7956},{4,0,7956},{1,31,697},{1,31,697},{1,31,697},{0,25,4},{0,18,4181},{0,18,4181},{5,31,65535},{3,31,60054},{2,31,28190},{2,31,18895},{5,31,65535},{2,31,44298},{1,31,6090},{0,30,1081},{0,31,65535},{0,27,39942},{10,31,4850},{10,31,3107},{9,31,1709},{8,31,325},{13,22,8069},{7,31,4574},{6,31,1553},{0,29,602},{12,25,8069},{0,29,602},{6,31,16067},{6,31,16067},{6,31,16067}, +{5,31,10872},{4,31,12824},{2,31,4662},{2,31,4662},{0,27,52},{0,30,14340},{0,25,6449},{9,31,1709},{9,31,1709},{9,31,1709},{8,31,325},{13,14,4418},{6,31,1553},{6,31,1553},{0,27,52},{8,25,4418},{0,27,52},{15,27,365},{13,31,205},{12,31,16},{11,31,4},{15,27,365},{13,31,365},{11,31,4},{0,29,377},{13,31,365},{0,29,377},{4,0,8980},{4,0,8980},{4,0,8980},{4,0,8980},{1,31,1097}, +{1,31,1097},{1,31,1097},{0,26,1},{0,20,4682},{0,20,4682},{6,31,65535},{4,31,58981},{2,31,29926},{2,31,19751},{5,31,65535},{3,31,43402},{1,31,6910},{0,30,765},{0,31,65535},{0,28,34909},{11,31,4502},{10,31,3011},{9,31,2045},{9,31,557},{15,17,7322},{8,31,4242},{7,31,1781},{0,29,314},{12,26,7322},{0,29,314},{6,31,16739},{6,31,16739},{6,31,16739},{5,31,11492},{4,31,13636},{3,31,5586},{3,31,5586}, +{0,28,65},{0,31,14139},{0,26,6041},{9,31,2045},{9,31,2045},{9,31,2045},{9,31,557},{14,13,4418},{7,31,1781},{7,31,1781},{0,28,29},{11,23,4418},{0,28,29},{15,28,181},{14,31,117},{13,31,4},{12,31,0},{15,28,181},{15,29,181},{12,31,0},{0,30,185},{15,29,181},{0,30,185},{4,0,9376},{4,0,9376},{4,0,9376},{4,0,9376},{2,31,1405},{2,31,1405},{2,31,1405},{0,28,40},{0,21,4520}, +{0,21,4520},{6,31,65535},{4,31,57316},{3,31,30345},{3,31,20808},{6,31,65535},{3,31,41449},{2,31,8321},{1,31,301},{0,31,65535},{0,28,28330},{11,31,4232},{11,31,3093},{10,31,2248},{9,31,809},{15,19,6584},{9,31,3992},{7,31,2105},{0,30,77},{13,26,6584},{0,30,77},{7,31,17380},{7,31,17380},{7,31,17380},{6,31,12161},{5,31,14315},{3,31,6405},{3,31,6405},{1,29,53},{0,31,13860},{0,28,5286},{10,31,2248}, +{10,31,2248},{10,31,2248},{9,31,809},{14,16,4418},{7,31,2105},{7,31,2105},{0,30,13},{15,20,4418},{0,30,13},{15,29,52},{14,31,36},{14,31,0},{13,31,9},{15,29,52},{15,30,50},{13,31,9},{0,30,68},{15,30,50},{0,30,68},{5,0,9250},{5,0,9250},{5,0,9250},{5,0,9250},{2,31,1549},{2,31,1549},{2,31,1549},{1,28,2},{0,23,4114},{0,23,4114},{6,31,65535},{5,31,55908},{4,31,31583}, +{3,31,21256},{6,31,65535},{4,31,39740},{2,31,9073},{1,31,285},{0,31,65535},{0,29,23356},{12,31,4011},{11,31,3125},{11,31,2500},{10,31,1037},{13,27,6019},{10,31,3738},{8,31,2340},{0,31,4},{13,27,6019},{0,31,4},{7,31,17796},{7,31,17796},{7,31,17796},{6,31,12625},{6,31,14996},{4,31,7139},{4,31,7139},{1,30,86},{0,31,14020},{0,29,4652},{11,31,2500},{11,31,2500},{11,31,2500},{10,31,1037},{13,22,4418}, +{8,31,2340},{8,31,2340},{0,31,4},{12,25,4418},{0,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{15,31,4},{0,31,4},{15,31,4},{0,31,4},{6,0,9376},{6,0,9376},{6,0,9376},{6,0,9376},{3,31,1765},{3,31,1765},{3,31,1765},{1,30,50},{0,25,3877},{0,25,3877},{7,31,65535},{5,31,53236},{4,31,30487},{4,31,21367},{6,31,65535},{4,31,37332},{3,31,9385}, +{2,31,36},{0,31,65535},{0,29,18680},{12,31,3443},{12,31,2843},{11,31,2248},{10,31,997},{14,25,5163},{10,31,3218},{9,31,2120},{1,31,4},{12,29,5163},{1,31,4},{7,31,17504},{7,31,17504},{7,31,17504},{7,31,12569},{6,31,14328},{4,31,7227},{4,31,7227},{2,31,20},{0,31,13376},{0,29,3944},{11,31,2248},{11,31,2248},{11,31,2248},{10,31,997},{15,17,3872},{9,31,2120},{9,31,2120},{1,31,4},{12,26,3872}, +{1,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{6,0,9248},{6,0,9248},{6,0,9248},{6,0,9248},{3,31,2005},{3,31,2005},{3,31,2005},{2,30,5},{0,27,3545},{0,27,3545},{7,31,65535},{6,31,50785},{4,31,29687},{4,31,20567},{7,31,65535},{4,31,35412},{3,31,8985},{2,31,196},{1,31,65535},{0,29,14712},{12,31,2883}, +{12,31,2283},{12,31,1922},{11,31,821},{13,29,4267},{11,31,2694},{10,31,1745},{3,31,4},{14,27,4267},{3,31,4},{8,31,16610},{8,31,16610},{8,31,16610},{7,31,12185},{6,31,13528},{5,31,6915},{5,31,6915},{2,31,52},{1,31,12556},{0,30,3314},{12,31,1922},{12,31,1922},{12,31,1922},{11,31,821},{12,28,3200},{10,31,1745},{10,31,1745},{3,31,4},{11,28,3200},{3,31,4},{15,31,0},{15,31,0},{15,31,0}, +{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{6,0,9376},{6,0,9376},{6,0,9376},{6,0,9376},{4,31,2250},{4,31,2250},{4,31,2250},{2,31,52},{0,28,3170},{0,28,3170},{7,31,65535},{6,31,47239},{5,31,28065},{5,31,20409},{7,31,65535},{5,31,32574},{4,31,8965},{3,31,54},{1,31,65206},{0,30,10964},{13,31,2326},{12,31,1806},{12,31,1445},{11,31,650},{13,30,3361}, +{11,31,2091},{10,31,1322},{4,31,0},{12,30,3361},{4,31,0},{8,31,15584},{8,31,15584},{8,31,15584},{7,31,12059},{7,31,12522},{6,31,6811},{6,31,6811},{3,31,50},{1,31,11710},{0,31,2834},{12,31,1445},{12,31,1445},{12,31,1445},{11,31,650},{14,23,2521},{10,31,1322},{10,31,1322},{4,31,0},{15,24,2521},{4,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0}, +{0,31,0},{15,31,0},{0,31,0},{7,0,9250},{7,0,9250},{7,0,9250},{7,0,9250},{5,31,2600},{5,31,2600},{5,31,2600},{3,31,50},{0,31,2834},{0,31,2834},{8,31,65535},{6,31,44903},{5,31,27361},{5,31,19705},{7,31,64494},{5,31,30846},{4,31,8677},{3,31,470},{2,31,60777},{0,30,8308},{13,31,1782},{13,31,1510},{12,31,1157},{12,31,557},{13,31,2646},{11,31,1691},{11,31,1066},{5,31,4},{15,27,2646}, +{5,31,4},{8,31,14944},{8,31,14944},{8,31,14944},{8,31,11696},{7,31,11850},{6,31,6555},{6,31,6555},{4,31,164},{2,31,11097},{0,31,2610},{12,31,1157},{12,31,1157},{12,31,1157},{12,31,557},{15,21,1985},{11,31,1066},{11,31,1066},{5,31,4},{15,25,1985},{5,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{7,0,9410}, +{7,0,9410},{7,0,9410},{7,0,9410},{5,31,2792},{5,31,2792},{5,31,2792},{4,31,164},{0,31,2610},{0,31,2610},{8,31,63584},{7,31,42019},{6,31,25930},{5,31,19769},{8,31,60273},{6,31,28860},{5,31,8761},{4,31,276},{3,31,56253},{0,30,6420},{13,31,1366},{13,31,1094},{13,31,925},{12,31,397},{15,25,2018},{12,31,1298},{11,31,794},{7,31,4},{13,30,2017},{7,31,4},{9,31,14244},{9,31,14244},{9,31,14244}, +{8,31,11312},{8,31,11249},{7,31,6499},{7,31,6499},{4,31,260},{3,31,10457},{0,31,2642},{13,31,925},{13,31,925},{13,31,925},{12,31,397},{15,22,1513},{11,31,794},{11,31,794},{7,31,4},{14,27,1513},{7,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{8,0,9376},{8,0,9376},{8,0,9376},{8,0,9376},{6,31,3074}, +{6,31,3074},{6,31,3074},{4,31,260},{0,31,2642},{0,31,2642},{8,31,58848},{7,31,39683},{6,31,25130},{6,31,19007},{8,31,54849},{6,31,27132},{5,31,8569},{4,31,756},{4,31,51302},{0,31,5046},{13,31,1078},{13,31,806},{13,31,637},{12,31,365},{15,26,1473},{12,31,978},{12,31,617},{8,31,9},{14,29,1473},{8,31,9},{9,31,13604},{9,31,13604},{9,31,13604},{8,31,11184},{8,31,10433},{7,31,6339},{7,31,6339}, +{5,31,424},{4,31,9713},{0,31,2930},{13,31,637},{13,31,637},{13,31,637},{12,31,365},{14,27,1105},{12,31,617},{12,31,617},{8,31,9},{13,29,1105},{8,31,9},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{8,0,9248},{8,0,9248},{8,0,9248},{8,0,9248},{6,31,3330},{6,31,3330},{6,31,3330},{5,31,424},{0,31,2930}, +{0,31,2930},
\ No newline at end of file diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc new file mode 100644 index 0000000000..10c94153ad --- /dev/null +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc @@ -0,0 +1,481 @@ +{0,0,20},{0,0,20},{0,0,97},{0,0,145},{0,0,56},{0,0,104},{0,0,181},{0,0,406},{0,0,204},{0,0,442},{0,0,20},{0,0,20},{0,0,97},{0,0,145},{0,0,56},{0,0,104},{0,0,181},{0,0,406},{0,0,168},{0,0,406},{0,0,16},{0,0,16},{0,0,16},{0,0,64},{0,0,52},{0,0,100},{0,0,100},{0,0,325},{0,0,200},{0,0,361},{0,0,16}, +{0,0,16},{0,0,16},{0,0,64},{0,0,52},{0,0,100},{0,0,100},{0,0,325},{0,0,164},{0,0,325},{0,0,20},{0,0,20},{0,0,97},{0,0,145},{0,0,20},{0,0,68},{0,0,145},{0,0,306},{0,0,68},{0,0,306},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,1,126},{0,0,88},{0,0,53}, +{0,0,37},{0,0,116},{0,0,36},{0,0,1},{0,0,66},{0,0,88},{0,0,102},{0,1,126},{0,0,88},{0,0,53},{0,0,37},{0,0,116},{0,0,36},{0,0,1},{0,0,66},{0,0,52},{0,0,66},{0,0,52},{0,0,52},{0,0,52},{0,0,36},{0,0,16},{0,0,0},{0,0,0},{0,0,65},{0,0,52},{0,0,101},{0,0,52},{0,0,52},{0,0,52},{0,0,36},{0,0,16}, +{0,0,0},{0,0,0},{0,0,65},{0,0,16},{0,0,65},{0,1,90},{0,0,52},{0,0,17},{0,0,1},{0,1,90},{0,0,36},{0,0,1},{0,0,50},{0,0,36},{0,0,50},{0,0,36},{0,0,36},{0,0,36},{0,0,36},{0,0,0},{0,0,0},{0,0,0},{0,0,16},{0,0,52},{0,0,52},{0,1,286},{0,1,310},{0,0,453},{0,0,373},{0,1,115},{0,1,307},{0,0,241}, +{0,0,130},{0,0,280},{0,0,70},{0,1,222},{0,1,246},{0,0,389},{0,0,309},{0,1,51},{1,0,195},{0,0,177},{0,0,66},{1,0,107},{0,0,66},{0,1,261},{0,1,261},{0,1,261},{0,0,324},{0,1,90},{0,0,192},{0,0,192},{0,0,81},{0,0,84},{0,0,21},{0,1,197},{0,1,197},{0,1,197},{0,0,260},{0,1,26},{0,0,128},{0,0,128},{0,0,17},{0,0,80}, +{0,0,17},{0,1,26},{0,1,50},{1,0,130},{1,0,74},{0,1,26},{1,0,26},{1,0,74},{0,0,50},{1,0,26},{0,0,50},{0,0,260},{0,0,260},{0,0,260},{0,0,260},{0,1,89},{0,1,89},{0,1,89},{0,0,80},{0,0,20},{0,0,20},{1,0,494},{1,0,550},{1,0,694},{1,0,702},{0,2,363},{0,1,291},{1,0,583},{1,0,631},{0,1,116},{1,0,428},{1,0,170}, +{1,0,226},{1,0,370},{1,0,378},{1,0,51},{0,1,35},{1,0,259},{1,0,307},{1,0,91},{1,0,307},{1,0,469},{1,0,469},{1,0,469},{1,0,477},{0,1,314},{0,1,290},{0,1,290},{1,0,406},{0,1,115},{1,0,203},{1,0,145},{1,0,145},{1,0,145},{1,0,153},{1,0,26},{1,0,34},{1,0,34},{1,0,82},{1,0,10},{1,0,82},{1,0,26},{0,1,50},{1,0,226}, +{1,0,234},{1,0,26},{0,1,26},{1,0,234},{0,0,306},{0,1,26},{0,0,306},{1,0,468},{1,0,468},{1,0,468},{1,0,468},{0,1,265},{0,1,265},{0,1,265},{1,0,325},{0,1,90},{0,1,90},{1,1,116},{1,1,124},{1,1,215},{1,1,271},{1,1,188},{1,1,252},{1,1,343},{1,1,606},{0,1,152},{0,1,392},{1,1,35},{1,1,43},{1,1,134},{1,1,190},{1,1,107}, +{1,1,171},{0,1,260},{0,1,356},{2,0,51},{0,1,356},{1,1,115},{1,1,115},{1,1,115},{1,1,171},{1,0,161},{1,0,241},{1,0,241},{1,0,469},{0,1,52},{0,1,292},{1,1,34},{1,1,34},{1,1,34},{1,1,90},{0,2,16},{1,0,160},{1,0,160},{0,1,256},{0,1,16},{0,1,256},{1,1,26},{1,1,34},{1,1,125},{0,1,116},{1,1,26},{2,0,26},{0,1,116}, +{0,1,356},{2,0,26},{0,1,356},{1,0,90},{1,0,90},{1,0,90},{1,0,90},{1,0,97},{1,0,97},{1,0,97},{1,0,145},{0,1,36},{0,1,36},{1,1,116},{1,1,60},{1,1,39},{1,1,31},{1,1,92},{1,1,28},{1,1,7},{1,1,94},{1,1,100},{1,1,142},{1,1,115},{1,1,59},{1,1,38},{1,1,30},{0,3,51},{1,1,27},{1,1,6},{1,1,93},{1,1,51}, +{1,1,93},{1,1,35},{1,1,35},{1,1,35},{1,1,27},{1,1,11},{1,1,3},{1,1,3},{1,1,90},{1,1,75},{1,1,138},{1,1,34},{1,1,34},{1,1,34},{1,1,26},{1,1,10},{1,1,2},{1,1,2},{1,1,89},{1,1,26},{1,1,89},{2,0,26},{1,1,34},{1,1,13},{1,1,5},{2,0,26},{3,0,26},{1,1,5},{0,1,68},{3,0,26},{0,1,68},{1,0,26}, +{1,0,26},{1,0,26},{1,0,26},{1,1,2},{1,1,2},{1,1,2},{1,1,26},{1,1,74},{1,1,74},{1,2,238},{1,2,286},{1,1,375},{1,1,303},{1,2,105},{1,1,316},{1,1,183},{1,1,94},{0,2,156},{1,1,46},{1,2,189},{1,2,237},{1,1,326},{1,1,254},{1,2,56},{2,1,232},{1,1,134},{1,1,45},{0,2,56},{1,1,45},{1,2,222},{1,2,222},{1,2,222}, +{1,1,267},{1,2,89},{1,1,147},{1,1,147},{1,1,58},{1,1,59},{1,1,10},{1,2,173},{1,2,173},{1,2,173},{1,1,218},{2,0,10},{1,1,98},{1,1,98},{1,1,9},{3,0,10},{1,1,9},{1,2,20},{1,2,68},{2,1,136},{2,1,72},{1,2,20},{0,2,20},{2,1,72},{0,1,36},{0,2,20},{0,1,36},{1,0,218},{1,0,218},{1,0,218},{1,0,218},{1,2,85}, +{1,2,85},{1,2,85},{1,1,58},{1,1,10},{1,1,10},{2,1,550},{2,1,598},{2,1,730},{2,1,730},{1,3,361},{1,2,265},{2,1,597},{1,1,606},{1,2,152},{2,1,408},{2,1,189},{2,1,237},{2,1,369},{2,1,369},{2,1,56},{1,2,40},{2,1,236},{2,1,264},{4,0,56},{2,1,264},{2,1,534},{2,1,534},{2,1,534},{2,1,534},{1,2,265},{1,2,265},{1,2,265}, +{1,1,410},{2,1,152},{2,1,212},{2,1,173},{2,1,173},{2,1,173},{2,1,173},{0,4,8},{2,1,40},{2,1,40},{2,1,68},{2,1,8},{2,1,68},{2,1,20},{1,2,36},{2,1,200},{2,1,200},{2,1,20},{4,0,20},{2,1,200},{0,1,260},{4,0,20},{0,1,260},{2,0,530},{2,0,530},{2,0,530},{2,0,530},{1,2,229},{1,2,229},{1,2,229},{1,2,325},{1,2,116}, +{1,2,116},{2,2,152},{2,2,168},{2,2,273},{2,2,337},{2,2,236},{2,2,316},{2,2,421},{2,2,706},{1,2,116},{1,2,436},{2,2,52},{2,2,68},{2,2,173},{2,2,237},{3,0,56},{1,2,211},{1,2,251},{1,2,411},{3,1,56},{1,2,411},{2,2,152},{2,2,152},{2,2,152},{2,2,216},{2,1,158},{2,1,230},{2,1,230},{2,1,438},{1,2,35},{1,2,315},{2,2,52}, +{2,2,52},{2,2,52},{2,2,116},{1,3,10},{2,1,130},{2,1,130},{1,2,290},{1,2,10},{1,2,290},{3,0,20},{2,2,52},{2,2,157},{1,2,130},{3,0,20},{3,1,20},{1,2,130},{0,2,410},{3,1,20},{0,2,410},{2,0,116},{2,0,116},{2,0,116},{2,0,116},{2,1,109},{2,1,109},{2,1,109},{2,1,149},{1,2,26},{1,2,26},{2,2,88},{2,2,40},{2,2,33}, +{2,2,33},{2,2,76},{2,2,28},{2,2,21},{2,2,130},{2,2,120},{2,2,190},{2,2,84},{2,2,36},{2,2,29},{2,2,29},{1,4,56},{2,2,24},{2,2,17},{2,2,126},{2,2,56},{2,2,126},{2,2,24},{2,2,24},{2,2,24},{2,2,24},{2,2,12},{2,2,12},{2,2,12},{2,2,121},{2,2,104},{2,2,181},{2,2,20},{2,2,20},{2,2,20},{2,2,20},{2,2,8}, +{2,2,8},{2,2,8},{2,2,117},{5,0,8},{2,2,117},{1,4,20},{2,2,20},{2,2,13},{2,2,13},{1,4,20},{2,2,20},{2,2,13},{0,2,90},{2,2,20},{0,2,90},{2,0,20},{2,0,20},{2,0,20},{2,0,20},{2,2,8},{2,2,8},{2,2,8},{2,2,40},{2,2,100},{2,2,100},{2,3,198},{2,3,270},{2,2,305},{2,2,241},{2,3,103},{2,2,252},{2,2,133}, +{2,2,66},{1,3,148},{2,2,30},{2,3,162},{2,3,234},{2,2,269},{2,2,205},{2,3,67},{2,2,216},{2,2,97},{2,2,30},{6,0,67},{2,2,30},{2,3,189},{2,3,189},{2,3,189},{2,2,216},{2,3,94},{2,2,108},{2,2,108},{2,2,41},{2,2,40},{2,2,5},{2,3,153},{2,3,153},{2,3,153},{2,2,180},{3,1,8},{2,2,72},{2,2,72},{2,2,5},{4,1,8}, +{2,2,5},{2,3,18},{2,3,90},{2,2,125},{2,2,61},{2,3,18},{6,0,18},{2,2,61},{0,2,26},{6,0,18},{0,2,26},{2,0,180},{2,0,180},{2,0,180},{2,0,180},{2,2,72},{2,2,72},{2,2,72},{2,2,40},{2,2,4},{2,2,4},{3,2,614},{2,3,622},{3,2,774},{3,2,766},{2,3,343},{2,3,247},{3,2,619},{2,2,514},{2,3,196},{2,2,382},{3,2,214}, +{3,2,254},{3,2,374},{3,2,366},{4,0,59},{2,3,51},{3,2,219},{3,2,227},{3,2,59},{3,2,227},{3,2,605},{3,2,605},{3,2,605},{3,2,597},{2,3,222},{2,3,246},{2,3,246},{2,2,345},{3,2,179},{2,2,213},{3,2,205},{3,2,205},{3,2,205},{3,2,197},{4,0,10},{3,2,50},{3,2,50},{3,2,58},{3,2,10},{3,2,58},{3,2,18},{2,3,26},{3,2,178}, +{3,2,170},{3,2,18},{5,1,18},{3,2,170},{0,2,218},{5,1,18},{0,2,218},{2,0,596},{2,0,596},{2,0,596},{2,0,596},{2,3,197},{2,3,197},{2,3,197},{2,2,296},{2,3,146},{2,3,146},{3,3,196},{3,3,220},{3,3,339},{3,3,411},{3,3,292},{3,3,388},{3,3,507},{3,3,814},{2,3,88},{2,3,488},{3,3,75},{3,3,99},{3,3,218},{3,3,290},{4,1,67}, +{2,3,168},{2,3,248},{2,3,472},{4,2,67},{2,3,472},{3,2,182},{3,2,182},{3,2,182},{3,2,246},{3,2,161},{3,2,225},{3,2,225},{3,2,413},{2,3,24},{3,2,308},{3,2,61},{3,2,61},{3,2,61},{3,2,125},{2,4,8},{3,2,104},{3,2,104},{3,2,292},{7,0,8},{3,2,292},{4,1,18},{3,3,74},{3,3,193},{2,3,148},{4,1,18},{4,2,18},{2,3,148}, +{0,3,468},{4,2,18},{0,3,468},{3,0,146},{3,0,146},{3,0,146},{3,0,146},{3,2,125},{3,2,125},{3,2,125},{3,2,157},{2,3,20},{2,3,20},{3,3,68},{3,3,28},{3,3,35},{3,3,43},{3,3,68},{3,3,36},{3,3,43},{3,3,174},{3,3,148},{3,3,246},{3,3,59},{3,3,19},{3,3,26},{3,3,34},{3,3,59},{3,3,27},{3,3,34},{2,3,152},{6,1,59}, +{2,3,152},{3,3,19},{3,3,19},{3,3,19},{3,3,27},{3,3,19},{3,3,27},{3,3,27},{3,3,158},{3,3,139},{3,3,230},{3,3,10},{3,3,10},{3,3,10},{3,3,18},{3,3,10},{3,3,18},{3,3,18},{2,3,136},{6,1,10},{2,3,136},{5,0,18},{3,3,10},{3,3,17},{3,3,25},{5,0,18},{3,3,18},{3,3,25},{0,3,116},{3,3,18},{0,3,116},{3,0,18}, +{3,0,18},{3,0,18},{3,0,18},{3,3,18},{3,3,18},{3,3,18},{3,3,58},{3,3,130},{3,3,130},{3,4,166},{3,4,262},{3,3,243},{3,3,187},{3,4,109},{3,3,196},{3,3,91},{3,3,46},{3,3,148},{3,3,22},{3,4,141},{3,4,237},{3,3,218},{3,3,162},{4,2,59},{3,3,171},{3,3,66},{3,3,21},{5,2,59},{3,3,21},{3,4,162},{3,4,162},{3,4,162}, +{3,3,171},{3,4,105},{3,3,75},{3,3,75},{3,3,30},{3,3,27},{3,3,6},{3,4,137},{3,4,137},{3,4,137},{3,3,146},{4,2,10},{3,3,50},{3,3,50},{3,3,5},{5,2,10},{3,3,5},{3,4,20},{3,4,116},{3,3,97},{3,3,41},{3,4,20},{7,1,20},{3,3,41},{0,3,20},{7,1,20},{0,3,20},{3,0,146},{3,0,146},{3,0,146},{3,0,146},{3,3,50}, +{3,3,50},{3,3,50},{3,3,26},{3,3,2},{3,3,2},{3,5,598},{3,4,550},{4,3,826},{4,3,810},{3,4,285},{3,4,237},{4,3,649},{3,3,430},{4,3,248},{3,3,310},{4,3,245},{4,3,277},{4,3,385},{4,3,369},{5,1,52},{3,4,68},{4,3,208},{4,3,196},{4,3,52},{4,3,196},{3,4,546},{3,4,546},{3,4,546},{3,4,594},{3,4,185},{3,4,233},{3,4,233}, +{3,3,286},{4,3,212},{3,3,166},{4,3,241},{4,3,241},{4,3,241},{4,3,225},{5,1,16},{4,3,64},{4,3,64},{4,3,52},{7,1,16},{4,3,52},{4,3,20},{3,4,20},{4,3,160},{4,3,144},{4,3,20},{6,2,20},{4,3,144},{0,3,180},{6,2,20},{0,3,180},{3,0,530},{3,0,530},{3,0,530},{3,0,530},{3,4,169},{3,4,169},{3,4,169},{3,3,250},{3,3,130}, +{3,3,130},{4,4,248},{4,4,280},{4,4,413},{4,4,493},{4,3,291},{4,3,451},{4,4,601},{4,3,835},{3,4,68},{3,4,548},{4,4,104},{4,4,136},{4,4,269},{4,4,349},{6,0,59},{3,4,131},{3,4,251},{3,4,539},{3,4,59},{3,4,539},{4,3,205},{4,3,205},{4,3,205},{4,3,261},{4,3,170},{4,3,226},{4,3,226},{4,3,394},{3,4,19},{4,3,275},{4,3,61}, +{4,3,61},{4,3,61},{4,3,117},{6,0,10},{4,3,82},{4,3,82},{4,3,250},{3,4,10},{4,3,250},{5,2,20},{4,4,100},{4,4,233},{3,4,170},{5,2,20},{5,3,20},{3,4,170},{0,4,530},{5,3,20},{0,4,530},{4,0,180},{4,0,180},{4,0,180},{4,0,180},{4,3,145},{4,3,145},{4,3,145},{4,3,169},{3,4,18},{3,4,18},{4,4,56},{4,4,24},{4,4,45}, +{4,4,61},{4,4,68},{4,4,52},{4,4,73},{4,4,226},{4,4,184},{3,4,292},{4,4,40},{4,4,8},{4,4,29},{4,4,45},{4,4,52},{4,4,36},{4,4,57},{3,4,171},{7,2,52},{3,4,171},{4,4,20},{4,4,20},{4,4,20},{4,4,36},{4,4,32},{4,4,48},{4,4,48},{4,4,201},{4,4,180},{3,4,267},{4,4,4},{4,4,4},{4,4,4},{4,4,20},{5,2,16}, +{4,4,32},{4,4,32},{3,4,146},{7,2,16},{3,4,146},{6,1,20},{4,4,4},{4,4,25},{4,4,41},{6,1,20},{4,4,20},{4,4,41},{0,4,146},{4,4,20},{0,4,146},{4,0,20},{4,0,20},{4,0,20},{4,0,20},{4,4,32},{4,4,32},{4,4,32},{4,4,80},{3,4,146},{3,4,146},{4,5,142},{4,5,262},{4,4,189},{4,4,141},{4,5,123},{4,4,148},{4,4,57}, +{4,4,34},{4,4,120},{4,4,22},{4,5,126},{4,5,246},{4,4,173},{4,4,125},{5,3,52},{4,4,132},{4,4,41},{4,4,18},{6,3,52},{4,4,18},{4,5,141},{4,5,141},{4,5,141},{4,4,132},{4,4,96},{4,4,48},{4,4,48},{4,4,25},{4,4,20},{4,4,13},{4,5,125},{4,5,125},{4,5,125},{4,4,116},{6,1,16},{4,4,32},{4,4,32},{4,4,9},{6,3,16}, +{4,4,9},{7,0,26},{4,5,146},{4,4,73},{4,4,25},{7,0,26},{3,5,26},{4,4,25},{0,4,18},{3,5,26},{0,4,18},{4,0,116},{4,0,116},{4,0,116},{4,0,116},{4,4,32},{4,4,32},{4,4,32},{4,4,16},{4,4,4},{4,4,4},{4,5,558},{4,5,486},{4,4,845},{4,4,733},{4,5,235},{4,5,235},{4,4,553},{4,4,354},{5,4,276},{4,4,246},{5,4,282}, +{5,4,306},{5,4,402},{5,4,378},{6,2,51},{4,5,91},{5,4,203},{5,4,171},{5,4,51},{5,4,171},{4,5,477},{4,5,477},{4,5,477},{4,5,549},{4,5,154},{4,5,226},{4,5,226},{4,4,233},{3,5,235},{4,4,125},{5,4,281},{5,4,281},{5,4,281},{5,4,257},{7,0,10},{5,4,82},{5,4,82},{5,4,50},{3,5,10},{5,4,50},{6,2,26},{4,5,18},{5,4,146}, +{5,4,122},{6,2,26},{7,3,26},{5,4,122},{0,4,146},{7,3,26},{0,4,146},{4,0,468},{4,0,468},{4,0,468},{4,0,468},{4,5,145},{4,5,145},{4,5,145},{4,4,208},{4,4,100},{4,4,100},{5,5,308},{5,5,348},{5,5,495},{5,5,583},{5,4,285},{5,4,429},{5,4,633},{5,4,781},{4,5,56},{4,5,616},{5,5,139},{5,5,179},{5,5,326},{5,5,414},{7,1,52}, +{4,5,100},{4,5,260},{5,4,612},{4,5,52},{5,4,612},{5,4,234},{5,4,234},{5,4,234},{5,4,282},{5,4,185},{5,4,233},{5,4,233},{5,4,381},{4,5,20},{5,4,248},{5,4,65},{5,4,65},{5,4,65},{5,4,113},{7,1,16},{5,4,64},{5,4,64},{5,4,212},{7,3,16},{5,4,212},{6,3,26},{5,5,130},{5,5,277},{4,5,196},{6,3,26},{6,4,26},{4,5,196}, +{0,4,596},{6,4,26},{0,4,596},{5,0,218},{5,0,218},{5,0,218},{5,0,218},{5,4,169},{5,4,169},{5,4,169},{5,4,185},{4,5,20},{4,5,20},{5,5,52},{5,5,28},{5,5,63},{5,5,87},{5,5,76},{5,5,76},{5,5,111},{5,5,286},{5,5,228},{4,5,296},{5,5,27},{5,5,3},{5,5,38},{5,5,62},{5,5,51},{5,5,51},{5,5,86},{4,5,196},{3,6,51}, +{4,5,196},{5,5,27},{5,5,27},{5,5,27},{5,5,51},{5,5,51},{5,5,75},{5,5,75},{5,5,250},{4,5,180},{4,5,260},{5,5,2},{5,5,2},{5,5,2},{5,5,26},{6,3,10},{5,5,50},{5,5,50},{4,5,160},{6,4,10},{4,5,160},{7,2,26},{5,5,2},{5,5,37},{5,5,61},{7,2,26},{5,5,26},{5,5,61},{0,5,180},{5,5,26},{0,5,180},{5,0,26}, +{5,0,26},{5,0,26},{5,0,26},{5,5,50},{5,5,50},{5,5,50},{5,5,106},{4,5,116},{4,5,116},{5,6,126},{5,5,220},{5,5,143},{5,5,103},{5,6,145},{5,5,108},{5,5,31},{5,5,30},{5,5,100},{5,5,30},{5,6,117},{5,5,211},{5,5,134},{5,5,94},{6,4,51},{5,5,99},{5,5,22},{5,5,21},{7,4,51},{5,5,21},{5,6,126},{5,6,126},{5,6,126}, +{5,5,99},{5,5,67},{5,5,27},{5,5,27},{5,5,26},{5,5,19},{5,5,26},{5,6,117},{5,6,117},{5,6,117},{5,5,90},{7,2,10},{5,5,18},{5,5,18},{5,5,17},{5,5,10},{5,5,17},{6,4,26},{5,5,130},{5,5,53},{5,5,13},{6,4,26},{7,4,26},{5,5,13},{0,5,20},{7,4,26},{0,5,20},{5,0,90},{5,0,90},{5,0,90},{5,0,90},{5,5,18}, +{5,5,18},{5,5,18},{5,5,10},{5,5,10},{5,5,10},{5,6,478},{5,6,430},{5,5,735},{5,5,631},{5,6,193},{5,6,241},{5,5,463},{5,5,286},{4,6,268},{5,5,190},{6,5,325},{5,6,309},{6,5,425},{6,5,393},{7,3,56},{6,5,120},{6,5,204},{6,5,152},{6,5,56},{6,5,152},{5,6,414},{5,6,414},{5,6,414},{5,6,510},{5,6,129},{5,6,225},{5,6,225}, +{5,5,186},{5,5,195},{5,5,90},{5,6,293},{5,6,293},{5,6,293},{6,5,293},{5,6,8},{6,5,104},{6,5,104},{6,5,52},{4,6,8},{6,5,52},{7,3,20},{5,6,20},{6,5,136},{6,5,104},{7,3,20},{6,5,20},{6,5,104},{0,5,116},{6,5,20},{0,5,116},{5,0,410},{5,0,410},{5,0,410},{5,0,410},{5,6,125},{5,6,125},{5,6,125},{5,5,170},{5,5,74}, +{5,5,74},{6,5,350},{6,6,424},{6,6,585},{6,5,670},{6,5,287},{6,5,415},{6,5,607},{6,5,735},{5,6,52},{6,5,588},{6,5,154},{6,6,228},{6,6,389},{6,5,474},{5,7,51},{5,6,75},{5,6,275},{6,5,539},{5,6,51},{6,5,539},{6,5,269},{6,5,269},{6,5,269},{6,5,309},{6,5,206},{6,5,246},{6,5,246},{6,5,374},{5,6,27},{6,5,227},{6,5,73}, +{6,5,73},{6,5,73},{6,5,113},{6,5,10},{6,5,50},{6,5,50},{6,5,178},{3,7,10},{6,5,178},{5,7,26},{5,6,146},{6,6,325},{5,6,226},{5,7,26},{5,6,26},{5,6,226},{0,5,530},{5,6,26},{0,5,530},{6,0,260},{6,0,260},{6,0,260},{6,0,260},{6,5,197},{6,5,197},{6,5,197},{6,5,205},{5,6,26},{5,6,26},{6,6,56},{6,6,40},{6,6,89}, +{6,6,121},{6,6,92},{6,6,108},{6,6,157},{6,6,354},{6,6,280},{5,6,308},{6,6,20},{6,6,4},{6,6,53},{6,6,85},{6,6,56},{6,6,72},{6,6,121},{5,6,227},{4,7,56},{5,6,227},{6,6,40},{6,6,40},{6,6,40},{6,6,72},{6,6,76},{6,6,108},{6,6,108},{6,6,305},{5,6,139},{5,6,259},{6,6,4},{6,6,4},{6,6,4},{6,6,36},{7,4,8}, +{6,6,72},{6,6,72},{5,6,178},{7,5,8},{5,6,178},{6,6,20},{6,6,4},{6,6,53},{6,6,85},{6,6,20},{4,7,20},{6,6,85},{0,6,218},{4,7,20},{0,6,218},{6,0,36},{6,0,36},{6,0,36},{6,0,36},{6,6,72},{6,6,72},{6,6,72},{6,6,136},{5,6,90},{5,6,90},{6,7,118},{6,6,168},{6,6,105},{6,6,73},{6,7,175},{6,6,76},{6,6,13}, +{6,6,34},{6,6,88},{6,6,46},{6,7,114},{6,6,164},{6,6,101},{6,6,69},{7,5,56},{6,6,72},{6,6,9},{6,6,30},{6,6,72},{6,6,30},{6,6,104},{6,6,104},{6,6,104},{6,6,72},{6,6,44},{6,6,12},{6,6,12},{6,6,33},{6,6,24},{6,6,45},{6,6,100},{6,6,100},{6,6,100},{6,6,68},{7,5,40},{6,6,8},{6,6,8},{6,6,29},{6,6,8}, +{6,6,29},{7,5,20},{6,6,100},{6,6,37},{6,6,5},{7,5,20},{5,7,50},{6,6,5},{0,6,26},{5,7,50},{0,6,26},{6,0,68},{6,0,68},{6,0,68},{6,0,68},{6,6,8},{6,6,8},{6,6,8},{6,6,8},{6,6,20},{6,6,20},{6,7,406},{6,7,382},{6,6,633},{6,6,537},{6,7,159},{6,7,255},{6,6,381},{6,6,226},{5,7,228},{6,6,142},{6,7,306}, +{6,7,282},{7,6,454},{7,6,414},{6,7,59},{7,6,139},{7,6,211},{6,6,126},{5,7,59},{6,6,126},{6,7,357},{6,7,357},{6,7,357},{6,6,456},{6,7,110},{6,7,230},{6,7,230},{6,6,145},{6,6,152},{6,6,61},{6,7,257},{6,7,257},{6,7,257},{7,6,333},{6,7,10},{7,6,130},{7,6,130},{6,6,45},{5,7,10},{6,6,45},{7,6,50},{6,7,26},{7,6,130}, +{7,6,90},{7,6,50},{7,6,18},{7,6,90},{0,6,90},{7,6,18},{0,6,90},{6,0,356},{6,0,356},{6,0,356},{6,0,356},{6,7,109},{6,7,109},{6,7,109},{6,6,136},{6,6,52},{6,6,52},{7,6,374},{7,6,454},{7,6,634},{7,6,666},{7,6,297},{7,6,409},{7,6,589},{7,6,697},{6,7,56},{7,6,536},{7,6,149},{7,6,229},{7,6,409},{7,6,441},{7,6,72}, +{6,7,56},{6,7,296},{7,6,472},{6,7,56},{7,6,472},{7,6,310},{7,6,310},{7,6,310},{7,6,342},{7,6,233},{7,6,265},{7,6,265},{7,6,373},{6,7,40},{7,6,212},{7,6,85},{7,6,85},{7,6,85},{7,6,117},{7,6,8},{7,6,40},{7,6,40},{7,6,148},{7,6,40},{7,6,148},{7,6,68},{6,7,116},{7,6,328},{6,7,260},{7,6,68},{6,7,20},{6,7,260}, +{0,6,468},{6,7,20},{0,6,468},{7,0,306},{7,0,306},{7,0,306},{7,0,306},{7,6,229},{7,6,229},{7,6,229},{7,6,229},{6,7,36},{6,7,36},{7,7,68},{7,7,60},{7,7,123},{7,7,163},{7,7,116},{7,7,148},{7,7,211},{7,7,430},{6,7,248},{6,7,328},{7,7,19},{7,7,11},{7,7,74},{7,7,114},{7,7,67},{7,7,99},{7,7,162},{6,7,264},{7,7,171}, +{6,7,264},{7,7,59},{7,7,59},{7,7,59},{7,7,99},{7,7,107},{7,7,147},{7,7,147},{7,7,366},{6,7,104},{6,7,264},{7,7,10},{7,7,10},{7,7,10},{7,7,50},{7,7,58},{7,7,98},{7,7,98},{6,7,200},{6,7,40},{6,7,200},{7,7,18},{7,7,10},{7,7,73},{6,7,100},{7,7,18},{7,7,50},{6,7,100},{0,7,260},{7,7,50},{0,7,260},{7,0,50}, +{7,0,50},{7,0,50},{7,0,50},{7,6,85},{7,6,85},{7,6,85},{7,6,149},{6,7,68},{6,7,68},{7,7,196},{7,7,124},{7,7,75},{7,7,51},{7,7,148},{7,7,52},{7,7,3},{7,7,46},{7,7,84},{7,7,70},{7,7,195},{7,7,123},{7,7,74},{7,7,50},{7,7,147},{7,7,51},{7,7,2},{7,7,45},{7,7,59},{7,7,45},{7,7,75},{7,7,75},{7,7,75}, +{7,7,51},{7,7,27},{7,7,3},{7,7,3},{7,7,46},{7,7,35},{7,7,70},{7,7,74},{7,7,74},{7,7,74},{7,7,50},{7,7,26},{7,7,2},{7,7,2},{7,7,45},{7,7,10},{7,7,45},{7,7,146},{7,7,74},{7,7,25},{7,7,1},{7,7,146},{7,7,50},{7,7,1},{0,7,36},{7,7,50},{0,7,36},{7,0,50},{7,0,50},{7,0,50},{7,0,50},{7,7,2}, +{7,7,2},{7,7,2},{7,7,10},{7,7,34},{7,7,34},{7,7,548},{7,7,476},{7,7,427},{7,7,355},{7,7,404},{7,7,260},{7,7,211},{7,7,106},{7,7,132},{7,7,34},{7,7,467},{7,7,395},{7,7,346},{7,7,274},{7,7,323},{7,7,179},{7,7,130},{7,7,25},{7,7,123},{7,7,25},{7,7,427},{7,7,427},{7,7,427},{7,7,355},{7,7,283},{7,7,211},{7,7,211}, +{7,7,106},{7,7,83},{7,7,34},{7,7,346},{7,7,346},{7,7,346},{7,7,274},{7,7,202},{7,7,130},{7,7,130},{7,7,25},{7,7,74},{7,7,25},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{7,0,306},{7,0,306},{7,0,306},{7,0,306},{7,7,162},{7,7,162},{7,7,162},{7,7,106},{7,7,34}, +{7,7,34},{0,0,122},{0,0,50},{0,0,1},{0,0,25},{0,0,158},{0,0,110},{0,0,61},{0,0,244},{0,0,210},{0,0,280},{0,0,122},{0,0,50},{0,0,1},{0,0,25},{0,0,158},{0,0,110},{0,0,61},{0,0,244},{0,0,174},{0,0,244},{0,0,1},{0,0,1},{0,0,1},{0,0,25},{0,0,37},{0,0,61},{0,0,61},{0,0,244},{0,0,161},{0,0,280},{0,0,1}, +{0,0,1},{0,0,1},{0,0,25},{0,0,37},{0,0,61},{0,0,61},{0,0,244},{0,0,125},{0,0,244},{0,0,122},{0,0,50},{0,0,1},{0,0,25},{0,0,122},{0,0,74},{0,0,25},{0,0,144},{0,0,74},{0,0,144},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,1,81},{0,1,81},{0,0,122}, +{0,0,82},{0,1,328},{0,0,243},{0,0,82},{0,0,129},{0,0,319},{0,0,165},{0,1,81},{0,1,81},{0,0,122},{0,0,82},{0,1,328},{0,0,243},{0,0,82},{0,0,129},{0,0,283},{0,0,129},{0,1,45},{0,1,45},{0,1,45},{0,0,18},{0,0,58},{0,0,18},{0,0,18},{0,0,65},{0,0,94},{0,0,101},{0,1,45},{0,1,45},{0,1,45},{0,0,18},{0,0,58}, +{0,0,18},{0,0,18},{0,0,65},{0,0,58},{0,0,65},{0,1,72},{0,1,72},{0,0,113},{0,0,73},{0,1,72},{1,0,104},{0,0,73},{0,0,80},{1,0,104},{0,0,80},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,0,49},{0,0,85},{0,0,85},{0,2,225},{0,1,129},{0,1,449},{0,0,498},{0,1,264},{0,1,168},{0,0,402}, +{0,0,273},{0,0,687},{0,0,309},{0,2,225},{0,1,129},{0,1,449},{0,0,498},{0,1,264},{0,1,168},{0,0,402},{0,0,273},{1,0,248},{0,0,273},{0,1,125},{0,1,125},{0,1,125},{0,1,221},{0,1,68},{0,0,146},{0,0,146},{0,0,17},{0,0,158},{0,0,53},{0,1,125},{0,1,125},{0,1,125},{0,1,221},{0,1,68},{0,0,146},{0,0,146},{0,0,17},{0,0,122}, +{0,0,17},{1,0,72},{0,1,8},{1,0,292},{1,0,260},{1,0,72},{1,0,104},{1,0,260},{0,0,272},{1,0,104},{0,0,272},{0,0,121},{0,0,121},{0,0,121},{0,0,121},{0,0,25},{0,0,25},{0,0,25},{0,0,1},{0,0,37},{0,0,37},{0,2,514},{0,2,558},{0,1,610},{0,1,514},{0,2,297},{0,1,153},{0,1,153},{0,1,777},{0,1,392},{0,0,802},{1,1,347}, +{1,1,355},{1,1,446},{0,1,465},{0,2,248},{0,1,104},{0,1,104},{0,1,728},{0,1,248},{0,1,728},{0,2,414},{0,2,414},{0,2,414},{0,1,414},{0,1,149},{0,1,53},{0,1,53},{0,0,274},{0,1,292},{0,0,226},{1,0,229},{1,0,229},{1,0,229},{1,0,261},{1,0,68},{0,1,4},{0,1,4},{1,0,160},{1,0,52},{1,0,160},{0,2,104},{1,1,130},{0,1,200}, +{0,1,104},{0,2,104},{2,0,74},{0,1,104},{0,1,584},{2,0,74},{0,1,584},{0,0,410},{0,0,410},{0,0,410},{0,0,410},{0,1,49},{0,1,49},{0,1,49},{0,0,130},{0,0,82},{0,0,82},{1,1,464},{1,1,400},{1,1,365},{1,1,397},{1,1,572},{0,2,499},{0,1,387},{0,1,435},{0,1,428},{0,1,188},{1,1,140},{1,1,76},{1,1,41},{1,1,73},{1,1,248}, +{1,1,216},{0,1,131},{0,1,179},{2,0,264},{0,1,179},{1,1,364},{1,1,364},{1,1,364},{1,1,396},{0,2,314},{0,1,386},{0,1,386},{0,1,434},{0,1,67},{0,1,187},{1,1,40},{1,1,40},{1,1,40},{1,1,72},{0,2,58},{0,1,130},{0,1,130},{0,1,178},{0,1,58},{0,1,178},{0,3,72},{1,1,40},{1,1,5},{1,1,37},{0,3,72},{1,1,72},{1,1,37}, +{0,1,170},{1,1,72},{0,1,170},{1,0,360},{1,0,360},{1,0,360},{1,0,360},{0,2,265},{0,2,265},{0,2,265},{0,1,265},{0,1,18},{0,1,18},{1,2,178},{1,2,202},{1,1,189},{1,1,157},{1,2,463},{1,1,316},{1,1,169},{1,1,238},{0,2,412},{0,1,124},{1,2,78},{1,2,102},{1,1,89},{1,1,57},{2,0,248},{0,2,99},{1,1,69},{0,1,99},{3,0,248}, +{0,1,99},{1,1,140},{1,1,140},{1,1,140},{1,1,108},{1,1,152},{1,1,120},{1,1,120},{1,1,189},{0,1,275},{0,1,75},{1,1,40},{1,1,40},{1,1,40},{1,1,8},{1,1,52},{1,1,20},{1,1,20},{0,1,50},{1,1,68},{0,1,50},{1,2,74},{1,2,98},{1,1,85},{1,1,53},{1,2,74},{0,2,74},{1,1,53},{0,1,74},{0,2,74},{0,1,74},{1,0,104}, +{1,0,104},{1,0,104},{1,0,104},{1,1,116},{1,1,116},{1,1,116},{1,1,164},{0,1,50},{0,1,50},{1,3,226},{1,2,106},{1,2,466},{1,1,429},{1,2,255},{1,2,207},{1,1,345},{1,1,238},{0,2,252},{1,1,298},{1,3,222},{1,2,102},{1,2,462},{1,1,425},{1,2,251},{1,2,203},{1,1,341},{1,1,234},{0,2,251},{1,1,234},{1,2,105},{1,2,105},{1,2,105}, +{1,1,204},{1,2,86},{1,1,120},{1,1,120},{1,1,13},{0,2,83},{1,1,73},{1,2,101},{1,2,101},{1,2,101},{1,1,200},{2,0,52},{1,1,116},{1,1,116},{1,1,9},{3,0,52},{1,1,9},{2,1,74},{1,2,2},{2,1,274},{2,1,234},{2,1,74},{4,0,74},{2,1,234},{0,1,234},{4,0,74},{0,1,234},{1,0,104},{1,0,104},{1,0,104},{1,0,104},{1,1,20}, +{1,1,20},{1,1,20},{1,1,4},{1,1,64},{1,1,64},{1,3,450},{1,2,522},{1,2,562},{1,2,490},{1,3,295},{1,2,127},{1,2,167},{1,1,750},{1,2,428},{1,1,714},{2,2,400},{2,2,416},{2,2,521},{1,2,454},{2,1,251},{1,2,91},{1,2,131},{0,2,651},{4,0,251},{0,2,651},{1,3,369},{1,3,369},{1,3,369},{1,2,369},{1,2,118},{1,2,46},{1,2,46}, +{1,1,221},{0,2,163},{1,1,185},{2,1,257},{2,1,257},{2,1,257},{2,1,281},{0,4,50},{1,2,10},{1,2,10},{2,1,146},{2,1,50},{2,1,146},{3,0,80},{2,2,160},{1,2,202},{1,2,130},{3,0,80},{3,1,80},{1,2,130},{0,1,650},{3,1,80},{0,1,650},{1,0,360},{1,0,360},{1,0,360},{1,0,360},{1,2,37},{1,2,37},{1,2,37},{1,1,100},{1,1,64}, +{1,1,64},{2,2,500},{2,2,444},{2,2,423},{2,2,463},{1,4,588},{1,3,513},{1,2,329},{1,2,441},{0,3,284},{1,2,232},{2,2,139},{2,2,83},{2,2,62},{2,2,102},{3,0,251},{2,2,243},{1,2,104},{1,2,216},{3,1,251},{1,2,216},{2,2,419},{2,2,419},{2,2,419},{2,2,459},{1,3,277},{1,2,325},{1,2,325},{1,2,437},{1,2,68},{1,2,228},{2,2,58}, +{2,2,58},{2,2,58},{2,2,98},{1,3,52},{1,2,100},{1,2,100},{1,2,212},{1,2,52},{1,2,212},{1,4,74},{2,2,34},{2,2,13},{1,2,40},{1,4,74},{2,2,74},{1,2,40},{0,2,200},{2,2,74},{0,2,200},{2,0,410},{2,0,410},{2,0,410},{2,0,410},{1,3,241},{1,3,241},{1,3,241},{1,2,241},{1,2,32},{1,2,32},{2,3,202},{2,3,250},{2,2,183}, +{2,2,159},{2,2,460},{2,2,316},{2,2,183},{2,2,274},{1,3,468},{1,2,104},{2,3,81},{2,3,129},{2,2,62},{2,2,38},{1,4,251},{1,3,96},{2,2,62},{1,2,88},{2,2,251},{1,2,88},{2,2,147},{2,2,147},{2,2,147},{2,2,123},{2,2,171},{2,2,147},{2,2,147},{2,2,238},{0,3,219},{1,2,68},{2,2,26},{2,2,26},{2,2,26},{2,2,2},{2,2,50}, +{2,2,26},{2,2,26},{1,2,52},{5,0,50},{1,2,52},{2,3,80},{2,3,128},{2,2,61},{2,2,37},{2,3,80},{6,0,80},{2,2,37},{0,2,72},{6,0,80},{0,2,72},{2,0,122},{2,0,122},{2,0,122},{2,0,122},{2,2,146},{2,2,146},{2,2,146},{2,2,202},{1,2,32},{1,2,32},{2,3,234},{2,3,90},{2,2,455},{2,2,367},{2,3,253},{2,3,253},{2,2,295}, +{2,2,210},{1,3,244},{2,2,282},{2,3,225},{2,3,81},{2,2,446},{2,2,358},{2,3,244},{2,3,244},{2,2,286},{2,2,201},{6,0,244},{2,2,201},{2,3,90},{2,3,90},{2,3,90},{2,2,171},{2,3,109},{2,2,99},{2,2,99},{2,2,14},{1,3,100},{2,2,86},{2,3,81},{2,3,81},{2,3,81},{2,2,162},{3,1,50},{2,2,90},{2,2,90},{2,2,5},{4,1,50}, +{2,2,5},{4,0,80},{2,3,0},{3,2,260},{3,2,212},{4,0,80},{5,1,80},{3,2,212},{0,2,200},{5,1,80},{0,2,200},{2,0,90},{2,0,90},{2,0,90},{2,0,90},{2,2,18},{2,2,18},{2,2,18},{2,2,10},{2,2,82},{2,2,82},{2,4,394},{2,3,442},{2,3,522},{2,3,474},{2,4,301},{2,3,109},{2,3,189},{2,2,658},{2,3,472},{2,2,634},{2,4,369}, +{2,3,417},{2,3,497},{2,3,449},{3,2,244},{2,3,84},{2,3,164},{3,2,620},{5,1,244},{3,2,620},{2,4,330},{2,4,330},{2,4,330},{2,3,330},{2,3,93},{2,3,45},{2,3,45},{2,2,174},{1,3,132},{2,2,150},{3,2,289},{3,2,289},{3,2,289},{3,2,305},{4,0,52},{2,3,20},{2,3,20},{3,2,136},{3,2,52},{3,2,136},{2,4,80},{2,3,128},{2,3,208}, +{2,3,160},{2,4,80},{7,0,80},{2,3,160},{0,2,584},{7,0,80},{0,2,584},{2,0,314},{2,0,314},{2,0,314},{2,0,314},{2,3,29},{2,3,29},{2,3,29},{2,2,74},{2,2,50},{2,2,50},{3,3,544},{3,3,496},{3,3,489},{3,3,537},{2,4,535},{2,4,535},{2,3,279},{2,3,455},{1,4,292},{2,3,284},{3,3,144},{3,3,96},{3,3,89},{3,3,137},{4,1,244}, +{3,3,276},{2,3,83},{2,3,259},{4,2,244},{2,3,259},{3,3,480},{3,3,480},{3,3,480},{3,3,528},{2,4,246},{2,3,270},{2,3,270},{2,3,446},{2,3,75},{2,3,275},{3,3,80},{3,3,80},{3,3,80},{3,3,128},{2,4,50},{2,3,74},{2,3,74},{2,3,250},{7,0,50},{2,3,250},{5,0,80},{3,3,32},{3,3,25},{2,3,34},{5,0,80},{6,1,80},{2,3,34}, +{0,3,234},{6,1,80},{0,3,234},{3,0,464},{3,0,464},{3,0,464},{3,0,464},{2,4,221},{2,4,221},{2,4,221},{2,3,221},{2,3,50},{2,3,50},{3,4,234},{3,3,304},{3,3,185},{3,3,169},{3,3,452},{3,3,324},{3,3,205},{3,3,318},{1,4,452},{2,3,92},{3,4,90},{3,3,160},{3,3,41},{3,3,25},{5,0,244},{2,4,99},{3,3,61},{2,3,83},{3,3,244}, +{2,3,83},{3,3,160},{3,3,160},{3,3,160},{3,3,144},{3,3,196},{3,3,180},{3,3,180},{3,3,293},{2,3,187},{2,3,67},{3,3,16},{3,3,16},{3,3,16},{3,3,0},{3,3,52},{3,3,36},{3,3,36},{2,3,58},{6,1,52},{2,3,58},{4,2,80},{3,3,160},{3,3,41},{3,3,25},{4,2,80},{5,2,80},{3,3,25},{0,3,74},{5,2,80},{0,3,74},{3,0,144}, +{3,0,144},{3,0,144},{3,0,144},{3,3,180},{3,3,180},{3,3,180},{3,3,244},{2,3,18},{2,3,18},{3,4,202},{3,4,82},{3,3,393},{3,3,313},{3,4,259},{3,4,307},{3,3,253},{3,3,190},{2,4,244},{3,3,274},{3,4,186},{3,4,66},{3,3,377},{3,3,297},{3,4,243},{2,4,243},{3,3,237},{3,3,174},{7,1,243},{3,3,174},{3,4,81},{3,4,81},{3,4,81}, +{3,3,144},{3,4,138},{3,3,84},{3,3,84},{3,3,21},{2,4,123},{3,3,105},{3,4,65},{3,4,65},{3,4,65},{3,3,128},{4,2,52},{3,3,68},{3,3,68},{3,3,5},{5,2,52},{3,3,5},{5,1,74},{3,4,2},{4,3,250},{4,3,194},{5,1,74},{4,3,74},{4,3,194},{0,3,170},{4,3,74},{0,3,170},{3,0,80},{3,0,80},{3,0,80},{3,0,80},{3,3,20}, +{3,3,20},{3,3,20},{3,3,20},{3,3,104},{3,3,104},{3,5,346},{3,4,370},{3,4,490},{3,4,466},{3,5,315},{3,4,99},{3,4,219},{3,3,574},{2,4,468},{3,3,562},{3,5,330},{3,4,354},{3,4,474},{3,4,450},{4,3,243},{3,4,83},{3,4,203},{3,3,558},{6,2,243},{3,3,558},{3,5,297},{3,5,297},{3,5,297},{3,4,297},{3,4,74},{3,4,50},{3,4,50}, +{3,3,133},{2,4,107},{3,3,121},{3,5,281},{3,5,281},{3,5,281},{3,4,281},{5,1,58},{3,4,34},{3,4,34},{3,3,117},{7,1,58},{3,3,117},{6,0,74},{3,4,98},{3,4,218},{3,4,194},{6,0,74},{3,4,74},{3,4,194},{0,3,522},{3,4,74},{0,3,522},{3,0,272},{3,0,272},{3,0,272},{3,0,272},{3,4,25},{3,4,25},{3,4,25},{3,3,52},{3,3,40}, +{3,3,40},{4,4,596},{4,4,556},{4,4,563},{4,4,619},{3,5,477},{3,4,477},{3,4,237},{3,4,477},{2,5,308},{3,4,344},{4,4,155},{4,4,115},{4,4,122},{4,4,178},{5,2,243},{2,5,299},{3,4,68},{2,4,308},{5,3,243},{2,4,308},{4,4,547},{4,4,547},{4,4,547},{4,4,603},{3,5,221},{3,4,221},{3,4,221},{3,4,461},{3,4,88},{3,4,328},{4,4,106}, +{4,4,106},{4,4,106},{4,4,162},{6,0,52},{3,4,52},{3,4,52},{2,4,292},{3,4,52},{2,4,292},{4,4,74},{4,4,34},{4,4,41},{3,4,32},{4,4,74},{7,2,74},{3,4,32},{0,4,272},{7,2,74},{0,4,272},{4,0,522},{4,0,522},{4,0,522},{4,0,522},{3,4,205},{3,4,205},{3,4,205},{3,4,205},{3,4,72},{3,4,72},{4,5,274},{4,4,300},{4,4,195}, +{4,4,187},{4,4,452},{4,4,340},{4,4,235},{4,4,370},{2,5,404},{3,4,88},{4,5,105},{4,4,131},{4,4,26},{4,4,18},{6,1,243},{3,5,108},{4,4,66},{3,4,84},{4,4,243},{3,4,84},{4,4,179},{4,4,179},{4,4,179},{4,4,171},{4,4,227},{4,4,219},{4,4,219},{4,4,354},{3,4,152},{3,4,72},{4,4,10},{4,4,10},{4,4,10},{4,4,2},{5,2,58}, +{4,4,50},{4,4,50},{3,4,68},{7,2,58},{3,4,68},{5,3,74},{4,4,130},{4,4,25},{4,4,17},{5,3,74},{6,3,74},{4,4,17},{0,4,80},{6,3,74},{0,4,80},{4,0,170},{4,0,170},{4,0,170},{4,0,170},{4,3,205},{4,3,205},{4,3,205},{4,3,269},{3,4,8},{3,4,8},{4,5,178},{4,5,82},{4,4,339},{4,4,267},{4,5,273},{4,5,369},{4,4,219}, +{4,4,178},{3,5,252},{4,4,274},{4,5,153},{4,5,57},{4,4,314},{4,4,242},{7,0,248},{3,5,204},{4,4,194},{4,4,153},{3,5,248},{4,4,153},{4,5,78},{4,5,78},{4,5,78},{4,4,123},{4,4,147},{4,4,75},{4,4,75},{4,4,34},{3,5,152},{4,4,130},{4,5,53},{4,5,53},{4,5,53},{4,4,98},{6,1,58},{4,4,50},{4,4,50},{4,4,9},{6,3,58}, +{4,4,9},{6,2,72},{4,5,8},{5,4,244},{5,4,180},{6,2,72},{5,4,72},{5,4,180},{0,4,144},{5,4,72},{0,4,144},{4,0,74},{4,0,74},{4,0,74},{4,0,74},{4,4,26},{4,4,26},{4,4,26},{4,4,34},{4,4,130},{4,4,130},{4,6,306},{4,5,306},{4,5,466},{4,5,466},{4,6,337},{4,5,97},{4,5,257},{4,4,498},{3,5,412},{4,4,498},{4,6,297}, +{4,5,297},{4,5,457},{4,5,457},{5,4,248},{4,5,88},{4,5,248},{4,4,489},{7,3,248},{4,4,489},{4,5,270},{4,5,270},{4,5,270},{4,5,270},{4,5,61},{4,5,61},{4,5,61},{4,4,98},{3,5,88},{4,4,98},{4,5,261},{4,5,261},{4,5,261},{4,5,261},{7,0,52},{4,5,52},{4,5,52},{4,4,89},{3,5,52},{4,4,89},{7,1,72},{4,5,72},{4,5,232}, +{3,5,232},{7,1,72},{4,5,72},{3,5,232},{0,4,464},{4,5,72},{0,4,464},{4,0,234},{4,0,234},{4,0,234},{4,0,234},{4,5,25},{4,5,25},{4,5,25},{4,4,34},{4,4,34},{4,4,34},{5,5,656},{5,5,624},{5,5,645},{5,5,709},{4,6,427},{4,5,403},{4,5,203},{4,5,507},{4,5,332},{4,5,412},{5,5,172},{5,5,140},{5,5,161},{5,5,225},{6,3,248}, +{4,5,259},{4,5,59},{3,5,339},{6,4,248},{3,5,339},{5,5,620},{5,5,620},{5,5,620},{5,5,684},{4,6,202},{4,5,178},{4,5,178},{4,5,482},{4,5,107},{4,5,387},{5,5,136},{5,5,136},{5,5,136},{5,5,200},{7,1,58},{4,5,34},{4,5,34},{5,4,290},{7,3,58},{5,4,290},{5,5,72},{5,5,40},{5,5,61},{4,5,34},{5,5,72},{3,6,72},{4,5,34}, +{0,5,314},{3,6,72},{0,5,314},{5,0,584},{5,0,584},{5,0,584},{5,0,584},{4,5,169},{4,5,169},{4,5,169},{4,5,193},{4,5,98},{4,5,98},{5,6,322},{5,5,304},{5,5,213},{5,5,213},{5,5,460},{5,5,364},{5,5,273},{5,5,430},{3,6,364},{4,5,92},{5,6,126},{5,5,108},{5,5,17},{5,5,17},{7,2,248},{4,6,123},{5,5,77},{4,5,91},{5,5,248}, +{4,5,91},{5,5,204},{5,5,204},{5,5,204},{5,5,204},{5,5,264},{5,5,264},{5,5,264},{5,5,421},{4,5,123},{4,5,83},{5,5,8},{5,5,8},{5,5,8},{5,5,8},{6,3,52},{5,5,68},{5,5,68},{4,5,82},{6,4,52},{4,5,82},{6,4,72},{5,5,104},{5,5,13},{5,5,13},{6,4,72},{7,4,72},{5,5,13},{0,5,90},{7,4,72},{0,5,90},{5,0,200}, +{5,0,200},{5,0,200},{5,0,200},{5,4,221},{5,4,221},{5,4,221},{5,4,277},{4,5,2},{4,5,2},{5,6,162},{5,6,90},{5,5,293},{5,5,229},{5,6,295},{5,5,396},{5,5,193},{5,5,174},{4,6,268},{5,5,282},{5,6,126},{5,6,54},{5,5,257},{5,5,193},{5,6,259},{4,6,171},{5,5,157},{5,5,138},{4,6,259},{5,5,138},{5,6,81},{5,6,81},{5,6,81}, +{5,5,108},{5,5,136},{5,5,72},{5,5,72},{5,5,53},{4,6,187},{5,5,161},{5,6,45},{5,6,45},{5,6,45},{5,5,72},{7,2,52},{5,5,36},{5,5,36},{5,5,17},{5,5,52},{5,5,17},{7,3,74},{5,6,18},{5,5,221},{5,5,157},{7,3,74},{6,5,74},{5,5,157},{0,5,122},{6,5,74},{0,5,122},{5,0,72},{5,0,72},{5,0,72},{5,0,72},{5,5,36}, +{5,5,36},{5,5,36},{5,5,52},{5,5,160},{5,5,160},{5,7,274},{5,6,250},{5,6,450},{5,6,474},{5,6,343},{5,6,103},{5,6,303},{5,5,430},{4,6,364},{5,5,442},{5,7,270},{5,6,246},{5,6,446},{5,6,470},{7,3,251},{5,6,99},{5,6,299},{5,5,426},{6,5,251},{5,5,426},{5,6,225},{5,6,225},{5,6,225},{5,6,249},{5,6,54},{5,6,78},{5,6,78}, +{5,5,69},{4,6,75},{5,5,81},{5,6,221},{5,6,221},{5,6,221},{5,6,245},{5,6,50},{5,6,74},{5,6,74},{5,5,65},{4,6,50},{5,5,65},{5,7,74},{5,6,50},{5,6,250},{4,6,250},{5,7,74},{5,6,74},{4,6,250},{0,5,410},{5,6,74},{0,5,410},{5,0,200},{5,0,200},{5,0,200},{5,0,200},{5,6,29},{5,6,29},{5,6,29},{5,5,20},{5,5,32}, +{5,5,32},{6,6,724},{6,6,700},{6,6,735},{5,6,690},{5,7,385},{5,6,337},{5,6,177},{5,6,545},{5,6,328},{5,6,488},{6,6,195},{6,6,171},{6,6,206},{6,6,278},{7,4,259},{5,6,216},{5,6,56},{4,6,376},{7,5,259},{4,6,376},{5,7,654},{5,7,654},{5,7,654},{5,6,654},{5,7,189},{5,6,141},{5,6,141},{5,6,509},{5,6,132},{5,5,450},{6,5,157}, +{6,5,157},{6,5,157},{6,5,221},{6,5,52},{5,6,20},{5,6,20},{6,5,256},{3,7,52},{6,5,256},{6,6,74},{6,6,50},{6,6,85},{5,6,40},{6,6,74},{4,7,74},{5,6,40},{0,6,360},{4,7,74},{0,6,360},{5,0,650},{5,0,650},{5,0,650},{5,0,650},{5,6,137},{5,6,137},{5,6,137},{5,6,185},{5,6,128},{5,6,128},{6,7,378},{6,6,316},{6,6,239}, +{6,6,247},{6,6,476},{6,6,396},{6,6,319},{5,6,465},{4,7,332},{5,6,104},{6,7,153},{6,6,91},{6,6,14},{6,6,22},{6,6,251},{5,7,144},{6,6,94},{5,6,104},{4,7,251},{5,6,104},{6,6,235},{6,6,235},{6,6,235},{6,6,243},{6,6,307},{6,6,315},{6,6,315},{5,6,461},{5,6,100},{5,6,100},{6,6,10},{6,6,10},{6,6,10},{6,6,18},{7,4,50}, +{6,6,90},{6,6,90},{5,6,100},{7,5,50},{5,6,100},{7,5,74},{6,6,82},{6,6,5},{6,6,13},{7,5,74},{6,6,90},{6,6,13},{0,6,104},{6,6,90},{0,6,104},{6,0,234},{6,0,234},{6,0,234},{6,0,234},{6,5,241},{6,5,241},{6,5,241},{6,5,289},{5,6,0},{5,6,0},{6,7,154},{6,7,106},{6,6,255},{6,6,199},{6,7,325},{6,6,364},{6,6,175}, +{6,6,178},{5,7,292},{5,6,232},{6,7,105},{6,7,57},{6,6,206},{6,6,150},{7,5,251},{5,7,144},{6,6,126},{6,6,129},{5,7,276},{6,6,129},{6,7,90},{6,7,90},{6,7,90},{6,6,99},{6,6,131},{6,6,75},{6,6,75},{6,6,78},{6,6,219},{5,6,132},{6,7,41},{6,7,41},{6,7,41},{6,6,50},{7,5,82},{6,6,26},{6,6,26},{6,6,29},{6,6,50}, +{6,6,29},{6,7,80},{6,7,32},{6,6,181},{6,6,125},{6,7,80},{7,6,80},{6,6,125},{0,6,104},{7,6,80},{0,6,104},{6,0,74},{6,0,74},{6,0,74},{6,0,74},{6,6,50},{6,6,50},{6,6,50},{6,6,74},{5,6,128},{5,6,128},{6,7,442},{6,7,202},{6,7,442},{6,7,490},{6,7,309},{6,7,117},{6,7,357},{6,6,370},{5,7,324},{6,6,394},{6,7,441}, +{6,7,201},{6,7,441},{6,7,489},{7,6,276},{6,7,116},{6,7,356},{6,6,369},{7,6,244},{6,6,369},{6,7,186},{6,7,186},{6,7,186},{6,7,234},{6,7,53},{6,7,101},{6,7,101},{6,6,46},{5,7,68},{6,6,70},{6,7,185},{6,7,185},{6,7,185},{6,7,233},{6,7,52},{6,7,100},{6,7,100},{6,6,45},{5,7,52},{6,6,45},{7,6,80},{6,7,32},{6,7,272}, +{5,7,272},{7,6,80},{6,7,80},{5,7,272},{0,6,360},{6,7,80},{0,6,360},{6,0,170},{6,0,170},{6,0,170},{6,0,170},{6,7,37},{6,7,37},{6,7,37},{6,6,10},{6,6,34},{6,6,34},{7,7,800},{7,7,784},{6,7,802},{6,7,634},{6,7,903},{6,7,279},{6,7,159},{6,7,591},{6,7,332},{6,7,572},{7,7,224},{7,7,208},{7,7,257},{7,7,337},{7,6,339}, +{6,7,179},{6,7,59},{5,7,419},{6,7,251},{5,7,419},{7,6,745},{7,6,745},{7,6,745},{6,7,585},{6,7,278},{6,7,110},{6,7,110},{6,6,469},{6,7,163},{6,6,385},{7,6,169},{7,6,169},{7,6,169},{7,6,225},{7,6,50},{6,7,10},{6,7,10},{7,6,226},{7,6,82},{7,6,226},{7,7,80},{7,7,64},{7,7,113},{6,7,50},{7,7,80},{7,7,144},{6,7,50}, +{0,7,410},{7,7,144},{0,7,410},{6,0,584},{6,0,584},{6,0,584},{6,0,584},{6,7,109},{6,7,109},{6,7,109},{6,7,181},{6,6,160},{6,6,160},{7,7,393},{7,7,321},{7,7,272},{7,7,288},{7,7,477},{7,7,421},{7,7,372},{6,7,446},{6,7,483},{6,7,123},{7,7,137},{7,7,65},{7,7,16},{7,7,32},{7,7,221},{7,7,165},{7,7,116},{6,7,122},{7,7,261}, +{6,7,122},{7,7,272},{7,7,272},{7,7,272},{7,7,288},{7,7,356},{7,7,372},{7,7,372},{6,7,446},{6,7,83},{6,7,123},{7,7,16},{7,7,16},{7,7,16},{7,7,32},{7,7,100},{7,7,116},{7,7,116},{6,7,122},{6,7,82},{6,7,122},{7,7,121},{7,7,49},{7,7,0},{7,7,16},{7,7,121},{7,7,65},{7,7,16},{0,7,121},{7,7,65},{0,7,121},{7,0,272}, +{7,0,272},{7,0,272},{7,0,272},{7,6,265},{7,6,265},{7,6,265},{7,6,305},{6,7,2},{6,7,2},{7,7,265},{7,7,193},{7,7,144},{7,7,96},{7,7,253},{7,7,133},{7,7,84},{7,7,109},{7,7,297},{6,7,107},{7,7,201},{7,7,129},{7,7,80},{7,7,32},{7,7,189},{7,7,69},{7,7,20},{7,7,45},{7,7,101},{7,7,45},{7,7,144},{7,7,144},{7,7,144}, +{7,7,96},{7,7,132},{7,7,84},{7,7,84},{7,7,109},{7,7,248},{6,7,107},{7,7,80},{7,7,80},{7,7,80},{7,7,32},{7,7,68},{7,7,20},{7,7,20},{7,7,45},{7,7,52},{7,7,45},{7,7,185},{7,7,113},{7,7,64},{7,7,16},{7,7,185},{7,7,65},{7,7,16},{0,7,9},{7,7,65},{0,7,9},{7,0,80},{7,0,80},{7,0,80},{7,0,80},{7,7,68}, +{7,7,68},{7,7,68},{7,7,100},{6,7,98},{6,7,98},{7,7,386},{7,7,314},{7,7,265},{7,7,193},{7,7,278},{7,7,134},{7,7,85},{7,7,4},{7,7,138},{7,7,40},{7,7,386},{7,7,314},{7,7,265},{7,7,193},{7,7,278},{7,7,134},{7,7,85},{7,7,4},{7,7,102},{7,7,4},{7,7,265},{7,7,265},{7,7,265},{7,7,193},{7,7,157},{7,7,85},{7,7,85}, +{7,7,4},{7,7,89},{7,7,40},{7,7,265},{7,7,265},{7,7,265},{7,7,193},{7,7,157},{7,7,85},{7,7,85},{7,7,4},{7,7,53},{7,7,4},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{7,0,144},{7,0,144},{7,0,144},{7,0,144},{7,7,36},{7,7,36},{7,7,36},{7,7,4},{7,7,40}, +{7,7,40},{0,1,200},{0,1,104},{0,0,153},{0,0,145},{0,1,561},{0,0,398},{0,0,181},{0,0,308},{0,0,498},{0,0,344},{0,1,200},{0,1,104},{0,0,153},{0,0,145},{0,1,561},{0,0,398},{0,0,181},{0,0,308},{0,0,462},{0,0,308},{0,0,9},{0,0,9},{0,0,9},{0,0,1},{0,0,45},{0,0,37},{0,0,37},{0,0,164},{0,0,137},{0,0,200},{0,0,9}, +{0,0,9},{0,0,9},{0,0,1},{0,0,45},{0,0,37},{0,0,37},{0,0,164},{0,0,101},{0,0,164},{0,1,200},{0,1,104},{0,0,153},{0,0,145},{0,1,200},{1,0,232},{0,0,145},{0,0,208},{1,0,232},{0,0,208},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,2,232},{0,1,40},{0,1,200}, +{0,1,392},{0,1,689},{0,1,593},{0,0,485},{0,0,500},{0,0,914},{0,0,536},{0,2,232},{0,1,40},{0,1,200},{0,1,392},{0,1,689},{0,1,593},{0,0,485},{0,0,500},{1,0,761},{0,0,500},{0,1,4},{0,1,4},{0,1,4},{0,0,49},{0,0,157},{0,0,85},{0,0,85},{0,0,100},{0,0,185},{0,0,136},{0,1,4},{0,1,4},{0,1,4},{0,0,49},{0,0,157}, +{0,0,85},{0,0,85},{0,0,100},{0,0,149},{0,0,100},{1,0,200},{0,1,40},{0,1,200},{0,1,392},{1,0,200},{1,0,232},{0,1,392},{0,0,400},{1,0,232},{0,0,400},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,2,281},{0,2,149},{0,1,121},{0,1,121},{0,2,808},{0,1,376},{0,1,216}, +{0,0,857},{0,1,1169},{0,0,893},{0,2,281},{0,2,149},{0,1,121},{0,1,121},{1,0,728},{0,1,376},{0,1,216},{0,0,857},{1,0,744},{0,0,857},{0,1,85},{0,1,85},{0,1,85},{0,1,85},{0,1,180},{0,1,180},{0,1,180},{0,0,73},{0,0,270},{0,0,109},{0,1,85},{0,1,85},{0,1,85},{0,1,85},{0,1,180},{0,1,180},{0,1,180},{0,0,73},{0,0,234}, +{0,0,73},{0,2,232},{0,2,100},{0,1,72},{0,1,72},{0,2,232},{2,0,202},{0,1,72},{0,1,712},{2,0,202},{0,1,712},{0,0,49},{0,0,49},{0,0,49},{0,0,49},{0,0,1},{0,0,1},{0,0,1},{0,0,9},{0,0,45},{0,0,45},{0,3,427},{0,2,229},{0,1,425},{0,1,233},{0,2,744},{0,1,504},{0,1,24},{0,1,584},{0,1,1105},{0,1,945},{0,3,427}, +{0,2,229},{1,1,414},{0,1,233},{0,2,744},{0,1,504},{0,1,24},{0,1,584},{2,0,739},{0,1,584},{0,2,229},{0,2,229},{0,2,229},{0,1,229},{0,1,212},{0,1,20},{0,1,20},{0,0,281},{0,0,590},{0,0,317},{0,2,229},{0,2,229},{0,2,229},{0,1,229},{1,0,180},{0,1,20},{0,1,20},{0,0,281},{1,0,164},{0,0,281},{0,3,202},{0,2,4},{1,1,53}, +{0,1,8},{0,3,202},{1,1,202},{0,1,8},{0,1,328},{1,1,202},{0,1,328},{0,0,225},{0,0,225},{0,0,225},{0,0,225},{0,1,16},{0,1,16},{0,1,16},{0,0,25},{0,0,61},{0,0,61},{0,4,842},{0,3,740},{1,1,1125},{0,1,834},{0,3,744},{0,2,267},{0,1,283},{0,1,267},{0,1,1356},{0,1,476},{1,2,302},{1,2,230},{1,1,225},{1,1,225},{0,3,728}, +{0,2,251},{0,1,267},{0,1,251},{1,1,728},{0,1,251},{0,3,596},{0,3,596},{0,3,596},{0,1,713},{0,2,186},{0,1,162},{0,1,162},{0,1,146},{0,1,395},{0,1,355},{1,1,104},{1,1,104},{1,1,104},{1,1,104},{0,2,170},{0,1,146},{0,1,146},{0,1,130},{0,1,170},{0,1,130},{1,2,202},{1,2,130},{1,1,125},{1,1,125},{1,2,202},{0,2,202},{1,1,125}, +{0,1,202},{0,2,202},{0,1,202},{0,0,592},{0,0,592},{0,0,592},{0,0,592},{0,1,41},{0,1,41},{0,1,41},{0,1,65},{0,0,200},{0,0,200},{1,3,738},{1,2,522},{1,2,722},{1,1,885},{0,4,987},{0,2,443},{0,2,379},{0,1,507},{0,2,1100},{0,1,412},{1,3,254},{1,2,38},{1,2,238},{1,1,401},{1,2,739},{0,2,299},{0,2,235},{0,1,363},{0,2,739}, +{0,1,363},{1,2,497},{1,2,497},{1,2,497},{1,1,524},{0,3,324},{0,2,154},{0,2,154},{0,1,146},{0,1,411},{0,1,51},{1,2,13},{1,2,13},{1,2,13},{1,1,40},{1,1,164},{0,2,10},{0,2,10},{0,1,2},{1,1,180},{0,1,2},{2,1,202},{1,2,34},{1,2,234},{0,2,234},{2,1,202},{4,0,202},{0,2,234},{0,1,362},{4,0,202},{0,1,362},{1,0,488}, +{1,0,488},{1,0,488},{1,0,488},{0,2,145},{0,2,145},{0,2,145},{0,1,145},{0,1,50},{0,1,50},{1,3,450},{1,3,362},{1,2,306},{1,2,330},{1,2,1015},{1,2,583},{1,2,463},{1,1,990},{0,2,940},{0,1,860},{1,3,254},{1,3,166},{1,2,110},{1,2,134},{0,4,731},{0,3,288},{0,2,155},{1,1,794},{2,1,731},{1,1,794},{1,2,257},{1,2,257},{1,2,257}, +{1,2,281},{1,2,390},{1,1,392},{1,1,392},{1,1,261},{0,2,315},{0,1,131},{1,2,61},{1,2,61},{1,2,61},{1,2,85},{2,0,164},{0,2,106},{0,2,106},{1,1,65},{3,0,164},{1,1,65},{3,0,208},{1,3,130},{1,2,74},{0,2,74},{3,0,208},{3,1,208},{0,2,74},{0,1,778},{3,1,208},{0,1,778},{1,0,232},{1,0,232},{1,0,232},{1,0,232},{1,1,196}, +{1,1,196},{1,1,196},{1,1,212},{0,1,82},{0,1,82},{1,4,440},{1,3,234},{1,2,402},{1,2,234},{1,3,767},{1,2,503},{1,2,63},{1,2,687},{0,3,1140},{0,2,396},{1,4,404},{1,3,198},{1,2,366},{1,2,198},{1,3,731},{0,3,224},{1,2,27},{0,2,387},{1,2,731},{0,2,387},{1,3,233},{1,3,233},{1,3,233},{1,2,233},{1,2,230},{1,2,62},{1,2,62}, +{1,1,277},{0,2,203},{1,1,385},{1,3,197},{1,3,197},{1,3,197},{1,2,197},{0,4,162},{1,2,26},{1,2,26},{1,1,241},{2,1,162},{1,1,241},{2,2,208},{1,3,2},{2,2,65},{1,2,2},{2,2,208},{5,0,208},{1,2,2},{0,2,362},{5,0,208},{0,2,362},{1,0,232},{1,0,232},{1,0,232},{1,0,232},{1,2,61},{1,2,61},{1,2,61},{1,1,52},{0,2,34}, +{0,2,34},{1,5,810},{1,3,702},{1,2,1122},{1,2,738},{1,4,748},{1,3,281},{1,2,225},{1,2,273},{0,3,780},{0,2,252},{2,3,329},{2,3,281},{2,2,222},{2,2,230},{2,2,731},{1,3,272},{1,2,216},{0,2,216},{5,0,731},{0,2,216},{1,4,547},{1,4,547},{1,4,547},{1,2,638},{1,3,173},{1,2,125},{1,2,125},{1,2,173},{0,3,339},{0,2,152},{2,2,122}, +{2,2,122},{2,2,122},{2,2,130},{1,3,164},{1,2,116},{1,2,116},{0,2,116},{1,2,164},{0,2,116},{2,3,208},{2,3,160},{2,2,101},{2,2,109},{2,3,208},{6,0,208},{2,2,109},{0,2,200},{6,0,208},{0,2,200},{1,0,538},{1,0,538},{1,0,538},{1,0,538},{1,2,25},{1,2,25},{1,2,25},{1,2,73},{0,2,52},{0,2,52},{2,3,810},{2,3,570},{2,3,810}, +{2,2,887},{1,4,940},{1,3,393},{1,3,393},{1,2,449},{0,3,1004},{1,2,392},{2,3,281},{2,3,41},{2,3,281},{2,2,358},{3,1,731},{1,3,272},{1,3,272},{1,2,328},{4,1,731},{1,2,328},{2,3,554},{2,3,554},{2,3,554},{2,2,563},{1,4,315},{1,3,137},{1,3,137},{1,2,125},{0,3,163},{1,2,68},{2,3,25},{2,3,25},{2,3,25},{2,2,34},{2,2,162}, +{1,3,16},{1,3,16},{1,2,4},{5,0,162},{1,2,4},{4,0,208},{2,3,32},{2,3,272},{1,3,272},{4,0,208},{5,1,208},{1,3,272},{0,2,328},{5,1,208},{0,2,328},{2,0,538},{2,0,538},{2,0,538},{2,0,538},{1,3,121},{1,3,121},{1,3,121},{1,2,121},{1,2,64},{1,2,64},{2,4,458},{2,3,410},{2,3,330},{2,3,378},{2,3,1013},{2,3,629},{1,3,505}, +{2,2,962},{0,4,772},{1,2,776},{2,4,233},{2,3,185},{2,3,105},{2,3,153},{4,0,724},{1,4,323},{1,3,144},{2,2,737},{3,2,724},{2,2,737},{2,3,266},{2,3,266},{2,3,266},{2,3,314},{2,3,437},{2,2,395},{2,2,395},{2,2,286},{1,3,356},{1,2,100},{2,3,41},{2,3,41},{2,3,41},{2,3,89},{3,1,162},{1,3,80},{1,3,80},{2,2,61},{4,1,162}, +{2,2,61},{2,4,208},{2,3,160},{2,3,80},{1,3,80},{2,4,208},{7,0,208},{1,3,80},{0,2,712},{7,0,208},{0,2,712},{2,0,250},{2,0,250},{2,0,250},{2,0,250},{2,2,226},{2,2,226},{2,2,226},{2,2,250},{1,2,64},{1,2,64},{2,5,436},{2,4,222},{2,3,362},{2,3,218},{2,4,773},{2,3,485},{2,3,85},{2,3,773},{0,4,804},{1,3,452},{2,5,387}, +{2,4,173},{2,3,313},{2,3,169},{2,4,724},{1,4,211},{2,3,36},{1,3,436},{7,0,724},{1,3,436},{2,4,218},{2,4,218},{2,4,218},{2,3,218},{2,3,229},{2,3,85},{2,3,85},{2,2,254},{1,3,196},{2,2,374},{2,4,169},{2,4,169},{2,4,169},{2,3,169},{4,0,164},{2,3,36},{2,3,36},{2,2,205},{3,2,164},{2,2,205},{3,3,202},{2,4,4},{3,3,81}, +{2,3,0},{3,3,202},{6,1,202},{2,3,0},{0,3,400},{6,1,202},{0,3,400},{2,0,218},{2,0,218},{2,0,218},{2,0,218},{2,3,85},{2,3,85},{2,3,85},{2,2,58},{1,3,52},{1,3,52},{2,5,760},{2,4,618},{2,3,1010},{2,3,650},{2,5,760},{2,4,303},{2,3,175},{2,3,287},{1,4,788},{1,3,236},{3,4,362},{3,4,338},{3,3,225},{3,3,241},{3,3,724}, +{2,4,299},{2,3,171},{1,3,211},{6,1,724},{1,3,211},{2,5,504},{2,5,504},{2,5,504},{2,3,569},{2,4,166},{2,3,94},{2,3,94},{2,3,206},{0,4,363},{1,3,155},{3,3,144},{3,3,144},{3,3,144},{3,3,160},{2,4,162},{2,3,90},{2,3,90},{1,3,130},{7,0,162},{1,3,130},{4,2,208},{2,4,130},{3,3,81},{3,3,97},{4,2,208},{5,2,208},{3,3,97}, +{0,3,202},{5,2,208},{0,3,202},{2,0,488},{2,0,488},{2,0,488},{2,0,488},{2,3,13},{2,3,13},{2,3,13},{2,3,85},{1,3,34},{1,3,34},{3,4,842},{3,4,626},{3,4,906},{3,3,897},{2,5,888},{2,4,351},{2,4,415},{2,3,399},{0,5,788},{2,3,380},{3,4,266},{3,4,50},{3,4,330},{3,3,321},{4,2,724},{2,4,251},{2,4,315},{2,3,299},{5,2,724}, +{2,3,299},{3,4,617},{3,4,617},{3,4,617},{3,3,608},{2,5,312},{2,4,126},{2,4,126},{2,3,110},{1,4,164},{2,3,91},{3,4,41},{3,4,41},{3,4,41},{3,3,32},{3,3,164},{2,4,26},{2,4,26},{2,3,10},{6,1,164},{2,3,10},{5,1,202},{3,4,34},{3,4,314},{3,3,305},{5,1,202},{4,3,202},{3,3,305},{0,3,298},{4,3,202},{0,3,298},{3,0,592}, +{3,0,592},{3,0,592},{3,0,592},{2,4,101},{2,4,101},{2,4,101},{2,3,101},{2,3,82},{2,3,82},{3,5,474},{3,4,402},{3,4,362},{3,4,434},{3,4,1019},{3,4,683},{2,4,463},{3,3,942},{1,5,804},{2,3,700},{3,5,218},{3,4,146},{3,4,106},{3,4,178},{5,1,723},{2,5,364},{2,4,139},{3,3,686},{4,3,723},{3,3,686},{3,4,281},{3,4,281},{3,4,281}, +{3,4,353},{3,4,490},{2,4,382},{2,4,382},{3,3,317},{1,4,324},{2,3,75},{3,4,25},{3,4,25},{3,4,25},{3,4,97},{4,2,164},{2,4,58},{2,4,58},{3,3,61},{5,2,164},{3,3,61},{6,0,202},{3,4,130},{3,4,90},{2,4,90},{6,0,202},{3,4,202},{2,4,90},{0,3,650},{3,4,202},{0,3,650},{3,0,272},{3,0,272},{3,0,272},{3,0,272},{3,3,260}, +{3,3,260},{3,3,260},{3,3,292},{2,3,50},{2,3,50},{3,6,440},{3,5,218},{3,4,330},{3,4,210},{3,5,787},{3,4,475},{3,4,115},{3,4,867},{1,5,772},{2,4,516},{3,6,376},{3,5,154},{3,4,266},{3,4,146},{6,0,723},{2,5,204},{3,4,51},{1,4,478},{3,4,723},{1,4,478},{3,5,209},{3,5,209},{3,5,209},{3,4,209},{3,4,234},{3,4,114},{3,4,114}, +{3,3,237},{2,4,195},{3,3,369},{3,5,145},{3,5,145},{3,5,145},{3,4,145},{5,1,170},{3,4,50},{3,4,50},{3,3,173},{7,1,170},{3,3,173},{4,4,200},{3,5,10},{4,4,101},{3,4,2},{4,4,200},{7,2,200},{3,4,2},{0,4,442},{7,2,200},{0,4,442},{3,0,208},{3,0,208},{3,0,208},{3,0,208},{3,3,100},{3,3,100},{3,3,100},{3,3,68},{2,4,74}, +{2,4,74},{3,6,692},{3,5,542},{3,4,906},{3,4,570},{3,6,780},{3,5,333},{3,4,133},{3,4,309},{2,5,804},{2,4,228},{4,5,401},{4,4,395},{4,4,234},{4,4,258},{4,4,723},{3,5,332},{3,4,132},{2,4,212},{7,2,723},{2,4,212},{3,6,467},{3,6,467},{3,6,467},{3,4,506},{3,5,165},{3,4,69},{3,4,69},{3,4,245},{1,5,324},{2,4,164},{4,4,170}, +{4,4,170},{4,4,170},{4,4,194},{6,0,164},{3,4,68},{3,4,68},{2,4,148},{3,4,164},{2,4,148},{5,3,202},{3,5,100},{4,4,65},{4,4,89},{5,3,202},{6,3,202},{4,4,89},{0,4,208},{6,3,202},{0,4,208},{3,0,442},{3,0,442},{3,0,442},{3,0,442},{3,4,5},{3,4,5},{3,4,5},{3,4,101},{2,4,20},{2,4,20},{4,5,882},{4,5,690},{4,4,955}, +{4,4,915},{3,6,844},{3,5,317},{3,5,445},{3,4,357},{1,6,772},{3,4,376},{4,5,257},{4,5,65},{4,4,330},{4,4,290},{5,3,723},{3,5,236},{3,5,364},{3,4,276},{6,3,723},{3,4,276},{4,5,686},{4,5,686},{4,5,686},{4,4,659},{3,6,315},{3,5,121},{3,5,121},{3,4,101},{2,5,171},{3,4,120},{4,5,61},{4,5,61},{4,5,61},{4,4,34},{5,2,170}, +{3,5,40},{3,5,40},{3,4,20},{7,2,170},{3,4,20},{6,2,200},{4,5,40},{4,4,305},{4,4,265},{6,2,200},{5,4,200},{4,4,265},{0,4,272},{5,4,200},{0,4,272},{4,0,650},{4,0,650},{4,0,650},{4,0,650},{3,5,85},{3,5,85},{3,5,85},{3,4,85},{3,4,104},{3,4,104},{4,6,498},{4,5,402},{4,5,402},{4,5,498},{3,7,1017},{3,6,700},{3,5,429}, +{3,4,917},{2,6,844},{3,4,632},{4,6,209},{4,5,113},{4,5,113},{4,5,209},{6,2,728},{3,6,411},{3,5,140},{3,4,628},{5,4,728},{3,4,628},{4,5,302},{4,5,302},{4,5,302},{4,5,398},{3,6,459},{3,5,329},{3,5,329},{3,4,341},{2,5,283},{3,4,56},{4,5,13},{4,5,13},{4,5,13},{4,5,109},{6,1,170},{3,5,40},{3,5,40},{3,4,52},{6,3,170}, +{3,4,52},{7,1,200},{4,5,104},{4,5,104},{3,5,104},{7,1,200},{4,5,200},{3,5,104},{0,4,592},{4,5,200},{0,4,592},{4,0,298},{4,0,298},{4,0,298},{4,0,298},{4,4,298},{4,4,298},{4,4,298},{3,4,325},{3,4,40},{3,4,40},{4,7,452},{4,6,222},{4,5,306},{4,5,210},{4,6,809},{4,5,473},{4,5,153},{4,5,969},{2,6,748},{3,5,588},{4,7,371}, +{4,6,141},{4,5,225},{4,5,129},{7,1,728},{3,6,203},{4,5,72},{2,5,513},{4,5,728},{2,5,513},{4,6,206},{4,6,206},{4,6,206},{4,5,206},{4,5,245},{4,5,149},{4,5,149},{4,4,226},{3,5,200},{4,4,370},{4,6,125},{4,6,125},{4,6,125},{4,5,125},{7,0,164},{4,5,68},{4,5,68},{4,4,145},{3,5,164},{4,4,145},{5,5,202},{4,6,20},{4,5,104}, +{4,5,8},{5,5,202},{3,6,202},{4,5,8},{0,5,488},{3,6,202},{0,5,488},{4,0,202},{4,0,202},{4,0,202},{4,0,202},{4,4,106},{4,4,106},{4,4,106},{4,4,82},{3,5,100},{3,5,100},{4,7,632},{4,6,474},{4,5,810},{4,5,498},{4,7,808},{4,6,371},{4,5,99},{4,5,339},{3,6,828},{3,5,228},{5,6,446},{5,5,396},{5,5,249},{5,5,281},{5,5,728}, +{4,6,371},{4,5,99},{3,5,219},{3,6,728},{3,5,219},{4,7,436},{4,7,436},{4,7,436},{4,5,449},{4,6,170},{4,5,50},{4,5,50},{4,5,290},{2,6,291},{3,5,179},{5,5,200},{5,5,200},{5,5,200},{5,5,232},{7,1,170},{4,5,50},{4,5,50},{3,5,170},{7,3,170},{3,5,170},{6,4,200},{4,6,74},{5,5,53},{5,5,85},{6,4,200},{7,4,200},{5,5,85}, +{0,5,218},{7,4,200},{0,5,218},{4,0,400},{4,0,400},{4,0,400},{4,0,400},{4,5,1},{4,5,1},{4,5,1},{4,4,100},{3,5,10},{3,5,10},{5,6,930},{5,6,762},{5,5,973},{5,5,941},{4,7,808},{4,6,291},{4,6,483},{4,5,323},{2,7,764},{4,5,380},{5,6,254},{5,6,86},{5,5,297},{5,5,265},{6,4,728},{4,6,227},{5,5,373},{4,5,259},{7,4,728}, +{4,5,259},{5,5,748},{5,5,748},{5,5,748},{5,5,716},{4,6,298},{4,6,122},{4,6,122},{4,5,98},{3,6,184},{4,5,155},{5,5,72},{5,5,72},{5,5,72},{5,5,40},{6,3,164},{4,6,58},{4,6,58},{4,5,34},{6,4,164},{4,5,34},{7,3,202},{5,6,50},{5,5,261},{5,5,229},{7,3,202},{6,5,202},{5,5,229},{0,5,250},{6,5,202},{0,5,250},{5,0,712}, +{5,0,712},{5,0,712},{5,0,712},{4,6,73},{4,6,73},{4,6,73},{4,5,73},{4,5,130},{4,5,130},{5,7,530},{5,6,410},{5,6,450},{5,6,570},{5,6,1055},{4,7,720},{4,6,403},{4,5,819},{3,7,892},{4,5,572},{5,7,206},{5,6,86},{5,6,126},{5,6,246},{5,6,731},{3,7,387},{4,6,147},{4,5,563},{4,6,731},{4,5,563},{5,6,329},{5,6,329},{5,6,329}, +{5,5,428},{4,7,420},{4,6,282},{4,6,282},{4,5,290},{3,6,248},{4,5,43},{5,6,5},{5,6,5},{5,6,5},{5,5,104},{7,2,164},{4,6,26},{4,6,26},{4,5,34},{5,5,164},{4,5,34},{5,7,202},{5,6,82},{5,6,122},{4,6,122},{5,7,202},{5,6,202},{4,6,122},{0,5,538},{5,6,202},{0,5,538},{5,0,328},{5,0,328},{5,0,328},{5,0,328},{4,6,281}, +{4,6,281},{4,6,281},{4,5,281},{4,5,34},{4,5,34},{5,7,498},{5,7,234},{5,6,290},{5,6,218},{5,7,839},{5,6,479},{5,6,199},{5,6,1079},{3,7,732},{4,6,668},{5,7,398},{5,7,134},{5,6,190},{5,6,118},{6,5,731},{4,7,208},{5,6,99},{3,6,554},{3,7,731},{3,6,554},{5,7,209},{5,7,209},{5,7,209},{5,6,209},{5,6,262},{5,6,190},{5,6,190}, +{5,5,221},{4,6,211},{4,5,315},{5,7,109},{5,7,109},{5,7,109},{5,6,109},{5,6,162},{5,6,90},{5,6,90},{5,5,121},{4,6,162},{5,5,121},{7,4,208},{5,7,34},{5,6,90},{5,6,18},{7,4,208},{7,5,208},{5,6,18},{0,6,538},{7,5,208},{0,6,538},{5,0,200},{5,0,200},{5,0,200},{5,0,200},{5,5,116},{5,5,116},{5,5,116},{5,5,100},{4,6,130}, +{4,6,130},{5,7,1074},{5,7,414},{5,6,722},{5,6,434},{5,7,857},{5,7,417},{5,6,73},{5,6,377},{4,7,860},{4,6,236},{6,7,497},{6,6,403},{6,6,270},{6,6,310},{7,4,731},{4,7,379},{5,6,72},{4,6,232},{7,5,731},{4,6,232},{5,7,398},{5,7,398},{5,7,398},{5,6,398},{5,7,181},{5,6,37},{5,6,37},{5,6,341},{3,7,264},{4,6,200},{6,6,234}, +{6,6,234},{6,6,234},{6,6,274},{6,5,164},{5,6,36},{5,6,36},{4,6,196},{3,7,164},{4,6,196},{7,5,202},{5,7,52},{6,6,45},{5,6,72},{7,5,202},{6,6,218},{5,6,72},{0,6,232},{6,6,218},{0,6,232},{5,0,362},{5,0,362},{5,0,362},{5,0,362},{5,6,1},{5,6,1},{5,6,1},{5,5,82},{4,6,4},{4,6,4},{6,7,986},{6,7,842},{6,6,999}, +{6,6,975},{5,7,1417},{5,7,273},{5,6,505},{5,6,297},{4,7,828},{5,6,392},{6,7,257},{6,7,113},{6,6,270},{6,6,246},{7,5,739},{5,7,224},{6,6,366},{5,6,248},{6,6,731},{5,6,248},{6,6,803},{6,6,803},{6,6,803},{6,6,779},{5,7,261},{5,7,129},{5,7,129},{5,6,101},{4,7,203},{5,6,196},{6,6,74},{6,6,74},{6,6,74},{6,6,50},{7,4,162}, +{5,7,80},{5,7,80},{5,6,52},{7,5,162},{5,6,52},{6,7,208},{6,7,64},{6,6,221},{6,6,197},{6,7,208},{7,6,208},{6,6,197},{0,6,232},{7,6,208},{0,6,232},{5,0,778},{5,0,778},{5,0,778},{5,0,778},{5,7,65},{5,7,65},{5,7,65},{5,6,65},{5,6,160},{5,6,160},{6,7,762},{6,7,426},{6,7,506},{6,7,650},{6,7,1085},{5,7,641},{5,7,385}, +{5,6,729},{5,7,980},{5,6,520},{6,7,401},{6,7,65},{6,7,145},{6,7,289},{6,7,724},{5,7,416},{5,7,160},{5,6,504},{5,7,724},{5,6,504},{6,7,362},{6,7,362},{6,7,362},{6,6,443},{6,6,555},{5,7,241},{5,7,241},{5,6,245},{4,7,219},{5,6,36},{6,7,1},{6,7,1},{6,7,1},{6,6,82},{7,5,194},{5,7,16},{5,7,16},{5,6,20},{6,6,162}, +{5,6,20},{7,6,208},{6,7,64},{6,7,144},{5,7,144},{7,6,208},{6,7,208},{5,7,144},{0,6,488},{6,7,208},{0,6,488},{6,0,362},{6,0,362},{6,0,362},{6,0,362},{5,7,241},{5,7,241},{5,7,241},{5,6,241},{5,6,32},{5,6,32},{6,7,1050},{6,7,522},{6,7,282},{6,7,234},{6,7,1069},{6,7,493},{6,7,253},{6,6,1122},{5,7,1012},{5,7,756},{7,7,843}, +{6,7,401},{6,7,161},{6,7,113},{7,6,724},{6,7,372},{6,7,132},{4,7,601},{6,7,756},{4,7,601},{6,7,266},{6,7,266},{6,7,266},{6,7,218},{6,7,285},{6,7,237},{6,7,237},{6,6,222},{5,7,228},{5,6,260},{6,7,145},{6,7,145},{6,7,145},{6,7,97},{6,7,164},{6,7,116},{6,7,116},{6,6,101},{5,7,164},{6,6,101},{7,7,218},{7,7,178},{6,7,80}, +{6,7,32},{7,7,218},{6,7,272},{6,7,32},{0,7,592},{6,7,272},{0,7,592},{6,0,202},{6,0,202},{6,0,202},{6,0,202},{6,6,130},{6,6,130},{6,6,130},{6,6,122},{5,6,160},{5,6,160},{6,7,1641},{6,7,1017},{6,7,617},{6,7,353},{6,7,1318},{6,7,430},{6,7,30},{6,7,398},{6,7,1035},{5,7,227},{7,7,393},{7,7,321},{7,7,272},{7,7,320},{7,7,621}, +{6,7,426},{6,7,26},{5,7,226},{6,7,594},{5,7,226},{6,7,617},{6,7,617},{6,7,617},{6,7,353},{6,7,294},{6,7,30},{6,7,30},{6,7,398},{5,7,291},{5,7,227},{7,7,272},{7,7,272},{7,7,272},{7,7,320},{7,6,162},{6,7,26},{6,7,26},{5,7,226},{7,6,194},{5,7,226},{7,7,137},{7,7,65},{7,7,16},{6,7,25},{7,7,137},{7,7,113},{6,7,25}, +{0,7,225},{7,7,113},{0,7,225},{6,0,328},{6,0,328},{6,0,328},{6,0,328},{6,7,5},{6,7,5},{6,7,5},{6,6,68},{5,7,2},{5,7,2},{7,7,985},{7,7,913},{7,7,864},{7,7,848},{7,7,1117},{6,7,654},{6,7,254},{6,7,110},{6,7,763},{5,7,179},{7,7,201},{7,7,129},{7,7,80},{7,7,64},{7,7,333},{7,7,245},{7,7,196},{6,7,74},{7,7,373}, +{6,7,74},{7,7,864},{7,7,864},{7,7,864},{7,7,848},{6,7,710},{6,7,254},{6,7,254},{6,7,110},{6,7,363},{5,7,179},{7,7,80},{7,7,80},{7,7,80},{7,7,64},{7,7,212},{7,7,196},{7,7,196},{6,7,74},{6,7,194},{6,7,74},{7,7,137},{7,7,65},{7,7,16},{7,7,0},{7,7,137},{7,7,49},{7,7,0},{0,7,49},{7,7,49},{0,7,49},{6,0,712}, +{6,0,712},{6,0,712},{6,0,712},{6,7,85},{6,7,85},{6,7,85},{6,7,61},{5,7,130},{5,7,130},{7,7,642},{7,7,570},{7,7,521},{7,7,449},{7,7,678},{7,7,534},{7,7,485},{6,7,205},{6,7,834},{6,7,34},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,278},{7,7,134},{7,7,85},{6,7,9},{7,7,198},{6,7,9},{7,7,521},{7,7,521},{7,7,521}, +{7,7,449},{7,7,557},{7,7,485},{7,7,485},{6,7,205},{6,7,434},{6,7,34},{7,7,121},{7,7,121},{7,7,121},{7,7,49},{7,7,157},{7,7,85},{7,7,85},{6,7,9},{7,7,149},{6,7,9},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{7,0,400},{7,0,400},{7,0,400},{7,0,400},{6,7,421}, +{6,7,421},{6,7,421},{6,7,205},{6,7,34},{6,7,34},{7,7,450},{7,7,378},{7,7,329},{7,7,257},{7,7,390},{7,7,246},{7,7,197},{7,7,148},{7,7,426},{6,7,130},{7,7,306},{7,7,234},{7,7,185},{7,7,113},{7,7,246},{7,7,102},{7,7,53},{7,7,4},{7,7,102},{7,7,4},{7,7,329},{7,7,329},{7,7,329},{7,7,257},{7,7,269},{7,7,197},{7,7,197}, +{7,7,148},{7,7,377},{6,7,130},{7,7,185},{7,7,185},{7,7,185},{7,7,113},{7,7,125},{7,7,53},{7,7,53},{7,7,4},{7,7,53},{7,7,4},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{7,0,208},{7,0,208},{7,0,208},{7,0,208},{7,7,148},{7,7,148},{7,7,148},{7,7,148},{6,7,130}, +{6,7,130},{0,2,445},{0,1,157},{0,1,117},{0,1,405},{0,1,926},{0,1,806},{0,0,670},{0,0,741},{0,0,1169},{0,0,777},{0,2,445},{0,1,157},{0,1,117},{0,1,405},{0,1,926},{0,1,806},{0,0,670},{0,0,741},{1,0,990},{0,0,741},{0,1,36},{0,1,36},{0,1,36},{0,0,9},{0,0,85},{0,0,45},{0,0,45},{0,0,116},{0,0,145},{0,0,152},{0,1,36}, +{0,1,36},{0,1,36},{0,0,9},{0,0,85},{0,0,45},{0,0,45},{0,0,116},{0,0,109},{0,0,116},{1,0,421},{0,1,157},{0,1,117},{0,1,405},{1,0,421},{0,1,445},{0,1,405},{0,0,641},{0,1,445},{0,0,641},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,2,461},{0,2,109},{0,1,5}, +{0,1,101},{0,1,1326},{0,1,822},{0,1,462},{0,0,1205},{0,1,1783},{0,0,1241},{0,2,461},{0,2,109},{0,1,5},{0,1,101},{1,0,1294},{0,1,822},{0,1,462},{0,0,1205},{1,0,1262},{0,0,1205},{0,1,4},{0,1,4},{0,1,4},{0,1,100},{0,0,261},{0,0,157},{0,0,157},{0,0,116},{0,0,257},{0,0,152},{0,1,4},{0,1,4},{0,1,4},{0,1,100},{0,0,261}, +{0,0,157},{0,0,157},{0,0,116},{0,0,221},{0,0,116},{1,1,461},{0,2,109},{0,1,5},{0,1,101},{1,1,461},{2,0,421},{0,1,101},{0,1,901},{2,0,421},{0,1,901},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,3,430},{0,2,38},{0,1,158},{0,1,62},{0,2,1517},{0,1,989},{0,1,309}, +{0,1,1317},{0,1,1878},{0,1,1678},{0,3,430},{0,2,38},{0,1,158},{0,1,62},{0,2,1517},{0,1,989},{0,1,309},{0,1,1317},{0,1,1517},{0,1,1317},{0,2,13},{0,2,13},{0,2,13},{0,1,13},{0,1,356},{0,1,260},{0,1,260},{0,0,193},{0,0,446},{0,0,229},{0,2,13},{0,2,13},{0,2,13},{0,1,13},{0,1,356},{0,1,260},{0,1,260},{0,0,193},{0,0,410}, +{0,0,193},{0,3,421},{0,2,29},{0,1,149},{0,1,53},{0,3,421},{1,1,421},{0,1,53},{0,1,533},{1,1,421},{0,1,533},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,0,9},{0,0,49},{0,0,85},{0,0,85},{0,4,602},{0,3,234},{0,2,518},{0,1,382},{0,3,1622},{0,2,825},{0,1,325},{0,1,821},{0,1,2022},{0,1,1182},{0,4,602}, +{0,3,234},{0,2,518},{0,1,382},{1,1,1526},{0,2,825},{0,1,325},{0,1,821},{2,0,1526},{0,1,821},{0,2,157},{0,2,157},{0,2,157},{0,1,157},{0,1,388},{0,1,100},{0,1,100},{0,0,401},{0,0,766},{0,0,437},{0,2,157},{0,2,157},{0,2,157},{0,1,157},{1,0,356},{0,1,100},{0,1,100},{0,0,401},{1,0,340},{0,0,401},{1,2,425},{0,3,113},{1,1,234}, +{0,1,261},{1,2,425},{0,2,425},{0,1,261},{0,1,421},{0,2,425},{0,1,421},{0,0,121},{0,0,121},{0,0,121},{0,0,121},{0,0,25},{0,0,25},{0,0,25},{0,0,1},{0,0,37},{0,0,37},{0,4,845},{0,3,405},{0,2,725},{0,2,549},{0,3,1541},{0,2,654},{0,2,270},{0,1,722},{0,2,2583},{0,1,1083},{1,3,657},{1,2,345},{1,2,345},{0,2,549},{2,0,1517}, +{0,2,654},{0,2,270},{0,1,722},{3,0,1517},{0,1,722},{0,3,404},{0,3,404},{0,3,404},{0,2,449},{0,2,346},{0,2,170},{0,2,170},{0,1,146},{0,1,707},{0,1,507},{1,1,232},{1,1,232},{1,1,232},{1,1,200},{0,2,346},{0,2,170},{0,2,170},{0,1,146},{0,1,346},{0,1,146},{2,1,421},{0,3,5},{1,2,149},{0,2,149},{2,1,421},{4,0,421},{0,2,149}, +{0,1,601},{4,0,421},{0,1,601},{0,0,400},{0,0,400},{0,0,400},{0,0,400},{0,1,1},{0,1,1},{0,1,1},{0,0,100},{0,0,136},{0,0,136},{0,5,1209},{0,4,937},{1,2,1197},{0,2,789},{0,4,1526},{0,3,737},{0,2,14},{0,1,1042},{0,2,2487},{0,1,1403},{1,3,481},{1,3,173},{1,2,41},{1,2,161},{1,2,1526},{0,3,737},{0,2,14},{0,1,1042},{2,1,1526}, +{0,1,1042},{0,4,793},{0,4,793},{0,4,793},{0,2,785},{0,3,356},{0,2,10},{0,2,10},{0,1,18},{0,1,899},{0,1,379},{1,2,37},{1,2,37},{1,2,37},{1,1,136},{1,1,340},{0,2,10},{0,2,10},{0,1,18},{1,1,356},{0,1,18},{3,0,425},{1,3,137},{1,2,5},{0,2,5},{3,0,425},{3,1,425},{0,2,5},{0,2,965},{3,1,425},{0,2,965},{0,0,784}, +{0,0,784},{0,0,784},{0,0,784},{0,2,9},{0,2,9},{0,2,9},{0,1,9},{0,0,360},{0,0,360},{1,4,1158},{1,3,758},{1,2,850},{1,2,778},{0,4,1671},{0,3,546},{0,2,191},{0,2,903},{0,2,2390},{0,2,1430},{1,4,429},{1,3,29},{1,2,121},{1,2,49},{2,1,1526},{0,3,497},{0,2,142},{0,2,854},{4,0,1526},{0,2,854},{1,3,742},{1,3,742},{1,3,742}, +{1,2,742},{0,3,437},{0,2,155},{0,2,155},{0,1,195},{0,2,946},{0,1,290},{1,3,13},{1,3,13},{1,3,13},{1,2,13},{2,0,340},{0,2,106},{0,2,106},{0,1,146},{3,0,340},{0,1,146},{1,4,425},{1,3,25},{1,2,117},{1,2,45},{1,4,425},{2,2,425},{1,2,45},{0,2,565},{2,2,425},{0,2,565},{1,0,733},{1,0,733},{1,0,733},{1,0,733},{0,2,74}, +{0,2,74},{0,2,74},{0,1,74},{0,1,169},{0,1,169},{1,4,966},{1,4,606},{1,3,886},{1,2,682},{0,5,1742},{0,3,866},{0,3,641},{0,2,727},{0,3,2382},{0,2,758},{1,4,605},{1,4,245},{1,3,525},{1,2,321},{3,0,1517},{0,3,641},{1,2,302},{0,2,502},{3,1,1517},{0,2,502},{1,3,486},{1,3,486},{1,3,486},{1,2,486},{0,4,563},{0,3,241},{0,3,241}, +{0,2,531},{0,2,626},{0,1,546},{1,3,125},{1,3,125},{1,3,125},{1,2,125},{0,4,338},{0,3,16},{0,3,16},{0,2,306},{2,1,338},{0,2,306},{3,1,433},{1,4,145},{2,2,212},{1,2,221},{3,1,433},{6,0,433},{1,2,221},{0,2,421},{6,0,433},{0,2,421},{1,0,461},{1,0,461},{1,0,461},{1,0,461},{0,3,225},{0,3,225},{0,3,225},{0,2,306},{0,1,185}, +{0,1,185},{1,5,894},{1,4,462},{1,3,778},{1,3,646},{1,4,1626},{1,3,749},{1,3,429},{1,2,809},{0,3,2022},{0,2,614},{2,4,706},{1,4,362},{2,3,410},{1,3,546},{3,1,1526},{0,4,441},{0,3,227},{0,2,565},{4,1,1526},{0,2,565},{1,4,462},{1,4,462},{1,4,462},{1,3,525},{1,3,440},{1,2,296},{1,2,296},{1,2,280},{0,2,725},{0,2,85},{2,2,250}, +{2,2,250},{2,2,250},{2,2,226},{1,3,340},{0,3,106},{0,3,106},{0,2,36},{1,2,340},{0,2,36},{3,2,425},{1,4,1},{2,3,185},{0,3,146},{3,2,425},{5,1,425},{0,3,146},{0,2,565},{5,1,425},{0,2,565},{1,0,461},{1,0,461},{1,0,461},{1,0,461},{1,2,100},{1,2,100},{1,2,100},{1,1,181},{0,2,49},{0,2,49},{1,6,1166},{1,4,878},{1,3,1226}, +{1,3,742},{1,5,1545},{1,4,798},{1,3,29},{1,2,985},{0,3,2246},{0,2,1030},{2,4,482},{2,4,218},{2,3,58},{2,3,202},{2,3,1517},{0,4,521},{1,3,25},{1,2,981},{6,0,1517},{1,2,981},{1,5,749},{1,5,749},{1,5,749},{1,3,733},{1,4,374},{1,3,20},{1,3,20},{1,2,24},{0,3,482},{0,2,69},{2,3,49},{2,3,49},{2,3,49},{2,2,130},{2,2,338}, +{1,3,16},{1,3,16},{1,2,20},{5,0,338},{1,2,20},{4,1,433},{1,4,145},{2,3,9},{1,3,9},{4,1,433},{7,0,433},{1,3,9},{0,2,965},{7,0,433},{0,2,965},{1,0,733},{1,0,733},{1,0,733},{1,0,733},{1,3,20},{1,3,20},{1,3,20},{1,2,20},{0,2,65},{0,2,65},{2,5,1218},{2,4,810},{2,3,874},{2,3,826},{1,5,1625},{1,4,542},{1,3,141}, +{1,3,961},{0,4,1806},{0,3,642},{2,5,434},{2,4,26},{2,3,90},{2,3,42},{3,2,1517},{1,4,506},{1,3,105},{0,3,626},{5,1,1517},{0,3,626},{2,4,801},{2,4,801},{2,4,801},{2,3,801},{1,4,406},{1,3,116},{1,3,116},{1,2,152},{0,3,482},{1,2,285},{2,4,17},{2,4,17},{2,4,17},{2,3,17},{3,1,338},{1,3,80},{1,3,80},{1,2,116},{4,1,338}, +{1,2,116},{3,3,425},{2,4,25},{2,3,89},{2,3,41},{3,3,425},{6,1,425},{2,3,41},{0,3,601},{6,1,425},{0,3,601},{2,0,785},{2,0,785},{2,0,785},{2,0,785},{1,3,52},{1,3,52},{1,3,52},{1,2,52},{0,3,41},{0,3,41},{2,5,962},{2,4,618},{2,3,906},{2,3,666},{1,6,1710},{1,4,798},{1,4,663},{1,3,721},{0,4,1838},{0,3,450},{2,5,562}, +{2,4,218},{2,3,506},{2,3,266},{4,1,1514},{0,5,474},{2,3,285},{0,3,434},{4,2,1514},{0,3,434},{2,4,497},{2,4,497},{2,4,497},{2,3,497},{1,5,536},{1,4,222},{1,4,222},{1,3,552},{0,4,469},{0,3,281},{2,4,97},{2,4,97},{2,4,97},{2,3,97},{4,0,340},{1,4,26},{1,4,26},{0,3,265},{3,2,340},{0,3,265},{4,2,425},{2,4,137},{3,3,194}, +{2,3,185},{4,2,425},{5,2,425},{2,3,185},{0,3,425},{5,2,425},{0,3,425},{2,0,481},{2,0,481},{2,0,481},{2,0,481},{1,4,197},{1,4,197},{1,4,197},{1,3,296},{0,3,25},{0,3,25},{2,6,870},{2,5,446},{2,4,758},{2,4,670},{2,5,1638},{2,4,771},{2,4,515},{2,3,823},{0,5,1710},{1,3,598},{3,4,737},{2,5,325},{3,4,481},{2,4,549},{5,0,1517}, +{1,5,458},{1,4,224},{1,3,534},{3,3,1517},{1,3,534},{2,5,445},{2,5,445},{2,5,445},{2,4,526},{2,4,459},{2,3,291},{2,3,291},{2,3,339},{0,4,370},{1,3,114},{3,3,272},{3,3,272},{3,3,272},{3,3,256},{2,4,338},{1,4,80},{1,4,80},{1,3,50},{7,0,338},{1,3,50},{5,1,425},{2,5,1},{3,4,225},{1,4,160},{5,1,425},{4,3,425},{1,4,160}, +{0,3,533},{4,3,425},{0,3,533},{2,0,445},{2,0,445},{2,0,445},{2,0,445},{2,3,122},{2,3,122},{2,3,122},{2,2,185},{1,3,65},{1,3,65},{2,7,1130},{2,5,798},{2,4,1142},{2,4,702},{2,6,1571},{2,4,819},{2,4,51},{2,3,935},{0,5,1614},{1,3,950},{3,5,489},{3,5,269},{3,4,81},{3,4,249},{3,4,1514},{1,5,490},{2,4,42},{2,3,926},{7,1,1514}, +{2,3,926},{2,6,710},{2,6,710},{2,6,710},{2,4,686},{2,5,397},{2,4,35},{2,4,35},{2,3,35},{1,4,509},{1,3,50},{3,4,65},{3,4,65},{3,4,65},{3,3,128},{3,3,340},{2,4,26},{2,4,26},{2,3,26},{6,1,340},{2,3,26},{6,0,425},{2,5,113},{3,4,17},{2,4,17},{6,0,425},{3,4,425},{2,4,17},{0,3,901},{3,4,425},{0,3,901},{2,0,685}, +{2,0,685},{2,0,685},{2,0,685},{2,4,34},{2,4,34},{2,4,34},{2,3,34},{1,3,49},{1,3,49},{3,6,1286},{3,5,870},{3,4,906},{3,4,882},{2,6,1587},{2,5,546},{2,4,99},{2,4,1027},{1,5,1838},{1,4,702},{3,6,445},{3,5,29},{3,4,65},{3,4,41},{4,3,1514},{2,5,521},{2,4,74},{1,4,677},{6,2,1514},{1,4,677},{3,5,866},{3,5,866},{3,5,866}, +{3,4,866},{2,5,381},{2,4,83},{2,4,83},{2,3,115},{0,5,349},{2,3,286},{3,5,25},{3,5,25},{3,5,25},{3,4,25},{4,2,340},{2,4,58},{2,4,58},{2,3,90},{5,2,340},{2,3,90},{4,4,421},{3,5,29},{3,4,65},{3,4,41},{4,4,421},{7,2,421},{3,4,41},{0,4,641},{7,2,421},{0,4,641},{3,0,841},{3,0,841},{3,0,841},{3,0,841},{2,4,34}, +{2,4,34},{2,4,34},{2,3,34},{1,4,61},{1,4,61},{3,6,966},{3,5,614},{3,4,874},{3,4,658},{2,7,1686},{2,5,738},{2,4,659},{2,4,723},{0,6,1518},{1,4,446},{3,6,525},{3,5,173},{3,4,433},{3,4,217},{5,2,1517},{1,6,457},{3,4,274},{1,4,437},{5,3,1517},{1,4,437},{3,5,514},{3,5,514},{3,5,514},{3,4,514},{2,6,515},{2,5,209},{2,5,209}, +{2,3,579},{1,5,510},{1,4,302},{3,5,73},{3,5,73},{3,5,73},{3,4,73},{5,1,346},{2,5,40},{2,5,40},{3,3,293},{7,1,346},{3,3,293},{5,3,421},{3,5,109},{4,4,180},{3,4,153},{5,3,421},{6,3,421},{3,4,153},{0,4,433},{6,3,421},{0,4,433},{3,0,505},{3,0,505},{3,0,505},{3,0,505},{2,5,173},{2,5,173},{2,5,173},{2,3,290},{1,4,13}, +{1,4,13},{3,7,854},{3,6,438},{3,5,746},{3,5,702},{3,6,1658},{3,5,801},{3,5,609},{3,4,845},{1,6,1758},{2,4,590},{3,7,710},{3,6,294},{4,5,558},{3,5,558},{6,1,1514},{2,6,481},{2,5,227},{2,4,509},{4,4,1514},{2,4,509},{3,6,434},{3,6,434},{3,6,434},{3,5,533},{3,5,484},{3,4,292},{3,4,292},{3,4,404},{1,5,357},{2,4,149},{3,6,290}, +{3,6,290},{3,6,290},{4,4,290},{6,0,340},{2,5,58},{2,5,58},{2,4,68},{3,4,340},{2,4,68},{6,2,421},{3,6,5},{4,5,269},{2,5,178},{6,2,421},{5,4,421},{2,5,178},{0,4,505},{5,4,421},{0,4,505},{3,0,433},{3,0,433},{3,0,433},{3,0,433},{3,4,148},{3,4,148},{3,4,148},{3,3,193},{2,4,85},{2,4,85},{3,7,1206},{3,6,726},{3,5,1066}, +{3,5,670},{3,7,1605},{3,5,785},{3,5,81},{3,4,893},{1,6,1598},{2,4,878},{4,6,502},{4,5,310},{4,5,110},{4,5,302},{7,0,1517},{2,6,465},{3,5,65},{2,4,877},{3,5,1517},{2,4,877},{3,7,677},{3,7,677},{3,7,677},{3,5,645},{3,6,426},{3,5,56},{3,5,56},{3,4,52},{2,5,542},{2,4,37},{4,5,85},{4,5,85},{4,5,85},{4,4,130},{5,2,346}, +{3,5,40},{3,5,40},{2,4,36},{7,2,346},{2,4,36},{7,1,421},{3,6,85},{4,5,29},{3,5,29},{7,1,421},{4,5,421},{3,5,29},{0,4,841},{4,5,421},{0,4,841},{3,0,641},{3,0,641},{3,0,641},{3,0,641},{3,4,52},{3,4,52},{3,4,52},{3,4,52},{2,4,37},{2,4,37},{4,7,1362},{4,6,938},{4,5,946},{4,5,946},{3,7,1557},{3,6,558},{3,5,65}, +{3,5,1101},{0,7,1662},{2,5,770},{4,7,462},{4,6,38},{4,5,46},{4,5,46},{5,4,1517},{3,6,542},{3,5,49},{1,5,721},{7,3,1517},{1,5,721},{4,5,937},{4,5,937},{4,5,937},{4,5,937},{3,6,362},{3,5,56},{3,5,56},{3,4,84},{1,6,350},{3,4,293},{4,5,37},{4,5,37},{4,5,37},{4,5,37},{6,1,346},{3,5,40},{3,5,40},{3,4,68},{6,3,346}, +{3,4,68},{5,5,421},{4,6,37},{4,5,45},{3,5,45},{5,5,421},{3,6,421},{3,5,45},{0,5,685},{3,6,421},{0,5,685},{4,0,901},{4,0,901},{4,0,901},{4,0,901},{3,5,20},{3,5,20},{3,5,20},{3,4,20},{2,5,85},{2,5,85},{4,7,978},{4,6,618},{4,5,850},{4,5,658},{3,7,2021},{3,6,686},{3,5,561},{3,5,733},{1,7,1530},{2,5,450},{4,7,494}, +{4,6,134},{4,5,366},{4,5,174},{6,3,1526},{2,7,446},{4,5,269},{2,5,446},{6,4,1526},{2,5,446},{4,6,537},{4,6,537},{4,6,537},{4,5,537},{3,7,500},{3,6,202},{3,6,202},{3,4,500},{1,6,510},{2,5,329},{4,6,53},{4,6,53},{4,6,53},{4,5,53},{7,0,340},{3,6,58},{3,6,58},{4,4,265},{3,5,340},{4,4,265},{6,4,421},{4,6,85},{5,5,170}, +{4,5,125},{6,4,421},{7,4,421},{4,5,125},{0,5,445},{7,4,421},{0,5,445},{4,0,533},{4,0,533},{4,0,533},{4,0,533},{3,6,153},{3,6,153},{3,6,153},{3,4,244},{2,5,5},{2,5,5},{4,7,1158},{4,7,438},{4,6,742},{4,6,742},{4,7,1686},{4,6,839},{3,6,677},{4,5,875},{1,7,1710},{3,5,590},{5,6,769},{4,7,269},{4,6,573},{4,6,573},{7,2,1517}, +{3,7,510},{3,6,236},{3,5,490},{5,5,1517},{3,5,490},{4,7,429},{4,7,429},{4,7,429},{4,5,546},{4,6,515},{4,5,299},{4,5,299},{4,5,475},{2,6,350},{3,5,190},{4,7,260},{4,7,260},{4,7,260},{5,5,328},{7,1,346},{3,6,40},{3,6,40},{3,5,90},{7,3,346},{3,5,90},{7,3,421},{4,7,13},{4,6,317},{3,6,200},{7,3,421},{6,5,421},{3,6,200}, +{0,5,481},{6,5,421},{0,5,481},{4,0,425},{4,0,425},{4,0,425},{4,0,425},{4,5,178},{4,5,178},{4,5,178},{4,4,205},{3,5,109},{3,5,109},{4,7,1862},{4,7,662},{4,6,998},{4,6,646},{4,7,1686},{4,6,759},{4,6,119},{4,5,859},{2,7,1590},{3,5,814},{5,7,521},{5,6,305},{5,6,145},{5,6,361},{5,6,1526},{3,7,446},{4,6,94},{3,5,810},{4,6,1526}, +{3,5,810},{4,7,637},{4,7,637},{4,7,637},{4,6,610},{4,6,435},{4,6,83},{4,6,83},{4,5,75},{1,7,565},{3,5,30},{5,6,109},{5,6,109},{5,6,109},{5,5,136},{6,3,340},{4,6,58},{4,6,58},{3,5,26},{6,4,340},{3,5,26},{5,7,421},{4,7,61},{5,6,45},{4,6,45},{5,7,421},{5,6,421},{4,6,45},{0,5,785},{5,6,421},{0,5,785},{4,0,601}, +{4,0,601},{4,0,601},{4,0,601},{4,5,50},{4,5,50},{4,5,50},{4,5,74},{3,5,29},{3,5,29},{5,7,1498},{5,7,1014},{5,6,994},{5,6,1018},{4,7,2198},{4,7,578},{4,6,39},{4,6,1183},{2,7,1878},{3,6,846},{5,7,537},{5,7,53},{5,6,33},{5,6,57},{7,3,1526},{4,7,569},{4,6,30},{2,6,758},{6,5,1526},{2,6,758},{5,6,990},{5,6,990},{5,6,990}, +{5,6,1014},{4,7,349},{4,6,35},{4,6,35},{4,5,59},{2,7,357},{3,5,254},{5,6,29},{5,6,29},{5,6,29},{5,6,53},{7,2,340},{4,6,26},{4,6,26},{4,5,50},{5,5,340},{4,5,50},{6,6,425},{5,7,49},{5,6,29},{4,6,29},{6,6,425},{4,7,425},{4,6,29},{0,6,733},{4,7,425},{0,6,733},{5,0,965},{5,0,965},{5,0,965},{5,0,965},{4,6,10}, +{4,6,10},{4,6,10},{4,5,10},{3,6,113},{3,6,113},{5,7,1466},{5,7,630},{5,6,834},{5,6,666},{5,7,2055},{4,7,642},{4,6,471},{4,6,751},{3,7,1766},{3,6,462},{5,7,937},{5,7,101},{5,6,305},{5,6,137},{5,7,1526},{4,7,521},{5,6,270},{3,6,461},{5,6,1526},{3,6,461},{5,7,566},{5,7,566},{5,7,566},{5,6,566},{4,7,621},{4,7,201},{4,7,201}, +{4,5,427},{2,7,469},{3,6,362},{5,7,37},{5,7,37},{5,7,37},{5,6,37},{5,6,338},{4,7,80},{4,7,80},{5,5,241},{4,6,338},{5,5,241},{7,5,425},{5,7,65},{6,6,164},{5,6,101},{7,5,425},{6,6,433},{5,6,101},{0,6,461},{6,6,433},{0,6,461},{5,0,565},{5,0,565},{5,0,565},{5,0,565},{4,7,137},{4,7,137},{4,7,137},{4,5,202},{3,6,1}, +{3,6,1},{5,7,2042},{5,7,810},{5,7,746},{5,7,790},{5,7,2073},{5,7,885},{4,7,651},{4,6,877},{4,7,2102},{4,6,598},{6,7,794},{6,7,530},{5,7,550},{5,7,594},{6,6,1526},{5,7,689},{4,7,251},{4,6,477},{6,6,1526},{4,6,477},{5,7,521},{5,7,521},{5,7,521},{5,6,521},{5,7,552},{5,6,312},{5,6,312},{4,6,516},{3,7,349},{4,6,237},{5,7,325}, +{5,7,325},{5,7,325},{5,6,325},{6,5,340},{4,7,26},{4,7,26},{4,6,116},{3,7,340},{4,6,116},{6,7,433},{6,7,169},{5,7,325},{4,7,226},{6,7,433},{7,6,425},{4,7,226},{0,6,461},{7,6,425},{0,6,461},{5,0,421},{5,0,421},{5,0,421},{5,0,421},{5,6,212},{5,6,212},{5,6,212},{5,5,221},{4,6,137},{4,6,137},{6,7,2362},{5,7,1514},{5,7,938}, +{5,7,630},{5,7,2633},{5,7,741},{5,7,165},{5,6,833},{4,7,2070},{4,6,758},{6,7,762},{6,7,306},{6,7,186},{6,7,426},{7,5,1526},{5,7,705},{5,7,129},{4,6,749},{5,7,1541},{4,6,749},{5,7,889},{5,7,889},{5,7,889},{5,7,581},{5,7,424},{5,7,116},{5,7,116},{5,6,104},{3,7,525},{4,6,29},{6,7,137},{6,7,137},{6,7,137},{6,6,146},{7,4,338}, +{5,7,80},{5,7,80},{4,6,20},{7,5,338},{4,6,20},{7,6,433},{6,7,185},{6,7,65},{5,7,65},{7,6,433},{6,7,425},{5,7,65},{0,6,733},{6,7,425},{0,6,733},{5,0,565},{5,0,565},{5,0,565},{5,0,565},{5,6,52},{5,6,52},{5,6,52},{5,6,100},{4,6,25},{4,6,25},{6,7,2073},{6,7,1449},{6,7,1049},{5,7,981},{6,7,2548},{5,7,1044},{5,7,20}, +{5,6,1196},{5,7,2365},{4,7,929},{6,7,1049},{6,7,425},{6,7,25},{6,7,73},{7,6,1492},{6,7,948},{5,7,16},{3,7,800},{7,6,1460},{3,7,800},{6,7,1049},{6,7,1049},{6,7,1049},{5,7,981},{5,7,680},{5,7,20},{5,7,20},{5,6,40},{4,7,434},{4,6,205},{6,7,25},{6,7,25},{6,7,25},{6,7,73},{7,5,370},{5,7,16},{5,7,16},{5,6,36},{6,6,338}, +{5,6,36},{7,7,410},{7,7,338},{6,7,16},{5,7,16},{7,7,410},{6,7,464},{5,7,16},{0,7,784},{6,7,464},{0,7,784},{5,0,965},{5,0,965},{5,0,965},{5,0,965},{5,7,4},{5,7,4},{5,7,4},{5,6,4},{4,7,145},{4,7,145},{6,7,1769},{6,7,1145},{6,7,745},{6,7,601},{6,7,1940},{6,7,1172},{5,7,308},{5,7,696},{5,7,1805},{4,7,401},{7,7,1043}, +{6,7,569},{6,7,169},{6,7,25},{7,6,1076},{6,7,596},{6,7,196},{4,7,401},{6,7,1076},{4,7,401},{6,7,745},{6,7,745},{6,7,745},{6,7,601},{6,7,916},{5,7,308},{5,7,308},{5,6,360},{4,7,626},{5,6,341},{6,7,169},{6,7,169},{6,7,169},{6,7,25},{6,7,340},{6,7,196},{6,7,196},{6,6,221},{5,7,340},{6,6,221},{7,7,202},{7,7,130},{7,7,81}, +{6,7,0},{7,7,202},{7,7,218},{6,7,0},{0,7,400},{7,7,218},{0,7,400},{6,0,601},{6,0,601},{6,0,601},{6,0,601},{5,7,164},{5,7,164},{5,7,164},{5,6,164},{4,7,1},{4,7,1},{6,7,1886},{6,7,1262},{6,7,862},{6,7,502},{6,7,1715},{6,7,731},{6,7,331},{5,7,507},{5,7,1634},{4,7,266},{7,7,521},{7,7,449},{7,7,400},{6,7,277},{7,7,797}, +{6,7,506},{6,7,106},{5,7,146},{6,7,770},{5,7,146},{6,7,862},{6,7,862},{6,7,862},{6,7,502},{6,7,691},{6,7,331},{6,7,331},{5,7,507},{5,7,610},{4,7,266},{7,7,400},{7,7,400},{7,7,400},{6,7,277},{7,6,338},{6,7,106},{6,7,106},{5,7,146},{7,6,370},{5,7,146},{7,7,121},{7,7,49},{7,7,0},{7,7,16},{7,7,121},{7,7,65},{7,7,16}, +{0,7,121},{7,7,65},{0,7,121},{6,0,421},{6,0,421},{6,0,421},{6,0,421},{6,7,250},{6,7,250},{6,7,250},{6,6,241},{4,7,145},{4,7,145},{7,7,2010},{6,7,1774},{6,7,1374},{6,7,822},{6,7,1923},{6,7,747},{6,7,347},{6,7,139},{6,7,1446},{5,7,34},{7,7,329},{7,7,257},{7,7,208},{7,7,160},{7,7,509},{7,7,389},{6,7,298},{5,7,18},{7,7,549}, +{5,7,18},{6,7,1374},{6,7,1374},{6,7,1374},{6,7,822},{6,7,899},{6,7,347},{6,7,347},{6,7,139},{5,7,866},{5,7,34},{7,7,208},{7,7,208},{7,7,208},{7,7,160},{7,7,388},{6,7,298},{6,7,298},{5,7,18},{6,7,370},{5,7,18},{7,7,185},{7,7,113},{7,7,64},{7,7,16},{7,7,185},{7,7,65},{7,7,16},{0,7,9},{7,7,65},{0,7,9},{6,0,533}, +{6,0,533},{6,0,533},{6,0,533},{6,7,58},{6,7,58},{6,7,58},{6,7,130},{5,7,25},{5,7,25},{7,7,1347},{7,7,1275},{7,7,1226},{7,7,1154},{7,7,1431},{6,7,922},{6,7,522},{6,7,2},{6,7,1125},{5,7,137},{7,7,258},{7,7,186},{7,7,137},{7,7,65},{7,7,342},{7,7,198},{7,7,149},{6,7,1},{7,7,294},{6,7,1},{7,7,1226},{7,7,1226},{7,7,1226}, +{7,7,1154},{6,7,1146},{6,7,522},{6,7,522},{6,7,2},{6,7,725},{5,7,137},{7,7,137},{7,7,137},{7,7,137},{7,7,65},{7,7,221},{7,7,149},{7,7,149},{6,7,1},{7,7,245},{6,7,1},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{6,0,901},{6,0,901},{6,0,901},{6,0,901},{6,7,122}, +{6,7,122},{6,7,122},{6,7,2},{5,7,137},{5,7,137},{7,7,883},{7,7,811},{7,7,762},{7,7,690},{7,7,871},{7,7,727},{7,7,678},{6,7,130},{6,7,949},{6,7,149},{7,7,258},{7,7,186},{7,7,137},{7,7,65},{7,7,246},{7,7,102},{7,7,53},{7,7,36},{7,7,134},{7,7,36},{7,7,762},{7,7,762},{7,7,762},{7,7,690},{7,7,750},{7,7,678},{7,7,678}, +{6,7,130},{6,7,549},{6,7,149},{7,7,137},{7,7,137},{7,7,137},{7,7,65},{7,7,125},{7,7,53},{7,7,53},{7,7,36},{7,7,85},{7,7,36},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{7,0,641},{7,0,641},{7,0,641},{7,0,641},{6,7,442},{6,7,442},{6,7,442},{6,7,130},{6,7,149}, +{6,7,149},{0,3,932},{0,2,218},{0,1,82},{0,1,250},{0,2,1971},{0,1,1371},{0,1,611},{0,0,1950},{0,1,2332},{0,0,1986},{0,3,932},{0,2,218},{0,1,82},{0,1,250},{1,0,1899},{0,1,1371},{0,1,611},{0,0,1950},{1,0,1923},{0,0,1950},{0,1,1},{0,1,1},{0,1,1},{0,0,64},{0,0,180},{0,0,100},{0,0,100},{0,0,101},{0,0,200},{0,0,137},{0,1,1}, +{0,1,1},{0,1,1},{0,0,64},{0,0,180},{0,0,100},{0,0,100},{0,0,101},{0,0,164},{0,0,101},{1,1,884},{0,2,218},{0,1,82},{0,1,250},{1,1,884},{2,0,900},{0,1,250},{0,1,1170},{2,0,900},{0,1,1170},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,3,900},{0,2,250},{0,2,314}, +{0,1,314},{0,2,2355},{0,1,1755},{0,1,675},{0,1,1875},{0,1,2716},{0,1,2236},{0,3,900},{0,2,250},{0,2,314},{0,1,314},{0,2,2355},{0,1,1755},{0,1,675},{0,1,1875},{0,1,2355},{0,1,1875},{0,2,25},{0,2,25},{0,2,25},{0,1,25},{0,1,410},{0,0,292},{0,0,292},{0,0,181},{0,0,392},{0,0,217},{0,2,25},{0,2,25},{0,2,25},{0,1,25},{0,1,410}, +{0,0,292},{0,0,292},{0,0,181},{0,0,356},{0,0,181},{2,0,884},{0,2,250},{0,2,314},{0,1,314},{2,0,884},{3,0,884},{0,1,314},{0,1,914},{3,0,884},{0,1,914},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,4,890},{0,3,104},{0,2,90},{0,2,442},{0,2,2995},{0,2,1851},{0,1,995}, +{0,1,1875},{0,1,3356},{0,1,2236},{0,4,890},{0,3,104},{0,2,90},{0,2,442},{1,1,2932},{0,2,1851},{0,1,995},{0,1,1875},{2,0,2900},{0,1,1875},{0,2,9},{0,2,9},{0,2,9},{0,1,9},{0,1,586},{0,1,370},{0,1,370},{0,0,389},{0,0,712},{0,0,425},{0,2,9},{0,2,9},{0,2,9},{0,1,9},{0,1,586},{0,1,370},{0,1,370},{0,0,389},{1,0,650}, +{0,0,389},{1,2,890},{0,3,104},{0,2,90},{0,2,442},{1,2,890},{2,1,890},{0,2,442},{0,1,914},{2,1,890},{0,1,914},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,4,990},{0,3,140},{0,2,158},{0,2,158},{0,3,3048},{0,2,1707},{0,2,747},{0,1,1795},{0,1,3916},{0,1,2156},{0,4,990}, +{0,3,140},{0,2,158},{0,2,158},{0,3,3048},{0,2,1707},{0,2,747},{0,1,1795},{1,1,3048},{0,1,1795},{0,3,40},{0,3,40},{0,3,40},{0,1,157},{0,1,698},{0,1,290},{0,1,290},{0,0,641},{0,0,1076},{0,0,677},{0,3,40},{0,3,40},{0,3,40},{0,1,157},{1,0,666},{0,1,290},{0,1,290},{0,0,641},{1,0,650},{0,0,641},{2,1,890},{0,3,104},{0,2,122}, +{0,2,122},{2,1,890},{4,0,890},{0,2,122},{0,1,1170},{4,0,890},{0,1,1170},{0,0,36},{0,0,36},{0,0,36},{0,0,36},{0,0,0},{0,0,0},{0,0,0},{0,0,16},{0,0,52},{0,0,52},{0,5,1115},{0,4,265},{0,2,689},{0,2,293},{0,4,3096},{0,3,1731},{0,2,324},{0,1,2020},{0,2,4009},{0,1,2381},{0,5,1115},{0,4,265},{1,2,429},{0,2,293},{1,2,3048}, +{0,3,1731},{0,2,324},{0,1,2020},{0,2,3048},{0,1,2020},{0,4,261},{0,4,261},{0,4,261},{0,2,229},{0,2,656},{0,2,260},{0,2,260},{0,1,256},{0,1,1017},{0,1,617},{0,4,261},{0,4,261},{0,4,261},{0,2,229},{0,2,656},{0,2,260},{0,2,260},{0,1,256},{0,1,656},{0,1,256},{3,0,890},{0,4,40},{1,2,68},{0,2,68},{3,0,890},{5,0,890},{0,2,68}, +{0,2,1220},{5,0,890},{0,2,1220},{0,0,225},{0,0,225},{0,0,225},{0,0,225},{0,1,16},{0,1,16},{0,1,16},{0,0,25},{0,0,61},{0,0,61},{0,6,1419},{0,4,569},{0,3,1078},{0,2,821},{0,4,3096},{0,3,1395},{0,2,356},{0,2,1832},{0,2,4201},{0,2,2793},{1,4,1011},{1,3,353},{1,2,413},{1,2,413},{2,1,3048},{0,3,1395},{0,2,356},{0,2,1832},{4,0,3048}, +{0,2,1832},{0,4,533},{0,4,533},{0,4,533},{0,2,565},{0,3,666},{0,2,100},{0,2,100},{0,1,128},{0,1,1209},{0,1,489},{1,2,157},{1,2,157},{1,2,157},{1,2,157},{1,1,650},{0,2,100},{0,2,100},{0,1,128},{1,1,666},{0,1,128},{3,1,890},{0,4,40},{1,2,292},{0,2,292},{3,1,890},{4,1,890},{0,2,292},{0,2,932},{4,1,890},{0,2,932},{0,0,529}, +{0,0,529},{0,0,529},{0,0,529},{0,1,16},{0,1,16},{0,1,16},{0,1,64},{0,0,205},{0,0,205},{0,6,1915},{0,5,1019},{1,3,1269},{0,3,1110},{0,5,3051},{0,3,1443},{0,3,318},{0,2,1384},{0,2,4777},{0,2,2345},{1,5,909},{1,4,131},{1,3,113},{1,3,509},{3,0,3051},{0,3,1443},{0,3,318},{0,2,1384},{3,1,3051},{0,2,1384},{0,5,970},{0,5,970},{0,5,970}, +{0,3,1010},{0,3,698},{0,2,196},{0,2,196},{0,1,256},{0,2,1641},{0,1,617},{1,3,13},{1,3,13},{1,3,13},{1,2,13},{2,0,650},{0,2,196},{0,2,196},{0,1,256},{3,0,650},{0,1,256},{2,3,884},{0,5,58},{1,3,104},{0,3,149},{2,3,884},{6,0,884},{0,3,149},{0,2,900},{6,0,884},{0,2,900},{0,0,961},{0,0,961},{0,0,961},{0,0,961},{0,2,0}, +{0,2,0},{0,2,0},{0,1,0},{0,1,361},{0,1,361},{1,5,2113},{1,4,1271},{1,3,1285},{1,3,1329},{0,6,3123},{0,4,1208},{0,3,30},{0,2,1320},{0,3,5011},{0,2,2281},{1,5,957},{1,4,115},{1,3,129},{1,3,173},{1,4,3051},{0,4,1208},{0,3,30},{0,2,1320},{2,2,3051},{0,2,1320},{1,4,1190},{1,4,1190},{1,4,1190},{1,2,1281},{0,4,648},{0,3,26},{0,3,26}, +{0,2,296},{0,2,1641},{0,1,1001},{1,4,34},{1,4,34},{1,4,34},{1,2,125},{0,4,648},{0,3,26},{0,3,26},{0,2,296},{2,1,648},{0,2,296},{3,2,884},{0,5,26},{1,3,104},{0,3,5},{3,2,884},{5,1,884},{0,3,5},{0,2,1124},{5,1,884},{0,2,1124},{1,0,1181},{1,0,1181},{1,0,1181},{1,0,1181},{0,3,25},{0,3,25},{0,3,25},{0,1,64},{0,1,425}, +{0,1,425},{1,6,1864},{1,5,1038},{1,3,1390},{1,3,1038},{0,6,3132},{0,4,1199},{0,3,201},{0,2,1743},{0,3,4924},{0,2,2332},{1,6,1080},{1,5,254},{2,3,458},{1,3,254},{2,3,3051},{0,4,1163},{0,3,165},{0,2,1707},{6,0,3051},{0,2,1707},{1,4,1016},{1,4,1016},{1,4,1016},{1,3,989},{0,5,716},{0,3,152},{0,3,152},{0,2,62},{0,2,1611},{0,2,651},{1,4,232}, +{1,4,232},{1,4,232},{1,3,205},{1,3,650},{0,3,116},{0,3,116},{0,2,26},{1,2,650},{0,2,26},{4,1,884},{1,5,58},{2,3,58},{1,3,58},{4,1,884},{4,2,884},{1,3,58},{0,3,1274},{4,2,884},{0,3,1274},{1,0,980},{1,0,980},{1,0,980},{1,0,980},{0,3,52},{0,3,52},{0,3,52},{0,2,61},{0,1,458},{0,1,458},{1,7,1784},{1,5,910},{1,4,1441}, +{1,3,1134},{0,7,3247},{0,5,1292},{0,4,567},{0,3,1474},{0,4,4900},{0,3,2178},{2,5,1028},{2,4,362},{2,3,394},{2,3,418},{3,2,3051},{0,5,1096},{1,3,331},{0,3,1278},{5,1,3051},{0,3,1278},{1,5,885},{1,5,885},{1,5,885},{1,3,909},{0,5,876},{0,4,206},{0,4,206},{0,2,254},{0,3,1548},{0,2,347},{2,3,169},{2,3,169},{2,3,169},{2,3,193},{2,2,648}, +{0,4,10},{0,4,10},{0,2,58},{5,0,648},{0,2,58},{5,0,884},{1,5,26},{2,3,250},{1,3,250},{5,0,884},{3,3,884},{1,3,250},{0,3,954},{3,3,884},{0,3,954},{1,0,884},{1,0,884},{1,0,884},{1,0,884},{0,4,197},{0,4,197},{0,4,197},{0,2,205},{0,2,298},{0,2,298},{1,7,1976},{1,6,1124},{1,4,1649},{1,4,1229},{1,6,3204},{0,5,1452},{1,4,525}, +{0,3,1474},{0,4,4420},{0,3,1474},{2,6,930},{2,5,160},{2,4,138},{2,3,546},{4,1,3060},{0,5,968},{0,4,195},{0,3,990},{4,2,3060},{0,3,990},{1,6,1060},{1,6,1060},{1,6,1060},{1,4,1108},{1,4,824},{1,3,314},{1,3,314},{1,2,370},{0,3,1260},{0,2,427},{2,4,17},{2,4,17},{2,4,17},{2,3,17},{3,1,648},{0,4,74},{0,4,74},{1,2,226},{4,1,648}, +{1,2,226},{3,4,882},{1,6,80},{2,4,122},{0,4,146},{3,4,882},{7,1,882},{0,4,146},{0,3,890},{7,1,882},{0,3,890},{1,0,1044},{1,0,1044},{1,0,1044},{1,0,1044},{1,3,145},{1,3,145},{1,3,145},{1,2,145},{0,2,202},{0,2,202},{2,6,2374},{1,6,1476},{2,4,1550},{1,4,1469},{1,6,3172},{1,5,1259},{1,4,61},{1,3,1323},{0,4,4452},{0,3,1282},{2,6,930}, +{2,5,96},{2,4,106},{2,4,194},{5,0,3060},{0,6,1144},{1,4,45},{0,3,1086},{6,1,3060},{0,3,1086},{2,5,1476},{2,5,1476},{2,5,1476},{1,4,1460},{1,5,666},{1,4,52},{1,4,52},{1,3,362},{0,3,1356},{0,3,321},{2,5,32},{2,5,32},{2,5,32},{2,3,97},{4,0,650},{1,4,36},{1,4,36},{0,3,125},{3,2,650},{0,3,125},{4,3,882},{1,6,16},{2,4,90}, +{1,4,9},{4,3,882},{6,2,882},{1,4,9},{0,3,1082},{6,2,882},{0,3,1082},{1,0,1460},{1,0,1460},{1,0,1460},{1,0,1460},{1,4,52},{1,4,52},{1,4,52},{1,2,65},{0,3,200},{0,3,200},{2,7,1892},{2,6,1090},{2,4,1370},{2,4,1062},{1,7,3100},{1,5,1169},{1,4,151},{1,3,1665},{0,5,4036},{0,3,1678},{2,7,1051},{2,6,249},{3,4,493},{2,4,221},{3,4,3060}, +{0,6,883},{1,4,126},{0,4,1528},{7,1,3060},{0,4,1528},{2,5,1035},{2,5,1035},{2,5,1035},{2,4,1026},{1,6,723},{1,4,115},{1,4,115},{1,3,65},{0,4,1004},{0,3,78},{2,5,194},{2,5,194},{2,5,194},{2,4,185},{2,4,648},{1,4,90},{1,4,90},{1,3,40},{7,0,648},{1,3,40},{5,2,882},{2,6,80},{3,4,52},{2,4,52},{5,2,882},{5,3,882},{2,4,52}, +{0,4,1332},{5,3,882},{0,4,1332},{2,0,1010},{2,0,1010},{2,0,1010},{2,0,1010},{1,4,34},{1,4,34},{1,4,34},{1,3,61},{0,3,74},{0,3,74},{2,7,1892},{2,6,898},{2,5,1451},{2,4,1094},{2,6,3501},{1,6,1308},{1,5,589},{1,4,1510},{0,5,3940},{0,4,1116},{3,6,1051},{3,5,377},{3,4,381},{3,4,429},{5,1,3060},{0,6,1059},{2,4,312},{0,4,1016},{6,2,3060}, +{0,4,1016},{2,6,882},{2,6,882},{2,6,882},{2,4,898},{1,6,835},{1,5,189},{1,5,189},{1,3,209},{0,4,1036},{0,3,270},{3,4,185},{3,4,185},{3,4,185},{3,4,233},{3,3,650},{1,5,20},{1,5,20},{1,3,40},{6,1,650},{1,3,40},{6,1,882},{2,6,16},{3,4,212},{2,4,212},{6,1,882},{4,4,882},{2,4,212},{0,4,980},{4,4,882},{0,4,980},{2,0,882}, +{2,0,882},{2,0,882},{2,0,882},{1,5,173},{1,5,173},{1,5,173},{1,3,173},{0,4,136},{0,4,136},{2,7,2404},{2,7,1116},{2,5,1595},{2,5,1235},{2,7,3244},{1,6,1404},{2,5,619},{1,4,1446},{0,6,3804},{0,4,892},{3,7,957},{3,6,195},{3,5,169},{3,4,509},{6,0,3060},{0,7,936},{1,5,196},{0,4,888},{3,4,3060},{0,4,888},{2,7,1035},{2,7,1035},{2,7,1035}, +{2,5,1091},{2,5,835},{2,4,317},{2,4,317},{2,3,369},{0,5,875},{1,3,396},{3,5,25},{3,5,25},{3,5,25},{3,4,25},{4,2,650},{1,5,52},{1,5,52},{2,3,200},{5,2,650},{2,3,200},{7,0,884},{2,7,106},{3,5,144},{1,5,160},{7,0,884},{3,5,884},{1,5,160},{0,4,884},{3,5,884},{0,4,884},{2,0,1010},{2,0,1010},{2,0,1010},{2,0,1010},{2,4,173}, +{2,4,173},{2,4,173},{2,3,173},{0,4,8},{0,4,8},{3,7,2430},{2,7,1404},{3,5,1610},{2,5,1411},{2,7,3148},{2,6,1309},{2,5,91},{2,4,1325},{0,6,3484},{0,4,1180},{3,7,909},{3,6,83},{3,5,89},{3,5,221},{4,4,3051},{0,7,1000},{2,5,66},{1,4,1053},{7,2,3051},{1,4,1053},{2,7,1403},{2,7,1403},{2,7,1403},{2,5,1395},{2,6,681},{2,5,75},{2,5,75}, +{2,4,425},{0,5,795},{0,4,280},{3,6,34},{3,6,34},{3,6,34},{3,4,73},{5,1,656},{2,5,50},{2,5,50},{1,4,153},{7,1,656},{1,4,153},{5,4,884},{2,7,10},{3,5,80},{2,5,17},{5,4,884},{7,3,884},{2,5,17},{0,4,1044},{7,3,884},{0,4,1044},{2,0,1394},{2,0,1394},{2,0,1394},{2,0,1394},{2,4,61},{2,4,61},{2,4,61},{2,3,61},{0,4,136}, +{0,4,136},{3,7,2214},{3,7,1150},{3,5,1358},{3,5,1094},{2,7,3652},{2,6,1147},{2,5,109},{2,4,1595},{0,7,3724},{0,5,1402},{3,7,1314},{3,7,250},{3,5,458},{3,5,194},{5,3,3060},{1,7,888},{2,5,93},{0,5,1398},{6,3,3060},{0,5,1398},{3,6,1060},{3,6,1060},{3,6,1060},{3,5,1069},{2,7,736},{2,5,84},{2,5,84},{2,4,74},{0,6,820},{1,4,81},{3,6,160}, +{3,6,160},{3,6,160},{3,5,169},{6,0,650},{2,5,68},{2,5,68},{1,4,45},{3,4,650},{1,4,45},{6,3,884},{3,7,106},{4,5,50},{3,5,50},{6,3,884},{6,4,884},{3,5,50},{0,5,1394},{6,4,884},{0,5,1394},{3,0,1044},{3,0,1044},{3,0,1044},{3,0,1044},{2,5,20},{2,5,20},{2,5,20},{2,4,65},{0,5,8},{0,5,8},{3,7,2566},{3,7,894},{3,6,1469}, +{3,5,1062},{3,7,3535},{2,7,1332},{2,6,619},{2,5,1554},{0,7,3276},{0,5,1146},{4,7,1080},{4,6,398},{4,5,374},{4,5,446},{6,2,3051},{1,7,1016},{3,5,299},{0,5,1046},{5,4,3051},{0,5,1046},{3,7,885},{3,7,885},{3,7,885},{3,5,893},{2,7,800},{2,6,178},{2,6,178},{2,4,170},{0,6,660},{1,4,225},{4,5,205},{4,5,205},{4,5,205},{4,5,277},{5,2,656}, +{2,6,34},{2,6,34},{2,4,26},{7,2,656},{2,4,26},{7,2,884},{3,7,10},{4,5,178},{3,5,178},{7,2,884},{5,5,884},{3,5,178},{0,5,1010},{5,5,884},{0,5,1010},{3,0,884},{3,0,884},{3,0,884},{3,0,884},{2,6,153},{2,6,153},{2,6,153},{2,4,145},{0,5,136},{0,5,136},{4,7,3320},{3,7,1150},{3,6,1549},{3,6,1249},{3,7,3487},{2,7,1364},{2,6,603}, +{2,5,1426},{0,7,3340},{1,5,892},{4,7,1016},{4,7,236},{4,6,206},{4,5,478},{7,1,3051},{2,7,964},{2,6,203},{1,5,883},{4,5,3051},{1,5,883},{3,7,1029},{3,7,1029},{3,7,1029},{3,6,1080},{3,6,852},{3,5,326},{3,5,326},{3,4,374},{0,6,884},{2,4,371},{4,6,37},{4,6,37},{4,6,37},{4,5,37},{6,1,656},{2,6,34},{2,6,34},{3,4,178},{6,3,656}, +{3,4,178},{5,6,890},{3,7,170},{4,6,170},{2,6,178},{5,6,890},{4,6,890},{2,6,178},{0,5,882},{4,6,890},{0,5,882},{3,0,980},{3,0,980},{3,0,980},{3,0,980},{3,5,205},{3,5,205},{3,5,205},{3,4,205},{1,5,10},{1,5,10},{4,7,2936},{4,7,1676},{4,6,1678},{3,6,1361},{3,7,3951},{3,7,1367},{3,6,129},{3,5,1335},{1,7,3496},{1,5,1116},{4,7,1336}, +{4,7,76},{4,6,78},{4,6,254},{5,5,3048},{2,7,1124},{3,6,93},{2,5,1026},{3,6,3048},{2,5,1026},{3,7,1557},{3,7,1557},{3,7,1557},{3,6,1336},{3,7,702},{3,6,104},{3,6,104},{3,5,494},{0,7,667},{1,5,275},{4,7,40},{4,7,40},{4,7,40},{4,5,53},{7,0,650},{3,6,68},{3,6,68},{2,5,185},{3,5,650},{2,5,185},{7,3,890},{4,7,72},{4,6,74}, +{3,6,29},{7,3,890},{6,5,890},{3,6,29},{0,5,1010},{6,5,890},{0,5,1010},{3,0,1332},{3,0,1332},{3,0,1332},{3,0,1332},{3,5,61},{3,5,61},{3,5,61},{3,4,61},{1,5,106},{1,5,106},{4,7,3116},{4,7,1316},{4,6,1354},{4,6,1134},{4,7,4084},{3,7,1133},{3,6,75},{3,5,1533},{1,7,3676},{1,6,1470},{5,7,1429},{4,7,355},{4,6,393},{4,6,173},{6,4,3051}, +{3,7,1124},{3,6,66},{1,6,1469},{7,4,3051},{1,6,1469},{4,7,1091},{4,7,1091},{4,7,1091},{4,6,1118},{3,7,729},{3,6,59},{3,6,59},{3,5,89},{0,7,820},{2,5,90},{4,7,130},{4,7,130},{4,7,130},{4,6,157},{7,1,656},{3,6,50},{3,6,50},{2,5,41},{7,3,656},{2,5,41},{7,4,890},{4,7,234},{5,6,52},{4,6,52},{7,4,890},{7,5,890},{4,6,52}, +{0,5,1460},{7,5,890},{0,5,1460},{4,0,1082},{4,0,1082},{4,0,1082},{4,0,1082},{3,6,10},{3,6,10},{3,6,10},{3,5,73},{1,6,10},{1,6,10},{4,7,3820},{4,7,1540},{4,7,1495},{4,6,1038},{4,7,4084},{3,7,1469},{3,6,571},{3,6,1606},{2,7,3916},{1,6,1150},{5,7,1349},{5,7,425},{5,6,373},{5,6,469},{7,3,3048},{3,7,1348},{4,6,292},{1,6,1069},{6,5,3048}, +{1,6,1069},{4,7,1011},{4,7,1011},{4,7,1011},{4,6,894},{3,7,1161},{3,7,173},{3,7,173},{3,5,137},{1,7,659},{2,5,186},{5,6,229},{5,6,229},{5,6,229},{5,6,325},{6,3,650},{3,7,52},{3,7,52},{3,5,16},{6,4,650},{3,5,16},{6,6,890},{5,7,200},{5,6,148},{4,6,148},{6,6,890},{6,6,890},{4,6,148},{0,6,1044},{6,6,890},{0,6,1044},{4,0,890}, +{4,0,890},{4,0,890},{4,0,890},{3,7,137},{3,7,137},{3,7,137},{3,5,121},{1,6,106},{1,6,106},{5,7,4054},{4,7,2276},{4,7,1511},{4,7,1271},{4,7,4596},{4,7,1596},{3,7,577},{3,6,1414},{2,7,4204},{2,6,900},{5,7,1653},{5,7,377},{5,7,249},{5,6,453},{5,7,3048},{4,7,1371},{3,7,216},{2,6,884},{5,6,3048},{2,6,884},{4,7,1315},{4,7,1315},{4,7,1315}, +{4,6,1054},{4,7,875},{4,6,341},{4,6,341},{4,5,385},{1,7,835},{3,5,352},{5,7,53},{5,7,53},{5,7,53},{5,6,53},{7,2,650},{3,7,20},{3,7,20},{4,5,160},{5,5,650},{4,5,160},{7,5,890},{5,7,328},{5,7,200},{3,7,200},{7,5,890},{5,7,900},{3,7,200},{0,6,884},{5,7,900},{0,6,884},{4,0,954},{4,0,954},{4,0,954},{4,0,954},{4,6,241}, +{4,6,241},{4,6,241},{4,5,241},{2,6,16},{2,6,16},{5,7,4022},{5,7,2394},{5,7,1754},{4,7,1319},{5,7,4921},{4,7,1660},{4,7,175},{4,6,1353},{3,7,4380},{2,6,1060},{6,7,2021},{5,7,713},{5,7,73},{5,7,293},{6,6,3051},{4,7,1611},{4,7,126},{3,6,1005},{4,7,3051},{3,6,1005},{5,7,1718},{5,7,1718},{5,7,1718},{4,7,1283},{4,7,859},{4,7,139},{4,7,139}, +{4,5,465},{2,7,779},{2,6,276},{5,7,37},{5,7,37},{5,7,37},{5,6,37},{5,6,648},{4,7,90},{4,7,90},{3,6,221},{4,6,648},{3,6,221},{7,6,900},{6,7,452},{5,7,72},{4,7,45},{7,6,900},{7,6,884},{4,7,45},{0,6,980},{7,6,884},{0,6,980},{4,0,1274},{4,0,1274},{4,0,1274},{4,0,1274},{4,6,65},{4,6,65},{4,6,65},{4,5,65},{2,6,80}, +{2,6,80},{5,7,4265},{5,7,2373},{5,7,1349},{5,7,1173},{5,7,4606},{4,7,2065},{4,7,40},{4,6,1266},{3,7,4455},{3,6,1261},{6,7,1649},{6,7,1025},{5,7,325},{5,7,149},{7,5,2817},{5,7,1514},{4,7,36},{3,6,1197},{6,6,2841},{3,6,1197},{5,7,1349},{5,7,1349},{5,7,1349},{5,7,1173},{4,7,1300},{4,7,40},{4,7,40},{4,6,110},{2,7,1040},{3,6,105},{5,7,325}, +{5,7,325},{5,7,325},{5,7,149},{6,5,650},{4,7,36},{4,7,36},{3,6,41},{3,7,650},{3,6,41},{7,6,801},{6,7,449},{6,7,49},{4,7,36},{7,6,801},{6,7,761},{4,7,36},{0,6,1181},{6,7,761},{0,6,1181},{5,0,1124},{5,0,1124},{5,0,1124},{5,0,1124},{4,7,4},{4,7,4},{4,7,4},{4,6,85},{2,7,16},{2,7,16},{5,7,4345},{5,7,2453},{5,7,1429}, +{5,7,901},{5,7,4190},{5,7,1770},{4,7,360},{4,6,1266},{4,7,3861},{2,7,1041},{6,7,1281},{6,7,657},{6,7,257},{5,7,325},{6,7,2250},{5,7,1194},{5,7,170},{2,7,977},{5,7,2250},{2,7,977},{5,7,1429},{5,7,1429},{5,7,1429},{5,7,901},{5,7,1274},{4,7,360},{4,7,360},{4,6,110},{3,7,979},{3,6,153},{6,7,257},{6,7,257},{6,7,257},{5,7,325},{7,4,648}, +{5,7,170},{5,7,170},{4,6,10},{7,5,648},{4,6,10},{7,7,521},{6,7,401},{6,7,1},{5,7,1},{7,7,521},{6,7,521},{5,7,1},{0,7,961},{6,7,521},{0,7,961},{5,0,900},{5,0,900},{5,0,900},{5,0,900},{4,7,164},{4,7,164},{4,7,164},{4,6,101},{2,7,80},{2,7,80},{6,7,3669},{5,7,2917},{5,7,1893},{5,7,1013},{5,7,4158},{5,7,1386},{5,7,362}, +{4,7,1049},{4,7,3381},{3,7,555},{6,7,1169},{6,7,545},{6,7,145},{6,7,73},{7,6,1802},{5,7,1130},{5,7,106},{3,7,530},{7,6,1770},{3,7,530},{5,7,1893},{5,7,1893},{5,7,1893},{5,7,1013},{5,7,1242},{5,7,362},{5,7,362},{5,6,402},{3,7,1251},{4,6,339},{6,7,145},{6,7,145},{6,7,145},{6,7,73},{7,5,680},{5,7,106},{5,7,106},{5,6,146},{6,6,648}, +{5,6,146},{7,7,265},{7,7,193},{6,7,81},{6,7,9},{7,7,265},{7,7,305},{6,7,9},{0,7,529},{7,7,305},{0,7,529},{5,0,932},{5,0,932},{5,0,932},{5,0,932},{5,7,281},{5,7,281},{5,7,281},{5,6,281},{3,7,26},{3,7,26},{6,7,3077},{6,7,2453},{6,7,2053},{5,7,1509},{6,7,3438},{5,7,1386},{5,7,362},{5,7,650},{5,7,3195},{3,7,283},{7,7,1293}, +{6,7,689},{6,7,289},{6,7,25},{7,6,1386},{6,7,786},{5,7,298},{4,7,261},{6,7,1386},{4,7,261},{6,7,2053},{6,7,2053},{6,7,2053},{5,7,1509},{5,7,1594},{5,7,362},{5,7,362},{5,6,434},{4,7,1260},{3,7,283},{6,7,289},{6,7,289},{6,7,289},{6,7,25},{6,7,650},{5,7,298},{5,7,298},{4,7,261},{5,7,650},{4,7,261},{7,7,137},{7,7,65},{7,7,16}, +{6,7,25},{7,7,137},{7,7,113},{6,7,25},{0,7,225},{7,7,113},{0,7,225},{5,0,1220},{5,0,1220},{5,0,1220},{5,0,1220},{5,7,73},{5,7,73},{5,7,73},{5,6,73},{3,7,58},{3,7,58},{6,7,2870},{6,7,2246},{6,7,1846},{6,7,1366},{6,7,2889},{6,7,1785},{5,7,821},{5,7,137},{5,7,2700},{4,7,126},{7,7,771},{7,7,699},{7,7,650},{6,7,277},{7,7,1107}, +{6,7,696},{6,7,296},{4,7,45},{6,7,1080},{4,7,45},{6,7,1846},{6,7,1846},{6,7,1846},{6,7,1366},{6,7,1865},{5,7,821},{5,7,821},{5,7,137},{4,7,1611},{4,7,126},{7,7,650},{7,7,650},{7,7,650},{6,7,277},{7,6,648},{6,7,296},{6,7,296},{4,7,45},{7,6,680},{4,7,45},{7,7,146},{7,7,74},{7,7,25},{7,7,1},{7,7,146},{7,7,50},{7,7,1}, +{0,7,36},{7,7,50},{0,7,36},{6,0,1170},{6,0,1170},{6,0,1170},{6,0,1170},{5,7,145},{5,7,145},{5,7,145},{5,7,101},{4,7,90},{4,7,90},{6,7,2962},{6,7,2338},{6,7,1938},{6,7,1314},{6,7,2677},{6,7,1429},{6,7,1029},{5,7,85},{5,7,2536},{4,7,122},{7,7,531},{7,7,459},{7,7,410},{7,7,338},{7,7,771},{7,7,627},{6,7,404},{5,7,4},{7,7,827}, +{5,7,4},{6,7,1938},{6,7,1938},{6,7,1938},{6,7,1314},{6,7,1653},{6,7,1029},{6,7,1029},{5,7,85},{5,7,1512},{4,7,122},{7,7,410},{7,7,410},{7,7,410},{7,7,338},{7,7,650},{6,7,404},{6,7,404},{5,7,4},{6,7,596},{5,7,4},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{6,0,914}, +{6,0,914},{6,0,914},{6,0,914},{5,7,481},{5,7,481},{5,7,481},{5,7,85},{4,7,122},{4,7,122},{7,7,2924},{6,7,2338},{6,7,1938},{6,7,1314},{6,7,2373},{6,7,1125},{6,7,725},{5,7,325},{6,7,2132},{5,7,232},{7,7,323},{7,7,251},{7,7,202},{7,7,130},{7,7,467},{7,7,323},{7,7,274},{5,7,36},{7,7,459},{5,7,36},{6,7,1938},{6,7,1938},{6,7,1938}, +{6,7,1314},{6,7,1349},{6,7,725},{6,7,725},{5,7,325},{5,7,1256},{5,7,232},{7,7,202},{7,7,202},{7,7,202},{7,7,130},{7,7,346},{7,7,274},{7,7,274},{5,7,36},{7,7,410},{5,7,36},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{6,0,914},{6,0,914},{6,0,914},{6,0,914},{6,7,325}, +{6,7,325},{6,7,325},{5,7,325},{5,7,232},{5,7,232},{7,7,2092},{7,7,2020},{7,7,1971},{6,7,1570},{7,7,2140},{6,7,1077},{6,7,677},{6,7,85},{6,7,1588},{5,7,232},{7,7,243},{7,7,171},{7,7,122},{7,7,50},{7,7,291},{7,7,147},{7,7,98},{6,7,4},{7,7,219},{6,7,4},{7,7,1971},{7,7,1971},{7,7,1971},{6,7,1570},{6,7,1301},{6,7,677},{6,7,677}, +{6,7,85},{6,7,1188},{5,7,232},{7,7,122},{7,7,122},{7,7,122},{7,7,50},{7,7,170},{7,7,98},{7,7,98},{6,7,4},{7,7,170},{6,7,4},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{6,0,1170},{6,0,1170},{6,0,1170},{6,0,1170},{6,7,277},{6,7,277},{6,7,277},{6,7,85},{5,7,232}, +{5,7,232},{0,4,1618},{0,3,436},{0,2,74},{0,2,866},{0,2,3411},{0,2,2531},{0,1,1251},{0,1,2531},{0,1,3772},{0,1,2892},{0,4,1618},{0,3,436},{0,2,74},{0,2,866},{0,2,3411},{0,2,2531},{0,1,1251},{0,1,2531},{2,0,3376},{0,1,2531},{0,1,25},{0,1,25},{0,1,25},{0,1,49},{0,0,360},{0,0,232},{0,0,232},{0,0,149},{0,0,332},{0,0,185},{0,1,25}, +{0,1,25},{0,1,25},{0,1,49},{0,0,360},{0,0,232},{0,0,232},{0,0,149},{0,0,296},{0,0,149},{1,2,1570},{0,3,436},{0,2,74},{0,2,866},{1,2,1570},{0,2,1570},{0,2,866},{0,1,1570},{0,2,1570},{0,1,1570},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,4,1586},{0,3,340},{0,2,10}, +{0,2,450},{0,3,4016},{0,2,2627},{0,2,1411},{0,1,2691},{0,1,4572},{0,1,3052},{0,4,1586},{0,3,340},{0,2,10},{0,2,450},{1,1,3968},{0,2,2627},{0,2,1411},{0,1,2691},{2,0,4016},{0,1,2691},{0,2,1},{0,2,1},{0,2,1},{0,1,1},{0,1,530},{0,1,362},{0,1,362},{0,0,325},{0,0,620},{0,0,361},{0,2,1},{0,2,1},{0,2,1},{0,1,1},{0,1,530}, +{0,1,362},{0,1,362},{0,0,325},{0,0,584},{0,0,325},{2,1,1570},{0,3,340},{0,2,10},{0,2,450},{2,1,1570},{4,0,1570},{0,2,450},{0,1,1730},{4,0,1570},{0,1,1730},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,5,1576},{0,4,290},{0,2,202},{0,2,290},{0,3,4656},{0,2,2979},{0,2,1251}, +{0,1,3107},{0,1,5628},{0,1,3468},{0,5,1576},{0,4,290},{0,2,202},{0,2,290},{0,3,4656},{0,2,2979},{0,2,1251},{0,1,3107},{1,1,4656},{0,1,3107},{0,3,16},{0,3,16},{0,3,16},{0,1,81},{0,1,802},{0,1,442},{0,1,442},{0,0,629},{0,0,1036},{0,0,665},{0,3,16},{0,3,16},{0,3,16},{0,1,81},{0,1,802},{0,1,442},{0,1,442},{0,0,629},{1,0,818}, +{0,0,629},{3,0,1576},{0,4,290},{0,2,202},{0,2,290},{3,0,1576},{3,1,1576},{0,2,290},{0,1,2146},{3,1,1576},{0,1,2146},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,5,1640},{0,4,162},{0,3,241},{0,2,386},{0,4,5539},{0,3,3512},{0,2,1347},{0,1,3779},{0,2,6396},{0,1,4140},{0,5,1640}, +{0,4,162},{0,3,241},{0,2,386},{1,2,5435},{0,3,3512},{0,2,1347},{0,1,3779},{0,2,5435},{0,1,3779},{0,3,16},{0,3,16},{0,3,16},{0,2,25},{0,1,1202},{0,1,650},{0,1,650},{0,1,970},{0,0,1580},{0,0,1097},{0,3,16},{0,3,16},{0,3,16},{0,2,25},{1,0,1170},{0,1,650},{0,1,650},{0,1,970},{1,0,1154},{0,1,970},{2,2,1576},{0,4,162},{0,3,241}, +{0,2,386},{2,2,1576},{5,0,1576},{0,2,386},{0,2,1730},{5,0,1576},{0,2,1730},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,6,1667},{0,5,259},{0,3,286},{0,3,406},{0,4,5440},{0,3,3035},{0,2,1284},{0,2,3504},{0,2,6513},{0,2,4465},{0,6,1667},{0,5,259},{0,3,286},{0,3,406},{2,1,5424}, +{0,3,3035},{0,2,1284},{0,2,3504},{4,0,5424},{0,2,3504},{0,4,81},{0,4,81},{0,4,81},{0,2,97},{0,2,1160},{0,2,500},{0,2,500},{0,1,520},{0,1,1521},{0,1,881},{0,4,81},{0,4,81},{0,4,81},{0,2,97},{0,2,1160},{0,2,500},{0,2,500},{0,1,520},{0,1,1160},{0,1,520},{2,3,1576},{0,5,178},{1,3,100},{0,3,325},{2,3,1576},{6,0,1576},{0,3,325}, +{0,2,1568},{6,0,1576},{0,2,1568},{0,0,81},{0,0,81},{0,0,81},{0,0,81},{0,0,9},{0,0,9},{0,0,9},{0,0,1},{0,0,37},{0,0,37},{0,7,1865},{0,5,339},{0,3,734},{0,3,374},{0,5,5435},{0,3,3019},{0,3,814},{0,2,2992},{0,2,7025},{0,2,3953},{1,5,1865},{0,5,339},{1,3,293},{0,3,374},{3,0,5435},{0,3,3019},{0,3,814},{0,2,2992},{3,1,5435}, +{0,2,2992},{0,5,314},{0,5,314},{0,5,314},{0,3,370},{0,3,1170},{0,2,340},{0,2,340},{0,1,392},{0,1,1713},{0,1,753},{1,3,289},{1,3,289},{1,3,289},{1,2,289},{1,1,1154},{0,2,340},{0,2,340},{0,1,392},{1,1,1170},{0,1,392},{4,0,1576},{0,5,50},{1,3,4},{0,3,85},{4,0,1576},{5,1,1576},{0,3,85},{0,2,1696},{5,1,1576},{0,2,1696},{0,0,289}, +{0,0,289},{0,0,289},{0,0,289},{0,1,4},{0,1,4},{0,1,4},{0,0,49},{0,0,85},{0,0,85},{0,7,2265},{0,6,787},{1,3,1401},{0,3,726},{0,5,5515},{0,4,2664},{0,3,462},{0,2,2864},{0,3,7363},{0,2,3825},{1,6,1667},{1,5,405},{1,3,245},{1,3,377},{2,2,5427},{0,4,2664},{0,3,462},{0,2,2864},{5,0,5427},{0,2,2864},{0,5,634},{0,5,634},{0,5,634}, +{0,3,626},{0,3,1202},{0,3,362},{0,3,362},{0,1,520},{0,2,2145},{0,1,881},{1,4,106},{1,4,106},{1,4,106},{1,2,145},{2,0,1154},{0,3,362},{0,3,362},{0,1,520},{3,0,1154},{0,1,520},{2,4,1576},{0,6,162},{1,3,164},{0,3,101},{2,4,1576},{7,0,1576},{0,3,101},{0,2,2080},{7,0,1576},{0,2,2080},{0,0,625},{0,0,625},{0,0,625},{0,0,625},{0,1,36}, +{0,1,36},{0,1,36},{0,1,36},{0,0,261},{0,0,261},{1,6,2775},{0,6,1091},{1,4,1422},{0,3,1462},{0,6,5427},{0,4,2536},{0,3,494},{0,2,3120},{0,3,7635},{0,2,4081},{1,6,1619},{1,5,165},{1,4,266},{1,3,361},{3,1,5427},{0,4,2536},{0,3,494},{0,2,3120},{4,1,5427},{0,2,3120},{0,6,1090},{0,6,1090},{0,6,1090},{0,3,1138},{0,4,1152},{0,3,170},{0,3,170}, +{0,2,416},{0,2,2145},{0,1,1265},{1,4,10},{1,4,10},{1,4,10},{1,3,37},{0,4,1152},{0,3,170},{0,3,170},{0,2,416},{2,1,1152},{0,2,416},{3,3,1570},{0,6,2},{1,4,265},{1,3,360},{3,3,1570},{6,1,1570},{1,3,360},{0,3,1768},{6,1,1570},{0,3,1768},{0,0,1089},{0,0,1089},{0,0,1089},{0,0,1089},{0,2,4},{0,2,4},{0,2,4},{0,1,4},{0,1,365}, +{0,1,365},{1,7,2796},{1,6,1432},{1,4,1413},{1,4,1593},{0,7,5435},{0,5,2360},{0,4,299},{0,3,2594},{0,3,8400},{0,3,4530},{1,7,1640},{1,6,276},{1,4,257},{1,4,437},{4,0,5427},{0,5,2360},{0,4,299},{0,3,2594},{3,2,5427},{0,3,2594},{1,5,1221},{1,5,1221},{1,5,1221},{1,3,1229},{0,5,1184},{0,4,250},{0,4,250},{0,2,146},{0,2,2451},{0,2,1107},{1,5,65}, +{1,5,65},{1,5,65},{1,3,73},{1,3,1154},{0,4,250},{0,4,250},{0,2,146},{1,2,1154},{0,2,146},{4,2,1576},{0,6,128},{2,4,130},{0,4,74},{4,2,1576},{5,2,1576},{0,4,74},{0,3,1570},{5,2,1576},{0,3,1570},{1,0,1220},{1,0,1220},{1,0,1220},{1,0,1220},{0,3,4},{0,3,4},{0,3,4},{0,1,121},{0,1,482},{0,1,482},{1,7,3180},{1,6,1464},{1,4,1813}, +{1,4,1513},{0,7,5515},{0,5,2168},{0,4,59},{0,3,2242},{0,4,8764},{0,3,4178},{2,6,1894},{1,6,308},{2,4,326},{1,4,357},{2,4,5427},{0,5,2168},{0,4,59},{0,3,2242},{7,0,5427},{0,3,2242},{1,6,1448},{1,6,1448},{1,6,1448},{1,4,1512},{0,5,1184},{0,4,58},{0,4,58},{0,2,178},{0,2,2995},{0,2,1139},{1,6,292},{1,6,292},{1,6,292},{2,3,325},{2,2,1152}, +{0,4,58},{0,4,58},{0,2,178},{5,0,1152},{0,2,178},{5,1,1570},{0,7,34},{2,4,2},{0,4,10},{5,1,1570},{4,3,1570},{0,4,10},{0,3,1666},{4,3,1570},{0,3,1666},{1,0,1412},{1,0,1412},{1,0,1412},{1,0,1412},{0,3,36},{0,3,36},{0,3,36},{0,2,9},{0,1,722},{0,1,722},{1,7,3816},{1,6,1748},{1,5,2450},{1,4,1685},{0,7,5983},{0,6,2180},{0,4,207}, +{0,3,2278},{0,4,9004},{0,3,4038},{2,7,1700},{2,6,462},{2,4,230},{2,4,406},{3,3,5420},{0,6,2176},{0,4,203},{0,3,2274},{6,1,5420},{0,3,2274},{1,6,1604},{1,6,1604},{1,6,1604},{1,4,1604},{0,6,1156},{0,4,126},{0,4,126},{0,3,429},{0,3,3044},{0,2,1307},{2,5,136},{2,5,136},{2,5,136},{2,3,149},{3,1,1152},{0,4,122},{0,4,122},{0,3,425},{4,1,1152}, +{0,3,425},{6,0,1570},{0,7,130},{2,4,130},{1,4,85},{6,0,1570},{3,4,1570},{1,4,85},{0,3,2018},{3,4,1570},{0,3,2018},{1,0,1600},{1,0,1600},{1,0,1600},{1,0,1600},{0,4,5},{0,4,5},{0,4,5},{0,2,29},{0,2,866},{0,2,866},{1,7,4520},{1,7,1608},{1,5,2418},{1,4,1925},{1,7,5996},{0,6,1956},{0,5,409},{0,4,2751},{0,5,9020},{0,3,3846},{2,7,1604}, +{2,6,174},{2,5,297},{2,4,342},{4,2,5420},{0,6,1856},{0,5,309},{0,4,2651},{5,2,5420},{0,4,2651},{1,7,1604},{1,7,1604},{1,7,1604},{1,4,1636},{0,7,1302},{0,5,120},{0,5,120},{0,3,189},{0,3,2820},{0,3,1245},{2,5,8},{2,5,8},{2,5,8},{2,4,53},{4,0,1154},{0,5,20},{0,5,20},{0,3,89},{3,2,1154},{0,3,89},{4,4,1568},{1,7,8},{2,5,293}, +{0,5,293},{4,4,1568},{7,2,1568},{0,5,293},{0,4,1810},{7,2,1568},{0,4,1810},{1,0,1600},{1,0,1600},{1,0,1600},{1,0,1600},{0,5,116},{0,5,116},{0,5,116},{0,3,164},{0,2,610},{0,2,610},{2,7,4356},{1,7,2004},{2,5,2635},{1,5,2006},{1,7,5924},{0,6,2316},{0,5,499},{0,4,2337},{0,5,8300},{0,4,3420},{2,7,1955},{2,7,299},{2,5,234},{2,5,474},{5,1,5420}, +{0,6,1955},{0,5,138},{0,4,1976},{4,3,5420},{0,4,1976},{1,7,1955},{1,7,1955},{1,7,1955},{1,5,1942},{1,6,1427},{0,5,435},{0,5,435},{0,3,378},{0,4,2628},{0,3,642},{2,6,53},{2,6,53},{2,6,53},{2,4,53},{2,4,1152},{0,5,74},{0,5,74},{0,3,17},{7,0,1152},{0,3,17},{5,3,1570},{1,7,98},{3,5,164},{1,5,100},{5,3,1570},{6,3,1570},{1,5,100}, +{0,4,1576},{6,3,1570},{0,4,1576},{1,0,1906},{1,0,1906},{1,0,1906},{1,0,1906},{1,4,234},{1,4,234},{1,4,234},{1,2,325},{0,3,626},{0,3,626},{2,7,4356},{2,7,1964},{2,5,2267},{2,5,2027},{1,7,6404},{1,6,2220},{1,5,117},{1,4,2314},{0,5,8204},{0,4,2684},{3,7,1929},{2,7,283},{3,5,365},{2,5,346},{6,0,5420},{0,7,1712},{1,5,68},{0,4,1784},{3,4,5420}, +{0,4,1784},{2,6,1942},{2,6,1942},{2,6,1942},{2,4,2006},{1,6,1219},{1,5,117},{1,5,117},{1,3,209},{0,4,2340},{0,3,514},{2,6,261},{2,6,261},{2,6,261},{2,4,325},{3,3,1154},{0,6,50},{0,6,50},{1,3,160},{6,1,1154},{1,3,160},{6,2,1568},{2,7,58},{3,5,4},{1,5,4},{6,2,1568},{5,4,1568},{1,5,4},{0,4,1640},{5,4,1568},{0,4,1640},{2,0,1906}, +{2,0,1906},{2,0,1906},{2,0,1906},{1,4,74},{1,4,74},{1,4,74},{1,3,65},{0,3,370},{0,3,370},{2,7,4868},{2,7,1740},{2,5,2411},{2,5,1691},{2,7,6548},{1,7,2244},{1,5,165},{1,4,2250},{0,6,7668},{0,4,2460},{3,7,1817},{3,7,525},{3,5,221},{3,5,441},{4,4,5419},{0,7,1712},{1,5,164},{0,4,1976},{7,2,5419},{0,4,1976},{2,7,1619},{2,7,1619},{2,7,1619}, +{2,5,1627},{1,7,1155},{1,5,101},{1,5,101},{1,3,417},{0,5,2379},{0,4,696},{3,5,157},{3,5,157},{3,5,157},{3,4,157},{4,2,1154},{0,6,82},{0,6,82},{0,4,212},{5,2,1154},{0,4,212},{7,1,1568},{2,7,122},{3,5,100},{2,5,73},{7,1,1568},{4,5,1568},{2,5,73},{0,4,1960},{4,5,1568},{0,4,1960},{2,0,1618},{2,0,1618},{2,0,1618},{2,0,1618},{1,5,1}, +{1,5,1},{1,5,1},{1,3,17},{0,3,370},{0,3,370},{3,7,5570},{2,7,2028},{2,6,2394},{2,5,1867},{2,7,6452},{1,7,1956},{1,6,439},{1,4,2698},{0,6,7348},{0,4,2748},{3,7,2089},{3,7,189},{3,6,334},{3,5,329},{5,3,5419},{1,7,1875},{1,6,358},{0,5,2145},{6,3,5419},{0,5,2145},{2,7,1667},{2,7,1667},{2,7,1667},{2,5,1611},{1,7,1331},{1,6,115},{1,6,115}, +{1,4,198},{0,5,1979},{0,4,248},{3,6,10},{3,6,10},{3,6,10},{3,5,73},{5,1,1160},{1,6,34},{1,6,34},{0,4,52},{7,1,1160},{0,4,52},{5,5,1570},{3,7,180},{4,5,320},{2,5,281},{5,5,1570},{3,6,1570},{2,5,281},{0,5,1856},{3,6,1570},{0,5,1856},{2,0,1586},{2,0,1586},{2,0,1586},{2,0,1586},{1,6,106},{1,6,106},{1,6,106},{1,4,162},{0,4,212}, +{0,4,212},{3,7,5354},{3,7,2770},{3,6,2717},{2,6,1986},{2,7,6956},{1,7,2244},{1,6,457},{1,5,2351},{0,7,7268},{0,5,1974},{4,7,2384},{3,7,270},{3,6,217},{3,6,517},{6,2,5419},{1,7,1920},{1,6,133},{0,5,1650},{5,4,5419},{0,5,1650},{2,7,2180},{2,7,2180},{2,7,2180},{2,6,1905},{2,7,1480},{1,6,376},{1,6,376},{1,4,333},{0,5,1988},{0,4,203},{3,7,45}, +{3,7,45},{3,7,45},{3,5,37},{6,0,1154},{1,6,52},{1,6,52},{1,4,9},{3,4,1154},{1,4,9},{6,4,1568},{3,7,234},{3,6,181},{1,6,117},{6,4,1568},{7,4,1568},{1,6,117},{0,5,1586},{7,4,1568},{0,5,1586},{2,0,1856},{2,0,1856},{2,0,1856},{2,0,1856},{2,5,272},{2,5,272},{2,5,272},{1,4,324},{0,4,194},{0,4,194},{3,7,5706},{3,7,2514},{3,6,2285}, +{3,6,2105},{3,7,7359},{2,7,2244},{2,6,147},{2,5,2358},{0,7,6820},{0,5,1718},{4,7,2256},{3,7,750},{4,6,410},{3,6,341},{7,1,5419},{2,7,2180},{2,6,83},{0,5,1618},{4,5,5419},{0,5,1618},{3,7,1985},{3,7,1985},{3,7,1985},{3,5,2041},{2,7,1224},{2,6,146},{2,6,146},{2,4,210},{0,6,1644},{1,4,509},{3,7,221},{3,7,221},{3,7,221},{3,5,277},{5,2,1160}, +{1,7,64},{1,7,64},{2,4,146},{7,2,1160},{2,4,146},{7,3,1570},{4,7,356},{4,6,10},{2,6,2},{7,3,1570},{6,5,1570},{2,6,2},{0,5,1618},{6,5,1570},{0,5,1618},{3,0,1960},{3,0,1960},{3,0,1960},{3,0,1960},{2,5,80},{2,5,80},{2,5,80},{2,4,89},{0,5,100},{0,5,100},{3,7,6570},{3,7,2770},{3,6,2365},{3,6,1705},{3,7,7311},{2,7,2276},{2,6,131}, +{2,5,2230},{0,7,6884},{0,5,1974},{4,7,2512},{4,7,532},{4,6,218},{4,6,482},{5,5,5424},{2,7,2276},{2,6,131},{1,5,1931},{3,6,5424},{1,5,1931},{3,7,1809},{3,7,1809},{3,7,1809},{3,6,1656},{2,7,1352},{2,6,82},{2,6,82},{2,4,370},{0,6,1548},{0,5,293},{4,6,169},{4,6,169},{4,6,169},{4,5,169},{6,1,1160},{1,7,64},{1,7,64},{1,5,250},{6,3,1160}, +{1,5,250},{5,7,1570},{4,7,388},{4,6,74},{3,6,65},{5,7,1570},{5,6,1570},{3,6,65},{0,5,1906},{5,6,1570},{0,5,1906},{3,0,1640},{3,0,1640},{3,0,1640},{3,0,1640},{2,6,1},{2,6,1},{2,6,1},{2,4,9},{0,5,68},{0,5,68},{4,7,6752},{3,7,3538},{3,7,2378},{3,6,1817},{3,7,7775},{2,7,2820},{2,7,477},{2,5,2614},{1,7,7360},{0,6,1978},{5,7,3110}, +{4,7,692},{4,7,377},{4,6,322},{6,4,5424},{3,7,2539},{2,7,413},{0,6,1942},{7,4,5424},{0,6,1942},{3,7,2017},{3,7,2017},{3,7,2017},{3,6,1592},{3,7,1846},{2,7,116},{2,7,116},{2,5,213},{0,7,1531},{1,5,283},{4,7,16},{4,7,16},{4,7,16},{4,6,97},{7,0,1154},{2,7,52},{2,7,52},{1,5,58},{3,5,1154},{1,5,58},{7,4,1576},{5,7,610},{5,6,306}, +{3,6,241},{7,4,1576},{7,5,1576},{3,6,241},{0,6,1906},{7,5,1576},{0,6,1906},{3,0,1576},{3,0,1576},{3,0,1576},{3,0,1576},{2,7,100},{2,7,100},{2,7,100},{2,5,164},{0,6,72},{0,6,72},{4,7,6932},{4,7,3932},{4,7,2807},{3,7,1974},{4,7,8428},{3,7,2981},{2,7,423},{2,6,2373},{1,7,7540},{0,6,1618},{5,7,2921},{4,7,1331},{4,7,206},{4,7,566},{7,3,5424}, +{3,7,2692},{2,7,134},{0,6,1609},{6,5,5424},{0,6,1609},{4,7,2707},{4,7,2707},{4,7,2707},{3,7,1874},{3,7,1513},{2,7,323},{2,7,323},{2,5,294},{0,7,1324},{1,5,184},{4,7,106},{4,7,106},{4,7,106},{4,6,25},{7,1,1160},{2,7,34},{2,7,34},{2,5,5},{7,3,1160},{2,5,5},{7,5,1570},{5,7,628},{4,7,181},{2,7,125},{7,5,1570},{6,6,1586},{2,7,125}, +{0,6,1600},{6,6,1586},{0,6,1600},{3,0,1810},{3,0,1810},{3,0,1810},{3,0,1810},{2,7,298},{2,7,298},{2,7,298},{2,5,290},{0,6,18},{0,6,18},{4,7,7636},{4,7,4156},{4,7,2311},{4,7,2191},{4,7,8428},{3,7,3317},{3,7,185},{3,6,2410},{2,7,8180},{1,6,1722},{5,7,3161},{5,7,1357},{5,7,461},{4,7,342},{5,7,5424},{4,7,2979},{3,7,104},{1,6,1601},{5,6,5424}, +{1,6,1601},{4,7,2307},{4,7,2307},{4,7,2307},{4,6,2082},{3,7,1625},{3,7,181},{3,7,181},{3,5,217},{0,7,1548},{1,5,504},{5,7,457},{5,7,457},{5,7,457},{4,6,233},{6,3,1154},{3,7,100},{3,7,100},{3,5,136},{6,4,1154},{3,5,136},{6,7,1576},{5,7,916},{5,7,20},{3,7,4},{6,7,1576},{7,6,1576},{3,7,4},{0,6,1600},{7,6,1576},{0,6,1600},{4,0,2018}, +{4,0,2018},{4,0,2018},{4,0,2018},{3,6,90},{3,6,90},{3,6,90},{3,5,117},{0,7,104},{0,7,104},{5,7,7862},{4,7,4316},{4,7,2291},{4,7,1691},{4,7,8004},{3,7,3433},{3,7,69},{3,6,1774},{2,7,7580},{1,6,1470},{5,7,3101},{5,7,1209},{5,7,185},{4,7,466},{7,4,4803},{4,7,2579},{3,7,68},{2,6,1448},{7,5,4803},{2,6,1448},{4,7,2291},{4,7,2291},{4,7,2291}, +{4,7,1691},{3,7,2121},{3,7,69},{3,7,69},{3,5,329},{1,7,1539},{1,6,314},{5,7,185},{5,7,185},{5,7,185},{5,6,185},{7,2,1154},{3,7,68},{3,7,68},{2,6,292},{5,5,1154},{2,6,292},{7,6,1252},{6,7,724},{5,7,16},{4,7,25},{7,6,1252},{7,6,1268},{4,7,25},{0,6,1412},{7,6,1268},{0,6,1412},{4,0,1666},{4,0,1666},{4,0,1666},{4,0,1666},{3,7,5}, +{3,7,5},{3,7,5},{3,5,5},{0,7,40},{0,7,40},{5,7,6806},{4,7,4684},{4,7,2659},{4,7,1579},{4,7,7668},{4,7,2988},{3,7,341},{3,6,1390},{2,7,7084},{1,6,1470},{6,7,2645},{5,7,1193},{5,7,169},{5,7,125},{6,6,4059},{4,7,2259},{4,7,234},{2,6,1224},{4,7,4059},{2,6,1224},{4,7,2659},{4,7,2659},{4,7,2659},{4,7,1579},{4,7,2043},{3,7,341},{3,7,341}, +{3,6,234},{1,7,1779},{1,6,314},{5,7,169},{5,7,169},{5,7,169},{5,7,125},{5,6,1152},{4,7,234},{4,7,234},{2,6,68},{4,6,1152},{2,6,68},{7,6,900},{6,7,500},{6,7,100},{4,7,9},{7,6,900},{6,7,884},{4,7,9},{0,6,1220},{6,7,884},{0,6,1220},{4,0,1570},{4,0,1570},{4,0,1570},{4,0,1570},{3,7,85},{3,7,85},{3,7,85},{3,5,149},{1,7,98}, +{1,7,98},{5,7,6077},{5,7,4185},{5,7,3161},{4,7,1912},{5,7,6790},{4,7,2529},{4,7,504},{3,6,1417},{3,7,6199},{1,7,1097},{6,7,1925},{6,7,1301},{5,7,457},{5,7,17},{7,5,3321},{5,7,1754},{4,7,180},{1,7,1093},{6,6,3345},{1,7,1093},{5,7,3161},{5,7,3161},{5,7,3161},{4,7,1912},{4,7,2124},{4,7,504},{4,7,504},{3,6,261},{2,7,1944},{2,6,171},{5,7,457}, +{5,7,457},{5,7,457},{5,7,17},{6,5,1154},{4,7,180},{4,7,180},{3,6,5},{3,7,1154},{3,6,5},{7,7,605},{6,7,401},{6,7,1},{5,7,1},{7,7,605},{6,7,569},{5,7,1},{0,7,1089},{6,7,569},{0,7,1089},{4,0,1768},{4,0,1768},{4,0,1768},{4,0,1768},{4,7,360},{4,7,360},{4,7,360},{3,6,260},{1,7,8},{1,7,8},{5,7,5837},{5,7,3945},{5,7,2921}, +{5,7,2129},{5,7,6054},{4,7,2529},{4,7,504},{4,6,1386},{3,7,5767},{2,7,773},{6,7,1557},{6,7,933},{6,7,533},{5,7,193},{6,7,2754},{5,7,1434},{4,7,404},{2,7,629},{5,7,2754},{2,7,629},{5,7,2921},{5,7,2921},{5,7,2921},{5,7,2129},{4,7,2604},{4,7,504},{4,7,504},{4,6,230},{2,7,2264},{2,6,443},{6,7,533},{6,7,533},{6,7,533},{5,7,193},{7,4,1152}, +{4,7,404},{4,7,404},{3,6,117},{7,5,1152},{3,6,117},{7,7,317},{7,7,245},{6,7,49},{6,7,25},{7,7,317},{7,7,373},{6,7,25},{0,7,625},{7,7,373},{0,7,625},{5,0,2080},{5,0,2080},{5,0,2080},{5,0,2080},{4,7,104},{4,7,104},{4,7,104},{4,6,149},{2,7,148},{2,7,148},{5,7,5981},{5,7,4089},{5,7,3065},{5,7,1921},{5,7,5702},{5,7,2666},{4,7,888}, +{4,7,693},{4,7,5325},{2,7,341},{6,7,1445},{6,7,821},{6,7,421},{6,7,205},{7,6,2306},{5,7,1370},{5,7,346},{2,7,325},{7,6,2274},{2,7,325},{5,7,3065},{5,7,3065},{5,7,3065},{5,7,1921},{5,7,2786},{4,7,888},{4,7,888},{4,6,294},{3,7,2355},{2,7,341},{6,7,421},{6,7,421},{6,7,421},{6,7,205},{7,5,1184},{5,7,346},{5,7,346},{4,6,290},{6,6,1152}, +{4,6,290},{7,7,157},{7,7,85},{7,7,36},{6,7,9},{7,7,157},{7,7,149},{6,7,9},{0,7,289},{7,7,149},{0,7,289},{5,0,1696},{5,0,1696},{5,0,1696},{5,0,1696},{4,7,104},{4,7,104},{4,7,104},{4,6,5},{2,7,52},{2,7,52},{6,7,5433},{5,7,4617},{5,7,3593},{5,7,2097},{5,7,5734},{5,7,2346},{5,7,1322},{4,7,261},{4,7,4909},{2,7,293},{6,7,1589}, +{6,7,965},{6,7,565},{6,7,157},{7,6,1890},{6,7,1146},{5,7,538},{3,7,82},{6,7,1890},{3,7,82},{5,7,3593},{5,7,3593},{5,7,3593},{5,7,2097},{5,7,2818},{5,7,1322},{5,7,1322},{4,7,261},{3,7,2691},{2,7,293},{6,7,565},{6,7,565},{6,7,565},{6,7,157},{6,7,1154},{5,7,538},{5,7,538},{3,7,82},{5,7,1154},{3,7,82},{7,7,125},{7,7,53},{7,7,4}, +{7,7,4},{7,7,125},{7,7,53},{7,7,4},{0,7,81},{7,7,53},{0,7,81},{5,0,1568},{5,0,1568},{5,0,1568},{5,0,1568},{4,7,360},{4,7,360},{4,7,360},{4,6,117},{2,7,212},{2,7,212},{6,7,4866},{6,7,4242},{6,7,3842},{5,7,2754},{6,7,5113},{5,7,2445},{5,7,1421},{4,7,234},{5,7,4804},{3,7,164},{7,7,1203},{7,7,1131},{6,7,1033},{6,7,409},{7,7,1611}, +{6,7,1056},{6,7,656},{4,7,9},{6,7,1584},{4,7,9},{6,7,3842},{6,7,3842},{6,7,3842},{5,7,2754},{5,7,3313},{5,7,1421},{5,7,1421},{4,7,234},{4,7,2875},{3,7,164},{6,7,1033},{6,7,1033},{6,7,1033},{6,7,409},{7,6,1152},{6,7,656},{6,7,656},{4,7,9},{7,6,1184},{4,7,9},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49}, +{0,7,0},{7,7,98},{0,7,0},{5,0,1730},{5,0,1730},{5,0,1730},{5,0,1730},{5,7,397},{5,7,397},{5,7,397},{4,7,234},{3,7,164},{3,7,164},{6,7,4194},{6,7,3570},{6,7,3170},{6,7,2546},{6,7,4137},{5,7,2365},{5,7,1341},{5,7,185},{5,7,3876},{3,7,324},{7,7,771},{7,7,699},{7,7,650},{6,7,521},{7,7,1083},{6,7,864},{6,7,464},{4,7,25},{7,7,1187}, +{4,7,25},{6,7,3170},{6,7,3170},{6,7,3170},{6,7,2546},{6,7,3113},{5,7,1341},{5,7,1341},{5,7,185},{4,7,2491},{3,7,324},{7,7,650},{7,7,650},{7,7,650},{6,7,521},{7,6,832},{6,7,464},{6,7,464},{4,7,25},{6,7,800},{4,7,25},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{5,0,2146}, +{5,0,2146},{5,0,2146},{5,0,2146},{5,7,317},{5,7,317},{5,7,317},{5,7,185},{3,7,324},{3,7,324},{6,7,3778},{6,7,3154},{6,7,2754},{6,7,2130},{6,7,3417},{6,7,2169},{5,7,1517},{5,7,9},{5,7,3204},{4,7,338},{7,7,467},{7,7,395},{7,7,346},{7,7,274},{7,7,683},{7,7,539},{6,7,400},{5,7,0},{7,7,723},{5,7,0},{6,7,2754},{6,7,2754},{6,7,2754}, +{6,7,2130},{6,7,2393},{5,7,1517},{5,7,1517},{5,7,9},{5,7,2180},{4,7,338},{7,7,346},{7,7,346},{7,7,346},{7,7,274},{7,7,562},{6,7,400},{6,7,400},{5,7,0},{6,7,544},{5,7,0},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{6,0,1730},{6,0,1730},{6,0,1730},{6,0,1730},{5,7,493}, +{5,7,493},{5,7,493},{5,7,9},{4,7,338},{4,7,338},{6,7,3618},{6,7,2994},{6,7,2594},{6,7,1970},{6,7,2953},{6,7,1705},{6,7,1305},{5,7,89},{5,7,2788},{4,7,466},{7,7,291},{7,7,219},{7,7,170},{7,7,98},{7,7,411},{7,7,267},{7,7,218},{6,7,16},{7,7,387},{6,7,16},{6,7,2594},{6,7,2594},{6,7,2594},{6,7,1970},{6,7,1929},{6,7,1305},{6,7,1305}, +{5,7,89},{5,7,1764},{4,7,466},{7,7,170},{7,7,170},{7,7,170},{7,7,98},{7,7,290},{7,7,218},{7,7,218},{6,7,16},{7,7,338},{6,7,16},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{6,0,1570},{6,0,1570},{6,0,1570},{6,0,1570},{6,7,905},{6,7,905},{6,7,905},{5,7,89},{4,7,466}, +{4,7,466},{0,5,2665},{0,4,697},{0,3,290},{0,2,841},{0,3,5901},{0,2,4170},{0,2,1802},{0,1,4310},{0,1,6951},{0,1,4671},{0,5,2665},{0,4,697},{0,3,290},{0,2,841},{2,0,5893},{0,2,4170},{0,2,1802},{0,1,4310},{3,0,5893},{0,1,4310},{0,2,4},{0,2,4},{0,2,4},{0,1,4},{0,1,557},{0,1,365},{0,1,365},{0,0,356},{0,0,665},{0,0,392},{0,2,4}, +{0,2,4},{0,2,4},{0,1,4},{0,1,557},{0,1,365},{0,1,365},{0,0,356},{0,0,629},{0,0,356},{3,0,2665},{0,4,697},{0,3,290},{0,2,841},{3,0,2665},{3,1,2665},{0,2,841},{0,2,3145},{3,1,2665},{0,2,3145},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,6,2705},{0,4,617},{0,3,34}, +{0,2,985},{0,4,6754},{0,3,4625},{0,2,1946},{0,1,5030},{0,2,7635},{0,1,5391},{0,6,2705},{0,4,617},{0,3,34},{0,2,985},{1,2,6674},{0,3,4625},{0,2,1946},{0,1,5030},{0,2,6674},{0,1,5030},{0,3,9},{0,3,9},{0,3,9},{0,1,100},{0,1,845},{0,1,461},{0,1,461},{0,0,676},{0,0,1097},{0,0,712},{0,3,9},{0,3,9},{0,3,9},{0,1,100},{0,1,845}, +{0,1,461},{0,1,461},{0,0,676},{1,0,853},{0,0,676},{1,4,2665},{0,4,617},{0,3,34},{0,2,985},{1,4,2665},{2,2,2665},{0,2,985},{0,2,2777},{2,2,2665},{0,2,2777},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,6,2689},{0,5,477},{0,3,34},{0,3,634},{0,4,7538},{0,3,4865},{0,2,2346}, +{0,2,5474},{0,2,8547},{0,1,6367},{0,6,2689},{0,5,477},{0,3,34},{0,3,634},{0,4,7538},{0,3,4865},{0,2,2346},{0,2,5474},{2,1,7538},{0,2,5474},{0,3,25},{0,3,25},{0,3,25},{0,2,16},{0,1,1261},{0,1,685},{0,1,685},{0,1,965},{0,1,1646},{0,0,1160},{0,3,25},{0,3,25},{0,3,25},{0,2,16},{1,0,1213},{0,1,685},{0,1,685},{0,1,965},{1,0,1205}, +{0,1,965},{2,3,2669},{0,5,477},{0,3,34},{0,3,634},{2,3,2669},{6,0,2669},{0,3,634},{0,2,2665},{6,0,2669},{0,2,2665},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,7,2669},{0,5,365},{0,3,290},{0,3,410},{0,4,8578},{0,3,5361},{0,3,2346},{0,2,5618},{0,2,9715},{0,2,6579},{0,7,2669}, +{0,5,365},{0,3,290},{0,3,410},{2,1,8498},{0,3,5361},{0,3,2346},{0,2,5618},{4,0,8498},{0,2,5618},{0,4,0},{0,4,0},{0,4,0},{0,2,16},{0,2,1637},{0,2,977},{0,2,977},{0,1,997},{0,1,1998},{0,1,1358},{0,4,0},{0,4,0},{0,4,0},{0,2,16},{1,0,1629},{0,2,977},{0,2,977},{0,1,997},{0,1,1637},{0,1,997},{3,2,2669},{0,5,365},{1,3,185}, +{0,3,410},{3,2,2669},{5,1,2669},{0,3,410},{0,2,2809},{5,1,2669},{0,2,2809},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,7,2777},{0,6,257},{0,4,277},{0,3,464},{0,5,9677},{0,4,6026},{0,3,2400},{0,2,6086},{0,2,11335},{0,2,7047},{0,7,2777},{0,6,257},{0,4,277},{0,3,464},{3,0,9677}, +{0,4,6026},{0,3,2400},{0,2,6086},{3,1,9677},{0,2,6086},{0,5,16},{0,5,16},{0,5,16},{0,3,64},{0,2,2186},{0,2,1130},{0,2,1130},{0,1,1186},{0,1,2547},{0,1,1547},{0,5,16},{0,5,16},{0,5,16},{0,3,64},{0,2,2186},{0,2,1130},{0,2,1130},{0,1,1186},{0,1,2186},{0,1,1186},{4,1,2669},{0,6,257},{0,4,277},{0,3,464},{4,1,2669},{4,2,2669},{0,3,464}, +{0,3,3209},{4,2,2669},{0,3,3209},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{0,7,3209},{0,6,209},{0,4,389},{0,4,541},{0,6,9765},{0,4,5546},{0,3,2080},{0,2,5990},{0,3,11621},{0,2,6951},{0,7,3209},{0,6,209},{0,4,389},{0,4,541},{1,4,9677},{0,4,5546},{0,3,2080},{0,2,5990},{2,2,9677}, +{0,2,5990},{0,5,80},{0,5,80},{0,5,80},{0,3,64},{0,3,2196},{0,2,970},{0,2,970},{0,1,1058},{0,1,2739},{0,1,1419},{0,5,80},{0,5,80},{0,5,80},{0,3,64},{1,1,2180},{0,2,970},{0,2,970},{0,1,1058},{1,1,2196},{0,1,1058},{5,0,2669},{0,6,145},{1,4,52},{0,4,477},{5,0,2669},{3,3,2669},{0,4,477},{0,3,2809},{3,3,2669},{0,3,2809},{0,0,64}, +{0,0,64},{0,0,64},{0,0,64},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,0,40},{0,0,40},{0,7,4025},{0,7,441},{0,4,885},{0,4,429},{0,6,9685},{0,4,5450},{0,4,1854},{0,3,6029},{0,3,11925},{0,2,7239},{1,7,3001},{0,7,441},{1,4,344},{0,4,429},{3,1,9685},{0,4,5450},{0,4,1854},{0,3,6029},{4,1,9685},{0,3,6029},{0,6,256},{0,6,256},{0,6,256}, +{0,3,320},{0,3,2228},{0,3,848},{0,3,848},{0,1,1186},{0,2,3171},{0,1,1547},{0,6,256},{0,6,256},{0,6,256},{0,3,320},{2,0,2180},{0,3,848},{0,3,848},{0,1,1186},{3,0,2180},{0,1,1186},{4,2,2677},{0,7,185},{1,4,20},{0,4,173},{4,2,2677},{7,1,2677},{0,4,173},{0,3,2665},{7,1,2677},{0,3,2665},{0,0,256},{0,0,256},{0,0,256},{0,0,256},{0,1,9}, +{0,1,9},{0,1,9},{0,0,36},{0,0,72},{0,0,72},{1,7,4141},{0,7,617},{1,4,1500},{0,4,701},{0,7,9690},{0,5,5001},{0,4,1214},{0,3,5277},{0,3,12613},{0,3,7213},{1,7,2985},{1,6,465},{1,4,344},{1,4,524},{4,0,9674},{0,5,5001},{0,4,1214},{0,3,5277},{3,2,9674},{0,3,5277},{0,7,601},{0,7,601},{0,7,601},{0,4,601},{0,4,2178},{0,3,656},{0,3,656}, +{0,2,866},{0,2,3171},{0,2,1827},{1,5,101},{1,5,101},{1,5,101},{1,3,109},{0,4,2178},{0,3,656},{0,3,656},{0,2,866},{2,1,2178},{0,2,866},{5,1,2669},{0,7,41},{2,4,181},{0,4,125},{5,1,2669},{4,3,2669},{0,4,125},{0,3,2777},{4,3,2669},{0,3,2777},{0,0,576},{0,0,576},{0,0,576},{0,0,576},{0,1,25},{0,1,25},{0,1,25},{0,1,49},{0,0,232}, +{0,0,232},{1,7,4582},{0,7,1274},{1,5,1446},{0,4,1466},{0,7,9789},{0,5,4794},{0,4,953},{0,3,4890},{0,4,13038},{0,3,6826},{1,7,3426},{1,7,290},{1,5,290},{1,4,443},{2,4,9685},{0,5,4794},{0,4,953},{0,3,4890},{7,0,9685},{0,3,4890},{0,7,1105},{0,7,1105},{0,7,1105},{0,4,1105},{0,5,2210},{0,4,592},{0,4,592},{0,2,596},{0,2,3477},{0,2,1557},{1,6,26}, +{1,6,26},{1,6,26},{1,4,82},{1,3,2180},{0,4,592},{0,4,592},{0,2,596},{1,2,2180},{0,2,596},{6,0,2677},{0,7,185},{1,5,289},{0,4,377},{6,0,2677},{5,3,2677},{0,4,377},{0,3,3209},{5,3,2677},{0,3,3209},{0,0,1089},{0,0,1089},{0,0,1089},{0,0,1089},{0,2,4},{0,2,4},{0,2,4},{0,1,4},{0,1,365},{0,1,365},{1,7,5382},{1,7,1350},{1,5,1510}, +{1,5,1738},{0,7,10285},{0,6,4406},{0,5,971},{0,3,4954},{0,4,13534},{0,3,6890},{2,7,3454},{1,7,194},{1,5,354},{1,5,582},{3,3,9674},{0,6,4406},{0,5,971},{0,3,4954},{6,1,9674},{0,3,4954},{1,6,1214},{1,6,1214},{1,6,1214},{1,4,1206},{0,5,2210},{0,4,400},{0,4,400},{0,2,628},{0,2,4021},{0,2,1589},{1,6,58},{1,6,58},{1,6,58},{1,4,50},{2,2,2178}, +{0,4,400},{0,4,400},{0,2,628},{5,0,2178},{0,2,628},{4,4,2669},{1,7,145},{2,5,74},{0,5,130},{4,4,2669},{7,2,2669},{0,5,130},{0,4,2845},{7,2,2669},{0,4,2845},{1,0,1205},{1,0,1205},{1,0,1205},{1,0,1205},{0,3,9},{0,3,9},{0,3,9},{0,1,100},{0,1,461},{0,1,461},{1,7,6566},{1,7,1638},{1,5,1958},{1,5,1578},{1,7,10830},{0,6,4118},{0,5,443}, +{0,4,4785},{0,4,14414},{0,3,7338},{2,7,3390},{1,7,482},{2,5,371},{1,5,422},{4,2,9674},{0,6,4118},{0,5,443},{0,4,4785},{5,2,9674},{0,4,4785},{1,7,1382},{1,7,1382},{1,7,1382},{1,4,1430},{0,6,2178},{0,5,442},{0,5,442},{0,3,641},{0,3,4242},{0,2,1877},{1,7,226},{1,7,226},{1,7,226},{1,4,274},{3,1,2178},{0,5,442},{0,5,442},{0,3,641},{4,1,2178}, +{0,3,641},{5,3,2669},{1,7,257},{2,5,10},{0,5,2},{5,3,2669},{6,3,2669},{0,5,2},{0,4,2669},{6,3,2669},{0,4,2669},{1,0,1381},{1,0,1381},{1,0,1381},{1,0,1381},{0,3,25},{0,3,25},{0,3,25},{0,2,16},{0,1,685},{0,1,685},{1,7,8134},{1,7,2310},{1,6,2671},{1,5,1802},{1,7,11086},{0,7,4109},{0,5,299},{0,4,4193},{0,5,14830},{0,4,7442},{2,7,3710}, +{2,7,490},{2,5,323},{2,5,563},{5,1,9669},{0,7,4109},{0,5,299},{0,4,4193},{4,3,9669},{0,4,4193},{1,7,1734},{1,7,1734},{1,7,1734},{1,5,1721},{0,7,2228},{0,5,218},{0,5,218},{0,3,305},{0,3,4626},{0,3,2241},{2,6,125},{2,6,125},{2,6,125},{2,4,125},{4,0,2180},{0,5,218},{0,5,218},{0,3,305},{3,2,2180},{0,3,305},{6,2,2665},{2,7,369},{3,5,181}, +{1,5,117},{6,2,2665},{5,4,2665},{1,5,117},{0,4,2749},{5,4,2665},{0,4,2749},{1,0,1685},{1,0,1685},{1,0,1685},{1,0,1685},{0,4,0},{0,4,0},{0,4,0},{0,2,16},{0,2,977},{0,2,977},{2,7,9153},{1,7,3525},{1,6,3220},{1,5,2513},{1,7,11833},{0,7,3686},{0,6,548},{0,4,3986},{0,5,15577},{0,4,7235},{3,7,4141},{2,7,481},{2,6,309},{2,5,428},{6,0,9674}, +{0,7,3686},{0,6,548},{0,4,3986},{3,4,9674},{0,4,3986},{1,7,2436},{1,7,2436},{1,7,2436},{1,5,2189},{0,7,2210},{0,5,272},{0,5,272},{0,3,233},{0,3,5364},{0,3,2169},{2,7,40},{2,7,40},{2,7,40},{2,5,104},{2,4,2178},{0,5,272},{0,5,272},{0,3,233},{7,0,2178},{0,3,233},{7,1,2669},{2,7,477},{2,6,305},{0,6,292},{7,1,2669},{4,5,2669},{0,6,292}, +{0,4,3145},{4,5,2669},{0,4,3145},{1,0,2180},{1,0,2180},{1,0,2180},{1,0,2180},{0,5,16},{0,5,16},{0,5,16},{0,3,64},{0,2,1130},{0,2,1130},{2,7,10154},{1,7,4946},{1,6,4049},{1,6,2853},{1,7,12838},{0,7,3719},{0,6,133},{0,4,4211},{0,6,16286},{0,4,7346},{3,7,4061},{2,7,881},{2,6,325},{2,6,629},{4,4,9669},{0,7,3718},{0,6,132},{0,4,4210},{7,2,9669}, +{0,4,4210},{1,7,3265},{1,7,3265},{1,7,3265},{1,6,2789},{0,7,2467},{0,6,69},{0,6,69},{0,3,442},{0,4,5602},{0,3,2290},{2,7,40},{2,7,40},{2,7,40},{2,5,40},{3,3,2180},{0,6,68},{0,6,68},{0,3,441},{6,1,2180},{0,3,441},{5,5,2665},{3,7,617},{3,6,100},{0,6,68},{5,5,2665},{3,6,2665},{0,6,68},{0,5,2885},{3,6,2665},{0,5,2885},{1,0,2689}, +{1,0,2689},{1,0,2689},{1,0,2689},{0,5,17},{0,5,17},{0,5,17},{0,3,1},{0,2,1341},{0,2,1341},{2,7,10666},{2,7,5146},{2,6,4206},{1,6,2933},{2,7,13606},{0,7,4215},{0,6,181},{0,5,3914},{0,6,15454},{0,4,7122},{3,7,4365},{3,7,1097},{3,6,404},{2,6,421},{5,3,9669},{1,7,4133},{0,6,100},{0,5,3833},{6,3,9669},{0,5,3833},{2,7,3777},{2,7,3777},{2,7,3777}, +{1,6,2933},{1,7,2805},{0,6,181},{0,6,181},{0,4,275},{0,4,5282},{0,3,2130},{2,7,296},{2,7,296},{2,7,296},{2,5,232},{4,2,2180},{0,6,100},{0,6,100},{0,4,194},{5,2,2180},{0,4,194},{6,4,2665},{3,7,697},{3,6,4},{1,6,4},{6,4,2665},{7,4,2665},{1,6,4},{0,5,2677},{7,4,2665},{0,5,2677},{1,0,2929},{1,0,2929},{1,0,2929},{1,0,2929},{0,6,81}, +{0,6,81},{0,6,81},{0,3,145},{0,3,1289},{0,3,1289},{2,7,11690},{2,7,5434},{2,7,4085},{2,6,3198},{2,7,13510},{1,7,4470},{1,6,585},{0,5,3690},{0,6,15134},{0,5,6210},{3,7,5053},{3,7,1177},{3,6,308},{2,6,597},{6,2,9670},{1,7,4181},{1,6,296},{0,5,3401},{5,4,9670},{0,5,3401},{2,7,3409},{2,7,3409},{2,7,3409},{2,6,3134},{1,7,2565},{0,7,323},{0,7,323}, +{0,4,323},{0,5,5085},{0,4,1634},{3,7,153},{3,7,153},{3,7,153},{3,5,145},{5,1,2186},{0,7,34},{0,7,34},{0,4,34},{7,1,2186},{0,4,34},{7,3,2665},{4,7,937},{3,6,164},{1,6,100},{7,3,2665},{6,5,2665},{1,6,100},{0,5,2725},{6,5,2665},{0,5,2725},{2,0,3085},{2,0,3085},{2,0,3085},{2,0,3085},{1,5,290},{1,5,290},{1,5,290},{1,3,298},{0,3,985}, +{0,3,985},{3,7,12062},{2,7,6370},{2,7,3743},{2,6,3018},{2,7,14014},{1,7,4758},{1,6,603},{1,5,4049},{0,7,14638},{0,5,5310},{4,7,4958},{3,7,1726},{3,7,334},{3,6,419},{7,1,9669},{1,7,4694},{0,7,341},{0,5,3374},{4,5,9669},{0,5,3374},{2,7,3454},{2,7,3454},{2,7,3454},{2,6,2729},{1,7,2754},{1,6,314},{1,6,314},{1,4,289},{0,5,4626},{0,4,1121},{3,7,45}, +{3,7,45},{3,7,45},{3,5,109},{6,0,2180},{0,7,52},{0,7,52},{0,4,160},{3,4,2180},{0,4,160},{5,7,2665},{4,7,1009},{4,6,293},{2,6,293},{5,7,2665},{5,6,2665},{2,6,293},{0,5,3085},{5,6,2665},{0,5,3085},{2,0,2725},{2,0,2725},{2,0,2725},{2,0,2725},{1,6,89},{1,6,89},{1,6,89},{1,4,145},{0,3,949},{0,3,949},{3,7,12414},{3,7,7246},{2,7,3983}, +{2,7,2879},{2,7,15006},{1,7,5558},{1,7,163},{1,5,4161},{0,7,14190},{0,5,5054},{4,7,5246},{4,7,2186},{3,7,302},{3,6,659},{5,5,9670},{2,7,4926},{1,7,163},{0,5,3758},{3,6,9670},{0,5,3758},{2,7,3902},{2,7,3902},{2,7,3902},{2,6,2777},{1,7,3330},{1,7,82},{1,7,82},{1,4,401},{0,6,4490},{0,4,1073},{3,7,221},{3,7,221},{3,7,221},{3,6,34},{5,2,2186}, +{1,7,82},{1,7,82},{0,5,277},{7,2,2186},{0,5,277},{6,6,2665},{5,7,1313},{4,7,130},{1,7,82},{6,6,2665},{4,7,2665},{1,7,82},{0,6,2929},{4,7,2665},{0,6,2929},{2,0,2677},{2,0,2677},{2,0,2677},{2,0,2677},{1,6,9},{1,6,9},{1,6,9},{1,4,1},{0,4,673},{0,4,673},{3,7,13278},{3,7,7502},{3,7,4254},{2,7,2895},{3,7,15045},{2,7,6114},{1,7,147}, +{1,6,3978},{0,7,14254},{0,6,4818},{4,7,5918},{4,7,2378},{4,7,443},{3,7,426},{6,4,9670},{2,7,5438},{1,7,83},{0,6,3218},{7,4,9670},{0,6,3218},{3,7,4253},{3,7,4253},{3,7,4253},{2,7,2894},{2,7,3054},{1,7,146},{1,7,146},{1,5,296},{0,6,3978},{0,5,821},{4,7,442},{4,7,442},{4,7,442},{3,6,194},{6,1,2186},{1,7,82},{1,7,82},{0,5,37},{6,3,2186}, +{0,5,37},{7,5,2665},{5,7,1361},{4,7,2},{2,7,10},{7,5,2665},{6,6,2689},{2,7,10},{0,6,2689},{6,6,2689},{0,6,2689},{2,0,2885},{2,0,2885},{2,0,2885},{2,0,2885},{1,7,65},{1,7,65},{1,7,65},{1,4,113},{0,4,625},{0,4,625},{3,7,13261},{3,7,7409},{3,7,4045},{3,7,3209},{3,7,14116},{2,7,5615},{2,7,574},{1,6,3165},{0,7,13437},{0,6,3429},{5,7,5269}, +{4,7,2275},{4,7,250},{3,7,505},{5,6,8712},{3,7,4724},{2,7,250},{0,6,2405},{4,6,8712},{0,6,2405},{3,7,4045},{3,7,4045},{3,7,4045},{3,7,3209},{2,7,3150},{2,7,574},{2,7,574},{1,5,296},{0,6,3850},{0,5,453},{4,7,250},{4,7,250},{4,7,250},{4,6,169},{7,0,2180},{2,7,250},{2,7,250},{1,5,40},{3,5,2180},{1,5,40},{6,7,2180},{5,7,1168},{4,7,81}, +{2,7,25},{6,7,2180},{5,7,2180},{2,7,25},{0,6,2180},{5,7,2180},{0,6,2180},{3,0,3145},{3,0,3145},{3,0,3145},{3,0,3145},{1,7,305},{1,7,305},{1,7,305},{1,5,292},{0,5,449},{0,5,449},{4,7,11894},{3,7,7634},{3,7,4270},{3,7,2750},{3,7,13315},{2,7,5354},{2,7,313},{1,6,2634},{1,7,12414},{0,6,2250},{5,7,4369},{4,7,2365},{4,7,340},{4,7,160},{7,3,7590}, +{3,7,4094},{2,7,232},{0,6,1721},{6,5,7590},{0,6,1721},{3,7,4270},{3,7,4270},{3,7,4270},{3,7,2750},{2,7,3717},{2,7,313},{2,7,313},{2,5,302},{0,7,3546},{0,5,498},{4,7,340},{4,7,340},{4,7,340},{4,6,97},{7,1,2186},{2,7,232},{2,7,232},{1,5,130},{7,3,2186},{1,5,130},{6,7,1649},{6,7,1025},{5,7,9},{3,7,1},{6,7,1649},{7,6,1625},{3,7,1}, +{0,6,1685},{7,6,1625},{0,6,1685},{3,0,2749},{3,0,2749},{3,0,2749},{3,0,2749},{2,7,117},{2,7,117},{2,7,117},{2,5,181},{0,5,377},{0,5,377},{4,7,11078},{4,7,7478},{3,7,4878},{3,7,2750},{4,7,12662},{3,7,5031},{2,7,489},{2,6,1911},{1,7,11470},{0,6,1610},{5,7,3841},{5,7,1949},{4,7,692},{4,7,32},{5,7,6662},{4,7,3641},{3,7,442},{0,6,1385},{5,6,6662}, +{0,6,1385},{3,7,4878},{3,7,4878},{3,7,4878},{3,7,2750},{3,7,3795},{2,7,489},{2,7,489},{2,5,366},{0,7,3354},{0,6,454},{4,7,692},{4,7,692},{4,7,692},{4,7,32},{6,3,2180},{3,7,442},{3,7,442},{0,6,229},{6,4,2180},{0,6,229},{7,6,1201},{6,7,689},{5,7,25},{4,7,16},{7,6,1201},{7,6,1225},{4,7,16},{0,6,1381},{7,6,1225},{0,6,1381},{3,0,2669}, +{3,0,2669},{3,0,2669},{3,0,2669},{2,7,5},{2,7,5},{2,7,5},{2,5,5},{0,6,229},{0,6,229},{4,7,10646},{4,7,7046},{4,7,5021},{3,7,3134},{4,7,11526},{3,7,4503},{2,7,1049},{2,6,1479},{1,7,10910},{0,6,1354},{5,7,3569},{5,7,1677},{5,7,653},{4,7,160},{7,4,5829},{4,7,3065},{3,7,410},{1,6,1209},{7,5,5829},{1,6,1209},{4,7,5021},{4,7,5021},{4,7,5021}, +{3,7,3134},{3,7,3875},{2,7,1049},{2,7,1049},{2,6,323},{0,7,3546},{0,6,198},{5,7,653},{5,7,653},{5,7,653},{4,7,160},{7,2,2180},{3,7,410},{3,7,410},{1,6,53},{5,5,2180},{1,6,53},{7,6,865},{6,7,481},{6,7,81},{4,7,16},{7,6,865},{6,7,841},{4,7,16},{0,6,1205},{6,7,841},{0,6,1205},{3,0,2845},{3,0,2845},{3,0,2845},{3,0,2845},{2,7,149}, +{2,7,149},{2,7,149},{2,5,85},{0,6,149},{0,6,149},{4,7,10598},{4,7,6998},{4,7,4973},{4,7,3353},{4,7,10774},{3,7,4359},{3,7,995},{2,6,1431},{2,7,10294},{0,7,1242},{6,7,3329},{5,7,1661},{5,7,637},{5,7,197},{6,6,5085},{4,7,2745},{3,7,634},{0,7,1098},{4,7,5085},{0,7,1098},{4,7,4973},{4,7,4973},{4,7,4973},{4,7,3353},{3,7,4339},{3,7,995},{3,7,995}, +{2,6,275},{1,7,3845},{0,6,326},{5,7,637},{5,7,637},{5,7,637},{5,7,197},{5,6,2178},{3,7,634},{3,7,634},{1,6,37},{4,6,2178},{1,6,37},{7,7,605},{6,7,401},{6,7,1},{5,7,1},{7,7,605},{6,7,569},{5,7,1},{0,7,1089},{6,7,569},{0,7,1089},{4,0,3209},{4,0,3209},{4,0,3209},{4,0,3209},{3,7,370},{3,7,370},{3,7,370},{2,6,274},{0,7,153}, +{0,7,153},{5,7,9925},{4,7,7403},{4,7,5378},{4,7,3218},{4,7,10387},{4,7,4627},{3,7,1292},{3,6,1477},{2,7,9727},{0,7,621},{6,7,2609},{5,7,1949},{5,7,925},{5,7,89},{7,5,4347},{5,7,2384},{4,7,666},{0,7,612},{6,6,4371},{0,7,612},{4,7,5378},{4,7,5378},{4,7,5378},{4,7,3218},{4,7,4762},{3,7,1292},{3,7,1292},{3,6,321},{1,7,4106},{1,6,469},{5,7,925}, +{5,7,925},{5,7,925},{5,7,89},{6,5,2180},{4,7,666},{4,7,666},{2,6,104},{3,7,2180},{2,6,104},{7,7,290},{7,7,218},{6,7,64},{6,7,16},{7,7,290},{7,7,338},{6,7,16},{0,7,576},{7,7,338},{0,7,576},{4,0,2777},{4,0,2777},{4,0,2777},{4,0,2777},{3,7,136},{3,7,136},{3,7,136},{3,5,200},{0,7,45},{0,7,45},{5,7,9269},{5,7,7377},{4,7,6146}, +{4,7,3506},{5,7,10044},{4,7,4211},{3,7,1964},{3,7,836},{3,7,9185},{0,7,477},{6,7,2241},{6,7,1617},{6,7,1217},{5,7,265},{6,7,3780},{5,7,2064},{4,7,890},{1,7,257},{5,7,3780},{1,7,257},{4,7,6146},{4,7,6146},{4,7,6146},{4,7,3506},{4,7,4826},{3,7,1964},{3,7,1964},{3,6,337},{2,7,4590},{0,7,477},{6,7,1217},{6,7,1217},{6,7,1217},{5,7,265},{7,4,2178}, +{4,7,890},{4,7,890},{1,7,257},{7,5,2178},{1,7,257},{7,7,146},{7,7,74},{7,7,25},{6,7,16},{7,7,146},{7,7,130},{6,7,16},{0,7,256},{7,7,130},{0,7,256},{4,0,2665},{4,0,2665},{4,0,2665},{4,0,2665},{3,7,200},{3,7,200},{3,7,200},{3,6,13},{0,7,221},{0,7,221},{5,7,8997},{5,7,7105},{5,7,6081},{4,7,4178},{5,7,9276},{4,7,4179},{4,7,2154}, +{3,7,356},{3,7,8721},{1,7,209},{6,7,2129},{6,7,1505},{6,7,1105},{6,7,673},{7,6,3332},{5,7,2000},{5,7,976},{2,7,73},{7,6,3300},{2,7,73},{5,7,6081},{5,7,6081},{5,7,6081},{4,7,4178},{4,7,5274},{4,7,2154},{4,7,2154},{3,7,356},{2,7,4878},{1,7,209},{6,7,1105},{6,7,1105},{6,7,1105},{6,7,673},{7,5,2210},{5,7,976},{5,7,976},{2,7,73},{6,6,2178}, +{2,7,73},{7,7,130},{7,7,58},{7,7,9},{7,7,1},{7,7,130},{7,7,50},{7,7,1},{0,7,64},{7,7,50},{0,7,64},{4,0,2809},{4,0,2809},{4,0,2809},{4,0,2809},{3,7,520},{3,7,520},{3,7,520},{3,6,61},{1,7,145},{1,7,145},{5,7,9109},{5,7,7217},{5,7,6193},{5,7,4301},{5,7,8892},{4,7,4531},{4,7,2506},{3,7,260},{4,7,8587},{1,7,289},{6,7,2273}, +{6,7,1649},{6,7,1249},{6,7,625},{7,6,2916},{6,7,1956},{5,7,1168},{2,7,25},{6,7,2916},{2,7,25},{5,7,6193},{5,7,6193},{5,7,6193},{5,7,4301},{5,7,5976},{4,7,2506},{4,7,2506},{3,7,260},{3,7,5277},{1,7,289},{6,7,1249},{6,7,1249},{6,7,1249},{6,7,625},{6,7,2180},{5,7,1168},{5,7,1168},{2,7,25},{5,7,2180},{2,7,25},{7,7,242},{7,7,170},{7,7,121}, +{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{4,0,3209},{4,0,3209},{4,0,3209},{4,0,3209},{4,7,481},{4,7,481},{4,7,481},{3,7,260},{1,7,289},{1,7,289},{6,7,8325},{5,7,6749},{5,7,5725},{5,7,3833},{5,7,7866},{5,7,4082},{4,7,2470},{4,7,265},{4,7,7219},{2,7,365},{7,7,1842},{6,7,1460},{6,7,1060},{6,7,436},{7,6,2241}, +{6,7,1425},{6,7,1025},{3,7,1},{6,7,2169},{3,7,1},{5,7,5725},{5,7,5725},{5,7,5725},{5,7,3833},{5,7,4950},{4,7,2470},{4,7,2470},{4,7,265},{3,7,4521},{2,7,365},{6,7,1060},{6,7,1060},{6,7,1060},{6,7,436},{6,7,1649},{6,7,1025},{6,7,1025},{3,7,1},{7,6,1625},{3,7,1},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49}, +{0,7,0},{7,7,98},{0,7,0},{5,0,2809},{5,0,2809},{5,0,2809},{5,0,2809},{4,7,445},{4,7,445},{4,7,445},{4,6,202},{2,7,365},{2,7,365},{6,7,7093},{6,7,6469},{5,7,5581},{5,7,3689},{5,7,7226},{5,7,3442},{5,7,2418},{4,7,25},{4,7,6275},{2,7,509},{7,7,1266},{7,7,1194},{6,7,1028},{6,7,404},{7,7,1686},{6,7,1089},{6,7,689},{4,7,16},{6,7,1641}, +{4,7,16},{5,7,5581},{5,7,5581},{5,7,5581},{5,7,3689},{5,7,4310},{5,7,2418},{5,7,2418},{4,7,25},{3,7,4121},{2,7,509},{6,7,1028},{6,7,1028},{6,7,1028},{6,7,404},{7,6,1201},{6,7,689},{6,7,689},{4,7,16},{7,6,1225},{4,7,16},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{5,0,2665}, +{5,0,2665},{5,0,2665},{5,0,2665},{4,7,685},{4,7,685},{4,7,685},{4,7,25},{2,7,509},{2,7,509},{6,7,6117},{6,7,5493},{6,7,5093},{5,7,3801},{6,7,6098},{5,7,3058},{5,7,2034},{4,7,41},{4,7,5587},{3,7,613},{7,7,818},{7,7,746},{7,7,697},{6,7,500},{7,7,1142},{6,7,881},{6,7,481},{4,7,16},{6,7,1241},{4,7,16},{6,7,5093},{6,7,5093},{6,7,5093}, +{5,7,3801},{5,7,3926},{5,7,2034},{5,7,2034},{4,7,41},{4,7,3562},{3,7,613},{7,7,697},{7,7,697},{7,7,697},{6,7,500},{7,6,865},{6,7,481},{6,7,481},{4,7,16},{6,7,841},{4,7,16},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{5,0,2777},{5,0,2777},{5,0,2777},{5,0,2777},{5,7,1010}, +{5,7,1010},{5,7,1010},{4,7,41},{3,7,613},{3,7,613},{6,7,5397},{6,7,4773},{6,7,4373},{6,7,3749},{6,7,5074},{5,7,2930},{5,7,1906},{4,7,313},{5,7,4753},{3,7,725},{7,7,498},{7,7,426},{7,7,377},{7,7,305},{7,7,726},{7,7,582},{6,7,401},{5,7,1},{7,7,774},{5,7,1},{6,7,4373},{6,7,4373},{6,7,4373},{6,7,3749},{5,7,3798},{5,7,1906},{5,7,1906}, +{4,7,313},{4,7,3130},{3,7,725},{7,7,377},{7,7,377},{7,7,377},{7,7,305},{7,7,605},{6,7,401},{6,7,401},{5,7,1},{6,7,569},{5,7,1},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{5,0,3145},{5,0,3145},{5,0,3145},{5,0,3145},{5,7,882},{5,7,882},{5,7,882},{4,7,313},{3,7,725}, +{3,7,725},{1,7,34142},{0,7,5184},{0,5,609},{0,5,4841},{1,7,46442},{0,7,24449},{0,5,9741},{0,4,24761},{0,5,65162},{0,3,40820},{0,7,10048},{0,7,2880},{0,5,545},{0,4,3204},{1,4,18070},{0,4,13297},{0,4,6453},{0,2,13857},{2,2,18070},{0,2,13857},{0,3,9},{0,3,9},{0,3,9},{0,2,36},{0,1,1145},{0,1,617},{0,1,617},{0,1,977},{0,0,1505},{0,0,1036},{0,3,9}, +{0,3,9},{0,3,9},{0,2,36},{1,0,1129},{0,1,617},{0,1,617},{0,1,977},{1,0,1105},{0,1,977},{4,2,9250},{0,7,2880},{0,5,545},{0,4,3204},{4,2,9250},{5,2,9250},{0,4,3204},{0,3,9280},{5,2,9250},{0,3,9280},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{1,7,38782},{0,7,6720},{0,5,305}, +{0,5,3801},{1,7,51082},{0,7,24961},{0,5,8701},{0,4,25849},{0,5,65535},{0,4,42094},{1,7,10502},{0,7,2624},{0,5,241},{0,4,3044},{3,1,19334},{0,4,14065},{0,4,6293},{0,3,14756},{4,1,19334},{0,3,14756},{0,4,4},{0,4,4},{0,4,4},{0,2,4},{0,2,1537},{0,1,937},{0,1,937},{0,1,977},{0,1,1898},{0,1,1338},{0,4,4},{0,4,4},{0,4,4},{0,2,4},{1,0,1513}, +{0,1,937},{0,1,937},{0,1,977},{0,1,1537},{0,1,977},{5,1,9256},{0,7,2624},{0,5,241},{0,4,3044},{5,1,9256},{7,1,9256},{0,4,3044},{0,3,9280},{7,1,9256},{0,3,9280},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{1,7,44190},{0,7,9024},{0,5,769},{0,5,3529},{1,7,56490},{0,7,26241},{0,5,8429}, +{0,4,27705},{0,5,65535},{0,4,43950},{1,7,10854},{0,7,2624},{0,5,193},{0,5,2953},{2,3,20689},{0,5,14598},{0,4,6389},{0,3,15012},{6,0,20689},{0,3,15012},{0,4,36},{0,4,36},{0,4,36},{0,2,100},{0,2,1985},{0,2,1061},{0,2,1061},{0,1,1105},{0,1,2346},{0,1,1466},{0,4,36},{0,4,36},{0,4,36},{0,2,100},{0,2,1985},{0,2,1061},{0,2,1061},{0,1,1105},{0,1,1985}, +{0,1,1105},{6,0,9256},{0,7,2624},{0,5,193},{0,5,2953},{6,0,9256},{6,2,9256},{0,5,2953},{0,3,9536},{6,2,9256},{0,3,9536},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{1,7,50366},{0,7,12096},{0,6,1101},{0,5,4025},{1,7,62666},{0,7,28289},{0,5,8925},{0,5,28912},{0,6,65535},{0,4,46574},{1,7,11462}, +{0,7,2880},{0,6,317},{0,5,2425},{4,0,22137},{0,5,15206},{0,4,6741},{0,3,15524},{3,2,22137},{0,3,15524},{0,5,1},{0,5,1},{0,5,1},{0,3,9},{0,2,2561},{0,2,1285},{0,2,1285},{0,1,1361},{0,1,2922},{0,1,1722},{0,5,1},{0,5,1},{0,5,1},{0,3,9},{1,1,2561},{0,2,1285},{0,2,1285},{0,1,1361},{2,0,2521},{0,1,1361},{5,2,9250},{0,7,2880},{0,6,317}, +{0,5,2425},{5,2,9250},{5,3,9250},{0,5,2425},{0,4,9640},{5,3,9250},{0,4,9640},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{1,7,58232},{0,7,16470},{0,6,129},{0,6,3489},{1,7,65535},{0,7,31511},{0,6,10213},{0,5,29110},{0,6,65535},{0,4,50444},{1,7,12452},{0,7,3474},{0,6,29},{0,5,2137},{2,4,23851}, +{0,6,16172},{0,5,7037},{0,3,16406},{7,0,23851},{0,3,16406},{0,6,4},{0,6,4},{0,6,4},{0,3,36},{0,3,3232},{0,2,1690},{0,2,1690},{0,1,1802},{0,1,3723},{0,1,2163},{0,6,4},{0,6,4},{0,6,4},{0,3,36},{1,1,3200},{0,2,1690},{0,2,1690},{0,1,1802},{2,0,3232},{0,1,1802},{6,1,9256},{1,7,3232},{0,6,29},{0,5,2137},{6,1,9256},{6,3,9256},{0,5,2137}, +{0,4,9298},{6,3,9256},{0,4,9298},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{1,7,65535},{0,7,21174},{0,6,81},{0,6,2545},{1,7,65535},{0,7,35191},{0,6,9269},{0,5,30102},{0,6,65535},{0,5,54602},{1,7,13604},{0,7,4274},{0,6,45},{0,5,2153},{4,1,25472},{0,6,16620},{0,5,7053},{0,3,17462},{4,2,25472}, +{0,3,17462},{0,6,36},{0,6,36},{0,6,36},{0,4,49},{0,3,3872},{0,3,2132},{0,3,2132},{0,1,2330},{0,1,4571},{0,1,2691},{0,6,36},{0,6,36},{0,6,36},{0,4,49},{0,3,3872},{0,3,2132},{0,3,2132},{0,1,2330},{1,1,3872},{0,1,2330},{7,0,9250},{1,7,3488},{0,6,45},{0,5,2153},{7,0,9250},{3,5,9250},{0,5,2153},{0,4,9266},{3,5,9250},{0,4,9266},{0,0,0}, +{0,0,0},{0,0,0},{0,0,0},{0,0,36},{0,0,36},{0,0,36},{0,0,100},{0,0,136},{0,0,136},{2,7,65535},{1,7,25204},{0,6,805},{0,6,2373},{1,7,65535},{0,7,39263},{0,6,8769},{0,5,31402},{0,6,65535},{0,5,55902},{1,7,14880},{1,7,5024},{0,6,321},{0,6,1889},{5,0,26756},{0,6,17000},{0,5,7049},{0,4,18139},{6,1,26756},{0,4,18139},{0,7,5},{0,7,5},{0,7,5}, +{0,4,5},{0,3,4468},{0,3,2248},{0,3,2248},{0,2,2722},{0,2,5411},{0,1,3227},{0,7,5},{0,7,5},{0,7,5},{0,4,5},{2,0,4420},{0,3,2248},{0,3,2248},{0,2,2722},{3,0,4420},{0,2,2722},{5,4,9250},{1,7,4000},{1,6,185},{0,6,1885},{5,4,9250},{7,3,9250},{0,6,1885},{0,4,9490},{7,3,9250},{0,4,9490},{0,0,4},{0,0,4},{0,0,4},{0,0,4},{0,0,16}, +{0,0,16},{0,0,16},{0,0,64},{0,0,100},{0,0,100},{2,7,65535},{1,7,29620},{0,7,1306},{0,6,3061},{2,7,65535},{0,7,43055},{0,6,8145},{0,6,31878},{0,7,65535},{0,5,56670},{2,7,14924},{1,7,5344},{0,7,406},{0,6,1617},{4,2,26756},{0,6,16744},{0,5,6553},{0,4,17195},{5,2,26756},{0,4,17195},{0,7,181},{0,7,181},{0,7,181},{0,4,181},{0,4,4418},{0,3,2056},{0,3,2056}, +{0,2,2210},{0,2,5411},{0,2,3171},{0,7,181},{0,7,181},{0,7,181},{0,4,181},{0,4,4418},{0,3,2056},{0,3,2056},{0,2,2210},{2,1,4418},{0,2,2210},{6,3,9248},{2,7,4292},{0,7,306},{0,6,1517},{6,3,9248},{6,4,9248},{0,6,1517},{0,5,9698},{6,4,9248},{0,5,9698},{0,0,100},{0,0,100},{0,0,100},{0,0,100},{0,0,16},{0,0,16},{0,0,16},{0,0,0},{0,0,36}, +{0,0,36},{2,7,65535},{1,7,35659},{0,7,865},{0,7,2657},{2,7,65535},{1,7,48315},{0,7,8072},{0,6,29745},{0,7,65535},{0,5,58605},{2,7,15347},{1,7,6163},{1,7,270},{0,6,1770},{5,1,26756},{0,7,15992},{0,6,5378},{0,4,16592},{6,2,26756},{0,4,16592},{0,7,685},{0,7,685},{0,7,685},{0,5,370},{0,5,4450},{0,4,1768},{0,4,1768},{0,2,1940},{0,2,5717},{0,2,2901},{1,7,234}, +{1,7,234},{1,7,234},{1,4,250},{1,3,4420},{0,4,1768},{0,4,1768},{0,2,1940},{1,2,4420},{0,2,1940},{7,2,9250},{3,7,4820},{1,7,45},{0,6,1409},{7,2,9250},{5,5,9250},{0,6,1409},{0,5,9320},{5,5,9250},{0,5,9320},{0,0,361},{0,0,361},{0,0,361},{0,0,361},{0,1,0},{0,1,0},{0,1,0},{0,0,81},{0,0,117},{0,0,117},{2,7,65535},{1,7,40299},{0,7,1405}, +{0,7,2173},{2,7,65535},{1,7,50747},{0,7,6068},{0,6,28101},{0,7,65535},{0,5,59897},{2,7,15659},{1,7,6963},{1,7,74},{1,6,2046},{6,0,26264},{0,7,15284},{0,6,4470},{0,4,16052},{3,4,26264},{0,4,16052},{1,7,1230},{1,7,1230},{1,7,1230},{0,5,754},{0,5,4450},{0,4,1576},{0,4,1576},{0,2,1972},{0,2,6261},{0,2,2933},{1,7,74},{1,7,74},{1,7,74},{1,5,113},{2,2,4418}, +{0,4,1576},{0,4,1576},{0,2,1972},{5,0,4418},{0,2,1972},{5,6,8980},{3,7,4808},{1,7,25},{0,7,1444},{5,6,8980},{4,6,8980},{0,7,1444},{0,5,8980},{4,6,8980},{0,5,8980},{0,0,729},{0,0,729},{0,0,729},{0,0,729},{0,2,16},{0,2,16},{0,2,16},{0,1,16},{0,0,325},{0,0,325},{2,7,65535},{1,7,40395},{0,7,2381},{0,7,2125},{2,7,65535},{1,7,48635},{0,7,4500}, +{0,6,24853},{0,7,65535},{0,5,57545},{3,7,14605},{2,7,6211},{1,7,170},{1,6,1598},{5,2,24379},{0,7,13716},{0,6,3446},{0,5,14549},{5,3,24379},{0,5,14549},{1,7,1326},{1,7,1326},{1,7,1326},{1,5,1157},{0,6,4418},{0,5,1394},{0,5,1394},{0,3,1621},{0,3,6482},{0,2,3221},{1,7,170},{1,7,170},{1,7,170},{1,5,1},{3,1,4418},{0,5,1394},{0,5,1394},{0,3,1621},{4,1,4418}, +{0,3,1621},{7,3,7940},{3,7,4264},{2,7,81},{0,7,900},{7,3,7940},{6,5,7940},{0,7,900},{0,5,7988},{6,5,7940},{0,5,7988},{1,0,1157},{1,0,1157},{1,0,1157},{1,0,1157},{0,2,16},{0,2,16},{0,2,16},{0,1,16},{0,1,377},{0,1,377},{2,7,65535},{1,7,40747},{0,7,3613},{0,7,2333},{2,7,65535},{1,7,46779},{0,7,3188},{0,6,21861},{0,7,65535},{0,5,55449},{3,7,13181}, +{2,7,5667},{1,7,522},{1,7,1306},{6,1,22571},{0,7,12404},{0,6,2678},{0,5,12453},{4,4,22571},{0,5,12453},{1,7,1678},{1,7,1678},{1,7,1678},{1,5,1301},{0,7,4468},{0,5,1170},{0,5,1170},{0,3,1285},{0,3,6866},{0,3,3221},{1,7,522},{1,7,522},{1,7,522},{1,5,145},{4,0,4420},{0,5,1170},{0,5,1170},{0,3,1285},{3,2,4420},{0,3,1285},{6,5,6964},{3,7,3848},{2,7,1}, +{0,7,484},{6,5,6964},{3,7,6964},{0,7,484},{0,5,7124},{3,7,6964},{0,5,7124},{1,0,1237},{1,0,1237},{1,0,1237},{1,0,1237},{0,3,1},{0,3,1},{0,3,1},{0,2,100},{0,1,505},{0,1,505},{2,7,65535},{1,7,41449},{0,7,5305},{0,7,2873},{2,7,65535},{1,7,44997},{0,7,2018},{0,6,18801},{0,7,65535},{0,6,52421},{3,7,11885},{2,7,5361},{2,7,320},{1,7,1000},{5,3,20645}, +{0,7,11234},{0,7,2018},{0,5,10401},{6,3,20645},{0,5,10401},{1,7,2380},{1,7,2380},{1,7,2380},{1,6,1496},{0,7,4450},{0,6,964},{0,6,964},{0,3,1213},{0,3,7604},{0,3,3149},{2,7,320},{2,7,320},{2,7,320},{2,5,272},{2,4,4418},{0,6,964},{0,6,964},{0,3,1213},{7,0,4418},{0,3,1213},{5,7,5941},{4,7,3181},{2,7,64},{0,7,169},{5,7,5941},{5,6,5941},{0,7,169}, +{0,5,6305},{5,6,5941},{0,5,6305},{1,0,1480},{1,0,1480},{1,0,1480},{1,0,1480},{0,4,25},{0,4,25},{0,4,25},{0,2,1},{0,1,802},{0,1,802},{2,7,65535},{1,7,42345},{0,7,7081},{0,7,3625},{2,7,65535},{1,7,43685},{0,7,1250},{0,6,16353},{0,7,65535},{0,6,49973},{3,7,11005},{3,7,5153},{2,7,320},{2,7,964},{7,0,19026},{1,7,10349},{0,7,1250},{0,5,8849},{3,5,19026}, +{0,5,8849},{1,7,3276},{1,7,3276},{1,7,3276},{1,6,1848},{0,7,4706},{0,6,740},{0,6,740},{0,4,1226},{0,4,7955},{0,3,3357},{2,7,320},{2,7,320},{2,7,320},{2,6,145},{3,3,4420},{0,6,740},{0,6,740},{0,4,1226},{6,1,4420},{0,4,1226},{7,4,5105},{4,7,2701},{3,7,25},{0,7,25},{7,4,5105},{7,5,5105},{0,7,25},{0,6,5645},{7,5,5105},{0,6,5645},{1,0,1832}, +{1,0,1832},{1,0,1832},{1,0,1832},{0,4,9},{0,4,9},{0,4,9},{0,2,49},{0,2,1010},{0,2,1010},{2,7,65535},{1,7,43497},{1,7,9052},{0,7,4633},{2,7,65535},{1,7,42629},{0,7,738},{0,6,14161},{0,7,65535},{0,6,47781},{3,7,10381},{3,7,4529},{2,7,576},{2,7,484},{5,4,17490},{1,7,9293},{0,7,738},{0,5,7553},{7,3,17490},{0,5,7553},{1,7,4428},{1,7,4428},{1,7,4428}, +{1,7,2412},{0,7,5218},{0,7,738},{0,7,738},{0,4,810},{0,4,8467},{0,3,3821},{2,7,576},{2,7,576},{2,7,576},{2,6,1},{4,2,4420},{0,7,738},{0,7,738},{0,4,810},{5,2,4420},{0,4,810},{6,6,4329},{4,7,2349},{3,7,9},{0,7,9},{6,6,4329},{4,7,4329},{0,7,9},{0,6,4637},{4,7,4329},{0,6,4637},{1,0,2312},{1,0,2312},{1,0,2312},{1,0,2312},{0,5,4}, +{0,5,4},{0,5,4},{0,3,36},{0,2,1186},{0,2,1186},{2,7,65535},{1,7,44905},{1,7,10460},{0,7,5897},{2,7,65535},{1,7,41829},{0,7,482},{0,6,12225},{0,7,65535},{0,6,45845},{4,7,9325},{3,7,4161},{3,7,797},{2,7,260},{7,1,16034},{1,7,8493},{0,7,482},{0,5,6513},{4,5,16034},{0,5,6513},{2,7,5712},{2,7,5712},{2,7,5712},{1,7,2924},{1,7,5672},{0,7,482},{0,7,482}, +{0,4,650},{0,4,9235},{0,4,3899},{3,7,797},{3,7,797},{3,7,797},{2,6,113},{5,1,4426},{0,7,482},{0,7,482},{0,4,650},{7,1,4426},{0,4,650},{6,6,3625},{5,7,1985},{4,7,100},{1,7,4},{6,6,3625},{6,6,3617},{1,7,4},{0,6,3757},{6,6,3617},{0,6,3757},{1,0,2920},{1,0,2920},{1,0,2920},{1,0,2920},{0,5,36},{0,5,36},{0,5,36},{0,3,4},{0,2,1490}, +{0,2,1490},{2,7,65535},{1,7,46795},{1,7,12350},{0,7,7625},{2,7,65535},{1,7,41235},{0,7,500},{0,6,10353},{0,7,65535},{0,6,43973},{4,7,8227},{3,7,4053},{3,7,689},{2,7,314},{6,3,14507},{2,7,7875},{0,7,500},{0,5,5649},{6,4,14507},{0,5,5649},{2,7,6594},{2,7,6594},{2,7,6594},{1,7,3806},{1,7,6086},{0,7,500},{0,7,500},{0,4,776},{0,5,9830},{0,4,4025},{3,7,689}, +{3,7,689},{3,7,689},{3,6,298},{6,0,4420},{0,7,500},{0,7,500},{0,4,776},{3,4,4420},{0,4,776},{7,5,2890},{5,7,1508},{4,7,1},{2,7,25},{7,5,2890},{6,6,2906},{2,7,25},{0,6,2920},{6,6,2906},{0,6,2920},{1,0,3757},{1,0,3757},{1,0,3757},{1,0,3757},{0,6,9},{0,6,9},{0,6,9},{0,4,100},{0,2,1985},{0,2,1985},{2,7,65535},{1,7,48747},{1,7,14302}, +{0,7,9433},{2,7,65535},{1,7,40979},{0,7,788},{0,6,8961},{0,7,65535},{0,6,42581},{4,7,7523},{4,7,3923},{3,7,865},{3,7,181},{7,2,13243},{2,7,7075},{1,7,754},{0,6,4337},{5,5,13243},{0,6,4337},{2,7,7650},{2,7,7650},{2,7,7650},{1,7,4862},{1,7,6726},{0,7,788},{0,7,788},{0,5,529},{0,5,10470},{0,4,4409},{3,7,865},{3,7,865},{3,7,865},{3,7,181},{5,2,4426}, +{1,7,754},{1,7,754},{0,5,529},{7,2,4426},{0,5,529},{6,7,2320},{5,7,1220},{4,7,49},{2,7,9},{6,7,2320},{5,7,2320},{2,7,9},{0,6,2312},{5,7,2320},{0,6,2312},{1,0,4637},{1,0,4637},{1,0,4637},{1,0,4637},{0,7,4},{0,7,4},{0,7,4},{0,4,4},{0,3,2297},{0,3,2297},{2,7,65535},{1,7,50955},{1,7,16510},{1,7,10798},{2,7,65535},{1,7,40979},{0,7,1332}, +{0,7,6964},{0,7,65535},{0,6,41445},{4,7,7075},{4,7,3475},{3,7,1297},{3,7,5},{6,4,12051},{2,7,6531},{1,7,754},{0,6,3201},{7,4,12051},{0,6,3201},{2,7,8962},{2,7,8962},{2,7,8962},{2,7,5834},{1,7,7622},{0,7,1332},{0,7,1332},{0,5,289},{0,6,11342},{0,4,5049},{3,7,1297},{3,7,1297},{3,7,1297},{3,7,5},{6,1,4426},{1,7,754},{1,7,754},{0,5,289},{6,3,4426}, +{0,5,289},{6,7,1808},{5,7,1060},{5,7,36},{3,7,4},{6,7,1808},{7,6,1808},{3,7,4},{0,6,1832},{7,6,1808},{0,6,1832},{1,0,5645},{1,0,5645},{1,0,5645},{1,0,5645},{0,7,36},{0,7,36},{0,7,36},{0,4,36},{0,3,2665},{0,3,2665},{2,7,65535},{1,7,53419},{1,7,18974},{1,7,12366},{2,7,65535},{1,7,41235},{0,7,2132},{0,7,5204},{0,7,65535},{0,6,40565},{5,7,6641}, +{4,7,3283},{4,7,1258},{3,7,85},{5,6,10952},{3,7,5900},{1,7,1010},{0,6,2321},{4,6,10952},{0,6,2321},{2,7,10530},{2,7,10530},{2,7,10530},{2,7,6666},{1,7,8774},{0,7,2132},{0,7,2132},{0,5,305},{0,6,11790},{0,5,5205},{4,7,1258},{4,7,1258},{4,7,1258},{3,7,85},{7,0,4420},{1,7,1010},{1,7,1010},{0,5,305},{3,5,4420},{0,5,305},{7,6,1360},{6,7,800},{5,7,4}, +{3,7,36},{7,6,1360},{7,6,1360},{3,7,36},{0,6,1480},{7,6,1360},{0,6,1480},{2,0,6305},{2,0,6305},{2,0,6305},{2,0,6305},{0,7,196},{0,7,196},{0,7,196},{0,5,49},{0,3,3161},{0,3,3161},{2,7,65535},{2,7,56301},{1,7,22052},{1,7,14436},{2,7,65535},{1,7,41829},{0,7,3338},{0,7,3530},{0,7,65535},{0,6,39881},{5,7,5741},{4,7,3373},{4,7,1348},{4,7,328},{7,3,9830}, +{3,7,5270},{2,7,1184},{0,6,1637},{6,5,9830},{0,6,1637},{2,7,12600},{2,7,12600},{2,7,12600},{2,7,7908},{1,7,10376},{1,7,2760},{1,7,2760},{0,6,481},{0,6,12600},{0,5,5529},{4,7,1348},{4,7,1348},{4,7,1348},{4,7,328},{7,1,4426},{2,7,1184},{2,7,1184},{0,6,481},{7,3,4426},{0,6,481},{7,6,937},{6,7,521},{5,7,121},{4,7,4},{7,6,937},{6,7,929},{4,7,4}, +{0,6,1237},{6,7,929},{0,6,1237},{2,0,7124},{2,0,7124},{2,0,7124},{2,0,7124},{0,7,529},{0,7,529},{0,7,529},{0,5,4},{0,4,3778},{0,4,3778},{2,7,65535},{2,7,58413},{1,7,25060},{1,7,16548},{2,7,65535},{1,7,42629},{0,7,4682},{0,7,2314},{0,7,65535},{0,6,39545},{5,7,5213},{5,7,3321},{4,7,1700},{4,7,200},{5,7,8902},{3,7,4982},{2,7,1440},{0,6,1301},{5,6,8902}, +{0,6,1301},{3,7,14701},{3,7,14701},{3,7,14701},{2,7,9284},{2,7,11492},{1,7,3560},{1,7,3560},{0,6,145},{0,6,13592},{0,5,6089},{4,7,1700},{4,7,1700},{4,7,1700},{4,7,200},{6,3,4420},{2,7,1440},{2,7,1440},{0,6,145},{6,4,4420},{0,6,145},{7,6,697},{6,7,409},{6,7,9},{5,7,9},{7,6,697},{6,7,625},{5,7,9},{0,6,1157},{6,7,625},{0,6,1157},{2,0,7988}, +{2,0,7988},{2,0,7988},{2,0,7988},{0,7,961},{0,7,961},{0,7,961},{0,5,100},{0,4,4210},{0,4,4210},{3,7,65535},{2,7,60781},{1,7,28324},{1,7,18916},{2,7,65535},{1,7,43685},{0,7,6282},{0,7,1354},{0,7,65535},{0,6,39465},{5,7,4941},{5,7,3049},{5,7,2025},{4,7,328},{7,4,8069},{4,7,4465},{3,7,1586},{0,6,1221},{7,5,8069},{0,6,1221},{3,7,16189},{3,7,16189},{3,7,16189}, +{2,7,10916},{2,7,12740},{1,7,4616},{1,7,4616},{0,6,65},{0,7,14411},{0,6,6789},{5,7,2025},{5,7,2025},{5,7,2025},{4,7,328},{7,2,4420},{3,7,1586},{3,7,1586},{0,6,65},{5,5,4420},{0,6,65},{7,7,377},{7,7,305},{6,7,25},{5,7,25},{7,7,377},{6,7,449},{5,7,25},{0,7,729},{6,7,449},{0,7,729},{2,0,8980},{2,0,8980},{2,0,8980},{2,0,8980},{1,7,1480}, +{1,7,1480},{1,7,1480},{0,6,16},{0,4,4770},{0,4,4770},{3,7,65535},{2,7,59505},{1,7,29984},{1,7,19680},{2,7,65535},{1,7,43137},{0,7,8318},{0,7,830},{0,7,65535},{0,6,34901},{5,7,4925},{5,7,3033},{5,7,2009},{4,7,712},{6,6,7325},{4,7,4145},{3,7,1810},{0,7,650},{4,7,7325},{0,7,650},{3,7,16745},{3,7,16745},{3,7,16745},{2,7,12024},{2,7,13464},{1,7,5556},{1,7,5556}, +{0,6,277},{0,7,14139},{0,6,6017},{5,7,2009},{5,7,2009},{5,7,2009},{4,7,712},{5,6,4418},{3,7,1810},{3,7,1810},{0,6,241},{4,6,4418},{0,6,241},{7,7,185},{7,7,113},{7,7,64},{6,7,1},{7,7,185},{7,7,193},{6,7,1},{0,7,361},{7,7,193},{0,7,361},{2,0,9320},{2,0,9320},{2,0,9320},{2,0,9320},{1,7,1460},{1,7,1460},{1,7,1460},{0,6,52},{0,5,4772}, +{0,5,4772},{3,7,65535},{2,7,57588},{1,7,32135},{1,7,20823},{3,7,65535},{1,7,42804},{1,7,8359},{0,7,1289},{0,7,65535},{0,6,28970},{6,7,4317},{5,7,3321},{5,7,2297},{5,7,845},{7,5,6587},{5,7,4008},{4,7,2066},{0,7,164},{6,6,6611},{0,7,164},{3,7,17366},{3,7,17366},{3,7,17366},{3,7,12274},{2,7,14427},{2,7,6699},{2,7,6699},{0,7,389},{0,7,13860},{0,6,5234},{5,7,2297}, +{5,7,2297},{5,7,2297},{5,7,845},{6,5,4420},{4,7,2066},{4,7,2066},{0,7,164},{3,7,4420},{0,7,164},{7,7,122},{7,7,50},{7,7,1},{7,7,9},{7,7,122},{7,7,58},{7,7,9},{0,7,100},{7,7,58},{0,7,100},{2,0,9698},{2,0,9698},{2,0,9698},{2,0,9698},{1,7,1586},{1,7,1586},{1,7,1586},{0,7,289},{0,5,4250},{0,5,4250},{3,7,65535},{2,7,56836},{2,7,31631}, +{1,7,22791},{3,7,65535},{2,7,40532},{1,7,9015},{1,7,778},{0,7,65535},{0,6,24650},{6,7,3949},{6,7,3325},{5,7,2825},{5,7,1021},{6,7,6020},{5,7,3688},{4,7,2290},{0,7,4},{5,7,6020},{0,7,4},{3,7,18326},{3,7,18326},{3,7,18326},{3,7,12626},{3,7,15077},{2,7,7227},{2,7,7227},{1,7,294},{0,7,14020},{0,6,4946},{5,7,2825},{5,7,2825},{5,7,2825},{5,7,1021},{7,4,4418}, +{4,7,2290},{4,7,2290},{0,7,4},{7,5,4418},{0,7,4},{7,7,202},{7,7,130},{7,7,81},{7,7,25},{7,7,202},{7,7,74},{7,7,25},{0,7,4},{7,7,74},{0,7,4},{3,0,9490},{3,0,9490},{3,0,9490},{3,0,9490},{1,7,1970},{1,7,1970},{1,7,1970},{1,6,202},{0,6,3922},{0,6,3922},{3,7,65535},{3,7,55466},{2,7,30335},{2,7,21687},{3,7,65535},{2,7,37932},{1,7,9535}, +{1,7,70},{0,7,65535},{0,7,20544},{6,7,3417},{6,7,2793},{6,7,2393},{5,7,1033},{6,7,5184},{5,7,3204},{5,7,2180},{1,7,25},{7,6,5168},{1,7,25},{4,7,17611},{4,7,17611},{4,7,17611},{3,7,12630},{3,7,14321},{2,7,7251},{2,7,7251},{1,7,34},{0,7,13376},{0,7,4160},{6,7,2393},{6,7,2393},{6,7,2393},{5,7,1033},{6,6,3874},{5,7,2180},{5,7,2180},{1,7,25},{4,7,3874}, +{1,7,25},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{3,0,9266},{3,0,9266},{3,0,9266},{3,0,9266},{2,7,2210},{2,7,2210},{2,7,2210},{1,7,34},{0,6,3442},{0,6,3442},{3,7,65535},{3,7,51210},{2,7,29343},{2,7,20695},{3,7,65535},{2,7,35820},{1,7,10495},{1,7,134},{1,7,65535},{0,7,15936},{6,7,2889}, +{6,7,2265},{6,7,1865},{5,7,1049},{7,6,4288},{5,7,2724},{5,7,1700},{1,7,9},{7,6,4272},{1,7,9},{4,7,16555},{4,7,16555},{4,7,16555},{3,7,12662},{3,7,13441},{2,7,7251},{2,7,7251},{1,7,34},{0,7,12608},{0,7,3392},{6,7,1865},{6,7,1865},{6,7,1865},{5,7,1049},{7,5,3218},{5,7,1700},{5,7,1700},{1,7,9},{6,6,3202},{1,7,9},{7,7,242},{7,7,170},{7,7,121}, +{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{3,0,9298},{3,0,9298},{3,0,9298},{3,0,9298},{2,7,2210},{2,7,2210},{2,7,2210},{1,7,34},{0,6,3218},{0,6,3218},{4,7,65535},{3,7,47340},{2,7,29145},{2,7,20497},{3,7,65535},{2,7,34362},{2,7,9157},{1,7,1124},{1,7,64598},{0,7,11670},{6,7,2448},{6,7,1824},{6,7,1424},{6,7,800},{7,6,3361}, +{6,7,2321},{5,7,1313},{2,7,0},{6,7,3401},{2,7,0},{4,7,15673},{4,7,15673},{4,7,15673},{4,7,12073},{3,7,12757},{3,7,6905},{3,7,6905},{1,7,340},{1,7,11657},{0,7,2834},{6,7,1424},{6,7,1424},{6,7,1424},{6,7,800},{7,5,2525},{5,7,1313},{5,7,1313},{2,7,0},{5,7,2545},{2,7,0},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49}, +{0,7,0},{7,7,98},{0,7,0},{3,0,9640},{3,0,9640},{3,0,9640},{3,0,9640},{2,7,2516},{2,7,2516},{2,7,2516},{1,7,340},{0,7,2834},{0,7,2834},{4,7,65535},{3,7,44716},{3,7,27896},{2,7,21137},{4,7,65535},{3,7,31853},{2,7,8677},{2,7,784},{1,7,59734},{0,7,8694},{6,7,2192},{6,7,1568},{6,7,1168},{6,7,544},{7,6,2673},{6,7,1761},{5,7,1105},{3,7,25},{6,7,2649}, +{3,7,25},{4,7,15161},{4,7,15161},{4,7,15161},{4,7,11561},{4,7,12169},{3,7,6569},{3,7,6569},{2,7,208},{1,7,10889},{0,7,2610},{6,7,1168},{6,7,1168},{6,7,1168},{6,7,544},{6,7,1985},{5,7,1105},{5,7,1105},{3,7,25},{5,7,1985},{3,7,25},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{4,0,9536}, +{4,0,9536},{4,0,9536},{4,0,9536},{2,7,3060},{2,7,3060},{2,7,3060},{2,7,208},{0,7,2610},{0,7,2610},{4,7,63766},{3,7,42860},{3,7,26040},{3,7,20188},{4,7,60070},{3,7,29085},{2,7,8965},{2,7,336},{1,7,55638},{0,7,6486},{7,7,1686},{6,7,1440},{6,7,1040},{6,7,416},{7,6,2113},{6,7,1329},{6,7,929},{3,7,9},{6,7,2025},{3,7,9},{4,7,14905},{4,7,14905},{4,7,14905}, +{4,7,11305},{4,7,11209},{3,7,6489},{3,7,6489},{2,7,272},{1,7,10377},{0,7,2642},{6,7,1040},{6,7,1040},{6,7,1040},{6,7,416},{7,6,1537},{6,7,929},{6,7,929},{3,7,9},{7,6,1513},{3,7,9},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{4,0,9280},{4,0,9280},{4,0,9280},{4,0,9280},{3,7,3125}, +{3,7,3125},{3,7,3125},{2,7,272},{0,7,2642},{0,7,2642},{4,7,59414},{4,7,41414},{3,7,24952},{3,7,19100},{4,7,55014},{3,7,27085},{2,7,10021},{2,7,656},{1,7,52310},{0,7,5046},{7,7,1142},{7,7,1070},{7,7,1021},{6,7,416},{7,7,1538},{6,7,1025},{6,7,625},{4,7,4},{6,7,1529},{4,7,4},{5,7,13964},{5,7,13964},{5,7,13964},{4,7,11305},{4,7,10505},{3,7,6665},{3,7,6665}, +{2,7,592},{2,7,9973},{0,7,2930},{7,7,1021},{7,7,1021},{7,7,1021},{6,7,416},{7,6,1105},{6,7,625},{6,7,625},{4,7,4},{6,7,1129},{4,7,4},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{4,0,9280},{4,0,9280},{4,0,9280},{4,0,9280},{3,7,3301},{3,7,3301},{3,7,3301},{2,7,592},{0,7,2930}, +{0,7,2930},
\ No newline at end of file |