/* kb_text_shape - v1.03 - text segmentation and shaping by Jimmy Lefevre SECURITY This library provides NO SECURITY GUARANTEE whatsoever. DO NOT use it on untrusted font files. FEATURE OVERVIEW This library provides: - Unicode segmentation LTR/RTL breaking Script breaking Line breaking Word breaking Grapheme breaking - OpenType text shaping Open and parse TTF and OTF fonts Extract glyph information Apply OpenType features such as ligatures and contextual typographic rules All OpenType shapers are supported, which means most languages in the world are supported (see LANGUAGE_SUPPORT for known non-supported cases) COMPILING & LINKING This library uses declare-anywhere, so it will not compile as C89/VC6 C. In one C/C++ file that #includes this file, do this: #define KB_TEXT_SHAPE_IMPLEMENTATION before the #include. That will create the implementation in that file. If you also do this: #define KB_TEXT_SHAPE_STATIC then all functions will be declared as static. If you do this: #define KB_TEXT_SHAPE_NO_CRT then we do not use the C runtime library. These functions are compiled out: kbts_CreateShapeState() kbts_FreeShapeState() kbts_FontFromFile() kbts_FreeFont() Additionally, we call KBTS_MEMSET(), which defaults to memset(), including outside of NO_CRT code. If you want to redirect it to your own function, you can do this: #define KBTS_MEMSET my_awesome_memset API Segmentation kbts_BeginBreak() kbts_BreakAddCodepoint() -- Feed a codepoint to the breaker, call kbts_Break() immediately after this to get results kbts_BreakFlush() kbts_Break() -- Call repeatedly to get breaks kbts_BreakStateIsValid() Easy font loading kbts_FontFromFile() -- Open a font, byteswap it in place, and allocate auxiliary structures kbts_FreeFont() kbts_FontIsValid() Shaping kbts_CreateShapeState() kbts_FreeShapeState() kbts_ShapeConfig() -- Bake a font/script-specific shaping configuration kbts_CodepointToGlyph() kbts_InferScript() -- Hacky script recognition for when no segmentation data is available kbts_Shape() -- Returns 1 if more memory is needed, you should probably call this in a while() kbts_ResetShapeState() Shaping - feature control kbts_FeatureOverride() -- Describe a manual override for a font feature kbts_FeatureOverrideFromTag() -- This also works on features that do not have a kbts_feature_id, but they will be slower. (Calling this with a feature that has a kbts_feature_id will not be slower.) kbts_GlyphConfig() -- Bake per-glyph parameters (for now, only feature overrides) Shaping - feature control - incremental API With this API, you provide a buffer first, and gradually construct the glyph_config. kbts_EmptyGlyphConfig() kbts_GlyphConfigOverrideFeature() kbts_GlyphConfigOverrideFeatureFromTag() Layout kbts_Cursor() kbts_PositionGlyph() Manual memory management kbts_SizeOfShapeState() kbts_PlaceShapeState() kbts_ReadFontHeader() -- Read the top of the file and return how many bytes are needed to read the rest kbts_ReadFontData() -- Read and byteswap the rest kbts_PostReadFontInitialize() -- Initialize auxiliary structures Utility, etc. kbts_ShaperIsComplex() kbts_ScriptIsComplex() kbts_InferScript() -- Stupid script detection. Do not ship this! Use script breaks instead. kbts_DecodeUtf8() kbts_ScriptTagToScript() kbts_FeatureTagToId() EXAMPLE USAGE Complete example: const char *String = "..."; size_t Length = strlen(String); // Open a font file kbts_font Font = kbts_FontFromFile("..."); // Make some glyphs kbts_glyph *Glyphs = (kbts_glyph *)malloc(sizeof(kbts_glyph) * Length); uint32_t GlyphCount = 0; kbts_script Script = KBTS_SCRIPT_DONT_KNOW; kbts_direction Direction = KBTS_DIRECTION_NONE; for(size_t StringAt = 0; StringAt < Length;) { kbts_decode Decode = kbts_DecodeUtf8(String, Length - StringAt); StringAt += Decode.SourceCharactersConsumed; if(Decode.Valid) { kbts_glyph Glyph = kbts_CodepointToGlyph(&Font, Decode.Codepoint); // Easy script inference for simple cases. (This is similar to hb_buffer_guess_segment_properties.) // If you have already segmented String with our API, you already have a script! // So no need to pass it in that case. // Only use this as a shorthand, when you are pretty sure String is a single // script. kbts_InferScript(&Direction, &Script, Glyph.Script); Glyphs[GlyphCount++] = Glyph; } } // Shape uint32_t GlyphCapacity = Length; kbts_shape_state *State = kbts_CreateShapeState(&Font); // A shape_config is immutable once created. You can freely share/hash it, etc. kbts_shape_config Config = kbts_ShapeConfig(&Font, Script, KBTS_LANGUAGE_DONT_KNOW); while(kbts_Shape(State, &Config, Direction, Direction, Glyphs, &GlyphCount, GlyphCapacity)) { Glyphs = realloc(Glyphs, sizeof(kbts_glyph) * State->RequiredGlyphCapacity); GlyphCapacity = State->RequiredGlyphCapacity; } // Get final positions kbts_cursor Cursor = kbts_Cursor(Direction); for(size_t GlyphIndex = 0; GlyphIndex < GlyphCount; ++GlyphIndex) { int X, Y; kbts_PositionGlyph(&Cursor, &Glyphs[GlyphIndex], &X, &Y); } Breaking Unicode text - finding the end of the current line: uint32_t LineLength = 0; kbts_break_state BreakState; kbts_BeginBreak(&BreakState, KBTS_DIRECTION_NONE, KBTS_JAPANESE_LINE_BREAK_STYLE_NORMAL); for(size_t CodepointIndex = 0; (CodepointIndex < CodepointCount) && !LineLength; ++CodepointIndex) { // We use a fixed-width encoding (codepoints) -- just pass a PositionIncrement of 1. // If we wanted to directly segment UTF-8 in-place, we would pass in however many bytes each UTF-8 character was. // The last parameter to AddCodepoint is a boolean signifying the end of text. // Alternatively, we could have written: // kbts_BreakAddCodepoint(..., 0); // if((CodepointIndex + 1) == CodepointCount) kbts_BreakFlush(); kbts_BreakAddCodepoint(&BreakState, Codepoints[CodepointIndex], 1, (CodepointIndex + 1) == CodepointCount); kbts_break Break; while(kbts_Break(&BreakState, &Break)) { // We could just as easily check for any other kind of break here. // See kbts_break_flags for the kind of breaks we can find. if(Break.Flags & KBTS_BREAK_FLAG_LINE_HARD) { LineLength = Break.Position; } } } Control which font features apply to which glyphs: kbts_feature_override Ss03FeatureOverrides[] = { kbts_FeatureOverride(KBTS_FEATURE_ID_ccmp, 0, 0), // Disable ccmp kbts_FeatureOverride(KBTS_FEATURE_ID_ss03, 0, 1), // Enable ss03 }; kbts_glyph_config Ss03Config = kbts_GlyphConfig(Ss03FeatureOverrides, 2); kbts_feature_override SaltFeatureOverrides[] = { kbts_FeatureOverride(KBTS_FEATURE_ID_salt, 1, 3), // Pick alternate glyph number 3 from feature 'salt' }; kbts_glyph_config SaltConfig = kbts_GlyphConfig(SaltFeatureOverrides, 1); // Then, do this before calling kbts_Shape(): MyGlyphs[0].Config = &Ss03Config; MyGlyphs[1].Config = &SaltConfig; Open a font with your own memory: kbts_font Font; size_t ScratchSize = kbts_ReadFontHeader(&Font, Data, Size); size_t PermanentMemorySize = kbts_ReadFontData(&Font, malloc(ScratchSize), ScratchSize); kbts_PostReadFontInitialize(&Font, malloc(PermanentMemorySize), PermanentMemorySize); // At any point, you can call kbts_FontIsValid(&Font) to check if the read went well. // You do not need to check for font validity in between API calls here; once a font is flagged // with an error, subsequent API calls simply do nothing. // If you have provided real font data, kbts_FontIsValid(&Font) will most likely be true. // We may still fail to parse some technically valid fonts that contain very deeply-nested or // self-referential lookups. // In those cases, Harfbuzz might open the font, but, at the time of writing, it silently limits // the recursion depth to 64 when applying the lookups anyway. Allocate a shape_state with your own memory: kbts_shape_state *State = kbts_PlaceShapeState(malloc(kbts_SizeOfShapeState(Font)), kbts_SizeOfShapeState(Font)); Use a single shape_state across multiple runs: while(kbts_Shape(State, ...)) {...} // If the previous shaping operation completed successfully, ResetShapeState is not necessary. // If, for any reason, you have decided to stop shaping in the middle of an operation, though, // you need to call it. // (This is just setting a state counter, so this is very cheap.) kbts_ResetShapeState(State); while(kbts_Shape(State, ...)) {...} Use a single shape_state across multiple fonts: // Different fonts have different memory requirements for shaping. However, beyond that, there // is nothing that ties a shape_state to a font. You may use it freely with multiple fonts, as // long as it is large enough. size_t Size0 = kbts_SizeOfShapeState(Font0); size_t Size1 = kbts_SizeOfShapeState(Font1); size_t Size = MAX(Size0, Size1) kbts_shape_state *State = kbts_PlaceShapeState(malloc(Size), Size); Use a single shape_config across multiple runs: // Once a shape_config has been created, it is assumed to be immutable and can be trivially shared // between runs/operations that have the same parameters. LANGUAGE SUPPORT Shaping is NOT supported for the following scripts: Zawgyi: some fonts exist, but no standardized OpenType feature set seems to exist as of writing. Syriac: Syriac Abbreviation Mark (0x070F) is not supported. Egyptian Hieroglyphs, I think, although example text is hard to come by. Word breaking is NOT supported for languages that require word dictionaries, like CJK. FONT SUPPORT Font collections (.ttc) are not supported. Indic fonts using the Indic1 shaping model are not supported. e.g., 'bng2' will work, but 'beng' will not. The Indic v2 shaping model was released with OpenType 1.5 in May 2008. Traditional Arabic Windows 3.1 fonts are not supported. https://github.com/harfbuzz/harfbuzz/issues/681 Thai/Lao PUA fonts are not supported. These are old fonts that use OS-specific codepages (PUA stands for [Unicode] "Private Use Area") and pre-OpenType shaping. https://linux.thai.net/~thep/th-otf/shaping.html More generally, we try to be compatible with most well-formed fonts, but we try less hard than Harfbuzz to be compatible with every font under the sun. OTHER LIMITATIONS Explicit direction control characters are not supported. This includes: 0x202A Left-to-right embedding 0x202B Right-to-left embedding 0x202D Left-to-right override 0x202E Right-to-left override 0x202C Pop directional formatting 0x2066 Left-to-right isolate 0x2067 Right-to-left isolate 0x2068 First strong isolate 0x2069 Pop directional isolate See https://unicode.org/reports/tr9 for more information. VERSION HISTORY 1.03 - New functions: kbts_FeatureTagToId(), kbts_FeatureOverrideFromTag(), kbts_EmptyGlyphConfig(), kbts_GlyphConfigOverrideFeature(), kbts_GlyphConfigOverrideFeatureFromTag(), kbts_ScriptTagToScript() Unregistered features can now be overriden using their tags. This is slower than overriding registered features, i.e. those that have a kbts_feature_id. Compiler warning cleanup 1.02b - Feature control for GPOS features Bounds checking in ReadFontHeader 1.02a - Positioning fix for format 2 GPOS pair adjustments 1.02 - Added per-glyph manual feature control through kbts_FeatureOverride(), kbts_GlyphConfig() Added enum definitions for features cv01-cv99 and ss01-ss20 1.01 - Header cleanup and glyph output documentation 1.0 - Initial release TODO Word dictionaries for word breaking: CJK, etc. 'stch' feature. Precompute GPOS nesting in advance and replace recursion with explicit frames. (Either that or limit to a hard depth for now.) LICENSE zlib License (C) Copyright 2024-2025 Jimmy Lefevre 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. */ #ifndef KB_TEXT_SHAPE_INCLUDED # define KB_TEXT_SHAPE_INCLUDED # ifndef kbts_s64 # if defined(_MSC_VER) || defined(__BORLANDC__) # define kbts_s64 __int64 # else # define kbts_s64 long long # endif # endif # ifndef kbts_u64 # if defined(_MSC_VER) || defined(__BORLANDC__) # define kbts_u64 unsigned __int64 # else # define kbts_u64 unsigned long long # endif # endif # ifndef kbts_u32 # define kbts_u32 unsigned # endif # ifndef kbts_u16 # define kbts_u16 unsigned short # endif # ifndef kbts_s32 # define kbts_s32 int # endif # ifndef kbts_s16 # define kbts_s16 short # endif # ifndef kbts_u8 # define kbts_u8 unsigned char # endif # ifndef kbts_s8 # define kbts_s8 signed char # endif # ifndef KB_TEXT_SHAPE_POINTER_SIZE # if defined(i386) || defined(__i386__) || defined(_M_IX86) || defined(_M_ARM) || defined(__arm__) || defined(__x86) || (defined(__APPLE__) && defined(__ppc)) || \ (defined(__TOS_AIX__) && !defined(__64BIT)) # define KB_TEXT_SHAPE_POINTER_SIZE 4 # else # define KB_TEXT_SHAPE_POINTER_SIZE 8 # endif # endif # if KB_TEXT_SHAPE_POINTER_SIZE == 4 # define kbts_un kbts_u32 # define kbts_sn kbts_s32 # else # define kbts_un kbts_u64 # define kbts_sn kbts_s64 # endif # ifdef __has_attribute # if __has_attribute(fallthrough) # define KBTS_FALLTHROUGH __attribute__((fallthrough)) # endif # endif # ifndef KBTS_FALLTHROUGH # define KBTS_FALLTHROUGH # endif # ifndef KBTS_EXPORT # ifdef KB_TEXT_SHAPE_STATIC # define KBTS_EXPORT static # else # ifdef __cplusplus # define KBTS_EXPORT extern "C" # else # define KBTS_EXPORT extern # endif # endif # endif # ifdef _MSC_VER # define KBTS_INLINE static __forceinline # define KBTS_NOINLINE static __declspec(noinline) # else # ifdef __has_attribute # if __has_attribute(always_inline) # define KBTS_INLINE static inline __attribute__((always_inline)) # endif # if __has_attribute(noinline) # define KBTS_NOINLINE static __attribute__((noinline)) # endif # endif # endif # ifndef KBTS_INLINE # define KBTS_INLINE static inline # endif # define KBTS_FOURCC(A, B, C, D) ((A) | ((B) << 8) | ((C) << 16) | ((D) << 24)) typedef kbts_u8 kbts_joining_feature; enum kbts_joining_feature_enum { KBTS_JOINING_FEATURE_NONE, // These must correspond with glyph_flags and FEATURE_IDs. KBTS_JOINING_FEATURE_ISOL, KBTS_JOINING_FEATURE_FINA, KBTS_JOINING_FEATURE_FIN2, KBTS_JOINING_FEATURE_FIN3, KBTS_JOINING_FEATURE_MEDI, KBTS_JOINING_FEATURE_MED2, KBTS_JOINING_FEATURE_INIT, KBTS_JOINING_FEATURE_COUNT, }; typedef kbts_u8 kbts_reph_position; enum kbts_reph_position_enum { KBTS_REPH_POSITION_AFTER_POST, KBTS_REPH_POSITION_BEFORE_POST, KBTS_REPH_POSITION_BEFORE_SUBJOINED, KBTS_REPH_POSITION_AFTER_SUBJOINED, KBTS_REPH_POSITION_AFTER_MAIN, KBTS_REPH_POSITION_COUNT, }; typedef kbts_u8 kbts_reph_encoding; enum kbts_reph_encoding_enum { KBTS_REPH_ENCODING_IMPLICIT, KBTS_REPH_ENCODING_EXPLICIT, KBTS_REPH_ENCODING_LOGICAL_REPHA, KBTS_REPH_ENCODING_VISUAL_REPHA, KBTS_REPH_ENCODING_COUNT, }; typedef kbts_u8 kbts_syllabic_position; enum kbts_syllabic_position_enum { KBTS_SYLLABIC_POSITION_NONE, KBTS_SYLLABIC_POSITION_RA_TO_BECOME_REPH, KBTS_SYLLABIC_POSITION_PREBASE_MATRA, KBTS_SYLLABIC_POSITION_PREBASE_CONSONANT, KBTS_SYLLABIC_POSITION_SYLLABLE_BASE, KBTS_SYLLABIC_POSITION_AFTER_MAIN, KBTS_SYLLABIC_POSITION_ABOVEBASE_CONSONANT, KBTS_SYLLABIC_POSITION_BEFORE_SUBJOINED, KBTS_SYLLABIC_POSITION_BELOWBASE_CONSONANT, KBTS_SYLLABIC_POSITION_AFTER_SUBJOINED, KBTS_SYLLABIC_POSITION_BEFORE_POST, KBTS_SYLLABIC_POSITION_POSTBASE_CONSONANT, KBTS_SYLLABIC_POSITION_AFTER_POST, KBTS_SYLLABIC_POSITION_FINAL_CONSONANT, KBTS_SYLLABIC_POSITION_SMVD, KBTS_SYLLABIC_POSITION_COUNT, }; typedef kbts_u32 kbts_language; enum kbts_language_enum { KBTS_LANGUAGE_DONT_KNOW = 0, KBTS_LANGUAGE_A_HMAO = KBTS_FOURCC('H', 'M', 'D', ' '), KBTS_LANGUAGE_AARI = KBTS_FOURCC('A', 'R', 'I', ' '), KBTS_LANGUAGE_ABAZA = KBTS_FOURCC('A', 'B', 'A', ' '), KBTS_LANGUAGE_ABKHAZIAN = KBTS_FOURCC('A', 'B', 'K', ' '), KBTS_LANGUAGE_ACHI = KBTS_FOURCC('A', 'C', 'R', ' '), KBTS_LANGUAGE_ACHOLI = KBTS_FOURCC('A', 'C', 'H', ' '), KBTS_LANGUAGE_ADYGHE = KBTS_FOURCC('A', 'D', 'Y', ' '), KBTS_LANGUAGE_AFAR = KBTS_FOURCC('A', 'F', 'R', ' '), KBTS_LANGUAGE_AFRIKAANS = KBTS_FOURCC('A', 'F', 'K', ' '), KBTS_LANGUAGE_AGAW = KBTS_FOURCC('A', 'G', 'W', ' '), KBTS_LANGUAGE_AITON = KBTS_FOURCC('A', 'I', 'O', ' '), KBTS_LANGUAGE_AKAN = KBTS_FOURCC('A', 'K', 'A', ' '), KBTS_LANGUAGE_ALBANIAN = KBTS_FOURCC('S', 'Q', 'I', ' '), KBTS_LANGUAGE_ALSATIAN = KBTS_FOURCC('A', 'L', 'S', ' '), KBTS_LANGUAGE_ALTAI = KBTS_FOURCC('A', 'L', 'T', ' '), KBTS_LANGUAGE_ALUO = KBTS_FOURCC('Y', 'N', 'A', ' '), KBTS_LANGUAGE_AMERICAN_PHONETIC = KBTS_FOURCC('A', 'P', 'P', 'H'), KBTS_LANGUAGE_AMHARIC = KBTS_FOURCC('A', 'M', 'H', ' '), KBTS_LANGUAGE_ANGLO_SAXON = KBTS_FOURCC('A', 'N', 'G', ' '), KBTS_LANGUAGE_ARABIC = KBTS_FOURCC('A', 'R', 'A', ' '), KBTS_LANGUAGE_ARAGONESE = KBTS_FOURCC('A', 'R', 'G', ' '), KBTS_LANGUAGE_ARAKANESE = KBTS_FOURCC('A', 'R', 'K', ' '), KBTS_LANGUAGE_ARAKWAL = KBTS_FOURCC('R', 'K', 'W', ' '), KBTS_LANGUAGE_ARMENIAN = KBTS_FOURCC('H', 'Y', 'E', ' '), KBTS_LANGUAGE_ARMENIAN_EAST = KBTS_FOURCC('H', 'Y', 'E', '0'), KBTS_LANGUAGE_AROMANIAN = KBTS_FOURCC('R', 'U', 'P', ' '), KBTS_LANGUAGE_ARPITAN = KBTS_FOURCC('F', 'R', 'P', ' '), KBTS_LANGUAGE_ASSAMESE = KBTS_FOURCC('A', 'S', 'M', ' '), KBTS_LANGUAGE_ASTURIAN = KBTS_FOURCC('A', 'S', 'T', ' '), KBTS_LANGUAGE_ATHAPASKAN = KBTS_FOURCC('A', 'T', 'H', ' '), KBTS_LANGUAGE_ATSINA = KBTS_FOURCC('A', 'T', 'S', ' '), KBTS_LANGUAGE_AVAR = KBTS_FOURCC('A', 'V', 'R', ' '), KBTS_LANGUAGE_AVATIME = KBTS_FOURCC('A', 'V', 'N', ' '), KBTS_LANGUAGE_AWADHI = KBTS_FOURCC('A', 'W', 'A', ' '), KBTS_LANGUAGE_AYMARA = KBTS_FOURCC('A', 'Y', 'M', ' '), KBTS_LANGUAGE_AZERBAIDJANI = KBTS_FOURCC('A', 'Z', 'E', ' '), KBTS_LANGUAGE_BADAGA = KBTS_FOURCC('B', 'A', 'D', ' '), KBTS_LANGUAGE_BAGHELKHANDI = KBTS_FOURCC('B', 'A', 'G', ' '), KBTS_LANGUAGE_BAGRI = KBTS_FOURCC('B', 'G', 'Q', ' '), KBTS_LANGUAGE_BALANTE = KBTS_FOURCC('B', 'L', 'N', ' '), KBTS_LANGUAGE_BALINESE = KBTS_FOURCC('B', 'A', 'N', ' '), KBTS_LANGUAGE_BALKAR = KBTS_FOURCC('B', 'A', 'L', ' '), KBTS_LANGUAGE_BALTI = KBTS_FOURCC('B', 'L', 'T', ' '), KBTS_LANGUAGE_BALUCHI = KBTS_FOURCC('B', 'L', 'I', ' '), KBTS_LANGUAGE_BAMBARA = KBTS_FOURCC('B', 'M', 'B', ' '), KBTS_LANGUAGE_BAMILEKE = KBTS_FOURCC('B', 'M', 'L', ' '), KBTS_LANGUAGE_BANDA = KBTS_FOURCC('B', 'A', 'D', '0'), KBTS_LANGUAGE_BANDJALANG = KBTS_FOURCC('B', 'D', 'Y', ' '), KBTS_LANGUAGE_BANGLA = KBTS_FOURCC('B', 'E', 'N', ' '), KBTS_LANGUAGE_BASHKIR = KBTS_FOURCC('B', 'S', 'H', ' '), KBTS_LANGUAGE_BASQUE = KBTS_FOURCC('E', 'U', 'Q', ' '), KBTS_LANGUAGE_BATAK = KBTS_FOURCC('B', 'T', 'K', ' '), KBTS_LANGUAGE_BATAK_ALAS_KLUET = KBTS_FOURCC('B', 'T', 'Z', ' '), KBTS_LANGUAGE_BATAK_ANGKOLA = KBTS_FOURCC('A', 'K', 'B', ' '), KBTS_LANGUAGE_BATAK_DAIRI = KBTS_FOURCC('B', 'T', 'D', ' '), KBTS_LANGUAGE_BATAK_KARO = KBTS_FOURCC('B', 'T', 'X', ' '), KBTS_LANGUAGE_BATAK_MANDAILING = KBTS_FOURCC('B', 'T', 'M', ' '), KBTS_LANGUAGE_BATAK_SIMALUNGUN = KBTS_FOURCC('B', 'T', 'S', ' '), KBTS_LANGUAGE_BATAK_TOBA = KBTS_FOURCC('B', 'B', 'C', ' '), KBTS_LANGUAGE_BAULE = KBTS_FOURCC('B', 'A', 'U', ' '), KBTS_LANGUAGE_BAVARIAN = KBTS_FOURCC('B', 'A', 'R', ' '), KBTS_LANGUAGE_BELARUSIAN = KBTS_FOURCC('B', 'E', 'L', ' '), KBTS_LANGUAGE_BEMBA = KBTS_FOURCC('B', 'E', 'M', ' '), KBTS_LANGUAGE_BENCH = KBTS_FOURCC('B', 'C', 'H', ' '), KBTS_LANGUAGE_BERBER = KBTS_FOURCC('B', 'B', 'R', ' '), KBTS_LANGUAGE_BETI = KBTS_FOURCC('B', 'T', 'I', ' '), KBTS_LANGUAGE_BETTE_KURUMA = KBTS_FOURCC('X', 'U', 'B', ' '), KBTS_LANGUAGE_BHILI = KBTS_FOURCC('B', 'H', 'I', ' '), KBTS_LANGUAGE_BHOJPURI = KBTS_FOURCC('B', 'H', 'O', ' '), KBTS_LANGUAGE_BHUTANESE = KBTS_FOURCC('D', 'Z', 'N', ' '), KBTS_LANGUAGE_BIBLE_CREE = KBTS_FOURCC('B', 'C', 'R', ' '), KBTS_LANGUAGE_BIKOL = KBTS_FOURCC('B', 'I', 'K', ' '), KBTS_LANGUAGE_BILEN = KBTS_FOURCC('B', 'I', 'L', ' '), KBTS_LANGUAGE_BISHNUPRIYA_MANIPURI = KBTS_FOURCC('B', 'P', 'Y', ' '), KBTS_LANGUAGE_BISLAMA = KBTS_FOURCC('B', 'I', 'S', ' '), KBTS_LANGUAGE_BLACKFOOT = KBTS_FOURCC('B', 'K', 'F', ' '), KBTS_LANGUAGE_BODO = KBTS_FOURCC('B', 'R', 'X', ' '), KBTS_LANGUAGE_BOSNIAN = KBTS_FOURCC('B', 'O', 'S', ' '), KBTS_LANGUAGE_BOUYEI = KBTS_FOURCC('P', 'C', 'C', ' '), KBTS_LANGUAGE_BRAHUI = KBTS_FOURCC('B', 'R', 'H', ' '), KBTS_LANGUAGE_BRAJ_BHASHA = KBTS_FOURCC('B', 'R', 'I', ' '), KBTS_LANGUAGE_BRETON = KBTS_FOURCC('B', 'R', 'E', ' '), KBTS_LANGUAGE_BUGIS = KBTS_FOURCC('B', 'U', 'G', ' '), KBTS_LANGUAGE_BULGARIAN = KBTS_FOURCC('B', 'G', 'R', ' '), KBTS_LANGUAGE_BUMTHANGKHA = KBTS_FOURCC('K', 'J', 'Z', ' '), KBTS_LANGUAGE_BURMESE = KBTS_FOURCC('B', 'R', 'M', ' '), KBTS_LANGUAGE_BURUSHASKI = KBTS_FOURCC('B', 'S', 'K', ' '), KBTS_LANGUAGE_CAJUN_FRENCH = KBTS_FOURCC('F', 'R', 'C', ' '), KBTS_LANGUAGE_CARRIER = KBTS_FOURCC('C', 'R', 'R', ' '), KBTS_LANGUAGE_CATALAN = KBTS_FOURCC('C', 'A', 'T', ' '), KBTS_LANGUAGE_CAYUGA = KBTS_FOURCC('C', 'A', 'Y', ' '), KBTS_LANGUAGE_CEBUANO = KBTS_FOURCC('C', 'E', 'B', ' '), KBTS_LANGUAGE_CENTRAL_YUPIK = KBTS_FOURCC('E', 'S', 'U', ' '), KBTS_LANGUAGE_CHAHA_GURAGE = KBTS_FOURCC('C', 'H', 'G', ' '), KBTS_LANGUAGE_CHAMORRO = KBTS_FOURCC('C', 'H', 'A', ' '), KBTS_LANGUAGE_CHATTISGARHI = KBTS_FOURCC('C', 'H', 'H', ' '), KBTS_LANGUAGE_CHECHEN = KBTS_FOURCC('C', 'H', 'E', ' '), KBTS_LANGUAGE_CHEROKEE = KBTS_FOURCC('C', 'H', 'R', ' '), KBTS_LANGUAGE_CHEYENNE = KBTS_FOURCC('C', 'H', 'Y', ' '), KBTS_LANGUAGE_CHICHEWA = KBTS_FOURCC('C', 'H', 'I', ' '), KBTS_LANGUAGE_CHIGA = KBTS_FOURCC('C', 'G', 'G', ' '), KBTS_LANGUAGE_CHIMILA = KBTS_FOURCC('C', 'B', 'G', ' '), KBTS_LANGUAGE_CHIN = KBTS_FOURCC('Q', 'I', 'N', ' '), KBTS_LANGUAGE_CHINANTEC = KBTS_FOURCC('C', 'C', 'H', 'N'), KBTS_LANGUAGE_CHINESE_PHONETIC = KBTS_FOURCC('Z', 'H', 'P', ' '), KBTS_LANGUAGE_CHINESE_SIMPLIFIED = KBTS_FOURCC('Z', 'H', 'S', ' '), KBTS_LANGUAGE_CHINESE_TRADITIONAL = KBTS_FOURCC('Z', 'H', 'T', ' '), KBTS_LANGUAGE_CHINESE_TRADITIONAL_HONG_KONG = KBTS_FOURCC('Z', 'H', 'H', ' '), KBTS_LANGUAGE_CHINESE_TRADITIONAL_MACAO = KBTS_FOURCC('Z', 'H', 'T', 'M'), KBTS_LANGUAGE_CHIPEWYAN = KBTS_FOURCC('C', 'H', 'P', ' '), KBTS_LANGUAGE_CHITTAGONIAN = KBTS_FOURCC('C', 'T', 'G', ' '), KBTS_LANGUAGE_CHOCTAW = KBTS_FOURCC('C', 'H', 'O', ' '), KBTS_LANGUAGE_CHUKCHI = KBTS_FOURCC('C', 'H', 'K', ' '), KBTS_LANGUAGE_CHURCH_SLAVONIC = KBTS_FOURCC('C', 'S', 'L', ' '), KBTS_LANGUAGE_CHUUKESE = KBTS_FOURCC('C', 'H', 'K', '0'), KBTS_LANGUAGE_CHUVASH = KBTS_FOURCC('C', 'H', 'U', ' '), KBTS_LANGUAGE_COMORIAN = KBTS_FOURCC('C', 'M', 'R', ' '), KBTS_LANGUAGE_COMOX = KBTS_FOURCC('C', 'O', 'O', ' '), KBTS_LANGUAGE_COPTIC = KBTS_FOURCC('C', 'O', 'P', ' '), KBTS_LANGUAGE_CORNISH = KBTS_FOURCC('C', 'O', 'R', ' '), KBTS_LANGUAGE_CORSICAN = KBTS_FOURCC('C', 'O', 'S', ' '), KBTS_LANGUAGE_CREE = KBTS_FOURCC('C', 'R', 'E', ' '), KBTS_LANGUAGE_CREOLES = KBTS_FOURCC('C', 'P', 'P', ' '), KBTS_LANGUAGE_CRIMEAN_TATAR = KBTS_FOURCC('C', 'R', 'T', ' '), KBTS_LANGUAGE_CRIOULO = KBTS_FOURCC('K', 'E', 'A', ' '), KBTS_LANGUAGE_CROATIAN = KBTS_FOURCC('H', 'R', 'V', ' '), KBTS_LANGUAGE_CYPRIOT_ARABIC = KBTS_FOURCC('A', 'C', 'Y', ' '), KBTS_LANGUAGE_CZECH = KBTS_FOURCC('C', 'S', 'Y', ' '), KBTS_LANGUAGE_DAGBANI = KBTS_FOURCC('D', 'A', 'G', ' '), KBTS_LANGUAGE_DAN = KBTS_FOURCC('D', 'N', 'J', ' '), KBTS_LANGUAGE_DANGME = KBTS_FOURCC('D', 'N', 'G', ' '), KBTS_LANGUAGE_DANISH = KBTS_FOURCC('D', 'A', 'N', ' '), KBTS_LANGUAGE_DARGWA = KBTS_FOURCC('D', 'A', 'R', ' '), KBTS_LANGUAGE_DARI = KBTS_FOURCC('D', 'R', 'I', ' '), KBTS_LANGUAGE_DAYI = KBTS_FOURCC('D', 'A', 'X', ' '), KBTS_LANGUAGE_DEFAULT = KBTS_FOURCC('d', 'f', 'l', 't'), // Can be DFLT too... KBTS_LANGUAGE_DEHONG_DAI = KBTS_FOURCC('T', 'D', 'D', ' '), KBTS_LANGUAGE_DHANGU = KBTS_FOURCC('D', 'H', 'G', ' '), KBTS_LANGUAGE_DHIVEHI = KBTS_FOURCC('D', 'I', 'V', ' '), KBTS_LANGUAGE_DHUWAL = KBTS_FOURCC('D', 'U', 'J', ' '), KBTS_LANGUAGE_DIMLI = KBTS_FOURCC('D', 'I', 'Q', ' '), KBTS_LANGUAGE_DINKA = KBTS_FOURCC('D', 'N', 'K', ' '), KBTS_LANGUAGE_DIVEHI = KBTS_FOURCC('D', 'I', 'V', ' '), KBTS_LANGUAGE_DJAMBARRPUYNGU = KBTS_FOURCC('D', 'J', 'R', '0'), KBTS_LANGUAGE_DOGRI = KBTS_FOURCC('D', 'G', 'O', ' '), KBTS_LANGUAGE_DOGRI_MACROLANGUAGE = KBTS_FOURCC('D', 'G', 'R', ' '), KBTS_LANGUAGE_DUNGAN = KBTS_FOURCC('D', 'U', 'N', ' '), KBTS_LANGUAGE_DUTCH = KBTS_FOURCC('N', 'L', 'D', ' '), KBTS_LANGUAGE_DZONGKHA = KBTS_FOURCC('D', 'Z', 'N', ' '), KBTS_LANGUAGE_EASTERN_ABENAKI = KBTS_FOURCC('A', 'A', 'Q', ' '), KBTS_LANGUAGE_EASTERN_CHAM = KBTS_FOURCC('C', 'J', 'M', ' '), KBTS_LANGUAGE_EASTERN_CREE = KBTS_FOURCC('E', 'C', 'R', ' '), KBTS_LANGUAGE_EASTERN_MANINKAKAN = KBTS_FOURCC('E', 'M', 'K', ' '), KBTS_LANGUAGE_EASTERN_PWO_KAREN = KBTS_FOURCC('K', 'J', 'P', ' '), KBTS_LANGUAGE_EBIRA = KBTS_FOURCC('E', 'B', 'I', ' '), KBTS_LANGUAGE_EDO = KBTS_FOURCC('E', 'D', 'O', ' '), KBTS_LANGUAGE_EFIK = KBTS_FOURCC('E', 'F', 'I', ' '), KBTS_LANGUAGE_EMBERA_BAUDO = KBTS_FOURCC('B', 'D', 'C', ' '), KBTS_LANGUAGE_EMBERA_CATIO = KBTS_FOURCC('C', 'T', 'O', ' '), KBTS_LANGUAGE_EMBERA_CHAMI = KBTS_FOURCC('C', 'M', 'I', ' '), KBTS_LANGUAGE_EMBERA_TADO = KBTS_FOURCC('T', 'D', 'C', ' '), KBTS_LANGUAGE_ENGLISH = KBTS_FOURCC('E', 'N', 'G', ' '), KBTS_LANGUAGE_EPENA = KBTS_FOURCC('S', 'J', 'A', ' '), KBTS_LANGUAGE_ERZYA = KBTS_FOURCC('E', 'R', 'Z', ' '), KBTS_LANGUAGE_KB_TEXT_SHAPEANTO = KBTS_FOURCC('N', 'T', 'O', ' '), KBTS_LANGUAGE_ESTONIAN = KBTS_FOURCC('E', 'T', 'I', ' '), KBTS_LANGUAGE_EVEN = KBTS_FOURCC('E', 'V', 'N', ' '), KBTS_LANGUAGE_EVENKI = KBTS_FOURCC('E', 'V', 'K', ' '), KBTS_LANGUAGE_EWE = KBTS_FOURCC('E', 'W', 'E', ' '), KBTS_LANGUAGE_FALAM_CHIN = KBTS_FOURCC('H', 'A', 'L', ' '), KBTS_LANGUAGE_FANG = KBTS_FOURCC('F', 'A', 'N', '0'), KBTS_LANGUAGE_FANTI = KBTS_FOURCC('F', 'A', 'T', ' '), KBTS_LANGUAGE_FAROESE = KBTS_FOURCC('F', 'O', 'S', ' '), KBTS_LANGUAGE_FEFE = KBTS_FOURCC('F', 'M', 'P', ' '), KBTS_LANGUAGE_FIJIAN = KBTS_FOURCC('F', 'J', 'I', ' '), KBTS_LANGUAGE_FILIPINO = KBTS_FOURCC('P', 'I', 'L', ' '), KBTS_LANGUAGE_FINNISH = KBTS_FOURCC('F', 'I', 'N', ' '), KBTS_LANGUAGE_FLEMISH = KBTS_FOURCC('F', 'L', 'E', ' '), KBTS_LANGUAGE_FON = KBTS_FOURCC('F', 'O', 'N', ' '), KBTS_LANGUAGE_FOREST_ENETS = KBTS_FOURCC('F', 'N', 'E', ' '), KBTS_LANGUAGE_FRENCH = KBTS_FOURCC('F', 'R', 'A', ' '), KBTS_LANGUAGE_FRENCH_ANTILLEAN = KBTS_FOURCC('F', 'A', 'N', ' '), KBTS_LANGUAGE_FRISIAN = KBTS_FOURCC('F', 'R', 'I', ' '), KBTS_LANGUAGE_FRIULIAN = KBTS_FOURCC('F', 'R', 'L', ' '), KBTS_LANGUAGE_FULAH = KBTS_FOURCC('F', 'U', 'L', ' '), KBTS_LANGUAGE_FUTA = KBTS_FOURCC('F', 'T', 'A', ' '), KBTS_LANGUAGE_GA = KBTS_FOURCC('G', 'A', 'D', ' '), KBTS_LANGUAGE_GAGAUZ = KBTS_FOURCC('G', 'A', 'G', ' '), KBTS_LANGUAGE_GALICIAN = KBTS_FOURCC('G', 'A', 'L', ' '), KBTS_LANGUAGE_GANDA = KBTS_FOURCC('L', 'U', 'G', ' '), KBTS_LANGUAGE_GARHWALI = KBTS_FOURCC('G', 'A', 'W', ' '), KBTS_LANGUAGE_GARO = KBTS_FOURCC('G', 'R', 'O', ' '), KBTS_LANGUAGE_GARSHUNI = KBTS_FOURCC('G', 'A', 'R', ' '), KBTS_LANGUAGE_GEBA_KAREN = KBTS_FOURCC('K', 'V', 'Q', ' '), KBTS_LANGUAGE_GEEZ = KBTS_FOURCC('G', 'E', 'Z', ' '), KBTS_LANGUAGE_GEORGIAN = KBTS_FOURCC('K', 'A', 'T', ' '), KBTS_LANGUAGE_GEPO = KBTS_FOURCC('Y', 'G', 'P', ' '), KBTS_LANGUAGE_GERMAN = KBTS_FOURCC('D', 'E', 'U', ' '), KBTS_LANGUAGE_GIKUYU = KBTS_FOURCC('K', 'I', 'K', ' '), KBTS_LANGUAGE_GILAKI = KBTS_FOURCC('G', 'L', 'K', ' '), KBTS_LANGUAGE_GILBERTESE = KBTS_FOURCC('G', 'I', 'L', '0'), KBTS_LANGUAGE_GILYAK = KBTS_FOURCC('G', 'I', 'L', ' '), KBTS_LANGUAGE_GITHABUL = KBTS_FOURCC('G', 'I', 'H', ' '), KBTS_LANGUAGE_GOGO = KBTS_FOURCC('G', 'O', 'G', ' '), KBTS_LANGUAGE_GONDI = KBTS_FOURCC('G', 'O', 'N', ' '), KBTS_LANGUAGE_GREEK = KBTS_FOURCC('E', 'L', 'L', ' '), KBTS_LANGUAGE_GREENLANDIC = KBTS_FOURCC('G', 'R', 'N', ' '), KBTS_LANGUAGE_GUARANI = KBTS_FOURCC('G', 'U', 'A', ' '), KBTS_LANGUAGE_GUINEA = KBTS_FOURCC('G', 'K', 'P', ' '), KBTS_LANGUAGE_GUJARATI = KBTS_FOURCC('G', 'U', 'J', ' '), KBTS_LANGUAGE_GUMATJ = KBTS_FOURCC('G', 'N', 'N', ' '), KBTS_LANGUAGE_GUMUZ = KBTS_FOURCC('G', 'M', 'Z', ' '), KBTS_LANGUAGE_GUPAPUYNGU = KBTS_FOURCC('G', 'U', 'F', ' '), KBTS_LANGUAGE_GUSII = KBTS_FOURCC('G', 'U', 'Z', ' '), KBTS_LANGUAGE_HAIDA = KBTS_FOURCC('H', 'A', 'I', '0'), KBTS_LANGUAGE_HAITIAN_CREOLE = KBTS_FOURCC('H', 'A', 'I', ' '), KBTS_LANGUAGE_HALKOMELEM = KBTS_FOURCC('H', 'U', 'R', ' '), KBTS_LANGUAGE_HAMMER_BANNA = KBTS_FOURCC('H', 'B', 'N', ' '), KBTS_LANGUAGE_HARARI = KBTS_FOURCC('H', 'R', 'I', ' '), KBTS_LANGUAGE_HARAUTI = KBTS_FOURCC('H', 'A', 'R', ' '), KBTS_LANGUAGE_HARYANVI = KBTS_FOURCC('B', 'G', 'C', ' '), KBTS_LANGUAGE_HAUSA = KBTS_FOURCC('H', 'A', 'U', ' '), KBTS_LANGUAGE_HAVASUPAI_WALAPAI_YAVAPAI = KBTS_FOURCC('Y', 'U', 'F', ' '), KBTS_LANGUAGE_HAWAIIAN = KBTS_FOURCC('H', 'A', 'W', ' '), KBTS_LANGUAGE_HAYA = KBTS_FOURCC('H', 'A', 'Y', ' '), KBTS_LANGUAGE_HAZARAGI = KBTS_FOURCC('H', 'A', 'Z', ' '), KBTS_LANGUAGE_HEBREW = KBTS_FOURCC('I', 'W', 'R', ' '), KBTS_LANGUAGE_HEILTSUK = KBTS_FOURCC('H', 'E', 'I', ' '), KBTS_LANGUAGE_HERERO = KBTS_FOURCC('H', 'E', 'R', ' '), KBTS_LANGUAGE_HIGH_MARI = KBTS_FOURCC('H', 'M', 'A', ' '), KBTS_LANGUAGE_HILIGAYNON = KBTS_FOURCC('H', 'I', 'L', ' '), KBTS_LANGUAGE_HINDI = KBTS_FOURCC('H', 'I', 'N', ' '), KBTS_LANGUAGE_HINDKO = KBTS_FOURCC('H', 'N', 'D', ' '), KBTS_LANGUAGE_HIRI_MOTU = KBTS_FOURCC('H', 'M', 'O', ' '), KBTS_LANGUAGE_HMONG = KBTS_FOURCC('H', 'M', 'N', ' '), KBTS_LANGUAGE_HMONG_DAW = KBTS_FOURCC('M', 'W', 'W', ' '), KBTS_LANGUAGE_HMONG_SHUAT = KBTS_FOURCC('H', 'M', 'Z', ' '), KBTS_LANGUAGE_HO = KBTS_FOURCC('H', 'O', ' ', ' '), KBTS_LANGUAGE_HUNGARIAN = KBTS_FOURCC('H', 'U', 'N', ' '), KBTS_LANGUAGE_IBAN = KBTS_FOURCC('I', 'B', 'A', ' '), KBTS_LANGUAGE_IBIBIO = KBTS_FOURCC('I', 'B', 'B', ' '), KBTS_LANGUAGE_ICELANDIC = KBTS_FOURCC('I', 'S', 'L', ' '), KBTS_LANGUAGE_IDO = KBTS_FOURCC('I', 'D', 'O', ' '), KBTS_LANGUAGE_IGBO = KBTS_FOURCC('I', 'B', 'O', ' '), KBTS_LANGUAGE_IJO = KBTS_FOURCC('I', 'J', 'O', ' '), KBTS_LANGUAGE_ILOKANO = KBTS_FOURCC('I', 'L', 'O', ' '), KBTS_LANGUAGE_INARI_SAMI = KBTS_FOURCC('I', 'S', 'M', ' '), KBTS_LANGUAGE_INDONESIAN = KBTS_FOURCC('I', 'N', 'D', ' '), KBTS_LANGUAGE_INGUSH = KBTS_FOURCC('I', 'N', 'G', ' '), KBTS_LANGUAGE_INTERLINGUA = KBTS_FOURCC('I', 'N', 'A', ' '), KBTS_LANGUAGE_INTERLINGUE = KBTS_FOURCC('I', 'L', 'E', ' '), KBTS_LANGUAGE_INUKTITUT = KBTS_FOURCC('I', 'N', 'U', ' '), KBTS_LANGUAGE_INUPIAT = KBTS_FOURCC('I', 'P', 'K', ' '), KBTS_LANGUAGE_IPA_PHONETIC = KBTS_FOURCC('I', 'P', 'P', ' '), KBTS_LANGUAGE_IRISH = KBTS_FOURCC('I', 'R', 'I', ' '), KBTS_LANGUAGE_IRISH_TRADITIONAL = KBTS_FOURCC('I', 'R', 'T', ' '), KBTS_LANGUAGE_IRULA = KBTS_FOURCC('I', 'R', 'U', ' '), KBTS_LANGUAGE_ITALIAN = KBTS_FOURCC('I', 'T', 'A', ' '), KBTS_LANGUAGE_JAMAICAN_CREOLE = KBTS_FOURCC('J', 'A', 'M', ' '), KBTS_LANGUAGE_JAPANESE = KBTS_FOURCC('J', 'A', 'N', ' '), KBTS_LANGUAGE_JAVANESE = KBTS_FOURCC('J', 'A', 'V', ' '), KBTS_LANGUAGE_JENNU_KURUMA = KBTS_FOURCC('X', 'U', 'J', ' '), KBTS_LANGUAGE_JUDEO_TAT = KBTS_FOURCC('J', 'D', 'T', ' '), KBTS_LANGUAGE_JULA = KBTS_FOURCC('J', 'U', 'L', ' '), KBTS_LANGUAGE_KABARDIAN = KBTS_FOURCC('K', 'A', 'B', ' '), KBTS_LANGUAGE_KABYLE = KBTS_FOURCC('K', 'A', 'B', '0'), KBTS_LANGUAGE_KACHCHI = KBTS_FOURCC('K', 'A', 'C', ' '), KBTS_LANGUAGE_KADIWEU = KBTS_FOURCC('K', 'B', 'C', ' '), KBTS_LANGUAGE_KALENJIN = KBTS_FOURCC('K', 'A', 'L', ' '), KBTS_LANGUAGE_KALMYK = KBTS_FOURCC('K', 'L', 'M', ' '), KBTS_LANGUAGE_KAMBA = KBTS_FOURCC('K', 'M', 'B', ' '), KBTS_LANGUAGE_KANAUJI = KBTS_FOURCC('B', 'J', 'J', ' '), KBTS_LANGUAGE_KANNADA = KBTS_FOURCC('K', 'A', 'N', ' '), KBTS_LANGUAGE_KANURI = KBTS_FOURCC('K', 'N', 'R', ' '), KBTS_LANGUAGE_KAQCHIKEL = KBTS_FOURCC('C', 'A', 'K', ' '), KBTS_LANGUAGE_KARACHAY = KBTS_FOURCC('K', 'A', 'R', ' '), KBTS_LANGUAGE_KARAIM = KBTS_FOURCC('K', 'R', 'M', ' '), KBTS_LANGUAGE_KARAKALPAK = KBTS_FOURCC('K', 'R', 'K', ' '), KBTS_LANGUAGE_KARELIAN = KBTS_FOURCC('K', 'R', 'L', ' '), KBTS_LANGUAGE_KAREN = KBTS_FOURCC('K', 'R', 'N', ' '), KBTS_LANGUAGE_KASHMIRI = KBTS_FOURCC('K', 'S', 'H', ' '), KBTS_LANGUAGE_KASHUBIAN = KBTS_FOURCC('C', 'S', 'B', ' '), KBTS_LANGUAGE_KATE = KBTS_FOURCC('K', 'M', 'G', ' '), KBTS_LANGUAGE_KAZAKH = KBTS_FOURCC('K', 'A', 'Z', ' '), KBTS_LANGUAGE_KEBENA = KBTS_FOURCC('K', 'E', 'B', ' '), KBTS_LANGUAGE_KEKCHI = KBTS_FOURCC('K', 'E', 'K', ' '), KBTS_LANGUAGE_KHAKASS = KBTS_FOURCC('K', 'H', 'A', ' '), KBTS_LANGUAGE_KHAMTI_SHAN = KBTS_FOURCC('K', 'H', 'T', ' '), KBTS_LANGUAGE_KHAMYANG = KBTS_FOURCC('K', 'S', 'U', ' '), KBTS_LANGUAGE_KHANTY_KAZIM = KBTS_FOURCC('K', 'H', 'K', ' '), KBTS_LANGUAGE_KHANTY_SHURISHKAR = KBTS_FOURCC('K', 'H', 'S', ' '), KBTS_LANGUAGE_KHANTY_VAKHI = KBTS_FOURCC('K', 'H', 'V', ' '), KBTS_LANGUAGE_KHASI = KBTS_FOURCC('K', 'S', 'I', ' '), KBTS_LANGUAGE_KHENGKHA = KBTS_FOURCC('X', 'K', 'F', ' '), KBTS_LANGUAGE_KHINALUG = KBTS_FOURCC('K', 'J', 'J', ' '), KBTS_LANGUAGE_KHMER = KBTS_FOURCC('K', 'H', 'M', ' '), KBTS_LANGUAGE_KHORASANI_TURKIC = KBTS_FOURCC('K', 'M', 'Z', ' '), KBTS_LANGUAGE_KHOWAR = KBTS_FOURCC('K', 'H', 'W', ' '), KBTS_LANGUAGE_KHUTSURI_GEORGIAN = KBTS_FOURCC('K', 'G', 'E', ' '), KBTS_LANGUAGE_KICHE = KBTS_FOURCC('Q', 'U', 'C', ' '), KBTS_LANGUAGE_KIKONGO = KBTS_FOURCC('K', 'O', 'N', ' '), KBTS_LANGUAGE_KILDIN_SAMI = KBTS_FOURCC('K', 'S', 'M', ' '), KBTS_LANGUAGE_KINYARWANDA = KBTS_FOURCC('R', 'U', 'A', ' '), KBTS_LANGUAGE_KIRMANJKI = KBTS_FOURCC('K', 'I', 'U', ' '), KBTS_LANGUAGE_KISII = KBTS_FOURCC('K', 'I', 'S', ' '), KBTS_LANGUAGE_KITUBA = KBTS_FOURCC('M', 'K', 'W', ' '), KBTS_LANGUAGE_KODAGU = KBTS_FOURCC('K', 'O', 'D', ' '), KBTS_LANGUAGE_KOKNI = KBTS_FOURCC('K', 'K', 'N', ' '), KBTS_LANGUAGE_KOMI = KBTS_FOURCC('K', 'O', 'M', ' '), KBTS_LANGUAGE_KOMI_PERMYAK = KBTS_FOURCC('K', 'O', 'P', ' '), KBTS_LANGUAGE_KOMI_ZYRIAN = KBTS_FOURCC('K', 'O', 'Z', ' '), KBTS_LANGUAGE_KOMO = KBTS_FOURCC('K', 'M', 'O', ' '), KBTS_LANGUAGE_KOMSO = KBTS_FOURCC('K', 'M', 'S', ' '), KBTS_LANGUAGE_KONGO = KBTS_FOURCC('K', 'O', 'N', '0'), KBTS_LANGUAGE_KONKANI = KBTS_FOURCC('K', 'O', 'K', ' '), KBTS_LANGUAGE_KOORETE = KBTS_FOURCC('K', 'R', 'T', ' '), KBTS_LANGUAGE_KOREAN = KBTS_FOURCC('K', 'O', 'R', ' '), KBTS_LANGUAGE_KOREAO_OLD_HANGUL = KBTS_FOURCC('K', 'O', 'H', ' '), KBTS_LANGUAGE_KORYAK = KBTS_FOURCC('K', 'Y', 'K', ' '), KBTS_LANGUAGE_KOSRAEAN = KBTS_FOURCC('K', 'O', 'S', ' '), KBTS_LANGUAGE_KPELLE = KBTS_FOURCC('K', 'P', 'L', ' '), KBTS_LANGUAGE_KPELLE_LIBERIA = KBTS_FOURCC('X', 'P', 'E', ' '), KBTS_LANGUAGE_KRIO = KBTS_FOURCC('K', 'R', 'I', ' '), KBTS_LANGUAGE_KRYMCHAK = KBTS_FOURCC('J', 'C', 'T', ' '), KBTS_LANGUAGE_KUANYAMA = KBTS_FOURCC('K', 'U', 'A', ' '), KBTS_LANGUAGE_KUBE = KBTS_FOURCC('K', 'G', 'F', ' '), KBTS_LANGUAGE_KUI = KBTS_FOURCC('K', 'U', 'I', ' '), KBTS_LANGUAGE_KULVI = KBTS_FOURCC('K', 'U', 'K', ' '), KBTS_LANGUAGE_KUMAONI = KBTS_FOURCC('K', 'M', 'N', ' '), KBTS_LANGUAGE_KUMYK = KBTS_FOURCC('K', 'U', 'M', ' '), KBTS_LANGUAGE_KURDISH = KBTS_FOURCC('K', 'U', 'R', ' '), KBTS_LANGUAGE_KURUKH = KBTS_FOURCC('K', 'U', 'U', ' '), KBTS_LANGUAGE_KUY = KBTS_FOURCC('K', 'U', 'Y', ' '), KBTS_LANGUAGE_KWAKWALA = KBTS_FOURCC('K', 'W', 'K', ' '), KBTS_LANGUAGE_KYRGYZ = KBTS_FOURCC('K', 'I', 'R', ' '), KBTS_LANGUAGE_L_CREE = KBTS_FOURCC('L', 'C', 'R', ' '), KBTS_LANGUAGE_LADAKHI = KBTS_FOURCC('L', 'D', 'K', ' '), KBTS_LANGUAGE_LADIN = KBTS_FOURCC('L', 'A', 'D', ' '), KBTS_LANGUAGE_LADINO = KBTS_FOURCC('J', 'U', 'D', ' '), KBTS_LANGUAGE_LAHULI = KBTS_FOURCC('L', 'A', 'H', ' '), KBTS_LANGUAGE_LAK = KBTS_FOURCC('L', 'A', 'K', ' '), KBTS_LANGUAGE_LAKI = KBTS_FOURCC('L', 'K', 'I', ' '), KBTS_LANGUAGE_LAMBANI = KBTS_FOURCC('L', 'A', 'M', ' '), KBTS_LANGUAGE_LAMPUNG = KBTS_FOURCC('L', 'J', 'P', ' '), KBTS_LANGUAGE_LAO = KBTS_FOURCC('L', 'A', 'O', ' '), KBTS_LANGUAGE_LATIN = KBTS_FOURCC('L', 'A', 'T', ' '), KBTS_LANGUAGE_LATVIAN = KBTS_FOURCC('L', 'V', 'I', ' '), KBTS_LANGUAGE_LAZ = KBTS_FOURCC('L', 'A', 'Z', ' '), KBTS_LANGUAGE_LELEMI = KBTS_FOURCC('L', 'E', 'F', ' '), KBTS_LANGUAGE_LEZGI = KBTS_FOURCC('L', 'E', 'Z', ' '), KBTS_LANGUAGE_LIGURIAN = KBTS_FOURCC('L', 'I', 'J', ' '), KBTS_LANGUAGE_LIMBU = KBTS_FOURCC('L', 'M', 'B', ' '), KBTS_LANGUAGE_LIMBURGISH = KBTS_FOURCC('L', 'I', 'M', ' '), KBTS_LANGUAGE_LINGALA = KBTS_FOURCC('L', 'I', 'N', ' '), KBTS_LANGUAGE_LIPO = KBTS_FOURCC('L', 'P', 'O', ' '), KBTS_LANGUAGE_LISU = KBTS_FOURCC('L', 'I', 'S', ' '), KBTS_LANGUAGE_LITHUANIAN = KBTS_FOURCC('L', 'T', 'H', ' '), KBTS_LANGUAGE_LIV = KBTS_FOURCC('L', 'I', 'V', ' '), KBTS_LANGUAGE_LOJBAN = KBTS_FOURCC('J', 'B', 'O', ' '), KBTS_LANGUAGE_LOMA = KBTS_FOURCC('L', 'O', 'M', ' '), KBTS_LANGUAGE_LOMBARD = KBTS_FOURCC('L', 'M', 'O', ' '), KBTS_LANGUAGE_LOMWE = KBTS_FOURCC('L', 'M', 'W', ' '), KBTS_LANGUAGE_LOW_MARI = KBTS_FOURCC('L', 'M', 'A', ' '), KBTS_LANGUAGE_LOW_SAXON = KBTS_FOURCC('N', 'D', 'S', ' '), KBTS_LANGUAGE_LOWER_SORBIAN = KBTS_FOURCC('L', 'S', 'B', ' '), KBTS_LANGUAGE_LU = KBTS_FOURCC('X', 'B', 'D', ' '), KBTS_LANGUAGE_LUBA_KATANGA = KBTS_FOURCC('L', 'U', 'B', ' '), KBTS_LANGUAGE_LUBA_LULUA = KBTS_FOURCC('L', 'U', 'A', ' '), KBTS_LANGUAGE_LULE_SAMI = KBTS_FOURCC('L', 'S', 'M', ' '), KBTS_LANGUAGE_LUO = KBTS_FOURCC('L', 'U', 'O', ' '), KBTS_LANGUAGE_LURI = KBTS_FOURCC('L', 'R', 'C', ' '), KBTS_LANGUAGE_LUSHOOTSEED = KBTS_FOURCC('L', 'U', 'T', ' '), KBTS_LANGUAGE_LUXEMBOURGISH = KBTS_FOURCC('L', 'T', 'Z', ' '), KBTS_LANGUAGE_LUYIA = KBTS_FOURCC('L', 'U', 'H', ' '), KBTS_LANGUAGE_MACEDONIAN = KBTS_FOURCC('M', 'K', 'D', ' '), KBTS_LANGUAGE_MADURA = KBTS_FOURCC('M', 'A', 'D', ' '), KBTS_LANGUAGE_MAGAHI = KBTS_FOURCC('M', 'A', 'G', ' '), KBTS_LANGUAGE_MAITHILI = KBTS_FOURCC('M', 'T', 'H', ' '), KBTS_LANGUAGE_MAJANG = KBTS_FOURCC('M', 'A', 'J', ' '), KBTS_LANGUAGE_MAKASAR = KBTS_FOURCC('M', 'K', 'R', ' '), KBTS_LANGUAGE_MAKHUWA = KBTS_FOURCC('M', 'A', 'K', ' '), KBTS_LANGUAGE_MAKONDE = KBTS_FOURCC('K', 'D', 'E', ' '), KBTS_LANGUAGE_MALAGASY = KBTS_FOURCC('M', 'L', 'G', ' '), KBTS_LANGUAGE_MALAY = KBTS_FOURCC('M', 'L', 'Y', ' '), KBTS_LANGUAGE_MALAYALAM = KBTS_FOURCC('M', 'A', 'L', ' '), KBTS_LANGUAGE_MALAYALAM_REFORMED = KBTS_FOURCC('M', 'L', 'R', ' '), KBTS_LANGUAGE_MALE = KBTS_FOURCC('M', 'L', 'E', ' '), KBTS_LANGUAGE_MALINKE = KBTS_FOURCC('M', 'L', 'N', ' '), KBTS_LANGUAGE_MALTESE = KBTS_FOURCC('M', 'T', 'S', ' '), KBTS_LANGUAGE_MAM = KBTS_FOURCC('M', 'A', 'M', ' '), KBTS_LANGUAGE_MANCHU = KBTS_FOURCC('M', 'C', 'H', ' '), KBTS_LANGUAGE_MANDAR = KBTS_FOURCC('M', 'D', 'R', ' '), KBTS_LANGUAGE_MANDINKA = KBTS_FOURCC('M', 'N', 'D', ' '), KBTS_LANGUAGE_MANINKA = KBTS_FOURCC('M', 'N', 'K', ' '), KBTS_LANGUAGE_MANIPURI = KBTS_FOURCC('M', 'N', 'I', ' '), KBTS_LANGUAGE_MANO = KBTS_FOURCC('M', 'E', 'V', ' '), KBTS_LANGUAGE_MANSI = KBTS_FOURCC('M', 'A', 'N', ' '), KBTS_LANGUAGE_MANX = KBTS_FOURCC('M', 'N', 'X', ' '), KBTS_LANGUAGE_MAORI = KBTS_FOURCC('M', 'R', 'I', ' '), KBTS_LANGUAGE_MAPUDUNGUN = KBTS_FOURCC('M', 'A', 'P', ' '), KBTS_LANGUAGE_MARATHI = KBTS_FOURCC('M', 'A', 'R', ' '), KBTS_LANGUAGE_MARSHALLESE = KBTS_FOURCC('M', 'A', 'H', ' '), KBTS_LANGUAGE_MARWARI = KBTS_FOURCC('M', 'A', 'W', ' '), KBTS_LANGUAGE_MAYAN = KBTS_FOURCC('M', 'Y', 'N', ' '), KBTS_LANGUAGE_MAZANDERANI = KBTS_FOURCC('M', 'Z', 'N', ' '), KBTS_LANGUAGE_MBEMBE_TIGON = KBTS_FOURCC('N', 'Z', 'A', ' '), KBTS_LANGUAGE_MBO = KBTS_FOURCC('M', 'B', 'O', ' '), KBTS_LANGUAGE_MBUNDU = KBTS_FOURCC('M', 'B', 'N', ' '), KBTS_LANGUAGE_MEDUMBA = KBTS_FOURCC('B', 'Y', 'V', ' '), KBTS_LANGUAGE_MEEN = KBTS_FOURCC('M', 'E', 'N', ' '), KBTS_LANGUAGE_MENDE = KBTS_FOURCC('M', 'D', 'E', ' '), KBTS_LANGUAGE_MERU = KBTS_FOURCC('M', 'E', 'R', ' '), KBTS_LANGUAGE_MEWATI = KBTS_FOURCC('W', 'T', 'M', ' '), KBTS_LANGUAGE_MINANGKABAU = KBTS_FOURCC('M', 'I', 'N', ' '), KBTS_LANGUAGE_MINJANGBAL = KBTS_FOURCC('X', 'J', 'B', ' '), KBTS_LANGUAGE_MIRANDESE = KBTS_FOURCC('M', 'W', 'L', ' '), KBTS_LANGUAGE_MIZO = KBTS_FOURCC('M', 'I', 'Z', ' '), KBTS_LANGUAGE_MOHAWK = KBTS_FOURCC('M', 'O', 'H', ' '), KBTS_LANGUAGE_MOKSHA = KBTS_FOURCC('M', 'O', 'K', ' '), KBTS_LANGUAGE_MOLDAVIAN = KBTS_FOURCC('M', 'O', 'L', ' '), KBTS_LANGUAGE_MON = KBTS_FOURCC('M', 'O', 'N', ' '), KBTS_LANGUAGE_MONGOLIAN = KBTS_FOURCC('M', 'N', 'G', ' '), KBTS_LANGUAGE_MOOSE_CREE = KBTS_FOURCC('M', 'C', 'R', ' '), KBTS_LANGUAGE_MORISYEN = KBTS_FOURCC('M', 'F', 'E', ' '), KBTS_LANGUAGE_MOROCCAN = KBTS_FOURCC('M', 'O', 'R', ' '), KBTS_LANGUAGE_MOSSI = KBTS_FOURCC('M', 'P', 'S', ' '), KBTS_LANGUAGE_MUNDARI = KBTS_FOURCC('M', 'U', 'N', ' '), KBTS_LANGUAGE_MUSCOGEE = KBTS_FOURCC('M', 'U', 'S', ' '), KBTS_LANGUAGE_N_CREE = KBTS_FOURCC('N', 'C', 'R', ' '), KBTS_LANGUAGE_NAGA_ASSAMESE = KBTS_FOURCC('N', 'A', 'G', ' '), KBTS_LANGUAGE_NAGARI = KBTS_FOURCC('N', 'G', 'R', ' '), KBTS_LANGUAGE_NAHUATL = KBTS_FOURCC('N', 'A', 'H', ' '), KBTS_LANGUAGE_NANAI = KBTS_FOURCC('N', 'A', 'N', ' '), KBTS_LANGUAGE_NASKAPI = KBTS_FOURCC('N', 'A', 'S', ' '), KBTS_LANGUAGE_NAURUAN = KBTS_FOURCC('N', 'A', 'U', ' '), KBTS_LANGUAGE_NAVAJO = KBTS_FOURCC('N', 'A', 'V', ' '), KBTS_LANGUAGE_NDAU = KBTS_FOURCC('N', 'D', 'C', ' '), KBTS_LANGUAGE_NDEBELE = KBTS_FOURCC('N', 'D', 'B', ' '), KBTS_LANGUAGE_NDONGA = KBTS_FOURCC('N', 'D', 'G', ' '), KBTS_LANGUAGE_NEAPOLITAN = KBTS_FOURCC('N', 'A', 'P', ' '), KBTS_LANGUAGE_NEPALI = KBTS_FOURCC('N', 'E', 'P', ' '), KBTS_LANGUAGE_NEWARI = KBTS_FOURCC('N', 'E', 'W', ' '), KBTS_LANGUAGE_NGBAKA = KBTS_FOURCC('N', 'G', 'A', ' '), KBTS_LANGUAGE_NIGERIAN_FULFULDE = KBTS_FOURCC('F', 'U', 'V', ' '), KBTS_LANGUAGE_NIMADI = KBTS_FOURCC('N', 'O', 'E', ' '), KBTS_LANGUAGE_NISI = KBTS_FOURCC('N', 'I', 'S', ' '), KBTS_LANGUAGE_NIUEAN = KBTS_FOURCC('N', 'I', 'U', ' '), KBTS_LANGUAGE_NKO = KBTS_FOURCC('N', 'K', 'O', ' '), KBTS_LANGUAGE_NOGAI = KBTS_FOURCC('N', 'O', 'G', ' '), KBTS_LANGUAGE_NORFOLK = KBTS_FOURCC('P', 'I', 'H', ' '), KBTS_LANGUAGE_NORTH_SLAVEY = KBTS_FOURCC('S', 'C', 'S', ' '), KBTS_LANGUAGE_NORTHERN_EMBERA = KBTS_FOURCC('E', 'M', 'P', ' '), KBTS_LANGUAGE_NORTHERN_SAMI = KBTS_FOURCC('N', 'S', 'M', ' '), KBTS_LANGUAGE_NORTHERN_SOTHO = KBTS_FOURCC('N', 'S', 'O', ' '), KBTS_LANGUAGE_NORTHERN_TAI = KBTS_FOURCC('N', 'T', 'A', ' '), KBTS_LANGUAGE_NORWAY_HOUSE_CREE = KBTS_FOURCC('N', 'H', 'C', ' '), KBTS_LANGUAGE_NORWEGIAN = KBTS_FOURCC('N', 'O', 'R', ' '), KBTS_LANGUAGE_NORWEGIAN_NYNORSK = KBTS_FOURCC('N', 'Y', 'N', ' '), KBTS_LANGUAGE_NOVIAL = KBTS_FOURCC('N', 'O', 'V', ' '), KBTS_LANGUAGE_NUMANGGANG = KBTS_FOURCC('N', 'O', 'P', ' '), KBTS_LANGUAGE_NUNAVIK_INUKTITUT = KBTS_FOURCC('I', 'N', 'U', ' '), KBTS_LANGUAGE_NUU_CHAH_NULTH = KBTS_FOURCC('N', 'U', 'K', ' '), KBTS_LANGUAGE_NYAMWEZI = KBTS_FOURCC('N', 'Y', 'M', ' '), KBTS_LANGUAGE_NYANKOLE = KBTS_FOURCC('N', 'K', 'L', ' '), KBTS_LANGUAGE_OCCITAN = KBTS_FOURCC('O', 'C', 'I', ' '), KBTS_LANGUAGE_ODIA = KBTS_FOURCC('O', 'R', 'I', ' '), KBTS_LANGUAGE_OJI_CREE = KBTS_FOURCC('O', 'C', 'R', ' '), KBTS_LANGUAGE_OJIBWAY = KBTS_FOURCC('O', 'J', 'B', ' '), KBTS_LANGUAGE_OLD_IRISH = KBTS_FOURCC('S', 'G', 'A', ' '), KBTS_LANGUAGE_OLD_JAVANESE = KBTS_FOURCC('K', 'A', 'W', ' '), KBTS_LANGUAGE_ONEIDA = KBTS_FOURCC('O', 'N', 'E', ' '), KBTS_LANGUAGE_ONONDAGA = KBTS_FOURCC('O', 'N', 'O', ' '), KBTS_LANGUAGE_OROMO = KBTS_FOURCC('O', 'R', 'O', ' '), KBTS_LANGUAGE_OSSETIAN = KBTS_FOURCC('O', 'S', 'S', ' '), KBTS_LANGUAGE_PA_O_KAREN = KBTS_FOURCC('B', 'L', 'K', ' '), KBTS_LANGUAGE_PALAUAN = KBTS_FOURCC('P', 'A', 'U', ' '), KBTS_LANGUAGE_PALAUNG = KBTS_FOURCC('P', 'L', 'G', ' '), KBTS_LANGUAGE_PALESTINIAN_ARAMAIC = KBTS_FOURCC('P', 'A', 'A', ' '), KBTS_LANGUAGE_PALI = KBTS_FOURCC('P', 'A', 'L', ' '), KBTS_LANGUAGE_PALPA = KBTS_FOURCC('P', 'A', 'P', ' '), KBTS_LANGUAGE_PAMPANGAN = KBTS_FOURCC('P', 'A', 'M', ' '), KBTS_LANGUAGE_PANGASINAN = KBTS_FOURCC('P', 'A', 'G', ' '), KBTS_LANGUAGE_PAPIAMENTU = KBTS_FOURCC('P', 'A', 'P', '0'), KBTS_LANGUAGE_PASHTO = KBTS_FOURCC('P', 'A', 'S', ' '), KBTS_LANGUAGE_PATTANI_MALAY = KBTS_FOURCC('M', 'F', 'A', ' '), KBTS_LANGUAGE_PENNSYLVANIA_GERMAN = KBTS_FOURCC('P', 'D', 'C', ' '), KBTS_LANGUAGE_PERSIAN = KBTS_FOURCC('F', 'A', 'R', ' '), KBTS_LANGUAGE_PHAKE = KBTS_FOURCC('P', 'J', 'K', ' '), KBTS_LANGUAGE_PICARD = KBTS_FOURCC('P', 'C', 'D', ' '), KBTS_LANGUAGE_PIEMONTESE = KBTS_FOURCC('P', 'M', 'S', ' '), KBTS_LANGUAGE_PILAGA = KBTS_FOURCC('P', 'L', 'G', ' '), KBTS_LANGUAGE_PITE_SAMI = KBTS_FOURCC('S', 'J', 'E', ' '), KBTS_LANGUAGE_POCOMCHI = KBTS_FOURCC('P', 'O', 'H', ' '), KBTS_LANGUAGE_POHNPEIAN = KBTS_FOURCC('P', 'O', 'N', ' '), KBTS_LANGUAGE_POLISH = KBTS_FOURCC('P', 'L', 'K', ' '), KBTS_LANGUAGE_POLYTONIC_GREEK = KBTS_FOURCC('P', 'G', 'R', ' '), KBTS_LANGUAGE_PORTUGUESE = KBTS_FOURCC('P', 'T', 'G', ' '), KBTS_LANGUAGE_PROVENCAL = KBTS_FOURCC('P', 'R', 'O', ' '), KBTS_LANGUAGE_PUNJABI = KBTS_FOURCC('P', 'A', 'N', ' '), KBTS_LANGUAGE_QUECHUA = KBTS_FOURCC('Q', 'U', 'Z', ' '), KBTS_LANGUAGE_QUECHUA_BOLIVIA = KBTS_FOURCC('Q', 'U', 'H', ' '), KBTS_LANGUAGE_QUECHUA_ECUADOR = KBTS_FOURCC('Q', 'V', 'I', ' '), KBTS_LANGUAGE_QUECHUA_PERU = KBTS_FOURCC('Q', 'W', 'H', ' '), KBTS_LANGUAGE_R_CREE = KBTS_FOURCC('R', 'C', 'R', ' '), KBTS_LANGUAGE_RAJASTHANI = KBTS_FOURCC('R', 'A', 'J', ' '), KBTS_LANGUAGE_RAKHINE = KBTS_FOURCC('A', 'R', 'K', ' '), KBTS_LANGUAGE_RAROTONGAN = KBTS_FOURCC('R', 'A', 'R', ' '), KBTS_LANGUAGE_REJANG = KBTS_FOURCC('R', 'E', 'J', ' '), KBTS_LANGUAGE_RIANG = KBTS_FOURCC('R', 'I', 'A', ' '), KBTS_LANGUAGE_RIPUARIAN = KBTS_FOURCC('K', 'S', 'H', ' '), KBTS_LANGUAGE_RITARUNGO = KBTS_FOURCC('R', 'I', 'T', ' '), KBTS_LANGUAGE_ROHINGYA = KBTS_FOURCC('R', 'H', 'G', ' '), KBTS_LANGUAGE_ROMANIAN = KBTS_FOURCC('R', 'O', 'M', ' '), KBTS_LANGUAGE_ROMANSH = KBTS_FOURCC('R', 'M', 'S', ' '), KBTS_LANGUAGE_ROMANY = KBTS_FOURCC('R', 'O', 'Y', ' '), KBTS_LANGUAGE_ROTUMAN = KBTS_FOURCC('R', 'T', 'M', ' '), KBTS_LANGUAGE_RUNDI = KBTS_FOURCC('R', 'U', 'N', ' '), KBTS_LANGUAGE_RUSSIAN = KBTS_FOURCC('R', 'U', 'S', ' '), KBTS_LANGUAGE_RUSSIAN_BURIAT = KBTS_FOURCC('R', 'B', 'U', ' '), KBTS_LANGUAGE_RUSYN = KBTS_FOURCC('R', 'S', 'Y', ' '), KBTS_LANGUAGE_SADRI = KBTS_FOURCC('S', 'A', 'D', ' '), KBTS_LANGUAGE_SAKHA = KBTS_FOURCC('Y', 'A', 'K', ' '), KBTS_LANGUAGE_SAMOAN = KBTS_FOURCC('S', 'M', 'O', ' '), KBTS_LANGUAGE_SAMOGITIAN = KBTS_FOURCC('S', 'G', 'S', ' '), KBTS_LANGUAGE_SAN_BLAS_KUNA = KBTS_FOURCC('C', 'U', 'K', ' '), KBTS_LANGUAGE_SANGO = KBTS_FOURCC('S', 'G', 'O', ' '), KBTS_LANGUAGE_SANSKRIT = KBTS_FOURCC('S', 'A', 'N', ' '), KBTS_LANGUAGE_SANTALI = KBTS_FOURCC('S', 'A', 'T', ' '), KBTS_LANGUAGE_SARAIKI = KBTS_FOURCC('S', 'R', 'K', ' '), KBTS_LANGUAGE_SARDINIAN = KBTS_FOURCC('S', 'R', 'D', ' '), KBTS_LANGUAGE_SASAK = KBTS_FOURCC('S', 'A', 'S', ' '), KBTS_LANGUAGE_SATERLAND_FRISIAN = KBTS_FOURCC('S', 'T', 'Q', ' '), KBTS_LANGUAGE_SAYISI = KBTS_FOURCC('S', 'A', 'Y', ' '), KBTS_LANGUAGE_SCOTS = KBTS_FOURCC('S', 'C', 'I', ' '), KBTS_LANGUAGE_SCOTTISH_GAELIC = KBTS_FOURCC('G', 'A', 'E', ' '), KBTS_LANGUAGE_SEKOTA = KBTS_FOURCC('S', 'E', 'J', ' '), KBTS_LANGUAGE_SELKUP = KBTS_FOURCC('S', 'E', 'L', ' '), KBTS_LANGUAGE_SENA = KBTS_FOURCC('S', 'N', 'A', ' '), KBTS_LANGUAGE_SENECA = KBTS_FOURCC('S', 'E', 'E', ' '), KBTS_LANGUAGE_SERBIAN = KBTS_FOURCC('S', 'R', 'B', ' '), KBTS_LANGUAGE_SERER = KBTS_FOURCC('S', 'R', 'R', ' '), KBTS_LANGUAGE_SGAW_KAREN = KBTS_FOURCC('K', 'S', 'W', ' '), KBTS_LANGUAGE_SHAN = KBTS_FOURCC('S', 'H', 'N', ' '), KBTS_LANGUAGE_SHONA = KBTS_FOURCC('S', 'N', 'A', ' '), KBTS_LANGUAGE_SIBE = KBTS_FOURCC('S', 'I', 'B', ' '), KBTS_LANGUAGE_SICILIAN = KBTS_FOURCC('S', 'C', 'N', ' '), KBTS_LANGUAGE_SIDAMO = KBTS_FOURCC('S', 'I', 'D', ' '), KBTS_LANGUAGE_SILESIAN = KBTS_FOURCC('S', 'Z', 'L', ' '), KBTS_LANGUAGE_SILTE_GURAGE = KBTS_FOURCC('S', 'I', 'G', ' '), KBTS_LANGUAGE_SINDHI = KBTS_FOURCC('S', 'N', 'D', ' '), KBTS_LANGUAGE_SINHALA = KBTS_FOURCC('S', 'N', 'H', ' '), KBTS_LANGUAGE_SKOLT_SAMI = KBTS_FOURCC('S', 'K', 'S', ' '), KBTS_LANGUAGE_SLAVEY = KBTS_FOURCC('S', 'L', 'A', ' '), KBTS_LANGUAGE_SLOVAK = KBTS_FOURCC('S', 'K', 'Y', ' '), KBTS_LANGUAGE_SLOVENIAN = KBTS_FOURCC('S', 'L', 'V', ' '), KBTS_LANGUAGE_SMALL_FLOWERY_MIAO = KBTS_FOURCC('S', 'F', 'M', ' '), KBTS_LANGUAGE_SODO_GURAGE = KBTS_FOURCC('S', 'O', 'G', ' '), KBTS_LANGUAGE_SOGA = KBTS_FOURCC('X', 'O', 'G', ' '), KBTS_LANGUAGE_SOMALI = KBTS_FOURCC('S', 'M', 'L', ' '), KBTS_LANGUAGE_SONGE = KBTS_FOURCC('S', 'O', 'P', ' '), KBTS_LANGUAGE_SONINKE = KBTS_FOURCC('S', 'N', 'K', ' '), KBTS_LANGUAGE_SOUTH_SLAVEY = KBTS_FOURCC('S', 'S', 'L', ' '), KBTS_LANGUAGE_SOUTHERN_KIWAI = KBTS_FOURCC('K', 'J', 'D', ' '), KBTS_LANGUAGE_SOUTHERN_SAMI = KBTS_FOURCC('S', 'S', 'M', ' '), KBTS_LANGUAGE_SOUTHERN_SOTHO = KBTS_FOURCC('S', 'O', 'T', ' '), KBTS_LANGUAGE_SPANISH = KBTS_FOURCC('E', 'S', 'P', ' '), KBTS_LANGUAGE_STANDARD_MOROCCAN_TAMAZIGHT = KBTS_FOURCC('Z', 'G', 'H', ' '), KBTS_LANGUAGE_STRAITS_SALISH = KBTS_FOURCC('S', 'T', 'R', ' '), KBTS_LANGUAGE_SUKUMA = KBTS_FOURCC('S', 'U', 'K', ' '), KBTS_LANGUAGE_SUNDANESE = KBTS_FOURCC('S', 'U', 'N', ' '), KBTS_LANGUAGE_SURI = KBTS_FOURCC('S', 'U', 'R', ' '), KBTS_LANGUAGE_SUTU = KBTS_FOURCC('S', 'X', 'T', ' '), KBTS_LANGUAGE_SVAN = KBTS_FOURCC('S', 'V', 'A', ' '), KBTS_LANGUAGE_SWADAYA_ARAMAIC = KBTS_FOURCC('S', 'W', 'A', ' '), KBTS_LANGUAGE_SWAHILI = KBTS_FOURCC('S', 'W', 'K', ' '), KBTS_LANGUAGE_SWATI = KBTS_FOURCC('S', 'W', 'Z', ' '), KBTS_LANGUAGE_SWEDISH = KBTS_FOURCC('S', 'V', 'E', ' '), KBTS_LANGUAGE_SYLHETI = KBTS_FOURCC('S', 'Y', 'L', ' '), KBTS_LANGUAGE_SYRIAC = KBTS_FOURCC('S', 'Y', 'R', ' '), KBTS_LANGUAGE_SYRIAC_EASTERN = KBTS_FOURCC('S', 'Y', 'R', 'N'), KBTS_LANGUAGE_SYRIAC_ESTRANGELA = KBTS_FOURCC('S', 'Y', 'R', 'E'), KBTS_LANGUAGE_SYRIAC_WESTERN = KBTS_FOURCC('S', 'Y', 'R', 'J'), KBTS_LANGUAGE_TABASARAN = KBTS_FOURCC('T', 'A', 'B', ' '), KBTS_LANGUAGE_TACHELHIT = KBTS_FOURCC('S', 'H', 'I', ' '), KBTS_LANGUAGE_TAGALOG = KBTS_FOURCC('T', 'G', 'L', ' '), KBTS_LANGUAGE_TAHAGGART_TAMAHAQ = KBTS_FOURCC('T', 'H', 'V', ' '), KBTS_LANGUAGE_TAHITIAN = KBTS_FOURCC('T', 'H', 'T', ' '), KBTS_LANGUAGE_TAI_LAING = KBTS_FOURCC('T', 'J', 'L', ' '), KBTS_LANGUAGE_TAJIKI = KBTS_FOURCC('T', 'A', 'J', ' '), KBTS_LANGUAGE_TALYSH = KBTS_FOURCC('T', 'L', 'Y', ' '), KBTS_LANGUAGE_TAMASHEK = KBTS_FOURCC('T', 'M', 'H', ' '), KBTS_LANGUAGE_TAMASHEQ = KBTS_FOURCC('T', 'A', 'Q', ' '), KBTS_LANGUAGE_TAMAZIGHT = KBTS_FOURCC('T', 'Z', 'M', ' '), KBTS_LANGUAGE_TAMIL = KBTS_FOURCC('T', 'A', 'M', ' '), KBTS_LANGUAGE_TARIFIT = KBTS_FOURCC('R', 'I', 'F', ' '), KBTS_LANGUAGE_TATAR = KBTS_FOURCC('T', 'A', 'T', ' '), KBTS_LANGUAGE_TAWALLAMMAT_TAMAJAQ = KBTS_FOURCC('T', 'T', 'Q', ' '), KBTS_LANGUAGE_TAY = KBTS_FOURCC('T', 'Y', 'Z', ' '), KBTS_LANGUAGE_TAYART_TAMAJEQ = KBTS_FOURCC('T', 'H', 'Z', ' '), KBTS_LANGUAGE_TELUGU = KBTS_FOURCC('T', 'E', 'L', ' '), KBTS_LANGUAGE_TEMNE = KBTS_FOURCC('T', 'M', 'N', ' '), KBTS_LANGUAGE_TETUM = KBTS_FOURCC('T', 'E', 'T', ' '), KBTS_LANGUAGE_TH_CREE = KBTS_FOURCC('T', 'C', 'R', ' '), KBTS_LANGUAGE_THAI = KBTS_FOURCC('T', 'H', 'A', ' '), KBTS_LANGUAGE_THAILAND_MON = KBTS_FOURCC('M', 'O', 'N', 'T'), KBTS_LANGUAGE_THOMPSON = KBTS_FOURCC('T', 'H', 'P', ' '), KBTS_LANGUAGE_TIBETAN = KBTS_FOURCC('T', 'I', 'B', ' '), KBTS_LANGUAGE_TIGRE = KBTS_FOURCC('T', 'G', 'R', ' '), KBTS_LANGUAGE_TIGRINYA = KBTS_FOURCC('T', 'G', 'Y', ' '), KBTS_LANGUAGE_TIV = KBTS_FOURCC('T', 'I', 'V', ' '), KBTS_LANGUAGE_TLINGIT = KBTS_FOURCC('T', 'L', 'I', ' '), KBTS_LANGUAGE_TOBO = KBTS_FOURCC('T', 'B', 'V', ' '), KBTS_LANGUAGE_TODO = KBTS_FOURCC('T', 'O', 'D', ' '), KBTS_LANGUAGE_TOK_PISIN = KBTS_FOURCC('T', 'P', 'I', ' '), KBTS_LANGUAGE_TOMA = KBTS_FOURCC('T', 'O', 'D', '0'), KBTS_LANGUAGE_TONGA = KBTS_FOURCC('T', 'N', 'G', ' '), KBTS_LANGUAGE_TONGAN = KBTS_FOURCC('T', 'G', 'N', ' '), KBTS_LANGUAGE_TORKI = KBTS_FOURCC('A', 'Z', 'B', ' '), KBTS_LANGUAGE_TSHANGLA = KBTS_FOURCC('T', 'S', 'J', ' '), KBTS_LANGUAGE_TSONGA = KBTS_FOURCC('T', 'S', 'G', ' '), KBTS_LANGUAGE_TSWANA = KBTS_FOURCC('T', 'N', 'A', ' '), KBTS_LANGUAGE_TULU = KBTS_FOURCC('T', 'U', 'L', ' '), KBTS_LANGUAGE_TUMBUKA = KBTS_FOURCC('T', 'U', 'M', ' '), KBTS_LANGUAGE_TUNDRA_ENETS = KBTS_FOURCC('T', 'N', 'E', ' '), KBTS_LANGUAGE_TURKISH = KBTS_FOURCC('T', 'R', 'K', ' '), KBTS_LANGUAGE_TURKMEN = KBTS_FOURCC('T', 'K', 'M', ' '), KBTS_LANGUAGE_TUROYO_ARAMAIC = KBTS_FOURCC('T', 'U', 'A', ' '), KBTS_LANGUAGE_TUSCARORA = KBTS_FOURCC('T', 'U', 'S', ' '), KBTS_LANGUAGE_TUVALU = KBTS_FOURCC('T', 'V', 'L', ' '), KBTS_LANGUAGE_TUVIN = KBTS_FOURCC('T', 'U', 'V', ' '), KBTS_LANGUAGE_TWI = KBTS_FOURCC('T', 'W', 'I', ' '), KBTS_LANGUAGE_TZOTZIL = KBTS_FOURCC('T', 'Z', 'O', ' '), KBTS_LANGUAGE_UDI = KBTS_FOURCC('U', 'D', 'I', ' '), KBTS_LANGUAGE_UDMURT = KBTS_FOURCC('U', 'D', 'M', ' '), KBTS_LANGUAGE_UKRAINIAN = KBTS_FOURCC('U', 'K', 'R', ' '), KBTS_LANGUAGE_UMBUNDU = KBTS_FOURCC('U', 'M', 'B', ' '), KBTS_LANGUAGE_UME_SAMI = KBTS_FOURCC('S', 'J', 'U', ' '), KBTS_LANGUAGE_UPPER_SAXON = KBTS_FOURCC('S', 'X', 'U', ' '), KBTS_LANGUAGE_UPPER_SORBIAN = KBTS_FOURCC('U', 'S', 'B', ' '), KBTS_LANGUAGE_URALIC_PHONETIC = KBTS_FOURCC('U', 'P', 'P', ' '), KBTS_LANGUAGE_URDU = KBTS_FOURCC('U', 'R', 'D', ' '), KBTS_LANGUAGE_UYGHUR = KBTS_FOURCC('U', 'Y', 'G', ' '), KBTS_LANGUAGE_UZBEK = KBTS_FOURCC('U', 'Z', 'B', ' '), KBTS_LANGUAGE_VENDA = KBTS_FOURCC('V', 'E', 'N', ' '), KBTS_LANGUAGE_VENETIAN = KBTS_FOURCC('V', 'E', 'C', ' '), KBTS_LANGUAGE_VIETNAMESE = KBTS_FOURCC('V', 'I', 'T', ' '), KBTS_LANGUAGE_VLAX_ROMANI = KBTS_FOURCC('R', 'M', 'Y', ' '), KBTS_LANGUAGE_VOLAPUK = KBTS_FOURCC('V', 'O', 'L', ' '), KBTS_LANGUAGE_VORO = KBTS_FOURCC('V', 'R', 'O', ' '), KBTS_LANGUAGE_WA = KBTS_FOURCC('W', 'A', ' ', ' '), KBTS_LANGUAGE_WACI_GBE = KBTS_FOURCC('W', 'C', 'I', ' '), KBTS_LANGUAGE_WAGDI = KBTS_FOURCC('W', 'A', 'G', ' '), KBTS_LANGUAGE_WAKHI = KBTS_FOURCC('W', 'B', 'L', ' '), KBTS_LANGUAGE_WALLOON = KBTS_FOURCC('W', 'L', 'N', ' '), KBTS_LANGUAGE_WARAY_WARAY = KBTS_FOURCC('W', 'A', 'R', ' '), KBTS_LANGUAGE_WAYANAD_CHETTI = KBTS_FOURCC('C', 'T', 'T', ' '), KBTS_LANGUAGE_WAYUU = KBTS_FOURCC('G', 'U', 'C', ' '), KBTS_LANGUAGE_WELSH = KBTS_FOURCC('W', 'E', 'L', ' '), KBTS_LANGUAGE_WENDAT = KBTS_FOURCC('W', 'D', 'T', ' '), KBTS_LANGUAGE_WEST_CREE = KBTS_FOURCC('W', 'C', 'R', ' '), KBTS_LANGUAGE_WESTERN_CHAM = KBTS_FOURCC('C', 'J', 'A', ' '), KBTS_LANGUAGE_WESTERN_KAYAH = KBTS_FOURCC('K', 'Y', 'U', ' '), KBTS_LANGUAGE_WESTERN_PANJABI = KBTS_FOURCC('P', 'N', 'B', ' '), KBTS_LANGUAGE_WESTERN_PWO_KAREN = KBTS_FOURCC('P', 'W', 'O', ' '), KBTS_LANGUAGE_WOLOF = KBTS_FOURCC('W', 'L', 'F', ' '), KBTS_LANGUAGE_WOODS_CREE = KBTS_FOURCC('D', 'C', 'R', ' '), KBTS_LANGUAGE_WUDING_LUQUAN_YI = KBTS_FOURCC('Y', 'W', 'Q', ' '), KBTS_LANGUAGE_WYANDOT = KBTS_FOURCC('W', 'Y', 'N', ' '), KBTS_LANGUAGE_XHOSA = KBTS_FOURCC('X', 'H', 'S', ' '), KBTS_LANGUAGE_Y_CREE = KBTS_FOURCC('Y', 'C', 'R', ' '), KBTS_LANGUAGE_YAO = KBTS_FOURCC('Y', 'A', 'O', ' '), KBTS_LANGUAGE_YAPESE = KBTS_FOURCC('Y', 'A', 'P', ' '), KBTS_LANGUAGE_YI_CLASSIC = KBTS_FOURCC('Y', 'I', 'C', ' '), KBTS_LANGUAGE_YI_MODERN = KBTS_FOURCC('Y', 'I', 'M', ' '), KBTS_LANGUAGE_YIDDISH = KBTS_FOURCC('J', 'I', 'I', ' '), KBTS_LANGUAGE_YORUBA = KBTS_FOURCC('Y', 'B', 'A', ' '), KBTS_LANGUAGE_ZAMBOANGA_CHAVACANO = KBTS_FOURCC('C', 'B', 'K', ' '), KBTS_LANGUAGE_ZANDE = KBTS_FOURCC('Z', 'N', 'D', ' '), KBTS_LANGUAGE_ZARMA = KBTS_FOURCC('D', 'J', 'R', ' '), KBTS_LANGUAGE_ZAZAKI = KBTS_FOURCC('Z', 'Z', 'A', ' '), KBTS_LANGUAGE_ZEALANDIC = KBTS_FOURCC('Z', 'E', 'A', ' '), KBTS_LANGUAGE_ZHUANG = KBTS_FOURCC('Z', 'H', 'A', ' '), KBTS_LANGUAGE_ZULU = KBTS_FOURCC('Z', 'U', 'L', ' '), }; typedef kbts_u32 kbts_break_flags; enum kbts_break_flags_enum { // Direction changes from left-to-right to right-to-left, or vice versa. KBTS_BREAK_FLAG_DIRECTION = 1 << 0, // Script changes. // Note that some characters, such as digits, are used in multiple // scripts and, as such, will not produce script breaks. KBTS_BREAK_FLAG_SCRIPT = 1 << 1, // Graphemes are "visual units". They may be composed of more than one codepoint. // They are used as interaction boundaries in graphical interfaces, e.g. moving the // caret. KBTS_BREAK_FLAG_GRAPHEME = 1 << 2, // In most scripts, words are broken up by whitespace, but Unicode word breaking has // better script coverage and also handles some special cases that a simple stateless // loop cannot handle. KBTS_BREAK_FLAG_WORD = 1 << 3, // By default, you are not allowed to break a line. // Soft line breaks allow for line breaking, but do not require it. // This is useful for when you are doing line wrapping. KBTS_BREAK_FLAG_LINE_SOFT = 1 << 4, // Hard line breaks are required. They signal the end of a paragraph. // (In Unicode, there is no meaningful distinction between a line and a paragraph. // a paragraph is pretty much just a line of text that can wrap.) KBTS_BREAK_FLAG_LINE_HARD = 1 << 5, KBTS_BREAK_FLAG_LINE = KBTS_BREAK_FLAG_LINE_SOFT | KBTS_BREAK_FLAG_LINE_HARD, KBTS_BREAK_FLAG_ANY = KBTS_BREAK_FLAG_DIRECTION | KBTS_BREAK_FLAG_SCRIPT | KBTS_BREAK_FLAG_GRAPHEME | KBTS_BREAK_FLAG_WORD | KBTS_BREAK_FLAG_LINE_SOFT | KBTS_BREAK_FLAG_LINE_HARD, }; typedef kbts_u8 kbts_op_kind; enum kbts_op_kind_enum { KBTS_OP_KIND_END, // Substitution ops. KBTS_OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES, KBTS_OP_KIND_NORMALIZE, KBTS_OP_KIND_NORMALIZE_HANGUL, KBTS_OP_KIND_FLAG_JOINING_LETTERS, KBTS_OP_KIND_GSUB_FEATURES, KBTS_OP_KIND_GSUB_FEATURES_WITH_USER, // Positioning ops. KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, KBTS_OP_KIND_POST_GPOS_FIXUP, KBTS_OP_KIND_STCH_POSTPASS, KBTS_OP_KIND_COUNT, }; typedef kbts_u32 kbts_glyph_flags; enum kbts_glyph_flags_enum { // These feature flags must coincide with kbts_joining_feature _and_ KBTS_FEATURE_FLAG! KBTS_GLYPH_FLAG_ISOL = (1 << 0), KBTS_GLYPH_FLAG_FINA = (1 << 1), KBTS_GLYPH_FLAG_FIN2 = (1 << 2), KBTS_GLYPH_FLAG_FIN3 = (1 << 3), KBTS_GLYPH_FLAG_MEDI = (1 << 4), KBTS_GLYPH_FLAG_MED2 = (1 << 5), KBTS_GLYPH_FLAG_INIT = (1 << 6), // These feature flags must coincide with FEATURE_FLAG! KBTS_GLYPH_FLAG_LJMO = (1 << 7), KBTS_GLYPH_FLAG_VJMO = (1 << 8), KBTS_GLYPH_FLAG_TJMO = (1 << 9), KBTS_GLYPH_FLAG_RPHF = (1 << 10), KBTS_GLYPH_FLAG_BLWF = (1 << 11), KBTS_GLYPH_FLAG_HALF = (1 << 12), KBTS_GLYPH_FLAG_PSTF = (1 << 13), KBTS_GLYPH_FLAG_ABVF = (1 << 14), KBTS_GLYPH_FLAG_PREF = (1 << 15), KBTS_GLYPH_FLAG_NUMR = (1 << 16), KBTS_GLYPH_FLAG_FRAC = (1 << 17), KBTS_GLYPH_FLAG_DNOM = (1 << 18), KBTS_GLYPH_FLAG_CFAR = (1 << 19), // These can be anything. KBTS_GLYPH_FLAG_DO_NOT_DECOMPOSE = (1 << 21), KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION = (1 << 22), KBTS_GLYPH_FLAG_NO_BREAK = (1 << 23), KBTS_GLYPH_FLAG_CURSIVE = (1 << 24), KBTS_GLYPH_FLAG_GENERATED_BY_GSUB = (1 << 25), KBTS_GLYPH_FLAG_USED_IN_GPOS = (1 << 26), KBTS_GLYPH_FLAG_STCH_ENDPOINT = (1 << 27), KBTS_GLYPH_FLAG_STCH_EXTENSION = (1 << 28), KBTS_GLYPH_FLAG_LIGATURE = (1 << 29), KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION = (1 << 30), }; #define KBTS_GLYPH_FEATURE_MASK ((KBTS_GLYPH_FLAG_CFAR << 1) - 1) // In USE, glyphs are mostly not pre-flagged for feature application. // However, we do want to flag rphf/pref results for reordering, so we want to // keep all of the flags as usual, and only use these feature flags for filtering. #define KBTS_USE_GLYPH_FEATURE_MASK (KBTS_GLYPH_FLAG_ISOL | KBTS_GLYPH_FLAG_FINA | KBTS_GLYPH_FLAG_FIN2 | KBTS_GLYPH_FLAG_FIN3 | \ KBTS_GLYPH_FLAG_MEDI | KBTS_GLYPH_FLAG_MED2 | KBTS_GLYPH_FLAG_INIT | KBTS_GLYPH_FLAG_NUMR | \ KBTS_GLYPH_FLAG_DNOM | KBTS_GLYPH_FLAG_FRAC) #define KBTS_JOINING_FEATURE_MASK (KBTS_GLYPH_FLAG_ISOL | KBTS_GLYPH_FLAG_FINA | KBTS_GLYPH_FLAG_FIN2 | KBTS_GLYPH_FLAG_FIN3 | \ KBTS_GLYPH_FLAG_MEDI | KBTS_GLYPH_FLAG_MED2 | KBTS_GLYPH_FLAG_INIT) #define KBTS_JOINING_FEATURE_TO_GLYPH_FLAG(Feature) (1 << ((Feature) - 1)) // Japanese text contains "kinsoku" characters, around which breaking a line is forbidden. // Exactly which characters are "kinsoku" or not depends on the context: // - Strict style has the largest amount of kinsoku characters, which leads to longer lines. // - Loose style has the smallest amount of kinsoku characters, which leads to smaller lines. // - Normal style is somewhere in the middle. // Note that, while the Unicode standard mentions all three of these styles, it does not mention // any differences between the normal and loose styles. // As such, normal and loose styles currently behave the same. typedef kbts_u8 kbts_japanese_line_break_style; enum kbts_japanese_line_break_style_enum { // The Unicode standard does not define what strict style is used for. // Supposedly, it is used for anything that does not fall into the other two categories of text. KBTS_JAPANESE_LINE_BREAK_STYLE_STRICT, // Normal style is used for books and documents. KBTS_JAPANESE_LINE_BREAK_STYLE_NORMAL, // Loose style is used for newspapers, and (I assume) any other narrow column format. KBTS_JAPANESE_LINE_BREAK_STYLE_LOOSE, KBTS_JAPANESE_LINE_BREAK_STYLE_COUNT, }; typedef kbts_u32 kbts_orientation; enum kbts_orientation_enum { KBTS_ORIENTATION_HORIZONTAL, KBTS_ORIENTATION_VERTICAL, KBTS_ORIENTATION_COUNT, }; typedef kbts_u32 kbts_direction; enum kbts_direction_enum { KBTS_DIRECTION_NONE, KBTS_DIRECTION_LTR, KBTS_DIRECTION_RTL, KBTS_DIRECTION_COUNT, }; typedef kbts_u8 kbts_unicode_joining_type; enum kbts_unicode_joining_type_enum { KBTS_UNICODE_JOINING_TYPE_NONE, KBTS_UNICODE_JOINING_TYPE_LEFT, KBTS_UNICODE_JOINING_TYPE_DUAL, KBTS_UNICODE_JOINING_TYPE_FORCE, KBTS_UNICODE_JOINING_TYPE_RIGHT, KBTS_UNICODE_JOINING_TYPE_TRANSPARENT, KBTS_UNICODE_JOINING_TYPE_COUNT, }; typedef kbts_u8 kbts_unicode_flags; enum kbts_unicode_flag_enum { KBTS_UNICODE_FLAG_MODIFIER_COMBINING_MARK = (1 << 0), KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE = (1 << 1), KBTS_UNICODE_FLAG_OPEN_BRACKET = (1 << 2), KBTS_UNICODE_FLAG_CLOSE_BRACKET = (1 << 3), KBTS_UNICODE_FLAG_PART_OF_WORD = (1 << 4), KBTS_UNICODE_FLAG_DECIMAL_DIGIT = (1 << 5), KBTS_UNICODE_FLAG_NON_SPACING_MARK = (1 << 6), }; typedef kbts_u8 kbts_unicode_bidirectional_class; enum kbts_unicode_bidirectional_class_enum { KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI, KBTS_UNICODE_BIDIRECTIONAL_CLASS_L, KBTS_UNICODE_BIDIRECTIONAL_CLASS_R, KBTS_UNICODE_BIDIRECTIONAL_CLASS_NSM, KBTS_UNICODE_BIDIRECTIONAL_CLASS_AL, KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN, KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN, KBTS_UNICODE_BIDIRECTIONAL_CLASS_ES, KBTS_UNICODE_BIDIRECTIONAL_CLASS_ET, KBTS_UNICODE_BIDIRECTIONAL_CLASS_CS, KBTS_UNICODE_BIDIRECTIONAL_CLASS_COUNT, }; typedef kbts_u8 kbts_line_break_class; enum kbts_line_break_class_enum { /* 0 */ KBTS_LINE_BREAK_CLASS_Onea, /* 1 */ KBTS_LINE_BREAK_CLASS_Oea, /* 2 */ KBTS_LINE_BREAK_CLASS_Ope, /* 3 */ KBTS_LINE_BREAK_CLASS_BK, /* 4 */ KBTS_LINE_BREAK_CLASS_CR, /* 5 */ KBTS_LINE_BREAK_CLASS_LF, /* 6 */ KBTS_LINE_BREAK_CLASS_NL, /* 7 */ KBTS_LINE_BREAK_CLASS_SP, /* 8 */ KBTS_LINE_BREAK_CLASS_ZW, /* 9 */ KBTS_LINE_BREAK_CLASS_WJ, /* 10 */ KBTS_LINE_BREAK_CLASS_GLnea, /* 11 */ KBTS_LINE_BREAK_CLASS_GLea, /* 12 */ KBTS_LINE_BREAK_CLASS_CLnea, /* 13 */ KBTS_LINE_BREAK_CLASS_CLea, /* 14 */ KBTS_LINE_BREAK_CLASS_CPnea, /* 15 */ KBTS_LINE_BREAK_CLASS_CPea, /* 16 */ KBTS_LINE_BREAK_CLASS_EXnea, /* 17 */ KBTS_LINE_BREAK_CLASS_EXea, /* 18 */ KBTS_LINE_BREAK_CLASS_SY, /* 19 */ KBTS_LINE_BREAK_CLASS_BAnea, /* 20 */ KBTS_LINE_BREAK_CLASS_BAea, /* 21 */ KBTS_LINE_BREAK_CLASS_OPnea, /* 22 */ KBTS_LINE_BREAK_CLASS_OPea, /* 23 */ KBTS_LINE_BREAK_CLASS_QU, /* 24 */ KBTS_LINE_BREAK_CLASS_QUPi, /* 25 */ KBTS_LINE_BREAK_CLASS_QUPf, /* 26 */ KBTS_LINE_BREAK_CLASS_IS, /* 27 */ KBTS_LINE_BREAK_CLASS_NSnea, /* 28 */ KBTS_LINE_BREAK_CLASS_NSea, /* 29 */ KBTS_LINE_BREAK_CLASS_B2, /* 30 */ KBTS_LINE_BREAK_CLASS_CB, /* 31 */ KBTS_LINE_BREAK_CLASS_HY, /* 32 */ KBTS_LINE_BREAK_CLASS_HYPHEN, /* 33 */ KBTS_LINE_BREAK_CLASS_INnea, /* 34 */ KBTS_LINE_BREAK_CLASS_INea, /* 35 */ KBTS_LINE_BREAK_CLASS_BB, /* 36 */ KBTS_LINE_BREAK_CLASS_HL, /* 37 */ KBTS_LINE_BREAK_CLASS_ALnea, /* 38 */ KBTS_LINE_BREAK_CLASS_ALea, /* 39 */ KBTS_LINE_BREAK_CLASS_NU, /* 40 */ KBTS_LINE_BREAK_CLASS_PRnea, /* 41 */ KBTS_LINE_BREAK_CLASS_PRea, /* 42 */ KBTS_LINE_BREAK_CLASS_IDnea, /* 43 */ KBTS_LINE_BREAK_CLASS_IDea, /* 44 */ KBTS_LINE_BREAK_CLASS_IDpe, /* 45 */ KBTS_LINE_BREAK_CLASS_EBnea, /* 46 */ KBTS_LINE_BREAK_CLASS_EBea, /* 47 */ KBTS_LINE_BREAK_CLASS_EM, /* 48 */ KBTS_LINE_BREAK_CLASS_POnea, /* 49 */ KBTS_LINE_BREAK_CLASS_POea, /* 50 */ KBTS_LINE_BREAK_CLASS_JL, /* 51 */ KBTS_LINE_BREAK_CLASS_JV, /* 52 */ KBTS_LINE_BREAK_CLASS_JT, /* 53 */ KBTS_LINE_BREAK_CLASS_H2, /* 54 */ KBTS_LINE_BREAK_CLASS_H3, /* 55 */ KBTS_LINE_BREAK_CLASS_AP, /* 56 */ KBTS_LINE_BREAK_CLASS_AK, /* 57 */ KBTS_LINE_BREAK_CLASS_DOTTED_CIRCLE, /* 58 */ KBTS_LINE_BREAK_CLASS_AS, /* 59 */ KBTS_LINE_BREAK_CLASS_VF, /* 60 */ KBTS_LINE_BREAK_CLASS_VI, /* 61 */ KBTS_LINE_BREAK_CLASS_RI, /* 62 */ KBTS_LINE_BREAK_CLASS_COUNT, /* 63 */ KBTS_LINE_BREAK_CLASS_CM, /* 64 */ KBTS_LINE_BREAK_CLASS_ZWJ, // CJ resolves to either NS or ID depending on the (Japanese) line break style. // NS is strict line breaking, used for long lines. // ID is normal line breaking, used for normal body text. /* 65 */ KBTS_LINE_BREAK_CLASS_CJ, /* 66 */ KBTS_LINE_BREAK_CLASS_SOT, /* 67 */ KBTS_LINE_BREAK_CLASS_EOT, }; // @Cleanup: Merge EX and FO. typedef kbts_u8 kbts_word_break_class; enum kbts_word_break_class_enum { KBTS_WORD_BREAK_CLASS_Onep, KBTS_WORD_BREAK_CLASS_Oep, KBTS_WORD_BREAK_CLASS_CR, KBTS_WORD_BREAK_CLASS_LF, KBTS_WORD_BREAK_CLASS_NL, KBTS_WORD_BREAK_CLASS_EX, KBTS_WORD_BREAK_CLASS_ZWJ, KBTS_WORD_BREAK_CLASS_RI, KBTS_WORD_BREAK_CLASS_FO, KBTS_WORD_BREAK_CLASS_KA, KBTS_WORD_BREAK_CLASS_HL, KBTS_WORD_BREAK_CLASS_ALnep, KBTS_WORD_BREAK_CLASS_ALep, KBTS_WORD_BREAK_CLASS_SQ, KBTS_WORD_BREAK_CLASS_DQ, KBTS_WORD_BREAK_CLASS_MNL, KBTS_WORD_BREAK_CLASS_ML, KBTS_WORD_BREAK_CLASS_MN, KBTS_WORD_BREAK_CLASS_NM, KBTS_WORD_BREAK_CLASS_ENL, KBTS_WORD_BREAK_CLASS_WSS, KBTS_WORD_BREAK_CLASS_SOT, }; // Unicode defines scripts and languages. // A language belongs to a single script, and a script belongs to a single writing system. // On top of these, OpenType defines shapers, which are basically just designations for // specific code paths that are taken depending on which script is being shapen. // // Some scripts, like Latin and Cyrillic, need relatively few operations, while complex // scripts like Arabic and Indic scripts have specific processing steps that need to happen // in order to obtain a correct result. // // These sequences of operations are _not_ described in the font file itself. The shaping // code needs to know which script it is shaping, and implement all of those passes itself. // That is why you, as a user, have to care about this. // // When creating shape_config, you can either pass in a known script, or you can specify // SCRIPT_DONT_KNOW and let the library figure it out. // While SCRIPT_DONT_KNOW may look appealing, it is worth noting that we can only infer // the _script_, and not the language, of the text you pass in. // This means that you might miss out on language-specific features when you use it. typedef kbts_u32 kbts_shaper; enum kbts_shaper_enum { KBTS_SHAPER_DEFAULT, KBTS_SHAPER_ARABIC, KBTS_SHAPER_HANGUL, KBTS_SHAPER_HEBREW, KBTS_SHAPER_INDIC, KBTS_SHAPER_KHMER, KBTS_SHAPER_MYANMAR, KBTS_SHAPER_TIBETAN, KBTS_SHAPER_USE, KBTS_SHAPER_COUNT, }; typedef kbts_u32 kbts_script_tag; enum kbts_script_tag_enum { KBTS_SCRIPT_TAG_DONT_KNOW = KBTS_FOURCC(' ', ' ', ' ', ' '), KBTS_SCRIPT_TAG_ADLAM = KBTS_FOURCC('a', 'd', 'l', 'm'), KBTS_SCRIPT_TAG_AHOM = KBTS_FOURCC('a', 'h', 'o', 'm'), KBTS_SCRIPT_TAG_ANATOLIAN_HIEROGLYPHS = KBTS_FOURCC('h', 'l', 'u', 'w'), KBTS_SCRIPT_TAG_ARABIC = KBTS_FOURCC('a', 'r', 'a', 'b'), KBTS_SCRIPT_TAG_ARMENIAN = KBTS_FOURCC('a', 'r', 'm', 'n'), KBTS_SCRIPT_TAG_AVESTAN = KBTS_FOURCC('a', 'v', 's', 't'), KBTS_SCRIPT_TAG_BALINESE = KBTS_FOURCC('b', 'a', 'l', 'i'), KBTS_SCRIPT_TAG_BAMUM = KBTS_FOURCC('b', 'a', 'm', 'u'), KBTS_SCRIPT_TAG_BASSA_VAH = KBTS_FOURCC('b', 'a', 's', 's'), KBTS_SCRIPT_TAG_BATAK = KBTS_FOURCC('b', 'a', 't', 'k'), KBTS_SCRIPT_TAG_BENGALI = KBTS_FOURCC('b', 'n', 'g', '2'), KBTS_SCRIPT_TAG_BHAIKSUKI = KBTS_FOURCC('b', 'h', 'k', 's'), KBTS_SCRIPT_TAG_BOPOMOFO = KBTS_FOURCC('b', 'o', 'p', 'o'), KBTS_SCRIPT_TAG_BRAHMI = KBTS_FOURCC('b', 'r', 'a', 'h'), KBTS_SCRIPT_TAG_BUGINESE = KBTS_FOURCC('b', 'u', 'g', 'i'), KBTS_SCRIPT_TAG_BUHID = KBTS_FOURCC('b', 'u', 'h', 'd'), KBTS_SCRIPT_TAG_CANADIAN_SYLLABICS = KBTS_FOURCC('c', 'a', 'n', 's'), KBTS_SCRIPT_TAG_CARIAN = KBTS_FOURCC('c', 'a', 'r', 'i'), KBTS_SCRIPT_TAG_CAUCASIAN_ALBANIAN = KBTS_FOURCC('a', 'g', 'h', 'b'), KBTS_SCRIPT_TAG_CHAKMA = KBTS_FOURCC('c', 'a', 'k', 'm'), KBTS_SCRIPT_TAG_CHAM = KBTS_FOURCC('c', 'h', 'a', 'm'), KBTS_SCRIPT_TAG_CHEROKEE = KBTS_FOURCC('c', 'h', 'e', 'r'), KBTS_SCRIPT_TAG_CHORASMIAN = KBTS_FOURCC('c', 'h', 'r', 's'), KBTS_SCRIPT_TAG_CJK_IDEOGRAPHIC = KBTS_FOURCC('h', 'a', 'n', 'i'), KBTS_SCRIPT_TAG_COPTIC = KBTS_FOURCC('c', 'o', 'p', 't'), KBTS_SCRIPT_TAG_CYPRIOT_SYLLABARY = KBTS_FOURCC('c', 'p', 'r', 't'), KBTS_SCRIPT_TAG_CYPRO_MINOAN = KBTS_FOURCC('c', 'p', 'm', 'n'), KBTS_SCRIPT_TAG_CYRILLIC = KBTS_FOURCC('c', 'y', 'r', 'l'), KBTS_SCRIPT_TAG_DEFAULT = KBTS_FOURCC('D', 'F', 'L', 'T'), KBTS_SCRIPT_TAG_DEFAULT2 = KBTS_FOURCC('D', 'F', 'L', 'T'), KBTS_SCRIPT_TAG_DESERET = KBTS_FOURCC('d', 's', 'r', 't'), KBTS_SCRIPT_TAG_DEVANAGARI = KBTS_FOURCC('d', 'e', 'v', '2'), KBTS_SCRIPT_TAG_DIVES_AKURU = KBTS_FOURCC('d', 'i', 'a', 'k'), KBTS_SCRIPT_TAG_DOGRA = KBTS_FOURCC('d', 'o', 'g', 'r'), KBTS_SCRIPT_TAG_DUPLOYAN = KBTS_FOURCC('d', 'u', 'p', 'l'), KBTS_SCRIPT_TAG_EGYPTIAN_HIEROGLYPHS = KBTS_FOURCC('e', 'g', 'y', 'p'), KBTS_SCRIPT_TAG_ELBASAN = KBTS_FOURCC('e', 'l', 'b', 'a'), KBTS_SCRIPT_TAG_ELYMAIC = KBTS_FOURCC('e', 'l', 'y', 'm'), KBTS_SCRIPT_TAG_ETHIOPIC = KBTS_FOURCC('e', 't', 'h', 'i'), KBTS_SCRIPT_TAG_GARAY = KBTS_FOURCC('g', 'a', 'r', 'a'), KBTS_SCRIPT_TAG_GEORGIAN = KBTS_FOURCC('g', 'e', 'o', 'r'), KBTS_SCRIPT_TAG_GLAGOLITIC = KBTS_FOURCC('g', 'l', 'a', 'g'), KBTS_SCRIPT_TAG_GOTHIC = KBTS_FOURCC('g', 'o', 't', 'h'), KBTS_SCRIPT_TAG_GRANTHA = KBTS_FOURCC('g', 'r', 'a', 'n'), KBTS_SCRIPT_TAG_GREEK = KBTS_FOURCC('g', 'r', 'e', 'k'), KBTS_SCRIPT_TAG_GUJARATI = KBTS_FOURCC('g', 'j', 'r', '2'), KBTS_SCRIPT_TAG_GUNJALA_GONDI = KBTS_FOURCC('g', 'o', 'n', 'g'), KBTS_SCRIPT_TAG_GURMUKHI = KBTS_FOURCC('g', 'u', 'r', '2'), KBTS_SCRIPT_TAG_GURUNG_KHEMA = KBTS_FOURCC('g', 'u', 'k', 'h'), KBTS_SCRIPT_TAG_HANGUL = KBTS_FOURCC('h', 'a', 'n', 'g'), KBTS_SCRIPT_TAG_HANIFI_ROHINGYA = KBTS_FOURCC('r', 'o', 'h', 'g'), KBTS_SCRIPT_TAG_HANUNOO = KBTS_FOURCC('h', 'a', 'n', 'o'), KBTS_SCRIPT_TAG_HATRAN = KBTS_FOURCC('h', 'a', 't', 'r'), KBTS_SCRIPT_TAG_HEBREW = KBTS_FOURCC('h', 'e', 'b', 'r'), KBTS_SCRIPT_TAG_HIRAGANA = KBTS_FOURCC('k', 'a', 'n', 'a'), KBTS_SCRIPT_TAG_IMPERIAL_ARAMAIC = KBTS_FOURCC('a', 'r', 'm', 'i'), KBTS_SCRIPT_TAG_INSCRIPTIONAL_PAHLAVI = KBTS_FOURCC('p', 'h', 'l', 'i'), KBTS_SCRIPT_TAG_INSCRIPTIONAL_PARTHIAN = KBTS_FOURCC('p', 'r', 't', 'i'), KBTS_SCRIPT_TAG_JAVANESE = KBTS_FOURCC('j', 'a', 'v', 'a'), KBTS_SCRIPT_TAG_KAITHI = KBTS_FOURCC('k', 't', 'h', 'i'), KBTS_SCRIPT_TAG_KANNADA = KBTS_FOURCC('k', 'n', 'd', '2'), KBTS_SCRIPT_TAG_KATAKANA = KBTS_FOURCC('k', 'a', 'n', 'a'), KBTS_SCRIPT_TAG_KAWI = KBTS_FOURCC('k', 'a', 'w', 'i'), KBTS_SCRIPT_TAG_KAYAH_LI = KBTS_FOURCC('k', 'a', 'l', 'i'), KBTS_SCRIPT_TAG_KHAROSHTHI = KBTS_FOURCC('k', 'h', 'a', 'r'), KBTS_SCRIPT_TAG_KHITAN_SMALL_SCRIPT = KBTS_FOURCC('k', 'i', 't', 's'), KBTS_SCRIPT_TAG_KHMER = KBTS_FOURCC('k', 'h', 'm', 'r'), KBTS_SCRIPT_TAG_KHOJKI = KBTS_FOURCC('k', 'h', 'o', 'j'), KBTS_SCRIPT_TAG_KHUDAWADI = KBTS_FOURCC('s', 'i', 'n', 'd'), KBTS_SCRIPT_TAG_KIRAT_RAI = KBTS_FOURCC('k', 'r', 'a', 'i'), KBTS_SCRIPT_TAG_LAO = KBTS_FOURCC('l', 'a', 'o', ' '), KBTS_SCRIPT_TAG_LATIN = KBTS_FOURCC('l', 'a', 't', 'n'), KBTS_SCRIPT_TAG_LEPCHA = KBTS_FOURCC('l', 'e', 'p', 'c'), KBTS_SCRIPT_TAG_LIMBU = KBTS_FOURCC('l', 'i', 'm', 'b'), KBTS_SCRIPT_TAG_LINEAR_A = KBTS_FOURCC('l', 'i', 'n', 'a'), KBTS_SCRIPT_TAG_LINEAR_B = KBTS_FOURCC('l', 'i', 'n', 'b'), KBTS_SCRIPT_TAG_LISU = KBTS_FOURCC('l', 'i', 's', 'u'), KBTS_SCRIPT_TAG_LYCIAN = KBTS_FOURCC('l', 'y', 'c', 'i'), KBTS_SCRIPT_TAG_LYDIAN = KBTS_FOURCC('l', 'y', 'd', 'i'), KBTS_SCRIPT_TAG_MAHAJANI = KBTS_FOURCC('m', 'a', 'h', 'j'), KBTS_SCRIPT_TAG_MAKASAR = KBTS_FOURCC('m', 'a', 'k', 'a'), KBTS_SCRIPT_TAG_MALAYALAM = KBTS_FOURCC('m', 'l', 'm', '2'), KBTS_SCRIPT_TAG_MANDAIC = KBTS_FOURCC('m', 'a', 'n', 'd'), KBTS_SCRIPT_TAG_MANICHAEAN = KBTS_FOURCC('m', 'a', 'n', 'i'), KBTS_SCRIPT_TAG_MARCHEN = KBTS_FOURCC('m', 'a', 'r', 'c'), KBTS_SCRIPT_TAG_MASARAM_GONDI = KBTS_FOURCC('g', 'o', 'n', 'm'), KBTS_SCRIPT_TAG_MEDEFAIDRIN = KBTS_FOURCC('m', 'e', 'd', 'f'), KBTS_SCRIPT_TAG_MEETEI_MAYEK = KBTS_FOURCC('m', 't', 'e', 'i'), KBTS_SCRIPT_TAG_MENDE_KIKAKUI = KBTS_FOURCC('m', 'e', 'n', 'd'), KBTS_SCRIPT_TAG_MEROITIC_CURSIVE = KBTS_FOURCC('m', 'e', 'r', 'c'), KBTS_SCRIPT_TAG_MEROITIC_HIEROGLYPHS = KBTS_FOURCC('m', 'e', 'r', 'o'), KBTS_SCRIPT_TAG_MIAO = KBTS_FOURCC('p', 'l', 'r', 'd'), KBTS_SCRIPT_TAG_MODI = KBTS_FOURCC('m', 'o', 'd', 'i'), KBTS_SCRIPT_TAG_MONGOLIAN = KBTS_FOURCC('m', 'o', 'n', 'g'), KBTS_SCRIPT_TAG_MRO = KBTS_FOURCC('m', 'r', 'o', 'o'), KBTS_SCRIPT_TAG_MULTANI = KBTS_FOURCC('m', 'u', 'l', 't'), KBTS_SCRIPT_TAG_MYANMAR = KBTS_FOURCC('m', 'y', 'm', '2'), KBTS_SCRIPT_TAG_NABATAEAN = KBTS_FOURCC('n', 'b', 'a', 't'), KBTS_SCRIPT_TAG_NAG_MUNDARI = KBTS_FOURCC('n', 'a', 'g', 'm'), KBTS_SCRIPT_TAG_NANDINAGARI = KBTS_FOURCC('n', 'a', 'n', 'd'), KBTS_SCRIPT_TAG_NEWA = KBTS_FOURCC('n', 'e', 'w', 'a'), KBTS_SCRIPT_TAG_NEW_TAI_LUE = KBTS_FOURCC('t', 'a', 'l', 'u'), KBTS_SCRIPT_TAG_NKO = KBTS_FOURCC('n', 'k', 'o', ' '), KBTS_SCRIPT_TAG_NUSHU = KBTS_FOURCC('n', 's', 'h', 'u'), KBTS_SCRIPT_TAG_NYIAKENG_PUACHUE_HMONG = KBTS_FOURCC('h', 'm', 'n', 'p'), KBTS_SCRIPT_TAG_OGHAM = KBTS_FOURCC('o', 'g', 'a', 'm'), KBTS_SCRIPT_TAG_OL_CHIKI = KBTS_FOURCC('o', 'l', 'c', 'k'), KBTS_SCRIPT_TAG_OL_ONAL = KBTS_FOURCC('o', 'n', 'a', 'o'), KBTS_SCRIPT_TAG_OLD_ITALIC = KBTS_FOURCC('i', 't', 'a', 'l'), KBTS_SCRIPT_TAG_OLD_HUNGARIAN = KBTS_FOURCC('h', 'u', 'n', 'g'), KBTS_SCRIPT_TAG_OLD_NORTH_ARABIAN = KBTS_FOURCC('n', 'a', 'r', 'b'), KBTS_SCRIPT_TAG_OLD_PERMIC = KBTS_FOURCC('p', 'e', 'r', 'm'), KBTS_SCRIPT_TAG_OLD_PERSIAN_CUNEIFORM = KBTS_FOURCC('x', 'p', 'e', 'o'), KBTS_SCRIPT_TAG_OLD_SOGDIAN = KBTS_FOURCC('s', 'o', 'g', 'o'), KBTS_SCRIPT_TAG_OLD_SOUTH_ARABIAN = KBTS_FOURCC('s', 'a', 'r', 'b'), KBTS_SCRIPT_TAG_OLD_TURKIC = KBTS_FOURCC('o', 'r', 'k', 'h'), KBTS_SCRIPT_TAG_OLD_UYGHUR = KBTS_FOURCC('o', 'u', 'g', 'r'), KBTS_SCRIPT_TAG_ODIA = KBTS_FOURCC('o', 'r', 'y', '2'), KBTS_SCRIPT_TAG_OSAGE = KBTS_FOURCC('o', 's', 'g', 'e'), KBTS_SCRIPT_TAG_OSMANYA = KBTS_FOURCC('o', 's', 'm', 'a'), KBTS_SCRIPT_TAG_PAHAWH_HMONG = KBTS_FOURCC('h', 'm', 'n', 'g'), KBTS_SCRIPT_TAG_PALMYRENE = KBTS_FOURCC('p', 'a', 'l', 'm'), KBTS_SCRIPT_TAG_PAU_CIN_HAU = KBTS_FOURCC('p', 'a', 'u', 'c'), KBTS_SCRIPT_TAG_PHAGS_PA = KBTS_FOURCC('p', 'h', 'a', 'g'), KBTS_SCRIPT_TAG_PHOENICIAN = KBTS_FOURCC('p', 'h', 'n', 'x'), KBTS_SCRIPT_TAG_PSALTER_PAHLAVI = KBTS_FOURCC('p', 'h', 'l', 'p'), KBTS_SCRIPT_TAG_REJANG = KBTS_FOURCC('r', 'j', 'n', 'g'), KBTS_SCRIPT_TAG_RUNIC = KBTS_FOURCC('r', 'u', 'n', 'r'), KBTS_SCRIPT_TAG_SAMARITAN = KBTS_FOURCC('s', 'a', 'm', 'r'), KBTS_SCRIPT_TAG_SAURASHTRA = KBTS_FOURCC('s', 'a', 'u', 'r'), KBTS_SCRIPT_TAG_SHARADA = KBTS_FOURCC('s', 'h', 'r', 'd'), KBTS_SCRIPT_TAG_SHAVIAN = KBTS_FOURCC('s', 'h', 'a', 'w'), KBTS_SCRIPT_TAG_SIDDHAM = KBTS_FOURCC('s', 'i', 'd', 'd'), KBTS_SCRIPT_TAG_SIGN_WRITING = KBTS_FOURCC('s', 'g', 'n', 'w'), KBTS_SCRIPT_TAG_SOGDIAN = KBTS_FOURCC('s', 'o', 'g', 'd'), KBTS_SCRIPT_TAG_SINHALA = KBTS_FOURCC('s', 'i', 'n', 'h'), KBTS_SCRIPT_TAG_SORA_SOMPENG = KBTS_FOURCC('s', 'o', 'r', 'a'), KBTS_SCRIPT_TAG_SOYOMBO = KBTS_FOURCC('s', 'o', 'y', 'o'), KBTS_SCRIPT_TAG_SUMERO_AKKADIAN_CUNEIFORM = KBTS_FOURCC('x', 's', 'u', 'x'), KBTS_SCRIPT_TAG_SUNDANESE = KBTS_FOURCC('s', 'u', 'n', 'd'), KBTS_SCRIPT_TAG_SUNUWAR = KBTS_FOURCC('s', 'u', 'n', 'u'), KBTS_SCRIPT_TAG_SYLOTI_NAGRI = KBTS_FOURCC('s', 'y', 'l', 'o'), KBTS_SCRIPT_TAG_SYRIAC = KBTS_FOURCC('s', 'y', 'r', 'c'), KBTS_SCRIPT_TAG_TAGALOG = KBTS_FOURCC('t', 'g', 'l', 'g'), KBTS_SCRIPT_TAG_TAGBANWA = KBTS_FOURCC('t', 'a', 'g', 'b'), KBTS_SCRIPT_TAG_TAI_LE = KBTS_FOURCC('t', 'a', 'l', 'e'), KBTS_SCRIPT_TAG_TAI_THAM = KBTS_FOURCC('l', 'a', 'n', 'a'), KBTS_SCRIPT_TAG_TAI_VIET = KBTS_FOURCC('t', 'a', 'v', 't'), KBTS_SCRIPT_TAG_TAKRI = KBTS_FOURCC('t', 'a', 'k', 'r'), KBTS_SCRIPT_TAG_TAMIL = KBTS_FOURCC('t', 'm', 'l', '2'), KBTS_SCRIPT_TAG_TANGSA = KBTS_FOURCC('t', 'n', 's', 'a'), KBTS_SCRIPT_TAG_TANGUT = KBTS_FOURCC('t', 'a', 'n', 'g'), KBTS_SCRIPT_TAG_TELUGU = KBTS_FOURCC('t', 'e', 'l', '2'), KBTS_SCRIPT_TAG_THAANA = KBTS_FOURCC('t', 'h', 'a', 'a'), KBTS_SCRIPT_TAG_THAI = KBTS_FOURCC('t', 'h', 'a', 'i'), KBTS_SCRIPT_TAG_TIBETAN = KBTS_FOURCC('t', 'i', 'b', 't'), KBTS_SCRIPT_TAG_TIFINAGH = KBTS_FOURCC('t', 'f', 'n', 'g'), KBTS_SCRIPT_TAG_TIRHUTA = KBTS_FOURCC('t', 'i', 'r', 'h'), KBTS_SCRIPT_TAG_TODHRI = KBTS_FOURCC('t', 'o', 'd', 'r'), KBTS_SCRIPT_TAG_TOTO = KBTS_FOURCC('t', 'o', 't', 'o'), KBTS_SCRIPT_TAG_TULU_TIGALARI = KBTS_FOURCC('t', 'u', 't', 'g'), KBTS_SCRIPT_TAG_UGARITIC_CUNEIFORM = KBTS_FOURCC('u', 'g', 'a', 'r'), KBTS_SCRIPT_TAG_VAI = KBTS_FOURCC('v', 'a', 'i', ' '), KBTS_SCRIPT_TAG_VITHKUQI = KBTS_FOURCC('v', 'i', 't', 'h'), KBTS_SCRIPT_TAG_WANCHO = KBTS_FOURCC('w', 'c', 'h', 'o'), KBTS_SCRIPT_TAG_WARANG_CITI = KBTS_FOURCC('w', 'a', 'r', 'a'), KBTS_SCRIPT_TAG_YEZIDI = KBTS_FOURCC('y', 'e', 'z', 'i'), KBTS_SCRIPT_TAG_YI = KBTS_FOURCC('y', 'i', ' ', ' '), KBTS_SCRIPT_TAG_ZANABAZAR_SQUARE = KBTS_FOURCC('z', 'a', 'n', 'b'), }; typedef kbts_u32 kbts_script; enum kbts_script_enum { KBTS_SCRIPT_DONT_KNOW, KBTS_SCRIPT_ADLAM, KBTS_SCRIPT_AHOM, KBTS_SCRIPT_ANATOLIAN_HIEROGLYPHS, KBTS_SCRIPT_ARABIC, KBTS_SCRIPT_ARMENIAN, KBTS_SCRIPT_AVESTAN, KBTS_SCRIPT_BALINESE, KBTS_SCRIPT_BAMUM, KBTS_SCRIPT_BASSA_VAH, KBTS_SCRIPT_BATAK, KBTS_SCRIPT_BENGALI, KBTS_SCRIPT_BHAIKSUKI, KBTS_SCRIPT_BOPOMOFO, KBTS_SCRIPT_BRAHMI, KBTS_SCRIPT_BUGINESE, KBTS_SCRIPT_BUHID, KBTS_SCRIPT_CANADIAN_SYLLABICS, KBTS_SCRIPT_CARIAN, KBTS_SCRIPT_CAUCASIAN_ALBANIAN, KBTS_SCRIPT_CHAKMA, KBTS_SCRIPT_CHAM, KBTS_SCRIPT_CHEROKEE, KBTS_SCRIPT_CHORASMIAN, KBTS_SCRIPT_CJK_IDEOGRAPHIC, KBTS_SCRIPT_COPTIC, KBTS_SCRIPT_CYPRIOT_SYLLABARY, KBTS_SCRIPT_CYPRO_MINOAN, KBTS_SCRIPT_CYRILLIC, KBTS_SCRIPT_DEFAULT, KBTS_SCRIPT_DEFAULT2, KBTS_SCRIPT_DESERET, KBTS_SCRIPT_DEVANAGARI, KBTS_SCRIPT_DIVES_AKURU, KBTS_SCRIPT_DOGRA, KBTS_SCRIPT_DUPLOYAN, KBTS_SCRIPT_EGYPTIAN_HIEROGLYPHS, KBTS_SCRIPT_ELBASAN, KBTS_SCRIPT_ELYMAIC, KBTS_SCRIPT_ETHIOPIC, KBTS_SCRIPT_GARAY, KBTS_SCRIPT_GEORGIAN, KBTS_SCRIPT_GLAGOLITIC, KBTS_SCRIPT_GOTHIC, KBTS_SCRIPT_GRANTHA, KBTS_SCRIPT_GREEK, KBTS_SCRIPT_GUJARATI, KBTS_SCRIPT_GUNJALA_GONDI, KBTS_SCRIPT_GURMUKHI, KBTS_SCRIPT_GURUNG_KHEMA, KBTS_SCRIPT_HANGUL, KBTS_SCRIPT_HANIFI_ROHINGYA, KBTS_SCRIPT_HANUNOO, KBTS_SCRIPT_HATRAN, KBTS_SCRIPT_HEBREW, KBTS_SCRIPT_HIRAGANA, KBTS_SCRIPT_IMPERIAL_ARAMAIC, KBTS_SCRIPT_INSCRIPTIONAL_PAHLAVI, KBTS_SCRIPT_INSCRIPTIONAL_PARTHIAN, KBTS_SCRIPT_JAVANESE, KBTS_SCRIPT_KAITHI, KBTS_SCRIPT_KANNADA, KBTS_SCRIPT_KATAKANA, KBTS_SCRIPT_KAWI, KBTS_SCRIPT_KAYAH_LI, KBTS_SCRIPT_KHAROSHTHI, KBTS_SCRIPT_KHITAN_SMALL_SCRIPT, KBTS_SCRIPT_KHMER, KBTS_SCRIPT_KHOJKI, KBTS_SCRIPT_KHUDAWADI, KBTS_SCRIPT_KIRAT_RAI, KBTS_SCRIPT_LAO, KBTS_SCRIPT_LATIN, KBTS_SCRIPT_LEPCHA, KBTS_SCRIPT_LIMBU, KBTS_SCRIPT_LINEAR_A, KBTS_SCRIPT_LINEAR_B, KBTS_SCRIPT_LISU, KBTS_SCRIPT_LYCIAN, KBTS_SCRIPT_LYDIAN, KBTS_SCRIPT_MAHAJANI, KBTS_SCRIPT_MAKASAR, KBTS_SCRIPT_MALAYALAM, KBTS_SCRIPT_MANDAIC, KBTS_SCRIPT_MANICHAEAN, KBTS_SCRIPT_MARCHEN, KBTS_SCRIPT_MASARAM_GONDI, KBTS_SCRIPT_MEDEFAIDRIN, KBTS_SCRIPT_MEETEI_MAYEK, KBTS_SCRIPT_MENDE_KIKAKUI, KBTS_SCRIPT_MEROITIC_CURSIVE, KBTS_SCRIPT_MEROITIC_HIEROGLYPHS, KBTS_SCRIPT_MIAO, KBTS_SCRIPT_MODI, KBTS_SCRIPT_MONGOLIAN, KBTS_SCRIPT_MRO, KBTS_SCRIPT_MULTANI, KBTS_SCRIPT_MYANMAR, KBTS_SCRIPT_NABATAEAN, KBTS_SCRIPT_NAG_MUNDARI, KBTS_SCRIPT_NANDINAGARI, KBTS_SCRIPT_NEWA, KBTS_SCRIPT_NEW_TAI_LUE, KBTS_SCRIPT_NKO, KBTS_SCRIPT_NUSHU, KBTS_SCRIPT_NYIAKENG_PUACHUE_HMONG, KBTS_SCRIPT_OGHAM, KBTS_SCRIPT_OL_CHIKI, KBTS_SCRIPT_OL_ONAL, KBTS_SCRIPT_OLD_ITALIC, KBTS_SCRIPT_OLD_HUNGARIAN, KBTS_SCRIPT_OLD_NORTH_ARABIAN, KBTS_SCRIPT_OLD_PERMIC, KBTS_SCRIPT_OLD_PERSIAN_CUNEIFORM, KBTS_SCRIPT_OLD_SOGDIAN, KBTS_SCRIPT_OLD_SOUTH_ARABIAN, KBTS_SCRIPT_OLD_TURKIC, KBTS_SCRIPT_OLD_UYGHUR, KBTS_SCRIPT_ODIA, KBTS_SCRIPT_OSAGE, KBTS_SCRIPT_OSMANYA, KBTS_SCRIPT_PAHAWH_HMONG, KBTS_SCRIPT_PALMYRENE, KBTS_SCRIPT_PAU_CIN_HAU, KBTS_SCRIPT_PHAGS_PA, KBTS_SCRIPT_PHOENICIAN, KBTS_SCRIPT_PSALTER_PAHLAVI, KBTS_SCRIPT_REJANG, KBTS_SCRIPT_RUNIC, KBTS_SCRIPT_SAMARITAN, KBTS_SCRIPT_SAURASHTRA, KBTS_SCRIPT_SHARADA, KBTS_SCRIPT_SHAVIAN, KBTS_SCRIPT_SIDDHAM, KBTS_SCRIPT_SIGN_WRITING, KBTS_SCRIPT_SOGDIAN, KBTS_SCRIPT_SINHALA, KBTS_SCRIPT_SORA_SOMPENG, KBTS_SCRIPT_SOYOMBO, KBTS_SCRIPT_SUMERO_AKKADIAN_CUNEIFORM, KBTS_SCRIPT_SUNDANESE, KBTS_SCRIPT_SUNUWAR, KBTS_SCRIPT_SYLOTI_NAGRI, KBTS_SCRIPT_SYRIAC, KBTS_SCRIPT_TAGALOG, KBTS_SCRIPT_TAGBANWA, KBTS_SCRIPT_TAI_LE, KBTS_SCRIPT_TAI_THAM, KBTS_SCRIPT_TAI_VIET, KBTS_SCRIPT_TAKRI, KBTS_SCRIPT_TAMIL, KBTS_SCRIPT_TANGSA, KBTS_SCRIPT_TANGUT, KBTS_SCRIPT_TELUGU, KBTS_SCRIPT_THAANA, KBTS_SCRIPT_THAI, KBTS_SCRIPT_TIBETAN, KBTS_SCRIPT_TIFINAGH, KBTS_SCRIPT_TIRHUTA, KBTS_SCRIPT_TODHRI, KBTS_SCRIPT_TOTO, KBTS_SCRIPT_TULU_TIGALARI, KBTS_SCRIPT_UGARITIC_CUNEIFORM, KBTS_SCRIPT_VAI, KBTS_SCRIPT_VITHKUQI, KBTS_SCRIPT_WANCHO, KBTS_SCRIPT_WARANG_CITI, KBTS_SCRIPT_YEZIDI, KBTS_SCRIPT_YI, KBTS_SCRIPT_ZANABAZAR_SQUARE, KBTS_SCRIPT_COUNT, }; typedef kbts_u32 kbts_feature_tag; enum kbts_feature_tag_enum { KBTS_FEATURE_TAG_UNREGISTERED = KBTS_FOURCC(0, 0, 0, 0), // Features that aren't pre-defined in the OpenType spec KBTS_FEATURE_TAG_isol = KBTS_FOURCC('i', 's', 'o', 'l'), // Isolated Forms KBTS_FEATURE_TAG_fina = KBTS_FOURCC('f', 'i', 'n', 'a'), // Terminal Forms KBTS_FEATURE_TAG_fin2 = KBTS_FOURCC('f', 'i', 'n', '2'), // Terminal Forms #2 KBTS_FEATURE_TAG_fin3 = KBTS_FOURCC('f', 'i', 'n', '3'), // Terminal Forms #3 KBTS_FEATURE_TAG_medi = KBTS_FOURCC('m', 'e', 'd', 'i'), // Medial Forms KBTS_FEATURE_TAG_med2 = KBTS_FOURCC('m', 'e', 'd', '2'), // Medial Forms #2 KBTS_FEATURE_TAG_init = KBTS_FOURCC('i', 'n', 'i', 't'), // Initial Forms KBTS_FEATURE_TAG_ljmo = KBTS_FOURCC('l', 'j', 'm', 'o'), // Leading Jamo Forms KBTS_FEATURE_TAG_vjmo = KBTS_FOURCC('v', 'j', 'm', 'o'), // Vowel Jamo Forms KBTS_FEATURE_TAG_tjmo = KBTS_FOURCC('t', 'j', 'm', 'o'), // Trailing Jamo Forms KBTS_FEATURE_TAG_rphf = KBTS_FOURCC('r', 'p', 'h', 'f'), // Reph Form KBTS_FEATURE_TAG_blwf = KBTS_FOURCC('b', 'l', 'w', 'f'), // Below-base Forms KBTS_FEATURE_TAG_half = KBTS_FOURCC('h', 'a', 'l', 'f'), // Half Forms KBTS_FEATURE_TAG_pstf = KBTS_FOURCC('p', 's', 't', 'f'), // Post-base Forms KBTS_FEATURE_TAG_abvf = KBTS_FOURCC('a', 'b', 'v', 'f'), // Above-base Forms KBTS_FEATURE_TAG_pref = KBTS_FOURCC('p', 'r', 'e', 'f'), // Pre-base Forms KBTS_FEATURE_TAG_numr = KBTS_FOURCC('n', 'u', 'm', 'r'), // Numerators KBTS_FEATURE_TAG_frac = KBTS_FOURCC('f', 'r', 'a', 'c'), // Fractions KBTS_FEATURE_TAG_dnom = KBTS_FOURCC('d', 'n', 'o', 'm'), // Denominators KBTS_FEATURE_TAG_cfar = KBTS_FOURCC('c', 'f', 'a', 'r'), // Conjunct Form After Ro KBTS_FEATURE_TAG_aalt = KBTS_FOURCC('a', 'a', 'l', 't'), // Access All Alternates KBTS_FEATURE_TAG_abvm = KBTS_FOURCC('a', 'b', 'v', 'm'), // Above-base Mark Positioning KBTS_FEATURE_TAG_abvs = KBTS_FOURCC('a', 'b', 'v', 's'), // Above-base Substitutions KBTS_FEATURE_TAG_afrc = KBTS_FOURCC('a', 'f', 'r', 'c'), // Alternative Fractions KBTS_FEATURE_TAG_akhn = KBTS_FOURCC('a', 'k', 'h', 'n'), // Akhand KBTS_FEATURE_TAG_apkn = KBTS_FOURCC('a', 'p', 'k', 'n'), // Kerning for Alternate Proportional Widths KBTS_FEATURE_TAG_blwm = KBTS_FOURCC('b', 'l', 'w', 'm'), // Below-base Mark Positioning KBTS_FEATURE_TAG_blws = KBTS_FOURCC('b', 'l', 'w', 's'), // Below-base Substitutions KBTS_FEATURE_TAG_calt = KBTS_FOURCC('c', 'a', 'l', 't'), // Contextual Alternates KBTS_FEATURE_TAG_case = KBTS_FOURCC('c', 'a', 's', 'e'), // Case-sensitive Forms KBTS_FEATURE_TAG_ccmp = KBTS_FOURCC('c', 'c', 'm', 'p'), // Glyph Composition / Decomposition KBTS_FEATURE_TAG_chws = KBTS_FOURCC('c', 'h', 'w', 's'), // Contextual Half-width Spacing KBTS_FEATURE_TAG_cjct = KBTS_FOURCC('c', 'j', 'c', 't'), // Conjunct Forms KBTS_FEATURE_TAG_clig = KBTS_FOURCC('c', 'l', 'i', 'g'), // Contextual Ligatures KBTS_FEATURE_TAG_cpct = KBTS_FOURCC('c', 'p', 'c', 't'), // Centered CJK Punctuation KBTS_FEATURE_TAG_cpsp = KBTS_FOURCC('c', 'p', 's', 'p'), // Capital Spacing KBTS_FEATURE_TAG_cswh = KBTS_FOURCC('c', 's', 'w', 'h'), // Contextual Swash KBTS_FEATURE_TAG_curs = KBTS_FOURCC('c', 'u', 'r', 's'), // Cursive Positioning KBTS_FEATURE_TAG_cv01 = KBTS_FOURCC('c', 'v', '0', '1'), // Character Variant 1 KBTS_FEATURE_TAG_cv02 = KBTS_FOURCC('c', 'v', '0', '2'), // Character Variant 2 KBTS_FEATURE_TAG_cv03 = KBTS_FOURCC('c', 'v', '0', '3'), // Character Variant 3 KBTS_FEATURE_TAG_cv04 = KBTS_FOURCC('c', 'v', '0', '4'), // Character Variant 4 KBTS_FEATURE_TAG_cv05 = KBTS_FOURCC('c', 'v', '0', '5'), // Character Variant 5 KBTS_FEATURE_TAG_cv06 = KBTS_FOURCC('c', 'v', '0', '6'), // Character Variant 6 KBTS_FEATURE_TAG_cv07 = KBTS_FOURCC('c', 'v', '0', '7'), // Character Variant 7 KBTS_FEATURE_TAG_cv08 = KBTS_FOURCC('c', 'v', '0', '8'), // Character Variant 8 KBTS_FEATURE_TAG_cv09 = KBTS_FOURCC('c', 'v', '0', '9'), // Character Variant 9 KBTS_FEATURE_TAG_cv10 = KBTS_FOURCC('c', 'v', '1', '0'), // Character Variant 10 KBTS_FEATURE_TAG_cv11 = KBTS_FOURCC('c', 'v', '1', '1'), // Character Variant 11 KBTS_FEATURE_TAG_cv12 = KBTS_FOURCC('c', 'v', '1', '2'), // Character Variant 12 KBTS_FEATURE_TAG_cv13 = KBTS_FOURCC('c', 'v', '1', '3'), // Character Variant 13 KBTS_FEATURE_TAG_cv14 = KBTS_FOURCC('c', 'v', '1', '4'), // Character Variant 14 KBTS_FEATURE_TAG_cv15 = KBTS_FOURCC('c', 'v', '1', '5'), // Character Variant 15 KBTS_FEATURE_TAG_cv16 = KBTS_FOURCC('c', 'v', '1', '6'), // Character Variant 16 KBTS_FEATURE_TAG_cv17 = KBTS_FOURCC('c', 'v', '1', '7'), // Character Variant 17 KBTS_FEATURE_TAG_cv18 = KBTS_FOURCC('c', 'v', '1', '8'), // Character Variant 18 KBTS_FEATURE_TAG_cv19 = KBTS_FOURCC('c', 'v', '1', '9'), // Character Variant 19 KBTS_FEATURE_TAG_cv20 = KBTS_FOURCC('c', 'v', '2', '0'), // Character Variant 20 KBTS_FEATURE_TAG_cv21 = KBTS_FOURCC('c', 'v', '2', '1'), // Character Variant 21 KBTS_FEATURE_TAG_cv22 = KBTS_FOURCC('c', 'v', '2', '2'), // Character Variant 22 KBTS_FEATURE_TAG_cv23 = KBTS_FOURCC('c', 'v', '2', '3'), // Character Variant 23 KBTS_FEATURE_TAG_cv24 = KBTS_FOURCC('c', 'v', '2', '4'), // Character Variant 24 KBTS_FEATURE_TAG_cv25 = KBTS_FOURCC('c', 'v', '2', '5'), // Character Variant 25 KBTS_FEATURE_TAG_cv26 = KBTS_FOURCC('c', 'v', '2', '6'), // Character Variant 26 KBTS_FEATURE_TAG_cv27 = KBTS_FOURCC('c', 'v', '2', '7'), // Character Variant 27 KBTS_FEATURE_TAG_cv28 = KBTS_FOURCC('c', 'v', '2', '8'), // Character Variant 28 KBTS_FEATURE_TAG_cv29 = KBTS_FOURCC('c', 'v', '2', '9'), // Character Variant 29 KBTS_FEATURE_TAG_cv30 = KBTS_FOURCC('c', 'v', '3', '0'), // Character Variant 30 KBTS_FEATURE_TAG_cv31 = KBTS_FOURCC('c', 'v', '3', '1'), // Character Variant 31 KBTS_FEATURE_TAG_cv32 = KBTS_FOURCC('c', 'v', '3', '2'), // Character Variant 32 KBTS_FEATURE_TAG_cv33 = KBTS_FOURCC('c', 'v', '3', '3'), // Character Variant 33 KBTS_FEATURE_TAG_cv34 = KBTS_FOURCC('c', 'v', '3', '4'), // Character Variant 34 KBTS_FEATURE_TAG_cv35 = KBTS_FOURCC('c', 'v', '3', '5'), // Character Variant 35 KBTS_FEATURE_TAG_cv36 = KBTS_FOURCC('c', 'v', '3', '6'), // Character Variant 36 KBTS_FEATURE_TAG_cv37 = KBTS_FOURCC('c', 'v', '3', '7'), // Character Variant 37 KBTS_FEATURE_TAG_cv38 = KBTS_FOURCC('c', 'v', '3', '8'), // Character Variant 38 KBTS_FEATURE_TAG_cv39 = KBTS_FOURCC('c', 'v', '3', '9'), // Character Variant 39 KBTS_FEATURE_TAG_cv40 = KBTS_FOURCC('c', 'v', '4', '0'), // Character Variant 40 KBTS_FEATURE_TAG_cv41 = KBTS_FOURCC('c', 'v', '4', '1'), // Character Variant 41 KBTS_FEATURE_TAG_cv42 = KBTS_FOURCC('c', 'v', '4', '2'), // Character Variant 42 KBTS_FEATURE_TAG_cv43 = KBTS_FOURCC('c', 'v', '4', '3'), // Character Variant 43 KBTS_FEATURE_TAG_cv44 = KBTS_FOURCC('c', 'v', '4', '4'), // Character Variant 44 KBTS_FEATURE_TAG_cv45 = KBTS_FOURCC('c', 'v', '4', '5'), // Character Variant 45 KBTS_FEATURE_TAG_cv46 = KBTS_FOURCC('c', 'v', '4', '6'), // Character Variant 46 KBTS_FEATURE_TAG_cv47 = KBTS_FOURCC('c', 'v', '4', '7'), // Character Variant 47 KBTS_FEATURE_TAG_cv48 = KBTS_FOURCC('c', 'v', '4', '8'), // Character Variant 48 KBTS_FEATURE_TAG_cv49 = KBTS_FOURCC('c', 'v', '4', '9'), // Character Variant 49 KBTS_FEATURE_TAG_cv50 = KBTS_FOURCC('c', 'v', '5', '0'), // Character Variant 50 KBTS_FEATURE_TAG_cv51 = KBTS_FOURCC('c', 'v', '5', '1'), // Character Variant 51 KBTS_FEATURE_TAG_cv52 = KBTS_FOURCC('c', 'v', '5', '2'), // Character Variant 52 KBTS_FEATURE_TAG_cv53 = KBTS_FOURCC('c', 'v', '5', '3'), // Character Variant 53 KBTS_FEATURE_TAG_cv54 = KBTS_FOURCC('c', 'v', '5', '4'), // Character Variant 54 KBTS_FEATURE_TAG_cv55 = KBTS_FOURCC('c', 'v', '5', '5'), // Character Variant 55 KBTS_FEATURE_TAG_cv56 = KBTS_FOURCC('c', 'v', '5', '6'), // Character Variant 56 KBTS_FEATURE_TAG_cv57 = KBTS_FOURCC('c', 'v', '5', '7'), // Character Variant 57 KBTS_FEATURE_TAG_cv58 = KBTS_FOURCC('c', 'v', '5', '8'), // Character Variant 58 KBTS_FEATURE_TAG_cv59 = KBTS_FOURCC('c', 'v', '5', '9'), // Character Variant 59 KBTS_FEATURE_TAG_cv60 = KBTS_FOURCC('c', 'v', '6', '0'), // Character Variant 60 KBTS_FEATURE_TAG_cv61 = KBTS_FOURCC('c', 'v', '6', '1'), // Character Variant 61 KBTS_FEATURE_TAG_cv62 = KBTS_FOURCC('c', 'v', '6', '2'), // Character Variant 62 KBTS_FEATURE_TAG_cv63 = KBTS_FOURCC('c', 'v', '6', '3'), // Character Variant 63 KBTS_FEATURE_TAG_cv64 = KBTS_FOURCC('c', 'v', '6', '4'), // Character Variant 64 KBTS_FEATURE_TAG_cv65 = KBTS_FOURCC('c', 'v', '6', '5'), // Character Variant 65 KBTS_FEATURE_TAG_cv66 = KBTS_FOURCC('c', 'v', '6', '6'), // Character Variant 66 KBTS_FEATURE_TAG_cv67 = KBTS_FOURCC('c', 'v', '6', '7'), // Character Variant 67 KBTS_FEATURE_TAG_cv68 = KBTS_FOURCC('c', 'v', '6', '8'), // Character Variant 68 KBTS_FEATURE_TAG_cv69 = KBTS_FOURCC('c', 'v', '6', '9'), // Character Variant 69 KBTS_FEATURE_TAG_cv70 = KBTS_FOURCC('c', 'v', '7', '0'), // Character Variant 70 KBTS_FEATURE_TAG_cv71 = KBTS_FOURCC('c', 'v', '7', '1'), // Character Variant 71 KBTS_FEATURE_TAG_cv72 = KBTS_FOURCC('c', 'v', '7', '2'), // Character Variant 72 KBTS_FEATURE_TAG_cv73 = KBTS_FOURCC('c', 'v', '7', '3'), // Character Variant 73 KBTS_FEATURE_TAG_cv74 = KBTS_FOURCC('c', 'v', '7', '4'), // Character Variant 74 KBTS_FEATURE_TAG_cv75 = KBTS_FOURCC('c', 'v', '7', '5'), // Character Variant 75 KBTS_FEATURE_TAG_cv76 = KBTS_FOURCC('c', 'v', '7', '6'), // Character Variant 76 KBTS_FEATURE_TAG_cv77 = KBTS_FOURCC('c', 'v', '7', '7'), // Character Variant 77 KBTS_FEATURE_TAG_cv78 = KBTS_FOURCC('c', 'v', '7', '8'), // Character Variant 78 KBTS_FEATURE_TAG_cv79 = KBTS_FOURCC('c', 'v', '7', '9'), // Character Variant 79 KBTS_FEATURE_TAG_cv80 = KBTS_FOURCC('c', 'v', '8', '0'), // Character Variant 80 KBTS_FEATURE_TAG_cv81 = KBTS_FOURCC('c', 'v', '8', '1'), // Character Variant 81 KBTS_FEATURE_TAG_cv82 = KBTS_FOURCC('c', 'v', '8', '2'), // Character Variant 82 KBTS_FEATURE_TAG_cv83 = KBTS_FOURCC('c', 'v', '8', '3'), // Character Variant 83 KBTS_FEATURE_TAG_cv84 = KBTS_FOURCC('c', 'v', '8', '4'), // Character Variant 84 KBTS_FEATURE_TAG_cv85 = KBTS_FOURCC('c', 'v', '8', '5'), // Character Variant 85 KBTS_FEATURE_TAG_cv86 = KBTS_FOURCC('c', 'v', '8', '6'), // Character Variant 86 KBTS_FEATURE_TAG_cv87 = KBTS_FOURCC('c', 'v', '8', '7'), // Character Variant 87 KBTS_FEATURE_TAG_cv88 = KBTS_FOURCC('c', 'v', '8', '8'), // Character Variant 88 KBTS_FEATURE_TAG_cv89 = KBTS_FOURCC('c', 'v', '8', '9'), // Character Variant 89 KBTS_FEATURE_TAG_cv90 = KBTS_FOURCC('c', 'v', '9', '0'), // Character Variant 90 KBTS_FEATURE_TAG_cv91 = KBTS_FOURCC('c', 'v', '9', '1'), // Character Variant 91 KBTS_FEATURE_TAG_cv92 = KBTS_FOURCC('c', 'v', '9', '2'), // Character Variant 92 KBTS_FEATURE_TAG_cv93 = KBTS_FOURCC('c', 'v', '9', '3'), // Character Variant 93 KBTS_FEATURE_TAG_cv94 = KBTS_FOURCC('c', 'v', '9', '4'), // Character Variant 94 KBTS_FEATURE_TAG_cv95 = KBTS_FOURCC('c', 'v', '9', '5'), // Character Variant 95 KBTS_FEATURE_TAG_cv96 = KBTS_FOURCC('c', 'v', '9', '6'), // Character Variant 96 KBTS_FEATURE_TAG_cv97 = KBTS_FOURCC('c', 'v', '9', '7'), // Character Variant 97 KBTS_FEATURE_TAG_cv98 = KBTS_FOURCC('c', 'v', '9', '8'), // Character Variant 98 KBTS_FEATURE_TAG_cv99 = KBTS_FOURCC('c', 'v', '9', '9'), // Character Variant 99 KBTS_FEATURE_TAG_c2pc = KBTS_FOURCC('c', '2', 'p', 'c'), // Petite Capitals From Capitals KBTS_FEATURE_TAG_c2sc = KBTS_FOURCC('c', '2', 's', 'c'), // Small Capitals From Capitals KBTS_FEATURE_TAG_dist = KBTS_FOURCC('d', 'i', 's', 't'), // Distances KBTS_FEATURE_TAG_dlig = KBTS_FOURCC('d', 'l', 'i', 'g'), // Discretionary Ligatures KBTS_FEATURE_TAG_dtls = KBTS_FOURCC('d', 't', 'l', 's'), // Dotless Forms KBTS_FEATURE_TAG_expt = KBTS_FOURCC('e', 'x', 'p', 't'), // Expert Forms KBTS_FEATURE_TAG_falt = KBTS_FOURCC('f', 'a', 'l', 't'), // Final Glyph on Line Alternates KBTS_FEATURE_TAG_flac = KBTS_FOURCC('f', 'l', 'a', 'c'), // Flattened Accent Forms KBTS_FEATURE_TAG_fwid = KBTS_FOURCC('f', 'w', 'i', 'd'), // Full Widths KBTS_FEATURE_TAG_haln = KBTS_FOURCC('h', 'a', 'l', 'n'), // Halant Forms KBTS_FEATURE_TAG_halt = KBTS_FOURCC('h', 'a', 'l', 't'), // Alternate Half Widths KBTS_FEATURE_TAG_hist = KBTS_FOURCC('h', 'i', 's', 't'), // Historical Forms KBTS_FEATURE_TAG_hkna = KBTS_FOURCC('h', 'k', 'n', 'a'), // Horizontal Kana Alternates KBTS_FEATURE_TAG_hlig = KBTS_FOURCC('h', 'l', 'i', 'g'), // Historical Ligatures KBTS_FEATURE_TAG_hngl = KBTS_FOURCC('h', 'n', 'g', 'l'), // Hangul KBTS_FEATURE_TAG_hojo = KBTS_FOURCC('h', 'o', 'j', 'o'), // Hojo Kanji Forms (JIS X 0212-1990 Kanji Forms) KBTS_FEATURE_TAG_hwid = KBTS_FOURCC('h', 'w', 'i', 'd'), // Half Widths KBTS_FEATURE_TAG_ital = KBTS_FOURCC('i', 't', 'a', 'l'), // Italics KBTS_FEATURE_TAG_jalt = KBTS_FOURCC('j', 'a', 'l', 't'), // Justification Alternates KBTS_FEATURE_TAG_jp78 = KBTS_FOURCC('j', 'p', '7', '8'), // JIS78 Forms KBTS_FEATURE_TAG_jp83 = KBTS_FOURCC('j', 'p', '8', '3'), // JIS83 Forms KBTS_FEATURE_TAG_jp90 = KBTS_FOURCC('j', 'p', '9', '0'), // JIS90 Forms KBTS_FEATURE_TAG_jp04 = KBTS_FOURCC('j', 'p', '0', '4'), // JIS2004 Forms KBTS_FEATURE_TAG_kern = KBTS_FOURCC('k', 'e', 'r', 'n'), // Kerning KBTS_FEATURE_TAG_lfbd = KBTS_FOURCC('l', 'f', 'b', 'd'), // Left Bounds KBTS_FEATURE_TAG_liga = KBTS_FOURCC('l', 'i', 'g', 'a'), // Standard Ligatures KBTS_FEATURE_TAG_lnum = KBTS_FOURCC('l', 'n', 'u', 'm'), // Lining Figures KBTS_FEATURE_TAG_locl = KBTS_FOURCC('l', 'o', 'c', 'l'), // Localized Forms KBTS_FEATURE_TAG_ltra = KBTS_FOURCC('l', 't', 'r', 'a'), // Left-to-right Alternates KBTS_FEATURE_TAG_ltrm = KBTS_FOURCC('l', 't', 'r', 'm'), // Left-to-right Mirrored Forms KBTS_FEATURE_TAG_mark = KBTS_FOURCC('m', 'a', 'r', 'k'), // Mark Positioning KBTS_FEATURE_TAG_mgrk = KBTS_FOURCC('m', 'g', 'r', 'k'), // Mathematical Greek KBTS_FEATURE_TAG_mkmk = KBTS_FOURCC('m', 'k', 'm', 'k'), // Mark to Mark Positioning KBTS_FEATURE_TAG_mset = KBTS_FOURCC('m', 's', 'e', 't'), // Mark Positioning via Substitution KBTS_FEATURE_TAG_nalt = KBTS_FOURCC('n', 'a', 'l', 't'), // Alternate Annotation Forms KBTS_FEATURE_TAG_nlck = KBTS_FOURCC('n', 'l', 'c', 'k'), // NLC Kanji Forms KBTS_FEATURE_TAG_nukt = KBTS_FOURCC('n', 'u', 'k', 't'), // Nukta Forms KBTS_FEATURE_TAG_onum = KBTS_FOURCC('o', 'n', 'u', 'm'), // Oldstyle Figures KBTS_FEATURE_TAG_opbd = KBTS_FOURCC('o', 'p', 'b', 'd'), // Optical Bounds KBTS_FEATURE_TAG_ordn = KBTS_FOURCC('o', 'r', 'd', 'n'), // Ordinals KBTS_FEATURE_TAG_ornm = KBTS_FOURCC('o', 'r', 'n', 'm'), // Ornaments KBTS_FEATURE_TAG_palt = KBTS_FOURCC('p', 'a', 'l', 't'), // Proportional Alternate Widths KBTS_FEATURE_TAG_pcap = KBTS_FOURCC('p', 'c', 'a', 'p'), // Petite Capitals KBTS_FEATURE_TAG_pkna = KBTS_FOURCC('p', 'k', 'n', 'a'), // Proportional Kana KBTS_FEATURE_TAG_pnum = KBTS_FOURCC('p', 'n', 'u', 'm'), // Proportional Figures KBTS_FEATURE_TAG_pres = KBTS_FOURCC('p', 'r', 'e', 's'), // Pre-base Substitutions KBTS_FEATURE_TAG_psts = KBTS_FOURCC('p', 's', 't', 's'), // Post-base Substitutions KBTS_FEATURE_TAG_pwid = KBTS_FOURCC('p', 'w', 'i', 'd'), // Proportional Widths KBTS_FEATURE_TAG_qwid = KBTS_FOURCC('q', 'w', 'i', 'd'), // Quarter Widths KBTS_FEATURE_TAG_rand = KBTS_FOURCC('r', 'a', 'n', 'd'), // Randomize KBTS_FEATURE_TAG_rclt = KBTS_FOURCC('r', 'c', 'l', 't'), // Required Contextual Alternates KBTS_FEATURE_TAG_rkrf = KBTS_FOURCC('r', 'k', 'r', 'f'), // Rakar Forms KBTS_FEATURE_TAG_rlig = KBTS_FOURCC('r', 'l', 'i', 'g'), // Required Ligatures KBTS_FEATURE_TAG_rtbd = KBTS_FOURCC('r', 't', 'b', 'd'), // Right Bounds KBTS_FEATURE_TAG_rtla = KBTS_FOURCC('r', 't', 'l', 'a'), // Right-to-left Alternates KBTS_FEATURE_TAG_rtlm = KBTS_FOURCC('r', 't', 'l', 'm'), // Right-to-left Mirrored Forms KBTS_FEATURE_TAG_ruby = KBTS_FOURCC('r', 'u', 'b', 'y'), // Ruby Notation Forms KBTS_FEATURE_TAG_rvrn = KBTS_FOURCC('r', 'v', 'r', 'n'), // Required Variation Alternates KBTS_FEATURE_TAG_salt = KBTS_FOURCC('s', 'a', 'l', 't'), // Stylistic Alternates KBTS_FEATURE_TAG_sinf = KBTS_FOURCC('s', 'i', 'n', 'f'), // Scientific Inferiors KBTS_FEATURE_TAG_size = KBTS_FOURCC('s', 'i', 'z', 'e'), // Optical size KBTS_FEATURE_TAG_smcp = KBTS_FOURCC('s', 'm', 'c', 'p'), // Small Capitals KBTS_FEATURE_TAG_smpl = KBTS_FOURCC('s', 'm', 'p', 'l'), // Simplified Forms KBTS_FEATURE_TAG_ss01 = KBTS_FOURCC('s', 's', '0', '1'), // Stylistic Set 1 KBTS_FEATURE_TAG_ss02 = KBTS_FOURCC('s', 's', '0', '2'), // Stylistic Set 2 KBTS_FEATURE_TAG_ss03 = KBTS_FOURCC('s', 's', '0', '3'), // Stylistic Set 3 KBTS_FEATURE_TAG_ss04 = KBTS_FOURCC('s', 's', '0', '4'), // Stylistic Set 4 KBTS_FEATURE_TAG_ss05 = KBTS_FOURCC('s', 's', '0', '5'), // Stylistic Set 5 KBTS_FEATURE_TAG_ss06 = KBTS_FOURCC('s', 's', '0', '6'), // Stylistic Set 6 KBTS_FEATURE_TAG_ss07 = KBTS_FOURCC('s', 's', '0', '7'), // Stylistic Set 7 KBTS_FEATURE_TAG_ss08 = KBTS_FOURCC('s', 's', '0', '8'), // Stylistic Set 8 KBTS_FEATURE_TAG_ss09 = KBTS_FOURCC('s', 's', '0', '9'), // Stylistic Set 9 KBTS_FEATURE_TAG_ss10 = KBTS_FOURCC('s', 's', '1', '0'), // Stylistic Set 10 KBTS_FEATURE_TAG_ss11 = KBTS_FOURCC('s', 's', '1', '1'), // Stylistic Set 11 KBTS_FEATURE_TAG_ss12 = KBTS_FOURCC('s', 's', '1', '2'), // Stylistic Set 12 KBTS_FEATURE_TAG_ss13 = KBTS_FOURCC('s', 's', '1', '3'), // Stylistic Set 13 KBTS_FEATURE_TAG_ss14 = KBTS_FOURCC('s', 's', '1', '4'), // Stylistic Set 14 KBTS_FEATURE_TAG_ss15 = KBTS_FOURCC('s', 's', '1', '5'), // Stylistic Set 15 KBTS_FEATURE_TAG_ss16 = KBTS_FOURCC('s', 's', '1', '6'), // Stylistic Set 16 KBTS_FEATURE_TAG_ss17 = KBTS_FOURCC('s', 's', '1', '7'), // Stylistic Set 17 KBTS_FEATURE_TAG_ss18 = KBTS_FOURCC('s', 's', '1', '8'), // Stylistic Set 18 KBTS_FEATURE_TAG_ss19 = KBTS_FOURCC('s', 's', '1', '9'), // Stylistic Set 19 KBTS_FEATURE_TAG_ss20 = KBTS_FOURCC('s', 's', '2', '0'), // Stylistic Set 20 KBTS_FEATURE_TAG_ssty = KBTS_FOURCC('s', 's', 't', 'y'), // Math Script-style Alternates KBTS_FEATURE_TAG_stch = KBTS_FOURCC('s', 't', 'c', 'h'), // Stretching Glyph Decomposition KBTS_FEATURE_TAG_subs = KBTS_FOURCC('s', 'u', 'b', 's'), // Subscript KBTS_FEATURE_TAG_sups = KBTS_FOURCC('s', 'u', 'p', 's'), // Superscript KBTS_FEATURE_TAG_swsh = KBTS_FOURCC('s', 'w', 's', 'h'), // Swash KBTS_FEATURE_TAG_test = KBTS_FOURCC('t', 'e', 's', 't'), // Test features, only for development KBTS_FEATURE_TAG_titl = KBTS_FOURCC('t', 'i', 't', 'l'), // Titling KBTS_FEATURE_TAG_tnam = KBTS_FOURCC('t', 'n', 'a', 'm'), // Traditional Name Forms KBTS_FEATURE_TAG_tnum = KBTS_FOURCC('t', 'n', 'u', 'm'), // Tabular Figures KBTS_FEATURE_TAG_trad = KBTS_FOURCC('t', 'r', 'a', 'd'), // Traditional Forms KBTS_FEATURE_TAG_twid = KBTS_FOURCC('t', 'w', 'i', 'd'), // Third Widths KBTS_FEATURE_TAG_unic = KBTS_FOURCC('u', 'n', 'i', 'c'), // Unicase KBTS_FEATURE_TAG_valt = KBTS_FOURCC('v', 'a', 'l', 't'), // Alternate Vertical Metrics KBTS_FEATURE_TAG_vapk = KBTS_FOURCC('v', 'a', 'p', 'k'), // Kerning for Alternate Proportional Vertical Metrics KBTS_FEATURE_TAG_vatu = KBTS_FOURCC('v', 'a', 't', 'u'), // Vattu Variants KBTS_FEATURE_TAG_vchw = KBTS_FOURCC('v', 'c', 'h', 'w'), // Vertical Contextual Half-width Spacing KBTS_FEATURE_TAG_vert = KBTS_FOURCC('v', 'e', 'r', 't'), // Vertical Alternates KBTS_FEATURE_TAG_vhal = KBTS_FOURCC('v', 'h', 'a', 'l'), // Alternate Vertical Half Metrics KBTS_FEATURE_TAG_vkna = KBTS_FOURCC('v', 'k', 'n', 'a'), // Vertical Kana Alternates KBTS_FEATURE_TAG_vkrn = KBTS_FOURCC('v', 'k', 'r', 'n'), // Vertical Kerning KBTS_FEATURE_TAG_vpal = KBTS_FOURCC('v', 'p', 'a', 'l'), // Proportional Alternate Vertical Metrics KBTS_FEATURE_TAG_vrt2 = KBTS_FOURCC('v', 'r', 't', '2'), // Vertical Alternates and Rotation KBTS_FEATURE_TAG_vrtr = KBTS_FOURCC('v', 'r', 't', 'r'), // Vertical Alternates for Rotation KBTS_FEATURE_TAG_zero = KBTS_FOURCC('z', 'e', 'r', 'o'), // Slashed Zero }; typedef kbts_u32 kbts_feature_id; enum kbts_feature_id_enum { KBTS_FEATURE_ID_UNREGISTERED, // Features that aren't pre-defined in the OpenType spec KBTS_FEATURE_ID_isol, // Isolated Forms KBTS_FEATURE_ID_fina, // Terminal Forms KBTS_FEATURE_ID_fin2, // Terminal Forms #2 KBTS_FEATURE_ID_fin3, // Terminal Forms #3 KBTS_FEATURE_ID_medi, // Medial Forms KBTS_FEATURE_ID_med2, // Medial Forms #2 KBTS_FEATURE_ID_init, // Initial Forms KBTS_FEATURE_ID_ljmo, // Leading Jamo Forms KBTS_FEATURE_ID_vjmo, // Vowel Jamo Forms KBTS_FEATURE_ID_tjmo, // Trailing Jamo Forms KBTS_FEATURE_ID_rphf, // Reph Form KBTS_FEATURE_ID_blwf, // Below-base Forms KBTS_FEATURE_ID_half, // Half Forms KBTS_FEATURE_ID_pstf, // Post-base Forms KBTS_FEATURE_ID_abvf, // Above-base Forms KBTS_FEATURE_ID_pref, // Pre-base Forms KBTS_FEATURE_ID_numr, // Numerators KBTS_FEATURE_ID_frac, // Fractions KBTS_FEATURE_ID_dnom, // Denominators KBTS_FEATURE_ID_cfar, // Conjunct Form After Ro KBTS_FEATURE_ID_aalt, // Access All Alternates KBTS_FEATURE_ID_abvm, // Above-base Mark Positioning KBTS_FEATURE_ID_abvs, // Above-base Substitutions KBTS_FEATURE_ID_afrc, // Alternative Fractions KBTS_FEATURE_ID_akhn, // Akhand KBTS_FEATURE_ID_apkn, // Kerning for Alternate Proportional Widths KBTS_FEATURE_ID_blwm, // Below-base Mark Positioning KBTS_FEATURE_ID_blws, // Below-base Substitutions KBTS_FEATURE_ID_calt, // Contextual Alternates KBTS_FEATURE_ID_case, // Case-sensitive Forms KBTS_FEATURE_ID_ccmp, // Glyph Composition / Decomposition KBTS_FEATURE_ID_chws, // Contextual Half-width Spacing KBTS_FEATURE_ID_cjct, // Conjunct Forms KBTS_FEATURE_ID_clig, // Contextual Ligatures KBTS_FEATURE_ID_cpct, // Centered CJK Punctuation KBTS_FEATURE_ID_cpsp, // Capital Spacing KBTS_FEATURE_ID_cswh, // Contextual Swash KBTS_FEATURE_ID_curs, // Cursive Positioning KBTS_FEATURE_ID_cv01, // Character Variant 1 KBTS_FEATURE_ID_cv02, // Character Variant 2 KBTS_FEATURE_ID_cv03, // Character Variant 3 KBTS_FEATURE_ID_cv04, // Character Variant 4 KBTS_FEATURE_ID_cv05, // Character Variant 5 KBTS_FEATURE_ID_cv06, // Character Variant 6 KBTS_FEATURE_ID_cv07, // Character Variant 7 KBTS_FEATURE_ID_cv08, // Character Variant 8 KBTS_FEATURE_ID_cv09, // Character Variant 9 KBTS_FEATURE_ID_cv10, // Character Variant 10 KBTS_FEATURE_ID_cv11, // Character Variant 11 KBTS_FEATURE_ID_cv12, // Character Variant 12 KBTS_FEATURE_ID_cv13, // Character Variant 13 KBTS_FEATURE_ID_cv14, // Character Variant 14 KBTS_FEATURE_ID_cv15, // Character Variant 15 KBTS_FEATURE_ID_cv16, // Character Variant 16 KBTS_FEATURE_ID_cv17, // Character Variant 17 KBTS_FEATURE_ID_cv18, // Character Variant 18 KBTS_FEATURE_ID_cv19, // Character Variant 19 KBTS_FEATURE_ID_cv20, // Character Variant 20 KBTS_FEATURE_ID_cv21, // Character Variant 21 KBTS_FEATURE_ID_cv22, // Character Variant 22 KBTS_FEATURE_ID_cv23, // Character Variant 23 KBTS_FEATURE_ID_cv24, // Character Variant 24 KBTS_FEATURE_ID_cv25, // Character Variant 25 KBTS_FEATURE_ID_cv26, // Character Variant 26 KBTS_FEATURE_ID_cv27, // Character Variant 27 KBTS_FEATURE_ID_cv28, // Character Variant 28 KBTS_FEATURE_ID_cv29, // Character Variant 29 KBTS_FEATURE_ID_cv30, // Character Variant 30 KBTS_FEATURE_ID_cv31, // Character Variant 31 KBTS_FEATURE_ID_cv32, // Character Variant 32 KBTS_FEATURE_ID_cv33, // Character Variant 33 KBTS_FEATURE_ID_cv34, // Character Variant 34 KBTS_FEATURE_ID_cv35, // Character Variant 35 KBTS_FEATURE_ID_cv36, // Character Variant 36 KBTS_FEATURE_ID_cv37, // Character Variant 37 KBTS_FEATURE_ID_cv38, // Character Variant 38 KBTS_FEATURE_ID_cv39, // Character Variant 39 KBTS_FEATURE_ID_cv40, // Character Variant 40 KBTS_FEATURE_ID_cv41, // Character Variant 41 KBTS_FEATURE_ID_cv42, // Character Variant 42 KBTS_FEATURE_ID_cv43, // Character Variant 43 KBTS_FEATURE_ID_cv44, // Character Variant 44 KBTS_FEATURE_ID_cv45, // Character Variant 45 KBTS_FEATURE_ID_cv46, // Character Variant 46 KBTS_FEATURE_ID_cv47, // Character Variant 47 KBTS_FEATURE_ID_cv48, // Character Variant 48 KBTS_FEATURE_ID_cv49, // Character Variant 49 KBTS_FEATURE_ID_cv50, // Character Variant 50 KBTS_FEATURE_ID_cv51, // Character Variant 51 KBTS_FEATURE_ID_cv52, // Character Variant 52 KBTS_FEATURE_ID_cv53, // Character Variant 53 KBTS_FEATURE_ID_cv54, // Character Variant 54 KBTS_FEATURE_ID_cv55, // Character Variant 55 KBTS_FEATURE_ID_cv56, // Character Variant 56 KBTS_FEATURE_ID_cv57, // Character Variant 57 KBTS_FEATURE_ID_cv58, // Character Variant 58 KBTS_FEATURE_ID_cv59, // Character Variant 59 KBTS_FEATURE_ID_cv60, // Character Variant 60 KBTS_FEATURE_ID_cv61, // Character Variant 61 KBTS_FEATURE_ID_cv62, // Character Variant 62 KBTS_FEATURE_ID_cv63, // Character Variant 63 KBTS_FEATURE_ID_cv64, // Character Variant 64 KBTS_FEATURE_ID_cv65, // Character Variant 65 KBTS_FEATURE_ID_cv66, // Character Variant 66 KBTS_FEATURE_ID_cv67, // Character Variant 67 KBTS_FEATURE_ID_cv68, // Character Variant 68 KBTS_FEATURE_ID_cv69, // Character Variant 69 KBTS_FEATURE_ID_cv70, // Character Variant 70 KBTS_FEATURE_ID_cv71, // Character Variant 71 KBTS_FEATURE_ID_cv72, // Character Variant 72 KBTS_FEATURE_ID_cv73, // Character Variant 73 KBTS_FEATURE_ID_cv74, // Character Variant 74 KBTS_FEATURE_ID_cv75, // Character Variant 75 KBTS_FEATURE_ID_cv76, // Character Variant 76 KBTS_FEATURE_ID_cv77, // Character Variant 77 KBTS_FEATURE_ID_cv78, // Character Variant 78 KBTS_FEATURE_ID_cv79, // Character Variant 79 KBTS_FEATURE_ID_cv80, // Character Variant 80 KBTS_FEATURE_ID_cv81, // Character Variant 81 KBTS_FEATURE_ID_cv82, // Character Variant 82 KBTS_FEATURE_ID_cv83, // Character Variant 83 KBTS_FEATURE_ID_cv84, // Character Variant 84 KBTS_FEATURE_ID_cv85, // Character Variant 85 KBTS_FEATURE_ID_cv86, // Character Variant 86 KBTS_FEATURE_ID_cv87, // Character Variant 87 KBTS_FEATURE_ID_cv88, // Character Variant 88 KBTS_FEATURE_ID_cv89, // Character Variant 89 KBTS_FEATURE_ID_cv90, // Character Variant 90 KBTS_FEATURE_ID_cv91, // Character Variant 91 KBTS_FEATURE_ID_cv92, // Character Variant 92 KBTS_FEATURE_ID_cv93, // Character Variant 93 KBTS_FEATURE_ID_cv94, // Character Variant 94 KBTS_FEATURE_ID_cv95, // Character Variant 95 KBTS_FEATURE_ID_cv96, // Character Variant 96 KBTS_FEATURE_ID_cv97, // Character Variant 97 KBTS_FEATURE_ID_cv98, // Character Variant 98 KBTS_FEATURE_ID_cv99, // Character Variant 99 KBTS_FEATURE_ID_c2pc, // Petite Capitals From Capitals KBTS_FEATURE_ID_c2sc, // Small Capitals From Capitals KBTS_FEATURE_ID_dist, // Distances KBTS_FEATURE_ID_dlig, // Discretionary Ligatures KBTS_FEATURE_ID_dtls, // Dotless Forms KBTS_FEATURE_ID_expt, // Expert Forms KBTS_FEATURE_ID_falt, // Final Glyph on Line Alternates KBTS_FEATURE_ID_flac, // Flattened Accent Forms KBTS_FEATURE_ID_fwid, // Full Widths KBTS_FEATURE_ID_haln, // Halant Forms KBTS_FEATURE_ID_halt, // Alternate Half Widths KBTS_FEATURE_ID_hist, // Historical Forms KBTS_FEATURE_ID_hkna, // Horizontal Kana Alternates KBTS_FEATURE_ID_hlig, // Historical Ligatures KBTS_FEATURE_ID_hngl, // Hangul KBTS_FEATURE_ID_hojo, // Hojo Kanji Forms (JIS X 0212-1990 Kanji Forms) KBTS_FEATURE_ID_hwid, // Half Widths KBTS_FEATURE_ID_ital, // Italics KBTS_FEATURE_ID_jalt, // Justification Alternates KBTS_FEATURE_ID_jp78, // JIS78 Forms KBTS_FEATURE_ID_jp83, // JIS83 Forms KBTS_FEATURE_ID_jp90, // JIS90 Forms KBTS_FEATURE_ID_jp04, // JIS2004 Forms KBTS_FEATURE_ID_kern, // Kerning KBTS_FEATURE_ID_lfbd, // Left Bounds KBTS_FEATURE_ID_liga, // Standard Ligatures KBTS_FEATURE_ID_lnum, // Lining Figures KBTS_FEATURE_ID_locl, // Localized Forms KBTS_FEATURE_ID_ltra, // Left-to-right Alternates KBTS_FEATURE_ID_ltrm, // Left-to-right Mirrored Forms KBTS_FEATURE_ID_mark, // Mark Positioning KBTS_FEATURE_ID_mgrk, // Mathematical Greek KBTS_FEATURE_ID_mkmk, // Mark to Mark Positioning KBTS_FEATURE_ID_mset, // Mark Positioning via Substitution KBTS_FEATURE_ID_nalt, // Alternate Annotation Forms KBTS_FEATURE_ID_nlck, // NLC Kanji Forms KBTS_FEATURE_ID_nukt, // Nukta Forms KBTS_FEATURE_ID_onum, // Oldstyle Figures KBTS_FEATURE_ID_opbd, // Optical Bounds KBTS_FEATURE_ID_ordn, // Ordinals KBTS_FEATURE_ID_ornm, // Ornaments KBTS_FEATURE_ID_palt, // Proportional Alternate Widths KBTS_FEATURE_ID_pcap, // Petite Capitals KBTS_FEATURE_ID_pkna, // Proportional Kana KBTS_FEATURE_ID_pnum, // Proportional Figures KBTS_FEATURE_ID_pres, // Pre-base Substitutions KBTS_FEATURE_ID_psts, // Post-base Substitutions KBTS_FEATURE_ID_pwid, // Proportional Widths KBTS_FEATURE_ID_qwid, // Quarter Widths KBTS_FEATURE_ID_rand, // Randomize KBTS_FEATURE_ID_rclt, // Required Contextual Alternates KBTS_FEATURE_ID_rkrf, // Rakar Forms KBTS_FEATURE_ID_rlig, // Required Ligatures KBTS_FEATURE_ID_rtbd, // Right Bounds KBTS_FEATURE_ID_rtla, // Right-to-left Alternates KBTS_FEATURE_ID_rtlm, // Right-to-left Mirrored Forms KBTS_FEATURE_ID_ruby, // Ruby Notation Forms KBTS_FEATURE_ID_rvrn, // Required Variation Alternates KBTS_FEATURE_ID_salt, // Stylistic Alternates KBTS_FEATURE_ID_sinf, // Scientific Inferiors KBTS_FEATURE_ID_size, // Optical size KBTS_FEATURE_ID_smcp, // Small Capitals KBTS_FEATURE_ID_smpl, // Simplified Forms KBTS_FEATURE_ID_ss01, // Stylistic Set 1 KBTS_FEATURE_ID_ss02, // Stylistic Set 2 KBTS_FEATURE_ID_ss03, // Stylistic Set 3 KBTS_FEATURE_ID_ss04, // Stylistic Set 4 KBTS_FEATURE_ID_ss05, // Stylistic Set 5 KBTS_FEATURE_ID_ss06, // Stylistic Set 6 KBTS_FEATURE_ID_ss07, // Stylistic Set 7 KBTS_FEATURE_ID_ss08, // Stylistic Set 8 KBTS_FEATURE_ID_ss09, // Stylistic Set 9 KBTS_FEATURE_ID_ss10, // Stylistic Set 10 KBTS_FEATURE_ID_ss11, // Stylistic Set 11 KBTS_FEATURE_ID_ss12, // Stylistic Set 12 KBTS_FEATURE_ID_ss13, // Stylistic Set 13 KBTS_FEATURE_ID_ss14, // Stylistic Set 14 KBTS_FEATURE_ID_ss15, // Stylistic Set 15 KBTS_FEATURE_ID_ss16, // Stylistic Set 16 KBTS_FEATURE_ID_ss17, // Stylistic Set 17 KBTS_FEATURE_ID_ss18, // Stylistic Set 18 KBTS_FEATURE_ID_ss19, // Stylistic Set 19 KBTS_FEATURE_ID_ss20, // Stylistic Set 20 KBTS_FEATURE_ID_ssty, // Math Script-style Alternates KBTS_FEATURE_ID_stch, // Stretching Glyph Decomposition KBTS_FEATURE_ID_subs, // Subscript KBTS_FEATURE_ID_sups, // Superscript KBTS_FEATURE_ID_swsh, // Swash KBTS_FEATURE_ID_test, // Test features, only for development KBTS_FEATURE_ID_titl, // Titling KBTS_FEATURE_ID_tnam, // Traditional Name Forms KBTS_FEATURE_ID_tnum, // Tabular Figures KBTS_FEATURE_ID_trad, // Traditional Forms KBTS_FEATURE_ID_twid, // Third Widths KBTS_FEATURE_ID_unic, // Unicase KBTS_FEATURE_ID_valt, // Alternate Vertical Metrics KBTS_FEATURE_ID_vapk, // Kerning for Alternate Proportional Vertical Metrics KBTS_FEATURE_ID_vatu, // Vattu Variants KBTS_FEATURE_ID_vchw, // Vertical Contextual Half-width Spacing KBTS_FEATURE_ID_vert, // Vertical Alternates KBTS_FEATURE_ID_vhal, // Alternate Vertical Half Metrics KBTS_FEATURE_ID_vkna, // Vertical Kana Alternates KBTS_FEATURE_ID_vkrn, // Vertical Kerning KBTS_FEATURE_ID_vpal, // Proportional Alternate Vertical Metrics KBTS_FEATURE_ID_vrt2, // Vertical Alternates and Rotation KBTS_FEATURE_ID_vrtr, // Vertical Alternates for Rotation KBTS_FEATURE_ID_zero, // Slashed Zero KBTS_FEATURE_ID_COUNT, }; typedef kbts_u8 kbts_shaping_table; enum kbts_shaping_table_enum { KBTS_SHAPING_TABLE_GSUB, KBTS_SHAPING_TABLE_GPOS, KBTS_SHAPING_TABLE_COUNT, }; typedef struct kbts_lookup_info { kbts_u32 MaximumBacktrackWithoutSkippingGlyphs; kbts_u32 MaximumLookaheadWithoutSkippingGlyphs; kbts_u32 MaximumSubstitutionOutputSize; kbts_u32 MaximumInputSequenceLength; kbts_u32 MaximumLookupStackSize; } kbts_lookup_info; typedef struct kbts_op_state kbts_op_state; typedef struct kbts_gdef kbts_gdef; typedef struct kbts_cmap_14 kbts_cmap_14; typedef struct kbts_gsub_gpos kbts_gsub_gpos; typedef struct kbts_maxp kbts_maxp; typedef struct kbts_hea kbts_hea; typedef struct kbts_iterate_features kbts_iterate_features; typedef struct kbts_shape_state kbts_shape_state; typedef struct kbts_shaper_properties kbts_shaper_properties; typedef struct kbts_feature kbts_feature; typedef struct kbts_head kbts_head; typedef struct kbts_lookup_subtable_info { kbts_u32 MinimumBacktrackPlusOne; kbts_u32 MinimumFollowupPlusOne; } kbts_lookup_subtable_info; typedef struct kbts_font { char *FileBase; kbts_un FileSize; kbts_head *Head; kbts_u16 *Cmap; kbts_gdef *Gdef; kbts_cmap_14 *Cmap14; kbts_gsub_gpos *ShapingTables[KBTS_SHAPING_TABLE_COUNT]; void *Fvar; kbts_maxp *Maxp; kbts_hea *Hea[KBTS_ORIENTATION_COUNT]; kbts_u16 *Mtx[KBTS_ORIENTATION_COUNT]; kbts_lookup_info LookupInfo; kbts_u32 GlyphCount; kbts_u32 LookupCount; kbts_u32 SubtableCount; kbts_u32 *GlyphLookupMatrix; // [LookupCount * GlyphCount] bitmap kbts_u32 *GlyphLookupSubtableMatrix; // [LookupSubtableCount * GlyphCount] bitmap kbts_u32 *LookupSubtableIndexOffsets; // [LookupCount] kbts_lookup_subtable_info *SubtableInfos; // [LookupSubtableCount] kbts_u32 GposLookupIndexOffset; int Error; } kbts_font; typedef struct kbts_glyph_classes { kbts_u16 Class; kbts_u16 MarkAttachmentClass; } kbts_glyph_classes; typedef struct kbts_feature_set { kbts_u64 Flags[(KBTS_FEATURE_ID_COUNT + 63) / 64]; } kbts_feature_set; typedef struct kbts_feature_override { kbts_feature_id Id; kbts_feature_tag Tag; kbts_u32 EnabledOrAlternatePlusOne; } kbts_feature_override; typedef struct kbts_glyph_config { kbts_feature_set EnabledFeatures; kbts_feature_set DisabledFeatures; kbts_u32 FeatureOverrideCount; kbts_u32 FeatureOverrideCapacity; kbts_u32 RequiredFeatureOverrideCapacity; kbts_feature_override *FeatureOverrides; // [FeatureOverrideCount] } kbts_glyph_config; typedef struct kbts_glyph { kbts_u32 Codepoint; kbts_u16 Id; // Glyph index. This is what you want to use to query outline data. kbts_u16 Uid; kbts_glyph_classes Classes; kbts_u64 Decomposition; kbts_glyph_config *Config; kbts_glyph_flags Flags; // These fields are the glyph's final positioning data. // For normal usage, you should not have to use these directly yourself. // In case you are curious or have a specific need, see kbts_PositionGlyph() to see how these are used. kbts_s32 OffsetX; kbts_s32 OffsetY; kbts_s32 AdvanceX; kbts_s32 AdvanceY; kbts_u32 ParentInfo; // This is set by GSUB and used by GPOS. // A 0-index means that we should attach to the last component in the ligature. // // From the Microsoft docs: // To correctly access the subtables, the client must keep track of the component associated with the mark. // // For a given mark assigned to a particular class, the appropriate base attachment point is determined by which // ligature component the mark is associated with. This is dependent on the original character string and subsequent // character- or glyph-sequence processing, not the font data alone. While a text-layout client is performing any // character-based preprocessing or any glyph-substitution operations using the GSUB table, the text-layout client // must keep track of associations of marks to particular ligature-glyph components. kbts_u16 LigatureUid; kbts_u16 LigatureComponentIndexPlusOne; // Earlier on, we used to assume that, if a glyph had no advance, or had the MARK glyph class, then // it could be handled as a mark in layout operations. This is inaccurate. // Unicode makes a distinction between attached marks and standalone marks. For our purposes, attached // marks are marks that have found a valid base character to attach to. In practice, this means that the // font contains a valid display position/configuration for it in the current context. // In contrast, standalone marks are marks that aren't attached to anything. Fonts may still have glyphs // for them, in which case we want to display those just like regular glyphs that take up horizontal space // on the line. When fonts don't have glyphs for them, they simply stay around as zero-width glyphs. // Standalone marks have notably different behavior compared to attached marks, and so, once we start // applying positioning features, it becomes worthwhile to track exactly which glyph has attached to which. kbts_u16 AttachGlyphIndexPlusOne; // Set by GPOS attachments. // Set in GSUB and used in GPOS, for STCH. kbts_joining_feature JoiningFeature; // Unicode properties filled in by CodepointToGlyph. kbts_unicode_joining_type JoiningType; kbts_u8 Script; kbts_u8 UnicodeFlags; kbts_u8 SyllabicClass; kbts_u8 SyllabicPosition; kbts_u8 UseClass; kbts_u8 CombiningClass; kbts_u8 MarkOrdering; // Only used temporarily in NORMALIZE for Arabic mark reordering. } kbts_glyph; typedef struct kbts_glyph_array { kbts_glyph *Glyphs; kbts_u32 Count; kbts_u32 TotalCount; kbts_u32 Capacity; kbts_u32 RequiredCapacity; } kbts_glyph_array; typedef struct kbts_op_state_normalize { kbts_un CodepointsToDecomposeCount; kbts_un AboveBaseGlyphCount; } kbts_op_state_normalize; typedef struct kbts_op_state_gsub { kbts_feature_set LookupFeatures; kbts_un LookupIndex; kbts_u32 GlyphFilter; kbts_u32 SkipFlags; } kbts_op_state_gsub; typedef struct kbts_op_state_normalize_hangul { kbts_glyph LvtGlyphs[4]; kbts_un LvtGlyphCount; } kbts_op_state_normalize_hangul; typedef union kbts_op_state_op_specific { kbts_op_state_normalize Normalize; kbts_op_state_gsub Gsub; kbts_op_state_normalize_hangul NormalizeHangul; } kbts_op_state_op_specific; typedef struct kbts_lookup_indices { kbts_u32 FeatureTag; kbts_u32 FeatureId; kbts_u32 SkipFlags; kbts_u32 GlyphFilter; kbts_u32 Count; kbts_u16 *Indices; } kbts_lookup_indices; typedef struct kbts_op { kbts_op_kind Kind; kbts_feature_set Features; } kbts_op; // This needs to be updated when we change the op lists! #define KBTS_MAX_SIMULTANEOUS_FEATURES 16 typedef struct kbts_op_state { kbts_un WrittenCount; kbts_un GlyphIndex; kbts_u32 FrameCount; kbts_u32 ResumePoint; kbts_u32 FeatureCount; kbts_lookup_indices FeatureLookupIndices[KBTS_MAX_SIMULTANEOUS_FEATURES]; kbts_u32 UnregisteredFeatureCount; kbts_feature_tag UnregisteredFeatureTags[KBTS_MAX_SIMULTANEOUS_FEATURES]; kbts_op_state_op_specific OpSpecific; // Ops are free to use the following as they please: // kbts_u8 LeftoverMemory[LeftoverMemorySize]; } kbts_op_state; typedef struct kbts_op_list { kbts_u8 *Ops; kbts_un Length; } kbts_op_list; typedef struct kbts_indic_script_properties { kbts_u32 ViramaCodepoint; kbts_u8 BlwfPostOnly; kbts_reph_position RephPosition; kbts_reph_encoding RephEncoding; kbts_syllabic_position RightSideMatraPosition; kbts_syllabic_position AboveBaseMatraPosition; kbts_syllabic_position BelowBaseMatraPosition; } kbts_indic_script_properties; typedef struct kbts_langsys kbts_langsys; typedef struct kbts_shape_config { kbts_font *Font; kbts_script Script; kbts_language Language; kbts_langsys *Langsys[KBTS_SHAPING_TABLE_COUNT]; kbts_op_list OpLists[4]; kbts_feature_set *Features; kbts_shaper Shaper; kbts_shaper_properties *ShaperProperties; kbts_indic_script_properties IndicScriptProperties; kbts_feature *Blwf; kbts_feature *Pref; kbts_feature *Pstf; kbts_feature *Locl; kbts_feature *Rphf; kbts_feature *Half; kbts_feature *Vatu; // Indic kbts_glyph Virama; kbts_glyph DottedCircle; kbts_glyph Whitespace; // Thai kbts_glyph Nikhahit; kbts_glyph SaraAa; } kbts_shape_config; typedef struct kbts_shape_state { kbts_op Op; kbts_shape_config *Config; kbts_direction MainDirection; kbts_direction RunDirection; kbts_feature_set UserFeatures; kbts_glyph_array GlyphArray; kbts_glyph_array ClusterGlyphArray; kbts_u32 DottedCircleInsertIndex; kbts_u32 GlyphCountStartingFromCurrentCluster; kbts_u32 At; kbts_u32 ResumePoint; kbts_u32 OpGlyphOffset; kbts_u32 ClusterGlyphCount; kbts_u32 Ip; kbts_u32 NextGlyphUid; kbts_u32 RequiredGlyphCapacity; int RealCluster; int ClusterAtStartOfWord; int WordBreak; // This must always be the last member! kbts_op_state OpState; } kbts_shape_state; typedef struct kbts_cursor { kbts_direction Direction; kbts_s32 LastAdvanceX; kbts_s32 X; kbts_s32 Y; } kbts_cursor; typedef struct kbts_break { // The break code mostly works in relative positions, but we convert to absolute positions for the user. // That way, breaks can be trivially stored and compared and such and it just works. kbts_u32 Position; kbts_break_flags Flags; kbts_direction Direction; // Only valid if (Flags & KBTS_BREAK_FLAG_DIRECTION). kbts_script Script; // Only valid if (Flags & KBTS_BREAK_FLAG_SCRIPT). } kbts_break; typedef struct kbts_bracket { kbts_u32 Codepoint; kbts_u8 Direction; kbts_u8 Script; } kbts_bracket; typedef kbts_u32 kbts_break_state_flags; enum kbts_break_state_flags_enum { KBTS_BREAK_STATE_FLAG_STARTED = 1, KBTS_BREAK_STATE_FLAG_END = 2, KBTS_BREAK_STATE_FLAG_RAN_OUT_OF_REORDER_BUFFER_SPACE = 4, // Bidirectional flags KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L = 8, KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR = 0x10, KBTS_BREAK_STATE_FLAG_LAST_WAS_BRACKET = 0x20, }; // In the worst case, a single call to BreakAddCodepoint would generate 4 breaks. // We buffer breaks to reorder them before returning them to the user. // This potentially requires infinite memory, which we don't have, so you may want to tweak this constant, // although, really, if the defaults don't work, then you have likely found very strange/adversarial text. #define KBTS_BREAK_REORDER_BUFFER_FLUSH_THRESHOLD 4 #define KBTS_BREAK_REORDER_BUFFER_SIZE (KBTS_BREAK_REORDER_BUFFER_FLUSH_THRESHOLD * 2) typedef struct kbts_break_state { kbts_break Breaks[KBTS_BREAK_REORDER_BUFFER_SIZE]; kbts_u32 BreakCount; kbts_direction MainDirection; kbts_u32 LastFlushedBreakPosition; kbts_u32 CurrentPosition; kbts_u8 LastScripts[2]; kbts_bracket Brackets[64]; kbts_u32 BracketCount; kbts_break_state_flags Flags; kbts_u32 FlagState; // u8(kbts_break_flags)x4 kbts_s16 PositionOffset2; kbts_s16 PositionOffset3; kbts_u32 WordBreakHistory; // u8x4 kbts_u16 WordBreaks; // u4x4 kbts_u16 WordUnbreaks; // u4x4 kbts_s16 WordBreak2PositionOffset; kbts_u64 LineBreaks; // u16x4 // Instead of staying synchronized with LineBreaks/LineUnbreaks, // this advances every character always. // (This is only needed because ZWJ can create an unbreak while simultaneously being ignored.) kbts_u64 LineUnbreaksAsync; // u16x4 kbts_u64 LineUnbreaks; // u16x4 kbts_u32 LineBreakHistory; // u8(line_break_class)x4 kbts_s16 LineBreak2PositionOffset; kbts_s16 LineBreak3PositionOffset; kbts_u8 LastDirection; kbts_u8 BidirectionalClass2; kbts_u8 BidirectionalClass1; kbts_japanese_line_break_style JapaneseLineBreakStyle; kbts_u8 GraphemeBreakState; kbts_u8 LastLineBreakClass; kbts_u8 LastWordBreakClass; kbts_u8 LastWordBreakClassIncludingIgnored; } kbts_break_state; typedef struct kbts_decode { kbts_u32 Codepoint; kbts_u32 SourceCharactersConsumed; kbts_u32 Valid; } kbts_decode; #ifndef KB_TEXT_SHAPE_NO_CRT KBTS_EXPORT kbts_font kbts_FontFromFile(const char *FileName); KBTS_EXPORT void kbts_FreeFont(kbts_font *Font); KBTS_EXPORT kbts_shape_state *kbts_CreateShapeState(kbts_font *Font); KBTS_EXPORT void kbts_FreeShapeState(kbts_shape_state *State); #endif KBTS_EXPORT kbts_feature_id kbts_FeatureTagToId(kbts_feature_tag Tag); KBTS_EXPORT kbts_feature_override kbts_FeatureOverride(kbts_feature_id Id, int Alternate, kbts_u32 Value); KBTS_EXPORT kbts_feature_override kbts_FeatureOverrideFromTag(kbts_feature_tag Tag, int Alternate, kbts_u32 Value); KBTS_EXPORT kbts_glyph_config kbts_GlyphConfig(kbts_feature_override *FeatureOverrides, kbts_u32 FeatureOverrideCount); KBTS_EXPORT kbts_glyph_config kbts_EmptyGlyphConfig(kbts_feature_override *FeatureOverrides, kbts_u32 FeatureOverrideCapacity); KBTS_EXPORT int kbts_GlyphConfigOverrideFeature(kbts_glyph_config *Config, kbts_feature_id Id, int Alternate, kbts_u32 Value); KBTS_EXPORT int kbts_GlyphConfigOverrideFeatureFromTag(kbts_glyph_config *Config, kbts_feature_tag Tag, int Alternate, kbts_u32 Value); KBTS_EXPORT int kbts_FontIsValid(kbts_font *Font); KBTS_EXPORT kbts_un kbts_ReadFontHeader(kbts_font *Font, void *Data, kbts_un Size); KBTS_EXPORT kbts_un kbts_ReadFontData(kbts_font *Font, void *Scratch, kbts_un ScratchSize); KBTS_EXPORT int kbts_PostReadFontInitialize(kbts_font *Font, void *Memory, kbts_un MemorySize); KBTS_EXPORT kbts_un kbts_SizeOfShapeState(kbts_font *Font); KBTS_EXPORT kbts_shape_state *kbts_PlaceShapeState(void *Address, kbts_un Size); KBTS_EXPORT void kbts_ResetShapeState(kbts_shape_state *State); KBTS_EXPORT kbts_shape_config kbts_ShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language); KBTS_EXPORT int kbts_ShaperIsComplex(kbts_shaper Shaper); KBTS_EXPORT int kbts_Shape(kbts_shape_state *State, kbts_shape_config *Config, kbts_direction MainDirection, kbts_direction RunDirection, kbts_glyph *Glyphs, kbts_u32 *GlyphCount, kbts_u32 GlyphCapacity); KBTS_EXPORT kbts_cursor kbts_Cursor(kbts_direction Direction); KBTS_EXPORT void kbts_PositionGlyph(kbts_cursor *Cursor, kbts_glyph *Glyph, kbts_s32 *X, kbts_s32 *Y); KBTS_EXPORT void kbts_BeginBreak(kbts_break_state *State, kbts_direction MainDirection, kbts_japanese_line_break_style JapaneseLineBreakStyle); KBTS_EXPORT int kbts_BreakStateIsValid(kbts_break_state *State); KBTS_EXPORT void kbts_BreakAddCodepoint(kbts_break_state *State, kbts_u32 Codepoint, kbts_u32 PositionIncrement, int EndOfText); KBTS_EXPORT void kbts_BreakFlush(kbts_break_state *State); KBTS_EXPORT int kbts_Break(kbts_break_state *State, kbts_break *Break); KBTS_EXPORT kbts_decode kbts_DecodeUtf8(const char *Utf8, kbts_un Length); KBTS_EXPORT kbts_glyph kbts_CodepointToGlyph(kbts_font *Font, kbts_u32 Codepoint); KBTS_EXPORT void kbts_InferScript(kbts_direction *Direction, kbts_script *Script, kbts_script GlyphScript); KBTS_EXPORT int kbts_ScriptIsComplex(kbts_script Script); KBTS_EXPORT kbts_script kbts_ScriptTagToScript(kbts_script_tag Tag); #endif #ifdef KB_TEXT_SHAPE_IMPLEMENTATION #ifdef _MSC_VER #define KBTS_UNUSED(X) (void)sizeof((X)) #else #define KBTS_UNUSED(X) (void)(X) #endif # define KBTS_FOR(I, Start, End) for(kbts_un I = (Start); I < (End); ++I) # ifdef __cplusplus # define KBTS_ZERO {} # define KBTS_ZERO_TYPE(T) T{} # else # define KBTS_ZERO {0} # define KBTS_ZERO_TYPE(T) (T){0} # endif # define KBTS_MAX(A, B) (((A) < (B)) ? (B) : (A)) # define KBTS_MIN(A, B) (((A) < (B)) ? (A) : (B)) # define KBTS_ARRAY_LENGTH(A) (sizeof(A)/sizeof(*(A))) # define KBTS_POINTER_AFTER(Type, X) ((Type *)((X) + 1)) # define KBTS_POINTER_OFFSET(Type, Base, Offset) ((Type *)((char *)(Base) + (Offset))) # define KBTS_POINTER_DIFF32(Pointer, Base) ((kbts_u32)((char *)(Pointer) - (char *)(Base))) # define KBTS_PASTE_1(A, B) A##B # define KBTS_PASTE_0(A, B) KBTS_PASTE_1(A, B) # define KBTS_PASTE(A, B) KBTS_PASTE_0(A, B) # define KBTS_IN_SET(X, Set) ((1u << (X)) & (Set)) # define KBTS_SET32_0(Arg) | (1u << (Arg)) KBTS_SET32_1 # define KBTS_SET32_1(Arg) | (1u << (Arg)) KBTS_SET32_0 # define KBTS_SET32_0End # define KBTS_SET32_1End # define KBTS_SET32(Args) (0u KBTS_PASTE(KBTS_SET32_0 Args, End)) # define KBTS_IN_SET64(X, Set) ((1ull << (X)) & (Set)) # define KBTS_SET64_0(Arg) | (1ull << (Arg)) KBTS_SET64_1 # define KBTS_SET64_1(Arg) | (1ull << (Arg)) KBTS_SET64_0 # define KBTS_SET64_0End # define KBTS_SET64_1End # define KBTS_SET64(Args) (0u KBTS_PASTE(KBTS_SET64_0 Args, End)) # ifndef KBTS_ASSERT #ifndef KB_TEXT_SHAPE_NO_CRT # include # define KBTS_ASSERT(Cond) assert(Cond) #else #define KBTS_ASSERT(Cond) #endif # endif #ifndef KB_TEXT_SHAPE_NO_CRT #include #endif #ifndef KBTS_MEMSET #include #define KBTS_MEMSET memset #endif #ifndef kbts_ByteSwap16 # if defined(_MSC_VER) && !defined(__clang__) # define kbts_ByteSwap16(X) _byteswap_ushort(X) # define kbts_ByteSwap32(X) _byteswap_ulong(X) # define kbts_PopCount32(X) (kbts_un)__popcnt(X) # elif defined(__clang__) || defined(__GNUC__) # define kbts_ByteSwap16(X) __builtin_bswap16(X) # define kbts_ByteSwap32(X) __builtin_bswap32(X) # define kbts_PopCount32(X) (kbts_un)__builtin_popcount(X) # else # error Unsupported compiler! # endif #endif #define KBTS_FEATURE_FLAG0(Feature) (1ull << KBTS_FEATURE_ID_##Feature) #define KBTS_FEATURE_FLAG1(Feature) (1ull << (KBTS_FEATURE_ID_##Feature - 64)) #define KBTS_FEATURE_FLAG2(Feature) (1ull << (KBTS_FEATURE_ID_##Feature - 128)) #define KBTS_FEATURE_FLAG3(Feature) (1ull << (KBTS_FEATURE_ID_##Feature - 192)) // # define KBTS_DUMP # ifdef KBTS_DUMP # define KBTS_DUMPF(...) printf(__VA_ARGS__), fflush(stdout) # else # define KBTS_DUMPF(...) # endif # define KBTS_GROW_BUFFER_MARGIN 16 #ifndef KBTS_INSTRUMENT_BLOCK_BEGIN #define KBTS_INSTRUMENT_BLOCK_BEGIN(Name) #define KBTS_INSTRUMENT_FUNCTION_BEGIN #define KBTS_INSTRUMENT_END #endif #define KBTS_MAXIMUM_DECOMPOSITION_CODEPOINTS 6 typedef struct kbts_script_properties { kbts_u32 Tag; kbts_shaper Shaper; } kbts_script_properties; static kbts_script_properties kbts_ScriptProperties[KBTS_SCRIPT_COUNT] = { {KBTS_FOURCC(' ', ' ', ' ', ' '), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('a', 'd', 'l', 'm'), KBTS_SHAPER_USE}, {KBTS_FOURCC('a', 'h', 'o', 'm'), KBTS_SHAPER_USE}, {KBTS_FOURCC('h', 'l', 'u', 'w'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('a', 'r', 'a', 'b'), KBTS_SHAPER_ARABIC}, {KBTS_FOURCC('a', 'r', 'm', 'n'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('a', 'v', 's', 't'), KBTS_SHAPER_USE}, {KBTS_FOURCC('b', 'a', 'l', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('b', 'a', 'm', 'u'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('b', 'a', 's', 's'), KBTS_SHAPER_USE}, {KBTS_FOURCC('b', 'a', 't', 'k'), KBTS_SHAPER_USE}, {KBTS_FOURCC('b', 'n', 'g', '2'), KBTS_SHAPER_INDIC}, {KBTS_FOURCC('b', 'h', 'k', 's'), KBTS_SHAPER_USE}, {KBTS_FOURCC('b', 'o', 'p', 'o'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('b', 'r', 'a', 'h'), KBTS_SHAPER_USE}, {KBTS_FOURCC('b', 'u', 'g', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('b', 'u', 'h', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('c', 'a', 'n', 's'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('c', 'a', 'r', 'i'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('a', 'g', 'h', 'b'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('c', 'a', 'k', 'm'), KBTS_SHAPER_USE}, {KBTS_FOURCC('c', 'h', 'a', 'm'), KBTS_SHAPER_USE}, {KBTS_FOURCC('c', 'h', 'e', 'r'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('c', 'h', 'r', 's'), KBTS_SHAPER_USE}, {KBTS_FOURCC('h', 'a', 'n', 'i'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('c', 'o', 'p', 't'), KBTS_SHAPER_USE}, {KBTS_FOURCC('c', 'p', 'r', 't'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('c', 'p', 'm', 'n'), KBTS_SHAPER_USE}, {KBTS_FOURCC('c', 'y', 'r', 'l'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('D', 'F', 'L', 'T'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('D', 'F', 'L', 'T'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('d', 's', 'r', 't'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('d', 'e', 'v', '2'), KBTS_SHAPER_INDIC}, {KBTS_FOURCC('d', 'i', 'a', 'k'), KBTS_SHAPER_USE}, {KBTS_FOURCC('d', 'o', 'g', 'r'), KBTS_SHAPER_USE}, {KBTS_FOURCC('d', 'u', 'p', 'l'), KBTS_SHAPER_USE}, {KBTS_FOURCC('e', 'g', 'y', 'p'), KBTS_SHAPER_USE}, {KBTS_FOURCC('e', 'l', 'b', 'a'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('e', 'l', 'y', 'm'), KBTS_SHAPER_USE}, {KBTS_FOURCC('e', 't', 'h', 'i'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('g', 'a', 'r', 'a'), KBTS_SHAPER_USE}, {KBTS_FOURCC('g', 'e', 'o', 'r'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('g', 'l', 'a', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('g', 'o', 't', 'h'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('g', 'r', 'a', 'n'), KBTS_SHAPER_USE}, {KBTS_FOURCC('g', 'r', 'e', 'k'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('g', 'j', 'r', '2'), KBTS_SHAPER_INDIC}, {KBTS_FOURCC('g', 'o', 'n', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('g', 'u', 'r', '2'), KBTS_SHAPER_INDIC}, {KBTS_FOURCC('g', 'u', 'k', 'h'), KBTS_SHAPER_USE}, {KBTS_FOURCC('h', 'a', 'n', 'g'), KBTS_SHAPER_HANGUL}, {KBTS_FOURCC('r', 'o', 'h', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('h', 'a', 'n', 'o'), KBTS_SHAPER_USE}, {KBTS_FOURCC('h', 'a', 't', 'r'), KBTS_SHAPER_USE}, {KBTS_FOURCC('h', 'e', 'b', 'r'), KBTS_SHAPER_HEBREW}, {KBTS_FOURCC('k', 'a', 'n', 'a'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('a', 'r', 'm', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('p', 'h', 'l', 'i'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('p', 'r', 't', 'i'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('j', 'a', 'v', 'a'), KBTS_SHAPER_USE}, {KBTS_FOURCC('k', 't', 'h', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('k', 'n', 'd', '2'), KBTS_SHAPER_INDIC}, {KBTS_FOURCC('k', 'a', 'n', 'a'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('k', 'a', 'w', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('k', 'a', 'l', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('k', 'h', 'a', 'r'), KBTS_SHAPER_USE}, {KBTS_FOURCC('k', 'i', 't', 's'), KBTS_SHAPER_USE}, {KBTS_FOURCC('k', 'h', 'm', 'r'), KBTS_SHAPER_KHMER}, {KBTS_FOURCC('k', 'h', 'o', 'j'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'i', 'n', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('k', 'r', 'a', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('l', 'a', 'o', ' '), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('l', 'a', 't', 'n'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('l', 'e', 'p', 'c'), KBTS_SHAPER_USE}, {KBTS_FOURCC('l', 'i', 'm', 'b'), KBTS_SHAPER_USE}, {KBTS_FOURCC('l', 'i', 'n', 'a'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('l', 'i', 'n', 'b'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('l', 'i', 's', 'u'), KBTS_SHAPER_USE}, {KBTS_FOURCC('l', 'y', 'c', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('l', 'y', 'd', 'i'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('m', 'a', 'h', 'j'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'a', 'k', 'a'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'l', 'm', '2'), KBTS_SHAPER_INDIC}, {KBTS_FOURCC('m', 'a', 'n', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'a', 'n', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'a', 'r', 'c'), KBTS_SHAPER_USE}, {KBTS_FOURCC('g', 'o', 'n', 'm'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'e', 'd', 'f'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 't', 'e', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'e', 'n', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'e', 'r', 'c'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'e', 'r', 'o'), KBTS_SHAPER_USE}, {KBTS_FOURCC('p', 'l', 'r', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'o', 'd', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'o', 'n', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'r', 'o', 'o'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('m', 'u', 'l', 't'), KBTS_SHAPER_USE}, {KBTS_FOURCC('m', 'y', 'm', '2'), KBTS_SHAPER_MYANMAR}, {KBTS_FOURCC('n', 'b', 'a', 't'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('n', 'a', 'g', 'm'), KBTS_SHAPER_USE}, {KBTS_FOURCC('n', 'a', 'n', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('n', 'e', 'w', 'a'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'a', 'l', 'u'), KBTS_SHAPER_USE}, {KBTS_FOURCC('n', 'k', 'o', ' '), KBTS_SHAPER_USE}, {KBTS_FOURCC('n', 's', 'h', 'u'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('h', 'm', 'n', 'p'), KBTS_SHAPER_USE}, {KBTS_FOURCC('o', 'g', 'a', 'm'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('o', 'l', 'c', 'k'), KBTS_SHAPER_USE}, {KBTS_FOURCC('o', 'n', 'a', 'o'), KBTS_SHAPER_USE}, {KBTS_FOURCC('i', 't', 'a', 'l'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('h', 'u', 'n', 'g'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('n', 'a', 'r', 'b'), KBTS_SHAPER_USE}, {KBTS_FOURCC('p', 'e', 'r', 'm'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('x', 'p', 'e', 'o'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'o', 'g', 'o'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'a', 'r', 'b'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('o', 'r', 'k', 'h'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('o', 'u', 'g', 'r'), KBTS_SHAPER_USE}, {KBTS_FOURCC('o', 'r', 'y', '2'), KBTS_SHAPER_INDIC}, {KBTS_FOURCC('o', 's', 'g', 'e'), KBTS_SHAPER_USE}, {KBTS_FOURCC('o', 's', 'm', 'a'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('h', 'm', 'n', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('p', 'a', 'l', 'm'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('p', 'a', 'u', 'c'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('p', 'h', 'a', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('p', 'h', 'n', 'x'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('p', 'h', 'l', 'p'), KBTS_SHAPER_USE}, {KBTS_FOURCC('r', 'j', 'n', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('r', 'u', 'n', 'r'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('s', 'a', 'm', 'r'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('s', 'a', 'u', 'r'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'h', 'r', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'h', 'a', 'w'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('s', 'i', 'd', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'g', 'n', 'w'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'o', 'g', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'i', 'n', 'h'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'o', 'r', 'a'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'o', 'y', 'o'), KBTS_SHAPER_USE}, {KBTS_FOURCC('x', 's', 'u', 'x'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'u', 'n', 'd'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'u', 'n', 'u'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'y', 'l', 'o'), KBTS_SHAPER_USE}, {KBTS_FOURCC('s', 'y', 'r', 'c'), KBTS_SHAPER_ARABIC}, {KBTS_FOURCC('t', 'g', 'l', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'a', 'g', 'b'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'a', 'l', 'e'), KBTS_SHAPER_USE}, {KBTS_FOURCC('l', 'a', 'n', 'a'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'a', 'v', 't'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'a', 'k', 'r'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'm', 'l', '2'), KBTS_SHAPER_INDIC}, {KBTS_FOURCC('t', 'n', 's', 'a'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'a', 'n', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'e', 'l', '2'), KBTS_SHAPER_INDIC}, {KBTS_FOURCC('t', 'h', 'a', 'a'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('t', 'h', 'a', 'i'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('t', 'i', 'b', 't'), KBTS_SHAPER_TIBETAN}, {KBTS_FOURCC('t', 'f', 'n', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'i', 'r', 'h'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'o', 'd', 'r'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'o', 't', 'o'), KBTS_SHAPER_USE}, {KBTS_FOURCC('t', 'u', 't', 'g'), KBTS_SHAPER_USE}, {KBTS_FOURCC('u', 'g', 'a', 'r'), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('v', 'a', 'i', ' '), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('v', 'i', 't', 'h'), KBTS_SHAPER_USE}, {KBTS_FOURCC('w', 'c', 'h', 'o'), KBTS_SHAPER_USE}, {KBTS_FOURCC('w', 'a', 'r', 'a'), KBTS_SHAPER_USE}, {KBTS_FOURCC('y', 'e', 'z', 'i'), KBTS_SHAPER_USE}, {KBTS_FOURCC('y', 'i', ' ', ' '), KBTS_SHAPER_DEFAULT}, {KBTS_FOURCC('z', 'a', 'n', 'b'), KBTS_SHAPER_USE}, }; KBTS_EXPORT kbts_script kbts_ScriptTagToScript(kbts_script_tag Tag) { kbts_script Result = 0; switch(Result) { case KBTS_SCRIPT_TAG_DONT_KNOW: Result = KBTS_SCRIPT_DONT_KNOW; break; case KBTS_SCRIPT_TAG_ADLAM: Result = KBTS_SCRIPT_ADLAM; break; case KBTS_SCRIPT_TAG_AHOM: Result = KBTS_SCRIPT_AHOM; break; case KBTS_SCRIPT_TAG_ANATOLIAN_HIEROGLYPHS: Result = KBTS_SCRIPT_ANATOLIAN_HIEROGLYPHS; break; case KBTS_SCRIPT_TAG_ARABIC: Result = KBTS_SCRIPT_ARABIC; break; case KBTS_SCRIPT_TAG_ARMENIAN: Result = KBTS_SCRIPT_ARMENIAN; break; case KBTS_SCRIPT_TAG_AVESTAN: Result = KBTS_SCRIPT_AVESTAN; break; case KBTS_SCRIPT_TAG_BALINESE: Result = KBTS_SCRIPT_BALINESE; break; case KBTS_SCRIPT_TAG_BAMUM: Result = KBTS_SCRIPT_BAMUM; break; case KBTS_SCRIPT_TAG_BASSA_VAH: Result = KBTS_SCRIPT_BASSA_VAH; break; case KBTS_SCRIPT_TAG_BATAK: Result = KBTS_SCRIPT_BATAK; break; case KBTS_SCRIPT_TAG_BENGALI: Result = KBTS_SCRIPT_BENGALI; break; case KBTS_SCRIPT_TAG_BHAIKSUKI: Result = KBTS_SCRIPT_BHAIKSUKI; break; case KBTS_SCRIPT_TAG_BOPOMOFO: Result = KBTS_SCRIPT_BOPOMOFO; break; case KBTS_SCRIPT_TAG_BRAHMI: Result = KBTS_SCRIPT_BRAHMI; break; case KBTS_SCRIPT_TAG_BUGINESE: Result = KBTS_SCRIPT_BUGINESE; break; case KBTS_SCRIPT_TAG_BUHID: Result = KBTS_SCRIPT_BUHID; break; case KBTS_SCRIPT_TAG_CANADIAN_SYLLABICS: Result = KBTS_SCRIPT_CANADIAN_SYLLABICS; break; case KBTS_SCRIPT_TAG_CARIAN: Result = KBTS_SCRIPT_CARIAN; break; case KBTS_SCRIPT_TAG_CAUCASIAN_ALBANIAN: Result = KBTS_SCRIPT_CAUCASIAN_ALBANIAN; break; case KBTS_SCRIPT_TAG_CHAKMA: Result = KBTS_SCRIPT_CHAKMA; break; case KBTS_SCRIPT_TAG_CHAM: Result = KBTS_SCRIPT_CHAM; break; case KBTS_SCRIPT_TAG_CHEROKEE: Result = KBTS_SCRIPT_CHEROKEE; break; case KBTS_SCRIPT_TAG_CHORASMIAN: Result = KBTS_SCRIPT_CHORASMIAN; break; case KBTS_SCRIPT_TAG_CJK_IDEOGRAPHIC: Result = KBTS_SCRIPT_CJK_IDEOGRAPHIC; break; case KBTS_SCRIPT_TAG_COPTIC: Result = KBTS_SCRIPT_COPTIC; break; case KBTS_SCRIPT_TAG_CYPRIOT_SYLLABARY: Result = KBTS_SCRIPT_CYPRIOT_SYLLABARY; break; case KBTS_SCRIPT_TAG_CYPRO_MINOAN: Result = KBTS_SCRIPT_CYPRO_MINOAN; break; case KBTS_SCRIPT_TAG_CYRILLIC: Result = KBTS_SCRIPT_CYRILLIC; break; case KBTS_SCRIPT_TAG_DEFAULT: Result = KBTS_SCRIPT_DEFAULT; break; case KBTS_SCRIPT_TAG_DESERET: Result = KBTS_SCRIPT_DESERET; break; case KBTS_SCRIPT_TAG_DEVANAGARI: Result = KBTS_SCRIPT_DEVANAGARI; break; case KBTS_SCRIPT_TAG_DIVES_AKURU: Result = KBTS_SCRIPT_DIVES_AKURU; break; case KBTS_SCRIPT_TAG_DOGRA: Result = KBTS_SCRIPT_DOGRA; break; case KBTS_SCRIPT_TAG_DUPLOYAN: Result = KBTS_SCRIPT_DUPLOYAN; break; case KBTS_SCRIPT_TAG_EGYPTIAN_HIEROGLYPHS: Result = KBTS_SCRIPT_EGYPTIAN_HIEROGLYPHS; break; case KBTS_SCRIPT_TAG_ELBASAN: Result = KBTS_SCRIPT_ELBASAN; break; case KBTS_SCRIPT_TAG_ELYMAIC: Result = KBTS_SCRIPT_ELYMAIC; break; case KBTS_SCRIPT_TAG_ETHIOPIC: Result = KBTS_SCRIPT_ETHIOPIC; break; case KBTS_SCRIPT_TAG_GARAY: Result = KBTS_SCRIPT_GARAY; break; case KBTS_SCRIPT_TAG_GEORGIAN: Result = KBTS_SCRIPT_GEORGIAN; break; case KBTS_SCRIPT_TAG_GLAGOLITIC: Result = KBTS_SCRIPT_GLAGOLITIC; break; case KBTS_SCRIPT_TAG_GOTHIC: Result = KBTS_SCRIPT_GOTHIC; break; case KBTS_SCRIPT_TAG_GRANTHA: Result = KBTS_SCRIPT_GRANTHA; break; case KBTS_SCRIPT_TAG_GREEK: Result = KBTS_SCRIPT_GREEK; break; case KBTS_SCRIPT_TAG_GUJARATI: Result = KBTS_SCRIPT_GUJARATI; break; case KBTS_SCRIPT_TAG_GUNJALA_GONDI: Result = KBTS_SCRIPT_GUNJALA_GONDI; break; case KBTS_SCRIPT_TAG_GURMUKHI: Result = KBTS_SCRIPT_GURMUKHI; break; case KBTS_SCRIPT_TAG_GURUNG_KHEMA: Result = KBTS_SCRIPT_GURUNG_KHEMA; break; case KBTS_SCRIPT_TAG_HANGUL: Result = KBTS_SCRIPT_HANGUL; break; case KBTS_SCRIPT_TAG_HANIFI_ROHINGYA: Result = KBTS_SCRIPT_HANIFI_ROHINGYA; break; case KBTS_SCRIPT_TAG_HANUNOO: Result = KBTS_SCRIPT_HANUNOO; break; case KBTS_SCRIPT_TAG_HATRAN: Result = KBTS_SCRIPT_HATRAN; break; case KBTS_SCRIPT_TAG_HEBREW: Result = KBTS_SCRIPT_HEBREW; break; case KBTS_SCRIPT_TAG_HIRAGANA: Result = KBTS_SCRIPT_HIRAGANA; break; case KBTS_SCRIPT_TAG_IMPERIAL_ARAMAIC: Result = KBTS_SCRIPT_IMPERIAL_ARAMAIC; break; case KBTS_SCRIPT_TAG_INSCRIPTIONAL_PAHLAVI: Result = KBTS_SCRIPT_INSCRIPTIONAL_PAHLAVI; break; case KBTS_SCRIPT_TAG_INSCRIPTIONAL_PARTHIAN: Result = KBTS_SCRIPT_INSCRIPTIONAL_PARTHIAN; break; case KBTS_SCRIPT_TAG_JAVANESE: Result = KBTS_SCRIPT_JAVANESE; break; case KBTS_SCRIPT_TAG_KAITHI: Result = KBTS_SCRIPT_KAITHI; break; case KBTS_SCRIPT_TAG_KANNADA: Result = KBTS_SCRIPT_KANNADA; break; case KBTS_SCRIPT_TAG_KAWI: Result = KBTS_SCRIPT_KAWI; break; case KBTS_SCRIPT_TAG_KAYAH_LI: Result = KBTS_SCRIPT_KAYAH_LI; break; case KBTS_SCRIPT_TAG_KHAROSHTHI: Result = KBTS_SCRIPT_KHAROSHTHI; break; case KBTS_SCRIPT_TAG_KHITAN_SMALL_SCRIPT: Result = KBTS_SCRIPT_KHITAN_SMALL_SCRIPT; break; case KBTS_SCRIPT_TAG_KHMER: Result = KBTS_SCRIPT_KHMER; break; case KBTS_SCRIPT_TAG_KHOJKI: Result = KBTS_SCRIPT_KHOJKI; break; case KBTS_SCRIPT_TAG_KHUDAWADI: Result = KBTS_SCRIPT_KHUDAWADI; break; case KBTS_SCRIPT_TAG_KIRAT_RAI: Result = KBTS_SCRIPT_KIRAT_RAI; break; case KBTS_SCRIPT_TAG_LAO: Result = KBTS_SCRIPT_LAO; break; case KBTS_SCRIPT_TAG_LATIN: Result = KBTS_SCRIPT_LATIN; break; case KBTS_SCRIPT_TAG_LEPCHA: Result = KBTS_SCRIPT_LEPCHA; break; case KBTS_SCRIPT_TAG_LIMBU: Result = KBTS_SCRIPT_LIMBU; break; case KBTS_SCRIPT_TAG_LINEAR_A: Result = KBTS_SCRIPT_LINEAR_A; break; case KBTS_SCRIPT_TAG_LINEAR_B: Result = KBTS_SCRIPT_LINEAR_B; break; case KBTS_SCRIPT_TAG_LISU: Result = KBTS_SCRIPT_LISU; break; case KBTS_SCRIPT_TAG_LYCIAN: Result = KBTS_SCRIPT_LYCIAN; break; case KBTS_SCRIPT_TAG_LYDIAN: Result = KBTS_SCRIPT_LYDIAN; break; case KBTS_SCRIPT_TAG_MAHAJANI: Result = KBTS_SCRIPT_MAHAJANI; break; case KBTS_SCRIPT_TAG_MAKASAR: Result = KBTS_SCRIPT_MAKASAR; break; case KBTS_SCRIPT_TAG_MALAYALAM: Result = KBTS_SCRIPT_MALAYALAM; break; case KBTS_SCRIPT_TAG_MANDAIC: Result = KBTS_SCRIPT_MANDAIC; break; case KBTS_SCRIPT_TAG_MANICHAEAN: Result = KBTS_SCRIPT_MANICHAEAN; break; case KBTS_SCRIPT_TAG_MARCHEN: Result = KBTS_SCRIPT_MARCHEN; break; case KBTS_SCRIPT_TAG_MASARAM_GONDI: Result = KBTS_SCRIPT_MASARAM_GONDI; break; case KBTS_SCRIPT_TAG_MEDEFAIDRIN: Result = KBTS_SCRIPT_MEDEFAIDRIN; break; case KBTS_SCRIPT_TAG_MEETEI_MAYEK: Result = KBTS_SCRIPT_MEETEI_MAYEK; break; case KBTS_SCRIPT_TAG_MENDE_KIKAKUI: Result = KBTS_SCRIPT_MENDE_KIKAKUI; break; case KBTS_SCRIPT_TAG_MEROITIC_CURSIVE: Result = KBTS_SCRIPT_MEROITIC_CURSIVE; break; case KBTS_SCRIPT_TAG_MEROITIC_HIEROGLYPHS: Result = KBTS_SCRIPT_MEROITIC_HIEROGLYPHS; break; case KBTS_SCRIPT_TAG_MIAO: Result = KBTS_SCRIPT_MIAO; break; case KBTS_SCRIPT_TAG_MODI: Result = KBTS_SCRIPT_MODI; break; case KBTS_SCRIPT_TAG_MONGOLIAN: Result = KBTS_SCRIPT_MONGOLIAN; break; case KBTS_SCRIPT_TAG_MRO: Result = KBTS_SCRIPT_MRO; break; case KBTS_SCRIPT_TAG_MULTANI: Result = KBTS_SCRIPT_MULTANI; break; case KBTS_SCRIPT_TAG_MYANMAR: Result = KBTS_SCRIPT_MYANMAR; break; case KBTS_SCRIPT_TAG_NABATAEAN: Result = KBTS_SCRIPT_NABATAEAN; break; case KBTS_SCRIPT_TAG_NAG_MUNDARI: Result = KBTS_SCRIPT_NAG_MUNDARI; break; case KBTS_SCRIPT_TAG_NANDINAGARI: Result = KBTS_SCRIPT_NANDINAGARI; break; case KBTS_SCRIPT_TAG_NEWA: Result = KBTS_SCRIPT_NEWA; break; case KBTS_SCRIPT_TAG_NEW_TAI_LUE: Result = KBTS_SCRIPT_NEW_TAI_LUE; break; case KBTS_SCRIPT_TAG_NKO: Result = KBTS_SCRIPT_NKO; break; case KBTS_SCRIPT_TAG_NUSHU: Result = KBTS_SCRIPT_NUSHU; break; case KBTS_SCRIPT_TAG_NYIAKENG_PUACHUE_HMONG: Result = KBTS_SCRIPT_NYIAKENG_PUACHUE_HMONG; break; case KBTS_SCRIPT_TAG_OGHAM: Result = KBTS_SCRIPT_OGHAM; break; case KBTS_SCRIPT_TAG_OL_CHIKI: Result = KBTS_SCRIPT_OL_CHIKI; break; case KBTS_SCRIPT_TAG_OL_ONAL: Result = KBTS_SCRIPT_OL_ONAL; break; case KBTS_SCRIPT_TAG_OLD_ITALIC: Result = KBTS_SCRIPT_OLD_ITALIC; break; case KBTS_SCRIPT_TAG_OLD_HUNGARIAN: Result = KBTS_SCRIPT_OLD_HUNGARIAN; break; case KBTS_SCRIPT_TAG_OLD_NORTH_ARABIAN: Result = KBTS_SCRIPT_OLD_NORTH_ARABIAN; break; case KBTS_SCRIPT_TAG_OLD_PERMIC: Result = KBTS_SCRIPT_OLD_PERMIC; break; case KBTS_SCRIPT_TAG_OLD_PERSIAN_CUNEIFORM: Result = KBTS_SCRIPT_OLD_PERSIAN_CUNEIFORM; break; case KBTS_SCRIPT_TAG_OLD_SOGDIAN: Result = KBTS_SCRIPT_OLD_SOGDIAN; break; case KBTS_SCRIPT_TAG_OLD_SOUTH_ARABIAN: Result = KBTS_SCRIPT_OLD_SOUTH_ARABIAN; break; case KBTS_SCRIPT_TAG_OLD_TURKIC: Result = KBTS_SCRIPT_OLD_TURKIC; break; case KBTS_SCRIPT_TAG_OLD_UYGHUR: Result = KBTS_SCRIPT_OLD_UYGHUR; break; case KBTS_SCRIPT_TAG_ODIA: Result = KBTS_SCRIPT_ODIA; break; case KBTS_SCRIPT_TAG_OSAGE: Result = KBTS_SCRIPT_OSAGE; break; case KBTS_SCRIPT_TAG_OSMANYA: Result = KBTS_SCRIPT_OSMANYA; break; case KBTS_SCRIPT_TAG_PAHAWH_HMONG: Result = KBTS_SCRIPT_PAHAWH_HMONG; break; case KBTS_SCRIPT_TAG_PALMYRENE: Result = KBTS_SCRIPT_PALMYRENE; break; case KBTS_SCRIPT_TAG_PAU_CIN_HAU: Result = KBTS_SCRIPT_PAU_CIN_HAU; break; case KBTS_SCRIPT_TAG_PHAGS_PA: Result = KBTS_SCRIPT_PHAGS_PA; break; case KBTS_SCRIPT_TAG_PHOENICIAN: Result = KBTS_SCRIPT_PHOENICIAN; break; case KBTS_SCRIPT_TAG_PSALTER_PAHLAVI: Result = KBTS_SCRIPT_PSALTER_PAHLAVI; break; case KBTS_SCRIPT_TAG_REJANG: Result = KBTS_SCRIPT_REJANG; break; case KBTS_SCRIPT_TAG_RUNIC: Result = KBTS_SCRIPT_RUNIC; break; case KBTS_SCRIPT_TAG_SAMARITAN: Result = KBTS_SCRIPT_SAMARITAN; break; case KBTS_SCRIPT_TAG_SAURASHTRA: Result = KBTS_SCRIPT_SAURASHTRA; break; case KBTS_SCRIPT_TAG_SHARADA: Result = KBTS_SCRIPT_SHARADA; break; case KBTS_SCRIPT_TAG_SHAVIAN: Result = KBTS_SCRIPT_SHAVIAN; break; case KBTS_SCRIPT_TAG_SIDDHAM: Result = KBTS_SCRIPT_SIDDHAM; break; case KBTS_SCRIPT_TAG_SIGN_WRITING: Result = KBTS_SCRIPT_SIGN_WRITING; break; case KBTS_SCRIPT_TAG_SOGDIAN: Result = KBTS_SCRIPT_SOGDIAN; break; case KBTS_SCRIPT_TAG_SINHALA: Result = KBTS_SCRIPT_SINHALA; break; case KBTS_SCRIPT_TAG_SORA_SOMPENG: Result = KBTS_SCRIPT_SORA_SOMPENG; break; case KBTS_SCRIPT_TAG_SOYOMBO: Result = KBTS_SCRIPT_SOYOMBO; break; case KBTS_SCRIPT_TAG_SUMERO_AKKADIAN_CUNEIFORM: Result = KBTS_SCRIPT_SUMERO_AKKADIAN_CUNEIFORM; break; case KBTS_SCRIPT_TAG_SUNDANESE: Result = KBTS_SCRIPT_SUNDANESE; break; case KBTS_SCRIPT_TAG_SUNUWAR: Result = KBTS_SCRIPT_SUNUWAR; break; case KBTS_SCRIPT_TAG_SYLOTI_NAGRI: Result = KBTS_SCRIPT_SYLOTI_NAGRI; break; case KBTS_SCRIPT_TAG_SYRIAC: Result = KBTS_SCRIPT_SYRIAC; break; case KBTS_SCRIPT_TAG_TAGALOG: Result = KBTS_SCRIPT_TAGALOG; break; case KBTS_SCRIPT_TAG_TAGBANWA: Result = KBTS_SCRIPT_TAGBANWA; break; case KBTS_SCRIPT_TAG_TAI_LE: Result = KBTS_SCRIPT_TAI_LE; break; case KBTS_SCRIPT_TAG_TAI_THAM: Result = KBTS_SCRIPT_TAI_THAM; break; case KBTS_SCRIPT_TAG_TAI_VIET: Result = KBTS_SCRIPT_TAI_VIET; break; case KBTS_SCRIPT_TAG_TAKRI: Result = KBTS_SCRIPT_TAKRI; break; case KBTS_SCRIPT_TAG_TAMIL: Result = KBTS_SCRIPT_TAMIL; break; case KBTS_SCRIPT_TAG_TANGSA: Result = KBTS_SCRIPT_TANGSA; break; case KBTS_SCRIPT_TAG_TANGUT: Result = KBTS_SCRIPT_TANGUT; break; case KBTS_SCRIPT_TAG_TELUGU: Result = KBTS_SCRIPT_TELUGU; break; case KBTS_SCRIPT_TAG_THAANA: Result = KBTS_SCRIPT_THAANA; break; case KBTS_SCRIPT_TAG_THAI: Result = KBTS_SCRIPT_THAI; break; case KBTS_SCRIPT_TAG_TIBETAN: Result = KBTS_SCRIPT_TIBETAN; break; case KBTS_SCRIPT_TAG_TIFINAGH: Result = KBTS_SCRIPT_TIFINAGH; break; case KBTS_SCRIPT_TAG_TIRHUTA: Result = KBTS_SCRIPT_TIRHUTA; break; case KBTS_SCRIPT_TAG_TODHRI: Result = KBTS_SCRIPT_TODHRI; break; case KBTS_SCRIPT_TAG_TOTO: Result = KBTS_SCRIPT_TOTO; break; case KBTS_SCRIPT_TAG_TULU_TIGALARI: Result = KBTS_SCRIPT_TULU_TIGALARI; break; case KBTS_SCRIPT_TAG_UGARITIC_CUNEIFORM: Result = KBTS_SCRIPT_UGARITIC_CUNEIFORM; break; case KBTS_SCRIPT_TAG_VAI: Result = KBTS_SCRIPT_VAI; break; case KBTS_SCRIPT_TAG_VITHKUQI: Result = KBTS_SCRIPT_VITHKUQI; break; case KBTS_SCRIPT_TAG_WANCHO: Result = KBTS_SCRIPT_WANCHO; break; case KBTS_SCRIPT_TAG_WARANG_CITI: Result = KBTS_SCRIPT_WARANG_CITI; break; case KBTS_SCRIPT_TAG_YEZIDI: Result = KBTS_SCRIPT_YEZIDI; break; case KBTS_SCRIPT_TAG_YI: Result = KBTS_SCRIPT_YI; break; case KBTS_SCRIPT_TAG_ZANABAZAR_SQUARE: Result = KBTS_SCRIPT_ZANABAZAR_SQUARE; break; default: break; } return Result; } KBTS_EXPORT kbts_feature_id kbts_FeatureTagToId(kbts_feature_tag Tag) { kbts_feature_id Result = 0; switch(Tag) { case KBTS_FEATURE_TAG_isol: Result = KBTS_FEATURE_ID_isol; break; case KBTS_FEATURE_TAG_fina: Result = KBTS_FEATURE_ID_fina; break; case KBTS_FEATURE_TAG_fin2: Result = KBTS_FEATURE_ID_fin2; break; case KBTS_FEATURE_TAG_fin3: Result = KBTS_FEATURE_ID_fin3; break; case KBTS_FEATURE_TAG_medi: Result = KBTS_FEATURE_ID_medi; break; case KBTS_FEATURE_TAG_med2: Result = KBTS_FEATURE_ID_med2; break; case KBTS_FEATURE_TAG_init: Result = KBTS_FEATURE_ID_init; break; case KBTS_FEATURE_TAG_ljmo: Result = KBTS_FEATURE_ID_ljmo; break; case KBTS_FEATURE_TAG_vjmo: Result = KBTS_FEATURE_ID_vjmo; break; case KBTS_FEATURE_TAG_tjmo: Result = KBTS_FEATURE_ID_tjmo; break; case KBTS_FEATURE_TAG_rphf: Result = KBTS_FEATURE_ID_rphf; break; case KBTS_FEATURE_TAG_blwf: Result = KBTS_FEATURE_ID_blwf; break; case KBTS_FEATURE_TAG_half: Result = KBTS_FEATURE_ID_half; break; case KBTS_FEATURE_TAG_pstf: Result = KBTS_FEATURE_ID_pstf; break; case KBTS_FEATURE_TAG_abvf: Result = KBTS_FEATURE_ID_abvf; break; case KBTS_FEATURE_TAG_pref: Result = KBTS_FEATURE_ID_pref; break; case KBTS_FEATURE_TAG_numr: Result = KBTS_FEATURE_ID_numr; break; case KBTS_FEATURE_TAG_frac: Result = KBTS_FEATURE_ID_frac; break; case KBTS_FEATURE_TAG_dnom: Result = KBTS_FEATURE_ID_dnom; break; case KBTS_FEATURE_TAG_cfar: Result = KBTS_FEATURE_ID_cfar; break; case KBTS_FEATURE_TAG_aalt: Result = KBTS_FEATURE_ID_aalt; break; case KBTS_FEATURE_TAG_abvm: Result = KBTS_FEATURE_ID_abvm; break; case KBTS_FEATURE_TAG_abvs: Result = KBTS_FEATURE_ID_abvs; break; case KBTS_FEATURE_TAG_afrc: Result = KBTS_FEATURE_ID_afrc; break; case KBTS_FEATURE_TAG_akhn: Result = KBTS_FEATURE_ID_akhn; break; case KBTS_FEATURE_TAG_apkn: Result = KBTS_FEATURE_ID_apkn; break; case KBTS_FEATURE_TAG_blwm: Result = KBTS_FEATURE_ID_blwm; break; case KBTS_FEATURE_TAG_blws: Result = KBTS_FEATURE_ID_blws; break; case KBTS_FEATURE_TAG_calt: Result = KBTS_FEATURE_ID_calt; break; case KBTS_FEATURE_TAG_case: Result = KBTS_FEATURE_ID_case; break; case KBTS_FEATURE_TAG_ccmp: Result = KBTS_FEATURE_ID_ccmp; break; case KBTS_FEATURE_TAG_chws: Result = KBTS_FEATURE_ID_chws; break; case KBTS_FEATURE_TAG_cjct: Result = KBTS_FEATURE_ID_cjct; break; case KBTS_FEATURE_TAG_clig: Result = KBTS_FEATURE_ID_clig; break; case KBTS_FEATURE_TAG_cpct: Result = KBTS_FEATURE_ID_cpct; break; case KBTS_FEATURE_TAG_cpsp: Result = KBTS_FEATURE_ID_cpsp; break; case KBTS_FEATURE_TAG_cswh: Result = KBTS_FEATURE_ID_cswh; break; case KBTS_FEATURE_TAG_curs: Result = KBTS_FEATURE_ID_curs; break; case KBTS_FEATURE_TAG_cv01: Result = KBTS_FEATURE_ID_cv01; break; case KBTS_FEATURE_TAG_cv02: Result = KBTS_FEATURE_ID_cv02; break; case KBTS_FEATURE_TAG_cv03: Result = KBTS_FEATURE_ID_cv03; break; case KBTS_FEATURE_TAG_cv04: Result = KBTS_FEATURE_ID_cv04; break; case KBTS_FEATURE_TAG_cv05: Result = KBTS_FEATURE_ID_cv05; break; case KBTS_FEATURE_TAG_cv06: Result = KBTS_FEATURE_ID_cv06; break; case KBTS_FEATURE_TAG_cv07: Result = KBTS_FEATURE_ID_cv07; break; case KBTS_FEATURE_TAG_cv08: Result = KBTS_FEATURE_ID_cv08; break; case KBTS_FEATURE_TAG_cv09: Result = KBTS_FEATURE_ID_cv09; break; case KBTS_FEATURE_TAG_cv10: Result = KBTS_FEATURE_ID_cv10; break; case KBTS_FEATURE_TAG_cv11: Result = KBTS_FEATURE_ID_cv11; break; case KBTS_FEATURE_TAG_cv12: Result = KBTS_FEATURE_ID_cv12; break; case KBTS_FEATURE_TAG_cv13: Result = KBTS_FEATURE_ID_cv13; break; case KBTS_FEATURE_TAG_cv14: Result = KBTS_FEATURE_ID_cv14; break; case KBTS_FEATURE_TAG_cv15: Result = KBTS_FEATURE_ID_cv15; break; case KBTS_FEATURE_TAG_cv16: Result = KBTS_FEATURE_ID_cv16; break; case KBTS_FEATURE_TAG_cv17: Result = KBTS_FEATURE_ID_cv17; break; case KBTS_FEATURE_TAG_cv18: Result = KBTS_FEATURE_ID_cv18; break; case KBTS_FEATURE_TAG_cv19: Result = KBTS_FEATURE_ID_cv19; break; case KBTS_FEATURE_TAG_cv20: Result = KBTS_FEATURE_ID_cv20; break; case KBTS_FEATURE_TAG_cv21: Result = KBTS_FEATURE_ID_cv21; break; case KBTS_FEATURE_TAG_cv22: Result = KBTS_FEATURE_ID_cv22; break; case KBTS_FEATURE_TAG_cv23: Result = KBTS_FEATURE_ID_cv23; break; case KBTS_FEATURE_TAG_cv24: Result = KBTS_FEATURE_ID_cv24; break; case KBTS_FEATURE_TAG_cv25: Result = KBTS_FEATURE_ID_cv25; break; case KBTS_FEATURE_TAG_cv26: Result = KBTS_FEATURE_ID_cv26; break; case KBTS_FEATURE_TAG_cv27: Result = KBTS_FEATURE_ID_cv27; break; case KBTS_FEATURE_TAG_cv28: Result = KBTS_FEATURE_ID_cv28; break; case KBTS_FEATURE_TAG_cv29: Result = KBTS_FEATURE_ID_cv29; break; case KBTS_FEATURE_TAG_cv30: Result = KBTS_FEATURE_ID_cv30; break; case KBTS_FEATURE_TAG_cv31: Result = KBTS_FEATURE_ID_cv31; break; case KBTS_FEATURE_TAG_cv32: Result = KBTS_FEATURE_ID_cv32; break; case KBTS_FEATURE_TAG_cv33: Result = KBTS_FEATURE_ID_cv33; break; case KBTS_FEATURE_TAG_cv34: Result = KBTS_FEATURE_ID_cv34; break; case KBTS_FEATURE_TAG_cv35: Result = KBTS_FEATURE_ID_cv35; break; case KBTS_FEATURE_TAG_cv36: Result = KBTS_FEATURE_ID_cv36; break; case KBTS_FEATURE_TAG_cv37: Result = KBTS_FEATURE_ID_cv37; break; case KBTS_FEATURE_TAG_cv38: Result = KBTS_FEATURE_ID_cv38; break; case KBTS_FEATURE_TAG_cv39: Result = KBTS_FEATURE_ID_cv39; break; case KBTS_FEATURE_TAG_cv40: Result = KBTS_FEATURE_ID_cv40; break; case KBTS_FEATURE_TAG_cv41: Result = KBTS_FEATURE_ID_cv41; break; case KBTS_FEATURE_TAG_cv42: Result = KBTS_FEATURE_ID_cv42; break; case KBTS_FEATURE_TAG_cv43: Result = KBTS_FEATURE_ID_cv43; break; case KBTS_FEATURE_TAG_cv44: Result = KBTS_FEATURE_ID_cv44; break; case KBTS_FEATURE_TAG_cv45: Result = KBTS_FEATURE_ID_cv45; break; case KBTS_FEATURE_TAG_cv46: Result = KBTS_FEATURE_ID_cv46; break; case KBTS_FEATURE_TAG_cv47: Result = KBTS_FEATURE_ID_cv47; break; case KBTS_FEATURE_TAG_cv48: Result = KBTS_FEATURE_ID_cv48; break; case KBTS_FEATURE_TAG_cv49: Result = KBTS_FEATURE_ID_cv49; break; case KBTS_FEATURE_TAG_cv50: Result = KBTS_FEATURE_ID_cv50; break; case KBTS_FEATURE_TAG_cv51: Result = KBTS_FEATURE_ID_cv51; break; case KBTS_FEATURE_TAG_cv52: Result = KBTS_FEATURE_ID_cv52; break; case KBTS_FEATURE_TAG_cv53: Result = KBTS_FEATURE_ID_cv53; break; case KBTS_FEATURE_TAG_cv54: Result = KBTS_FEATURE_ID_cv54; break; case KBTS_FEATURE_TAG_cv55: Result = KBTS_FEATURE_ID_cv55; break; case KBTS_FEATURE_TAG_cv56: Result = KBTS_FEATURE_ID_cv56; break; case KBTS_FEATURE_TAG_cv57: Result = KBTS_FEATURE_ID_cv57; break; case KBTS_FEATURE_TAG_cv58: Result = KBTS_FEATURE_ID_cv58; break; case KBTS_FEATURE_TAG_cv59: Result = KBTS_FEATURE_ID_cv59; break; case KBTS_FEATURE_TAG_cv60: Result = KBTS_FEATURE_ID_cv60; break; case KBTS_FEATURE_TAG_cv61: Result = KBTS_FEATURE_ID_cv61; break; case KBTS_FEATURE_TAG_cv62: Result = KBTS_FEATURE_ID_cv62; break; case KBTS_FEATURE_TAG_cv63: Result = KBTS_FEATURE_ID_cv63; break; case KBTS_FEATURE_TAG_cv64: Result = KBTS_FEATURE_ID_cv64; break; case KBTS_FEATURE_TAG_cv65: Result = KBTS_FEATURE_ID_cv65; break; case KBTS_FEATURE_TAG_cv66: Result = KBTS_FEATURE_ID_cv66; break; case KBTS_FEATURE_TAG_cv67: Result = KBTS_FEATURE_ID_cv67; break; case KBTS_FEATURE_TAG_cv68: Result = KBTS_FEATURE_ID_cv68; break; case KBTS_FEATURE_TAG_cv69: Result = KBTS_FEATURE_ID_cv69; break; case KBTS_FEATURE_TAG_cv70: Result = KBTS_FEATURE_ID_cv70; break; case KBTS_FEATURE_TAG_cv71: Result = KBTS_FEATURE_ID_cv71; break; case KBTS_FEATURE_TAG_cv72: Result = KBTS_FEATURE_ID_cv72; break; case KBTS_FEATURE_TAG_cv73: Result = KBTS_FEATURE_ID_cv73; break; case KBTS_FEATURE_TAG_cv74: Result = KBTS_FEATURE_ID_cv74; break; case KBTS_FEATURE_TAG_cv75: Result = KBTS_FEATURE_ID_cv75; break; case KBTS_FEATURE_TAG_cv76: Result = KBTS_FEATURE_ID_cv76; break; case KBTS_FEATURE_TAG_cv77: Result = KBTS_FEATURE_ID_cv77; break; case KBTS_FEATURE_TAG_cv78: Result = KBTS_FEATURE_ID_cv78; break; case KBTS_FEATURE_TAG_cv79: Result = KBTS_FEATURE_ID_cv79; break; case KBTS_FEATURE_TAG_cv80: Result = KBTS_FEATURE_ID_cv80; break; case KBTS_FEATURE_TAG_cv81: Result = KBTS_FEATURE_ID_cv81; break; case KBTS_FEATURE_TAG_cv82: Result = KBTS_FEATURE_ID_cv82; break; case KBTS_FEATURE_TAG_cv83: Result = KBTS_FEATURE_ID_cv83; break; case KBTS_FEATURE_TAG_cv84: Result = KBTS_FEATURE_ID_cv84; break; case KBTS_FEATURE_TAG_cv85: Result = KBTS_FEATURE_ID_cv85; break; case KBTS_FEATURE_TAG_cv86: Result = KBTS_FEATURE_ID_cv86; break; case KBTS_FEATURE_TAG_cv87: Result = KBTS_FEATURE_ID_cv87; break; case KBTS_FEATURE_TAG_cv88: Result = KBTS_FEATURE_ID_cv88; break; case KBTS_FEATURE_TAG_cv89: Result = KBTS_FEATURE_ID_cv89; break; case KBTS_FEATURE_TAG_cv90: Result = KBTS_FEATURE_ID_cv90; break; case KBTS_FEATURE_TAG_cv91: Result = KBTS_FEATURE_ID_cv91; break; case KBTS_FEATURE_TAG_cv92: Result = KBTS_FEATURE_ID_cv92; break; case KBTS_FEATURE_TAG_cv93: Result = KBTS_FEATURE_ID_cv93; break; case KBTS_FEATURE_TAG_cv94: Result = KBTS_FEATURE_ID_cv94; break; case KBTS_FEATURE_TAG_cv95: Result = KBTS_FEATURE_ID_cv95; break; case KBTS_FEATURE_TAG_cv96: Result = KBTS_FEATURE_ID_cv96; break; case KBTS_FEATURE_TAG_cv97: Result = KBTS_FEATURE_ID_cv97; break; case KBTS_FEATURE_TAG_cv98: Result = KBTS_FEATURE_ID_cv98; break; case KBTS_FEATURE_TAG_cv99: Result = KBTS_FEATURE_ID_cv99; break; case KBTS_FEATURE_TAG_c2pc: Result = KBTS_FEATURE_ID_c2pc; break; case KBTS_FEATURE_TAG_c2sc: Result = KBTS_FEATURE_ID_c2sc; break; case KBTS_FEATURE_TAG_dist: Result = KBTS_FEATURE_ID_dist; break; case KBTS_FEATURE_TAG_dlig: Result = KBTS_FEATURE_ID_dlig; break; case KBTS_FEATURE_TAG_dtls: Result = KBTS_FEATURE_ID_dtls; break; case KBTS_FEATURE_TAG_expt: Result = KBTS_FEATURE_ID_expt; break; case KBTS_FEATURE_TAG_falt: Result = KBTS_FEATURE_ID_falt; break; case KBTS_FEATURE_TAG_flac: Result = KBTS_FEATURE_ID_flac; break; case KBTS_FEATURE_TAG_fwid: Result = KBTS_FEATURE_ID_fwid; break; case KBTS_FEATURE_TAG_haln: Result = KBTS_FEATURE_ID_haln; break; case KBTS_FEATURE_TAG_halt: Result = KBTS_FEATURE_ID_halt; break; case KBTS_FEATURE_TAG_hist: Result = KBTS_FEATURE_ID_hist; break; case KBTS_FEATURE_TAG_hkna: Result = KBTS_FEATURE_ID_hkna; break; case KBTS_FEATURE_TAG_hlig: Result = KBTS_FEATURE_ID_hlig; break; case KBTS_FEATURE_TAG_hngl: Result = KBTS_FEATURE_ID_hngl; break; case KBTS_FEATURE_TAG_hojo: Result = KBTS_FEATURE_ID_hojo; break; case KBTS_FEATURE_TAG_hwid: Result = KBTS_FEATURE_ID_hwid; break; case KBTS_FEATURE_TAG_ital: Result = KBTS_FEATURE_ID_ital; break; case KBTS_FEATURE_TAG_jalt: Result = KBTS_FEATURE_ID_jalt; break; case KBTS_FEATURE_TAG_jp78: Result = KBTS_FEATURE_ID_jp78; break; case KBTS_FEATURE_TAG_jp83: Result = KBTS_FEATURE_ID_jp83; break; case KBTS_FEATURE_TAG_jp90: Result = KBTS_FEATURE_ID_jp90; break; case KBTS_FEATURE_TAG_jp04: Result = KBTS_FEATURE_ID_jp04; break; case KBTS_FEATURE_TAG_kern: Result = KBTS_FEATURE_ID_kern; break; case KBTS_FEATURE_TAG_lfbd: Result = KBTS_FEATURE_ID_lfbd; break; case KBTS_FEATURE_TAG_liga: Result = KBTS_FEATURE_ID_liga; break; case KBTS_FEATURE_TAG_lnum: Result = KBTS_FEATURE_ID_lnum; break; case KBTS_FEATURE_TAG_locl: Result = KBTS_FEATURE_ID_locl; break; case KBTS_FEATURE_TAG_ltra: Result = KBTS_FEATURE_ID_ltra; break; case KBTS_FEATURE_TAG_ltrm: Result = KBTS_FEATURE_ID_ltrm; break; case KBTS_FEATURE_TAG_mark: Result = KBTS_FEATURE_ID_mark; break; case KBTS_FEATURE_TAG_mgrk: Result = KBTS_FEATURE_ID_mgrk; break; case KBTS_FEATURE_TAG_mkmk: Result = KBTS_FEATURE_ID_mkmk; break; case KBTS_FEATURE_TAG_mset: Result = KBTS_FEATURE_ID_mset; break; case KBTS_FEATURE_TAG_nalt: Result = KBTS_FEATURE_ID_nalt; break; case KBTS_FEATURE_TAG_nlck: Result = KBTS_FEATURE_ID_nlck; break; case KBTS_FEATURE_TAG_nukt: Result = KBTS_FEATURE_ID_nukt; break; case KBTS_FEATURE_TAG_onum: Result = KBTS_FEATURE_ID_onum; break; case KBTS_FEATURE_TAG_opbd: Result = KBTS_FEATURE_ID_opbd; break; case KBTS_FEATURE_TAG_ordn: Result = KBTS_FEATURE_ID_ordn; break; case KBTS_FEATURE_TAG_ornm: Result = KBTS_FEATURE_ID_ornm; break; case KBTS_FEATURE_TAG_palt: Result = KBTS_FEATURE_ID_palt; break; case KBTS_FEATURE_TAG_pcap: Result = KBTS_FEATURE_ID_pcap; break; case KBTS_FEATURE_TAG_pkna: Result = KBTS_FEATURE_ID_pkna; break; case KBTS_FEATURE_TAG_pnum: Result = KBTS_FEATURE_ID_pnum; break; case KBTS_FEATURE_TAG_pres: Result = KBTS_FEATURE_ID_pres; break; case KBTS_FEATURE_TAG_psts: Result = KBTS_FEATURE_ID_psts; break; case KBTS_FEATURE_TAG_pwid: Result = KBTS_FEATURE_ID_pwid; break; case KBTS_FEATURE_TAG_qwid: Result = KBTS_FEATURE_ID_qwid; break; case KBTS_FEATURE_TAG_rand: Result = KBTS_FEATURE_ID_rand; break; case KBTS_FEATURE_TAG_rclt: Result = KBTS_FEATURE_ID_rclt; break; case KBTS_FEATURE_TAG_rkrf: Result = KBTS_FEATURE_ID_rkrf; break; case KBTS_FEATURE_TAG_rlig: Result = KBTS_FEATURE_ID_rlig; break; case KBTS_FEATURE_TAG_rtbd: Result = KBTS_FEATURE_ID_rtbd; break; case KBTS_FEATURE_TAG_rtla: Result = KBTS_FEATURE_ID_rtla; break; case KBTS_FEATURE_TAG_rtlm: Result = KBTS_FEATURE_ID_rtlm; break; case KBTS_FEATURE_TAG_ruby: Result = KBTS_FEATURE_ID_ruby; break; case KBTS_FEATURE_TAG_rvrn: Result = KBTS_FEATURE_ID_rvrn; break; case KBTS_FEATURE_TAG_salt: Result = KBTS_FEATURE_ID_salt; break; case KBTS_FEATURE_TAG_sinf: Result = KBTS_FEATURE_ID_sinf; break; case KBTS_FEATURE_TAG_size: Result = KBTS_FEATURE_ID_size; break; case KBTS_FEATURE_TAG_smcp: Result = KBTS_FEATURE_ID_smcp; break; case KBTS_FEATURE_TAG_smpl: Result = KBTS_FEATURE_ID_smpl; break; case KBTS_FEATURE_TAG_ss01: Result = KBTS_FEATURE_ID_ss01; break; case KBTS_FEATURE_TAG_ss02: Result = KBTS_FEATURE_ID_ss02; break; case KBTS_FEATURE_TAG_ss03: Result = KBTS_FEATURE_ID_ss03; break; case KBTS_FEATURE_TAG_ss04: Result = KBTS_FEATURE_ID_ss04; break; case KBTS_FEATURE_TAG_ss05: Result = KBTS_FEATURE_ID_ss05; break; case KBTS_FEATURE_TAG_ss06: Result = KBTS_FEATURE_ID_ss06; break; case KBTS_FEATURE_TAG_ss07: Result = KBTS_FEATURE_ID_ss07; break; case KBTS_FEATURE_TAG_ss08: Result = KBTS_FEATURE_ID_ss08; break; case KBTS_FEATURE_TAG_ss09: Result = KBTS_FEATURE_ID_ss09; break; case KBTS_FEATURE_TAG_ss10: Result = KBTS_FEATURE_ID_ss10; break; case KBTS_FEATURE_TAG_ss11: Result = KBTS_FEATURE_ID_ss11; break; case KBTS_FEATURE_TAG_ss12: Result = KBTS_FEATURE_ID_ss12; break; case KBTS_FEATURE_TAG_ss13: Result = KBTS_FEATURE_ID_ss13; break; case KBTS_FEATURE_TAG_ss14: Result = KBTS_FEATURE_ID_ss14; break; case KBTS_FEATURE_TAG_ss15: Result = KBTS_FEATURE_ID_ss15; break; case KBTS_FEATURE_TAG_ss16: Result = KBTS_FEATURE_ID_ss16; break; case KBTS_FEATURE_TAG_ss17: Result = KBTS_FEATURE_ID_ss17; break; case KBTS_FEATURE_TAG_ss18: Result = KBTS_FEATURE_ID_ss18; break; case KBTS_FEATURE_TAG_ss19: Result = KBTS_FEATURE_ID_ss19; break; case KBTS_FEATURE_TAG_ss20: Result = KBTS_FEATURE_ID_ss20; break; case KBTS_FEATURE_TAG_ssty: Result = KBTS_FEATURE_ID_ssty; break; case KBTS_FEATURE_TAG_stch: Result = KBTS_FEATURE_ID_stch; break; case KBTS_FEATURE_TAG_subs: Result = KBTS_FEATURE_ID_subs; break; case KBTS_FEATURE_TAG_sups: Result = KBTS_FEATURE_ID_sups; break; case KBTS_FEATURE_TAG_swsh: Result = KBTS_FEATURE_ID_swsh; break; case KBTS_FEATURE_TAG_test: Result = KBTS_FEATURE_ID_test; break; case KBTS_FEATURE_TAG_titl: Result = KBTS_FEATURE_ID_titl; break; case KBTS_FEATURE_TAG_tnam: Result = KBTS_FEATURE_ID_tnam; break; case KBTS_FEATURE_TAG_tnum: Result = KBTS_FEATURE_ID_tnum; break; case KBTS_FEATURE_TAG_trad: Result = KBTS_FEATURE_ID_trad; break; case KBTS_FEATURE_TAG_twid: Result = KBTS_FEATURE_ID_twid; break; case KBTS_FEATURE_TAG_unic: Result = KBTS_FEATURE_ID_unic; break; case KBTS_FEATURE_TAG_valt: Result = KBTS_FEATURE_ID_valt; break; case KBTS_FEATURE_TAG_vapk: Result = KBTS_FEATURE_ID_vapk; break; case KBTS_FEATURE_TAG_vatu: Result = KBTS_FEATURE_ID_vatu; break; case KBTS_FEATURE_TAG_vchw: Result = KBTS_FEATURE_ID_vchw; break; case KBTS_FEATURE_TAG_vert: Result = KBTS_FEATURE_ID_vert; break; case KBTS_FEATURE_TAG_vhal: Result = KBTS_FEATURE_ID_vhal; break; case KBTS_FEATURE_TAG_vkna: Result = KBTS_FEATURE_ID_vkna; break; case KBTS_FEATURE_TAG_vkrn: Result = KBTS_FEATURE_ID_vkrn; break; case KBTS_FEATURE_TAG_vpal: Result = KBTS_FEATURE_ID_vpal; break; case KBTS_FEATURE_TAG_vrt2: Result = KBTS_FEATURE_ID_vrt2; break; case KBTS_FEATURE_TAG_vrtr: Result = KBTS_FEATURE_ID_vrtr; break; case KBTS_FEATURE_TAG_zero: Result = KBTS_FEATURE_ID_zero; break; default: break; } return Result; } static kbts_s32 kbts_UnicodeParentDeltas[1679] = { 132,133,134,135,244,246,248,250,252,254,315,351,416,418,7678,7680,7682,7792,7794,132,133,134,135,275,277,279,281,283,285,346,382,447, 449,7709,7711,7713,7823,7825,131,132,133,134,174,176,178,180,182,416,418,452,7604,7606,7764,7766,7768,131,132,133,134,205,207,209,211,213, 447,449,483,7635,7637,7795,7797,7799,127,128,129,130,131,132,160,162,164,365,416,418,454,7584,7744,7746,127,128,129,130,131,132,191,193, 195,396,447,449,485,7615,7775,7777,131,132,133,134,135,222,224,226,306,355,380,414,416,448,7774,7776,131,132,133,134,135,253,255,257, 337,386,411,445,447,479,7805,7807,131,132,133,134,223,225,227,229,231,390,447,449,7651,7807,7809,131,132,133,134,192,194,196,198,359, 416,418,7620,7776,7778,132,134,254,442,7702,7712,7802,7804,7806,7808,-10,17,7031,7032,7101,7173,7191,7192,7197,131,214,216,218,395,7639,7641,7643, 7645,131,245,247,249,426,7670,7672,7674,7676,132,285,287,473,7733,7833,7835,7837,7839,227,229,231,415,417,7655,7657,7661,6,8,7051,7052,7093, 7195,7196,7201,189,439,7611,7613,7615,7617,7619,7726,239,241,423,7671,7673,7675,7677,7715,-5,6991,6992,7103,7167,7168,7170,7173,258,260,262,446,448, 7686,7688,7692,182,184,186,188,384,398,7610,213,215,217,219,415,429,7641,232,234,236,238,422,7662,7664,263,265,267,269,453,7693,7695,-15, 17,7071,7072,7231,7232,7233,220,470,7642,7644,7646,7648,7650,-11,7031,7032,7207,7208,7209,7211,254,7690,7692,7694,7696,7698,7713,270,272,454,7702,7704, 7706,7708,206,208,210,7627,7631,7633,-23,6,7092,7235,7236,7237,-26,7103,7104,7249,7251,7549,235,413,7653,7655,7657,8415,237,239,241,7658,7662,7664, -9,7017,7018,7101,7180,7183,5,7063,7064,7091,7210,7213,256,258,260,7703,7705,7707,171,7591,7593,7595,7597,7599,287,289,291,7734,7736,7738,202,7622, 7624,7626,7628,7630,285,7721,7723,7725,7727,7729,-3,-2,-1,3,4,1,2,3,4,5,132,164,166,168,170,-14,7057,7058,7219,7221,132,195, 197,199,201,7481,7483,7485,7487,7489,7482,7484,7486,7488,7490,204,382,7622,7624,7626,2,4,6,64,3,4,5,7,-21,203,205,207,2,4, 6,112,-11,1,202,204,2,4,6,128,1,37,171,173,-8,7003,7004,7101,-19,7081,7082,7257,27,172,174,176,-13,7043,7044,7219,218,220, 222,224,249,251,253,255,13,7041,7042,7097,7596,7598,7600,7602,7619,7621,7623,7625,7637,7639,7641,7643,7645,7647,7649,7651,7650,7652,7654,7656,7668,7670, 7672,7674,7676,7678,7680,7682,-33,-32,-31,-58,7176,7181,-27,7191,7196,-5,-4,-2,1,2,4,1,3,5,2,3,5,1,4,5,-21,-20, 193,2,4,16,3,5,6,14,15,16,27,28,162,312,7512,7514,343,7543,7545,7585,7587,7589,733,7961,8005,7616,7618,7620,7634,7636,7638,7665, 7667,7669,22891,22892,23346,31318,31405,162165,31650,31843,31932,35977,36182,166849,36278,36572,167227,36626,36698,36797,62785,62786,62816,25280,156147,156148,37394,37755,168385,38990,39065,169662, 62814,62815,62816,39089,39163,169757,40312,40387,171144,173234,173235,173236,-29,-28,12,22,161,163,140,167,171,198,253,279,203,390,284,310,7109,7176,7111,7190, 7087,7206,7203,7204,7426,7428,7428,7430,7684,7686,309,8294,7687,7689,7699,7701,7718,7720,7730,7732,25135,25233,25194,25291,25286,25458,25477,25572,27117,27183,27997,28089, 28255,28607,28357,28407,28458,28550,28458,28610,28513,28603,28875,28962,30692,30693,24507,155384,32406,32493,27530,158375,28470,159303,33613,33756,28625,159459,29500,160322,34266,34388,34540,34678, 29402,160600,30216,161096,35034,35118,30351,161459,32788,163609,32908,163783,35621,35704,37790,37917,32943,164035,33018,163837,40630,40631,41398,41506,42137,42203,33247,163972,54624,54625,33631,164350, 33716,164428,33778,164808,34352,165055,34921,165612,35453,166134,35790,166464,62788,62816,62816,62826,36046,166794,62816,62834,62816,62838,37311,168029,37752,168382,37810,168510,62816,62843,161426,161674, 38130,168825,38679,169659,39225,169818,39337,169999,39518,170436,40398,171018,42033,172614,42209,172718,164391,164392,169819,169821,42724,173276,42572,173332,42877,173358,42832,173379,170354,170355,42858,173405, 42927,173406,43001,173641,43196,173670,43237,173761,171308,171309,43338,173859,172737,172738,43650,174167,47771,178448,178804,178805,48949,179530,-99324,-90618,-87924,-84098,-80132,-77179,-77172,-3295,-163,-70, -60,-59,-36,-16,-6,9,10,26,32,34,41,48,51,55,56,59,60,63,66,67,78,81,100,118,169,187,200,278,282,294,340,720, 835,7085,7086,7110,7112,7156,7234,7243,7261,7273,7276,7277,7434,7440,7452,7458,7519,7609,7640,8009,8079,8739,8753,8754,21533,21757,22403,22533,22797,22850,23095,23227, 23233,23281,23298,23360,23371,23380,23445,23673,23963,24010,24281,24349,24361,24836,24879,24891,24946,24988,25094,25170,25195,25276,25316,25326,25344,25350,25352,25422,25430,25435,25464,25496, 25532,25561,25674,25675,25959,26097,26171,26173,26193,26425,26493,26543,26589,26627,26653,26703,26718,26756,26801,26921,26923,26951,26960,26999,27073,27179,27192,27217,27250,27309,27312,27340, 27464,27707,27770,27782,27832,28049,28122,28147,28267,28324,28331,28608,28656,28666,28698,28799,28894,28935,28936,28952,28977,29008,29015,29045,29116,29367,29393,29426,29487,29526,29684,29686, 29710,29867,29894,29915,29989,30055,30069,30405,30408,30477,30542,30561,30734,30805,30831,30919,30920,31016,31027,31082,31114,31253,31329,31341,31401,31464,31513,31603,31641,31645,31768,31776, 31816,31823,31892,31935,31972,32043,32045,32084,32095,32103,32104,32307,32472,32556,32570,32701,32715,32724,32763,32776,32859,32870,32873,32893,32949,32955,32965,32988,33012,33023,33028,33030, 33038,33053,33123,33210,33356,33388,33445,33526,33630,33642,33663,33740,33795,33809,33908,33926,33927,34059,34105,34117,34135,34152,34204,34243,34270,34273,34299,34344,34351,34354,34532,34563, 34594,34618,34800,34802,34846,34877,34890,35031,35039,35127,35170,35206,35327,35379,35391,35439,35457,35631,35634,35699,35773,35776,35820,35834,35882,35884,35898,35996,36049,36071,36074,36094, 36206,36343,36373,36377,36443,36446,36636,36665,37113,37178,37315,37331,37334,37344,37389,37453,37469,37523,37573,37693,37694,37714,37822,37837,37846,37873,37925,37977,37984,37996,38049,38135, 38202,38357,38441,38457,38461,38492,38514,38517,38540,38556,38590,38601,38700,38703,38730,38800,38820,38911,39000,39061,39126,39128,39210,39246,39296,39312,39342,39357,39397,39414,39487,39501, 39574,39640,39641,39706,39707,39736,39771,39850,39856,39889,39921,40124,40165,40169,40314,40318,40374,40407,40575,40793,40888,40900,40928,40974,40990,41059,41074,41230,41259,41274,41362,41418, 41465,41616,41648,41658,41772,41860,41936,42061,42273,42276,42288,42302,42407,42408,42447,42448,42577,42624,42634,42668,42735,42746,42814,42871,42872,42885,42889,42928,42932,42949,43023,43025, 43050,43063,43086,43088,43108,43212,43233,43253,43257,43274,43311,43396,43418,43430,43431,43433,43562,43673,43716,43721,43731,43763,43813,43828,43837,43866,44106,44197,44287,45331,45553,45851, 46452,46778,47491,47538,47676,47803,48104,48191,48639,48746,49225,49737,50294,50458,50655,50670,50678,50721,51392,52429,52652,53712,55046,55194,55959,56301,56665,56996,57719,57784,58229,60629, 60936,61695,61907,61909,62155,62198,62454,62765,63201,154337,154373,154379,154388,154394,154398,154458,154792,154895,155083,155657,155716,155742,155867,155936,156119,156186,156370,156464,156729,156771,157143,157170, 157457,157550,157615,157899,157907,157938,158030,158191,158474,158700,158735,158751,158816,158907,158996,159017,159101,159535,159951,159977,159983,160097,160099,160192,160223,160312,160338,160404,160427,160472,160526,160560, 160589,160590,160611,160840,160916,160950,160951,161207,161223,161238,161239,161248,161262,161335,161357,161401,161404,161456,161496,161505,161506,161524,161534,161541,161672,161833,161863,161920,162000,162063,162077,162175, 162275,162300,162603,162669,162727,162825,162922,162944,162950,162964,163226,163228,163441,163596,163600,163692,164096,164287,164650,164856,164880,164968,165036,165075,165095,165254,165278,165294,165520,165540,165586,165624, 165762,165829,165847,165997,166043,166050,166093,166106,166138,166220,166305,166469,166555,166617,166677,166784,166796,166810,166850,166867,166889,166960,166973,167063,167084,167253,167297,167325,167374,167442,167491,167680, 167750,167846,167890,168022,168079,168134,168165,168283,168317,168329,168377,168404,168505,168580,168680,168797,169000,169030,169039,169050,169117,169177,169211,169240,169273,169299,169319,169340,169406,169442,169476,169559, 169624,169634,169681,169722,169727,169737,169776,169822,169950,170015,170150,170183,170192,170242,170273,170287,170295,170386,170455,170457,170459,170526,170569,170589,170631,170656,170756,170768,170772,170809,170937,170989, 171031,171074,171091,171117,171123,171133,171158,171178,171361,171520,171581,171592,171638,171661,171729,171773,171836,171843,171862,171875,171876,171880,171948,172068,172070,172103,172127,172164,172234,172341,172342,172507, 172541,172680,172694,172701,172769,172784,172850,172875,172958,173015,173046,173061,173109,173129,173134,173144,173164,173244,173268,173283,173348,173484,173488,173531,173541,173595,173608,173678,173684,173696,173704,173722, 173740,173741,173755,173791,173884,173886,173888,173936,173966,174085,174155,174244,174413,174529,174531,174537,175296,175385,175393,175423,175674,175824,175946,176003,176010,176140,176218,176903,176911,177043,177097,177128, 177223,177230,177233,177276,177406,177443,177529,177580,177691,177725,177772,177863,177981,178014,178217,178286,178358,178437,178487,178498,178712,178814,179072,179159,179364,179414,179605,179637,179656,179693,179803,179860, 180071,180102,180152,180175,180238,180262,180308,180469,180588,180601,181007,181056,181082,181102,181519, }; static kbts_u8 kbts_UnicodeDecomposition_PageIndices[17407] = { 0,1,1,2,3,4,5,6,7,1,1,1,1,8,9,10,11,12,1,13,1,1,1,1,14,1,1,15,1,1,1,1, 1,1,1,1,16,17,1,18,19,20,1,1,1,21,1,22,1,23,1,24,1,25,1,26,1,1,1,1,1,27,28,1, 29,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,30,31, 1,1,1,1,1,1,1,1,1,1,1,1,32,33,1,1,1,1,1,1,1,1,1,1,34,35,36,37,38,39,40,41, 42,1,1,1,43,1,44,45,46,47,48,49,50,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,51,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,52,53,54,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,55,56,57,58,59,60,61,62,63,64,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,65,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,66,1,67,1,1,1,1,1,1,1,1,68,69,70,1,1,71,1,1,1,72,1,1,1,1,1,1,1,1,1, 1,1,1,1,73,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,74,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,75,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,76,77,78,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 79,80,81,82,83,84,85,86,87,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, }; static kbts_u64 kbts_UnicodeDecomposition_Data[5632] = { 52776558133248ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,343932928ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 6442451206ull,6450839814ull,6459228422ull,6467617030ull,6509560070ull,6526337286ull,0ull,6769606926ull,6442451222ull,6450839830ull,6459228438ull,6509560086ull,6442451238ull,6450839846ull,6459228454ull,6509560102ull,0ull,6467617082ull,6442451262ull,6450839870ull,6459228478ull,6467617086ull,6509560126ull,0ull,0ull,6442451286ull,6450839894ull,6459228502ull,6509560150ull,6450839910ull,0ull,0ull, 6442451334ull,6450839942ull,6459228550ull,6467617158ull,6509560198ull,6526337414ull,0ull,6769607054ull,6442451350ull,6450839958ull,6459228566ull,6509560214ull,6442451366ull,6450839974ull,6459228582ull,6509560230ull,0ull,6467617210ull,6442451390ull,6450839998ull,6459228606ull,6467617214ull,6509560254ull,0ull,0ull,6442451414ull,6450840022ull,6459228630ull,6509560278ull,6450840038ull,0ull,6509560294ull, 6476005638ull,6476005766ull,6492782854ull,6492782982ull,6777995526ull,6777995654ull,6450839822ull,6450839950ull,6459228430ull,6459228558ull,6501171470ull,6501171598ull,6543114510ull,6543114638ull,6543114514ull,6543114642ull,0ull,0ull,6476005654ull,6476005782ull,6492782870ull,6492782998ull,6501171478ull,6501171606ull,6777995542ull,6777995670ull,6543114518ull,6543114646ull,6459228446ull,6459228574ull,6492782878ull,6492783006ull, 6501171486ull,6501171614ull,6769606942ull,6769607070ull,6459228450ull,6459228578ull,0ull,0ull,6467617062ull,6467617190ull,6476005670ull,6476005798ull,6492782886ull,6492783014ull,6777995558ull,6777995686ull,6501171494ull,0ull,0ull,0ull,6459228458ull,6459228586ull,6769606958ull,6769607086ull,0ull,6450839858ull,6450839986ull,6769606962ull,6769607090ull,6543114546ull,6543114674ull,0ull, 0ull,0ull,0ull,6450839866ull,6450839994ull,6769606970ull,6769607098ull,6543114554ull,6543114682ull,0ull,0ull,0ull,6476005694ull,6476005822ull,6492782910ull,6492783038ull,6534725950ull,6534726078ull,0ull,0ull,6450839882ull,6450840010ull,6769606986ull,6769607114ull,6543114570ull,6543114698ull,6450839886ull,6450840014ull,6459228494ull,6459228622ull,6769606990ull,6769607118ull, 6543114574ull,6543114702ull,6769606994ull,6769607122ull,6543114578ull,6543114706ull,0ull,0ull,6467617110ull,6467617238ull,6476005718ull,6476005846ull,6492782934ull,6492783062ull,6526337366ull,6526337494ull,6534725974ull,6534726102ull,6777995606ull,6777995734ull,6459228510ull,6459228638ull,6459228518ull,6459228646ull,6509560166ull,6450839914ull,6450840042ull,6501171562ull,6501171690ull,6543114602ull,6543114730ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 6668943678ull,6668943806ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6668943702ull,6668943830ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6543114502ull,6543114630ull,6543114534ull,6543114662ull,6543114558ull,6543114686ull,6543114582ull,6543114710ull,6476006258ull,6476006386ull,6450840434ull,6450840562ull,6543115122ull,6543115250ull,6442451826ull,6442451954ull,0ull,6476006162ull,6476006290ull, 6476007578ull,6476007582ull,6476006170ull,6476006298ull,0ull,0ull,6543114526ull,6543114654ull,6543114542ull,6543114670ull,6777995582ull,6777995710ull,6476007338ull,6476007342ull,6543115998ull,6543116874ull,6543114666ull,0ull,0ull,0ull,6450839838ull,6450839966ull,0ull,0ull,6442451258ull,6442451386ull,6450840342ull,6450840470ull,6450840346ull,6450840474ull,6450840418ull,6450840546ull, 6568280326ull,6568280454ull,6585057542ull,6585057670ull,6568280342ull,6568280470ull,6585057558ull,6585057686ull,6568280358ull,6568280486ull,6585057574ull,6585057702ull,6568280382ull,6568280510ull,6585057598ull,6585057726ull,6568280394ull,6568280522ull,6585057610ull,6585057738ull,6568280406ull,6568280534ull,6585057622ull,6585057750ull,6761218382ull,6761218510ull,6761218386ull,6761218514ull,0ull,0ull,6543114530ull,6543114658ull, 0ull,0ull,0ull,0ull,0ull,0ull,6501171462ull,6501171590ull,6769606934ull,6769607062ull,6476006234ull,6476006362ull,6476006230ull,6476006358ull,6501171518ull,6501171646ull,6476007610ull,6476007614ull,6476005734ull,6476005862ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 3073ull,3077ull,0ull,3149ull,6450842658ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,2789ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,237ull,0ull, 0ull,0ull,0ull,0ull,0ull,6450840226ull,6450843206ull,733ull,6450843222ull,6450843230ull,6450843238ull,0ull,6450843262ull,0ull,6450843286ull,6450843302ull,6450843434ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6509563494ull,6509563542ull,6450843334ull,6450843350ull,6450843358ull,6450843366ull,6450843438ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6509563622ull,6509563670ull,6450843390ull,6450843414ull,6450843430ull,0ull,0ull,0ull,0ull,6450843466ull,6509563722ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 6442455126ull,6509563990ull,0ull,6450843726ull,0ull,0ull,0ull,6509563930ull,0ull,0ull,0ull,0ull,6450843754ull,6442455138ull,6492786830ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6492786786ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6492786914ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6442455254ull,6509564118ull,0ull,6450843854ull,0ull,0ull,0ull,6509564250ull,0ull,0ull,0ull,0ull,6450843882ull,6442455266ull,6492786958ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6568284626ull,6568284630ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,6492786778ull,6492786906ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6492786754ull,6492786882ull,6509563970ull,6509564098ull,0ull,0ull,6492786774ull,6492786902ull,0ull,0ull,6509564770ull,6509564774ull,6509563994ull,6509564122ull,6509563998ull,6509564126ull, 0ull,0ull,6476009570ull,6476009698ull,6509564002ull,6509564130ull,6509564026ull,6509564154ull,0ull,0ull,6509564834ull,6509564838ull,6509564086ull,6509564214ull,6476009614ull,6476009742ull,6509564046ull,6509564174ull,6534729870ull,6534729998ull,6509564062ull,6509564190ull,0ull,0ull,6509564078ull,6509564206ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,13581162654ull,13589551262ull,13589551394ull,13597939870ull,13589551402ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 13589551958ull,0ull,13589551878ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,13589551946ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,19830678690ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,19830678734ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,19830678614ull,19830678618ull,19830678622ull,19830678642ull,19830678662ull,19830678666ull,19830678702ull,19830678718ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,20921198366ull,21130913566ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,20904421054ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,21978163402ull,0ull,0ull,21978163426ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,21978163290ull,21978163294ull,21978163314ull,0ull,0ull,21978163374ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,24343751966ull,0ull,0ull,24142425374ull,24352140574ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,24125648006ull,24125648010ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,25216167706ull,25216167710ull,25425882906ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,26491236634ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 27556590334ull,0ull,0ull,0ull,0ull,0ull,0ull,27556590362ull,27564978970ull,0ull,27397206810ull,27556590378ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,28437394714ull,28437394718ull,28647109914ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,29611800422ull,0ull,29653743462ull,29611800434ull,29787961190ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,33747385610ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33747385650ull,0ull,0ull,0ull,0ull,33747385670ull,0ull,0ull,0ull,0ull,33747385690ull,0ull,0ull,0ull,0ull,33747385710ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33730608386ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33168571846ull,0ull,33185349062ull,33286012618ull,0ull,33286012622ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,33286012358ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33747385930ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33747385970ull,0ull,0ull, 0ull,0ull,33747385990ull,0ull,0ull,0ull,0ull,33747386010ull,0ull,0ull,0ull,0ull,33747386030ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,33730608706ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,34745630870ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,35235358072582ull,35235366461190ull, 35235374849798ull,0ull,0ull,0ull,35235408404230ull,35235416792838ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,58426682390ull,0ull,58426682398ull,0ull,58426682406ull,0ull,58426682414ull,0ull,58426682422ull,0ull,0ull,0ull,58426682438ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,58426682602ull,0ull,58426682610ull,0ull,0ull, 58426682618ull,58426682622ull,0ull,58426682634ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 6752829702ull,6752829830ull,6501171466ull,6501171594ull,6736052490ull,6736052618ull,6853493002ull,6853493130ull,6450840350ull,6450840478ull,6501171474ull,6501171602ull,6736052498ull,6736052626ull,6853493010ull,6853493138ull,6769606930ull,6769607058ull,6819938578ull,6819938706ull,6442452042ull,6442452046ull,6450840650ull,6450840654ull,6819938582ull,6819938710ull,6845104406ull,6845104534ull,6492784802ull,6492784806ull,6501171482ull,6501171610ull, 6476005662ull,6476005790ull,6501171490ull,6501171618ull,6736052514ull,6736052642ull,6509560098ull,6509560226ull,6769606946ull,6769607074ull,6828327202ull,6828327330ull,6845104422ull,6845104550ull,6450840382ull,6450840510ull,6450839854ull,6450839982ull,6736052526ull,6736052654ull,6853493038ull,6853493166ull,6736052530ull,6736052658ull,6476036314ull,6476036318ull,6853493042ull,6853493170ull,6819938610ull,6819938738ull,6450839862ull,6450839990ull, 6501171510ull,6501171638ull,6736052534ull,6736052662ull,6501171514ull,6501171642ull,6736052538ull,6736052666ull,6853493050ull,6853493178ull,6819938618ull,6819938746ull,6450840406ull,6450840534ull,6509560662ull,6509560790ull,6442452274ull,6442452278ull,6450840882ull,6450840886ull,6450839874ull,6450840002ull,6501171522ull,6501171650ull,6501171530ull,6501171658ull,6736052554ull,6736052682ull,6476036458ull,6476036462ull,6853493066ull,6853493194ull, 6501171534ull,6501171662ull,6736052558ull,6736052686ull,6501172586ull,6501172590ull,6501172610ull,6501172614ull,6501202314ull,6501202318ull,6501171538ull,6501171666ull,6736052562ull,6736052690ull,6853493074ull,6853493202ull,6819938642ull,6819938770ull,6744441174ull,6744441302ull,6845104470ull,6845104598ull,6819938646ull,6819938774ull,6450840994ull,6450840998ull,6509561258ull,6509561262ull,6467617114ull,6467617242ull,6736052570ull,6736052698ull, 6442451294ull,6442451422ull,6450839902ull,6450840030ull,6509560158ull,6509560286ull,6501171550ull,6501171678ull,6736052574ull,6736052702ull,6501171554ull,6501171682ull,6509560162ull,6509560290ull,6501171558ull,6501171686ull,6459228522ull,6459228650ull,6736052586ull,6736052714ull,6853493098ull,6853493226ull,6853493154ull,6509560274ull,6526337502ull,6526337510ull,0ull,6501172734ull,0ull,0ull,0ull,0ull, 6736052486ull,6736052614ull,6517948678ull,6517948806ull,6450840330ull,6450840458ull,6442451722ull,6442451850ull,6517949194ull,6517949322ull,6467617546ull,6467617674ull,6459259522ull,6459259526ull,6450840586ull,6450840590ull,6442451978ull,6442451982ull,6517949450ull,6517949454ull,6467617802ull,6467617806ull,6492813954ull,6492813958ull,6736052502ull,6736052630ull,6517948694ull,6517948822ull,6467617046ull,6467617174ull,6450840362ull,6450840490ull, 6442451754ull,6442451882ull,6517949226ull,6517949354ull,6467617578ull,6467617706ull,6459259618ull,6459259622ull,6517948710ull,6517948838ull,6736052518ull,6736052646ull,6736052542ull,6736052670ull,6517948734ull,6517948862ull,6450840402ull,6450840530ull,6442451794ull,6442451922ull,6517949266ull,6517949394ull,6467617618ull,6467617746ull,6459259698ull,6459259702ull,6450841218ull,6450841222ull,6442452610ull,6442452614ull,6517950082ull,6517950086ull, 6467618434ull,6467618438ull,6736053890ull,6736053894ull,6736052566ull,6736052694ull,6517948758ull,6517948886ull,6450841278ull,6450841282ull,6442452670ull,6442452674ull,6517950142ull,6517950146ull,6467618494ull,6467618498ull,6736053950ull,6736053954ull,6442451302ull,6442451430ull,6736052582ull,6736052710ull,6517948774ull,6517948902ull,6467617126ull,6467617254ull,0ull,0ull,0ull,0ull,0ull,0ull, 6601838278ull,6610226886ull,6442482690ull,6442482694ull,6450871298ull,6450871302ull,6996130818ull,6996130822ull,6601838150ull,6610226758ull,6442482722ull,6442482726ull,6450871330ull,6450871334ull,6996130850ull,6996130854ull,6601838294ull,6610226902ull,6442482754ull,6442482758ull,6450871362ull,6450871366ull,0ull,0ull,6601838166ull,6610226774ull,6442482786ull,6442482790ull,6450871394ull,6450871398ull,0ull,0ull, 6601838302ull,6610226910ull,6442482818ull,6442482822ull,6450871426ull,6450871430ull,6996130946ull,6996130950ull,6601838174ull,6610226782ull,6442482850ull,6442482854ull,6450871458ull,6450871462ull,6996130978ull,6996130982ull,6601838310ull,6610226918ull,6442482882ull,6442482886ull,6450871490ull,6450871494ull,6996131010ull,6996131014ull,6601838182ull,6610226790ull,6442482914ull,6442482918ull,6450871522ull,6450871526ull,6996131042ull,6996131046ull, 6601838334ull,6610226942ull,6442482946ull,6442482950ull,6450871554ull,6450871558ull,0ull,0ull,6601838206ull,6610226814ull,6442482978ull,6442482982ull,6450871586ull,6450871590ull,0ull,0ull,6601838358ull,6610226966ull,6442483010ull,6442483014ull,6450871618ull,6450871622ull,6996131138ull,6996131142ull,0ull,6610226838ull,0ull,6442483046ull,0ull,6450871654ull,0ull,6996131174ull, 6601838374ull,6610226982ull,6442483074ull,6442483078ull,6450871682ull,6450871686ull,6996131202ull,6996131206ull,6601838246ull,6610226854ull,6442483106ull,6442483110ull,6450871714ull,6450871718ull,6996131234ull,6996131238ull,6442454726ull,3761ull,6442454742ull,3765ull,6442454750ull,3769ull,6442454758ull,3773ull,6442454782ull,3889ull,6442454806ull,3893ull,6442454822ull,3897ull,0ull,0ull, 7021296642ull,7021296646ull,7021296650ull,7021296654ull,7021296658ull,7021296662ull,7021296666ull,7021296670ull,7021296674ull,7021296678ull,7021296682ull,7021296686ull,7021296690ull,7021296694ull,7021296698ull,7021296702ull,7021296770ull,7021296774ull,7021296778ull,7021296782ull,7021296786ull,7021296790ull,7021296794ull,7021296798ull,7021296802ull,7021296806ull,7021296810ull,7021296814ull,7021296818ull,7021296822ull,7021296826ull,7021296830ull, 7021297026ull,7021297030ull,7021297034ull,7021297038ull,7021297042ull,7021297046ull,7021297050ull,7021297054ull,7021297058ull,7021297062ull,7021297066ull,7021297070ull,7021297074ull,7021297078ull,7021297082ull,7021297086ull,6492786374ull,6476009158ull,7021297090ull,7021268678ull,7021268658ull,0ull,6996102854ull,7021297370ull,6492786246ull,6476009030ull,6442454598ull,3609ull,7021268550ull,0ull,3813ull,0ull, 0ull,6996099746ull,7021297106ull,7021268702ull,7021268666ull,0ull,6996102878ull,7021297434ull,6442454614ull,3617ull,6442454622ull,3621ull,7021268574ull,6442483454ull,6450872062ull,6996131582ull,6492786406ull,6476009190ull,6442454826ull,3649ull,0ull,0ull,6996102886ull,6996102954ull,6492786278ull,6476009062ull,6442454630ull,3625ull,0ull,6442483706ull,6450872314ull,6996131834ull, 6492786454ull,6476009238ull,6442454830ull,3777ull,6601838342ull,6610226950ull,6996102934ull,6996102958ull,6492786326ull,6476009110ull,6442454678ull,3641ull,6610226822ull,6442451618ull,3605ull,385ull,0ull,0ull,7021297138ull,7021268774ull,7021268794ull,0ull,6996102950ull,7021297626ull,6442454654ull,3633ull,6442454694ull,3645ull,7021268646ull,721ull,0ull,0ull, 32777ull,32781ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,32833ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,3749ull,0ull,0ull,0ull,301ull,789ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912247362ull,6912247370ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912247378ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912247618ull,6912247634ull,6912247626ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,6912247822ull,0ull,0ull,0ull,0ull,6912247842ull,0ull,0ull,6912247854ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,6912247950ull,0ull,6912247958ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,6912248050ull,0ull,0ull,6912248078ull,0ull,0ull,6912248086ull,0ull,6912248098ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 6912213238ull,0ull,6912248198ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912248118ull,6912213234ull,6912213242ull,6912248210ull,6912248214ull,0ull,0ull,6912248266ull,6912248270ull,0ull,0ull,6912248282ull,6912248286ull,0ull,0ull,0ull,0ull,0ull,0ull, 6912248298ull,6912248302ull,0ull,0ull,6912248330ull,6912248334ull,0ull,0ull,6912248346ull,6912248350ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912248458ull,6912248482ull,6912248486ull,6912248494ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 6912248306ull,6912248310ull,6912248390ull,6912248394ull,0ull,0ull,0ull,0ull,0ull,0ull,6912248522ull,6912248526ull,6912248530ull,6912248534ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,49185ull,49189ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6912256886ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721582ull,0ull,104362721590ull,0ull,104362721598ull,0ull,104362721606ull,0ull,104362721614ull,0ull,104362721622ull,0ull,104362721630ull,0ull,104362721638ull,0ull,104362721646ull,0ull,104362721654ull,0ull, 104362721662ull,0ull,104362721670ull,0ull,0ull,104362721682ull,0ull,104362721690ull,0ull,104362721698ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721726ull,104371110334ull,0ull,104362721738ull,104371110346ull,0ull,104362721750ull,104371110358ull,0ull,104362721762ull,104371110370ull,0ull,104362721774ull,104371110382ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721562ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721910ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721966ull,0ull,104362721974ull,0ull,104362721982ull,0ull,104362721990ull,0ull,104362721998ull,0ull,104362722006ull,0ull,104362722014ull,0ull,104362722022ull,0ull,104362722030ull,0ull,104362722038ull,0ull, 104362722046ull,0ull,104362722054ull,0ull,0ull,104362722066ull,0ull,104362722074ull,0ull,104362722082ull,0ull,0ull,0ull,0ull,0ull,0ull,104362722110ull,104371110718ull,0ull,104362722122ull,104371110730ull,0ull,104362722134ull,104371110742ull,0ull,104362722146ull,104371110754ull,0ull,104362722158ull,104371110766ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,104362721946ull,0ull,0ull,104362722238ull,104362722242ull,104362722246ull,104362722250ull,0ull,0ull,0ull,104362722294ull,0ull, 143649ull,105425ull,146217ull,144161ull,113477ull,80073ull,85909ull,163441ull,163441ull,91461ull,149317ull,87581ull,91425ull,100313ull,121253ull,130581ull,137469ull,138985ull,140257ull,148029ull,108553ull,111725ull,115557ull,118649ull,135413ull,148905ull,157637ull,80393ull,85461ull,109585ull,116845ull,137397ull, 161913ull,95553ull,114605ull,137013ull,140689ull,101157ull,132961ull,139389ull,97065ull,105565ull,112041ull,117745ull,148281ull,81433ull,83677ull,84857ull,103185ull,109389ull,116801ull,121757ull,131077ull,137241ull,137585ull,145341ull,154825ull,159165ull,161769ull,123441ull,124413ull,128641ull,134949ull,150545ull, 162301ull,142169ull,91005ull,97297ull,127361ull,131577ull,117129ull,123689ull,144137ull,154589ull,90977ull,94601ull,108621ull,112489ull,113725ull,128189ull,129245ull,153901ull,84809ull,131629ull,83825ull,83761ull,125041ull,128761ull,135109ull,154069ull,142849ull,101181ull,108553ull,142329ull,80101ull,94109ull, 98377ull,118301ull,120257ull,85085ull,123885ull,81661ull,97957ull,79925ull,111409ull,103905ull,128137ull,85773ull,90489ull,121861ull,135461ull,141993ull,110313ull,147137ull,111137ull,101369ull,134037ull,102017ull,120213ull,80569ull,83365ull,83749ull,107013ull,127901ull,133565ull,142153ull,149309ull,84949ull, 86281ull,91597ull,97201ull,104213ull,114681ull,124073ull,153269ull,158121ull,162397ull,162617ull,84589ull,105241ull,110045ull,146825ull,96721ull,99905ull,100353ull,103017ull,113805ull,116005ull,119333ull,124713ull,128977ull,131517ull,146585ull,136121ull,147597ull,150825ull,84061ull,84621ull,86773ull,115489ull, 140041ull,141993ull,97061ull,98261ull,101869ull,110265ull,127225ull,118229ull,80785ull,89061ull,94109ull,95977ull,98417ull,118473ull,119205ull,130665ull,131353ull,149713ull,154585ull,154913ull,155745ull,81453ull,124601ull,149201ull,154337ull,99205ull,80409ull,82793ull,94137ull,94461ull,104037ull,108553ull, 116537ull,121097ull,136177ull,147953ull,163381ull,104993ull,153785ull,84517ull,105965ull,106445ull,111877ull,113265ull,118821ull,120165ull,123309ull,128065ull,156025ull,83381ull,100537ull,154081ull,82093ull,95333ull,112553ull,146601ull,97837ull,99601ull,106589ull,118301ull,154137ull,84133ull,86077ull,94613ull, 104525ull,105785ull,107169ull,111509ull,118809ull,120713ull,130533ull,140093ull,140165ull,149297ull,154505ull,85245ull,113385ull,86133ull,116545ull,119393ull,137193ull,154253ull,160093ull,162429ull,106077ull,112429ull,133025ull,125741ull,126081ull,127561ull,117505ull,115301ull,142689ull,80641ull,134361ull,84201ull, 83997ull,96921ull,101197ull,127833ull,93717ull,111737ull,105169ull,146669ull,139569ull,153909ull,140845ull,97101ull,83201ull,87809ull,0ull,0ull,90473ull,0ull,104913ull,0ull,0ull,83833ull,117929ull,121641ull,124145ull,124281ull,124309ull,124477ull,154969ull,127737ull,130805ull,0ull, 137289ull,0ull,142305ull,0ull,0ull,147681ull,148469ull,0ull,0ull,0ull,156605ull,156657ull,156833ull,161489ull,148345ull,154333ull,81593ull,82845ull,83253ull,84773ull,84881ull,85317ull,87669ull,88089ull,88481ull,90369ull,90785ull,94609ull,94649ull,98897ull,99745ull,99897ull, 100297ull,103741ull,104329ull,105029ull,107029ull,112093ull,112745ull,113801ull,116153ull,116909ull,118921ull,123461ull,124153ull,124197ull,124193ull,124225ull,124249ull,124277ull,124469ull,124473ull,125185ull,125445ull,126721ull,128977ull,129061ull,129285ull,130505ull,131093ull,133045ull,133605ull,133605ull,135517ull, 140353ull,140889ull,142341ull,142565ull,144205ull,144417ull,147161ull,147681ull,154509ull,155645ull,155885ull,98773ull,592825ull,133217ull,0ull,0ull,80025ull,83669ull,83361ull,81409ull,83221ull,83457ull,84765ull,84969ull,87669ull,87381ull,87653ull,87945ull,90473ull,90829ull,91409ull,91473ull, 92553ull,93345ull,97097ull,97125ull,97701ull,97973ull,99169ull,99641ull,99361ull,99897ull,99713ull,100297ull,100561ull,102161ull,102513ull,102729ull,103769ull,104913ull,105565ull,105581ull,105817ull,110053ull,110313ull,111877ull,113517ull,113453ull,113801ull,114809ull,116153ull,122525ull,116949ull,117437ull, 117929ull,119237ull,119833ull,120045ull,120949ull,120957ull,121641ull,121709ull,121809ull,122153ull,122113ull,123697ull,125637ull,126721ull,127469ull,128365ull,128977ull,130297ull,131093ull,134473ull,135101ull,138725ull,140549ull,140825ull,140889ull,142077ull,142305ull,142125ull,142341ull,142329ull,142261ull,142565ull, 142889ull,144417ull,146657ull,147913ull,149093ull,149977ull,154097ull,154509ull,154969ull,155501ull,155645ull,155693ull,155885ull,158793ull,163441ull,565545ull,565521ull,577365ull,61045ull,65633ull,65765ull,608549ull,619329ull,654157ull,163085ull,163385ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,12247373670ull,0ull,12272539594ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,12356425638ull,12364814246ull,12356676902ull,12365065510ull,12272539458ull,12280928066ull,12314482498ull,12314482502ull,12314482506ull,12314482510ull,12314482514ull,12314482518ull,12314482522ull,0ull,12314482530ull,12314482534ull,12314482538ull,12314482542ull,12314482546ull,0ull,12314482554ull,0ull, 12314482562ull,12314482566ull,0ull,12314482574ull,12314482578ull,0ull,12314482586ull,12314482590ull,12314482594ull,12314482598ull,12314482602ull,12289316694ull,12339648326ull,12339648366ull,12339648402ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,6501439306ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,6501439338ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,585676112486ull,0ull,585676112494ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,585676112534ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,586590471366ull,586590471370ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,591078378782ull,591288093982ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,592244395530ull,0ull,592126955026ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,592185675310ull,0ull,0ull,592244395586ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,592185675530ull,0ull,592101789450ull,592244395786ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,594266051302ull,594182165222ull,0ull,594291217126ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,596321261282ull,596321261286ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,603845846230ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,758313747578ull,758406022266ull,758322136186ull,758322136230ull,758330524794ull,758322136198ull,758322136202ull,758330524806ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,784695932318ull,784695932302ull,784695932326ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,999427622238ull,999427622242ull, 999503119742ull,999511508350ull,999519896958ull,999528285566ull,999536674174ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,999427622630ull,999427622634ull,999503120110ull,999503120114ull,999511508718ull, 999511508722ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, 80117ull,80097ull,80133ull,525449ull,81281ull,81593ull,81645ull,81929ull,82409ull,82533ull,82845ull,82749ull,53881ull,530665ull,83253ull,83281ull,83345ull,83421ull,529521ull,53989ull,83357ull,83509ull,529709ull,83549ull,83601ull,80689ull,83633ull,83669ull,673661ull,83925ull,83981ull,54141ull, 84205ull,84249ull,84425ull,84445ull,54357ull,84765ull,84773ull,84881ull,84969ull,85013ull,85017ull,85085ull,85285ull,85317ull,85353ull,85453ull,85493ull,85501ull,85501ull,85501ull,534705ull,115137ull,85801ull,85885ull,535949ull,85933ull,85957ull,86041ull,86649ull,86241ull,86305ull,86433ull, 86665ull,87001ull,87105ull,87373ull,87437ull,87569ull,87569ull,87653ull,87725ull,87757ull,87817ull,89177ull,88089ull,89181ull,88389ull,88529ull,83997ull,91065ull,89913ull,90065ull,90165ull,89645ull,90313ull,90309ull,90801ull,545681ull,91081ull,91101ull,91161ull,91241ull,91273ull,91529ull, 547489ull,547753ull,92081ull,92269ull,92317ull,92001ull,92569ull,56249ull,56305ull,93217ull,93433ull,93433ull,550689ull,93965ull,94049ull,94109ull,94157ull,552033ull,94205ull,94233ull,97613ull,94345ull,56837ull,94593ull,94649ull,94977ull,94773ull,554897ull,95501ull,554905ull,95673ull,95661ull, 95729ull,96133ull,96137ull,57533ull,96245ull,96417ull,96501ull,96677ull,57737ull,558605ull,57841ull,96961ull,96973ull,96985ull,97065ull,691785ull,97273ull,560325ull,560325ull,133125ull,97417ull,97417ull,58141ull,576225ull,624489ull,97673ull,97709ull,58253ull,97897ull,98101ull,98141ull,98277ull, 98821ull,58601ull,58481ull,98897ull,564049ull,99101ull,99617ull,99633ull,99641ull,99633ull,99817ull,99897ull,100041ull,99985ull,100029ull,100217ull,100297ull,100313ull,100417ull,100461ull,100725ull,101061ull,101201ull,101697ull,568369ull,101621ull,101361ull,101793ull,101901ull,102289ull,569285ull,102537ull, 102165ull,102053ull,59577ull,102821ull,102905ull,103029ull,102877ull,59825ull,103741ull,103857ull,573481ull,104333ull,105441ull,104741ull,60517ull,105029ull,60449ull,60305ull,83529ull,83541ull,105473ull,105073ull,131765ull,69477ull,105565ull,105581ull,105605ull,105849ull,105805ull,577293ull,60709ull,106473ull, 106005ull,106825ull,107029ull,577973ull,107065ull,106621ull,107601ull,61045ull,107785ull,108173ull,108457ull,109217ull,580237ull,109421ull,61537ull,109701ull,582301ull,109905ull,61753ull,110025ull,110205ull,110313ull,110317ull,584245ull,554029ull,584681ull,110905ull,586481ull,111357ull,111413ull,111005ull,111705ull, 111865ull,112093ull,111877ull,112037ull,112097ull,112149ull,586873ull,111825ull,112829ull,113081ull,62669ull,113453ull,113437ull,588613ull,112613ull,114105ull,589177ull,589369ull,114457ull,114917ull,114809ull,114797ull,63065ull,114985ull,115189ull,115165ull,115381ull,529557ull,115989ull,592269ull,116337ull,593581ull, 116897ull,116949ull,117057ull,596001ull,117249ull,117333ull,597205ull,598097ull,118249ull,118317ull,64177ull,118421ull,64225ull,64225ull,119069ull,119153ull,119237ull,119317ull,119593ull,64621ull,119953ull,602329ull,120057ull,602697ull,120257ull,558717ull,120897ull,605829ull,605921ull,606481ull,65521ull,65569ull, 121809ull,607181ull,607177ull,607333ull,607437ull,121977ull,121981ull,121981ull,122153ull,65765ull,122413ull,65817ull,66137ull,610421ull,123193ull,123441ull,123697ull,66445ull,612505ull,124249ull,612969ull,613141ull,124477ull,124845ull,66749ull,125185ull,125225ull,125245ull,615921ull,617117ull,617117ull,125881ull, 67593ull,618157ull,126745ull,126757ull,67741ull,619009ull,127817ull,68225ull,127905ull,127885ull,128001ull,622105ull,128397ull,68613ull,128797ull,129033ull,129301ull,68817ull,624801ull,624925ull,68965ull,625509ull,130537ull,625913ull,130645ull,131049ull,131093ull,627561ull,627853ull,131457ull,628385ull,131521ull, 576893ull,69461ull,131785ull,132109ull,69677ull,132345ull,92885ull,630429ull,630485ull,577101ull,577137ull,133125ull,133137ull,147065ull,70061ull,133701ull,133677ull,133749ull,84685ull,133829ull,133837ull,133877ull,134041ull,634097ull,134037ull,134261ull,134541ull,134837ull,134285ull,134901ull,135069ull,135517ull, 134477ull,134953ull,134961ull,135025ull,635097ull,636333ull,635733ull,70829ull,136133ull,136141ull,136281ull,642857ull,136593ull,638129ull,71029ull,71045ull,638661ull,639817ull,71085ull,137537ull,137585ull,137629ull,137637ull,137893ull,137761ull,138297ull,138121ull,138725ull,138401ull,138669ull,138777ull,71517ull, 139141ull,139269ull,71653ull,139649ull,139661ull,645533ull,140125ull,140153ull,71893ull,140265ull,53997ull,647865ull,648601ull,72441ull,72477ull,141953ull,142261ull,142889ull,143701ull,651937ull,144045ull,144133ull,144493ull,144861ull,654525ull,532497ull,145197ull,145137ull,145345ull,533369ull,146257ull,146657ull, 661321ull,661429ull,148049ull,148421ull,148549ull,662713ull,148589ull,149729ull,150365ull,150369ull,150001ull,151525ull,151637ull,667625ull,153133ull,75349ull,153309ull,669149ull,75673ull,154381ull,95945ull,154765ull,673045ull,673897ull,76217ull,76249ull,155521ull,675881ull,76489ull,676441ull,155693ull,155693ull, 155813ull,677593ull,156553ull,77005ull,156837ull,157341ull,157449ull,157689ull,77625ull,683201ull,158793ull,160001ull,160757ull,78649ull,78773ull,161181ull,688953ull,78817ull,689173ull,690233ull,690757ull,162541ull,79193ull,162789ull,162809ull,162837ull,162877ull,162905ull,163053ull,694273ull,0ull,0ull, 0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull,0ull, }; KBTS_INLINE kbts_u64 kbts_GetUnicodeDecomposition(kbts_u32 Codepoint) { return kbts_UnicodeDecomposition_Data[((kbts_un)kbts_UnicodeDecomposition_PageIndices[Codepoint/64] * 64) | (Codepoint & 63)]; } static kbts_u8 kbts_UnicodeWordBreakClass_PageIndices[8703] = { 0,1,2,2,2,3,4,5,2,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, 29,30,2,2,31,32,33,34,35,2,2,2,36,37,38,39,40,41,42,43,44,45,46,47,48,49,2,50,2,2,51,52, 53,54,55,56,57,57,58,59,57,60,57,61,62,63,64,65,57,57,66,57,57,57,67,57,2,68,69,70,71,57,57,57, 72,73,74,75,57,76,77,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 2,2,2,2,2,2,2,2,2,78,2,2,79,80,81,82,83,84,85,86,87,88,89,90,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,91,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,92,93,2,2,94,95,96,97,98,99, 100,101,102,103,57,104,105,106,2,107,108,109,2,2,110,111,112,113,114,115,116,117,118,119,120,121,122,123,57,124,125,126, 127,128,129,130,131,132,133,134,135,136,57,137,138,139,140,57,141,142,143,144,145,146,57,147,148,149,150,151,57,152,153,154, 2,2,2,2,2,2,2,155,156,2,157,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,158, 2,2,2,2,2,2,2,2,159,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,101,2,2,2,2,160,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,161,57,57,57,57,57,57,57,57,57,57,57,57,57,2,2,2,2,162,163,164,165,57,57,166,57,167,57,168,169, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,170, 171,57,172,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,173,174,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,175,57,57,57,57,176,57, 57,57,177,178,179,57,57,57,180,181,182,2,2,183,184,185,57,57,57,57,186,187,57,57,57,57,57,57,57,57,188,57, 189,190,191,57,57,192,57,57,57,193,57,194,57,57,57,195,2,196,197,57,57,57,57,57,57,57,57,57,198,199,57,57, 200,200,201,202,203,200,200,204,200,200,205,200,206,200,207,208,209,210,211,200,200,200,57,175,200,200,200,200,200,200,200,212, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 213,57,214,215,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, }; static kbts_u8 kbts_UnicodeWordBreakClass_Data[27648] = { 0,0,0,0,0,0,0,0,0,0,3,4,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,14,0,0,0,0,13,0,0,0,0,17,0,15,0,18,18,18,18,18,18,18,18,18,18,16,17,0,0,0,0, 0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,19,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0, 0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,11,0,0,8,1,0,0,0,0,0,0,11,0,16,0,0,11,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,11,11,11,11,11,0,11,11,0,0,11,11,11,11,17,11, 0,0,0,0,0,0,11,16,11,11,11,0,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11, 11,11,0,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,0,11,16,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,17,11,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5, 0,5,5,0,5,5,0,5,0,0,0,0,0,0,0,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,0,0,0,0,10,10,10,10,11,16,0,0,0,0,0,0,0,0,0,0,0, 18,18,18,18,18,18,0,0,0,0,0,0,17,17,0,0,5,5,5,5,5,5,5,5,5,5,5,0,8,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,18,18,18,18,18,18,18,18,18,18,0,18,17,0,11,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,5,5,5,5,5,5,5,18,0,5,5,5,5,5,5,11,11,5,5,0,5,5,5,5,11,11,18,18,18,18,18,18,18,18,18,18,11,11,11,0,0,11, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,11,11,0,0,17,0,11,0,0,5,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,11,5,5,5,5,5,5,5,5,5,11,5,5,5,11,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,0,18,18,0,0,0,0,0,5,5,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,18,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,11,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,11,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,5,5,5,0,11,11,11,11,11,11,11,11,0,0,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,0,0,0,11,11,11,11,0,0,5,11,5,5, 5,5,5,5,5,0,0,5,5,0,0,5,5,5,11,0,0,0,0,0,0,0,0,5,0,0,0,0,11,11,0,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,11,11,0,0,0,0,0,0,0,0,0,0,11,0,5,0, 0,5,5,5,0,11,11,11,11,11,11,0,0,0,0,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,0,11,11,0,0,5,0,5,5, 5,5,5,0,0,0,0,5,5,0,0,5,5,5,0,0,0,5,0,0,0,0,0,0,0,11,11,11,11,0,11,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,5,5,11,11,11,5,0,0,0,0,0,0,0,0,0,0, 0,5,5,5,0,11,11,11,11,11,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,0,0,5,11,5,5, 5,5,5,5,5,5,0,5,5,5,0,5,5,5,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,11,5,5,5,5,5,5, 0,5,5,5,0,11,11,11,11,11,11,11,11,0,0,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,0,0,5,11,5,5, 5,5,5,5,5,0,0,5,5,0,0,5,5,5,0,0,0,0,0,0,0,5,5,5,0,0,0,0,11,11,0,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,5,11,0,11,11,11,11,11,11,0,0,0,11,11,11,0,11,11,11,11,0,0,0,11,11,0,11,0,11,11,0,0,0,11,11,0,0,0,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,5,5, 5,5,5,0,0,0,5,5,5,0,5,5,5,5,0,0,11,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,5,11,11,11,11,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,11,5,5, 5,5,5,5,5,0,5,5,5,0,5,5,5,5,0,0,0,0,0,0,0,5,5,0,11,11,11,0,0,11,0,0,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,5,5,5,0,11,11,11,11,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,0,0,5,11,5,5, 5,5,5,5,5,0,5,5,5,0,5,5,5,5,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,11,11,0,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,11,11,5,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,11,11,11,11,11,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,11,5,5, 5,5,5,5,5,0,5,5,5,0,5,5,5,5,11,0,0,0,0,0,11,11,11,5,0,0,0,0,0,0,0,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11, 0,5,5,5,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,0,11,0,0, 11,11,11,11,11,11,11,0,0,0,5,0,0,0,0,5,5,5,5,5,5,0,5,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,0,0,0,0,0, 0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,5,5,0,0,0, 0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,5,0,0,0,0,5,5, 11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,0,5,5,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0, 0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0, 18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,5,5,5,0,5,5,5,0,0,5,5,5,5,5,5,5,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0, 0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,5,18,18,18,18,18,18,18,18,18,18,5,5,5,5,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,0,11,0,0,0,0,0,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,0,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,0, 11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0, 0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 20,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,5,5,5,8,5,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0, 11,11,11,11,11,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0, 0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5, 18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,11,11,11,11,11,11,11,11,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,11,11,18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0, 18,18,18,18,18,18,18,18,18,18,0,0,0,11,11,11,18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0, 11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,11,11,11,11,5,11,11,11,11,11,11,5,11,11,5,5,5,11,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,0,11,0,11,0,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,0, 0,0,11,11,11,0,11,11,11,11,11,11,11,0,0,0,11,11,11,11,0,0,11,11,11,11,11,11,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,0,11,11,11,11,11,11,11,0,0,0, 20,20,20,20,20,20,20,0,20,20,20,0,5,6,8,8,0,0,0,0,0,0,0,0,15,15,0,0,0,0,0,0,0,0,0,0,15,0,0,16,4,4,8,8,8,8,8,19,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,19, 19,0,0,0,17,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,20,8,8,8,8,8,0,8,8,8,8,8,8,8,8,8,8,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,11, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,11,0,0,0,0,11,0,0,11,11,11,11,11,11,11,11,11,11,0,11,0,0,0,11,11,11,11,11,0,0,0,0,1,0,11,0,11,0,11,0,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,12,0,0,11,11,11,11, 0,0,0,0,0,11,11,11,11,11,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11, 11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0, 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,5,5,5,11,11,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,0,0,0,0,0,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0, 11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 20,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,1,9,9,9,9,9,0,0,0,0,0,11,11,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,9,9,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,9,9,9,9, 0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,18,18,18,18,18,18,18,18,18,18,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,0,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,0,11,0,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,5,11,11,11,5,11,11,11,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,11,11,11,11,11,11,0,0,0,11,0,11,11,5, 18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0, 5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0, 11,11,11,5,11,11,11,11,11,11,11,11,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,5,0,0,5,5,0,0,0,0,0,5,5, 0,5,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,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,0,11,11,11,5,5,0,0,0,0,0,0,0,0,0, 0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,0,5,5,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0, 11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,0,0,0,0,0,10,5,10,10,10,10,10,10,10,10,10,10,0,10,10,10,10,10,10,10,10,10,10,10,10,10,0,10,10,10,10,10,0,10,0, 10,10,0,10,10,0,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,19,19,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,19,19,19,17,0,15,0,17,16,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,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,8, 0,0,0,0,0,0,0,15,0,0,0,0,17,0,15,0,18,18,18,18,18,18,18,18,18,18,16,17,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,19, 0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0, 0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,11,11,11,0,0,11,11,11,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,8,8,8,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,0,0,0,0,11,11,11,11,11,11,11,11,0,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,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,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,0,0,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,0,0,11,0,0,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,0,5,5,0,0,0,0,0,5,5,5,5,11,11,11,11,0,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,5,5,0,0,0,0,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 18,18,18,18,18,18,18,18,18,18,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,5,5,5,5,5,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,5,5,0,0,0,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0, 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,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,18,18,18,18,18,18,18,18,18,5,11,11,5,5,11,0,0,0,0,0,0,0,0,0,5, 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,0,0,18,0,0, 0,0,5,0,0,0,0,0,0,0,0,0,0,18,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,18,18,18,18,18,18,18,18,18,18, 0,0,0,0,11,5,5,11,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,0,0,11,0,0,0,0,0,0,0,0,0, 5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,11,11,11,11,0,0,0,0,5,5,5,5,0,5,5,18,18,18,18,18,18,18,18,18,18,11,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,5,11, 11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,0,11,0,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 5,5,5,5,0,11,11,11,11,11,11,11,11,0,0,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,0,5,5,11,5,5, 5,5,5,5,5,0,0,5,5,0,0,5,5,5,0,0,11,0,0,0,0,0,0,5,0,0,0,0,0,11,11,11,11,11,5,5,0,0,5,5,5,5,5,5,5,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,0,11,0,0,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,5,5,5,5,5,5,5,5, 5,0,5,0,0,5,0,5,5,5,5,0,5,5,5,5,5,11,5,11,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,11,11,11,11,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,5,11,11,11,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,11,11,0,11,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,5, 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,11,0,0,0,0,0,0,0, 18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11, 11,11,11,11,11,11,11,0,0,11,0,0,11,11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,0,5,5,0,0,5,5,5,5,11, 5,11,5,5,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,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,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,11,0,11,5,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,5,5,5,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,11,5,5,5,5,0, 0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,11,5,5,5,5,5,5,5,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5, 11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,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,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,0,0,0,5,0,5,5,0,5, 5,5,5,5,5,5,11,5,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,0,5,5,0,5,5,5,5,5,11,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,0,0,0,0,0,0,0,0,0, 5,5,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,0,0,0,5,5, 5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 5,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0, 18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0, 11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,5,11,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,5,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,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,11,0,11,5,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,0,9,9,9,9,9,9,9,0,9,9,0, 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0, 11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,0,0,0,5,5,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,5,5,5,5,5,5,8,8,8,8,8,8,8,8,5,5,5,5,5, 5,5,5,0,0,5,5,5,5,5,5,5,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,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,0,11,0,0,11,11,0,0,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,0,11,0,11,11,11, 11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,0,11,11,11,11,0,0,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0, 11,11,11,11,11,0,11,0,0,0,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,0,11,11,11,11,11,11,11,11,0,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,0,5,5,0,5,5,5,5,5,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,5,5,5,5,5,5,5,11,11,11,11,11,11,11,0,0, 18,18,18,18,18,18,18,18,18,18,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,5,11,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,11,0,11,11,11,11,0,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,5,5,5,5,5,5,5,11,0,0,0,0,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,0,11,0,0,11,0,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,11,0,11,0,0,0,0, 0,0,11,0,0,0,0,11,0,11,0,11,0,11,11,11,0,11,11,0,11,0,0,11,0,11,0,11,0,11,0,11,0,11,11,0,11,0,0,11,11,11,11,0,11,11,11,11,11,11,11,0,11,11,11,11,0,11,11,11,11,0,11,0, 11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,11,11,11,0,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,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,1,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,0,0,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,1,1,1,1,12,12,11,11,11,11,11,11,11,11,11,11,11,11,12,12, 11,11,11,11,11,11,11,11,11,11,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1, 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,5, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0, 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1, 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0, 0,8,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,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; KBTS_INLINE kbts_u8 kbts_GetUnicodeWordBreakClass(kbts_u32 Codepoint) { return kbts_UnicodeWordBreakClass_Data[((kbts_un)kbts_UnicodeWordBreakClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)]; } static kbts_u8 kbts_UnicodeLineBreakClass_PageIndices[8703] = { 0,1,2,2,2,3,4,2,2,5,2,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26, 27,28,29,30,2,2,31,2,32,2,2,2,2,33,34,35,36,37,38,39,40,41,42,43,44,45,2,46,2,2,2,47, 48,49,50,2,51,52,53,54,2,2,2,55,56,57,58,59,2,2,2,60,2,2,61,2,2,62,63,64,65,66,67,68, 69,70,71,72,73,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,74,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 75,67,67,67,67,67,67,67,67,76,2,2,77,78,2,2,79,80,81,82,83,84,2,85,86,87,88,89,90,91,92,86, 87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90, 91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,89,90,91,92,86,87, 88,89,90,91,92,86,87,88,89,90,91,92,86,87,88,93,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,67,67,67,67,95,2,2,2,96,97,98,99,100,101, 2,2,102,103,2,104,105,106,2,107,2,2,2,2,2,2,108,2,109,2,110,111,112,2,2,2,113,2,2,114,115,116, 117,118,119,120,121,122,123,124,125,126,2,127,128,129,130,2,131,132,133,134,135,136,137,138,139,140,141,142,2,143,144,145, 2,2,2,2,2,2,2,2,146,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,147,148,149,2,150,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,151,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,152,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,153,154,155,2,2,2,156,2,2,157,158,159, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,160,67,67,67,67,67,67,161,161,161,162,163,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,164, 67,67,165,67,67,166,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,167,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,138,2,2,2,2,168,2, 2,2,169,170,171,2,172,2,2,2,2,2,2,2,2,173,2,2,2,2,174,175,2,2,2,2,2,2,2,2,2,2, 176,177,178,2,2,179,2,2,2,180,2,181,2,2,2,2,2,182,183,2,2,2,2,2,2,184,2,2,2,2,2,2, 185,186,2,187,188,189,190,191,192,193,194,195,196,197,198,199,2,2,200,201,202,203,2,138,189,189,189,189,189,189,189,204, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,205, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,205, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 206,2,207,208,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, }; static kbts_u8 kbts_UnicodeLineBreakClass_Data[26752] = { 63,63,63,63,63,63,63,63,63,19,5,3,3,4,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,7,16,23,37,40,48,37,23,21,14,37,40,26,31,26,18,39,39,39,39,39,39,39,39,39,39,26,26,37,37,37,16, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,40,14,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,19,12,37,63, 63,63,63,63,63,6,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,10,21,48,40,40,40,37,37,37,37,37,24,37,19,37,37,48,40,37,37,35,37,37,37,37,37,37,25,37,37,37,21, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,35,37,37,37,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,10,63,63,63,63,63,63,63,63,63,63,63,63,10,10,10,10,10,10,10,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,26,37, 37,37,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,26,19,37,37,37,37,40,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,19,63, 37,63,63,37,63,63,16,63,37,37,37,37,37,37,37,37,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37,37, 39,39,39,39,39,39,37,37,37,48,48,48,26,26,37,37,63,63,63,63,63,63,63,63,63,63,63,16,63,16,16,16,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,39,39,39,39,39,39,39,39,39,39,48,39,39,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,16,37,63,63,63,63,63,63,63,39,37,63,63,63,63,63,63,37,37,63,63,37,63,63,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,37,37,37,37,26,16,37,37,37,63,40,40, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,63,63,63,63,63,63,63,63,63,37,63,63,63,37,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,37,37,37,37,37,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,39,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,63,63,19,19,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63, 63,63,63,63,63,37,37,63,63,37,37,63,63,63,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,48,48,37,37,37,37,37,48,37,40,37,37,63,37, 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63, 63,63,63,37,37,37,37,63,63,37,37,63,63,63,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,63,63,37,37,37,63,37,37,37,37,37,37,37,37,37,37, 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63, 63,63,63,63,63,63,37,63,63,63,37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,40,37,37,37,37,37,37,37,37,63,63,63,63,63,63, 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63, 63,63,63,63,63,37,37,63,63,37,37,63,63,63,37,37,37,37,37,37,37,63,63,63,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63, 63,63,63,37,37,37,63,63,63,37,63,63,63,63,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,40,37,37,37,37,37,37, 63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63, 63,63,63,63,63,37,63,63,63,37,63,63,63,63,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,35,37,37,37,37,37,37,37,37, 37,63,63,63,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63, 63,63,63,63,63,37,63,63,63,37,63,63,63,63,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37, 63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,63,63, 63,63,63,63,63,37,63,63,63,37,63,63,63,63,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,48,37,37,37,37,37,37, 37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,63,63,63,63,63,63,37,63,37,63,63,63,63,63,63,63,63,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,40, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,35,35,35,35,37,35,35,10,35,35,19,10,16,16,16,16,16,10,37,16,37,37,37,63,63,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,19,63,37,63,37,63,21,12,21,12,63,63, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,19, 63,63,63,63,63,19,63,63,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,19,19, 37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,35,35,19,35,37,37,37,37,37,10,10,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 39,39,39,39,39,39,39,39,39,39,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, 51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, 52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,19,19,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,27,37,19,37,19,40,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,16,16,19,19,35,37,16,16,37,63,63,63,10,63,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37, 37,37,37,37,16,16,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63, 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 63,63,63,63,63,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,60,56,56,56,56,56,56,56,56,37,19,19,58,58,58,58,58,58,58,58,58,58,19,19,42,19,19,19,19,42,42,42,42,42,42,42,42,42,42,63,63,63,63,63,63,63,63,63,42,42,42,42,42,42,42,42,42,19,19,19, 63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,63,63,63,63,63,63,63,63,63,63,63,63,59,59,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,19,19,19,19,19, 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,63,37,37,37,37,37,37,63,37,37,63,63,63,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 63,63,63,63,63,63,63,63,63,63,63,63,63,10,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,10,63,63,63, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,35,37,37, 19,19,19,19,19,19,19,10,19,19,19,8,63,64,63,63,32,10,19,19,29,37,37,37,24,25,21,24,24,25,21,24,37,37,37,37,33,33,33,19,3,3,63,63,63,63,63,10,48,48,48,48,48,48,48,48,37,24,25,37,27,27,37,37, 37,37,37,37,26,21,12,27,27,27,37,37,37,37,37,37,37,37,37,37,37,37,19,48,19,19,19,19,37,19,19,19,9,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,40,40,40,40,40,40,40,48,40,41,40,40,40,40,40,40,40,40,40,40,40,40,48,40,40,40,40,48,40,40,48,40, 48,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,48,37,37,37,37,37,48,37,37,37,37,37,37,37,37,37,37,37,37,40,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,40,40,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,33,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,22,13,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,38,38,37,37,37,43,42,42,43,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,57,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,37, 42,42,42,42,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43,43,37,37,42,37,42,42,42,45,42,42,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,38,38,38,38,38,38,37,42,42,42,37,37,37,37, 37,37,37,37,37,37,37,37,38,38,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,42,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43, 37,37,37,37,37,37,37,37,37,37,38,38,38,38,38,38,37,37,37,38,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,37,37,37,37,37,37,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43,43,42, 42,42,42,42,43,43,42,42,42,37,37,37,37,42,38,42,42,42,37,42,43,37,37,37,42,42,37,37,42,37,37,42,42,42,37,37,37,37,37,37,37,37,43,37,37,37,37,37,37,42,43,43,42,43,37,42,42,45,43,37,37,43,42,42, 42,42,42,42,42,38,37,37,42,42,46,46,45,45,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,38,37,38,37,37,37,37,38,38,38,37,38,37,37,37,23,23,23,23,23,23,37,16,16,42,37,37,37,21,12,21,12,21,12,21,12,21,12,21,12,21,12,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38, 37,37,37,37,37,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,21,12,21,12,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,21,12,21,12,21,12,21,12,21,12,21,12,21,12,21,12,21,12,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,37,37,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,37,37,37,37,37,37,16,19,19,19,37,16,19, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 23,23,24,25,24,25,23,23,23,24,25,23,24,25,19,19,19,19,19,19,19,19,37,19,21,19,37,37,24,25,37,37,24,25,21,12,21,12,21,12,21,12,19,19,19,19,16,37,19,19,37,19,19,37,37,37,37,37,29,29,19,19,19,37, 19,19,21,19,19,19,19,19,19,19,19,37,19,37,19,19,37,37,37,16,16,21,14,21,14,21,14,21,14,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 20,13,13,43,43,28,43,43,22,13,22,13,22,13,22,13,22,13,43,43,22,13,22,13,22,13,22,13,28,22,13,13,43,43,43,43,43,43,43,43,43,43,63,63,63,63,63,63,43,43,43,43,43,63,43,43,43,43,43,28,28,43,43,42, 37,65,43,65,43,65,43,65,43,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,65,43,65,43,65,43,43,43,43,43,43,65,43,43,43,43,43,43,65,65,37,37,63,63,28,28,28,28,43,28,65,43,65,43,65,43,65,43,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,65,43,65,43,65,43,43,43,43,43,43,65,43,43,43,43,43,43,65,65,43,43,43,43,28,65,28,28,43, 37,37,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,43,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,28,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19, 37,37,37,37,37,37,37,37,37,37,37,37,37,19,16,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,19,19,19,19,19,37,37,37,37,37,37,37,37, 37,37,63,37,37,37,63,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,48,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,35,35,16,16,37,37,37,37,37,37,37,37, 63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,37,37,37,37,37,37,37,37,19,19,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,35,37,37,63, 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,37,37,37, 63,63,63,63,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,63,63,63,63,63,63,63, 60,42,42,42,42,42,42,19,19,19,42,42,42,42,37,19,58,58,58,58,58,58,58,58,58,58,37,37,37,37,42,42,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37, 19,19,19,63,19,19,19,19,19,19,19,19,63,63,37,37,58,58,58,58,58,58,58,58,58,58,37,37,42,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,19,19,37,37,37,63,63,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,19,63,63,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54, 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, 53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54, 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,37,37,37,37,37,37,37,37,37,37,37,37,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, 51,51,51,51,51,51,51,37,37,37,37,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,37,37,37,37, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,36,63,36,36,36,36,36,36,36,36,36,36,37,36,36,36,36,36,36,36,36,36,36,36,36,36,37,36,36,36,36,36,37,36,37, 36,36,37,36,36,37,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,12,21, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,48,37,37,37, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,13,13,13,28,28,17,17,22,13,34,37,37,37,37,37,37,10,63,10,63,10,63,10,10,63,10,63,10,63,10,10,63,43,43,43,43,43,22,13,22,13,22,13,22,13,22,13,22, 13,22,13,22,13,43,43,22,13,43,43,43,43,43,43,43,13,43,13,37,28,28,17,17,43,22,13,22,13,22,13,43,43,43,43,43,43,43,43,37,43,41,49,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,9, 37,17,43,43,41,49,43,43,22,13,43,43,13,43,13,43,43,43,43,43,43,43,43,43,43,43,28,28,43,43,43,17,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,22,43,13,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,22,43,13,43,22,13,13,22,13,13,28,43,65,65,65,65,65,65,65,65,65,65,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,28,28,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37, 37,37,43,43,43,43,43,43,37,37,43,43,43,43,43,43,37,37,43,43,43,43,43,43,37,37,43,43,43,37,37,37,49,41,43,43,43,41,41,37,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,37,63,63,63,30,37,37,37, 19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,63,63,63,37,63,63,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,37,37,37,37,63, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,19,19,19,19,19,19,33,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,19,19, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 63,63,63,55,55,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,60,19,19,42,42,42,42,42,37,37,37,37,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,58,58,58,58,58,58,58,58,58,58,63,56,56,63,63,56,37,37,37,37,37,37,37,37,37,10, 63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,37,39,19,19, 19,19,63,37,37,37,37,37,37,37,37,37,37,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,39,39,39,39,39,39,39,39,39,39, 19,19,19,19,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,35,37,37,37,37,37,37,37,37,37,37, 63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,37,37,37,37,19,19,37,19,63,63,63,63,37,63,63,39,39,39,39,39,39,39,39,39,39,37,35,37,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,19,19,37,19,19,37,63,37, 37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 63,63,63,63,37,56,56,56,56,56,56,56,56,37,37,56,56,37,37,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,37,56,56,56,56,56,56,56,37,56,56,37,56,56,56,56,56,37,63,63,19,63,63, 63,63,63,63,63,37,37,63,63,37,37,63,63,60,37,37,58,37,37,37,37,37,37,63,37,37,37,37,37,19,58,58,56,56,63,63,37,37,63,63,63,63,63,63,63,37,37,37,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37, 58,58,58,58,58,58,58,58,58,58,37,58,37,37,58,37,58,58,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,37,42,63,63,63,63,63,63,63,63, 63,37,63,37,37,63,37,63,63,63,63,37,63,63,63,63,60,55,63,42,42,42,37,42,42,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,37,37,37,37,19,19,19,19,37,39,39,39,39,39,39,39,39,39,39,19,19,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,37,63,63,63,63,63,63,63,63, 63,35,19,19,16,16,37,37,37,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,35,35,35,35,35,35,35,35,35,35,35,35,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37, 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,19,19,19,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 56,56,56,56,56,56,56,37,37,56,37,37,56,56,56,56,56,56,56,56,37,56,56,37,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,37,63,63,37,37,63,63,63,60,55, 63,55,63,63,19,19,19,37,37,37,37,37,37,37,37,37,58,58,58,58,58,58,58,58,58,58,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,37,63,63,63,63,63,63,63,37,35,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,63,63,63,63,35, 37,19,19,19,19,35,37,63,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,19,19,19,37,35,35,35,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 35,35,35,35,35,35,35,35,35,35,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,63, 37,19,19,19,19,19,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,35,16,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,37,37,37,63,37,63,63,37,63, 63,63,63,63,63,63,37,63,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,63,63,37,63,63,63,63,63,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,19,63,63,63,63,19,19,37,37,37,37,37,37,37, 63,63,55,63,56,56,56,56,56,56,56,56,56,56,56,56,56,37,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,63,63,63,63,63,63,63,37,37,37,63,63, 63,63,60,19,19,42,42,42,42,42,42,42,42,42,42,42,58,58,58,58,58,58,58,58,58,58,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,48,48,48,48,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,21,21,12,12,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,12,37,37,37,21,12,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,12,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,10,10,10,10,10,10,10,21,12,10,10,10,21,12,21,12, 63,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,12,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,58,58,58,58,58,58,58,58,58,58,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,19,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,19,19,19,37,37,37,37,37,37, 37,37,37,37,19,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,28,28,28,28,11,37,37,37,37,37,37,37,37,37,37,37,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37, 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38, 43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,38,38,38,37,38,38,38,38,38,38,38,37,38,38,37, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,65,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,65,65,65,37,37,65,37,37,37,37,37,37,37,37,37,37,37,37,37,37,65,65,65,65,37,37,37,37,37,37,37,37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,19,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,37,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,63,63,63,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,63,37,37,19,19,19,19,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 63,63,63,63,63,63,63,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,63,63,63,63,63,63,63,37,63,63,37,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37, 39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,40, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,63,63,63,63,63,63,63,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,37,37,37,37,21,21,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,48,37,37,37,48,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 42,42,42,42,43,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,44,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,44,44,44,44,44,44,44,44,44,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, 44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,43,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,44,44,44,44,44,44,44,44, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 43,43,43,44,44,44,44,44,44,44,44,44,44,44,44,44,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,44,44,44,44, 43,43,43,43,43,43,43,43,43,44,44,44,44,44,44,44,43,43,44,44,44,44,44,44,44,44,44,44,44,44,44,44,43,43,43,43,43,43,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,42,42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,43,43,42,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,43,43, 43,43,43,43,43,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,42,42,42,42,42,42,37,37,42,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,38,38,43,43,43,43,43,38,43,43,43, 43,43,46,46,46,43,43,46,43,43,46,45,45,42,42,43,43,43,43,43,42,42,42,42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,42,43,42,42,42,43,43,43,47,47,47,47,47, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42, 43,42,46,46,43,43,46,46,46,46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,43,43,43,46,43,43,43, 43,46,46,46,43,46,46,46,43,43,43,43,43,43,43,46,43,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,38,43,38,43,38,43,43,43,43,43,46,43,43,43,43,38,43,38,38,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,43, 38,38,38,38,38,38,38,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,38,38,38,38,38,38,38,38,38,38,38,38,38,38,43,43,43,43,43,43,43,43,43,43,43,43,43,38,38,38,38,38,38,38,38,38,38,38,38,37,37, 37,37,37,37,37,37,37,37,37,37,42,43,43,43,43,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,42,42,42,42,42,42,42,42,42,42,42,45,45,42,42,42,42,46,42,42,42,42,42, 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,45,42,42,42,42,46,46,42,42,42,42,42,42,42,42,42,42,42,42,42,43,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,37,37,37,37,37,37,37,37,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,37,37,37,37,37,37,42,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,46,46,46,43,43,43,46,46,46,46,46,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,23,23,23,27,27,27,37,37,37,37, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,46,46,43,43,43,43,43,43,43,43,43, 46,43,43,43,43,43,42,42,42,42,42,42,46,42,42,42,43,43,43,42,42,43,43,43,44,44,44,44,43,43,43,43,42,42,42,42,42,42,42,42,42,42,42,43,43,44,44,44,42,42,42,42,43,43,43,43,43,43,43,43,43,44,44,44, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,42,42,42,44,44,44,44,42,42,42,42,42, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,42,42,42,42,42,44,44,44,44,44,44,43,43,43,43,43,43,43,43,43,43,43,43,44,44,44,44,43,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 37,37,37,37,37,37,37,37,37,37,37,37,46,43,43,46,43,43,43,43,43,43,43,43,46,46,46,46,46,46,46,46,43,43,43,43,43,43,46,43,43,43,43,43,43,43,43,43,46,46,46,46,46,46,46,46,46,46,43,42,46,46,46,43, 43,43,43,43,43,43,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,46,46,43,46,46,43,46,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,46,46,46,43,46,46,46,46,46,46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,44,44,44,44,44,44,44,44,44,44,44,44,42,42,42,42,42,42,42,42,42,42,42,42,42,42,44,44,43,43,43,43,43,43,43,43,43,43,43,43,43,44,44,44, 43,43,43,43,43,43,43,43,43,43,44,44,44,44,44,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,46,46,46,43,44,44,44,44,44,44,44,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,44,44,43,43,43,43,43,43,43,43,43,43,43,44,44,44,44,44,44,46,46,46,46,46,46,46,46,46,44,44,44,44,44,44,44, 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,37,37, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,37,37, 37,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, }; KBTS_INLINE kbts_u8 kbts_GetUnicodeLineBreakClass(kbts_u32 Codepoint) { return kbts_UnicodeLineBreakClass_Data[((kbts_un)kbts_UnicodeLineBreakClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)]; } static kbts_u8 kbts_UnicodeGraphemeBreakClass_PageIndices[8703] = { 0,1,2,2,2,2,3,2,2,4,2,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25, 26,27,28,29,2,2,30,2,2,2,2,2,2,2,31,32,33,34,35,2,36,37,38,39,40,41,2,42,2,2,2,2, 43,44,45,46,2,2,47,48,2,49,2,50,51,52,53,54,2,2,55,2,2,2,56,2,2,57,58,59,2,2,2,2, 60,61,2,2,2,62,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,63,64,2,2,65,66,67,68,69,70,2,71,72,73,74,75,76,77,78,79, 73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76, 77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,75,76,77,78,79,73, 74,75,76,77,78,79,73,74,75,76,77,78,79,73,74,80,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,81,2,2,2,2,2,82,83,2,84, 2,2,2,85,2,86,87,2,2,2,2,2,2,2,2,2,2,2,2,2,88,89,2,2,2,2,90,2,2,91,92,93, 94,95,96,97,98,99,100,101,102,103,2,104,105,106,107,2,108,2,109,110,111,112,2,2,113,114,115,116,2,117,118,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,119,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,120,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,121,122,2,2,2,123,2,2,2,124,125, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,126,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,127,2, 2,2,128,129,130,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,131,132,2,2,2,2,2,2,2,2,2,2, 133,134,122,2,2,135,2,2,2,136,2,137,2,2,2,2,2,138,139,2,2,2,2,2,2,2,2,2,2,2,2,2, 140,140,141,142,143,140,140,144,140,140,145,140,146,140,147,148,149,150,151,140,140,140,2,2,140,140,140,140,140,140,140,152, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 153,154,155,156,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, }; static kbts_u8 kbts_UnicodeGraphemeBreakClass_Data[20096] = { 3,3,3,3,3,3,3,3,3,3,2,0,3,1,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,16,0,0,0,3,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,14, 0,14,14,0,14,14,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 12,12,12,12,12,12,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,12,0,14,14,14,14,14,14,0,0,14,14,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,14,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,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,14,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,14,14,14,0,14,14,14,14,14,14,14,14,14,0,14,14,14,0,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0,0,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,12,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,6,14,0,6,6, 6,14,14,14,14,14,14,14,14,6,6,6,6,15,6,6,0,14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13, 0,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,13,13,13,13,13,13,13,0,13,0,0,0,13,13,13,13,0,0,14,0,14,6, 6,14,14,14,14,0,0,6,6,0,0,6,6,15,0,0,0,0,0,0,0,0,0,14,0,0,0,0,13,13,0,13,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,13,13,0,0,0,0,0,0,0,0,0,0,0,0,14,0, 0,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,6, 6,14,14,0,0,0,0,14,14,0,0,14,14,14,0,0,0,14,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,14,0,0,0,14,0,0,0,0,0,0,0,0,0,0, 0,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,13,13,13,13,13,13,13,0,13,13,0,13,13,13,13,13,0,0,14,0,6,6, 6,14,14,14,14,14,0,14,14,6,0,6,6,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,14,14,14,14,14,14, 0,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,13,13,13,13,13,13,13,0,13,13,0,13,13,13,13,13,0,0,14,0,14,14, 6,14,14,14,14,0,0,6,6,0,0,6,6,15,0,0,0,0,0,0,0,14,14,14,0,0,0,0,13,13,0,13,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6, 14,6,6,0,0,0,6,6,6,0,6,6,6,14,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 14,6,6,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,0,14,0,14,14, 14,6,6,6,6,0,14,14,14,0,14,14,14,15,0,0,0,0,0,0,0,14,14,0,13,13,13,0,0,0,0,0,0,0,14,14,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,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,14, 14,6,14,6,6,0,14,14,14,0,14,14,14,14,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,0,14,6, 6,14,14,14,14,0,6,6,6,0,6,6,6,15,12,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,14,14,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,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,14,6,6,14,14,14,0,14,0,6,6,6,6,6,6,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,14,14,14,14,14,14,14,0,0,0,0,0, 0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,14,14,14,14,14,14,14,14,14,0,0,0, 0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,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,0,14,0,14,0,0,0,0,6,6, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,6, 14,14,14,14,14,0,14,14,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0, 0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,6,14,14,14,14,14,14,0,14,14,6,6,14,14,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,14,14,0,0,0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0, 0,0,14,0,6,14,14,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,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,14,14,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,14,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,14,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,14,6,14,14,14,14,14,14,14,6,6, 6,6,6,6,6,6,14,6,6,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,14,14,14,3,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,6,6,6,6,14,14,6,6,6,0,0,0,0,6,6,14,6,6,6,6,6,6,14,14,14,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,6,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,14,6,14,14,14,14,14,14,14,0,14,0,14,0,0,14,14,14,14,14,14,14,14,6,6,6,6,6,6,14,14,14,14,14,14,14,14,14,14,0,0,14, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,6,6, 6,6,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,6,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,14,14,14,14,6,6,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,14,14,6,6,6,14,6,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,14,14,14,14,14,14,14,14,6,6,14,14,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,14,14,14,14,14,14,14,14,14,14,14,14,14,6,14,14,14,14,14,14,14,0,0,0,0,14,0,0,0,0,0,0,14,0,0,6,14,14,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 0,0,0,0,0,0,0,0,0,0,0,3,4,5,3,3,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,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0, 0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,16,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,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0, 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0, 16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,0,16,0,16,0,0,0,0,0,0,16,0,0,0,16,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,16,0,0,16,0,0,0,0,16,0,16,0,0,0,0,16,16,16,0,16,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,16,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,14,14,14,14,14,14,14,14,14,14,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,14,0,0,0,14,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,14,14,6,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,14,14,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,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,14, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,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,14,14,14,14,14,14,14,14,14,14,6,14,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0, 14,14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,14,14,14,14,6,6,14,14,6,6, 14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,14,14,14,14,14,6,6,14,14,6,6,14,14,0,0,0,0,0,0,0,0,0, 0,0,0,14,0,0,0,0,0,0,0,0,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,14,14,14,0,0,14,14,0,0,0,0,0,14,14, 0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,14,14,6,6,0,0,0,0,0,6,14,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,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,6,14,6,6,14,6,6,0,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,9,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,0,0,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, 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,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,0,3,3,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,14,14,14,14,0,0,0,0,0, 0,14,14,14,0,14,14,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,0,0,0,0,14, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 6,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,14,14,0,0,0,0,0,0,0,0,0,0,14, 14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,6,6,14,14,0,0,12,0,0, 0,0,14,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,6,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,14,14,14,14,14,6, 14,0,12,12,0,0,0,0,0,14,14,14,14,0,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,6,6,14,14,14,14,0,0,0,0,0,0,14,0, 0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,6,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,14,6, 14,6,6,6,6,0,0,6,6,0,0,6,6,14,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,6,6,0,0,14,14,14,14,14,14,14,0,0,0,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,6,6,14,14,14,14,14, 14,0,14,0,0,14,0,14,14,14,6,0,6,6,14,14,14,12,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,14,14,14,14, 6,6,14,14,14,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,14,14,14,14,14,14,6,14,6,6,14,6,14, 14,6,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,6,6,14,14,14,14,0,0,6,6,6,6,14,14,6,14, 14,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,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,14,14,14,14,6,6,14,6,14, 14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,6,14,6,6,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,14,0,0,14,14,14,14,6,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,14,14,14,14,14,6,14,14,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,6,6,6,6,6,0,6,6,0,0,14,14,14,14,12, 6,12,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,14,14,14,14,0,0,14,14,6,6,6,6,14,0,0,0,6,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,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,6,12,14,14,14,14,0, 0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,6,6,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,12,12,12,12,12,12,14,14,14,14,14,14,14,14,14,14,14,14,14,6,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,14,14,14,14,14,14,14,0,14,14,14,14,14,14,6,14, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,6,14,14,14,14,14,14,14,6,14,14,6,14,14,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,0,0,0,14,0,14,14,0,14, 14,14,14,14,14,14,12,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,6,6,6,6,0,14,14,0,6,6,14,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,6,6,0,0,0,0,0,0,0,0,0, 14,14,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,14,14,14,14,14,0,0,0,6,6, 14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 14,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,6,6,6,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,0,0,0,14,14,14,14,14,14,3,3,3,3,3,3,3,3,14,14,14,14,14, 14,14,14,0,0,14,14,14,14,14,14,14,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,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 14,14,14,14,14,14,14,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,14,14,14,14,14,14,14,0,14,14,0,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,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,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,16,16,16,16,16,16,16,16,16,0,16,16,16,16, 0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,14,14,14,14,14, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0, 0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,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,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16, 16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0, 3,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, }; KBTS_INLINE kbts_u8 kbts_GetUnicodeGraphemeBreakClass(kbts_u32 Codepoint) { return kbts_UnicodeGraphemeBreakClass_Data[((kbts_un)kbts_UnicodeGraphemeBreakClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)]; } static kbts_u8 kbts_UnicodeSyllabicInfo_PageIndices[8703] = { 0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,2,5,6,7,8,9,10,11,12,13,14,15,16,17,18, 19,20,2,2,2,2,2,2,2,2,2,2,2,2,21,22,23,24,25,26,27,28,29,30,31,32,2,33,2,2,2,2, 34,35,2,2,2,2,2,2,2,2,2,36,2,2,2,2,2,2,2,2,2,2,2,2,2,2,37,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,38,39,40,41,42,43,2,44,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,45,2,2,2, 2,2,2,2,2,2,2,2,2,2,46,47,2,2,2,2,2,2,2,2,48,49,2,2,2,2,50,51,2,52,53,54, 55,56,57,58,59,60,61,62,63,64,2,65,66,67,68,2,69,2,70,71,72,73,2,2,74,75,76,77,2,78,79,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,80,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,81,82,2,2,2,83,2,2,2,84,85, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,86,86,86,87,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,88,89,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,90,2,2,91,2,2,2,92,2,93,2,2,2,2,2,2,94,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, }; static kbts_u16 kbts_UnicodeSyllabicInfo_Data[12160] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1034,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3592,3592,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,3,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,3,3,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,2311,2311,2307,3601,2311,519, 2311,2311,2311,2311,2311,2311,2311,2311,2311,2311,2311,2311,2311,2308,519,2311,0,3593,3593,3592,3592,2311,2311,2311,1025,1025,1025,1025,1025,1025,1025,1025, 1026,1026,2311,2311,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025, 1034,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,0,0,1026,1026,0,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,0,1025,0,0,0,1025,1025,1025,1025,0,0,2307,3601,3079,519, 3079,2311,2311,2311,2311,0,0,519,519,0,0,3079,3079,2308,1025,0,0,0,0,0,0,0,0,3079,0,0,0,0,1025,1025,0,1025, 1026,1026,2311,2311,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,1025,0,0,0,0,0,0,0,0,0,0,1034,0,3592,0, 0,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,0,0,0,0,1026,1026,0,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,0,1025,1025,0,1025,1025,0,1025,1025,0,0,3075,0,3079,519, 3085,3079,3079,0,0,0,0,3079,3079,0,0,3079,3079,3076,0,0,0,2055,0,0,0,0,0,0,0,1025,1025,1025,1025,0,1025,0, 0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,3592,3592,1025,1025,0,1040,0,0,0,0,0,0,0,0,0,0, 0,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,0,1025,1025,0,1025,1025,1025,1025,1025,0,0,3075,3601,3079,519, 3079,3079,3079,3079,3079,2311,0,2311,2311,3079,0,3079,3079,3076,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,3079,3079,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,1025,3593,2307,3593,2307,2307,2307, 0,1800,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,0,0,1026,1026,0,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,0,1025,1025,0,1025,1025,1025,1025,1025,0,0,2307,3601,3079,1287, 3079,2311,2311,2311,2311,0,0,519,1287,0,0,3079,3079,2308,0,0,0,0,0,0,0,1283,1287,3079,0,0,0,0,1025,1025,0,1025, 1026,1026,2311,2311,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3592,0,0,1026,1026,1026,1026,1026,1026,0,0,0,1026,1026,1026,0,1026,1026,1026,1025,0,0,0,1025,1025,0,1025,0,1025,1025, 0,0,0,1025,1025,0,0,0,1025,1025,1025,0,0,0,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,3079,3079, 2311,3079,3079,0,0,0,519,519,519,0,3079,3079,3079,2308,0,0,0,0,0,0,0,0,0,3079,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,3592,3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,0,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,1795,3601,1799,1799, 1799,1799,1799,2311,2311,0,1799,1799,1799,0,1799,1799,1799,1796,0,0,0,0,0,0,0,1799,1799,0,1025,1025,1025,0,0,1025,0,0, 1026,1026,1799,1799,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1034,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,0,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,0,1025,1025,1025,1025,1025,0,0,1795,3601,1799,1799, 1799,1799,1799,2311,2311,0,1799,2311,2311,0,2311,2311,1799,1796,0,0,0,0,0,0,0,2311,2311,0,0,0,0,0,0,1025,1025,0, 1026,1026,1799,1799,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,1042,1042,3592,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,3592,3592,1034,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,0,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,3601,3079,3079, 3079,3079,3079,3079,3079,0,519,519,519,0,3079,3079,3079,4,14,0,0,0,0,0,1025,1025,1025,3079,0,0,0,0,0,0,0,1026, 1026,1026,3079,3079,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025, 0,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,0,0,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,0,0, 1025,1025,1025,1025,1025,1025,1025,0,0,0,2308,0,0,0,0,2311,2311,2311,2311,2311,2311,0,2311,0,2311,519,2311,519,2311,2311,2311,2311, 0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,2311,2311,0,0,0,0,0,0,0,0,0,0,0,0, 0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, 519,519,519,519,519,7,0,7,3,3,3,3,7,3592,7,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1025,1025,0,1025,0,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,0,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,0,7,7,7,7,7,7,7,7,7,7,7,7,1040,1040,0,0, 519,519,519,519,519,0,0,0,3,3,3,3,0,3592,3592,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,1025,1025,1025,1025, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,0,0,1025,1025,1025,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, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,3592,0,3592,0,3,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,3,7,7,7,7,7,7,7,7,7,7,7,7,3592,1025, 7,7,3592,3592,7,3601,3,3,1025,1025,1025,1025,1025,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,0,1040,1040,1040,1040,1040,1040,1040, 1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,0,0,0, 0,0,0,0,0,0,3592,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1039,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025, 1025,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,23,23,20,20,21,21,22,3593,20,20,20,3593,3,1034,4,27,33,31,32,30,1025, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,1025,0,1025,1025,1026,1026,1026,1026,23,23,21,21,1039,1025,1025,1025,33,33, 36,1025,23,34,34,1025,1025,23,23,34,34,34,34,34,1025,1025,1025,20,20,20,20,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,32,23,22,20,20,1034,1034,1034,1034,1034,1034,1034,1025,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,20,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,0,0,0,0,0,0,0,0,0,1025, 1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1039,1025,1025,1025,1025,1025, 1025,1025,1025,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,0,23,20,20,20,20,21,21,21,20,23, 23,22,22,22,23,23,25,25,25,24,24,25,24,25,25,25,25,25,4,25,0,0,0,0,0,1034,0,0,3601,25,0,0, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,0,0,0,0,0,0,1025,0,0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0, 1034,1034,1034,1034,1034,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1034,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0, 7,7,7,7,7,7,7,7,7,1040,1040,1040,0,0,0,0,1040,1040,3592,1040,1040,1040,1040,1040,1040,1040,3592,3592,0,0,0,0, 0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,7,7,7,7,7,519,519,519,7,7,519,7,7,7,7,7, 7,1025,1025,1025,1025,1025,1025,1025,3,3,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1026,1026,1026,1026,1026,1026,1025,1025,1040,1040,1040,1040,1040,1025,1040,1040,1040,1040,0, 4,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,3592,3,3,3,3,3,7,3,3,0,0,3, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,3592,1040,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,4,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3592,1040,3592,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1040,1040,1040,7,7,7,7,7,7,7,4,1040,1040,1025,1025,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,3601,1025,1025,1025,1040,1040, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1026,1026,3,7,7,7,7,7,7,7,7,7,1040,1040,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1040,1040,7,7,7,7,7,7,7,1040,1040,1040,1040,1040,1040,1040,3592,3592,0,3,0,0,0,0,0,0,0,0, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,1025,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3593,3593,3593,0,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593, 3593,3593,3593,3593,3593,3593,3593,3593,3593,3601,3601,3601,3601,3593,3601,3601,3601,3601,1025,1025,3593,1025,1025,3593,3593,3593,1034,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3592,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,5,6,0,0,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0, 0,0,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3592,0,0,0,0,0,0,0,0,0,0,0, 0,0,3592,3592,3592,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,3593,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1035,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, 1026,1026,7,1026,1026,1026,4,1025,1025,1025,1025,3592,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,7,7,7,7,7,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1026,1026, 1026,1026,1025,1025,1025,1025,1026,1040,1040,1025,1025,1025,1025,1025,1025,1025,1025,1040,1025,3592,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1040,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,4,3592,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3593,3601,3601,3601,3601,3601,3601,0,0,0,0,0,0,1026,2311, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1026,1026,1026,1026,1026,1026,1026,1026,1026,3,3,3,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,1040,1040,1040,1040,7,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,1040,3592,1026,1026,1026,1026,1026,1025,1025,1025,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,7,7,7,7,7,7,7,7,7,1040,1040,1040, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 1025,1025,1025,1025,1025,20,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,1025,1025,1025,1025,0, 1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,3592,7,7,7,7,7,7,7,7,7,1040,1040,1040,1040,0,0,0,0,0,0,0,0,0, 1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1034,1034,1034,0,0,0,1025,34,3,3,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,1026,7,7,7,519,519,7,7,519,1026,519,519,1026,7,3, 0,3,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, 1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,0,0,0,0,0,3592,4,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1026,1026,1025,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1040,1040,1040,1040,1040, 1040,1040,1040,7,7,7,7,7,7,7,7,0,3,7,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,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, 1025,1287,7,7,0,7,1287,0,0,0,0,0,7,3592,3592,3592,1025,1025,1025,1025,0,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,3,3,3,0,0,0,0,4, 1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,3,3,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, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,3,3,3,3592,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,0,0,0,7,7,7,7,7,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,7,7,0,0,0,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,3,3,3,3,3,3,3,3,3,3,3,1034,1034,1034,1034,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,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,3592,1042,1042,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,4,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,7,1026,1026,7,7,1025,0,0,0,0,0,0,0,0,0,1034, 3592,3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,4,3,0,0,0,0,0, 0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,3592,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,7,4,3592,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034, 0,0,0,0,1025,7,7,1025,0,0,0,0,0,0,0,0,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,7,7, 4,3601,0,0,0,0,0,0,0,3592,3,7,7,0,7,3592,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1025,0,0,0,0,0, 0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,3592,4,3,3592,0,0,0,0,0,0,3593,1025, 1026,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1026,1025,1025,1025,0,1025,0,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3592, 7,7,7,7,7,7,7,7,7,3,7,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 3592,3592,3592,3592,0,1026,1026,1026,1026,1026,1026,1026,1026,0,0,1026,1026,0,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,0,1025,1025,1025,1025,1025,0,3,3,3601,7,7, 7,7,7,7,7,0,0,7,7,0,0,7,7,4,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,3592,3592, 1026,1026,7,7,0,0,3593,3593,3593,3593,3593,3593,3593,0,0,0,3593,3593,3593,3593,3593,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,0,0,1026,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,3601,7,7,7,7,7,7,7,7, 7,0,7,0,0,7,0,7,7,7,3592,0,3592,3592,3592,3,4,14,3592,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3593,3593,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, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7, 7,7,4,3592,3592,3592,3,3601,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,3592,3592, 1042,1042,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,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,3592, 3592,3592,4,3,3601,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,0,0,7,7,7,7,3592,3592,3592,4, 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1026,1026,1026,1026,7,7,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,7,7,3592,3592,4, 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3592,3592,7,7,7,7,7,7,7,7,7,4,3,1025,0,0,0,0,0,0,0, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034, 1034,1034,1034,1034,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, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,1040,1040,1040, 7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,7,7,7,3592,3592,4,3,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,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, 1026,1026,1026,1026,1026,1026,1026,0,0,1026,0,0,1025,1025,1025,1025,1025,1025,1025,1025,0,1025,1025,0,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,0,7,7,0,0,3592,3592,7,4,0, 1040,14,1040,3,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,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, 1026,1026,1026,1026,1026,1026,1026,1026,0,0,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,0,0,7,7,7,7,3592,3592, 4,3601,0,0,7,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, 1026,7,7,7,7,7,7,7,7,7,7,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3592,7,3592,3592,3592,3592,3592,1042,1040,1040,1040,1040,1034, 0,0,0,0,0,1034,0,4,0,0,0,0,0,0,0,0,1026,7,7,7,7,7,7,7,7,7,7,7,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,0,0,0,0,0,0,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,3592,3592,3592,4,0,0,0,3601,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1026,1026,1026,1026,1026,1026,0,1026,1026,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,7,0,7,7,7,7,3592,3592,3592,4, 3601,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040, 1040,1040,1040,1040,1040,1040,1040,1040,0,1040,1040,1040,1040,1040,1040,1040,7,7,7,7,7,3592,3592,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1026,1026,1026,1026,1026,1026,0,1026,1026,0,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,0,0,0,7,0,7,7,0,7, 3592,3592,3,7,7,4,14,1040,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 1026,1026,1026,1026,1026,1026,0,1026,1026,0,1026,1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,0,7,7,0,7,7,3592,3592,4,0,0,0,0,0,0,0,0, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1034,7,7,7,7,0,0,0,0,0,0,0,0,0, 3592,3592,14,3592,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,7,7,7,0,0,0,7,7, 7,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,3,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1026,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7, 7,7,7,7,7,7,7,7,7,7,1040,1040,1040,3592,1040,7,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3592,3592,3592,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,7,7,7,7,7,7,7,7,7,7,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,3,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1025,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, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,1283,1283,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,0,0,0,3,3,3,3,3,3,3,1025,1025,1025,1025,1025,1025,1025,0,0, 1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,1025,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,3,3,3,3,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,7,7,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,7,7,1025,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, 1025,1025,1025,1025,3,3,3,3,3,3,3,1025,0,0,0,0,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; KBTS_INLINE kbts_u16 kbts_GetUnicodeSyllabicInfo(kbts_u32 Codepoint) { return kbts_UnicodeSyllabicInfo_Data[((kbts_un)kbts_UnicodeSyllabicInfo_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)]; } static kbts_u8 kbts_UnicodeScript_PageIndices[8703] = { 0,1,2,2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29, 30,31,32,32,33,34,35,36,37,37,37,37,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,2,2,53,54, 55,56,57,58,59,59,59,59,60,59,59,59,59,59,59,59,61,61,59,59,59,59,62,63,64,65,66,67,68,61,61,69, 70,71,72,73,74,75,76,59,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,77,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 78,78,78,78,78,78,78,78,78,79,80,80,81,82,83,84,85,86,87,88,89,90,91,92,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,93,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,94,95,96,96,97,98,99,100,101,102, 103,104,105,106,61,107,108,109,110,111,112,113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132, 133,134,135,136,137,138,139,140,141,142,61,143,144,145,146,61,147,148,149,150,151,152,153,154,155,156,157,158,61,159,160,161, 162,162,162,162,162,162,162,163,164,162,165,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,166, 167,167,167,167,167,167,167,167,168,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, 167,167,167,167,167,167,167,169,170,170,170,170,171,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,172,61,61,61,61,61,61,61,61,61,61,61,61,61,173,173,173,173,174,175,176,177,61,61,178,61,179,180,181,182, 183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,184,183,183,183,183,183,183,185,185,185,186,187,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,188, 189,190,191,192,192,193,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,194,195,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,59,196,59,59,59,197,198,199, 59,200,201,202,203,204,205,61,206,207,208,59,59,209,59,210,211,211,211,211,211,212,61,61,61,61,61,61,61,61,213,61, 214,215,216,61,61,217,61,61,61,218,61,219,61,61,61,220,221,222,223,61,61,61,61,61,224,225,226,61,227,228,61,61, 229,230,59,231,232,61,59,59,59,59,59,59,59,233,234,235,236,237,59,59,238,239,59,240,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 241,61,242,243,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, }; static kbts_u8 kbts_UnicodeScript_Data[31232] = { 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,29,29,29,29,29,29,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,72,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,72,29,29,29,29,29, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,29,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,29,72,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,72,72,72,72,72,29,29,29,29,29,13,13,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,45,45,45,45,29,45,45,45,0,0,45,45,45,45,29,45, 0,0,0,0,45,29,45,29,45,45,45,0,45,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,25,25,25,25,25,25,25,25,25,25,25,25,25,25,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, 28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 28,28,28,28,28,30,30,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,0,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, 54,54,54,54,54,54,54,54,0,0,0,0,0,0,0,0,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,0,0,0,0,54,54,54,54,54,54,0,0,0,0,0,0,0,0,0,0,0, 4,4,4,4,4,29,4,4,4,4,4,4,29,4,4,4,4,4,4,4,4,4,4,4,4,4,4,29,4,4,4,29,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 29,4,4,4,4,4,4,4,4,4,4,30,30,30,30,30,30,30,30,30,30,30,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,30,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,29,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 143,143,143,143,143,143,143,143,143,143,143,143,143,143,0,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, 143,143,143,143,143,143,143,143,143,143,143,0,0,143,143,143,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,0,0,103,103,103, 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,0,0,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,0, 83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,0,0,83,0,143,143,143,143,143,143,143,143,143,143,143,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,29,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,30,30,30,30,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,29,29,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 11,11,11,11,0,11,11,11,11,11,11,11,11,0,0,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,0,11,0,0,0,11,11,11,11,0,0,11,11,11,11, 11,11,11,11,11,0,0,11,11,0,0,11,11,11,11,0,0,0,0,0,0,0,0,11,0,0,0,0,11,11,0,11,11,11,11,11,0,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0, 0,48,48,48,0,48,48,48,48,48,48,0,0,0,0,48,48,0,0,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,0,48,48,48,48,48,48,48,0,48,48,0,48,48,0,48,48,0,0,48,0,48,48, 48,48,48,0,0,0,0,48,48,0,0,48,48,48,0,0,0,48,0,0,0,0,0,0,0,48,48,48,48,0,48,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0, 0,46,46,46,0,46,46,46,46,46,46,46,46,46,0,46,46,46,0,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,0,46,46,46,46,46,46,46,0,46,46,0,46,46,46,46,46,0,0,46,46,46,46, 46,46,46,46,46,46,0,46,46,46,0,46,46,46,0,0,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,46,46,46,0,0,46,46,46,46,46,46,46,46,46,46,46,46,0,0,0,0,0,0,0,46,46,46,46,46,46,46, 0,118,118,118,0,118,118,118,118,118,118,118,118,0,0,118,118,0,0,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,0,118,118,118,118,118,118,118,0,118,118,0,118,118,118,118,118,0,0,118,118,118,118, 118,118,118,118,118,0,0,118,118,0,0,118,118,118,0,0,0,0,0,0,0,118,118,118,0,0,0,0,118,118,0,118,118,118,118,118,0,0,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,0,0,0,0,0,0,0,0, 0,0,150,150,0,150,150,150,150,150,150,0,0,0,150,150,150,0,150,150,150,150,0,0,0,150,150,0,150,0,150,150,0,0,0,150,150,0,0,0,150,150,150,0,0,0,150,150,150,150,150,150,150,150,150,150,150,150,0,0,0,0,150,150, 150,150,150,0,0,0,150,150,150,0,150,150,150,150,0,0,150,0,0,0,0,0,0,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,0,0,0,0,0, 153,153,153,153,153,153,153,153,153,153,153,153,153,0,153,153,153,0,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,0,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,0,0,153,153,153,153, 153,153,153,153,153,0,153,153,153,0,153,153,153,153,0,0,0,0,0,0,0,153,153,0,153,153,153,0,0,153,0,0,153,153,153,153,0,0,153,153,153,153,153,153,153,153,153,153,0,0,0,0,0,0,0,153,153,153,153,153,153,153,153,153, 61,61,61,61,61,61,61,61,61,61,61,61,61,0,61,61,61,0,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,0,61,61,61,61,61,61,61,61,61,61,0,61,61,61,61,61,0,0,61,61,61,61, 61,61,61,61,61,0,61,61,61,0,61,61,61,61,0,0,0,0,0,0,0,61,61,0,0,0,0,0,0,61,61,0,61,61,61,61,0,0,61,61,61,61,61,61,61,61,61,61,0,61,61,61,0,0,0,0,0,0,0,0,0,0,0,0, 82,82,82,82,82,82,82,82,82,82,82,82,82,0,82,82,82,0,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, 82,82,82,82,82,0,82,82,82,0,82,82,82,82,82,82,0,0,0,0,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,0,0,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, 0,136,136,136,0,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,0,0,0,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,0,136,136,136,136,136,136,136,136,136,0,136,0,0, 136,136,136,136,136,136,136,0,0,0,136,0,0,0,0,136,136,136,136,136,136,0,136,0,136,136,136,136,136,136,136,136,0,0,0,0,0,0,136,136,136,136,136,136,136,136,136,136,0,0,136,136,136,0,0,0,0,0,0,0,0,0,0,0, 0,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,0,0,0,0,29, 155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,71,71,0,71,0,71,71,71,71,71,0,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,0,71,0,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,0,0, 71,71,71,71,71,0,71,0,71,71,71,71,71,71,71,0,71,71,71,71,71,71,71,71,71,71,0,0,71,71,71,71,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, 156,156,156,156,156,156,156,156,0,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,0,0,0,0,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, 156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,0,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,0,156,156, 156,156,156,156,156,156,156,156,156,156,156,156,156,0,156,156,156,156,156,156,156,29,29,29,29,156,156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, 41,41,41,41,41,41,0,41,0,0,0,0,0,41,0,0,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,29,41,41,41,41, 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, 39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39,39,0,39,39,39,39,0,0,39,39,39,39,39,39,39,0,39,0,39,39,39,39,0,0,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39,39,0,39,39,39,39,0,0,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,39,39,39,39,0,0,39,39,39,39,39,39,39,0, 39,0,39,39,39,39,0,0,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,39,39,39,39,0,0,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0, 39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,0,0,0,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,0,0,22,22,22,22,22,22,0,0, 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,0,0,0,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,29,29,29,128,128,128,128,128,128,128,128,128,128,128,0,0,0,0,0,0,0, 144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,0,0,0,0,0,0,0,0,0,144,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,29,29,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,145,145,145,145,145,145,145,145,145,145,145,145,145,0,145,145,145,0,145,145,0,0,0,0,0,0,0,0,0,0,0,0, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,0,0,67,67,67,67,67,67,67,67,67,67,0,0,0,0,0,0,67,67,67,67,67,67,67,67,67,67,0,0,0,0,0,0, 94,94,29,29,94,29,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,0,0,0,0,0,0,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, 94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,0,0,0,0,0,0,0, 94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,0,0,0,0,0,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,0,0, 74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,0,74,74,74,74,74,74,74,74,74,74,74,74,0,0,0,0,74,74,74,74,74,74,74,74,74,74,74,74,0,0,0,0, 74,0,0,0,74,74,74,74,74,74,74,74,74,74,74,74,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,0,0,146,146,146,146,146,0,0,0,0,0,0,0,0,0,0,0, 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,0,0,0,0,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 102,102,102,102,102,102,102,102,102,102,0,0,0,0,0,0,102,102,102,102,102,102,102,102,102,102,102,0,0,0,102,102,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,15,15,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,0,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,0,0,147, 147,147,147,147,147,147,147,147,147,147,0,0,0,0,0,0,147,147,147,147,147,147,147,147,147,147,0,0,0,0,0,0,147,147,147,147,147,147,147,147,147,147,147,147,147,147,0,0,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,0,0,0,0,0,0,0,0,10,10,10,10, 73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,0,0,0,73,73,73,73,73, 73,73,73,73,73,73,73,73,73,73,0,0,0,73,73,73,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 28,28,28,28,28,28,28,28,28,28,28,0,0,0,0,0,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,0,0,41,41,41, 140,140,140,140,140,140,140,140,0,0,0,0,0,0,0,0,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,29,29,29,30,29,29,29,29,29,29,30,29,29,29,30,30,29,0,0,0,0,0, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,45,45,45,45,45,28,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,45,45,45,45,45,72,72,72,72,45,45,45,45,45,72,72,72,72,72,72,72,72,72,72,72,72,72,28,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,45, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,0,0,45,45,45,45,45,45,0,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, 45,45,45,45,45,45,0,0,45,45,45,45,45,45,0,0,45,45,45,45,45,45,45,45,0,45,0,45,0,45,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,0,0, 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,0,45,45,45,45,45,45,45,45,45,45, 45,45,45,45,45,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,0,0,45,45,45,45,45,45,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,0,0,45,45,45,0,45,45,45,45,45,45,45,45,45,0, 29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,72,0,0,29,29,29,29,29,29,29,29,29,29,29,72, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,72,72,72,72,72,72,72,72,72,72,72,72,72,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,45,29,29,29,72,72,29,29,29,29,29,29,72,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,72,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,72,29,29,29,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,0,0,0,0,0,25,25,25,25,25,25,25, 41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,0,41,0,0,0,0,0,41,0,0,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, 157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,0,0,0,0,0,0,0,157,157,0,0,0,0,0,0,0,0,0,0,0,0,0,0,157, 39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,0,39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,0, 39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,0,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,0,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,30,30,30,30,50,50,29,29,29,29,29,29,29,29,0,0,0,0,29,29,29,29, 0,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,0,0,30,30,29,29,55,55,55,29,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,29,29,62,62,62, 0,0,0,0,0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,0,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,29,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,29, 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, 168,168,168,168,168,168,168,168,168,168,168,168,168,0,0,0,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, 168,168,168,168,168,168,168,0,0,0,0,0,0,0,0,0,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,29,29,29,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,0,0,72,72,0,72,0,72,72,72,72,72,72,72,72,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,0,0,0,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0, 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,0,0,0,0,0,0,0,0, 130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, 130,130,130,130,130,130,0,0,0,0,0,0,0,0,130,130,130,130,130,130,130,130,130,130,130,130,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,29,64,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,0,0,0,0,0,0,0,0,0,0,0,127,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,0,0,0, 59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, 59,59,59,59,59,59,59,59,59,59,59,59,59,59,0,29,59,59,59,59,59,59,59,59,59,59,0,0,0,0,59,59,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,0, 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,0,0,0,0,0,0,0,0,0, 21,21,21,21,21,21,21,21,21,21,21,21,21,21,0,0,21,21,21,21,21,21,21,21,21,21,0,0,21,21,21,21,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, 148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, 148,148,148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,148,148,148,148,148,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,0,0,0,0,0,0,0,0,0, 0,39,39,39,39,39,39,0,0,39,39,39,39,39,39,0,0,39,39,39,39,39,39,0,0,0,0,0,0,0,0,0,39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,0,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,29,72,72,72,72,72,72,72,72,72,45,72,72,72,72,29,29,0,0,0,0,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,0,0,88,88,88,88,88,88,88,88,88,88,0,0,0,0,0,0, 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,0,0,0,0,0,0,0,0,0,0,0,0,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, 50,50,50,50,50,50,50,0,0,0,0,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,0,0,0,0, 72,72,72,72,72,72,72,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,0,54,54,54,54,54,0,54,0, 54,54,0,54,54,0,54,54,54,54,54,54,54,54,54,54,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,29,29, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,30,30,30,30,30,30,30,30,30,30,30,30,30,30,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,29,29,29,29,0,0,0,0,4,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,29, 0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,29,29,29,29,29, 29,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,29,29,29,29,29,29,29,29,29,29,29,62,62,62,62,62,62,62,62,62,62,29,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,29,29,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,0, 0,0,50,50,50,50,50,50,0,0,50,50,50,50,50,50,0,0,50,50,50,50,50,50,0,0,50,50,50,0,0,0,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,29,29,29,29,29,0,0, 76,76,76,76,76,76,76,76,76,76,76,76,0,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,0,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,0,76,76,0,76, 76,76,76,76,76,76,76,76,76,76,76,76,76,76,0,0,76,76,76,76,76,76,76,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, 76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,0,0,0,0,0, 29,29,29,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,29,29,29,29,29,29,29,29,29, 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,0,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,0,0, 78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,0,0,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,0,0,0,0,0,0,0,0,0,109,109,109,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, 43,43,43,43,43,43,43,43,43,43,43,0,0,0,0,0,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,0,0,0,0,0, 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,0,162,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 113,113,113,113,0,0,0,0,113,113,113,113,113,113,113,113,113,113,113,113,113,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31, 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,0,0,120,120,120,120,120,120,120,120,120,120,0,0,0,0,0,0,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, 119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,0,0,0,0,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,0,0,0,0, 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,0,0,0,0,0,0,0,0,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,0,0,0,0,0,0,0,0,0,0,0,19,164,164,164,164,164,164,164,164,164,164,164,0,164,164,164,164, 164,164,164,164,164,164,164,164,164,164,164,0,164,164,164,164,164,164,164,0,164,164,0,164,164,164,164,164,164,164,164,164,164,164,0,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,0,164,164,164,164,164,164,164,0,164,164,0,0,0, 159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,0,0,0,0,0,0,0,0,0,0,0,0, 75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, 75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, 75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,0,0,0,0,0,0,0,0,0, 75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,0,0,0,0,0,0,0,0,0,0,75,75,75,75,75,75,75,75,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 72,72,72,72,72,72,0,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,0,72,72,72,72,72,72,72,72,72,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 26,26,26,26,26,26,0,0,26,0,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,26,26,0,0,0,26,0,0,26, 56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,0,56,56,56,56,56,56,56,56,56,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, 98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,0,0,0,0,0,0,0,0,98,98,98,98,98,98,98,98,98,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,0,53,53,0,0,0,0,0,53,53,53,53,53, 125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,0,0,0,125,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,0,0,0,0,0,79, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,0,0,0,0,90,90,90,90, 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,0,0,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, 65,65,65,65,0,65,65,0,0,0,0,0,65,65,65,65,65,65,65,65,0,65,65,65,0,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,0,0,65,65,65,0,0,0,0,65, 65,65,65,65,65,65,65,65,65,0,0,0,0,0,0,0,65,65,65,65,65,65,65,65,65,0,0,0,0,0,0,0,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,0,0,0,0,84,84,84,84,84,84,84,84,84,84,84,84,0,0,0,0,0,0,0,0,0, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,0,0,0,6,6,6,6,6,6,6, 58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,0,0,58,58,58,58,58,58,58,58,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,0,0,0,0,0,57,57,57,57,57,57,57,57, 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,0,0,0,0,0,0,0,126,126,126,126,0,0,0,0,0,0,0,0,0,0,0,0,126,126,126,126,126,126,126,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, 116,116,116,116,116,116,116,116,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,0,0,0,0,0,0,0,0,0,0,0,0,0, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,0,0,0,0,0,0,0,110,110,110,110,110,110, 51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,0,0,0,0,0,0,0,0,51,51,51,51,51,51,51,51,51,51,0,0,0,0,0,0, 40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,0,0,0,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, 40,40,40,40,40,40,0,0,0,0,0,0,0,0,40,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0, 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,0,167,167,167,0,0,167,167,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4, 114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,0,0,0,0,0,0,0,0,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, 117,117,117,117,117,117,117,117,117,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, 23,23,23,23,23,23,23,23,23,23,23,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,0,0,0,0,0,0,0,0,0, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,0,0,0,0,0,0,0,0,0,14, 60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, 60,60,60,0,0,0,0,0,0,0,0,0,0,60,0,0,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,0,0,0,0,0,0,0,137,137,137,137,137,137,137,137,137,137,0,0,0,0,0,0, 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,20,20,20,20,20,20,20,20,20,20, 20,20,20,20,20,20,20,20,0,0,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0, 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,0,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,0,0,0,0,0,0,0,0,0,0,0, 68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,0,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, 68,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 96,96,96,96,96,96,96,0,96,0,96,96,96,96,0,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,0,96,96,96,96,96,96,96,96,96,96,96,0,0,0,0,0,0,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, 69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,0,0,0,0,0,69,69,69,69,69,69,69,69,69,69,0,0,0,0,0,0, 44,44,44,44,0,44,44,44,44,44,44,44,44,0,0,44,44,0,0,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,0,44,44,44,44,44,44,44,0,44,44,0,44,44,44,44,44,0,30,44,44,44,44, 44,44,44,44,44,0,0,44,44,0,0,44,44,44,0,0,44,0,0,0,0,0,0,44,0,0,0,0,0,44,44,44,44,44,44,44,0,0,44,44,44,44,44,44,44,0,0,0,44,44,44,44,44,0,0,0,0,0,0,0,0,0,0,0, 161,161,161,161,161,161,161,161,161,161,0,161,0,0,161,0,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,0,161,161,161,161,161,161,161,161,161, 161,0,161,0,0,161,0,161,161,161,161,0,161,161,161,161,161,161,161,161,161,161,0,161,161,0,0,0,0,0,0,0,0,161,161,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, 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,0,101,101,101,101,101,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, 158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, 158,158,158,158,158,158,158,158,0,0,0,0,0,0,0,0,158,158,158,158,158,158,158,158,158,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,0,0,133,133,133,133,133,133,133,133, 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, 93,93,93,93,93,0,0,0,0,0,0,0,0,0,0,0,93,93,93,93,93,93,93,93,93,93,0,0,0,0,0,0,94,94,94,94,94,94,94,94,94,94,94,94,94,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,0,0,0,0,0,0, 149,149,149,149,149,149,149,149,149,149,0,0,0,0,0,0,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,0,0,0,0,0,0,0,0,0,0,0,0,166, 33,33,33,33,33,33,33,0,0,33,0,0,33,33,33,33,33,33,33,33,0,33,33,0,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,0,33,33,0,0,33,33,33,33,33, 33,33,33,33,33,33,33,0,0,0,0,0,0,0,0,0,33,33,33,33,33,33,33,33,33,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,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,100,100,100,100,100,100,100,100,0,0,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,0,0,100,100,100,100,100,100,100,100,100,100,100,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, 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, 169,169,169,169,169,169,169,169,0,0,0,0,0,0,0,0,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, 138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,0,0,0,0,0,0,0, 32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,0,0,0,0,0,0,0,0,0,0,0,0,0,0,141,141,141,141,141,141,141,141,141,141,0,0,0,0,0,0, 12,12,12,12,12,12,12,12,12,0,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,0,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,0,0,0,0,0,0,0,0,0,0,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,0,0,0,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, 85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,0,0,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,0,85,85,85,85,85,85,85,85,85,85,85,85,85,85,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 86,86,86,86,86,86,86,0,86,86,0,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,0,0,0,86,0,86,86,0,86, 86,86,86,86,86,86,86,86,0,0,0,0,0,0,0,0,86,86,86,86,86,86,86,86,86,86,0,0,0,0,0,0,47,47,47,47,47,47,0,47,47,0,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,0,47,47,0,47,47,47,47,47,47,0,0,0,0,0,0,0,47,47,47,47,47,47,47,47,47,47,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,0,0,0,0,0,0,0, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,0,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,0,0,0,63,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,0,0,0,0,0,0,0,0,0,0,0,0,0,150, 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,0,139,139,139,139,139,0,0,0,0,0,0,0,0,0,0,0, 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, 139,139,139,139,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27, 27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,0,0,0,0,0,0,0,0,0,0,0,0,0, 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,0,0,0,0,0,0,0,0,0,0,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,0, 95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,0,95,95,95,95,95,95,95,95,95,95,0,0,0,0,95,95,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, 151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,0, 151,151,151,151,151,151,151,151,151,151,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0, 121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, 121,121,121,121,121,121,0,0,0,0,0,0,0,0,0,0,121,121,121,121,121,121,121,121,121,121,0,121,121,121,121,121,121,121,0,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,0,0,0,0,0,121,121,121, 121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, 87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, 92,92,92,92,92,92,92,92,92,92,92,0,0,0,0,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, 92,92,92,92,92,92,92,92,0,0,0,0,0,0,0,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,152,104,0,0,66,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, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,0,0,0,0,0,0,0,0, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66, 152,152,152,152,152,152,152,152,152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,62,62,62,62,0,62,62,62,62,62,62,62,0,62,62,0, 62,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,62,62,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55,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,55,55,55,0,0,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62,62,62,62,0,0,0,0,0,0,0,0,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, 104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, 104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, 104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, 104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,0,0,0,0, 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,0,0,0,0,0,35,35,35,35,35,35,35,35,35,35,35,35,35,0,0,0, 35,35,35,35,35,35,35,35,35,0,0,0,0,0,0,0,35,35,35,35,35,35,35,35,35,35,0,0,35,35,35,35,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,0,0,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, 30,30,30,30,30,30,30,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30, 30,30,30,29,29,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, 45,45,45,45,45,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,29,29,0,0,29,0,0,29,29,0,0,29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,0,29,0,29,29,29, 29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,0,29,29,29,29,0,0,29,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,29,29,29,29,0, 29,29,29,29,29,0,29,0,0,0,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, 134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, 134,134,134,134,134,134,134,134,134,134,134,134,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,134,134,134,134,134,0,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,0,0,0,0,0,0,72,72,72,72,72,72,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 42,42,42,42,42,42,42,0,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,0,0,42,42,42,42,42,42,42,0,42,42,0,42,42,42,42,42,0,0,0,0,0,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,0,0,0,105,105,105,105,105,105,105,105,105,105,105,105,105,105,0,0, 105,105,105,105,105,105,105,105,105,105,0,0,0,0,105,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,0,0,0,0,0,165, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,0,0,0,0,108, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39,39,39,39,39,39,39,0,39,39,39,39,0,39,39,0,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0, 89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, 89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, 89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, 89,89,89,89,89,0,0,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,0,4,0,0,4,0,4,4,4,4,4,4,4,4,4,4,0,4,4,4,4,0,4,0,4,0,0,0,0, 0,0,4,0,0,0,0,4,0,4,0,4,0,4,4,4,0,4,4,0,4,0,0,4,0,4,0,4,0,4,0,4,0,4,4,0,4,0,0,4,4,4,4,0,4,4,4,4,4,4,4,0,4,4,4,4,0,4,4,4,4,0,4,0, 4,4,4,4,4,4,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,4,4,4,0,4,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 55,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0, 29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,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, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0, 29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0, 29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,0,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,0, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0, 0,29,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,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, 30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; KBTS_INLINE kbts_u8 kbts_GetUnicodeScript(kbts_u32 Codepoint) { return kbts_UnicodeScript_Data[((kbts_un)kbts_UnicodeScript_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)]; } static kbts_u8 kbts_UnicodeFlags_PageIndices[8703] = { 0,1,2,3,2,4,5,6,2,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29, 30,31,32,33,34,35,36,37,38,33,33,33,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,2,2,2,55, 56,57,58,59,33,33,60,33,61,33,33,33,33,33,62,63,33,33,33,64,33,33,65,66,67,68,69,70,71,72,33,73, 74,75,76,77,78,33,33,33,79,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,80,79,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,81, 33,33,33,33,33,33,33,33,33,82,33,33,83,84,85,86,87,88,89,90,91,92,93,94,79,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,95,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 79,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,81,33,33,96,97,98,99,33,33,100,101,102,103,104,105, 106,107,108,109,2,110,111,112,113,114,115,116,33,33,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134, 135,136,137,138,139,140,141,142,143,144,2,145,146,147,148,2,149,150,151,152,153,154,2,155,156,157,158,159,2,160,161,162, 33,33,33,33,33,33,33,37,163,33,164,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,165, 33,33,33,33,33,33,33,33,166,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33, 33,33,33,33,33,33,33,107,33,33,33,33,167,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,168,2,2,2,2,2,2,2,2,2,2,2,2,2,33,33,33,33,169,170,171,172,2,2,173,2,2,174,175,176, 79,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,177,33,33,33,33,33,33,33,33,33,178,179,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,180, 33,33,181,33,33,182,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,183,184,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,33,185,33,33,33,186,187,164, 33,188,189,190,191,192,193,2,2,2,2,2,2,194,195,196,33,33,33,33,197,198,2,2,2,2,2,2,2,2,199,2, 200,201,202,2,2,203,2,2,2,204,2,205,2,2,2,206,33,207,208,2,2,2,2,2,209,210,211,2,212,213,2,2, 214,215,33,216,217,2,33,33,33,33,33,33,33,218,219,220,221,222,33,33,223,224,33,225,2,2,2,2,2,2,2,2, 79,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,226,79,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,227,2,228,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,229,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,230,2,2,2,2,231,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,33,33,33,33,232,2,2,2,2,2,2,2,2,2,2,2, 79,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,233,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,234,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 235,235,236,237,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 79,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,238, 79,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, }; static kbts_u8 kbts_UnicodeFlags_Data[30592] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,4,0,0,16,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,16,16,16,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,16,0,16,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,16,0,16,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,0,16,16,16,0,16,2,16,16,16,16,16,16,16,0,0,0,16,16,16,0,16,16,16,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,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,16,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0, 16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,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,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,82,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,16,16,0,0,0,0,16,0,0,0,0,0, 0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0, 0,0,16,80,80,80,80,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,80, 0,80,80,0,80,80,0,80,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,16,16,16,0,0,16,0,0,16,16,80,80,80,80,80,80,80,80,80,80,80,0,2,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,81,81,80,80,81,80,80,80,80,80,80,80,48,48,48,48,48,48,48,48,48,48,0,0,0,0,16,16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,80,80,80,80,80,80,81,0,16,80,80,80,80,81,80,16,16,81,81,16,80,80,80,80,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, 80,80,80,80,80,80,80,80,80,80,80,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,16,16,16,0,0,0,16,0,0,80,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,80,80,80,80,80,80,80,80,80,16,80,80,80,16,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,81,81,80,81,81,81,80,80,80,81,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,81,80,80,80,80,80,80,80,80,80,80,80,80, 80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,16,16,16, 16,80,80,80,80,80,80,80,80,16,16,16,16,80,16,16,16,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,80,16,16,0,16,16,16,16,16,16,16,16,0,0,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,0,0,0,16,16,16,16,0,0,80,16,16,16, 16,80,80,80,80,0,0,16,16,0,0,16,16,80,16,0,0,0,0,0,0,0,0,16,0,0,0,0,16,16,0,16,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,0,80,0, 0,80,80,16,0,16,16,16,16,16,16,0,0,0,0,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0,16,16,0,16,16,0,0,80,0,16,16, 16,80,80,0,0,0,0,80,80,0,0,80,80,80,0,0,0,80,0,0,0,0,0,0,0,16,16,16,16,0,16,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,80,80,16,16,16,80,0,0,0,0,0,0,0,0,0,0, 0,80,80,16,0,16,16,16,16,16,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,0,0,80,16,16,16, 16,80,80,80,80,80,0,80,80,16,0,16,16,80,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,0,16,0,0,0,0,0,0,0,16,80,80,80,80,80,80, 0,80,16,16,0,16,16,16,16,16,16,16,16,0,0,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,0,0,80,16,16,80, 16,80,80,80,80,0,0,16,16,0,0,16,16,80,0,0,0,0,0,0,0,80,80,16,0,0,0,0,16,16,0,16,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0, 0,0,80,16,0,16,16,16,16,16,16,0,0,0,16,16,16,0,16,16,16,16,0,0,0,16,16,0,16,0,16,16,0,0,0,16,16,0,0,0,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16, 80,16,16,0,0,0,16,16,16,0,16,16,16,80,0,0,16,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0, 80,16,16,16,80,16,16,16,16,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,16,80,80, 80,16,16,16,16,0,80,80,80,0,80,80,80,80,0,0,0,0,0,0,0,80,80,0,16,16,16,0,0,16,0,0,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16, 16,80,16,16,0,16,16,16,16,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,0,0,80,16,16,80, 16,16,16,16,16,0,80,16,16,0,16,16,80,80,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,16,16,0,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0, 80,80,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,16, 16,80,80,80,80,0,16,16,16,0,16,16,16,80,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0,80,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,0,16,0,0, 16,16,16,16,16,16,16,0,0,0,80,0,0,0,0,16,16,16,80,80,80,0,80,0,16,16,16,16,16,16,16,16,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0, 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,80,80,80,80,80,80,80,0,0,0,0,16, 16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,16,16,0,16,0,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,0,16,16,16,16,16,16,16,16,16,16,80,16,16,80,80,80,80,80,80,80,80,80,16,0,0, 16,16,16,16,16,0,16,0,80,80,80,80,80,80,80,0,48,48,48,48,48,48,48,48,48,48,0,0,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16,16,16,80,80,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,80,16,80,16,80,0,0,0,0,16,16, 16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16, 80,80,80,80,80,0,80,80,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,16,16, 16,16,16,16,16,16,80,16,16,16,16,16,16,0,16,16,0,0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,80,80,80,80,80,80,16,80,80,16,16,80,80,16, 48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,80,80,16,16,16,16,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16, 16,16,80,16,16,80,80,16,16,16,16,16,16,80,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,18,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,0,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,0, 16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,80,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,0,80,80,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,82,82,16,80,80,80,80,80,80,80,16,16, 16,16,16,16,16,16,80,16,16,80,80,80,80,80,80,80,80,80,80,80,0,0,0,16,0,0,0,16,16,80,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,82,82,82,2,82,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0, 16,16,16,16,16,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,80,80,80,16,16,16,16,80,80,16,16,16,0,0,0,0,16,16,80,16,16,16,16,16,16,80,80,80,0,0,0,0, 16,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,80,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,80,80,80,80,80,80,0,80,16,80,16,16,80,80,80,80,80,80,80,80,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,0,0,80, 48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16,80, 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,80,80,80,80,16,80,16,16,16, 16,16,80,16,16,16,16,16,16,16,16,16,16,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,0,0,0, 80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,80,80,16,80,80,80,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,80,16,16,16,80,16,80,80,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,16,16,80,80,0,0,0,0,0,0,0,0, 48,48,48,48,48,48,48,48,48,48,0,0,0,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,16,80,80,80,80,80,80,80,16,16,16,16,80,16,16,16,16,16,16,80,16,16,16,80,80,16,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16, 16,16,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0, 0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,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,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,16,16,0,0,16,16,16,16,16,16,16,16,16,0,0,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,80,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,0,16,16,16,16,0,16,16,0,0,0,0,0,0,0,0,0,0,16,0,16,16,16,0,0,0,0,0,16,16,16,16,16,16,0,16,0,16,0,16,0,0,0,0,16,0,0,0,0,0,0,16,16,16,16,0,16,16,0,0,0,0, 16,16,16,16,16,0,0,0,0,0,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,0,0,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,0,0,0,0,80,80,80,0,0,0,0,0,0,0,0,0,0,0,16,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0, 16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,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,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16, 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16, 0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,16,80,16,16,16,0,80,80,80,80,80,80,80,80,80,80,0,16, 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,16,16,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,16,16,16,0,16,16,16,16,16, 16,16,80,16,16,16,80,16,16,16,16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,16,16,16,80,0,0,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,80,80,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,0,0,0,16,0,16,16,80, 48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0, 80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,80,80,80,80,16,16,80,80,16,16, 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,80,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,16,16,80,80,16,16,80,80,0,0,0,0,0,0,0,0,0, 16,16,16,80,16,16,16,16,16,16,16,16,80,16,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,80,80,16,16,80,80,16,16,16,16,16,80,80, 16,80,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,0,0,16,16,16,16,80,0,0,0,0,0,0,0,0,0, 0,16,16,16,16,16,16,0,0,16,16,16,16,16,16,0,0,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,80,16,16,0,16,80,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,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,16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,0,16,0, 16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16,16,16,0,0,16,0,0,0,0,0,0,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,2, 0,0,0,0,16,0,0,0,0,0,0,16,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,16,16,16,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,16,0, 16,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,16,0,16,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0, 0,0,16,16,16,16,16,16,0,0,16,16,16,16,16,16,0,0,16,16,16,16,16,16,0,0,16,16,16,0,0,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,2,2,2,2,2,2,2,2,2,0,0,0,16,16,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0, 0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 16,16,16,16,16,16,0,0,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,0,0,16,0,0,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,0,0,0,0,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,80,80,80,0,80,80,0,0,0,0,0,80,80,80,80,16,16,16,16,0,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,80,0,0,0,0,80, 16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,0,0,0,0,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,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,80,80,80,80,80,0,16,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,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,80,80,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,80, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,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,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0, 16,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80, 80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,80,16,16,80,80,16,0,0,0,0,0,0,0,0,0,80, 80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,80,80,0,0,0,0,0, 0,0,80,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,16,80,80,80,80,80,80,80,80,0,48,48,48,48,48,48,48,48,48,48, 0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,0,0,16,0,0,0,0,0,0,0,0,0, 80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,16, 16,16,16,16,16,0,0,0,0,80,80,80,80,0,16,80,48,48,48,48,48,48,48,48,48,48,16,0,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,16,16,80,16,80,80,0,0,0,0,0,0,80,16, 16,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,0,16,0,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,16,16,80,80,80,80,80,80,80,80,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 80,80,16,16,0,16,16,16,16,16,16,16,16,0,0,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,0,80,80,16,16,16, 80,16,16,16,16,0,0,16,16,0,0,16,16,16,0,0,16,0,0,0,0,0,0,16,0,0,0,0,0,16,16,16,16,16,16,16,0,0,80,80,80,80,80,80,80,0,0,0,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,0,16,0,0,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,80,80,80,80,80, 80,0,16,0,0,16,0,16,16,16,16,0,16,16,80,16,80,16,80,16,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,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, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80, 16,16,80,80,80,16,80,16,16,16,16,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,80,16,16,16,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, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,16,80,16,16,16,16,80, 80,16,80,80,16,16,0,16,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,0,0,16,16,16,16,80,80,16,80, 80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,16,16,80,16,80, 80,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,16,80,16,16,80,80,80,80,80,80,16,80,16,0,0,0,0,0,0,0, 48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,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, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,16,80,16,16,80,80,80,80,16,80,80,80,80,80,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,16,0,0,0,16, 16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,16,80,80,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16, 16,16,16,16,16,16,16,0,0,16,0,0,16,16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,0,80,80,16,80,16, 16,16,16,80,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,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,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,0,0,80,80,16,16,16,16,80,16,0,16,16,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, 16,80,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,16,16,80,80,80,80,0, 0,0,0,0,0,0,0,80,0,0,0,0,0,0,0,0,16,80,80,80,80,80,80,16,16,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,80,16,80,80,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,0,80,80,80,80,80,80,16,80, 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,16,80,80,80,80,80,80,80,16,80,80,16,80,80,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,0,0,0,80,0,80,80,0,80, 80,80,80,80,80,80,16,80,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,80,80,0,16,16,80,16,80,16,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,16,0,0,0,0,0,0,0,0,0, 80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,0,0,0,16,16, 80,16,80,0,0,0,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 80,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,80,80,80,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0, 48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,0,0,0,0,0,16,16,16,16, 16,16,16,16,0,16,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,16,80,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16, 16,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,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,16,16,16,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0, 16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,0,0,16,80,80,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, 80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,16,16,16,16,16,16,16,16,16,2,2,2,2,2,2,2,2,80,80,80,80,80, 80,80,80,16,16,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,80,80,80,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,16,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,16,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,16,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,16,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,16,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,16,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,16,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,16,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,16,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,16,0,0,0,0,0,0,0,0,0,0,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,80,80,80,80,80, 80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,16,16,16,16,16,16,16,16,80,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,80,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,80,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 80,80,80,80,80,80,80,0,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,0,0,80,80,80,80,80,80,80,0,80,80,0,80,80,80,80,80,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,80,80,80,80,80,80,80,16,16,16,16,16,16,16,0,0, 48,48,48,48,48,48,48,48,48,48,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,16, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,80,80,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,80,80,16,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,0,16,16,16,16,0,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,80,80,80,80,80,80,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,80,80,80,80,80,80,80,16,0,0,0,0,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,0,16,0,0,16,0,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,0,16,0,16,0,0,0,0, 0,0,16,0,0,0,0,16,0,16,0,16,0,16,16,16,0,16,16,0,16,0,0,16,0,16,0,16,0,16,0,16,0,16,16,0,16,0,0,16,16,16,16,0,16,16,16,16,16,16,16,0,16,16,16,16,0,16,16,16,16,0,16,0, 16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,0,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0, 16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,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, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0, 16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0, 16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0, 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,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,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, 82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0, }; KBTS_INLINE kbts_u8 kbts_GetUnicodeFlags(kbts_u32 Codepoint) { return kbts_UnicodeFlags_Data[((kbts_un)kbts_UnicodeFlags_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)]; } static kbts_u8 kbts_UnicodeBidirectionalClass_PageIndices[8703] = { 0,1,2,2,2,3,4,5,2,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, 29,30,2,2,31,32,33,34,35,2,2,2,2,36,37,38,39,40,41,42,43,44,45,46,47,48,2,49,2,2,50,51, 52,53,54,55,56,57,58,59,57,60,57,57,57,61,57,57,2,2,57,57,57,57,57,57,2,62,63,64,57,57,57,57, 65,66,67,68,69,70,71,72,73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,74,73,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,75, 2,2,2,2,2,2,2,2,2,76,2,2,77,78,79,80,81,82,83,84,85,86,87,88,73,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,89,73,57,57,57,57,57,75,90,73,57,57,57,57,57,57,75, 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,75,2,2,91,92,93,94,95,95,96,97,98,99,100,101, 102,103,104,105,57,106,107,108,2,109,110,111,2,2,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129, 130,131,132,133,134,135,136,137,138,139,57,140,141,142,143,57,144,145,146,147,148,149,150,151,152,153,154,155,57,156,157,158, 2,2,2,2,2,2,2,159,160,2,161,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,162, 2,2,2,2,2,2,2,2,163,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,103,2,2,2,2,164,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,165,57,57,57,57,57,57,57,57,57,57,57,57,57,2,2,2,2,166,167,168,169,57,57,170,57,171,172,173,174, 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,175,2,2,2,2,2,2,2,2,2,176,177,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,178, 2,2,179,2,2,180,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,181,182,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,183,57,57,57,57,184,161, 2,185,186,187,188,189,190,57,191,192,193,2,2,194,195,196,2,2,2,2,197,198,57,57,57,57,57,57,57,57,199,57, 200,201,202,57,57,203,57,57,57,204,57,205,57,57,57,206,207,208,209,57,57,57,57,57,210,211,212,57,213,214,57,57, 57,57,215,216,217,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,218,57,57,57,57,57,57,57,57, 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,219,73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,220,57,221,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,222,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,223,57,57,57,57,224,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,2,2,2,2,225,57,57,57,57,57,57,57,57,57,57,57, 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,226,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,227,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,228,229,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,230, 73,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, }; static kbts_u8 kbts_UnicodeBidirectionalClass_Data[29568] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,0,0,0,0,0,7,9,7,9,9,6,6,6,6,6,6,6,6,6,6,9,0,0,0,0,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,8,8,8,8,0,0,0,0,1,0,0,0,0,0,8,8,6,6,0,1,0,0,0,6,1,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1, 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,0,0,1,1,0,0,1,1,1,1,0,1, 0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, 1,1,1,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,8,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3, 2,3,3,2,3,3,2,3,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,5,5,0,0,4,8,8,4,9,4,0,0,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,5,5,5,5,5,5,8,5,5,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,5,0,3,3,3,3,3,3,4,4,3,3,0,3,3,3,3,4,4,6,6,6,6,6,6,6,6,6,6,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,0,0,0,0,2,0,0,3,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,0,0,2,0,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,5,5,0,0,0,0,0,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1, 1,3,3,3,3,3,3,3,3,1,1,1,1,3,1,1,1,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,3,1,1,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,1,0,0,3,1,1,1, 1,3,3,3,3,0,0,1,1,0,0,1,1,3,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,1,3,3,0,0,1,1,1,1,1,1,1,1,1,1,1,1,8,8,1,1,1,1,1,1,1,8,1,1,3,0, 0,3,3,1,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,0,3,0,1,1, 1,3,3,0,0,0,0,3,3,0,0,3,3,3,0,0,0,3,0,0,0,0,0,0,0,1,1,1,1,0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,3,1,0,0,0,0,0,0,0,0,0, 0,3,3,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0,3,1,1,1, 1,3,3,3,3,3,0,3,3,1,0,1,1,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,3,3,0,0,1,1,1,1,1,1,1,1,1,1,1,8,0,0,0,0,0,0,0,1,3,3,3,3,3,3, 0,3,1,1,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0,3,1,1,3, 1,3,3,3,3,0,0,1,1,0,0,1,1,3,0,0,0,0,0,0,0,3,3,1,0,0,0,0,1,1,0,1,1,1,3,3,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, 0,0,3,1,0,1,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1, 3,1,1,0,0,0,1,1,1,0,1,1,1,3,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,8,0,0,0,0,0,0, 3,1,1,1,3,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,3,1,3,3, 3,1,1,1,1,0,3,3,3,0,3,3,3,3,0,0,0,0,0,0,0,3,3,0,1,1,1,0,0,1,0,0,1,1,3,3,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, 1,3,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,3,1,1,1, 1,1,1,1,1,0,1,1,1,0,1,1,3,3,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,1,1,3,3,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1, 1,3,3,3,3,0,1,1,1,0,1,1,1,3,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,3,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,0,0, 1,1,1,1,1,1,1,0,0,0,3,0,0,0,0,1,1,1,3,3,3,0,3,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,3,3,3,3,3,3,3,0,0,0,0,8, 1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,3,1,1,3,3,3,3,3,3,3,3,3,1,0,0, 1,1,1,1,1,0,1,0,3,3,3,3,3,3,3,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,3,0,0,0,0,1,1, 1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1, 3,3,3,3,3,1,3,3,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,1,1, 1,1,1,1,1,1,3,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,1,3,3,3,3,3,3,1,3,3,1,1,3,3,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1, 1,1,3,1,1,3,3,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, 1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,3,3,3,3,3,3,3,1,1, 1,1,1,1,1,1,3,1,1,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,8,1,3,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,3,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, 1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,3,3,3,1,1,1,1,3,3,1,1,1,0,0,0,0,1,1,3,1,1,1,1,1,1,3,3,3,0,0,0,0, 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,3,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,3,3,3,3,3,3,0,3,1,3,1,1,3,3,3,3,3,3,3,3,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,0,0,3, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,3,3,3,3,1,3,1,1,1, 1,1,3,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1, 3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,1,1,3,3,1,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,3,1,1,1,3,1,3,3,3,1,1,0,0,0,0,0,0,0,0,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,1,1,3,3,0,0,0,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1, 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,1,1,1,1,3,1,1,1,1,1,1,3,1,1,1,3,3,1,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,0, 0,0,1,1,1,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,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,8,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,1,0,0,6,6,6,6,6,6,7,7,0,0,0,1, 6,6,6,6,6,6,6,6,6,6,7,7,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,0,1,0,1,0,1,1,1,1,8,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, 0,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,3,3,3,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0, 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 0,0,0,0,0,1,1,1,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,1,1,1,1,1,1,1,1,3,3,3,3,1,1,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,3,3,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1, 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,3,1,1,1,3,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,0,0,0,0,3,0,0,0,1,1,1,1,1,1,1,1,8,8,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,3, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0, 3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,3,3,3,3,1,1,3,3,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,1,1,3,3,1,1,3,3,0,0,0,0,0,0,0,0,0, 1,1,1,3,1,1,1,1,1,1,1,1,3,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,3,3,1,1,3,3,1,1,1,1,1,3,3, 1,3,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,3,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,3,1,1,1,1,3,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,2,3,2,2,2,2,2,2,2,2,2,2,7,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,0,2,0, 2,2,0,2,2,0,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,9,0,0,9,0,0,0,0,0,0,0,0,0,8,0,0,7,7,0,0,0,0,0,8,8,0,0,0,0,0,4,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0, 0,0,0,8,8,8,0,0,0,0,0,7,9,7,9,9,6,6,6,6,6,6,6,6,6,6,9,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,0,0,0,8,8,0,0,0,8,8,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,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, 1,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,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,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,2,2,2,2,0,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,2,0,0,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,2, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,3,3,3,0,3,3,0,0,0,0,0,3,3,3,3,2,2,2,2,0,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,3,3,3,0,0,0,0,3, 2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,2, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0, 5,5,5,5,5,5,5,5,5,5,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,3,3,3,3,3,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,3,3,2,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,3,3,3,3,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0, 1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,3,1,1,3,3,1,0,0,0,0,0,0,0,0,0,3, 3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,1,1,3,3,1,1,1,1,1, 1,1,3,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,1,3,3,3,3,3,3,3,3,0,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,0,0,0,0,0,0,0,0,0, 3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,1, 1,1,1,1,1,1,1,1,1,3,3,3,3,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,3,1,3,3,1,1,1,1,1,1,3,1, 1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,3,3,3,3,3,3,3,3,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 3,3,1,1,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,3,3,1,1,1, 3,1,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,3,3,3,3,3,3,3,0,0,0,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,3,3,3,3,3, 3,0,1,0,0,1,0,1,1,1,1,0,1,1,3,1,3,1,3,1,1,1,0,1,1,0,0,0,0,0,0,0,0,3,3,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3, 1,1,3,3,3,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,3,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,1,3,1,1,1,1,3, 3,1,3,3,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,0,0,1,1,1,1,3,3,1,3, 3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,1,1,3,1,3, 3,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,3,3,3,3,3,3,1,3,1,1,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,3,1,3,1,1,3,3,3,3,1,3,3,3,3,3,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,1,3,3,1,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,3,3,1,3,1, 1,1,1,3,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,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,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,0,0,3,3,1,1,1,1,3,1,1,1,1,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,3,3,3,3,3,3,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,1,1,3,3,3,3,1, 1,1,1,1,1,1,1,3,0,0,0,0,0,0,0,0,1,3,3,3,3,3,3,1,1,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,0,3,3,3,3,3,3,1,1, 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,1,3,3,3,3,3,3,3,1,3,3,1,3,3,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,0,0,0,3,0,3,3,0,3, 3,3,3,3,3,3,1,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,3,3,0,1,1,3,1,3,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,0,0,0,0,0,0,0, 3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,0,0,0,1,1, 3,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,8,8,8,8,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, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 3,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,3,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,3,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,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,1,0,1,3,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,3,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,6,6,6,6,6,6,6,6,6,6,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3, 3,3,3,1,1,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1, 1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0, 1,1,1,1,1,0,1,0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1,1,1,1,1,0,0,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,3,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,3,3,3,3,3,3,3,1,1,1,1,1,1,1,0,0, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,8, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,3,3,3,3,3,3,3,2,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,0,4,0,0,4,0,4,4,4,4,4,4,4,4,4,4,0,4,4,4,4,0,4,0,4,0,0,0,0, 0,0,4,0,0,0,0,4,0,4,0,4,0,4,4,4,0,4,4,0,4,0,0,4,0,4,0,4,0,4,0,4,0,4,4,0,4,0,0,4,4,4,4,0,4,4,4,4,4,4,4,0,4,4,4,4,0,4,4,4,4,0,4,0, 4,4,4,4,4,4,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,4,4,4,0,4,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,6,6,6,6,6,6,6,6,6,6,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,6,6,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, }; KBTS_INLINE kbts_u8 kbts_GetUnicodeBidirectionalClass(kbts_u32 Codepoint) { return kbts_UnicodeBidirectionalClass_Data[((kbts_un)kbts_UnicodeBidirectionalClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)]; } static kbts_u8 kbts_UnicodeJoiningType_PageIndices[8703] = { 0,1,0,0,0,0,2,0,0,3,0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, 25,26,0,0,0,0,27,0,0,0,0,0,0,0,28,29,30,31,32,0,33,34,35,36,37,38,0,39,0,0,0,0, 40,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,43,44,0,0,0,0, 45,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,47,48,0,0,49,50,51,52,53,54,0,55,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,0,0,57,43,0,58, 0,0,0,59,0,60,61,0,0,0,0,0,0,0,0,0,0,0,0,0,62,63,0,64,0,0,65,0,0,66,67,68, 69,70,71,72,73,74,75,76,77,78,0,79,80,81,82,0,83,0,84,85,86,87,0,0,88,89,90,91,0,92,93,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,94,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,97,0,0,0,0,0,0,0,98,99, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0, 0,0,102,103,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,105,106,0,0,0,0,0,0,0,0,0,0, 107,108,97,0,0,109,0,0,0,110,0,111,0,0,0,0,0,112,113,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,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, 114,0,115,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; static kbts_u8 kbts_UnicodeJoiningType_Data[14848] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5, 0,5,5,0,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,0,5,0,0,0,2,0,4,4,4,4,2,4,2,4,2,2,2,2,2,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,2,2,2,2,2,2,2,4,2,2,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,5,4,4,4,0,4,4,4,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 4,2,2,4,4,4,4,4,4,4,4,4,2,4,2,4,2,2,4,4,0,4,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,0,0,5,5,0,5,5,5,5,4,4,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,2, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,4,5,2,2,2,4,4,4,4,4,2,2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,4,2,4,2,2,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,0,0,4,2,2,2,2,2,2,2,2,2,2,2,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,2,2,2,2,4,2,4,4,2,2,2,4,4,2,2,2,2,2,2, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,3,0,0,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,5,5,5,5,5,5,5,5,5,0,5,5,5,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 4,2,2,2,2,2,4,4,2,4,2,2,2,2,2,2,2,2,2,2,4,2,4,4,4,5,5,5,0,0,0,0,2,0,2,2,2,2,0,4,2,4,4,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,3,3,3,2,0,0,2,2,2,2,2,4,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,2,2,2,2,2,2,2,2,2,2,4,4,4,0,4,2,2,4,4,2,2,2,2,2,2,4,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,0, 0,5,5,5,5,5,5,5,5,0,0,0,0,5,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,5,5,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,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, 0,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,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,5,0, 0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, 0,5,5,0,0,0,0,5,5,0,0,5,5,5,0,0,0,5,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,5,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0, 0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, 0,5,5,5,5,5,0,5,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5, 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5, 0,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,5,5,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,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5, 5,0,0,0,0,0,5,5,5,0,5,5,5,5,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,5,5,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,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5, 0,0,0,0,0,0,5,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,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, 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0, 0,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,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,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,0,0,0,0,0, 0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,5,5,0,0,0, 0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,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,5,0,5,0,5,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0, 5,5,5,5,5,0,5,5,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0, 0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,5,5,5,5,5,5,0,5,5,0,0,5,5,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,5,5,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0, 0,0,5,0,0,5,5,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,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,5,5,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,5,5,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,5,5,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,5,5,5,5,5,5,5,0,0, 0,0,0,0,0,0,5,0,0,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,2,0,0,3,5,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0, 0,0,0,0,0,5,5,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,5,5,5,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,5,5,5,5,5,0,5,0,5,0,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,0,0,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,5,5,5,0,5,0,0,0, 0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,5,5,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,0,0,0,5,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,0,0,5,5,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,0,0,0,0,5,0,0,0,0,0,0,5,0,0,0,5,5,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 0,0,0,0,0,0,0,0,0,0,0,5,0,3,5,5,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,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,5,0,0,0,5,0,0,0,0,5,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,5,5,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,5,5,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,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,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,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,5,5,0,0,5,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,5,5,5,0,0,5,5,0,0,5,5,0,0,0,0,0,0,0,0,0, 0,0,0,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,5,5,0,0,5,5,0,0,0,0,0,5,5, 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,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,5,0,0,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,5,5,0,0,0,0,0, 0,5,5,5,0,5,5,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,4,0,4,0,4,4,0,0,1,4,4,4,4,4,2,2,2,2,1,2,2,2,2,2,4,2,2,2,4,0,0,4,5,5,0,0,0,0,2,2,2,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,4,2,4,4,4,2,2,2,4,2,2,4,2,4,4,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,4,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,4,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,0,5,5,5,5,5,5,5,5,5,5,5,2,2,2,4,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,2,2,2,4,4,2,2,2,2,2,2,2,2,2,2, 2,2,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,2,4,4,4,0,2,4,4,2,2,4,2,2, 0,2,4,4,2,0,0,0,0,4,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,5,0,0,0,0,0,0,0,0,0,0,5, 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,5,5,0,0,0,0,0, 0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,0, 0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,5,0,5,5,0,0,0,0,0,0,5,0, 0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0, 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,5,5, 5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5, 0,0,5,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,5,0,0,0,0,5, 5,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,5,0,0,0,0,0,0,5,5,0,5, 5,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,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,0,0,5,0,5, 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,0,5,0,0,5,5,5,5,5,5,0,5,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,5,5,5,5,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,0,5,5,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,5,0, 0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,5,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,5,5,5,5,0, 0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,5,5,5,5,0,5,5,5,5,5,5,0,5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,0,5,5,0,5,5,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,0,5,0,5,5,0,5, 5,5,5,5,5,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0, 5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0, 5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,0,0,5,5,5,5,5,5,5,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,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,5,0,5,5,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,5,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,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, }; KBTS_INLINE kbts_u8 kbts_GetUnicodeJoiningType(kbts_u32 Codepoint) { return kbts_UnicodeJoiningType_Data[((kbts_un)kbts_UnicodeJoiningType_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)]; } static kbts_u8 kbts_UnicodeCombiningClass_PageIndices[8703] = { 0,0,0,0,0,0,1,0,0,2,0,3,4,5,6,7,8,9,10,11,12,12,12,13,14,12,15,16,17,18,19,20, 21,22,0,0,0,0,23,0,0,0,0,0,0,0,24,25,0,26,27,0,28,29,30,31,32,33,0,34,0,0,0,0, 0,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,37,38,0,0,0,0, 39,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,41,42,0,0,43,44,45,46,0,47,0,48,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,0,0,0,0,0,50,0,0,0, 0,0,0,51,0,52,53,0,0,0,0,0,0,0,0,0,0,0,0,0,54,55,0,0,0,0,56,0,0,57,58,59, 60,61,62,63,64,65,66,67,68,69,0,70,71,72,73,0,61,0,74,75,76,77,0,0,71,0,78,79,0,0,80,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,82,83,0,0,0,0,0,0,0,0,84, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,85,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,86,87,88,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, 89,90,83,0,0,91,0,0,0,92,0,93,0,0,0,0,0,94,95,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; static kbts_u8 kbts_UnicodeCombiningClass_Data[12288] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220,220,220,220,220,220,220,220,220,1,1,1,1,1,220,220,220,220,230,230,230, 230,230,230,230,230,240,230,220,220,220,230,230,230,220,220,0,230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,234,234,233,230,230,230,230,230,230,230,230,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,230,230,230,230,220,230,230,230,222,220,230,230,230,230,230,230,220,220,220,220,220,220,230,230,220,230,230,222,228,230,22,15,16,17,23,18,19,20,21,14,14,24,12,25,0,13, 0,10,11,0,230,220,0,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,230,31,32,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,28,29,30,31,32,33,27,34,230,230,220,220,230,230,230,230,230,220,230,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,0,0,230,230,230,230,220,230,0,0,230,230,0,220,230,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,230,220,230,230,220,230,230,220,220,220,230,220,220,230,220,230, 230,230,220,230,220,230,220,230,220,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,220,230,0,0,0,0,0,0,0,0,0,220,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,0,230,230,230,230,230,230,230,230,230,0,230,230,230,0,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,220,220,220,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,220,220,220,220,220,230,230,230,230,230,230,230,230,230,230,230,230,230,230,0,220,230,230,220,230,230,220,230,230,230,220,220,220,28,29,30,230,230,230,220,230,230,220,220,230,230,230,230,230, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,230,220,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,7,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,3,9,0,0,0,0,0, 0,0,0,0,0,0,0,0,107,107,107,107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,118,118,9,0,0,0,0,0, 0,0,0,0,0,0,0,0,122,122,122,122,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,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,220,0,220,0,127,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,132,0,131,0,0,0,0,0,132,132,132,132,0,0, 132,0,230,230,9,0,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,9,9,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,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,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,228,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,222,230,220,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,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,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,230,0,0,220, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,220,220,220,220,220,220,230,230,220,0,220, 220,230,230,220,220,230,230,230,230,230,220,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,220,230,230,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,7,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,0,1,220,220,220,220,220,230,230,220,220,220,220,230,0,1,1,1,1,1,1,1,0,0,0,0,220,0,0,0,0,0,0,230,0,0,0,230,230,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 230,230,220,230,230,230,230,230,230,230,220,230,230,234,214,220,202,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,232,228,228,220,218,230,233,220,230,220, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,1,1,230,230,230,230,1,1,1,230,230,0,0,0,0,230,0,0,0,1,1,230,220,230,1,1,220,220,220,220,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,218,228,232,222,224,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 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,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,230,230,230,230,230,230,230,230,230,230,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,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,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0, 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,230,0,230,230,220,0,0,230,230,0,0,0,0,0,230,230, 0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,220,220,220,220,220,220,220,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,230,230,230,230,230,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,1,220,0,0,0,0,9, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,220, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,220,220,230,230,230,220,230,220,220,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,230,220,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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, 230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 9,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,7,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,0,0,0,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,9,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9, 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,9,0, 0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,7,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,230,230,230,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,216,216,1,1,1,0,0,0,226,216,216,216,216,216,0,0,0,0,0,0,0,0,220,220,220,220,220, 220,220,220,0,0,230,230,230,230,230,220,220,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,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 230,230,230,230,230,230,230,0,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,0,0,230,230,230,230,230,230,230,0,230,230,0,230,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,230,230,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,232,232,220,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220,220,220,220,220,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,230,230,230,230,230,230,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; KBTS_INLINE kbts_u8 kbts_GetUnicodeCombiningClass(kbts_u32 Codepoint) { return kbts_UnicodeCombiningClass_Data[((kbts_un)kbts_UnicodeCombiningClass_PageIndices[Codepoint/128] * 128) | (Codepoint & 127)]; } static kbts_u16 kbts_UnicodeParentInfo_PageIndices[34815] = { 0,1,2,3,0,4,5,6,7,0,8,9,0,10,0,11,0,12,0,0,13,14,0,0,15,0,0,0,16,17,18,0, 19,20,21,22,0,0,23,24,0,0,0,0,0,0,25,26,0,27,28,0,0,0,29,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,30,31,0,0,0,32,33,0,34,35,0,0,0,0,0,0,0,36,37,0,0,0,38,0, 0,0,39,0,0,40,41,0,0,0,38,0,0,0,42,0,0,0,0,0,0,0,0,0,0,0,43,44,45,46,0,0, 0,47,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,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,49,50,51,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,53,54,0,55,56,0,57,58,59,60,0,61,62,63, 64,0,0,0,0,0,0,0,0,0,0,0,65,0,66,0,67,68,69,70,71,72,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,73,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 74,0,75,76,77,75,76,78,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,79,80,81,0,82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,83,0,0,0,0,84,0,0,0, 0,85,0,86,0,0,87,88,89,90,0,0,0,0,0,0,0,91,0,92,0,0,0,93,94,0,95,0,96,0,0,0, 97,0,98,0,0,0,0,0,0,99,0,0,100,0,0,0,0,0,0,0,0,101,0,0,102,0,0,0,0,0,0,103, 104,105,106,0,107,0,0,108,0,109,0,0,0,0,0,0,110,111,0,0,0,112,0,0,113,114,115,0,0,0,116,0, 117,0,0,118,0,0,0,0,0,119,120,121,0,0,122,123,0,124,0,0,0,125,126,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,128,0,0,0,129,0,130,0,0,0,131,0,0,0,0,132,0, 0,0,0,0,0,0,133,134,0,0,135,0,0,0,0,0,136,137,138,0,139,140,141,142,0,0,0,143,144,145,0,0, 146,147,0,148,149,0,150,151,0,0,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,0,0,170,171, 172,173,174,175,176,177,0,178,179,0,180,181,182,183,184,185,186,0,187,188,0,0,0,189,190,0,0,0,191,0,192,193, 194,195,196,0,0,197,198,199,200,201,202,203,0,0,204,205,206,207,0,208,0,209,0,0,210,211,0,0,212,0,213,214, 215,216,0,217,218,0,219,0,220,0,221,222,0,223,0,224,0,225,0,226,0,227,228,229,230,231,232,233,234,235,236,237, 238,0,0,239,240,0,241,242,243,0,244,245,246,247,248,249,250,251,252,0,0,253,254,255,0,256,257,258,259,260,261,262, 263,264,265,266,267,0,268,0,0,0,269,270,271,0,272,273,274,0,275,276,277,278,279,280,281,282,283,284,285,0,0,286, 287,0,288,0,289,290,0,0,291,0,292,0,0,293,0,294,295,0,0,0,0,296,297,0,298,299,300,301,302,303,0,0, 0,0,304,305,306,307,308,309,310,311,312,313,314,0,315,316,317,318,0,319,320,321,322,0,323,324,0,325,0,0,326,327, 328,329,330,331,332,333,334,0,0,0,335,336,337,0,338,0,339,340,341,342,343,344,345,346,0,347,0,348,349,350,351,0, 352,353,354,355,356,0,357,0,358,359,360,361,0,0,0,362,363,0,364,365,0,0,366,367,368,0,369,0,370,371,0,0, 0,0,372,373,374,0,375,376,0,377,378,379,380,381,382,383,384,0,385,0,386,387,388,389,0,390,0,0,0,0,391,0, 0,392,0,393,394,395,396,397,398,399,400,401,0,402,403,404,405,406,407,0,0,0,0,0,0,408,0,409,410,411,0,412, 413,0,414,415,416,417,0,0,418,419,0,0,0,0,420,421,422,0,0,423,424,425,0,426,427,428,429,430,0,431,432,433, 0,434,435,0,0,0,0,436,437,0,0,438,0,0,439,440,441,442,443,444,445,446,0,447,448,449,0,450,451,452,0,453, 454,0,455,456,0,0,457,458,459,0,460,461,462,0,0,0,0,0,0,0,0,463,464,465,466,467,468,0,469,0,0,0, 0,0,470,0,0,471,472,0,473,0,0,474,0,475,476,477,0,0,0,0,0,0,478,0,0,479,0,480,481,482,0,0, 0,483,0,484,485,0,486,487,488,0,0,489,490,491,492,0,0,493,0,494,0,0,495,0,496,0,497,0,0,0,0,498, 499,0,0,0,0,0,0,0,0,0,0,0,500,501,0,0,0,502,503,504,505,506,507,508,0,509,510,0,0,0,511,512, 513,514,515,0,0,0,0,516,0,517,0,0,0,518,519,520,0,0,0,521,0,0,0,0,522,0,0,523,0,0,0,0, 0,0,524,0,0,0,0,525,0,0,0,526,0,527,0,528,529,0,0,530,531,532,533,534,535,536,537,0,538,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,539,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,541,542,0,0,0,543,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,0,544,0,545,0, 0,0,0,0,0,546,0,0,0,0,0,0,0,23,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,547,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,548,549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,551,0,0,552,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,553,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,554,555,556,0,0,0,0,0,0,557,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 558,0,0,0,0,0,559,0,0,0,0,0,0,0,0,0,0,560,0,0,0,0,0,0,0,0,0,561,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,562,0,0,0,0,0,0,0,0,0,0,0,0,0,563,0,564,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,565,0,0,0,0,0,0,0,0,0,566,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,567,0,0,0,0,0,0,568,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,569,0,0,0,0,0,0,0,0,0,0,0,0,570,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,571,0,0,0,0,0,0,0,0,0, 0,0,572,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,573,0,0,0,0,0,0,574, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 575,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,576,0,0,0,0,577,0,578,0,579,0, 0,0,0,580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,581,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,582,0,0,0,0,0,0,0,0,0,0,0,0,0,0,583,0,0,584,0,0,0,0,0,0,0,0, 0,0,0,0,0,585,0,0,586,0,0,0,0,0,0,0,0,0,0,0,0,0,587,0,0,0,588,0,589,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,590,0,0,0,591,0,0,0,0,0,592,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,593,0,0,0,0,0,0,0,0,594,0,0,0,0,0,0, 595,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,596,0,0,597,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,598,0,0, 0,0,599,0,0,0,0,600,601,602,0,0,0,0,0,0,0,0,603,0,0,0,0,0,0,0,0,0,0,0,0,0, 604,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,605,0,0,606,0,607,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,608,0,0,0,0,0,0,0,0,0,609,0,0,0,0,0,0,0,610,0,0, 0,0,0,0,611,0,612,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,613,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,614,0,0,615,616,0,0,0,617,0,0,618,0,0,0,0,0,0, 0,0,0,0,0,0,619,0,0,620,0,0,0,621,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,622,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,623,0,0,0,0,0,0, 0,624,0,0,0,0,625,0,0,0,0,626,0,0,0,0,0,0,0,0,0,0,0,0,0,627,0,0,0,628,0,0, 0,0,0,0,0,0,629,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,630,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,631,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,632,0,0,0,0,0,633,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,634,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,635,0,0,636,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,637,638,0,0,0,0,0,0,0,0,0,639,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,640, 0,0,0,0,0,0,0,0,0,0,0,641,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,642,0,0,0,643,0,644,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 645,0,0,0,646,0,0,0,0,0,0,0,0,647,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,648,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,649,0,650,0,0,0,0,0,0,0,651,0,0,0,652,0,0,0,0,0,0,0,653,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,654,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,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, }; static kbts_u32 kbts_UnicodeParentInfo_Data[20960] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66400,66423,66421,66422,0, 0,1048664,197177,328094,393598,1114167,66418,459018,459046,983176,65810,393556,393562,197183,590017,1048696,131720,0,524539,459032,459067,1245203,131728,393604,131730,590026,393592,0,0,0,0,0, 66420,1048648,197171,328084,393586,1114150,66417,459011,524515,917655,131704,328109,393538,197180,590008,1048680,131414,0,524499,459025,524523,1245184,131724,459060,131726,655525,393580,0,0,0,0,0, 0,0,0,0,0,0,0,0,197174,0,0,0,0,0,0,0,0,0,0,0,66419,0,0,66399,0,0,0,0,0,0,0,0, 0,0,262650,0,66396,131722,131706,65959,0,0,262654,0,0,0,0,66416,0,0,0,0,262658,197168,66398,0,66397,0,0,0,262626,0,0,0, 0,0,262638,0,66019,66395,131702,66415,0,0,262642,0,0,0,0,65963,0,0,0,0,262646,197165,66186,0,65816,0,0,0,262622,0,0,0, 0,0,262634,262634,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131716,131716,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,131718,131718,0,0,0,0,0,0,0,0,0,0,0,0,66412,66412,0,0,0,0, 66183,66183,0,0,0,0,0,0,66413,66413,66413,66413,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66414, 328104,328104,0,0,0,0,0,0,0,0,0,0,0,0,0,328099,328099,0,0,0,0,0,0,66381,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,65936,65936,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,66367,66367,66405,66405,0,0,0,0,65936,65936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66366,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66393,0,0,0,0,0,0, 65973,65973,0,0,0,0,0,0,66384,0,0,0,0,0,0,0,0,0,0,66379,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,66409,65949,0,65829,66406,65873,0,66411,0,66408,66410,65867,459053,0,0,0,262618,0,328089,0,459039,0,0,0,0,0,262610, 0,66407,0,0,0,393544,0,0,0,393550,0,0,131708,66403,131710,66404,65948,524531,0,0,0,262606,0,393568,0,589999,0,0,0,0,0,262630, 0,131714,0,0,0,524507,0,0,0,393574,197129,197132,66401,66402,131712,0,0,0,131471,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,65935,0,0,0,0,0,0,0,0,0,131227,0,0,66371,0,197150,131700,65953,262594,0,65945,0,0,0,66394,0, 0,0,0,262586,0,0,0,65595,0,0,0,65595,0,65630,0,0,131696,0,0,66376,0,197162,131698,65943,262602,0,66377,0,0,0,66392,0, 0,0,0,262614,0,0,0,65578,0,0,0,65578,0,65614,0,0,0,0,0,0,0,0,65935,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,65936,65936,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,65936,65936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197216,131836,66134,66134,66134,131828,66134,0,66134,131820,66134,131826,66134,0,66134,0, 66134,66134,0,66134,131822,0,66134,66134,66134,197204,66134,0,0,0,0,0,0,0,66855,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,197135,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66370,0,66370,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,0,65978,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,66387,66387,66387,0,0,0,0,66385,0,0,0, 0,66383,66383,0,0,0,0,0,65935,0,0,66380,0,0,0,66379,0,0,0,65935,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,66379,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,131474,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66387,66387,0,0,0,0,66385,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66380,0,0,0,0,0,0,65935,0,0,0,0,0,65931,0,0,0,0,0,0,0, 0,66383,66383,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,197147,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,131507,65934,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,65936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935, 0,0,0,0,0,0,197138,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197141,0,0,65935,0,0,0, 66378,0,65935,0,0,0,0,0,0,0,0,0,65935,0,0,0,0,65935,0,0,0,0,65935,0,0,0,0,65935,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197153,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,66378,0,65935,0,0,0,0,0,0,0,0,0,65935,0,0,0, 0,65935,0,0,0,0,65935,0,0,0,0,65935,0,0,0,0,0,0,66368,66369,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,65935,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,328074,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,65935,0,65935,0,65935,0,65935,0,65935,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,65935,0,65936,65936, 0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,0,0, 0,0,65755,65755,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, 131694,131694,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66087,66087,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,66158,66158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 262598,262598,65609,65609,65609,65609,65609,65609,262598,262598,65609,65609,65609,65609,65609,65609,131506,131506,0,0,0,0,0,0,131506,131506,0,0,0,0,0,0, 262590,262590,65985,65985,65985,65985,65985,65985,262590,262590,65985,65985,65985,65985,65985,65985,197042,197042,0,0,0,0,0,0,197042,197042,0,0,0,0,0,0, 131506,131506,0,0,0,0,0,0,131506,131506,0,0,0,0,0,0,197042,197042,0,0,0,0,0,0,0,197042,0,0,0,0,0,0, 262578,262578,65973,65973,65973,65973,65973,65973,262578,262578,65973,65973,65973,65973,65973,65973,66386,0,0,0,66388,0,0,0,0,0,0,0,66391,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,65935,0,0,0,0,0,0,0,0,197159, 0,0,0,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,0,0,0,0,0,0,197126,0, 0,0,65931,65931,0,0,0,0,0,0,0,0,0,0,0,0,65935,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,66374,0,66373,0,66375,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,65930,0,65930,0,66372,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,65935,0,0,0,0,65935,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,65935,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65894,0,0,0, 0,0,0,65935,0,65936,0,0,65935,0,0,0,0,66376,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,65935,0,0,66158,66158,0,0,0,0,0,0,0,0,0,0,0,0,65936,65936,0,0,65936,65936,0,0,65755,65755,66390,66390,0,0, 0,0,65936,65936,0,0,65936,65936,0,0,0,0,0,0,0,0,0,66389,66389,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,66374,0,0,0,0,0,65894,65894,0,65934,0,0,0,0,0,0,66382,66382,66382,66382,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65932,0,0, 0,0,0,0,0,0,0,0,66365,66365,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,66388,0,0,0,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935,0,65935, 0,65935,0,0,65935,0,65935,0,65935,0,0,0,0,0,0,131471,0,0,131471,0,0,131471,0,0,131471,0,0,131471,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65935,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65756,65756,65756,65756,0,0,0,0,0,0,0,0,0,0,65935,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67213,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,67212,0,67214,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67211, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67210,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67209,0,0,0,0,0,0,0,0,0,0,0,0,0,67208,0,0,0, 0,67207,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67206,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,67205,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,67204,0,0,0, 0,0,0,0,0,0,0,67203,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,67202,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67201,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,67200,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67199,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,67198,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,67197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,67196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67195,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,67194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131892,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,67193,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67191,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67190,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,67189,0,0,0,0,0,0,0,0,0,0,0,131890,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67188,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67187,0,0,0, 0,0,0,0,0,0,0,0,67186,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66821,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131888,0,0,0,0,0,0, 0,0,0,0,0,0,67185,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67184,0,0,0,0,0,0,0,0,0, 0,0,0,67183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67182,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,67181,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,67180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 67179,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,67178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67177,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67176,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,67175,0,0,0,67172,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,67174,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,67173,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,67171,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67170,0,0, 0,67169,0,0,0,0,0,0,0,0,0,67168,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67167,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67166,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,67165,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67164,0, 0,0,0,0,0,0,0,67163,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67162,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,67161,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67160,0,0,0,0,0,0,0,67159,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,67158,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67157,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,67156,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,67155,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,67154,0,0,0,0,0,0,0,0,0,0,67153,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,67152,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,66809,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66810,0,0,0,0,0,0,0,0,0,0,0,66804,0,0,0,0,0,67151,66806,0,0,0,67150,0,0, 0,67149,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,66801,0,0,0,66807,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66803,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 66808,0,0,0,0,0,0,0,0,0,0,0,67148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,66802,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, 67147,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, 66805,0,0,0,0,0,66798,0,0,0,0,66800,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,131886,0,0,0,0,0,0,0,0,0,0,0,0,67146,0,0,0,66797, 0,0,67145,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66799,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67144,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,67143,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67140,0,0,0,0,0,0,0,0,0,0,66790,0,0,0,0,0, 0,0,0,0,0,0,0,131882,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 66789,0,0,0,0,66794,0,0,0,0,0,0,0,131878,0,0,0,0,0,0,67138,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,67136,0,0,67137,66793,66782,0,0,0,66788,0,0,0,0,0,0,0,0,0,67135,0,0,0,0,0,0,0,0, 66791,0,0,0,0,0,0,0,0,0,0,0,0,67134,0,0,0,0,67142,0,0,67141,0,67133,0,0,0,0,0,0,0,0, 0,0,0,0,67132,0,0,0,0,0,0,0,67131,0,0,0,0,0,0,0,0,131876,0,66775,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66779,0,0,66778,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66776,0,66785,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67130,0,0,0,0,0,0,0,0,0,0, 0,0,0,67129,0,0,0,131874,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66777,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66781,67128,0,0,0,0, 0,0,0,0,0,0,67127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67126,0,0,0,0,67125,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66774,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66772,0,0,0,0, 0,0,0,66773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67139,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,131872,0,131870,0,0,0,0,0,0,0,0,66769,0,0,0,0,0,0,0,0,0,0,0,66768,0, 0,0,0,0,131866,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66770,0,0,0,0,131864,0,0,0,0,0, 0,0,0,0,0,67124,67124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131862,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66771, 0,0,0,0,0,0,0,0,0,67123,0,0,0,0,0,0,0,131860,0,0,0,0,0,0,0,0,67122,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67121,0,66764,0,0,0,0,0,0,0,66154,0,197225, 0,0,0,66765,0,0,0,0,0,0,67120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67119, 0,0,0,0,0,66760,0,0,0,0,0,67118,0,0,0,0,0,67117,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,67116,0,0,0,0,0,0,0,0,66766,0,0,0,0,0,0,0,0,0,0,0,0,0,66767,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,67115,0,0,0,0,0,0,0, 0,0,66763,0,0,0,0,0,67114,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,67113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67112,0, 0,0,67112,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,66318,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67111,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,67110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67109,0,66761,0,0,0,0,0,0,0,0,0,0, 0,0,0,67108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,131884,0,0,66757,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131854,0,0,0,131800,0,0, 0,0,0,0,0,0,0,0,0,0,0,67107,0,0,0,0,0,0,0,67106,0,0,0,0,0,0,0,0,0,0,0,0, 66759,0,67105,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,66264,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,131852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67104,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66758,0,0,0,0,0,0,0,0,0,0,0,67103,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66754,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,67101,67102,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,67100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67099,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67098,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,67097,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67096,67095,0,0,0,0,0,0,0,0,0,0,0,0,0, 66752,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,131798,0,0,0,66747,0, 0,0,0,0,0,0,0,0,66750,0,0,0,67094,0,0,0,0,0,0,66751,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66746,0,0,0,0,0,0,66745, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67091,0,0,0,67093,0,0,0,0,67092,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,67090,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67089,0,0,0,0,0, 0,0,67088,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,66749,0,0,0,66741,0,0,0,0,0,0,0,0,66740,0,0,66748,0,0,0,0,0,0,0,0,0,0,0, 0,0,67087,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66743,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67085,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,67084,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67083,0,0,0,0, 0,0,0,0,0,0,0,67082,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,66744,0,0,0,67081,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67086,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,67080,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,66739,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131880,0, 0,0,0,0,0,66738,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,67079,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67078,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,197222,0,0,0,0,0,0,66314,0,0,0,0,67077,0,0,0,0,0,0,0,0,0,0,0,67076, 0,0,0,0,0,0,67075,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,67074,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,66735, 67072,0,66733,0,66737,66734,0,0,0,0,0,0,0,0,131850,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,67071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 67070,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66731,0,0,0,0,0,0, 0,0,0,67069,0,0,0,0,0,0,0,0,0,0,0,0,66729,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,67068,0,0,67067,0,0,0,0,0,0,0,0,0,0,0,0,0,67066,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67073,0,0,0,0,0,0,0,66730,0,0,0,0,0, 0,67065,67065,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,67064,0,0, 0,0,0,0,0,0,0,0,67063,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67062,0,0, 0,0,0,0,0,0,0,0,0,67061,0,0,0,0,0,0,0,0,0,0,66723,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66726,0,0,0,0,0,0,0,0,0,67060,0,0,67059,0,0,67058,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66722,131848,0,0,0,0,0,0,0,66728,66725,0,0,0,0,0,66727,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,66720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67057,0, 0,0,0,0,66718,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,131868,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67054,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,67056,0,0,0,0,0,0,66724,0,67055,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,66719,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67053,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66715,0,0,0,66721,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,67052,0,0,0,0,0,0,0,0,0,67051,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,66714,0,0,0,67050,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66711,0,0,0,0,0,0,0,0,0,66713,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66717,0,0,0,0,0,0,0,0,0,0, 0,67049,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131846,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,67048,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66714,0,0,0,0,0,0,0, 0,66709,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66712,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,66707,0,0,0,67047,0,0,0,131858,0,131844,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 66710,0,0,0,0,0,0,0,66708,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67046,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,197219,0,66705,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,67045,0,0,0,0,0,0,0,0,0,0,67044,0,0,67043,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67042,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197213,0,0,0,131842,0,0,0,0,0,0,0,0,0, 66703,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67041,0,0,0,0,0,0,0,0,0,0,67040,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66704,0,0,0,0,0,66706,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67039,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67038,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66693,0,0,0,0,0,66696,0,0,0,66701,67037,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67036,0,66695,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,67035,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67034,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,67033,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66690,0,0,0,0, 0,0,0,67032,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, 66689,0,0,0,0,0,0,0,0,67031,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,66699,67030,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,67029,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66694,0,0,0, 0,0,67028,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66692,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,67027,0,0,0,0,0,0,0,0,0,0,0,0,0,67026,0,0,0,0,0,0,67025,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,66687,0,0,67024,0,0, 0,0,0,0,66685,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131840,0,0,0,0,0,0,66688,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,67023,0,0,0,0,0,0,0,0,0,0,0,66681,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66682,0,0,0,0,0,0, 0,0,0,0,0,66678,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,66684,67022,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66679,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,67021,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131790,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66675,0,0,0,0,0,0,0,0,131834,0,0,0,0,0,0,0,0,0,0,67020,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66677,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66674,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66670,0,0,0,67019,0,0,0,0,0,0,0, 67019,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197210,0,0,0,131832,0,0,0,0, 0,67018,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66673,0,0,0,0,67017,0,0,66676,0,0,0,0,0,0,0,67016,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,66671,0,0,0,0, 0,0,0,0,0,67015,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66672,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,66668,0,0,0,0,0,0,67014,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,66666,0,0,0,0,0,0,0,67013, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67012,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,66664,0,0,0,131830,0,0,0,0,0,0,0,0,67011,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,66665,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67010,0,0,0,0,0,0,0,0,0,0,0, 0,0,67009,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,67008,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,67007,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,197201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66663,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,67006,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66661,0,0,0,0,0,0,0,67005,0,0,0,0, 0,0,0,0,66659,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,67004,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67003,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,67002,0,0,0,0,66658,0,66662,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67001, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66657,0,0,0,0,0,0,0,0,0,0,0,197198,66128,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,66999,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66654,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66998, 0,0,0,0,0,0,0,0,0,0,0,0,66651,66997,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,66655,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66996,0,0,0,0,66647,0,0,66653,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66995,0,0,0,0,0,0,0,0,0,66994,0, 0,197195,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66993,66645,0,0,0,0,0,0,0,0,0,0,0,0,131824,66992,0,0,0,0,0,0,0, 0,0,0,0,0,66991,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66648,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66643,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66646,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66990,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66649,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66989,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,66988,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66641,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,66642,0,0,0,0,0, 0,0,0,0,0,0,0,66987,0,0,0,131818,0,0,0,0,0,66637,0,0,0,0,0,0,0,0,0,66644,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66638,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,131788,66639,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66986,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66985,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66633,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66635,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,66984,0,0,131816,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,66983,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66982,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66977,0,0,0,0,0,0,66981,0,0,0,0,0,66980,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,66634,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,66979,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,66631,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66629,0,0,0,0,0,0, 0,0,0,0,0,66978,0,0,0,66630,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,131780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66976,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66627,0,66628,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,66624,0,0,0,0,0,0,0,0,0,0,66623,0,0,0,0, 0,0,0,0,0,0,0,0,66975,0,0,66628,0,0,0,0,0,0,0,0,0,131814,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,66974,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,66622,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, 66973,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66972,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,66626,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 66625,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66620,0,0,0, 0,0,0,0,0,0,0,0,0,0,131774,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66621,0,0,0,0,66971,0,0,0,0,0, 0,0,0,0,0,0,0,131772,0,0,0,66970,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,66969,0,0,0,0,0,0,0,0,0,0,0,0,66618,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66610,0, 0,0,0,0,0,0,66616,0,0,66615,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,66619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,66968,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66967,0,0,0, 0,0,0,0,0,0,0,0,0,66611,0,0,0,0,0,0,0,131812,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,66966,0,0,0,66609,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66612,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66965,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,66614,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,66964,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66613,0,0,66963,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,66606,0,0,0,0,0,0, 0,0,0,0,0,66605,0,0,0,0,0,0,0,0,0,0,131810,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,66604,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66962,0,0,0,0,0,0,0,0,0,0,0,0,66608,0,66607, 0,0,66602,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66598,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,131766,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66603,0,0,0,0, 0,0,0,0,0,0,0,66596,0,0,0,0,0,0,0,0,0,0,0,0,131808,0,0,0,0,0,0,0,0,0,0,0, 0,66597,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,66320,131856, 66601,0,0,0,0,0,0,0,0,0,131806,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66961,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,66599,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66960,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,66594,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,131792,0,0,0,0,66595,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66583,0,131802,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66582,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66587,0,66592,0, 0,0,0,0,0,0,0,0,66591,66590,0,0,0,0,0,0,66589,0,0,0,0,0,131794,0,0,0,0,0,0,66588,66585,0, 0,0,0,0,0,66584,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,66575, 0,0,0,0,0,0,0,0,0,0,0,0,0,66586,66586,131786,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,66579,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,66576,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66959,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66574,0,0,0, 131784,0,0,0,0,0,0,0,0,0,66958,0,0,0,0,66957,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,66577,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66578,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,66573,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66956,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 66572,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, 131760,0,0,0,0,0,66955,0,0,66954,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66570,0, 66564,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,66571,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66569,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66568,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66953,0,0,0,66566,0,0,0,0,0,0,0,0,0, 0,0,0,66952,0,0,0,66562,66951,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 66950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66563,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,66560,0,0,0,0,0,0,0,0,0,0,0,0,66559,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66567,0,0,0,0, 0,0,0,66949,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, 66557,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,66556,0, 0,0,0,0,0,0,0,66948,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197192,0,0,0,0,0,0,0,0,0,0,0, 0,0,66947,0,0,0,0,0,0,66561,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66554,0,0,0,0,0,0,0,0, 0,66558,0,0,0,66946,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66555,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66553,0,0,0,0,0,0,66551,66945,0,0,0,0,0, 0,0,0,0,0,66548,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66944,0,0,0,0,66549,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66550,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,66943,0,0,0,0,0, 0,66546,0,0,0,197189,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66547,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, 66942,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66545,66941,0,0,0,0,0,0,0,0,0,0,0,0,0,66543,0, 0,0,0,0,0,0,0,0,0,0,0,66544,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,66937,0,0,0,0,66940,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,66939,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66938,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,66538,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66540,0,0,0,0,66542,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,131838,0,0,66936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66541,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66537,0,0,0,0,0,0,0,0,0,131756,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66935,0,0,0,0,0,66934,0,0,0,0,0,0,0,0,0,0,0,66933,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66932,0,66931,0,0,0,0,0,0,0,0,0,66930,0,0, 0,0,0,0,0,131782,66929,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66928,0,0, 0,0,0,66927,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66536,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,66539,66926,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,66925,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,66924,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66923,0,0, 0,0,0,0,0,0,0,0,0,66534,66922,0,66921,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66920,0,0,0, 0,0,0,0,0,0,0,66919,0,0,0,0,0,0,0,66535,0,66533,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66531,0,0, 0,0,0,0,0,0,0,0,0,66532,0,0,0,0,0,0,0,0,0,0,0,0,0,131778,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66529,0,0,66918,0,66917,0,0,0,0,0,0,0,0,66530,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,66916,0,0,0,0,0,0,0,0,0, 0,0,0,0,66915,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,66525,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66527,0,0,0,0,0, 0,0,0,0,0,0,66524,0,0,0,0,0,0,0,0,0,0,0,66528,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,66523,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66522, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66914,0,0,0,0,0,0,0,0,0,0,0,131776,0,0,0, 0,0,0,0,0,0,0,66913,0,66912,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,66911,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,66909,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66908,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,66907,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66906,0,0,0,0,0,0,0,0,0,0,0,0,0,131770,0,0,0,0,0,0, 0,0,0,0,0,0,66905,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66518,0,0,0,0,0, 0,66904,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,66903,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,66514, 0,0,0,0,0,0,0,0,0,0,0,0,66520,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 66902,0,0,66901,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,66512,0,0,0,0,0,0,0,0,0,0,0,0,66515,0,0,0,0,0,0,0,66900,0,0,0,0,0,0,66899,0, 0,66513,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66510,0,66898,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66517,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,66519,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,66507,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66516,0,0,0,0,66511,0,0,0,0,0,0,0,0,0,0,131754,0,0,0,0,0,0,0,0,0, 66897,0,0,0,0,0,0,0,0,0,131746,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66509, 0,0,0,0,0,0,0,0,0,0,0,66508,0,0,0,0,0,0,66506,0,0,0,66504,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,131768,0,0,0,0,0,0,0,0,0,0,131750,0,0,0,0,0,131744,0, 0,131752,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131748,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,66505,0,0,0,0,0,0,0, 66502,0,0,0,0,0,0,0,0,0,131764,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,66500,0,0,0,0,0,0,0,0,0,0,0,0,66896,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66895,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,66894,66499,0,0,0,0,0,66497,0,0,0,0,0,0,0,0,0,0,66501,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,131742,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66893,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,66892,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66891,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66890,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66496,66889,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,66490,0,0,0,0,0,0,0,0,0,66888,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66492,0,0,0,66493,0,0,0,0,0,0,0,0,0,0,0,0,0,131762,0,0,66495,0,0,0,0, 0,0,66489,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66887,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66488,0,0,0,0,0,66494,0,0,0,0,0,0,0,0,0, 0,0,0,66487,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131740,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,66491,0,0,0,0,0,0,0,0,0,66485,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66481,0,0,0,0,66886,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,66480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66486,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66885,0,0,0,0,0,0,0,0,0,0,0,66483,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66884,0,0,0,0,0,0,0,0,0,66883,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66475,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66484,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,66477,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,66478,0,0,66475,0,66473,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66474,0,0,0,66882,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,66479,0,0,0,0,0,66881,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,66880,66880,0,0,0,0,0,0,0, 0,0,0,0,66470,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66472,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66879,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,66878,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66877,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,66465,0,0,0,0,0,0,0,0,0,66876,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66463,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,66457,0,66464,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66454,0,0,66461,0,0,0,66466,0,0,0, 0,0,0,0,0,0,66460,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,66459,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66462,66456,0,0,0,0,0,0,0, 0,0,0,66875,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,66458,131738,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66453,66451,0,0,0,0,0,0,0,0, 0,0,0,66874,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66450,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66452,0,0,0,0,0,0,0,0,0,0,0,0,0,131736,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66455,0,0,0,0, 66873,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,131734, 0,0,0,0,0,0,0,0,0,0,0,197207,0,0,0,0,0,0,0,0,0,0,0,0,66449,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66872,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131732,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66448,0, 0,0,66871,0,0,0,0,0,0,0,0,0,0,0,0,66447,0,0,0,0,0,0,0,0,0,0,0,0,66446,0,0,0, 0,0,0,0,0,0,0,0,66445,66870,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,66869,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,66868,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66444,0,0,0,0,0,0,0,0,0,0,0,0,66867,0, 0,0,0,0,0,0,0,0,0,0,66443,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131758,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,66441,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 66866,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66440,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66865,0,0, 0,0,0,0,0,0,0,66864,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66439,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66435,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66434,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66432, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66433,0,0,0,0,0,0,0,66437, 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,66863,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66431,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66862,0,0,0,0,66861,0, 0,0,0,0,0,66860,0,0,0,0,0,0,0,0,0,66859,0,0,0,0,0,0,66858,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66857,0,0,0,0, 0,0,0,66438,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,66430,66436,0,0,0,0,0,0,0,0,0,0,0,0,0,197186,0,0,0, 0,0,0,0,0,0,0,0,0,131692,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65888,0,0,0,0,0,0,0,66374,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,65935,0,65935,0,0,0,0, 0,0,0,0,0,65755,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65930,65930,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,65935,0,65935,0,0,0,0,0,0,65933,0,0,0,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,197156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197144,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,65933,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262582,0, 0,131512,65894,0,0,0,0,0,0,65779,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,65755,0,0,0,65935,0,65935,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65977,65977,0,0,0,0,0,0,328079, 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,65936,65936,131506,131506,0,0,0, 0,0,66856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66853,0,0,0, 0,0,0,0,0,66854,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66850,0,0,0,0,0, 0,0,0,0,66851,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66849,0, 0,0,0,0,0,0,0,0,0,0,0,0,66848,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,66847,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,66846,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66845,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66844,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,66843,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66842,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66841,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,66840,0,66840,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,66838,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,66839, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131804,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66837,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,66364,0,0,0,0,0,66363,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,66836,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66835,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66834,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66830,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66833, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66832,0,0,0,0,0,0,0,0,66831,0,0,0, 0,0,0,66829,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66362,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,66828,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,66827,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,66826,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,66825,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66824,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66823,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66822,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66820,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66819,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66818,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,66817,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66361,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,66816,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,66815,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66814,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,66813,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66812,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,66811,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,66796,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66795,0,0,0,0,0,0,0, 0,0,0,0,66792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66787,66786,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66784,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,66783,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,66360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66762,0,0, 0,0,0,0,0,0,66756,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66755,0,0,0,0,0, 0,0,0,0,0,66753,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66742,0,0,0, 0,0,0,0,0,0,0,131796,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66736,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 66732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66359,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66716,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66698,0,0,0,0,0, 0,0,0,0,0,0,0,0,66702,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,66700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66697,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66691,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,66686,0,0,0,0,0, 0,0,0,66683,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66680,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,66669,0,0,0,0,0,0,0,0,0,0,0,0,0,66667,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66660,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,66656,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,66652,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,66650,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,66640,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66636,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66632,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66617,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,66600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66593,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66581,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,66565,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66358,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,66552,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66528,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,66526,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66521,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66503,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,66498,0,0,0,0,0,0,0,0, 0,0,0,0,0,66482,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66471, 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,66476,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,66469,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66468,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,66467,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,66442,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,66429,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,66428,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,66427,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66426,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66425,0,0,0,0,0,0,0,0,0,0,0,0,0, 66424,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, }; KBTS_INLINE kbts_u32 kbts_GetUnicodeParentInfo(kbts_u32 Codepoint) { return kbts_UnicodeParentInfo_Data[((kbts_un)kbts_UnicodeParentInfo_PageIndices[Codepoint/32] * 32) | (Codepoint & 31)]; } static kbts_u8 kbts_UnicodeUseClass_PageIndices[4351] = { 0,1,1,1,1,1,2,3,4,5,6,7,8,9,10,11,12,1,1,1,1,1,1,13,14,15,16,17,18,19,1,1, 20,1,1,1,1,21,1,22,1,1,1,1,1,23,24,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,25,26,27,28,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,29,1,1,1,1,30,31,1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,1,46,47,48,49, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,50,50,50,50,51,50,50,50,50,50,50,50,50,50,50,50, 50,50,50,52,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,53,1,1,1,1,1,1,1,1,54,55,1,56,1,57,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,58,59,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,60,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,61,62,1,63,64,1,1,1,65,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, }; static kbts_u8 kbts_UnicodeUseClass_Data[16896] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,21,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,19,0,21,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,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,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,29,29,29,29,29,29,29,29,0,0,0,0,0,0,1,0,0,29,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,0,0,0,0,1,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,36,9,1,36,33, 36,35,35,35,35,34,34,34,34,36,36,36,36,3,33,36,0,29,30,0,0,34,35,35,1,1,1,1,1,1,1,1,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,29,31,31,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,1,0,0,9,1,36,33, 36,35,35,35,35,0,0,33,33,0,0,33,33,3,0,0,0,0,0,0,0,0,0,36,0,0,0,0,1,1,0,1,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,6,0, 0,29,29,31,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,0,9,0,36,33, 36,35,35,0,0,0,0,34,34,0,0,34,34,3,0,0,0,30,0,0,0,0,0,0,0,1,1,1,1,0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,29,8,2,2,0,12,0,0,0,0,0,0,0,0,0,0, 0,29,29,31,0,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0,9,1,36,33, 36,35,35,35,35,34,0,34,34,34,0,36,36,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,29,8,29,8,8,8, 0,29,31,31,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0,9,1,36,34, 36,35,35,35,35,0,0,33,33,0,0,33,33,3,0,0,0,0,0,0,0,34,34,34,0,0,0,0,1,1,0,1,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,29,0,0,1,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,36,36, 34,36,36,0,0,0,33,33,33,0,33,33,33,3,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,31,31,31,29,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,9,1,34,34, 34,36,36,36,36,0,34,34,34,0,34,34,34,3,0,0,0,0,0,0,0,34,35,0,1,1,1,0,0,0,0,0,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,29,31,31,0,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,9,1,36,34, 34,36,36,36,36,0,34,34,34,0,34,34,34,3,0,0,0,0,0,0,0,36,36,0,0,0,0,0,0,0,1,0,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,37,37,31,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,31,31,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,1,36,36, 36,35,35,35,35,0,33,33,33,0,33,33,33,3,38,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,1,1,1,35,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,29,31,31,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,0,0, 1,1,1,1,1,1,1,0,0,0,4,0,0,0,0,36,36,36,34,34,35,0,35,0,36,33,33,33,33,33,33,36,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,36,36,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,34,1,1,34,34,34,34,35,35,35,0,0,0,0,0, 1,1,1,1,1,1,0,34,29,29,29,29,8,29,34,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,0,1,34,1,1,34,34,34,34,35,35,35,34,12,1,0,0, 1,1,1,1,1,0,0,0,29,29,29,29,0,29,6,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,6,0,6,0,8,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,9,35,34,34,35,34,34,34,34,35,35,35,35,29,0, 35,34,29,29,35,0,29,29,1,1,1,1,1,7,7,7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0, 0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,34,34,35,35,33,34,34,34,34,29,30,31,6,34,13,10,12,12,1, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,36,36,35,35,1,1,1,1,12,12,12,1,36,31,31,1,1,36,36,31,31,31,31,31,1,1,1,34,34,34,34,1,1,1,1,1,1,1,1,1,1,1, 1,1,12,36,33,34,34,31,31,31,31,31,31,30,1,31,1,1,1,1,1,1,1,1,1,1,31,31,36,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,35,35,36,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,35,36,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,35,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,34,35,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,36,34,34,34,34,35,35,35,33,33, 33,33,33,33,33,33,29,31,36,29,29,6,14,8,6,29,6,34,6,6,0,0,0,0,0,0,0,0,1,6,0,0,1,1,1,1,1,1,1,1,1,1,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,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, 2,2,2,2,2,8,8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,34,34,35,36,36,34,34,34,34,7,7,7,0,0,0,0,16,16,30,16,16,16,16,16,16,15,29,6,0,0,0,0, 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,31,31,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,33,36,34,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10,12,7,14,14,11,7,7,7,7,0,5,36,34,36,36,34,34,34,34,35,35,34,35,36,33,33,33,33,33,34,29,29,29,29,29,29,34,29,29,0,0,30, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,14,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,8,36,34,34,35,35,35,35,34,34,33,33, 33,33,34,34,3,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,14,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,7,7,34,35,33,36,34,34,36,6,7,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,8,36,34,34,36,36,36,34,36,34,14,14,17,17,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,7,36,33,33,33,36,36,35,14,14,14,14,14,14,14,32,32,0,9,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,29,29,0,30,30,30,30,30,30,29,29,30,30,30,30,29,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,37,37,31,29,29,2,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,39,1,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0, 0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,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,19,21,19,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,21,19,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,34,1,1,1,3,1,1,1,1,29,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,35,34,36,0,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 31,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,36,36,36,36,36,36,36,36,36,36,36, 36,36,36,36,3,29,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,1,1,0,0,0,0,0,0,0,0,0,0,1,34, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,34,30,30,30,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,35,35,35,34,35,35,35,35,14,14,14,16,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,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,14,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,8,36,36,34,34,35,35,33,33,34,12,13,12, 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,34,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,34,34,34,35,34,33,33,34,35,13,10,11,12,0,0,0,0,0,0,0,0,0, 1,1,1,14,1,1,1,1,1,1,1,1,14,16,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,2,2,2,0,0,0,1,31,29,31,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,35,1,35,35,34,1,1,35,35,1,1,1,1,1,35,29, 1,29,1,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,1,1,1,1,1,1,1,1,1,1,33,35,34,33,36,0,0,0,0,0,31,6,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,34,36,36,35,36,36,0,31,35,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,35,35,35,0,34,35,0,0,0,0,0,36,30,30,29,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,9,9,9,0,0,0,0,6, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,29,29,8,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,34,34,34,34,34,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,34,34,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,30,30,30,30,30,30,30,30,30,30,30,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1, 0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 31,29,31,37,37,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,35,35,35,35, 35,35,34,34,34,34,3,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,1,1,1,1,1,1,1,1,1,1,34,1,1,34,34,1,0,0,0,0,0,0,0,0,0,40, 29,29,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,34,34,36,36,3,9,0,0,0,0,0, 0,0,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,29,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,35,35,35,34,34,33,35,34,34,35,34,34,6,8,0,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,1,36,36,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,0,0,0,0,0,0,0,0,0,0,0,0, 29,29,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,35,35,34,34,34,34, 3,1,38,38,0,0,0,0,0,6,9,34,35,0,33,29,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,36,35,34,34,34,34,29,3,8,8,0,0,0,0,0,0,29,1, 1,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,36,33,36,35,35,34,34,34,34,9,35,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 29,29,31,31,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,9,9,1,36,36, 34,36,36,36,36,0,0,33,33,0,0,33,33,3,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,1,1,1,1,36,36,0,0,29,29,29,29,29,29,29,0,0,0,29,29,29,29,29,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,36,34,34,35,35,35,35,35, 35,0,33,0,0,33,0,33,33,36,31,0,31,31,29,9,6,38,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,30,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,35,35,34,34, 36,36,3,29,29,31,9,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,6,1,37,37,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,35,35,33,34,33,33,36,33,29, 29,31,3,9,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,0,0,33,33,33,33,29,29,31,3, 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,35,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,36,35,35,35,35,35,35,34,34,36,36,29,31,3, 34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,31,34,33,36,35,35,34,34,34,34,3,9,1,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,12,3,11,36,36,34,34,35,35,33,34,35,34,34,34,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,34,34,34,34,29,31,3,9,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,36,36,36,33,0,33,33,0,0,29,29,36,6,38, 13,38,13,9,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,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,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,33,36,35,35,35,35,0,0,34,34,36,36,31,31,3,1,0,0,33,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,34,35,35,34,34,34,34,34,34,35,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,6,35,29,29,29,29,31,37,7,7,7,7,0, 0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,1,34,35,35,34,34,34,36,36,35,35,35,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,38,38,38,38,38,38,15,15,15,15,15,15,15,15,15,15,15,15,29,31,8,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,34,34,35,35,35,35,35,0,34,34,34,34,29,29,31,3, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,35,33,35,34,36,29,29,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,34,35,0,0,0,34,0,34,34,0,34, 29,29,9,34,35,6,38,12,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,36,36,36,36,36,0,34,34,0,36,36,29,31,6,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,34,35,33,36,0,0,0,0,0,0,0,0,0, 29,29,38,31,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,34,34,35,35,35,0,0,0,33,33, 34,36,6,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,22,22,22,22,22,22,22,19,21,22,22,22,18,18,18,18, 23,18,18,18,18,18,18,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,34,34,34,34,34,34,34,34,10,10,13,29,12,35,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,29,29,29,29,29,29,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,31,31,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,36,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,9,0,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, 35,35,35,35,35,35,35,35,0,0,0,0,0,0,0,30,30,30,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,29,29,29,29,29,29,29,1,1,1,1,1,1,1,0,0, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,29,29,29,29,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,34,34,34,34,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,35,35,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,8,8,8,8,8,8,8,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; KBTS_INLINE kbts_u8 kbts_GetUnicodeUseClass(kbts_u32 Codepoint) { return kbts_UnicodeUseClass_Data[((kbts_un)kbts_UnicodeUseClass_PageIndices[Codepoint/256] * 256) | (Codepoint & 255)]; } KBTS_INLINE kbts_u32 kbts_GetDecompositionSize(kbts_u64 Decomposition) { return Decomposition & 3; } KBTS_INLINE kbts_u32 kbts_GetDecompositionCodepoint(kbts_u64 Decomposition, kbts_un Index){ return (Decomposition >> (Index ? 23 : 2)) & 0x1FFFFF; } #define KBTS_UNICODE_DECOMPOSITION_DO_NOT_RECURSE0 (1ull << 44) #define KBTS_UNICODE_DECOMPOSITION_DO_NOT_RECURSE1 (1ull << 45) KBTS_INLINE kbts_u32 kbts_GetMatchingBracket(kbts_u64 Decomposition) { return (Decomposition >> 23) & 0x1FFFFF; } KBTS_INLINE kbts_u32 kbts_GetUnicodeMatchingBracket(kbts_u32 Codepoint) { kbts_u64 Decomposition = kbts_GetUnicodeDecomposition(Codepoint); return (Decomposition >> 23) & 0x1FFFFF; } KBTS_INLINE kbts_u8 kbts_GetSyllabicClass(kbts_u16 SyllabicInfo) { return SyllabicInfo & 0xFF; } KBTS_INLINE kbts_u8 kbts_GetSyllabicPosition(kbts_u16 SyllabicInfo) { return SyllabicInfo >> 8; } KBTS_INLINE kbts_s32 *kbts_GetParentInfoDeltas(kbts_u32 ParentInfo) { return kbts_UnicodeParentDeltas + (ParentInfo & 0xFFFF); } KBTS_INLINE kbts_un kbts_GetParentInfoCount(kbts_u32 ParentInfo) { return ParentInfo >> 16; } typedef kbts_u8 kbts_grapheme_break_class; enum kbts_grapheme_break_class_enum { /* 0 */ KBTS_GRAPHEME_BREAK_CLASS_DEFAULT, /* 1 */ KBTS_GRAPHEME_BREAK_CLASS_CR, /* 2 */ KBTS_GRAPHEME_BREAK_CLASS_LF, /* 3 */ KBTS_GRAPHEME_BREAK_CLASS_Control, /* 4 */ KBTS_GRAPHEME_BREAK_CLASS_Extend, /* 5 */ KBTS_GRAPHEME_BREAK_CLASS_ZWJ, /* 6 */ KBTS_GRAPHEME_BREAK_CLASS_SpacingMark, /* 7 */ KBTS_GRAPHEME_BREAK_CLASS_L, /* 8 */ KBTS_GRAPHEME_BREAK_CLASS_V, /* 9 */ KBTS_GRAPHEME_BREAK_CLASS_LV, /* 10 */ KBTS_GRAPHEME_BREAK_CLASS_LVT, /* 11 */ KBTS_GRAPHEME_BREAK_CLASS_T, /* 12 */ KBTS_GRAPHEME_BREAK_CLASS_Prepend, /* 13 */ KBTS_GRAPHEME_BREAK_CLASS_IndicConsonant, /* 14 */ KBTS_GRAPHEME_BREAK_CLASS_IndicExtend, /* 15 */ KBTS_GRAPHEME_BREAK_CLASS_IndicLinker, /* 16 */ KBTS_GRAPHEME_BREAK_CLASS_ExtendedPictographic, /* 17 */ KBTS_GRAPHEME_BREAK_CLASS_RI, KBTS_GRAPHEME_BREAK_CLASS_COUNT, }; typedef kbts_u8 kbts_grapheme_break_state; enum kbts_grapheme_break_state_enum { /* 0 */ KBTS_GRAPHEME_BREAK_STATE_START, /* 1 */ KBTS_GRAPHEME_BREAK_STATE_CR, /* 2 */ KBTS_GRAPHEME_BREAK_STATE_L, /* 3 */ KBTS_GRAPHEME_BREAK_STATE_LVxV, /* 4 */ KBTS_GRAPHEME_BREAK_STATE_LVTxT, /* 5 */ KBTS_GRAPHEME_BREAK_STATE_IndicConsonantxIndicLinker, /* 6 */ KBTS_GRAPHEME_BREAK_STATE_IndicExtendr, /* 7 */ KBTS_GRAPHEME_BREAK_STATE_IndicExtendLinkerr, /* 8 */ KBTS_GRAPHEME_BREAK_STATE_ExtendedPictographic, /* 9 */ KBTS_GRAPHEME_BREAK_STATE_ExtendR, /* 10 */ KBTS_GRAPHEME_BREAK_STATE_ExtendR_ZWJ, /* 11 */ KBTS_GRAPHEME_BREAK_STATE_RI, /* 12 */ KBTS_GRAPHEME_BREAK_STATE_SKIP, /* 13 */ KBTS_GRAPHEME_BREAK_STATE_COUNT, /* 14 */ KBTS_GRAPHEME_BREAK_STATE_b0, /* 15 */ KBTS_GRAPHEME_BREAK_STATE_b01, // The values below have to be in the same order as their corresponding states. /* 16 */ KBTS_GRAPHEME_BREAK_STATE_b1, /* 17 */ KBTS_GRAPHEME_BREAK_STATE_b1toCR, /* 18 */ KBTS_GRAPHEME_BREAK_STATE_b1toL, /* 19 */ KBTS_GRAPHEME_BREAK_STATE_b1toLVxV, /* 20 */ KBTS_GRAPHEME_BREAK_STATE_b1toLVTxT, /* 21 */ KBTS_GRAPHEME_BREAK_STATE_b1toIndicConsonantxIndicLinker, /* 22 */ KBTS_GRAPHEME_BREAK_STATE_PADDING0, /* 23 */ KBTS_GRAPHEME_BREAK_STATE_PADDING1, /* 24 */ KBTS_GRAPHEME_BREAK_STATE_b1toExtendedPictographic, /* 25 */ KBTS_GRAPHEME_BREAK_STATE_PADDING2, /* 26 */ KBTS_GRAPHEME_BREAK_STATE_PADDING3, /* 27 */ KBTS_GRAPHEME_BREAK_STATE_b1toRI, /* 28 */ KBTS_GRAPHEME_BREAK_STATE_b1toSKIP, }; // In the SKIP column, CR, LF and Control all still break before the cursor // because their rules have a higher priority. // In Indic-related states, ZWJ should behave like an Indic Extend. static kbts_grapheme_break_state kbts_GraphemeBreakTransition[KBTS_GRAPHEME_BREAK_CLASS_COUNT][KBTS_GRAPHEME_BREAK_STATE_COUNT] = { /* 0 1 2 3 4 5 6 7 8 9 10 11 12 */ /* 0 */ {16,16,16,16,16,16,16,16,16,16,16,16, 0}, /* 1 */ {17,17,17,17,17,17,17,17,17,17,17,17,17}, /* 2 */ {15,14,15,15,15,15,15,15,15,15,15,15,15}, /* 3 */ {15,15,15,15,15,15,15,15,15,15,15,15,15}, /* 4 */ { 0,16, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0}, /* 5 */ { 0,16, 0, 0, 0, 6, 6, 7,10,10, 0, 0, 0}, /* 6 */ { 0,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 7 */ {18,18, 2,18,18,18,18,16,18,18,18,18, 2}, /* 8 */ {19,19, 3, 3,19,19,19,16,19,19,19,19, 3}, /* 9 */ {19,19, 3,19,19,19,19,16,19,19,19,19, 3}, /* 10 */ {20,20, 4,20,20,20,20,16,20,20,20,20, 4}, /* 11 */ {20,20,20, 4, 4,20,20,16,20,20,20,20, 4}, /* 12 */ {28,28,28,28,28,28,28,28,28,28,28,28,12}, /* 13 */ {21,21,21,21,21,21,21, 5,21,21,21,21, 5}, /* 14 */ { 0,16, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0}, /* 15 */ { 5,21, 5, 5, 5, 7, 7, 7, 5, 5, 5, 5, 5}, /* 16 */ {24,24,24,24,24,24,24,16,24,24, 0,24, 8}, /* 17 */ {27,27,27,27,27,27,27,27,27,27,27, 0,11}, }; // These classes are for Indic, Myanmar and Khmer. typedef kbts_u8 kbts_indic_syllabic_class; enum kbts_indic_syllabic_class_enum { /* 0 A */ KBTS_INDIC_SYLLABIC_CLASS_OTHER, /* 1 B */ KBTS_INDIC_SYLLABIC_CLASS_CONSONANT, /* 2 C */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL, /* 3 D */ KBTS_INDIC_SYLLABIC_CLASS_NUKTA, /* 4 E */ KBTS_INDIC_SYLLABIC_CLASS_HALANT, /* 5 F */ KBTS_INDIC_SYLLABIC_CLASS_ZWNJ, /* 6 G */ KBTS_INDIC_SYLLABIC_CLASS_ZWJ, /* 7 H */ KBTS_INDIC_SYLLABIC_CLASS_MATRA, /* 8 I */ KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MODIFIER, /* 9 J */ KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN, /* 10 K */ KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER, /* 11 L */ KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE, /* 12 M */ KBTS_INDIC_SYLLABIC_CLASS_REGISTER_SHIFTER, /* 13 N */ KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST, /* 14 O */ KBTS_INDIC_SYLLABIC_CLASS_REPHA, /* 15 P */ KBTS_INDIC_SYLLABIC_CLASS_RA, /* 16 Q */ KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL, /* 17 R */ KBTS_INDIC_SYLLABIC_CLASS_SYMBOL, /* 18 S */ KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER, /* 19 T */ KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MODIFIER_POST, /* 20 U */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL_ABOVE, /* 21 V */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL_BELOW, /* 22 W */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL_PRE, /* 23 X */ KBTS_INDIC_SYLLABIC_CLASS_VOWEL_POST, /* 24 Y */ KBTS_INDIC_SYLLABIC_CLASS_ROBATIC, /* 25 Z */ KBTS_INDIC_SYLLABIC_CLASS_X_GROUP, /* 26 a */ KBTS_INDIC_SYLLABIC_CLASS_Y_GROUP, /* 27 b */ KBTS_INDIC_SYLLABIC_CLASS_ASAT, /* 28 c */ KBTS_INDIC_SYLLABIC_CLASS_DOT_BELOW, /* 29 d */ KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MOD, /* 30 e */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_HA, /* 31 f */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_RA, /* 32 g */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_WA, /* 33 h */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_YA, /* 34 i */ KBTS_INDIC_SYLLABIC_CLASS_PWO, /* 35 j */ KBTS_INDIC_SYLLABIC_CLASS_VARIATION_SELECTOR, /* 36 k */ KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_MON_LA, KBTS_MYANMAR_SYLLABIC_CLASS_COUNT, KBTS_INDIC_SYLLABIC_CLASS_COUNT = KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MODIFIER_POST + 1, KBTS_KHMER_SYLLABIC_CLASS_COUNT = KBTS_INDIC_SYLLABIC_CLASS_Y_GROUP + 1, }; #define KBTS_INDIC_SYLLABIC_STATE_COUNT 41 #define KBTS_MYANMAR_SYLLABIC_STATE_COUNT 31 #define KBTS_KHMER_SYLLABIC_STATE_COUNT 23 // @Incomplete: Decrement every state by 1. static kbts_u8 kbts_IndicSyllabicTransition[KBTS_INDIC_SYLLABIC_CLASS_COUNT][KBTS_INDIC_SYLLABIC_STATE_COUNT] = { /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 */ /* A */ {43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,}, /* B */ {14,43,43,43,43,43,43,14,43,43,43,43,43,43,43,14,43,14,43,43,43,43,43,43,43,14,43,43,43,43,43,43,14,43,43,14,43,43,14,43,14,}, /* C */ {30,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,30,43,43,43,43,43,43,43,43,43,43,43,43,30,43,43,}, /* D */ {24,43,24,20,43,43,31,43,43,43, 7,43,43,24,43,33,43,43,43,43,43,43,43,12,43,24,43,43,43, 7,43,24,43,43,43,33,15,43,24,24,43,}, /* E */ { 8,43, 8,21,27,43, 8,43,18,18, 8, 8,18, 8,43,43,43,43,43,21,43,43,43, 8,18, 8,43,38,43, 8, 8, 8,43,43,18,18,43,43, 8,26,43,}, /* F */ {25,43,13,22,28, 2,13,15,19,19,13,13,19,25,29,29, 2,29,19,22,22,19, 2,13,19,35,15,19,43, 9,13,25,29,43,22,22,29,29,25,25,43,}, /* G */ {13,43,13,22,28,43,10,16,19,19,10,13,19,32,29,29,43,16,19,22,22,19,43,13,19,36,37,19,43,10,10,13,29,43,22,22,29,37,13,32,43,}, /* H */ { 4,43, 4, 4, 4,43, 4,43, 4, 4, 4, 4, 4, 4,43,43,43,43, 4, 4, 4, 4,43, 4, 4, 4,43, 4,43, 4, 4, 4,43,43, 4, 4,43,43, 4, 4,43,}, /* I */ { 6,43, 6, 6, 6,23, 6,17, 6, 6, 6, 6, 6, 6,17,17,23,17,34, 6, 6, 6,43, 6, 6, 6,17, 6,17, 6, 6, 6,17,43, 6, 6,17,17, 6, 6,43,}, /* J */ { 2, 2, 2, 2, 2, 2, 2, 2,43,43, 2, 2,43, 2, 2, 2, 2, 2,43, 2, 2,43, 2, 2,43, 2, 2,43,43, 2, 2, 2, 2,43, 2, 2, 2, 2, 2, 2,43,}, /* K */ {32,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,32,43,32,}, /* L */ {32,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,32,43,43,43,43,43,43,43,43,43,43,43,43,32,43,43,}, /* M */ { 3,43,43,43,43,43,43,43,11,43,43,43,43, 3,43,43,43,43,43,43,43,43,43,43, 3, 3,43,43,43,11,43, 3,43,43, 3,43,43,43, 3, 3,43,}, /* N */ { 4,43, 4, 4, 4, 4, 4,43, 4, 4, 4, 4, 4, 4,43,43,43,43, 4, 4, 4, 4,43, 4, 4, 4,43, 4,43, 4, 4, 4,43, 4, 4, 4,43,43, 4, 4,43,}, /* O */ {39,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,}, /* P */ {40,43,43,43,43,43,43,14,43,43,43,43,43,43,43,14,43,14,43,43,43,43,43,43,43,14,43,43,43,43,43,43,14,43,43,14,43,43,14,43,14,}, /* Q */ { 5,43, 5,43,43,43, 5,43,43,43, 5, 5,43, 5,43,43,43,43,43,43,43,43,43, 5,43, 5,43,43,43, 5, 5, 5,43,43,43,43,43,43, 5, 5,43,}, /* R */ {37,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,}, /* S */ {41,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,}, /* T */ { 6,43, 6, 6, 6,23, 6,17, 6, 6, 6, 6, 6, 6,17,17,23,17,34, 6, 6, 6,43, 6, 6, 6,17, 6,17, 6, 6, 6,17,43, 6, 6,17,17, 6, 6,43,}, }; // @Incomplete: Decrement every state by 1. static kbts_u8 kbts_MyanmarSyllabicTransition[KBTS_MYANMAR_SYLLABIC_CLASS_COUNT][KBTS_MYANMAR_SYLLABIC_STATE_COUNT] = { /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 */ /* A */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* B */ {18,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,18,33,33,33,33,33,33,33,33,18,18,33,18,}, /* C */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* D */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* E */ {19,33,33,33,33,33,33,33,33,33,33,33,33,33,33,28,33,28,19,29,33,33,33,33,33,33,33,18,19,28,18,}, /* F */ { 2,33, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,33, 2, 2,33,}, /* G */ { 2,33, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,33, 2, 2,33,}, /* H */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* I */ { 3,33, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,33, 3, 3,33,}, /* J */ { 4,33,33, 4, 4, 4, 4, 4, 4,33, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4, 4, 4, 4,33, 4,33,33, 4, 4, 4,}, /* K */ {18,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,18,33,18,}, /* L */ {18,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,18,33,18,}, /* M */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* N */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* O */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* P */ {30,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,18,33,33,33,33,33,33,33,33,18,18,33,18,}, /* Q */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* R */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* S */ {31,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* T */ { 3,33, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,33, 3, 3,33,}, /* U */ { 5,33,33,33, 5,33, 5,22, 5,33, 5, 5, 5, 5,33, 5, 5, 5, 5, 5, 5,22,22,22,33, 5,33,33, 5, 5,33,}, /* V */ { 6,33,33,33, 6, 6, 6,33, 6,33, 6, 6, 6, 6,33, 6, 6, 6, 6, 6, 6,33,33,33,33, 6,33,33, 6, 6,33,}, /* W */ { 7,33,33,33,33,33, 7,33, 7,33, 7, 7, 7, 7,33, 7, 7, 7, 7, 7, 7,33,33,33,33, 7,33,33, 7, 7,33,}, /* X */ { 8,33,33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,33,33, 8, 8,33,}, /* Y */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* Z */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* a */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* b */ { 9,33,33,33,33,33,33,23, 9,25,21,33,21,26, 3, 9,21, 9, 9, 9,33,33,23,23,33,33, 3,33, 9,20,33,}, /* c */ {10,33,33,10,10,10,10,10,10,33,10,10,10,10,27,10,10,10,10,10,10,10,10,10,33,10,33,33,10,10,33,}, /* d */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,}, /* e */ {11,33,33,33,33,33,33,24,11,33,33,11,11,11,33,11,33,11,11,11,33,33,33,33,33,11,33,33,11,11,33,}, /* f */ {12,33,33,33,33,33,33,33,12,33,33,33,33,12,33,12,33,12,12,12,33,33,33,33,33,12,33,33,12,12,33,}, /* g */ {13,33,33,33,33,33,33,33,13,33,33,13,33,13,33,13,33,13,13,13,33,33,33,33,33,13,33,33,13,13,33,}, /* h */ {14,33,33,33,33,33,33,33,14,33,33,33,33,33,33,14,33,14,14,14,33,33,33,33,33,33,33,33,14,14,33,}, /* i */ {15,33,15,15,15,15,15,15,15,15,15,15,15,15,33,15,15,15,15,15,15,15,15,15,15,15,15,33,15,15,33,}, /* j */ {16,33,33,33,33,33,21,33,33,33,33,33,33,33,33,33,33,16,16,33,33,33,33,33,33,33,33,33,16,16,33,}, /* k */ {17,33,33,33,33,33,33,23,17,33,17,17,17,17,33,17,33,17,17,17,33,33,33,23,33,17,33,33,17,17,33,}, }; // @Incomplete: Decrement every state by 1. static kbts_u8 kbts_KhmerSyllabicTransition[KBTS_KHMER_SYLLABIC_CLASS_COUNT][KBTS_KHMER_SYLLABIC_STATE_COUNT] = { /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 */ /* A */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* B */ {15,25,25,25,25,18,25,25,25,25,25,25,25,25,25,25,25,25,25,25, 2,25,25,}, /* C */ {15,25,25,25,25,18,25,25,25,25,25,25,25,25,25,25,25,25,25,25, 2,25,25,}, /* D */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* E */ {21,21,25,25,21,25,25, 6,25, 6,25, 6,25, 6,21,21,25,25,25,25,25, 6,25,}, /* F */ { 4,17, 3, 3, 4,25, 7, 7,19, 9,20,11,13,13,23, 4, 3,25,19,20,25, 4, 3,}, /* G */ { 4,17, 3, 3, 4,25, 7, 7,19, 9,20,11,13,13,23, 4, 3,25,19,20,25, 4, 3,}, /* H */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* I */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* J */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* K */ {16,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* L */ {16,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* M */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* N */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* O */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* P */ {15,25,25,25,25,18,25,25,25,25,25,25,25,25,25,25,25,25,25,25, 2,25,25,}, /* Q */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* R */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* S */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* T */ {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,}, /* U */ { 8, 8,25, 8, 8,25,25,25, 8, 8, 8, 8,25,25, 8, 8, 8,25,25,25,25, 8, 8,}, /* V */ {10,10,25,25,10,25,25,25,25,25,25,10,25,25,10,10,25,25,25,25,25,10,25,}, /* W */ {12,12,25,25,12,25,25,25,25,25,25,25,25,25,12,12,25,25,25,25,25,12,25,}, /* X */ {14,14,25,25,14,25,25,14,25,14,25,14,25,25,14,14,25,25,25,25,25,14,25,}, /* Y */ { 5, 5,25,25,25,25,25,25,25,25,25,25,25,25,16, 5, 5,25,25,25,25,25,16,}, /* Z */ {22,22,22,22,22,25, 8, 8,10,10,12,12,14,14,22,22,22,25,10,12,25,22,22,}, /* a */ {18,18,25,25,18,25,25,18,25,18,25,18,25,18,18,18,25,18,25,25,25,18,25,}, }; typedef kbts_u8 kbts_use_syllabic_class; enum kbts_use_syllabic_class_enum { /* 0 */ KBTS_USE_SYLLABIC_CLASS_OTHER, /* 1 */ KBTS_USE_SYLLABIC_CLASS_BASE, /* 2 */ KBTS_USE_SYLLABIC_CLASS_BASE_OTHER, /* 3 */ KBTS_USE_SYLLABIC_CLASS_HALANT, /* 4 */ KBTS_USE_SYLLABIC_CLASS_HALANT_OR_VOWEL_MODIFIER, /* 5 */ KBTS_USE_SYLLABIC_CLASS_SAKOT, /* 6 */ KBTS_USE_SYLLABIC_CLASS_INVISIBLE_STACKER, /* 7 */ KBTS_USE_SYLLABIC_CLASS_CONS_SUB, /* 8 */ KBTS_USE_SYLLABIC_CLASS_CONS_MOD_ABOVE, /* 9 */ KBTS_USE_SYLLABIC_CLASS_CONS_MOD_BELOW, /* 10 */ KBTS_USE_SYLLABIC_CLASS_CONS_MED_PRE, /* 11 */ KBTS_USE_SYLLABIC_CLASS_CONS_MED_ABOVE, /* 12 */ KBTS_USE_SYLLABIC_CLASS_CONS_MED_BELOW, /* 13 */ KBTS_USE_SYLLABIC_CLASS_CONS_MED_POST, /* 14 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_ABOVE, /* 15 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_BELOW, /* 16 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_POST, /* 17 */ KBTS_USE_SYLLABIC_CLASS_REORDERING_KILLER, /* 18 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH, /* 19 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_SEGMENT_BEGIN, /* 20 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_MOD, /* 21 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_SEGMENT_END, /* 22 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_JOINER, /* 23 */ KBTS_USE_SYLLABIC_CLASS_HIEROGLYPH_MIRROR, /* 24 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_ABOVE, /* 25 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_BELOW, /* 26 */ KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_POST, /* 27 */ KBTS_USE_SYLLABIC_CLASS_SYMBOL_MOD_ABOVE, /* 28 */ KBTS_USE_SYLLABIC_CLASS_SYMBOL_MOD_BELOW, /* 29 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_ABOVE, /* 30 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_BELOW, /* 31 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_POST, /* 32 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_PRE, /* 33 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_PRE, /* 34 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_ABOVE, /* 35 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_BELOW, /* 36 */ KBTS_USE_SYLLABIC_CLASS_VOWEL_POST, /* 37 */ KBTS_USE_SYLLABIC_CLASS_CONSONANT_WITH_STACKER, /* 38 */ KBTS_USE_SYLLABIC_CLASS_REPHA, /* 39 */ KBTS_USE_SYLLABIC_CLASS_ZWNJ, /* 40 */ KBTS_USE_SYLLABIC_CLASS_HALANT_NUM, /* 41 */ KBTS_USE_SYLLABIC_CLASS_BASE_NUM, KBTS_USE_SYLLABIC_CLASS_COUNT, }; enum { KBTS_USE_STATE_s0 = 42, }; // @Incomplete: Decrement every state by 1. static kbts_u8 kbts_UseTransition[KBTS_USE_SYLLABIC_CLASS_COUNT][KBTS_USE_STATE_s0] = { /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 */ /* A */ {24,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,}, /* B */ {15,44,44,44,44,44,44,44,44,15,15,44,44,15,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,37,44,37,44,44,44,44,44,44,44,44,44,44,}, /* C */ {24,44,44,44,44,44,44,44,44,15,15,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,}, /* D */ {14,44,44,44,44,44,44,44,44,44,14,44,44,44,14,14,31,31,31,31,44,44,44,14,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,14,}, /* E */ {14,44,44,44,44, 5, 5, 5, 5,44,14,44,44, 5,14,14,31,31,31,31,44,44,44,14,44,44,44,44,44,44, 5, 5,44,44,44,44,44,44,44,44,44,14,}, /* F */ {14,30,30,30,30,30,30,30,30,44,14,44,44,30,14,14,32,32,32,32,44,44,44,14,44,44,44,44,44,44,30,30,44,44,44,44,30,44,44,44,44,14,}, /* G */ {14,44,44,44,44,44,44,44,44,44,14,44,44,44,14,14,31,31,31,31,44,44,44,14,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,14,}, /* H */ {15,44,44,44,44,44,44,44,44,44,15,44,44,44,15,15,44,44,44,44,44,44,44,15,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,15,}, /* I */ {15,44,44,44,44,44,44,44,44,44,15,44,44,44,15,44,44,44,44,44,44,44,44,15,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,15,}, /* J */ {16,44,44,44,44,44,44,44,44,44,16,44,44,44,16,16,44,44,44,44,44,44,44,16,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,16,}, /* K */ {17,44,44,44,44,44,44,44,44,44,17,44,44,44,17,17,44,44,44,44,44,44,44,17,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,17,}, /* L */ {18,44,44,44,44,44,44,44,44,44,18,44,44,44,18,18,18,44,44,44,44,44,44,18,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,18,}, /* M */ {19,44,44,44,44,44,44,44,44,44,19,44,44,44,19,19,19,19,44,44,44,44,44,19,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,19,}, /* N */ {20,44,44,44,44,44,44,44,44,44,20,44,44,44,20,20,20,20,20,44,44,44,44,20,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,20,}, /* O */ {21,21,21,21,21,21,21,21,21,44,21,44,44,21,21,21,21,21,21,21,21,44,44,21,44,44,44,44,44,44,21,21,44,44,44,44,21,44,44,44,44,21,}, /* P */ {22,22,22,22,22,22,22,22,22,44,22,44,44,22,22,22,22,22,22,22,22,22,44,22,44,44,44,44,44,44,22,22,44,44,44,44,22,44,44,44,44,22,}, /* Q */ {23,23,23,23,23,23,23,23,23,44,23,44,44,23,23,23,23,23,23,23,23,23,23,23,44,44,44,44,44,44,23,23,44,44,44,44,23,44,44,44,44,23,}, /* R */ {25,44,44,44,44,44,44,44,44,44,25,44,44,44,25,25,44,44,44,44,44,44,44,25,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,25,}, /* S */ {41,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,38,44,41,44,44,44,44,44,41,}, /* T */ {42,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,34,44,36,44,39,39,39,44,36,}, /* U */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,33,44,44,39,44,39,33,44,}, /* V */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,33,44,33,44,44,44,44,44,33,44,}, /* W */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,34,34,34,44,44,34,34,34,34,44,}, /* X */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,40,44,44,35,44,}, /* Y */ {26,26,26,26,26,26,26,26,26,44,26,44,44,26,26,26,26,26,26,26,26,26,26,26,44,26,44,44,44,44,26,26,44,44,44,44,26,44,44,44,44,26,}, /* Z */ {27,27,27,27,27,27,27,27,27,44,27,44,44,27,27,27,27,27,27,27,27,27,27,27,44,27,27,44,44,44,27,27,44,44,44,44,27,44,44,44,44,27,}, /* a */ {25,25,25,25,25,25,25,25,25,44,25,44,44,25,25,25,25,25,25,25,25,25,25,25,44,44,44,44,44,44,25,25,44,44,44,44,25,44,44,44,44,25,}, /* b */ {28,44,44,44,44,44,44,44,44,44,11,44,44,44,44,44,44,44,44,44,44,44,44,28,44,44,44,28,44,44,44,44,44,44,44,44,44,44,44,44,44,28,}, /* c */ {29,44,44,44,44,44,44,44,44,44,29,44,44,44,44,44,44,44,44,44,44,44,44,29,44,44,44,29,29,44,44,44,44,44,44,44,44,44,44,44,44,29,}, /* d */ { 2, 2,44,44, 2, 2, 2, 2, 2,44, 2,44,44, 2, 2, 2, 2, 2, 2, 2,44,44,44, 2,44,44,44,44,44,44, 2, 2,44,44,44,44,44,44,44,44,44, 2,}, /* e */ { 3, 3, 3,44, 3, 3, 3, 3, 3,44, 3,44,44, 3, 3, 3, 3, 3, 3, 3,44,44,44, 3,44,44,44,44,44,44, 3, 3,44,44,44,44,44,44,44,44,44, 3,}, /* f */ { 4, 4, 4,44, 4, 4, 4, 4, 4,44, 4,44,44, 4, 4, 4, 4, 4, 4, 4,44,44,44, 4,44,44,44,44,44,44, 4, 4,44,44,44,44,44,44,44,44,44, 4,}, /* g */ { 5,44,44,44, 5, 5, 5, 5, 5,44, 5,44,44, 5, 5, 5, 5, 5, 5, 5,44,44,44, 5,44,44,44,44,44,44, 5, 5,44,44,44,44,44,44,44,44,44, 5,}, /* h */ { 6,44,44,44,44, 6,44,44,44,44, 6,44,44,44, 6, 6, 6, 6, 6, 6,44,44,44, 6,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 6,}, /* i */ { 7,44,44,44,44, 7, 7,44,44,44, 7,44,44,44, 7, 7, 7, 7, 7, 7,44,44,44, 7,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 7,}, /* j */ { 8,44,44,44,44, 8, 8, 8,44,44, 8,44,44,44, 8, 8, 8, 8, 8, 8,44,44,44, 8,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 8,}, /* k */ { 9,44,44,44,44, 9, 9, 9, 9,44, 9,44,44,44, 9, 9, 9, 9, 9, 9,44,44,44, 9,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, 9,}, /* l */ {10,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,}, /* m */ {11,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,}, /* n */ {44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,}, /* o */ {12,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,}, /* p */ {13,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,}, }; static const kbts_u8 kbts_CmapFormatPrecedence[14] = {1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 3, 0, 4, 5}; static int kbts_ShaperClearsMarkAdvancesInPostGposFixup(kbts_u32 Shaper) { int Result = (1 << Shaper) & ((1 << KBTS_SHAPER_ARABIC) | (1 << KBTS_SHAPER_DEFAULT) | (1 << KBTS_SHAPER_HEBREW)); return Result; } static kbts_indic_script_properties kbts_IndicScriptProperties(kbts_u32 Script) { kbts_indic_script_properties Result = KBTS_ZERO; switch(Script) { case KBTS_SCRIPT_DEVANAGARI: { Result.ViramaCodepoint = 0x94D; Result.RephPosition = KBTS_REPH_POSITION_BEFORE_POST; Result.RightSideMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_SUBJOINED; Result.AboveBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_SUBJOINED; Result.BelowBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_SUBJOINED; } break; case KBTS_SCRIPT_BENGALI: { Result.ViramaCodepoint = 0x9CD; Result.RephPosition = KBTS_REPH_POSITION_AFTER_SUBJOINED; Result.RightSideMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; Result.BelowBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_SUBJOINED; } break; case KBTS_SCRIPT_GUJARATI: { Result.ViramaCodepoint = 0xACD; Result.RephPosition = KBTS_REPH_POSITION_BEFORE_POST; Result.RightSideMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; Result.AboveBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_SUBJOINED; Result.BelowBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; } break; case KBTS_SCRIPT_GURMUKHI: { Result.ViramaCodepoint = 0xA4D; Result.RephPosition = KBTS_REPH_POSITION_BEFORE_SUBJOINED; Result.RightSideMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; Result.AboveBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; Result.BelowBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; } break; case KBTS_SCRIPT_KANNADA: { Result.ViramaCodepoint = 0xCCD; Result.BlwfPostOnly = 1; Result.AboveBaseMatraPosition = KBTS_SYLLABIC_POSITION_BEFORE_SUBJOINED; Result.BelowBaseMatraPosition = KBTS_SYLLABIC_POSITION_BEFORE_SUBJOINED; } break; case KBTS_SCRIPT_MALAYALAM: { Result.ViramaCodepoint = 0xD4D; Result.RephPosition = KBTS_REPH_POSITION_AFTER_MAIN; Result.RephEncoding = KBTS_REPH_ENCODING_LOGICAL_REPHA; Result.RightSideMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; Result.BelowBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; } break; case KBTS_SCRIPT_ODIA: { Result.ViramaCodepoint = 0xB4D; Result.RephPosition = KBTS_REPH_POSITION_AFTER_MAIN; Result.RightSideMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; Result.AboveBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_MAIN; Result.BelowBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_SUBJOINED; } break; case KBTS_SCRIPT_TAMIL: { Result.ViramaCodepoint = 0xBCD; Result.RightSideMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; Result.AboveBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_SUBJOINED; Result.BelowBaseMatraPosition = KBTS_SYLLABIC_POSITION_AFTER_POST; } break; case KBTS_SCRIPT_TELUGU: { Result.ViramaCodepoint = 0xC4D; Result.RephEncoding = KBTS_REPH_ENCODING_EXPLICIT; Result.BlwfPostOnly = 1; Result.AboveBaseMatraPosition = KBTS_SYLLABIC_POSITION_BEFORE_SUBJOINED; Result.BelowBaseMatraPosition = KBTS_SYLLABIC_POSITION_BEFORE_SUBJOINED; } break; } return Result; } static void kbts_ByteSwapArray16Unchecked(kbts_u16 *Array, kbts_un Count) { KBTS_FOR(It, 0, Count) { Array[It] = kbts_ByteSwap16(Array[It]); } } static int kbts_ByteSwapArray16(kbts_u16 *Array, kbts_un Count, char *End) { int Result = 0; if((char *)(Array + Count) <= End) { kbts_ByteSwapArray16Unchecked(Array, Count); Result = 1; } return Result; } static void kbts_ByteSwapArray32Unchecked(kbts_u32 *Array, kbts_un Count) { KBTS_FOR(It, 0, Count) { Array[It] = kbts_ByteSwap32(Array[It]); } } static int kbts_ByteSwapArray32(kbts_u32 *Array, kbts_un Count, char *End) { int Result = 0; if((char *)(Array + Count) <= End) { kbts_ByteSwapArray32Unchecked(Array, Count); Result = 1; } return Result; } static kbts_u64 kbts_ContainsFeature(kbts_feature_set *Set, kbts_feature_id Id) { kbts_un WordIndex = Id / 64; kbts_un BitIndex = Id % 64; kbts_u64 Result = Set->Flags[WordIndex] & (1ull << BitIndex); return Result; } static void kbts_AddFeature(kbts_feature_set *Set, kbts_feature_id Id) { kbts_un WordIndex = Id / 64; kbts_un BitIndex = Id % 64; Set->Flags[WordIndex] |= 1ull << BitIndex; } static kbts_feature_override kbts_FeatureOverrideBase(kbts_feature_id Id, kbts_feature_tag Tag, int Alternate, kbts_u32 Value) { kbts_feature_override Result = KBTS_ZERO; Result.Id = Id; Result.Tag = Tag; if(Alternate) { Result.EnabledOrAlternatePlusOne = Value + 1; } else { Result.EnabledOrAlternatePlusOne = Value; } return Result; } KBTS_EXPORT kbts_feature_override kbts_FeatureOverrideFromTag(kbts_feature_tag Tag, int Alternate, kbts_u32 Value) { kbts_feature_override Result = kbts_FeatureOverrideBase(kbts_FeatureTagToId(Tag), Tag, Alternate, Value); return Result; } KBTS_EXPORT kbts_feature_override kbts_FeatureOverride(kbts_feature_id Id, int Alternate, kbts_u32 Value) { kbts_feature_override Result = kbts_FeatureOverrideBase(Id, 0, Alternate, Value); return Result; } KBTS_EXPORT kbts_glyph_config kbts_GlyphConfig(kbts_feature_override *FeatureOverrides, kbts_u32 FeatureOverrideCount) { kbts_glyph_config Result = KBTS_ZERO; Result.FeatureOverrides = FeatureOverrides; Result.FeatureOverrideCount = FeatureOverrideCount; KBTS_FOR(FeatureOverrideIndex, 0, FeatureOverrideCount) { kbts_feature_override *Override = &FeatureOverrides[FeatureOverrideIndex]; if(Override->EnabledOrAlternatePlusOne) { kbts_AddFeature(&Result.EnabledFeatures, FeatureOverrides[FeatureOverrideIndex].Id); } else { kbts_AddFeature(&Result.DisabledFeatures, FeatureOverrides[FeatureOverrideIndex].Id); } } return Result; } KBTS_EXPORT kbts_glyph_config kbts_EmptyGlyphConfig(kbts_feature_override *FeatureOverrides, kbts_u32 FeatureOverrideCapacity) { kbts_glyph_config Result = KBTS_ZERO; Result.FeatureOverrides = FeatureOverrides; Result.FeatureOverrideCapacity = FeatureOverrideCapacity; return Result; } static int kbts_GlyphConfigOverrideFeatureBase(kbts_glyph_config *Config, kbts_feature_id Id, kbts_feature_tag Tag, int Alternate, kbts_u32 Value) { kbts_feature_set *Set = &Config->EnabledFeatures; if(!Value) { Set = &Config->DisabledFeatures; } kbts_AddFeature(Set, Id); if(!Id || Alternate) { if(Config->FeatureOverrideCount < Config->FeatureOverrideCapacity) { kbts_feature_override Override = kbts_FeatureOverrideFromTag(Tag, Alternate, Value); Config->FeatureOverrides[Config->FeatureOverrideCount++] = Override; } Config->RequiredFeatureOverrideCapacity += 1; } int Result = Config->RequiredFeatureOverrideCapacity <= Config->FeatureOverrideCapacity; return Result; } KBTS_EXPORT int kbts_GlyphConfigOverrideFeature(kbts_glyph_config *Config, kbts_feature_id Id, int Alternate, kbts_u32 Value) { int Result = kbts_GlyphConfigOverrideFeatureBase(Config, Id, 0, Alternate, Value); return Result; } KBTS_EXPORT int kbts_GlyphConfigOverrideFeatureFromTag(kbts_glyph_config *Config, kbts_feature_tag Tag, int Alternate, kbts_u32 Value) { int Result = kbts_GlyphConfigOverrideFeatureBase(Config, kbts_FeatureTagToId(Tag), Tag, Alternate, Value); return Result; } // // TTF struct definitions. // enum { KBTS_GLYPH_CLASS_BASE = 1, KBTS_GLYPH_CLASS_LIGATURE = 2, KBTS_GLYPH_CLASS_MARK = 3, KBTS_GLYPH_CLASS_COMPONENT = 4, }; enum { KBTS_LOOKUP_FLAG_RIGHT_TO_LEFT = 1 << 0, KBTS_LOOKUP_FLAG_IGNORE_BASE_GLYPHS = 1 << 1, KBTS_LOOKUP_FLAG_IGNORE_LIGATURES = 1 << 2, KBTS_LOOKUP_FLAG_IGNORE_MARKS = 1 << 3, KBTS_LOOKUP_FLAG_USE_MARK_FILTERING_SET = 1 << 4, KBTS_LOOKUP_FLAG_MARK_ATTACHMENT_CLASS_FILTER = 0xFF00, }; enum { KBTS_VALUE_FORMAT_X_PLACEMENT = 1 << 0, KBTS_VALUE_FORMAT_Y_PLACEMENT = 1 << 1, KBTS_VALUE_FORMAT_X_ADVANCE = 1 << 2, KBTS_VALUE_FORMAT_Y_ADVANCE = 1 << 3, KBTS_VALUE_FORMAT_X_PLACEMENT_DEVICE = 1 << 4, KBTS_VALUE_FORMAT_Y_PLACEMENT_DEVICE = 1 << 5, KBTS_VALUE_FORMAT_X_ADVANCE_DEVICE = 1 << 6, KBTS_VALUE_FORMAT_Y_ADVANCE_DEVICE = 1 << 7, }; enum { KBTS_DELTA_FORMAT_2_BIT = 1, KBTS_DELTA_FORMAT_4_BIT = 2, KBTS_DELTA_FORMAT_8_BIT = 3, KBTS_DELTA_FORMAT_VARIATION_INDEX = 0x8000, }; # pragma pack(push, 1) typedef struct kbts_glyph_header { kbts_s16 ContourCount; kbts_s16 MinX; kbts_s16 MinY; kbts_s16 MaxX; kbts_s16 MaxY; } kbts_glyph_header; typedef struct kbts_script_record { kbts_u32 Tag; kbts_u16 Offset; } kbts_script_record; typedef struct kbts_script_list { kbts_u16 Count; // kbts_script_record Records[Count]; } kbts_script_list; typedef struct kbts_ot_script { kbts_u16 DefaultLangsysOffset; kbts_u16 Count; // kbts_langsys_record Records[Count]; } kbts_ot_script; typedef struct kbts_langsys_record { kbts_u32 Tag; kbts_u16 Offset; } kbts_langsys_record; typedef struct kbts_langsys { kbts_u16 LookupOrderOffset; // reserved kbts_u16 RequiredFeatureIndex; kbts_u16 FeatureIndexCount; // kbts_u16 FeatureIndices[FeatureIndexCount]; } kbts_langsys; typedef struct kbts_feature_list { kbts_u16 Count; // kbts_feature_record Records[Count]; } kbts_feature_list; typedef struct kbts_feature_record { kbts_u32 Tag; kbts_u16 Offset; } kbts_feature_record; typedef struct kbts_feature { kbts_u16 FeatureParamsOffset; kbts_u16 LookupIndexCount; // kbts_u16 LookupIndices[LookupIndexCount]; } kbts_feature; typedef struct kbts_lookup_list { kbts_u16 Count; // kbts_u16 Offsets[Count]; } kbts_lookup_list; // Lookups are used both in GSUB and GPOS. // Type means either GSUB Lookup Type, or GPOS Lookup Type, depending on the table we are parsing. typedef struct kbts_lookup { kbts_u16 Type; kbts_u16 Flag; kbts_u16 SubtableCount; // kbts_u16 SubtableOffsets[SubtableCount]; // If USE_MARK_FILTERING_SET: // kbts_u16 MarkFilteringSet; } kbts_lookup; typedef struct kbts_coverage { kbts_u16 Format; kbts_u16 Count; // If Format == 1: // kbts_u16 GlyphArray[Count]; // If Format == 2: // kbts_range_record Ranges[Count]; } kbts_coverage; typedef struct kbts_range_record { kbts_u16 StartGlyphId; kbts_u16 EndGlyphId; kbts_u16 StartCoverageIndex; } kbts_range_record; typedef struct kbts_class_definition_1 { kbts_u16 Format; kbts_u16 StartGlyphId; kbts_u16 GlyphCount; // kbts_u16 ClassValues[GlyphCount]; } kbts_class_definition_1; typedef struct kbts_class_definition_2 { kbts_u16 Format; kbts_u16 Count; // kbts_class_range_record Ranges[Count]; } kbts_class_definition_2; typedef struct kbts_class_range_record { kbts_u16 StartGlyphId; kbts_u16 EndGlyphId; kbts_u16 Class; } kbts_class_range_record; typedef struct kbts_sequence_lookup_record { kbts_u16 SequenceIndex; kbts_u16 LookupListIndex; } kbts_sequence_lookup_record; typedef struct kbts_sequence_rule { kbts_u16 GlyphCount; kbts_u16 SequenceLookupCount; // kbts_u16 InputSequence[GlyphCount - 1]; // kbts_sequence_lookup_record SequenceLookupRecords[SequenceLookupCount]; } kbts_sequence_rule; typedef struct kbts_sequence_rule_set { kbts_u16 Count; // kbts_u16 Offsets[Count]; } kbts_sequence_rule_set; typedef struct kbts_sequence_context_1 { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 SeqRuleSetCount; // kbts_u16 SeqRuleSetOffsets[]; } kbts_sequence_context_1; typedef struct kbts_sequence_context_2 { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 ClassDefOffset; kbts_u16 ClassSequenceRuleSetCount; // kbts_u16 ClassSequenceRuleSetOffsets[ClassSequenceRuleSetCount]; May be NULL! } kbts_sequence_context_2; typedef struct kbts_class_sequence_rule_set { kbts_u16 Count; // kbts_u16 ClassSequenceRuleOffsets[Count]; } kbts_class_sequence_rule_set; typedef struct kbts_class_sequence_rule { kbts_u16 GlyphCount; kbts_u16 SequenceLookupCount; // kbts_u16 InputSequence[GlyphCount-1]; // kbts_sequence_lookup_record SequenceLookupRecords[SequenceLookupCount]; } kbts_class_sequence_rule; typedef struct kbts_sequence_context_3 { kbts_u16 Format; kbts_u16 GlyphCount; kbts_u16 SequenceLookupCount; // kbts_u16 CoverageOffsets[GlyphCount]; // kbts_sequence_lookup_record SequenceLookupRecords[SequenceLookupCount]; } kbts_sequence_context_3; typedef struct kbts_chained_sequence_context_1 { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 ChainedSequenceRuleSetCount; // kbts_u16 ChainedSequenceRuleSetOffsets[ChainedSequenceRuleSetCount]; } kbts_chained_sequence_context_1; typedef struct kbts_chained_sequence_rule_set { kbts_u16 Count; // kbts_u16 Offsets[Count]; } kbts_chained_sequence_rule_set; typedef struct kbts_chained_sequence_rule { kbts_u16 BacktrackGlyphCount; // kbts_u16 BacktrackSequence[BacktrackCount]; // kbts_u16 InputGlyphCount; // kbts_u16 InputSequence[InputGlyphCount - 1]; // kbts_u16 LookaheadGlyphCount; // kbts_u16 LookaheadSequence[LookaheadGlyphCount]; // kbts_u16 SequenceLookupCount; // kbts_sequence_lookup_record SequenceLookupRecords[SequenceLookupCount]; } kbts_chained_sequence_rule; typedef struct kbts_chained_sequence_context_2 { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 BacktrackClassDefOffset; kbts_u16 InputClassDefOffset; kbts_u16 LookaheadClassDefOffset; kbts_u16 ChainedClassSequenceRuleSetCount; // kbts_u16 ChainedClassSequenceRuleSetOffsets[ChainedClassSequenceRuleSetCount]; } kbts_chained_sequence_context_2; typedef struct kbts_chained_sequence_context_3 { kbts_u16 Format; kbts_u16 BacktrackGlyphCount; // kbts_u16 BacktrackCoverageOffsets[BacktrackGlyphCount]; // kbts_u16 InputGlyphCount; // kbts_u16 InputCoverageOffsets[InputGlyphCount]; // kbts_u16 LookaheadGlyphCount; // kbts_u16 LookaheadCoverageOffsets[LookaheadGlyphCount]; // kbts_u16 SequenceLookupCount; // kbts_sequence_lookup_record SequenceLookupRecords[SequenceLookupCount]; } kbts_chained_sequence_context_3; typedef struct kbts_device { union { struct { kbts_u16 StartSize; kbts_u16 EndSize; } Device; struct { kbts_u16 DeltaSetOuterIndex; kbts_u16 DeltaSetInnerIndex; } VariationIndex; } U; kbts_u16 DeltaFormat; // kbts_u16 DeltaValue[]; } kbts_device; typedef struct kbts_feature_variations { kbts_u16 Major; kbts_u16 Minor; kbts_u32 RecordCount; // kbts_feature_variation_record Records[RecordCount]; } kbts_feature_variations; typedef struct kbts_feature_variation_record { kbts_u32 ConditionSetOffset; kbts_u32 FeatureTableSubstitutionOffset; } kbts_feature_variation_record; typedef struct kbts_condition_set { kbts_u16 Count; // kbts_u32 Offsets[Count]; } kbts_condition_set; typedef struct kbts_condition_1 { kbts_u16 Format; kbts_u16 AxisIndex; kbts_u16 FilterRangeMinValue; kbts_u16 FilterRangeMaxValue; } kbts_condition_1; typedef struct kbts_feature_table_substitution { kbts_u16 Major; kbts_u16 Minor; kbts_u16 Count; // kbts_feature_table_substitution_record Records[Count]; } kbts_feature_table_substitution; typedef struct kbts_feature_table_substitution_record { kbts_u16 FeatureIndex; kbts_u32 AlternateFeatureOffset; } kbts_feature_table_substitution_record; typedef struct kbts_table_directory { kbts_u32 Version; kbts_u16 TableCount; kbts_u16 SearchRange; kbts_u16 EntrySelector; kbts_u16 RangeShift; // kbts_table_record Records[TableCount]; } kbts_table_directory; typedef struct kbts_table_record { kbts_u32 Tag; kbts_u32 Checksum; kbts_u32 Offset; kbts_u32 Length; } kbts_table_record; typedef struct kbts_cmap { kbts_u16 Version; kbts_u16 TableCount; // kbts_encoding_record Records[TableCount]; } kbts_cmap; typedef struct kbts_encoding_record { kbts_u16 PlatformId; kbts_u16 EncodingId; kbts_u32 SubtableOffset; } kbts_encoding_record; /* Precedence rules for cmap tables: - Tables are mutually exclusive, except for format 14 which completes the others. - 8, 10, 12 > 0, 2, 4, 6 - Formats 4, 12, 13, 14 are used today. - Formats 4 and 12 are basic cmap tables. - Format 13 is for fallback fonts that want to map lots of codepoints to a few fallback glyphs. - Format 14 is for Unicode Variation Sequences. - There can be Unicode and Windows tables with the same formats. In that case, we prefer the Windows tables. */ typedef struct kbts_cmap_0 { kbts_u16 Format; kbts_u16 Length; kbts_u16 Language; kbts_u8 GlyphIdArray[256]; } kbts_cmap_0; typedef struct kbts_cmap_2 { kbts_u16 Format; kbts_u16 Length; kbts_u16 Language; kbts_u16 SubHeaderKeys[256]; // kbts_sub_header SubHeaders[]; // kbts_u16 GlyphIdArray[]; } kbts_cmap_2; typedef struct kbts_sub_header { kbts_u16 FirstCode; kbts_u16 EntryCount; kbts_s16 IdDelta; kbts_u16 IdRangeOffset; } kbts_sub_header; typedef struct kbts_cmap_4 { kbts_u16 Format; kbts_u16 Length; kbts_u16 Language; kbts_u16 SegmentCountTimesTwo; kbts_u16 SearchRange; kbts_u16 EntrySelector; kbts_u16 RangeShift; // kbts_u16 EndCode[SegmentCount]; // kbts_u16 Reserved; // kbts_u16 StartCode[SegmentCount]; // kbts_s16 IdDelta[SegmentCount]; // kbts_u16 IdRangeOffsets[SegmentCount]; // kbts_u16 GlyphIdArray[]; } kbts_cmap_4; typedef struct kbts_cmap_6 { kbts_u16 Format; kbts_u16 Length; kbts_u16 Language; kbts_u16 FirstCode; kbts_u16 EntryCount; // kbts_u16 GlyphIdArray[EntryCount]; } kbts_cmap_6; typedef struct kbts_cmap_12_13 { kbts_u16 Format; kbts_u16 Reserved; kbts_u32 Length; kbts_u32 Language; kbts_u32 GroupCount; // kbts_sequential_map_group Groups[GroupCount]; } kbts_cmap_12_13; typedef struct kbts_sequential_map_group { kbts_u32 StartCharacterCode; kbts_u32 EndCharacterCode; kbts_u32 StartGlyphId; } kbts_sequential_map_group; typedef struct kbts_cmap_14 { kbts_u16 Format; kbts_u32 Length; kbts_u32 SelectorCount; // kbts_variation_selector Selectors[SelectorCount]; } kbts_cmap_14; typedef struct kbts_variation_selector { kbts_u8 Selector[3]; kbts_u32 DefaultUvsOffset; kbts_u32 NonDefaultUvsOffset; } kbts_variation_selector; typedef struct kbts_default_uvs { kbts_u32 RangeCount; // kbts_unicode_range Ranges[RangeCount]; } kbts_default_uvs; typedef struct kbts_unicode_range { kbts_u8 Start[3]; kbts_u8 Count; } kbts_unicode_range; typedef struct kbts_non_default_uvs { kbts_u32 MappingCount; // kbts_uvs_mapping Mappings[MappingCount]; } kbts_non_default_uvs; typedef struct kbts_uvs_mapping { kbts_u8 UnicodeValue[3]; kbts_u16 GlyphId; } kbts_uvs_mapping; typedef struct kbts_gsub_gpos { kbts_u16 Major; kbts_u16 Minor; kbts_u16 ScriptListOffset; kbts_u16 FeatureListOffset; kbts_u16 LookupListOffset; kbts_u32 FeatureVariationsOffset; // Only present in v1.1 } kbts_gsub_gpos; typedef struct kbts_single_substitution { kbts_u16 Format; kbts_u16 CoverageOffset; union { kbts_s16 DeltaGlyphId; // Format == 1 kbts_u16 GlyphCount; // Format == 2 } DeltaOrCount; // If Format == 2: // kbts_u16 SubstituteGlyphIds[GlyphCount]; } kbts_single_substitution; typedef struct kbts_multiple_substitution { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 SequenceCount; // kbts_u16 SequenceOffsets[SequenceCount]; } kbts_multiple_substitution; typedef struct kbts_sequence { kbts_u16 GlyphCount; // kbts_u16 SubstituteGlyphIds[GlyphCount]; } kbts_sequence; typedef struct kbts_alternate_substitution { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 AlternateSetCount; // kbts_u16 AlternateSetOffsets[AlternateSetCount]; } kbts_alternate_substitution; typedef struct kbts_alternate_set { kbts_u16 GlyphCount; // kbts_u16 AlternateGlyphIds[GlyphCount]; } kbts_alternate_set; typedef struct kbts_ligature_substitution { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 LigatureSetCount; // kbts_u16 LigatureSetOffsets[LigatureSetCount]; } kbts_ligature_substitution; typedef struct kbts_ligature_set { kbts_u16 Count; // kbts_u16 Offsets[Count]; } kbts_ligature_set; typedef struct kbts_ligature { kbts_u16 Glyph; kbts_u16 ComponentCount; // kbts_u16 ComponentGlyphIds[ComponentCount - 1]; } kbts_ligature; typedef struct kbts_extension { kbts_u16 Format; kbts_u16 LookupType; kbts_u32 Offset; } kbts_extension; typedef struct kbts_reverse_chain_substitution { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 BacktrackGlyphCount; // kbts_u16 BacktrackCoverageOffsets[BacktrackGlyphCount]; // kbts_u16 LookaheadGlyphCount; // kbts_u16 LookaheadCoverageOffsets[LookaheadGlyphCount]; // kbts_u16 GlyphCount; // kbts_u16 SubstituteGlyphIds[GlyphCount]; } kbts_reverse_chain_substitution; typedef struct kbts_mark_glyph_sets { kbts_u16 Format; kbts_u16 MarkGlyphSetCount; // kbts_u32 CoverageOffsets[MarkGlyphSetCount]; } kbts_mark_glyph_sets; typedef struct kbts_gdef { kbts_u16 Major; kbts_u16 Minor; kbts_u16 ClassDefinitionOffset; // May be 0 kbts_u16 AttachListOffset; // May be 0 kbts_u16 LigatureCaretListOffset; // May be 0 kbts_u16 MarkAttachmentClassDefinitionOffset; // May be 0 kbts_u16 MarkGlyphSetsDefinitionOffset; // v1.2 and up; may be 0 kbts_u32 ItemVariationStoreOffset; // v1.3 and up; may be 0 } kbts_gdef; typedef struct kbts_anchor { kbts_u16 Format; kbts_s16 X; kbts_s16 Y; union { kbts_u16 AnchorPoint; // If Format == 2 kbts_u16 XDeviceOffset; // If Format == 3 } U; kbts_u16 YDeviceOffset; // If Format == 3 } kbts_anchor; typedef struct kbts_mark_record { kbts_u16 Class; kbts_u16 AnchorOffset; } kbts_mark_record; typedef struct kbts_mark_array { kbts_u16 Count; // kbts_mark_record Records[Count]; } kbts_mark_array; typedef struct kbts_single_adjustment_1 { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 ValueFormat; // ValueRecord; } kbts_single_adjustment_1; typedef struct kbts_single_adjustment_2 { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 ValueFormat; kbts_u16 RecordCount; // ValueRecord Records[RecordCount]; } kbts_single_adjustment_2; typedef struct kbts_pair_value_record { kbts_u16 SecondGlyph; // ValueRecord Record1; // ValueRecord Record2; } kbts_pair_value_record; typedef struct kbts_pair_set { kbts_u16 Count; // kbts_pair_value_record PairValueRecords[Count]; } kbts_pair_set; typedef struct kbts_pair_adjustment_1 { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 ValueFormat1; // May be 0 kbts_u16 ValueFormat2; // May be 0 kbts_u16 SetCount; // kbts_u16 SetOffsets[PairSetCount]; } kbts_pair_adjustment_1; typedef struct kbts_pair_adjustment_2 { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 ValueFormat1; // May be 0 kbts_u16 ValueFormat2; // May be 0 kbts_u16 ClassDefinition1Offset; kbts_u16 ClassDefinition2Offset; kbts_u16 Class1Count; kbts_u16 Class2Count; // ValueRecord ValueRecords[Class1Count][Class2Count][2]; } kbts_pair_adjustment_2; typedef struct kbts_entry_exit { kbts_u16 EntryAnchorOffset; kbts_u16 ExitAnchorOffset; } kbts_entry_exit; typedef struct kbts_cursive_attachment { kbts_u16 Format; kbts_u16 CoverageOffset; kbts_u16 EntryExitCount; // kbts_entry_exit Records[EntryExitCount]; } kbts_cursive_attachment; typedef struct kbts_base_array { kbts_u16 BaseCount; // kbts_u16 BaseAnchorOffsets[BaseCount][MarkClassCount]; // May be NULL } kbts_base_array; typedef struct kbts_mark_to_base_attachment { kbts_u16 Format; kbts_u16 MarkCoverageOffset; kbts_u16 BaseCoverageOffset; kbts_u16 MarkClassCount; kbts_u16 MarkArrayOffset; kbts_u16 BaseArrayOffset; } kbts_mark_to_base_attachment; typedef struct kbts_ligature_attach { kbts_u16 Count; // kbts_u16 LigatureAnchorOffsets[Count][MarkClassCount]; // May be NULL } kbts_ligature_attach; typedef struct kbts_ligature_array { kbts_u16 Count; // kbts_u16 LigatureAttachOffsets[Count]; } kbts_ligature_array; typedef struct kbts_mark_to_ligature_attachment { kbts_u16 Format; kbts_u16 MarkCoverageOffset; kbts_u16 LigatureCoverageOffset; kbts_u16 MarkClassCount; kbts_u16 MarkArrayOffset; kbts_u16 LigatureArrayOffset; } kbts_mark_to_ligature_attachment; typedef struct kbts_long_mtx { kbts_u16 Advance; kbts_s16 PreviousSideBearing; } kbts_long_mtx; struct kbts_head { kbts_u16 Major; kbts_u16 Minor; kbts_u32 Revision; kbts_u32 ChecksumAdjustment; kbts_u32 MagicNumber; kbts_u16 Flags; kbts_u16 UnitsPerEm; kbts_s64 CreatedTime; kbts_s64 LastModifiedTime; kbts_s16 XMin; kbts_s16 YMin; kbts_s16 XMax; kbts_s16 YMax; kbts_u16 MacStyle; // OS/2 style takes priority on Windows. kbts_u16 LowestRecommendedPpem; kbts_s16 DirectionHint; // Deprecated. Should ~always be 2. kbts_s16 IndexToLocFormat; kbts_s16 GlyphDataFormat; // Only 0 is defined. }; typedef struct kbts_hea { kbts_u16 Major; kbts_u16 Minor; // According to Microsoft, these metrics are deprecated. // The OS/2 table is the preferred way to get these, now. kbts_s16 Ascent; kbts_s16 Descent; kbts_s16 LineGap; kbts_u16 MaxAdvance; kbts_s16 MinPreviousSideBearing; kbts_s16 MinNextSideBearing; kbts_s16 MaxExtent; kbts_s16 CaretSlopeRise; kbts_s16 CaretSlopeRun; kbts_s16 CaretOffset; kbts_u16 Reserved[4]; kbts_s16 MetricDataFormat; kbts_u16 MetricCount; } kbts_hea; typedef struct kbts_maxp { kbts_u16 Major; kbts_u16 Minor; kbts_u16 GlyphCount; // If Major == 1: kbts_u16 MaxPointCount; kbts_u16 MaxContourCount; kbts_u16 MaxCompositePointCount; kbts_u16 MaxCompositeContourCount; kbts_u16 MaxZoneCount; kbts_u16 MaxTwilightPointCount; kbts_u16 StorageAreaCount; kbts_u16 FunctionDefinitionCount; kbts_u16 InstructionDefinitionCount; kbts_u16 MaximumStackDepth; kbts_u16 MaximumInstructionSize; kbts_u16 MaximumTopLevelComponentCount; kbts_u16 MaximumComponentDepth; } kbts_maxp; # pragma pack(pop) // // Unpack functions for TTF structs. // typedef struct kbts_script_pointer { kbts_u32 Tag; kbts_ot_script *Script; } kbts_script_pointer; typedef struct kbts_langsys_pointer { kbts_u32 Tag; kbts_langsys *Langsys; } kbts_langsys_pointer; typedef struct kbts_feature_pointer { kbts_u32 Tag; kbts_feature *Feature; } kbts_feature_pointer; typedef struct kbts_feature_variation_pointer { kbts_condition_set *ConditionSet; kbts_feature_table_substitution *FeatureTableSubstitution; } kbts_feature_variation_pointer; typedef struct kbts_feature_substitution_pointer { kbts_u16 SubstitutedFeatureIndex; kbts_feature *AlternateFeature; } kbts_feature_substitution_pointer; typedef struct kbts_cmap_subtable_pointer { kbts_u16 PlatformId; kbts_u16 EncodingId; kbts_u16 *Subtable; } kbts_cmap_subtable_pointer; typedef struct kbts_unpacked_chained_sequence_rule { kbts_u16 *Input; kbts_u16 *Backtrack; kbts_u16 *Lookahead; kbts_sequence_lookup_record *Records; kbts_u16 BacktrackCount; kbts_u16 InputCount; kbts_u16 LookaheadCount; kbts_u16 RecordCount; } kbts_unpacked_chained_sequence_rule; typedef struct kbts_unpacked_chained_sequence_context_3 { kbts_u16 *BacktrackCoverageOffsets; kbts_u16 *InputCoverageOffsets; kbts_u16 *LookaheadCoverageOffsets; kbts_sequence_lookup_record *Records; kbts_u16 BacktrackCount; kbts_u16 InputCount; kbts_u16 LookaheadCount; kbts_u16 RecordCount; } kbts_unpacked_chained_sequence_context_3; typedef struct kbts_unpacked_reverse_chain_substitution { kbts_u16 *BacktrackCoverageOffsets; kbts_u16 *LookaheadCoverageOffsets; kbts_u16 *SubstituteGlyphIds; kbts_u16 BacktrackCount; kbts_u16 LookaheadCount; kbts_u16 GlyphCount; } kbts_unpacked_reverse_chain_substitution; typedef struct kbts_unpacked_value_record { kbts_u16 Size; kbts_s16 PlacementX; kbts_s16 PlacementY; kbts_s16 AdvanceX; kbts_s16 AdvanceY; kbts_device *PlacementXDevice; kbts_device *PlacementYDevice; kbts_device *AdvanceXDevice; kbts_device *AdvanceYDevice; } kbts_unpacked_value_record; static kbts_unpacked_value_record kbts_UnpackValueRecord(void *Parent, kbts_u16 Format, kbts_u16 *Record) { kbts_unpacked_value_record Result = KBTS_ZERO; kbts_u16 *At = Record; if(Format & KBTS_VALUE_FORMAT_X_PLACEMENT) { Result.PlacementX = (kbts_s16)*At++; } if(Format & KBTS_VALUE_FORMAT_Y_PLACEMENT) { Result.PlacementY = (kbts_s16)*At++; } if(Format & KBTS_VALUE_FORMAT_X_ADVANCE) { Result.AdvanceX = (kbts_s16)*At++; } if(Format & KBTS_VALUE_FORMAT_Y_ADVANCE) { Result.AdvanceY = (kbts_s16)*At++; } if(Format & KBTS_VALUE_FORMAT_X_PLACEMENT_DEVICE) { kbts_u16 Offset = *At++; if(Offset) { Result.PlacementXDevice = KBTS_POINTER_OFFSET(kbts_device, Parent, Offset); } } if(Format & KBTS_VALUE_FORMAT_Y_PLACEMENT_DEVICE) { kbts_u16 Offset = *At++; if(Offset) { Result.PlacementYDevice = KBTS_POINTER_OFFSET(kbts_device, Parent, Offset); } } if(Format & KBTS_VALUE_FORMAT_X_ADVANCE_DEVICE) { kbts_u16 Offset = *At++; if(Offset) { Result.AdvanceXDevice = KBTS_POINTER_OFFSET(kbts_device, Parent, Offset); } } if(Format & KBTS_VALUE_FORMAT_Y_ADVANCE_DEVICE) { kbts_u16 Offset = *At++; if(Offset) { Result.AdvanceYDevice = KBTS_POINTER_OFFSET(kbts_device, Parent, Offset); } } Result.Size = (kbts_u16)(At - Record); return Result; } static kbts_unpacked_reverse_chain_substitution kbts_UnpackReverseChainSubstitution(kbts_reverse_chain_substitution *Subst, int ByteSwap) { kbts_unpacked_reverse_chain_substitution Result; Result.BacktrackCoverageOffsets = KBTS_POINTER_AFTER(kbts_u16, Subst); Result.BacktrackCount = Subst->BacktrackGlyphCount; if(ByteSwap) { Result.BacktrackCount = kbts_ByteSwap16(Result.BacktrackCount); } Result.LookaheadCoverageOffsets = Result.BacktrackCoverageOffsets + Result.BacktrackCount + 1; Result.LookaheadCount = Result.BacktrackCoverageOffsets[Result.BacktrackCount]; if(ByteSwap) { Result.LookaheadCount = kbts_ByteSwap16(Result.LookaheadCount); } Result.SubstituteGlyphIds = Result.LookaheadCoverageOffsets + Result.LookaheadCount + 1; Result.GlyphCount = Result.LookaheadCoverageOffsets[Result.LookaheadCount]; if(ByteSwap) { Result.GlyphCount = kbts_ByteSwap16(Result.GlyphCount); } return Result; } static kbts_unpacked_chained_sequence_rule kbts_UnpackChainedSequenceRule(kbts_chained_sequence_rule *Rule, int ByteSwap) { kbts_unpacked_chained_sequence_rule Result; Result.Backtrack = KBTS_POINTER_AFTER(kbts_u16, Rule); Result.BacktrackCount = Rule->BacktrackGlyphCount; if(ByteSwap) { Result.BacktrackCount = kbts_ByteSwap16(Result.BacktrackCount); } Result.Input = Result.Backtrack + Result.BacktrackCount + 1; Result.InputCount = Result.Backtrack[Result.BacktrackCount]; if(ByteSwap) { Result.InputCount = kbts_ByteSwap16(Result.InputCount); } Result.Lookahead = Result.Input + Result.InputCount; Result.LookaheadCount = Result.Input[Result.InputCount - 1]; if(ByteSwap) { Result.LookaheadCount = kbts_ByteSwap16(Result.LookaheadCount); } Result.Records = (kbts_sequence_lookup_record *)(Result.Lookahead + Result.LookaheadCount + 1); Result.RecordCount = Result.Lookahead[Result.LookaheadCount]; if(ByteSwap) { Result.RecordCount = kbts_ByteSwap16(Result.RecordCount); } return Result; } static kbts_unpacked_chained_sequence_context_3 kbts_UnpackChainedSequenceContext3(kbts_chained_sequence_context_3 *Subst, int ByteSwap) { kbts_unpacked_chained_sequence_context_3 Result; Result.BacktrackCoverageOffsets = KBTS_POINTER_AFTER(kbts_u16, Subst); Result.BacktrackCount = Subst->BacktrackGlyphCount; if(ByteSwap) { Result.BacktrackCount = kbts_ByteSwap16(Result.BacktrackCount); } Result.InputCoverageOffsets = Result.BacktrackCoverageOffsets + Result.BacktrackCount + 1; Result.InputCount = Result.BacktrackCoverageOffsets[Result.BacktrackCount]; if(ByteSwap) { Result.InputCount = kbts_ByteSwap16(Result.InputCount); } Result.LookaheadCoverageOffsets = Result.InputCoverageOffsets + Result.InputCount + 1; Result.LookaheadCount = Result.InputCoverageOffsets[Result.InputCount]; if(ByteSwap) { Result.LookaheadCount = kbts_ByteSwap16(Result.LookaheadCount); } Result.Records = (kbts_sequence_lookup_record *)(Result.LookaheadCoverageOffsets + Result.LookaheadCount + 1); Result.RecordCount = Result.LookaheadCoverageOffsets[Result.LookaheadCount]; if(ByteSwap) { Result.RecordCount = kbts_ByteSwap16(Result.RecordCount); } return Result; } typedef struct kbts_unpacked_lookup { kbts_u16 *SubtableOffsets; kbts_coverage *MarkFilteringSet; kbts_u16 Type; kbts_u16 Flags; kbts_u16 SubtableCount; } kbts_unpacked_lookup; static kbts_unpacked_lookup kbts_UnpackLookup(kbts_gdef *Gdef, kbts_lookup *Lookup) { kbts_unpacked_lookup Result = KBTS_ZERO; Result.Type = Lookup->Type; Result.Flags = Lookup->Flag; Result.SubtableCount = Lookup->SubtableCount; Result.SubtableOffsets = KBTS_POINTER_AFTER(kbts_u16, Lookup); if(Result.Flags & KBTS_LOOKUP_FLAG_USE_MARK_FILTERING_SET) { kbts_u16 MarkFilteringSetIndex = Result.SubtableOffsets[Result.SubtableCount]; if(Gdef && Gdef->MarkGlyphSetsDefinitionOffset) { kbts_mark_glyph_sets *MarkGlyphSets = KBTS_POINTER_OFFSET(kbts_mark_glyph_sets, Gdef, Gdef->MarkGlyphSetsDefinitionOffset); if(MarkGlyphSets->MarkGlyphSetCount > MarkFilteringSetIndex) { kbts_u32 *CoverageOffsets = KBTS_POINTER_AFTER(kbts_u32, MarkGlyphSets); Result.MarkFilteringSet = KBTS_POINTER_OFFSET(kbts_coverage, MarkGlyphSets, CoverageOffsets[MarkFilteringSetIndex]); } } } return Result; } static kbts_script_pointer kbts_GetScript(kbts_script_list *List, kbts_un Index) { kbts_script_record *Records = (kbts_script_record *)(List + 1); kbts_script_record *Record = &Records[Index]; kbts_script_pointer Result; Result.Tag = Record->Tag; Result.Script = (kbts_ot_script *)((char *)List + Record->Offset); return Result; } static kbts_langsys *kbts_GetDefaultLangsys(kbts_ot_script *Script) { kbts_langsys *Result = Script->DefaultLangsysOffset ? KBTS_POINTER_OFFSET(kbts_langsys, Script, Script->DefaultLangsysOffset) : 0; return Result; } static kbts_langsys_pointer kbts_GetLangsys(kbts_ot_script *Script, kbts_un Index) { kbts_langsys_record *Records = (kbts_langsys_record *)(Script + 1); kbts_langsys_record *Record = &Records[Index]; kbts_langsys_pointer Result; Result.Tag = Record->Tag; Result.Langsys = KBTS_POINTER_OFFSET(kbts_langsys, Script, Record->Offset); return Result; } static kbts_feature_pointer kbts_GetFeature(kbts_feature_list *List, kbts_un Index) { kbts_feature_record *Records = (kbts_feature_record *)(List + 1); kbts_feature_record *Record = &Records[Index]; kbts_feature_pointer Result; Result.Tag = Record->Tag; Result.Feature = KBTS_POINTER_OFFSET(kbts_feature, List, Record->Offset); return Result; } static kbts_lookup_list *kbts_GetLookupList(kbts_gsub_gpos *GsubGpos) { kbts_lookup_list *Result = 0; if(GsubGpos) { Result = KBTS_POINTER_OFFSET(kbts_lookup_list, GsubGpos, GsubGpos->LookupListOffset); } return Result; } static kbts_lookup *kbts_GetLookup(kbts_lookup_list *List, kbts_un Index) { KBTS_ASSERT(Index < List->Count); kbts_u16 *Offsets = (kbts_u16 *)(List + 1); kbts_lookup *Result = KBTS_POINTER_OFFSET(kbts_lookup, List, Offsets[Index]); return Result; } static kbts_sequence_rule_set *kbts_GetSequenceRuleSet(kbts_sequence_context_1 *Context, kbts_un Index) { KBTS_ASSERT(Index < Context->SeqRuleSetCount); kbts_u16 *Offsets = (kbts_u16 *)(Context + 1); kbts_u16 Offset = Offsets[Index]; kbts_sequence_rule_set *Result = Offset ? KBTS_POINTER_OFFSET(kbts_sequence_rule_set, Context, Offsets[Index]) : 0; return Result; } static kbts_sequence_rule *kbts_GetSequenceRule(kbts_sequence_rule_set *Set, kbts_un Index) { KBTS_ASSERT(Index < Set->Count); kbts_u16 *Offsets = (kbts_u16 *)(Set + 1); kbts_sequence_rule *Result = KBTS_POINTER_OFFSET(kbts_sequence_rule, Set, Offsets[Index]); return Result; } // A single class definition table can be used by multiple lookups, so it is possible // (and valid) to get an out-of-bounds glyph class. static kbts_class_sequence_rule_set *kbts_GetClassSequenceRuleSet(kbts_sequence_context_2 *Context, kbts_un Index) { kbts_class_sequence_rule_set *Result = 0; if(Index < Context->ClassSequenceRuleSetCount) { kbts_u16 *Offsets = (kbts_u16 *)(Context + 1); Result = Offsets[Index] ? KBTS_POINTER_OFFSET(kbts_class_sequence_rule_set, Context, Offsets[Index]) : 0; } return Result; } static kbts_class_sequence_rule *kbts_GetClassSequenceRule(kbts_class_sequence_rule_set *Set, kbts_un Index) { KBTS_ASSERT(Index < Set->Count); kbts_u16 *Offsets = (kbts_u16 *)(Set + 1); kbts_class_sequence_rule *Result = KBTS_POINTER_OFFSET(kbts_class_sequence_rule, Set, Offsets[Index]); return Result; } static kbts_chained_sequence_rule_set *kbts_GetChainedSequenceRuleSet(kbts_chained_sequence_context_1 *Context, kbts_un Index) { kbts_u16 *Offsets = (kbts_u16 *)(Context + 1); kbts_chained_sequence_rule_set *Result = Offsets[Index] ? KBTS_POINTER_OFFSET(kbts_chained_sequence_rule_set, Context, Offsets[Index]) : 0; return Result; } static kbts_chained_sequence_rule *kbts_GetChainedSequenceRule(kbts_chained_sequence_rule_set *Set, kbts_un Index) { kbts_u16 *Offsets = (kbts_u16 *)(Set + 1); kbts_chained_sequence_rule *Result = KBTS_POINTER_OFFSET(kbts_chained_sequence_rule, Set, Offsets[Index]); return Result; } static kbts_chained_sequence_rule_set *kbts_GetChainedClassSequenceRuleSet(kbts_chained_sequence_context_2 *Context, kbts_un Index) { kbts_u16 *Offsets = (kbts_u16 *)(Context + 1); kbts_u16 Offset = Offsets[Index]; kbts_chained_sequence_rule_set *Result = Offset ? KBTS_POINTER_OFFSET(kbts_chained_sequence_rule_set, Context, Offset) : NULL; return Result; } static kbts_chained_sequence_rule *kbts_GetChainedClassSequenceRule(kbts_chained_sequence_rule_set *Set, kbts_un Index) { kbts_u16 *Offsets = (kbts_u16 *)(Set + 1); kbts_chained_sequence_rule *Result = KBTS_POINTER_OFFSET(kbts_chained_sequence_rule, Set, Offsets[Index]); return Result; } #if 0 // @Incomplete static kbts_feature_variation_pointer kbts_GetFeatureVariation(kbts_feature_variations *Variations, kbts_un Index) { kbts_feature_variation_record *Records = (kbts_feature_variation_record *)(Variations + 1); kbts_feature_variation_record *Record = &Records[Index]; kbts_feature_variation_pointer Result; Result.ConditionSet = KBTS_POINTER_OFFSET(kbts_condition_set, Variations, Record->ConditionSetOffset); Result.FeatureTableSubstitution = KBTS_POINTER_OFFSET(kbts_feature_table_substitution, Variations, Record->FeatureTableSubstitutionOffset); return Result; } static kbts_condition_1 *kbts_GetCondition(kbts_condition_set *Set, kbts_un Index) { kbts_u32 *Offsets = (kbts_u32 *)(Set + 1); kbts_condition_1 *Result = KBTS_POINTER_OFFSET(kbts_condition_1, Set, Offsets[Index]); return Result; } static kbts_feature_substitution_pointer kbts_GetFeatureSubstitution(kbts_feature_table_substitution *Table, kbts_un Index) { kbts_feature_table_substitution_record *Records = (kbts_feature_table_substitution_record *)(Table + 1); kbts_feature_table_substitution_record *Record = &Records[Index]; kbts_feature_substitution_pointer Result; Result.SubstitutedFeatureIndex = Record->FeatureIndex; Result.AlternateFeature = KBTS_POINTER_OFFSET(kbts_feature, Table, Record->AlternateFeatureOffset); return Result; } #endif static kbts_cmap_subtable_pointer kbts_GetCmapSubtable(kbts_cmap *Cmap, kbts_un Index) { kbts_encoding_record *Records = (kbts_encoding_record *)(Cmap + 1); kbts_encoding_record *Record = &Records[Index]; kbts_cmap_subtable_pointer Result; Result.PlatformId = Record->PlatformId; Result.EncodingId = Record->EncodingId; Result.Subtable = KBTS_POINTER_OFFSET(kbts_u16, Cmap, Record->SubtableOffset); return Result; } static kbts_sequence *kbts_GetSequence(kbts_multiple_substitution *Subst, kbts_un Index) { kbts_u16 *Offsets = (kbts_u16 *)(Subst + 1); kbts_sequence *Result = KBTS_POINTER_OFFSET(kbts_sequence, Subst, Offsets[Index]); return Result; } static kbts_alternate_set *kbts_GetAlternateSet(kbts_alternate_substitution *Subst, kbts_un Index) { kbts_u16 *Offsets = (kbts_u16 *)(Subst + 1); kbts_alternate_set *Result = KBTS_POINTER_OFFSET(kbts_alternate_set, Subst, Offsets[Index]); return Result; } static kbts_ligature_set *kbts_GetLigatureSet(kbts_ligature_substitution *Subst, kbts_un Index) { kbts_u16 *Offsets = (kbts_u16 *)(Subst + 1); kbts_ligature_set *Result = KBTS_POINTER_OFFSET(kbts_ligature_set, Subst, Offsets[Index]); return Result; } static kbts_ligature *kbts_GetLigature(kbts_ligature_set *Set, kbts_un Index) { kbts_u16 *Offsets = (kbts_u16 *)(Set + 1); kbts_ligature *Result = KBTS_POINTER_OFFSET(kbts_ligature, Set, Offsets[Index]); return Result; } static kbts_mark_record *kbts_GetMarkRecord(kbts_mark_array *Array, kbts_un Index) { kbts_mark_record *Records = KBTS_POINTER_AFTER(kbts_mark_record, Array); kbts_mark_record *Result = &Records[Index]; return Result; } static kbts_ligature_attach *kbts_GetLigatureAttach(kbts_ligature_array *Array, kbts_un Index) { kbts_u16 *Offsets = KBTS_POINTER_AFTER(kbts_u16, Array); kbts_ligature_attach *Result = KBTS_POINTER_OFFSET(kbts_ligature_attach, Array, Offsets[Index]); return Result; } static kbts_anchor *kbts_GetLigatureAttachAnchor(kbts_mark_to_ligature_attachment *Adjust, kbts_ligature_attach *Attach, kbts_u16 MarkClass, kbts_un ComponentIndex) { kbts_u16 *Offsets = KBTS_POINTER_AFTER(kbts_u16, Attach); kbts_u16 Offset = Offsets[ComponentIndex * Adjust->MarkClassCount + MarkClass]; kbts_anchor *Result = 0; if(Offset) { Result = KBTS_POINTER_OFFSET(kbts_anchor, Attach, Offset); } return Result; } typedef struct kbts_mark_info { kbts_mark_array *Array; kbts_mark_record *Record; kbts_anchor *Anchor; } kbts_mark_info; static kbts_mark_info kbts_GetMarkInfo(void *Subtable, kbts_un SubtableOffsetToMarkArray, kbts_un CoverageIndex) { kbts_mark_info Result = KBTS_ZERO; Result.Array = KBTS_POINTER_OFFSET(kbts_mark_array, Subtable, SubtableOffsetToMarkArray); Result.Record = kbts_GetMarkRecord(Result.Array, CoverageIndex); Result.Anchor = KBTS_POINTER_OFFSET(kbts_anchor, Result.Array, Result.Record->AnchorOffset); return Result; } // // // typedef struct kbts_byteswap_context { char *FileBase; char *FileEnd; kbts_u32 *Pointers; kbts_un PointerCapacity; kbts_un PointerCount; int Error; } kbts_byteswap_context; static int kbts_ByteSwapArray16Context(kbts_u16 *Array, kbts_un Count, kbts_byteswap_context *Context) { int Result = kbts_ByteSwapArray16(Array, Count, Context->FileEnd); Context->Error |= !Result; return Result; } static int kbts_ByteSwapArray32Context(kbts_u32 *Array, kbts_un Count, kbts_byteswap_context *Context) { int Result = kbts_ByteSwapArray32(Array, Count, Context->FileEnd); Context->Error |= !Result; return Result; } typedef struct kbts_cover_glyph_result { kbts_u32 Valid; kbts_u32 Index; } kbts_cover_glyph_result; static int kbts_LookupBeginsWithCoverage(kbts_shaping_table ShapingTable, kbts_u16 LookupType, kbts_u16 Format) { int Result = 0; if(ShapingTable == KBTS_SHAPING_TABLE_GSUB) { Result = (LookupType != 7) && (Format != 3); } else { Result = (LookupType != 9) && (Format != 3); } return Result; } // Except for lookup tables 5.3, 6.3 and 7, all tables begin with (kbts_u16 Format, kbts_u16 CoverageOffset). KBTS_INLINE int kbts_GsubLookupBeginsWithCoverage(kbts_u16 LookupType, kbts_u16 Format) { int Result = kbts_LookupBeginsWithCoverage(KBTS_SHAPING_TABLE_GSUB, LookupType, Format); return Result; } KBTS_INLINE int kbts_GposLookupBeginsWithCoverage(kbts_u16 LookupType, kbts_u16 Format) { int Result = kbts_LookupBeginsWithCoverage(KBTS_SHAPING_TABLE_GPOS, LookupType, Format); return Result; } typedef struct kbts_lookup_info_frame { kbts_u16 *Base; kbts_u16 LookupType; kbts_u32 LookaheadOffset; kbts_u32 StackSize; } kbts_lookup_info_frame; static int kbts_PushLookup(kbts_gdef *Gdef, kbts_lookup_info_frame *Frames, kbts_un *FrameCount, kbts_un FrameCapacity, kbts_lookup *PackedLookup, kbts_u32 LookaheadOffset, kbts_un StackSize) { int Result = 0; kbts_unpacked_lookup Lookup = kbts_UnpackLookup(Gdef, PackedLookup); if((*FrameCount + Lookup.SubtableCount) <= FrameCapacity) { KBTS_FOR(SubtableIndex, 0, Lookup.SubtableCount) { kbts_lookup_info_frame *Frame = &Frames[(*FrameCount)++]; Frame->Base = KBTS_POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[SubtableIndex]); Frame->LookupType = Lookup.Type; Frame->LookaheadOffset = LookaheadOffset; Frame->StackSize = (kbts_u32)StackSize; } Result = 1; } return Result; } static int kbts_AlreadyVisited(kbts_byteswap_context *Context, void *Pointer) { int Result = !Pointer || Context->Error; if(!Result) { kbts_u32 *Pointers = Context->Pointers; kbts_u32 Pointer32 = KBTS_POINTER_DIFF32(Pointer, Context->FileBase); kbts_un Index = 0; if(Context->PointerCount) { kbts_un PointerCount = Context->PointerCount; if(PointerCount) { while(PointerCount > 1) { kbts_un HalfCount = PointerCount / 2; Index = (Pointers[Index + HalfCount - 1] < Pointer32) ? (Index + HalfCount) : Index; PointerCount -= HalfCount; } Result = (Pointer32 == Pointers[Index]); } } if(!Result && (Context->PointerCount < Context->PointerCapacity)) { while((Index < Context->PointerCount) && (Pointers[Index] < Pointer32)) ++Index; for(kbts_un GrowIndex = Context->PointerCount; GrowIndex > Index; --GrowIndex) { Pointers[GrowIndex] = Pointers[GrowIndex - 1]; } Pointers[Index] = Pointer32; Context->PointerCount += 1; } } return Result; } static void kbts_ByteSwapFeature(kbts_byteswap_context *Context, kbts_feature *Feature) { if(!kbts_AlreadyVisited(Context, Feature)) { kbts_u16 *LookupIndices = KBTS_POINTER_AFTER(kbts_u16, Feature); Context->Error |= !kbts_ByteSwapArray16(&Feature->FeatureParamsOffset, 2, Context->FileEnd); Context->Error |= !kbts_ByteSwapArray16(LookupIndices, Feature->LookupIndexCount, Context->FileEnd); // We require lookup indices to be sorted per feature for the lookup application order to match Harfbuzz. // Lookup indices are _typically_ sorted per feature, but we can't assume it is always the case. kbts_un LookupIndexCount = Feature->LookupIndexCount; KBTS_FOR(Iter, 0, LookupIndexCount) { KBTS_FOR(IndexIndex, 1, LookupIndexCount) { kbts_u16 Left = LookupIndices[IndexIndex - 1]; kbts_u16 Right = LookupIndices[IndexIndex]; if(Left > Right) { LookupIndices[IndexIndex - 1] = Right; LookupIndices[IndexIndex] = Left; } } } } # ifdef KBTS_DUMP kbts_u16 *LookupIndices = KBTS_POINTER_AFTER(kbts_u16, Feature); KBTS_FOR(LookupIndexIndex, 0, Feature->LookupIndexCount) { KBTS_DUMPF(" Lookup index %u\n", LookupIndices[LookupIndexIndex]); } # endif } static void kbts_ByteSwapGsubGposCommon(kbts_byteswap_context *Context, kbts_gsub_gpos *Header) { kbts_ByteSwapArray16Context(&Header->Major, 5, Context); if(Header->Minor == 1) { Header->FeatureVariationsOffset = kbts_ByteSwap32(Header->FeatureVariationsOffset); } kbts_script_list *ScriptList = KBTS_POINTER_OFFSET(kbts_script_list, Header, Header->ScriptListOffset); if(!kbts_AlreadyVisited(Context, ScriptList)) { ScriptList->Count = kbts_ByteSwap16(ScriptList->Count); kbts_script_record *ScriptRecords = KBTS_POINTER_AFTER(kbts_script_record, ScriptList); KBTS_FOR(It, 0, ScriptList->Count) { kbts_script_record *Record = &ScriptRecords[It]; Record->Offset = kbts_ByteSwap16(Record->Offset); KBTS_DUMPF("Script %.4s\n", (char *)&Record->Tag); kbts_ot_script *Script = KBTS_POINTER_OFFSET(kbts_ot_script, ScriptList, Record->Offset); if(!kbts_AlreadyVisited(Context, Script)) { Script->DefaultLangsysOffset = kbts_ByteSwap16(Script->DefaultLangsysOffset); Script->Count = kbts_ByteSwap16(Script->Count); kbts_langsys *DefaultLangsys = kbts_GetDefaultLangsys(Script); if(DefaultLangsys && !kbts_AlreadyVisited(Context, DefaultLangsys)) { kbts_ByteSwapArray16Context(&DefaultLangsys->LookupOrderOffset, 3, Context); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, DefaultLangsys), DefaultLangsys->FeatureIndexCount, Context); } kbts_langsys_record *LangsysRecords = KBTS_POINTER_AFTER(kbts_langsys_record, Script); KBTS_FOR(LangsysIndex, 0, Script->Count) { kbts_langsys_record *LangsysRecord = &LangsysRecords[LangsysIndex]; LangsysRecord->Offset = kbts_ByteSwap16(LangsysRecord->Offset); kbts_langsys *Langsys = KBTS_POINTER_OFFSET(kbts_langsys, Script, LangsysRecord->Offset); if(!kbts_AlreadyVisited(Context, Langsys)) { kbts_ByteSwapArray16Context(&Langsys->LookupOrderOffset, 3, Context); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Langsys), Langsys->FeatureIndexCount, Context); } } # ifdef KBTS_DUMP if(DefaultLangsys) { KBTS_DUMPF(" Default langsys @ %zu\n", (char *)DefaultLangsys - Context->FileBase); KBTS_DUMPF(" Lookup order offset %u\n", DefaultLangsys->LookupOrderOffset); KBTS_DUMPF(" Required feature %u\n", DefaultLangsys->RequiredFeatureIndex); kbts_u16 *FeatureIndices = KBTS_POINTER_AFTER(kbts_u16, DefaultLangsys); KBTS_FOR(FeatureIndexIndex, 0, DefaultLangsys->FeatureIndexCount) { KBTS_DUMPF(" Feature %u\n", FeatureIndices[FeatureIndexIndex]); } } KBTS_FOR(LangsysIndex, 0, Script->Count) { kbts_langsys_record *LangsysRecord = &LangsysRecords[LangsysIndex]; kbts_langsys *Langsys = KBTS_POINTER_OFFSET(kbts_langsys, Script, LangsysRecord->Offset); KBTS_DUMPF(" Langsys %.4s @ %zu\n", (char *)&LangsysRecord->Tag, (char *)Script + LangsysRecord->Offset - Context->FileBase); KBTS_DUMPF(" Lookup order offset %u\n" " Required feature %u\n", Langsys->LookupOrderOffset, Langsys->RequiredFeatureIndex); kbts_u16 *FeatureIndices = KBTS_POINTER_AFTER(kbts_u16, Langsys); KBTS_FOR(FeatureIndexIndex, 0, Langsys->FeatureIndexCount) { KBTS_DUMPF(" Feature %u\n", FeatureIndices[FeatureIndexIndex]); } } # endif } } if((Header->Minor == 1) && Header->FeatureVariationsOffset) { kbts_feature_variations *FeatureVariations = KBTS_POINTER_OFFSET(kbts_feature_variations, Header, Header->FeatureVariationsOffset); if(!kbts_AlreadyVisited(Context, FeatureVariations)) { kbts_ByteSwapArray16Context(&FeatureVariations->Major, 2, Context); FeatureVariations->RecordCount = kbts_ByteSwap32(FeatureVariations->RecordCount); kbts_feature_variation_record *Records = KBTS_POINTER_AFTER(kbts_feature_variation_record, FeatureVariations); KBTS_FOR(VariationIndex, 0, FeatureVariations->RecordCount) { kbts_feature_variation_record *Record = &Records[VariationIndex]; kbts_ByteSwapArray32Context(&Record->ConditionSetOffset, 2, Context); kbts_condition_set *Set = KBTS_POINTER_OFFSET(kbts_condition_set, FeatureVariations, Record->ConditionSetOffset); if(!kbts_AlreadyVisited(Context, Set)) { Set->Count = kbts_ByteSwap16(Set->Count); kbts_u32 *ConditionOffsets = KBTS_POINTER_AFTER(kbts_u32, Set); kbts_ByteSwapArray32Context(ConditionOffsets, Set->Count, Context); KBTS_FOR(ConditionIndex, 0, Set->Count) { kbts_condition_1 *Condition = KBTS_POINTER_OFFSET(kbts_condition_1, Set, ConditionOffsets[ConditionIndex]); if(!kbts_AlreadyVisited(Context, Condition)) { kbts_ByteSwapArray16Context(&Condition->Format, 4, Context); } } kbts_feature_table_substitution *FeatureSubst = KBTS_POINTER_OFFSET(kbts_feature_table_substitution, FeatureVariations, Record->FeatureTableSubstitutionOffset); if(!kbts_AlreadyVisited(Context, FeatureSubst)) { kbts_ByteSwapArray16Context(&FeatureSubst->Major, 3, Context); kbts_feature_table_substitution_record *SubstRecords = KBTS_POINTER_AFTER(kbts_feature_table_substitution_record, FeatureSubst); KBTS_FOR(SubstRecordIndex, 0, FeatureSubst->Count) { kbts_feature_table_substitution_record *SubstRecord = &SubstRecords[SubstRecordIndex]; SubstRecord->FeatureIndex = kbts_ByteSwap16(SubstRecord->FeatureIndex); kbts_feature *Feature = KBTS_POINTER_OFFSET(kbts_feature, FeatureSubst, SubstRecord->AlternateFeatureOffset); kbts_ByteSwapFeature(Context, Feature); } } } } } } } kbts_feature_list *FeatureList = KBTS_POINTER_OFFSET(kbts_feature_list, Header, Header->FeatureListOffset); if(!kbts_AlreadyVisited(Context, FeatureList)) { FeatureList->Count = kbts_ByteSwap16(FeatureList->Count); kbts_feature_record *FeatureRecords = KBTS_POINTER_AFTER(kbts_feature_record, FeatureList); KBTS_FOR(FeatureRecordIndex, 0, FeatureList->Count) { kbts_feature_record *FeatureRecord = &FeatureRecords[FeatureRecordIndex]; KBTS_DUMPF("Feature %llu %.4s\n", FeatureRecordIndex, (char *)&FeatureRecord->Tag); if(!kbts_AlreadyVisited(Context, FeatureRecord)) { FeatureRecord->Offset = kbts_ByteSwap16(FeatureRecord->Offset); kbts_feature *Feature = KBTS_POINTER_OFFSET(kbts_feature, FeatureList, FeatureRecord->Offset); kbts_ByteSwapFeature(Context, Feature); } } } } static int kbts_ByteSwapLookup(kbts_byteswap_context *Context, kbts_lookup *Lookup) { int Result = 0; if(!kbts_AlreadyVisited(Context, Lookup)) { Result = 1; kbts_ByteSwapArray16Context(&Lookup->Type, 3, Context); kbts_u16 *SubtableOffsets = KBTS_POINTER_AFTER(kbts_u16, Lookup); kbts_un U16Count = Lookup->SubtableCount; if(Lookup->Flag & KBTS_LOOKUP_FLAG_USE_MARK_FILTERING_SET) { U16Count += 1; } kbts_ByteSwapArray16Context(SubtableOffsets, U16Count, Context); } return Result; } static void kbts_ByteSwapCoverage(kbts_byteswap_context *Context, kbts_coverage *Coverage) { if(!kbts_AlreadyVisited(Context, Coverage)) { kbts_ByteSwapArray16Context(&Coverage->Format, 2, Context); kbts_un U16Count = 0; if(Coverage->Format == 1) { U16Count = Coverage->Count; } else if(Coverage->Format == 2) { U16Count = Coverage->Count * 3; } kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Coverage), U16Count, Context); } } static void kbts_ByteSwapAnchor(kbts_byteswap_context *Context, kbts_anchor *Anchor) { if(!kbts_AlreadyVisited(Context, Anchor)) { Anchor->Format = kbts_ByteSwap16(Anchor->Format); kbts_un U16Count = 2; if(Anchor->Format == 2) { U16Count = 3; } else if(Anchor->Format == 3) { U16Count = 4; } kbts_ByteSwapArray16Context((kbts_u16 *)&Anchor->X, U16Count, Context); } } static void kbts_ByteSwapBaseArray(kbts_byteswap_context *Context, kbts_u16 MarkClassCount, kbts_base_array *Array) { if(!kbts_AlreadyVisited(Context, Array)) { Array->BaseCount = kbts_ByteSwap16(Array->BaseCount); kbts_u16 *BaseAnchorOffsets = KBTS_POINTER_AFTER(kbts_u16, Array); kbts_ByteSwapArray16Context(BaseAnchorOffsets, Array->BaseCount * MarkClassCount, Context); KBTS_FOR(OffsetIndex, 0, (kbts_un)Array->BaseCount * MarkClassCount) { kbts_u16 Offset = BaseAnchorOffsets[OffsetIndex]; if(Offset) { kbts_ByteSwapAnchor(Context, KBTS_POINTER_OFFSET(kbts_anchor, Array, Offset)); } } } } static void kbts_ByteSwapDevice(kbts_byteswap_context *Context, kbts_device *Device) { if(!kbts_AlreadyVisited(Context, Device)) { kbts_ByteSwapArray16Context(&Device->U.Device.StartSize, 3, Context); if(Device->DeltaFormat <= 3) { // @Incomplete } } } static kbts_unpacked_value_record kbts_ByteSwapValueRecord(kbts_byteswap_context *Context, void *Parent, kbts_u16 ValueFormat, kbts_u16 *Record) { kbts_unpacked_value_record Result = KBTS_ZERO; if(ValueFormat) { kbts_un U16Count = kbts_PopCount32(ValueFormat); kbts_ByteSwapArray16Context(Record, U16Count, Context); Result = kbts_UnpackValueRecord(Parent, ValueFormat, Record); kbts_ByteSwapDevice(Context, Result.PlacementXDevice); kbts_ByteSwapDevice(Context, Result.PlacementYDevice); kbts_ByteSwapDevice(Context, Result.AdvanceXDevice); kbts_ByteSwapDevice(Context, Result.AdvanceYDevice); } return Result; } static void kbts_ByteSwapMarkArray(kbts_byteswap_context *Context, kbts_mark_array *MarkArray) { if(!kbts_AlreadyVisited(Context, MarkArray)) { MarkArray->Count = kbts_ByteSwap16(MarkArray->Count); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, MarkArray), MarkArray->Count * 2, Context); kbts_mark_record *MarkRecords = KBTS_POINTER_AFTER(kbts_mark_record, MarkArray); KBTS_FOR(MarkRecordIndex, 0, MarkArray->Count) { kbts_mark_record *MarkRecord = &MarkRecords[MarkRecordIndex]; kbts_ByteSwapAnchor(Context, KBTS_POINTER_OFFSET(kbts_anchor, MarkArray, MarkRecord->AnchorOffset)); } } } static void kbts_ByteSwapChainedSequenceRuleSet(kbts_byteswap_context *Context, kbts_chained_sequence_rule_set *Set) { if(Set && !kbts_AlreadyVisited(Context, Set)) { Set->Count = kbts_ByteSwap16(Set->Count); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Set), Set->Count, Context); KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_chained_sequence_rule *Rule = kbts_GetChainedSequenceRule(Set, RuleIndex); if(!kbts_AlreadyVisited(Context, Rule)) { kbts_unpacked_chained_sequence_rule Unpacked = kbts_UnpackChainedSequenceRule(Rule, 1); kbts_un U16Count = Unpacked.BacktrackCount + Unpacked.InputCount + Unpacked.LookaheadCount + Unpacked.RecordCount * 2 + 3; kbts_ByteSwapArray16Context(&Rule->BacktrackGlyphCount, U16Count, Context); } } } } #ifdef KBTS_DUMP static void kbts_DumpClassDefinition(kbts_u16 *Base) { if(*Base == 1) { kbts_class_definition_1 *ClassDef = (kbts_class_definition_1 *)Base; kbts_u16 *ClassValues = KBTS_POINTER_AFTER(kbts_u16, ClassDef); KBTS_FOR(GlyphIndex, 0, ClassDef->GlyphCount) { KBTS_DUMPF("%llx -> %u\n", ClassDef->StartGlyphId + GlyphIndex, ClassValues[GlyphIndex]); } } else if(*Base == 2) { kbts_class_definition_2 *ClassDef = (kbts_class_definition_2 *)Base; kbts_class_range_record *Ranges = KBTS_POINTER_AFTER(kbts_class_range_record, ClassDef); KBTS_FOR(RangeIndex, 0, ClassDef->Count) { kbts_class_range_record *Range = &Ranges[RangeIndex]; KBTS_DUMPF("[%x..%x] -> %u\n", Range->StartGlyphId, Range->EndGlyphId, Range->Class); } } } #endif static void kbts_ByteSwapClassDefinition(kbts_byteswap_context *Context, kbts_u16 *Base) { if(!kbts_AlreadyVisited(Context, Base)) { *Base = kbts_ByteSwap16(*Base); if(*Base == 1) { kbts_class_definition_1 *ClassDef = (kbts_class_definition_1 *)Base; kbts_ByteSwapArray16Context(&ClassDef->StartGlyphId, 2, Context); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, ClassDef), ClassDef->GlyphCount, Context); } else if(*Base == 2) { kbts_class_definition_2 *ClassDef = (kbts_class_definition_2 *)Base; ClassDef->Count = kbts_ByteSwap16(ClassDef->Count); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, ClassDef), ClassDef->Count * 3, Context); } } } typedef struct kbts_glyph_class_from_table_result { int Found; kbts_u16 Class; } kbts_glyph_class_from_table_result; static kbts_glyph_class_from_table_result kbts_GlyphClassFromTable(kbts_u16 *ClassDefinitionBase, kbts_un Id) { kbts_glyph_class_from_table_result Result = KBTS_ZERO; // From the Microsoft docs: // There is one offset to a ChainedClassSequenceRuleSet subtable for each class defined in the input sequence // class definition table. The offsets are listed in class value order. // This means that we do not actually care what the class _values_ are. We only care about the classes' relative // values. // Also from the Microsoft docs, about class definition tables: // A class definition table (ClassDef) assigns glyphs into classes, beginning with Class 1, then Class 2, and so // on. All glyphs not assigned to a class fall into Class 0. // So, we should be able to pretty reliably just subtract 1 from the class to get. if(*ClassDefinitionBase == 1) { kbts_class_definition_1 *ClassDef = (kbts_class_definition_1 *)ClassDefinitionBase; kbts_u16 *GlyphClasses = KBTS_POINTER_AFTER(kbts_u16, ClassDef); kbts_un Offset = Id - ClassDef->StartGlyphId; if(Offset < ClassDef->GlyphCount) { Result.Class = GlyphClasses[Offset]; Result.Found = 1; } } else if(*ClassDefinitionBase == 2) { kbts_class_definition_2 *ClassDef = (kbts_class_definition_2 *)ClassDefinitionBase; kbts_class_range_record *Ranges = KBTS_POINTER_AFTER(kbts_class_range_record, ClassDef); kbts_un RangeCount = ClassDef->Count; if(RangeCount) { while(RangeCount > 1) { kbts_un HalfCount = RangeCount / 2; Ranges = (Ranges[HalfCount - 1].EndGlyphId < Id) ? (Ranges + HalfCount) : Ranges; RangeCount -= HalfCount; } if((Id >= Ranges->StartGlyphId) && (Id <= Ranges->EndGlyphId)) { Result.Class = Ranges->Class; Result.Found = 1; } } } return Result; } static kbts_cover_glyph_result kbts_CoverGlyph(kbts_coverage *Coverage, kbts_u32 GlyphId) { KBTS_INSTRUMENT_FUNCTION_BEGIN kbts_cover_glyph_result Result = KBTS_ZERO; kbts_un Count = Coverage->Count; if(Count) { if(Coverage->Format == 1) { kbts_u16 *GlyphIds = KBTS_POINTER_AFTER(kbts_u16, Coverage); while(Count > 1) { kbts_un HalfCount = Count / 2; GlyphIds = (GlyphIds[HalfCount - 1] < GlyphId) ? (GlyphIds + HalfCount) : GlyphIds; Count -= HalfCount; } if(GlyphId == *GlyphIds) { Result.Valid = 1; Result.Index = (kbts_u32)(GlyphIds - KBTS_POINTER_AFTER(kbts_u16, Coverage)); } } else if(Coverage->Format == 2) { kbts_range_record *Ranges = KBTS_POINTER_AFTER(kbts_range_record, Coverage); while(Count > 1) { kbts_un HalfCount = Count / 2; Ranges = (Ranges[HalfCount - 1].EndGlyphId < GlyphId) ? (Ranges + HalfCount) : Ranges; Count -= HalfCount; } if((GlyphId >= Ranges->StartGlyphId) && (GlyphId <= Ranges->EndGlyphId)) { Result.Valid = 1; Result.Index = Ranges->StartCoverageIndex + GlyphId - Ranges->StartGlyphId; } } } KBTS_INSTRUMENT_END return Result; } static void kbts_ByteSwapSequenceContextSubtable(kbts_byteswap_context *Context, kbts_u16 *Base) { if(Base[0] == 1) { kbts_sequence_context_1 *Subst = (kbts_sequence_context_1 *)Base; Subst->SeqRuleSetCount = kbts_ByteSwap16(Subst->SeqRuleSetCount); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->SeqRuleSetCount, Context); KBTS_FOR(SetIndex, 0, Subst->SeqRuleSetCount) { kbts_sequence_rule_set *Set = kbts_GetSequenceRuleSet(Subst, SetIndex); if(Set && !kbts_AlreadyVisited(Context, Set)) { Set->Count = kbts_ByteSwap16(Set->Count); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Set), Set->Count, Context); KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_sequence_rule *Rule = kbts_GetSequenceRule(Set, RuleIndex); if(!kbts_AlreadyVisited(Context, Rule)) { kbts_ByteSwapArray16Context(&Rule->GlyphCount, 2, Context); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Rule), (kbts_un)Rule->GlyphCount - 1 + (kbts_un)Rule->SequenceLookupCount * 2, Context); } } } } } else if(Base[0] == 2) { kbts_sequence_context_2 *Subst = (kbts_sequence_context_2 *)Base; kbts_ByteSwapArray16Context(&Subst->ClassDefOffset, 2, Context); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->ClassSequenceRuleSetCount, Context); kbts_u16 *ClassDefBase = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->ClassDefOffset); kbts_ByteSwapClassDefinition(Context, ClassDefBase); KBTS_FOR(SetIndex, 0, Subst->ClassSequenceRuleSetCount) { kbts_class_sequence_rule_set *Set = kbts_GetClassSequenceRuleSet(Subst, SetIndex); if(Set && !kbts_AlreadyVisited(Context, Set)) { Set->Count = kbts_ByteSwap16(Set->Count); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Set), Set->Count, Context); KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_class_sequence_rule *Rule = kbts_GetClassSequenceRule(Set, RuleIndex); if(!kbts_AlreadyVisited(Context, Rule)) { kbts_ByteSwapArray16Context(&Rule->GlyphCount, 2, Context); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Rule), Rule->GlyphCount - 1 + 2 * Rule->SequenceLookupCount, Context); } } } } #ifdef KBTS_DUMP kbts_DumpClassDefinition(ClassDefBase); KBTS_FOR(SetIndex, 0, Subst->ClassSequenceRuleSetCount) { kbts_class_sequence_rule_set *Set = kbts_GetClassSequenceRuleSet(Subst, SetIndex); if(Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_class_sequence_rule *Rule = kbts_GetClassSequenceRule(Set, RuleIndex); kbts_u16 *InputSequence = KBTS_POINTER_AFTER(kbts_u16, Rule); kbts_sequence_lookup_record *Records = (kbts_sequence_lookup_record *)(InputSequence + Rule->GlyphCount - 1); KBTS_DUMPF("Input: ["); KBTS_FOR(GlyphIndex, 1, Rule->GlyphCount) { KBTS_DUMPF(", %x", InputSequence[GlyphIndex - 1]); } KBTS_DUMPF("]\nRecords: ["); KBTS_FOR(RecordIndex, 0, Rule->SequenceLookupCount) { kbts_sequence_lookup_record *Record = &Records[RecordIndex]; if(RecordIndex) KBTS_DUMPF(", "); KBTS_DUMPF("%u@%u", Record->LookupListIndex, Record->SequenceIndex); } KBTS_DUMPF("]\n"); } } } #endif } else if(Base[0] == 3) { kbts_sequence_context_3 *Subst = (kbts_sequence_context_3 *)Base; kbts_ByteSwapArray16Context(&Subst->GlyphCount, 2, Context); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->GlyphCount + 2 * Subst->SequenceLookupCount, Context); kbts_u16 *CoverageOffsets = KBTS_POINTER_AFTER(kbts_u16, Subst); KBTS_FOR(CoverageIndex, 0, Subst->GlyphCount) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Subst, CoverageOffsets[CoverageIndex]); kbts_ByteSwapCoverage(Context, Coverage); } } } typedef kbts_u32 kbts_skip_flags; enum kbts_skip_flags_enum { KBTS_SKIP_FLAG_NONE, KBTS_SKIP_FLAG_ZWNJ = (1 << 0), KBTS_SKIP_FLAG_ZWJ = (1 << 1), }; // The Harfbuzz behavior is: // - GPOS lookups always skip ZWNJ. // - Sequence lookups always skip ZWJ. // - GSUB sequence lookups skip ZWNJ when requested. // - Regular lookups skip ZWJ when requested. #define KBTS_SKIP_FLAGS_GSUB_REGULAR(RequestedFlags) ((RequestedFlags) & KBTS_SKIP_FLAG_ZWJ) #define KBTS_SKIP_FLAGS_GSUB_SEQUENCE(RequestedFlags) (KBTS_SKIP_FLAG_ZWJ | ((RequestedFlags) & KBTS_SKIP_FLAG_ZWNJ)) #define KBTS_SKIP_FLAGS_GPOS_REGULAR(RequestedFlags) (((RequestedFlags) & KBTS_SKIP_FLAG_ZWJ) | KBTS_SKIP_FLAG_ZWNJ) #define KBTS_SKIP_FLAGS_GPOS_SEQUENCE(RequestedFlags) (KBTS_SKIP_FLAG_ZWJ | KBTS_SKIP_FLAG_ZWNJ) static kbts_skip_flags kbts_SkipFlags(kbts_feature_id FeatureId, kbts_shaper Shaper) { kbts_skip_flags Result = 0; switch(FeatureId) { case KBTS_FEATURE_ID_nukt: case KBTS_FEATURE_ID_akhn: case KBTS_FEATURE_ID_rphf: case KBTS_FEATURE_ID_rkrf: case KBTS_FEATURE_ID_pref: case KBTS_FEATURE_ID_blwf: case KBTS_FEATURE_ID_abvf: case KBTS_FEATURE_ID_half: case KBTS_FEATURE_ID_pstf: case KBTS_FEATURE_ID_vatu: case KBTS_FEATURE_ID_cjct: case KBTS_FEATURE_ID_pres: case KBTS_FEATURE_ID_abvs: case KBTS_FEATURE_ID_blws: case KBTS_FEATURE_ID_psts: case KBTS_FEATURE_ID_haln: Result = (Shaper == KBTS_SHAPER_INDIC) ? 0 : KBTS_SKIP_FLAG_ZWNJ | KBTS_SKIP_FLAG_ZWJ; break; case KBTS_FEATURE_ID_init: if (Shaper == KBTS_SHAPER_INDIC) {Result = 0;} else if(Shaper == KBTS_SHAPER_ARABIC) {Result = KBTS_SKIP_FLAG_ZWNJ;} else {Result = KBTS_SKIP_FLAG_ZWNJ | KBTS_SKIP_FLAG_ZWJ;} break; case KBTS_FEATURE_ID_ccmp: case KBTS_FEATURE_ID_locl: case KBTS_FEATURE_ID_isol: case KBTS_FEATURE_ID_fina: case KBTS_FEATURE_ID_fin2: case KBTS_FEATURE_ID_fin3: case KBTS_FEATURE_ID_medi: case KBTS_FEATURE_ID_med2: case KBTS_FEATURE_ID_calt: case KBTS_FEATURE_ID_liga: case KBTS_FEATURE_ID_clig: case KBTS_FEATURE_ID_rlig: case KBTS_FEATURE_ID_mset: Result = (Shaper == KBTS_SHAPER_ARABIC) ? KBTS_SKIP_FLAG_ZWNJ : KBTS_SKIP_FLAG_ZWNJ | KBTS_SKIP_FLAG_ZWJ; break; case KBTS_FEATURE_ID_mark: case KBTS_FEATURE_ID_mkmk: Result = 0; break; default: Result = KBTS_SKIP_FLAG_ZWNJ | KBTS_SKIP_FLAG_ZWJ; break; } return Result; } static kbts_u32 kbts_GlyphIncludedInLookup(kbts_font *Font, int Gpos, kbts_un LookupIndex, kbts_u32 Id) { kbts_u32 Result = 1; if(Font->GlyphLookupMatrix && (Id < Font->GlyphCount)) { kbts_un FlatLookupIndex = (Gpos ? Font->GposLookupIndexOffset : 0) + LookupIndex; kbts_un FlatIndex = FlatLookupIndex * Font->Maxp->GlyphCount + Id; kbts_un WordIndex = FlatIndex / 32; kbts_un BitIndex = FlatIndex % 32; Result = Font->GlyphLookupMatrix[WordIndex] & (1 << BitIndex); } return Result; } static int kbts_GlyphPassesLookupFilter(kbts_glyph *Glyph, kbts_unpacked_lookup *Lookup) { int Result = 1; kbts_u16 Class = Glyph->Classes.Class; if(Class && (Lookup->Flags & (1 << Class))) { Result = 0; } if(Result && (Class == KBTS_GLYPH_CLASS_MARK)) { if(Lookup->Flags & KBTS_LOOKUP_FLAG_MARK_ATTACHMENT_CLASS_FILTER) { kbts_u32 DesiredMarkAttachmentClass = Lookup->Flags >> 8; if(Glyph->Classes.MarkAttachmentClass != DesiredMarkAttachmentClass) { Result = 0; } } if(Result && Lookup->MarkFilteringSet) { // @Speed: We may want to save the result of the last mark filtering test on the glyph itself. kbts_cover_glyph_result Cover = kbts_CoverGlyph(Lookup->MarkFilteringSet, Glyph->Id); if(!Cover.Valid) { Result = 0; } } } return Result; } static int kbts_SkipGlyph(kbts_glyph *Glyph, kbts_unpacked_lookup *Lookup, kbts_skip_flags SkipFlags, kbts_u32 SkipUnicodeFlags) { int Result = (Glyph->UnicodeFlags & SkipUnicodeFlags) || ((SkipFlags & KBTS_SKIP_FLAG_ZWNJ) && (Glyph->Codepoint == 0x200C)) || ((SkipFlags & KBTS_SKIP_FLAG_ZWJ) && (Glyph->Codepoint == 0x200D)) || !kbts_GlyphPassesLookupFilter(Glyph, Lookup); return Result; } static int kbts_GlyphsIncludedInLookupSubtable(kbts_font *Font, int Gpos, kbts_unpacked_lookup *Lookup, kbts_un LookupIndex, kbts_un SubtableIndex, kbts_glyph_array *Array, kbts_un CurrentGlyphIndex, kbts_skip_flags SkipFlags, kbts_unicode_flags SkipUnicodeFlags) { if(Font->GlyphLookupSubtableMatrix) { kbts_un FlatLookupIndex = (Gpos ? Font->GposLookupIndexOffset : 0) + LookupIndex; kbts_un FlatSubtableIndex = Font->LookupSubtableIndexOffsets[FlatLookupIndex] + SubtableIndex; kbts_un MatrixRowOffset = FlatSubtableIndex * Font->Maxp->GlyphCount; kbts_lookup_subtable_info *Info = &Font->SubtableInfos[FlatSubtableIndex]; kbts_un MinimumBacktrack = (Info->MinimumBacktrackPlusOne) ? Info->MinimumBacktrackPlusOne - 1 : 0; kbts_un MinimumFollowup = (Info->MinimumFollowupPlusOne) ? Info->MinimumFollowupPlusOne - 1 : 0; kbts_un GlyphCount = Font->GlyphCount; if((MinimumBacktrack <= CurrentGlyphIndex) && (MinimumFollowup <= (Array->Count - CurrentGlyphIndex))) { { // Check the current glyph. kbts_un Id = Array->Glyphs[CurrentGlyphIndex].Id; kbts_un FlatIndex = MatrixRowOffset + Id; kbts_un WordIndex = FlatIndex / 32; kbts_un BitIndex = FlatIndex % 32; if(Id >= GlyphCount) { return 1; } else if(!(Font->GlyphLookupSubtableMatrix[WordIndex] & (1 << BitIndex))) { return 0; } } { kbts_un BacktrackCounter = 0; kbts_glyph *BacktrackGlyph = &Array->Glyphs[CurrentGlyphIndex - 1]; while((BacktrackGlyph >= Array->Glyphs) && (BacktrackCounter < MinimumBacktrack)) { kbts_un FlatIndex = MatrixRowOffset + BacktrackGlyph->Id; kbts_un WordIndex = FlatIndex / 32; kbts_un BitIndex = FlatIndex % 32; if(BacktrackGlyph->Id >= GlyphCount) { return 1; } else if(Font->GlyphLookupSubtableMatrix[WordIndex] & (1 << BitIndex)) { BacktrackCounter += 1; } else if(!kbts_SkipGlyph(BacktrackGlyph, Lookup, SkipFlags, SkipUnicodeFlags)) { return 0; } BacktrackGlyph -= 1; } if(BacktrackCounter < MinimumBacktrack) { return 0; } } { kbts_un LookaheadCounter = 0; kbts_glyph *LookaheadGlyph = &Array->Glyphs[CurrentGlyphIndex + 1]; kbts_glyph *OnePastLastGlyph = Array->Glyphs + Array->Count; while((LookaheadGlyph < OnePastLastGlyph) && (LookaheadCounter < MinimumFollowup)) { kbts_un FlatIndex = MatrixRowOffset + LookaheadGlyph->Id; kbts_un WordIndex = FlatIndex / 32; kbts_un BitIndex = FlatIndex % 32; if(LookaheadGlyph->Id >= GlyphCount) { return 1; } else if(Font->GlyphLookupSubtableMatrix[WordIndex] & (1 << BitIndex)) { LookaheadCounter += 1; } else if(!kbts_SkipGlyph(LookaheadGlyph, Lookup, SkipFlags, SkipUnicodeFlags)) { return 0; } LookaheadGlyph += 1; } if(LookaheadCounter < MinimumFollowup) { return 0; } } } else { return 0; } } return 1; } # ifdef KBTS_DUMP static void kbts_DumpCoverage(kbts_coverage *Coverage) { KBTS_DUMPF("["); if(Coverage->Format == 1) { kbts_u16 *GlyphIds = KBTS_POINTER_AFTER(kbts_u16, Coverage); KBTS_FOR(GlyphIndex, 0, Coverage->Count) { KBTS_DUMPF("%x,", GlyphIds[GlyphIndex]); } } else if(Coverage->Format == 2) { kbts_range_record *Ranges = KBTS_POINTER_AFTER(kbts_range_record, Coverage); KBTS_FOR(RangeIndex, 0, Coverage->Count) { kbts_range_record *Range = &Ranges[RangeIndex]; KBTS_DUMPF("%x..%x @ %u,", Range->StartGlyphId, Range->EndGlyphId, Range->StartCoverageIndex); } } KBTS_DUMPF("]"); } # endif static void kbts_ByteSwapChainedSequenceContextSubtable(kbts_byteswap_context *Context, kbts_u16 *Base) { if(Base[0] == 1) { kbts_chained_sequence_context_1 *Subst = (kbts_chained_sequence_context_1 *)Base; Subst->ChainedSequenceRuleSetCount = kbts_ByteSwap16(Subst->ChainedSequenceRuleSetCount); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->ChainedSequenceRuleSetCount, Context); KBTS_FOR(SetIndex, 0, Subst->ChainedSequenceRuleSetCount) { kbts_ByteSwapChainedSequenceRuleSet(Context, kbts_GetChainedSequenceRuleSet(Subst, SetIndex)); } } else if(Base[0] == 2) { kbts_chained_sequence_context_2 *Subst = (kbts_chained_sequence_context_2 *)Base; kbts_ByteSwapArray16Context(&Subst->BacktrackClassDefOffset, 4, Context); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->ChainedClassSequenceRuleSetCount, Context); kbts_u16 *BacktrackClassDefinition = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->BacktrackClassDefOffset); kbts_ByteSwapClassDefinition(Context, BacktrackClassDefinition); kbts_u16 *InputClassDefinition = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->InputClassDefOffset); kbts_ByteSwapClassDefinition(Context, InputClassDefinition); kbts_u16 *LookaheadClassDefinition = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->LookaheadClassDefOffset); kbts_ByteSwapClassDefinition(Context, LookaheadClassDefinition); #ifdef KBTS_DUMP KBTS_DUMPF("Backtrack classes:\n"); // kbts_DumpClassDefinition(BacktrackClassDefinition); KBTS_DUMPF("Input classes:\n"); // kbts_DumpClassDefinition(InputClassDefinition); KBTS_DUMPF("Lookahead classes:\n"); // kbts_DumpClassDefinition(LookaheadClassDefinition); #endif KBTS_FOR(SetIndex, 0, Subst->ChainedClassSequenceRuleSetCount) { kbts_chained_sequence_rule_set *Set = kbts_GetChainedClassSequenceRuleSet(Subst, SetIndex); kbts_ByteSwapChainedSequenceRuleSet(Context, Set); #ifdef KBTS_DUMP if(Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_chained_sequence_rule *Rule = kbts_GetChainedClassSequenceRule(Set, RuleIndex); kbts_unpacked_chained_sequence_rule Unpacked = kbts_UnpackChainedSequenceRule(Rule, 0); KBTS_DUMPF("Backtrack: ["); KBTS_FOR(BacktrackIndex, 0, Unpacked.BacktrackCount) { if(BacktrackIndex) KBTS_DUMPF(", "); KBTS_DUMPF("%u", Unpacked.Backtrack[BacktrackIndex]); } KBTS_DUMPF("]\n" "Input: ["); KBTS_FOR(InputIndex, 1, Unpacked.InputCount) { if(InputIndex) KBTS_DUMPF(", "); KBTS_DUMPF("%u", Unpacked.Input[InputIndex - 1]); } KBTS_DUMPF("]\n" "Lookahead: ["); KBTS_FOR(LookaheadIndex, 0, Unpacked.LookaheadCount) { if(LookaheadIndex) KBTS_DUMPF(", "); KBTS_DUMPF("%u", Unpacked.Lookahead[LookaheadIndex]); } KBTS_DUMPF("]\n" "Records: ["); KBTS_FOR(RecordIndex, 0, Unpacked.RecordCount) { kbts_sequence_lookup_record *Record = &Unpacked.Records[RecordIndex]; if(RecordIndex) KBTS_DUMPF(", "); KBTS_DUMPF("%u@%u", Record->LookupListIndex, Record->SequenceIndex); } KBTS_DUMPF("]\n"); } } #endif } } else if(Base[0] == 3) { kbts_chained_sequence_context_3 *Subst = (kbts_chained_sequence_context_3 *)Base; kbts_unpacked_chained_sequence_context_3 Unpacked = kbts_UnpackChainedSequenceContext3(Subst, 1); kbts_un U16Count = Unpacked.BacktrackCount + Unpacked.InputCount + Unpacked.LookaheadCount + Unpacked.RecordCount * 2 + 4; kbts_ByteSwapArray16Context(&Subst->BacktrackGlyphCount, U16Count, Context); KBTS_FOR(BacktrackCoverageIndex, 0, Unpacked.BacktrackCount) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackCoverageIndex]); kbts_ByteSwapCoverage(Context, Coverage); } KBTS_FOR(InputCoverageIndex, 0, Unpacked.InputCount) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.InputCoverageOffsets[InputCoverageIndex]); kbts_ByteSwapCoverage(Context, Coverage); } KBTS_FOR(LookaheadCoverageIndex, 0, Unpacked.LookaheadCount) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadCoverageIndex]); kbts_ByteSwapCoverage(Context, Coverage); } # ifdef KBTS_DUMP KBTS_DUMPF(" Backtrack: "); KBTS_FOR(BacktrackCoverageIndex, 0, Unpacked.BacktrackCount) { kbts_DumpCoverage(KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackCoverageIndex])); } KBTS_DUMPF("\n Input: "); KBTS_FOR(InputCoverageIndex, 0, Unpacked.InputCount) { kbts_DumpCoverage(KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.InputCoverageOffsets[InputCoverageIndex])); } KBTS_DUMPF("\n Lookahead: "); KBTS_FOR(LookaheadCoverageIndex, 0, Unpacked.LookaheadCount) { kbts_DumpCoverage(KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadCoverageIndex])); } KBTS_DUMPF("\n Lookups: ["); KBTS_FOR(RecordIndex, 0, Unpacked.RecordCount) { kbts_sequence_lookup_record *Record = &Unpacked.Records[RecordIndex]; KBTS_DUMPF("%u@%u,", Record->LookupListIndex, Record->SequenceIndex); } KBTS_DUMPF("]\n"); # endif } } static void kbts_ByteSwapGsubLookupSubtable(kbts_byteswap_context *Context, kbts_u16 LookupType, kbts_u16 *Base) { int Swap = !kbts_AlreadyVisited(Context, Base); while(Swap && (LookupType == 7)) { kbts_extension *Subst = (kbts_extension *)Base; Subst->Format = kbts_ByteSwap16(Subst->Format); Subst->LookupType = kbts_ByteSwap16(Subst->LookupType); Subst->Offset = kbts_ByteSwap32(Subst->Offset); KBTS_DUMPF(" Type 7.1\n" " Offset %zu\n" " -> %zu\n", (char *)Base - Context->FileBase, (char *)Subst + Subst->Offset - Context->FileBase); Base = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->Offset); LookupType = Subst->LookupType; Swap = !kbts_AlreadyVisited(Context, Base); } if(Swap) { *Base = kbts_ByteSwap16(*Base); KBTS_DUMPF(" Type %u.%u\n" " Offset %zu\n", LookupType, *Base, (char *)Base - Context->FileBase); if(kbts_GsubLookupBeginsWithCoverage(LookupType, Base[0])) { Base[1] = kbts_ByteSwap16(Base[1]); kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Base, Base[1]); kbts_ByteSwapCoverage(Context, Coverage); # ifdef KBTS_DUMP KBTS_DUMPF(" Coverage %u\n", Coverage->Format); if(Coverage->Format == 1) { kbts_u16 *GlyphIds = KBTS_POINTER_AFTER(kbts_u16, Coverage); KBTS_FOR(GlyphIndex, 0, Coverage->Count) { KBTS_DUMPF(" %x\n", GlyphIds[GlyphIndex]); } } else if(Coverage->Format == 2) { kbts_range_record *Ranges = KBTS_POINTER_AFTER(kbts_range_record, Coverage); KBTS_FOR(RangeIndex, 0, Coverage->Count) { kbts_range_record Range = Ranges[RangeIndex]; KBTS_DUMPF(" %x..%x@%u..%u\n", Range.StartGlyphId, Range.EndGlyphId, Range.StartCoverageIndex, Range.StartCoverageIndex + (Range.EndGlyphId - Range.StartGlyphId)); } } # endif } switch(LookupType) { case 1: { kbts_single_substitution *Subst = (kbts_single_substitution *)Base; Subst->DeltaOrCount.GlyphCount = kbts_ByteSwap16(Subst->DeltaOrCount.GlyphCount); # ifdef KBTS_DUMP if(Subst->Format == 1) { KBTS_DUMPF(" += %d\n", Subst->DeltaOrCount.DeltaGlyphId); } # endif if(Subst->Format == 2) { kbts_u16 *GlyphIds = KBTS_POINTER_AFTER(kbts_u16, Subst); kbts_ByteSwapArray16Context(GlyphIds, Subst->DeltaOrCount.GlyphCount, Context); #ifdef KBTS_DUMP KBTS_DUMPF(" ["); KBTS_FOR(IdIndex, 0, Subst->DeltaOrCount.GlyphCount) { if(IdIndex) KBTS_DUMPF(" "); KBTS_DUMPF("%x", GlyphIds[IdIndex]); } KBTS_DUMPF("]\n"); #endif } } break; case 2: { kbts_multiple_substitution *Subst = (kbts_multiple_substitution *)Base; Subst->SequenceCount = kbts_ByteSwap16(Subst->SequenceCount); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->SequenceCount, Context); KBTS_FOR(SequenceIndex, 0, Subst->SequenceCount) { kbts_sequence *Sequence = kbts_GetSequence(Subst, SequenceIndex); if(!kbts_AlreadyVisited(Context, Sequence)) { Sequence->GlyphCount = kbts_ByteSwap16(Sequence->GlyphCount); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Sequence), Sequence->GlyphCount, Context); } #ifdef KBTS_DUMP KBTS_DUMPF(" ["); kbts_u16 *SequenceGlyphIds = KBTS_POINTER_AFTER(kbts_u16, Sequence); KBTS_FOR(SequenceGlyphIndex, 0, Sequence->GlyphCount) { if(SequenceGlyphIndex) KBTS_DUMPF(" "); KBTS_DUMPF("%x", SequenceGlyphIds[SequenceGlyphIndex]); } KBTS_DUMPF("]\n"); #endif } } break; case 3: { kbts_alternate_substitution *Subst = (kbts_alternate_substitution *)Base; Subst->AlternateSetCount = kbts_ByteSwap16(Subst->AlternateSetCount); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->AlternateSetCount, Context); KBTS_FOR(SetIndex, 0, Subst->AlternateSetCount) { kbts_alternate_set *Set = kbts_GetAlternateSet(Subst, SetIndex); if(!kbts_AlreadyVisited(Context, Set)) { Set->GlyphCount = kbts_ByteSwap16(Set->GlyphCount); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Set), Set->GlyphCount, Context); } #ifdef KBTS_DUMP KBTS_DUMPF(" ["); kbts_u16 *SetGlyphIds = KBTS_POINTER_AFTER(kbts_u16, Set); KBTS_FOR(SetGlyphIndex, 0, Set->GlyphCount) { if(SetGlyphIndex) KBTS_DUMPF(" "); KBTS_DUMPF("%x", SetGlyphIds[SetGlyphIndex]); } KBTS_DUMPF("]\n"); #endif } } break; case 4: { kbts_ligature_substitution *Subst = (kbts_ligature_substitution *)Base; Subst->LigatureSetCount = kbts_ByteSwap16(Subst->LigatureSetCount); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->LigatureSetCount, Context); KBTS_FOR(SetIndex, 0, Subst->LigatureSetCount) { kbts_ligature_set *Set = kbts_GetLigatureSet(Subst, SetIndex); if(!kbts_AlreadyVisited(Context, Set)) { Set->Count = kbts_ByteSwap16(Set->Count); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Set), Set->Count, Context); KBTS_FOR(LigatureIndex, 0, Set->Count) { kbts_ligature *Ligature = kbts_GetLigature(Set, LigatureIndex); if(!kbts_AlreadyVisited(Context, Ligature)) { kbts_ByteSwapArray16Context(&Ligature->Glyph, 2, Context); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Ligature), Ligature->ComponentCount - 1, Context); # ifdef KBTS_DUMP KBTS_DUMPF("ligature: ["); kbts_u16 *ComponentIds = KBTS_POINTER_AFTER(kbts_u16, Ligature); KBTS_FOR(ComponentIndex, 1, Ligature->ComponentCount) { KBTS_DUMPF("%x,", ComponentIds[ComponentIndex - 1]); } KBTS_DUMPF("] -> %x\n", Ligature->Glyph); # endif } } } } # ifdef KBTS_DUMP # endif } break; case 5: { kbts_ByteSwapSequenceContextSubtable(Context, Base); } break; case 6: { kbts_ByteSwapChainedSequenceContextSubtable(Context, Base); } break; case 8: { kbts_reverse_chain_substitution *Subst = (kbts_reverse_chain_substitution *)Base; kbts_unpacked_reverse_chain_substitution Unpacked = kbts_UnpackReverseChainSubstitution(Subst, 1); kbts_un U16Count = Unpacked.BacktrackCount + Unpacked.GlyphCount + Unpacked.LookaheadCount + 3; kbts_ByteSwapArray16Context(&Subst->BacktrackGlyphCount, U16Count, Context); KBTS_FOR(BacktrackCoverageIndex, 0, Unpacked.BacktrackCount) { kbts_ByteSwapCoverage(Context, KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackCoverageIndex])); } KBTS_FOR(LookaheadCoverageIndex, 0, Unpacked.LookaheadCount) { kbts_ByteSwapCoverage(Context, KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadCoverageIndex])); } } break; } } } static void kbts_ByteSwapGposLookupSubtable(kbts_byteswap_context *Context, kbts_lookup_list *LookupList, kbts_u16 LookupType, kbts_u16 *Base) { if(!kbts_AlreadyVisited(Context, Base)) { *Base = kbts_ByteSwap16(*Base); KBTS_DUMPF(" GPOS subtable %u.%u\n", LookupType, *Base); if(kbts_GposLookupBeginsWithCoverage(LookupType, *Base)) { kbts_u16 *CoverageOffset = &Base[1]; *CoverageOffset = kbts_ByteSwap16(*CoverageOffset); kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Base, *CoverageOffset); kbts_ByteSwapCoverage(Context, Coverage); } switch(LookupType) { case 1: { kbts_single_adjustment_1 *Adjust = (kbts_single_adjustment_1 *)Base; Adjust->ValueFormat = kbts_ByteSwap16(Adjust->ValueFormat); if(Adjust->Format == 1) { kbts_ByteSwapValueRecord(Context, Adjust, Adjust->ValueFormat, KBTS_POINTER_AFTER(kbts_u16, Adjust)); } else if(Adjust->Format == 2) { kbts_single_adjustment_2 *Adjust2 = (kbts_single_adjustment_2 *)Base; Adjust2->RecordCount = kbts_ByteSwap16(Adjust2->RecordCount); kbts_u16 *At = KBTS_POINTER_AFTER(kbts_u16, Adjust2); KBTS_FOR(RecordIndex, 0, Adjust2->RecordCount) { kbts_unpacked_value_record Unpacked = kbts_ByteSwapValueRecord(Context, Adjust2, Adjust2->ValueFormat, At); At += Unpacked.Size; } } } break; case 2: { if(*Base == 1) { kbts_pair_adjustment_1 *Adjust = (kbts_pair_adjustment_1 *)Base; kbts_ByteSwapArray16Context(&Adjust->ValueFormat1, 3, Context); kbts_u16 *SetOffsets = KBTS_POINTER_AFTER(kbts_u16, Adjust); kbts_ByteSwapArray16Context(SetOffsets, Adjust->SetCount, Context); kbts_un Size1 = kbts_PopCount32(Adjust->ValueFormat1); kbts_un Size2 = kbts_PopCount32(Adjust->ValueFormat2); kbts_un PairRecordSize = Size1 + Size2 + 1; KBTS_FOR(SetIndex, 0, Adjust->SetCount) { kbts_pair_set *Set = KBTS_POINTER_OFFSET(kbts_pair_set, Adjust, SetOffsets[SetIndex]); if(!kbts_AlreadyVisited(Context, Set)) { Set->Count = kbts_ByteSwap16(Set->Count); kbts_u16 *At = KBTS_POINTER_AFTER(kbts_u16, Set); KBTS_FOR(RecordIndex, 0, Set->Count) { kbts_pair_value_record *PairRecord = (kbts_pair_value_record *)(At + RecordIndex * PairRecordSize); PairRecord->SecondGlyph = kbts_ByteSwap16(PairRecord->SecondGlyph); kbts_u16 *Record = KBTS_POINTER_AFTER(kbts_u16, PairRecord); kbts_unpacked_value_record Unpacked1 = kbts_ByteSwapValueRecord(Context, Record, Adjust->ValueFormat1, Record); Record += Unpacked1.Size; kbts_ByteSwapValueRecord(Context, Record, Adjust->ValueFormat2, Record); } } } } else if(*Base == 2) { kbts_pair_adjustment_2 *Adjust = (kbts_pair_adjustment_2 *)Base; kbts_ByteSwapArray16Context(&Adjust->ValueFormat1, 6, Context); kbts_ByteSwapClassDefinition(Context, KBTS_POINTER_OFFSET(kbts_u16, Adjust, Adjust->ClassDefinition1Offset)); kbts_ByteSwapClassDefinition(Context, KBTS_POINTER_OFFSET(kbts_u16, Adjust, Adjust->ClassDefinition2Offset)); kbts_u16 *Records = KBTS_POINTER_AFTER(kbts_u16, Adjust); kbts_un Size1 = kbts_PopCount32(Adjust->ValueFormat1); kbts_un Size2 = kbts_PopCount32(Adjust->ValueFormat2); kbts_u16 *RecordPair = Records; KBTS_FOR(RecordIndex, 0, (kbts_un)Adjust->Class1Count * (kbts_un)Adjust->Class2Count) { kbts_ByteSwapValueRecord(Context, Adjust, Adjust->ValueFormat1, RecordPair); RecordPair += Size1; kbts_ByteSwapValueRecord(Context, Adjust, Adjust->ValueFormat2, RecordPair); RecordPair += Size2; } } } break; case 3: { kbts_cursive_attachment *Adjust = (kbts_cursive_attachment *)Base; Adjust->EntryExitCount = kbts_ByteSwap16(Adjust->EntryExitCount); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, Adjust), Adjust->EntryExitCount * 2, Context); kbts_entry_exit *EntryExits = KBTS_POINTER_AFTER(kbts_entry_exit, Adjust); KBTS_FOR(EntryExitIndex, 0, Adjust->EntryExitCount) { kbts_entry_exit *EntryExit = &EntryExits[EntryExitIndex]; if(EntryExit->EntryAnchorOffset) { kbts_ByteSwapAnchor(Context, KBTS_POINTER_OFFSET(kbts_anchor, Adjust, EntryExit->EntryAnchorOffset)); } if(EntryExit->ExitAnchorOffset) { kbts_ByteSwapAnchor(Context, KBTS_POINTER_OFFSET(kbts_anchor, Adjust, EntryExit->ExitAnchorOffset)); } } } break; case 4: case 6: { kbts_mark_to_base_attachment *Adjust = (kbts_mark_to_base_attachment *)Base; kbts_ByteSwapArray16Context(&Adjust->BaseCoverageOffset, 4, Context); kbts_ByteSwapCoverage(Context, KBTS_POINTER_OFFSET(kbts_coverage, Adjust, Adjust->BaseCoverageOffset)); kbts_ByteSwapMarkArray(Context, KBTS_POINTER_OFFSET(kbts_mark_array, Adjust, Adjust->MarkArrayOffset)); kbts_ByteSwapBaseArray(Context, Adjust->MarkClassCount, KBTS_POINTER_OFFSET(kbts_base_array, Adjust, Adjust->BaseArrayOffset)); } break; case 5: { kbts_mark_to_ligature_attachment *Adjust = (kbts_mark_to_ligature_attachment *)Base; kbts_ByteSwapArray16Context(&Adjust->LigatureCoverageOffset, 4, Context); kbts_ByteSwapCoverage(Context, KBTS_POINTER_OFFSET(kbts_coverage, Adjust, Adjust->LigatureCoverageOffset)); kbts_ByteSwapMarkArray(Context, KBTS_POINTER_OFFSET(kbts_mark_array, Adjust, Adjust->MarkArrayOffset)); kbts_ligature_array *LigatureArray = KBTS_POINTER_OFFSET(kbts_ligature_array, Adjust, Adjust->LigatureArrayOffset); if(!kbts_AlreadyVisited(Context, LigatureArray)) { LigatureArray->Count = kbts_ByteSwap16(LigatureArray->Count); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, LigatureArray), LigatureArray->Count, Context); KBTS_FOR(AttachIndex, 0, LigatureArray->Count) { kbts_ligature_attach *Attach = kbts_GetLigatureAttach(LigatureArray, AttachIndex); if(!kbts_AlreadyVisited(Context, Attach)) { Attach->Count = kbts_ByteSwap16(Attach->Count); kbts_u16 *AttachAnchorOffsets = KBTS_POINTER_AFTER(kbts_u16, Attach); kbts_ByteSwapArray16Context(AttachAnchorOffsets, Attach->Count * Adjust->MarkClassCount, Context); KBTS_FOR(ComponentIndex, 0, Attach->Count) { KBTS_FOR(MarkClass, 0, Adjust->MarkClassCount) { kbts_anchor *Anchor = kbts_GetLigatureAttachAnchor(Adjust, Attach, (kbts_u16)MarkClass, ComponentIndex); kbts_ByteSwapAnchor(Context, Anchor); } } } } } } break; case 7: { kbts_ByteSwapSequenceContextSubtable(Context, Base); } break; case 8: { kbts_ByteSwapChainedSequenceContextSubtable(Context, Base); } break; case 9: { // @Cleanup: Replace recursion with a loop at the start of this function! kbts_extension *Adjust = (kbts_extension *)Base; Adjust->LookupType = kbts_ByteSwap16(Adjust->LookupType); Adjust->Offset = kbts_ByteSwap32(Adjust->Offset); kbts_ByteSwapGposLookupSubtable(Context, LookupList, Adjust->LookupType, KBTS_POINTER_OFFSET(kbts_u16, Adjust, Adjust->Offset)); } break; } } } static kbts_glyph_classes kbts_GlyphClasses(kbts_font *Font, kbts_u32 Id) { kbts_glyph_classes Result = KBTS_ZERO; // Look up all glyph classes. kbts_gdef *Gdef = Font->Gdef; if(Gdef) { if(Gdef->ClassDefinitionOffset) { kbts_u16 *ClassDefBase = KBTS_POINTER_OFFSET(kbts_u16, Gdef, Gdef->ClassDefinitionOffset); Result.Class = kbts_GlyphClassFromTable(ClassDefBase, Id).Class; } if(Gdef->MarkAttachmentClassDefinitionOffset && (Result.Class == KBTS_GLYPH_CLASS_MARK)) { kbts_u16 *MarkAttachmentClassDefBase = KBTS_POINTER_OFFSET(kbts_u16, Gdef, Gdef->MarkAttachmentClassDefinitionOffset); Result.MarkAttachmentClass = kbts_GlyphClassFromTable(MarkAttachmentClassDefBase, Id).Class; } } return Result; } static int kbts_ScriptIsWeak(kbts_script Script) { int Result = (Script == KBTS_SCRIPT_DONT_KNOW) || (Script == KBTS_SCRIPT_DEFAULT) || (Script == KBTS_SCRIPT_DEFAULT2); return Result; } static int kbts_ShaperRtl(kbts_shaper Shaper) { int Result = (Shaper == KBTS_SHAPER_ARABIC) || (Shaper == KBTS_SHAPER_HEBREW); return Result; } // Easy shorthand for determining scripts in simple cases. // Do not ship this! You should use script breaks instead. KBTS_EXPORT void kbts_InferScript(kbts_direction *Direction, kbts_script *Script, kbts_script GlyphScript) { if(Script) { if(kbts_ScriptIsWeak(*Script) && !kbts_ScriptIsWeak(GlyphScript)) { *Script = GlyphScript; if(Direction && (!*Direction)) { kbts_script_properties *Properties = &kbts_ScriptProperties[GlyphScript]; *Direction = kbts_ShaperRtl(Properties->Shaper) ? KBTS_DIRECTION_RTL : KBTS_DIRECTION_LTR; } } } } KBTS_EXPORT kbts_glyph kbts_CodepointToGlyph(kbts_font *Font, kbts_u32 Codepoint) { kbts_glyph Result = KBTS_ZERO; Result.Codepoint = Codepoint; // Look up Unicode properties. Result.Decomposition = kbts_GetUnicodeDecomposition(Codepoint); Result.JoiningType = kbts_GetUnicodeJoiningType(Codepoint); Result.UnicodeFlags = kbts_GetUnicodeFlags(Codepoint); kbts_u16 SyllabicInfo = kbts_GetUnicodeSyllabicInfo(Codepoint); Result.SyllabicClass = kbts_GetSyllabicClass(SyllabicInfo); Result.SyllabicPosition = kbts_GetSyllabicPosition(SyllabicInfo); Result.CombiningClass = kbts_GetUnicodeCombiningClass(Codepoint); Result.UseClass = kbts_GetUnicodeUseClass(Codepoint); Result.Script = kbts_GetUnicodeScript(Codepoint); Result.ParentInfo = kbts_GetUnicodeParentInfo(Codepoint); kbts_u16 *CmapBase = Font->Cmap; if(CmapBase) { switch(*CmapBase) { case 0: { kbts_cmap_0 *Cmap0 = (kbts_cmap_0 *)CmapBase; if((kbts_un)Codepoint < KBTS_ARRAY_LENGTH(Cmap0->GlyphIdArray)) { Result.Id = Cmap0->GlyphIdArray[Codepoint]; } } break; case 2: { kbts_cmap_2 *Cmap2 = (kbts_cmap_2 *)CmapBase; kbts_sub_header *SubHeaders = KBTS_POINTER_AFTER(kbts_sub_header, Cmap2); kbts_u32 High = (Codepoint >> 8) & 0xFF; if(!(Codepoint & 0xFF00)) { High = Codepoint & 0xFF; } // The Microsoft documentation doesn't mention that the SubHeaderKeys are indices multiplied by 8, for some // reason..! The Apple documentation does. kbts_u16 SubHeaderIndex = Cmap2->SubHeaderKeys[High] / 8; kbts_sub_header *SubHeader = &SubHeaders[SubHeaderIndex]; if(!SubHeaderIndex) { // With SubHeader 0, we only use the first byte. Codepoint = High; } else { Codepoint = Codepoint & 0xFF; } kbts_u32 Offset = Codepoint - SubHeader->FirstCode; if(Offset < SubHeader->EntryCount) { kbts_u16 *GlyphIds = KBTS_POINTER_OFFSET(kbts_u16, &SubHeader->IdRangeOffset, SubHeader->IdRangeOffset); kbts_u16 GlyphId = GlyphIds[Offset]; if(GlyphId) { GlyphId += SubHeader->IdDelta; } Result.Id = GlyphId; } } break; case 4: { kbts_cmap_4 *Cmap4 = (kbts_cmap_4 *)CmapBase; kbts_un SegmentCount = Cmap4->SegmentCountTimesTwo / 2; kbts_u16 *EndCodes = KBTS_POINTER_AFTER(kbts_u16, Cmap4); kbts_u16 *StartCodes = EndCodes + SegmentCount + 1; kbts_s16 *IdDeltas = (kbts_s16 *)(StartCodes + SegmentCount); kbts_u16 *IdRangeOffsets = (kbts_u16 *)(IdDeltas + SegmentCount); KBTS_FOR(SegmentIndex, 0, SegmentCount) { kbts_u16 Start = StartCodes[SegmentIndex]; if((Codepoint >= Start) && (Codepoint <= EndCodes[SegmentIndex])) { kbts_s16 Delta = IdDeltas[SegmentIndex]; kbts_u16 RangeOffset = IdRangeOffsets[SegmentIndex]; kbts_u16 GlyphId = (kbts_u16)Delta; if(RangeOffset) { GlyphId += *(&IdRangeOffsets[SegmentIndex] + (Codepoint - Start) + RangeOffset / 2); } else { GlyphId += (kbts_u16)(Codepoint); } Result.Id = GlyphId; break; } } } break; case 6: { kbts_cmap_6 *Cmap6 = (kbts_cmap_6 *)CmapBase; kbts_u16 *GlyphIds = KBTS_POINTER_AFTER(kbts_u16, Cmap6); kbts_un Offset = Codepoint - Cmap6->FirstCode; if(Offset < Cmap6->EntryCount) { Result.Id = GlyphIds[Offset]; } } break; case 12: { kbts_cmap_12_13 *Cmap12 = (kbts_cmap_12_13 *)CmapBase; kbts_sequential_map_group *Groups = KBTS_POINTER_AFTER(kbts_sequential_map_group, Cmap12); kbts_un GlyphId = 0; KBTS_FOR(GroupIndex, 0, Cmap12->GroupCount) { kbts_sequential_map_group *Group = &Groups[GroupIndex]; if((Codepoint >= Group->StartCharacterCode) && (Codepoint <= Group->EndCharacterCode)) { kbts_un Offset = Codepoint - Group->StartCharacterCode; GlyphId = Group->StartGlyphId + Offset; break; } } Result.Id = (kbts_u16)GlyphId; } break; } } if(Font->Gdef) { Result.Classes = kbts_GlyphClasses(Font, Result.Id); } else { // @Cleanup: This is garbage compatibility-with-broken-fonts code. I would very much like to get rid of it. if((Result.UnicodeFlags & KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE) || !(Result.UnicodeFlags & KBTS_UNICODE_FLAG_NON_SPACING_MARK)) { Result.Classes.Class = KBTS_GLYPH_CLASS_BASE; } else { Result.Classes.Class = KBTS_GLYPH_CLASS_MARK; } } return Result; } typedef struct kbts_iterate_features { kbts_gsub_gpos *Header; kbts_feature_list *FeatureList; // @Incomplete // kbts_feature_variations *FeatureVariations; kbts_langsys *Langsys; kbts_feature_set EnabledFeatures; kbts_u32 CurrentFeatureTag; kbts_u32 CurrentFeatureFlag; kbts_u32 FeatureIndex; kbts_feature *Feature; } kbts_iterate_features; static kbts_iterate_features kbts_IterateFeatures(kbts_shape_config *Config, kbts_shaping_table ShapingTable, kbts_feature_set EnabledFeatures) { kbts_iterate_features Result = KBTS_ZERO; kbts_gsub_gpos *Header = Config->Font->ShapingTables[ShapingTable]; if(Header) { // @Incomplete // if(Header->Minor == 1) // { // Result.FeatureVariations = KBTS_POINTER_OFFSET(kbts_feature_variations, Header, Header->FeatureVariationsOffset); // } Result.FeatureList = KBTS_POINTER_OFFSET(kbts_feature_list, Header, Header->FeatureListOffset); Result.Header = Header; Result.Langsys = Config->Langsys[ShapingTable]; Result.EnabledFeatures = EnabledFeatures; } return Result; } static kbts_u32 kbts_IsValidFeatureIteration(kbts_iterate_features *It) { kbts_u32 Result = It->Langsys != 0; return Result; } static kbts_u32 kbts_NextFeature(kbts_iterate_features *It) { kbts_u32 Result = 0; It->Feature = 0; if(kbts_IsValidFeatureIteration(It)) { kbts_u16 *FeatureIndices = KBTS_POINTER_AFTER(kbts_u16, It->Langsys); // @Incomplete // kbts_feature_variations *FeatureVariations = It->FeatureVariations; while(It->FeatureIndex < It->Langsys->FeatureIndexCount) { kbts_feature_pointer Feature = kbts_GetFeature(It->FeatureList, FeatureIndices[It->FeatureIndex]); // We might need to swap out this feature with another. // Check for variations. // @Incomplete //if(FeatureVariations) //{ // KBTS_FOR(VariationIndex, 0, FeatureVariations->RecordCount) // { // kbts_feature_variation_pointer Variation = kbts_GetFeatureVariation(FeatureVariations, VariationIndex); // KBTS_FOR(ConditionIndex, 0, Variation.ConditionSet->Count) // { // kbts_condition_1 *Condition = kbts_GetCondition(Variation.ConditionSet, ConditionIndex); // KBTS_ASSERT(0); // } // } //} It->FeatureIndex += 1; kbts_u32 FeatureId = kbts_FeatureTagToId(Feature.Tag); if(kbts_ContainsFeature(&It->EnabledFeatures, FeatureId)) { It->Feature = Feature.Feature; It->CurrentFeatureTag = Feature.Tag; if(FeatureId && (FeatureId <= 32)) { It->CurrentFeatureFlag = (1 << (FeatureId - 1)) & KBTS_GLYPH_FEATURE_MASK; } Result = 1; break; } } } return Result; } typedef struct kbts_iterate_lookups { kbts_lookup_list *LookupList; kbts_feature *Feature; kbts_lookup *Lookup; kbts_u16 LookupIndex; kbts_u32 LookupIndexIndex; } kbts_iterate_lookups; static kbts_iterate_lookups kbts_IterateLookups(kbts_lookup_list *List, kbts_feature *Feature) { kbts_iterate_lookups Result = KBTS_ZERO; Result.LookupList = List; Result.Feature = Feature; return Result; } static kbts_u32 kbts_NextLookup(kbts_iterate_lookups *It) { kbts_u32 Result = 0; kbts_feature *Feature = It->Feature; if(It->LookupList && Feature && (It->LookupIndexIndex < Feature->LookupIndexCount)) { kbts_u16 *LookupIndices = KBTS_POINTER_AFTER(kbts_u16, Feature); It->LookupIndex = LookupIndices[It->LookupIndexIndex]; It->Lookup = kbts_GetLookup(It->LookupList, It->LookupIndex); Result = 1; It->LookupIndexIndex += 1; } return Result; } KBTS_INLINE void kbts_GsubMutate(kbts_font *Font, kbts_glyph *Glyph, kbts_u16 NewId, kbts_u32 Flags) { Glyph->Id = NewId; Glyph->Classes = kbts_GlyphClasses(Font, NewId); Glyph->Flags = (Glyph->Flags & ~KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION) | Flags; } typedef struct kbts_do_single_substitution_result { kbts_u32 ConsumedGlyphCount; kbts_u32 WrittenGlyphCount; kbts_u32 PerformedSubstitution; } kbts_do_single_substitution_result; static kbts_feature_set kbts_ShaperFeatures[] = { /* KBTS_SHAPER_DEFAULT */ {{KBTS_FEATURE_FLAG0(abvm) | KBTS_FEATURE_FLAG0(blwm) | KBTS_FEATURE_FLAG0(curs) | KBTS_FEATURE_FLAG0(frac) | KBTS_FEATURE_FLAG0(numr) | KBTS_FEATURE_FLAG0(dnom) | KBTS_FEATURE_FLAG0(ccmp) | KBTS_FEATURE_FLAG0(clig) | KBTS_FEATURE_FLAG0(calt), 0, KBTS_FEATURE_FLAG2(locl) | KBTS_FEATURE_FLAG2(ltra) | KBTS_FEATURE_FLAG2(ltrm) | KBTS_FEATURE_FLAG2(liga) | KBTS_FEATURE_FLAG2(rlig) | KBTS_FEATURE_FLAG2(rclt) | KBTS_FEATURE_FLAG2(dist) | KBTS_FEATURE_FLAG2(kern) | KBTS_FEATURE_FLAG2(mark) | KBTS_FEATURE_FLAG2(mkmk), KBTS_FEATURE_FLAG3(rvrn)}}, /* KBTS_SHAPER_ARABIC */ {{KBTS_FEATURE_FLAG0(frac) | KBTS_FEATURE_FLAG0(numr) | KBTS_FEATURE_FLAG0(dnom) | KBTS_FEATURE_FLAG0(ccmp) | KBTS_FEATURE_FLAG0(isol) | KBTS_FEATURE_FLAG0(fina) | KBTS_FEATURE_FLAG0(fin2) | KBTS_FEATURE_FLAG0(fin3) | KBTS_FEATURE_FLAG0(medi) | KBTS_FEATURE_FLAG0(med2) | KBTS_FEATURE_FLAG0(init) | KBTS_FEATURE_FLAG0(calt) | KBTS_FEATURE_FLAG0(clig) | KBTS_FEATURE_FLAG2(mset) | KBTS_FEATURE_FLAG0(abvm) | KBTS_FEATURE_FLAG0(blwm) | KBTS_FEATURE_FLAG0(curs), 0, KBTS_FEATURE_FLAG2(rlig) | KBTS_FEATURE_FLAG2(liga) | KBTS_FEATURE_FLAG2(rclt) | KBTS_FEATURE_FLAG2(mark) | KBTS_FEATURE_FLAG2(mkmk) | KBTS_FEATURE_FLAG2(dist) | KBTS_FEATURE_FLAG2(kern) | KBTS_FEATURE_FLAG2(locl), KBTS_FEATURE_FLAG3(rvrn) | KBTS_FEATURE_FLAG3(rtlm) | KBTS_FEATURE_FLAG3(stch) | KBTS_FEATURE_FLAG3(rtla)}}, /* KBTS_SHAPER_HANGUL */ {{KBTS_FEATURE_FLAG0(frac) | KBTS_FEATURE_FLAG0(numr) | KBTS_FEATURE_FLAG0(dnom) | KBTS_FEATURE_FLAG0(ljmo) | KBTS_FEATURE_FLAG0(vjmo) | KBTS_FEATURE_FLAG0(tjmo) | KBTS_FEATURE_FLAG0(abvm) | KBTS_FEATURE_FLAG0(blwm) | KBTS_FEATURE_FLAG0(ccmp) | KBTS_FEATURE_FLAG0(clig) | KBTS_FEATURE_FLAG0(curs), 0, KBTS_FEATURE_FLAG2(ltra) | KBTS_FEATURE_FLAG2(ltrm) | KBTS_FEATURE_FLAG2(dist) | KBTS_FEATURE_FLAG2(kern) | KBTS_FEATURE_FLAG2(rclt) | KBTS_FEATURE_FLAG2(locl) | KBTS_FEATURE_FLAG2(mark) | KBTS_FEATURE_FLAG2(mkmk) | KBTS_FEATURE_FLAG2(rlig) | KBTS_FEATURE_FLAG2(liga), KBTS_FEATURE_FLAG3(rvrn)}}, /* KBTS_SHAPER_HEBREW */ {{KBTS_FEATURE_FLAG0(abvm) | KBTS_FEATURE_FLAG0(blwm) | KBTS_FEATURE_FLAG0(curs) | KBTS_FEATURE_FLAG0(frac) | KBTS_FEATURE_FLAG0(numr) | KBTS_FEATURE_FLAG0(dnom) | KBTS_FEATURE_FLAG0(ccmp) | KBTS_FEATURE_FLAG0(clig) | KBTS_FEATURE_FLAG0(calt), 0, KBTS_FEATURE_FLAG2(locl) | KBTS_FEATURE_FLAG2(ltra) | KBTS_FEATURE_FLAG2(ltrm) | KBTS_FEATURE_FLAG2(liga) | KBTS_FEATURE_FLAG2(rlig) | KBTS_FEATURE_FLAG2(rclt) | KBTS_FEATURE_FLAG2(dist) | KBTS_FEATURE_FLAG2(kern) | KBTS_FEATURE_FLAG2(mark) | KBTS_FEATURE_FLAG2(mkmk), KBTS_FEATURE_FLAG3(rvrn)}}, // (Same as DEFAULT) /* KBTS_SHAPER_INDIC */ {{KBTS_FEATURE_FLAG0(frac) | KBTS_FEATURE_FLAG0(numr) | KBTS_FEATURE_FLAG0(dnom) | KBTS_FEATURE_FLAG0(akhn) | KBTS_FEATURE_FLAG0(rphf) | KBTS_FEATURE_FLAG0(pref) | KBTS_FEATURE_FLAG0(blwf) | KBTS_FEATURE_FLAG0(abvf) | KBTS_FEATURE_FLAG0(half) | KBTS_FEATURE_FLAG0(pstf) | KBTS_FEATURE_FLAG0(cjct) | KBTS_FEATURE_FLAG0(abvs) | KBTS_FEATURE_FLAG0(blws) | KBTS_FEATURE_FLAG0(init) | KBTS_FEATURE_FLAG0(calt) | KBTS_FEATURE_FLAG0(clig) | KBTS_FEATURE_FLAG0(abvm) | KBTS_FEATURE_FLAG0(blwm) | KBTS_FEATURE_FLAG0(curs), 0, KBTS_FEATURE_FLAG2(ltra) | KBTS_FEATURE_FLAG2(ltrm) | KBTS_FEATURE_FLAG2(nukt) | KBTS_FEATURE_FLAG2(rkrf) | KBTS_FEATURE_FLAG2(pres) | KBTS_FEATURE_FLAG2(psts) | KBTS_FEATURE_FLAG2(locl) | KBTS_FEATURE_FLAG2(rlig) | KBTS_FEATURE_FLAG2(dist) | KBTS_FEATURE_FLAG2(haln) | KBTS_FEATURE_FLAG2(rclt) | KBTS_FEATURE_FLAG2(mark) | KBTS_FEATURE_FLAG2(mkmk) | KBTS_FEATURE_FLAG2(kern), KBTS_FEATURE_FLAG3(rvrn) | KBTS_FEATURE_FLAG3(vatu),}}, /* KBTS_SHAPER_KHMER */ {{KBTS_FEATURE_FLAG0(frac) | KBTS_FEATURE_FLAG0(numr) | KBTS_FEATURE_FLAG0(dnom) | KBTS_FEATURE_FLAG0(ccmp) | KBTS_FEATURE_FLAG0(pref) | KBTS_FEATURE_FLAG0(blwf) | KBTS_FEATURE_FLAG0(abvf) | KBTS_FEATURE_FLAG0(pstf) | KBTS_FEATURE_FLAG0(cfar) | KBTS_FEATURE_FLAG0(abvs) | KBTS_FEATURE_FLAG0(blws) | KBTS_FEATURE_FLAG0(calt) | KBTS_FEATURE_FLAG0(clig) | KBTS_FEATURE_FLAG0(abvm) | KBTS_FEATURE_FLAG0(blwm) | KBTS_FEATURE_FLAG0(curs), 0, KBTS_FEATURE_FLAG2(dist) | KBTS_FEATURE_FLAG2(kern) | KBTS_FEATURE_FLAG2(mark) | KBTS_FEATURE_FLAG2(mkmk) | KBTS_FEATURE_FLAG2(pres) | KBTS_FEATURE_FLAG2(ltra) | KBTS_FEATURE_FLAG2(ltrm) | KBTS_FEATURE_FLAG2(locl) | KBTS_FEATURE_FLAG2(psts) | KBTS_FEATURE_FLAG2(rclt) | KBTS_FEATURE_FLAG2(rlig), KBTS_FEATURE_FLAG3(rvrn)}}, /* KBTS_SHAPER_MYANMAR */ {{KBTS_FEATURE_FLAG0(rphf) | KBTS_FEATURE_FLAG0(pref) | KBTS_FEATURE_FLAG0(blwf) | KBTS_FEATURE_FLAG0(pstf) | KBTS_FEATURE_FLAG0(frac) | KBTS_FEATURE_FLAG0(numr) | KBTS_FEATURE_FLAG0(dnom) | KBTS_FEATURE_FLAG0(ccmp) | KBTS_FEATURE_FLAG0(abvs) | KBTS_FEATURE_FLAG0(blws) | KBTS_FEATURE_FLAG0(calt) | KBTS_FEATURE_FLAG0(clig) | KBTS_FEATURE_FLAG0(abvm) | KBTS_FEATURE_FLAG0(blwm) | KBTS_FEATURE_FLAG0(curs), 0, KBTS_FEATURE_FLAG2(mark) | KBTS_FEATURE_FLAG2(mkmk) | KBTS_FEATURE_FLAG2(ltra) | KBTS_FEATURE_FLAG2(ltrm) | KBTS_FEATURE_FLAG2(locl) | KBTS_FEATURE_FLAG2(psts) | KBTS_FEATURE_FLAG2(rlig) | KBTS_FEATURE_FLAG2(pres) | KBTS_FEATURE_FLAG2(liga) | KBTS_FEATURE_FLAG2(rclt) | KBTS_FEATURE_FLAG2(dist) | KBTS_FEATURE_FLAG2(kern), KBTS_FEATURE_FLAG3(rvrn)}}, /* KBTS_SHAPER_TIBETAN */ {{KBTS_FEATURE_FLAG0(ccmp) | KBTS_FEATURE_FLAG0(abvs) | KBTS_FEATURE_FLAG0(blws) | KBTS_FEATURE_FLAG0(calt) | KBTS_FEATURE_FLAG0(abvm) | KBTS_FEATURE_FLAG0(blwm), 0, KBTS_FEATURE_FLAG2(locl) | KBTS_FEATURE_FLAG2(liga) | KBTS_FEATURE_FLAG2(kern) | KBTS_FEATURE_FLAG2(mkmk), 0}}, /* KBTS_SHAPER_USE */ {{KBTS_FEATURE_FLAG0(frac) | KBTS_FEATURE_FLAG0(numr) | KBTS_FEATURE_FLAG0(dnom) | KBTS_FEATURE_FLAG0(ccmp) | KBTS_FEATURE_FLAG0(akhn) | KBTS_FEATURE_FLAG0(rphf) | KBTS_FEATURE_FLAG0(pref) | KBTS_FEATURE_FLAG0(abvf) | KBTS_FEATURE_FLAG0(blwf) | KBTS_FEATURE_FLAG0(cjct) | KBTS_FEATURE_FLAG0(half) | KBTS_FEATURE_FLAG0(pstf) | KBTS_FEATURE_FLAG0(fina) | KBTS_FEATURE_FLAG0(init) | KBTS_FEATURE_FLAG0(isol) | KBTS_FEATURE_FLAG0(medi) | KBTS_FEATURE_FLAG0(abvs) | KBTS_FEATURE_FLAG0(blws) | KBTS_FEATURE_FLAG0(calt) | KBTS_FEATURE_FLAG0(clig) | KBTS_FEATURE_FLAG0(abvm) | KBTS_FEATURE_FLAG0(blwm) | KBTS_FEATURE_FLAG0(curs), 0, KBTS_FEATURE_FLAG2(ltra) | KBTS_FEATURE_FLAG2(ltrm) | KBTS_FEATURE_FLAG2(locl) | KBTS_FEATURE_FLAG2(nukt) | KBTS_FEATURE_FLAG2(rkrf) | KBTS_FEATURE_FLAG2(rlig) | KBTS_FEATURE_FLAG2(dist) | KBTS_FEATURE_FLAG2(kern) | KBTS_FEATURE_FLAG2(mark) | KBTS_FEATURE_FLAG2(mkmk) | KBTS_FEATURE_FLAG2(haln) | KBTS_FEATURE_FLAG2(liga) | KBTS_FEATURE_FLAG2(rclt) | KBTS_FEATURE_FLAG2(pres) | KBTS_FEATURE_FLAG2(psts), KBTS_FEATURE_FLAG3(rvrn) | KBTS_FEATURE_FLAG3(vatu)}}, }; // Make sure that these fit KBTS_MAX_SIMULTANEOUS_FEATURES! static kbts_u8 kbts_Ops_Default[] = { KBTS_OP_KIND_NORMALIZE, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rvrn, KBTS_OP_KIND_GSUB_FEATURES_WITH_USER, 12, KBTS_FEATURE_ID_frac, KBTS_FEATURE_ID_numr, KBTS_FEATURE_ID_dnom, KBTS_FEATURE_ID_ltra, KBTS_FEATURE_ID_ltrm, KBTS_FEATURE_ID_liga, KBTS_FEATURE_ID_ccmp, KBTS_FEATURE_ID_locl, KBTS_FEATURE_ID_rlig, KBTS_FEATURE_ID_clig, KBTS_FEATURE_ID_calt, KBTS_FEATURE_ID_rclt, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 7, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_mark, KBTS_FEATURE_ID_mkmk, KBTS_FEATURE_ID_curs, KBTS_FEATURE_ID_dist, KBTS_FEATURE_ID_kern, KBTS_OP_KIND_POST_GPOS_FIXUP, }; /* @Incomplete: Vertical text. static kbts_u8 kbts_Ops_DefaultTtbBtt[] = { KBTS_OP_KIND_NORMALIZE, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rvrn, KBTS_OP_KIND_GSUB_FEATURES, 3, KBTS_FEATURE_ID_frac, KBTS_FEATURE_ID_numr, KBTS_FEATURE_ID_dnom, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 10, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_ccmp, KBTS_FEATURE_ID_locl, KBTS_FEATURE_ID_mark, KBTS_FEATURE_ID_mkmk, KBTS_FEATURE_ID_rlig, KBTS_FEATURE_ID_calt, KBTS_FEATURE_ID_liga, KBTS_FEATURE_ID_vert, KBTS_OP_KIND_POST_GPOS_FIXUP, }; */ static kbts_u8 kbts_Ops_Hangul[] = { KBTS_OP_KIND_NORMALIZE, KBTS_OP_KIND_NORMALIZE_HANGUL, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rvrn, KBTS_OP_KIND_GSUB_FEATURES_WITH_USER, 8, KBTS_FEATURE_ID_frac, KBTS_FEATURE_ID_numr, KBTS_FEATURE_ID_dnom, KBTS_FEATURE_ID_ltra, KBTS_FEATURE_ID_ltrm, KBTS_FEATURE_ID_ljmo, KBTS_FEATURE_ID_vjmo, KBTS_FEATURE_ID_tjmo, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 13, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_ccmp, KBTS_FEATURE_ID_locl, KBTS_FEATURE_ID_mark, KBTS_FEATURE_ID_mkmk, KBTS_FEATURE_ID_rlig, KBTS_FEATURE_ID_liga, KBTS_FEATURE_ID_clig, KBTS_FEATURE_ID_curs, KBTS_FEATURE_ID_dist, KBTS_FEATURE_ID_kern, KBTS_FEATURE_ID_rclt, KBTS_OP_KIND_POST_GPOS_FIXUP, }; static kbts_u8 kbts_Ops_ArabicRclt[] = { KBTS_OP_KIND_NORMALIZE, KBTS_OP_KIND_FLAG_JOINING_LETTERS, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rvrn, KBTS_OP_KIND_GSUB_FEATURES_WITH_USER, 5, KBTS_FEATURE_ID_frac, KBTS_FEATURE_ID_numr, KBTS_FEATURE_ID_dnom, KBTS_FEATURE_ID_rtla, KBTS_FEATURE_ID_rtlm, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_stch, KBTS_OP_KIND_GSUB_FEATURES, 2, KBTS_FEATURE_ID_ccmp, KBTS_FEATURE_ID_locl, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_isol, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_fina, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_fin2, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_fin3, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_medi, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_med2, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_init, // @Incomplete: In Arabic rlig, ZWJ should not be skipped in lookups (i.e. it should block ligatures). KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rlig, // @Incomplete: In non-Arabic scripts, e.g. Syriac, Harfbuzz does not pause here. KBTS_OP_KIND_GSUB_FEATURES, 5, KBTS_FEATURE_ID_calt, KBTS_FEATURE_ID_liga, KBTS_FEATURE_ID_clig, KBTS_FEATURE_ID_mset, KBTS_FEATURE_ID_rclt, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 7, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_mark, KBTS_FEATURE_ID_mkmk, KBTS_FEATURE_ID_curs, KBTS_FEATURE_ID_dist, KBTS_FEATURE_ID_kern, KBTS_OP_KIND_STCH_POSTPASS, KBTS_OP_KIND_POST_GPOS_FIXUP, }; static kbts_u8 kbts_Ops_ArabicNoRclt[] = { KBTS_OP_KIND_NORMALIZE, KBTS_OP_KIND_FLAG_JOINING_LETTERS, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rvrn, KBTS_OP_KIND_GSUB_FEATURES_WITH_USER, 5, KBTS_FEATURE_ID_frac, KBTS_FEATURE_ID_numr, KBTS_FEATURE_ID_dnom, KBTS_FEATURE_ID_rtla, KBTS_FEATURE_ID_rtlm, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_stch, KBTS_OP_KIND_GSUB_FEATURES, 2, KBTS_FEATURE_ID_ccmp, KBTS_FEATURE_ID_locl, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_isol, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_fina, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_fin2, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_fin3, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_medi, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_med2, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_init, // @Incomplete: In Arabic rlig, ZWJ should not be skipped in lookups (i.e. it should block ligatures). KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rlig, // @Incomplete: In non-Arabic scripts, e.g. Syriac, Harfbuzz does not pause here. KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_calt, // When the font does not contain rclt, Uniscribe puts calt in its own pass, and so we pause here. KBTS_OP_KIND_GSUB_FEATURES, 4, KBTS_FEATURE_ID_liga, KBTS_FEATURE_ID_clig, KBTS_FEATURE_ID_mset, KBTS_FEATURE_ID_rclt, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 7, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_mark, KBTS_FEATURE_ID_mkmk, KBTS_FEATURE_ID_curs, KBTS_FEATURE_ID_dist, KBTS_FEATURE_ID_kern, KBTS_OP_KIND_STCH_POSTPASS, KBTS_OP_KIND_POST_GPOS_FIXUP, }; static kbts_u8 kbts_Ops_Indic0[] = { KBTS_OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES, KBTS_OP_KIND_NORMALIZE, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rvrn, KBTS_OP_KIND_GSUB_FEATURES_WITH_USER, 5, KBTS_FEATURE_ID_frac, KBTS_FEATURE_ID_numr, KBTS_FEATURE_ID_dnom, KBTS_FEATURE_ID_ltra, KBTS_FEATURE_ID_ltrm, }; // After BeginCluster. static kbts_u8 kbts_Ops_Indic1[] = { KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_nukt, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_akhn, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rphf, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rkrf, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_pref, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_blwf, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_abvf, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_half, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_pstf, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_vatu, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_cjct, }; // After EndCluster. static kbts_u8 kbts_Ops_Indic2[] = { KBTS_OP_KIND_GSUB_FEATURES, 6, KBTS_FEATURE_ID_abvs, KBTS_FEATURE_ID_blws, KBTS_FEATURE_ID_haln, KBTS_FEATURE_ID_init, KBTS_FEATURE_ID_pres, KBTS_FEATURE_ID_psts, }; // After syllable processing. static kbts_u8 kbts_Ops_Indic3[] = { KBTS_OP_KIND_GSUB_FEATURES, 5, KBTS_FEATURE_ID_locl, KBTS_FEATURE_ID_rlig, KBTS_FEATURE_ID_calt, KBTS_FEATURE_ID_clig, KBTS_FEATURE_ID_rclt, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 7, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_mark, KBTS_FEATURE_ID_mkmk, KBTS_FEATURE_ID_curs, KBTS_FEATURE_ID_dist, KBTS_FEATURE_ID_kern, KBTS_OP_KIND_POST_GPOS_FIXUP, }; static kbts_u8 kbts_Ops_Use0[] = { KBTS_OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES, KBTS_OP_KIND_NORMALIZE, KBTS_OP_KIND_FLAG_JOINING_LETTERS, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rvrn, KBTS_OP_KIND_GSUB_FEATURES_WITH_USER, 5, KBTS_FEATURE_ID_frac, KBTS_FEATURE_ID_numr, KBTS_FEATURE_ID_dnom, KBTS_FEATURE_ID_ltra, KBTS_FEATURE_ID_ltrm, }; static kbts_u8 kbts_Ops_Use1[] = { KBTS_OP_KIND_GSUB_FEATURES, 4, KBTS_FEATURE_ID_locl, KBTS_FEATURE_ID_ccmp, KBTS_FEATURE_ID_nukt, KBTS_FEATURE_ID_akhn, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rphf, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_pref, KBTS_OP_KIND_GSUB_FEATURES, 7, KBTS_FEATURE_ID_abvf, KBTS_FEATURE_ID_blwf, KBTS_FEATURE_ID_cjct, KBTS_FEATURE_ID_half, KBTS_FEATURE_ID_pstf, KBTS_FEATURE_ID_rkrf, KBTS_FEATURE_ID_vatu, }; // There is no kbts_Ops_Use2, because there are no features that apply per syllable after reordering. static kbts_u8 kbts_Ops_Use3[] = { KBTS_OP_KIND_GSUB_FEATURES, 4, KBTS_FEATURE_ID_fina, KBTS_FEATURE_ID_init, KBTS_FEATURE_ID_isol, KBTS_FEATURE_ID_medi, KBTS_OP_KIND_GSUB_FEATURES,10, KBTS_FEATURE_ID_abvs, KBTS_FEATURE_ID_blws, KBTS_FEATURE_ID_haln, KBTS_FEATURE_ID_pres, KBTS_FEATURE_ID_psts, KBTS_FEATURE_ID_calt, KBTS_FEATURE_ID_clig, KBTS_FEATURE_ID_liga, KBTS_FEATURE_ID_rclt, KBTS_FEATURE_ID_rlig, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 7, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_curs, KBTS_FEATURE_ID_dist, KBTS_FEATURE_ID_kern, KBTS_FEATURE_ID_mark, KBTS_FEATURE_ID_mkmk, KBTS_OP_KIND_POST_GPOS_FIXUP, }; static kbts_u8 kbts_Ops_Tibetan[] = { KBTS_OP_KIND_GSUB_FEATURES_WITH_USER, 1, KBTS_FEATURE_ID_locl, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_ccmp, KBTS_OP_KIND_GSUB_FEATURES, 4, KBTS_FEATURE_ID_abvs, KBTS_FEATURE_ID_blws, KBTS_FEATURE_ID_calt, KBTS_FEATURE_ID_liga, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 4, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_kern, KBTS_FEATURE_ID_mkmk, KBTS_OP_KIND_POST_GPOS_FIXUP, }; static kbts_u8 kbts_Ops_Khmer0[] = { KBTS_OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES, KBTS_OP_KIND_NORMALIZE, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rvrn, KBTS_OP_KIND_GSUB_FEATURES_WITH_USER, 5, KBTS_FEATURE_ID_frac, KBTS_FEATURE_ID_numr, KBTS_FEATURE_ID_dnom, KBTS_FEATURE_ID_ltra, KBTS_FEATURE_ID_ltrm, }; static kbts_u8 kbts_Ops_Khmer1[] = { KBTS_OP_KIND_GSUB_FEATURES, 7, KBTS_FEATURE_ID_locl, KBTS_FEATURE_ID_ccmp, KBTS_FEATURE_ID_pref, KBTS_FEATURE_ID_blwf, KBTS_FEATURE_ID_abvf, KBTS_FEATURE_ID_pstf, KBTS_FEATURE_ID_cfar, }; static kbts_u8 kbts_Ops_Khmer3[] = { KBTS_OP_KIND_GSUB_FEATURES, 8, KBTS_FEATURE_ID_pres, KBTS_FEATURE_ID_abvs, KBTS_FEATURE_ID_blws, KBTS_FEATURE_ID_psts, KBTS_FEATURE_ID_calt, KBTS_FEATURE_ID_rclt, KBTS_FEATURE_ID_rlig, KBTS_FEATURE_ID_clig, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 7, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_curs, KBTS_FEATURE_ID_dist, KBTS_FEATURE_ID_kern, KBTS_FEATURE_ID_mark, KBTS_FEATURE_ID_mkmk, KBTS_OP_KIND_POST_GPOS_FIXUP, }; #define kbts_Ops_Myanmar0 kbts_Ops_Khmer0 static kbts_u8 kbts_Ops_Myanmar1[] = { KBTS_OP_KIND_GSUB_FEATURES, 2, KBTS_FEATURE_ID_locl, KBTS_FEATURE_ID_ccmp, }; static kbts_u8 kbts_Ops_Myanmar2[] = { KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_rphf, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_pref, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_blwf, KBTS_OP_KIND_GSUB_FEATURES, 1, KBTS_FEATURE_ID_pstf, }; static kbts_u8 kbts_Ops_Myanmar3[] = { KBTS_OP_KIND_GSUB_FEATURES, 9, KBTS_FEATURE_ID_pres, KBTS_FEATURE_ID_abvs, KBTS_FEATURE_ID_blws, KBTS_FEATURE_ID_psts, KBTS_FEATURE_ID_rlig, KBTS_FEATURE_ID_calt, KBTS_FEATURE_ID_clig, KBTS_FEATURE_ID_liga, KBTS_FEATURE_ID_rclt, KBTS_OP_KIND_GPOS_METRICS, KBTS_OP_KIND_GPOS_FEATURES, 7, KBTS_FEATURE_ID_abvm, KBTS_FEATURE_ID_blwm, KBTS_FEATURE_ID_curs, KBTS_FEATURE_ID_dist, KBTS_FEATURE_ID_kern, KBTS_FEATURE_ID_mark, KBTS_FEATURE_ID_mkmk, KBTS_OP_KIND_POST_GPOS_FIXUP, }; static kbts_op_list kbts_ShaperOpLists[KBTS_SHAPER_COUNT] = { /* DEFAULT, */ {kbts_Ops_Default, KBTS_ARRAY_LENGTH(kbts_Ops_Default)}, /* ARABIC, */ {kbts_Ops_ArabicRclt, KBTS_ARRAY_LENGTH(kbts_Ops_ArabicRclt)}, /* HANGUL, */ {kbts_Ops_Hangul, KBTS_ARRAY_LENGTH(kbts_Ops_Hangul)}, /* HEBREW, */ {kbts_Ops_Default, KBTS_ARRAY_LENGTH(kbts_Ops_Default)}, /* INDIC, */ {kbts_Ops_Indic0, KBTS_ARRAY_LENGTH(kbts_Ops_Indic0)}, /* KHMER, */ {kbts_Ops_Khmer0, KBTS_ARRAY_LENGTH(kbts_Ops_Khmer0)}, /* MYANMAR, */ {kbts_Ops_Myanmar0, KBTS_ARRAY_LENGTH(kbts_Ops_Myanmar0)}, /* TIBETAN, */ {kbts_Ops_Tibetan, KBTS_ARRAY_LENGTH(kbts_Ops_Tibetan)}, /* USE, */ {kbts_Ops_Use0, KBTS_ARRAY_LENGTH(kbts_Ops_Use0)}, }; typedef struct kbts_gsub_frame { kbts_u16 LookupIndex; kbts_u16 SubtableIndex; kbts_u16 InputGlyphIndex; kbts_u16 InputGlyphCount; // Defined for nested lookups. kbts_sequence_lookup_record *Records; kbts_u16 RecordCount; kbts_u16 RecordIndex; } kbts_gsub_frame; KBTS_EXPORT kbts_un kbts_SizeOfShapeState(kbts_font *Font) { kbts_un GsubMemorySize = Font->LookupInfo.MaximumLookupStackSize * sizeof(kbts_gsub_frame); kbts_un NormalizationMemorySize = KBTS_MAXIMUM_DECOMPOSITION_CODEPOINTS * sizeof(kbts_glyph); kbts_un LeftoverMemorySize = KBTS_MAX(GsubMemorySize, NormalizationMemorySize); kbts_un Result = sizeof(kbts_shape_state) + LeftoverMemorySize; return Result; } KBTS_EXPORT kbts_shape_state *kbts_PlaceShapeState(void *Address, kbts_un Size) { kbts_shape_state *State = (kbts_shape_state *)Address; KBTS_MEMSET(State, 0, Size); return State; } #ifndef KB_TEXT_SHAPE_NO_CRT KBTS_EXPORT kbts_shape_state *kbts_CreateShapeState(kbts_font *Font) { kbts_un Size = kbts_SizeOfShapeState(Font); void *Memory = malloc(Size); kbts_shape_state *Result = kbts_PlaceShapeState(Memory, Size); return Result; } KBTS_EXPORT void kbts_FreeShapeState(kbts_shape_state *State) { if(State) { free(State); } } #endif KBTS_EXPORT void kbts_ResetShapeState(kbts_shape_state *State) { State->ResumePoint = 0; } static kbts_glyph_array kbts_ClipGlyphArray(kbts_glyph_array *Source, kbts_un Count) { kbts_glyph_array Result = KBTS_ZERO; Result.Glyphs = Source->Glyphs; Result.Count = (kbts_u32)Count; Result.TotalCount = (kbts_u32)Count; Result.Capacity = (kbts_u32)Count; return Result; } static void kbts_TransferGrowRequest(kbts_glyph_array *From, kbts_glyph_array *To) { if(From->RequiredCapacity > From->Capacity) { To->RequiredCapacity = To->Capacity + From->RequiredCapacity - From->Capacity; } } static kbts_glyph_array kbts_GlyphSubArray(kbts_glyph_array *Source, kbts_un FromIndex) { kbts_glyph_array Result = KBTS_ZERO; Result.Glyphs = Source->Glyphs + FromIndex; Result.Count = (kbts_u32)(Source->Count - FromIndex); Result.TotalCount = (kbts_u32)(Source->TotalCount - FromIndex); Result.Capacity = (kbts_u32)(Source->Capacity - FromIndex); return Result; } static kbts_glyph_array kbts_GlyphArray(kbts_glyph *Glyphs, kbts_un Count, kbts_un TotalCount, kbts_un Capacity) { kbts_glyph_array Result = KBTS_ZERO; Result.Glyphs = Glyphs; Result.Count = (kbts_u32)Count; Result.TotalCount = (kbts_u32)TotalCount; Result.Capacity = (kbts_u32)Capacity; return Result; } static int kbts_GrowGlyphArray(kbts_u32 *ResumePoint_, kbts_glyph_array *Array, kbts_un InsertIndex, kbts_un GrowCount, kbts_u32 ResumePoint, int DoNotModifyGlyphCounts) { int Result = 0; kbts_un TotalCount = Array->TotalCount; kbts_un NewTotalCount = TotalCount + GrowCount; if(NewTotalCount <= Array->Capacity) { if(NewTotalCount > TotalCount) { for(kbts_un ToIndex = NewTotalCount; ToIndex > InsertIndex + GrowCount; --ToIndex) { Array->Glyphs[ToIndex - 1] = Array->Glyphs[ToIndex - 1 - GrowCount]; } } else if(NewTotalCount < TotalCount) { // Multiple substitutions that generate 0 glyphs exist. In that case, GrowCount will be negative. KBTS_FOR(ToIndex, InsertIndex, NewTotalCount) { Array->Glyphs[ToIndex] = Array->Glyphs[ToIndex - GrowCount]; } } if(!DoNotModifyGlyphCounts) { Array->Count += GrowCount; Array->TotalCount = (kbts_u32)NewTotalCount; } Result = 1; } else { Array->RequiredCapacity = (kbts_u32)(NewTotalCount + KBTS_GROW_BUFFER_MARGIN); if(ResumePoint_) *ResumePoint_ = ResumePoint; } return Result; } static void kbts_BeginFeatures(kbts_op_state *State, kbts_shape_config *Config, kbts_shaping_table ShapingTable, kbts_feature_set EnabledFeatures) { kbts_un FeatureCount = 0; kbts_gsub_gpos *Header = Config->Font->ShapingTables[ShapingTable]; kbts_langsys *Langsys = Config->Langsys[ShapingTable]; if(Header && Langsys) { kbts_feature_list *FeatureList = KBTS_POINTER_OFFSET(kbts_feature_list, Header, Header->FeatureListOffset); kbts_u16 *FeatureIndices = KBTS_POINTER_AFTER(kbts_u16, Langsys); // @Incomplete // if(Header->Minor == 1) // { // kbts_feature_variations *FeatureVariations = KBTS_POINTER_OFFSET(kbts_feature_variations, Header, Header->FeatureVariationsOffset); // } KBTS_FOR(FeatureIndexIndex, 0, Langsys->FeatureIndexCount) { kbts_un FeatureIndex = FeatureIndices[FeatureIndexIndex]; kbts_feature_pointer Feature = kbts_GetFeature(FeatureList, FeatureIndex); // @Incomplete //if(FeatureVariations) //{ // KBTS_FOR(VariationIndex, 0, FeatureVariations->RecordCount) // { // kbts_feature_variation_pointer Variation = kbts_GetFeatureVariation(FeatureVariations, VariationIndex); // KBTS_FOR(ConditionIndex, 0, Variation.ConditionSet->Count) // { // kbts_condition_1 *Condition = kbts_GetCondition(Variation.ConditionSet, ConditionIndex); // KBTS_ASSERT(0); // } // } //} kbts_u32 FeatureId = kbts_FeatureTagToId(Feature.Tag); if(Feature.Feature->LookupIndexCount && kbts_ContainsFeature(&EnabledFeatures, FeatureId)) { kbts_lookup_indices LookupIndices = KBTS_ZERO; LookupIndices.FeatureTag = Feature.Tag; LookupIndices.FeatureId = FeatureId; LookupIndices.SkipFlags = kbts_SkipFlags(FeatureId, Config->Shaper); // For Myanmar, we could try and tag glyphs depending on their Indic properties in BeginCluster, just like we do for // Indic scripts. // However, Harfbuzz does _not_ do this, so it seems like a bunch of work that would, at best, make us diverge from // Harfbuzz more often. if((Config->Shaper != KBTS_SHAPER_MYANMAR) && (FeatureId >= 1) && (FeatureId <= 32)) { // These must properly map KBTS_FEATURE_ID to kbts_glyph_flags! LookupIndices.GlyphFilter = (1 << (FeatureId - 1)) & KBTS_GLYPH_FEATURE_MASK; } LookupIndices.Count = Feature.Feature->LookupIndexCount; LookupIndices.Indices = KBTS_POINTER_AFTER(kbts_u16, Feature.Feature); State->FeatureLookupIndices[FeatureCount++] = LookupIndices; } } } State->FeatureCount = (kbts_u32)FeatureCount; } typedef struct kbts_sequence_lookup_result { kbts_sequence_lookup_record *Records; kbts_un RecordCount; kbts_un InputSequenceCountIncludingSkippedGlyphs; // This is specified _nowhere_ in the docs, BUT some sequence lookups have 0 records, and exist just to prevent the // next lookups from executing. // So, checking if we got any records is not enough to figure out whether we need to "apply" this lookup. // We need to have an explicit bool as well. // Sigh. int Matched; } kbts_sequence_lookup_result; typedef struct kbts_sequence_match { kbts_un MatchCount; kbts_un MatchOrSkipCount; } kbts_sequence_match; static kbts_sequence_match kbts_MatchCoverageSequence(kbts_unpacked_lookup *Lookup, kbts_u32 SkipFlags, kbts_u32 SkipUnicodeFlags, void *Base, kbts_u16 *CoverageOffsets, kbts_un CoverageCount, kbts_glyph_array *GlyphArray, kbts_un GlyphStartIndex, kbts_un GlyphIndexIncrement) { kbts_un CoverageIndex = 0; kbts_un GlyphCounter = 0; kbts_un GlyphIndex = GlyphStartIndex; while((GlyphCounter < GlyphArray->Count) && (CoverageIndex < CoverageCount)) { kbts_glyph *Glyph = &GlyphArray->Glyphs[GlyphIndex]; kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Base, CoverageOffsets[CoverageIndex]); if(!kbts_SkipGlyph(Glyph, Lookup, SkipFlags, SkipUnicodeFlags)) { kbts_cover_glyph_result Cover = kbts_CoverGlyph(Coverage, Glyph->Id); if(Cover.Valid) { CoverageIndex += 1; } else { break; } } GlyphIndex += GlyphIndexIncrement; GlyphCounter += 1; } kbts_sequence_match Result = KBTS_ZERO; Result.MatchCount = CoverageIndex; Result.MatchOrSkipCount = GlyphCounter; return Result; } static int kbts_BranchlessCompareArray16(kbts_u16 *A, kbts_u16 *B, kbts_un Count) { kbts_u16 DifferenceMask = 0; KBTS_FOR(Index, 0, Count) { DifferenceMask |= A[Index] ^ B[Index]; } return (int)DifferenceMask; } static kbts_sequence_lookup_result kbts_DoSequenceLookup(kbts_unpacked_lookup *Lookup, kbts_u16 *Base, kbts_cover_glyph_result Cover, kbts_glyph_array *GlyphArray, kbts_un InputGlyphOffset, kbts_skip_flags SkipFlags, kbts_u32 SkipUnicodeFlags) { KBTS_INSTRUMENT_FUNCTION_BEGIN kbts_sequence_lookup_result Result = KBTS_ZERO; kbts_glyph_array BacktrackGlyphs = kbts_ClipGlyphArray(GlyphArray, InputGlyphOffset); kbts_glyph_array InputGlyphs = kbts_GlyphSubArray(GlyphArray, InputGlyphOffset); kbts_glyph_array FollowupGlyphs = kbts_GlyphSubArray(&InputGlyphs, 1); kbts_glyph *FirstGlyph = &GlyphArray->Glyphs[0]; kbts_glyph *CurrentGlyph = &GlyphArray->Glyphs[InputGlyphOffset]; kbts_glyph *InputGlyph = &GlyphArray->Glyphs[InputGlyphOffset + 1]; kbts_glyph *OnePastLastGlyph = &GlyphArray->Glyphs[GlyphArray->Count]; kbts_glyph *BacktrackGlyph = &GlyphArray->Glyphs[InputGlyphOffset - 1]; // Lookup types 7 and 8 are dispatch mechanisms. They do not substitute anything by themselves, they only point to // other rules. // Some formats have multiple rules; when that happens, we only ever match on the first one that fits. // We want to go to the right LookupType/SubtableFormat combination in a single jump, so we concatenate them here. // GSUB format 5 == GPOS format 7. // GSUB format 6 == GPOS format 8. switch(((kbts_u32)Lookup->Type << 16) | (kbts_u32)Base[0]) { case 0x50001: case 0x70001: { kbts_sequence_context_1 *Subst = (kbts_sequence_context_1 *)Base; kbts_sequence_rule_set *Set = kbts_GetSequenceRuleSet(Subst, Cover.Index); if(Set) { kbts_u16 Ids[64]; // @Hardcoded kbts_u16 GlyphOffsets[64]; kbts_un IdCount = 0; KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_sequence_rule *Rule = kbts_GetSequenceRule(Set, RuleIndex); kbts_u16 *InputSequence = KBTS_POINTER_AFTER(kbts_u16, Rule); // @Hardcoded! KBTS_ASSERT(Rule->GlyphCount <= 64); while((InputGlyph < OnePastLastGlyph) && ((IdCount + 1) < Rule->GlyphCount)) { if(!kbts_SkipGlyph(InputGlyph, Lookup, SkipFlags, SkipUnicodeFlags)) { GlyphOffsets[IdCount] = (kbts_u16)(InputGlyph - CurrentGlyph); Ids[IdCount++] = InputGlyph->Id; } InputGlyph += 1; } if(((IdCount + 1) >= Rule->GlyphCount) && !kbts_BranchlessCompareArray16(Ids, InputSequence, Rule->GlyphCount - 1)) { Result.Records = (kbts_sequence_lookup_record *)(InputSequence + Rule->GlyphCount - 1); Result.RecordCount = Rule->SequenceLookupCount; Result.InputSequenceCountIncludingSkippedGlyphs = 1; if(Rule->GlyphCount > 1) { Result.InputSequenceCountIncludingSkippedGlyphs = GlyphOffsets[Rule->GlyphCount - 2] + 1; } Result.Matched = 1; break; } } } } break; case 0x50002: case 0x70002: { kbts_sequence_context_2 *Subst = (kbts_sequence_context_2 *)Base; kbts_u16 *ClassDefinitionBase = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->ClassDefOffset); // @Hardcoded! kbts_u16 InputClasses[64]; kbts_u16 InputOffsets[64]; kbts_un InputCount = 0; // For class-based contexts, the coverage index is not used. // Instead, we know which set to use based on the current glyph's class. // From the Microsoft docs: // The class value is used as the index into an array of offsets to ClassSequenceRuleSet tables. kbts_glyph_class_from_table_result CurrentGlyphClass = kbts_GlyphClassFromTable(ClassDefinitionBase, CurrentGlyph->Id); kbts_class_sequence_rule_set *Set = kbts_GetClassSequenceRuleSet(Subst, CurrentGlyphClass.Class); if((CurrentGlyphClass.Class < Subst->ClassSequenceRuleSetCount) && Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_class_sequence_rule *Rule = kbts_GetClassSequenceRule(Set, RuleIndex); kbts_u16 *InputSequence = KBTS_POINTER_AFTER(kbts_u16, Rule); while((InputGlyph < OnePastLastGlyph) && ((InputCount + 1) < Rule->GlyphCount)) { if(!kbts_SkipGlyph(InputGlyph, Lookup, SkipFlags, SkipUnicodeFlags)) { InputOffsets[InputCount] = (kbts_u16)(InputGlyph - CurrentGlyph); InputClasses[InputCount++] = kbts_GlyphClassFromTable(ClassDefinitionBase, InputGlyph->Id).Class; } InputGlyph += 1; } if(((InputCount + 1) >= Rule->GlyphCount) && !kbts_BranchlessCompareArray16(InputClasses, InputSequence, Rule->GlyphCount - 1)) { Result.Records = (kbts_sequence_lookup_record *)(InputSequence + Rule->GlyphCount - 1); Result.RecordCount = Rule->SequenceLookupCount; Result.InputSequenceCountIncludingSkippedGlyphs = 1; if(Rule->GlyphCount > 1) { Result.InputSequenceCountIncludingSkippedGlyphs = InputOffsets[Rule->GlyphCount - 2] + 1; } Result.Matched = 1; break; } } } } break; case 0x50003: case 0x70003: { kbts_sequence_context_3 *Subst = (kbts_sequence_context_3 *)Base; kbts_u16 *CoverageOffsets = KBTS_POINTER_AFTER(kbts_u16, Subst); kbts_sequence_match InputMatch = kbts_MatchCoverageSequence(Lookup, SkipFlags, SkipUnicodeFlags, Subst, CoverageOffsets, Subst->GlyphCount, &InputGlyphs, 0, 1); if(InputMatch.MatchCount == Subst->GlyphCount) { Result.Records = (kbts_sequence_lookup_record *)(CoverageOffsets + Subst->GlyphCount); Result.RecordCount = Subst->SequenceLookupCount; Result.InputSequenceCountIncludingSkippedGlyphs = InputMatch.MatchOrSkipCount; Result.Matched = 1; } } break; case 0x60001: case 0x80001: { kbts_chained_sequence_context_1 *Subst = (kbts_chained_sequence_context_1 *)Base; kbts_chained_sequence_rule_set *Set = kbts_GetChainedSequenceRuleSet(Subst, Cover.Index); if(Set) { // @Hardcoded! kbts_u16 BacktrackIds[64]; kbts_u16 InputIds[64]; kbts_u16 InputOffsets[64]; kbts_un BacktrackCount = 0; kbts_un InputCount = 0; KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_chained_sequence_rule *Rule = kbts_GetChainedSequenceRule(Set, RuleIndex); kbts_unpacked_chained_sequence_rule Unpacked = kbts_UnpackChainedSequenceRule(Rule, 0); while((BacktrackGlyph >= FirstGlyph) && (BacktrackCount < Unpacked.BacktrackCount)) { if(!kbts_SkipGlyph(BacktrackGlyph, Lookup, SkipFlags, SkipUnicodeFlags)) { BacktrackIds[BacktrackCount++] = BacktrackGlyph->Id; } BacktrackGlyph -= 1; } kbts_un TotalInputGlyphsRequired = Unpacked.InputCount - 1 + Unpacked.LookaheadCount; while((InputGlyph < OnePastLastGlyph) && (InputCount < TotalInputGlyphsRequired)) { if(!kbts_SkipGlyph(InputGlyph, Lookup, SkipFlags, SkipUnicodeFlags)) { InputOffsets[InputCount] = (kbts_u16)(InputGlyph - CurrentGlyph); InputIds[InputCount++] = InputGlyph->Id; } InputGlyph += 1; } if((BacktrackCount >= Unpacked.BacktrackCount) && (InputCount >= TotalInputGlyphsRequired) && !kbts_BranchlessCompareArray16(BacktrackIds, Unpacked.Backtrack, Unpacked.BacktrackCount) && !kbts_BranchlessCompareArray16(InputIds, Unpacked.Input, Unpacked.InputCount - 1) && !kbts_BranchlessCompareArray16(InputIds + Unpacked.InputCount - 1, Unpacked.Lookahead, Unpacked.LookaheadCount)) { Result.Records = Unpacked.Records; Result.RecordCount = Unpacked.RecordCount; Result.InputSequenceCountIncludingSkippedGlyphs = 1; if(Unpacked.InputCount > 1) { Result.InputSequenceCountIncludingSkippedGlyphs = InputOffsets[Unpacked.InputCount - 2] + 1; } Result.Matched = 1; break; } } } } break; case 0x60002: case 0x80002: { kbts_chained_sequence_context_2 *Subst = (kbts_chained_sequence_context_2 *)Base; kbts_u16 *BacktrackClassDefinition = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->BacktrackClassDefOffset); kbts_u16 *InputClassDefinition = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->InputClassDefOffset); kbts_u16 *LookaheadClassDefinition = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->LookaheadClassDefOffset); // @Incomplete: Do this with all sequence types! // @Hardcoded: Pre-alloc this using LookupInfo! kbts_u16 BacktrackClasses[64]; kbts_u16 InputClasses[64]; kbts_u16 InputClassOffsets[64]; kbts_u16 LookaheadClasses[64]; kbts_un BacktrackClassCount = 0; kbts_un InputClassCount = 0; // Just like lookup 5.2, we use the current glyph class to figure out which set to look up. // From the Microsoft docs: // If found, the client then searches in the class definition table to find the class value assigned to the // current glyph. The class value is used as the index into an array of offsets to ChainedClassSequenceRuleSet // tables. // kbts_u16 CurrentGlyphClass = kbts_GlyphClassFromTable(InputClassDefinition, CurrentGlyph->Id).Class; kbts_chained_sequence_rule_set *Set = kbts_GetChainedClassSequenceRuleSet(Subst, CurrentGlyphClass); // If the glyph was contained in the coverage table, then it should have a valid class. // Nevertheless, one Harfbuzz test font did not remove out-of-bounds glyph classes from the class definition // table here, so we double-check it here. // (It is also possible for a font to want to reuse the same class definition table across multiple lookups, // in which case ignoring these classes becomes a feature.) if((CurrentGlyphClass < Subst->ChainedClassSequenceRuleSetCount) && Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_chained_sequence_rule *Rule = kbts_GetChainedClassSequenceRule(Set, RuleIndex); kbts_unpacked_chained_sequence_rule Unpacked = kbts_UnpackChainedSequenceRule(Rule, 0); // @Hardcoded KBTS_ASSERT(Unpacked.BacktrackCount <= 64); KBTS_ASSERT(Unpacked.InputCount <= 64); KBTS_ASSERT(Unpacked.LookaheadCount <= 64); while((BacktrackGlyph >= FirstGlyph) && (BacktrackClassCount < Unpacked.BacktrackCount)) { if(!kbts_SkipGlyph(BacktrackGlyph, Lookup, SkipFlags, SkipUnicodeFlags)) { // @Robustness: Do we want to break if we don't find a class? kbts_glyph_class_from_table_result Class = kbts_GlyphClassFromTable(BacktrackClassDefinition, BacktrackGlyph->Id); BacktrackClasses[BacktrackClassCount++] = Class.Class; } BacktrackGlyph -= 1; } kbts_un InputClassCountRequired = Unpacked.InputCount - 1 + Unpacked.LookaheadCount; while((InputGlyph < OnePastLastGlyph) && (InputClassCount < InputClassCountRequired)) { if(!kbts_SkipGlyph(InputGlyph, Lookup, SkipFlags, SkipUnicodeFlags)) { kbts_glyph_class_from_table_result InputClass = kbts_GlyphClassFromTable(InputClassDefinition, InputGlyph->Id); // In many cases, the font designer just wants to match "a set of glyphs" forward, // and it doesn't matter whether those glyphs are in the input sequence or part of the lookahead. // This happens often enough that we care to special-case it. kbts_glyph_class_from_table_result LookaheadClass = InputClass; if(LookaheadClassDefinition != InputClassDefinition) { LookaheadClass = kbts_GlyphClassFromTable(LookaheadClassDefinition, InputGlyph->Id); } // @Robustness: Do we want to break if we don't find a class? InputClassOffsets[InputClassCount] = (kbts_u16)(InputGlyph - CurrentGlyph); InputClasses[InputClassCount] = InputClass.Class; LookaheadClasses[InputClassCount] = LookaheadClass.Class; InputClassCount += 1; } InputGlyph += 1; } if((BacktrackClassCount >= Unpacked.BacktrackCount) && (InputClassCount >= InputClassCountRequired) && !kbts_BranchlessCompareArray16(BacktrackClasses, Unpacked.Backtrack, Unpacked.BacktrackCount) && !kbts_BranchlessCompareArray16(InputClasses, Unpacked.Input, Unpacked.InputCount - 1) && !kbts_BranchlessCompareArray16(LookaheadClasses + Unpacked.InputCount - 1, Unpacked.Lookahead, Unpacked.LookaheadCount)) { Result.Records = Unpacked.Records; Result.RecordCount = Unpacked.RecordCount; Result.InputSequenceCountIncludingSkippedGlyphs = 1; if(Unpacked.InputCount > 1) { Result.InputSequenceCountIncludingSkippedGlyphs = InputClassOffsets[Unpacked.InputCount - 2] + 1; } Result.Matched = 1; break; } } } } break; case 0x60003: case 0x80003: { kbts_chained_sequence_context_3 *Subst = (kbts_chained_sequence_context_3 *)Base; kbts_unpacked_chained_sequence_context_3 Unpacked = kbts_UnpackChainedSequenceContext3(Subst, 0); // Since chained sequence contexts roll the coverage for the first glyph into an array, you'd think that // the matching logic for the first glyph would be the same as for any other glyph in that array. // You'd be wrong! // The first glyph does _not_ have to pass glyph filtering logic. It just has to pass the coverage test. // Every other input glyph still does, though. kbts_cover_glyph_result CurrentCover = KBTS_ZERO; CurrentCover.Valid = !Unpacked.InputCount || kbts_GlyphPassesLookupFilter(InputGlyphs.Glyphs, Lookup); if(Unpacked.InputCount) { kbts_coverage *CurrentCoverage = KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.InputCoverageOffsets[0]); CurrentCover = kbts_CoverGlyph(CurrentCoverage, InputGlyphs.Glyphs[0].Id); } if(CurrentCover.Valid) { kbts_sequence_match BacktrackMatch = kbts_MatchCoverageSequence(Lookup, SkipFlags, SkipUnicodeFlags, Subst, Unpacked.BacktrackCoverageOffsets, Unpacked.BacktrackCount, &BacktrackGlyphs, BacktrackGlyphs.Count - 1, -1); kbts_sequence_match InputMatch = kbts_MatchCoverageSequence(Lookup, SkipFlags, SkipUnicodeFlags, Subst, Unpacked.InputCoverageOffsets + 1, Unpacked.InputCount - 1, &FollowupGlyphs, 0, 1); kbts_un MatchingInputGlyphCount = 1 + InputMatch.MatchCount; kbts_un MatchedOrSkippedInputGlyphCount = 1 + InputMatch.MatchOrSkipCount; kbts_glyph_array LookaheadGlyphs = kbts_GlyphSubArray(&InputGlyphs, MatchedOrSkippedInputGlyphCount); kbts_sequence_match LookaheadMatch = kbts_MatchCoverageSequence(Lookup, SkipFlags, SkipUnicodeFlags, Subst, Unpacked.LookaheadCoverageOffsets, Unpacked.LookaheadCount, &LookaheadGlyphs, 0, 1); if((BacktrackMatch.MatchCount == Unpacked.BacktrackCount) && ((MatchingInputGlyphCount) == Unpacked.InputCount) && (LookaheadMatch.MatchCount == Unpacked.LookaheadCount)) { Result.Records = Unpacked.Records; Result.RecordCount = Unpacked.RecordCount; Result.InputSequenceCountIncludingSkippedGlyphs = MatchedOrSkippedInputGlyphCount; Result.Matched = 1; break; } } } break; } KBTS_INSTRUMENT_END return Result; } static void kbts_ApplyValueRecord(kbts_glyph *Glyph, kbts_unpacked_value_record *Unpacked) { Glyph->OffsetX += Unpacked->PlacementX; Glyph->OffsetY += Unpacked->PlacementY; Glyph->AdvanceX += Unpacked->AdvanceX; Glyph->AdvanceY += Unpacked->AdvanceY; } typedef struct kbts_indexed_glyph { kbts_glyph *Glyph; kbts_un Index; } kbts_indexed_glyph; static int kbts_NextGlyph(kbts_unpacked_lookup *Lookup, kbts_glyph *InputGlyphs, kbts_un CurrentIndex, kbts_un InputGlyphCount, kbts_skip_flags SkipFlags, kbts_u32 SkipUnicodeFlags, kbts_indexed_glyph *IndexedGlyph) { kbts_glyph *MatchingGlyph = 0; kbts_un GlyphIndex = CurrentIndex; while(GlyphIndex < InputGlyphCount) { kbts_glyph *Glyph = &InputGlyphs[GlyphIndex]; if(!kbts_SkipGlyph(Glyph, Lookup, SkipFlags, SkipUnicodeFlags)) { MatchingGlyph = Glyph; break; } else { GlyphIndex += 1; } } IndexedGlyph->Glyph = MatchingGlyph; IndexedGlyph->Index = GlyphIndex; return MatchingGlyph != 0; } static void kbts_AttachGlyph(kbts_glyph_array *GlyphArray, kbts_glyph *Parent, kbts_glyph *Child, kbts_s32 X, kbts_s32 Y) { kbts_s32 DeltaOffsetX = X - Child->OffsetX; kbts_s32 DeltaOffsetY = Y - Child->OffsetY; Child->OffsetX = X; Child->OffsetY = Y; Child->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS; Child->AttachGlyphIndexPlusOne = (kbts_u16)(Parent - GlyphArray->Glyphs + 1); Parent->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS; for(kbts_glyph *MiddleGlyph = Parent + 1; MiddleGlyph < Child; ++MiddleGlyph) { MiddleGlyph->Flags |= KBTS_GLYPH_FLAG_NO_BREAK; } // @Speed: Fuck this. // Attachments can happen in anti-topological order, so we have to fix them up here. // We should store glyph parent/child indices instead of traversing all glyphs. kbts_un ChildIndex = (kbts_un)(Child - GlyphArray->Glyphs); KBTS_FOR(PostGlyphIndex, ChildIndex + 1, GlyphArray->Count) { kbts_glyph *Glyph = &GlyphArray->Glyphs[PostGlyphIndex]; if(Glyph->AttachGlyphIndexPlusOne == (ChildIndex + 1)) { Glyph->OffsetX += DeltaOffsetX; Glyph->OffsetY += DeltaOffsetY; } } } typedef struct kbts_do_single_adjustment_result { kbts_un PositionedGlyphCount; kbts_u32 PerformedAdjustment; } kbts_do_single_adjustment_result; static kbts_do_single_adjustment_result kbts_DoSingleAdjustment(kbts_shape_config *Config, kbts_lookup_list *LookupList, kbts_un LookupIndex, kbts_un SubtableIndex, kbts_unpacked_lookup *Lookup, kbts_u16 *Base, kbts_glyph_array *GlyphArray, kbts_un CurrentGlyphIndex, kbts_skip_flags RequestedSkipFlags) { KBTS_INSTRUMENT_FUNCTION_BEGIN kbts_unicode_flags SkipUnicodeFlags = KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE; kbts_skip_flags RegularSkipFlags = KBTS_SKIP_FLAGS_GPOS_REGULAR(RequestedSkipFlags); kbts_skip_flags SequenceSkipFlags = KBTS_SKIP_FLAGS_GPOS_SEQUENCE(RequestedSkipFlags); kbts_do_single_adjustment_result Result = KBTS_ZERO; kbts_glyph *CurrentGlyph = &GlyphArray->Glyphs[CurrentGlyphIndex]; if(kbts_GlyphsIncludedInLookupSubtable(Config->Font, 1, Lookup, LookupIndex, SubtableIndex, GlyphArray, CurrentGlyphIndex, SequenceSkipFlags, SkipUnicodeFlags)) { Result.PerformedAdjustment = 1; // CAREFUL: We want kbts_unpacked_lookup to be a useful bag-of-arguments type, but, for extension // lookups, each subtable may specify its own lookup type, so we save it here and restore it at // the end of this function. kbts_u16 OriginalLookupType = Lookup->Type; while(Lookup->Type == 9) { kbts_extension *Extension = (kbts_extension *)Base; Lookup->Type = Extension->LookupType; Base = KBTS_POINTER_OFFSET(kbts_u16, Extension, Extension->Offset); } kbts_glyph *InputGlyphs = GlyphArray->Glyphs + CurrentGlyphIndex; kbts_un InputGlyphCount = GlyphArray->Count - CurrentGlyphIndex; kbts_cover_glyph_result Cover = KBTS_ZERO; Cover.Valid = kbts_GlyphPassesLookupFilter(CurrentGlyph, Lookup); kbts_coverage *Coverage = 0; if(Cover.Valid && kbts_GposLookupBeginsWithCoverage(Lookup->Type, Base[0])) { kbts_u16 *CoverageOffset = Base + 1; Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Base, *CoverageOffset); Cover = kbts_CoverGlyph(Coverage, CurrentGlyph->Id); } if(Cover.Valid) { switch(Lookup->Type) { case 1: { kbts_unpacked_value_record Unpacked = KBTS_ZERO; if(Base[0] == 1) { kbts_single_adjustment_1 *Adjust = (kbts_single_adjustment_1 *)Base; Unpacked = kbts_UnpackValueRecord(Adjust, Adjust->ValueFormat, KBTS_POINTER_AFTER(kbts_u16, Adjust)); } else if(Base[0] == 2) { kbts_single_adjustment_2 *Adjust = (kbts_single_adjustment_2 *)Base; kbts_un RecordSize = kbts_PopCount32(Adjust->ValueFormat); kbts_u16 *Records = KBTS_POINTER_AFTER(kbts_u16, Adjust); kbts_u16 *Record = Records + RecordSize * Cover.Index; Unpacked = kbts_UnpackValueRecord(Adjust, Adjust->ValueFormat, Record); } kbts_ApplyValueRecord(CurrentGlyph, &Unpacked); CurrentGlyph->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS; Result.PositionedGlyphCount = 1; } break; case 2: { kbts_indexed_glyph NextGlyph; if(kbts_NextGlyph(Lookup, InputGlyphs, 1, InputGlyphCount, RegularSkipFlags, SkipUnicodeFlags, &NextGlyph)) { kbts_u32 NextGlyphId = NextGlyph.Glyph->Id; kbts_unpacked_value_record Unpacked1 = KBTS_ZERO; kbts_unpacked_value_record Unpacked2 = KBTS_ZERO; int Valid = 0; if(Base[0] == 1) { kbts_pair_adjustment_1 *Adjust = (kbts_pair_adjustment_1 *)Base; kbts_un Size1 = kbts_PopCount32(Adjust->ValueFormat1); kbts_un Size2 = kbts_PopCount32(Adjust->ValueFormat2); kbts_u16 *SetOffsets = KBTS_POINTER_AFTER(kbts_u16, Adjust); kbts_pair_set *Set = KBTS_POINTER_OFFSET(kbts_pair_set, Adjust, SetOffsets[Cover.Index]); kbts_un PairRecordSize = Size1 + Size2 + 1; // + 1 because each pair stores the next glyph ID. kbts_pair_value_record *PairRecords = KBTS_POINTER_AFTER(kbts_pair_value_record, Set); KBTS_FOR(PairIndex, 0, Set->Count) { kbts_pair_value_record *PairRecord = PairRecords + PairRecordSize * PairIndex; if(PairRecord->SecondGlyph == NextGlyphId) { kbts_u16 *Records = KBTS_POINTER_AFTER(kbts_u16, PairRecord); Unpacked1 = kbts_UnpackValueRecord(Adjust, Adjust->ValueFormat1, Records); Records += Unpacked1.Size; Unpacked2 = kbts_UnpackValueRecord(Adjust, Adjust->ValueFormat2, Records); Valid = 1; } } } else if(Base[0] == 2) { kbts_pair_adjustment_2 *Adjust = (kbts_pair_adjustment_2 *)Base; kbts_u16 *ClassDef1 = KBTS_POINTER_OFFSET(kbts_u16, Adjust, Adjust->ClassDefinition1Offset); kbts_u16 *ClassDef2 = KBTS_POINTER_OFFSET(kbts_u16, Adjust, Adjust->ClassDefinition2Offset); kbts_un Size1 = kbts_PopCount32(Adjust->ValueFormat1); kbts_un Size2 = kbts_PopCount32(Adjust->ValueFormat2); kbts_un PairRecordSize = Size1 + Size2; kbts_u16 *PairRecords = KBTS_POINTER_AFTER(kbts_u16, Adjust); // From the Microsoft docs: // PairPosFormat2 requires that each glyph in all pairs be assigned to a class, which is // identified by an integer called a class value. // This _seems_ like it would mean that, if either glyph is not specified in its respective // class definition table, then we should skip the lookup. // However, this seems wrong in practice. Undefined classes seem to just default to 0, and then // the bounds check takes care of deciding whether the lookup is okay to apply or not. kbts_glyph_class_from_table_result Class1 = kbts_GlyphClassFromTable(ClassDef1, CurrentGlyph->Id); kbts_glyph_class_from_table_result Class2 = kbts_GlyphClassFromTable(ClassDef2, NextGlyphId); if((Class1.Class < Adjust->Class1Count) && (Class2.Class < Adjust->Class2Count)) { kbts_u16 *PairRecord = PairRecords + Class1.Class * PairRecordSize * Adjust->Class2Count + Class2.Class * PairRecordSize; Unpacked1 = kbts_UnpackValueRecord(Adjust, Adjust->ValueFormat1, PairRecord); PairRecord += Size1; Unpacked2 = kbts_UnpackValueRecord(Adjust, Adjust->ValueFormat2, PairRecord); PairRecord += Size2; Valid = 1; } } if(Valid) { kbts_ApplyValueRecord(CurrentGlyph, &Unpacked1); CurrentGlyph->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS; kbts_ApplyValueRecord(&InputGlyphs[NextGlyph.Index], &Unpacked2); NextGlyph.Glyph->Flags |= KBTS_GLYPH_FLAG_USED_IN_GPOS; Result.PositionedGlyphCount = 2; if(!Unpacked2.Size) { Result.PositionedGlyphCount = 1; } } } } break; // All three types of attachment (cursive, mark-to-base, mark-to-ligature) look backward instead of forward. case 3: { kbts_cursive_attachment *Adjust = (kbts_cursive_attachment *)Base; kbts_entry_exit *EntryExits = KBTS_POINTER_AFTER(kbts_entry_exit, Adjust); kbts_glyph *Prev = 0; for(kbts_un PrevIndex = CurrentGlyphIndex; PrevIndex > 0; --PrevIndex) { kbts_glyph *PrevGlyph = &GlyphArray->Glyphs[PrevIndex - 1]; if(!kbts_SkipGlyph(PrevGlyph, Lookup, RegularSkipFlags, SkipUnicodeFlags)) { Prev = PrevGlyph; break; } } if(Prev) { // For two cursive glyphs to be aligned, they both need to be defined by the same cursive attachment table. kbts_cover_glyph_result PrevCover = kbts_CoverGlyph(Coverage, Prev->Id); if(PrevCover.Valid) { // Get anchor points for both glyphs. kbts_entry_exit *PrevEntryExit = &EntryExits[PrevCover.Index]; kbts_entry_exit *EntryExit = &EntryExits[Cover.Index]; if(PrevEntryExit->ExitAnchorOffset && EntryExit->EntryAnchorOffset) { kbts_anchor *PrevExitAnchor = KBTS_POINTER_OFFSET(kbts_anchor, Adjust, PrevEntryExit->ExitAnchorOffset); kbts_anchor *EntryAnchor = KBTS_POINTER_OFFSET(kbts_anchor, Adjust, EntryExit->EntryAnchorOffset); kbts_s32 Anchor0X = PrevExitAnchor->X; kbts_s32 Anchor0Y = PrevExitAnchor->Y; kbts_s32 Anchor1X = EntryAnchor->X; kbts_s32 Anchor1Y = EntryAnchor->Y; kbts_s32 Advance0X = Prev->AdvanceX; kbts_s32 Advance1X = CurrentGlyph->AdvanceX; kbts_s32 Offset0X = Prev->OffsetX; kbts_s32 Offset0Y = Prev->OffsetY; kbts_s32 Offset1X = CurrentGlyph->OffsetX; kbts_s32 Offset1Y = CurrentGlyph->OffsetY; // Cursive positioning is made up of two parts. // The first part is glyph-to-glyph alignment, which depends on the text direction. // Here, we are only concerned with making the relative placements of the glyphs correct, // insofar as they follow the specified anchor positions. // // The OpenType spec makes no attempt to describe how the two glyphs should be aligned, mathematically // speaking. // // This is all we get: // // "To position glyphs using the CursivePosFormat1 subtable, a text-processing client aligns the exit // anchor point of a glyph with the entry anchor point of the following glyph." // // In practice, we reproduce harfbuzz's behavior here, which is: // - Glyph1.Offset.X is unaffected // - Glyph1.Advance.X = Glyph1.Offset.X + Glyph1.Anchor.X, aka. the _actual position of its anchor_ // - Glyph2.Offset.X = -Glyph2.Anchor.X // - Glyph2.Offset.Y = Glyph1.Anchor.Y - Glyph2.Anchor.Y // - Glyph2.Advance.X -= Glyph2.Anchor.X // // (...where "X" here just means "the main direction". In top-to-bottom or bottom-to-top contexts, that // would be the Y coordinate, but we do not support those yet.) // // So, instead of aligning everything with offsets, we use Advance to align _the rest of the string_ // horizontally with the first glyph, and not just the next glyph. // // It might seem dumb to modify both Glyph2.Offset _and_ Glyph2.Advance, because, when the glyphs are next // to one another, this is equivalent to modifying Glyph1.Advance. However, due to lookup flag nonsense, // there may be some glyphs between Glyph1 and Glyph2, and, _apparently_, it is fine to adjust them by the // position of Glyph1's anchor point, and it is not fine to adjust them by the position of Glyph2's anchor // point. // // This Advance tweak seems like it would be wrong, because any marks attached to Glyph1 will then have // invalid positions. The hope is that this does not matter in practice, because 'mark' is applied after // 'curs', and font designers are expected to know that and to know never to apply mark attachments // before cursive positioning, I guess. if(!kbts_ShaperRtl(Config->Shaper)) { Advance0X = Offset0X + Anchor0X; kbts_s32 Dx = -Anchor1X - Offset1X; Advance1X += Dx; Offset1X += Dx; } else { kbts_s32 Dx = -Anchor0X - Offset0X; Advance0X += Dx; Offset0X += Dx; Advance1X = Offset1X + Anchor1X; } Prev->AdvanceX = Advance0X; Prev->OffsetX = Offset0X; Prev->Flags |= (KBTS_GLYPH_FLAG_CURSIVE | KBTS_GLYPH_FLAG_USED_IN_GPOS | KBTS_GLYPH_FLAG_NO_BREAK); CurrentGlyph->AdvanceX = Advance1X; CurrentGlyph->OffsetX = Offset1X; CurrentGlyph->Flags |= (KBTS_GLYPH_FLAG_CURSIVE | KBTS_GLYPH_FLAG_USED_IN_GPOS); for(kbts_glyph *CursiveGlyph = Prev + 1; CursiveGlyph < CurrentGlyph; ++CursiveGlyph) { CursiveGlyph->Flags |= KBTS_GLYPH_FLAG_NO_BREAK; } // The second part is aligning the newly-formed cursive cluster to the "baseline". It is trickier than you'd expect. // // When applying cursive attachments, Glyph1 (RIGHT_TO_LEFT=0) or Glyph2 (RIGHT_TO_LEFT=1) is treated as being // "on the baseline" and its Y coordinate is used as the reference Y coordinate for the entire cursive glyph // cluster that has been formed so far. // This means that, anytime we apply a cursive attachment, we have to offset _all_ of the cursive glyphs to the // left (RIGHT_TO_LEFT=0) or to the right (RIGHT_TO_LEFT=1) of it. // This is obviously O(n^2), and @Speed: it might be worthwhile to record cursive offsets as we go, and only resolve // them when we actually need them, i.e. when applying a non-cursive lookup or, at the latest, when we are done with // positioning. // // The glyph being attached is set at a hard relative offset from the reference glyph. Its previous Y coordinate only // matters insofar as we need to align every other cursive glyph in its direction. kbts_s32 CursiveDy = 0; kbts_un CursiveStartIndex = CurrentGlyphIndex; kbts_un DIndex = 1; if(!(Lookup->Flags & KBTS_LOOKUP_FLAG_RIGHT_TO_LEFT)) { kbts_s32 NewOffset1Y = Offset0Y + Anchor0Y - Anchor1Y; CursiveDy = NewOffset1Y - Offset1Y; } else { kbts_s32 NewOffset0Y = Offset1Y + Anchor1Y - Anchor0Y; CursiveDy = NewOffset0Y - Offset0Y; DIndex = -1; CursiveStartIndex = (kbts_un)(Prev - GlyphArray->Glyphs); } for(kbts_un CursiveGlyphIndex = CursiveStartIndex; CursiveGlyphIndex < GlyphArray->Count; CursiveGlyphIndex += DIndex) { kbts_glyph *CursiveGlyph = &GlyphArray->Glyphs[CursiveGlyphIndex]; if(CursiveGlyph->Flags & KBTS_GLYPH_FLAG_CURSIVE) { CursiveGlyph->OffsetY += CursiveDy; } else if(CursiveGlyph->AdvanceX | CursiveGlyph->AdvanceY) // Ignore marks. { break; } } Result.PositionedGlyphCount = 1; } } } } break; case 4: case 6: { kbts_mark_to_base_attachment *Adjust = (kbts_mark_to_base_attachment *)Base; // We want to know which glyph to attach to, and how far that glyph is from us. // To do that, we add up all advances between it and us. // There is a slight wrinkle here: most shapers end up zeroing mark advances at the _end_ // of the shaping process, which would retroactively make a naive advance accumulation wrong. // We have to take that into account here, and only accumulate mark advances for shapers that // don't do that zeroing at the end (either because they do it at the beginning of GPOS, or // because they don't do it at all). int CountMarkAdvances = !kbts_ShaperClearsMarkAdvancesInPostGposFixup(Config->Shaper); kbts_s32 AdvanceSinceBaseX = 0; kbts_s32 AdvanceSinceBaseY = 0; kbts_u32 BaseClasses = Lookup->Type == 6 ? (1 << KBTS_GLYPH_CLASS_MARK) : (1 | (1 << KBTS_GLYPH_CLASS_BASE) | (1 << KBTS_GLYPH_CLASS_LIGATURE) | (1 << KBTS_GLYPH_CLASS_COMPONENT)); kbts_glyph *BaseGlyph = 0; for(kbts_un PrevGlyphIndex = CurrentGlyphIndex; PrevGlyphIndex; --PrevGlyphIndex) { kbts_glyph *PrevGlyph = &GlyphArray->Glyphs[PrevGlyphIndex - 1]; if(CountMarkAdvances || (PrevGlyph->Classes.Class != KBTS_GLYPH_CLASS_MARK)) { AdvanceSinceBaseX += PrevGlyph->AdvanceX; AdvanceSinceBaseY += PrevGlyph->AdvanceY; } if(!kbts_SkipGlyph(PrevGlyph, Lookup, RegularSkipFlags, SkipUnicodeFlags)) { if((1 << PrevGlyph->Classes.Class) & BaseClasses) { BaseGlyph = PrevGlyph; break; } else if(Lookup->Type == 6) { // Unskipped non-marks block mark attachments. break; } } } if(BaseGlyph) { int Ok = (Lookup->Type == 4) || // This is a mark-to-base attachment ((BaseGlyph->LigatureUid == CurrentGlyph->LigatureUid) && (BaseGlyph->LigatureComponentIndexPlusOne == CurrentGlyph->LigatureComponentIndexPlusOne)) || // This is a mark-to-mark attachment, and both marks belong to the same ligature component ((BaseGlyph->Flags | CurrentGlyph->Flags) & KBTS_GLYPH_FLAG_LIGATURE); // This is a mark-to-mark attachment, and either mark was created by a ligature substitution if(Ok) { kbts_cover_glyph_result BaseCover = kbts_CoverGlyph(KBTS_POINTER_OFFSET(kbts_coverage, Adjust, Adjust->BaseCoverageOffset), BaseGlyph->Id); if(BaseCover.Valid) { kbts_base_array *BaseArray = KBTS_POINTER_OFFSET(kbts_base_array, Adjust, Adjust->BaseArrayOffset); kbts_u16 *BaseAnchorOffsets = KBTS_POINTER_AFTER(kbts_u16, BaseArray) + BaseCover.Index * Adjust->MarkClassCount; kbts_mark_info MarkInfo = kbts_GetMarkInfo(Adjust, Adjust->MarkArrayOffset, Cover.Index); kbts_u16 BaseAnchorOffset = BaseAnchorOffsets[MarkInfo.Record->Class]; if(BaseAnchorOffset) { kbts_anchor *BaseAnchor = KBTS_POINTER_OFFSET(kbts_anchor, BaseArray, BaseAnchorOffset); /* From the Microsoft docs: When a mark is combined with a given base, the mark placement is adjusted so that the mark anchor is aligned with the base anchor for the applicable mark class. Placement of the base glyph and advances of both glyphs are not affected. */ kbts_s32 NewOffsetX = BaseGlyph->OffsetX - AdvanceSinceBaseX + (BaseAnchor->X - MarkInfo.Anchor->X); kbts_s32 NewOffsetY = BaseGlyph->OffsetY - AdvanceSinceBaseY + (BaseAnchor->Y - MarkInfo.Anchor->Y); kbts_AttachGlyph(GlyphArray, BaseGlyph, CurrentGlyph, NewOffsetX, NewOffsetY); Result.PositionedGlyphCount = 1; } } } } } break; case 5: { kbts_mark_to_ligature_attachment *Adjust = (kbts_mark_to_ligature_attachment *)Base; kbts_s32 AdvanceSinceBaseX = 0; kbts_s32 AdvanceSinceBaseY = 0; kbts_u32 BaseClasses = (1 | (1 << KBTS_GLYPH_CLASS_BASE) | (1 << KBTS_GLYPH_CLASS_LIGATURE) | (1 << KBTS_GLYPH_CLASS_COMPONENT)); kbts_glyph *LigatureGlyph = 0; for(kbts_un PrevGlyphIndex = CurrentGlyphIndex; PrevGlyphIndex; --PrevGlyphIndex) { kbts_glyph *PrevGlyph = &GlyphArray->Glyphs[PrevGlyphIndex - 1]; AdvanceSinceBaseX += PrevGlyph->AdvanceX; AdvanceSinceBaseY += PrevGlyph->AdvanceY; if(!kbts_SkipGlyph(PrevGlyph, Lookup, RegularSkipFlags, SkipUnicodeFlags) && ((1 << PrevGlyph->Classes.Class) & BaseClasses)) { LigatureGlyph = PrevGlyph; break; } } if(LigatureGlyph) { kbts_cover_glyph_result LigatureCover = kbts_CoverGlyph(KBTS_POINTER_OFFSET(kbts_coverage, Adjust, Adjust->LigatureCoverageOffset), LigatureGlyph->Id); if(LigatureCover.Valid) { kbts_ligature_array *LigatureArray = KBTS_POINTER_OFFSET(kbts_ligature_array, Adjust, Adjust->LigatureArrayOffset); kbts_ligature_attach *LigatureAttach = kbts_GetLigatureAttach(LigatureArray, LigatureCover.Index); kbts_mark_info MarkInfo = kbts_GetMarkInfo(Adjust, Adjust->MarkArrayOffset, Cover.Index); kbts_un LigatureComponentIndex = CurrentGlyph->LigatureComponentIndexPlusOne; if(CurrentGlyph->LigatureUid != LigatureGlyph->Uid) { // If the mark is not yet attached to the ligature, attach it now. // Apparently, in this case, the mark should be considered part of the _last_ component of the ligature. LigatureComponentIndex = LigatureAttach->Count; } if(CurrentGlyph->LigatureComponentIndexPlusOne <= LigatureAttach->Count) { kbts_un AnchorIndex = LigatureComponentIndex; if(AnchorIndex) { AnchorIndex -= 1; } else { AnchorIndex = LigatureAttach->Count - 1; } kbts_anchor *LigatureAnchor = kbts_GetLigatureAttachAnchor(Adjust, LigatureAttach, MarkInfo.Record->Class, AnchorIndex); kbts_s32 NewOffsetX = LigatureGlyph->OffsetX - AdvanceSinceBaseX + (LigatureAnchor->X - MarkInfo.Anchor->X); kbts_s32 NewOffsetY = LigatureGlyph->OffsetY - AdvanceSinceBaseY + (LigatureAnchor->Y - MarkInfo.Anchor->Y); kbts_AttachGlyph(GlyphArray, LigatureGlyph, CurrentGlyph, NewOffsetX, NewOffsetY); CurrentGlyph->LigatureComponentIndexPlusOne = (kbts_u16)LigatureComponentIndex; CurrentGlyph->LigatureUid = LigatureGlyph->Uid; // I'm not sure why, but Harfbuzz only clears this in mark-to-ligature substitutions, and not in mark-to-base or // mark-to-mark. CurrentGlyph->AdvanceX = 0; CurrentGlyph->AdvanceY = 0; for(kbts_glyph *MiddleGlyph = LigatureGlyph + 1; MiddleGlyph < CurrentGlyph; ++MiddleGlyph) { MiddleGlyph->Flags |= KBTS_GLYPH_FLAG_NO_BREAK; } Result.PositionedGlyphCount = 1; } } } } break; case 7: case 8: { kbts_sequence_lookup_result SequenceLookup = kbts_DoSequenceLookup(Lookup, Base, Cover, GlyphArray, CurrentGlyphIndex, SequenceSkipFlags, SkipUnicodeFlags); if(SequenceLookup.RecordCount) { KBTS_FOR(RecordIndex, 0, SequenceLookup.RecordCount) { kbts_sequence_lookup_record *Record = &SequenceLookup.Records[RecordIndex]; kbts_lookup *PackedRecordLookup = kbts_GetLookup(LookupList, Record->LookupListIndex); kbts_unpacked_lookup RecordLookup = kbts_UnpackLookup(Config->Font->Gdef, PackedRecordLookup); kbts_un NestedCurrentGlyphIndex = CurrentGlyphIndex; { // Figure out where in the input sequence we need to apply the lookup. kbts_un SequenceIndex = 0; KBTS_FOR(InputGlyphIndex, 0, InputGlyphCount) { kbts_un NestedIndex = CurrentGlyphIndex + InputGlyphIndex; kbts_glyph *Glyph = &GlyphArray->Glyphs[NestedIndex]; if(!kbts_SkipGlyph(Glyph, Lookup, SequenceSkipFlags, SkipUnicodeFlags)) { if(SequenceIndex == Record->SequenceIndex) { NestedCurrentGlyphIndex = NestedIndex; break; } SequenceIndex += 1; } } } KBTS_FOR(NestedSubtableIndex, 0, RecordLookup.SubtableCount) { kbts_u16 *NestedBase = KBTS_POINTER_OFFSET(kbts_u16, PackedRecordLookup, RecordLookup.SubtableOffsets[NestedSubtableIndex]); kbts_DoSingleAdjustment(Config, LookupList, Record->LookupListIndex, NestedSubtableIndex, &RecordLookup, NestedBase, GlyphArray, NestedCurrentGlyphIndex, RequestedSkipFlags); } } Result.PositionedGlyphCount = SequenceLookup.InputSequenceCountIncludingSkippedGlyphs; } } break; } } Lookup->Type = OriginalLookupType; } if(!Result.PositionedGlyphCount) { Result.PositionedGlyphCount = 1; Result.PerformedAdjustment = 0; } KBTS_INSTRUMENT_END return Result; } typedef kbts_u32 kbts_mcm_sequence_state; enum kbts_mcm_sequence_state_enum { KBTS_MCM_SEQUENCE_STATE_NONE, KBTS_MCM_SEQUENCE_STATE_OUT, KBTS_MCM_SEQUENCE_STATE_IN, }; typedef kbts_u32 kbts_hangul_syllable_type; enum kbts_hangul_syllable_type_enum { KBTS_HANGUL_SYLLABLE_TYPE_NONE, KBTS_HANGUL_SYLLABLE_TYPE_L, KBTS_HANGUL_SYLLABLE_TYPE_V, KBTS_HANGUL_SYLLABLE_TYPE_T, KBTS_HANGUL_SYLLABLE_TYPE_LV, KBTS_HANGUL_SYLLABLE_TYPE_LVT, KBTS_HANGUL_SYLLABLE_TYPE_COUNT, }; typedef struct kbts_hangul_syllable_info { kbts_hangul_syllable_type Type; kbts_u32 Composable; } kbts_hangul_syllable_info; static kbts_hangul_syllable_info kbts_HangulSyllableInfo(kbts_u32 Codepoint) { kbts_hangul_syllable_info Result = KBTS_ZERO; if((Codepoint >= 0x1100) && (Codepoint <= 0x115F)) { Result.Type = KBTS_HANGUL_SYLLABLE_TYPE_L; Result.Composable = (Codepoint < 0x1113); } else if((Codepoint >= 0x1160) && (Codepoint <= 0x11A7)) { Result.Type = KBTS_HANGUL_SYLLABLE_TYPE_V; Result.Composable = ((Codepoint >= 0x1161) & (Codepoint <= 0x1175)); } else if((Codepoint >= 0x11A8) && (Codepoint <= 0x11FF)) { Result.Type = KBTS_HANGUL_SYLLABLE_TYPE_T; Result.Composable = (Codepoint < 0x11C3); } else if((Codepoint >= 0xA960) && (Codepoint <= 0xA97C)) { Result.Type = KBTS_HANGUL_SYLLABLE_TYPE_L; } else if((Codepoint == 0xAC00) && (Codepoint <= 0xD7A3)) { Result.Type = KBTS_HANGUL_SYLLABLE_TYPE_LVT; if(!((Codepoint - 0xAC00) % 28)) { Result.Type = KBTS_HANGUL_SYLLABLE_TYPE_LV; } } else if((Codepoint >= 0xD7B0) && (Codepoint <= 0xD7C6)) { Result.Type = KBTS_HANGUL_SYLLABLE_TYPE_V; } else if((Codepoint >= 0xD7CB) && (Codepoint <= 0xD7FB)) { Result.Type = KBTS_HANGUL_SYLLABLE_TYPE_T; } return Result; } KBTS_INLINE kbts_u32 kbts_SyllabicClassIsConsonant(kbts_indic_syllabic_class Class) { kbts_u32 Result = KBTS_IN_SET(Class, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_CONSONANT)(KBTS_INDIC_SYLLABIC_CLASS_RA)(KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER)(KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL))); return Result; } enum { KBTS_FEATURE_MATCH_FLAG_KA_JA = (1 << 0), KBTS_FEATURE_MATCH_FLAG_SSA_NYA = (1 << 1), KBTS_FEATURE_MATCH_FLAG_RA_HA_VA = (1 << 2), KBTS_FEATURE_MATCH_FLAG_YA = (1 << 3), KBTS_FEATURE_MATCH_FLAG_CONSONANT = (1 << 4), KBTS_FEATURE_MATCH_FLAG_NUKTA = (1 << 5), KBTS_FEATURE_MATCH_FLAG_HALANT = (1 << 6), KBTS_FEATURE_MATCH_FLAG_ZWJ = (1 << 7), KBTS_FEATURE_MATCH_FLAG_ZWNJ = (1 << 8), KBTS_FEATURE_MATCH_FLAG_INITIAL = (1 << 10), KBTS_FEATURE_MATCH_FLAG_POST_BASE = (1 << 11), KBTS_FEATURE_MATCH_FLAG_RPHF = KBTS_FEATURE_FLAG0(rphf), }; # define KBTS_FEATURE_MATCH_MASK(W0, W1, W2, W3) (((kbts_u64)(W0) << 48) | ((kbts_u64)(W1) << 32) | ((kbts_u64)(W0) << 16) | (kbts_u64)(W0)) # define KBTS_FEATURE_MATCH_MASK_AKHN KBTS_FEATURE_MATCH_MASK(0, KBTS_FEATURE_MATCH_FLAG_KA_JA, KBTS_FEATURE_MATCH_FLAG_HALANT, KBTS_FEATURE_MATCH_FLAG_SSA_NYA) # define KBTS_FEATURE_MATCH_MASK_BLWF_PRE KBTS_FEATURE_MATCH_MASK(0, 0, KBTS_FEATURE_MATCH_FLAG_RA_HA_VA | KBTS_FEATURE_MATCH_FLAG_INITIAL, KBTS_FEATURE_MATCH_FLAG_HALANT) # define KBTS_FEATURE_MATCH_MASK_BLWF_PRE_OK KBTS_FEATURE_MATCH_MASK(0, 0, KBTS_FEATURE_MATCH_FLAG_RA_HA_VA, KBTS_FEATURE_MATCH_FLAG_HALANT) # define KBTS_FEATURE_MATCH_MASK_BLWF_POST KBTS_FEATURE_MATCH_MASK(0, 0, KBTS_FEATURE_MATCH_FLAG_HALANT, KBTS_FEATURE_MATCH_FLAG_RA_HA_VA) # define KBTS_FEATURE_MATCH_MASK_CJCT KBTS_FEATURE_MATCH_MASK(0, KBTS_FEATURE_MATCH_FLAG_CONSONANT, KBTS_FEATURE_MATCH_FLAG_HALANT, KBTS_FEATURE_MATCH_FLAG_CONSONANT) # define KBTS_FEATURE_MATCH_MASK_HALF KBTS_FEATURE_MATCH_MASK(KBTS_FEATURE_MATCH_FLAG_CONSONANT | KBTS_FEATURE_MATCH_FLAG_RPHF | KBTS_FEATURE_MATCH_FLAG_POST_BASE, KBTS_FEATURE_MATCH_FLAG_HALANT, KBTS_FEATURE_MATCH_FLAG_ZWNJ, KBTS_FEATURE_MATCH_FLAG_CONSONANT) # define KBTS_FEATURE_MATCH_MASK_HALF_OK KBTS_FEATURE_MATCH_MASK(KBTS_FEATURE_MATCH_FLAG_CONSONANT, KBTS_FEATURE_MATCH_FLAG_HALANT, 0, 0) # define KBTS_FEATURE_MATCH_MASK_NUKT KBTS_FEATURE_MATCH_MASK(0, 0, KBTS_FEATURE_MATCH_FLAG_CONSONANT, KBTS_FEATURE_MATCH_FLAG_HALANT) # define KBTS_FEATURE_MATCH_MASK_PSTF KBTS_FEATURE_MATCH_MASK(0, 0, KBTS_FEATURE_MATCH_FLAG_HALANT | KBTS_FEATURE_MATCH_FLAG_INITIAL, KBTS_FEATURE_MATCH_FLAG_YA) # define KBTS_FEATURE_MATCH_MASK_VATU KBTS_FEATURE_MATCH_MASK(0, KBTS_FEATURE_MATCH_FLAG_CONSONANT, KBTS_FEATURE_MATCH_FLAG_HALANT, KBTS_FEATURE_MATCH_FLAG_RA_HA_VA) typedef kbts_u32 kbts_substitution_result_flags; enum kbts_substitution_result_flags_enum { KBTS_SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION = (1 << 0), KBTS_SUBSTITUTION_RESULT_FLAG_GROW_BUFFER = (1 << 1), }; static kbts_substitution_result_flags kbts_DoSubstitution(kbts_shape_state *ShapeState, kbts_lookup_list *LookupList, kbts_gsub_frame *Frames, kbts_u32 *FrameCount_, kbts_glyph_array *GlyphArray, kbts_u32 CheckOnly, kbts_skip_flags RequestedSkipFlags, kbts_u32 GeneratedGlyphFlags) { kbts_substitution_result_flags Result = 0; kbts_font *Font = ShapeState->Config->Font; kbts_glyph *Glyphs = GlyphArray->Glyphs; kbts_unicode_flags SkipUnicodeFlags = 0; // @Incomplete kbts_skip_flags RegularSkipFlags = KBTS_SKIP_FLAGS_GSUB_REGULAR(RequestedSkipFlags); kbts_skip_flags SequenceSkipFlags = KBTS_SKIP_FLAGS_GSUB_SEQUENCE(RequestedSkipFlags); GeneratedGlyphFlags |= KBTS_GLYPH_FLAG_GENERATED_BY_GSUB; kbts_un FrameCount = *FrameCount_; kbts_gsub_frame *Frame = &Frames[FrameCount - 1]; kbts_lookup *PackedLookup = kbts_GetLookup(LookupList, Frame->LookupIndex); kbts_unpacked_lookup Lookup = kbts_UnpackLookup(Font->Gdef, PackedLookup); kbts_u16 BaseLookupType = Lookup.Type; while(Frame->SubtableIndex < Lookup.SubtableCount) { kbts_u16 *Subtable = KBTS_POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[Frame->SubtableIndex]); // In a type-7 lookup, each subtable can specify a different lookup type. // We still want to pass kbts_unpacked_lookup around as a useful bag of arguments, though. // So, we restore the original lookup's type here before resolving each subtable. Lookup.Type = BaseLookupType; while(Lookup.Type == 7) { kbts_extension *Extension = (kbts_extension *)Subtable; Lookup.Type = Extension->LookupType; Subtable = KBTS_POINTER_OFFSET(kbts_u16, Extension, Extension->Offset); } // :ReverseChaining // From the Microsoft docs: // In processing a reverse chaining substitution, i begins at the logical end of the string and moves to the beginning. // This comment only makes sense when the reverse chaining substitution happens at the top level. // When it _is_ at the top level, we know we are just doing a linear scan through the string, and since this is a single // substitution (i.e. one glyph -> one glyph), we know the size of the buffer won't change throughout the scan. // Given all of this, handling the reverse-scanning nature of this lookup actually becomes very easy: if((Lookup.Type == 8) && (FrameCount == 1)) { Frame->InputGlyphIndex = (kbts_u16)(GlyphArray->Count - 1 - Frame->InputGlyphIndex); } kbts_glyph *CurrentGlyph = &Glyphs[Frame->InputGlyphIndex]; kbts_glyph_array InputGlyphs = kbts_GlyphSubArray(GlyphArray, Frame->InputGlyphIndex); kbts_skip_flags SkipFlags = (Lookup.Type >= 5) ? SequenceSkipFlags : RegularSkipFlags; if(kbts_GlyphsIncludedInLookupSubtable(Font, 0, &Lookup, Frame->LookupIndex, Frame->SubtableIndex, GlyphArray, Frame->InputGlyphIndex, SkipFlags, SkipUnicodeFlags)) { kbts_cover_glyph_result Cover = KBTS_ZERO; Cover.Valid = kbts_GlyphPassesLookupFilter(CurrentGlyph, &Lookup); if(Cover.Valid && kbts_GsubLookupBeginsWithCoverage(Lookup.Type, Subtable[0])) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Subtable, Subtable[1]); Cover = kbts_CoverGlyph(Coverage, CurrentGlyph->Id); } if(Cover.Valid) { kbts_un DeltaGlyphCount = 0; if((Lookup.Type == 5) || (Lookup.Type == 6)) { kbts_sequence_lookup_result SequenceLookup = kbts_DoSequenceLookup(&Lookup, Subtable, Cover, GlyphArray, Frame->InputGlyphIndex, SequenceSkipFlags, SkipUnicodeFlags); if(SequenceLookup.Matched) { KBTS_FOR(FrameIndex, 0, FrameCount - 1) { kbts_gsub_frame *ParentFrame = &Frames[FrameIndex]; if((ParentFrame->InputGlyphIndex < (Frame->InputGlyphIndex + SequenceLookup.InputSequenceCountIncludingSkippedGlyphs)) && ((ParentFrame->InputGlyphIndex + ParentFrame->InputGlyphCount) > Frame->InputGlyphIndex)) { ParentFrame->InputGlyphCount += (kbts_u16)(SequenceLookup.InputSequenceCountIncludingSkippedGlyphs - Frame->InputGlyphCount); } } Frame->InputGlyphCount = (kbts_u16)SequenceLookup.InputSequenceCountIncludingSkippedGlyphs; Frame->Records = SequenceLookup.Records; Frame->RecordCount = (kbts_u16)SequenceLookup.RecordCount; Frame->RecordIndex = 0; Frame->SubtableIndex = 0xFFFE; } } else { // Do single substitution. switch(Lookup.Type) { case 1: { Result |= KBTS_SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION; if(!CheckOnly) { kbts_single_substitution *Subst = (kbts_single_substitution *)Subtable; kbts_u16 NewId = 0; if(Subst->Format == 1) { // From the Microsoft docs: // "Addition of deltaGlyphID is modulo 65536." NewId = (CurrentGlyph->Id + (kbts_u32)Subst->DeltaOrCount.DeltaGlyphId) & 0xFFFF; } else if(Subst->Format == 2) { kbts_u16 *SubstituteGlyphIds = KBTS_POINTER_AFTER(kbts_u16, Subst); NewId = SubstituteGlyphIds[Cover.Index]; } kbts_GsubMutate(Font, CurrentGlyph, NewId, GeneratedGlyphFlags); } } break; case 2: { Result |= KBTS_SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION; if(!CheckOnly) { kbts_multiple_substitution *Subst = (kbts_multiple_substitution *)Subtable; kbts_sequence *Sequence = kbts_GetSequence(Subst, Cover.Index); kbts_u16 *SubstGlyphIds = KBTS_POINTER_AFTER(kbts_u16, Sequence); kbts_un GrowCount = Sequence->GlyphCount - 1; if(!kbts_GrowGlyphArray(0, &InputGlyphs, 0, GrowCount, 0, 0)) { Result |= KBTS_SUBSTITUTION_RESULT_FLAG_GROW_BUFFER; kbts_TransferGrowRequest(&InputGlyphs, GlyphArray); goto Cleanup; } DeltaGlyphCount += GrowCount; kbts_glyph OriginalGlyph = *CurrentGlyph; KBTS_FOR(SubstGlyphIndex, 0, Sequence->GlyphCount) { kbts_glyph NewGlyph = OriginalGlyph; kbts_GsubMutate(Font, &NewGlyph, SubstGlyphIds[SubstGlyphIndex], GeneratedGlyphFlags | KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION); if(SubstGlyphIndex) { NewGlyph.Uid = (kbts_u16)++ShapeState->NextGlyphUid; } else { NewGlyph.Flags |= KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION; } Glyphs[Frame->InputGlyphIndex + SubstGlyphIndex] = NewGlyph; } Frame->InputGlyphCount = Sequence->GlyphCount; // Shift other frames' input cursors. KBTS_FOR(FrameIndex, 0, FrameCount - 1) { kbts_gsub_frame *OtherFrame = &Frames[FrameIndex]; if(OtherFrame->InputGlyphIndex > Frame->InputGlyphIndex) { OtherFrame->InputGlyphIndex = (kbts_u16)(OtherFrame->InputGlyphIndex + GrowCount); } else if((OtherFrame->InputGlyphIndex + OtherFrame->InputGlyphCount) > Frame->InputGlyphIndex) { OtherFrame->InputGlyphCount = (kbts_u16)(OtherFrame->InputGlyphCount + GrowCount); } } } } break; case 3: { Result |= KBTS_SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION; if(!CheckOnly) { kbts_alternate_substitution *Subst = (kbts_alternate_substitution *)Subtable; kbts_alternate_set *Set = kbts_GetAlternateSet(Subst, Cover.Index); kbts_u16 *AltGlyphIds = KBTS_POINTER_AFTER(kbts_u16, Set); kbts_un AlternateIndex = 0; { kbts_feature_set *ShaperFeatures = ShapeState->Config->Features; kbts_glyph_config *GlyphConfig = CurrentGlyph->Config; if(GlyphConfig) { int HasOverride = 0; KBTS_FOR(WordIndex, 0, KBTS_ARRAY_LENGTH(GlyphConfig->EnabledFeatures.Flags)) { kbts_u64 Flags = GlyphConfig->EnabledFeatures.Flags[WordIndex] & ShaperFeatures->Flags[WordIndex]; if(Flags) { HasOverride = 1; break; } } if(HasOverride) { kbts_op_state_gsub *Gsub = &ShapeState->OpState.OpSpecific.Gsub; KBTS_FOR(OverrideIndex, 0, GlyphConfig->FeatureOverrideCount) { kbts_feature_override *Override = &GlyphConfig->FeatureOverrides[OverrideIndex]; kbts_u32 EnabledOrAlternatePlusOne = Override->EnabledOrAlternatePlusOne; if(EnabledOrAlternatePlusOne && kbts_ContainsFeature(&Gsub->LookupFeatures, Override->Id)) { int Match = 1; if(!Override->Id) { // Slow path for unregistered features. Match = 0; KBTS_FOR(UnregisteredFeatureIndex, 0, ShapeState->OpState.UnregisteredFeatureCount) { if(Override->Tag == ShapeState->OpState.UnregisteredFeatureTags[UnregisteredFeatureIndex]) { Match = 1; break; } } } if(Match) { AlternateIndex = EnabledOrAlternatePlusOne - 1; break; } } } } } } if(AlternateIndex >= Set->GlyphCount) { AlternateIndex = 0; } kbts_u16 NewId = AltGlyphIds[AlternateIndex]; kbts_GsubMutate(Font, CurrentGlyph, NewId, GeneratedGlyphFlags); } } break; case 4: { kbts_ligature_substitution *Subst = (kbts_ligature_substitution *)Subtable; kbts_ligature_set *Set = kbts_GetLigatureSet(Subst, Cover.Index); KBTS_FOR(LigatureIndex, 0, Set->Count) { kbts_ligature *Ligature = kbts_GetLigature(Set, LigatureIndex); kbts_u16 *ComponentIds = KBTS_POINTER_AFTER(kbts_u16, Ligature); if(Ligature->ComponentCount <= InputGlyphs.Count) { kbts_un MatchingGlyphCount = 1; { kbts_un InputIndex = 1; while((InputIndex < InputGlyphs.Count) && (MatchingGlyphCount < Ligature->ComponentCount)) { kbts_glyph *Glyph = &InputGlyphs.Glyphs[InputIndex]; // A ligature may contain an explicit ZWJ, which SkipGlyph() would probably skip. // The expected behavior in that case is to assume the font designer knows what they are doing // and match the ZWJ. if(Glyph->Id == ComponentIds[MatchingGlyphCount - 1]) { MatchingGlyphCount += 1; } else if(!kbts_SkipGlyph(Glyph, &Lookup, RegularSkipFlags, SkipUnicodeFlags)) { break; } InputIndex += 1; } } if(MatchingGlyphCount == Ligature->ComponentCount) { Result |= KBTS_SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION; if(!CheckOnly) { kbts_u32 LigatureUid = ++ShapeState->NextGlyphUid; { // For glyphs that aren't part of the ligature, store which component it is attached to. // For glyphs that _are_, eat them. kbts_un LigatureGlyphCount = 1; kbts_un ReadCursor = 1; kbts_un WriteCursor = 1; while((LigatureGlyphCount < InputGlyphs.Count) && (LigatureGlyphCount < Ligature->ComponentCount) && (ReadCursor < InputGlyphs.Count)) { kbts_glyph *Glyph = &InputGlyphs.Glyphs[ReadCursor]; if(Glyph->Id == ComponentIds[LigatureGlyphCount - 1]) { LigatureGlyphCount += 1; ReadCursor += 1; } else if(kbts_SkipGlyph(Glyph, &Lookup, RegularSkipFlags, SkipUnicodeFlags)) { Glyph->LigatureComponentIndexPlusOne = (kbts_u16)LigatureGlyphCount; Glyph->LigatureUid = (kbts_u16)LigatureUid; InputGlyphs.Glyphs[WriteCursor++] = InputGlyphs.Glyphs[ReadCursor++]; } else { break; } } // Finish moving all non-ligature glyphs in their place. // We are effectively shrinking the whole buffer here, so we have to touch // glyphs outside of our own cluster. kbts_un GrowCount = WriteCursor - ReadCursor; // Negative kbts_GrowGlyphArray(0, &InputGlyphs, WriteCursor, GrowCount, 0, 0); DeltaGlyphCount += GrowCount; // Update frame input cursors. KBTS_FOR(FrameIndex, 0, FrameCount - 1) { kbts_gsub_frame *OtherFrame = &Frames[FrameIndex]; if(OtherFrame->InputGlyphIndex >= Frame->InputGlyphIndex) { kbts_un OtherInputIndex = OtherFrame->InputGlyphIndex + GrowCount; OtherInputIndex = KBTS_MAX(OtherInputIndex, Frame->InputGlyphIndex); OtherFrame->InputGlyphIndex = (kbts_u16)OtherInputIndex; } else { kbts_un End = OtherFrame->InputGlyphIndex + OtherFrame->InputGlyphCount; End = KBTS_MIN(End, GlyphArray->TotalCount); OtherFrame->InputGlyphCount = (kbts_u16)(End - OtherFrame->InputGlyphIndex); } } } // Currently, we only take the main glyph's config into account while making the ligature's config. // Maybe we should merge all of the components' configs into one instead? kbts_GsubMutate(Font, CurrentGlyph, Ligature->Glyph, GeneratedGlyphFlags | KBTS_GLYPH_FLAG_LIGATURE); CurrentGlyph->Uid = (kbts_u16)LigatureUid; // Harfbuzz does this, because Uniscribe does this, and so we do the same. Sigh. CurrentGlyph->Flags &= ~KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION; } break; } } } } break; case 8: { kbts_reverse_chain_substitution *Subst = (kbts_reverse_chain_substitution *)Subtable; kbts_unpacked_reverse_chain_substitution Unpacked = kbts_UnpackReverseChainSubstitution(Subst, 0); // :BoundsChecking if(Cover.Index < Unpacked.GlyphCount) { // Should we use regular or sequence skip flags here? kbts_glyph_array BacktrackGlyphs = kbts_ClipGlyphArray(GlyphArray, Frame->InputGlyphIndex); kbts_sequence_match BacktrackMatch = kbts_MatchCoverageSequence(&Lookup, RegularSkipFlags, SkipUnicodeFlags, Subst, Unpacked.BacktrackCoverageOffsets, Unpacked.BacktrackCount, &BacktrackGlyphs, (kbts_un)Frame->InputGlyphIndex - 1, -1); kbts_glyph_array FollowupGlyphs = kbts_GlyphSubArray(&InputGlyphs, 1); kbts_sequence_match LookaheadMatch = kbts_MatchCoverageSequence(&Lookup, RegularSkipFlags, SkipUnicodeFlags, Subst, Unpacked.LookaheadCoverageOffsets, Unpacked.LookaheadCount, &FollowupGlyphs, 0, 1); if((BacktrackMatch.MatchCount == Unpacked.BacktrackCount) && (LookaheadMatch.MatchCount == Unpacked.LookaheadCount)) { Result |= KBTS_SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION; kbts_GsubMutate(Font, CurrentGlyph, Unpacked.SubstituteGlyphIds[Cover.Index], GeneratedGlyphFlags); } } } break; } if(Result & KBTS_SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION) { Frame->SubtableIndex = 0xFFFE; // From the Microsoft docs: // To move to the “next” glyph, the client skips all the glyphs that participated in the lookup operation: // glyphs that were substituted/positioned as well as any other glyphs in the matched input sequence. GlyphArray->Count += DeltaGlyphCount; GlyphArray->TotalCount += DeltaGlyphCount; } } } } Frame->SubtableIndex += 1; } if(Frame->RecordIndex < Frame->RecordCount) { kbts_sequence_lookup_record *SequenceRecord = &Frame->Records[Frame->RecordIndex++]; kbts_gsub_frame NewFrame = KBTS_ZERO; NewFrame.LookupIndex = SequenceRecord->LookupListIndex; NewFrame.SubtableIndex = 0; NewFrame.InputGlyphIndex = Frame->InputGlyphIndex; if(SequenceRecord->SequenceIndex) { // @Speed: Re-scan the sequence to find where we are in the _filtered_ sequence. kbts_un SequenceInputIndex = 0; KBTS_FOR(FilterAt, Frame->InputGlyphIndex + 1, GlyphArray->Count) { kbts_glyph *FilterGlyph = &Glyphs[FilterAt]; // @Incomplete: SequenceSkipFlags? 0? // What do we use here? if(!kbts_SkipGlyph(FilterGlyph, &Lookup, 0, SkipUnicodeFlags)) { SequenceInputIndex += 1; if(SequenceInputIndex == SequenceRecord->SequenceIndex) { NewFrame.InputGlyphIndex = (kbts_u16)FilterAt; break; } } } } NewFrame.InputGlyphCount = 1; Frames[FrameCount++] = NewFrame; } // Only actually pop the frame if we haven't pushed anything else in the meantime. if(Frame == &Frames[FrameCount - 1]) { FrameCount -= 1; } Cleanup:; *FrameCount_ = (kbts_u32)FrameCount; return Result; } static kbts_u32 kbts_WouldSubstitute(kbts_shape_state *ShapeState, kbts_lookup_list *LookupList, kbts_gsub_frame *Frames, kbts_feature *Feature, kbts_skip_flags SkipFlags, kbts_glyph *Glyphs, kbts_un GlyphCount) { kbts_u32 Result = 0; kbts_glyph_array GlyphArray = kbts_GlyphArray(Glyphs, GlyphCount, GlyphCount, GlyphCount); kbts_iterate_lookups IterateLookups = kbts_IterateLookups(LookupList, Feature); while(kbts_NextLookup(&IterateLookups)) { kbts_un GlyphIndex = 0; while(GlyphIndex < GlyphCount) { kbts_gsub_frame *Frame = &Frames[0]; Frame->LookupIndex = IterateLookups.LookupIndex; Frame->SubtableIndex = 0; Frame->InputGlyphIndex = 0; Frame->InputGlyphCount = 1; kbts_u32 FrameCount = 1; while(FrameCount) { kbts_substitution_result_flags SubstitutionResult = kbts_DoSubstitution(ShapeState, LookupList, Frames, &FrameCount, &GlyphArray, 1, SkipFlags, 0); if(SubstitutionResult & KBTS_SUBSTITUTION_RESULT_FLAG_MATCHED_SUBSTITUTION) { Result = 1; goto Done; } } GlyphIndex += Frames[0].InputGlyphCount; } } Done:; return Result; } static int kbts_NextLookupIndex(kbts_op_state *S, kbts_un *LookupIndex, kbts_u32 *SkipFlags_, kbts_u32 *GlyphFilter_, kbts_feature_set *FeatureSet_) { kbts_un LowestIndex = 0xFFFFFFFF; KBTS_FOR(FeatureIndex, 0, S->FeatureCount) { kbts_lookup_indices *Indices = &S->FeatureLookupIndices[FeatureIndex]; kbts_un Index = Indices->Indices[0]; if(Index < LowestIndex) { LowestIndex = Index; } } kbts_feature_set FeatureSet = KBTS_ZERO; kbts_skip_flags SkipFlags = 0; kbts_u32 GlyphFilter = 0; kbts_un UnregisteredFeatureCount = 0; KBTS_FOR(FeatureIndex, 0, S->FeatureCount) { kbts_lookup_indices *Indices = &S->FeatureLookupIndices[FeatureIndex]; kbts_un Index = Indices->Indices[0]; if(Index == LowestIndex) { SkipFlags |= Indices->SkipFlags; GlyphFilter |= Indices->GlyphFilter; kbts_AddFeature(&FeatureSet, Indices->FeatureId); if(!Indices->FeatureId && (UnregisteredFeatureCount < KBTS_MAX_SIMULTANEOUS_FEATURES)) { S->UnregisteredFeatureTags[UnregisteredFeatureCount++] = Indices->FeatureTag; } ++Indices->Indices; --Indices->Count; if(!Indices->Count) { S->FeatureLookupIndices[FeatureIndex--] = S->FeatureLookupIndices[--S->FeatureCount]; } } } S->UnregisteredFeatureCount = (kbts_u32)UnregisteredFeatureCount; *LookupIndex = LowestIndex; *SkipFlags_ = SkipFlags; *GlyphFilter_ = GlyphFilter; *FeatureSet_ = FeatureSet; return LowestIndex != 0xFFFFFFFF; } static int kbts_ConfigAllowsFeatures(kbts_op_state *S, kbts_shape_config *Config, kbts_glyph_config *GlyphConfig, kbts_feature_set *Features) { kbts_glyph_config DummyGlyphConfig = KBTS_ZERO; kbts_u64 UserEnabled = 0; // Whether the user enabled _any_ feature corresponding to this lookup. kbts_u64 UserDisabled = 1; // Whether the user disabled _all_ features corresponding to this lookup. kbts_u64 DefaultEnabled = 0; // Whether any feature is non-user. if(!GlyphConfig) { GlyphConfig = &DummyGlyphConfig; } kbts_u64 Mask = 1; // Ignore unregistered features in the broad pass. KBTS_FOR(WordIndex, 0, KBTS_ARRAY_LENGTH(GlyphConfig->EnabledFeatures.Flags)) { kbts_u64 LookupFeatureFlags = Features->Flags[WordIndex] & ~Mask; Mask = 0; UserEnabled |= GlyphConfig->EnabledFeatures.Flags[WordIndex] & LookupFeatureFlags; UserDisabled &= (GlyphConfig->DisabledFeatures.Flags[WordIndex] & LookupFeatureFlags) == LookupFeatureFlags; DefaultEnabled |= Features->Flags[WordIndex] & Config->Features->Flags[WordIndex]; } if(Features->Flags[0] & (GlyphConfig->EnabledFeatures.Flags[0] | GlyphConfig->DisabledFeatures.Flags[0]) & KBTS_FEATURE_FLAG0(UNREGISTERED)) { // Slow path for unregistered features. KBTS_FOR(FeatureOverrideIndex, 0, GlyphConfig->FeatureOverrideCount) { kbts_feature_override *Override = &GlyphConfig->FeatureOverrides[FeatureOverrideIndex]; if(Override->Id == KBTS_FEATURE_ID_UNREGISTERED) { kbts_feature_tag OverrideTag = Override->Tag; KBTS_FOR(UnregisteredFeatureIndex, 0, S->UnregisteredFeatureCount) { if(OverrideTag == S->UnregisteredFeatureTags[UnregisteredFeatureIndex]) { UserEnabled |= Override->EnabledOrAlternatePlusOne; UserDisabled &= !Override->EnabledOrAlternatePlusOne; break; } } } } } int Result = (!UserDisabled && (DefaultEnabled || UserEnabled)); return Result; } static kbts_u32 kbts_ExecuteOp(kbts_shape_state *ShapeState, kbts_glyph_array *GlyphArray) { KBTS_INSTRUMENT_FUNCTION_BEGIN kbts_shape_config *Config = ShapeState->Config; kbts_font *Font = Config->Font; kbts_op *Op = &ShapeState->Op; kbts_op_state *S = &ShapeState->OpState; kbts_glyph *Glyphs = GlyphArray->Glyphs; kbts_u32 ResumePoint = S->ResumePoint; S->ResumePoint = 0; switch(ResumePoint) { case 1: goto ResumePoint1; break; case 2: goto ResumePoint2; break; case 3: goto ResumePoint3; break; case 4: goto ResumePoint4; break; case 5: goto ResumePoint5; break; } S->WrittenCount = 0; switch(Op->Kind) { case KBTS_OP_KIND_PRE_NORMALIZE_DOTTED_CIRCLES: { KBTS_INSTRUMENT_BLOCK_BEGIN("PRE_NORMALIZE_DOTTED_CIRCLES") // Before even trying to normalize anything, there are some _exceptions_ we have to take care of. // The USE spec gives us a list of codepoint sequences which necessitate insertion of a dotted circle. // These sequences are from IndicShapingInvalidClusters.txt. S->GlyphIndex = 0; kbts_u64 Codepoints; Codepoints = 0; // 0xABBBBBCCCCCDDDDD for(; S->GlyphIndex < GlyphArray->Count; ++S->GlyphIndex) { kbts_u32 NewCodepoint; NewCodepoint = Glyphs[S->GlyphIndex].Codepoint & 0x1FFFFF; Codepoints = (Codepoints << 21) | NewCodepoint; // This switch is faster than any table lookup I could come up with in my tests. #define KBTS_C2(A, B) case (((kbts_u64)(A) << 21) | (kbts_u64)(B)): switch(Codepoints & (((kbts_u64)1 << 42) - 1)) { default: if((Codepoints & (((kbts_u64)1 << 63) - 1)) == (((kbts_u64)0x930 << 42) | ((kbts_u64)0x94D << 21) | ((kbts_u64)0x907))) { if(0) { ResumePoint4:; Codepoints = 0; } KBTS_C2(0x905, 0x93A) KBTS_C2(0x905, 0x93B) KBTS_C2(0x905, 0x93E) KBTS_C2(0x905, 0x945) KBTS_C2(0x905, 0x946) KBTS_C2(0x905, 0x949) KBTS_C2(0x905, 0x94A) KBTS_C2(0x905, 0x94B) KBTS_C2(0x905, 0x94C) KBTS_C2(0x905, 0x94F) KBTS_C2(0x905, 0x956) KBTS_C2(0x905, 0x957) KBTS_C2(0x906, 0x93A) KBTS_C2(0x906, 0x945) KBTS_C2(0x906, 0x946) KBTS_C2(0x906, 0x947) KBTS_C2(0x906, 0x948) KBTS_C2(0x909, 0x941) KBTS_C2(0x90F, 0x945) KBTS_C2(0x90F, 0x946) KBTS_C2(0x90F, 0x947) KBTS_C2(0x985, 0x9BE) KBTS_C2(0x98B, 0x9C3) KBTS_C2(0x98C, 0x9E2) KBTS_C2(0xA05, 0xA3E) KBTS_C2(0xA05, 0xA48) KBTS_C2(0xA05, 0xA4C) KBTS_C2(0xA72, 0xA3F) KBTS_C2(0xA72, 0xA40) KBTS_C2(0xA72, 0xA47) KBTS_C2(0xA73, 0xA41) KBTS_C2(0xA73, 0xA42) KBTS_C2(0xA73, 0xA4B) KBTS_C2(0xA85, 0xABE) KBTS_C2(0xA85, 0xAC5) KBTS_C2(0xA85, 0xAC7) KBTS_C2(0xA85, 0xAC8) KBTS_C2(0xA85, 0xAC9) KBTS_C2(0xA85, 0xACB) KBTS_C2(0xA85, 0xACC) KBTS_C2(0xAC5, 0xABE) KBTS_C2(0xB05, 0xB3E) KBTS_C2(0xB0F, 0xB57) KBTS_C2(0xB13, 0xB57) KBTS_C2(0xB85, 0xBC2) KBTS_C2(0xC12, 0xC4C) KBTS_C2(0xC12, 0xC55) KBTS_C2(0xC3F, 0xC55) KBTS_C2(0xC46, 0xC55) KBTS_C2(0xC4A, 0xC55) KBTS_C2(0xC89, 0xCBE) KBTS_C2(0xC8B, 0xCBE) KBTS_C2(0xC92, 0xCCC) KBTS_C2(0xD07, 0xD57) KBTS_C2(0xD09, 0xD57) KBTS_C2(0xD0E, 0xD46) KBTS_C2(0xD12, 0xD3E) KBTS_C2(0xD12, 0xD57) KBTS_C2(0xD85, 0xDCF) KBTS_C2(0xD85, 0xDD0) KBTS_C2(0xD85, 0xDD1) KBTS_C2(0xD8B, 0xDDF) KBTS_C2(0xD8D, 0xDD8) KBTS_C2(0xD8F, 0xDDF) KBTS_C2(0xD91, 0xDCA) KBTS_C2(0xD91, 0xDD9) KBTS_C2(0xD91, 0xDDA) KBTS_C2(0xD91, 0xDDC) KBTS_C2(0xD91, 0xDDD) KBTS_C2(0xD91, 0xDDE) KBTS_C2(0xD94, 0xDDF) KBTS_C2(0x11005, 0x11038) KBTS_C2(0x1100B, 0x1103E) KBTS_C2(0x1100F, 0x11042) KBTS_C2(0x11200, 0x1122C) KBTS_C2(0x11200, 0x11231) KBTS_C2(0x11200, 0x11233) KBTS_C2(0x11206, 0x1122C) KBTS_C2(0x1122C, 0x11230) KBTS_C2(0x1122C, 0x11231) KBTS_C2(0x11240, 0x1122E) KBTS_C2(0x112B0, 0x112E0) KBTS_C2(0x112B0, 0x112E5) KBTS_C2(0x112B0, 0x112E6) KBTS_C2(0x112B0, 0x112E7) KBTS_C2(0x112B0, 0x112E8) KBTS_C2(0x11481, 0x114B0) KBTS_C2(0x1148B, 0x114BA) KBTS_C2(0x1148D, 0x114BA) KBTS_C2(0x114AA, 0x114B5) KBTS_C2(0x114AA, 0x114B6) KBTS_C2(0x11600, 0x11639) KBTS_C2(0x11600, 0x1163A) KBTS_C2(0x11601, 0x11639) KBTS_C2(0x11601, 0x1163A) KBTS_C2(0x11680, 0x116AD) KBTS_C2(0x11680, 0x116B4) KBTS_C2(0x11680, 0x116B5) KBTS_C2(0x11686, 0x116B2) if(!kbts_GrowGlyphArray(&S->ResumePoint, GlyphArray, S->GlyphIndex, 1, 4, 0)) { KBTS_INSTRUMENT_END return 1; } GlyphArray->Glyphs[S->GlyphIndex] = Config->DottedCircle; } } #undef KBTS_C2 } S->WrittenCount = GlyphArray->TotalCount; KBTS_INSTRUMENT_END } break; case KBTS_OP_KIND_NORMALIZE: { KBTS_INSTRUMENT_BLOCK_BEGIN("NORMALIZE") // @Incomplete: We need to honor this. // HB_OT_SHAPE_NORMALIZATION_MODE_NONE, // HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, // HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* Always fully decomposes and then recompose back */ // // hangul: HB_OT_SHAPE_NORMALIZATION_MODE_NONE, // arabic: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, // default: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, // hebrew: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, // thai: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, // indic: HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, // khmer: HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, // myanmar: HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, // use: HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, { // Full NFD decomposition kbts_glyph *DecompositionGlyphs; DecompositionGlyphs = KBTS_POINTER_AFTER(kbts_glyph, S); for(S->GlyphIndex = 0; S->GlyphIndex < GlyphArray->Count; ++S->GlyphIndex) { DecompositionGlyphs[0] = Glyphs[S->GlyphIndex]; S->OpSpecific.Normalize.CodepointsToDecomposeCount = 1; while(S->OpSpecific.Normalize.CodepointsToDecomposeCount) { if(0) { ResumePoint1:; DecompositionGlyphs = KBTS_POINTER_AFTER(kbts_glyph, S); } kbts_glyph GlyphToDecompose = DecompositionGlyphs[--S->OpSpecific.Normalize.CodepointsToDecomposeCount]; kbts_u64 Decomposition = 0; kbts_u32 DecompositionSize = 0; kbts_u32 AnyUnsupported = 0; kbts_glyph Decomposed[2]; if(!(GlyphToDecompose.Flags & KBTS_GLYPH_FLAG_DO_NOT_DECOMPOSE)) { Decomposition = GlyphToDecompose.Decomposition; DecompositionSize = kbts_GetDecompositionSize(Decomposition); // Only decompose when the font supports the decomposed form. KBTS_FOR(DecompositionIndex, 0, DecompositionSize) { kbts_glyph DecompositionGlyph = kbts_CodepointToGlyph(Font, kbts_GetDecompositionCodepoint(Decomposition, DecompositionIndex)); DecompositionGlyph.Config = GlyphToDecompose.Config; AnyUnsupported |= !DecompositionGlyph.Id; Decomposed[DecompositionIndex] = DecompositionGlyph; } } if(AnyUnsupported | !DecompositionSize) { if(S->WrittenCount > S->GlyphIndex) { if(!kbts_GrowGlyphArray(&S->ResumePoint, GlyphArray, S->WrittenCount, 1, 1, 0)) { S->OpSpecific.Normalize.CodepointsToDecomposeCount += 1; // Push the codepoint back on the stack. KBTS_INSTRUMENT_END return 1; } S->GlyphIndex += 1; } Glyphs[S->WrittenCount++] = GlyphToDecompose; } else { KBTS_ASSERT((S->OpSpecific.Normalize.CodepointsToDecomposeCount + DecompositionSize) <= KBTS_MAXIMUM_DECOMPOSITION_CODEPOINTS); if(Decomposition & KBTS_UNICODE_DECOMPOSITION_DO_NOT_RECURSE0) { Decomposed[0].Flags |= KBTS_GLYPH_FLAG_DO_NOT_DECOMPOSE; } if(Decomposition & KBTS_UNICODE_DECOMPOSITION_DO_NOT_RECURSE1) { Decomposed[1].Flags |= KBTS_GLYPH_FLAG_DO_NOT_DECOMPOSE; } KBTS_FOR(DecompositionIndex, 0, DecompositionSize) { // We reverse the glyphs here because we use a stack. DecompositionGlyphs[S->OpSpecific.Normalize.CodepointsToDecomposeCount++] = Decomposed[DecompositionSize - 1 - DecompositionIndex]; } } } } } { // Selective recomposition. // The OpenType shaping documents say that Hebrew Alphabetic Presentation Form compositions aren't canonical, // but looking at UnicodeData.txt, it seems like they totally are, so they are handled here. kbts_glyph *LastBase = 0; kbts_un LastBaseParentCount = 0; kbts_s32 *LastBaseParentDeltas = 0; kbts_un PreSlashDecimalDigitCount = 0; kbts_un DecimalDigitCount = 0; int InFraction = 0; kbts_u32 BeforeFractionSlashGlyphFlags = KBTS_GLYPH_FLAG_NUMR | KBTS_GLYPH_FLAG_FRAC; kbts_u32 AfterFractionSlashGlyphFlags = KBTS_GLYPH_FLAG_DNOM | KBTS_GLYPH_FLAG_FRAC; if(kbts_ShaperRtl(Config->Shaper)) { // RTL needs to invert NUMR and DNOM. kbts_u32 Swap = BeforeFractionSlashGlyphFlags; BeforeFractionSlashGlyphFlags = AfterFractionSlashGlyphFlags; AfterFractionSlashGlyphFlags = Swap; } // We also collate user features here. kbts_feature_set UserFeatures = KBTS_ZERO; kbts_feature_set *DefaultFeatures = Config->Features; KBTS_FOR(GlyphIndex, 0, S->WrittenCount) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; Glyph->Uid = (kbts_u16)++ShapeState->NextGlyphUid; if(Glyph->Config) { kbts_glyph_config *GlyphConfig = Glyph->Config; KBTS_FOR(WordIndex, 0, KBTS_ARRAY_LENGTH(UserFeatures.Flags)) { UserFeatures.Flags[WordIndex] |= GlyphConfig->EnabledFeatures.Flags[WordIndex] & ~DefaultFeatures->Flags[WordIndex]; } } kbts_un AvailableGlyphCount = 0; if(!Glyph->CombiningClass) { LastBase = Glyph; // From the Microsoft docs: // USE decomposes split vowel characters belonging to UISC = Vowel_Dependent according to character // decomposition mappings defined in UnicodeData.txt // Cluster validation, is done based on the decomposed state of a split vowel. // // (Note: our Matra corresponds to Vowel_Dependent + Pure_Killer.) if((Config->Shaper != KBTS_SHAPER_USE) || (Glyph->SyllabicClass != KBTS_INDIC_SYLLABIC_CLASS_MATRA)) { LastBaseParentDeltas = kbts_GetParentInfoDeltas(Glyph->ParentInfo); LastBaseParentCount = kbts_GetParentInfoCount(Glyph->ParentInfo); AvailableGlyphCount = 1; } else { LastBaseParentDeltas = 0; LastBaseParentCount = 0; } } else { if(LastBase) { AvailableGlyphCount = 2; } } KBTS_FOR(ParentIndex, 0, LastBaseParentCount) { kbts_u32 ParentCodepoint = LastBase->Codepoint + (kbts_u32)LastBaseParentDeltas[ParentIndex]; kbts_glyph ParentGlyph = kbts_CodepointToGlyph(Font, ParentCodepoint); kbts_u32 DecompositionSize = kbts_GetDecompositionSize(ParentGlyph.Decomposition); ParentGlyph.Uid = LastBase->Uid; ParentGlyph.Config = LastBase->Config; if((DecompositionSize == AvailableGlyphCount) && ParentGlyph.Id) { if(DecompositionSize == 2) { if(kbts_GetDecompositionCodepoint(ParentGlyph.Decomposition, 1) == Glyph->Codepoint) { // Both match. Reclaim space. // @Speed: We should use separate read and write cursors instead. KBTS_FOR(ShrinkIndex, GlyphIndex + 1, S->WrittenCount) { Glyphs[ShrinkIndex - 1] = Glyphs[ShrinkIndex]; } S->WrittenCount -= 1; } else { continue; } } *LastBase = ParentGlyph; GlyphIndex = (kbts_un)((LastBase - Glyphs) - 1); // Handle recursive recomposition. break; } } // It is safe to look for fractions here, because decimal digits/the fraction slash are not marks or // jamos, so they should not get reordered after this pass. if(Glyph->UnicodeFlags & KBTS_UNICODE_FLAG_DECIMAL_DIGIT) { if(InFraction) { // We are in the post-slash part of the fraction. Glyph->Flags |= AfterFractionSlashGlyphFlags; // Only flag the pre-slash part of the fraction if there is a post-slash part. KBTS_FOR(DecimalDigitIndex, 0, PreSlashDecimalDigitCount) { Glyphs[GlyphIndex - PreSlashDecimalDigitCount - 1 + DecimalDigitIndex].Flags |= BeforeFractionSlashGlyphFlags; } PreSlashDecimalDigitCount = 0; } DecimalDigitCount += 1; } else if((Glyph->Codepoint == 0x2044) && (!InFraction || DecimalDigitCount)) { // Fraction slash. Glyph->Flags |= KBTS_GLYPH_FLAG_FRAC; PreSlashDecimalDigitCount = DecimalDigitCount; InFraction = DecimalDigitCount != 0; DecimalDigitCount = 0; } else { InFraction = 0; } } // Ignore added features that are already part of the shaper. kbts_feature_set *ShaperFeatures = Config->Features; KBTS_FOR(WordIndex, 0, KBTS_ARRAY_LENGTH(UserFeatures.Flags)) { UserFeatures.Flags[WordIndex] &= ~ShaperFeatures->Flags[WordIndex]; } ShapeState->UserFeatures = UserFeatures; } { // Unicode mark reordering. S->GlyphIndex = 0; while(S->GlyphIndex < S->WrittenCount) { kbts_glyph *Glyph = &Glyphs[S->GlyphIndex]; kbts_u8 CombiningClass = Glyph->CombiningClass; kbts_un IndexIncrement = 1; if(CombiningClass) { Glyph->MarkOrdering = CombiningClass; kbts_un MarkSequenceLength = 1; while((S->GlyphIndex + MarkSequenceLength) < S->WrittenCount) { kbts_glyph *SequenceGlyph = &Glyphs[S->GlyphIndex + MarkSequenceLength]; kbts_u8 SequenceGlyphCombiningClass = SequenceGlyph->CombiningClass; if(SequenceGlyphCombiningClass) { SequenceGlyph->MarkOrdering = SequenceGlyphCombiningClass; MarkSequenceLength += 1; } else { break; } } KBTS_FOR(Iter, 0, MarkSequenceLength) { KBTS_FOR(SequenceIndex, 1, MarkSequenceLength) { kbts_glyph *Glyph0 = &Glyphs[S->GlyphIndex + SequenceIndex - 1]; kbts_glyph *Glyph1 = &Glyphs[S->GlyphIndex + SequenceIndex]; if(Glyph0->MarkOrdering > Glyph1->MarkOrdering) { kbts_glyph Swap = *Glyph0; *Glyph0 = *Glyph1; *Glyph1 = Swap; } } } IndexIncrement = MarkSequenceLength; } S->GlyphIndex += IndexIncrement; } } if(Config->Script == KBTS_SCRIPT_ARABIC) { S->GlyphIndex = 0; while(S->GlyphIndex < S->WrittenCount) { // Find a mark sequence. kbts_glyph *Glyph = &Glyphs[S->GlyphIndex]; kbts_u8 CombiningClass = Glyph->CombiningClass; if(CombiningClass) { // Arabic: Reorder sequences of mark glyphs. // // From the Unicode standard: // - Move any shadda characters (ccc=33) to the beginning of S. // - If a sequence of ccc=230 characters begins with any MCM characters, move the sequence of such MCM // characters // to the beginning of S (before any characters with ccc=33). // - If a sequence of ccc=220 characters begins with any MCM characters, move the sequence of such MCM // characters // to the beginning of S (before any MCM with ccc=230 or ccc=33). // // Final ordering: 220 230 shadda other kbts_mcm_sequence_state Mcm220SequenceState = 0; kbts_mcm_sequence_state Mcm230SequenceState = 0; kbts_un SequenceStart = S->GlyphIndex; # define KBTS_REMAPPED_CCC_33 27 while(S->GlyphIndex < S->WrittenCount) { kbts_glyph *SequenceGlyph = &Glyphs[S->GlyphIndex]; kbts_u16 SequenceGlyphCombiningClass = SequenceGlyph->CombiningClass; kbts_u16 SequenceGlyphFlags = SequenceGlyph->UnicodeFlags; kbts_u8 MarkOrdering = 3; if(SequenceGlyphCombiningClass == KBTS_REMAPPED_CCC_33) { MarkOrdering = 2; } else if(SequenceGlyphCombiningClass == 220) { if(SequenceGlyphFlags & KBTS_UNICODE_FLAG_MODIFIER_COMBINING_MARK) { if(Mcm220SequenceState != KBTS_MCM_SEQUENCE_STATE_OUT) { Mcm220SequenceState = KBTS_MCM_SEQUENCE_STATE_IN; } } else { Mcm220SequenceState = KBTS_MCM_SEQUENCE_STATE_OUT; } if(Mcm220SequenceState == KBTS_MCM_SEQUENCE_STATE_IN) { MarkOrdering = 0; } Mcm230SequenceState = KBTS_MCM_SEQUENCE_STATE_NONE; } else if(SequenceGlyphCombiningClass == 230) { if(SequenceGlyphFlags & KBTS_UNICODE_FLAG_MODIFIER_COMBINING_MARK) { if(Mcm230SequenceState != KBTS_MCM_SEQUENCE_STATE_OUT) { Mcm230SequenceState = KBTS_MCM_SEQUENCE_STATE_IN; } } else { Mcm230SequenceState = KBTS_MCM_SEQUENCE_STATE_OUT; } if(Mcm230SequenceState == KBTS_MCM_SEQUENCE_STATE_IN) { MarkOrdering = 1; } } else if(SequenceGlyphCombiningClass) { Mcm220SequenceState = KBTS_MCM_SEQUENCE_STATE_NONE; Mcm230SequenceState = KBTS_MCM_SEQUENCE_STATE_NONE; } else { break; } SequenceGlyph->MarkOrdering = MarkOrdering; S->GlyphIndex += 1; } KBTS_FOR(Iter, SequenceStart, S->GlyphIndex) { KBTS_FOR(SortIndex, SequenceStart + 1, S->GlyphIndex) { kbts_glyph *Left = &Glyphs[SortIndex - 1]; kbts_glyph *Right = &Glyphs[SortIndex]; if(Left->MarkOrdering > Right->MarkOrdering) { kbts_glyph Swap = *Left; *Left = *Right; *Right = Swap; } } } } else { S->GlyphIndex += 1; } } } else if((Config->Script == KBTS_SCRIPT_THAI) || (Config->Script == KBTS_SCRIPT_LAO)) { // Decompose sara/sala ams. kbts_un AboveBaseGlyphCount; AboveBaseGlyphCount = 0; for(S->GlyphIndex = 0; S->GlyphIndex < S->WrittenCount; ++S->GlyphIndex) { if(0) { ResumePoint5:; AboveBaseGlyphCount = S->OpSpecific.Normalize.AboveBaseGlyphCount; } kbts_glyph *Glyph = &Glyphs[S->GlyphIndex]; kbts_u32 Codepoint = Glyph->Codepoint; switch(Codepoint) { // Sara am/sala am. // We match both because storing the sara am codepoint that corresponds to the current script // doesn't seem that worthwhile, given that this is already a pretty big switch case. // If we choose to use a unicode flag or indic syllabic category to notate above-base marks, // then this loops gets a lot tighter and it would probably become the right call to pre-determine // the sara am codepoint. case 0xE33: case 0xEB3: // Sara am { if(!kbts_GrowGlyphArray(&S->ResumePoint, GlyphArray, S->GlyphIndex, 1, 5, 0)) { S->OpSpecific.Normalize.AboveBaseGlyphCount = AboveBaseGlyphCount; KBTS_INSTRUMENT_END return 1; } AboveBaseGlyphCount = S->OpSpecific.Normalize.AboveBaseGlyphCount; for(kbts_un AboveBaseIndex = 0; AboveBaseIndex < AboveBaseGlyphCount; ++AboveBaseIndex) { Glyphs[S->GlyphIndex - AboveBaseIndex] = Glyphs[S->GlyphIndex - AboveBaseIndex - 1]; } Glyphs[S->GlyphIndex - AboveBaseGlyphCount] = Config->Nikhahit; Glyphs[S->GlyphIndex + 1] = Config->SaraAa; S->WrittenCount += 1; } break; case 0xE31: case 0xE34: case 0xE35: case 0xE36: case 0xE37: case 0xE3B: case 0xE47: case 0xE48: case 0xE49: case 0xE4A: case 0xE4B: case 0xE4C: case 0xE4D: case 0xE4E: case 0xEB1: case 0xEB4: case 0xEB5: case 0xEB6: case 0xEB7: case 0xEBB: case 0xEC7: case 0xEC8: case 0xEC9: case 0xECA: case 0xECB: case 0xECC: case 0xECD: case 0xECE: AboveBaseGlyphCount += 1; break; default: AboveBaseGlyphCount = 0; break; } } } KBTS_INSTRUMENT_END } break; case KBTS_OP_KIND_NORMALIZE_HANGUL: { KBTS_INSTRUMENT_BLOCK_BEGIN("NORMALIZE_HANGUL") kbts_op_state_normalize_hangul *NormalizeHangul; NormalizeHangul = &S->OpSpecific.NormalizeHangul; S->GlyphIndex = 0; while(S->GlyphIndex < GlyphArray->Count) { { kbts_glyph *Glyph = &Glyphs[S->GlyphIndex]; kbts_un L = 0; kbts_un V = 0; kbts_un T = 0; kbts_hangul_syllable_info LInfo = kbts_HangulSyllableInfo(Glyph->Codepoint); if(LInfo.Type >= KBTS_HANGUL_SYLLABLE_TYPE_LV) { kbts_un SIndex = (Glyph->Codepoint - 0xAC00); L = 0x1100 + SIndex / 588; V = 0x1161 + (SIndex % 588) / 28; kbts_un TIndex = SIndex % 28; if(TIndex) { T = 0x11A7 + TIndex; } } else if(LInfo.Type == KBTS_HANGUL_SYLLABLE_TYPE_L) { L = Glyph->Codepoint; } S->GlyphIndex += 1; if(L) { kbts_hangul_syllable_info VInfo = KBTS_ZERO; if(!V && (S->GlyphIndex < GlyphArray->Count)) { kbts_u32 VCodepoint = Glyphs[S->GlyphIndex].Codepoint; VInfo = kbts_HangulSyllableInfo(VCodepoint); if(VInfo.Type == KBTS_HANGUL_SYLLABLE_TYPE_V) { V = VCodepoint; S->GlyphIndex += 1; } } if(V) { kbts_hangul_syllable_info TInfo = KBTS_ZERO; if(!T && (S->GlyphIndex < GlyphArray->Count)) { kbts_u32 TCodepoint = Glyphs[S->GlyphIndex].Codepoint; TInfo = kbts_HangulSyllableInfo(TCodepoint); if(TInfo.Type == KBTS_HANGUL_SYLLABLE_TYPE_T) { T = TCodepoint; S->GlyphIndex += 1; } } NormalizeHangul->LvtGlyphCount = 0; // Check for any tone marks that we need to swap to the front of the syllable. // The OpenType shaping documents say that we need to do this after applying GSUB features, but // harfbuzz does it before, so it's probably fine to do it here? // It's also basically free to do here, which is nice. if(S->GlyphIndex < GlyphArray->Count) { kbts_u32 ToneMarkCodepoint = Glyphs[S->GlyphIndex].Codepoint; if((ToneMarkCodepoint >= 0x302E) && (ToneMarkCodepoint <= 0x302F)) { NormalizeHangul->LvtGlyphs[NormalizeHangul->LvtGlyphCount++] = kbts_CodepointToGlyph(Font, ToneMarkCodepoint); S->GlyphIndex += 1; } } if(LInfo.Composable & VInfo.Composable & TInfo.Composable) { // Try LVT. kbts_un LvtCodepoint = 0xAC00 + (L - 0x1100) * 588 + (V - 0x1161) * 28 + (T - 0x11A7); kbts_glyph LvtGlyph = kbts_CodepointToGlyph(Font, (kbts_u32)LvtCodepoint); if(LvtGlyph.Id) { NormalizeHangul->LvtGlyphs[NormalizeHangul->LvtGlyphCount++] = LvtGlyph; } } if(!NormalizeHangul->LvtGlyphCount) { kbts_glyph LvGlyph = KBTS_ZERO; if(LInfo.Composable & VInfo.Composable) { // Try LV. kbts_un LvCodepoint = 0xAC00 + (L - 0x1100) * 588 + (V - 0x1161) * 28; LvGlyph = kbts_CodepointToGlyph(Font, (kbts_u32)LvCodepoint); } if(LvGlyph.Id) { NormalizeHangul->LvtGlyphs[NormalizeHangul->LvtGlyphCount++] = LvGlyph; } else { // Do L-V. kbts_glyph LGlyph = kbts_CodepointToGlyph(Font, (kbts_u32)L); LGlyph.Flags |= KBTS_GLYPH_FLAG_LJMO; kbts_glyph VGlyph = kbts_CodepointToGlyph(Font, (kbts_u32)V); VGlyph.Flags |= KBTS_GLYPH_FLAG_VJMO; NormalizeHangul->LvtGlyphs[NormalizeHangul->LvtGlyphCount++] = LGlyph; NormalizeHangul->LvtGlyphs[NormalizeHangul->LvtGlyphCount++] = VGlyph; } if(T) { kbts_glyph TGlyph = kbts_CodepointToGlyph(Font, (kbts_u32)T); TGlyph.Flags |= KBTS_GLYPH_FLAG_TJMO; NormalizeHangul->LvtGlyphs[NormalizeHangul->LvtGlyphCount++] = TGlyph; } } } } if(!NormalizeHangul->LvtGlyphCount) { kbts_glyph NewGlyph = kbts_CodepointToGlyph(Font, Glyph->Codepoint); NormalizeHangul->LvtGlyphs[NormalizeHangul->LvtGlyphCount++] = NewGlyph; } } { // Insert the LVT glyphs. ResumePoint3:; NormalizeHangul = &S->OpSpecific.NormalizeHangul; kbts_un NewWrittenCount = S->WrittenCount + NormalizeHangul->LvtGlyphCount; if(NewWrittenCount > S->GlyphIndex) { if(!kbts_GrowGlyphArray(&S->ResumePoint, GlyphArray, S->WrittenCount, NormalizeHangul->LvtGlyphCount, 3, 0)) { KBTS_INSTRUMENT_END return 1; } S->GlyphIndex += NormalizeHangul->LvtGlyphCount; } KBTS_FOR(LvtGlyphIndex, 0, NormalizeHangul->LvtGlyphCount) { Glyphs[S->WrittenCount++] = NormalizeHangul->LvtGlyphs[LvtGlyphIndex]; } } } KBTS_INSTRUMENT_END } break; case KBTS_OP_KIND_GSUB_FEATURES: { KBTS_INSTRUMENT_BLOCK_BEGIN("GSUB_FEATURES") kbts_gsub_gpos *FontGsub; FontGsub = Font->ShapingTables[KBTS_SHAPING_TABLE_GSUB]; kbts_lookup_list *LookupList; LookupList = kbts_GetLookupList(FontGsub); kbts_gsub_frame *Frames; Frames = KBTS_POINTER_AFTER(kbts_gsub_frame, S); kbts_op_state_gsub *Gsub; Gsub = &S->OpSpecific.Gsub; kbts_u32 GlyphFilter; kbts_skip_flags SkipFlags; kbts_feature_set LookupFeatures; kbts_BeginFeatures(S, Config, KBTS_SHAPING_TABLE_GSUB, Op->Features); while(kbts_NextLookupIndex(S, &Gsub->LookupIndex, &SkipFlags, &GlyphFilter, &LookupFeatures)) { Gsub->LookupFeatures = LookupFeatures; S->GlyphIndex = 0; // From the Microsoft docs: // If a Lookup table has multiple subtables, the subtables are processed in order, testing the glyph sequence // at the current glyph position for a match with the input sequence patterns specified by each subtable in // turn. // // This means the subtable loop is _inside_ of the loop over our glyphs. while(S->GlyphIndex < GlyphArray->Count) { Frames[0].InputGlyphCount = 1; { kbts_u32 FilterMask = Config->Shaper == KBTS_SHAPER_USE ? KBTS_USE_GLYPH_FEATURE_MASK : KBTS_GLYPH_FEATURE_MASK; kbts_u32 EffectiveGlyphFilter = GlyphFilter & FilterMask; // Reverse chaining substitutions are tricky. // See the comment at :ReverseChaining. // @Duplication: We just copy the top-level mirroring logic from DoSubstitution here for now. kbts_lookup *Lookup = kbts_GetLookup(LookupList, Gsub->LookupIndex); kbts_un CurrentGlyphIndex = (Lookup->Type == 8) ? GlyphArray->Count - 1 - S->GlyphIndex : S->GlyphIndex; kbts_glyph *CurrentGlyph = &Glyphs[CurrentGlyphIndex]; if(kbts_GlyphIncludedInLookup(Config->Font, 0, Gsub->LookupIndex, CurrentGlyph->Id) && ((CurrentGlyph->Flags & EffectiveGlyphFilter) == EffectiveGlyphFilter) && kbts_ConfigAllowsFeatures(S, Config, CurrentGlyph->Config, &LookupFeatures)) { kbts_gsub_frame *Frame = &Frames[0]; Frame->LookupIndex = (kbts_u16)Gsub->LookupIndex; Frame->SubtableIndex = 0; Frame->InputGlyphIndex = (kbts_u16)S->GlyphIndex; S->FrameCount = 1; } } while(S->FrameCount) { if(0) { ResumePoint2:; FontGsub = Font->ShapingTables[KBTS_SHAPING_TABLE_GSUB]; Gsub = &S->OpSpecific.Gsub; LookupList = kbts_GetLookupList(FontGsub); Frames = KBTS_POINTER_AFTER(kbts_gsub_frame, S); LookupFeatures = Gsub->LookupFeatures; GlyphFilter = Gsub->GlyphFilter; SkipFlags = Gsub->SkipFlags; } // These flags are used by USE. kbts_u32 GeneratedGlyphFlags = GlyphFilter & (KBTS_GLYPH_FLAG_RPHF | KBTS_GLYPH_FLAG_PREF); kbts_substitution_result_flags SubstitutionFlags = kbts_DoSubstitution(ShapeState, LookupList, Frames, &S->FrameCount, GlyphArray, 0, SkipFlags, GeneratedGlyphFlags); if(SubstitutionFlags & KBTS_SUBSTITUTION_RESULT_FLAG_GROW_BUFFER) { Gsub->GlyphFilter = GlyphFilter; Gsub->SkipFlags = SkipFlags; S->ResumePoint = 2; KBTS_INSTRUMENT_END return 1; } } S->GlyphIndex += Frames[0].InputGlyphCount; } } S->WrittenCount = GlyphArray->Count; KBTS_INSTRUMENT_END } break; case KBTS_OP_KIND_FLAG_JOINING_LETTERS: { KBTS_INSTRUMENT_BLOCK_BEGIN("FLAG_JOINING_LETTERS") kbts_u64 JoiningTypesMatchLookup = (((1ull << KBTS_UNICODE_JOINING_TYPE_RIGHT) | (1ull << KBTS_UNICODE_JOINING_TYPE_DUAL) | (1ull << KBTS_UNICODE_JOINING_TYPE_FORCE)) << (8 * KBTS_UNICODE_JOINING_TYPE_LEFT)) | (((1ull << KBTS_UNICODE_JOINING_TYPE_RIGHT) | (1ull << KBTS_UNICODE_JOINING_TYPE_DUAL) | (1ull << KBTS_UNICODE_JOINING_TYPE_FORCE)) << (8 * KBTS_UNICODE_JOINING_TYPE_DUAL)) | (((1ull << KBTS_UNICODE_JOINING_TYPE_RIGHT) | (1ull << KBTS_UNICODE_JOINING_TYPE_DUAL) | (1ull << KBTS_UNICODE_JOINING_TYPE_FORCE)) << (8 * KBTS_UNICODE_JOINING_TYPE_FORCE)); kbts_u64 JoiningFeatureTransition = ((kbts_u64)KBTS_JOINING_FEATURE_INIT << (8 * KBTS_JOINING_FEATURE_ISOL)) | ((kbts_u64)KBTS_JOINING_FEATURE_MEDI << (8 * KBTS_JOINING_FEATURE_FINA)) | ((kbts_u64)KBTS_JOINING_FEATURE_MEDI << (8 * KBTS_JOINING_FEATURE_MEDI)) | ((kbts_u64)KBTS_JOINING_FEATURE_MED2 << (8 * KBTS_JOINING_FEATURE_MED2)); // Tag letters for joining features. kbts_glyph PreviousGlyph_ = KBTS_ZERO; kbts_glyph *PreviousGlyph = &PreviousGlyph_; KBTS_FOR(GlyphIndex, 0, GlyphArray->Count) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; if(Glyph->JoiningType != KBTS_UNICODE_JOINING_TYPE_TRANSPARENT) { Glyph->JoiningFeature = !PreviousGlyph->JoiningType ? KBTS_JOINING_FEATURE_INIT : KBTS_JOINING_FEATURE_FINA; if(JoiningTypesMatchLookup & (1ull << (Glyph->JoiningType + 8 * PreviousGlyph->JoiningType))) { PreviousGlyph->JoiningFeature = (JoiningFeatureTransition >> (8 * PreviousGlyph->JoiningFeature)) & 0xFF; PreviousGlyph->Flags = (PreviousGlyph->Flags & ~KBTS_JOINING_FEATURE_MASK) | KBTS_JOINING_FEATURE_TO_GLYPH_FLAG(PreviousGlyph->JoiningFeature); Glyph->JoiningFeature = KBTS_JOINING_FEATURE_FINA; } else { Glyph->JoiningFeature = KBTS_JOINING_FEATURE_ISOL; } if(Glyph->JoiningFeature) { // Be careful that this properly maps kbts_joining_feature to KBTS_GLYPH_FLAG! Glyph->Flags = (Glyph->Flags & ~KBTS_JOINING_FEATURE_MASK) | KBTS_JOINING_FEATURE_TO_GLYPH_FLAG(Glyph->JoiningFeature); } PreviousGlyph = Glyph; } } S->WrittenCount = GlyphArray->Count; KBTS_INSTRUMENT_END } break; case KBTS_OP_KIND_GPOS_METRICS: { KBTS_INSTRUMENT_BLOCK_BEGIN("GPOS_METRICS") // hmtx/vmtx pass. int ClearMarkAdvances = (Config->Shaper == KBTS_SHAPER_MYANMAR) || (Config->Shaper == KBTS_SHAPER_USE); kbts_u32 Orientation = KBTS_ORIENTATION_HORIZONTAL; // @Hardcoded kbts_hea *Hea = Font->Hea[Orientation]; kbts_u16 *Mtx = Font->Mtx[Orientation]; kbts_long_mtx *LongMetrics = 0; kbts_s16 *ShortMetrics = 0; if(Hea && Mtx) { LongMetrics = (kbts_long_mtx *)Mtx; ShortMetrics = (kbts_s16 *)(LongMetrics + Hea->MetricCount); } kbts_long_mtx DefaultMetric = {1024, 0}; if(Font->Head) { DefaultMetric.Advance = Font->Head->UnitsPerEm; if(Orientation == KBTS_ORIENTATION_HORIZONTAL) { DefaultMetric.Advance /= 2; } } KBTS_FOR(GlyphIndex, 0, GlyphArray->Count) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; kbts_long_mtx Metric = DefaultMetric; if(LongMetrics) { kbts_u32 Id = Glyph->Id; // At the end of shaping, default ignorable glyphs that are not generated by GSUB are replaced with zero-width // whitespace glyphs (or a zero-width empty glyph if no whitespace glyph is present). // (By the way, we do this because Harfbuzz does it, and Harfbuzz does it probably because Uniscribe does it.) // We handle this in two steps: // - The first is here. We want cursive attachments, and mark-to-base attachments, and other relative placements // to take the zero width into account, and zeroing the width right at the beginning of GPOS is the most // straighforward way to accomplish this. // (@Incomplete: It is likely that we also need to take the default ignorable case into account when accumulating // cursive offsets.) // - In POST_GPOS_FIXUP, we perform the glyph ID substitution. We have to wait until all GPOS features have been // executed to do this because they might possibly match the original ID. if(!(Glyph->Flags & KBTS_GLYPH_FLAG_GENERATED_BY_GSUB) && (Glyph->UnicodeFlags & KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE)) { Metric.Advance = 0; Metric.PreviousSideBearing = 0; } else if(Id < Hea->MetricCount) { Metric = LongMetrics[Id]; } else { Metric.Advance = LongMetrics[Hea->MetricCount - 1].Advance; Metric.PreviousSideBearing = ShortMetrics[Id - Hea->MetricCount]; } } if(!ClearMarkAdvances | (Glyph->Classes.Class != KBTS_GLYPH_CLASS_MARK)) { if(Orientation == KBTS_ORIENTATION_HORIZONTAL) { // @Cleanup: Why does harfbuzz not take bearings into account in these tests? // P.X += Metric.PreviousSideBearing; Glyph->AdvanceX = Metric.Advance; } else { // @Cleanup: Why does harfbuzz not take bearings into account in these tests? // P.Y += Metric.PreviousSideBearing; Glyph->AdvanceY = Metric.Advance; } } } KBTS_INSTRUMENT_END } break; case KBTS_OP_KIND_GPOS_FEATURES: { KBTS_INSTRUMENT_BLOCK_BEGIN("GPOS_FEATURES") kbts_gsub_gpos *Gpos = Font->ShapingTables[KBTS_SHAPING_TABLE_GPOS]; kbts_BeginFeatures(S, Config, KBTS_SHAPING_TABLE_GPOS, Op->Features); kbts_lookup_list *LookupList = kbts_GetLookupList(Gpos); kbts_un LookupIndex; kbts_skip_flags SkipFlags; kbts_u32 GlyphFilter; kbts_feature_set LookupFeatures; while(kbts_NextLookupIndex(S, &LookupIndex, &SkipFlags, &GlyphFilter, &LookupFeatures)) { kbts_lookup *PackedLookup = kbts_GetLookup(LookupList, LookupIndex); kbts_unpacked_lookup Lookup = kbts_UnpackLookup(Font->Gdef, PackedLookup); kbts_un PositionedGlyphCount = 0; while(PositionedGlyphCount < GlyphArray->Count) { kbts_un DeltaGlyphIndex = 1; if(kbts_GlyphIncludedInLookup(Config->Font, 1, LookupIndex, GlyphArray->Glyphs[PositionedGlyphCount].Id) && kbts_ConfigAllowsFeatures(S, Config, Glyphs[PositionedGlyphCount].Config, &LookupFeatures)) { KBTS_FOR(SubtableIndex, 0, Lookup.SubtableCount) { kbts_u16 *Subtable = KBTS_POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[SubtableIndex]); kbts_do_single_adjustment_result Adjustment = kbts_DoSingleAdjustment(Config, LookupList, LookupIndex, SubtableIndex, &Lookup, Subtable, GlyphArray, PositionedGlyphCount, SkipFlags); if(Adjustment.PerformedAdjustment) { DeltaGlyphIndex = Adjustment.PositionedGlyphCount; break; } } } PositionedGlyphCount += DeltaGlyphIndex; } } KBTS_INSTRUMENT_END } break; case KBTS_OP_KIND_POST_GPOS_FIXUP: { KBTS_INSTRUMENT_BLOCK_BEGIN("POST_GPOS_FIXUP") kbts_un WriteAt = 0; kbts_glyph WhitespaceGlyph = Config->Whitespace; int ClearMarkAdvances = kbts_ShaperClearsMarkAdvancesInPostGposFixup(Config->Shaper); if(ShapeState->MainDirection != ShapeState->RunDirection) { // Flip direction. // This might seem like a totally superfluous thing to do, because we have to do a bunch // of work to reverse glyph order while still preserving their relative positions. // However, for mainly LTR documents, the anchor position will naturally be left-aligned, // while, in RTL documents, it will naturally right-align. // As such, going through the glyph sequence and reversing it is needed _anyway_ at some point, // and we might as well do it here, because this is where we can take resolve attachments // for relatively cheap, since they are always back-looking. (The next paragraph explains this // in more detail.) // The unintuitive part about this pass is the glyph advances. // Normally, when iterating over a sequence of glyphs, we see base glyphs before marks. Obviously. // However, when flipping the sequence, we see the marks before seeing the bases, which means we // won't have accumulated the base glyph's advance yet! So we have to go through the sequence here // and compensate for missing advances by precomputing them and baking them into the marks. // Another way to reach the same result would be to keep marks on the same side as their bases when // flipping, but that is not what Harfbuzz does, and, the day we decide we want to diverge from Harfbuzz, // we will very likely be better off not flipping the sequence at all and deleting all of this garbage code. kbts_s32 MarkAttachAdvanceX = 0; kbts_s32 MarkAttachAdvanceY = 0; KBTS_FOR(GlyphIndex, 0, GlyphArray->Count) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; if(Glyph->AttachGlyphIndexPlusOne) { kbts_glyph *Attach = &Glyphs[Glyph->AttachGlyphIndexPlusOne - 1]; kbts_s32 AttachAdvanceX = MarkAttachAdvanceX; kbts_s32 AttachAdvanceY = MarkAttachAdvanceY; if(Attach->Classes.Class != KBTS_GLYPH_CLASS_MARK) { AttachAdvanceX = Attach->AdvanceX; AttachAdvanceY = Attach->AdvanceY; } Glyph->OffsetX += AttachAdvanceX; Glyph->OffsetY += AttachAdvanceY; MarkAttachAdvanceX = AttachAdvanceX; MarkAttachAdvanceY = AttachAdvanceY; } } kbts_un SwapCount = GlyphArray->Count / 2; KBTS_FOR(LeftIndex, 0, SwapCount) { kbts_un RightIndex = GlyphArray->Count - 1 - LeftIndex; kbts_glyph SwapGlyph = Glyphs[LeftIndex]; Glyphs[LeftIndex] = Glyphs[RightIndex]; Glyphs[RightIndex] = SwapGlyph; } } // Make default ignorables that weren't explicitly created by the font invisible. // // It is tempting to put this loop inside of an if(WhitespaceGlyph.Id), just like we do // for dotted circle insertion. However, Harfbuzz does not do this! // When the font does not contain a dotted circle, nothing is inserted, but when the font // does not contain a whitespace glyph, _we still insert an empty glyph_. KBTS_FOR(GlyphIndex, 0, GlyphArray->Count) { kbts_glyph Glyph = Glyphs[GlyphIndex]; int Write = 0; // It might be tempting to keep glyphs that were used in GPOS, but Harfbuzz doesn't care. if(!(Glyph.Flags & KBTS_GLYPH_FLAG_GENERATED_BY_GSUB) && (Glyph.UnicodeFlags & KBTS_UNICODE_FLAG_DEFAULT_IGNORABLE)) { // This glyph is default ignorable and should be ignored. if(WhitespaceGlyph.Id) { Write = 1; Glyph = WhitespaceGlyph; } } else { if(ClearMarkAdvances && (Glyph.Classes.Class == KBTS_GLYPH_CLASS_MARK)) { Glyph.AdvanceX = Glyph.AdvanceY = 0; } Write = 1; } if(Write) { Glyphs[WriteAt++] = Glyph; } } GlyphArray->Count = (kbts_u32)WriteAt; GlyphArray->TotalCount = GlyphArray->Count; KBTS_INSTRUMENT_END } break; case KBTS_OP_KIND_STCH_POSTPASS: { KBTS_FOR(GlyphIndex, 0, GlyphArray->Count) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; if(Glyph->Flags & (KBTS_GLYPH_FLAG_STCH_ENDPOINT | KBTS_GLYPH_FLAG_STCH_EXTENSION)) { kbts_un At = GlyphIndex; kbts_un ExtensionIndex = At; kbts_u32 SawExtension = 0; kbts_s32 EndpointWidth = 0; kbts_s32 ExtensionWidth = 0; while(At < GlyphArray->Count) { kbts_glyph *AtGlyph = &Glyphs[At]; if(AtGlyph->Flags & KBTS_GLYPH_FLAG_STCH_ENDPOINT) { EndpointWidth += AtGlyph->AdvanceX; At += 1; } else if(AtGlyph->Flags & KBTS_GLYPH_FLAG_STCH_EXTENSION) { ExtensionIndex = At; ExtensionWidth += AtGlyph->AdvanceX; SawExtension = 1; At += 1; } else { break; } } kbts_sn WordWidth = 0; while(At < GlyphArray->Count) { kbts_glyph *AtGlyph = &Glyphs[At]; int Ok = 0; if(!(AtGlyph->Flags & (KBTS_GLYPH_FLAG_STCH_ENDPOINT | KBTS_GLYPH_FLAG_STCH_EXTENSION)) && (AtGlyph->UnicodeFlags & KBTS_UNICODE_FLAG_PART_OF_WORD)) { Ok = 1; } if(Ok) { WordWidth += AtGlyph->AdvanceX; At += 1; } else { break; } } if(WordWidth > EndpointWidth) { kbts_sn ExtensionCount = (WordWidth - EndpointWidth) / ExtensionWidth; if((ExtensionWidth * ExtensionCount) < (WordWidth - EndpointWidth)) { ExtensionCount += 1; } (void)ExtensionCount; (void)ExtensionIndex; (void)SawExtension; /* @Incomplete kbts_glyph_adjustment *ExtensionAdjustment = &Positions[ExtensionIndex]; ExtensionAdjustment->LastRepeatIndex = ExtensionCount - 1; ExtensionAdjustment->RepeatOffsetX = (WordWidth - EndpointWidth - ExtensionWidth) / ExtensionCount; */ } GlyphIndex = At; } } } break; } if(Op->Kind < KBTS_OP_KIND_GPOS_METRICS) { kbts_un DeltaCount = S->WrittenCount - GlyphArray->Count; GlyphArray->Count += (kbts_u32)DeltaCount; GlyphArray->TotalCount += (kbts_u32)DeltaCount; } KBTS_INSTRUMENT_END return 0; } static kbts_glyph kbts_Substitute1(kbts_shape_state *ShapeState, kbts_lookup_list *LookupList, kbts_feature *Feature, kbts_skip_flags SkipFlags, kbts_glyph *Glyph) { kbts_glyph Result = *Glyph; kbts_glyph_array GlyphArray = kbts_GlyphArray(Glyph, 1, 1, 1); kbts_iterate_lookups IterateLookups = kbts_IterateLookups(LookupList, Feature); while(kbts_NextLookup(&IterateLookups)) { kbts_gsub_frame Frames[8]; Frames[0].InputGlyphCount = 1; kbts_u32 FrameCount = 1; while(FrameCount) { kbts_substitution_result_flags SubstitutionResult = kbts_DoSubstitution(ShapeState, LookupList, Frames, &FrameCount, &GlyphArray, 0, SkipFlags, 0); if(SubstitutionResult & KBTS_SUBSTITUTION_RESULT_FLAG_GROW_BUFFER) { goto Done; } } } Done:; return Result; } typedef struct kbts_attach_state { kbts_syllabic_position CurrentPosition; kbts_syllabic_position LastPositionThatWasNotPreBaseMatra; kbts_indic_syllabic_class LastClass; kbts_un Start; kbts_un OnePastLast; } kbts_attach_state; typedef struct kbts_begin_cluster_result { kbts_un ClusterGlyphCount; kbts_un InsertedGlyphCount; } kbts_begin_cluster_result; static kbts_begin_cluster_result kbts_BeginCluster(kbts_shape_state *ShapeState, kbts_glyph *Glyphs, kbts_un GlyphCount) { kbts_begin_cluster_result Result = KBTS_ZERO; Result.ClusterGlyphCount = GlyphCount; kbts_op_state *OpState = &ShapeState->OpState; kbts_shape_config *Config = ShapeState->Config; kbts_font *Font = Config->Font; ShapeState->RealCluster = 0; switch(Config->Shaper) { case KBTS_SHAPER_INDIC: { kbts_lookup_list *LookupList = kbts_GetLookupList(Font->ShapingTables[KBTS_SHAPING_TABLE_GSUB]); kbts_un OtherCount = 0; while((OtherCount < GlyphCount) && ((Glyphs[OtherCount].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_OTHER) || (Glyphs[OtherCount].SyllabicClass >= KBTS_INDIC_SYLLABIC_CLASS_COUNT))) { ++OtherCount; } if(OtherCount) { // Not an Indic syllable. // Just pass it along. Result.ClusterGlyphCount = OtherCount; } else { kbts_un ScanGlyphIndex = 0; kbts_un State = 0; kbts_un Broken = 1; kbts_un BrokenState = 0; while((ScanGlyphIndex < GlyphCount) && (State < KBTS_INDIC_SYLLABIC_STATE_COUNT)) { kbts_glyph *Glyph = &Glyphs[ScanGlyphIndex]; kbts_un Class = Glyph->SyllabicClass; if(KBTS_IN_SET(Class, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_RA)(KBTS_INDIC_SYLLABIC_CLASS_CONSONANT) (KBTS_INDIC_SYLLABIC_CLASS_VOWEL)(KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE) (KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER)(KBTS_INDIC_SYLLABIC_CLASS_SYMBOL)))) { Broken = 0; } BrokenState = (BrokenState << 1) | Broken; State = kbts_IndicSyllabicTransition[Class][State]; State -= 1; // @Incomplete @Cleanup: Decrement every state by 1 in the transition table. ScanGlyphIndex += 1; } if(State > KBTS_INDIC_SYLLABIC_STATE_COUNT) { ScanGlyphIndex -= State - KBTS_INDIC_SYLLABIC_STATE_COUNT; BrokenState >>= State - KBTS_INDIC_SYLLABIC_STATE_COUNT; if(!ScanGlyphIndex) { // If we backtrack all the way to the beginning, still eat a character. ScanGlyphIndex = 1; } } // NOTE: Symbols, vedics, modifiers, matras have their syllabic positions tagged at build time. // It is tempting to use Unicode's positional information for consonants, too, but OpenType // _strongly_ recommends that shapers use the font's tables instead, ie. doing tentative lookups // with specific features. kbts_gsub_frame *Frames = KBTS_POINTER_AFTER(kbts_gsub_frame, OpState); kbts_glyph *OnePastLastSyllableGlyph = Glyphs + ScanGlyphIndex; if((Config->Script == KBTS_SCRIPT_KANNADA) && (ScanGlyphIndex >= 3) && (Glyphs[0].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_RA) && (Glyphs[1].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT) && (Glyphs[2].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ)) { // In older versions of Unicode (~4.x, pre-2004), Ra-Virama-Zwj was recommended in Kannada // to communicate the intent of displaying (Ra + (next consonant as below-base form)). // This was changed in Unicode 5. Now, the recommended sequence to display (Ra + // (next consonant as below-base form)) is Ra-Zwj-Virama. // Since Ra-Virama-Zwj is not a useful sequence that happens organically in Kannada, // we are free to transform it into Ra-Zwj-Virama here without losing information. kbts_glyph Swap = Glyphs[1]; Glyphs[1] = Glyphs[2]; Glyphs[2] = Swap; } kbts_glyph_flags RephFlags = KBTS_GLYPH_FLAG_RPHF; kbts_un OnePastRephIndex = 0; { // Reph tagging. // This first pass only figures out where the reph ends. // We delay updating glyph properties until we know whether the reph is the base or not. kbts_glyph *First = &Glyphs[0]; kbts_glyph *Second = &Glyphs[1]; kbts_feature *Rphf = Config->Rphf; switch(Config->IndicScriptProperties.RephEncoding) { case KBTS_REPH_ENCODING_LOGICAL_REPHA: if(First->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_REPHA) { RephFlags = 0; OnePastRephIndex = 1; } break; case KBTS_REPH_ENCODING_IMPLICIT: if((ScanGlyphIndex >= 2) && (Second->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT) && kbts_WouldSubstitute(ShapeState, LookupList, Frames, Rphf, 0, Glyphs, 2)) { OnePastRephIndex = 2; } break; case KBTS_REPH_ENCODING_EXPLICIT: if((ScanGlyphIndex >= 3) && (Second->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT) && (Glyphs[2].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ) && kbts_WouldSubstitute(ShapeState, LookupList, Frames, Rphf, 0, Glyphs, 3)) { OnePastRephIndex = 3; } break; } // Extend the reph with suffixed joiners. if(OnePastRephIndex) { while((OnePastRephIndex < ScanGlyphIndex) && KBTS_IN_SET(Glyphs[OnePastRephIndex].SyllabicClass, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_ZWJ)(KBTS_INDIC_SYLLABIC_CLASS_ZWNJ)))) { OnePastRephIndex += 1; } } } kbts_feature *Pref = Config->Pref; kbts_un BaseIndex = ScanGlyphIndex; kbts_un LastConsonantIndex = 0; kbts_syllabic_position LastConsonantPosition = KBTS_SYLLABIC_POSITION_SYLLABLE_BASE; if(Config->DottedCircle.Id && (BrokenState & 1)) { // Insert a dotted circle after Reph. for(kbts_un GlyphIndex = GlyphCount; GlyphIndex > OnePastRephIndex; --GlyphIndex) { Glyphs[GlyphIndex] = Glyphs[GlyphIndex - 1]; } ScanGlyphIndex += 1; Result.InsertedGlyphCount = 1; Glyphs[OnePastRephIndex] = Config->DottedCircle; BaseIndex = OnePastRephIndex; } else { // Going backwards, tag blwf and pstf consonants until we get to the base. kbts_glyph Scratch[3]; Scratch[0] = Config->Virama; Scratch[2] = Config->Virama; kbts_feature *Locl = Config->Locl; kbts_feature *Vatu = Config->Vatu; // pstf forms come last, then blwf. kbts_feature *SectionFeature = Config->Pstf; kbts_syllabic_position SectionPosition = KBTS_SYLLABIC_POSITION_POSTBASE_CONSONANT; // If we see no consonant/matra, then surely we want to attach to the base. kbts_syllabic_position SyllabicPosition = KBTS_SYLLABIC_POSITION_SYLLABLE_BASE; kbts_indic_syllabic_class LastClass = KBTS_INDIC_SYLLABIC_CLASS_COUNT; for(kbts_un GlyphIndex = ScanGlyphIndex; GlyphIndex > OnePastRephIndex; --GlyphIndex) { kbts_glyph *Glyph = &Glyphs[GlyphIndex - 1]; kbts_indic_syllabic_class Class = Glyph->SyllabicClass; switch(Class) { case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT: case KBTS_INDIC_SYLLABIC_CLASS_RA: case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER: case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL: // Apply locl first. Scratch[1] = kbts_Substitute1(ShapeState, LookupList, Locl, KBTS_SKIP_FLAG_ZWNJ | KBTS_SKIP_FLAG_ZWJ, Glyph); // Microsoft says to "move backwards until a consonant is found that does not have a below-base // or post-base form". // As with everything else the spec says, it is wrong. There are cases in which the only consonant // in a syllable has a below-base or post-base form. In those cases, we still want them to be the // syllable base. // So, as we sweep backward, set the base index on consonants unconditionally. // @Robustness: Do we want to update Base only if we do not match Pref/Vatu? BaseIndex = GlyphIndex - 1; if(kbts_WouldSubstitute(ShapeState, LookupList, Frames, Pref, 0, Scratch, 2) || kbts_WouldSubstitute(ShapeState, LookupList, Frames, Pref, 0, Scratch + 1, 2) || kbts_WouldSubstitute(ShapeState, LookupList, Frames, Vatu, 0, Scratch, 2) || kbts_WouldSubstitute(ShapeState, LookupList, Frames, Vatu, 0, Scratch + 1, 2)) { SyllabicPosition = KBTS_SYLLABIC_POSITION_POSTBASE_CONSONANT; } else { for(;;) { if(kbts_WouldSubstitute(ShapeState, LookupList, Frames, SectionFeature, 0, Scratch, 2) || kbts_WouldSubstitute(ShapeState, LookupList, Frames, SectionFeature, 0, Scratch + 1, 2)) { SyllabicPosition = SectionPosition; break; } else if(SectionPosition == KBTS_SYLLABIC_POSITION_POSTBASE_CONSONANT) { SectionFeature = Config->Blwf; SectionPosition = KBTS_SYLLABIC_POSITION_BELOWBASE_CONSONANT; // Retry with Blwf. } else { goto DoneScanningForBase; } } } if(!LastConsonantIndex) { LastConsonantIndex = GlyphIndex - 1; LastConsonantPosition = SyllabicPosition; } Glyph->SyllabicPosition = SyllabicPosition; break; case KBTS_INDIC_SYLLABIC_CLASS_VOWEL: case KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER: case KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE: BaseIndex = GlyphIndex - 1; goto DoneScanningForBase; break; case KBTS_INDIC_SYLLABIC_CLASS_HALANT: if(LastClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ) { // Explicit half form. // Since half forms are always before the base, we can safely stop here. goto DoneScanningForBase; } case KBTS_INDIC_SYLLABIC_CLASS_NUKTA: case KBTS_INDIC_SYLLABIC_CLASS_ZWJ: case KBTS_INDIC_SYLLABIC_CLASS_ZWNJ: // @Incomplete: Register Shifter Glyph->SyllabicPosition = SyllabicPosition; break; } LastClass = Class; } DoneScanningForBase:; } // Fix reph position now. if(OnePastRephIndex) { kbts_syllabic_position RephPosition = KBTS_SYLLABIC_POSITION_RA_TO_BECOME_REPH; kbts_glyph_flags Flags = RephFlags; kbts_un OnePastLast = OnePastRephIndex; if(BaseIndex == ScanGlyphIndex) { RephPosition = KBTS_SYLLABIC_POSITION_SYLLABLE_BASE; Flags = 0; BaseIndex = 0; OnePastRephIndex = 0; } KBTS_FOR(GlyphIndex, 0, OnePastLast) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; Glyph->SyllabicPosition = RephPosition; Glyph->Flags |= Flags; } } if(BaseIndex < ScanGlyphIndex) { Glyphs[BaseIndex].SyllabicPosition = KBTS_SYLLABIC_POSITION_SYLLABLE_BASE; if(!LastConsonantIndex) { LastConsonantIndex = BaseIndex; // LastConsonantPosition is already set to SYLLABLE_BASE. } } { // Reorder marks. // @Cleanup @Speed: Supposedly, NORMALIZE already does this... kbts_glyph *ReorderGlyph = Glyphs + ScanGlyphIndex - 1; while(ReorderGlyph >= Glyphs) { if(ReorderGlyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_NUKTA) { kbts_glyph *Prev = ReorderGlyph - 1; while((Prev >= Glyphs) && KBTS_IN_SET(Prev->SyllabicClass, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_HALANT)(KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN)))) { kbts_glyph Swap = *Prev; *Prev = Prev[1]; Prev[1] = Swap; Prev -= 1; } ReorderGlyph = Prev; } else { ReorderGlyph -= 1; } } } { // @Temporary @Cleanup // Left matras should be ordered backwards. // We want to bake this ordering into our sort, so we increase our syllabic position bits // and sub-order matras with the low nibble. (There should only be 4 matras tops, anyway.) kbts_un LeftMatraCount = 0; KBTS_FOR(GlyphIndex, 0, ScanGlyphIndex) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; Glyph->SyllabicPosition <<= 4; if(Glyph->SyllabicPosition == (KBTS_SYLLABIC_POSITION_PREBASE_MATRA << 4)) { Glyph->SyllabicPosition += (15 - LeftMatraCount++) & 0xF; } } } { // Attach stuff to the right of consonants/matras. // Pre-base consonants, the base consonant, and matras all have right attachments, // while post-base consonants have left attachments. // Since matras always come after all consonants, we try to separate the buffer into three parts: // a pre-base+base part (right attachments), a post-base consonant part (left attachments), and // a post-consonant part (right attachments again). // This part handles right attachments. Left attachments were handled in the base syllable search. kbts_attach_state States[2] = { {KBTS_SYLLABIC_POSITION_RA_TO_BECOME_REPH << 4, KBTS_SYLLABIC_POSITION_RA_TO_BECOME_REPH << 4, KBTS_INDIC_SYLLABIC_CLASS_COUNT, OnePastRephIndex, BaseIndex}, {(kbts_u8)(LastConsonantPosition << 4), (kbts_u8)(LastConsonantPosition << 4), KBTS_INDIC_SYLLABIC_CLASS_COUNT, LastConsonantIndex + 1, ScanGlyphIndex}, }; kbts_un Iterations = KBTS_MAX(States[0].OnePastLast - States[0].Start, States[1].OnePastLast - States[1].Start); KBTS_FOR(GlyphIndex, 0, Iterations) { KBTS_FOR(StateIndex, 0, KBTS_ARRAY_LENGTH(States)) { kbts_attach_state *Attach = &States[StateIndex]; if((Attach->Start + GlyphIndex) < Attach->OnePastLast) { kbts_glyph *Glyph = &Glyphs[Attach->Start + GlyphIndex]; kbts_indic_syllabic_class Class = Glyph->SyllabicClass; switch(Class) { case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT: case KBTS_INDIC_SYLLABIC_CLASS_RA: case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER: case KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL: // This only happens in the pre-base state. Glyph->SyllabicPosition = (KBTS_SYLLABIC_POSITION_PREBASE_CONSONANT << 4); Attach->CurrentPosition = (KBTS_SYLLABIC_POSITION_PREBASE_CONSONANT << 4); break; case KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST: // This specific category (which is composed of a single character) may come after // a syllable modifier in a sequence like Consonant-SyllableModifier-MatraPost. // In this very particular case (!), the syllable modifier is attached _to the matra_, // and not to the consonant. if(Attach->LastClass == KBTS_INDIC_SYLLABIC_CLASS_SYLLABLE_MODIFIER) { Glyph[-1].SyllabicPosition = Glyph->SyllabicPosition; } case KBTS_INDIC_SYLLABIC_CLASS_MATRA: Attach->CurrentPosition = Glyph->SyllabicPosition; if((Attach->CurrentPosition >> 4) != KBTS_SYLLABIC_POSITION_PREBASE_MATRA) { Attach->LastPositionThatWasNotPreBaseMatra = Attach->CurrentPosition; } break; case KBTS_INDIC_SYLLABIC_CLASS_HALANT: if((Attach->CurrentPosition >> 4) == KBTS_SYLLABIC_POSITION_PREBASE_MATRA) { // Uniscribe does not reorder halants with pre-base matras. Not sure why. Glyph->SyllabicPosition = Attach->LastPositionThatWasNotPreBaseMatra; break; } case KBTS_INDIC_SYLLABIC_CLASS_NUKTA: case KBTS_INDIC_SYLLABIC_CLASS_ZWJ: case KBTS_INDIC_SYLLABIC_CLASS_ZWNJ: // @Incomplete: Register Shifter Glyph->SyllabicPosition = Attach->CurrentPosition; break; } Attach->LastClass = Class; } } } } { // Do the sort! // NOTE: It is important that we sort _now_, because some characters will be reordered across the base from // where they started, which can change which features will apply to them. KBTS_FOR(Iteration, 0, ScanGlyphIndex) { KBTS_FOR(GlyphIndex, 1, ScanGlyphIndex) { kbts_glyph *Left = &Glyphs[GlyphIndex - 1]; kbts_glyph *Right = &Glyphs[GlyphIndex]; if(Left->SyllabicPosition > Right->SyllabicPosition) { kbts_glyph Swap = *Left; *Left = *Right; *Right = Swap; // Make sure we don't lose track of the base... if(GlyphIndex == BaseIndex) { BaseIndex = GlyphIndex - 1; } else if((GlyphIndex - 1) == BaseIndex) { BaseIndex = GlyphIndex; } } } } } { // @Temporary @Cleanup // Revert our syllabic position shift for now. KBTS_FOR(GlyphIndex, 0, ScanGlyphIndex) { Glyphs[GlyphIndex].SyllabicPosition >>= 4; } } // This is what Harfbuzz does: // - NUKT, AKHN, RKRF, VATU, CJCT are active for all characters, but they count ZWJ/ZWNJ in their sequence // lookups. // - Note that, by default, Harfbuzz skips ZWJ/ZWNJ in sequence lookups, and selectively disables it for CJCT. // - Anyway, since these are active for all characters, we don't need flags for them. // (RPHF was already handled before sorting.) { // All pre-base glyphs get HALF, which is then selectively disabled in front of ZWNJs. kbts_glyph_flags BaseFlags = 0; if(!Config->IndicScriptProperties.BlwfPostOnly) { BaseFlags = KBTS_GLYPH_FLAG_BLWF; } kbts_indic_syllabic_class LastClass = 0; for(kbts_un GlyphIndex = BaseIndex; GlyphIndex > 0; --GlyphIndex) { kbts_glyph *Glyph = &Glyphs[GlyphIndex - 1]; kbts_glyph_flags Flags = BaseFlags; if(LastClass != KBTS_INDIC_SYLLABIC_CLASS_ZWNJ) { Flags |= KBTS_GLYPH_FLAG_HALF; } Glyph->Flags |= Flags; LastClass = Glyph->SyllabicClass; } } // All post-base glyphs get BLWF, ABVF, PSTF. Some get PREF. kbts_glyph Scratch[2]; Scratch[0] = Scratch[1] = KBTS_ZERO_TYPE(kbts_glyph); kbts_glyph *LastGlyph; LastGlyph = 0; KBTS_FOR(GlyphIndex, BaseIndex + 1, ScanGlyphIndex) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; // It is tempting to apply PREF to every glyph after the base. // However, the PREF flag is also used to find the syllable base again in EndCluster, // so we have to be precise with it. Scratch[1] = *Glyph; if(kbts_WouldSubstitute(ShapeState, LookupList, Frames, Pref, 0, Scratch, 2)) { LastGlyph->Flags |= KBTS_GLYPH_FLAG_PREF; Glyph->Flags |= KBTS_GLYPH_FLAG_PREF; } Glyph->Flags |= (KBTS_GLYPH_FLAG_BLWF | KBTS_GLYPH_FLAG_ABVF | KBTS_GLYPH_FLAG_PSTF); Scratch[0] = Scratch[1]; LastGlyph = Glyph; } // The base only inherits stuff after it, up to whatever and not including what was grabbed by // post-base consonants. if(BaseIndex < ScanGlyphIndex) { Glyphs[BaseIndex].SyllabicPosition = KBTS_SYLLABIC_POSITION_SYLLABLE_BASE; kbts_u64 Classes = (1ull << KBTS_INDIC_SYLLABIC_CLASS_HALANT) | (1ull << KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN) | (1ull << KBTS_INDIC_SYLLABIC_CLASS_NUKTA) | (1ull << KBTS_INDIC_SYLLABIC_CLASS_ZWJ) | (1ull << KBTS_INDIC_SYLLABIC_CLASS_ZWNJ); kbts_glyph *Next = &Glyphs[BaseIndex + 1]; while((Next < OnePastLastSyllableGlyph) && (Next->SyllabicPosition < KBTS_SYLLABIC_POSITION_SYLLABLE_BASE) && ((1ull << Next->SyllabicClass) & Classes)) { Next->SyllabicPosition = KBTS_SYLLABIC_POSITION_SYLLABLE_BASE; Next += 1; } } Result.ClusterGlyphCount = ScanGlyphIndex; ShapeState->RealCluster = 1; } } break; case KBTS_SHAPER_USE: { kbts_un OtherCount = 0; while((OtherCount < GlyphCount) && ((Glyphs[OtherCount].UseClass == KBTS_USE_SYLLABIC_CLASS_OTHER) || (Glyphs[OtherCount].UseClass == KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_POST))) { OtherCount += 1; } if(OtherCount) { Result.ClusterGlyphCount = OtherCount; } else { // Parse a real cluster. kbts_u8 State = 0; kbts_un ScanGlyphIndex = 0; while((ScanGlyphIndex < GlyphCount) && (State < KBTS_USE_STATE_s0)) { kbts_glyph *Glyph = &Glyphs[ScanGlyphIndex++]; State = kbts_UseTransition[Glyph->UseClass][State]; // @Incomplete: Remove this!!! State -= 1; } if(State >= KBTS_USE_STATE_s0) { ScanGlyphIndex -= 1; } if((ScanGlyphIndex < GlyphCount) && (Glyphs[ScanGlyphIndex].UseClass == KBTS_USE_SYLLABIC_CLASS_ZWNJ)) { ScanGlyphIndex += 1; } if(!ScanGlyphIndex) ScanGlyphIndex = 1; Result.ClusterGlyphCount = ScanGlyphIndex; ShapeState->RealCluster = 1; } } break; case KBTS_SHAPER_KHMER: { kbts_un OtherCount = 0; while((OtherCount < GlyphCount) && ((Glyphs[OtherCount].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_OTHER) || (Glyphs[OtherCount].SyllabicClass >= KBTS_KHMER_SYLLABIC_CLASS_COUNT))) { OtherCount += 1; } if(OtherCount) { Result.ClusterGlyphCount = OtherCount; } else { kbts_u8 State = 0; kbts_un ScanGlyphIndex = 0; while((ScanGlyphIndex < GlyphCount) && (State < KBTS_KHMER_SYLLABIC_STATE_COUNT)) { kbts_glyph *Glyph = &Glyphs[ScanGlyphIndex++]; kbts_indic_syllabic_class Class = Glyph->SyllabicClass; State = kbts_KhmerSyllabicTransition[Class][State]; // @Incomplete: Remove this! State -= 1; } if(State >= KBTS_KHMER_SYLLABIC_STATE_COUNT) { ScanGlyphIndex -= 1; } if(!ScanGlyphIndex) ScanGlyphIndex = 1; if(Config->DottedCircle.Id && !KBTS_IN_SET64(Glyphs->SyllabicClass, KBTS_SET64((KBTS_INDIC_SYLLABIC_CLASS_CONSONANT)(KBTS_INDIC_SYLLABIC_CLASS_RA) (KBTS_INDIC_SYLLABIC_CLASS_VOWEL)(KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE) (KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER)))) { // Broken cluster. // Insert a dotted circle. for(kbts_un GlyphIndex = GlyphCount; GlyphIndex; --GlyphIndex) { Glyphs[GlyphIndex] = Glyphs[GlyphIndex - 1]; } ScanGlyphIndex += 1; Result.InsertedGlyphCount = 1; Glyphs[0] = Config->DottedCircle; } // In Khmer, the first glyph is always the base. kbts_glyph PreBaseGlyphs[3]; int SawHalantRa = 0; kbts_un PreBaseGlyphCount = 0; kbts_un Classes = 0; kbts_un WriteCursor = ScanGlyphIndex - 1; for(kbts_un GlyphIndex = ScanGlyphIndex; GlyphIndex; --GlyphIndex) { kbts_glyph *Glyph = &Glyphs[GlyphIndex - 1]; kbts_indic_syllabic_class Class = Glyph->SyllabicClass; if(GlyphIndex > 1) {Glyph->Flags |= KBTS_GLYPH_FLAG_ABVF | KBTS_GLYPH_FLAG_BLWF | KBTS_GLYPH_FLAG_PSTF;} Classes = ((Classes << 8) | Class) & 0xFFFF; if(Class == KBTS_INDIC_SYLLABIC_CLASS_VOWEL_PRE) { PreBaseGlyphs[PreBaseGlyphCount++] = *Glyph; } else if(!SawHalantRa && (Classes == (KBTS_INDIC_SYLLABIC_CLASS_HALANT | (KBTS_INDIC_SYLLABIC_CLASS_RA << 8)))) { kbts_glyph *Ra = &Glyphs[GlyphIndex]; Glyph->Flags |= KBTS_GLYPH_FLAG_PREF; Ra->Flags |= KBTS_GLYPH_FLAG_PREF; PreBaseGlyphs[PreBaseGlyphCount++] = *Glyph; PreBaseGlyphs[PreBaseGlyphCount++] = *Ra; WriteCursor += 1; // Cancel the Ra write. // All of the glyphs written so far need to be flagged with cfar. KBTS_FOR(CfarGlyphIndex, WriteCursor, ScanGlyphIndex) { Glyphs[CfarGlyphIndex].Flags |= KBTS_GLYPH_FLAG_CFAR; } SawHalantRa = 1; } else { Glyphs[WriteCursor--] = *Glyph; } } KBTS_FOR(PreBaseGlyphIndex, 0, PreBaseGlyphCount) { Glyphs[PreBaseGlyphIndex] = PreBaseGlyphs[PreBaseGlyphIndex]; } Result.ClusterGlyphCount = ScanGlyphIndex; } } break; case KBTS_SHAPER_MYANMAR: { kbts_un OtherCount = 0; while((OtherCount < GlyphCount) && ((Glyphs[OtherCount].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_OTHER) || (Glyphs[OtherCount].SyllabicClass >= KBTS_MYANMAR_SYLLABIC_CLASS_COUNT))) { OtherCount += 1; } if(OtherCount) { Result.ClusterGlyphCount = OtherCount; } else { kbts_u8 State = 0; kbts_un ScanGlyphIndex = 0; while((ScanGlyphIndex < GlyphCount) && (State < KBTS_MYANMAR_SYLLABIC_STATE_COUNT)) { kbts_glyph *Glyph = &Glyphs[ScanGlyphIndex++]; kbts_indic_syllabic_class Class = Glyph->SyllabicClass; State = kbts_MyanmarSyllabicTransition[Class][State]; // @Incomplete: Remove this! State -= 1; } if(State >= KBTS_MYANMAR_SYLLABIC_STATE_COUNT) { ScanGlyphIndex -= 1; } if(!ScanGlyphIndex) ScanGlyphIndex = 1; ShapeState->RealCluster = 1; Result.ClusterGlyphCount = ScanGlyphIndex; } } break; } return Result; } typedef struct kbts_end_cluster_result { int InsertDottedCircle; kbts_un DottedCircleIndex; } kbts_end_cluster_result; static kbts_end_cluster_result kbts_EndCluster(kbts_shape_state *ShapeState, kbts_glyph_array *Cluster) { kbts_end_cluster_result Result = KBTS_ZERO; kbts_shape_config *Config = ShapeState->Config; kbts_glyph *Glyphs = Cluster->Glyphs; kbts_un GlyphCount = Cluster->Count; switch(Config->Shaper) { case KBTS_SHAPER_INDIC: if(GlyphCount > 1) { // Final syllable reordering. // We are just copying Harfbuzz here, because I've read all the documentation I can and, frankly, I have no idea. kbts_feature *Pref = Config->Pref; kbts_u32 ViramaId = Config->Virama.Id; KBTS_FOR(GlyphIndex, 0, GlyphCount) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; // Harfbuzz tests for (ligated | multiplied) here. // I don't really get why, because, supposedly, all viramas should be // classified as halants regardless. if(ViramaId && (Glyph->Id == ViramaId)) { Glyph->SyllabicClass = KBTS_INDIC_SYLLABIC_CLASS_HALANT; Glyph->Flags &= ~(KBTS_GLYPH_FLAG_LIGATURE | KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION); } else if(Glyph->Flags & KBTS_GLYPH_FLAG_LIGATURE) { // We can't know the syllabic classes of ligatures for sure. Glyph->SyllabicClass = KBTS_INDIC_SYLLABIC_CLASS_COUNT; } } // Locate the syllable base. kbts_un BaseIndex = GlyphCount; { kbts_un AfterPreBaseIndex = 0; while((AfterPreBaseIndex < GlyphCount) && (Glyphs[AfterPreBaseIndex].SyllabicPosition < KBTS_SYLLABIC_POSITION_SYLLABLE_BASE)) { ++AfterPreBaseIndex; } if(AfterPreBaseIndex < GlyphCount) { BaseIndex = AfterPreBaseIndex; if(Pref && ((AfterPreBaseIndex + 1) < GlyphCount)) { // If we find a pre-base-reordering ra, then the base is probably right after it! kbts_un At = AfterPreBaseIndex + 1; while((At < GlyphCount) && !(Glyphs[At].Flags & KBTS_GLYPH_FLAG_PREF)) { ++At; } // If we are not a consonant, then we are attached to a consonant. // If we are a pref-able consonant, but we did not form a pref, then we should be right after the base. // Either way, we are very close to the base. kbts_glyph *Prefable = &Glyphs[At]; if((At < GlyphCount) && (!(Prefable->Flags & KBTS_GLYPH_FLAG_GENERATED_BY_GSUB) || !(Prefable->Flags & KBTS_GLYPH_FLAG_LIGATURE) || (Prefable->Flags & KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION))) { while((At < GlyphCount) && (Prefable->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT)) { ++At; ++Prefable; } if(At < GlyphCount) { Prefable->SyllabicPosition = KBTS_SYLLABIC_POSITION_SYLLABLE_BASE; BaseIndex = At; // Fall through to the Malayalam test. } } } if(Config->Script == KBTS_SCRIPT_MALAYALAM) { // In Malayalam, the base is after below-base forms. // (We actually just give all below-base forms the base pos.) // @Speed: This would be way simpler with a null sentinel at the end of Glyphs! kbts_un At = BaseIndex + 1; while(At < GlyphCount) { while((At < GlyphCount) && KBTS_IN_SET(Glyphs[At].SyllabicClass, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_ZWJ)(KBTS_INDIC_SYLLABIC_CLASS_ZWNJ)))) { ++At; } if((At < GlyphCount) && (Glyphs[At].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT)) { ++At; } else { break; } while((At < GlyphCount) && KBTS_IN_SET(Glyphs[At].SyllabicClass, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_ZWJ)(KBTS_INDIC_SYLLABIC_CLASS_ZWNJ)))) { ++At; } if(At < GlyphCount) { kbts_glyph *Glyph = &Glyphs[At]; if(kbts_SyllabicClassIsConsonant(Glyph->SyllabicClass) && (Glyph->SyllabicPosition == KBTS_SYLLABIC_POSITION_BELOWBASE_CONSONANT)) { Glyph->SyllabicPosition = KBTS_SYLLABIC_POSITION_SYLLABLE_BASE; BaseIndex = At; // Do not break; keep matching below-base forms. } } } } } if(BaseIndex && (BaseIndex < GlyphCount) && (Glyphs[BaseIndex].SyllabicPosition > KBTS_SYLLABIC_POSITION_SYLLABLE_BASE)) { BaseIndex -= 1; } if((BaseIndex == GlyphCount) && (Glyphs[GlyphCount - 1].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ)) { BaseIndex = GlyphCount - 1; } if(BaseIndex < GlyphCount) { while(BaseIndex && KBTS_IN_SET(Glyphs[BaseIndex].SyllabicClass, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_NUKTA)(KBTS_INDIC_SYLLABIC_CLASS_HALANT)))) { BaseIndex -= 1; } } } // Reorder matras. if(BaseIndex && (GlyphCount > 1)) { kbts_un ToIndex = BaseIndex - 1; if(BaseIndex == GlyphCount) { ToIndex = GlyphCount - 2; } if((Config->Script != KBTS_SCRIPT_MALAYALAM) && (Config->Script != KBTS_SCRIPT_TAMIL)) { for(;;) { while(ToIndex && !KBTS_IN_SET(Glyphs[ToIndex].SyllabicClass, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_MATRA)(KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST)(KBTS_INDIC_SYLLABIC_CLASS_HALANT)))) { --ToIndex; } kbts_glyph *Glyph = &Glyphs[ToIndex]; if((Glyph->SyllabicClass != KBTS_INDIC_SYLLABIC_CLASS_HALANT) || (Glyph->SyllabicPosition == KBTS_SYLLABIC_POSITION_PREBASE_MATRA)) { // We have nothing to move. ToIndex = 0; break; } else if(ToIndex && ((ToIndex + 1) < GlyphCount) && (Glyphs[ToIndex + 1].SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ)) { // Zwj+Halant cancels matra movement when the Halant is not attached to the matra. --ToIndex; } else { break; } } } if(ToIndex && (Glyphs[ToIndex].SyllabicPosition != KBTS_SYLLABIC_POSITION_PREBASE_MATRA)) { for(kbts_un MatraIndex = ToIndex; MatraIndex; --MatraIndex) { kbts_glyph *Matra = &Glyphs[MatraIndex - 1]; if(Matra->SyllabicPosition == KBTS_SYLLABIC_POSITION_PREBASE_MATRA) { kbts_glyph MatraToReorder = *Matra; KBTS_FOR(GlyphIndex, MatraIndex, ToIndex + 1) { Glyphs[GlyphIndex - 1] = Glyphs[GlyphIndex]; } Glyphs[ToIndex] = MatraToReorder; ToIndex -= 1; } } } } // Reorder reph. // We should only reorder reph when it is a single Repha glyph, and not a Ra sequence. if((Glyphs[0].SyllabicPosition == KBTS_SYLLABIC_POSITION_RA_TO_BECOME_REPH) && (Glyphs[1].SyllabicPosition != KBTS_SYLLABIC_POSITION_RA_TO_BECOME_REPH)) { kbts_reph_position RephPosition = Config->IndicScriptProperties.RephPosition; kbts_un ToIndex = 0; KBTS_FOR(GlyphIndex, 0, BaseIndex) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; if(Glyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT) { ToIndex = GlyphIndex; if((GlyphIndex + 1) < BaseIndex) { kbts_u8 NextClass = Glyphs[GlyphIndex + 1].SyllabicClass; if((NextClass == KBTS_INDIC_SYLLABIC_CLASS_ZWJ) || (NextClass == KBTS_INDIC_SYLLABIC_CLASS_ZWNJ)) { ToIndex = GlyphIndex + 1; } } break; } } if(!ToIndex) { if(RephPosition == KBTS_REPH_POSITION_AFTER_SUBJOINED) { KBTS_FOR(GlyphIndex, BaseIndex, GlyphCount) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; kbts_u8 SyllabicPosition = Glyph->SyllabicPosition; if(KBTS_IN_SET(SyllabicPosition, KBTS_SET32((KBTS_SYLLABIC_POSITION_POSTBASE_CONSONANT)(KBTS_SYLLABIC_POSITION_AFTER_POST)(KBTS_SYLLABIC_POSITION_SMVD)))) { ToIndex = GlyphIndex - 1; break; } } } else if(RephPosition == KBTS_REPH_POSITION_AFTER_MAIN) { KBTS_FOR(GlyphIndex, BaseIndex, GlyphCount) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; if(Glyph->SyllabicPosition > KBTS_SYLLABIC_POSITION_AFTER_MAIN) { ToIndex = GlyphIndex - 1; break; } } } } if(!ToIndex) { // As a fallback, move reph to the end of the syllable. for(kbts_un GlyphIndex = GlyphCount; GlyphIndex; --GlyphIndex) { kbts_glyph *Glyph = &Glyphs[GlyphIndex - 1]; if(Glyph->SyllabicPosition != KBTS_SYLLABIC_POSITION_SMVD) { ToIndex = GlyphIndex - 1; break; } } // Matras will still come after reph. kbts_glyph *Glyph = &Glyphs[ToIndex]; if(Glyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT) { KBTS_FOR(MatraIndex, BaseIndex + 1, ToIndex) { kbts_glyph *Matra = &Glyphs[MatraIndex]; kbts_u8 Class = Matra->SyllabicClass; if(KBTS_IN_SET(Class, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_MATRA)(KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST)(KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL)))) { ToIndex -= 1; } } } } if(ToIndex) { // Do the reorder! kbts_glyph Reph = Glyphs[0]; KBTS_FOR(GlyphIndex, 0, ToIndex) { Glyphs[GlyphIndex] = Glyphs[GlyphIndex + 1]; } Glyphs[ToIndex] = Reph; if(BaseIndex && (BaseIndex <= ToIndex)) { BaseIndex -= 1; } } } // Reorder pre-base-reordering consonants. if(Pref) { kbts_un PrefIndex = 0; KBTS_FOR(GlyphIndex, BaseIndex + 1, GlyphCount) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; if(Glyph->Flags & KBTS_GLYPH_FLAG_PREF) { PrefIndex = GlyphIndex; break; } } if(PrefIndex) { kbts_glyph PrefGlyph = Glyphs[PrefIndex]; // Harfbuzz says the ideal is to check that this glyph was generated by the pref feature specifically, // but then just uses a generic flag like this. // The ideal solution would not be very difficult to implement! if(PrefGlyph.Flags & KBTS_GLYPH_FLAG_GENERATED_BY_GSUB) { kbts_un ToIndex = 0; for(kbts_un GlyphIndex = BaseIndex; GlyphIndex; --GlyphIndex) { kbts_u8 Class = Glyphs[GlyphIndex - 1].SyllabicClass; if(KBTS_IN_SET(Class, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_MATRA)(KBTS_INDIC_SYLLABIC_CLASS_MATRA_POST)(KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_MEDIAL)(KBTS_INDIC_SYLLABIC_CLASS_HALANT)))) { ToIndex = GlyphIndex; break; } } if(ToIndex && (ToIndex < GlyphCount)) { kbts_glyph *Prev = &Glyphs[ToIndex - 1]; kbts_u8 CurrentClass = Glyphs[ToIndex].SyllabicClass; if((Prev->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT) && KBTS_IN_SET(CurrentClass, KBTS_SET32((KBTS_INDIC_SYLLABIC_CLASS_ZWJ)(KBTS_INDIC_SYLLABIC_CLASS_ZWNJ)))) { ToIndex += 1; } } // Do the reorder! for(kbts_un GlyphIndex = PrefIndex; GlyphIndex > ToIndex; --GlyphIndex) { Glyphs[GlyphIndex] = Glyphs[GlyphIndex - 1]; } Glyphs[ToIndex] = PrefGlyph; // @Cleanup: This is probably always true? if((BaseIndex >= ToIndex) && (BaseIndex < PrefIndex)) { BaseIndex += 1; } } } } { // Mark matras at the beginning of a word for init application. // It is tempting to check for this at the same time as the reph reordering, but glyphs could have been // reordered since then and the reordering procedure is clearly defined to happen in sequential steps. kbts_glyph *First = &Glyphs[0]; if((First->SyllabicPosition == KBTS_SYLLABIC_POSITION_PREBASE_MATRA) && ShapeState->ClusterAtStartOfWord) { First->Flags |= KBTS_GLYPH_FLAG_INIT; } } } break; case KBTS_SHAPER_USE: { kbts_u64 PostBaseSet = KBTS_SET64((KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_ABOVE)(KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_BELOW) (KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_ABOVE)(KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_BELOW) (KBTS_USE_SYLLABIC_CLASS_CONS_FINAL_MOD_POST)(KBTS_USE_SYLLABIC_CLASS_CONS_MED_ABOVE) (KBTS_USE_SYLLABIC_CLASS_CONS_MED_BELOW)(KBTS_USE_SYLLABIC_CLASS_CONS_MED_POST) (KBTS_USE_SYLLABIC_CLASS_CONS_MED_PRE)(KBTS_USE_SYLLABIC_CLASS_VOWEL_ABOVE) (KBTS_USE_SYLLABIC_CLASS_VOWEL_BELOW)(KBTS_USE_SYLLABIC_CLASS_VOWEL_POST) (KBTS_USE_SYLLABIC_CLASS_VOWEL_PRE)(KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_ABOVE) (KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_BELOW)(KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_POST) (KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_PRE)); kbts_u64 HalantSet = KBTS_SET64((KBTS_USE_SYLLABIC_CLASS_HALANT)(KBTS_USE_SYLLABIC_CLASS_HALANT_OR_VOWEL_MODIFIER)(KBTS_USE_SYLLABIC_CLASS_INVISIBLE_STACKER)); // In the reorderings below, we check for halants because that's what Harfbuzz does. // Nowhere does Microsoft mention that halants should block reorderings! kbts_glyph Repha = Glyphs[0]; if((Repha.UseClass == KBTS_USE_SYLLABIC_CLASS_REPHA) || (Repha.Flags & KBTS_GLYPH_FLAG_RPHF)) { kbts_un GlyphIndex = 1; for(; GlyphIndex < GlyphCount; ++GlyphIndex) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; // Microsoft says that rephas are reordered "after a following full base", which is needlessly vague. // Harfbuzz reorders them in front of the first post-base glyph. if(KBTS_IN_SET64(Glyph->UseClass, PostBaseSet) || (!(Glyph->Flags & KBTS_GLYPH_FLAG_LIGATURE) && KBTS_IN_SET64(Glyph->UseClass, HalantSet))) { break; } Glyphs[GlyphIndex - 1] = *Glyph; } Glyphs[GlyphIndex - 1] = Repha; } { // Microsoft says that pre-base vowels and vowel modifiers should be reordered "before the base glyph // and, if present, before a pre-base glyph reordered via the 'pref' feature". // In practice, we tag 'pref'-generated glyphs with the VOWEL_PRE class so that they get reordered here. // Note that the final reordered glyphs end up backwards from their original order. kbts_glyph PreBaseVowels[16]; // @Robustness: How many vowels can there realistically be in a single cluster? kbts_un PreBaseVowelCount = 0; kbts_u64 SawBase = 0; for(kbts_un GlyphIndex = GlyphCount; GlyphIndex; --GlyphIndex) { kbts_glyph *Glyph = &Glyphs[GlyphIndex - 1]; SawBase |= KBTS_IN_SET64(Glyph->UseClass, KBTS_SET64((KBTS_USE_SYLLABIC_CLASS_BASE)(KBTS_USE_SYLLABIC_CLASS_BASE_OTHER)(KBTS_USE_SYLLABIC_CLASS_BASE_NUM))); kbts_u32 Flags = Glyph->Flags; // Only accept the first glyphs produced by multiple substitutions. if(((Flags & KBTS_GLYPH_FLAG_FIRST_IN_MULTIPLE_SUBSTITUTION) || !(Flags & KBTS_GLYPH_FLAG_MULTIPLE_SUBSTITUTION)) && (KBTS_IN_SET64(Glyph->UseClass, KBTS_SET64((KBTS_USE_SYLLABIC_CLASS_VOWEL_PRE)(KBTS_USE_SYLLABIC_CLASS_VOWEL_MOD_PRE))) || (Flags & KBTS_GLYPH_FLAG_PREF))) { if(PreBaseVowelCount < KBTS_ARRAY_LENGTH(PreBaseVowels)) { PreBaseVowels[PreBaseVowelCount++] = *Glyph; } } else if(!(Glyph->Flags & KBTS_GLYPH_FLAG_LIGATURE) && KBTS_IN_SET64(Glyph->UseClass, HalantSet)) { // Reordering stops at halants, apparently. // We want to write the vowels in the reverse order they appear in the glyph sequence. // Since we are iterating backwards, they already _are_ backwards in the PreBaseVowels array, // so there's no need to do anything. KBTS_FOR(PreBaseVowelIndex, 0, PreBaseVowelCount) { Glyphs[GlyphIndex + PreBaseVowelIndex] = PreBaseVowels[PreBaseVowelIndex]; } PreBaseVowelCount = 0; // Valid bases only show up before halants. SawBase = 0; } else { Glyphs[GlyphIndex - 1 + PreBaseVowelCount] = *Glyph; } } // Flush the rest of the vowels. KBTS_FOR(PreBaseVowelIndex, 0, PreBaseVowelCount) { Glyphs[PreBaseVowelIndex] = PreBaseVowels[PreBaseVowelIndex]; } // We are supposed to insert a dotted circle after repha when a base is missing. // The issue is that we have no idea whether the first glyph is a repha or not before we apply // RPHF. // So, this is really sucky, but I haven't found a way to merge this logic into any already- // existing loop, so we have to eat the extra traversal for now. if(ShapeState->RealCluster && !SawBase) { Result.InsertDottedCircle = 1; Result.DottedCircleIndex = PreBaseVowelCount; } } } break; case KBTS_SHAPER_MYANMAR: if(ShapeState->RealCluster) { kbts_un OnePastRephIndex = 0; kbts_un BaseIndex = GlyphCount; if(GlyphCount >= 3) { kbts_glyph *First = &Glyphs[0]; kbts_glyph *Second = &Glyphs[1]; kbts_glyph *Third = &Glyphs[2]; if((First->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_RA) && (Second->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_ASAT) && (Third->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_HALANT)) { First->SyllabicPosition = KBTS_SYLLABIC_POSITION_AFTER_MAIN; Second->SyllabicPosition = KBTS_SYLLABIC_POSITION_AFTER_MAIN; Third->SyllabicPosition = KBTS_SYLLABIC_POSITION_AFTER_MAIN; OnePastRephIndex = 3; BaseIndex = 0; } } kbts_u64 BaseSet = KBTS_SET64((KBTS_INDIC_SYLLABIC_CLASS_CONSONANT) (KBTS_INDIC_SYLLABIC_CLASS_CONSONANT_WITH_STACKER) (KBTS_INDIC_SYLLABIC_CLASS_RA) (KBTS_INDIC_SYLLABIC_CLASS_VOWEL) (KBTS_INDIC_SYLLABIC_CLASS_PLACEHOLDER) (KBTS_INDIC_SYLLABIC_CLASS_DOTTED_CIRCLE)); KBTS_FOR(GlyphIndex, OnePastRephIndex, GlyphCount) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; kbts_indic_syllabic_class Class = Glyph->SyllabicClass; if((BaseIndex == GlyphCount) && KBTS_IN_SET64(Class, BaseSet)) { BaseIndex = GlyphIndex; break; } } if((BaseIndex == GlyphCount) && OnePastRephIndex) { BaseIndex = 0; } kbts_syllabic_position LastPosition = KBTS_SYLLABIC_POSITION_SYLLABLE_BASE; kbts_syllabic_position SectionPosition = KBTS_SYLLABIC_POSITION_AFTER_MAIN; kbts_un LastPreBaseMatraIndex = GlyphCount; KBTS_FOR(GlyphIndex, BaseIndex + 1, GlyphCount) { kbts_glyph *Glyph = &Glyphs[GlyphIndex]; kbts_syllabic_position Position = SectionPosition; switch(Glyph->SyllabicClass) { case KBTS_INDIC_SYLLABIC_CLASS_MEDIAL_RA: Position = KBTS_SYLLABIC_POSITION_PREBASE_CONSONANT; break; case KBTS_INDIC_SYLLABIC_CLASS_VOWEL_PRE: { Position = KBTS_SYLLABIC_POSITION_PREBASE_MATRA; // According to Unicode 15.0: // For combining characters placed to the left of a base character, the combining characters start from the base // character and are arranged leftward. // Since these guys will get reordered into being pre-base, we need to flip them. if(GlyphIndex > LastPreBaseMatraIndex) { kbts_un FlipCount = GlyphIndex - LastPreBaseMatraIndex + 1; KBTS_FOR(FlipIndex, 0, FlipCount / 2) { kbts_un LeftIndex = LastPreBaseMatraIndex + FlipIndex; kbts_un RightIndex = LastPreBaseMatraIndex + FlipCount - 1 - FlipIndex; kbts_glyph Swap = Glyphs[LeftIndex]; Glyphs[LeftIndex] = Glyphs[RightIndex]; Glyphs[RightIndex] = Swap; } // Readjust Glyph to compensate for the flip. Glyph = &Glyphs[LastPreBaseMatraIndex]; } LastPreBaseMatraIndex = GlyphIndex; } break; case KBTS_INDIC_SYLLABIC_CLASS_VARIATION_SELECTOR: Position = LastPosition; break; case KBTS_INDIC_SYLLABIC_CLASS_VOWEL_BELOW: if(Position == KBTS_SYLLABIC_POSITION_AFTER_MAIN) { Position = KBTS_SYLLABIC_POSITION_BELOWBASE_CONSONANT; } else if(Position == KBTS_SYLLABIC_POSITION_BELOWBASE_CONSONANT) { Position = SectionPosition; } break; case KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN: if(Position == KBTS_SYLLABIC_POSITION_BELOWBASE_CONSONANT) { Position = KBTS_SYLLABIC_POSITION_BEFORE_SUBJOINED; } break; } if((SectionPosition == KBTS_SYLLABIC_POSITION_BELOWBASE_CONSONANT) && (Glyph->SyllabicClass == KBTS_INDIC_SYLLABIC_CLASS_VEDIC_SIGN)) { SectionPosition = KBTS_SYLLABIC_POSITION_AFTER_SUBJOINED; Position = SectionPosition; } Glyph->SyllabicPosition = Position; LastPosition = Position; } KBTS_FOR(Iter, 1, GlyphCount) { KBTS_FOR(GlyphIndex, 1, GlyphCount) { kbts_glyph *A = &Glyphs[GlyphIndex - 1]; kbts_glyph *B = &Glyphs[GlyphIndex]; if(A->SyllabicPosition > B->SyllabicPosition) { kbts_glyph Swap = *A; *A = *B; *B = Swap; } } } } break; } return Result; } static kbts_op_list kbts_OpList(kbts_u8 *Ops, kbts_un Size) { kbts_op_list Result = KBTS_ZERO; Result.Ops = Ops; Result.Length = Size; return Result; } #define KBTS_OP_LIST(OpList) kbts_OpList((kbts_Ops_##OpList), KBTS_ARRAY_LENGTH(kbts_Ops_##OpList)) KBTS_EXPORT kbts_shape_config kbts_ShapeConfig(kbts_font *Font, kbts_script Script, kbts_language Language) { kbts_shape_config Result = KBTS_ZERO; Result.Font = Font; Result.Script = Script; Result.Language = Language; kbts_gsub_gpos *Gsub = Font->ShapingTables[KBTS_SHAPING_TABLE_GSUB]; // Find the appropriate language system in GSUB/GPOS. kbts_script_properties *ScriptProperties = &kbts_ScriptProperties[Script]; int FoundScriptIsIndic3 = 0; KBTS_FOR(ShapingTableIndex, 0, KBTS_SHAPING_TABLE_COUNT) { kbts_gsub_gpos *ShapingTable = Font->ShapingTables[ShapingTableIndex]; if(ShapingTable) { kbts_script_list *ScriptList = KBTS_POINTER_OFFSET(kbts_script_list, ShapingTable, ShapingTable->ScriptListOffset); kbts_langsys *ChosenLangsys = 0; kbts_u32 DesiredTag = ScriptProperties->Tag; KBTS_FOR(ScriptIndex, 0, ScriptList->Count) { kbts_script_pointer ThisScript = kbts_GetScript(ScriptList, ScriptIndex); kbts_u32 Tag = ThisScript.Tag; // The OpenType spec does not define or even mention "Indic3" scripts at all. // Nevertheless, Harfbuzz at least checks for '3' at the end of script tags, and, if one exists, they choose USE. int Indic3 = (ThisScript.Tag >> 24) == '3'; kbts_u32 MatchMask = Indic3 ? 0xFFFFFF : 0xFFFFFFFF; int PerfectMatch = !((Tag ^ DesiredTag) & MatchMask); if(!ScriptIndex || PerfectMatch || (Tag == KBTS_FOURCC('D', 'F', 'L', 'T'))) { kbts_langsys *Langsys = kbts_GetDefaultLangsys(ThisScript.Script); KBTS_FOR(LangsysIndex, 0, ThisScript.Script->Count) { kbts_langsys_pointer LangsysPointer = kbts_GetLangsys(ThisScript.Script, LangsysIndex); if(LangsysPointer.Tag == Language) { Langsys = LangsysPointer.Langsys; break; } } // It is tempting to try to look for another script if the one we want has no langsys. // However, it is possible for a script to purposefully have no langsys at all. In that case, // the shaper should not apply any GSUB features. // In that case, the shaper should not apply any GSUB features. // So, store the result _regardless_ of whether Langsys is null or not. ChosenLangsys = Langsys; if(ShapingTableIndex == KBTS_SHAPING_TABLE_GSUB) { // Apparently, it is allowed to have script-specific GSUB tables, and a huge DFLT GPOS table. FoundScriptIsIndic3 = Indic3; } // And then get out if we found the appropriate script, even if the langsys is null! if(PerfectMatch) { break; } } } Result.Langsys[ShapingTableIndex] = ChosenLangsys; } } Result.IndicScriptProperties = kbts_IndicScriptProperties(Script); Result.Shaper = FoundScriptIsIndic3 ? KBTS_SHAPER_USE : ScriptProperties->Shaper; Result.OpLists[0] = kbts_ShaperOpLists[Result.Shaper]; switch(Result.Shaper) { case KBTS_SHAPER_INDIC: Result.OpLists[1] = KBTS_OP_LIST(Indic1); Result.OpLists[2] = KBTS_OP_LIST(Indic2); Result.OpLists[3] = KBTS_OP_LIST(Indic3); break; case KBTS_SHAPER_USE: Result.OpLists[1] = KBTS_OP_LIST(Use1); Result.OpLists[3] = KBTS_OP_LIST(Use3); break; case KBTS_SHAPER_KHMER: Result.OpLists[1] = KBTS_OP_LIST(Khmer1); Result.OpLists[3] = KBTS_OP_LIST(Khmer3); break; case KBTS_SHAPER_MYANMAR: Result.OpLists[1] = KBTS_OP_LIST(Myanmar1); Result.OpLists[2] = KBTS_OP_LIST(Myanmar2); Result.OpLists[3] = KBTS_OP_LIST(Myanmar3); break; } Result.Features = &kbts_ShaperFeatures[Result.Shaper]; kbts_feature *Rclt = 0; kbts_feature_set SyllableFeatureSet = {{KBTS_FEATURE_FLAG0(rphf) | KBTS_FEATURE_FLAG0(blwf) | KBTS_FEATURE_FLAG0(half) | KBTS_FEATURE_FLAG0(pstf) | KBTS_FEATURE_FLAG0(pref), 0, KBTS_FEATURE_FLAG2(rclt) | KBTS_FEATURE_FLAG2(locl), KBTS_FEATURE_FLAG3(vatu)}}; kbts_iterate_features IterateFeatures = kbts_IterateFeatures(&Result, KBTS_SHAPING_TABLE_GSUB, SyllableFeatureSet); while(kbts_NextFeature(&IterateFeatures)) { switch(IterateFeatures.CurrentFeatureTag) { case KBTS_FEATURE_TAG_blwf: Result.Blwf = IterateFeatures.Feature; break; case KBTS_FEATURE_TAG_pref: Result.Pref = IterateFeatures.Feature; break; case KBTS_FEATURE_TAG_pstf: Result.Pstf = IterateFeatures.Feature; break; case KBTS_FEATURE_TAG_locl: Result.Locl = IterateFeatures.Feature; break; case KBTS_FEATURE_TAG_rphf: Result.Rphf = IterateFeatures.Feature; break; case KBTS_FEATURE_TAG_half: Result.Half = IterateFeatures.Feature; break; case KBTS_FEATURE_TAG_vatu: Result.Vatu = IterateFeatures.Feature; break; case KBTS_FEATURE_TAG_rclt: Rclt = IterateFeatures.Feature; break; } } if((Result.Shaper == KBTS_SHAPER_ARABIC) && !Rclt) { Result.OpLists[0] = KBTS_OP_LIST(ArabicNoRclt); } kbts_shape_state DummyState = KBTS_ZERO; DummyState.Config = &Result; if(Result.IndicScriptProperties.ViramaCodepoint) { // Bake the locl-ized virama. kbts_glyph Virama = kbts_CodepointToGlyph(Font, Result.IndicScriptProperties.ViramaCodepoint); Result.Virama = kbts_Substitute1(&DummyState, kbts_GetLookupList(Gsub), Result.Locl, KBTS_SKIP_FLAG_ZWNJ | KBTS_SKIP_FLAG_ZWJ, &Virama); } if((Result.Script == KBTS_SCRIPT_THAI) || (Result.Script == KBTS_SCRIPT_LAO)) { kbts_u32 NikhahitCodepoint = (Result.Script == KBTS_SCRIPT_THAI) ? 0xE4D : 0xECD; kbts_u32 SaraAaCodepoint = (Result.Script == KBTS_SCRIPT_THAI) ? 0xE32 : 0xEB2; Result.Nikhahit = kbts_CodepointToGlyph(Font, NikhahitCodepoint); Result.SaraAa = kbts_CodepointToGlyph(Font, SaraAaCodepoint); } Result.DottedCircle = kbts_CodepointToGlyph(Font, 0x25CC); Result.Whitespace = kbts_CodepointToGlyph(Font, ' '); return Result; } static kbts_op kbts_ReadOp(kbts_shape_state *State, kbts_u8 *Ops) { kbts_op Result = KBTS_ZERO; Result.Kind = Ops[State->Ip++]; if(Result.Kind == KBTS_OP_KIND_GSUB_FEATURES_WITH_USER) { Result.Kind = KBTS_OP_KIND_GSUB_FEATURES; Result.Features = State->UserFeatures; } if((Result.Kind == KBTS_OP_KIND_GSUB_FEATURES) || (Result.Kind == KBTS_OP_KIND_GPOS_FEATURES)) { kbts_un FeatureCount = Ops[State->Ip++]; int Rtl = (State->RunDirection == KBTS_DIRECTION_RTL); KBTS_FOR(FeatureIndex, 0, FeatureCount) { kbts_u32 FeatureId = Ops[State->Ip++]; if((FeatureId == KBTS_FEATURE_ID_ltra) && Rtl) { FeatureId = KBTS_FEATURE_ID_rtla; } else if((FeatureId == KBTS_FEATURE_ID_ltrm) && Rtl) { FeatureId = KBTS_FEATURE_ID_rtlm; } kbts_AddFeature(&Result.Features, FeatureId); } } return Result; } KBTS_EXPORT int kbts_Shape(kbts_shape_state *State, kbts_shape_config *Config, kbts_direction MainDirection, kbts_direction RunDirection, kbts_glyph *Glyphs, kbts_u32 *GlyphCount, kbts_u32 GlyphCapacity) { KBTS_INSTRUMENT_FUNCTION_BEGIN State->Config = Config; State->MainDirection = MainDirection; State->RunDirection = RunDirection; kbts_glyph_array *GlyphArray = &State->GlyphArray; // The Glyphs array might move after a grow, so update the pointers here. // We preserve Count information, though, because it makes it simpler not to touch anything // when we are dealing with sub-arrays like Cluster. GlyphArray->Glyphs = Glyphs; GlyphArray->Capacity = GlyphCapacity; kbts_glyph_array *Cluster = &State->ClusterGlyphArray; Cluster->Glyphs = Glyphs + State->At; Cluster->Capacity = GlyphCapacity - State->At; kbts_u32 ResumePoint = State->ResumePoint; State->ResumePoint = 0; switch(ResumePoint) { case 1: goto ResumePoint1; break; case 2: goto ResumePoint2; break; case 3: goto ResumePoint3; break; case 4: goto ResumePoint4; break; case 5: goto ResumePoint5; break; case 6: goto ResumePoint6; break; } *GlyphArray = kbts_GlyphArray(Glyphs, *GlyphCount, *GlyphCount, GlyphCapacity); // For simple shapers, all of the shaping happens in this single loop. // For complex shapers, this loop is preparing the text for clustering logic, which happens below. for(State->Ip = 0; State->Ip < Config->OpLists[0].Length;) { State->Op = kbts_ReadOp(State, Config->OpLists[0].Ops); ResumePoint1:; if(kbts_ExecuteOp(State, GlyphArray)) { State->ResumePoint = 1; goto GrowRequest; } } if(KBTS_IN_SET(Config->Shaper, KBTS_SET32((KBTS_SHAPER_INDIC)(KBTS_SHAPER_USE)(KBTS_SHAPER_KHMER)(KBTS_SHAPER_MYANMAR)))) { State->ClusterAtStartOfWord = 1; State->At = 0; while(State->At < GlyphArray->Count) { if(KBTS_IN_SET(Config->Shaper, KBTS_SET32((KBTS_SHAPER_INDIC)(KBTS_SHAPER_KHMER)))) { // Reserve a slot in case we need to insert a dotted circle into a broken syllable. ResumePoint2:; if(!kbts_GrowGlyphArray(&State->ResumePoint, GlyphArray, GlyphArray->Count, 1, 2, 1)) { goto GrowRequest; } } { kbts_begin_cluster_result BeginClusterResult = kbts_BeginCluster(State, Glyphs + State->At, GlyphArray->Count - State->At); GlyphArray->Count += BeginClusterResult.InsertedGlyphCount; GlyphArray->TotalCount += BeginClusterResult.InsertedGlyphCount; State->ClusterGlyphCount = (kbts_u32)BeginClusterResult.ClusterGlyphCount; *Cluster = kbts_GlyphArray(Glyphs + State->At, BeginClusterResult.ClusterGlyphCount, GlyphArray->Count - State->At, GlyphCapacity - State->At); } kbts_glyph *LastGlyphInCluster; LastGlyphInCluster = &Glyphs[State->At + Cluster->Count - 1]; State->WordBreak = !(LastGlyphInCluster->UnicodeFlags & KBTS_UNICODE_FLAG_PART_OF_WORD); for(State->Ip = 0; State->Ip < Config->OpLists[1].Length;) { State->Op = kbts_ReadOp(State, Config->OpLists[1].Ops); ResumePoint3:; if(kbts_ExecuteOp(State, Cluster)) { State->ResumePoint = 3; goto GrowRequest; } } kbts_end_cluster_result EndClusterResult; EndClusterResult = kbts_EndCluster(State, Cluster); if(EndClusterResult.InsertDottedCircle) { State->DottedCircleInsertIndex = (kbts_u32)EndClusterResult.DottedCircleIndex; ResumePoint6:; if(!kbts_GrowGlyphArray(&State->ResumePoint, Cluster, State->DottedCircleInsertIndex, 1, 6, 0)) { State->RequiredGlyphCapacity = Cluster->RequiredCapacity + State->At; goto GrowRequest; } Glyphs[State->At + State->DottedCircleInsertIndex] = Config->DottedCircle; } for(State->Ip = 0; State->Ip < Config->OpLists[2].Length;) { State->Op = kbts_ReadOp(State, Config->OpLists[2].Ops); ResumePoint4:; if(kbts_ExecuteOp(State, Cluster)) { State->ResumePoint = 4; goto GrowRequest; } } State->At += Cluster->Count; kbts_un DeltaClusterGlyphCount = Cluster->Count - State->ClusterGlyphCount; GlyphArray->Count += DeltaClusterGlyphCount; GlyphArray->TotalCount += DeltaClusterGlyphCount; State->ClusterAtStartOfWord = State->WordBreak; } // Post-clustering ops work across clusters. // This is where Indic GPOS + post-passes happen. for(State->Ip = 0; State->Ip < Config->OpLists[3].Length;) { State->Op = kbts_ReadOp(State, Config->OpLists[3].Ops); ResumePoint5:; if(kbts_ExecuteOp(State, GlyphArray)) { State->ResumePoint = 5; goto GrowRequest; } } } if(0) { GrowRequest:; kbts_TransferGrowRequest(Cluster, GlyphArray); State->RequiredGlyphCapacity = GlyphArray->RequiredCapacity; KBTS_INSTRUMENT_END return 1; } *GlyphCount = GlyphArray->Count; KBTS_INSTRUMENT_END return 0; } KBTS_EXPORT kbts_cursor kbts_Cursor(kbts_direction Direction) { kbts_cursor Result = KBTS_ZERO; Result.Direction = Direction; return Result; } KBTS_EXPORT void kbts_PositionGlyph(kbts_cursor *Cursor, kbts_glyph *Glyph, kbts_s32 *X, kbts_s32 *Y) { kbts_s32 AdvanceX = Glyph->AdvanceX; kbts_s32 AdvanceY = Glyph->AdvanceY; kbts_s32 OffsetX = Glyph->OffsetX; kbts_s32 OffsetY = Glyph->OffsetY; if(Cursor->Direction != KBTS_DIRECTION_RTL) { *X = Cursor->X + OffsetX; *Y = Cursor->Y + OffsetY; Cursor->X += AdvanceX; Cursor->Y += AdvanceY; } else { // Right-to-left should, in theory, work almost identically to left-to-right: just right-align everything. // However, the convention for glyph bounding boxes, etc., is that they are left-aligned. // To compensate for this, we add base glyphs' advances to their positions, which should left-align them. // We can't accumulate the advances immediately into the cursor, though, because then mark offsets will be wrong. // // By the way, Harfbuzz just reverses glyphs to always be left-to-right for the sake of layout. // The reason we try to handle right-to-left somewhat properly here is that it allows the user to position one // glyph at a time by just going through the glyph sequence, no matter the text direction. // This should hopefully save the user from having to allocate a buffer of glyph positions and/or doing a pre-pass // just to get the total string width, in the case of cross-direction text. // // The classic Harfbuzz behavior can be obtained by passing MainDirection = LTR to Shape, even for RTL text. // (Cursor.Direction also needs to be NONE or LTR, of course, which is the default.) if(AdvanceX) { Cursor->X -= Cursor->LastAdvanceX; Cursor->LastAdvanceX = AdvanceX; } *X = Cursor->X - AdvanceX + OffsetX; *Y = Cursor->Y + OffsetY; Cursor->Y += AdvanceY; } } KBTS_EXPORT kbts_un kbts_ReadFontHeader(kbts_font *Font, void *Data, kbts_un Size) { KBTS_UNUSED(Size); kbts_un Result = 0; if(Size >= sizeof(kbts_table_directory)) { char *FileEnd = (char *)Data + Size; Font->FileBase = (char *)Data; Font->FileSize = Size; kbts_table_directory *Directory = (kbts_table_directory *)Font->FileBase; Directory->TableCount = kbts_ByteSwap16(Directory->TableCount); Directory->SearchRange = kbts_ByteSwap16(Directory->SearchRange); Directory->EntrySelector = kbts_ByteSwap16(Directory->EntrySelector); Directory->RangeShift = kbts_ByteSwap16(Directory->RangeShift); kbts_table_record *Tables = KBTS_POINTER_AFTER(kbts_table_record, Directory); kbts_un ShapingTableSizes[KBTS_SHAPING_TABLE_COUNT] = {0}; kbts_u32 GdefSize = 0; kbts_un DirectoryTableCapacity = (FileEnd - (char *)Tables) / sizeof(kbts_table_record); if(Directory->TableCount <= DirectoryTableCapacity) { for(kbts_un TableIndex = 0; TableIndex < Directory->TableCount; ++TableIndex) { kbts_table_record *Table = &Tables[TableIndex]; Table->Checksum = kbts_ByteSwap32(Table->Checksum); Table->Offset = kbts_ByteSwap32(Table->Offset); Table->Length = kbts_ByteSwap32(Table->Length); int TableValid = 0; void *TableBase = KBTS_POINTER_OFFSET(void, Font->FileBase, Table->Offset); char *TableEnd = (char *)TableBase + Table->Length; if(((char *)TableBase >= (char *)(Tables + Directory->TableCount)) && (TableEnd <= FileEnd)) { switch(Table->Tag) { case KBTS_FOURCC('h', 'e', 'a', 'd'): { if(Table->Length >= sizeof(kbts_head)) { kbts_head *Head = (kbts_head *)TableBase; kbts_ByteSwapArray16Unchecked(&Head->Major, 2); kbts_ByteSwapArray32Unchecked(&Head->Revision, 2); // We do not swap the magic number. kbts_ByteSwapArray16Unchecked(&Head->Flags, 2); // We do not swap file times. kbts_ByteSwapArray16Unchecked((kbts_u16 *)&Head->XMin, 9); Font->Head = Head; TableValid = 1; } } break; case KBTS_FOURCC('c', 'm', 'a', 'p'): { if(Table->Length >= sizeof(kbts_cmap)) { kbts_cmap *Cmap = (kbts_cmap *)TableBase; Cmap->Version = kbts_ByteSwap16(Cmap->Version); Cmap->TableCount = kbts_ByteSwap16(Cmap->TableCount); kbts_encoding_record *Records = KBTS_POINTER_AFTER(kbts_encoding_record, Cmap); if((char *)(Records + Cmap->TableCount) <= TableEnd) { KBTS_FOR(It, 0, Cmap->TableCount) { kbts_encoding_record *Record = &Records[It]; Record->EncodingId = kbts_ByteSwap16(Record->EncodingId); Record->PlatformId = kbts_ByteSwap16(Record->PlatformId); Record->SubtableOffset = kbts_ByteSwap32(Record->SubtableOffset); } kbts_cmap_subtable_pointer PreferredSubtable = KBTS_ZERO; kbts_u16 PreferredFormat = 1; KBTS_FOR(It, 0, Cmap->TableCount) { kbts_cmap_subtable_pointer Subtable = kbts_GetCmapSubtable(Cmap, It); if((char *)(Subtable.Subtable + 1) <= TableEnd) { kbts_u16 Format = kbts_ByteSwap16(*Subtable.Subtable); if(Format == 14) { if((char *)(Subtable.Subtable + sizeof(kbts_cmap_14)) <= TableEnd) { Font->Cmap14 = (kbts_cmap_14 *)Subtable.Subtable; } } else if(!PreferredSubtable.Subtable) { PreferredSubtable = Subtable; } else if(Format < KBTS_ARRAY_LENGTH(kbts_CmapFormatPrecedence)) { kbts_u16 Precedence = kbts_CmapFormatPrecedence[Format]; kbts_u16 PreferredPrecedence = kbts_CmapFormatPrecedence[PreferredFormat]; if((Precedence > PreferredPrecedence) || ((Precedence == PreferredPrecedence) && (Subtable.PlatformId == 3))) { PreferredSubtable = Subtable; PreferredFormat = Format; } } } } if(PreferredSubtable.Subtable) { *PreferredSubtable.Subtable = kbts_ByteSwap16(*PreferredSubtable.Subtable); switch(*PreferredSubtable.Subtable) { case 0: { kbts_cmap_0 *Cmap0 = (kbts_cmap_0 *)PreferredSubtable.Subtable; if((char *)(Cmap0 + 1) <= TableEnd) { Cmap0->Length = kbts_ByteSwap16(Cmap0->Length); Cmap0->Language = kbts_ByteSwap16(Cmap0->Language); TableValid = 1; } } break; case 2: { kbts_cmap_2 *Cmap2 = (kbts_cmap_2 *)PreferredSubtable.Subtable; if(kbts_ByteSwapArray16(&Cmap2->Length, 258, TableEnd)) { kbts_un SubHeaderCount = 0; KBTS_FOR(It, 0, 256) { kbts_un SubHeaderIndex = Cmap2->SubHeaderKeys[It]; SubHeaderCount = KBTS_MAX(SubHeaderCount, SubHeaderIndex + 1); } kbts_sub_header *SubHeaders = KBTS_POINTER_AFTER(kbts_sub_header, Cmap2); if(kbts_ByteSwapArray16(&SubHeaders->FirstCode, 4 * SubHeaderCount, TableEnd)) { kbts_u16 *GlyphIds = (kbts_u16 *)(SubHeaders + SubHeaderCount); kbts_sn GlyphIdCount = 0; KBTS_FOR(It, 0, SubHeaderCount) { kbts_sub_header *SubHeader = &SubHeaders[It]; kbts_u16 *OnePastLastGlyphId = &SubHeader->IdRangeOffset + SubHeader->IdRangeOffset / 2 + SubHeader->EntryCount; GlyphIdCount = KBTS_MAX(GlyphIdCount, OnePastLastGlyphId - GlyphIds); } if(kbts_ByteSwapArray16(GlyphIds, (kbts_un)GlyphIdCount, TableEnd)) { TableValid = 1; } } } } break; case 4: { kbts_cmap_4 *Cmap4 = (kbts_cmap_4 *)PreferredSubtable.Subtable; if(kbts_ByteSwapArray16(&Cmap4->Length, 5, TableEnd) && kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Cmap4), Cmap4->SegmentCountTimesTwo * 2 + 1, TableEnd)) { kbts_un SegmentCount = Cmap4->SegmentCountTimesTwo / 2; kbts_u16 *EndCodes = KBTS_POINTER_AFTER(kbts_u16, Cmap4); kbts_u16 *StartCodes = EndCodes + SegmentCount + 1; kbts_s16 *IdDeltas = (kbts_s16 *)(StartCodes + SegmentCount); kbts_u16 *IdRangeOffsets = (kbts_u16 *)(IdDeltas + SegmentCount); kbts_u16 *GlyphIds = IdRangeOffsets + SegmentCount; kbts_sn GlyphIdCount = 0; KBTS_FOR(SegmentIndex, 0, SegmentCount) { kbts_u16 Offset = IdRangeOffsets[SegmentIndex]; if(Offset) { kbts_u16 *IdLookup = &IdRangeOffsets[SegmentIndex] + (EndCodes[SegmentIndex] - StartCodes[SegmentIndex] + 1) + Offset / 2; GlyphIdCount = KBTS_MAX(GlyphIdCount, (IdLookup - GlyphIds)); } } if(kbts_ByteSwapArray16(GlyphIds, (kbts_un)GlyphIdCount, TableEnd)) { TableValid = 1; } } } break; case 6: { kbts_cmap_6 *Cmap6 = (kbts_cmap_6 *)PreferredSubtable.Subtable; if(kbts_ByteSwapArray16(&Cmap6->Length, 4, TableEnd) && kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Cmap6), Cmap6->EntryCount, TableEnd)) { TableValid = 1; } } break; case 12: { kbts_cmap_12_13 *Cmap12 = (kbts_cmap_12_13 *)PreferredSubtable.Subtable; if(kbts_ByteSwapArray32(&Cmap12->Length, 3, TableEnd) && kbts_ByteSwapArray32(KBTS_POINTER_AFTER(kbts_u32, Cmap12), Cmap12->GroupCount * 3, TableEnd)) { TableValid = 1; } } break; } Font->Cmap = PreferredSubtable.Subtable; } } } } break; case KBTS_FOURCC('G', 'D', 'E', 'F'): { kbts_gdef *Gdef = (kbts_gdef *)TableBase; GdefSize = Table->Length; if(kbts_ByteSwapArray16(&Gdef->Major, 6, TableEnd)) { if(Gdef->Minor >= 2) { if(Table->Length >= 14) { Gdef->MarkGlyphSetsDefinitionOffset = kbts_ByteSwap16(Gdef->MarkGlyphSetsDefinitionOffset); if(Gdef->Minor == 3) { if(Table->Length >= sizeof(kbts_gdef)) { // @Incomplete Gdef->ItemVariationStoreOffset = kbts_ByteSwap32(Gdef->ItemVariationStoreOffset); TableValid = 1; } } else { TableValid = 1; } } } else { TableValid = 1; } } Font->Gdef = Gdef; } break; case KBTS_FOURCC('G', 'S', 'U', 'B'): case KBTS_FOURCC('G', 'P', 'O', 'S'): { // We do not do any bounds checking here because Gsub/Gpos tables get byteswapped later on, // in ByteSwapGsubGposCommon. kbts_un Index = (Table->Tag == KBTS_FOURCC('G', 'S', 'U', 'B')) ? KBTS_SHAPING_TABLE_GSUB : KBTS_SHAPING_TABLE_GPOS; Font->ShapingTables[Index] = (kbts_gsub_gpos *)TableBase; ShapingTableSizes[Index] = Table->Length; TableValid = 1; } break; case KBTS_FOURCC('h', 'h', 'e', 'a'): case KBTS_FOURCC('v', 'h', 'e', 'a'): { kbts_un Orientation = Table->Tag == KBTS_FOURCC('h', 'h', 'e', 'a') ? KBTS_ORIENTATION_HORIZONTAL : KBTS_ORIENTATION_VERTICAL; kbts_hea *Hea = (kbts_hea *)TableBase; if(kbts_ByteSwapArray16((kbts_u16 *)Hea, sizeof(kbts_hea) / sizeof(kbts_u16), TableEnd)) { Font->Hea[Orientation] = Hea; TableValid = 1; } } break; case KBTS_FOURCC('h', 'm', 't', 'x'): case KBTS_FOURCC('v', 'm', 't', 'x'): { kbts_un Orientation = Table->Tag == KBTS_FOURCC('h', 'm', 't', 'x') ? KBTS_ORIENTATION_HORIZONTAL : KBTS_ORIENTATION_VERTICAL; kbts_u16 *Mtx = (kbts_u16 *)TableBase; kbts_ByteSwapArray16Unchecked(Mtx, Table->Length / sizeof(kbts_u16)); Font->Mtx[Orientation] = Mtx; TableValid = 1; } break; case KBTS_FOURCC('m', 'a', 'x', 'p'): { if(Table->Length >= 6) { Font->Maxp = (kbts_maxp *)TableBase; Font->Maxp->Major = kbts_ByteSwap16(Font->Maxp->Major); Font->Maxp->Minor = kbts_ByteSwap16(Font->Maxp->Minor); kbts_un U16Count = 0; if(!Font->Maxp->Major && (Font->Maxp->Minor == 0x5000)) { U16Count = 1; } else if((Font->Maxp->Major == 1) && !Font->Maxp->Minor) { U16Count = 14; } if(kbts_ByteSwapArray16(&Font->Maxp->GlyphCount, U16Count, TableEnd)) { Font->GlyphCount = Font->Maxp->GlyphCount; TableValid = 1; } } } break; default: { TableValid = 1; } break; } } if(!TableValid) { goto Error; } } } else { goto Error; } if(kbts_FontIsValid(Font)) { Result = sizeof(kbts_u32) * ((ShapingTableSizes[KBTS_SHAPING_TABLE_GSUB] + ShapingTableSizes[KBTS_SHAPING_TABLE_GPOS] + GdefSize) / 2); } } else { goto Error; } if(0) { Error:; Font->Error = 1; } return (kbts_u32)Result; } KBTS_EXPORT kbts_un kbts_ReadFontData(kbts_font *Font, void *Scratch, kbts_un ScratchSize) { kbts_un Result = 0; if(kbts_FontIsValid(Font)) { kbts_byteswap_context ByteSwapContext = KBTS_ZERO; ByteSwapContext.FileBase = Font->FileBase; ByteSwapContext.FileEnd = Font->FileBase + Font->FileSize; ByteSwapContext.PointerCapacity = ScratchSize / sizeof(kbts_u32); ByteSwapContext.Pointers = (kbts_u32 *)Scratch; kbts_un TotalLookupCount = 0; kbts_un TotalSubtableCount = 0; kbts_gdef *Gdef = Font->Gdef; if(Gdef) { if(Gdef->ClassDefinitionOffset) { kbts_u16 *ClassDefBase = KBTS_POINTER_OFFSET(kbts_u16, Gdef, Gdef->ClassDefinitionOffset); kbts_ByteSwapClassDefinition(&ByteSwapContext, ClassDefBase); } if(Gdef->MarkAttachmentClassDefinitionOffset) { kbts_u16 *ClassDefBase = KBTS_POINTER_OFFSET(kbts_u16, Gdef, Gdef->MarkAttachmentClassDefinitionOffset); kbts_ByteSwapClassDefinition(&ByteSwapContext, ClassDefBase); } if((Gdef->Minor >= 2) && Gdef->MarkGlyphSetsDefinitionOffset) { kbts_mark_glyph_sets *MarkGlyphSets = KBTS_POINTER_OFFSET(kbts_mark_glyph_sets, Gdef, Gdef->MarkGlyphSetsDefinitionOffset); kbts_ByteSwapArray16Context(&MarkGlyphSets->Format, 2, &ByteSwapContext); if(MarkGlyphSets->Format == 1) { kbts_u32 *CoverageOffsets = KBTS_POINTER_AFTER(kbts_u32, MarkGlyphSets); kbts_ByteSwapArray32Context(CoverageOffsets, MarkGlyphSets->MarkGlyphSetCount, &ByteSwapContext); KBTS_FOR(MarkGlyphSetIndex, 0, MarkGlyphSets->MarkGlyphSetCount) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, MarkGlyphSets, CoverageOffsets[MarkGlyphSetIndex]); kbts_ByteSwapCoverage(&ByteSwapContext, Coverage); } } } } kbts_gsub_gpos *Gsub = Font->ShapingTables[KBTS_SHAPING_TABLE_GSUB]; if(Gsub) { kbts_ByteSwapGsubGposCommon(&ByteSwapContext, Gsub); kbts_lookup_list *LookupList = kbts_GetLookupList(Gsub); LookupList->Count = kbts_ByteSwap16(LookupList->Count); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, LookupList), LookupList->Count, &ByteSwapContext); TotalLookupCount += LookupList->Count; KBTS_FOR(LookupIndex, 0, LookupList->Count) { kbts_lookup *PackedLookup = kbts_GetLookup(LookupList, LookupIndex); KBTS_DUMPF("GSUB Lookup %llu:\n", LookupIndex); if(kbts_ByteSwapLookup(&ByteSwapContext, PackedLookup)) { kbts_unpacked_lookup Lookup = kbts_UnpackLookup(Font->Gdef, PackedLookup); KBTS_DUMPF(" Flags %u\n", Lookup.Flags); KBTS_FOR(SubstitutionIndex, 0, Lookup.SubtableCount) { kbts_u16 *Base = KBTS_POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[SubstitutionIndex]); KBTS_DUMPF(" Subtable %llu:\n", SubstitutionIndex); kbts_ByteSwapGsubLookupSubtable(&ByteSwapContext, Lookup.Type, Base); } } TotalSubtableCount += PackedLookup->SubtableCount; } } kbts_gsub_gpos *Gpos = Font->ShapingTables[KBTS_SHAPING_TABLE_GPOS]; if(Gpos) { kbts_ByteSwapGsubGposCommon(&ByteSwapContext, Gpos); kbts_lookup_list *LookupList = kbts_GetLookupList(Gpos); LookupList->Count = kbts_ByteSwap16(LookupList->Count); kbts_ByteSwapArray16Context(KBTS_POINTER_AFTER(kbts_u16, LookupList), LookupList->Count, &ByteSwapContext); TotalLookupCount += LookupList->Count; KBTS_FOR(LookupIndex, 0, LookupList->Count) { kbts_lookup *PackedLookup = kbts_GetLookup(LookupList, LookupIndex); KBTS_DUMPF("GPOS Lookup %llu:\n", LookupIndex); if(kbts_ByteSwapLookup(&ByteSwapContext, PackedLookup)) { kbts_unpacked_lookup Lookup = kbts_UnpackLookup(Font->Gdef, PackedLookup); KBTS_DUMPF(" Flags %x\n", Lookup.Flags); KBTS_FOR(SubstitutionIndex, 0, Lookup.SubtableCount) { kbts_u16 *Base = KBTS_POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[SubstitutionIndex]); KBTS_DUMPF(" Subtable %llu:\n", (kbts_un)SubstitutionIndex); kbts_ByteSwapGposLookupSubtable(&ByteSwapContext, LookupList, Lookup.Type, Base); } } TotalSubtableCount += PackedLookup->SubtableCount; } } // At this point, we are done byteswapping the file, so we can start reusing the scratch memory. if(Gsub) { kbts_lookup_list *LookupList = kbts_GetLookupList(Gsub); // Figure out lookup recursion depth and other useful metrics. // Most of these are not used yet, but would be useful for a streaming shaper and/or to inform GLYPH_BUFFER_GROW_MARGIN. kbts_un MaximumBacktrackWithoutSkippingGlyphs = 0; kbts_un MaximumLookaheadWithoutSkippingGlyphs = 0; kbts_un MaximumLookupStackSize = 1; kbts_un MaximumSubstitutionOutputSize = 1; kbts_un MaximumInputSequenceLength = 1; // We are done byteswapping the file, so we can reclaim the scratch memory. kbts_lookup_info_frame *Frames = (kbts_lookup_info_frame *)Scratch; kbts_un FrameCapacity = ScratchSize / sizeof(kbts_lookup_info_frame); KBTS_FOR(RootLookupIndex, 0, LookupList->Count) { kbts_lookup *PackedRootLookup = kbts_GetLookup(LookupList, RootLookupIndex); kbts_unpacked_lookup RootLookup = kbts_UnpackLookup(Gdef, PackedRootLookup); KBTS_FOR(RootSubtableIndex, 0, RootLookup.SubtableCount) { kbts_un FrameCount = 0; { kbts_lookup_info_frame First = KBTS_ZERO; First.LookupType = RootLookup.Type; First.Base = KBTS_POINTER_OFFSET(kbts_u16, PackedRootLookup, RootLookup.SubtableOffsets[RootSubtableIndex]); First.StackSize = 1; if(FrameCount < FrameCapacity) { Frames[FrameCount++] = First; } else { Font->Error = 1; goto DoneGatheringLookupInfo; } } while(FrameCount) { kbts_lookup_info_frame Frame = Frames[--FrameCount]; kbts_u16 LookupType = Frame.LookupType; kbts_u16 *Base = Frame.Base; kbts_u32 LookaheadOffset = Frame.LookaheadOffset; kbts_u32 StackSize = Frame.StackSize; MaximumLookupStackSize = KBTS_MAX(MaximumLookupStackSize, StackSize); while(LookupType == 7) { kbts_extension *Subst = (kbts_extension *)Base; Base = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->Offset); LookupType = Subst->LookupType; } switch(LookupType) { case 2: { kbts_multiple_substitution *Subst = (kbts_multiple_substitution *)Base; KBTS_FOR(SequenceIndex, 0, Subst->SequenceCount) { kbts_sequence *Sequence = kbts_GetSequence(Subst, SequenceIndex); MaximumSubstitutionOutputSize = KBTS_MAX(MaximumSubstitutionOutputSize, Sequence->GlyphCount); } } break; case 4: { kbts_ligature_substitution *Subst = (kbts_ligature_substitution *)Base; KBTS_FOR(SetIndex, 0, Subst->LigatureSetCount) { kbts_ligature_set *Set = kbts_GetLigatureSet(Subst, SetIndex); KBTS_FOR(LigatureIndex, 0, Set->Count) { kbts_ligature *Ligature = kbts_GetLigature(Set, LigatureIndex); MaximumLookaheadWithoutSkippingGlyphs = KBTS_MAX(MaximumLookaheadWithoutSkippingGlyphs, LookaheadOffset + Ligature->ComponentCount - 1); } } } break; case 5: { if(Base[0] == 1) { kbts_sequence_context_1 *Subst = (kbts_sequence_context_1 *)Base; KBTS_FOR(SetIndex, 0, Subst->SeqRuleSetCount) { kbts_sequence_rule_set *Set = kbts_GetSequenceRuleSet(Subst, SetIndex); KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_sequence_rule *Rule = kbts_GetSequenceRule(Set, RuleIndex); MaximumLookaheadWithoutSkippingGlyphs = KBTS_MAX(MaximumLookaheadWithoutSkippingGlyphs, LookaheadOffset + Rule->GlyphCount - 1); MaximumInputSequenceLength = KBTS_MAX(MaximumInputSequenceLength, Rule->GlyphCount); kbts_u16 *InputSequence = KBTS_POINTER_AFTER(kbts_u16, Rule); kbts_sequence_lookup_record *Records = (kbts_sequence_lookup_record *)(InputSequence + Rule->GlyphCount - 1); KBTS_FOR(RecordIndex, 0, Rule->SequenceLookupCount) { kbts_sequence_lookup_record *Record = &Records[RecordIndex]; if(!kbts_PushLookup(Gdef, Frames, &FrameCount, FrameCapacity, kbts_GetLookup(LookupList, Record->LookupListIndex), LookaheadOffset + Record->SequenceIndex, StackSize + RecordIndex + 1)) { Font->Error = 1; goto DoneGatheringLookupInfo; } } } } } else if(Base[0] == 2) { kbts_sequence_context_2 *Subst = (kbts_sequence_context_2 *)Base; KBTS_FOR(SetIndex, 0, Subst->ClassSequenceRuleSetCount) { kbts_class_sequence_rule_set *Set = kbts_GetClassSequenceRuleSet(Subst, SetIndex); if(Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_class_sequence_rule *Rule = kbts_GetClassSequenceRule(Set, RuleIndex); MaximumLookaheadWithoutSkippingGlyphs = KBTS_MAX(MaximumLookaheadWithoutSkippingGlyphs, LookaheadOffset + Rule->GlyphCount - 1); MaximumInputSequenceLength = KBTS_MAX(MaximumInputSequenceLength, Rule->GlyphCount); kbts_u16 *InputSequence = KBTS_POINTER_AFTER(kbts_u16, Rule); kbts_sequence_lookup_record *Records = (kbts_sequence_lookup_record *)(InputSequence + Rule->GlyphCount - 1); KBTS_FOR(RecordIndex, 0, Rule->SequenceLookupCount) { kbts_sequence_lookup_record *Record = &Records[RecordIndex]; if(!kbts_PushLookup(Gdef, Frames, &FrameCount, FrameCapacity, kbts_GetLookup(LookupList, Record->LookupListIndex), LookaheadOffset + Record->SequenceIndex, StackSize + RecordIndex + 1)) { Font->Error = 1; goto DoneGatheringLookupInfo; } } } } } } else if(Base[0] == 3) { kbts_sequence_context_3 *Subst = (kbts_sequence_context_3 *)Base; MaximumLookaheadWithoutSkippingGlyphs = KBTS_MAX(MaximumLookaheadWithoutSkippingGlyphs, LookaheadOffset + Subst->GlyphCount - 1); MaximumInputSequenceLength = KBTS_MAX(MaximumInputSequenceLength, Subst->GlyphCount); kbts_u16 *CoverageOffsets = KBTS_POINTER_AFTER(kbts_u16, Subst); kbts_sequence_lookup_record *Records = (kbts_sequence_lookup_record *)(CoverageOffsets + Subst->GlyphCount); KBTS_FOR(RecordIndex, 0, Subst->SequenceLookupCount) { kbts_sequence_lookup_record *Record = &Records[RecordIndex]; if(!kbts_PushLookup(Gdef, Frames, &FrameCount, FrameCapacity, kbts_GetLookup(LookupList, Record->LookupListIndex), LookaheadOffset + Record->SequenceIndex, StackSize + RecordIndex + 1)) { Font->Error = 1; goto DoneGatheringLookupInfo; } } } } break; case 6: { if(Base[0] == 1) { kbts_chained_sequence_context_1 *Subst = (kbts_chained_sequence_context_1 *)Base; KBTS_FOR(SetIndex, 0, Subst->ChainedSequenceRuleSetCount) { kbts_chained_sequence_rule_set *Set = kbts_GetChainedSequenceRuleSet(Subst, SetIndex); if(Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_chained_sequence_rule *Rule = kbts_GetChainedSequenceRule(Set, RuleIndex); kbts_unpacked_chained_sequence_rule Unpacked = kbts_UnpackChainedSequenceRule(Rule, 0); MaximumBacktrackWithoutSkippingGlyphs = KBTS_MAX(MaximumBacktrackWithoutSkippingGlyphs, Unpacked.BacktrackCount); MaximumLookaheadWithoutSkippingGlyphs = KBTS_MAX(MaximumLookaheadWithoutSkippingGlyphs, LookaheadOffset + Unpacked.LookaheadCount); MaximumInputSequenceLength = KBTS_MAX(MaximumInputSequenceLength, Unpacked.InputCount); KBTS_FOR(RecordIndex, 0, Unpacked.RecordCount) { kbts_sequence_lookup_record *Record = &Unpacked.Records[RecordIndex]; if(!kbts_PushLookup(Gdef, Frames, &FrameCount, FrameCapacity, kbts_GetLookup(LookupList, Record->LookupListIndex), LookaheadOffset + Record->SequenceIndex, StackSize + RecordIndex + 1)) { Font->Error = 1; goto DoneGatheringLookupInfo; } } } } } } else if(Base[0] == 2) { kbts_chained_sequence_context_2 *Subst = (kbts_chained_sequence_context_2 *)Base; KBTS_FOR(SetIndex, 0, Subst->ChainedClassSequenceRuleSetCount) { // @Duplication with 6.1. kbts_chained_sequence_rule_set *Set = kbts_GetChainedClassSequenceRuleSet(Subst, SetIndex); if(Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_chained_sequence_rule *Rule = kbts_GetChainedSequenceRule(Set, RuleIndex); kbts_unpacked_chained_sequence_rule Unpacked = kbts_UnpackChainedSequenceRule(Rule, 0); MaximumBacktrackWithoutSkippingGlyphs = KBTS_MAX(MaximumBacktrackWithoutSkippingGlyphs, Unpacked.BacktrackCount); MaximumLookaheadWithoutSkippingGlyphs = KBTS_MAX(MaximumLookaheadWithoutSkippingGlyphs, LookaheadOffset + Unpacked.LookaheadCount); MaximumInputSequenceLength = KBTS_MAX(MaximumInputSequenceLength, Unpacked.InputCount); KBTS_FOR(RecordIndex, 0, Unpacked.RecordCount) { kbts_sequence_lookup_record *Record = &Unpacked.Records[RecordIndex]; if(!kbts_PushLookup(Gdef, Frames, &FrameCount, FrameCapacity, kbts_GetLookup(LookupList, Record->LookupListIndex), LookaheadOffset + Record->SequenceIndex, StackSize + RecordIndex + 1)) { Font->Error = 1; goto DoneGatheringLookupInfo; } } } } } } else if(Base[0] == 3) { kbts_chained_sequence_context_3 *Subst = (kbts_chained_sequence_context_3 *)Base; kbts_unpacked_chained_sequence_context_3 Unpacked = kbts_UnpackChainedSequenceContext3(Subst, 0); MaximumBacktrackWithoutSkippingGlyphs = KBTS_MAX(MaximumBacktrackWithoutSkippingGlyphs, Unpacked.BacktrackCount); MaximumLookaheadWithoutSkippingGlyphs = KBTS_MAX(MaximumLookaheadWithoutSkippingGlyphs, LookaheadOffset + Unpacked.LookaheadCount); MaximumInputSequenceLength = KBTS_MAX(MaximumInputSequenceLength, Unpacked.InputCount); KBTS_FOR(RecordIndex, 0, Unpacked.RecordCount) { kbts_sequence_lookup_record *Record = &Unpacked.Records[RecordIndex]; if(!kbts_PushLookup(Gdef, Frames, &FrameCount, FrameCapacity, kbts_GetLookup(LookupList, Record->LookupListIndex), LookaheadOffset + Record->SequenceIndex, StackSize + RecordIndex + 1)) { Font->Error = 1; goto DoneGatheringLookupInfo; } } } } break; case 8: { kbts_reverse_chain_substitution *Subst = (kbts_reverse_chain_substitution *)Base; kbts_unpacked_reverse_chain_substitution Unpacked = kbts_UnpackReverseChainSubstitution(Subst, 0); MaximumBacktrackWithoutSkippingGlyphs = KBTS_MAX(MaximumBacktrackWithoutSkippingGlyphs, Unpacked.BacktrackCount); MaximumLookaheadWithoutSkippingGlyphs = KBTS_MAX(MaximumLookaheadWithoutSkippingGlyphs, LookaheadOffset + Unpacked.LookaheadCount); } break; } } } } DoneGatheringLookupInfo:; Font->LookupInfo.MaximumBacktrackWithoutSkippingGlyphs = (kbts_u32)MaximumBacktrackWithoutSkippingGlyphs; Font->LookupInfo.MaximumLookaheadWithoutSkippingGlyphs = (kbts_u32)MaximumLookaheadWithoutSkippingGlyphs; Font->LookupInfo.MaximumSubstitutionOutputSize = (kbts_u32)MaximumSubstitutionOutputSize; Font->LookupInfo.MaximumInputSequenceLength = (kbts_u32)MaximumInputSequenceLength; Font->LookupInfo.MaximumLookupStackSize = (kbts_u32)MaximumLookupStackSize; } Font->LookupCount = (kbts_u32)TotalLookupCount; Font->SubtableCount = (kbts_u32)TotalSubtableCount; kbts_un GlyphLookupMatrixSizeInBytes = ((((TotalLookupCount * Font->GlyphCount) + 7) / 8) + 3) & ~3; kbts_un GlyphLookupSubtableMatrixSizeInBytes = ((((TotalSubtableCount * Font->GlyphCount) + 7) / 8) + 3) & ~3; Result = GlyphLookupMatrixSizeInBytes + GlyphLookupSubtableMatrixSizeInBytes + sizeof(kbts_u32) * TotalLookupCount + sizeof(kbts_lookup_subtable_info) * TotalSubtableCount; Font->Error |= ByteSwapContext.Error; } return Result; } KBTS_EXPORT int kbts_PostReadFontInitialize(kbts_font *Font, void *Memory, kbts_un MemorySize) { if(kbts_FontIsValid(Font) && Font->Maxp) { // Bake table filters. kbts_un GlyphCount = Font->GlyphCount; kbts_un GlyphLookupMatrixSizeInBits = Font->LookupCount * GlyphCount; kbts_un GlyphLookupMatrixSizeInBytes = (GlyphLookupMatrixSizeInBits + 7) / 8; GlyphLookupMatrixSizeInBytes = (GlyphLookupMatrixSizeInBytes + 3) & ~3; // Align to u32 kbts_un GlyphLookupSubtableMatrixSizeInBits = Font->SubtableCount * GlyphCount; kbts_un GlyphLookupSubtableMatrixSizeInBytes = (GlyphLookupSubtableMatrixSizeInBits + 7) / 8; GlyphLookupSubtableMatrixSizeInBytes = (GlyphLookupSubtableMatrixSizeInBytes + 3) & ~3; // Align to u32 KBTS_MEMSET(Memory, 0, MemorySize); kbts_u32 *GlyphLookupMatrix = (kbts_u32 *)Memory; kbts_u32 *GlyphLookupSubtableMatrix = KBTS_POINTER_OFFSET(kbts_u32, GlyphLookupMatrix, GlyphLookupMatrixSizeInBytes); kbts_u32 *LookupSubtableIndexOffsets = KBTS_POINTER_OFFSET(kbts_u32, GlyphLookupSubtableMatrix, GlyphLookupSubtableMatrixSizeInBytes); kbts_lookup_subtable_info *SubtableInfos = KBTS_POINTER_OFFSET(kbts_lookup_subtable_info, LookupSubtableIndexOffsets, sizeof(kbts_u32) * Font->LookupCount); kbts_un GposLookupIndexOffset = 0; kbts_un RunningLookupIndex = 0; kbts_un RunningSubtableIndex = 0; KBTS_FOR(ShapingTableIndex, 0, KBTS_SHAPING_TABLE_COUNT) { kbts_gsub_gpos *ShapingTable = Font->ShapingTables[ShapingTableIndex]; if(ShapingTableIndex == KBTS_SHAPING_TABLE_GPOS) { GposLookupIndexOffset = RunningLookupIndex; } if(ShapingTable) { kbts_lookup_list *LookupList = kbts_GetLookupList(ShapingTable); KBTS_FOR(LookupIndex, 0, LookupList->Count) { kbts_lookup *PackedLookup = kbts_GetLookup(LookupList, LookupIndex); kbts_unpacked_lookup Lookup = kbts_UnpackLookup(Font->Gdef, PackedLookup); LookupSubtableIndexOffsets[RunningLookupIndex] = (kbts_u32)RunningSubtableIndex; KBTS_FOR(SubtableIndex, 0, Lookup.SubtableCount) { kbts_lookup_subtable_info SubtableInfo = KBTS_ZERO; kbts_u32 LookupType = Lookup.Type; kbts_u16 *Base = KBTS_POINTER_OFFSET(kbts_u16, PackedLookup, Lookup.SubtableOffsets[SubtableIndex]); while(((ShapingTableIndex == KBTS_SHAPING_TABLE_GSUB) && (LookupType == 7)) || ((ShapingTableIndex == KBTS_SHAPING_TABLE_GPOS) && (LookupType == 9))) { kbts_extension *Extension = (kbts_extension *)Base; LookupType = Extension->LookupType; Base = KBTS_POINTER_OFFSET(kbts_u16, Extension, Extension->Offset); } KBTS_FOR(GlyphIndex, 0, GlyphCount) { kbts_glyph Glyph = KBTS_ZERO; Glyph.Id = (kbts_u16)GlyphIndex; Glyph.Classes = kbts_GlyphClasses(Font, Glyph.Id); // @Duplication kbts_cover_glyph_result Cover = KBTS_ZERO; Cover.Valid = kbts_GlyphPassesLookupFilter(&Glyph, &Lookup); if(Cover.Valid && kbts_LookupBeginsWithCoverage((kbts_shaping_table)ShapingTableIndex, Lookup.Type, Base[0])) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Base, Base[1]); Cover = kbts_CoverGlyph(Coverage, Glyph.Id); } // The "primary" slot here refers to the "current glyph" when matching. // It is the first glyph in the input sequence, not counting backtrack. // We use the primary slot for per-feature filtering. int InPrimary = Cover.Valid; // The secondary slot is anything else: input sequence, lookahead, backtrack, ligature components. // They are used for subtable filtering. int InSecondary = 0; if((ShapingTableIndex == KBTS_SHAPING_TABLE_GSUB) && (LookupType == 4)) { kbts_ligature_substitution *Subst = (kbts_ligature_substitution *)Base; KBTS_FOR(SetIndex, 0, Subst->LigatureSetCount) { kbts_ligature_set *Set = kbts_GetLigatureSet(Subst, SetIndex); KBTS_FOR(LigatureIndex, 0, Set->Count) { kbts_ligature *Ligature = kbts_GetLigature(Set, LigatureIndex); kbts_u16 *Ids = KBTS_POINTER_AFTER(kbts_u16, Ligature); SubtableInfo.MinimumFollowupPlusOne = KBTS_MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Ligature->ComponentCount - 1) + 1; KBTS_FOR(IdIndex, 1, Ligature->ComponentCount) { kbts_u16 LigatureGlyphId = Ids[IdIndex - 1]; if(LigatureGlyphId == Glyph.Id) { InSecondary = 1; goto DoneCheckingForInclusion; } } } } } else if(((ShapingTableIndex == KBTS_SHAPING_TABLE_GSUB) && (LookupType == 5)) || ((ShapingTableIndex == KBTS_SHAPING_TABLE_GPOS) && (LookupType == 7))) { if(Base[0] == 1) { kbts_sequence_context_1 *Subst = (kbts_sequence_context_1 *)Base; KBTS_FOR(SetIndex, 0, Subst->SeqRuleSetCount) { kbts_sequence_rule_set *Set = kbts_GetSequenceRuleSet(Subst, SetIndex); if(Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_sequence_rule *Rule = kbts_GetSequenceRule(Set, RuleIndex); SubtableInfo.MinimumFollowupPlusOne = KBTS_MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Rule->GlyphCount - 1) + 1; kbts_u16 *SequenceIds = KBTS_POINTER_AFTER(kbts_u16, Rule); KBTS_FOR(InputIndex, 1, Rule->GlyphCount) { kbts_u16 SequenceId = SequenceIds[InputIndex - 1]; if(SequenceId == Glyph.Id) { InSecondary = 1; goto DoneCheckingForInclusion; } } } } } } else if(Base[0] == 2) { kbts_sequence_context_2 *Subst = (kbts_sequence_context_2 *)Base; kbts_u16 *ClassDefBase = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->ClassDefOffset); kbts_glyph_class_from_table_result Class = kbts_GlyphClassFromTable(ClassDefBase, Glyph.Id); KBTS_FOR(SetIndex, 0, Subst->ClassSequenceRuleSetCount) { kbts_class_sequence_rule_set *Set = kbts_GetClassSequenceRuleSet(Subst, SetIndex); if(Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_class_sequence_rule *Rule = kbts_GetClassSequenceRule(Set, RuleIndex); kbts_u16 *SequenceClasses = KBTS_POINTER_AFTER(kbts_u16, Rule); SubtableInfo.MinimumFollowupPlusOne = KBTS_MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Rule->GlyphCount - 1) + 1; KBTS_FOR(SequenceIndex, 1, Rule->GlyphCount) { if(SequenceClasses[SequenceIndex - 1] == Class.Class) { InSecondary = 1; goto DoneCheckingForInclusion; } } } } } } else if(Base[0] == 3) { kbts_sequence_context_3 *Subst = (kbts_sequence_context_3 *)Base; kbts_u16 *CoverageOffsets = KBTS_POINTER_AFTER(kbts_u16, Subst); SubtableInfo.MinimumFollowupPlusOne = KBTS_MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Subst->GlyphCount - 1) + 1; InPrimary = 0; KBTS_FOR(CoverageIndex, 0, Subst->GlyphCount) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Subst, CoverageOffsets[CoverageIndex]); kbts_cover_glyph_result SequenceCover = kbts_CoverGlyph(Coverage, Glyph.Id); if(SequenceCover.Valid) { if(!CoverageIndex) { InPrimary = 1; } else { InSecondary = 1; } goto DoneCheckingForInclusion; } } } } else if(((ShapingTableIndex == KBTS_SHAPING_TABLE_GSUB) && (LookupType == 6)) || ((ShapingTableIndex == KBTS_SHAPING_TABLE_GPOS) && (LookupType == 8))) { if(Base[0] == 1) { kbts_chained_sequence_context_1 *Subst = (kbts_chained_sequence_context_1 *)Base; kbts_u16 *ChainedSequenceRuleSetOffsets = KBTS_POINTER_AFTER(kbts_u16, Subst); KBTS_FOR(SetIndex, 0, Subst->ChainedSequenceRuleSetCount) { kbts_chained_sequence_rule_set *Set = KBTS_POINTER_OFFSET(kbts_chained_sequence_rule_set, Subst, ChainedSequenceRuleSetOffsets[SetIndex]); KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_chained_sequence_rule *Rule = kbts_GetChainedClassSequenceRule(Set, RuleIndex); kbts_unpacked_chained_sequence_rule Unpacked = kbts_UnpackChainedSequenceRule(Rule, 0); SubtableInfo.MinimumBacktrackPlusOne = KBTS_MIN(SubtableInfo.MinimumBacktrackPlusOne - 1, Unpacked.BacktrackCount) + 1; SubtableInfo.MinimumFollowupPlusOne = KBTS_MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Unpacked.InputCount - 1 + Unpacked.LookaheadCount) + 1; KBTS_FOR(BacktrackIndex, 0, Unpacked.BacktrackCount) { if(Unpacked.Backtrack[BacktrackIndex] == Glyph.Id) { InSecondary = 1; goto DoneCheckingForInclusion; } } KBTS_FOR(InputIndex, 1, Unpacked.InputCount) { if(Unpacked.Input[InputIndex - 1] == Glyph.Id) { InSecondary = 1; goto DoneCheckingForInclusion; } } KBTS_FOR(LookaheadIndex, 0, Unpacked.LookaheadCount) { if(Unpacked.Lookahead[LookaheadIndex] == Glyph.Id) { InSecondary = 1; goto DoneCheckingForInclusion; } } } } } else if(Base[0] == 2) { kbts_chained_sequence_context_2 *Subst = (kbts_chained_sequence_context_2 *)Base; kbts_u16 *BacktrackClassDefinition = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->BacktrackClassDefOffset); kbts_u16 *InputClassDefinition = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->InputClassDefOffset); kbts_u16 *LookaheadClassDefinition = KBTS_POINTER_OFFSET(kbts_u16, Subst, Subst->LookaheadClassDefOffset); kbts_u16 BacktrackClass = kbts_GlyphClassFromTable(BacktrackClassDefinition, Glyph.Id).Class; kbts_u16 InputClass = kbts_GlyphClassFromTable(InputClassDefinition, Glyph.Id).Class; kbts_u16 LookaheadClass = kbts_GlyphClassFromTable(LookaheadClassDefinition, Glyph.Id).Class; KBTS_FOR(SetIndex, 0, Subst->ChainedClassSequenceRuleSetCount) { kbts_chained_sequence_rule_set *Set = kbts_GetChainedClassSequenceRuleSet(Subst, SetIndex); if(Set) { KBTS_FOR(RuleIndex, 0, Set->Count) { kbts_chained_sequence_rule *Rule = kbts_GetChainedSequenceRule(Set, RuleIndex); kbts_unpacked_chained_sequence_rule Unpacked = kbts_UnpackChainedSequenceRule(Rule, 0); SubtableInfo.MinimumBacktrackPlusOne = KBTS_MIN(SubtableInfo.MinimumBacktrackPlusOne - 1, Unpacked.BacktrackCount) + 1; SubtableInfo.MinimumFollowupPlusOne = KBTS_MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Unpacked.InputCount - 1 + Unpacked.LookaheadCount) + 1; KBTS_FOR(BacktrackIndex, 0, Unpacked.BacktrackCount) { if(Unpacked.Backtrack[BacktrackIndex] == BacktrackClass) { InSecondary = 1; goto DoneCheckingForInclusion; } } KBTS_FOR(InputIndex, 1, Unpacked.InputCount) { if(Unpacked.Input[InputIndex - 1] == InputClass) { InSecondary = 1; goto DoneCheckingForInclusion; } } KBTS_FOR(LookaheadIndex, 0, Unpacked.LookaheadCount) { if(Unpacked.Lookahead[LookaheadIndex] == LookaheadClass) { InSecondary = 1; goto DoneCheckingForInclusion; } } } } } } else if(Base[0] == 3) { kbts_chained_sequence_context_3 *Subst = (kbts_chained_sequence_context_3 *)Base; kbts_unpacked_chained_sequence_context_3 Unpacked = kbts_UnpackChainedSequenceContext3(Subst, 0); SubtableInfo.MinimumBacktrackPlusOne = KBTS_MIN(SubtableInfo.MinimumBacktrackPlusOne - 1, Unpacked.BacktrackCount) + 1; SubtableInfo.MinimumFollowupPlusOne = KBTS_MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Unpacked.InputCount - 1 + Unpacked.LookaheadCount) + 1; KBTS_FOR(BacktrackCoverageIndex, 0, Unpacked.BacktrackCount) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackCoverageIndex]); kbts_cover_glyph_result SequenceCover = kbts_CoverGlyph(Coverage, Glyph.Id); if(SequenceCover.Valid) { InSecondary = 1; goto DoneCheckingForInclusion; } } InPrimary = 0; KBTS_FOR(InputCoverageIndex, 0, Unpacked.InputCount) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.InputCoverageOffsets[InputCoverageIndex]); kbts_cover_glyph_result SequenceCover = kbts_CoverGlyph(Coverage, Glyph.Id); if(SequenceCover.Valid) { if(!InputCoverageIndex) { InPrimary = 1; } else { InSecondary = 1; } goto DoneCheckingForInclusion; } } KBTS_FOR(LookaheadCoverageIndex, 0, Unpacked.LookaheadCount) { kbts_coverage *Coverage = KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadCoverageIndex]); kbts_cover_glyph_result SequenceCover = kbts_CoverGlyph(Coverage, Glyph.Id); if(SequenceCover.Valid) { InSecondary = 1; goto DoneCheckingForInclusion; } } } } else if((ShapingTableIndex == KBTS_SHAPING_TABLE_GSUB) && (LookupType == 8)) { kbts_reverse_chain_substitution *Subst = (kbts_reverse_chain_substitution *)Base; kbts_unpacked_reverse_chain_substitution Unpacked = kbts_UnpackReverseChainSubstitution(Subst, 0); SubtableInfo.MinimumBacktrackPlusOne = KBTS_MIN(SubtableInfo.MinimumBacktrackPlusOne - 1, Unpacked.BacktrackCount) + 1; SubtableInfo.MinimumFollowupPlusOne = KBTS_MIN(SubtableInfo.MinimumFollowupPlusOne - 1, Unpacked.LookaheadCount) + 1; KBTS_FOR(BacktrackIndex, 0, Unpacked.BacktrackCount) { kbts_cover_glyph_result BacktrackCover = kbts_CoverGlyph(KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.BacktrackCoverageOffsets[BacktrackIndex]), Glyph.Id); if(BacktrackCover.Valid) { InSecondary = 1; goto DoneCheckingForInclusion; } } KBTS_FOR(LookaheadIndex, 0, Unpacked.LookaheadCount) { kbts_cover_glyph_result LookaheadCover = kbts_CoverGlyph(KBTS_POINTER_OFFSET(kbts_coverage, Subst, Unpacked.LookaheadCoverageOffsets[LookaheadIndex]), Glyph.Id); if(LookaheadCover.Valid) { InSecondary = 1; goto DoneCheckingForInclusion; } } } DoneCheckingForInclusion:; if(InPrimary) { kbts_un FlatIndex = RunningLookupIndex * GlyphCount + GlyphIndex; kbts_un WordIndex = FlatIndex / 32; kbts_un BitIndex = FlatIndex % 32; GlyphLookupMatrix[WordIndex] |= (1 << BitIndex); } if(InPrimary || InSecondary) { kbts_un FlatIndex = RunningSubtableIndex * GlyphCount + GlyphIndex; kbts_un WordIndex = FlatIndex / 32; kbts_un BitIndex = FlatIndex % 32; GlyphLookupSubtableMatrix[WordIndex] |= (1 << BitIndex); } } SubtableInfos[RunningSubtableIndex] = SubtableInfo; RunningSubtableIndex += 1; } RunningLookupIndex += 1; } } } Font->SubtableInfos = SubtableInfos; Font->GlyphLookupMatrix = GlyphLookupMatrix; Font->GlyphLookupSubtableMatrix = GlyphLookupSubtableMatrix; Font->LookupSubtableIndexOffsets = LookupSubtableIndexOffsets; Font->GposLookupIndexOffset = (kbts_u32)GposLookupIndexOffset; Font->GlyphCount = (kbts_u32)GlyphCount; } return kbts_FontIsValid(Font); } KBTS_EXPORT int kbts_FontIsValid(kbts_font *Font) { int Result = !Font->Error; return Result; } #ifndef KB_TEXT_SHAPE_NO_CRT KBTS_EXPORT kbts_font kbts_FontFromFile(const char *FileName) { kbts_font Result = KBTS_ZERO; FILE *File; # ifndef _MSC_VER File = fopen(FileName, "rb"); # else fopen_s(&File, FileName, "rb"); # endif if(File) { fseek(File, 0, SEEK_END); long FileSize = ftell(File); fseek(File, 0, SEEK_SET); void *Data = malloc((kbts_un)FileSize); kbts_un Ok = fread(Data, (kbts_un)FileSize, 1, File); fclose(File); if(Ok) { kbts_un ScratchSize = kbts_ReadFontHeader(&Result, Data, (kbts_un)FileSize); void *Scratch = malloc(ScratchSize); kbts_un MemorySize = kbts_ReadFontData(&Result, Scratch, ScratchSize); void *Memory = Scratch; if(MemorySize > ScratchSize) { free(Scratch); Memory = malloc(MemorySize); } kbts_PostReadFontInitialize(&Result, Memory, MemorySize); } } return Result; } KBTS_EXPORT void kbts_FreeFont(kbts_font *Font) { if(Font->FileBase) { free(Font->FileBase); if(Font->GlyphLookupMatrix) { free(Font->GlyphLookupMatrix); // This frees everything else. } } } #endif KBTS_EXPORT int kbts_BreakStateIsValid(kbts_break_state *State) { int Result = !(State->Flags & KBTS_BREAK_STATE_FLAG_RAN_OUT_OF_REORDER_BUFFER_SPACE); return Result; } static void kbts_DoBreak(kbts_break_state *State, kbts_s32 Position, kbts_u8 Flags, kbts_direction Direction, kbts_script Script) { if(kbts_BreakStateIsValid(State) && Flags && (State->BreakCount < KBTS_BREAK_REORDER_BUFFER_SIZE)) { if(State->BreakCount < KBTS_BREAK_REORDER_BUFFER_SIZE) { kbts_break Break = KBTS_ZERO; Break.Position = State->CurrentPosition + (kbts_u32)Position; Break.Flags = Flags; Break.Direction = Direction; Break.Script = Script; int Matched = 0; KBTS_FOR(BreakIndex, 0, State->BreakCount) { kbts_break *Existing = &State->Breaks[BreakIndex]; if(Existing->Position == Break.Position) { Existing->Flags |= Break.Flags; if(Break.Flags & KBTS_BREAK_FLAG_DIRECTION) Existing->Direction = Break.Direction; if(Break.Flags & KBTS_BREAK_FLAG_SCRIPT) Existing->Script = Break.Script; Matched = 1; break; } else if(Existing->Position < Break.Position) { kbts_break Swap = *Existing; *Existing = Break; Break = Swap; } } State->Breaks[State->BreakCount] = Break; State->BreakCount += !Matched; } else { // This should never happen as long as we call Break() after every BreakAddCodepoint(). State->Flags |= KBTS_BREAK_STATE_FLAG_RAN_OUT_OF_REORDER_BUFFER_SPACE; } } } // The line break state is a 4-character history. Each character is a bags of 12 bits (padded to 16 bits). // Each character specifies allowed and required breaks on 6 levels of priority. // A required break implies an allowed break. // A priority N break implies priority 0..N-1 breaks. enum { KBTS_LINE_BREAK_ALLOWED0 = 1, KBTS_LINE_BREAK_ALLOWED1 = 3, KBTS_LINE_BREAK_ALLOWED2 = 7, KBTS_LINE_BREAK_ALLOWED3 = 0xF, KBTS_LINE_BREAK_ALLOWED4 = 0x1F, KBTS_LINE_BREAK_ALLOWED5 = 0x3F, KBTS_LINE_BREAK_REQUIRED0 = (1 << 6) | KBTS_LINE_BREAK_ALLOWED0, KBTS_LINE_BREAK_REQUIRED1 = (3 << 6) | KBTS_LINE_BREAK_ALLOWED1, KBTS_LINE_BREAK_REQUIRED2 = (7 << 6) | KBTS_LINE_BREAK_ALLOWED2, KBTS_LINE_BREAK_REQUIRED3 = (0xF << 6) | KBTS_LINE_BREAK_ALLOWED3, KBTS_LINE_BREAK_REQUIRED4 = (0x1F << 6) | KBTS_LINE_BREAK_ALLOWED4, KBTS_LINE_BREAK_REQUIRED5 = (0x3F << 6) | KBTS_LINE_BREAK_ALLOWED5, KBTS_LINE_BREAK_REQUIRED_MASK = 0x3F << 6, KBTS_LINE_BREAK_ALLOWED_MASK = 0x3F, KBTS_LINE_BREAK_MASK = KBTS_LINE_BREAK_REQUIRED_MASK | KBTS_LINE_BREAK_ALLOWED_MASK, }; static void kbts_DoLineBreak(kbts_break_state *State, int Position, kbts_u64 EffectiveLineBreaks, int Rtl, kbts_script Script) { if(EffectiveLineBreaks & KBTS_LINE_BREAK_MASK) { kbts_u8 Flags = 0; if(EffectiveLineBreaks & KBTS_LINE_BREAK_ALLOWED_MASK) Flags |= KBTS_BREAK_FLAG_LINE_SOFT; if(EffectiveLineBreaks & KBTS_LINE_BREAK_REQUIRED_MASK) Flags |= KBTS_BREAK_FLAG_LINE_HARD; kbts_DoBreak(State, Position, Flags, Rtl, Script); } } static void kbts_BreakAddCodepoint_(kbts_break_state *State, kbts_u32 Codepoint, kbts_u32 PositionIncrement, int MaybeEndOfText) { // In these macros, and in FlagState, and in the way we buffer our state in general, // index 0 means _after_ the codepoint currently being added, // index 1 means _before_ the codepoint currently being added. #define KBTS_BREAK(Flags, Position) do {FlagState |= ((Flags) << (8 * (Position)));} while(0) #define KBTS_BREAK2(Flags, Position0, Position1) do {FlagState |= ((Flags) << (8 * (Position0))) | ((Flags) << (8 * (Position1)));} while(0) if(!kbts_BreakStateIsValid(State)) return; kbts_u8 Script = kbts_GetUnicodeScript(Codepoint); kbts_unicode_bidirectional_class BidirectionalClass = kbts_GetUnicodeBidirectionalClass(Codepoint); kbts_u8 UnicodeFlags = kbts_GetUnicodeFlags(Codepoint); kbts_u32 MatchingBracket = kbts_GetUnicodeMatchingBracket(Codepoint); kbts_u8 GraphemeBreakClass = kbts_GetUnicodeGraphemeBreakClass(Codepoint); kbts_u8 LineBreakClass = kbts_GetUnicodeLineBreakClass(Codepoint); kbts_u8 WordBreakClass = kbts_GetUnicodeWordBreakClass(Codepoint); kbts_u8 LastScript = State->LastScripts[0]; kbts_u32 FlagState = State->FlagState << 8; kbts_u8 LastLineBreakClass = State->LastLineBreakClass; // Super secret cheat code for signaling end-of-text int EndOfText = (Codepoint == 3) && MaybeEndOfText; int StartOfText = !(State->Flags & KBTS_BREAK_STATE_FLAG_STARTED); kbts_u32 LineBreakHistory = State->LineBreakHistory; kbts_u32 WordBreakHistory = State->WordBreakHistory; kbts_u8 LastWordBreakClass = State->LastWordBreakClass; kbts_s16 WordBreak2PositionOffset = State->WordBreak2PositionOffset; kbts_u8 LastWordBreakClassIncludingIgnored = State->LastWordBreakClassIncludingIgnored; kbts_s16 PositionOffset2 = State->PositionOffset2; kbts_s16 PositionOffset3 = State->PositionOffset3; kbts_u32 Flags = State->Flags; kbts_direction LastDirection = State->LastDirection; if(StartOfText) { LineBreakHistory = LastLineBreakClass = KBTS_LINE_BREAK_CLASS_SOT; WordBreakHistory = LastWordBreakClass = KBTS_WORD_BREAK_CLASS_SOT; } if((Script == KBTS_SCRIPT_DEFAULT) || (Script == KBTS_SCRIPT_DEFAULT2)) { Script = LastScript; } // Bracket pairing overrides default directions/scripts. if(UnicodeFlags & KBTS_UNICODE_FLAG_OPEN_BRACKET) { if(State->BracketCount < KBTS_ARRAY_LENGTH(State->Brackets)) { kbts_bracket *Bracket = &State->Brackets[State->BracketCount++]; // @Incomplete: Canonicalize the bracket. Bracket->Codepoint = Codepoint; Bracket->Direction = KBTS_DIRECTION_NONE; Bracket->Script = Script; State->Flags |= KBTS_BREAK_STATE_FLAG_LAST_WAS_BRACKET; } } else if(UnicodeFlags & KBTS_UNICODE_FLAG_CLOSE_BRACKET) { if(State->BracketCount) { kbts_un FoundBracketIndex = 0; kbts_bracket *FoundBracket = 0; // @Incomplete: Canonicalize the bracket. KBTS_FOR(BracketIndex, 0, State->BracketCount) { kbts_bracket *Bracket = &State->Brackets[State->BracketCount - 1 - BracketIndex]; if(Bracket->Codepoint == MatchingBracket) { FoundBracket = Bracket; FoundBracketIndex = State->BracketCount - 1 - BracketIndex; break; } } if(FoundBracket) { BidirectionalClass = FoundBracket->Direction; Script = FoundBracket->Script; State->BracketCount = (kbts_u32)FoundBracketIndex; } } } { // Direction breaking. kbts_u8 Bidirectional2 = State->BidirectionalClass2; kbts_u8 Bidirectional1 = State->BidirectionalClass1; switch(BidirectionalClass) { case KBTS_UNICODE_BIDIRECTIONAL_CLASS_NSM: BidirectionalClass = Bidirectional1; break; case KBTS_UNICODE_BIDIRECTIONAL_CLASS_L: Flags &= ~(KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L | KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR); break; case KBTS_UNICODE_BIDIRECTIONAL_CLASS_R: Flags |= KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L; Flags &= ~KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR; break; case KBTS_UNICODE_BIDIRECTIONAL_CLASS_AL: // Rule W3 occurs before W7, so we treat AL as R for the purposes of rule W7. Flags |= (KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR | KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L); BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_R; break; case KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN: if(Flags & KBTS_BREAK_STATE_FLAG_SAW_AL_AFTER_LR) { BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN; goto CaseAn; } if((Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN) && ((Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_ES) || (Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_CS))) { Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN; } if(!(Flags & KBTS_BREAK_STATE_FLAG_SAW_R_AFTER_L)) { BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_L; } break; case KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN: CaseAn:; if((Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN) && (Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_CS)) { Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN; } break; case KBTS_UNICODE_BIDIRECTIONAL_CLASS_ET: if(Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN) { BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN; } break; } if(KBTS_IN_SET(BidirectionalClass, KBTS_SET32((KBTS_UNICODE_BIDIRECTIONAL_CLASS_ET)(KBTS_UNICODE_BIDIRECTIONAL_CLASS_ES)(KBTS_UNICODE_BIDIRECTIONAL_CLASS_CS)))) { BidirectionalClass = KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI; } if(Bidirectional1 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_NI) { if(KBTS_IN_SET(Bidirectional2, KBTS_SET32((KBTS_UNICODE_BIDIRECTIONAL_CLASS_R)(KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN)(KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN))) && KBTS_IN_SET(BidirectionalClass, KBTS_SET32((KBTS_UNICODE_BIDIRECTIONAL_CLASS_R)(KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN)(KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN)))) { Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_R; } else if((Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_L) && (BidirectionalClass == KBTS_UNICODE_BIDIRECTIONAL_CLASS_L)) { Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_L; } else { if (State->MainDirection == KBTS_DIRECTION_LTR) Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_L; else if(State->MainDirection == KBTS_DIRECTION_RTL) Bidirectional1 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_R; } } // These rules happen at the very end, so we wait until the last slot to apply them. if((Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_AN) || (Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_EN)) { Bidirectional2 = KBTS_UNICODE_BIDIRECTIONAL_CLASS_L; } // @Incomplete: ET+ EN -> EN+ EN kbts_direction Direction = KBTS_DIRECTION_NONE; if(Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_L) Direction = KBTS_DIRECTION_LTR; else if(Bidirectional2 == KBTS_UNICODE_BIDIRECTIONAL_CLASS_R) Direction = KBTS_DIRECTION_RTL; if(Direction && (Direction != LastDirection)) { LastDirection = Direction; KBTS_BREAK(KBTS_BREAK_FLAG_DIRECTION, 3); if(!State->MainDirection) { State->MainDirection = (kbts_u8)Direction; } } State->BidirectionalClass2 = Bidirectional1; State->BidirectionalClass1 = BidirectionalClass; } if(Script != LastScript) { KBTS_BREAK(KBTS_BREAK_FLAG_SCRIPT, 1); } { // Grapheme breaking. if(EndOfText && !StartOfText) { KBTS_BREAK(KBTS_BREAK_FLAG_GRAPHEME, 1); State->GraphemeBreakState = KBTS_GRAPHEME_BREAK_STATE_START; } else { kbts_u8 GraphemeBreakState = kbts_GraphemeBreakTransition[GraphemeBreakClass][State->GraphemeBreakState]; switch(GraphemeBreakState) { case KBTS_GRAPHEME_BREAK_STATE_b01: KBTS_BREAK2(KBTS_BREAK_FLAG_GRAPHEME, 1, 0); GraphemeBreakState = KBTS_GRAPHEME_BREAK_STATE_START; break; case KBTS_GRAPHEME_BREAK_STATE_b0: KBTS_BREAK(KBTS_BREAK_FLAG_GRAPHEME, 0); GraphemeBreakState = KBTS_GRAPHEME_BREAK_STATE_START; break; case KBTS_GRAPHEME_BREAK_STATE_b1: case KBTS_GRAPHEME_BREAK_STATE_b1toCR: case KBTS_GRAPHEME_BREAK_STATE_b1toL: case KBTS_GRAPHEME_BREAK_STATE_b1toLVxV: case KBTS_GRAPHEME_BREAK_STATE_b1toLVTxT: case KBTS_GRAPHEME_BREAK_STATE_b1toIndicConsonantxIndicLinker: case KBTS_GRAPHEME_BREAK_STATE_PADDING0: // Padding values are just here to help the compiler. case KBTS_GRAPHEME_BREAK_STATE_PADDING1: case KBTS_GRAPHEME_BREAK_STATE_b1toExtendedPictographic: case KBTS_GRAPHEME_BREAK_STATE_PADDING2: case KBTS_GRAPHEME_BREAK_STATE_PADDING3: case KBTS_GRAPHEME_BREAK_STATE_b1toRI: case KBTS_GRAPHEME_BREAK_STATE_b1toSKIP: KBTS_BREAK(KBTS_BREAK_FLAG_GRAPHEME, 1); GraphemeBreakState -= KBTS_GRAPHEME_BREAK_STATE_b1; } State->GraphemeBreakState = GraphemeBreakState; } } // Word breaks. // We buffer 3 characters for word breaks. // Each character gets 3 bits (padded to 4) representing 3 levels of priority. #define KBTS_WORD_BREAK_BITS(Priority, Position) (((1 << ((Priority) + 1)) - 1) << ((Position) * 4)) #define KBTS_C2(A, B) case (KBTS_WORD_BREAK_CLASS_##A << 8) | (KBTS_WORD_BREAK_CLASS_##B) #define KBTS_C3(A, B, C) case (KBTS_WORD_BREAK_CLASS_##A << 16) | (KBTS_WORD_BREAK_CLASS_##B << 8) | (KBTS_WORD_BREAK_CLASS_##C) // Ignore [EX FO ZWJ] after ^[_sot_ CR LF NL]. // @Cleanup: This is the only time we explicitly use EX and FO. They can be merged. if(KBTS_IN_SET(WordBreakClass, KBTS_SET32((KBTS_WORD_BREAK_CLASS_EX)(KBTS_WORD_BREAK_CLASS_FO)(KBTS_WORD_BREAK_CLASS_ZWJ))) && !KBTS_IN_SET(LastWordBreakClass, KBTS_SET32((KBTS_WORD_BREAK_CLASS_SOT)(KBTS_WORD_BREAK_CLASS_CR)(KBTS_WORD_BREAK_CLASS_LF)(KBTS_WORD_BREAK_CLASS_NL)))) { WordBreak2PositionOffset -= PositionIncrement; State->WordBreak2PositionOffset = WordBreak2PositionOffset; } else { kbts_u32 WordBreaks = State->WordBreaks << 4; kbts_u32 WordUnbreaks = State->WordUnbreaks << 4; WordBreakHistory = (WordBreakHistory << 8) | WordBreakClass; WordBreaks |= KBTS_WORD_BREAK_BITS(0, 1) | KBTS_WORD_BREAK_BITS(0, 0); if(StartOfText) { WordBreaks |= KBTS_WORD_BREAK_BITS(2, 1); } if(KBTS_IN_SET(WordBreakClass, KBTS_SET32((KBTS_WORD_BREAK_CLASS_CR)(KBTS_WORD_BREAK_CLASS_LF)(KBTS_WORD_BREAK_CLASS_NL)))) { WordBreaks |= KBTS_WORD_BREAK_BITS(1, 1) | KBTS_WORD_BREAK_BITS(1, 0); } else if(KBTS_IN_SET(WordBreakClass, KBTS_SET32((KBTS_WORD_BREAK_CLASS_Oep)(KBTS_WORD_BREAK_CLASS_ALep)))) { // ZWJ x {Extended_Pictographic} if(LastWordBreakClassIncludingIgnored == KBTS_WORD_BREAK_CLASS_ZWJ) { WordUnbreaks |= KBTS_WORD_BREAK_BITS(0, 1); } } switch(WordBreakHistory & 0xFFFF) { KBTS_C2(CR, LF): WordUnbreaks |= KBTS_WORD_BREAK_BITS(1, 1); break; KBTS_C2(WSS, WSS): // WSS x WSS is a special rule, because it is supposed to happen _before_ ignores. if(WordBreak2PositionOffset >= 0) WordUnbreaks |= KBTS_WORD_BREAK_BITS(0, 1); break; // (RI RI)* RI x RI KBTS_C2(RI, RI): WordBreakHistory = 0; // fallthrough KBTS_C2(HL, SQ): KBTS_C2(ALnep, ALnep): KBTS_C2(ALnep, ALep): KBTS_C2(ALnep, HL): KBTS_C2(ALnep, NM): KBTS_C2(ALnep, ENL): KBTS_C2(ALep, ALnep): KBTS_C2(ALep, ALep): KBTS_C2(ALep, HL): KBTS_C2(ALep, NM): KBTS_C2(ALep, ENL): KBTS_C2(HL, ALnep): KBTS_C2(HL, ALep): KBTS_C2(HL, HL): KBTS_C2(HL, NM): KBTS_C2(HL, ENL): KBTS_C2(NM, ALnep): KBTS_C2(NM, ALep): KBTS_C2(NM, HL): KBTS_C2(NM, NM): KBTS_C2(NM, ENL): KBTS_C2(KA, KA): KBTS_C2(KA, ENL): KBTS_C2(ENL, ALnep): KBTS_C2(ENL, ALep): KBTS_C2(ENL, HL): KBTS_C2(ENL, NM): KBTS_C2(ENL, KA): KBTS_C2(ENL, ENL): WordUnbreaks |= KBTS_WORD_BREAK_BITS(0, 1); break; } switch(WordBreakHistory & 0xFFFFFF) { KBTS_C3(ALnep, ML, ALnep): KBTS_C3(ALnep, ML, ALep): KBTS_C3(ALnep, ML, HL): KBTS_C3(ALnep, MNL, ALnep): KBTS_C3(ALnep, MNL, ALep): KBTS_C3(ALnep, MNL, HL): KBTS_C3(ALnep, SQ, ALnep): KBTS_C3(ALnep, SQ, ALep): KBTS_C3(ALnep, SQ, HL): KBTS_C3(ALep, ML, ALnep): KBTS_C3(ALep, ML, ALep): KBTS_C3(ALep, ML, HL): KBTS_C3(ALep, MNL, ALnep): KBTS_C3(ALep, MNL, ALep): KBTS_C3(ALep, MNL, HL): KBTS_C3(ALep, SQ, ALnep): KBTS_C3(ALep, SQ, ALep): KBTS_C3(ALep, SQ, HL): KBTS_C3(HL, ML, ALnep): KBTS_C3(HL, ML, ALep): KBTS_C3(HL, ML, HL): KBTS_C3(HL, MNL, ALnep): KBTS_C3(HL, MNL, ALep): KBTS_C3(HL, MNL, HL): KBTS_C3(HL, SQ, ALnep): KBTS_C3(HL, SQ, ALep): KBTS_C3(HL, SQ, HL): KBTS_C3(HL, DQ, HL): KBTS_C3(NM, MN, NM): KBTS_C3(NM, MNL, NM): KBTS_C3(NM, SQ, NM): WordUnbreaks |= KBTS_WORD_BREAK_BITS(0, 1) | KBTS_WORD_BREAK_BITS(0, 2); break; } kbts_u32 EffectiveWordBreaks = WordBreaks & ~WordUnbreaks; if(EffectiveWordBreaks & KBTS_WORD_BREAK_BITS(2, 2)) { kbts_DoBreak(State, PositionOffset2 + WordBreak2PositionOffset, KBTS_BREAK_FLAG_WORD, 0, 0); } if(EndOfText) { // Always break at the end of the text. KBTS_BREAK(KBTS_BREAK_FLAG_WORD, 1); // Do not break after the end of the text. } State->WordBreaks = (kbts_u16)WordBreaks; State->WordUnbreaks = (kbts_u16)WordUnbreaks; State->LastWordBreakClass = WordBreakClass; State->WordBreak2PositionOffset = 0; State->WordBreakHistory = WordBreakHistory; } State->LastWordBreakClassIncludingIgnored = WordBreakClass; #undef KBTS_WORD_BREAK_BITS #undef KBTS_C2 #undef KBTS_C3 kbts_s16 LineBreak3PositionOffset = State->LineBreak3PositionOffset; kbts_s16 LineBreak2PositionOffset = State->LineBreak2PositionOffset; { // Line breaking. kbts_u64 LineBreaks = State->LineBreaks << 16; kbts_u64 LineUnbreaks = State->LineUnbreaks << 16; kbts_u64 LineUnbreaksAsync = State->LineUnbreaksAsync << 16; #define KBTS_C1(A) case KBTS_LINE_BREAK_CLASS_##A #define KBTS_C2(A, B) case (KBTS_LINE_BREAK_CLASS_##A << 8) | (KBTS_LINE_BREAK_CLASS_##B) #define KBTS_C3(A, B, C) case (KBTS_LINE_BREAK_CLASS_##A << 16) | (KBTS_LINE_BREAK_CLASS_##B << 8) | KBTS_LINE_BREAK_CLASS_##C #define KBTS_C4(A, B, C, D) case (KBTS_LINE_BREAK_CLASS_##A << 24) | (KBTS_LINE_BREAK_CLASS_##B << 16) | (KBTS_LINE_BREAK_CLASS_##C << 8) | KBTS_LINE_BREAK_CLASS_##D #define KBTS_REQUIRED_LINE_BREAK(Priority, Position) do {LineBreaks |= (kbts_u64)KBTS_LINE_BREAK_REQUIRED##Priority << ((Position) * 16);} while(0) #define KBTS_LINE_BREAK(Priority, Position) do {LineBreaks |= (kbts_u64)KBTS_LINE_BREAK_ALLOWED##Priority << ((Position) * 16);} while(0) #define KBTS_LINE_UNBREAK(Priority, Position) do {LineUnbreaks |= (kbts_u64)KBTS_LINE_BREAK_REQUIRED##Priority << ((Position) * 16);} while(0) #define KBTS_LINE_UNBREAK_ASYNC(Priority, Position) do {LineUnbreaksAsync |= (kbts_u64)KBTS_LINE_BREAK_REQUIRED##Priority << ((Position) * 16);} while(0) if(EndOfText) { // Depending on the current line break state, we might need very different breaks. // For now, we copy the transitions from the first row of the transition table, but // we might want to special-case these. LineBreakClass = KBTS_LINE_BREAK_CLASS_Onea; } else if(LineBreakClass > KBTS_LINE_BREAK_CLASS_COUNT) { // These guys have special rules. if((LineBreakClass == KBTS_LINE_BREAK_CLASS_CM) || (LineBreakClass == KBTS_LINE_BREAK_CLASS_ZWJ)) { if(LineBreakClass == KBTS_LINE_BREAK_CLASS_ZWJ) { KBTS_LINE_UNBREAK_ASYNC(3, 0); } switch(LastLineBreakClass) { case KBTS_LINE_BREAK_CLASS_SOT: case KBTS_LINE_BREAK_CLASS_BK: case KBTS_LINE_BREAK_CLASS_CR: case KBTS_LINE_BREAK_CLASS_LF: case KBTS_LINE_BREAK_CLASS_NL: case KBTS_LINE_BREAK_CLASS_SP: case KBTS_LINE_BREAK_CLASS_ZW: LineBreakClass = KBTS_LINE_BREAK_CLASS_ALnea; break; default: // The standard says to treat X [CM ZWJ]* as X. // This means that we need to hoist [CM ZWJ] completely out of the line breaking logic. // However, we give our results in index offsets relative to the current glyph, so we // do have to acknowledge that we are skipping glyphs. goto LineBreakAbsorbCharacter; } } else if(LineBreakClass == KBTS_LINE_BREAK_CLASS_CJ) { LineBreakClass = State->JapaneseLineBreakStyle == KBTS_JAPANESE_LINE_BREAK_STYLE_STRICT ? KBTS_LINE_BREAK_CLASS_NSea : KBTS_LINE_BREAK_CLASS_IDea; } } if(LastLineBreakClass == LineBreakClass) { // @Incomplete: Handle repeats that aren't SP*. if(LineBreakClass == KBTS_LINE_BREAK_CLASS_SP) { goto LineBreakAbsorbCharacter; } } LineBreakHistory = (LineBreakHistory << 8) | LineBreakClass; if(EndOfText) { // Always break at the end of text. KBTS_REQUIRED_LINE_BREAK(5, 1); // x QUPf _eot_ if((LineBreakHistory & 0xFF00) == (KBTS_LINE_BREAK_CLASS_QUPf << 8)) { KBTS_LINE_UNBREAK(3, 2); } } KBTS_LINE_BREAK(0, 0); KBTS_LINE_BREAK(0, 1); switch(LineBreakClass) { KBTS_C1(BK): KBTS_C1(CR): KBTS_C1(LF): KBTS_C1(NL): KBTS_LINE_UNBREAK(4, 1); KBTS_REQUIRED_LINE_BREAK(5, 0); break; KBTS_C1(ZW): KBTS_LINE_BREAK(4, 0); KBTS_LINE_UNBREAK(4, 1); break; KBTS_C1(BB): KBTS_LINE_UNBREAK(0, 0); break; KBTS_C1(GLea): KBTS_C1(GLnea): KBTS_C1(OPea): KBTS_C1(OPnea): KBTS_LINE_UNBREAK(3, 0); break; KBTS_C1(WJ): KBTS_LINE_UNBREAK(3, 0); KBTS_LINE_UNBREAK(3, 1); break; KBTS_C1(CLea): KBTS_C1(CLnea): KBTS_C1(CPea): KBTS_C1(CPnea): KBTS_C1(EXea): KBTS_C1(EXnea): KBTS_C1(SY): KBTS_LINE_UNBREAK(3, 1); break; KBTS_C1(IS): KBTS_LINE_UNBREAK(2, 1); break; KBTS_C1(SP): KBTS_LINE_UNBREAK(4, 1); KBTS_LINE_BREAK(2, 0); break; KBTS_C1(QU): KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); break; KBTS_C1(QUPi): KBTS_LINE_UNBREAK(1, 0); break; KBTS_C1(QUPf): KBTS_LINE_UNBREAK(1, 1); break; KBTS_C1(CB): KBTS_LINE_BREAK(1, 0); KBTS_LINE_BREAK(1, 1); break; KBTS_C1(BAnea): KBTS_C1(BAea): KBTS_C1(HYPHEN): KBTS_C1(HY): KBTS_C1(NSnea): KBTS_C1(NSea): KBTS_C1(INnea): KBTS_C1(INea): KBTS_LINE_UNBREAK(0, 1); break; } switch(LineBreakHistory & 0xFFFF) { KBTS_C2(CR, LF): KBTS_LINE_UNBREAK(5, 1); break; KBTS_C2(ZW, SP): KBTS_LINE_BREAK(4, 0); break; KBTS_C2(OPea, QUPi): KBTS_C2(GLea, QUPi): KBTS_C2(OPea, SP): KBTS_C2(OPnea,SP): KBTS_LINE_UNBREAK(3, 0); break; KBTS_C2(SOT, QUPi): KBTS_C2(BK, QUPi): KBTS_C2(CR, QUPi): KBTS_C2(LF, QUPi): KBTS_C2(NL, QUPi): KBTS_C2(SP, QUPi): KBTS_C2(ZW, QUPi): KBTS_C2(GLnea, QUPi): KBTS_C2(QU, QUPi): KBTS_C2(OPnea, QUPi): KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); KBTS_LINE_UNBREAK(3, 0); break; KBTS_C2(QUPi, QUPi): KBTS_LINE_UNBREAK(3, 0); KBTS_LINE_UNBREAK(1, 2); KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); break; KBTS_C2(QUPf, QUPi): KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); KBTS_LINE_UNBREAK(3, 0); KBTS_LINE_UNBREAK(3, 2); KBTS_LINE_UNBREAK(1, 1); break; KBTS_C2(QUPf, GLnea): KBTS_LINE_UNBREAK(3, 2); KBTS_LINE_UNBREAK(3, 1); KBTS_LINE_UNBREAK(1, 1); break; KBTS_C2(QUPf, BK): KBTS_C2(QUPf, CR): KBTS_C2(QUPf, LF): KBTS_C2(QUPf, NL): KBTS_C2(QUPf, ZW): KBTS_C2(QUPf, WJ): KBTS_C2(QUPf, CLnea): KBTS_C2(QUPf, CPnea): KBTS_C2(QUPf, EXnea): KBTS_C2(QUPf, SY): KBTS_C2(QUPf, IS): KBTS_C2(QUPf, SP): KBTS_LINE_UNBREAK(3, 2); KBTS_LINE_UNBREAK(1, 1); break; KBTS_C2(QUPf, QUPf): KBTS_LINE_UNBREAK(3, 2); KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); break; KBTS_C2(QUPf, QU): KBTS_LINE_UNBREAK(3, 2); KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); break; KBTS_C2(QUPf, GLea): KBTS_LINE_UNBREAK(3, 2); KBTS_LINE_UNBREAK(3, 1); break; KBTS_C2(QUPf, CPea): KBTS_C2(QUPf, CLea): KBTS_C2(QUPf, EXea): KBTS_LINE_UNBREAK(3, 2); break; KBTS_C2(QUPi, QU): KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); KBTS_LINE_UNBREAK(1, 2); break; KBTS_C2(QUPi, QUPf): KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); KBTS_LINE_UNBREAK(1, 2); break; KBTS_C2(QUPi, GLnea): KBTS_LINE_UNBREAK(1, 2); KBTS_LINE_UNBREAK(3, 1); break; KBTS_C2(QUPi, Onea): KBTS_C2(QUPi, Ope): KBTS_C2(QUPi, BK): KBTS_C2(QUPi, CR): KBTS_C2(QUPi, LF): KBTS_C2(QUPi, NL): KBTS_C2(QUPi, SP): KBTS_C2(QUPi, ZW): KBTS_C2(QUPi, WJ): KBTS_C2(QUPi, CLnea): KBTS_C2(QUPi, CPnea): KBTS_C2(QUPi, EXnea): KBTS_C2(QUPi, SY): KBTS_C2(QUPi, BAnea): KBTS_C2(QUPi, OPnea): KBTS_C2(QUPi, IS): KBTS_C2(QUPi, NSnea): KBTS_C2(QUPi, B2): KBTS_C2(QUPi, CB): KBTS_C2(QUPi, HY): KBTS_C2(QUPi, HYPHEN): KBTS_C2(QUPi, INnea): KBTS_C2(QUPi, BB): KBTS_C2(QUPi, HL): KBTS_C2(QUPi, ALnea): KBTS_C2(QUPi, NU): KBTS_C2(QUPi, PRnea): KBTS_C2(QUPi, IDnea): KBTS_C2(QUPi, IDpe): KBTS_C2(QUPi, EBnea): KBTS_C2(QUPi, POnea): KBTS_C2(QUPi, JV): KBTS_C2(QUPi, JT): KBTS_C2(QUPi, AP): KBTS_C2(QUPi, AK): KBTS_C2(QUPi, DOTTED_CIRCLE): KBTS_C2(QUPi, AS): KBTS_C2(QUPi, VF): KBTS_C2(QUPi, VI): KBTS_C2(QUPi, RI): KBTS_LINE_UNBREAK(1, 2); break; KBTS_C2(QUPf, Onea): KBTS_C2(QUPf, Ope): KBTS_C2(QUPf, BAnea): KBTS_C2(QUPf, OPnea): KBTS_C2(QUPf, NSnea): KBTS_C2(QUPf, B2): KBTS_C2(QUPf, CB): KBTS_C2(QUPf, HY): KBTS_C2(QUPf, HYPHEN): KBTS_C2(QUPf, INnea): KBTS_C2(QUPf, BB): KBTS_C2(QUPf, HL): KBTS_C2(QUPf, ALnea): KBTS_C2(QUPf, NU): KBTS_C2(QUPf, PRnea): KBTS_C2(QUPf, IDnea): KBTS_C2(QUPf, IDpe): KBTS_C2(QUPf, EBnea): KBTS_C2(QUPf, POnea): KBTS_C2(QUPf, JV): KBTS_C2(QUPf, JT): KBTS_C2(QUPf, AP): KBTS_C2(QUPf, AK): KBTS_C2(QUPf, DOTTED_CIRCLE): KBTS_C2(QUPf, AS): KBTS_C2(QUPf, VF): KBTS_C2(QUPf, VI): KBTS_C2(QUPf, RI): KBTS_LINE_UNBREAK(1, 1); break; KBTS_C2(SOT, QU): KBTS_C2(SOT, QUPf): KBTS_C2(Onea, QU): KBTS_C2(Ope, QU): KBTS_C2(BK, QU): KBTS_C2(CR, QU): KBTS_C2(LF, QU): KBTS_C2(NL, QU): KBTS_C2(SP, QU): KBTS_C2(ZW, QU): KBTS_C2(WJ, QU): KBTS_C2(GLnea, QU): KBTS_C2(CLnea, QU): KBTS_C2(CPnea, QU): KBTS_C2(EXnea, QU): KBTS_C2(SY, QU): KBTS_C2(BAnea, QU): KBTS_C2(OPnea, QU): KBTS_C2(QU, QU): KBTS_C2(IS, QU): KBTS_C2(NSnea, QU): KBTS_C2(B2, QU): KBTS_C2(CB, QU): KBTS_C2(HY, QU): KBTS_C2(HYPHEN, QU): KBTS_C2(INnea, QU): KBTS_C2(BB, QU): KBTS_C2(HL, QU): KBTS_C2(ALnea, QU): KBTS_C2(NU, QU): KBTS_C2(PRnea, QU): KBTS_C2(IDnea, QU): KBTS_C2(IDpe, QU): KBTS_C2(EBnea, QU): KBTS_C2(POnea, QU): KBTS_C2(JV, QU): KBTS_C2(JT, QU): KBTS_C2(AP, QU): KBTS_C2(AK, QU): KBTS_C2(DOTTED_CIRCLE, QU): KBTS_C2(AS, QU): KBTS_C2(VF, QU): KBTS_C2(VI, QU): KBTS_C2(RI, QU): KBTS_C2(Onea, QUPi): KBTS_C2(Ope, QUPi): KBTS_C2(WJ, QUPi): KBTS_C2(CLnea, QUPi): KBTS_C2(CPnea, QUPi): KBTS_C2(EXnea, QUPi): KBTS_C2(SY, QUPi): KBTS_C2(BAnea, QUPi): KBTS_C2(IS, QUPi): KBTS_C2(NSnea, QUPi): KBTS_C2(B2, QUPi): KBTS_C2(CB, QUPi): KBTS_C2(HY, QUPi): KBTS_C2(HYPHEN, QUPi): KBTS_C2(INnea, QUPi): KBTS_C2(BB, QUPi): KBTS_C2(HL, QUPi): KBTS_C2(ALnea, QUPi): KBTS_C2(NU, QUPi): KBTS_C2(PRnea, QUPi): KBTS_C2(IDnea, QUPi): KBTS_C2(IDpe, QUPi): KBTS_C2(EBnea, QUPi): KBTS_C2(POnea, QUPi): KBTS_C2(JV, QUPi): KBTS_C2(JT, QUPi): KBTS_C2(AP, QUPi): KBTS_C2(AK, QUPi): KBTS_C2(DOTTED_CIRCLE, QUPi): KBTS_C2(AS, QUPi): KBTS_C2(VF, QUPi): KBTS_C2(VI, QUPi): KBTS_C2(RI, QUPi): KBTS_C2(Onea, QUPf): KBTS_C2(Ope, QUPf): KBTS_C2(BK, QUPf): KBTS_C2(CR, QUPf): KBTS_C2(LF, QUPf): KBTS_C2(NL, QUPf): KBTS_C2(SP, QUPf): KBTS_C2(ZW, QUPf): KBTS_C2(WJ, QUPf): KBTS_C2(GLnea, QUPf): KBTS_C2(CLnea, QUPf): KBTS_C2(CPnea, QUPf): KBTS_C2(EXnea, QUPf): KBTS_C2(SY, QUPf): KBTS_C2(BAnea, QUPf): KBTS_C2(OPnea, QUPf): KBTS_C2(QU, QUPf): KBTS_C2(IS, QUPf): KBTS_C2(NSnea, QUPf): KBTS_C2(B2, QUPf): KBTS_C2(CB, QUPf): KBTS_C2(HY, QUPf): KBTS_C2(HYPHEN, QUPf): KBTS_C2(INnea, QUPf): KBTS_C2(BB, QUPf): KBTS_C2(HL, QUPf): KBTS_C2(ALnea, QUPf): KBTS_C2(NU, QUPf): KBTS_C2(PRnea, QUPf): KBTS_C2(IDnea, QUPf): KBTS_C2(IDpe, QUPf): KBTS_C2(EBnea, QUPf): KBTS_C2(POnea, QUPf): KBTS_C2(JV, QUPf): KBTS_C2(JT, QUPf): KBTS_C2(AP, QUPf): KBTS_C2(AK, QUPf): KBTS_C2(DOTTED_CIRCLE, QUPf): KBTS_C2(AS, QUPf): KBTS_C2(VF, QUPf): KBTS_C2(VI, QUPf): KBTS_C2(RI, QUPf): KBTS_LINE_UNBREAK(1, 1); KBTS_LINE_UNBREAK(1, 0); break; KBTS_C2(HL, NU): KBTS_C2(ALnea, NU): KBTS_C2(ALea, NU): KBTS_C2(DOTTED_CIRCLE, NU): KBTS_C2(NU, ALnea): KBTS_C2(NU, ALea): KBTS_C2(NU, DOTTED_CIRCLE): KBTS_C2(NU, HL): KBTS_C2(PRnea, IDnea): KBTS_C2(PRnea, IDea): KBTS_C2(PRnea, IDpe): KBTS_C2(PRnea, EBea): KBTS_C2(PRnea, EBnea): KBTS_C2(PRnea, EM): KBTS_C2(PRea, IDnea): KBTS_C2(PRea, IDea): KBTS_C2(PRea, IDpe): KBTS_C2(PRea, EBea): KBTS_C2(PRea, EBnea): KBTS_C2(PRea, EM): KBTS_C2(IDnea, POea): KBTS_C2(IDnea, POnea): KBTS_C2(IDea, POea): KBTS_C2(IDea, POnea): KBTS_C2(IDpe, POea): KBTS_C2(IDpe, POnea): KBTS_C2(EBnea, POea): KBTS_C2(EBnea, POnea): KBTS_C2(EBea, POea): KBTS_C2(EBea, POnea): KBTS_C2(EM, POea): KBTS_C2(EM, POnea): KBTS_C2(PRea, ALea): KBTS_C2(PRea, ALnea): KBTS_C2(PRea, DOTTED_CIRCLE): KBTS_C2(PRea, HL): KBTS_C2(PRnea, ALea): KBTS_C2(PRnea, ALnea): KBTS_C2(PRnea, DOTTED_CIRCLE): KBTS_C2(PRnea, HL): KBTS_C2(POea, ALea): KBTS_C2(POea, ALnea): KBTS_C2(POea, DOTTED_CIRCLE): KBTS_C2(POea, HL): KBTS_C2(POnea, ALea): KBTS_C2(POnea, ALnea): KBTS_C2(POnea, DOTTED_CIRCLE): KBTS_C2(POnea, HL): KBTS_C2(ALea, PRea): KBTS_C2(ALea, PRnea): KBTS_C2(ALea, POea): KBTS_C2(ALea, POnea): KBTS_C2(ALnea, PRea): KBTS_C2(ALnea, PRnea): KBTS_C2(ALnea, POea): KBTS_C2(ALnea, POnea): KBTS_C2(DOTTED_CIRCLE, PRea): KBTS_C2(DOTTED_CIRCLE, PRnea): KBTS_C2(DOTTED_CIRCLE, POea): KBTS_C2(DOTTED_CIRCLE, POnea): KBTS_C2(HL, PRea): KBTS_C2(HL, PRnea): KBTS_C2(HL, POea): KBTS_C2(HL, POnea): KBTS_C2(NU, POea): KBTS_C2(NU, POnea): KBTS_C2(NU, PRea): KBTS_C2(NU, PRnea): KBTS_C2(NU, NU): KBTS_C2(POea, NU): KBTS_C2(POnea, NU): KBTS_C2(PRea, NU): KBTS_C2(PRnea, NU): KBTS_C2(SY, HL): KBTS_C2(JL, JL): KBTS_C2(JL, JV): KBTS_C2(JL, H2): KBTS_C2(JL, H3): KBTS_C2(JV, JV): KBTS_C2(JV, JT): KBTS_C2(H2, JV): KBTS_C2(H2, JT): KBTS_C2(JT, JT): KBTS_C2(H3, JT): KBTS_C2(JL, POea): KBTS_C2(JL, POnea): KBTS_C2(JV, POea): KBTS_C2(JV, POnea): KBTS_C2(JT, POea): KBTS_C2(JT, POnea): KBTS_C2(H2, POea): KBTS_C2(H2, POnea): KBTS_C2(H3, POea): KBTS_C2(H3, POnea): KBTS_C2(PRea, JL): KBTS_C2(PRea, JV): KBTS_C2(PRea, JT): KBTS_C2(PRea, H2): KBTS_C2(PRea, H3): KBTS_C2(PRnea, JL): KBTS_C2(PRnea, JV): KBTS_C2(PRnea, JT): KBTS_C2(PRnea, H2): KBTS_C2(PRnea, H3): KBTS_C2(ALea, ALea): KBTS_C2(ALea, ALnea): KBTS_C2(ALea, DOTTED_CIRCLE): KBTS_C2(ALea, HL): KBTS_C2(ALnea, ALea): KBTS_C2(ALnea, ALnea): KBTS_C2(ALnea, DOTTED_CIRCLE): KBTS_C2(ALnea, HL): KBTS_C2(DOTTED_CIRCLE, ALea): KBTS_C2(DOTTED_CIRCLE, ALnea): KBTS_C2(DOTTED_CIRCLE, DOTTED_CIRCLE): KBTS_C2(DOTTED_CIRCLE, HL): KBTS_C2(HL, ALea): KBTS_C2(HL, ALnea): KBTS_C2(HL, DOTTED_CIRCLE): KBTS_C2(HL, HL): KBTS_C2(AP, AK): KBTS_C2(AP, DOTTED_CIRCLE): KBTS_C2(AP, AS): KBTS_C2(AK, VF): KBTS_C2(AK, VI): KBTS_C2(DOTTED_CIRCLE, VF): KBTS_C2(DOTTED_CIRCLE, VI): KBTS_C2(AS, VF): KBTS_C2(AS, VI): KBTS_C2(IS, ALea): KBTS_C2(IS, ALnea): KBTS_C2(IS, DOTTED_CIRCLE): KBTS_C2(IS, HL): KBTS_C2(ALea, OPnea): KBTS_C2(ALnea, OPnea): KBTS_C2(DOTTED_CIRCLE, OPnea): KBTS_C2(HL, OPnea): KBTS_C2(NU, OPnea): KBTS_C2(CPnea, ALea): KBTS_C2(CPnea, ALnea): KBTS_C2(CPnea, DOTTED_CIRCLE): KBTS_C2(CPnea, HL): KBTS_C2(CPnea, NU): KBTS_C2(EBea, EM): KBTS_C2(EBnea, EM): KBTS_C2(Ope, EM): KBTS_C2(IDpe, EM): KBTS_C2(HY, NU): KBTS_C2(IS, NU): KBTS_LINE_UNBREAK(0, 1); break; KBTS_C2(Oea, GLea):KBTS_C2(Oea, GLnea): KBTS_C2(Onea, GLea):KBTS_C2(Onea, GLnea): KBTS_C2(Ope, GLea):KBTS_C2(Ope, GLnea): KBTS_C2(BK, GLea):KBTS_C2(BK, GLnea): KBTS_C2(CR, GLea):KBTS_C2(CR, GLnea): KBTS_C2(LF, GLea):KBTS_C2(LF, GLnea): KBTS_C2(NL, GLea):KBTS_C2(NL, GLnea): KBTS_C2(ZW, GLea):KBTS_C2(ZW, GLnea): KBTS_C2(WJ, GLea):KBTS_C2(WJ, GLnea): KBTS_C2(GLea, GLea):KBTS_C2(GLea, GLnea): KBTS_C2(GLnea, GLea):KBTS_C2(GLnea, GLnea): KBTS_C2(CLea, GLea):KBTS_C2(CLea, GLnea): KBTS_C2(CLnea, GLea):KBTS_C2(CLnea, GLnea): KBTS_C2(CPea, GLea):KBTS_C2(CPea, GLnea): KBTS_C2(CPnea, GLea):KBTS_C2(CPnea, GLnea): KBTS_C2(EXea, GLea):KBTS_C2(EXea, GLnea): KBTS_C2(EXnea, GLea):KBTS_C2(EXnea, GLnea): KBTS_C2(SY, GLea):KBTS_C2(SY, GLnea): KBTS_C2(OPea, GLea):KBTS_C2(OPea, GLnea): KBTS_C2(OPnea, GLea):KBTS_C2(OPnea, GLnea): KBTS_C2(QU, GLea):KBTS_C2(QU, GLnea): KBTS_C2(QUPi, GLea): KBTS_C2(IS, GLea):KBTS_C2(IS, GLnea): KBTS_C2(NSea, GLea):KBTS_C2(NSea, GLnea): KBTS_C2(NSnea, GLea):KBTS_C2(NSnea, GLnea): KBTS_C2(B2, GLea):KBTS_C2(B2, GLnea): KBTS_C2(CB, GLea):KBTS_C2(CB, GLnea): KBTS_C2(INea, GLea):KBTS_C2(INea, GLnea): KBTS_C2(INnea, GLea):KBTS_C2(INnea, GLnea): KBTS_C2(BB, GLea):KBTS_C2(BB, GLnea): KBTS_C2(HL, GLea):KBTS_C2(HL, GLnea): KBTS_C2(ALea, GLea):KBTS_C2(ALea, GLnea): KBTS_C2(ALnea, GLea):KBTS_C2(ALnea, GLnea): KBTS_C2(NU, GLea):KBTS_C2(NU, GLnea): KBTS_C2(PRea, GLea):KBTS_C2(PRea, GLnea): KBTS_C2(PRnea, GLea):KBTS_C2(PRnea, GLnea): KBTS_C2(IDea, GLea):KBTS_C2(IDea, GLnea): KBTS_C2(IDnea, GLea):KBTS_C2(IDnea, GLnea): KBTS_C2(IDpe, GLea):KBTS_C2(IDpe, GLnea): KBTS_C2(EBea, GLea):KBTS_C2(EBea, GLnea): KBTS_C2(EBnea, GLea):KBTS_C2(EBnea, GLnea): KBTS_C2(EM, GLea):KBTS_C2(EM, GLnea): KBTS_C2(POea, GLea):KBTS_C2(POea, GLnea): KBTS_C2(POnea, GLea):KBTS_C2(POnea, GLnea): KBTS_C2(JL, GLea):KBTS_C2(JL, GLnea): KBTS_C2(JV, GLea):KBTS_C2(JV, GLnea): KBTS_C2(JT, GLea):KBTS_C2(JT, GLnea): KBTS_C2(H2, GLea):KBTS_C2(H2, GLnea): KBTS_C2(H3, GLea):KBTS_C2(H3, GLnea): KBTS_C2(AP, GLea):KBTS_C2(AP, GLnea): KBTS_C2(AK, GLea):KBTS_C2(AK, GLnea): KBTS_C2(DOTTED_CIRCLE, GLea):KBTS_C2(DOTTED_CIRCLE, GLnea): KBTS_C2(AS, GLea):KBTS_C2(AS, GLnea): KBTS_C2(VF, GLea):KBTS_C2(VF, GLnea): KBTS_C2(VI, GLea):KBTS_C2(VI, GLnea): KBTS_C2(RI, GLea):KBTS_C2(RI, GLnea): KBTS_LINE_UNBREAK(3, 1); break; KBTS_C2(CLea, NSnea): KBTS_C2(CLea, NSea): KBTS_C2(CLnea, NSnea): KBTS_C2(CLnea, NSea): KBTS_C2(CPea, NSnea): KBTS_C2(CPea, NSea): KBTS_C2(CPnea, NSnea): KBTS_C2(CPnea, NSea): KBTS_C2(B2, B2): KBTS_LINE_UNBREAK(2, 1); break; KBTS_C2(RI, RI): // (RI RI)* RI x RI KBTS_LINE_UNBREAK(0, 1); LineBreakHistory = 0; break; } switch(LineBreakHistory & 0xFFFFFF) { KBTS_C3(SOT, QUPi, SP): KBTS_C3(BK, QUPi, SP): KBTS_C3(CR, QUPi, SP): KBTS_C3(LF, QUPi, SP): KBTS_C3(NL, QUPi, SP): KBTS_C3(OPea, QUPi, SP): KBTS_C3(OPnea, QUPi, SP): KBTS_C3(SP, QUPi, SP): KBTS_C3(ZW, QUPi, SP): KBTS_C3(QU, QUPi, SP): KBTS_C3(QUPi, QUPi, SP): KBTS_C3(QUPf, QUPi, SP): KBTS_C3(GLea, QUPi, SP): KBTS_C3(GLnea, QUPi, SP): KBTS_LINE_UNBREAK(3, 0); break; KBTS_C3(SP, IS, NU): KBTS_LINE_BREAK(3, 2); break; KBTS_C3(CLea, SP, NSnea): KBTS_C3(CLea, SP, NSea): KBTS_C3(CLnea, SP, NSnea): KBTS_C3(CLnea, SP, NSea): KBTS_C3(CPea, SP, NSnea): KBTS_C3(CPea, SP, NSea): KBTS_C3(CPnea, SP, NSnea): KBTS_C3(CPnea, SP, NSea): KBTS_C3(B2, SP, B2): KBTS_LINE_UNBREAK(2, 1); break; KBTS_C3(SOT, HY, ALnea): KBTS_C3(SOT, HY, ALea): KBTS_C3(SOT, HY, DOTTED_CIRCLE): KBTS_C3(SOT, HYPHEN, ALnea): KBTS_C3(SOT, HYPHEN, ALea): KBTS_C3(SOT, HYPHEN, DOTTED_CIRCLE): KBTS_C3(BK, HY, ALnea): KBTS_C3(BK, HY, ALea): KBTS_C3(BK, HY, DOTTED_CIRCLE): KBTS_C3(BK, HYPHEN, ALnea): KBTS_C3(BK, HYPHEN, ALea): KBTS_C3(BK, HYPHEN, DOTTED_CIRCLE): KBTS_C3(LF, HY, ALnea): KBTS_C3(LF, HY, ALea): KBTS_C3(LF, HY, DOTTED_CIRCLE): KBTS_C3(LF, HYPHEN, ALnea): KBTS_C3(LF, HYPHEN, ALea): KBTS_C3(LF, HYPHEN, DOTTED_CIRCLE): KBTS_C3(NL, HY, ALnea): KBTS_C3(NL, HY, ALea): KBTS_C3(NL, HY, DOTTED_CIRCLE): KBTS_C3(NL, HYPHEN, ALnea): KBTS_C3(NL, HYPHEN, ALea): KBTS_C3(NL, HYPHEN, DOTTED_CIRCLE): KBTS_C3(CR, HY, ALnea): KBTS_C3(CR, HY, ALea): KBTS_C3(CR, HY, DOTTED_CIRCLE): KBTS_C3(CR, HYPHEN, ALnea): KBTS_C3(CR, HYPHEN, ALea): KBTS_C3(CR, HYPHEN, DOTTED_CIRCLE): KBTS_C3(SP, HY, ALnea): KBTS_C3(SP, HY, ALea): KBTS_C3(SP, HY, DOTTED_CIRCLE): KBTS_C3(SP, HYPHEN, ALnea): KBTS_C3(SP, HYPHEN, ALea): KBTS_C3(SP, HYPHEN, DOTTED_CIRCLE): KBTS_C3(ZW, HY, ALnea): KBTS_C3(ZW, HY, ALea): KBTS_C3(ZW, HY, DOTTED_CIRCLE): KBTS_C3(ZW, HYPHEN, ALnea): KBTS_C3(ZW, HYPHEN, ALea): KBTS_C3(ZW, HYPHEN, DOTTED_CIRCLE): KBTS_C3(CB, HY, ALnea): KBTS_C3(CB, HY, ALea): KBTS_C3(CB, HY, DOTTED_CIRCLE): KBTS_C3(CB, HYPHEN, ALnea): KBTS_C3(CB, HYPHEN, ALea): KBTS_C3(CB, HYPHEN, DOTTED_CIRCLE): KBTS_C3(GLnea, HY, ALnea): KBTS_C3(GLnea, HY, ALea): KBTS_C3(GLnea, HY, DOTTED_CIRCLE): KBTS_C3(GLnea, HYPHEN, ALnea): KBTS_C3(GLnea, HYPHEN, ALea): KBTS_C3(GLnea, HYPHEN, DOTTED_CIRCLE): KBTS_C3(GLea, HY, ALnea): KBTS_C3(GLea, HY, ALea): KBTS_C3(GLea, HY, DOTTED_CIRCLE): KBTS_C3(GLea, HYPHEN, ALnea): KBTS_C3(GLea, HYPHEN, ALea): KBTS_C3(GLea, HYPHEN, DOTTED_CIRCLE): KBTS_C3(NU, SY, POea): KBTS_C3(NU, SY, POnea): KBTS_C3(NU, SY, PRea): KBTS_C3(NU, SY, PRnea): KBTS_C3(NU, SY, NU): KBTS_C3(NU, IS, POea): KBTS_C3(NU, IS, POnea): KBTS_C3(NU, IS, PRea): KBTS_C3(NU, IS, PRnea): KBTS_C3(NU, IS, NU): KBTS_C3(NU, CLea, POea): KBTS_C3(NU, CLea, POnea): KBTS_C3(NU, CLea, PRea): KBTS_C3(NU, CLea, PRnea): KBTS_C3(NU, CLnea, POea): KBTS_C3(NU, CLnea, POnea): KBTS_C3(NU, CLnea, PRea): KBTS_C3(NU, CLnea, PRnea): KBTS_C3(NU, CPea, POea): KBTS_C3(NU, CPea, POnea): KBTS_C3(NU, CPea, PRea): KBTS_C3(NU, CPea, PRnea): KBTS_C3(NU, CPnea, POea): KBTS_C3(NU, CPnea, POnea): KBTS_C3(NU, CPnea, PRea): KBTS_C3(NU, CPnea, PRnea): KBTS_C3(AK, VI, AK): KBTS_C3(AK, VI, DOTTED_CIRCLE): KBTS_C3(DOTTED_CIRCLE, VI, AK): KBTS_C3(DOTTED_CIRCLE, VI, DOTTED_CIRCLE): KBTS_C3(AS, VI, AK): KBTS_C3(AS, VI, DOTTED_CIRCLE): KBTS_LINE_UNBREAK(0, 1); break; KBTS_C3(POea, OPea, NU): KBTS_C3(POea, OPnea, NU): KBTS_C3(POnea, OPea, NU): KBTS_C3(POnea, OPnea, NU): KBTS_C3(PRea, OPea, NU): KBTS_C3(PRea, OPnea, NU): KBTS_C3(PRnea, OPea, NU): KBTS_C3(PRnea, OPnea, NU): KBTS_LINE_UNBREAK(0, 2); break; KBTS_C3(AK, AK, VF): KBTS_C3(AK, DOTTED_CIRCLE, VF): KBTS_C3(AK, AS, VF): KBTS_C3(DOTTED_CIRCLE, AK, VF): KBTS_C3(DOTTED_CIRCLE, DOTTED_CIRCLE, VF): KBTS_C3(DOTTED_CIRCLE, AS, VF): KBTS_C3(AS, AK, VF): KBTS_C3(AS, DOTTED_CIRCLE, VF): KBTS_C3(AS, AS, VF): KBTS_LINE_UNBREAK(0, 2); break; KBTS_C3(HL, BAnea, Oea): KBTS_C3(HL, BAnea, Onea): KBTS_C3(HL, BAnea, Ope): KBTS_C3(HL, BAnea, BK): KBTS_C3(HL, BAnea, CR): KBTS_C3(HL, BAnea, LF): KBTS_C3(HL, BAnea, NL): KBTS_C3(HL, BAnea, SP): KBTS_C3(HL, BAnea, ZW): KBTS_C3(HL, BAnea, WJ): KBTS_C3(HL, BAnea, GLea): KBTS_C3(HL, BAnea, GLnea): KBTS_C3(HL, BAnea, CLea): KBTS_C3(HL, BAnea, CLnea): KBTS_C3(HL, BAnea, CPea): KBTS_C3(HL, BAnea, CPnea): KBTS_C3(HL, BAnea, EXea): KBTS_C3(HL, BAnea, EXnea): KBTS_C3(HL, BAnea, SY): KBTS_C3(HL, BAnea, BAea): KBTS_C3(HL, BAnea, BAnea): KBTS_C3(HL, BAnea, OPea): KBTS_C3(HL, BAnea, OPnea): KBTS_C3(HL, BAnea, QU): KBTS_C3(HL, BAnea, QUPi): KBTS_C3(HL, BAnea, QUPf): KBTS_C3(HL, BAnea, IS): KBTS_C3(HL, BAnea, NSea): KBTS_C3(HL, BAnea, NSnea): KBTS_C3(HL, BAnea, B2): KBTS_C3(HL, BAnea, CB): KBTS_C3(HL, BAnea, HY): KBTS_C3(HL, BAnea, HYPHEN): KBTS_C3(HL, BAnea, INea): KBTS_C3(HL, BAnea, INnea): KBTS_C3(HL, BAnea, BB): KBTS_C3(HL, BAnea, ALea): KBTS_C3(HL, BAnea, ALnea): KBTS_C3(HL, BAnea, NU): KBTS_C3(HL, BAnea, PRea): KBTS_C3(HL, BAnea, PRnea): KBTS_C3(HL, BAnea, IDea): KBTS_C3(HL, BAnea, IDnea): KBTS_C3(HL, BAnea, IDpe): KBTS_C3(HL, BAnea, EBea): KBTS_C3(HL, BAnea, EBnea): KBTS_C3(HL, BAnea, EM): KBTS_C3(HL, BAnea, POea): KBTS_C3(HL, BAnea, POnea): KBTS_C3(HL, BAnea, JL): KBTS_C3(HL, BAnea, JV): KBTS_C3(HL, BAnea, JT): KBTS_C3(HL, BAnea, H2): KBTS_C3(HL, BAnea, H3): KBTS_C3(HL, BAnea, AP): KBTS_C3(HL, BAnea, AK): KBTS_C3(HL, BAnea, DOTTED_CIRCLE): KBTS_C3(HL, BAnea, AS): KBTS_C3(HL, BAnea, VF): KBTS_C3(HL, BAnea, VI): KBTS_C3(HL, BAnea, RI): KBTS_C3(HL, HYPHEN, Oea): KBTS_C3(HL, HYPHEN, Onea): KBTS_C3(HL, HYPHEN, Ope): KBTS_C3(HL, HYPHEN, BK): KBTS_C3(HL, HYPHEN, CR): KBTS_C3(HL, HYPHEN, LF): KBTS_C3(HL, HYPHEN, NL): KBTS_C3(HL, HYPHEN, SP): KBTS_C3(HL, HYPHEN, ZW): KBTS_C3(HL, HYPHEN, WJ): KBTS_C3(HL, HYPHEN, GLea): KBTS_C3(HL, HYPHEN, GLnea): KBTS_C3(HL, HYPHEN, CLea): KBTS_C3(HL, HYPHEN, CLnea): KBTS_C3(HL, HYPHEN, CPea): KBTS_C3(HL, HYPHEN, CPnea): KBTS_C3(HL, HYPHEN, EXea): KBTS_C3(HL, HYPHEN, EXnea): KBTS_C3(HL, HYPHEN, SY): KBTS_C3(HL, HYPHEN, BAea): KBTS_C3(HL, HYPHEN, BAnea): KBTS_C3(HL, HYPHEN, OPea): KBTS_C3(HL, HYPHEN, OPnea): KBTS_C3(HL, HYPHEN, QU): KBTS_C3(HL, HYPHEN, QUPi): KBTS_C3(HL, HYPHEN, QUPf): KBTS_C3(HL, HYPHEN, IS): KBTS_C3(HL, HYPHEN, NSea): KBTS_C3(HL, HYPHEN, NSnea): KBTS_C3(HL, HYPHEN, B2): KBTS_C3(HL, HYPHEN, CB): KBTS_C3(HL, HYPHEN, HY): KBTS_C3(HL, HYPHEN, HYPHEN): KBTS_C3(HL, HYPHEN, INea): KBTS_C3(HL, HYPHEN, INnea): KBTS_C3(HL, HYPHEN, BB): KBTS_C3(HL, HYPHEN, ALea): KBTS_C3(HL, HYPHEN, ALnea): KBTS_C3(HL, HYPHEN, NU): KBTS_C3(HL, HYPHEN, PRea): KBTS_C3(HL, HYPHEN, PRnea): KBTS_C3(HL, HYPHEN, IDea): KBTS_C3(HL, HYPHEN, IDnea): KBTS_C3(HL, HYPHEN, IDpe): KBTS_C3(HL, HYPHEN, EBea): KBTS_C3(HL, HYPHEN, EBnea): KBTS_C3(HL, HYPHEN, EM): KBTS_C3(HL, HYPHEN, POea): KBTS_C3(HL, HYPHEN, POnea): KBTS_C3(HL, HYPHEN, JL): KBTS_C3(HL, HYPHEN, JV): KBTS_C3(HL, HYPHEN, JT): KBTS_C3(HL, HYPHEN, H2): KBTS_C3(HL, HYPHEN, H3): KBTS_C3(HL, HYPHEN, AP): KBTS_C3(HL, HYPHEN, AK): KBTS_C3(HL, HYPHEN, DOTTED_CIRCLE): KBTS_C3(HL, HYPHEN, AS): KBTS_C3(HL, HYPHEN, VF): KBTS_C3(HL, HYPHEN, VI): KBTS_C3(HL, HYPHEN, RI): KBTS_C3(HL, HY, Oea): KBTS_C3(HL, HY, Onea): KBTS_C3(HL, HY, Ope): KBTS_C3(HL, HY, BK): KBTS_C3(HL, HY, CR): KBTS_C3(HL, HY, LF): KBTS_C3(HL, HY, NL): KBTS_C3(HL, HY, SP): KBTS_C3(HL, HY, ZW): KBTS_C3(HL, HY, WJ): KBTS_C3(HL, HY, GLea): KBTS_C3(HL, HY, GLnea): KBTS_C3(HL, HY, CLea): KBTS_C3(HL, HY, CLnea): KBTS_C3(HL, HY, CPea): KBTS_C3(HL, HY, CPnea): KBTS_C3(HL, HY, EXea): KBTS_C3(HL, HY, EXnea): KBTS_C3(HL, HY, SY): KBTS_C3(HL, HY, BAea): KBTS_C3(HL, HY, BAnea): KBTS_C3(HL, HY, OPea): KBTS_C3(HL, HY, OPnea): KBTS_C3(HL, HY, QU): KBTS_C3(HL, HY, QUPi): KBTS_C3(HL, HY, QUPf): KBTS_C3(HL, HY, IS): KBTS_C3(HL, HY, NSea): KBTS_C3(HL, HY, NSnea): KBTS_C3(HL, HY, B2): KBTS_C3(HL, HY, CB): KBTS_C3(HL, HY, HY): KBTS_C3(HL, HY, HYPHEN): KBTS_C3(HL, HY, INea): KBTS_C3(HL, HY, INnea): KBTS_C3(HL, HY, BB): KBTS_C3(HL, HY, ALea): KBTS_C3(HL, HY, ALnea): KBTS_C3(HL, HY, NU): KBTS_C3(HL, HY, PRea): KBTS_C3(HL, HY, PRnea): KBTS_C3(HL, HY, IDea): KBTS_C3(HL, HY, IDnea): KBTS_C3(HL, HY, IDpe): KBTS_C3(HL, HY, EBea): KBTS_C3(HL, HY, EBnea): KBTS_C3(HL, HY, EM): KBTS_C3(HL, HY, POea): KBTS_C3(HL, HY, POnea): KBTS_C3(HL, HY, JL): KBTS_C3(HL, HY, JV): KBTS_C3(HL, HY, JT): KBTS_C3(HL, HY, H2): KBTS_C3(HL, HY, H3): KBTS_C3(HL, HY, AP): KBTS_C3(HL, HY, AK): KBTS_C3(HL, HY, DOTTED_CIRCLE): KBTS_C3(HL, HY, AS): KBTS_C3(HL, HY, VF): KBTS_C3(HL, HY, VI): KBTS_C3(HL, HY, RI): KBTS_LINE_UNBREAK(0, 1); break; } switch(LineBreakHistory) { KBTS_C4(NU, SY, CLnea, POnea): KBTS_C4(NU, SY, CLnea, POea): KBTS_C4(NU, SY, CLnea, PRnea): KBTS_C4(NU, SY, CLnea, PRea): KBTS_C4(NU, SY, CLea, POnea): KBTS_C4(NU, SY, CLea, POea): KBTS_C4(NU, SY, CLea, PRnea): KBTS_C4(NU, SY, CLea, PRea): KBTS_C4(NU, SY, CPnea, POnea): KBTS_C4(NU, SY, CPnea, POea): KBTS_C4(NU, SY, CPnea, PRnea): KBTS_C4(NU, SY, CPnea, PRea): KBTS_C4(NU, SY, CPea, POnea): KBTS_C4(NU, SY, CPea, POea): KBTS_C4(NU, SY, CPea, PRnea): KBTS_C4(NU, SY, CPea, PRea): KBTS_C4(NU, IS, CLnea, POnea): KBTS_C4(NU, IS, CLnea, POea): KBTS_C4(NU, IS, CLnea, PRnea): KBTS_C4(NU, IS, CLnea, PRea): KBTS_C4(NU, IS, CLea, POnea): KBTS_C4(NU, IS, CLea, POea): KBTS_C4(NU, IS, CLea, PRnea): KBTS_C4(NU, IS, CLea, PRea): KBTS_C4(NU, IS, CPnea, POnea): KBTS_C4(NU, IS, CPnea, POea): KBTS_C4(NU, IS, CPnea, PRnea): KBTS_C4(NU, IS, CPnea, PRea): KBTS_C4(NU, IS, CPea, POnea): KBTS_C4(NU, IS, CPea, POea): KBTS_C4(NU, IS, CPea, PRnea): KBTS_C4(NU, IS, CPea, PRea): KBTS_LINE_UNBREAK(0, 1); break; KBTS_C4(POea, OPea, IS, NU): KBTS_C4(POea, OPnea, IS, NU): KBTS_C4(POnea, OPea, IS, NU): KBTS_C4(POnea, OPnea, IS, NU): KBTS_C4(PRea, OPea, IS, NU): KBTS_C4(PRea, OPnea, IS, NU): KBTS_C4(PRnea, OPea, IS, NU): KBTS_C4(PRnea, OPnea, IS, NU): KBTS_LINE_UNBREAK(0, 3); break; } if(StartOfText) { // Never break lines. KBTS_LINE_UNBREAK(5, 1); // Always break graphemes. KBTS_BREAK(KBTS_BREAK_FLAG_GRAPHEME, 1); } #undef KBTS_C1 #undef KBTS_C2 #undef KBTS_C3 #undef KBTS_C4 #undef KBTS_REQUIRED_LINE_BREAK #undef KBTS_LINE_BREAK #undef KBTS_LINE_UNBREAK { kbts_u64 EffectiveLineBreaks = LineBreaks & ~(LineUnbreaks | LineUnbreaksAsync); kbts_DoLineBreak(State, PositionOffset3 + LineBreak3PositionOffset, EffectiveLineBreaks >> 48, 0, 0); if(EndOfText) { kbts_DoLineBreak(State, PositionOffset2 + LineBreak2PositionOffset, EffectiveLineBreaks >> 32, 0, 0); { // @Cleanup: This is the same flag code as DoLineBreak, but we want to use FlagState buffering for this. // The only places where we want to manually call DoBreak is for asynchronous/buffered guys. kbts_u8 FlushFlags = 0; if((EffectiveLineBreaks >> 16) & KBTS_LINE_BREAK_ALLOWED_MASK) FlushFlags |= KBTS_BREAK_FLAG_LINE_SOFT; if((EffectiveLineBreaks >> 16) & KBTS_LINE_BREAK_REQUIRED_MASK) FlushFlags |= KBTS_BREAK_FLAG_LINE_HARD; KBTS_BREAK(FlushFlags, 1); } // Lines are never broken after the end of text. } } State->LineBreaks = LineBreaks; State->LineUnbreaks = LineUnbreaks; State->LineBreak2PositionOffset = 0; State->LineBreak3PositionOffset = LineBreak2PositionOffset; State->LastLineBreakClass = LineBreakClass; State->LineBreakHistory = LineBreakHistory; State->LastDirection = (kbts_u8)LastDirection; if(0) { LineBreakAbsorbCharacter:; State->LineBreak2PositionOffset -= PositionIncrement; State->LineBreak3PositionOffset -= PositionIncrement; } // This always gets updated. State->LineUnbreaksAsync = LineUnbreaksAsync; } // This is where we flush the normal breaks that don't need any special position adjustment. kbts_DoBreak(State, PositionOffset3, (FlagState >> 24) & 0xFF, LastDirection, State->LastScripts[1]); if(EndOfText) { kbts_DoBreak(State, PositionOffset2, (FlagState >> 16) & 0xFF, 0, LastScript); kbts_DoBreak(State, 0, (FlagState >> 8) & 0xFF, 0, Script); kbts_DoBreak(State, PositionIncrement, FlagState & 0xFF, 0, Script); } State->FlagState = FlagState; State->Flags |= KBTS_BREAK_STATE_FLAG_STARTED; if(EndOfText) State->Flags |= KBTS_BREAK_STATE_FLAG_END; State->PositionOffset2 = (kbts_s16)-(int)PositionIncrement; State->PositionOffset3 = (kbts_s16)(PositionOffset2 - (int)PositionIncrement); State->CurrentPosition += PositionIncrement; State->LastScripts[1] = State->LastScripts[0]; State->LastScripts[0] = Script; #undef KBTS_BREAK #undef KBTS_BREAK2 } KBTS_EXPORT void kbts_BreakFlush(kbts_break_state *State) { // We pass 3, aka. ASCII end-of-text, at the end of text. kbts_BreakAddCodepoint_(State, 3, 0, 1); } KBTS_EXPORT void kbts_BreakAddCodepoint(kbts_break_state *State, kbts_u32 Codepoint, kbts_u32 PositionIncrement, int EndOfText) { kbts_BreakAddCodepoint_(State, Codepoint, PositionIncrement, 0); if(EndOfText) kbts_BreakFlush(State); } KBTS_EXPORT int kbts_Break(kbts_break_state *State, kbts_break *Break) { int Result = 0; kbts_un Threshold = State->Flags & KBTS_BREAK_STATE_FLAG_END ? 0 : KBTS_BREAK_REORDER_BUFFER_FLUSH_THRESHOLD; if(kbts_BreakStateIsValid(State) && (State->BreakCount > Threshold)) { kbts_break *ToFlush = &State->Breaks[State->BreakCount - 1]; // @Incomplete: Handle wrapping. if(ToFlush->Position >= State->LastFlushedBreakPosition) { *Break = *ToFlush; State->LastFlushedBreakPosition = ToFlush->Position; State->BreakCount -= 1; Result = 1; } else { State->Flags |= KBTS_BREAK_STATE_FLAG_RAN_OUT_OF_REORDER_BUFFER_SPACE; } } return Result; } KBTS_EXPORT void kbts_BeginBreak(kbts_break_state *State, kbts_direction MainDirection, kbts_japanese_line_break_style JapaneseLineBreakStyle) { if(State) { KBTS_MEMSET(State, 0, sizeof(*State)); State->MainDirection = (kbts_u8)MainDirection; State->JapaneseLineBreakStyle = JapaneseLineBreakStyle; } } KBTS_EXPORT kbts_decode kbts_DecodeUtf8(const char *Utf8, kbts_un Length) { kbts_decode Result = KBTS_ZERO; const char *Utf8Start = Utf8; if(Length) { kbts_u8 First = (kbts_u8)*Utf8++; kbts_un FollowupCharacterCount = 0; switch((First & 0xF0) >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: { Result.Codepoint = First & 0x7F; Result.Valid = 1; } break; case 0xC: case 0xD: { FollowupCharacterCount = 1; Result.Codepoint = First & 0x1F; Result.Valid = 1; } break; case 0xE: { FollowupCharacterCount = 2; Result.Codepoint = First & 0xF; Result.Valid = 1; } break; case 0xF: { FollowupCharacterCount = 3; Result.Codepoint = First & 7; Result.Valid = 1; } break; } if(Length > FollowupCharacterCount) { KBTS_FOR(FollowupCharacterIndex, 0, FollowupCharacterCount) { kbts_u8 C = (kbts_u8)*Utf8++; if((C & 0xC0) == 0x80) { Result.Codepoint = (Result.Codepoint << 6) | (C & 0x3F); } else { Result.Valid = 0; break; } } } else { Result.Valid = 0; } } Result.SourceCharactersConsumed = (kbts_u32)(Utf8 - Utf8Start); return Result; } KBTS_EXPORT int kbts_ShaperIsComplex(kbts_shaper Shaper) { int Result = Shaper != KBTS_SHAPER_DEFAULT; // @Incomplete? return Result; } KBTS_EXPORT int kbts_ScriptIsComplex(kbts_script Script) { kbts_script_properties *Properties = &kbts_ScriptProperties[Script]; int Result = kbts_ShaperIsComplex(Properties->Shaper); return Result; } #endif #undef KBTS_X_FEATURES