#include <array>
#include <cstddef>
#include <iostream>
#include <set>
#include <tuple>
#include <vector>
// The individual 8x8 pixel tiles
struct Tile
{
enum
{
blank,
cloud1, cloud2, cloud3, cloud4, cloud5, cloud6, cloud7, cloud8, cloud9,
bush1, bush2, bush3, bush4, bush5,
floor1, floor2, floor3, floor4,
mound1, mound2, mound3, mound4, mound5, mound6,
pipe1, pipe2, pipe3, pipe4,
pipetop1, pipetop2, pipetop3, pipetop4, pipetop5, pipetop6, pipetop7, pipetop8,
bricks,
mystery1, mystery2, mystery3, mystery4,
block1, block2, block3, block4,
pole1, pole2,
poletop1, poletop2,
castledoor1, castledoor2, castledoor3,
castletop1, castletop2, castletop3, castletop4,
num
};
};
// Blocks made up from 2x2 tiles
struct Block
{
enum
{
blank,
cloud_top_left,
cloud_top_middle,
cloud_top_right,
cloud_bottom_left,
cloud_bottom_middle,
cloud_bottom_right,
bush_left,
bush_middle,
bush_right,
floor,
mound_top,
mound_left,
mound_center,
mound_center_detail,
mound_right,
pipe_left,
pipe_right,
pipetop_left,
pipetop_right,
bricks,
mystery,
block,
pole,
poletop,
castledoor_top,
castledoor_bottom,
castlewindow_1,
castlewindow_2,
castletop_1,
castletop_2,
num
};
std::array<int, 4> tiles;
};
// Block definitions, order 0 1
// 2 3
Block block_defs[] =
{
{{Tile::blank, Tile::blank, Tile::blank, Tile::blank}},
{{Tile::blank, Tile::blank, Tile::blank, Tile::cloud3}},
{{Tile::cloud1, Tile::cloud2, Tile::cloud4, Tile::cloud4}},
{{Tile::blank, Tile::blank, Tile::cloud5, Tile::blank}},
{{Tile::blank, Tile::cloud6, Tile::blank, Tile::blank}},
{{Tile::cloud7, Tile::cloud8, Tile::blank, Tile::blank}},
{{Tile::cloud9, Tile::blank, Tile::blank, Tile::blank}},
{{Tile::blank, Tile::blank, Tile::blank, Tile::bush3}},
{{Tile::bush1, Tile::bush2, Tile::bush4, Tile::bush4}},
{{Tile::blank, Tile::blank, Tile::bush5, Tile::blank}},
{{Tile::floor1, Tile::floor2, Tile::floor3, Tile::floor4}},
{{Tile::blank, Tile::blank, Tile::mound1, Tile::mound2}},
{{Tile::blank, Tile::mound3, Tile::mound3, Tile::mound4}},
{{Tile::mound4, Tile::mound4, Tile::mound4, Tile::mound4}},
{{Tile::mound4, Tile::mound5, Tile::mound4, Tile::mound4}},
{{Tile::mound6, Tile::blank, Tile::mound4, Tile::mound6}},
{{Tile::pipe1, Tile::pipe2, Tile::pipe1, Tile::pipe2}},
{{Tile::pipe3, Tile::pipe4, Tile::pipe3, Tile::pipe4}},
{{Tile::pipetop1, Tile::pipetop2, Tile::pipetop3, Tile::pipetop4}},
{{Tile::pipetop5, Tile::pipetop6, Tile::pipetop7, Tile::pipetop8}},
{{Tile::bricks, Tile::bricks, Tile::bricks, Tile::bricks}},
{{Tile::mystery1, Tile::mystery2, Tile::mystery3, Tile::mystery4}},
{{Tile::block1, Tile::block2, Tile::block3, Tile::block4}},
{{Tile::pole1, Tile::pole2, Tile::pole1, Tile::pole2}},
{{Tile::blank, Tile::blank, Tile::poletop1, Tile::poletop2}},
{{Tile::castledoor1, Tile::castledoor2, Tile::castledoor3, Tile::castledoor3}},
{{Tile::castledoor3, Tile::castledoor3, Tile::castledoor3, Tile::castledoor3}},
{{Tile::bricks, Tile::castledoor3, Tile::bricks, Tile::castledoor3}},
{{Tile::castledoor3, Tile::bricks, Tile::castledoor3, Tile::bricks}},
{{Tile::castletop1, Tile::castletop2, Tile::bricks, Tile::bricks}},
{{Tile::castletop3, Tile::castletop4, Tile::bricks, Tile::bricks}}
};
std::set<std::tuple<int, int>> tile_pairs;
std::size_t map_size = 0;
void add(int x, int y, const std::vector<int>& v)
{
int last_tile_top = Tile::blank;
int last_tile_bottom = Tile::blank;
for (int i : v)
{
const Block& b = block_defs[i];
for (int t = 0; t < 2; t++)
{
if (b.tiles[t] != Tile::blank || last_tile_top != Tile::blank)
{
tile_pairs.insert(std::make_tuple(last_tile_top, b.tiles[t]));
}
if (b.tiles[t+2] != Tile::blank || last_tile_bottom != Tile::blank)
{
tile_pairs.insert(std::make_tuple(last_tile_bottom, b.tiles[t+2]));
}
last_tile_top = b.tiles[t];
last_tile_bottom = b.tiles[t+2];
}
if (last_tile_top != Tile::blank)
{
tile_pairs.insert(std::make_tuple(last_tile_top, Tile::blank));
}
if (last_tile_bottom != Tile::blank)
{
tile_pairs.insert(std::make_tuple(last_tile_bottom, Tile::blank));
}
}
map_size += (2 + v.size() * 2) * 2;
}
void add(int x1, int x2, int y, int t)
{
const int size = x2 - x1 + 1;
add(x1, y, std::vector<int>(size, t));
map_size -= (2 + size * 2) * 2;
map_size += 5 * 2;
}
int main()
{
// row 1
add(19, 1, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_right});
add(36, 1, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_right});
add(67, 1, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_right});
add(84, 1, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_right});
add(115, 1, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_right});
add(132, 1, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_right});
add(163, 1, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_right});
add(180, 1, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_right});
add(198, 1, {Block::poletop});
// row 2
add(8, 2, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_right});
add(19, 2, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(27, 2, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_right});
add(36, 2, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(56, 2, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_right});
add(67, 2, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(75, 2, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_right});
add(84, 2, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(104, 2, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_right});
add(115, 2, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(123, 2, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_right});
add(132, 2, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(152, 2, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_right});
add(163, 2, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(171, 2, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_middle, Block::cloud_top_right});
add(180, 2, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(198, 2, {Block::pole});
add(200, 2, {Block::cloud_top_left, Block::cloud_top_middle, Block::cloud_top_right});
// row 3
add(8, 3, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(27, 3, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(56, 3, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(75, 3, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(104, 3, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(123, 3, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(152, 3, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(171, 3, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_middle, Block::cloud_bottom_right});
add(198, 3, {Block::pole});
add(200, 3, {Block::cloud_bottom_left, Block::cloud_bottom_middle, Block::cloud_bottom_right});
// row 4
add(22, 4, {Block::mystery});
add(80, 87, 4, Block::bricks);
add(91, 4, {Block::bricks, Block::bricks, Block::bricks, Block::mystery});
add(109, 4, {Block::mystery});
add(121, 4, {Block::bricks, Block::bricks, Block::bricks});
add(128, 4, {Block::bricks, Block::mystery, Block::mystery, Block::bricks});
add(188, 189, 4, Block::block);
add(198, 4, {Block::pole});
// row 5
add(187, 189, 5, Block::block);
add(198, 5, {Block::pole});
// row 6
add(186, 189, 6, Block::block);
add(198, 6, {Block::pole});
// row 7
add(185, 189, 7, Block::block);
add(198, 7, {Block::pole});
add(203, 7, {Block::castletop_1, Block::castletop_1, Block::castletop_1});
// row 8
add(16, 8, {Block::mystery});
add(20, 8, {Block::bricks, Block::mystery, Block::bricks, Block::mystery, Block::bricks});
add(46, 8, {Block::pipetop_left, Block::pipetop_right});
add(57, 8, {Block::pipetop_left, Block::pipetop_right});
add(77, 8, {Block::bricks, Block::mystery, Block::bricks});
add(94, 8, {Block::bricks});
add(100, 8, {Block::bricks});
add(106, 8, {Block::mystery});
add(109, 8, {Block::mystery});
add(112, 8, {Block::mystery});
add(118, 8, {Block::bricks});
add(129, 8, {Block::bricks, Block::bricks});
add(137, 8, {Block::block});
add(140, 8, {Block::block});
add(151, 8, {Block::block, Block::block});
add(155, 8, {Block::block});
add(168, 8, {Block::bricks, Block::bricks, Block::mystery, Block::bricks});
add(184, 189, 8, Block::block);
add(198, 7, {Block::pole});
add(203, 7, {Block::castlewindow_1, Block::bricks, Block::castlewindow_2});
// row 9
add(38, 9, {Block::pipetop_left, Block::pipetop_right});
add(46, 9, {Block::pipe_left, Block::pipe_right});
add(50, 9, {Block::mound_top});
add(57, 9, {Block::pipe_left, Block::pipe_right});
add(98, 9, {Block::mound_top});
add(136, 9, {Block::block, Block::block});
add(140, 9, {Block::block, Block::block});
add(150, 9, {Block::block, Block::block, Block::block});
add(155, 9, {Block::block, Block::block});
add(183, 189, 9, Block::block);
add(194, 9, {Block::mound_top});
add(198, 9, {Block::pole});
add(202, 9, {Block::castletop_1, Block::castletop_2, Block::castletop_2, Block::castletop_1});
// row 10
add(1, 10, {Block::mound_left, Block::mound_center_detail, Block::mound_right});
add(17, 10, {Block::mound_top});
add(28, 10, {Block::pipetop_left, Block::pipetop_right});
add(38, 10, {Block::pipe_left, Block::pipe_right});
add(46, 10, {Block::pipe_left, Block::pipe_right});
add(49, 10, {Block::mound_left, Block::mound_center_detail, Block::mound_right});
add(57, 10, {Block::pipe_left, Block::pipe_right});
add(65, 10, {Block::mound_top});
add(97, 10, {Block::mound_left, Block::mound_center_detail, Block::mound_right});
add(113, 10, {Block::mound_top});
add(135, 10, {Block::block, Block::block, Block::block});
add(140, 10, {Block::block, Block::block, Block::block});
add(145, 10, {Block::mound_left, Block::mound_center_detail, Block::mound_right});
add(149, 10, {Block::block, Block::block, Block::block, Block::block});
add(155, 10, {Block::block, Block::block, Block::block});
add(161, 10, {Block::mound_top});
add(163, 10, {Block::pipetop_left, Block::pipetop_right});
add(179, 10, {Block::pipetop_left, Block::pipetop_right});
add(182, 189, 10, Block::block);
add(193, 10, {Block::mound_left, Block::mound_center_detail, Block::mound_right});
add(198, 10, {Block::pole});
add(202, 10, {Block::bricks, Block::bricks, Block::castledoor_top, Block::bricks, Block::bricks});
add(209, 10, {Block::mound_top});
// row 11
add(0, 11, {Block::mound_left, Block::mound_center_detail, Block::mound_center, Block::mound_center_detail, Block::mound_right});
add(11, 11, {Block::bush_left, Block::bush_middle, Block::bush_middle, Block::bush_middle, Block::bush_right, Block::mound_left, Block::mound_center_detail, Block::mound_right});
add(23, 11, {Block::bush_left, Block::bush_middle, Block::bush_right});
add(28, 11, {Block::pipe_left, Block::pipe_right});
add(38, 11, {Block::pipe_left, Block::pipe_right});
add(41, 11, {Block::bush_left, Block::bush_middle, Block::bush_middle, Block::bush_right});
add(46, 11, {Block::pipe_left, Block::pipe_right, Block::mound_left, Block::mound_center_detail, Block::mound_center, Block::mound_center_detail, Block::mound_right});
add(57, 11, {Block::pipe_left, Block::pipe_right, Block::bush_left, Block::bush_middle, Block::bush_middle, Block::bush_middle, Block::bush_right, Block::mound_left, Block::mound_center_detail, Block::mound_right});
add(71, 11, {Block::bush_left, Block::bush_middle, Block::bush_right});
add(89, 11, {Block::bush_left, Block::bush_middle, Block::bush_middle, Block::bush_right});
add(96, 11, {Block::mound_left, Block::mound_center_detail, Block::mound_center, Block::mound_center_detail, Block::mound_right});
add(107, 11, {Block::bush_left, Block::bush_middle, Block::bush_middle, Block::bush_middle, Block::bush_right, Block::mound_left, Block::mound_center_detail, Block::mound_right});
add(119, 11, {Block::bush_left, Block::bush_middle, Block::bush_right});
add(134, 11, {Block::block, Block::block, Block::block, Block::block, Block::bush_middle, Block::bush_middle, Block::block, Block::block, Block::block, Block::block, Block::mound_left, Block::mound_center_detail, Block::mound_center, Block::mound_center_detail, Block::block, Block::block, Block::block, Block::block, Block::block});
add(155, 11, {Block::block, Block::block, Block::block, Block::block, Block::bush_right, Block::mound_left, Block::mound_center_detail, Block::mound_right, Block::pipe_left, Block::pipe_right});
add(167, 11, {Block::bush_left, Block::bush_middle, Block::bush_right});
add(179, 11, {Block::pipe_left, Block::pipe_right, Block::block, Block::block, Block::block, Block::block, Block::block, Block::block, Block::block, Block::block, Block::block});
add(192, 11, {Block::mound_left, Block::mound_center_detail, Block::mound_center, Block::mound_center_detail, Block::mound_right});
add(198, 11, {Block::block});
add(202, 11, {Block::bricks, Block::bricks, Block::castledoor_bottom, Block::bricks, Block::bricks, Block::bush_right, Block::mound_left, Block::mound_center_detail, Block::mound_right});
// row 12
add(0, 68, 12, Block::floor);
add(71, 85, 12, Block::floor);
add(89, 152, 12, Block::floor);
add(155, 211, 12, Block::floor);
std::cout << "Number of tiles: " << Tile::num << std::endl;
std::cout << "Number of blocks: " << Block::num << std::endl;
std::cout << "Number tile pairs: " << tile_pairs.size() << std::endl;
std::cout << "Map size: " << map_size << std::endl;
for (const auto& tp : tile_pairs)
{
std::cout << std::get<0>(tp) << ", " << std::get<1>(tp) << std::endl;
}
}
I2luY2x1ZGUgPGFycmF5PgojaW5jbHVkZSA8Y3N0ZGRlZj4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDx2ZWN0b3I+CgovLyBUaGUgaW5kaXZpZHVhbCA4eDggcGl4ZWwgdGlsZXMKc3RydWN0IFRpbGUKewoJZW51bQoJewoJCWJsYW5rLAoJCWNsb3VkMSwgY2xvdWQyLCBjbG91ZDMsIGNsb3VkNCwgY2xvdWQ1LCBjbG91ZDYsIGNsb3VkNywgY2xvdWQ4LCBjbG91ZDksCgkJYnVzaDEsIGJ1c2gyLCBidXNoMywgYnVzaDQsIGJ1c2g1LAoJCWZsb29yMSwgZmxvb3IyLCBmbG9vcjMsIGZsb29yNCwKCQltb3VuZDEsIG1vdW5kMiwgbW91bmQzLCBtb3VuZDQsIG1vdW5kNSwgbW91bmQ2LAoJCXBpcGUxLCBwaXBlMiwgcGlwZTMsIHBpcGU0LAoJCXBpcGV0b3AxLCBwaXBldG9wMiwgcGlwZXRvcDMsIHBpcGV0b3A0LCBwaXBldG9wNSwgcGlwZXRvcDYsIHBpcGV0b3A3LCBwaXBldG9wOCwKCQlicmlja3MsCgkJbXlzdGVyeTEsIG15c3RlcnkyLCBteXN0ZXJ5MywgbXlzdGVyeTQsCgkJYmxvY2sxLCBibG9jazIsIGJsb2NrMywgYmxvY2s0LAoJCXBvbGUxLCBwb2xlMiwKCQlwb2xldG9wMSwgcG9sZXRvcDIsCgkJY2FzdGxlZG9vcjEsIGNhc3RsZWRvb3IyLCBjYXN0bGVkb29yMywKCQljYXN0bGV0b3AxLCBjYXN0bGV0b3AyLCBjYXN0bGV0b3AzLCBjYXN0bGV0b3A0LAoJCQoJCW51bQoJfTsKfTsKCi8vIEJsb2NrcyBtYWRlIHVwIGZyb20gMngyIHRpbGVzCnN0cnVjdCBCbG9jawp7CgllbnVtCgl7CgkJYmxhbmssCgkJCgkJY2xvdWRfdG9wX2xlZnQsCgkJY2xvdWRfdG9wX21pZGRsZSwKCQljbG91ZF90b3BfcmlnaHQsCgkJY2xvdWRfYm90dG9tX2xlZnQsCgkJY2xvdWRfYm90dG9tX21pZGRsZSwKCQljbG91ZF9ib3R0b21fcmlnaHQsCgkJCgkJYnVzaF9sZWZ0LAoJCWJ1c2hfbWlkZGxlLAoJCWJ1c2hfcmlnaHQsCgkJCgkJZmxvb3IsCgkJCgkJbW91bmRfdG9wLAoJCW1vdW5kX2xlZnQsCgkJbW91bmRfY2VudGVyLAoJCW1vdW5kX2NlbnRlcl9kZXRhaWwsCgkJbW91bmRfcmlnaHQsCgkJCgkJcGlwZV9sZWZ0LAoJCXBpcGVfcmlnaHQsCgkJCgkJcGlwZXRvcF9sZWZ0LAoJCXBpcGV0b3BfcmlnaHQsCgkJCgkJYnJpY2tzLAoJCQoJCW15c3RlcnksCgkJCgkJYmxvY2ssCgkJCgkJcG9sZSwKCQkKCQlwb2xldG9wLAoJCQoJCWNhc3RsZWRvb3JfdG9wLAoJCWNhc3RsZWRvb3JfYm90dG9tLAoJCQoJCWNhc3RsZXdpbmRvd18xLAoJCWNhc3RsZXdpbmRvd18yLAoJCQoJCWNhc3RsZXRvcF8xLAoJCWNhc3RsZXRvcF8yLAoJCQoJCW51bQoJfTsKCQoJc3RkOjphcnJheTxpbnQsIDQ+IHRpbGVzOwp9OwoKCi8vIEJsb2NrIGRlZmluaXRpb25zLCBvcmRlciAwIDEKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIDIgMwpCbG9jayBibG9ja19kZWZzW10gPQp7Cgl7e1RpbGU6OmJsYW5rLCBUaWxlOjpibGFuaywgVGlsZTo6YmxhbmssIFRpbGU6OmJsYW5rfX0sCgkKCXt7VGlsZTo6YmxhbmssIFRpbGU6OmJsYW5rLCBUaWxlOjpibGFuaywgVGlsZTo6Y2xvdWQzfX0sCgl7e1RpbGU6OmNsb3VkMSwgVGlsZTo6Y2xvdWQyLCBUaWxlOjpjbG91ZDQsIFRpbGU6OmNsb3VkNH19LAoJe3tUaWxlOjpibGFuaywgVGlsZTo6YmxhbmssIFRpbGU6OmNsb3VkNSwgVGlsZTo6Ymxhbmt9fSwKCXt7VGlsZTo6YmxhbmssIFRpbGU6OmNsb3VkNiwgVGlsZTo6YmxhbmssIFRpbGU6OmJsYW5rfX0sCgl7e1RpbGU6OmNsb3VkNywgVGlsZTo6Y2xvdWQ4LCBUaWxlOjpibGFuaywgVGlsZTo6Ymxhbmt9fSwKCXt7VGlsZTo6Y2xvdWQ5LCBUaWxlOjpibGFuaywgVGlsZTo6YmxhbmssIFRpbGU6OmJsYW5rfX0sCgkKCXt7VGlsZTo6YmxhbmssIFRpbGU6OmJsYW5rLCBUaWxlOjpibGFuaywgVGlsZTo6YnVzaDN9fSwKCXt7VGlsZTo6YnVzaDEsIFRpbGU6OmJ1c2gyLCBUaWxlOjpidXNoNCwgVGlsZTo6YnVzaDR9fSwKCXt7VGlsZTo6YmxhbmssIFRpbGU6OmJsYW5rLCBUaWxlOjpidXNoNSwgVGlsZTo6Ymxhbmt9fSwKCQoJe3tUaWxlOjpmbG9vcjEsIFRpbGU6OmZsb29yMiwgVGlsZTo6Zmxvb3IzLCBUaWxlOjpmbG9vcjR9fSwKCQoJe3tUaWxlOjpibGFuaywgVGlsZTo6YmxhbmssIFRpbGU6Om1vdW5kMSwgVGlsZTo6bW91bmQyfX0sCgl7e1RpbGU6OmJsYW5rLCBUaWxlOjptb3VuZDMsIFRpbGU6Om1vdW5kMywgVGlsZTo6bW91bmQ0fX0sCgl7e1RpbGU6Om1vdW5kNCwgVGlsZTo6bW91bmQ0LCBUaWxlOjptb3VuZDQsIFRpbGU6Om1vdW5kNH19LAoJe3tUaWxlOjptb3VuZDQsIFRpbGU6Om1vdW5kNSwgVGlsZTo6bW91bmQ0LCBUaWxlOjptb3VuZDR9fSwKCXt7VGlsZTo6bW91bmQ2LCBUaWxlOjpibGFuaywgVGlsZTo6bW91bmQ0LCBUaWxlOjptb3VuZDZ9fSwKCQoJe3tUaWxlOjpwaXBlMSwgVGlsZTo6cGlwZTIsIFRpbGU6OnBpcGUxLCBUaWxlOjpwaXBlMn19LAoJe3tUaWxlOjpwaXBlMywgVGlsZTo6cGlwZTQsIFRpbGU6OnBpcGUzLCBUaWxlOjpwaXBlNH19LAoJCgl7e1RpbGU6OnBpcGV0b3AxLCBUaWxlOjpwaXBldG9wMiwgVGlsZTo6cGlwZXRvcDMsIFRpbGU6OnBpcGV0b3A0fX0sCgl7e1RpbGU6OnBpcGV0b3A1LCBUaWxlOjpwaXBldG9wNiwgVGlsZTo6cGlwZXRvcDcsIFRpbGU6OnBpcGV0b3A4fX0sCgkKCXt7VGlsZTo6YnJpY2tzLCBUaWxlOjpicmlja3MsIFRpbGU6OmJyaWNrcywgVGlsZTo6YnJpY2tzfX0sCgkKCXt7VGlsZTo6bXlzdGVyeTEsIFRpbGU6Om15c3RlcnkyLCBUaWxlOjpteXN0ZXJ5MywgVGlsZTo6bXlzdGVyeTR9fSwKCQoJe3tUaWxlOjpibG9jazEsIFRpbGU6OmJsb2NrMiwgVGlsZTo6YmxvY2szLCBUaWxlOjpibG9jazR9fSwKCgl7e1RpbGU6OnBvbGUxLCBUaWxlOjpwb2xlMiwgVGlsZTo6cG9sZTEsIFRpbGU6OnBvbGUyfX0sCgkKCXt7VGlsZTo6YmxhbmssIFRpbGU6OmJsYW5rLCBUaWxlOjpwb2xldG9wMSwgVGlsZTo6cG9sZXRvcDJ9fSwKCQoJe3tUaWxlOjpjYXN0bGVkb29yMSwgVGlsZTo6Y2FzdGxlZG9vcjIsIFRpbGU6OmNhc3RsZWRvb3IzLCBUaWxlOjpjYXN0bGVkb29yM319LAoJe3tUaWxlOjpjYXN0bGVkb29yMywgVGlsZTo6Y2FzdGxlZG9vcjMsIFRpbGU6OmNhc3RsZWRvb3IzLCBUaWxlOjpjYXN0bGVkb29yM319LAoJCgl7e1RpbGU6OmJyaWNrcywgVGlsZTo6Y2FzdGxlZG9vcjMsIFRpbGU6OmJyaWNrcywgVGlsZTo6Y2FzdGxlZG9vcjN9fSwKCXt7VGlsZTo6Y2FzdGxlZG9vcjMsIFRpbGU6OmJyaWNrcywgVGlsZTo6Y2FzdGxlZG9vcjMsIFRpbGU6OmJyaWNrc319LAoJCgl7e1RpbGU6OmNhc3RsZXRvcDEsIFRpbGU6OmNhc3RsZXRvcDIsIFRpbGU6OmJyaWNrcywgVGlsZTo6YnJpY2tzfX0sCgl7e1RpbGU6OmNhc3RsZXRvcDMsIFRpbGU6OmNhc3RsZXRvcDQsIFRpbGU6OmJyaWNrcywgVGlsZTo6YnJpY2tzfX0KfTsKCgpzdGQ6OnNldDxzdGQ6OnR1cGxlPGludCwgaW50Pj4gdGlsZV9wYWlyczsKc3RkOjpzaXplX3QgbWFwX3NpemUgPSAwOwoKdm9pZCBhZGQoaW50IHgsIGludCB5LCBjb25zdCBzdGQ6OnZlY3RvcjxpbnQ+JiB2KQp7CglpbnQgbGFzdF90aWxlX3RvcCA9IFRpbGU6OmJsYW5rOwoJaW50IGxhc3RfdGlsZV9ib3R0b20gPSBUaWxlOjpibGFuazsKCWZvciAoaW50IGkgOiB2KQoJewoJCWNvbnN0IEJsb2NrJiBiID0gYmxvY2tfZGVmc1tpXTsKCQkKCQlmb3IgKGludCB0ID0gMDsgdCA8IDI7IHQrKykKCQl7CgkJCWlmIChiLnRpbGVzW3RdICE9IFRpbGU6OmJsYW5rIHx8IGxhc3RfdGlsZV90b3AgIT0gVGlsZTo6YmxhbmspCgkJCXsKCQkJCXRpbGVfcGFpcnMuaW5zZXJ0KHN0ZDo6bWFrZV90dXBsZShsYXN0X3RpbGVfdG9wLCBiLnRpbGVzW3RdKSk7CgkJCX0KCQkJCgkJCWlmIChiLnRpbGVzW3QrMl0gIT0gVGlsZTo6YmxhbmsgfHwgbGFzdF90aWxlX2JvdHRvbSAhPSBUaWxlOjpibGFuaykKCQkJewoJCQkJdGlsZV9wYWlycy5pbnNlcnQoc3RkOjptYWtlX3R1cGxlKGxhc3RfdGlsZV9ib3R0b20sIGIudGlsZXNbdCsyXSkpOwoJCQl9CgkJCQoJCQlsYXN0X3RpbGVfdG9wID0gYi50aWxlc1t0XTsKCQkJbGFzdF90aWxlX2JvdHRvbSA9IGIudGlsZXNbdCsyXTsKCQl9CgkJCgkJaWYgKGxhc3RfdGlsZV90b3AgIT0gVGlsZTo6YmxhbmspCgkJewoJCQl0aWxlX3BhaXJzLmluc2VydChzdGQ6Om1ha2VfdHVwbGUobGFzdF90aWxlX3RvcCwgVGlsZTo6YmxhbmspKTsKCQl9CgoJCWlmIChsYXN0X3RpbGVfYm90dG9tICE9IFRpbGU6OmJsYW5rKQoJCXsKCQkJdGlsZV9wYWlycy5pbnNlcnQoc3RkOjptYWtlX3R1cGxlKGxhc3RfdGlsZV9ib3R0b20sIFRpbGU6OmJsYW5rKSk7CgkJfQoJfQoJCgltYXBfc2l6ZSArPSAoMiArIHYuc2l6ZSgpICogMikgKiAyOwp9Cgp2b2lkIGFkZChpbnQgeDEsIGludCB4MiwgaW50IHksIGludCB0KQp7Cgljb25zdCBpbnQgc2l6ZSA9IHgyIC0geDEgKyAxOwoJYWRkKHgxLCB5LCBzdGQ6OnZlY3RvcjxpbnQ+KHNpemUsIHQpKTsKCW1hcF9zaXplIC09ICgyICsgc2l6ZSAqIDIpICogMjsKCW1hcF9zaXplICs9IDUgKiAyOwp9CgppbnQgbWFpbigpCnsKCS8vIHJvdyAxCglhZGQoMTksIDEsIHtCbG9jazo6Y2xvdWRfdG9wX2xlZnQsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX3JpZ2h0fSk7CglhZGQoMzYsIDEsIHtCbG9jazo6Y2xvdWRfdG9wX2xlZnQsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9yaWdodH0pOwoJYWRkKDY3LCAxLCB7QmxvY2s6OmNsb3VkX3RvcF9sZWZ0LCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9yaWdodH0pOwoJYWRkKDg0LCAxLCB7QmxvY2s6OmNsb3VkX3RvcF9sZWZ0LCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9taWRkbGUsIEJsb2NrOjpjbG91ZF90b3BfcmlnaHR9KTsKCWFkZCgxMTUsIDEsIHtCbG9jazo6Y2xvdWRfdG9wX2xlZnQsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX3JpZ2h0fSk7CglhZGQoMTMyLCAxLCB7QmxvY2s6OmNsb3VkX3RvcF9sZWZ0LCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9taWRkbGUsIEJsb2NrOjpjbG91ZF90b3BfcmlnaHR9KTsKCWFkZCgxNjMsIDEsIHtCbG9jazo6Y2xvdWRfdG9wX2xlZnQsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX3JpZ2h0fSk7CglhZGQoMTgwLCAxLCB7QmxvY2s6OmNsb3VkX3RvcF9sZWZ0LCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9taWRkbGUsIEJsb2NrOjpjbG91ZF90b3BfcmlnaHR9KTsKCWFkZCgxOTgsIDEsIHtCbG9jazo6cG9sZXRvcH0pOwoJCgkvLyByb3cgMgoJYWRkKDgsIDIsIHtCbG9jazo6Y2xvdWRfdG9wX2xlZnQsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX3JpZ2h0fSk7CglhZGQoMTksIDIsIHtCbG9jazo6Y2xvdWRfYm90dG9tX2xlZnQsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX3JpZ2h0fSk7CglhZGQoMjcsIDIsIHtCbG9jazo6Y2xvdWRfdG9wX2xlZnQsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9taWRkbGUsIEJsb2NrOjpjbG91ZF90b3BfcmlnaHR9KTsKCWFkZCgzNiwgMiwge0Jsb2NrOjpjbG91ZF9ib3R0b21fbGVmdCwgQmxvY2s6OmNsb3VkX2JvdHRvbV9taWRkbGUsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX3JpZ2h0fSk7CglhZGQoNTYsIDIsIHtCbG9jazo6Y2xvdWRfdG9wX2xlZnQsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX3JpZ2h0fSk7CglhZGQoNjcsIDIsIHtCbG9jazo6Y2xvdWRfYm90dG9tX2xlZnQsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX3JpZ2h0fSk7CglhZGQoNzUsIDIsIHtCbG9jazo6Y2xvdWRfdG9wX2xlZnQsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9taWRkbGUsIEJsb2NrOjpjbG91ZF90b3BfcmlnaHR9KTsKCWFkZCg4NCwgMiwge0Jsb2NrOjpjbG91ZF9ib3R0b21fbGVmdCwgQmxvY2s6OmNsb3VkX2JvdHRvbV9taWRkbGUsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX3JpZ2h0fSk7CglhZGQoMTA0LCAyLCB7QmxvY2s6OmNsb3VkX3RvcF9sZWZ0LCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9yaWdodH0pOwoJYWRkKDExNSwgMiwge0Jsb2NrOjpjbG91ZF9ib3R0b21fbGVmdCwgQmxvY2s6OmNsb3VkX2JvdHRvbV9taWRkbGUsIEJsb2NrOjpjbG91ZF9ib3R0b21fcmlnaHR9KTsKCWFkZCgxMjMsIDIsIHtCbG9jazo6Y2xvdWRfdG9wX2xlZnQsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9taWRkbGUsIEJsb2NrOjpjbG91ZF90b3BfcmlnaHR9KTsKCWFkZCgxMzIsIDIsIHtCbG9jazo6Y2xvdWRfYm90dG9tX2xlZnQsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX21pZGRsZSwgQmxvY2s6OmNsb3VkX2JvdHRvbV9yaWdodH0pOwoJYWRkKDE1MiwgMiwge0Jsb2NrOjpjbG91ZF90b3BfbGVmdCwgQmxvY2s6OmNsb3VkX3RvcF9taWRkbGUsIEJsb2NrOjpjbG91ZF90b3BfcmlnaHR9KTsKCWFkZCgxNjMsIDIsIHtCbG9jazo6Y2xvdWRfYm90dG9tX2xlZnQsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX3JpZ2h0fSk7CglhZGQoMTcxLCAyLCB7QmxvY2s6OmNsb3VkX3RvcF9sZWZ0LCBCbG9jazo6Y2xvdWRfdG9wX21pZGRsZSwgQmxvY2s6OmNsb3VkX3RvcF9taWRkbGUsIEJsb2NrOjpjbG91ZF90b3BfbWlkZGxlLCBCbG9jazo6Y2xvdWRfdG9wX3JpZ2h0fSk7CglhZGQoMTgwLCAyLCB7QmxvY2s6OmNsb3VkX2JvdHRvbV9sZWZ0LCBCbG9jazo6Y2xvdWRfYm90dG9tX21pZGRsZSwgQmxvY2s6OmNsb3VkX2JvdHRvbV9taWRkbGUsIEJsb2NrOjpjbG91ZF9ib3R0b21fcmlnaHR9KTsKCWFkZCgxOTgsIDIsIHtCbG9jazo6cG9sZX0pOwoJYWRkKDIwMCwgMiwge0Jsb2NrOjpjbG91ZF90b3BfbGVmdCwgQmxvY2s6OmNsb3VkX3RvcF9taWRkbGUsIEJsb2NrOjpjbG91ZF90b3BfcmlnaHR9KTsKCQoJLy8gcm93IDMKCWFkZCg4LCAzLCB7QmxvY2s6OmNsb3VkX2JvdHRvbV9sZWZ0LCBCbG9jazo6Y2xvdWRfYm90dG9tX21pZGRsZSwgQmxvY2s6OmNsb3VkX2JvdHRvbV9yaWdodH0pOwoJYWRkKDI3LCAzLCB7QmxvY2s6OmNsb3VkX2JvdHRvbV9sZWZ0LCBCbG9jazo6Y2xvdWRfYm90dG9tX21pZGRsZSwgQmxvY2s6OmNsb3VkX2JvdHRvbV9taWRkbGUsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX3JpZ2h0fSk7CglhZGQoNTYsIDMsIHtCbG9jazo6Y2xvdWRfYm90dG9tX2xlZnQsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX3JpZ2h0fSk7CglhZGQoNzUsIDMsIHtCbG9jazo6Y2xvdWRfYm90dG9tX2xlZnQsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX21pZGRsZSwgQmxvY2s6OmNsb3VkX2JvdHRvbV9taWRkbGUsIEJsb2NrOjpjbG91ZF9ib3R0b21fcmlnaHR9KTsKCWFkZCgxMDQsIDMsIHtCbG9jazo6Y2xvdWRfYm90dG9tX2xlZnQsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX3JpZ2h0fSk7CglhZGQoMTIzLCAzLCB7QmxvY2s6OmNsb3VkX2JvdHRvbV9sZWZ0LCBCbG9jazo6Y2xvdWRfYm90dG9tX21pZGRsZSwgQmxvY2s6OmNsb3VkX2JvdHRvbV9taWRkbGUsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX3JpZ2h0fSk7CglhZGQoMTUyLCAzLCB7QmxvY2s6OmNsb3VkX2JvdHRvbV9sZWZ0LCBCbG9jazo6Y2xvdWRfYm90dG9tX21pZGRsZSwgQmxvY2s6OmNsb3VkX2JvdHRvbV9yaWdodH0pOwoJYWRkKDE3MSwgMywge0Jsb2NrOjpjbG91ZF9ib3R0b21fbGVmdCwgQmxvY2s6OmNsb3VkX2JvdHRvbV9taWRkbGUsIEJsb2NrOjpjbG91ZF9ib3R0b21fbWlkZGxlLCBCbG9jazo6Y2xvdWRfYm90dG9tX21pZGRsZSwgQmxvY2s6OmNsb3VkX2JvdHRvbV9yaWdodH0pOwoJYWRkKDE5OCwgMywge0Jsb2NrOjpwb2xlfSk7CglhZGQoMjAwLCAzLCB7QmxvY2s6OmNsb3VkX2JvdHRvbV9sZWZ0LCBCbG9jazo6Y2xvdWRfYm90dG9tX21pZGRsZSwgQmxvY2s6OmNsb3VkX2JvdHRvbV9yaWdodH0pOwoJCgkvLyByb3cgNAoJYWRkKDIyLCA0LCB7QmxvY2s6Om15c3Rlcnl9KTsKCWFkZCg4MCwgODcsIDQsIEJsb2NrOjpicmlja3MpOwoJYWRkKDkxLCA0LCB7QmxvY2s6OmJyaWNrcywgQmxvY2s6OmJyaWNrcywgQmxvY2s6OmJyaWNrcywgQmxvY2s6Om15c3Rlcnl9KTsKCWFkZCgxMDksIDQsIHtCbG9jazo6bXlzdGVyeX0pOwoJYWRkKDEyMSwgNCwge0Jsb2NrOjpicmlja3MsIEJsb2NrOjpicmlja3MsIEJsb2NrOjpicmlja3N9KTsKCWFkZCgxMjgsIDQsIHtCbG9jazo6YnJpY2tzLCBCbG9jazo6bXlzdGVyeSwgQmxvY2s6Om15c3RlcnksIEJsb2NrOjpicmlja3N9KTsKCWFkZCgxODgsIDE4OSwgNCwgQmxvY2s6OmJsb2NrKTsKCWFkZCgxOTgsIDQsIHtCbG9jazo6cG9sZX0pOwoJCgkvLyByb3cgNQoJYWRkKDE4NywgMTg5LCA1LCBCbG9jazo6YmxvY2spOwoJYWRkKDE5OCwgNSwge0Jsb2NrOjpwb2xlfSk7CgkKCS8vIHJvdyA2CglhZGQoMTg2LCAxODksIDYsIEJsb2NrOjpibG9jayk7CglhZGQoMTk4LCA2LCB7QmxvY2s6OnBvbGV9KTsKCQoJLy8gcm93IDcKCWFkZCgxODUsIDE4OSwgNywgQmxvY2s6OmJsb2NrKTsKCWFkZCgxOTgsIDcsIHtCbG9jazo6cG9sZX0pOwoJYWRkKDIwMywgNywge0Jsb2NrOjpjYXN0bGV0b3BfMSwgQmxvY2s6OmNhc3RsZXRvcF8xLCBCbG9jazo6Y2FzdGxldG9wXzF9KTsKCQoJLy8gcm93IDgKCWFkZCgxNiwgOCwge0Jsb2NrOjpteXN0ZXJ5fSk7CglhZGQoMjAsIDgsIHtCbG9jazo6YnJpY2tzLCBCbG9jazo6bXlzdGVyeSwgQmxvY2s6OmJyaWNrcywgQmxvY2s6Om15c3RlcnksIEJsb2NrOjpicmlja3N9KTsKCWFkZCg0NiwgOCwge0Jsb2NrOjpwaXBldG9wX2xlZnQsIEJsb2NrOjpwaXBldG9wX3JpZ2h0fSk7CglhZGQoNTcsIDgsIHtCbG9jazo6cGlwZXRvcF9sZWZ0LCBCbG9jazo6cGlwZXRvcF9yaWdodH0pOwoJYWRkKDc3LCA4LCB7QmxvY2s6OmJyaWNrcywgQmxvY2s6Om15c3RlcnksIEJsb2NrOjpicmlja3N9KTsKCWFkZCg5NCwgOCwge0Jsb2NrOjpicmlja3N9KTsKCWFkZCgxMDAsIDgsIHtCbG9jazo6YnJpY2tzfSk7CglhZGQoMTA2LCA4LCB7QmxvY2s6Om15c3Rlcnl9KTsKCWFkZCgxMDksIDgsIHtCbG9jazo6bXlzdGVyeX0pOwoJYWRkKDExMiwgOCwge0Jsb2NrOjpteXN0ZXJ5fSk7CglhZGQoMTE4LCA4LCB7QmxvY2s6OmJyaWNrc30pOwoJYWRkKDEyOSwgOCwge0Jsb2NrOjpicmlja3MsIEJsb2NrOjpicmlja3N9KTsKCWFkZCgxMzcsIDgsIHtCbG9jazo6YmxvY2t9KTsKCWFkZCgxNDAsIDgsIHtCbG9jazo6YmxvY2t9KTsKCWFkZCgxNTEsIDgsIHtCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9ja30pOwoJYWRkKDE1NSwgOCwge0Jsb2NrOjpibG9ja30pOwoJYWRkKDE2OCwgOCwge0Jsb2NrOjpicmlja3MsIEJsb2NrOjpicmlja3MsIEJsb2NrOjpteXN0ZXJ5LCBCbG9jazo6YnJpY2tzfSk7CglhZGQoMTg0LCAxODksIDgsIEJsb2NrOjpibG9jayk7CglhZGQoMTk4LCA3LCB7QmxvY2s6OnBvbGV9KTsKCWFkZCgyMDMsIDcsIHtCbG9jazo6Y2FzdGxld2luZG93XzEsIEJsb2NrOjpicmlja3MsIEJsb2NrOjpjYXN0bGV3aW5kb3dfMn0pOwoKCS8vIHJvdyA5CglhZGQoMzgsIDksIHtCbG9jazo6cGlwZXRvcF9sZWZ0LCBCbG9jazo6cGlwZXRvcF9yaWdodH0pOwoJYWRkKDQ2LCA5LCB7QmxvY2s6OnBpcGVfbGVmdCwgQmxvY2s6OnBpcGVfcmlnaHR9KTsKCWFkZCg1MCwgOSwge0Jsb2NrOjptb3VuZF90b3B9KTsKCWFkZCg1NywgOSwge0Jsb2NrOjpwaXBlX2xlZnQsIEJsb2NrOjpwaXBlX3JpZ2h0fSk7CglhZGQoOTgsIDksIHtCbG9jazo6bW91bmRfdG9wfSk7CglhZGQoMTM2LCA5LCB7QmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2t9KTsKCWFkZCgxNDAsIDksIHtCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9ja30pOwoJYWRkKDE1MCwgOSwge0Jsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2t9KTsKCWFkZCgxNTUsIDksIHtCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9ja30pOwoJYWRkKDE4MywgMTg5LCA5LCBCbG9jazo6YmxvY2spOwoJYWRkKDE5NCwgOSwge0Jsb2NrOjptb3VuZF90b3B9KTsKCWFkZCgxOTgsIDksIHtCbG9jazo6cG9sZX0pOwoJYWRkKDIwMiwgOSwge0Jsb2NrOjpjYXN0bGV0b3BfMSwgQmxvY2s6OmNhc3RsZXRvcF8yLCBCbG9jazo6Y2FzdGxldG9wXzIsIEJsb2NrOjpjYXN0bGV0b3BfMX0pOwoJCgkvLyByb3cgMTAKCWFkZCgxLCAxMCwge0Jsb2NrOjptb3VuZF9sZWZ0LCBCbG9jazo6bW91bmRfY2VudGVyX2RldGFpbCwgQmxvY2s6Om1vdW5kX3JpZ2h0fSk7CglhZGQoMTcsIDEwLCB7QmxvY2s6Om1vdW5kX3RvcH0pOwoJYWRkKDI4LCAxMCwge0Jsb2NrOjpwaXBldG9wX2xlZnQsIEJsb2NrOjpwaXBldG9wX3JpZ2h0fSk7CglhZGQoMzgsIDEwLCB7QmxvY2s6OnBpcGVfbGVmdCwgQmxvY2s6OnBpcGVfcmlnaHR9KTsKCWFkZCg0NiwgMTAsIHtCbG9jazo6cGlwZV9sZWZ0LCBCbG9jazo6cGlwZV9yaWdodH0pOwoJYWRkKDQ5LCAxMCwge0Jsb2NrOjptb3VuZF9sZWZ0LCBCbG9jazo6bW91bmRfY2VudGVyX2RldGFpbCwgQmxvY2s6Om1vdW5kX3JpZ2h0fSk7CglhZGQoNTcsIDEwLCB7QmxvY2s6OnBpcGVfbGVmdCwgQmxvY2s6OnBpcGVfcmlnaHR9KTsKCWFkZCg2NSwgMTAsIHtCbG9jazo6bW91bmRfdG9wfSk7CglhZGQoOTcsIDEwLCB7QmxvY2s6Om1vdW5kX2xlZnQsIEJsb2NrOjptb3VuZF9jZW50ZXJfZGV0YWlsLCBCbG9jazo6bW91bmRfcmlnaHR9KTsKCWFkZCgxMTMsIDEwLCB7QmxvY2s6Om1vdW5kX3RvcH0pOwoJYWRkKDEzNSwgMTAsIHtCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrfSk7CglhZGQoMTQwLCAxMCwge0Jsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2t9KTsKCWFkZCgxNDUsIDEwLCB7QmxvY2s6Om1vdW5kX2xlZnQsIEJsb2NrOjptb3VuZF9jZW50ZXJfZGV0YWlsLCBCbG9jazo6bW91bmRfcmlnaHR9KTsKCWFkZCgxNDksIDEwLCB7QmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrfSk7CglhZGQoMTU1LCAxMCwge0Jsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2t9KTsKCWFkZCgxNjEsIDEwLCB7QmxvY2s6Om1vdW5kX3RvcH0pOwoJYWRkKDE2MywgMTAsIHtCbG9jazo6cGlwZXRvcF9sZWZ0LCBCbG9jazo6cGlwZXRvcF9yaWdodH0pOwoJYWRkKDE3OSwgMTAsIHtCbG9jazo6cGlwZXRvcF9sZWZ0LCBCbG9jazo6cGlwZXRvcF9yaWdodH0pOwoJYWRkKDE4MiwgMTg5LCAxMCwgQmxvY2s6OmJsb2NrKTsKCWFkZCgxOTMsIDEwLCB7QmxvY2s6Om1vdW5kX2xlZnQsIEJsb2NrOjptb3VuZF9jZW50ZXJfZGV0YWlsLCBCbG9jazo6bW91bmRfcmlnaHR9KTsKCWFkZCgxOTgsIDEwLCB7QmxvY2s6OnBvbGV9KTsKCWFkZCgyMDIsIDEwLCB7QmxvY2s6OmJyaWNrcywgQmxvY2s6OmJyaWNrcywgQmxvY2s6OmNhc3RsZWRvb3JfdG9wLCBCbG9jazo6YnJpY2tzLCBCbG9jazo6YnJpY2tzfSk7CglhZGQoMjA5LCAxMCwge0Jsb2NrOjptb3VuZF90b3B9KTsKCQoJLy8gcm93IDExCglhZGQoMCwgMTEsIHtCbG9jazo6bW91bmRfbGVmdCwgQmxvY2s6Om1vdW5kX2NlbnRlcl9kZXRhaWwsIEJsb2NrOjptb3VuZF9jZW50ZXIsIEJsb2NrOjptb3VuZF9jZW50ZXJfZGV0YWlsLCBCbG9jazo6bW91bmRfcmlnaHR9KTsKCWFkZCgxMSwgMTEsIHtCbG9jazo6YnVzaF9sZWZ0LCBCbG9jazo6YnVzaF9taWRkbGUsIEJsb2NrOjpidXNoX21pZGRsZSwgQmxvY2s6OmJ1c2hfbWlkZGxlLCBCbG9jazo6YnVzaF9yaWdodCwgQmxvY2s6Om1vdW5kX2xlZnQsIEJsb2NrOjptb3VuZF9jZW50ZXJfZGV0YWlsLCBCbG9jazo6bW91bmRfcmlnaHR9KTsKCWFkZCgyMywgMTEsIHtCbG9jazo6YnVzaF9sZWZ0LCBCbG9jazo6YnVzaF9taWRkbGUsIEJsb2NrOjpidXNoX3JpZ2h0fSk7CglhZGQoMjgsIDExLCB7QmxvY2s6OnBpcGVfbGVmdCwgQmxvY2s6OnBpcGVfcmlnaHR9KTsKCWFkZCgzOCwgMTEsIHtCbG9jazo6cGlwZV9sZWZ0LCBCbG9jazo6cGlwZV9yaWdodH0pOwoJYWRkKDQxLCAxMSwge0Jsb2NrOjpidXNoX2xlZnQsIEJsb2NrOjpidXNoX21pZGRsZSwgQmxvY2s6OmJ1c2hfbWlkZGxlLCBCbG9jazo6YnVzaF9yaWdodH0pOwoJYWRkKDQ2LCAxMSwge0Jsb2NrOjpwaXBlX2xlZnQsIEJsb2NrOjpwaXBlX3JpZ2h0LCBCbG9jazo6bW91bmRfbGVmdCwgQmxvY2s6Om1vdW5kX2NlbnRlcl9kZXRhaWwsIEJsb2NrOjptb3VuZF9jZW50ZXIsIEJsb2NrOjptb3VuZF9jZW50ZXJfZGV0YWlsLCBCbG9jazo6bW91bmRfcmlnaHR9KTsKCWFkZCg1NywgMTEsIHtCbG9jazo6cGlwZV9sZWZ0LCBCbG9jazo6cGlwZV9yaWdodCwgQmxvY2s6OmJ1c2hfbGVmdCwgQmxvY2s6OmJ1c2hfbWlkZGxlLCBCbG9jazo6YnVzaF9taWRkbGUsIEJsb2NrOjpidXNoX21pZGRsZSwgQmxvY2s6OmJ1c2hfcmlnaHQsIEJsb2NrOjptb3VuZF9sZWZ0LCBCbG9jazo6bW91bmRfY2VudGVyX2RldGFpbCwgQmxvY2s6Om1vdW5kX3JpZ2h0fSk7CglhZGQoNzEsIDExLCB7QmxvY2s6OmJ1c2hfbGVmdCwgQmxvY2s6OmJ1c2hfbWlkZGxlLCBCbG9jazo6YnVzaF9yaWdodH0pOwoJYWRkKDg5LCAxMSwge0Jsb2NrOjpidXNoX2xlZnQsIEJsb2NrOjpidXNoX21pZGRsZSwgQmxvY2s6OmJ1c2hfbWlkZGxlLCBCbG9jazo6YnVzaF9yaWdodH0pOwoJYWRkKDk2LCAxMSwge0Jsb2NrOjptb3VuZF9sZWZ0LCBCbG9jazo6bW91bmRfY2VudGVyX2RldGFpbCwgQmxvY2s6Om1vdW5kX2NlbnRlciwgQmxvY2s6Om1vdW5kX2NlbnRlcl9kZXRhaWwsIEJsb2NrOjptb3VuZF9yaWdodH0pOwoJYWRkKDEwNywgMTEsIHtCbG9jazo6YnVzaF9sZWZ0LCBCbG9jazo6YnVzaF9taWRkbGUsIEJsb2NrOjpidXNoX21pZGRsZSwgQmxvY2s6OmJ1c2hfbWlkZGxlLCBCbG9jazo6YnVzaF9yaWdodCwgQmxvY2s6Om1vdW5kX2xlZnQsIEJsb2NrOjptb3VuZF9jZW50ZXJfZGV0YWlsLCBCbG9jazo6bW91bmRfcmlnaHR9KTsKCWFkZCgxMTksIDExLCB7QmxvY2s6OmJ1c2hfbGVmdCwgQmxvY2s6OmJ1c2hfbWlkZGxlLCBCbG9jazo6YnVzaF9yaWdodH0pOwoJYWRkKDEzNCwgMTEsIHtCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2ssIEJsb2NrOjpidXNoX21pZGRsZSwgQmxvY2s6OmJ1c2hfbWlkZGxlLCBCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2ssIEJsb2NrOjptb3VuZF9sZWZ0LCBCbG9jazo6bW91bmRfY2VudGVyX2RldGFpbCwgQmxvY2s6Om1vdW5kX2NlbnRlciwgQmxvY2s6Om1vdW5kX2NlbnRlcl9kZXRhaWwsIEJsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrfSk7CglhZGQoMTU1LCAxMSwge0Jsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9jaywgQmxvY2s6OmJ1c2hfcmlnaHQsIEJsb2NrOjptb3VuZF9sZWZ0LCBCbG9jazo6bW91bmRfY2VudGVyX2RldGFpbCwgQmxvY2s6Om1vdW5kX3JpZ2h0LCBCbG9jazo6cGlwZV9sZWZ0LCBCbG9jazo6cGlwZV9yaWdodH0pOwoJYWRkKDE2NywgMTEsIHtCbG9jazo6YnVzaF9sZWZ0LCBCbG9jazo6YnVzaF9taWRkbGUsIEJsb2NrOjpidXNoX3JpZ2h0fSk7CglhZGQoMTc5LCAxMSwge0Jsb2NrOjpwaXBlX2xlZnQsIEJsb2NrOjpwaXBlX3JpZ2h0LCBCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrLCBCbG9jazo6YmxvY2ssIEJsb2NrOjpibG9jaywgQmxvY2s6OmJsb2NrfSk7CglhZGQoMTkyLCAxMSwge0Jsb2NrOjptb3VuZF9sZWZ0LCBCbG9jazo6bW91bmRfY2VudGVyX2RldGFpbCwgQmxvY2s6Om1vdW5kX2NlbnRlciwgQmxvY2s6Om1vdW5kX2NlbnRlcl9kZXRhaWwsIEJsb2NrOjptb3VuZF9yaWdodH0pOwoJYWRkKDE5OCwgMTEsIHtCbG9jazo6YmxvY2t9KTsKCWFkZCgyMDIsIDExLCB7QmxvY2s6OmJyaWNrcywgQmxvY2s6OmJyaWNrcywgQmxvY2s6OmNhc3RsZWRvb3JfYm90dG9tLCBCbG9jazo6YnJpY2tzLCBCbG9jazo6YnJpY2tzLCBCbG9jazo6YnVzaF9yaWdodCwgQmxvY2s6Om1vdW5kX2xlZnQsIEJsb2NrOjptb3VuZF9jZW50ZXJfZGV0YWlsLCBCbG9jazo6bW91bmRfcmlnaHR9KTsKCgkvLyByb3cgMTIKCWFkZCgwLCA2OCwgMTIsIEJsb2NrOjpmbG9vcik7CglhZGQoNzEsIDg1LCAxMiwgQmxvY2s6OmZsb29yKTsKCWFkZCg4OSwgMTUyLCAxMiwgQmxvY2s6OmZsb29yKTsKCWFkZCgxNTUsIDIxMSwgMTIsIEJsb2NrOjpmbG9vcik7CgkKCXN0ZDo6Y291dCA8PCAiTnVtYmVyIG9mIHRpbGVzOiAiIDw8IFRpbGU6Om51bSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgIk51bWJlciBvZiBibG9ja3M6ICIgPDwgQmxvY2s6Om51bSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgIk51bWJlciB0aWxlIHBhaXJzOiAiIDw8IHRpbGVfcGFpcnMuc2l6ZSgpIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAiTWFwIHNpemU6ICIgPDwgbWFwX3NpemUgPDwgc3RkOjplbmRsOwoJCglmb3IgKGNvbnN0IGF1dG8mIHRwIDogdGlsZV9wYWlycykKCXsKCQlzdGQ6OmNvdXQgPDwgc3RkOjpnZXQ8MD4odHApIDw8ICIsICIgPDwgc3RkOjpnZXQ8MT4odHApIDw8IHN0ZDo6ZW5kbDsKCX0KfQ==