#include <iostream>
#include <numeric>
#include <cstdlib>
#include <cstddef>
#include <stdint.h>
enum {
// Config
ZERO_POS = 2,
INDEX_SIZE = 5,
VALUE_LIMIT = -100,
// Constants
NUM_ROWS = 37,
NUM_COLUMNS = 73,
VALUE_LIMIT_POS = -VALUE_LIMIT,
NUM_BIN_OUTLIERS = 8,
NUM_VALUES = NUM_ROWS * (NUM_COLUMNS - 1),
INDEX_PLUS = INDEX_SIZE - ZERO_POS - 1,
BIN4 = 0,
BIN12 = 1,
INDEX_FULL_SIZE = INDEX_SIZE + 2
};
int16_t my_array[NUM_ROWS][NUM_COLUMNS] = {
{150,145,140,135,130,125,120,115,110,105,100,95,90,85,80,75,70,65,60,55,50,45,40,35,30,25,20,15,10,5,0,-4,-9,-14,-19,-24,-29,-34,-39,-44,-49,-54,-59,-64,-69,-74,-79,-84,-89,-94,-99,104,109,114,119,124,129,134,139,144,149,154,159,164,169,174,179,175,170,165,160,155,150}, \
{143,137,131,126,120,115,110,105,100,95,90,85,80,75,71,66,62,57,53,48,44,39,35,31,27,22,18,14,9,5,1,-3,-7,-11,-16,-20,-25,-29,-34,-38,-43,-47,-52,-57,-61,-66,-71,-76,-81,-86,-91,-96,101,107,112,117,123,128,134,140,146,151,157,163,169,175,178,172,166,160,154,148,143}, \
{130,124,118,112,107,101,96,92,87,82,78,74,70,65,61,57,54,50,46,42,38,34,31,27,23,19,16,12,8,4,1,-2,-6,-10,-14,-18,-22,-26,-30,-34,-38,-43,-47,-51,-56,-61,-65,-70,-75,-79,-84,-89,-94,100,105,111,116,122,128,135,141,148,155,162,170,177,174,166,159,151,144,137,130}, \
{111,104,99,94,89,85,81,77,73,70,66,63,60,56,53,50,46,43,40,36,33,30,26,23,20,16,13,10,6,3,0,-3,-6,-9,-13,-16,-20,-24,-28,-32,-36,-40,-44,-48,-52,-57,-61,-65,-70,-74,-79,-84,-88,-93,-98,103,109,115,121,128,135,143,152,162,172,176,165,154,144,134,125,118,111}, \
{85,81,77,74,71,68,65,63,60,58,56,53,51,49,46,43,41,38,35,32,29,26,23,19,16,13,10,7,4,1,-1,-3,-6,-9,-13,-16,-19,-23,-26,-30,-34,-38,-42,-46,-50,-54,-58,-62,-66,-70,-74,-78,-83,-87,-91,-95,100,105,110,117,124,133,144,159,178,160,141,125,112,103,96,90,85}, \
{62,60,58,57,55,54,52,51,50,48,47,46,44,42,41,39,36,34,31,28,25,22,19,16,13,10,7,4,2,0,-3,-5,-8,-10,-13,-16,-19,-22,-26,-29,-33,-37,-41,-45,-49,-53,-56,-60,-64,-67,-70,-74,-77,-80,-83,-86,-89,-91,-94,-97,101,105,111,130,109,84,77,74,71,68,66,64,62}, \
{46,46,45,44,44,43,42,42,41,41,40,39,38,37,36,35,33,31,28,26,23,20,16,13,10,7,4,1,-1,-3,-5,-7,-9,-12,-14,-16,-19,-22,-26,-29,-33,-36,-40,-44,-48,-51,-55,-58,-61,-64,-66,-68,-71,-72,-74,-74,-75,-74,-72,-68,-61,-48,-25,2,22,33,40,43,45,46,47,46,46}, \
{36,36,36,36,36,35,35,35,35,34,34,34,34,33,32,31,30,28,26,23,20,17,14,10,6,3,0,-2,-4,-7,-9,-10,-12,-14,-15,-17,-20,-23,-26,-29,-32,-36,-40,-43,-47,-50,-53,-56,-58,-60,-62,-63,-64,-64,-63,-62,-59,-55,-49,-41,-30,-17,-4,6,15,22,27,31,33,34,35,36,36}, \
{30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,28,27,26,24,21,18,15,11,7,3,0,-3,-6,-9,-11,-12,-14,-15,-16,-17,-19,-21,-23,-26,-29,-32,-35,-39,-42,-45,-48,-51,-53,-55,-56,-57,-57,-56,-55,-53,-49,-44,-38,-31,-23,-14,-6,0,7,13,17,21,24,26,27,29,29,30}, \
{25,25,26,26,26,25,25,25,25,25,25,25,25,26,25,25,24,23,21,19,16,12,8,4,0,-3,-7,-10,-13,-15,-16,-17,-18,-19,-20,-21,-22,-23,-25,-28,-31,-34,-37,-40,-43,-46,-48,-49,-50,-51,-51,-50,-48,-45,-42,-37,-32,-26,-19,-13,-7,-1,3,7,11,14,17,19,21,23,24,25,25}, \
{21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,21,20,18,16,13,9,5,1,-3,-7,-11,-14,-17,-18,-20,-21,-21,-22,-22,-22,-23,-23,-25,-27,-29,-32,-35,-37,-40,-42,-44,-45,-45,-45,-44,-42,-40,-36,-32,-27,-22,-17,-12,-7,-3,0,3,7,9,12,14,16,18,19,20,21,21}, \
{18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,18,17,16,14,10,7,2,-1,-6,-10,-14,-17,-19,-21,-22,-23,-24,-24,-24,-24,-23,-23,-23,-24,-26,-28,-30,-33,-35,-37,-38,-39,-39,-38,-36,-34,-31,-28,-24,-19,-15,-10,-6,-3,0,1,4,6,8,10,12,14,15,16,17,18,18}, \
{16,16,17,17,17,17,17,17,17,17,17,16,16,16,16,16,16,15,13,11,8,4,0,-4,-9,-13,-16,-19,-21,-23,-24,-25,-25,-25,-25,-24,-23,-21,-20,-20,-21,-22,-24,-26,-28,-30,-31,-32,-31,-30,-29,-27,-24,-21,-17,-13,-9,-6,-3,-1,0,2,4,5,7,9,10,12,13,14,15,16,16}, \
{14,14,14,15,15,15,15,15,15,15,14,14,14,14,14,14,13,12,11,9,5,2,-2,-6,-11,-15,-18,-21,-23,-24,-25,-25,-25,-25,-24,-22,-21,-18,-16,-15,-15,-15,-17,-19,-21,-22,-24,-24,-24,-23,-22,-20,-18,-15,-12,-9,-5,-3,-1,0,1,2,4,5,6,8,9,10,11,12,13,14,14}, \
{12,13,13,13,13,13,13,13,13,13,13,13,12,12,12,12,11,10,9,6,3,0,-4,-8,-12,-16,-19,-21,-23,-24,-24,-24,-24,-23,-22,-20,-17,-15,-12,-10,-9,-9,-10,-12,-13,-15,-17,-17,-18,-17,-16,-15,-13,-11,-8,-5,-3,-1,0,1,1,2,3,4,6,7,8,9,10,11,12,12,12}, \
{11,11,11,11,11,12,12,12,12,12,11,11,11,11,11,10,10,9,7,5,2,-1,-5,-9,-13,-17,-20,-22,-23,-23,-23,-23,-22,-20,-18,-16,-14,-11,-9,-6,-5,-4,-5,-6,-8,-9,-11,-12,-12,-12,-12,-11,-9,-8,-6,-3,-1,0,0,1,1,2,3,4,5,6,7,8,9,10,11,11,11}, \
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,9,9,7,6,3,0,-3,-6,-10,-14,-17,-20,-21,-22,-22,-22,-21,-19,-17,-15,-13,-10,-8,-6,-4,-2,-2,-2,-2,-4,-5,-7,-8,-8,-9,-8,-8,-7,-5,-4,-2,0,0,1,1,1,2,2,3,4,5,6,7,8,9,10,10,10}, \
{9,9,9,9,9,9,9,10,10,9,9,9,9,9,9,8,8,6,5,2,0,-4,-7,-11,-15,-17,-19,-21,-21,-21,-20,-18,-16,-14,-12,-10,-8,-6,-4,-2,-1,0,0,0,-1,-2,-4,-5,-5,-6,-6,-5,-5,-4,-3,-1,0,0,1,1,1,1,2,3,3,5,6,7,8,8,9,9,9}, \
{9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,8,7,5,4,1,-1,-5,-8,-12,-15,-17,-19,-20,-20,-19,-18,-16,-14,-11,-9,-7,-5,-4,-2,-1,0,0,1,1,0,0,-2,-3,-3,-4,-4,-4,-3,-3,-2,-1,0,0,0,0,0,1,1,2,3,4,5,6,7,8,8,9,9}, \
{9,9,9,8,8,8,9,9,9,9,9,8,8,8,8,7,6,5,3,0,-2,-5,-9,-12,-15,-17,-18,-19,-19,-18,-16,-14,-12,-9,-7,-5,-4,-2,-1,0,0,1,1,1,1,0,0,-1,-2,-2,-3,-3,-2,-2,-1,-1,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,8,9}, \
{8,8,8,8,8,8,9,9,9,9,9,9,8,8,8,7,6,4,2,0,-3,-6,-9,-12,-15,-17,-18,-18,-17,-16,-14,-12,-10,-8,-6,-4,-2,-1,0,0,1,2,2,2,2,1,0,0,-1,-1,-1,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,8}, \
{8,8,8,8,9,9,9,9,9,9,9,9,9,8,8,7,5,3,1,-1,-4,-7,-10,-13,-15,-16,-17,-17,-16,-15,-13,-11,-9,-6,-5,-3,-2,0,0,0,1,2,2,2,2,1,1,0,0,0,-1,-1,-1,-1,-1,0,0,0,0,-1,-1,-1,-1,-1,0,0,1,3,4,5,7,7,8}, \
{8,8,9,9,9,9,10,10,10,10,10,10,10,9,8,7,5,3,0,-2,-5,-8,-11,-13,-15,-16,-16,-16,-15,-13,-12,-10,-8,-6,-4,-2,-1,0,0,1,2,2,3,3,2,2,1,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-2,-1,0,0,1,3,4,6,7,8}, \
{7,8,9,9,9,10,10,11,11,11,11,11,10,10,9,7,5,3,0,-2,-6,-9,-11,-13,-15,-16,-16,-15,-14,-13,-11,-9,-7,-5,-3,-2,0,0,1,1,2,3,3,3,3,2,2,1,1,0,0,0,0,0,0,0,-1,-1,-2,-3,-3,-4,-4,-4,-3,-2,-1,0,1,3,5,6,7}, \
{6,8,9,9,10,11,11,12,12,12,12,12,11,11,9,7,5,2,0,-3,-7,-10,-12,-14,-15,-16,-15,-15,-13,-12,-10,-8,-7,-5,-3,-1,0,0,1,2,2,3,3,4,3,3,3,2,2,1,1,1,0,0,0,0,-1,-2,-3,-4,-4,-5,-5,-5,-5,-4,-2,-1,0,2,3,5,6}, \
{6,7,8,10,11,12,12,13,13,14,14,13,13,11,10,8,5,2,0,-4,-8,-11,-13,-15,-16,-16,-16,-15,-13,-12,-10,-8,-6,-5,-3,-1,0,0,1,2,3,3,4,4,4,4,4,3,3,3,2,2,1,1,0,0,-1,-2,-3,-5,-6,-7,-7,-7,-6,-5,-4,-3,-1,0,2,4,6}, \
{5,7,8,10,11,12,13,14,15,15,15,14,14,12,11,8,5,2,-1,-5,-9,-12,-14,-16,-17,-17,-16,-15,-14,-12,-11,-9,-7,-5,-3,-1,0,0,1,2,3,4,4,5,5,5,5,5,5,4,4,3,3,2,1,0,-1,-2,-4,-6,-7,-8,-8,-8,-8,-7,-6,-4,-2,0,1,3,5}, \
{4,6,8,10,12,13,14,15,16,16,16,16,15,13,11,9,5,2,-2,-6,-10,-13,-16,-17,-18,-18,-17,-16,-15,-13,-11,-9,-7,-5,-4,-2,0,0,1,3,3,4,5,6,6,7,7,7,7,7,6,5,4,3,2,0,-1,-3,-5,-7,-8,-9,-10,-10,-10,-9,-7,-5,-4,-1,0,2,4}, \
{4,6,8,10,12,14,15,16,17,18,18,17,16,15,12,9,5,1,-3,-8,-12,-15,-18,-19,-20,-20,-19,-18,-16,-15,-13,-11,-8,-6,-4,-2,-1,0,1,3,4,5,6,7,8,9,9,9,9,9,9,8,7,5,3,1,-1,-3,-6,-8,-10,-11,-12,-12,-11,-10,-9,-7,-5,-2,0,1,4}, \
{4,6,8,11,13,15,16,18,19,19,19,19,18,16,13,10,5,0,-5,-10,-15,-18,-21,-22,-23,-22,-22,-20,-18,-17,-14,-12,-10,-8,-5,-3,-1,0,1,3,5,6,8,9,10,11,12,12,13,12,12,11,9,7,5,2,0,-3,-6,-9,-11,-12,-13,-13,-12,-11,-10,-8,-6,-3,-1,1,4}, \
{3,6,9,11,14,16,17,19,20,21,21,21,19,17,14,10,4,-1,-8,-14,-19,-22,-25,-26,-26,-26,-25,-23,-21,-19,-17,-14,-12,-9,-7,-4,-2,0,1,3,5,7,9,11,13,14,15,16,16,16,16,15,13,10,7,4,0,-3,-7,-10,-12,-14,-15,-14,-14,-12,-11,-9,-6,-4,-1,1,3}, \
{4,6,9,12,14,17,19,21,22,23,23,23,21,19,15,9,2,-5,-13,-20,-25,-28,-30,-31,-31,-30,-29,-27,-25,-22,-20,-17,-14,-11,-9,-6,-3,0,1,4,6,9,11,13,15,17,19,20,21,21,21,20,18,15,11,6,2,-2,-7,-11,-13,-15,-16,-16,-15,-13,-11,-9,-7,-4,-1,1,4}, \
{4,7,10,13,15,18,20,22,24,25,25,25,23,20,15,7,-2,-12,-22,-29,-34,-37,-38,-38,-37,-36,-34,-31,-29,-26,-23,-20,-17,-13,-10,-7,-4,-1,2,5,8,11,13,16,18,21,23,24,26,26,26,26,24,21,17,12,5,0,-6,-10,-14,-16,-16,-16,-15,-14,-12,-10,-7,-4,-1,1,4}, \
{4,7,10,13,16,19,22,24,26,27,27,26,24,19,11,-1,-15,-28,-37,-43,-46,-47,-47,-45,-44,-41,-39,-36,-32,-29,-26,-22,-19,-15,-11,-8,-4,-1,2,5,9,12,15,19,22,24,27,29,31,33,33,33,32,30,26,21,14,6,0,-6,-11,-14,-15,-16,-15,-14,-12,-9,-7,-4,-1,1,4}, \
{6,9,12,15,18,21,23,25,27,28,27,24,17,4,-14,-34,-49,-56,-60,-60,-60,-58,-56,-53,-50,-47,-43,-40,-36,-32,-28,-25,-21,-17,-13,-9,-5,-1,2,6,10,14,17,21,24,28,31,34,37,39,41,42,43,43,41,38,33,25,17,8,0,-4,-8,-10,-10,-10,-8,-7,-4,-2,0,3,6}, \
{22,24,26,28,30,32,33,31,23,-18,-81,-96,-99,-98,-95,-93,-89,-86,-82,-78,-74,-70,-66,-62,-57,-53,-49,-44,-40,-36,-32,-27,-23,-19,-14,-10,-6,-1,2,6,10,15,19,23,27,31,35,38,42,45,49,52,55,57,60,61,63,63,62,61,57,53,47,40,33,28,23,21,19,19,19,20,22}, \
{168,173,178,176,171,166,161,156,151,146,141,136,131,126,121,116,111,106,101,-96,-91,-86,-81,-76,-71,-66,-61,-56,-51,-46,-41,-36,-31,-26,-21,-16,-11,-6,-1,3,8,13,18,23,28,33,38,43,48,53,58,63,68,73,78,83,88,93,98,103,108,113,118,123,128,133,138,143,148,153,158,163,168}};
using namespace std;
uint16_t compacted[] = {
0, 0x4b, 0x292, 0x776, 0x9ce, 0xa18, 0xa55, 0xa68,
0x601f, 0xea09, 0x4e8c, 0xafff, 0xbfed, 0x6ff1, 0x10fe, 0xfdb1,
0xa100, 0xd1fe, 0xd800, 0x129f, 0xf010, 0x730f, 0x9ec1, 0x80e9,
0x9a9c, 0x8888, 0x9880, 0x1, 0x2ab9, 0x8105, 0x101, 0xdfb8,
0xfeaf, 0xc030, 0x8100, 0x930, 0x8c1, 0xcaf4, 0, 0xfff6,
0xefb9, 0x416, 0x78eb, 0xe5d2, 0xeaf7, 0x597e, 0x8a50, 0xf278,
0x30c, 0xad5a, 0x7f2a, 0x96cd, 0x860a, 0xbad7, 0x2145, 0x1b7,
0x807f, 0xba8f, 0x8b22, 0x40c9, 0xcfe5, 0x43c, 0x56a9, 0x75e4,
0x6b43, 0x23e, 0x3db4, 0xac48, 0x71bf, 0xeaf9, 0x4a9a, 0xe927,
0x855, 0xe54, 0xd56f, 0xe170, 0x1c88, 0x57c, 0x99b2, 0xfd79,
0xa8c8, 0xf5f6, 0xcd89, 0xfd66, 0x9815, 0xc126, 0x32e1, 0x56f,
0xfe7a, 0xd86d, 0x155b, 0x4a22, 0x62d2, 0x36b8, 0x877e, 0xbd70,
0x2746, 0xa87f, 0x169d, 0x4af0, 0xe059, 0x6cfb, 0xb27a, 0x49a6,
0xae32, 0xd0ab, 0x14b1, 0xa498, 0xb5e9, 0xae0e, 0x9427, 0x9b4f,
0x4957, 0xebd5, 0xf1fa, 0xf288, 0xff72, 0xc29f, 0x475e, 0xf4ca,
0xaa0e, 0xd455, 0x1b1f, 0xeaee, 0xf2ba, 0xaee, 0x96d2, 0xa942,
0xaeed, 0x8a5a, 0xdfda, 0x3ce7, 0x31d2, 0x60cb, 0xe98d, 0x8162,
0xb0c, 0x27af, 0x6e6c, 0xd2e5, 0x6022, 0xe421, 0xe7f7, 0x394a,
0x173b, 0xed47, 0xaef7, 0x4b78, 0x283b, 0x9d78, 0x3e13, 0x4a6,
0xa6e, 0xcda6, 0x3bb0, 0x62b7, 0x2b9a, 0xee3f, 0xda27, 0x88ee,
0x8280, 0xe658, 0x1668, 0xb701, 0x4e70, 0x147, 0xe058, 0xa1a0,
0x3455, 0x5994, 0xd390, 0x1fac, 0xb58c, 0x3680, 0x3d42, 0xf12,
0xba9e, 0x949f, 0x51df, 0x9603, 0x52af, 0x74d8, 0xbdc7, 0xefe9,
0x3b5e, 0xe273, 0xbae, 0x13c4, 0x5844, 0x3c6d, 0xf045, 0x52ba,
0x6ef2, 0xa428, 0x67b7, 0x91f7, 0x31ee, 0xbcb9, 0xfe7f, 0xefd3,
0x367e, 0x4308, 0x2b58, 0xbd30, 0xc4bd, 0xa28f, 0xca5d, 0x2230,
0x8f65, 0x134e, 0xaaa8, 0x6499, 0x4a14, 0x15ec, 0xf83f, 0x8c92,
0x3928, 0x2d35, 0x176f, 0x1080, 0xc982, 0x1bae, 0xfb7a, 0x616a,
0xc069, 0x8177, 0xe7f3, 0x70e3, 0x5d99, 0x8dfa, 0xdf80, 0x364b,
0x6b3f, 0x1aec, 0x66c8, 0x87cc, 0xd62f, 0x687, 0x9a3d, 0x3704,
0xe486, 0xa47e, 0xa87a, 0x1bd, 0xd8e2, 0x9f6d, 0xdd2, 0xd150,
0xcdf3, 0xb4e4, 0x9bd7, 0xabc9, 0x52e8, 0x553c, 0xa2ab, 0x18b8,
0x70fb, 0xa594, 0xd34c, 0x9450, 0xd928, 0xd581, 0x54a, 0x3096,
0x30c7, 0x6899, 0xcfd0, 0x5a37, 0xa664, 0xfe0, 0x4b1a, 0x616c,
0x9eba, 0x591a, 0xfa80, 0x2911, 0x2c5b, 0xe310, 0x32e1, 0x3680,
0x55a8, 0x7e, 0xd7fd, 0xe81d, 0x13f2, 0x919d, 0x972f, 0x5c52,
0xdf86, 0x4576, 0xd6ea, 0x2afd, 0x1759, 0xcf24, 0x1b0e, 0xc73f,
0x75aa, 0x7f2, 0x7432, 0x8691, 0x389c, 0xb9a4, 0xf1ad, 0xb21a,
0xa644, 0x2b0f, 0x8e52, 0x8a81, 0x9558, 0xed0a, 0xcff4, 0x217,
0x5e98, 0x1d53, 0x59f2, 0x9b70, 0xb4b1, 0x2bd9, 0xbbec, 0xfa03,
0xbf55, 0x3651, 0x6d8, 0xcdc0, 0x132d, 0x9c88, 0x349b, 0x4ac9,
0x89c6, 0x5cc1, 0x7826, 0xc599, 0x763f, 0x735f, 0x1e1, 0xc668,
0x67b6, 0xc22, 0xbc5, 0x2324, 0x9c9c, 0xc8fe, 0xf55a, 0x5218,
0x4406, 0x2fff, 0xfffb, 0xe0e6, 0x12b0, 0xc3e9, 0xc119, 0x883c,
0xd877, 0x8973, 0xf93f, 0x3684, 0xfffb, 0x7eeb, 0x730c, 0x7cbb,
0xcea, 0x856, 0x8000,
};
struct Taylor
{
int16_t d[2];
Taylor()
{
fill(d, d + 2, 0);
}
Taylor(int16_t val, const Taylor& other)
{
d[0] = val;
update(other);
}
int16_t predict()
{
return accumulate(d, d + 2, 0);
}
void copyFrom(const Taylor& other, size_t end = 2)
{
copy(other.d, other.d + end, d);
}
void update(const Taylor& other)
{
d[1] = d[0] - other.d[0];
}
void negate()
{
d[0] = -d[0];
d[1] = -d[1];
}
void clear()
{
fill(d, d + 2, 0);
}
};
class NibbleReader
{
uint16_t* stream;
uint16_t block;
uint16_t pos;
public:
NibbleReader(uint16_t* p)
: stream(p)
, block(0)
, pos(0)
{}
uint16_t read4()
{
if (pos == 0)
load();
uint16_t result = block & 15;
block >>= 4;
pos -= 4;
return result;
}
uint16_t read12()
{
return read4() | (read4() << 4) | (read4() << 8);
}
void load()
{
block = *stream++;
pos = 16;
}
};
class ArReader
{ // http://w...content-available-to-author-only...s.com/ac_arithmetic.html
uint16_t* stream;
uint16_t* table;
uint16_t* tableEnd;
uint16_t high;
uint16_t low;
uint16_t code;
uint16_t source;
uint16_t sourceUsed;
public:
ArReader(uint16_t* p, uint16_t* t, uint16_t* e)
: stream(p + 1)
, table(t) // Zero value in *(t-1) expected
, tableEnd(e)
, high(0xFFFF)
, low(0)
, code(*p)
, source(0)
, sourceUsed(0)
{}
uint16_t read()
{
uint32_t range = static_cast<uint32_t>(high) - low + 1;
uint16_t temp =
((static_cast<uint32_t>(code) - low + 1) * *(tableEnd - 1) - 1) /
range;
uint16_t result = searchTable(temp);
high = low + ((range * table[result]) / *(tableEnd - 1)) - 1;
low = low + (range * table[result - 1]) / *(tableEnd - 1);
while (true) {
if ((high ^ low) & 0x8000) // different msb
{
if ((high & 0x4000) < (low & 0x4000))
{
code ^= 0x4000;
low &= 0x3FFF;
high |= 0x4000;
shift();
}
else
{
break;
}
}
else // equal msb
{
shift();
}
}
return result;
}
uint16_t searchTable(uint16_t x)
{
uint16_t* p = table;
while (x >= *p)
++p;
return p - table;
}
void shift()
{
low <<= 1;
high <<= 1;
high |= 1;
code <<= 1;
code |= readBit();
}
uint16_t readBit()
{
if (sourceUsed == 0)
load();
return (source >> --sourceUsed) & 1;
}
void load()
{
source = *stream++;
sourceUsed = 16;
}
};
int16_t get(size_t r, size_t c)
{
if (c == NUM_COLUMNS - 1)
c = 0; // last column is equal to the first one
Taylor lastTaylor;
NibbleReader nibbleReader(compacted + 1 + INDEX_FULL_SIZE);
ArReader
arReader(compacted + 1 + INDEX_FULL_SIZE + nibbleReader.read12(),
compacted + 1,
compacted + 1 + INDEX_FULL_SIZE);
for (size_t row = 0; row < NUM_ROWS; ++row)
{
for (size_t col = 0; col < NUM_COLUMNS - 1; ++col)
{ // last column is not encoded
uint16_t value = arReader.read();
int16_t fixup = static_cast<int16_t>(value) - ZERO_POS;
// Value was encoded in nibbles
if (value == INDEX_SIZE + BIN4)
{
uint16_t x16 = nibbleReader.read4();
if (x16 & 0x8)
fixup = -ZERO_POS - 1 - (x16 & ~0x8);
else
fixup = INDEX_PLUS + 1 + x16;
}
else if (value == INDEX_SIZE + BIN12)
{
fixup = static_cast<int16_t>(nibbleReader.read12());
fixup |= -(fixup & (1 << 11));
}
// Restore original value (extrapolate and add a correction)
Taylor taylor(lastTaylor.predict() + fixup, lastTaylor);
// Hack for values, jumping from -100 to 100
if (taylor.d[0] <= VALUE_LIMIT)
{
taylor.d[0] = -taylor.d[0];
lastTaylor.negate();
taylor.update(lastTaylor);
}
// Got the result
if (row == r && col == c)
return taylor.d[0];
// This will be used to predict the next value
// (derivative is not updated for the first column)
lastTaylor.copyFrom(taylor, col? 3: 1);
}
}
return 0; // Out of range
}
int main()
{
for (int row = 0; row < NUM_ROWS; ++row)
for (int col = 0; col < NUM_COLUMNS; ++col)
if (get(row, col) != my_array[row][col])
{
cerr
<< "Mismatch in row " << row << ", column " << col
<< "; got " << get(row, col)
<< ", must be " << my_array[row][col]
<< "\n";
exit(1);
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bnVtZXJpYz4KI2luY2x1ZGUgPGNzdGRsaWI+IAojaW5jbHVkZSA8Y3N0ZGRlZj4KI2luY2x1ZGUgPHN0ZGludC5oPgoKZW51bSB7CiAgLy8gQ29uZmlnCiAgWkVST19QT1MgPSAyLAogIElOREVYX1NJWkUgPSA1LAogIFZBTFVFX0xJTUlUID0gLTEwMCwKCiAgLy8gQ29uc3RhbnRzCiAgTlVNX1JPV1MgPSAzNywKICBOVU1fQ09MVU1OUyA9IDczLAogIFZBTFVFX0xJTUlUX1BPUyA9IC1WQUxVRV9MSU1JVCwKICBOVU1fQklOX09VVExJRVJTID0gOCwKICBOVU1fVkFMVUVTID0gTlVNX1JPV1MgKiAoTlVNX0NPTFVNTlMgLSAxKSwKICBJTkRFWF9QTFVTID0gSU5ERVhfU0laRSAtIFpFUk9fUE9TIC0gMSwKICBCSU40ID0gMCwKICBCSU4xMiA9IDEsCiAgSU5ERVhfRlVMTF9TSVpFID0gSU5ERVhfU0laRSArIDIKfTsKCmludDE2X3QgbXlfYXJyYXlbTlVNX1JPV1NdW05VTV9DT0xVTU5TXSA9IHsKezE1MCwxNDUsMTQwLDEzNSwxMzAsMTI1LDEyMCwxMTUsMTEwLDEwNSwxMDAsOTUsOTAsODUsODAsNzUsNzAsNjUsNjAsNTUsNTAsNDUsNDAsMzUsMzAsMjUsMjAsMTUsMTAsNSwwLC00LC05LC0xNCwtMTksLTI0LC0yOSwtMzQsLTM5LC00NCwtNDksLTU0LC01OSwtNjQsLTY5LC03NCwtNzksLTg0LC04OSwtOTQsLTk5LDEwNCwxMDksMTE0LDExOSwxMjQsMTI5LDEzNCwxMzksMTQ0LDE0OSwxNTQsMTU5LDE2NCwxNjksMTc0LDE3OSwxNzUsMTcwLDE2NSwxNjAsMTU1LDE1MH0sIFwKezE0MywxMzcsMTMxLDEyNiwxMjAsMTE1LDExMCwxMDUsMTAwLDk1LDkwLDg1LDgwLDc1LDcxLDY2LDYyLDU3LDUzLDQ4LDQ0LDM5LDM1LDMxLDI3LDIyLDE4LDE0LDksNSwxLC0zLC03LC0xMSwtMTYsLTIwLC0yNSwtMjksLTM0LC0zOCwtNDMsLTQ3LC01MiwtNTcsLTYxLC02NiwtNzEsLTc2LC04MSwtODYsLTkxLC05NiwxMDEsMTA3LDExMiwxMTcsMTIzLDEyOCwxMzQsMTQwLDE0NiwxNTEsMTU3LDE2MywxNjksMTc1LDE3OCwxNzIsMTY2LDE2MCwxNTQsMTQ4LDE0M30sIFwKezEzMCwxMjQsMTE4LDExMiwxMDcsMTAxLDk2LDkyLDg3LDgyLDc4LDc0LDcwLDY1LDYxLDU3LDU0LDUwLDQ2LDQyLDM4LDM0LDMxLDI3LDIzLDE5LDE2LDEyLDgsNCwxLC0yLC02LC0xMCwtMTQsLTE4LC0yMiwtMjYsLTMwLC0zNCwtMzgsLTQzLC00NywtNTEsLTU2LC02MSwtNjUsLTcwLC03NSwtNzksLTg0LC04OSwtOTQsMTAwLDEwNSwxMTEsMTE2LDEyMiwxMjgsMTM1LDE0MSwxNDgsMTU1LDE2MiwxNzAsMTc3LDE3NCwxNjYsMTU5LDE1MSwxNDQsMTM3LDEzMH0sIFwKezExMSwxMDQsOTksOTQsODksODUsODEsNzcsNzMsNzAsNjYsNjMsNjAsNTYsNTMsNTAsNDYsNDMsNDAsMzYsMzMsMzAsMjYsMjMsMjAsMTYsMTMsMTAsNiwzLDAsLTMsLTYsLTksLTEzLC0xNiwtMjAsLTI0LC0yOCwtMzIsLTM2LC00MCwtNDQsLTQ4LC01MiwtNTcsLTYxLC02NSwtNzAsLTc0LC03OSwtODQsLTg4LC05MywtOTgsMTAzLDEwOSwxMTUsMTIxLDEyOCwxMzUsMTQzLDE1MiwxNjIsMTcyLDE3NiwxNjUsMTU0LDE0NCwxMzQsMTI1LDExOCwxMTF9LCBcCns4NSw4MSw3Nyw3NCw3MSw2OCw2NSw2Myw2MCw1OCw1Niw1Myw1MSw0OSw0Niw0Myw0MSwzOCwzNSwzMiwyOSwyNiwyMywxOSwxNiwxMywxMCw3LDQsMSwtMSwtMywtNiwtOSwtMTMsLTE2LC0xOSwtMjMsLTI2LC0zMCwtMzQsLTM4LC00MiwtNDYsLTUwLC01NCwtNTgsLTYyLC02NiwtNzAsLTc0LC03OCwtODMsLTg3LC05MSwtOTUsMTAwLDEwNSwxMTAsMTE3LDEyNCwxMzMsMTQ0LDE1OSwxNzgsMTYwLDE0MSwxMjUsMTEyLDEwMyw5Niw5MCw4NX0sIFwKezYyLDYwLDU4LDU3LDU1LDU0LDUyLDUxLDUwLDQ4LDQ3LDQ2LDQ0LDQyLDQxLDM5LDM2LDM0LDMxLDI4LDI1LDIyLDE5LDE2LDEzLDEwLDcsNCwyLDAsLTMsLTUsLTgsLTEwLC0xMywtMTYsLTE5LC0yMiwtMjYsLTI5LC0zMywtMzcsLTQxLC00NSwtNDksLTUzLC01NiwtNjAsLTY0LC02NywtNzAsLTc0LC03NywtODAsLTgzLC04NiwtODksLTkxLC05NCwtOTcsMTAxLDEwNSwxMTEsMTMwLDEwOSw4NCw3Nyw3NCw3MSw2OCw2Niw2NCw2Mn0sIFwKezQ2LDQ2LDQ1LDQ0LDQ0LDQzLDQyLDQyLDQxLDQxLDQwLDM5LDM4LDM3LDM2LDM1LDMzLDMxLDI4LDI2LDIzLDIwLDE2LDEzLDEwLDcsNCwxLC0xLC0zLC01LC03LC05LC0xMiwtMTQsLTE2LC0xOSwtMjIsLTI2LC0yOSwtMzMsLTM2LC00MCwtNDQsLTQ4LC01MSwtNTUsLTU4LC02MSwtNjQsLTY2LC02OCwtNzEsLTcyLC03NCwtNzQsLTc1LC03NCwtNzIsLTY4LC02MSwtNDgsLTI1LDIsMjIsMzMsNDAsNDMsNDUsNDYsNDcsNDYsNDZ9LCBcCnszNiwzNiwzNiwzNiwzNiwzNSwzNSwzNSwzNSwzNCwzNCwzNCwzNCwzMywzMiwzMSwzMCwyOCwyNiwyMywyMCwxNywxNCwxMCw2LDMsMCwtMiwtNCwtNywtOSwtMTAsLTEyLC0xNCwtMTUsLTE3LC0yMCwtMjMsLTI2LC0yOSwtMzIsLTM2LC00MCwtNDMsLTQ3LC01MCwtNTMsLTU2LC01OCwtNjAsLTYyLC02MywtNjQsLTY0LC02MywtNjIsLTU5LC01NSwtNDksLTQxLC0zMCwtMTcsLTQsNiwxNSwyMiwyNywzMSwzMywzNCwzNSwzNiwzNn0sIFwKezMwLDMwLDMwLDMwLDMwLDMwLDMwLDI5LDI5LDI5LDI5LDI5LDI5LDI5LDI5LDI4LDI3LDI2LDI0LDIxLDE4LDE1LDExLDcsMywwLC0zLC02LC05LC0xMSwtMTIsLTE0LC0xNSwtMTYsLTE3LC0xOSwtMjEsLTIzLC0yNiwtMjksLTMyLC0zNSwtMzksLTQyLC00NSwtNDgsLTUxLC01MywtNTUsLTU2LC01NywtNTcsLTU2LC01NSwtNTMsLTQ5LC00NCwtMzgsLTMxLC0yMywtMTQsLTYsMCw3LDEzLDE3LDIxLDI0LDI2LDI3LDI5LDI5LDMwfSwgXAp7MjUsMjUsMjYsMjYsMjYsMjUsMjUsMjUsMjUsMjUsMjUsMjUsMjUsMjYsMjUsMjUsMjQsMjMsMjEsMTksMTYsMTIsOCw0LDAsLTMsLTcsLTEwLC0xMywtMTUsLTE2LC0xNywtMTgsLTE5LC0yMCwtMjEsLTIyLC0yMywtMjUsLTI4LC0zMSwtMzQsLTM3LC00MCwtNDMsLTQ2LC00OCwtNDksLTUwLC01MSwtNTEsLTUwLC00OCwtNDUsLTQyLC0zNywtMzIsLTI2LC0xOSwtMTMsLTcsLTEsMyw3LDExLDE0LDE3LDE5LDIxLDIzLDI0LDI1LDI1fSwgXAp7MjEsMjIsMjIsMjIsMjIsMjIsMjIsMjIsMjIsMjIsMjIsMjIsMjIsMjIsMjIsMjIsMjEsMjAsMTgsMTYsMTMsOSw1LDEsLTMsLTcsLTExLC0xNCwtMTcsLTE4LC0yMCwtMjEsLTIxLC0yMiwtMjIsLTIyLC0yMywtMjMsLTI1LC0yNywtMjksLTMyLC0zNSwtMzcsLTQwLC00MiwtNDQsLTQ1LC00NSwtNDUsLTQ0LC00MiwtNDAsLTM2LC0zMiwtMjcsLTIyLC0xNywtMTIsLTcsLTMsMCwzLDcsOSwxMiwxNCwxNiwxOCwxOSwyMCwyMSwyMX0sIFwKezE4LDE5LDE5LDE5LDE5LDE5LDE5LDE5LDE5LDE5LDE5LDE5LDE5LDE5LDE5LDE5LDE4LDE3LDE2LDE0LDEwLDcsMiwtMSwtNiwtMTAsLTE0LC0xNywtMTksLTIxLC0yMiwtMjMsLTI0LC0yNCwtMjQsLTI0LC0yMywtMjMsLTIzLC0yNCwtMjYsLTI4LC0zMCwtMzMsLTM1LC0zNywtMzgsLTM5LC0zOSwtMzgsLTM2LC0zNCwtMzEsLTI4LC0yNCwtMTksLTE1LC0xMCwtNiwtMywwLDEsNCw2LDgsMTAsMTIsMTQsMTUsMTYsMTcsMTgsMTh9LCBcCnsxNiwxNiwxNywxNywxNywxNywxNywxNywxNywxNywxNywxNiwxNiwxNiwxNiwxNiwxNiwxNSwxMywxMSw4LDQsMCwtNCwtOSwtMTMsLTE2LC0xOSwtMjEsLTIzLC0yNCwtMjUsLTI1LC0yNSwtMjUsLTI0LC0yMywtMjEsLTIwLC0yMCwtMjEsLTIyLC0yNCwtMjYsLTI4LC0zMCwtMzEsLTMyLC0zMSwtMzAsLTI5LC0yNywtMjQsLTIxLC0xNywtMTMsLTksLTYsLTMsLTEsMCwyLDQsNSw3LDksMTAsMTIsMTMsMTQsMTUsMTYsMTZ9LCBcCnsxNCwxNCwxNCwxNSwxNSwxNSwxNSwxNSwxNSwxNSwxNCwxNCwxNCwxNCwxNCwxNCwxMywxMiwxMSw5LDUsMiwtMiwtNiwtMTEsLTE1LC0xOCwtMjEsLTIzLC0yNCwtMjUsLTI1LC0yNSwtMjUsLTI0LC0yMiwtMjEsLTE4LC0xNiwtMTUsLTE1LC0xNSwtMTcsLTE5LC0yMSwtMjIsLTI0LC0yNCwtMjQsLTIzLC0yMiwtMjAsLTE4LC0xNSwtMTIsLTksLTUsLTMsLTEsMCwxLDIsNCw1LDYsOCw5LDEwLDExLDEyLDEzLDE0LDE0fSwgXAp7MTIsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTMsMTIsMTIsMTIsMTIsMTEsMTAsOSw2LDMsMCwtNCwtOCwtMTIsLTE2LC0xOSwtMjEsLTIzLC0yNCwtMjQsLTI0LC0yNCwtMjMsLTIyLC0yMCwtMTcsLTE1LC0xMiwtMTAsLTksLTksLTEwLC0xMiwtMTMsLTE1LC0xNywtMTcsLTE4LC0xNywtMTYsLTE1LC0xMywtMTEsLTgsLTUsLTMsLTEsMCwxLDEsMiwzLDQsNiw3LDgsOSwxMCwxMSwxMiwxMiwxMn0sIFwKezExLDExLDExLDExLDExLDEyLDEyLDEyLDEyLDEyLDExLDExLDExLDExLDExLDEwLDEwLDksNyw1LDIsLTEsLTUsLTksLTEzLC0xNywtMjAsLTIyLC0yMywtMjMsLTIzLC0yMywtMjIsLTIwLC0xOCwtMTYsLTE0LC0xMSwtOSwtNiwtNSwtNCwtNSwtNiwtOCwtOSwtMTEsLTEyLC0xMiwtMTIsLTEyLC0xMSwtOSwtOCwtNiwtMywtMSwwLDAsMSwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMSwxMX0sIFwKezEwLDEwLDEwLDEwLDEwLDEwLDEwLDEwLDEwLDEwLDEwLDEwLDEwLDEwLDksOSw5LDcsNiwzLDAsLTMsLTYsLTEwLC0xNCwtMTcsLTIwLC0yMSwtMjIsLTIyLC0yMiwtMjEsLTE5LC0xNywtMTUsLTEzLC0xMCwtOCwtNiwtNCwtMiwtMiwtMiwtMiwtNCwtNSwtNywtOCwtOCwtOSwtOCwtOCwtNywtNSwtNCwtMiwwLDAsMSwxLDEsMiwyLDMsNCw1LDYsNyw4LDksMTAsMTAsMTB9LCBcCns5LDksOSw5LDksOSw5LDEwLDEwLDksOSw5LDksOSw5LDgsOCw2LDUsMiwwLC00LC03LC0xMSwtMTUsLTE3LC0xOSwtMjEsLTIxLC0yMSwtMjAsLTE4LC0xNiwtMTQsLTEyLC0xMCwtOCwtNiwtNCwtMiwtMSwwLDAsMCwtMSwtMiwtNCwtNSwtNSwtNiwtNiwtNSwtNSwtNCwtMywtMSwwLDAsMSwxLDEsMSwyLDMsMyw1LDYsNyw4LDgsOSw5LDl9LCBcCns5LDksOSw5LDksOSw5LDksOSw5LDksOSw4LDgsOCw4LDcsNSw0LDEsLTEsLTUsLTgsLTEyLC0xNSwtMTcsLTE5LC0yMCwtMjAsLTE5LC0xOCwtMTYsLTE0LC0xMSwtOSwtNywtNSwtNCwtMiwtMSwwLDAsMSwxLDAsMCwtMiwtMywtMywtNCwtNCwtNCwtMywtMywtMiwtMSwwLDAsMCwwLDAsMSwxLDIsMyw0LDUsNiw3LDgsOCw5LDl9LCBcCns5LDksOSw4LDgsOCw5LDksOSw5LDksOCw4LDgsOCw3LDYsNSwzLDAsLTIsLTUsLTksLTEyLC0xNSwtMTcsLTE4LC0xOSwtMTksLTE4LC0xNiwtMTQsLTEyLC05LC03LC01LC00LC0yLC0xLDAsMCwxLDEsMSwxLDAsMCwtMSwtMiwtMiwtMywtMywtMiwtMiwtMSwtMSwwLDAsMCwwLDAsMCwwLDEsMiwzLDQsNSw2LDcsOCw4LDl9LCBcCns4LDgsOCw4LDgsOCw5LDksOSw5LDksOSw4LDgsOCw3LDYsNCwyLDAsLTMsLTYsLTksLTEyLC0xNSwtMTcsLTE4LC0xOCwtMTcsLTE2LC0xNCwtMTIsLTEwLC04LC02LC00LC0yLC0xLDAsMCwxLDIsMiwyLDIsMSwwLDAsLTEsLTEsLTEsLTIsLTIsLTEsLTEsMCwwLDAsMCwwLDAsMCwwLDAsMSwyLDMsNCw1LDYsNyw4LDh9LCBcCns4LDgsOCw4LDksOSw5LDksOSw5LDksOSw5LDgsOCw3LDUsMywxLC0xLC00LC03LC0xMCwtMTMsLTE1LC0xNiwtMTcsLTE3LC0xNiwtMTUsLTEzLC0xMSwtOSwtNiwtNSwtMywtMiwwLDAsMCwxLDIsMiwyLDIsMSwxLDAsMCwwLC0xLC0xLC0xLC0xLC0xLDAsMCwwLDAsLTEsLTEsLTEsLTEsLTEsMCwwLDEsMyw0LDUsNyw3LDh9LCBcCns4LDgsOSw5LDksOSwxMCwxMCwxMCwxMCwxMCwxMCwxMCw5LDgsNyw1LDMsMCwtMiwtNSwtOCwtMTEsLTEzLC0xNSwtMTYsLTE2LC0xNiwtMTUsLTEzLC0xMiwtMTAsLTgsLTYsLTQsLTIsLTEsMCwwLDEsMiwyLDMsMywyLDIsMSwwLDAsMCwwLDAsMCwwLDAsMCwwLC0xLC0xLC0yLC0yLC0yLC0yLC0yLC0xLDAsMCwxLDMsNCw2LDcsOH0sIFwKezcsOCw5LDksOSwxMCwxMCwxMSwxMSwxMSwxMSwxMSwxMCwxMCw5LDcsNSwzLDAsLTIsLTYsLTksLTExLC0xMywtMTUsLTE2LC0xNiwtMTUsLTE0LC0xMywtMTEsLTksLTcsLTUsLTMsLTIsMCwwLDEsMSwyLDMsMywzLDMsMiwyLDEsMSwwLDAsMCwwLDAsMCwwLC0xLC0xLC0yLC0zLC0zLC00LC00LC00LC0zLC0yLC0xLDAsMSwzLDUsNiw3fSwgXAp7Niw4LDksOSwxMCwxMSwxMSwxMiwxMiwxMiwxMiwxMiwxMSwxMSw5LDcsNSwyLDAsLTMsLTcsLTEwLC0xMiwtMTQsLTE1LC0xNiwtMTUsLTE1LC0xMywtMTIsLTEwLC04LC03LC01LC0zLC0xLDAsMCwxLDIsMiwzLDMsNCwzLDMsMywyLDIsMSwxLDEsMCwwLDAsMCwtMSwtMiwtMywtNCwtNCwtNSwtNSwtNSwtNSwtNCwtMiwtMSwwLDIsMyw1LDZ9LCBcCns2LDcsOCwxMCwxMSwxMiwxMiwxMywxMywxNCwxNCwxMywxMywxMSwxMCw4LDUsMiwwLC00LC04LC0xMSwtMTMsLTE1LC0xNiwtMTYsLTE2LC0xNSwtMTMsLTEyLC0xMCwtOCwtNiwtNSwtMywtMSwwLDAsMSwyLDMsMyw0LDQsNCw0LDQsMywzLDMsMiwyLDEsMSwwLDAsLTEsLTIsLTMsLTUsLTYsLTcsLTcsLTcsLTYsLTUsLTQsLTMsLTEsMCwyLDQsNn0sIFwKezUsNyw4LDEwLDExLDEyLDEzLDE0LDE1LDE1LDE1LDE0LDE0LDEyLDExLDgsNSwyLC0xLC01LC05LC0xMiwtMTQsLTE2LC0xNywtMTcsLTE2LC0xNSwtMTQsLTEyLC0xMSwtOSwtNywtNSwtMywtMSwwLDAsMSwyLDMsNCw0LDUsNSw1LDUsNSw1LDQsNCwzLDMsMiwxLDAsLTEsLTIsLTQsLTYsLTcsLTgsLTgsLTgsLTgsLTcsLTYsLTQsLTIsMCwxLDMsNX0sIFwKezQsNiw4LDEwLDEyLDEzLDE0LDE1LDE2LDE2LDE2LDE2LDE1LDEzLDExLDksNSwyLC0yLC02LC0xMCwtMTMsLTE2LC0xNywtMTgsLTE4LC0xNywtMTYsLTE1LC0xMywtMTEsLTksLTcsLTUsLTQsLTIsMCwwLDEsMywzLDQsNSw2LDYsNyw3LDcsNyw3LDYsNSw0LDMsMiwwLC0xLC0zLC01LC03LC04LC05LC0xMCwtMTAsLTEwLC05LC03LC01LC00LC0xLDAsMiw0fSwgXAp7NCw2LDgsMTAsMTIsMTQsMTUsMTYsMTcsMTgsMTgsMTcsMTYsMTUsMTIsOSw1LDEsLTMsLTgsLTEyLC0xNSwtMTgsLTE5LC0yMCwtMjAsLTE5LC0xOCwtMTYsLTE1LC0xMywtMTEsLTgsLTYsLTQsLTIsLTEsMCwxLDMsNCw1LDYsNyw4LDksOSw5LDksOSw5LDgsNyw1LDMsMSwtMSwtMywtNiwtOCwtMTAsLTExLC0xMiwtMTIsLTExLC0xMCwtOSwtNywtNSwtMiwwLDEsNH0sIFwKezQsNiw4LDExLDEzLDE1LDE2LDE4LDE5LDE5LDE5LDE5LDE4LDE2LDEzLDEwLDUsMCwtNSwtMTAsLTE1LC0xOCwtMjEsLTIyLC0yMywtMjIsLTIyLC0yMCwtMTgsLTE3LC0xNCwtMTIsLTEwLC04LC01LC0zLC0xLDAsMSwzLDUsNiw4LDksMTAsMTEsMTIsMTIsMTMsMTIsMTIsMTEsOSw3LDUsMiwwLC0zLC02LC05LC0xMSwtMTIsLTEzLC0xMywtMTIsLTExLC0xMCwtOCwtNiwtMywtMSwxLDR9LCBcCnszLDYsOSwxMSwxNCwxNiwxNywxOSwyMCwyMSwyMSwyMSwxOSwxNywxNCwxMCw0LC0xLC04LC0xNCwtMTksLTIyLC0yNSwtMjYsLTI2LC0yNiwtMjUsLTIzLC0yMSwtMTksLTE3LC0xNCwtMTIsLTksLTcsLTQsLTIsMCwxLDMsNSw3LDksMTEsMTMsMTQsMTUsMTYsMTYsMTYsMTYsMTUsMTMsMTAsNyw0LDAsLTMsLTcsLTEwLC0xMiwtMTQsLTE1LC0xNCwtMTQsLTEyLC0xMSwtOSwtNiwtNCwtMSwxLDN9LCBcCns0LDYsOSwxMiwxNCwxNywxOSwyMSwyMiwyMywyMywyMywyMSwxOSwxNSw5LDIsLTUsLTEzLC0yMCwtMjUsLTI4LC0zMCwtMzEsLTMxLC0zMCwtMjksLTI3LC0yNSwtMjIsLTIwLC0xNywtMTQsLTExLC05LC02LC0zLDAsMSw0LDYsOSwxMSwxMywxNSwxNywxOSwyMCwyMSwyMSwyMSwyMCwxOCwxNSwxMSw2LDIsLTIsLTcsLTExLC0xMywtMTUsLTE2LC0xNiwtMTUsLTEzLC0xMSwtOSwtNywtNCwtMSwxLDR9LCBcCns0LDcsMTAsMTMsMTUsMTgsMjAsMjIsMjQsMjUsMjUsMjUsMjMsMjAsMTUsNywtMiwtMTIsLTIyLC0yOSwtMzQsLTM3LC0zOCwtMzgsLTM3LC0zNiwtMzQsLTMxLC0yOSwtMjYsLTIzLC0yMCwtMTcsLTEzLC0xMCwtNywtNCwtMSwyLDUsOCwxMSwxMywxNiwxOCwyMSwyMywyNCwyNiwyNiwyNiwyNiwyNCwyMSwxNywxMiw1LDAsLTYsLTEwLC0xNCwtMTYsLTE2LC0xNiwtMTUsLTE0LC0xMiwtMTAsLTcsLTQsLTEsMSw0fSwgXAp7NCw3LDEwLDEzLDE2LDE5LDIyLDI0LDI2LDI3LDI3LDI2LDI0LDE5LDExLC0xLC0xNSwtMjgsLTM3LC00MywtNDYsLTQ3LC00NywtNDUsLTQ0LC00MSwtMzksLTM2LC0zMiwtMjksLTI2LC0yMiwtMTksLTE1LC0xMSwtOCwtNCwtMSwyLDUsOSwxMiwxNSwxOSwyMiwyNCwyNywyOSwzMSwzMywzMywzMywzMiwzMCwyNiwyMSwxNCw2LDAsLTYsLTExLC0xNCwtMTUsLTE2LC0xNSwtMTQsLTEyLC05LC03LC00LC0xLDEsNH0sIFwKezYsOSwxMiwxNSwxOCwyMSwyMywyNSwyNywyOCwyNywyNCwxNyw0LC0xNCwtMzQsLTQ5LC01NiwtNjAsLTYwLC02MCwtNTgsLTU2LC01MywtNTAsLTQ3LC00MywtNDAsLTM2LC0zMiwtMjgsLTI1LC0yMSwtMTcsLTEzLC05LC01LC0xLDIsNiwxMCwxNCwxNywyMSwyNCwyOCwzMSwzNCwzNywzOSw0MSw0Miw0Myw0Myw0MSwzOCwzMywyNSwxNyw4LDAsLTQsLTgsLTEwLC0xMCwtMTAsLTgsLTcsLTQsLTIsMCwzLDZ9LCBcCnsyMiwyNCwyNiwyOCwzMCwzMiwzMywzMSwyMywtMTgsLTgxLC05NiwtOTksLTk4LC05NSwtOTMsLTg5LC04NiwtODIsLTc4LC03NCwtNzAsLTY2LC02MiwtNTcsLTUzLC00OSwtNDQsLTQwLC0zNiwtMzIsLTI3LC0yMywtMTksLTE0LC0xMCwtNiwtMSwyLDYsMTAsMTUsMTksMjMsMjcsMzEsMzUsMzgsNDIsNDUsNDksNTIsNTUsNTcsNjAsNjEsNjMsNjMsNjIsNjEsNTcsNTMsNDcsNDAsMzMsMjgsMjMsMjEsMTksMTksMTksMjAsMjJ9LCBcCnsxNjgsMTczLDE3OCwxNzYsMTcxLDE2NiwxNjEsMTU2LDE1MSwxNDYsMTQxLDEzNiwxMzEsMTI2LDEyMSwxMTYsMTExLDEwNiwxMDEsLTk2LC05MSwtODYsLTgxLC03NiwtNzEsLTY2LC02MSwtNTYsLTUxLC00NiwtNDEsLTM2LC0zMSwtMjYsLTIxLC0xNiwtMTEsLTYsLTEsMyw4LDEzLDE4LDIzLDI4LDMzLDM4LDQzLDQ4LDUzLDU4LDYzLDY4LDczLDc4LDgzLDg4LDkzLDk4LDEwMywxMDgsMTEzLDExOCwxMjMsMTI4LDEzMywxMzgsMTQzLDE0OCwxNTMsMTU4LDE2MywxNjh9fTsKCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp1aW50MTZfdCBjb21wYWN0ZWRbXSA9IHsKICAgIDAsIDB4NGIsIDB4MjkyLCAweDc3NiwgMHg5Y2UsIDB4YTE4LCAweGE1NSwgMHhhNjgsIAogICAgMHg2MDFmLCAweGVhMDksIDB4NGU4YywgMHhhZmZmLCAweGJmZWQsIDB4NmZmMSwgMHgxMGZlLCAweGZkYjEsIAogICAgMHhhMTAwLCAweGQxZmUsIDB4ZDgwMCwgMHgxMjlmLCAweGYwMTAsIDB4NzMwZiwgMHg5ZWMxLCAweDgwZTksIAogICAgMHg5YTljLCAweDg4ODgsIDB4OTg4MCwgMHgxLCAweDJhYjksIDB4ODEwNSwgMHgxMDEsIDB4ZGZiOCwgCiAgICAweGZlYWYsIDB4YzAzMCwgMHg4MTAwLCAweDkzMCwgMHg4YzEsIDB4Y2FmNCwgMCwgMHhmZmY2LCAKICAgIDB4ZWZiOSwgMHg0MTYsIDB4NzhlYiwgMHhlNWQyLCAweGVhZjcsIDB4NTk3ZSwgMHg4YTUwLCAweGYyNzgsIAogICAgMHgzMGMsIDB4YWQ1YSwgMHg3ZjJhLCAweDk2Y2QsIDB4ODYwYSwgMHhiYWQ3LCAweDIxNDUsIDB4MWI3LCAKICAgIDB4ODA3ZiwgMHhiYThmLCAweDhiMjIsIDB4NDBjOSwgMHhjZmU1LCAweDQzYywgMHg1NmE5LCAweDc1ZTQsIAogICAgMHg2YjQzLCAweDIzZSwgMHgzZGI0LCAweGFjNDgsIDB4NzFiZiwgMHhlYWY5LCAweDRhOWEsIDB4ZTkyNywgCiAgICAweDg1NSwgMHhlNTQsIDB4ZDU2ZiwgMHhlMTcwLCAweDFjODgsIDB4NTdjLCAweDk5YjIsIDB4ZmQ3OSwgCiAgICAweGE4YzgsIDB4ZjVmNiwgMHhjZDg5LCAweGZkNjYsIDB4OTgxNSwgMHhjMTI2LCAweDMyZTEsIDB4NTZmLCAKICAgIDB4ZmU3YSwgMHhkODZkLCAweDE1NWIsIDB4NGEyMiwgMHg2MmQyLCAweDM2YjgsIDB4ODc3ZSwgMHhiZDcwLCAKICAgIDB4Mjc0NiwgMHhhODdmLCAweDE2OWQsIDB4NGFmMCwgMHhlMDU5LCAweDZjZmIsIDB4YjI3YSwgMHg0OWE2LCAKICAgIDB4YWUzMiwgMHhkMGFiLCAweDE0YjEsIDB4YTQ5OCwgMHhiNWU5LCAweGFlMGUsIDB4OTQyNywgMHg5YjRmLCAKICAgIDB4NDk1NywgMHhlYmQ1LCAweGYxZmEsIDB4ZjI4OCwgMHhmZjcyLCAweGMyOWYsIDB4NDc1ZSwgMHhmNGNhLCAKICAgIDB4YWEwZSwgMHhkNDU1LCAweDFiMWYsIDB4ZWFlZSwgMHhmMmJhLCAweGFlZSwgMHg5NmQyLCAweGE5NDIsIAogICAgMHhhZWVkLCAweDhhNWEsIDB4ZGZkYSwgMHgzY2U3LCAweDMxZDIsIDB4NjBjYiwgMHhlOThkLCAweDgxNjIsIAogICAgMHhiMGMsIDB4MjdhZiwgMHg2ZTZjLCAweGQyZTUsIDB4NjAyMiwgMHhlNDIxLCAweGU3ZjcsIDB4Mzk0YSwgCiAgICAweDE3M2IsIDB4ZWQ0NywgMHhhZWY3LCAweDRiNzgsIDB4MjgzYiwgMHg5ZDc4LCAweDNlMTMsIDB4NGE2LCAKICAgIDB4YTZlLCAweGNkYTYsIDB4M2JiMCwgMHg2MmI3LCAweDJiOWEsIDB4ZWUzZiwgMHhkYTI3LCAweDg4ZWUsIAogICAgMHg4MjgwLCAweGU2NTgsIDB4MTY2OCwgMHhiNzAxLCAweDRlNzAsIDB4MTQ3LCAweGUwNTgsIDB4YTFhMCwgCiAgICAweDM0NTUsIDB4NTk5NCwgMHhkMzkwLCAweDFmYWMsIDB4YjU4YywgMHgzNjgwLCAweDNkNDIsIDB4ZjEyLCAKICAgIDB4YmE5ZSwgMHg5NDlmLCAweDUxZGYsIDB4OTYwMywgMHg1MmFmLCAweDc0ZDgsIDB4YmRjNywgMHhlZmU5LCAKICAgIDB4M2I1ZSwgMHhlMjczLCAweGJhZSwgMHgxM2M0LCAweDU4NDQsIDB4M2M2ZCwgMHhmMDQ1LCAweDUyYmEsIAogICAgMHg2ZWYyLCAweGE0MjgsIDB4NjdiNywgMHg5MWY3LCAweDMxZWUsIDB4YmNiOSwgMHhmZTdmLCAweGVmZDMsIAogICAgMHgzNjdlLCAweDQzMDgsIDB4MmI1OCwgMHhiZDMwLCAweGM0YmQsIDB4YTI4ZiwgMHhjYTVkLCAweDIyMzAsIAogICAgMHg4ZjY1LCAweDEzNGUsIDB4YWFhOCwgMHg2NDk5LCAweDRhMTQsIDB4MTVlYywgMHhmODNmLCAweDhjOTIsIAogICAgMHgzOTI4LCAweDJkMzUsIDB4MTc2ZiwgMHgxMDgwLCAweGM5ODIsIDB4MWJhZSwgMHhmYjdhLCAweDYxNmEsIAogICAgMHhjMDY5LCAweDgxNzcsIDB4ZTdmMywgMHg3MGUzLCAweDVkOTksIDB4OGRmYSwgMHhkZjgwLCAweDM2NGIsIAogICAgMHg2YjNmLCAweDFhZWMsIDB4NjZjOCwgMHg4N2NjLCAweGQ2MmYsIDB4Njg3LCAweDlhM2QsIDB4MzcwNCwgCiAgICAweGU0ODYsIDB4YTQ3ZSwgMHhhODdhLCAweDFiZCwgMHhkOGUyLCAweDlmNmQsIDB4ZGQyLCAweGQxNTAsIAogICAgMHhjZGYzLCAweGI0ZTQsIDB4OWJkNywgMHhhYmM5LCAweDUyZTgsIDB4NTUzYywgMHhhMmFiLCAweDE4YjgsIAogICAgMHg3MGZiLCAweGE1OTQsIDB4ZDM0YywgMHg5NDUwLCAweGQ5MjgsIDB4ZDU4MSwgMHg1NGEsIDB4MzA5NiwgCiAgICAweDMwYzcsIDB4Njg5OSwgMHhjZmQwLCAweDVhMzcsIDB4YTY2NCwgMHhmZTAsIDB4NGIxYSwgMHg2MTZjLCAKICAgIDB4OWViYSwgMHg1OTFhLCAweGZhODAsIDB4MjkxMSwgMHgyYzViLCAweGUzMTAsIDB4MzJlMSwgMHgzNjgwLCAKICAgIDB4NTVhOCwgMHg3ZSwgMHhkN2ZkLCAweGU4MWQsIDB4MTNmMiwgMHg5MTlkLCAweDk3MmYsIDB4NWM1MiwgCiAgICAweGRmODYsIDB4NDU3NiwgMHhkNmVhLCAweDJhZmQsIDB4MTc1OSwgMHhjZjI0LCAweDFiMGUsIDB4YzczZiwgCiAgICAweDc1YWEsIDB4N2YyLCAweDc0MzIsIDB4ODY5MSwgMHgzODljLCAweGI5YTQsIDB4ZjFhZCwgMHhiMjFhLCAKICAgIDB4YTY0NCwgMHgyYjBmLCAweDhlNTIsIDB4OGE4MSwgMHg5NTU4LCAweGVkMGEsIDB4Y2ZmNCwgMHgyMTcsIAogICAgMHg1ZTk4LCAweDFkNTMsIDB4NTlmMiwgMHg5YjcwLCAweGI0YjEsIDB4MmJkOSwgMHhiYmVjLCAweGZhMDMsIAogICAgMHhiZjU1LCAweDM2NTEsIDB4NmQ4LCAweGNkYzAsIDB4MTMyZCwgMHg5Yzg4LCAweDM0OWIsIDB4NGFjOSwgCiAgICAweDg5YzYsIDB4NWNjMSwgMHg3ODI2LCAweGM1OTksIDB4NzYzZiwgMHg3MzVmLCAweDFlMSwgMHhjNjY4LCAKICAgIDB4NjdiNiwgMHhjMjIsIDB4YmM1LCAweDIzMjQsIDB4OWM5YywgMHhjOGZlLCAweGY1NWEsIDB4NTIxOCwgCiAgICAweDQ0MDYsIDB4MmZmZiwgMHhmZmZiLCAweGUwZTYsIDB4MTJiMCwgMHhjM2U5LCAweGMxMTksIDB4ODgzYywgCiAgICAweGQ4NzcsIDB4ODk3MywgMHhmOTNmLCAweDM2ODQsIDB4ZmZmYiwgMHg3ZWViLCAweDczMGMsIDB4N2NiYiwgCiAgICAweGNlYSwgMHg4NTYsIDB4ODAwMCwgCn07CgogICAgICBzdHJ1Y3QgVGF5bG9yCiAgICAgIHsKCWludDE2X3QgZFsyXTsKCVRheWxvcigpCgl7CgkgIGZpbGwoZCwgZCArIDIsIDApOwoJfQoJVGF5bG9yKGludDE2X3QgdmFsLCBjb25zdCBUYXlsb3ImIG90aGVyKQoJewoJICBkWzBdID0gdmFsOwoJICB1cGRhdGUob3RoZXIpOwoJfQoJaW50MTZfdCBwcmVkaWN0KCkKCXsKCSAgcmV0dXJuIGFjY3VtdWxhdGUoZCwgZCArIDIsIDApOwoJfQoJdm9pZCBjb3B5RnJvbShjb25zdCBUYXlsb3ImIG90aGVyLCBzaXplX3QgZW5kID0gMikKCXsKCSAgY29weShvdGhlci5kLCBvdGhlci5kICsgZW5kLCBkKTsKCX0KCXZvaWQgdXBkYXRlKGNvbnN0IFRheWxvciYgb3RoZXIpCgl7CgkgIGRbMV0gPSBkWzBdIC0gb3RoZXIuZFswXTsKCX0KCXZvaWQgbmVnYXRlKCkKCXsKCSAgZFswXSA9IC1kWzBdOwoJICBkWzFdID0gLWRbMV07Cgl9Cgl2b2lkIGNsZWFyKCkKCXsKCSAgZmlsbChkLCBkICsgMiwgMCk7Cgl9CiAgICAgIH07CgogICAgICBjbGFzcyBOaWJibGVSZWFkZXIKICAgICAgewoJdWludDE2X3QqIHN0cmVhbTsKCXVpbnQxNl90IGJsb2NrOwoJdWludDE2X3QgcG9zOwogICAgICBwdWJsaWM6CglOaWJibGVSZWFkZXIodWludDE2X3QqIHApCgk6IHN0cmVhbShwKQoJLCBibG9jaygwKQoJLCBwb3MoMCkKCXt9Cgl1aW50MTZfdCByZWFkNCgpCgl7CgkgIGlmIChwb3MgPT0gMCkKCSAgICBsb2FkKCk7CgoJICB1aW50MTZfdCByZXN1bHQgPSBibG9jayAmIDE1OwoJICBibG9jayA+Pj0gNDsKCSAgcG9zIC09IDQ7CgkgIHJldHVybiByZXN1bHQ7Cgl9Cgl1aW50MTZfdCByZWFkMTIoKQoJewoJICByZXR1cm4gcmVhZDQoKSB8IChyZWFkNCgpIDw8IDQpIHwgKHJlYWQ0KCkgPDwgOCk7Cgl9Cgl2b2lkIGxvYWQoKQoJewoJICBibG9jayA9ICpzdHJlYW0rKzsKCSAgcG9zID0gMTY7Cgl9CiAgICAgIH07CgogICAgICBjbGFzcyBBclJlYWRlcgogICAgICB7IC8vIGh0dHA6Ly93Li4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5zLmNvbS9hY19hcml0aG1ldGljLmh0bWwKCXVpbnQxNl90KiBzdHJlYW07Cgl1aW50MTZfdCogdGFibGU7Cgl1aW50MTZfdCogdGFibGVFbmQ7Cgl1aW50MTZfdCBoaWdoOwoJdWludDE2X3QgbG93OwoJdWludDE2X3QgY29kZTsKCXVpbnQxNl90IHNvdXJjZTsKCXVpbnQxNl90IHNvdXJjZVVzZWQ7CiAgICAgIHB1YmxpYzoKCUFyUmVhZGVyKHVpbnQxNl90KiBwLCB1aW50MTZfdCogdCwgdWludDE2X3QqIGUpCgk6IHN0cmVhbShwICsgMSkKCSwgdGFibGUodCkgLy8gWmVybyB2YWx1ZSBpbiAqKHQtMSkgZXhwZWN0ZWQKCSwgdGFibGVFbmQoZSkKCSwgaGlnaCgweEZGRkYpCgksIGxvdygwKQoJLCBjb2RlKCpwKQoJLCBzb3VyY2UoMCkKCSwgc291cmNlVXNlZCgwKQoJe30KCXVpbnQxNl90IHJlYWQoKQoJewoJICB1aW50MzJfdCByYW5nZSA9IHN0YXRpY19jYXN0PHVpbnQzMl90PihoaWdoKSAtIGxvdyArIDE7CgoJICB1aW50MTZfdCB0ZW1wID0KCSAgICAoKHN0YXRpY19jYXN0PHVpbnQzMl90Pihjb2RlKSAtIGxvdyArIDEpICogKih0YWJsZUVuZCAtIDEpIC0gMSkgLwoJICAgIHJhbmdlOwoKCSAgdWludDE2X3QgcmVzdWx0ID0gc2VhcmNoVGFibGUodGVtcCk7CgkgIGhpZ2ggPSBsb3cgKyAoKHJhbmdlICogdGFibGVbcmVzdWx0XSkgLyAqKHRhYmxlRW5kIC0gMSkpIC0gMTsKCSAgbG93ID0gbG93ICsgKHJhbmdlICogdGFibGVbcmVzdWx0IC0gMV0pIC8gKih0YWJsZUVuZCAtIDEpOwoKCSAgd2hpbGUgKHRydWUpIHsKCSAgICBpZiAoKGhpZ2ggXiBsb3cpICYgMHg4MDAwKSAvLyBkaWZmZXJlbnQgbXNiCgkgICAgewoJICAgICAgaWYgKChoaWdoICYgMHg0MDAwKSA8IChsb3cgJiAweDQwMDApKQoJICAgICAgewoJCWNvZGUgXj0gMHg0MDAwOwoJCWxvdyAmPSAweDNGRkY7CgkJaGlnaCB8PSAweDQwMDA7CgkJc2hpZnQoKTsKCSAgICAgIH0KCSAgICAgIGVsc2UKCSAgICAgIHsKCQlicmVhazsKCSAgICAgIH0KCSAgICB9CgkgICAgZWxzZSAvLyBlcXVhbCBtc2IKCSAgICB7CgkgICAgICBzaGlmdCgpOwoJICAgIH0KCSAgfQoKCSAgcmV0dXJuIHJlc3VsdDsKCX0KCXVpbnQxNl90IHNlYXJjaFRhYmxlKHVpbnQxNl90IHgpCgl7CgkgIHVpbnQxNl90KiBwID0gdGFibGU7CgkgIHdoaWxlICh4ID49ICpwKQoJICAgICsrcDsKCSAgcmV0dXJuIHAgLSB0YWJsZTsKCX0KCXZvaWQgc2hpZnQoKQoJewoJICBsb3cgPDw9IDE7CgkgIGhpZ2ggPDw9IDE7CgkgIGhpZ2ggfD0gMTsKCSAgY29kZSA8PD0gMTsKCSAgY29kZSB8PSByZWFkQml0KCk7Cgl9CiAgICAgICAgdWludDE2X3QgcmVhZEJpdCgpCgl7CgkgIGlmIChzb3VyY2VVc2VkID09IDApCgkgICAgbG9hZCgpOwoKCSAgcmV0dXJuIChzb3VyY2UgPj4gLS1zb3VyY2VVc2VkKSAmIDE7Cgl9Cgl2b2lkIGxvYWQoKQoJewoJICBzb3VyY2UgPSAqc3RyZWFtKys7CgkgIHNvdXJjZVVzZWQgPSAxNjsKCX0KICAgICAgfTsKCiAgICAgIGludDE2X3QgZ2V0KHNpemVfdCByLCBzaXplX3QgYykKICAgICAgewoJaWYgKGMgPT0gTlVNX0NPTFVNTlMgLSAxKQoJICBjID0gMDsgLy8gbGFzdCBjb2x1bW4gaXMgZXF1YWwgdG8gdGhlIGZpcnN0IG9uZQoKCVRheWxvciBsYXN0VGF5bG9yOwoJTmliYmxlUmVhZGVyIG5pYmJsZVJlYWRlcihjb21wYWN0ZWQgKyAxICsgSU5ERVhfRlVMTF9TSVpFKTsKCglBclJlYWRlcgoJICBhclJlYWRlcihjb21wYWN0ZWQgKyAxICsgSU5ERVhfRlVMTF9TSVpFICsgbmliYmxlUmVhZGVyLnJlYWQxMigpLAoJCSAgIGNvbXBhY3RlZCArIDEsCgkJICAgY29tcGFjdGVkICsgMSArIElOREVYX0ZVTExfU0laRSk7CgoJZm9yIChzaXplX3Qgcm93ID0gMDsgcm93IDwgTlVNX1JPV1M7ICsrcm93KQoJewoJICBmb3IgKHNpemVfdCBjb2wgPSAwOyBjb2wgPCBOVU1fQ09MVU1OUyAtIDE7ICsrY29sKQoJICB7IC8vIGxhc3QgY29sdW1uIGlzIG5vdCBlbmNvZGVkCgkgICAgdWludDE2X3QgdmFsdWUgPSBhclJlYWRlci5yZWFkKCk7CgkgICAgaW50MTZfdCBmaXh1cCA9IHN0YXRpY19jYXN0PGludDE2X3Q+KHZhbHVlKSAtIFpFUk9fUE9TOwoKCSAgICAvLyBWYWx1ZSB3YXMgZW5jb2RlZCBpbiBuaWJibGVzCgkgICAgaWYgKHZhbHVlID09IElOREVYX1NJWkUgKyBCSU40KQoJICAgIHsKCSAgICAgIHVpbnQxNl90IHgxNiA9IG5pYmJsZVJlYWRlci5yZWFkNCgpOwoKCSAgICAgIGlmICh4MTYgJiAweDgpCgkJZml4dXAgPSAtWkVST19QT1MgLSAxIC0gKHgxNiAmIH4weDgpOwoJICAgICAgZWxzZQoJCWZpeHVwID0gSU5ERVhfUExVUyArIDEgKyB4MTY7CgkgICAgfQoJICAgIGVsc2UgaWYgKHZhbHVlID09IElOREVYX1NJWkUgKyBCSU4xMikKCSAgICB7CgkgICAgICBmaXh1cCA9IHN0YXRpY19jYXN0PGludDE2X3Q+KG5pYmJsZVJlYWRlci5yZWFkMTIoKSk7CgkgICAgICBmaXh1cCB8PSAtKGZpeHVwICYgKDEgPDwgMTEpKTsKCSAgICB9CgoJICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgdmFsdWUgKGV4dHJhcG9sYXRlIGFuZCBhZGQgYSBjb3JyZWN0aW9uKQoJICAgIFRheWxvciB0YXlsb3IobGFzdFRheWxvci5wcmVkaWN0KCkgKyBmaXh1cCwgbGFzdFRheWxvcik7CgoJICAgIC8vIEhhY2sgZm9yIHZhbHVlcywganVtcGluZyBmcm9tIC0xMDAgdG8gMTAwCgkgICAgaWYgKHRheWxvci5kWzBdIDw9IFZBTFVFX0xJTUlUKQoJICAgIHsKCSAgICAgIHRheWxvci5kWzBdID0gLXRheWxvci5kWzBdOwoJICAgICAgbGFzdFRheWxvci5uZWdhdGUoKTsKCSAgICAgIHRheWxvci51cGRhdGUobGFzdFRheWxvcik7CgkgICAgfQoKCSAgICAvLyBHb3QgdGhlIHJlc3VsdAoJICAgIGlmIChyb3cgPT0gciAmJiBjb2wgPT0gYykKCSAgICAgIHJldHVybiB0YXlsb3IuZFswXTsKCgkgICAgLy8gVGhpcyB3aWxsIGJlIHVzZWQgdG8gcHJlZGljdCB0aGUgbmV4dCB2YWx1ZQoJICAgIC8vIChkZXJpdmF0aXZlIGlzIG5vdCB1cGRhdGVkIGZvciB0aGUgZmlyc3QgY29sdW1uKQoJICAgIGxhc3RUYXlsb3IuY29weUZyb20odGF5bG9yLCBjb2w/IDM6IDEpOwoJICB9Cgl9CgoJcmV0dXJuIDA7IC8vIE91dCBvZiByYW5nZQogICAgICB9CgogICAgICBpbnQgbWFpbigpCiAgICAgIHsKCWZvciAoaW50IHJvdyA9IDA7IHJvdyA8IE5VTV9ST1dTOyArK3JvdykKCSAgZm9yIChpbnQgY29sID0gMDsgY29sIDwgTlVNX0NPTFVNTlM7ICsrY29sKQoJICAgIGlmIChnZXQocm93LCBjb2wpICE9IG15X2FycmF5W3Jvd11bY29sXSkKCSAgICB7CgkgICAgICBjZXJyCgkJPDwgIk1pc21hdGNoIGluIHJvdyAiIDw8IHJvdyA8PCAiLCBjb2x1bW4gIiA8PCBjb2wKCQk8PCAiOyBnb3QgIiA8PCBnZXQocm93LCBjb2wpCgkJPDwgIiwgbXVzdCBiZSAiIDw8IG15X2FycmF5W3Jvd11bY29sXQoJCTw8ICJcbiI7CgkgICAgICBleGl0KDEpOwoJICAgIH0KCglyZXR1cm4gMDsKICAgICAgfQo=