ui/modules/kb_text_shape/kb_text_shape.h

23193 lines
1.5 MiB

/* kb_text_shape - v1.02 - 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()
API
Segmentation
kbts_BeginBreak()
kbts_BreakAddCodepoint() -- Feed a codepoint to the breaker, call kbts_Break() after this
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_FeatureOverride() -- Describe a manual override for a font feature
kbts_GlyphConfig() -- Bake per-glyph parameters (like feature overrides)
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()
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()
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.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_INDLUDED
# 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,
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_INIT << 1) - 1) | 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;
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_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_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_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_u32 EnabledOrAlternatePlusOne;
} kbts_feature_override;
typedef struct kbts_glyph_config
{
kbts_feature_set EnabledFeatures;
kbts_feature_set DisabledFeatures;
kbts_u32 FeatureOverrideCount;
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 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_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;
// Shaping
#ifndef KB_TEXT_SHAPE_NO_CRT
KBTS_EXPORT kbts_feature_override kbts_FeatureOverride(kbts_feature_id Id, int Alternate, kbts_u32 Value);
KBTS_EXPORT kbts_glyph_config kbts_GlyphConfig(kbts_feature_override *FeatureOverrides, kbts_u32 FeatureOverrideCount);
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 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);
#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 <assert.h>
# define KBTS_ASSERT(Cond) assert(Cond)
#else
#define KBTS_ASSERT(Cond)
#endif
# endif
#ifndef KB_TEXT_SHAPE_NO_CRT
#include <stdio.h>
#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},
};
static kbts_feature_id kbts_FeatureToId(kbts_feature_tag Feature)
{
kbts_feature_id Result = 0;
switch(Feature)
{
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_ByteSwapArray16(kbts_u16 *Array, kbts_un Count)
{
KBTS_FOR(It, 0, Count)
{
Array[It] = kbts_ByteSwap16(Array[It]);
}
}
static void kbts_ByteSwapArray32(kbts_u32 *Array, kbts_un Count)
{
KBTS_FOR(It, 0, Count)
{
Array[It] = kbts_ByteSwap32(Array[It]);
}
}
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;
}
KBTS_EXPORT kbts_feature_override kbts_FeatureOverride(kbts_feature_id Id, int Alternate, kbts_u32 Value)
{
kbts_feature_override Result = KBTS_ZERO;
Result.Id = Id;
if(Alternate)
{
Result.EnabledOrAlternatePlusOne = Value + 1;
}
else
{
Result.EnabledOrAlternatePlusOne = 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;
}
//
// 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_coverage *kbts_GetCoverage(kbts_sequence_context_3 *Context, kbts_un Index)
{
kbts_u16 *Offsets = (kbts_u16 *)(Context + 1);
kbts_coverage *Result = KBTS_POINTER_OFFSET(kbts_coverage, Context, 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;
}
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;
}
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;
kbts_u32 *Pointers;
kbts_un PointerCapacity;
kbts_un PointerCount;
} kbts_byteswap_context;
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;
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;
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);
kbts_ByteSwapArray16(&Feature->FeatureParamsOffset, 2);
kbts_ByteSwapArray16(LookupIndices, Feature->LookupIndexCount);
// 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_ByteSwapArray16(&Header->Major, 5);
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_ByteSwapArray16(&DefaultLangsys->LookupOrderOffset, 3);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, DefaultLangsys), DefaultLangsys->FeatureIndexCount);
}
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_ByteSwapArray16(&Langsys->LookupOrderOffset, 3);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Langsys), Langsys->FeatureIndexCount);
}
}
# 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_ByteSwapArray16(&FeatureVariations->Major, 2);
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_ByteSwapArray32(&Record->ConditionSetOffset, 2);
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_ByteSwapArray32(ConditionOffsets, Set->Count);
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_ByteSwapArray16(&Condition->Format, 4);
}
}
kbts_feature_table_substitution *FeatureSubst = KBTS_POINTER_OFFSET(kbts_feature_table_substitution, FeatureVariations, Record->FeatureTableSubstitutionOffset);
if(!kbts_AlreadyVisited(Context, FeatureSubst))
{
kbts_ByteSwapArray16(&FeatureSubst->Major, 3);
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_ByteSwapArray16(&Lookup->Type, 3);
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_ByteSwapArray16(SubtableOffsets, U16Count);
}
return Result;
}
static void kbts_ByteSwapCoverage(kbts_byteswap_context *Context, kbts_coverage *Coverage)
{
if(!kbts_AlreadyVisited(Context, Coverage))
{
kbts_ByteSwapArray16(&Coverage->Format, 2);
kbts_un U16Count = 0;
if(Coverage->Format == 1)
{
U16Count = Coverage->Count;
}
else if(Coverage->Format == 2)
{
U16Count = Coverage->Count * 3;
}
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Coverage), U16Count);
}
}
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_ByteSwapArray16((kbts_u16 *)&Anchor->X, U16Count);
}
}
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_ByteSwapArray16(BaseAnchorOffsets, Array->BaseCount * MarkClassCount);
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_ByteSwapArray16(&Device->U.Device.StartSize, 3);
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_ByteSwapArray16(Record, U16Count);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, MarkArray), MarkArray->Count * 2);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Set), Set->Count);
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_ByteSwapArray16(&Rule->BacktrackGlyphCount, U16Count);
}
}
}
}
#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_ByteSwapArray16(&ClassDef->StartGlyphId, 2);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, ClassDef), ClassDef->GlyphCount);
}
else if(*Base == 2)
{
kbts_class_definition_2 *ClassDef = (kbts_class_definition_2 *)Base;
ClassDef->Count = kbts_ByteSwap16(ClassDef->Count);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, ClassDef), ClassDef->Count * 3);
}
}
}
static kbts_u16 kbts_GlyphClassFromTable(kbts_u16 *ClassDefinitionBase, kbts_un Id)
{
kbts_u16 Result = 0;
// 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 = GlyphClasses[Offset];
}
}
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;
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 = Ranges->Class;
}
}
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(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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->SeqRuleSetCount);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Set), Set->Count);
KBTS_FOR(RuleIndex, 0, Set->Count)
{
kbts_sequence_rule *Rule = kbts_GetSequenceRule(Set, RuleIndex);
if(!kbts_AlreadyVisited(Context, Rule))
{
kbts_ByteSwapArray16(&Rule->GlyphCount, 2);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Rule), (kbts_un)Rule->GlyphCount - 1 + (kbts_un)Rule->SequenceLookupCount * 2);
}
}
}
}
}
else if(Base[0] == 2)
{
kbts_sequence_context_2 *Subst = (kbts_sequence_context_2 *)Base;
kbts_ByteSwapArray16(&Subst->ClassDefOffset, 2);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->ClassSequenceRuleSetCount);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Set), Set->Count);
KBTS_FOR(RuleIndex, 0, Set->Count)
{
kbts_class_sequence_rule *Rule = kbts_GetClassSequenceRule(Set, RuleIndex);
if(!kbts_AlreadyVisited(Context, Rule))
{
kbts_ByteSwapArray16(&Rule->GlyphCount, 2);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Rule), Rule->GlyphCount - 1 + 2 * Rule->SequenceLookupCount);
}
}
}
}
#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_ByteSwapArray16(&Subst->GlyphCount, 2);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->GlyphCount + 2 * Subst->SequenceLookupCount);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->ChainedSequenceRuleSetCount);
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_ByteSwapArray16(&Subst->BacktrackClassDefOffset, 4);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->ChainedClassSequenceRuleSetCount);
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_ByteSwapArray16(&Subst->BacktrackGlyphCount, U16Count);
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_ByteSwapArray16(GlyphIds, Subst->DeltaOrCount.GlyphCount);
#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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->SequenceCount);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Sequence), Sequence->GlyphCount);
}
#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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->AlternateSetCount);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Set), Set->GlyphCount);
}
#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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Subst), Subst->LigatureSetCount);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Set), Set->Count);
KBTS_FOR(LigatureIndex, 0, Set->Count)
{
kbts_ligature *Ligature = kbts_GetLigature(Set, LigatureIndex);
if(!kbts_AlreadyVisited(Context, Ligature))
{
kbts_ByteSwapArray16(&Ligature->Glyph, 2);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Ligature), Ligature->ComponentCount - 1);
# 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_ByteSwapArray16(&Subst->BacktrackGlyphCount, U16Count);
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_ByteSwapArray16(&Adjust->ValueFormat1, 3);
kbts_u16 *SetOffsets = KBTS_POINTER_AFTER(kbts_u16, Adjust);
kbts_ByteSwapArray16(SetOffsets, Adjust->SetCount);
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_ByteSwapArray16(&Adjust->ValueFormat1, 6);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Adjust), Adjust->EntryExitCount * 2);
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_ByteSwapArray16(&Adjust->BaseCoverageOffset, 4);
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_ByteSwapArray16(&Adjust->LigatureCoverageOffset, 4);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, LigatureArray), LigatureArray->Count);
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_ByteSwapArray16(AttachAnchorOffsets, Attach->Count * Adjust->MarkClassCount);
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)
{
kbts_u16 Class = 0;
if(Gdef->ClassDefinitionOffset)
{
kbts_u16 *ClassDefBase = KBTS_POINTER_OFFSET(kbts_u16, Gdef, Gdef->ClassDefinitionOffset);
Class = kbts_GlyphClassFromTable(ClassDefBase, Id);
}
if(Gdef->MarkAttachmentClassDefinitionOffset && (Class == KBTS_GLYPH_CLASS_MARK))
{
kbts_u16 *MarkAttachmentClassDefBase = KBTS_POINTER_OFFSET(kbts_u16, Gdef, Gdef->MarkAttachmentClassDefinitionOffset);
Result.MarkAttachmentClass = kbts_GlyphClassFromTable(MarkAttachmentClassDefBase, Id);
}
Result.Class = 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_FeatureToId(Feature.Tag);
kbts_u64 FeatureFlag = (FeatureId < 32) ? (1ull << FeatureId) : 0;
if(kbts_ContainsFeature(&It->EnabledFeatures, kbts_FeatureToId(Feature.Tag)))
{
It->Feature = Feature.Feature;
It->CurrentFeatureTag = Feature.Tag;
It->CurrentFeatureFlag = FeatureFlag & 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(rtla) |
KBTS_FEATURE_FLAG2(locl),
KBTS_FEATURE_FLAG3(rvrn) | KBTS_FEATURE_FLAG3(rtlm) | KBTS_FEATURE_FLAG3(stch)}},
/* 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;
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)
{
// @Cleanup: memmove
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_FeatureToId(Feature.Tag);
if(Feature.Feature->LookupIndexCount && kbts_ContainsFeature(&EnabledFeatures, FeatureId))
{
kbts_lookup_indices LookupIndices = KBTS_ZERO;
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)
{
LookupIndices.GlyphFilter = (FeatureId < 32) ? (1 << FeatureId) & KBTS_GLYPH_FEATURE_MASK : 0;
}
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_u16 CurrentGlyphClass = kbts_GlyphClassFromTable(ClassDefinitionBase, CurrentGlyph->Id);
kbts_class_sequence_rule_set *Set = kbts_GetClassSequenceRuleSet(Subst, CurrentGlyphClass);
if((CurrentGlyphClass < 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);
}
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);
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))
{
kbts_u16 Class = kbts_GlyphClassFromTable(BacktrackClassDefinition, BacktrackGlyph->Id);
BacktrackClasses[BacktrackClassCount++] = Class;
}
BacktrackGlyph -= 1;
}
kbts_un InputClassCountRequired = Unpacked.InputCount - 1 + Unpacked.LookaheadCount;
while((InputGlyph < OnePastLastGlyph) && (InputClassCount < InputClassCountRequired))
{
if(!kbts_SkipGlyph(InputGlyph, Lookup, SkipFlags, SkipUnicodeFlags))
{
kbts_u16 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_u16 LookaheadClass = InputClass;
if(LookaheadClassDefinition != InputClassDefinition)
{
LookaheadClass = kbts_GlyphClassFromTable(LookaheadClassDefinition, InputGlyph->Id);
}
InputClassOffsets[InputClassCount] = (kbts_u16)(InputGlyph - CurrentGlyph);
InputClasses[InputClassCount] = InputClass;
LookaheadClasses[InputClassCount] = LookaheadClass;
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;
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);
}
}
}
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);
kbts_u32 Class1 = kbts_GlyphClassFromTable(ClassDef1, CurrentGlyph->Id);
kbts_u32 Class2 = kbts_GlyphClassFromTable(ClassDef2, NextGlyphId);
kbts_u16 *PairRecord = PairRecords + Class1 * PairRecordSize * Adjust->Class2Count + Class2 * PairRecordSize;
Unpacked1 = kbts_UnpackValueRecord(Adjust, Adjust->ValueFormat1, PairRecord);
PairRecord += Size1;
Unpacked2 = kbts_UnpackValueRecord(Adjust, Adjust->ValueFormat2, PairRecord);
PairRecord += Size2;
}
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))
{
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_u32 DummyGlyphCount = (kbts_u32)GlyphCount;
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_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);
++Indices->Indices; --Indices->Count;
if(!Indices->Count)
{
S->FeatureLookupIndices[FeatureIndex--] = S->FeatureLookupIndices[--S->FeatureCount];
}
}
}
*LookupIndex = LowestIndex;
*SkipFlags_ = SkipFlags;
*GlyphFilter_ = GlyphFilter;
*FeatureSet_ = FeatureSet;
return LowestIndex != 0xFFFFFFFF;
}
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 = 0; // 0xABBBBBCCCCCDDDDD
for(; S->GlyphIndex < GlyphArray->Count; ++S->GlyphIndex)
{
kbts_u32 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,
kbts_glyph *DecompositionGlyphs = KBTS_POINTER_AFTER(kbts_glyph, S);
{ // Full NFD decomposition
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 = 0;
for(S->GlyphIndex = 0; S->GlyphIndex < S->WrittenCount; ++S->GlyphIndex)
{
ResumePoint5:;
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")
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;
kbts_op_state_normalize_hangul *NormalizeHangul = &S->OpSpecific.NormalizeHangul;
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 = {0};
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 = Font->ShapingTables[KBTS_SHAPING_TABLE_GSUB];
kbts_lookup_list *LookupList = kbts_GetLookupList(FontGsub);
kbts_gsub_frame *Frames = KBTS_POINTER_AFTER(kbts_gsub_frame, S);
kbts_op_state_gsub *Gsub = &S->OpSpecific.Gsub;
kbts_BeginFeatures(S, Config, KBTS_SHAPING_TABLE_GSUB, Op->Features);
kbts_u32 GlyphFilter;
kbts_skip_flags SkipFlags = 0;
kbts_feature_set LookupFeatures;
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))
{
// Handle per-glyph feature overrides.
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.
{
kbts_glyph_config DummyGlyphConfig = KBTS_ZERO;
kbts_glyph_config *GlyphConfig = &DummyGlyphConfig;
if(CurrentGlyph->Config)
{
GlyphConfig = CurrentGlyph->Config;
}
KBTS_FOR(WordIndex, 0, KBTS_ARRAY_LENGTH(GlyphConfig->EnabledFeatures.Flags))
{
kbts_u64 LookupFeatureFlags = LookupFeatures.Flags[WordIndex];
UserEnabled |= GlyphConfig->EnabledFeatures.Flags[WordIndex] & LookupFeatureFlags;
UserDisabled &= (GlyphConfig->DisabledFeatures.Flags[WordIndex] & LookupFeatureFlags) == LookupFeatureFlags;
DefaultEnabled |= LookupFeatures.Flags[WordIndex] & Config->Features->Flags[WordIndex];
}
}
if(!UserDisabled && (DefaultEnabled || UserEnabled))
{
S->FrameCount = 0;
{
kbts_gsub_frame *Frame = &Frames[S->FrameCount++];
Frame->LookupIndex = (kbts_u16)Gsub->LookupIndex;
Frame->SubtableIndex = 0;
Frame->InputGlyphIndex = (kbts_u16)S->GlyphIndex;
}
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_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;
kbts_u32 GlyphCount = 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;
kbts_script Script = ShapeState->Config->Script;
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 *Pstf = Config->Pstf;
kbts_feature *Blwf = Config->Blwf;
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] = {0};
kbts_glyph *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(uint8_t *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;
State->GlyphArray = kbts_GlyphArray(Glyphs, *GlyphCount, *GlyphCount, GlyphCapacity);
kbts_glyph_array *GlyphArray = &State->GlyphArray;
kbts_glyph_array *Cluster = &State->ClusterGlyphArray;
Cluster->Glyphs = Glyphs + State->At; // In case the Glyphs array moved after a grow.
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;
}
// 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 = &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 = 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)
{
// @Incomplete: Add a bounds checking/validation pass.
KBTS_UNUSED(Size);
Font->FileBase = (char *)Data;
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_table_record *)(Directory + 1);
kbts_un ShapingTableSizes[KBTS_SHAPING_TABLE_COUNT] = {0};
kbts_u32 GdefSize = 0;
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);
void *TableBase = KBTS_POINTER_OFFSET(void, Font->FileBase, Table->Offset);
switch(Table->Tag)
{
case KBTS_FOURCC('h', 'e', 'a', 'd'):
{
kbts_head *Head = (kbts_head *)TableBase;
kbts_ByteSwapArray16(&Head->Major, 2);
kbts_ByteSwapArray32(&Head->Revision, 2);
// We do not swap the magic number.
kbts_ByteSwapArray16(&Head->Flags, 2);
// We do not swap file times.
kbts_ByteSwapArray16((kbts_u16 *)&Head->XMin, 9);
Font->Head = Head;
} break;
case KBTS_FOURCC('c', 'm', 'a', 'p'):
{
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);
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);
kbts_u16 Format = kbts_ByteSwap16(*Subtable.Subtable);
if(Format == 14)
{
Font->Cmap14 = (kbts_cmap_14 *)Subtable.Subtable;
}
else if(!PreferredSubtable.Subtable)
{
PreferredSubtable = Subtable;
}
else
{
kbts_u16 Precedence = kbts_CmapFormatPrecedence[Format];
kbts_u16 PreferredPrecedence = kbts_CmapFormatPrecedence[PreferredFormat];
if((Precedence > PreferredPrecedence) || ((Precedence == PreferredPrecedence) && (Subtable.PlatformId == 3)))
{
PreferredSubtable = Subtable;
PreferredFormat = Format;
}
}
}
*PreferredSubtable.Subtable = kbts_ByteSwap16(*PreferredSubtable.Subtable);
switch(*PreferredSubtable.Subtable)
{
case 0:
{
kbts_cmap_0 *Cmap0 = (kbts_cmap_0 *)PreferredSubtable.Subtable;
Cmap0->Length = kbts_ByteSwap16(Cmap0->Length);
Cmap0->Language = kbts_ByteSwap16(Cmap0->Language);
}
break;
case 2:
{
kbts_cmap_2 *Cmap2 = (kbts_cmap_2 *)PreferredSubtable.Subtable;
kbts_ByteSwapArray16(&Cmap2->Length, 258);
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);
kbts_ByteSwapArray16(&SubHeaders->FirstCode, 4 * SubHeaderCount);
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);
}
kbts_ByteSwapArray16(GlyphIds, (kbts_un)GlyphIdCount);
}
break;
case 4:
{
kbts_cmap_4 *Cmap4 = (kbts_cmap_4 *)PreferredSubtable.Subtable;
kbts_ByteSwapArray16(&Cmap4->Length, 5);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Cmap4), Cmap4->SegmentCountTimesTwo * 2 + 1);
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));
}
}
kbts_ByteSwapArray16(GlyphIds, (kbts_un)GlyphIdCount);
}
break;
case 6:
{
kbts_cmap_6 *Cmap6 = (kbts_cmap_6 *)PreferredSubtable.Subtable;
kbts_ByteSwapArray16(&Cmap6->Length, 4);
kbts_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, Cmap6), Cmap6->EntryCount);
}
break;
case 12:
{
kbts_cmap_12_13 *Cmap12 = (kbts_cmap_12_13 *)PreferredSubtable.Subtable;
kbts_ByteSwapArray32(&Cmap12->Length, 3);
kbts_ByteSwapArray32(KBTS_POINTER_AFTER(kbts_u32, Cmap12), Cmap12->GroupCount * 3);
}
break;
}
Font->Cmap = PreferredSubtable.Subtable;
}
break;
case KBTS_FOURCC('G', 'D', 'E', 'F'):
{
Font->Gdef = (kbts_gdef *)TableBase;
GdefSize = Table->Length;
kbts_gdef *Gdef = Font->Gdef;
kbts_ByteSwapArray16(&Gdef->Major, 6);
if(Gdef->Minor >= 2)
{
Gdef->MarkGlyphSetsDefinitionOffset = kbts_ByteSwap16(Gdef->MarkGlyphSetsDefinitionOffset);
if(Gdef->Minor == 3)
{
// @Incomplete
Gdef->ItemVariationStoreOffset = kbts_ByteSwap32(Gdef->ItemVariationStoreOffset);
}
}
}
break;
case KBTS_FOURCC('G', 'S', 'U', 'B'):
case KBTS_FOURCC('G', 'P', 'O', 'S'):
{
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;
}
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;
Font->Hea[Orientation] = (kbts_hea *)TableBase;
kbts_ByteSwapArray16((kbts_u16 *)Font->Hea[Orientation], Table->Length / sizeof(kbts_u16));
}
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;
Font->Mtx[Orientation] = KBTS_POINTER_OFFSET(kbts_u16, Font->FileBase, Table->Offset);
kbts_ByteSwapArray16(Font->Mtx[Orientation], Table->Length / sizeof(kbts_u16));
}
break;
case KBTS_FOURCC('m', 'a', 'x', 'p'):
{
Font->Maxp = KBTS_POINTER_OFFSET(kbts_maxp, Font->FileBase, Table->Offset);
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;
}
kbts_ByteSwapArray16(&Font->Maxp->GlyphCount, U16Count);
Font->GlyphCount = Font->Maxp->GlyphCount;
}
break;
}
}
kbts_un Result = sizeof(kbts_u32) * ((ShapingTableSizes[KBTS_SHAPING_TABLE_GSUB] + ShapingTableSizes[KBTS_SHAPING_TABLE_GPOS] + GdefSize) / 2);
return (kbts_u32)Result;
}
KBTS_EXPORT kbts_un kbts_ReadFontData(kbts_font *Font, void *Scratch, kbts_un ScratchSize)
{
kbts_byteswap_context ByteSwapContext = KBTS_ZERO;
ByteSwapContext.FileBase = Font->FileBase;
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_ByteSwapArray16(&MarkGlyphSets->Format, 2);
if(MarkGlyphSets->Format == 1)
{
kbts_u32 *CoverageOffsets = KBTS_POINTER_AFTER(kbts_u32, MarkGlyphSets);
kbts_ByteSwapArray32(CoverageOffsets, MarkGlyphSets->MarkGlyphSetCount);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, LookupList), LookupList->Count);
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_ByteSwapArray16(KBTS_POINTER_AFTER(kbts_u16, LookupList), LookupList->Count);
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;
}
kbts_u32 Result = 1;
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;
kbts_un Result = GlyphLookupMatrixSizeInBytes + GlyphLookupSubtableMatrixSizeInBytes + sizeof(kbts_u32) * TotalLookupCount + sizeof(kbts_lookup_subtable_info) * TotalSubtableCount;
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
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_u32 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)
{
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);
kbts_u16 InputClass = kbts_GlyphClassFromTable(InputClassDefinition, Glyph.Id);
kbts_u16 LookaheadClass = kbts_GlyphClassFromTable(LookaheadClassDefinition, Glyph.Id);
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)
{
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