#include <iostream>
#include <vector>
#include <limits>
enum class Operator{
None,
Plus,
Minus,
Multi,
Div,
Mod,
Wall,
Max,
} ;
static const int Top = 0 ;
static const int Right = 1 ;
static const int Bottom = 2 ;
static const int Left = 3 ;
struct Wall{
Operator Op;
double Value;
bool IsWalked;
} ;
struct Floor{
union {
struct {
int Top;
int Right;
int Bottom;
int Left;
} ;
int Dir[ 4 ] ;
} ;
Floor( int Top_, int Right_, int Bottom_, int Left_) {
Dir[ 0 ] = Top_;
Dir[ 1 ] = Right_;
Dir[ 2 ] = Bottom_;
Dir[ 3 ] = Left_;
}
} ;
struct FootPrint;
typedef std:: pair < std:: vector < std:: vector < Floor>> ,std:: vector < Wall>> Map;
typedef std:: vector < FootPrint> Stack;
struct Point{
int X, Y;
} ;
struct FootPrint{
Point Pos;
int From, To;
int Score;
//Stack MB;
} ;
Point Direction[ 4 ] { { 0 , - 1 } , { 1 , 0 } , { 0 , 1 } , { - 1 , 0 } } ;
static const int Width = 7 ;
static const int Height = 7 ;
Map MakeData( ) {
std:: vector < Wall> WallData = {
{ Operator:: Minus , 2 , false } , { Operator:: Plus , 5 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 3 , false } , { Operator:: Plus , 2 , false } , { Operator:: Minus , 1 , false } ,///
{ Operator:: Plus , 1 , false } , { Operator:: Plus , 3 , false } , { Operator:: Plus , 2 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 2 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 3 , false } ,///
{ Operator:: Plus , 1 , false } , { Operator:: Plus , 4 , false } , { Operator:: Multi , 2 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 4 , false } , { Operator:: Minus , 2 , false } ,///
{ Operator:: Plus , 4 , false } , { Operator:: Plus , 2 , false } , { Operator:: Plus , 1 , false } , { Operator:: Plus , 3 , false } , { Operator:: Plus , 3 , false } , { Operator:: Plus , 5 , false } , { Operator:: Minus , 1 , false } ,///
{ Operator:: Plus , 3 , false } , { Operator:: Plus , 2 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 4 , false } , { Operator:: Plus , 1 , false } , { Operator:: Multi , 3 , false } ,///
{ Operator:: Minus , 2 , false } , { Operator:: Minus , 1 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 5 , false } , { Operator:: Minus , 1 , false } , { Operator:: Minus , 2 , false } , { Operator:: Plus , 2 , false } ,///
{ Operator:: Plus , 4 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 3 , false } , { Operator:: Minus , 2 , false } , { Operator:: Plus , 5 , false } , { Operator:: Plus , 1 , false } ,///
{ Operator:: Plus , 3 , false } , { Operator:: Plus , 5 , false } , { Operator:: Plus , 4 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 2 , false } , { Operator:: Plus , 2 , false } , { Operator:: Plus , 1 , false } ,///
{ Operator:: Minus , 2 , false } , { Operator:: Multi , 3 , false } , { Operator:: Plus , 1 , false } , { Operator:: Plus , 2 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 3 , false } ,///
{ Operator:: Minus , 1 , false } , { Operator:: Plus , 1 , false } , { Operator:: Minus , 2 , false } , { Operator:: Plus , 4 , false } , { Operator:: Plus , 4 , false } , { Operator:: Plus , 1 , false } , { Operator:: Minus , 2 , false } ,///
{ Operator:: Plus , 5 , false } , { Operator:: Plus , 1 , false } , { Operator:: Plus , 3 , false } , { Operator:: Minus , 1 , false } , { Operator:: Multi , 2 , false } , { Operator:: Plus , 4 , false } ,///
{ Operator:: Plus , 1 , false } , { Operator:: Plus , 2 , false } , { Operator:: Plus , 2 , false } , { Operator:: Minus , 2 , false } , { Operator:: Plus , 1 , false } , { Operator:: Plus , 5 , false } , { Operator:: Plus , 3 , false } ,///
{ Operator:: Plus , 3 , false } , { Operator:: Minus , 1 , false } , { Operator:: Plus , 2 , false } , { Operator:: Plus , 4 , false } , { Operator:: Minus , 2 , false } , { Operator:: Plus , 1 , false } ,///
} ;
std:: vector < std:: vector < Floor>> FloorData = { //これは自動生成できそうだけど、わからん。脳弱になるー。うぎゃーーーー!!!上下幅は7*7で13。
{ { - 1 , 0 , 6 , - 1 } , { - 1 , 1 , 7 , 0 } , { - 1 , 2 , 8 , 1 } , { - 1 , 3 , 9 , 2 } , { - 1 , 4 , 10 , 3 } , { - 1 , 5 , 11 , 4 } , { - 1 , - 1 , 12 , 5 } , } ,
{ { 6 , 13 , 19 , - 1 } , { 7 , 14 , 20 , 13 } , { 8 , 15 , 21 , 14 } , { 9 , 16 , 22 , 15 } , { 10 , 17 , 23 , 16 } , { 11 , 18 , 24 , 17 } , { 12 , - 1 , 25 , 18 } , } ,
{ { 19 , 26 , 32 , - 1 } , { 20 , 27 , 33 , 26 } , { 21 , 28 , 34 , 27 } , { 22 , 29 , 35 , 28 } , { 23 , 30 , 36 , 29 } , { 24 , 31 , 37 , 30 } , { 25 , - 1 , 38 , 31 } , } ,
{ { 32 , 39 , 45 , - 1 } , { 33 , 40 , 46 , 39 } , { 34 , 41 , 47 , 40 } , { 35 , 42 , 48 , 41 } , { 36 , 43 , 49 , 42 } , { 37 , 44 , 50 , 43 } , { 38 , - 1 , 51 , 44 } } ,
{ { 45 , 52 , 58 , - 1 } , { 46 , 53 , 59 , 52 } , { 47 , 54 , 60 , 53 } , { 48 , 55 , 61 , 54 } , { 49 , 56 , 62 , 55 } , { 50 , 57 , 63 , 56 } , { 51 , - 1 , 64 , 57 } , } ,
{ { 58 , 65 , 71 , - 1 } , { 59 , 66 , 72 , 65 } , { 60 , 67 , 73 , 66 } , { 61 , 68 , 74 , 67 } , { 62 , 69 , 75 , 68 } , { 63 , 70 , 76 , 69 } , { 64 ,- 1 ,77 ,70 } , } ,
{ { 71 , 78 , - 1 , - 1 } , { 72 , 79 , - 1 , 78 } , { 73 , 80 , - 1 , 79 } , { 74 , 81 , - 1 , 80 } , { 75 , 82 , - 1 , 81 } , { 76 , 83 , - 1 , 82 } , { 77 ,- 1 ,- 1 ,83 } , } ,
} ;
return std:: make_pair ( FloorData,WallData) ;
}
bool ShowMap( Map& M,bool ViewType = true ) {
bool F2 = false ;
for ( auto & oo : M.first ) {
if ( ViewType == true ) {
std:: cout << " " ;
for ( auto & o : oo) {
if ( o.Dir [ Right] == - 1 ) continue ;
if ( M.second [ o.Dir [ Right] ] .Op == Operator:: Plus ) std:: cout << '+' ;
if ( M.second [ o.Dir [ Right] ] .Op == Operator:: Minus ) std:: cout << '-' ;
if ( M.second [ o.Dir [ Right] ] .Op == Operator:: Multi ) std:: cout << '*' ;
if ( M.second [ o.Dir [ Right] ] .Op == Operator:: Div ) std:: cout << '/' ;
std:: cout << M.second [ o.Dir [ Right] ] .Value << " " ;
}
std:: cout << std:: endl ;
for ( auto & o : oo) {
if ( o.Dir [ Bottom] == - 1 ) continue ;
if ( M.second [ o.Dir [ Bottom] ] .Op == Operator:: Plus ) std:: cout << '+' ;
if ( M.second [ o.Dir [ Bottom] ] .Op == Operator:: Minus ) std:: cout << '-' ;
if ( M.second [ o.Dir [ Bottom] ] .Op == Operator:: Multi ) std:: cout << '*' ;
if ( M.second [ o.Dir [ Bottom] ] .Op == Operator:: Div ) std:: cout << '/' ;
std:: cout << M.second [ o.Dir [ Bottom] ] .Value << " " ;
}
std:: cout << std:: endl ;
}
else {
for ( auto & o : oo) {
if ( o.Dir [ Top] == - 1 ) continue ;
F2 = true ;
if ( M.second [ o.Dir [ Top] ] .Op == Operator:: Plus ) std:: cout << '+' ;
if ( M.second [ o.Dir [ Top] ] .Op == Operator:: Minus ) std:: cout << '-' ;
if ( M.second [ o.Dir [ Top] ] .Op == Operator:: Multi ) std:: cout << '*' ;
if ( M.second [ o.Dir [ Top] ] .Op == Operator:: Div ) std:: cout << '/' ;
std:: cout << M.second [ o.Dir [ Top] ] .Value << " " ;
}
if ( F2 == true ) std:: cout << std:: endl ;
for ( auto & o : oo) {
if ( o.Dir [ Left] == - 1 ) continue ;
std:: cout << " " ;
if ( M.second [ o.Dir [ Left] ] .Op == Operator:: Plus ) std:: cout << '+' ;
if ( M.second [ o.Dir [ Left] ] .Op == Operator:: Minus ) std:: cout << '-' ;
if ( M.second [ o.Dir [ Left] ] .Op == Operator:: Multi ) std:: cout << '*' ;
if ( M.second [ o.Dir [ Left] ] .Op == Operator:: Div ) std:: cout << '/' ;
std:: cout << M.second [ o.Dir [ Left] ] .Value ;
}
std:: cout << std:: endl ;
}
}
return 0 ;
}
bool Find( Stack& ST,Point P,int D) {
for ( auto & o : ST) {
if ( ( o.Pos .X == P.X ) && ( o.Pos .Y == P.Y ) && ( ( o.From == D) || ( o.To == D) ) ) return true ;
}
return false ;
}
int CalcScore( Operator Op, int SA, int SB) {
switch ( Op)
{
case Operator:: Plus :
return SA + SB;
case Operator:: Minus :
return SA - SB;
case Operator:: Multi :
return SA* SB;
case Operator:: Div :
return SA / SB;
case Operator:: Mod :
return SA% SB;
default :
break ;
}
return std:: numeric_limits < int > :: min ( ) / 16 ;
}
int From( Point A, Point B) {
Point To{ A.X - B.X , A.Y - B.Y } ;
for ( int i = 0 ; i < 4 ; i++ ) {
if ( Direction[ i] .X == To.X && Direction[ i] .Y == To.Y ) return ( i + 2 ) % 4 ;
}
return - 1 ;
}
bool IsMove( Point P, Point L) {
if ( P.X < 0 ) return false ;
if ( P.Y < 0 ) return false ;
if ( P.X < L.X ) return false ;
if ( P.Y < L.Y ) return false ;
return true ;
}
bool Search( Map& M,Stack& S,int & Score,const Point& Start,const Point& End) {
Point Now = Start;
Stack ST;
Stack MST;
int MaxScore = 0 ;
int ScoreT = Score;
int Dir = 0 ;
FootPrint FP{ Now, - 1 , Dir, Score } ;
while ( ! ( ( Now.X == End.X ) && ( Now.Y == End.Y ) ) ) {
//while (true){
if ( ST.size ( ) >= 1 ) {
FP.From = From( Now, ST[ ST.size ( ) - 1 ] .Pos ) ;
}
ST.push_back ( FP) ;
if ( IsMove( { Now.X + Direction[ Dir] .X , Now.Y + Direction[ Dir] .Y } , { Width, Height } ) ) {
Dir++ ;
L1:
if ( Dir == 4 ) {
ST.pop_back ( ) ;
Dir = ST.back ( ) .To + 1 ;
}
if ( Dir == 4 ) goto L1;
if ( ST.size ( ) == 0 ) {
S = MST;
Score = MaxScore;
return true ;
}
Dir % = 4 ;
continue ;
}
if ( Find( ST, { Now.X + Direction[ Dir] .X , Now.Y + Direction[ Dir] .Y } , Dir) == true ) {
Dir++ ;
L2:
if ( Dir == 4 ) {
ST.pop_back ( ) ;
Dir = ST.back ( ) .To + 1 ;
}
if ( Dir == 4 ) goto L2;
if ( ST.size ( ) == 0 ) {
S = MST;
Score = MaxScore;
return true ;
}
Dir % = 4 ;
continue ;
}
Point PT{ Now.X + Direction[ Dir] .X , Now.Y + Direction[ Dir] .Y } ;
Operator Op = M.second [ M.first [ PT.Y ] [ PT.X ] .Dir [ Dir] ] .Op ;
int V = M.second [ M.first [ PT.Y ] [ PT.X ] .Dir [ Dir] ] .Value ;
ScoreT = CalcScore( Op, V, ScoreT) ;
FP.Pos = PT;
FP.Score = ScoreT;
FP.To = Dir
}
}
int main( ) {
auto M = MakeData( ) ;
ShowMap( M) ;
std:: cout << std:: endl ;
ShowMap( M, false ) ;
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bGltaXRzPgoKZW51bSBjbGFzcyBPcGVyYXRvcnsKCU5vbmUsCglQbHVzLAoJTWludXMsCglNdWx0aSwKCURpdiwKCU1vZCwKCVdhbGwsCglNYXgsCn07CgpzdGF0aWMgY29uc3QgaW50IFRvcCA9IDA7CnN0YXRpYyBjb25zdCBpbnQgUmlnaHQgPSAxOwpzdGF0aWMgY29uc3QgaW50IEJvdHRvbSA9IDI7CnN0YXRpYyBjb25zdCBpbnQgTGVmdCA9IDM7CgpzdHJ1Y3QgV2FsbHsKCU9wZXJhdG9yIE9wOwoJZG91YmxlIFZhbHVlOwoJYm9vbCBJc1dhbGtlZDsKfTsKCnN0cnVjdCBGbG9vcnsKCgl1bmlvbnsKCQlzdHJ1Y3R7CgkJCWludCBUb3A7CgkJCWludCBSaWdodDsKCQkJaW50IEJvdHRvbTsKCQkJaW50IExlZnQ7CgkJfTsKCQlpbnQgRGlyWzRdOwoJfTsKCUZsb29yKGludCBUb3BfLCBpbnQgUmlnaHRfLCBpbnQgQm90dG9tXywgaW50IExlZnRfKXsKCQlEaXJbMF0gPSBUb3BfOwoJCURpclsxXSA9IFJpZ2h0XzsgCgkJRGlyWzJdID0gQm90dG9tXzsKCQlEaXJbM10gPSBMZWZ0XzsKCX0KfTsKCnN0cnVjdCBGb290UHJpbnQ7CnR5cGVkZWYgc3RkOjpwYWlyPHN0ZDo6dmVjdG9yPHN0ZDo6dmVjdG9yPEZsb29yPj4sc3RkOjp2ZWN0b3I8V2FsbD4+IE1hcDsKdHlwZWRlZiBzdGQ6OnZlY3RvcjxGb290UHJpbnQ+IFN0YWNrOwoKc3RydWN0IFBvaW50ewoJaW50IFgsIFk7Cn07CgoKc3RydWN0IEZvb3RQcmludHsKCVBvaW50IFBvczsKCWludCBGcm9tLCBUbzsKCWludCBTY29yZTsKCS8vU3RhY2sgTUI7Cn07CgpQb2ludCBEaXJlY3Rpb25bNF17eyAwLCAtMSB9LCB7IDEsIDAgfSwgeyAwLCAxIH0sIHsgLTEsIDAgfX07CgpzdGF0aWMgY29uc3QgaW50IFdpZHRoID0gNzsKc3RhdGljIGNvbnN0IGludCBIZWlnaHQgPSA3OwoKTWFwIE1ha2VEYXRhKCl7CglzdGQ6OnZlY3RvcjxXYWxsPiBXYWxsRGF0YSA9IHsKCQl7IE9wZXJhdG9yOjpNaW51cywgMiwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6UGx1cywgNSwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6TWludXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDMsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDIsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAxLCBmYWxzZSB9LC8vLwoJCXsgT3BlcmF0b3I6OlBsdXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDMsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDIsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAxLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAyLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpNaW51cywgMSwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6UGx1cywgMywgZmFsc2UgfSwvLy8KCQl7IE9wZXJhdG9yOjpQbHVzLCAxLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCA0LCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpNdWx0aSwgMiwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6TWludXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDQsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAyLCBmYWxzZSB9LC8vLwoJCXsgT3BlcmF0b3I6OlBsdXMsIDQsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDIsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDMsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDMsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDUsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAxLCBmYWxzZSB9LC8vLwoJCXsgT3BlcmF0b3I6OlBsdXMsIDMsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDIsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAxLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCA0LCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAxLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpNdWx0aSwgMywgZmFsc2UgfSwvLy8KCQl7IE9wZXJhdG9yOjpNaW51cywgMiwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6TWludXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAxLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCA1LCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpNaW51cywgMSwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6TWludXMsIDIsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDIsIGZhbHNlIH0sLy8vCgkJeyBPcGVyYXRvcjo6UGx1cywgNCwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6TWludXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDMsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAyLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCA1LCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAxLCBmYWxzZSB9LC8vLwoJCXsgT3BlcmF0b3I6OlBsdXMsIDMsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDUsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDQsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAxLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAyLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAyLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAxLCBmYWxzZSB9LC8vLwoJCXsgT3BlcmF0b3I6Ok1pbnVzLCAyLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpNdWx0aSwgMywgZmFsc2UgfSwgeyBPcGVyYXRvcjo6UGx1cywgMSwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6UGx1cywgMiwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6TWludXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDMsIGZhbHNlIH0sLy8vCgkJeyBPcGVyYXRvcjo6TWludXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAyLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCA0LCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCA0LCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAxLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpNaW51cywgMiwgZmFsc2UgfSwvLy8KCQl7IE9wZXJhdG9yOjpQbHVzLCA1LCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAxLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAzLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpNaW51cywgMSwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6TXVsdGksIDIsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDQsIGZhbHNlIH0sLy8vCgkJeyBPcGVyYXRvcjo6UGx1cywgMSwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6UGx1cywgMiwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6UGx1cywgMiwgZmFsc2UgfSwgeyBPcGVyYXRvcjo6TWludXMsIDIsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDUsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDMsIGZhbHNlIH0sLy8vCgkJeyBPcGVyYXRvcjo6UGx1cywgMywgZmFsc2UgfSwgeyBPcGVyYXRvcjo6TWludXMsIDEsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDIsIGZhbHNlIH0sIHsgT3BlcmF0b3I6OlBsdXMsIDQsIGZhbHNlIH0sIHsgT3BlcmF0b3I6Ok1pbnVzLCAyLCBmYWxzZSB9LCB7IE9wZXJhdG9yOjpQbHVzLCAxLCBmYWxzZSB9LC8vLwoJfTsKCXN0ZDo6dmVjdG9yPHN0ZDo6dmVjdG9yPEZsb29yPj4gRmxvb3JEYXRhID0gey8v44GT44KM44Gv6Ieq5YuV55Sf5oiQ44Gn44GN44Gd44GG44Gg44GR44Gp44CB44KP44GL44KJ44KT44CC6ISz5byx44Gr44Gq44KL44O844CC44GG44GO44KD44O844O844O844O877yB77yB77yB5LiK5LiL5bmF44GvNyo344GnMTPjgIIKCQl7IHsgLTEsIDAsIDYsIC0xIH0sIHsgLTEsIDEsIDcsIDAgfSwgeyAtMSwgMiwgOCwgMSB9LCB7IC0xLCAzLCA5LCAyIH0sIHsgLTEsIDQsIDEwLCAzIH0sIHsgLTEsIDUsIDExLCA0IH0sIHsgLTEsIC0xLCAxMiwgNSB9LCB9LAoJCXsgeyA2LCAxMywgMTksIC0xIH0sIHsgNywgMTQsIDIwLCAxMyB9LCB7IDgsIDE1LCAyMSwgMTQgfSwgeyA5LCAxNiwgMjIsIDE1IH0sIHsgMTAsIDE3LCAyMywgMTYgfSwgeyAxMSwgMTgsIDI0LCAxNyB9LCB7IDEyLCAtMSwgMjUsIDE4IH0sIH0sCgkJeyB7IDE5LCAyNiwgMzIsIC0xIH0sIHsgMjAsIDI3LCAzMywgMjYgfSwgeyAyMSwgMjgsIDM0LCAyNyB9LCB7IDIyLCAyOSwgMzUsIDI4IH0sIHsgMjMsIDMwLCAzNiwgMjkgfSwgeyAyNCwgMzEsIDM3LCAzMCB9LCB7IDI1LCAtMSwgMzgsIDMxIH0sIH0sCgkJeyB7IDMyLCAzOSwgNDUsIC0xIH0sIHsgMzMsIDQwLCA0NiwgMzkgfSwgeyAzNCwgNDEsIDQ3LCA0MCB9LCB7IDM1LCA0MiwgNDgsIDQxIH0sIHsgMzYsIDQzLCA0OSwgNDIgfSwgeyAzNywgNDQsIDUwLCA0MyB9LCB7IDM4LCAtMSwgNTEsIDQ0IH0gfSwKCQl7IHsgNDUsIDUyLCA1OCwgLTEgfSwgeyA0NiwgNTMsIDU5LCA1MiB9LCB7IDQ3LCA1NCwgNjAsIDUzIH0sIHsgNDgsIDU1LCA2MSwgNTQgfSwgeyA0OSwgNTYsIDYyLCA1NSB9LCB7IDUwLCA1NywgNjMsIDU2IH0sIHsgNTEsIC0xLCA2NCwgNTcgfSwgfSwKCQl7IHsgNTgsIDY1LCA3MSwgLTEgfSwgeyA1OSwgNjYsIDcyLCA2NSB9LCB7IDYwLCA2NywgNzMsIDY2IH0sIHsgNjEsIDY4LCA3NCwgNjcgfSwgeyA2MiwgNjksIDc1LCA2OCB9LCB7IDYzLCA3MCwgNzYsIDY5IH0sIHs2NCwtMSw3Nyw3MH0sIH0sCgkJeyB7IDcxLCA3OCwgLTEsIC0xIH0sIHsgNzIsIDc5LCAtMSwgNzggfSwgeyA3MywgODAsIC0xLCA3OSB9LCB7IDc0LCA4MSwgLTEsIDgwIH0sIHsgNzUsIDgyLCAtMSwgODEgfSwgeyA3NiwgODMsIC0xLCA4MiB9LCB7NzcsLTEsLTEsODN9LCB9LAoJfTsKCglyZXR1cm4gc3RkOjptYWtlX3BhaXIoRmxvb3JEYXRhLFdhbGxEYXRhKTsKfQoKYm9vbCBTaG93TWFwKE1hcCYgTSxib29sIFZpZXdUeXBlID0gdHJ1ZSApewoJYm9vbCBGMiA9IGZhbHNlOwoKCWZvciAoYXV0byYgb28gOiBNLmZpcnN0KXsKCQlpZiAoVmlld1R5cGUgPT0gdHJ1ZSl7CgkJCXN0ZDo6Y291dCA8PCAiICAiOwoJCQlmb3IgKGF1dG8mIG8gOiBvbyl7CgkJCQlpZiAoby5EaXJbUmlnaHRdID09IC0xKWNvbnRpbnVlOwoJCQkJaWYgKE0uc2Vjb25kW28uRGlyW1JpZ2h0XV0uT3AgPT0gT3BlcmF0b3I6OlBsdXMpIHN0ZDo6Y291dCA8PCAnKyc7CgkJCQlpZiAoTS5zZWNvbmRbby5EaXJbUmlnaHRdXS5PcCA9PSBPcGVyYXRvcjo6TWludXMpIHN0ZDo6Y291dCA8PCAnLSc7CgkJCQlpZiAoTS5zZWNvbmRbby5EaXJbUmlnaHRdXS5PcCA9PSBPcGVyYXRvcjo6TXVsdGkpIHN0ZDo6Y291dCA8PCAnKic7CgkJCQlpZiAoTS5zZWNvbmRbby5EaXJbUmlnaHRdXS5PcCA9PSBPcGVyYXRvcjo6RGl2KSBzdGQ6OmNvdXQgPDwgJy8nOwoJCQkJc3RkOjpjb3V0IDw8IE0uc2Vjb25kW28uRGlyW1JpZ2h0XV0uVmFsdWUgPDwgIiAgIjsKCQkJfQoJCQlzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoJCQlmb3IgKGF1dG8mIG8gOiBvbyl7CgkJCQlpZiAoby5EaXJbQm90dG9tXSA9PSAtMSljb250aW51ZTsKCQkJCWlmIChNLnNlY29uZFtvLkRpcltCb3R0b21dXS5PcCA9PSBPcGVyYXRvcjo6UGx1cykgc3RkOjpjb3V0IDw8ICcrJzsKCQkJCWlmIChNLnNlY29uZFtvLkRpcltCb3R0b21dXS5PcCA9PSBPcGVyYXRvcjo6TWludXMpIHN0ZDo6Y291dCA8PCAnLSc7CgkJCQlpZiAoTS5zZWNvbmRbby5EaXJbQm90dG9tXV0uT3AgPT0gT3BlcmF0b3I6Ok11bHRpKSBzdGQ6OmNvdXQgPDwgJyonOwoJCQkJaWYgKE0uc2Vjb25kW28uRGlyW0JvdHRvbV1dLk9wID09IE9wZXJhdG9yOjpEaXYpIHN0ZDo6Y291dCA8PCAnLyc7CgkJCQlzdGQ6OmNvdXQgPDwgTS5zZWNvbmRbby5EaXJbQm90dG9tXV0uVmFsdWUgPDwgIiAgIjsKCQkJfQoJCQlzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoJCX0KCQllbHNlewoJCQlmb3IgKGF1dG8mIG8gOiBvbyl7CgkJCQlpZiAoby5EaXJbVG9wXSA9PSAtMSljb250aW51ZTsKCQkJCUYyID0gdHJ1ZTsKCQkJCWlmIChNLnNlY29uZFtvLkRpcltUb3BdXS5PcCA9PSBPcGVyYXRvcjo6UGx1cykgc3RkOjpjb3V0IDw8ICcrJzsKCQkJCWlmIChNLnNlY29uZFtvLkRpcltUb3BdXS5PcCA9PSBPcGVyYXRvcjo6TWludXMpIHN0ZDo6Y291dCA8PCAnLSc7CgkJCQlpZiAoTS5zZWNvbmRbby5EaXJbVG9wXV0uT3AgPT0gT3BlcmF0b3I6Ok11bHRpKSBzdGQ6OmNvdXQgPDwgJyonOwoJCQkJaWYgKE0uc2Vjb25kW28uRGlyW1RvcF1dLk9wID09IE9wZXJhdG9yOjpEaXYpIHN0ZDo6Y291dCA8PCAnLyc7CgkJCQlzdGQ6OmNvdXQgPDwgTS5zZWNvbmRbby5EaXJbVG9wXV0uVmFsdWUgPDwgIiAgIjsKCQkJfQoJCQlpZihGMiA9PSB0cnVlKSBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoJCQlmb3IgKGF1dG8mIG8gOiBvbyl7CgkJCQlpZiAoby5EaXJbTGVmdF0gPT0gLTEpY29udGludWU7CgkJCQlzdGQ6OmNvdXQgPDwgIiAgIjsKCQkJCWlmIChNLnNlY29uZFtvLkRpcltMZWZ0XV0uT3AgPT0gT3BlcmF0b3I6OlBsdXMpIHN0ZDo6Y291dCA8PCAnKyc7CgkJCQlpZiAoTS5zZWNvbmRbby5EaXJbTGVmdF1dLk9wID09IE9wZXJhdG9yOjpNaW51cykgc3RkOjpjb3V0IDw8ICctJzsKCQkJCWlmIChNLnNlY29uZFtvLkRpcltMZWZ0XV0uT3AgPT0gT3BlcmF0b3I6Ok11bHRpKSBzdGQ6OmNvdXQgPDwgJyonOwoJCQkJaWYgKE0uc2Vjb25kW28uRGlyW0xlZnRdXS5PcCA9PSBPcGVyYXRvcjo6RGl2KSBzdGQ6OmNvdXQgPDwgJy8nOwoJCQkJc3RkOjpjb3V0IDw8IE0uc2Vjb25kW28uRGlyW0xlZnRdXS5WYWx1ZTsKCQkJfQoJCQlzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoKCgkJfQoJfQoKCXJldHVybiAwOwp9Cgpib29sIEZpbmQoU3RhY2smIFNULFBvaW50IFAsaW50IEQpewoKCWZvciAoYXV0byYgbyA6IFNUKXsKCQlpZiAoKG8uUG9zLlggPT0gUC5YKSAmJiAoby5Qb3MuWSA9PSBQLlkpICYmICgoby5Gcm9tID09IEQpIHx8IChvLlRvID09IEQpKSkgcmV0dXJuIHRydWU7Cgl9CgoJcmV0dXJuIGZhbHNlOwp9CgppbnQgQ2FsY1Njb3JlKE9wZXJhdG9yIE9wLCBpbnQgU0EsIGludCBTQil7Cglzd2l0Y2ggKE9wKQoJewoJCWNhc2UgT3BlcmF0b3I6OlBsdXM6CgkJCXJldHVybiBTQSArIFNCOwoJCWNhc2UgT3BlcmF0b3I6Ok1pbnVzOgoJCQlyZXR1cm4gU0EgLSBTQjsKCQljYXNlIE9wZXJhdG9yOjpNdWx0aToKCQkJcmV0dXJuIFNBKlNCOwoJCWNhc2UgT3BlcmF0b3I6OkRpdjoKCQkJcmV0dXJuIFNBIC8gU0I7CgkJY2FzZSBPcGVyYXRvcjo6TW9kOgoJCQlyZXR1cm4gU0ElU0I7CgkJZGVmYXVsdDoKCQkJYnJlYWs7Cgl9CglyZXR1cm4gc3RkOjpudW1lcmljX2xpbWl0czxpbnQ+OjptaW4oKSAvIDE2Owp9CgppbnQgRnJvbShQb2ludCBBLCBQb2ludCBCKXsKCglQb2ludCBUb3sgQS5YIC0gQi5YLCBBLlkgLSBCLlkgfTsKCgoJZm9yIChpbnQgaSA9IDA7IGkgPCA0OyBpKyspewoJCWlmIChEaXJlY3Rpb25baV0uWCA9PSBUby5YICYmIERpcmVjdGlvbltpXS5ZID09IFRvLlkpIHJldHVybiAoaSArIDIpICUgNDsKCX0KCglyZXR1cm4gLTE7Cgp9CgoKYm9vbCBJc01vdmUoUG9pbnQgUCwgUG9pbnQgTCl7CglpZiAoUC5YIDwgMCkgcmV0dXJuIGZhbHNlOwoJaWYgKFAuWSA8IDApIHJldHVybiBmYWxzZTsKCWlmIChQLlggPCBMLlgpIHJldHVybiBmYWxzZTsKCWlmIChQLlkgPCBMLlkpIHJldHVybiBmYWxzZTsKCglyZXR1cm4gdHJ1ZTsKfQoKYm9vbCBTZWFyY2goTWFwJiBNLFN0YWNrJiBTLGludCYgU2NvcmUsY29uc3QgUG9pbnQmIFN0YXJ0LGNvbnN0IFBvaW50JiBFbmQpewoJUG9pbnQgTm93ID0gU3RhcnQ7CglTdGFjayBTVDsKCVN0YWNrIE1TVDsKCWludCBNYXhTY29yZSA9IDA7CglpbnQgU2NvcmVUID0gU2NvcmU7CglpbnQgRGlyID0gMDsKCUZvb3RQcmludCBGUHsgTm93LCAtMSwgRGlyLCBTY29yZSB9OwoKCgl3aGlsZSAoISgoTm93LlggPT0gRW5kLlgpICYmIChOb3cuWSA9PSBFbmQuWSkpKXsKCS8vd2hpbGUgKHRydWUpewoJCQoJCWlmIChTVC5zaXplKCkgPj0gMSl7CgkJCUZQLkZyb20gPSBGcm9tKE5vdywgU1RbU1Quc2l6ZSgpIC0gMV0uUG9zKTsKCQl9CgkJU1QucHVzaF9iYWNrKEZQKTsKCgkJaWYgKElzTW92ZSh7IE5vdy5YICsgRGlyZWN0aW9uW0Rpcl0uWCwgTm93LlkgKyBEaXJlY3Rpb25bRGlyXS5ZIH0sIHsgV2lkdGgsIEhlaWdodCB9KSl7CgkJCURpcisrOwoJCQlMMToKCQkJaWYgKERpciA9PSA0KXsKCQkJCVNULnBvcF9iYWNrKCk7CgkJCQlEaXIgPSBTVC5iYWNrKCkuVG8rMTsKCQkJfQoJCQlpZiAoRGlyID09IDQpIGdvdG8gTDE7CgkJCWlmIChTVC5zaXplKCkgPT0gMCl7CgkJCQlTID0gTVNUOwoJCQkJU2NvcmUgPSBNYXhTY29yZTsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJCURpciAlPSA0OwoJCQljb250aW51ZTsKCQl9CgkJaWYgKEZpbmQoU1QsIHsgTm93LlggKyBEaXJlY3Rpb25bRGlyXS5YLCBOb3cuWSArIERpcmVjdGlvbltEaXJdLlkgfSwgRGlyKSA9PSB0cnVlKXsKCQkJRGlyKys7CgkJCUwyOgoJCQlpZiAoRGlyID09IDQpewoJCQkJU1QucG9wX2JhY2soKTsKCQkJCURpciA9IFNULmJhY2soKS5UbysxOwoJCQl9CgkJCWlmIChEaXIgPT0gNCkgZ290byBMMjsKCQkJaWYgKFNULnNpemUoKSA9PSAwKXsKCQkJCVMgPSBNU1Q7CgkJCQlTY29yZSA9IE1heFNjb3JlOwoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQkJRGlyICU9IDQ7CgkJCWNvbnRpbnVlOwoJCX0KCQlQb2ludCBQVHsgTm93LlggKyBEaXJlY3Rpb25bRGlyXS5YLCBOb3cuWSArIERpcmVjdGlvbltEaXJdLlkgfTsKCQlPcGVyYXRvciBPcCA9IE0uc2Vjb25kW00uZmlyc3RbUFQuWV1bUFQuWF0uRGlyW0Rpcl1dLk9wOwoJCWludCBWID0gTS5zZWNvbmRbTS5maXJzdFtQVC5ZXVtQVC5YXS5EaXJbRGlyXV0uVmFsdWU7CgkJU2NvcmVUID0gQ2FsY1Njb3JlKE9wLCBWLCBTY29yZVQpOwoKCQlGUC5Qb3MgPSBQVDsKCQlGUC5TY29yZSA9IFNjb3JlVDsKCQlGUC5Ubz1EaXIKCgl9CgoKfQoKCmludCBtYWluKCl7CgoJYXV0byBNID0gTWFrZURhdGEoKTsKCVNob3dNYXAoTSk7CglzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoJU2hvd01hcChNLCBmYWxzZSk7CglyZXR1cm4gMDsKCn0KCg==