#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4")
#define _CRT_SECURE_NO_WARNINGS
# include <iostream>
# include <cmath>
# include <algorithm>
# include <stdio.h>
# include <cstdint>
# include <cstring>
# include <string>
# include <cstdlib>
# include <vector>
# include <bitset>
# include <map>
# include <queue>
# include <ctime>
# include <stack>
# include <set>
# include <list>
# include <random>
# include <deque>
# include <functional>
# include <iomanip>
# include <sstream>
# include <fstream>
# include <complex>
# include <numeric>
# include <immintrin.h>
# include <cassert>
# include <array>
# include <tuple>
# include <unordered_map>
# include <unordered_set>
#ifdef LOCAL0000
# include <opencv2/core/core.hpp>
# include <opencv2/highgui/highgui.hpp>
# include <opencv2/imgproc/imgproc.hpp>
#endif
using namespace std;
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL_((0,__VA_ARGS__, 6,5,4,3,2,1))
#define VA_NUM_ARGS_IMPL_(tuple) VA_NUM_ARGS_IMPL tuple
#define VA_NUM_ARGS_IMPL(_0,_1,_2,_3,_4,_5,_6,N,...) N
#define macro_dispatcher(macro, ...) macro_dispatcher_(macro, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(macro, nargs) macro_dispatcher__(macro, nargs)
#define macro_dispatcher__(macro, nargs) macro_dispatcher___(macro, nargs)
#define macro_dispatcher___(macro, nargs) macro ## nargs
#define DBN1(a) cerr<<#a<<"="<<(a)<<"\n"
#define DBN2(a,b) cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<"\n"
#define DBN3(a,b,c) cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<"\n"
#define DBN4(a,b,c,d) cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<"\n"
#define DBN5(a,b,c,d,e) cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<"\n"
#define DBN6(a,b,c,d,e,f) cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<", "<<#f<<"="<<(f)<<"\n"
#define DBN(...) macro_dispatcher(DBN, __VA_ARGS__)(__VA_ARGS__)
#define DA(a,n) cerr<<#a<<"=["; printarray(a,n); cerr<<"]\n"
#define DAR(a,n,s) cerr<<#a<<"["<<s<<"-"<<n-1<<"]=["; printarray(a,n,s); cerr<<"]\n"
#ifdef _MSC_VER
#define PREFETCH(ptr, rw, level) ((void)0)
#else
#define PREFETCH(ptr, rw, level) __builtin_prefetch(ptr, rw, level)
#endif
#if defined _MSC_VER
#define ASSUME(condition) ((void)0)
#define __restrict
#elif defined __clang__
#define ASSUME(condition) __builtin_assume(condition)
#elif defined __GNUC__
[ [ noreturn] ] __attribute__( ( always_inline) ) inline void undefinedBehaviour( ) { }
#define ASSUME(condition) ((condition) ? true : (undefinedBehaviour(), false))
#endif
#ifdef LOCAL
#define CURTIME() cerr << clock() * 1.0 / CLOCKS_PER_SEC << endl
#else
#define CURTIME()
#endif
typedef long long ll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair< int , int > pii;
typedef pair< long long , long long > pll;
typedef vector< int > vi;
typedef vector< long long > vll;
typedef int itn;
template < class T1, class T2, class T3>
struct triple{ T1 a; T2 b; T3 c; triple( ) : a( T1( ) ) , b( T2( ) ) , c( T3( ) ) { } ; triple( T1 _a, T2 _b, T3 _c) : a( _a) , b( _b) , c( _c) { } } ;
template < class T1, class T2, class T3>
bool operator< ( const triple< T1,T2,T3> & t1,const triple< T1,T2,T3> & t2) { if ( t1.a ! = t2.a ) return t1.a < t2.a ; else if ( t1.b ! = t2.b ) return t1.b < t2.b ; else return t1.c < t2.c ; }
template < class T1, class T2, class T3>
bool operator> ( const triple< T1,T2,T3> & t1,const triple< T1,T2,T3> & t2) { if ( t1.a ! = t2.a ) return t1.a > t2.a ; else if ( t1.b ! = t2.b ) return t1.b > t2.b ; else return t1.c > t2.c ; }
#define tri triple<int,int,int>
#define trll triple<ll,ll,ll>
#define FI(n) for(int i=0;i<(n);++i)
#define FJ(n) for(int j=0;j<(n);++j)
#define FK(n) for(int k=0;k<(n);++k)
#define FL(n) for(int l=0;l<(n);++l)
#define FQ(n) for(int q=0;q<(n);++q)
#define FOR(i,a,b) for(int i = (a), __e = (int) (b); i < __e; ++i)
#define all(a) std::begin(a), std::end(a)
#define reunique(v) v.resize(std::unique(v.begin(), v.end()) - v.begin())
#define sqr(x) ((x) * (x))
#define sqrt(x) sqrt(1.0 * (x))
#define pow(x, n) pow(1.0 * (x), n)
#define COMPARE(obj) [&](const std::decay_t<decltype(obj)>& a, const std::decay_t<decltype(obj)>& b)
#define COMPARE_BY(obj, field) [&](const std::decay_t<decltype(obj)>& a, const std::decay_t<decltype(obj)>& b) { return a.field < b.field; }
#define checkbit(n, b) (((n) >> (b)) & 1)
#define setbit(n, b) ((n) | (static_cast<std::decay<decltype(n)>::type>(1) << (b)))
#define removebit(n, b) ((n) & ~(static_cast<std::decay<decltype(n)>::type>(1) << (b)))
#define flipbit(n, b) ((n) ^ (static_cast<std::decay<decltype(n)>::type>(1) << (b)))
inline int countBits( uint v) { v= v- ( ( v>> 1 ) & 0x55555555 ) ; v= ( v& 0x33333333 ) + ( ( v>> 2 ) & 0x33333333 ) ; return ( ( v+ ( v>> 4 ) & 0xF0F0F0F ) * 0x1010101 ) >> 24 ; }
inline int countBits( ull v) { uint t= v>> 32 ; uint p= ( v & ( ( 1ULL << 32 ) - 1 ) ) ; return countBits( t) + countBits( p) ; }
inline int countBits( ll v) { return countBits( ( ull) v) ; }
inline int countBits( int v) { return countBits( ( uint) v) ; }
unsigned int reverseBits( uint x) { x = ( ( ( x & 0xaaaaaaaa ) >> 1 ) | ( ( x & 0x55555555 ) << 1 ) ) ; x = ( ( ( x & 0xcccccccc ) >> 2 ) | ( ( x & 0x33333333 ) << 2 ) ) ; x = ( ( ( x & 0xf0f0f0f0 ) >> 4 ) | ( ( x & 0x0f0f0f0f ) << 4 ) ) ; x = ( ( ( x & 0xff00ff00 ) >> 8 ) | ( ( x & 0x00ff00ff ) << 8 ) ) ; return ( ( x >> 16 ) | ( x << 16 ) ) ; }
template < class T> inline int sign( T x) { return x > 0 ? 1 : x < 0 ? - 1 : 0 ; }
inline bool isPowerOfTwo( int x) { return ( x ! = 0 && ( x& ( x - 1 ) ) == 0 ) ; }
constexpr ll power( ll x, int p) { return p == 0 ? 1 : ( x * power( x, p - 1 ) ) ; }
template < class T>
inline bool inRange( const T& val, const T& min, const T& max) { return min <= val && val <= max; }
//template<class T1, class T2, class T3> T1 inline clamp(T1 x, const T2& a, const T3& b) { if (x < a) return a; else if (x > b) return b; else return x; }
unsigned long long rdtsc( ) { unsigned long long ret = 0 ;
#ifdef __clang__
return __builtin_readcyclecounter( ) ;
#endif
#ifndef _MSC_VER
asm volatile ( "rdtsc" : "=A" ( ret) : : ) ;
#endif
return ret; }
// Fast IO ********************************************************************************************************
const int __BS = 4096 ;
static char __bur[ __BS + 16 ] , * __er = __bur + __BS, * __ir = __er;
template < class T = int > T readInt( ) {
auto c = [ & ] ( ) { if ( __ir == __er) std:: fill ( __bur, __bur + __BS, 0 ) , cin .read ( __bur, __BS) , __ir = __bur; } ;
c( ) ; while ( * __ir && ( * __ir < '0' || * __ir > '9' ) && * __ir ! = '-' ) ++ __ir; c( ) ;
bool m = false ; if ( * __ir == '-' ) ++ __ir, c( ) , m = true ;
T r = 0 ; while ( * __ir >= '0' && * __ir <= '9' ) r = r * 10 + * __ir - '0' , ++ __ir, c( ) ;
++ __ir; return m ? - r : r;
}
string readString( ) {
auto c = [ & ] ( ) { if ( __ir == __er) std:: fill ( __bur, __bur + __BS, 0 ) , cin .read ( __bur, __BS) , __ir = __bur; } ;
string r; c( ) ; while ( * __ir && isspace ( * __ir) ) ++ __ir, c( ) ;
while ( ! isspace ( * __ir) ) r.push_back ( * __ir) , ++ __ir, c( ) ;
++ __ir; return r;
}
char readChar( ) {
auto c = [ & ] ( ) { if ( __ir == __er) std:: fill ( __bur, __bur + __BS, 0 ) , cin .read ( __bur, __BS) , __ir = __bur; } ;
c( ) ; while ( * __ir && isspace ( * __ir) ) ++ __ir, c( ) ; return * __ir++ ;
}
static char __buw[ __BS + 20 ] , * __iw = __buw, * __ew = __buw + __BS;
template < class T>
void writeInt( T x, char endc = '\n ' ) {
if ( x < 0 ) * __iw++ = '-' , x = - x; if ( x == 0 ) * __iw++ = '0' ;
char * s = __iw;
while ( x) { T t = x / 10 ; char c = x - 10 * t + '0' ; * __iw++ = c; x = t; }
char * f = __iw - 1 ; while ( s < f) swap( * s, * f) , ++ s, -- f;
if ( __iw > __ew) cout .write ( __buw, __iw - __buw) , __iw = __buw;
if ( endc) { * __iw++ = endc; }
}
template < class T>
void writeStr( const T& str) {
int i = 0 ; while ( str[ i] ) { * __iw++ = str[ i++ ] ; if ( __iw > __ew) cout .write ( __buw, __iw - __buw) , __iw = __buw; }
}
struct __FL__ { ~__FL__( ) { if ( __iw ! = __buw) cout .write ( __buw, __iw - __buw) ; } } ;
static __FL__ __flushVar__;
//STL output *****************************************************************************************************
#define TT1 template<class T>
#define TT1T2 template<class T1, class T2>
#define TT1T2T3 template<class T1, class T2, class T3>
TT1T2 ostream& operator << ( ostream& os, const pair< T1, T2> & p) ;
TT1 ostream& operator << ( ostream& os, const vector< T> & v) ;
TT1T2 ostream& operator << ( ostream& os, const set< T1, T2> & v) ;
TT1T2 ostream& operator << ( ostream& os, const multiset< T1, T2> & v) ;
TT1T2 ostream& operator << ( ostream& os, priority_queue< T1, T2> v) ;
TT1T2T3 ostream& operator << ( ostream& os, const map< T1, T2, T3> & v) ;
TT1T2T3 ostream& operator << ( ostream& os, const multimap< T1, T2, T3> & v) ;
TT1T2T3 ostream& operator << ( ostream& os, const triple< T1, T2, T3> & t) ;
template < class T, size_t N> ostream& operator << ( ostream& os, const array< T, N> & v) ;
TT1T2 ostream& operator << ( ostream& os, const pair< T1, T2> & p) { return os << "(" << p.first << ", " << p.second << ")" ; }
TT1 ostream& operator << ( ostream& os, const vector< T> & v) { bool f= 1 ; os<< "[" ; for ( auto & i : v) { if ( ! f) os << ", " ; os<< i; f= 0 ; } return os << "]" ; }
template < class T, size_t N> ostream& operator << ( ostream& os, const array< T, N> & v) { bool f= 1 ; os<< "[" ; for ( auto & i : v) { if ( ! f) os << ", " ; os<< i; f= 0 ; } return os << "]" ; }
TT1T2 ostream& operator << ( ostream& os, const set< T1, T2> & v) { bool f= 1 ; os<< "[" ; for ( auto & i : v) { if ( ! f) os << ", " ; os<< i; f= 0 ; } return os << "]" ; }
TT1T2 ostream& operator << ( ostream& os, const multiset< T1,T2> & v) { bool f= 1 ; os<< "[" ; for ( auto & i : v) { if ( ! f) os << ", " ; os<< i; f= 0 ; } return os << "]" ; }
TT1T2T3 ostream& operator << ( ostream& os, const map< T1,T2,T3> & v) { bool f = 1 ; os << "[" ; for ( auto & ii : v) { if ( ! f) os << ", " ; os << "(" << ii.first << " -> " << ii.second << ") " ; f = 0 ; } return os << "]" ; }
TT1T2 ostream& operator << ( ostream& os, const multimap< T1, T2> & v) { bool f = 1 ; os << "[" ; for ( auto & ii : v) { if ( ! f) os << ", " ; os << "(" << ii.first << " -> " << ii.second << ") " ; f = 0 ; } return os << "]" ; }
TT1T2 ostream& operator << ( ostream& os, priority_queue< T1, T2> v) { bool f = 1 ; os << "[" ; while ( ! v.empty ( ) ) { auto x = v.top ( ) ; v.pop ( ) ; if ( ! f) os << ", " ; f = 0 ; os << x; } return os << "]" ; }
TT1T2T3 ostream& operator << ( ostream& os, const triple< T1, T2, T3> & t) { return os << "(" << t.a << ", " << t.b << ", " << t.c << ")" ; }
TT1T2 void printarray( const T1& a, T2 sz, T2 beg = 0 ) { for ( T2 i = beg; i< sz; i++ ) cout << a[ i] << " " ; cout << endl; }
//STL input *****************************************************************************************************
TT1T2T3 inline istream& operator >> ( istream& os, triple< T1, T2, T3> & t) ;
TT1T2 inline istream& operator >> ( istream& os, pair< T1, T2> & p) { return os >> p.first >> p.second ; }
TT1 inline istream& operator >> ( istream& os, vector< T> & v) {
if ( v.size ( ) ) for ( T& t : v) os >> t; else {
string s; T obj; while ( s.empty ( ) ) { getline( os, s) ; if ( ! os) return os; }
stringstream ss( s) ; while ( ss >> obj) v.push_back ( obj) ;
}
return os;
}
TT1T2T3 inline istream& operator >> ( istream& os, triple< T1, T2, T3> & t) { return os >> t.a >> t.b >> t.c ; }
//Pair magic *****************************************************************************************************
#define PT1T2 pair<T1, T2>
TT1T2 inline PT1T2 operator+ ( const PT1T2 & p1 , const PT1T2 & p2) { return PT1T2( p1.first + p2.first , p1.second + p2.second ) ; }
TT1T2 inline PT1T2& operator+ = ( PT1T2 & p1 , const PT1T2 & p2) { p1.first + = p2.first , p1.second + = p2.second ; return p1; }
TT1T2 inline PT1T2 operator- ( const PT1T2 & p1 , const PT1T2 & p2) { return PT1T2( p1.first - p2.first , p1.second - p2.second ) ; }
TT1T2 inline PT1T2& operator- = ( PT1T2 & p1 , const PT1T2 & p2) { p1.first - = p2.first , p1.second - = p2.second ; return p1; }
#undef TT1
#undef TT1T2
#undef TT1T2T3
#define FREIN(FILE) freopen(FILE, "rt", stdin)
#define FREOUT(FILE) freopen(FILE, "wt", stdout)
#ifdef LOCAL
#define BEGIN_PROFILE(idx, name) int profileIdx = idx; profileName[profileIdx] = name; totalTime[profileIdx] -= rdtsc() / 1e3;
#define END_PROFILE totalTime[profileIdx] += rdtsc() / 1e3; totalCount[profileIdx]++;
#else
#define BEGIN_PROFILE(idx, name)
#define END_PROFILE
#endif
const int USUAL_MOD = 1000000007 ;
template < class T> inline void normmod( T & x, T m = USUAL_MOD) { x % = m; if ( x < 0 ) x + = m; }
template < class T1, class T2> inline T2 summodfast( T1 x, T1 y, T2 m = USUAL_MOD) { T2 res = x + y; if ( res >= m) res - = m; return res; }
template < class T1, class T2, class T3 = int > inline void addmodfast( T1 & x, T2 y, T3 m = USUAL_MOD) { x + = y; if ( x >= m) x - = m; }
template < class T1, class T2, class T3 = int > inline void submodfast( T1 & x, T2 y, T3 m = USUAL_MOD) { x - = y; if ( x < 0 ) x + = m; }
inline ll mulmod( ll x, ll n, ll m) { x % = m; n % = m; ll r = x * n - ll( ld( x) * ld( n) / ld( m) ) * m; while ( r < 0 ) r + = m; while ( r >= m) r - = m; return r; }
inline ll powmod( ll x, ll n, ll m) { ll r = 1 ; normmod( x, m) ; while ( n) { if ( n & 1 ) r * = x; x * = x; r % = m; x % = m; n / = 2 ; } return r; }
inline ll powmulmod( ll x, ll n, ll m) { ll res = 1 ; normmod( x, m) ; while ( n) { if ( n & 1 ) res = mulmod( res, x, m) ; x = mulmod( x, x, m) ; n / = 2 ; } return res; }
template < class T> inline T gcd( T a, T b) { while ( b) { T t = a % b; a = b; b = t; } return a; }
template < class T>
T fast_gcd( T u, T v) {
int shl = 0 ; while ( u && v && u ! = v) { T eu = u & 1 ; u >>= eu ^ 1 ; T ev = v & 1 ; v >>= ev ^ 1 ;
shl + = ( ~( eu | ev) & 1 ) ; T d = u & v & 1 ? ( u + v) >> 1 : 0 ; T dif = ( u - v) >> ( sizeof ( T) * 8 - 1 ) ; u - = d & ~dif; v - = d & dif;
} return std:: max ( u, v) << shl;
}
inline ll lcm( ll a, ll b) { return a / gcd( a, b) * b; }
template < class T> inline T gcd( T a, T b, T c) { return gcd( gcd( a, b) , c) ; }
ll gcdex( ll a, ll b, ll& x, ll& y) {
if ( ! a) { x = 0 ; y = 1 ; return b; }
ll y1; ll d = gcdex( b % a, a, y, y1) ; x = y1 - ( b / a) * y;
return d;
}
template < class T> bool isPrime( T x) { if ( x <= 4 || x % 2 == 0 || x % 3 == 0 ) return x == 2 || x == 3 ;
for ( T i = 5 ; i * i <= x; i + = 6 ) if ( x % i == 0 || x % ( i + 2 ) == 0 ) return 0 ; return 1 ; }
bool millerRabin( long long n) {
if ( n <= 1000 ) return isPrime( n) ;
long long s = n - 1 ; int t = 0 ; while ( s % 2 == 0 ) s / = 2 , ++ t;
for ( int a : { 2 , 325 , 9375 , 28178 , 450775 , 9780504 , 1795265022 } ) { if ( ! ( a % = n) ) return true ;
long long f = powmulmod( a, s, n) ; if ( f == 1 || f == n - 1 ) continue ;
for ( int i = 1 ; i < t; ++ i) if ( ( f = mulmod( f, f, n) ) == n - 1 ) goto nextp;
return false ; nextp:;
} return true ;
}
// Useful constants
//int some_primes[7] = {24443, 100271, 1000003, 1000333, 5000321, 98765431,
#define T9 1000000000
#define T18 1000000000000000000LL
#define INF 1011111111
#define LLINF 1000111000111000111LL
#define mod 1000000007
#define fftmod 998244353
#define EPS (double)1e-10
#define PI 3.14159265358979323846264
#define link asaxlajrewqwe
#define rank wahayawehasdakw
//*************************************************************************************
int32_t solve( ) ;
int32_t main( int argc, char ** argv) {
ios_base:: sync_with_stdio ( 0 ) ; cin .tie ( 0 ) ;
#ifdef LOCAL
if ( argc == 1 || argv[ 1 ] == string( "test" ) ) {
FREIN( "examples/001" ) ;
} else {
FREIN( argv[ 1 ] ) ;
}
FREOUT( "out.txt" ) ;
#endif
return solve( ) ;
}
string world;
string q;
constexpr int MAXQ = 10010 ;
constexpr int TEN = 10 ;
template < typename T, size_t N> struct alignas( 16 ) aligned_array : public std:: array < T, N> { } ;
using ArrTen = array< int , TEN> ;
void updString( string& s) { for ( char & c : s) c - = 'A' ; }
mt19937_64 gen;
int rnd( int n) {
return uniform_int_distribution<> ( 0 , n - 1 ) ( gen) ;
}
ArrTen nex[ 50001 ] ;
struct Hist {
Hist * parent;
pii move;
} ;
Hist allHist[ 1 << 21 ] ;
Hist * lastHist = allHist;
vector< Hist* > histPool;
Hist * getNewHist( ) {
if ( histPool.empty ( ) ) {
return lastHist++ ;
} else {
auto res = histPool.back ( ) ;
histPool.pop_back ( ) ;
return res;
}
}
/***** PARAMS *****/
int NOT_LAST_BONUS = 8 ;
constexpr int MAX_STATES_CNT = 60 ;
constexpr int DEPTH1_TRIES = 6 ;
constexpr int DEPTH0_TRIES = 2 ;
constexpr int GREEDY_STEPS = 24 ;
/***** PARAMS *****/
bool used[ 50000 ] ;
struct State {
ArrTen whereIsUnit = { } ;
ArrTen colorsInPocket = { } ;
int score = 0 ;
Hist* hist = nullptr;
int calcScore( ) {
int score = 0 ;
auto tmp = whereIsUnit;
sort( tmp.begin ( ) , tmp.end ( ) , std:: greater < int > ( ) ) ;
for ( int i = 0 ; i < TEN; ++ i) {
score + = ( i + 4 ) * tmp[ i] ;
}
score + = tmp[ TEN - 1 ] * 8 ;
return score;
}
inline bool anyoneAtPos( int pos) const {
for ( int x : whereIsUnit) {
if ( x == pos) return true ;
}
return false ;
}
int getLastUnit( ) const {
return int ( min_element( all( whereIsUnit) ) - begin( whereIsUnit) ) ;
}
int getNextSameColor_Used( int pos, int color) const {
do {
pos = nex[ pos] [ color] ;
} while ( used[ pos] ) ;
return pos;
}
int getNextSameColor( int pos, int color) const {
do {
pos = nex[ pos] [ color] ;
} while ( anyoneAtPos( pos) ) ;
return pos;
}
inline void addColor( int color) {
colorsInPocket[ color] ++ ;
}
inline void delColor( int color) {
colorsInPocket[ color] -- ;
}
void makeTheMove( int idx, int color) {
whereIsUnit[ idx] = getNextSameColor( whereIsUnit[ idx] , color) ;
delColor( color) ;
}
void makeTheMove( int idx, int color, int pos) {
whereIsUnit[ idx] = pos;
delColor( color) ;
}
void mutateGreedy( int cur, int stepsCnt) {
for ( int x : whereIsUnit) {
used[ x] = true ;
}
while ( stepsCnt-- > 0 && cur < MAXQ) {
addColor( q[ cur++ ] ) ;
int idx = getLastUnit( ) ;
int pos = whereIsUnit[ idx] ;
used[ pos] = false ;
int maxNextPos = - 1 ;
int what = - 1 ;
for ( int i = 0 ; i < TEN; ++ i) {
if ( ! colorsInPocket[ i] ) continue ;
int nextPos = getNextSameColor_Used( pos, i) ;
if ( nextPos > maxNextPos) {
maxNextPos = nextPos;
what = i;
}
}
used[ maxNextPos] = true ;
makeTheMove( idx, what, maxNextPos) ;
}
for ( int x : whereIsUnit) {
used[ x] = false ;
}
}
template < int depth>
int generateNewStates( int maxCnt, State* res, int cur) {
addColor( q[ cur] ) ;
tri whoWhatAndWhere[ depth == 0 ? 10 : 100 ] ;
int sz = 0 ;
int idx = getLastUnit( ) ;
for ( int who = ( depth ? 0 : idx) ; who < ( depth ? TEN : idx + 1 ) ; ++ who) {
for ( int what = 0 ; what < TEN; ++ what) {
if ( ! colorsInPocket[ what] ) continue ;
int where = getNextSameColor( whereIsUnit[ who] , what) - whereIsUnit[ who] ;
if ( idx ! = who) {
where - = NOT_LAST_BONUS;
}
whoWhatAndWhere[ sz++ ] = { who, what, where} ;
}
}
sort( whoWhatAndWhere, whoWhatAndWhere + sz , [ ] ( tri a, tri b) {
return a.c > b.c ;
} ) ;
int resultMoves = 0 ;
maxCnt = min( maxCnt, sz) ;
for ( auto [ who, what, _] : whoWhatAndWhere) {
if ( maxCnt-- == 0 ) break ;
int oldPos = whereIsUnit[ who] ;
int where = getNextSameColor( oldPos, what) ;
makeTheMove( who, what, where) ;
if ( depth == 0 || cur + 1 == MAXQ) {
auto greedy = * this ;
greedy.mutateGreedy ( cur + 1 , GREEDY_STEPS) ;
score = max( score, greedy.calcScore ( ) ) ;
} else {
score = 0 ;
generateNewStates< 0 > ( DEPTH0_TRIES, nullptr, cur + 1 ) ;
}
if ( res ! = nullptr) {
auto prevHist = hist;
hist = getNewHist( ) ;
hist- > move = { who, what} ;
hist- > parent = prevHist;
* res++ = * this ;
hist = prevHist;
}
whereIsUnit[ who] = oldPos;
colorsInPocket[ what] ++ ;
++ resultMoves;
}
delColor( q[ cur] ) ;
return resultMoves;
}
} ;
std:: ostream & operator<< ( std:: ostream & os, const State& s) {
return os << s.colorsInPocket << ' ' << s.whereIsUnit ;
}
bool operator < ( const State& a, const State& b) {
return ( a.score > b.score ) || ( a.score == b.score && a.colorsInPocket < b.colorsInPocket ) ;
}
bool operator == ( const State& a, const State& b) {
return a.score == b.score && a.colorsInPocket == b.colorsInPocket ;
}
int solve( ) {
// ifstream fin("examples/001");
int n, s, c, h, U;
cin >> n >> s >> c >> h >> U;
cin >> world;
cin >> q;
updString( world) ;
updString( q) ;
const int MAXPOS = 50000 ;
for ( int i = 0 ; i < TEN; ++ i) nex[ MAXPOS] [ i] = MAXPOS;
for ( int i = MAXPOS - 1 ; i >= 0 ; -- i) {
for ( int j = 0 ; j < TEN; ++ j) {
nex[ i] [ j] = nex[ i + 1 ] [ j] ;
}
nex[ i] [ world[ i + 1 ] ] = i + 1 ;
}
static int indices[ MAX_STATES_CNT * TEN] ;
static State __states[ 2 ] [ MAX_STATES_CNT * TEN] ;
auto states = __states[ 0 ] ;
auto newStates = __states[ 1 ] ;
int statesCnt = 1 ;
for ( int i = 0 ; i < TEN - 1 ; ++ i) {
states[ 0 ] .addColor ( q[ i] ) ;
}
for ( int i = 0 ; i < TEN; ++ i) {
states[ 0 ] .whereIsUnit [ i] = i;
}
for ( int i = TEN - 1 ; i + 1 < ( int ) q.size ( ) ; ++ i) {
if ( i == 9000 ) NOT_LAST_BONUS = 24 ;
if ( i == 9500 ) NOT_LAST_BONUS = 64 ;
if ( i == 9900 ) NOT_LAST_BONUS = 256 ;
for ( int i = 0 ; i < statesCnt; ++ i) {
indices[ i] = i;
}
auto cmp = [ & ] ( int x, int y) { return states[ x] < states[ y] ; } ;
shuffle( indices, indices + statesCnt, gen) ;
sort( indices, indices + statesCnt, cmp) ;
int oldStatesCnt = statesCnt;
statesCnt = 1 ;
for ( int j = 1 ; j < oldStatesCnt; ++ j) {
int x = indices[ j] ;
int y = indices[ statesCnt - 1 ] ;
if ( statesCnt == MAX_STATES_CNT || states[ x] == states[ y] ) {
histPool.push_back ( states[ x] .hist ) ;
} else {
indices[ statesCnt++ ] = x;
}
}
int newStatesCnt = 0 ;
for ( int j = 0 ; j < statesCnt; ++ j) {
auto & state = states[ indices[ j] ] ;
state.score = 0 ;
newStatesCnt + = state.generateNewStates < 1 > ( DEPTH1_TRIES, newStates + newStatesCnt, i) ;
}
statesCnt = newStatesCnt;
swap( states, newStates) ;
}
sort( states, states + statesCnt) ;
auto bestScore = states[ 0 ] .whereIsUnit [ states[ 0 ] .getLastUnit ( ) ] ;
vector< pii> ans;
auto hist = states[ 0 ] .hist ;
while ( hist ! = nullptr) {
ans.push_back ( hist- > move) ;
hist = hist- > parent;
}
reverse( all( ans) ) ;
for ( auto p : ans) {
cout << p.first << ' ' << char ( p.second + 'A' ) << endl;
}
DBN( bestScore) ;
CURTIME( ) ;
FREOUT( "score.txt" ) ;
cout << bestScore << endl;
// DBN(bestScore);
return 0 ;
}
I3ByYWdtYSBjb21tZW50KGxpbmtlciwgIi9zdGFjazoyMDAwMDAwMDAiKQovLyNwcmFnbWEgR0NDIG9wdGltaXplKCJPZmFzdCIpCi8vI3ByYWdtYSBHQ0MgdGFyZ2V0KCJzc2Usc3NlMixzc2UzLHNzc2UzLHNzZTQiKQoKI2RlZmluZSBfQ1JUX1NFQ1VSRV9OT19XQVJOSU5HUwojIGluY2x1ZGUgPGlvc3RyZWFtPgojIGluY2x1ZGUgPGNtYXRoPgojIGluY2x1ZGUgPGFsZ29yaXRobT4KIyBpbmNsdWRlIDxzdGRpby5oPgojIGluY2x1ZGUgPGNzdGRpbnQ+CiMgaW5jbHVkZSA8Y3N0cmluZz4KIyBpbmNsdWRlIDxzdHJpbmc+CiMgaW5jbHVkZSA8Y3N0ZGxpYj4KIyBpbmNsdWRlIDx2ZWN0b3I+CiMgaW5jbHVkZSA8Yml0c2V0PgojIGluY2x1ZGUgPG1hcD4KIyBpbmNsdWRlIDxxdWV1ZT4KIyBpbmNsdWRlIDxjdGltZT4KIyBpbmNsdWRlIDxzdGFjaz4KIyBpbmNsdWRlIDxzZXQ+CiMgaW5jbHVkZSA8bGlzdD4KIyBpbmNsdWRlIDxyYW5kb20+CiMgaW5jbHVkZSA8ZGVxdWU+CiMgaW5jbHVkZSA8ZnVuY3Rpb25hbD4KIyBpbmNsdWRlIDxpb21hbmlwPgojIGluY2x1ZGUgPHNzdHJlYW0+CiMgaW5jbHVkZSA8ZnN0cmVhbT4KIyBpbmNsdWRlIDxjb21wbGV4PgojIGluY2x1ZGUgPG51bWVyaWM+CiMgaW5jbHVkZSA8aW1taW50cmluLmg+CiMgaW5jbHVkZSA8Y2Fzc2VydD4KIyBpbmNsdWRlIDxhcnJheT4KIyBpbmNsdWRlIDx0dXBsZT4KIyBpbmNsdWRlIDx1bm9yZGVyZWRfbWFwPgojIGluY2x1ZGUgPHVub3JkZXJlZF9zZXQ+CgojaWZkZWYgTE9DQUwwMDAwCiMgaW5jbHVkZSA8b3BlbmN2Mi9jb3JlL2NvcmUuaHBwPgojIGluY2x1ZGUgPG9wZW5jdjIvaGlnaGd1aS9oaWdoZ3VpLmhwcD4KIyBpbmNsdWRlIDxvcGVuY3YyL2ltZ3Byb2MvaW1ncHJvYy5ocHA+CiNlbmRpZgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCiNkZWZpbmUgVkFfTlVNX0FSR1MoLi4uKSBWQV9OVU1fQVJHU19JTVBMXygoMCxfX1ZBX0FSR1NfXywgNiw1LDQsMywyLDEpKQojZGVmaW5lIFZBX05VTV9BUkdTX0lNUExfKHR1cGxlKSBWQV9OVU1fQVJHU19JTVBMIHR1cGxlCiNkZWZpbmUgVkFfTlVNX0FSR1NfSU1QTChfMCxfMSxfMixfMyxfNCxfNSxfNixOLC4uLikgTgojZGVmaW5lIG1hY3JvX2Rpc3BhdGNoZXIobWFjcm8sIC4uLikgbWFjcm9fZGlzcGF0Y2hlcl8obWFjcm8sIFZBX05VTV9BUkdTKF9fVkFfQVJHU19fKSkKI2RlZmluZSBtYWNyb19kaXNwYXRjaGVyXyhtYWNybywgbmFyZ3MpIG1hY3JvX2Rpc3BhdGNoZXJfXyhtYWNybywgbmFyZ3MpCiNkZWZpbmUgbWFjcm9fZGlzcGF0Y2hlcl9fKG1hY3JvLCBuYXJncykgbWFjcm9fZGlzcGF0Y2hlcl9fXyhtYWNybywgbmFyZ3MpCiNkZWZpbmUgbWFjcm9fZGlzcGF0Y2hlcl9fXyhtYWNybywgbmFyZ3MpIG1hY3JvICMjIG5hcmdzCiNkZWZpbmUgREJOMShhKSAgICAgICAgICAgY2Vycjw8I2E8PCI9Ijw8KGEpPDwiXG4iCiNkZWZpbmUgREJOMihhLGIpICAgICAgICAgY2Vycjw8I2E8PCI9Ijw8KGEpPDwiLCAiPDwjYjw8Ij0iPDwoYik8PCJcbiIKI2RlZmluZSBEQk4zKGEsYixjKSAgICAgICBjZXJyPDwjYTw8Ij0iPDwoYSk8PCIsICI8PCNiPDwiPSI8PChiKTw8IiwgIjw8I2M8PCI9Ijw8KGMpPDwiXG4iCiNkZWZpbmUgREJONChhLGIsYyxkKSAgICAgY2Vycjw8I2E8PCI9Ijw8KGEpPDwiLCAiPDwjYjw8Ij0iPDwoYik8PCIsICI8PCNjPDwiPSI8PChjKTw8IiwgIjw8I2Q8PCI9Ijw8KGQpPDwiXG4iCiNkZWZpbmUgREJONShhLGIsYyxkLGUpICAgY2Vycjw8I2E8PCI9Ijw8KGEpPDwiLCAiPDwjYjw8Ij0iPDwoYik8PCIsICI8PCNjPDwiPSI8PChjKTw8IiwgIjw8I2Q8PCI9Ijw8KGQpPDwiLCAiPDwjZTw8Ij0iPDwoZSk8PCJcbiIKI2RlZmluZSBEQk42KGEsYixjLGQsZSxmKSBjZXJyPDwjYTw8Ij0iPDwoYSk8PCIsICI8PCNiPDwiPSI8PChiKTw8IiwgIjw8I2M8PCI9Ijw8KGMpPDwiLCAiPDwjZDw8Ij0iPDwoZCk8PCIsICI8PCNlPDwiPSI8PChlKTw8IiwgIjw8I2Y8PCI9Ijw8KGYpPDwiXG4iCiNkZWZpbmUgREJOKC4uLikgbWFjcm9fZGlzcGF0Y2hlcihEQk4sIF9fVkFfQVJHU19fKShfX1ZBX0FSR1NfXykKI2RlZmluZSBEQShhLG4pIGNlcnI8PCNhPDwiPVsiOyBwcmludGFycmF5KGEsbik7IGNlcnI8PCJdXG4iCiNkZWZpbmUgREFSKGEsbixzKSBjZXJyPDwjYTw8IlsiPDxzPDwiLSI8PG4tMTw8Il09WyI7IHByaW50YXJyYXkoYSxuLHMpOyBjZXJyPDwiXVxuIgoKI2lmZGVmIF9NU0NfVkVSCiNkZWZpbmUgUFJFRkVUQ0gocHRyLCBydywgbGV2ZWwpICgodm9pZCkwKQojZWxzZQojZGVmaW5lIFBSRUZFVENIKHB0ciwgcncsIGxldmVsKSBfX2J1aWx0aW5fcHJlZmV0Y2gocHRyLCBydywgbGV2ZWwpCiNlbmRpZgoKI2lmIGRlZmluZWQgX01TQ19WRVIKI2RlZmluZSBBU1NVTUUoY29uZGl0aW9uKSAoKHZvaWQpMCkKI2RlZmluZSBfX3Jlc3RyaWN0CiNlbGlmIGRlZmluZWQgX19jbGFuZ19fCiNkZWZpbmUgQVNTVU1FKGNvbmRpdGlvbikgICAgICAgX19idWlsdGluX2Fzc3VtZShjb25kaXRpb24pCiNlbGlmIGRlZmluZWQgX19HTlVDX18KW1tub3JldHVybl1dIF9fYXR0cmlidXRlX18oKGFsd2F5c19pbmxpbmUpKSBpbmxpbmUgdm9pZCB1bmRlZmluZWRCZWhhdmlvdXIoKSB7fQojZGVmaW5lIEFTU1VNRShjb25kaXRpb24pICAgICAgICgoY29uZGl0aW9uKSA/IHRydWUgOiAodW5kZWZpbmVkQmVoYXZpb3VyKCksIGZhbHNlKSkKI2VuZGlmCgojaWZkZWYgTE9DQUwKI2RlZmluZSBDVVJUSU1FKCkgY2VyciA8PCBjbG9jaygpICogMS4wIC8gQ0xPQ0tTX1BFUl9TRUMgPDwgZW5kbAojZWxzZQojZGVmaW5lIENVUlRJTUUoKQojZW5kaWYKCnR5cGVkZWYgbG9uZyBsb25nIGxsOwp0eXBlZGVmIGxvbmcgZG91YmxlIGxkOwp0eXBlZGVmIHVuc2lnbmVkIGludCB1aW50Owp0eXBlZGVmIHVuc2lnbmVkIGxvbmcgbG9uZyB1bGw7CnR5cGVkZWYgcGFpcjxpbnQsIGludD4gcGlpOwp0eXBlZGVmIHBhaXI8bG9uZyBsb25nLCBsb25nIGxvbmc+IHBsbDsKdHlwZWRlZiB2ZWN0b3I8aW50PiB2aTsKdHlwZWRlZiB2ZWN0b3I8bG9uZyBsb25nPiB2bGw7CnR5cGVkZWYgaW50IGl0bjsKCnRlbXBsYXRlPGNsYXNzIFQxLCBjbGFzcyBUMiwgY2xhc3MgVDM+CnN0cnVjdCB0cmlwbGV7IFQxIGE7IFQyIGI7IFQzIGM7IHRyaXBsZSgpIDogYShUMSgpKSwgYihUMigpKSwgYyhUMygpKSB7fTsgdHJpcGxlKFQxIF9hLCBUMiBfYiwgVDMgX2MpIDphKF9hKSwgYihfYiksIGMoX2Mpe30gfTsKdGVtcGxhdGU8Y2xhc3MgVDEsIGNsYXNzIFQyLCBjbGFzcyBUMz4KYm9vbCBvcGVyYXRvcjwoY29uc3QgdHJpcGxlPFQxLFQyLFQzPiZ0MSxjb25zdCB0cmlwbGU8VDEsVDIsVDM+JnQyKXtpZih0MS5hIT10Mi5hKXJldHVybiB0MS5hPHQyLmE7ZWxzZSBpZih0MS5iIT10Mi5iKXJldHVybiB0MS5iPHQyLmI7ZWxzZSByZXR1cm4gdDEuYzx0Mi5jO30KdGVtcGxhdGU8Y2xhc3MgVDEsIGNsYXNzIFQyLCBjbGFzcyBUMz4KYm9vbCBvcGVyYXRvcj4oY29uc3QgdHJpcGxlPFQxLFQyLFQzPiZ0MSxjb25zdCB0cmlwbGU8VDEsVDIsVDM+JnQyKXtpZih0MS5hIT10Mi5hKXJldHVybiB0MS5hPnQyLmE7ZWxzZSBpZih0MS5iIT10Mi5iKXJldHVybiB0MS5iPnQyLmI7ZWxzZSByZXR1cm4gdDEuYz50Mi5jO30KI2RlZmluZSB0cmkgdHJpcGxlPGludCxpbnQsaW50PgojZGVmaW5lIHRybGwgdHJpcGxlPGxsLGxsLGxsPgoKI2RlZmluZSBGSShuKSBmb3IoaW50IGk9MDtpPChuKTsrK2kpCiNkZWZpbmUgRkoobikgZm9yKGludCBqPTA7ajwobik7KytqKQojZGVmaW5lIEZLKG4pIGZvcihpbnQgaz0wO2s8KG4pOysraykKI2RlZmluZSBGTChuKSBmb3IoaW50IGw9MDtsPChuKTsrK2wpCiNkZWZpbmUgRlEobikgZm9yKGludCBxPTA7cTwobik7KytxKQojZGVmaW5lIEZPUihpLGEsYikgZm9yKGludCBpID0gKGEpLCBfX2UgPSAoaW50KSAoYik7IGkgPCBfX2U7ICsraSkKI2RlZmluZSBhbGwoYSkgc3RkOjpiZWdpbihhKSwgc3RkOjplbmQoYSkKI2RlZmluZSByZXVuaXF1ZSh2KSB2LnJlc2l6ZShzdGQ6OnVuaXF1ZSh2LmJlZ2luKCksIHYuZW5kKCkpIC0gdi5iZWdpbigpKQoKI2RlZmluZSBzcXIoeCkgKCh4KSAqICh4KSkKI2RlZmluZSBzcXJ0KHgpIHNxcnQoMS4wICogKHgpKQojZGVmaW5lIHBvdyh4LCBuKSBwb3coMS4wICogKHgpLCBuKQoKI2RlZmluZSBDT01QQVJFKG9iaikgWyZdKGNvbnN0IHN0ZDo6ZGVjYXlfdDxkZWNsdHlwZShvYmopPiYgYSwgY29uc3Qgc3RkOjpkZWNheV90PGRlY2x0eXBlKG9iaik+JiBiKQojZGVmaW5lIENPTVBBUkVfQlkob2JqLCBmaWVsZCkgWyZdKGNvbnN0IHN0ZDo6ZGVjYXlfdDxkZWNsdHlwZShvYmopPiYgYSwgY29uc3Qgc3RkOjpkZWNheV90PGRlY2x0eXBlKG9iaik+JiBiKSB7IHJldHVybiBhLmZpZWxkIDwgYi5maWVsZDsgfQoKI2RlZmluZSBjaGVja2JpdChuLCBiKSAoKChuKSA+PiAoYikpICYgMSkKI2RlZmluZSBzZXRiaXQobiwgYikgKChuKSB8IChzdGF0aWNfY2FzdDxzdGQ6OmRlY2F5PGRlY2x0eXBlKG4pPjo6dHlwZT4oMSkgPDwgKGIpKSkKI2RlZmluZSByZW1vdmViaXQobiwgYikgKChuKSAmIH4oc3RhdGljX2Nhc3Q8c3RkOjpkZWNheTxkZWNsdHlwZShuKT46OnR5cGU+KDEpIDw8IChiKSkpCiNkZWZpbmUgZmxpcGJpdChuLCBiKSAoKG4pIF4gKHN0YXRpY19jYXN0PHN0ZDo6ZGVjYXk8ZGVjbHR5cGUobik+Ojp0eXBlPigxKSA8PCAoYikpKQppbmxpbmUgaW50IGNvdW50Qml0cyh1aW50IHYpe3Y9di0oKHY+PjEpJjB4NTU1NTU1NTUpO3Y9KHYmMHgzMzMzMzMzMykrKCh2Pj4yKSYweDMzMzMzMzMzKTtyZXR1cm4oKHYrKHY+PjQpJjB4RjBGMEYwRikqMHgxMDEwMTAxKT4+MjQ7fQppbmxpbmUgaW50IGNvdW50Qml0cyh1bGwgdil7dWludCB0PXY+PjMyO3VpbnQgcD0odiAmICgoMVVMTCA8PCAzMikgLSAxKSk7IHJldHVybiBjb3VudEJpdHModCkgKyBjb3VudEJpdHMocCk7IH0KaW5saW5lIGludCBjb3VudEJpdHMobGwgdil7cmV0dXJuIGNvdW50Qml0cygodWxsKXYpOyB9CmlubGluZSBpbnQgY291bnRCaXRzKGludCB2KXtyZXR1cm4gY291bnRCaXRzKCh1aW50KXYpOyB9CnVuc2lnbmVkIGludCByZXZlcnNlQml0cyh1aW50IHgpeyB4ID0gKCgoeCAmIDB4YWFhYWFhYWEpID4+IDEpIHwgKCh4ICYgMHg1NTU1NTU1NSkgPDwgMSkpOyB4ID0gKCgoeCAmIDB4Y2NjY2NjY2MpID4+IDIpIHwgKCh4ICYgMHgzMzMzMzMzMykgPDwgMikpOyB4ID0gKCgoeCAmIDB4ZjBmMGYwZjApID4+IDQpIHwgKCh4ICYgMHgwZjBmMGYwZikgPDwgNCkpOyB4ID0gKCgoeCAmIDB4ZmYwMGZmMDApID4+IDgpIHwgKCh4ICYgMHgwMGZmMDBmZikgPDwgOCkpOyByZXR1cm4oKHggPj4gMTYpIHwgKHggPDwgMTYpKTsgfQp0ZW1wbGF0ZTxjbGFzcyBUPiBpbmxpbmUgaW50IHNpZ24oVCB4KXsgcmV0dXJuIHggPiAwID8gMSA6IHggPCAwID8gLTEgOiAwOyB9CmlubGluZSBib29sIGlzUG93ZXJPZlR3byhpbnQgeCl7IHJldHVybiAoeCAhPSAwICYmICh4Jih4IC0gMSkpID09IDApOyB9CmNvbnN0ZXhwciBsbCBwb3dlcihsbCB4LCBpbnQgcCkgeyByZXR1cm4gcCA9PSAwID8gMSA6ICh4ICogcG93ZXIoeCwgcCAtIDEpKTsgfQp0ZW1wbGF0ZTxjbGFzcyBUPgppbmxpbmUgYm9vbCBpblJhbmdlKGNvbnN0IFQmIHZhbCwgY29uc3QgVCYgbWluLCBjb25zdCBUJiBtYXgpIHsgcmV0dXJuIG1pbiA8PSB2YWwgJiYgdmFsIDw9IG1heDsgfQovL3RlbXBsYXRlPGNsYXNzIFQxLCBjbGFzcyBUMiwgY2xhc3MgVDM+IFQxIGlubGluZSBjbGFtcChUMSB4LCBjb25zdCBUMiYgYSwgY29uc3QgVDMmIGIpIHsgaWYgKHggPCBhKSByZXR1cm4gYTsgZWxzZSBpZiAoeCA+IGIpIHJldHVybiBiOyBlbHNlIHJldHVybiB4OyB9CnVuc2lnbmVkIGxvbmcgbG9uZyByZHRzYygpIHsgdW5zaWduZWQgbG9uZyBsb25nIHJldCA9IDA7CiNpZmRlZiBfX2NsYW5nX18KICAgIHJldHVybiBfX2J1aWx0aW5fcmVhZGN5Y2xlY291bnRlcigpOwojZW5kaWYKI2lmbmRlZiBfTVNDX1ZFUgogICAgYXNtIHZvbGF0aWxlKCJyZHRzYyIgOiAiPUEiIChyZXQpIDogOik7CiNlbmRpZgogICAgcmV0dXJuIHJldDsgfQovLyBGYXN0IElPICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCmNvbnN0IGludCBfX0JTID0gNDA5NjsKc3RhdGljIGNoYXIgX19idXJbX19CUyArIDE2XSwgKl9fZXIgPSBfX2J1ciArIF9fQlMsICpfX2lyID0gX19lcjsKdGVtcGxhdGU8Y2xhc3MgVCA9IGludD4gVCByZWFkSW50KCkgewogICAgYXV0byBjID0gWyZdKCkgeyBpZiAoX19pciA9PSBfX2VyKSBzdGQ6OmZpbGwoX19idXIsIF9fYnVyICsgX19CUywgMCksIGNpbi5yZWFkKF9fYnVyLCBfX0JTKSwgX19pciA9IF9fYnVyOyB9OwogICAgYygpOyB3aGlsZSAoKl9faXIgJiYgKCpfX2lyIDwgJzAnIHx8ICpfX2lyID4gJzknKSAmJiAqX19pciAhPSAnLScpICsrX19pcjsgYygpOwogICAgYm9vbCBtID0gZmFsc2U7IGlmICgqX19pciA9PSAnLScpICsrX19pciwgYygpLCBtID0gdHJ1ZTsKICAgIFQgciA9IDA7IHdoaWxlICgqX19pciA+PSAnMCcgJiYgKl9faXIgPD0gJzknKSByID0gciAqIDEwICsgKl9faXIgLSAnMCcsICsrX19pciwgYygpOwogICAgKytfX2lyOyByZXR1cm4gbSA/IC1yIDogcjsKfQpzdHJpbmcgcmVhZFN0cmluZygpIHsKICAgIGF1dG8gYyA9IFsmXSgpIHsgaWYgKF9faXIgPT0gX19lcikgc3RkOjpmaWxsKF9fYnVyLCBfX2J1ciArIF9fQlMsIDApLCBjaW4ucmVhZChfX2J1ciwgX19CUyksIF9faXIgPSBfX2J1cjsgfTsKICAgIHN0cmluZyByOyBjKCk7IHdoaWxlICgqX19pciAmJiBpc3NwYWNlKCpfX2lyKSkgKytfX2lyLCBjKCk7CiAgICB3aGlsZSAoIWlzc3BhY2UoKl9faXIpKSByLnB1c2hfYmFjaygqX19pciksICsrX19pciwgYygpOwogICAgKytfX2lyOyByZXR1cm4gcjsKfQpjaGFyIHJlYWRDaGFyKCkgewogICAgYXV0byBjID0gWyZdKCkgeyBpZiAoX19pciA9PSBfX2VyKSBzdGQ6OmZpbGwoX19idXIsIF9fYnVyICsgX19CUywgMCksIGNpbi5yZWFkKF9fYnVyLCBfX0JTKSwgX19pciA9IF9fYnVyOyB9OwogICAgYygpOyB3aGlsZSAoKl9faXIgJiYgaXNzcGFjZSgqX19pcikpICsrX19pciwgYygpOyByZXR1cm4gKl9faXIrKzsKfQpzdGF0aWMgY2hhciBfX2J1d1tfX0JTICsgMjBdLCAqX19pdyA9IF9fYnV3LCAqX19ldyA9IF9fYnV3ICsgX19CUzsKdGVtcGxhdGU8Y2xhc3MgVD4Kdm9pZCB3cml0ZUludChUIHgsIGNoYXIgZW5kYyA9ICdcbicpIHsKICAgIGlmICh4IDwgMCkgKl9faXcrKyA9ICctJywgeCA9IC14OyBpZiAoeCA9PSAwKSAqX19pdysrID0gJzAnOwogICAgY2hhciogcyA9IF9faXc7CiAgICB3aGlsZSAoeCkgeyBUIHQgPSB4IC8gMTA7IGNoYXIgYyA9IHggLSAxMCAqIHQgKyAnMCc7ICpfX2l3KysgPSBjOyB4ID0gdDsgfQogICAgY2hhciogZiA9IF9faXcgLSAxOyB3aGlsZSAocyA8IGYpIHN3YXAoKnMsICpmKSwgKytzLCAtLWY7CiAgICBpZiAoX19pdyA+IF9fZXcpIGNvdXQud3JpdGUoX19idXcsIF9faXcgLSBfX2J1dyksIF9faXcgPSBfX2J1dzsKICAgIGlmIChlbmRjKSB7ICpfX2l3KysgPSBlbmRjOyB9Cn0KdGVtcGxhdGU8Y2xhc3MgVD4Kdm9pZCB3cml0ZVN0cihjb25zdCBUJiBzdHIpIHsKICAgIGludCBpID0gMDsgd2hpbGUgKHN0cltpXSkgeyAqX19pdysrID0gc3RyW2krK107IGlmIChfX2l3ID4gX19ldykgY291dC53cml0ZShfX2J1dywgX19pdyAtIF9fYnV3KSwgX19pdyA9IF9fYnV3OyB9Cn0Kc3RydWN0IF9fRkxfXyB7IH5fX0ZMX18oKSB7IGlmIChfX2l3ICE9IF9fYnV3KSBjb3V0LndyaXRlKF9fYnV3LCBfX2l3IC0gX19idXcpOyB9IH07CnN0YXRpYyBfX0ZMX18gX19mbHVzaFZhcl9fOwoKLy9TVEwgb3V0cHV0ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiNkZWZpbmUgVFQxIHRlbXBsYXRlPGNsYXNzIFQ+CiNkZWZpbmUgVFQxVDIgdGVtcGxhdGU8Y2xhc3MgVDEsIGNsYXNzIFQyPgojZGVmaW5lIFRUMVQyVDMgdGVtcGxhdGU8Y2xhc3MgVDEsIGNsYXNzIFQyLCBjbGFzcyBUMz4KVFQxVDIgb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0mIG9zLCBjb25zdCBwYWlyPFQxLCBUMj4mIHApOwpUVDEgb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0mIG9zLCBjb25zdCB2ZWN0b3I8VD4mIHYpOwpUVDFUMiBvc3RyZWFtJiBvcGVyYXRvciA8PCAob3N0cmVhbSYgb3MsIGNvbnN0IHNldDxUMSwgVDI+JnYpOwpUVDFUMiBvc3RyZWFtJiBvcGVyYXRvciA8PCAob3N0cmVhbSYgb3MsIGNvbnN0IG11bHRpc2V0PFQxLCBUMj4mdik7ClRUMVQyIG9zdHJlYW0mIG9wZXJhdG9yIDw8IChvc3RyZWFtJiBvcywgcHJpb3JpdHlfcXVldWU8VDEsIFQyPiB2KTsKVFQxVDJUMyBvc3RyZWFtJiBvcGVyYXRvciA8PCAob3N0cmVhbSYgb3MsIGNvbnN0IG1hcDxUMSwgVDIsIFQzPiYgdik7ClRUMVQyVDMgb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0mIG9zLCBjb25zdCBtdWx0aW1hcDxUMSwgVDIsIFQzPiYgdik7ClRUMVQyVDMgb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0mIG9zLCBjb25zdCB0cmlwbGU8VDEsIFQyLCBUMz4mIHQpOwp0ZW1wbGF0ZTxjbGFzcyBULCBzaXplX3QgTj4gb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0mIG9zLCBjb25zdCBhcnJheTxULCBOPiYgdik7ClRUMVQyIG9zdHJlYW0mIG9wZXJhdG9yIDw8IChvc3RyZWFtJiBvcywgY29uc3QgcGFpcjxUMSwgVDI+JiBwKXsgcmV0dXJuIG9zIDw8IigiPDxwLmZpcnN0PDwiLCAiPDwgcC5zZWNvbmQ8PCIpIjsgfQpUVDEgb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0mIG9zLCBjb25zdCB2ZWN0b3I8VD4mIHYpeyAgICAgICBib29sIGY9MTtvczw8IlsiO2ZvcihhdXRvJiBpIDogdikgeyBpZiAoIWYpb3MgPDwgIiwgIjtvczw8aTtmPTA7fXJldHVybiBvcyA8PCAiXSI7IH0KdGVtcGxhdGU8Y2xhc3MgVCwgc2l6ZV90IE4+IG9zdHJlYW0mIG9wZXJhdG9yIDw8IChvc3RyZWFtJiBvcywgY29uc3QgYXJyYXk8VCwgTj4mIHYpIHsgICAgIGJvb2wgZj0xO29zPDwiWyI7Zm9yKGF1dG8mIGkgOiB2KSB7IGlmICghZilvcyA8PCAiLCAiO29zPDxpO2Y9MDt9cmV0dXJuIG9zIDw8ICJdIjsgfQpUVDFUMiBvc3RyZWFtJiBvcGVyYXRvciA8PCAob3N0cmVhbSYgb3MsIGNvbnN0IHNldDxUMSwgVDI+JnYpeyAgICBib29sIGY9MTtvczw8IlsiO2ZvcihhdXRvJiBpIDogdikgeyBpZiAoIWYpb3MgPDwgIiwgIjtvczw8aTtmPTA7fXJldHVybiBvcyA8PCAiXSI7IH0KVFQxVDIgb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0mIG9zLCBjb25zdCBtdWx0aXNldDxUMSxUMj4mdil7Ym9vbCBmPTE7b3M8PCJbIjtmb3IoYXV0byYgaSA6IHYpIHsgaWYgKCFmKW9zIDw8ICIsICI7b3M8PGk7Zj0wO31yZXR1cm4gb3MgPDwgIl0iOyB9ClRUMVQyVDMgb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0mIG9zLCBjb25zdCBtYXA8VDEsVDIsVDM+JiB2KXsgYm9vbCBmID0gMTsgb3MgPDwgIlsiOyBmb3IgKGF1dG8mIGlpIDogdikgeyBpZiAoIWYpb3MgPDwgIiwgIjsgb3MgPDwgIigiIDw8IGlpLmZpcnN0IDw8ICIgLT4gIiA8PCBpaS5zZWNvbmQgPDwgIikgIjsgZiA9IDA7IH1yZXR1cm4gb3MgPDwgIl0iOyB9ClRUMVQyIG9zdHJlYW0mIG9wZXJhdG9yIDw8IChvc3RyZWFtJiBvcywgY29uc3QgbXVsdGltYXA8VDEsIFQyPiYgdil7IGJvb2wgZiA9IDE7IG9zIDw8ICJbIjsgZm9yIChhdXRvJiBpaSA6IHYpIHsgaWYgKCFmKW9zIDw8ICIsICI7IG9zIDw8ICIoIiA8PCBpaS5maXJzdCA8PCAiIC0+ICIgPDwgaWkuc2Vjb25kIDw8ICIpICI7IGYgPSAwOyB9cmV0dXJuIG9zIDw8ICJdIjsgfQpUVDFUMiBvc3RyZWFtJiBvcGVyYXRvciA8PCAob3N0cmVhbSYgb3MsIHByaW9yaXR5X3F1ZXVlPFQxLCBUMj4gdikgeyBib29sIGYgPSAxOyBvcyA8PCAiWyI7IHdoaWxlICghdi5lbXB0eSgpKSB7IGF1dG8geCA9IHYudG9wKCk7IHYucG9wKCk7IGlmICghZikgb3MgPDwgIiwgIjsgZiA9IDA7IG9zIDw8IHg7IH0gcmV0dXJuIG9zIDw8ICJdIjsgfQpUVDFUMlQzIG9zdHJlYW0mIG9wZXJhdG9yIDw8IChvc3RyZWFtJiBvcywgY29uc3QgdHJpcGxlPFQxLCBUMiwgVDM+JiB0KXsgcmV0dXJuIG9zIDw8ICIoIiA8PCB0LmEgPDwgIiwgIiA8PCB0LmIgPDwgIiwgIiA8PCB0LmMgPDwgIikiOyB9ClRUMVQyIHZvaWQgcHJpbnRhcnJheShjb25zdCBUMSYgYSwgVDIgc3osIFQyIGJlZyA9IDApeyBmb3IgKFQyIGkgPSBiZWc7IGk8c3o7IGkrKykgY291dCA8PCBhW2ldIDw8ICIgIjsgY291dCA8PCBlbmRsOyB9CgovL1NUTCBpbnB1dCAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgpUVDFUMlQzIGlubGluZSBpc3RyZWFtJiBvcGVyYXRvciA+PiAoaXN0cmVhbSYgb3MsIHRyaXBsZTxUMSwgVDIsIFQzPiYgdCk7ClRUMVQyIGlubGluZSBpc3RyZWFtJiBvcGVyYXRvciA+PiAoaXN0cmVhbSYgb3MsIHBhaXI8VDEsIFQyPiYgcCkgeyByZXR1cm4gb3MgPj4gcC5maXJzdCA+PiBwLnNlY29uZDsgfQpUVDEgaW5saW5lIGlzdHJlYW0mIG9wZXJhdG9yID4+IChpc3RyZWFtJiBvcywgdmVjdG9yPFQ+JiB2KSB7CiAgICBpZiAodi5zaXplKCkpIGZvciAoVCYgdCA6IHYpIG9zID4+IHQ7IGVsc2UgewogICAgICAgIHN0cmluZyBzOyBUIG9iajsgd2hpbGUgKHMuZW1wdHkoKSkge2dldGxpbmUob3MsIHMpOyBpZiAoIW9zKSByZXR1cm4gb3M7fQogICAgICAgIHN0cmluZ3N0cmVhbSBzcyhzKTsgd2hpbGUgKHNzID4+IG9iaikgdi5wdXNoX2JhY2sob2JqKTsKICAgIH0KICAgIHJldHVybiBvczsKfQpUVDFUMlQzIGlubGluZSBpc3RyZWFtJiBvcGVyYXRvciA+PiAoaXN0cmVhbSYgb3MsIHRyaXBsZTxUMSwgVDIsIFQzPiYgdCkgeyByZXR1cm4gb3MgPj4gdC5hID4+IHQuYiA+PiB0LmM7IH0KCi8vUGFpciBtYWdpYyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgojZGVmaW5lIFBUMVQyIHBhaXI8VDEsIFQyPgpUVDFUMiBpbmxpbmUgUFQxVDIgb3BlcmF0b3IrKGNvbnN0IFBUMVQyICZwMSAsIGNvbnN0IFBUMVQyICZwMikgeyByZXR1cm4gUFQxVDIocDEuZmlyc3QgKyBwMi5maXJzdCwgcDEuc2Vjb25kICsgcDIuc2Vjb25kKTsgfQpUVDFUMiBpbmxpbmUgUFQxVDImIG9wZXJhdG9yKz0oUFQxVDIgJnAxICwgY29uc3QgUFQxVDIgJnAyKSB7IHAxLmZpcnN0ICs9IHAyLmZpcnN0LCBwMS5zZWNvbmQgKz0gcDIuc2Vjb25kOyByZXR1cm4gcDE7IH0KVFQxVDIgaW5saW5lIFBUMVQyIG9wZXJhdG9yLShjb25zdCBQVDFUMiAmcDEgLCBjb25zdCBQVDFUMiAmcDIpIHsgcmV0dXJuIFBUMVQyKHAxLmZpcnN0IC0gcDIuZmlyc3QsIHAxLnNlY29uZCAtIHAyLnNlY29uZCk7IH0KVFQxVDIgaW5saW5lIFBUMVQyJiBvcGVyYXRvci09KFBUMVQyICZwMSAsIGNvbnN0IFBUMVQyICZwMikgeyBwMS5maXJzdCAtPSBwMi5maXJzdCwgcDEuc2Vjb25kIC09IHAyLnNlY29uZDsgcmV0dXJuIHAxOyB9CgojdW5kZWYgVFQxCiN1bmRlZiBUVDFUMgojdW5kZWYgVFQxVDJUMwoKI2RlZmluZSBGUkVJTihGSUxFKSBmcmVvcGVuKEZJTEUsICJydCIsIHN0ZGluKQojZGVmaW5lIEZSRU9VVChGSUxFKSBmcmVvcGVuKEZJTEUsICJ3dCIsIHN0ZG91dCkKI2lmZGVmIExPQ0FMCiNkZWZpbmUgQkVHSU5fUFJPRklMRShpZHgsIG5hbWUpIGludCBwcm9maWxlSWR4ID0gaWR4OyBwcm9maWxlTmFtZVtwcm9maWxlSWR4XSA9IG5hbWU7IHRvdGFsVGltZVtwcm9maWxlSWR4XSAtPSByZHRzYygpIC8gMWUzOwojZGVmaW5lIEVORF9QUk9GSUxFIHRvdGFsVGltZVtwcm9maWxlSWR4XSArPSByZHRzYygpIC8gMWUzOyB0b3RhbENvdW50W3Byb2ZpbGVJZHhdKys7CiNlbHNlCiNkZWZpbmUgQkVHSU5fUFJPRklMRShpZHgsIG5hbWUpCiNkZWZpbmUgRU5EX1BST0ZJTEUKI2VuZGlmCgpjb25zdCBpbnQgVVNVQUxfTU9EID0gMTAwMDAwMDAwNzsKdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIHZvaWQgbm9ybW1vZChUICZ4LCBUIG0gPSBVU1VBTF9NT0QpIHsgeCAlPSBtOyBpZiAoeCA8IDApIHggKz0gbTsgfQp0ZW1wbGF0ZTxjbGFzcyBUMSwgY2xhc3MgVDI+IGlubGluZSBUMiBzdW1tb2RmYXN0KFQxIHgsIFQxIHksIFQyIG0gPSBVU1VBTF9NT0QpIHsgVDIgcmVzID0geCArIHk7IGlmIChyZXMgPj0gbSkgcmVzIC09IG07IHJldHVybiByZXM7IH0KdGVtcGxhdGU8Y2xhc3MgVDEsIGNsYXNzIFQyLCBjbGFzcyBUMyA9IGludD4gaW5saW5lIHZvaWQgYWRkbW9kZmFzdChUMSAmeCwgVDIgeSwgVDMgbSA9IFVTVUFMX01PRCkgeyB4ICs9IHk7IGlmICh4ID49IG0pIHggLT0gbTsgfQp0ZW1wbGF0ZTxjbGFzcyBUMSwgY2xhc3MgVDIsIGNsYXNzIFQzID0gaW50PiBpbmxpbmUgdm9pZCBzdWJtb2RmYXN0KFQxICZ4LCBUMiB5LCBUMyBtID0gVVNVQUxfTU9EKSB7IHggLT0geTsgaWYgKHggPCAwKSB4ICs9IG07IH0KaW5saW5lIGxsIG11bG1vZChsbCB4LCBsbCBuLCBsbCBtKXsgeCAlPSBtOyBuICU9IG07IGxsIHIgPSB4ICogbiAtIGxsKGxkKHgpKmxkKG4pIC8gbGQobSkpICogbTsgd2hpbGUgKHIgPCAwKSByICs9IG07IHdoaWxlIChyID49IG0pIHIgLT0gbTsgcmV0dXJuIHI7IH0KaW5saW5lIGxsIHBvd21vZChsbCB4LCBsbCBuLCBsbCBtKXsgbGwgciA9IDE7IG5vcm1tb2QoeCwgbSk7IHdoaWxlIChuKXsgaWYgKG4gJiAxKSByICo9IHg7IHggKj0geDsgciAlPSBtOyB4ICU9IG07IG4gLz0gMjsgfXJldHVybiByOyB9CmlubGluZSBsbCBwb3dtdWxtb2QobGwgeCwgbGwgbiwgbGwgbSkgeyBsbCByZXMgPSAxOyBub3JtbW9kKHgsIG0pOyB3aGlsZSAobil7IGlmIChuICYgMSlyZXMgPSBtdWxtb2QocmVzLCB4LCBtKTsgeCA9IG11bG1vZCh4LCB4LCBtKTsgbiAvPSAyOyB9IHJldHVybiByZXM7IH0KdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIFQgZ2NkKFQgYSwgVCBiKSB7IHdoaWxlIChiKSB7IFQgdCA9IGEgJSBiOyBhID0gYjsgYiA9IHQ7IH0gcmV0dXJuIGE7IH0KdGVtcGxhdGU8Y2xhc3MgVD4KVCBmYXN0X2djZChUIHUsIFQgdikgewogICAgaW50IHNobCA9IDA7IHdoaWxlICggdSAmJiB2ICYmIHUgIT0gdikgeyBUIGV1ID0gdSAmIDE7IHUgPj49IGV1IF4gMTsgVCBldiA9IHYgJiAxOyB2ID4+PSBldiBeIDE7CiAgICAgICAgc2hsICs9ICh+KGV1IHwgZXYpICYgMSk7IFQgZCA9IHUgJiB2ICYgMSA/ICh1ICsgdikgPj4gMSA6IDA7IFQgZGlmID0gKHUgLSB2KSA+PiAoc2l6ZW9mKFQpICogOCAtIDEpOyB1IC09IGQgJiB+ZGlmOyB2IC09IGQgJiBkaWY7CiAgICB9IHJldHVybiBzdGQ6Om1heCh1LCB2KSA8PCBzaGw7Cn0KCmlubGluZSBsbCBsY20obGwgYSwgbGwgYil7IHJldHVybiBhIC8gZ2NkKGEsIGIpICogYjsgfQp0ZW1wbGF0ZTxjbGFzcyBUPiBpbmxpbmUgVCBnY2QoVCBhLCBUIGIsIFQgYyl7IHJldHVybiBnY2QoZ2NkKGEsIGIpLCBjKTsgfQpsbCBnY2RleChsbCBhLCBsbCBiLCBsbCYgeCwgbGwmIHkpIHsKICAgIGlmICghYSkgeyB4ID0gMDsgeSA9IDE7IHJldHVybiBiOyB9CiAgICBsbCB5MTsgbGwgZCA9IGdjZGV4KGIgJSBhLCBhLCB5LCB5MSk7IHggPSB5MSAtIChiIC8gYSkgKiB5OwogICAgcmV0dXJuIGQ7Cn0KdGVtcGxhdGU8Y2xhc3MgVD4gYm9vbCBpc1ByaW1lKFQgeCkgeyBpZiAoeCA8PSA0IHx8IHggJSAyID09IDAgfHwgeCAlIDMgPT0gMCkgcmV0dXJuIHggPT0gMiB8fCB4ID09IDM7CiAgICBmb3IgKFQgaSA9IDU7IGkgKiBpIDw9IHg7IGkgKz0gNikgaWYgKHggJSBpID09IDAgfHwgeCAlIChpICsgMikgPT0gMCkgcmV0dXJuIDA7IHJldHVybiAxOyB9CmJvb2wgbWlsbGVyUmFiaW4obG9uZyBsb25nIG4pIHsKICAgIGlmIChuIDw9IDEwMDApIHJldHVybiBpc1ByaW1lKG4pOwogICAgbG9uZyBsb25nIHMgPSBuIC0gMTsgaW50IHQgPSAwOyB3aGlsZSAocyAlIDIgPT0gMCkgcyAvPSAyLCArK3Q7CiAgICBmb3IgKGludCBhIDogezIsIDMyNSwgOTM3NSwgMjgxNzgsIDQ1MDc3NSwgOTc4MDUwNCwgMTc5NTI2NTAyMn0pIHsgaWYgKCEoYSAlPSBuKSkgcmV0dXJuIHRydWU7CiAgICAgICAgbG9uZyBsb25nIGYgPSBwb3dtdWxtb2QoYSwgcywgbik7IGlmIChmID09IDEgfHwgZiA9PSBuIC0gMSkgY29udGludWU7CiAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCB0OyArK2kpIGlmICgoZiA9IG11bG1vZChmLCBmLCBuKSkgPT0gbiAtIDEpIGdvdG8gbmV4dHA7CiAgICAgICAgcmV0dXJuIGZhbHNlOyBuZXh0cDo7CiAgICB9IHJldHVybiB0cnVlOwp9CgovLyBVc2VmdWwgY29uc3RhbnRzCgovL2ludCBzb21lX3ByaW1lc1s3XSA9IHsyNDQ0MywgMTAwMjcxLCAxMDAwMDAzLCAxMDAwMzMzLCA1MDAwMzIxLCA5ODc2NTQzMSwKI2RlZmluZSBUOSAgICAgICAgICAxMDAwMDAwMDAwCiNkZWZpbmUgVDE4ICAgICAgICAgMTAwMDAwMDAwMDAwMDAwMDAwMExMCiNkZWZpbmUgSU5GICAgICAgICAgMTAxMTExMTExMQojZGVmaW5lIExMSU5GICAgICAgIDEwMDAxMTEwMDAxMTEwMDAxMTFMTAojZGVmaW5lIG1vZCAgICAgICAgIDEwMDAwMDAwMDcKI2RlZmluZSBmZnRtb2QgICAgICA5OTgyNDQzNTMKI2RlZmluZSBFUFMgICAgICAgICAoZG91YmxlKTFlLTEwCiNkZWZpbmUgUEkgICAgICAgICAgMy4xNDE1OTI2NTM1ODk3OTMyMzg0NjI2NAojZGVmaW5lIGxpbmsgICAgICAgIGFzYXhsYWpyZXdxd2UKI2RlZmluZSByYW5rICAgICAgICB3YWhheWF3ZWhhc2Rha3cKLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgoKaW50MzJfdCBzb2x2ZSgpOwppbnQzMl90IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KSB7CiAgICBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKDApO2Npbi50aWUoMCk7CiNpZmRlZiBMT0NBTAogICAgaWYgKGFyZ2MgPT0gMSB8fCBhcmd2WzFdID09IHN0cmluZygidGVzdCIpKSB7CiAgICAgICAgRlJFSU4oImV4YW1wbGVzLzAwMSIpOwogICAgfSBlbHNlIHsKICAgICAgICBGUkVJTihhcmd2WzFdKTsKICAgIH0KICAgIEZSRU9VVCgib3V0LnR4dCIpOwojZW5kaWYKICAgIHJldHVybiBzb2x2ZSgpOwp9CnN0cmluZyB3b3JsZDsKc3RyaW5nIHE7CmNvbnN0ZXhwciBpbnQgTUFYUSA9IDEwMDEwOwpjb25zdGV4cHIgaW50IFRFTiA9IDEwOwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHNpemVfdCBOPiBzdHJ1Y3QgYWxpZ25hcygxNikgYWxpZ25lZF9hcnJheSA6IHB1YmxpYyBzdGQ6OmFycmF5PFQsIE4+IHt9Owp1c2luZyBBcnJUZW4gPSBhcnJheTxpbnQsIFRFTj47CnZvaWQgdXBkU3RyaW5nKHN0cmluZyYgcykgeyBmb3IgKGNoYXImIGMgOiBzKSBjIC09ICdBJzsgfQptdDE5OTM3XzY0IGdlbjsKaW50IHJuZChpbnQgbikgewogICAgcmV0dXJuIHVuaWZvcm1faW50X2Rpc3RyaWJ1dGlvbjw+KDAsIG4gLSAxKShnZW4pOwp9CkFyclRlbiBuZXhbNTAwMDFdOwpzdHJ1Y3QgSGlzdCB7CiAgICBIaXN0ICpwYXJlbnQ7CiAgICBwaWkgbW92ZTsKfTsKSGlzdCBhbGxIaXN0WzEgPDwgMjFdOwpIaXN0ICpsYXN0SGlzdCA9IGFsbEhpc3Q7CnZlY3RvcjxIaXN0Kj4gaGlzdFBvb2w7Ckhpc3QgKmdldE5ld0hpc3QoKSB7CiAgICBpZiAoaGlzdFBvb2wuZW1wdHkoKSkgewogICAgICAgIHJldHVybiBsYXN0SGlzdCsrOwogICAgfSBlbHNlIHsKICAgICAgICBhdXRvIHJlcyA9IGhpc3RQb29sLmJhY2soKTsKICAgICAgICBoaXN0UG9vbC5wb3BfYmFjaygpOwogICAgICAgIHJldHVybiByZXM7CiAgICB9Cn0KLyoqKioqIFBBUkFNUyAqKioqKi8KaW50IE5PVF9MQVNUX0JPTlVTID0gODsKY29uc3RleHByIGludCBNQVhfU1RBVEVTX0NOVCA9IDYwOwpjb25zdGV4cHIgaW50IERFUFRIMV9UUklFUyA9IDY7CmNvbnN0ZXhwciBpbnQgREVQVEgwX1RSSUVTID0gMjsKY29uc3RleHByIGludCBHUkVFRFlfU1RFUFMgPSAyNDsKLyoqKioqIFBBUkFNUyAqKioqKi8KYm9vbCB1c2VkWzUwMDAwXTsKc3RydWN0IFN0YXRlIHsKICAgIEFyclRlbiB3aGVyZUlzVW5pdCA9IHt9OwogICAgQXJyVGVuIGNvbG9yc0luUG9ja2V0ID0ge307CiAgICBpbnQgc2NvcmUgPSAwOwogICAgSGlzdCogaGlzdCA9IG51bGxwdHI7CiAgICBpbnQgY2FsY1Njb3JlKCkgewogICAgICAgIGludCBzY29yZSA9IDA7CiAgICAgICAgYXV0byB0bXAgPSB3aGVyZUlzVW5pdDsKICAgICAgICBzb3J0KHRtcC5iZWdpbigpLCB0bXAuZW5kKCksIHN0ZDo6Z3JlYXRlcjxpbnQ+KCkpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgVEVOOyArK2kpIHsKICAgICAgICAgICAgc2NvcmUgKz0gKGkgKyA0KSAqIHRtcFtpXTsKICAgICAgICB9CiAgICAgICAgc2NvcmUgKz0gdG1wW1RFTiAtIDFdICogODsKICAgICAgICByZXR1cm4gc2NvcmU7CiAgICB9CiAgICBpbmxpbmUgYm9vbCBhbnlvbmVBdFBvcyhpbnQgcG9zKSBjb25zdCB7CiAgICAgICAgZm9yIChpbnQgeCA6IHdoZXJlSXNVbml0KSB7CiAgICAgICAgICAgIGlmICh4ID09IHBvcykgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGludCBnZXRMYXN0VW5pdCgpIGNvbnN0IHsKICAgICAgICByZXR1cm4gaW50KG1pbl9lbGVtZW50KGFsbCh3aGVyZUlzVW5pdCkpIC0gYmVnaW4od2hlcmVJc1VuaXQpKTsKICAgIH0KICAgIGludCBnZXROZXh0U2FtZUNvbG9yX1VzZWQoaW50IHBvcywgaW50IGNvbG9yKSBjb25zdCB7CiAgICAgICAgZG8gewogICAgICAgICAgICBwb3MgPSBuZXhbcG9zXVtjb2xvcl07CiAgICAgICAgfSB3aGlsZSAodXNlZFtwb3NdKTsKICAgICAgICByZXR1cm4gcG9zOwogICAgfQogICAgaW50IGdldE5leHRTYW1lQ29sb3IoaW50IHBvcywgaW50IGNvbG9yKSBjb25zdCB7CiAgICAgICAgZG8gewogICAgICAgICAgICBwb3MgPSBuZXhbcG9zXVtjb2xvcl07CiAgICAgICAgfSB3aGlsZSAoYW55b25lQXRQb3MocG9zKSk7CiAgICAgICAgcmV0dXJuIHBvczsKICAgIH0KICAgIGlubGluZSB2b2lkIGFkZENvbG9yKGludCBjb2xvcikgewogICAgICAgIGNvbG9yc0luUG9ja2V0W2NvbG9yXSsrOwogICAgfQogICAgaW5saW5lIHZvaWQgZGVsQ29sb3IoaW50IGNvbG9yKSB7CiAgICAgICAgY29sb3JzSW5Qb2NrZXRbY29sb3JdLS07CiAgICB9CiAgICB2b2lkIG1ha2VUaGVNb3ZlKGludCBpZHgsIGludCBjb2xvcikgewogICAgICAgIHdoZXJlSXNVbml0W2lkeF0gPSBnZXROZXh0U2FtZUNvbG9yKHdoZXJlSXNVbml0W2lkeF0sIGNvbG9yKTsKICAgICAgICBkZWxDb2xvcihjb2xvcik7CiAgICB9CiAgICB2b2lkIG1ha2VUaGVNb3ZlKGludCBpZHgsIGludCBjb2xvciwgaW50IHBvcykgewogICAgICAgIHdoZXJlSXNVbml0W2lkeF0gPSBwb3M7CiAgICAgICAgZGVsQ29sb3IoY29sb3IpOwogICAgfQogICAgdm9pZCBtdXRhdGVHcmVlZHkoaW50IGN1ciwgaW50IHN0ZXBzQ250KSB7CiAgICAgICAgZm9yIChpbnQgeCA6IHdoZXJlSXNVbml0KSB7CiAgICAgICAgICAgIHVzZWRbeF0gPSB0cnVlOwogICAgICAgIH0KICAgICAgICB3aGlsZSAoc3RlcHNDbnQtLSA+IDAgJiYgY3VyIDwgTUFYUSkgewogICAgICAgICAgICBhZGRDb2xvcihxW2N1cisrXSk7CiAgICAgICAgICAgIGludCBpZHggPSBnZXRMYXN0VW5pdCgpOwogICAgICAgICAgICBpbnQgcG9zID0gd2hlcmVJc1VuaXRbaWR4XTsKICAgICAgICAgICAgdXNlZFtwb3NdID0gZmFsc2U7CiAgICAgICAgICAgIGludCBtYXhOZXh0UG9zID0gLTE7CiAgICAgICAgICAgIGludCB3aGF0ID0gLTE7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgVEVOOyArK2kpIHsKICAgICAgICAgICAgICAgIGlmICghY29sb3JzSW5Qb2NrZXRbaV0pIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaW50IG5leHRQb3MgPSBnZXROZXh0U2FtZUNvbG9yX1VzZWQocG9zLCBpKTsKICAgICAgICAgICAgICAgIGlmIChuZXh0UG9zID4gbWF4TmV4dFBvcykgewogICAgICAgICAgICAgICAgICAgIG1heE5leHRQb3MgPSBuZXh0UG9zOwogICAgICAgICAgICAgICAgICAgIHdoYXQgPSBpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVzZWRbbWF4TmV4dFBvc10gPSB0cnVlOwogICAgICAgICAgICBtYWtlVGhlTW92ZShpZHgsIHdoYXQsIG1heE5leHRQb3MpOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCB4IDogd2hlcmVJc1VuaXQpIHsKICAgICAgICAgICAgdXNlZFt4XSA9IGZhbHNlOwogICAgICAgIH0KICAgIH0KICAgIHRlbXBsYXRlPGludCBkZXB0aD4KICAgIGludCBnZW5lcmF0ZU5ld1N0YXRlcyhpbnQgbWF4Q250LCBTdGF0ZSogcmVzLCBpbnQgY3VyKSB7CiAgICAgICAgYWRkQ29sb3IocVtjdXJdKTsKICAgICAgICB0cmkgd2hvV2hhdEFuZFdoZXJlW2RlcHRoID09IDAgPyAxMCA6IDEwMF07CiAgICAgICAgaW50IHN6ID0gMDsKICAgICAgICBpbnQgaWR4ID0gZ2V0TGFzdFVuaXQoKTsKICAgICAgICBmb3IgKGludCB3aG8gPSAoZGVwdGggPyAwIDogaWR4KTsgd2hvIDwgKGRlcHRoID8gVEVOIDogaWR4ICsgMSk7ICsrd2hvKSB7CiAgICAgICAgICAgIGZvciAoaW50IHdoYXQgPSAwOyB3aGF0IDwgVEVOOyArK3doYXQpIHsKICAgICAgICAgICAgICAgIGlmICghY29sb3JzSW5Qb2NrZXRbd2hhdF0pIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaW50IHdoZXJlID0gZ2V0TmV4dFNhbWVDb2xvcih3aGVyZUlzVW5pdFt3aG9dLCB3aGF0KSAtIHdoZXJlSXNVbml0W3dob107CiAgICAgICAgICAgICAgICBpZiAoaWR4ICE9IHdobykgewogICAgICAgICAgICAgICAgICAgIHdoZXJlIC09IE5PVF9MQVNUX0JPTlVTOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgd2hvV2hhdEFuZFdoZXJlW3N6KytdID0ge3dobywgd2hhdCwgd2hlcmV9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNvcnQod2hvV2hhdEFuZFdoZXJlLCB3aG9XaGF0QW5kV2hlcmUgKyBzeiAsIFtdKHRyaSBhLCB0cmkgYil7CiAgICAgICAgICAgIHJldHVybiBhLmMgPiBiLmM7CiAgICAgICAgfSk7CiAgICAgICAgaW50IHJlc3VsdE1vdmVzID0gMDsKICAgICAgICBtYXhDbnQgPSBtaW4obWF4Q250LCBzeik7CiAgICAgICAgZm9yIChhdXRvIFt3aG8sIHdoYXQsIF9dIDogd2hvV2hhdEFuZFdoZXJlKSB7CiAgICAgICAgICAgIGlmIChtYXhDbnQtLSA9PSAwKSBicmVhazsKICAgICAgICAgICAgaW50IG9sZFBvcyA9IHdoZXJlSXNVbml0W3dob107CiAgICAgICAgICAgIGludCB3aGVyZSA9IGdldE5leHRTYW1lQ29sb3Iob2xkUG9zLCB3aGF0KTsKICAgICAgICAgICAgbWFrZVRoZU1vdmUod2hvLCB3aGF0LCB3aGVyZSk7CiAgICAgICAgICAgIGlmIChkZXB0aCA9PSAwIHx8IGN1ciArIDEgPT0gTUFYUSkgewogICAgICAgICAgICAgICAgYXV0byBncmVlZHkgPSAqdGhpczsKICAgICAgICAgICAgICAgIGdyZWVkeS5tdXRhdGVHcmVlZHkoY3VyICsgMSwgR1JFRURZX1NURVBTKTsKICAgICAgICAgICAgICAgIHNjb3JlID0gbWF4KHNjb3JlLCBncmVlZHkuY2FsY1Njb3JlKCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2NvcmUgPSAwOwogICAgICAgICAgICAgICAgZ2VuZXJhdGVOZXdTdGF0ZXM8MD4oREVQVEgwX1RSSUVTLCBudWxscHRyLCBjdXIgKyAxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocmVzICE9IG51bGxwdHIpIHsKICAgICAgICAgICAgICAgIGF1dG8gcHJldkhpc3QgPSBoaXN0OwogICAgICAgICAgICAgICAgaGlzdCA9IGdldE5ld0hpc3QoKTsKICAgICAgICAgICAgICAgIGhpc3QtPm1vdmUgPSB7d2hvLCB3aGF0fTsKICAgICAgICAgICAgICAgIGhpc3QtPnBhcmVudCA9IHByZXZIaXN0OwogICAgICAgICAgICAgICAgKnJlcysrID0gKnRoaXM7CiAgICAgICAgICAgICAgICBoaXN0ID0gcHJldkhpc3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd2hlcmVJc1VuaXRbd2hvXSA9IG9sZFBvczsKICAgICAgICAgICAgY29sb3JzSW5Qb2NrZXRbd2hhdF0rKzsKICAgICAgICAgICAgKytyZXN1bHRNb3ZlczsKICAgICAgICB9CiAgICAgICAgZGVsQ29sb3IocVtjdXJdKTsKICAgICAgICByZXR1cm4gcmVzdWx0TW92ZXM7CiAgICB9Cn07CnN0ZDo6b3N0cmVhbSYgb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIG9zLCBjb25zdCBTdGF0ZSYgcykgewogICAgcmV0dXJuIG9zIDw8IHMuY29sb3JzSW5Qb2NrZXQgPDwgJyAnIDw8IHMud2hlcmVJc1VuaXQ7Cn0KYm9vbCBvcGVyYXRvciA8IChjb25zdCBTdGF0ZSYgYSwgY29uc3QgU3RhdGUmIGIpIHsKICAgIHJldHVybiAoYS5zY29yZSA+IGIuc2NvcmUpIHx8IChhLnNjb3JlID09IGIuc2NvcmUgJiYgYS5jb2xvcnNJblBvY2tldCA8IGIuY29sb3JzSW5Qb2NrZXQpOwp9CmJvb2wgb3BlcmF0b3IgPT0gKGNvbnN0IFN0YXRlJiBhLCBjb25zdCBTdGF0ZSYgYikgewogICAgcmV0dXJuIGEuc2NvcmUgPT0gYi5zY29yZSAmJiBhLmNvbG9yc0luUG9ja2V0ID09IGIuY29sb3JzSW5Qb2NrZXQ7Cn0KaW50IHNvbHZlKCkgewogICAgLy8gICAgaWZzdHJlYW0gZmluKCJleGFtcGxlcy8wMDEiKTsKICAgIGludCBuLCBzLCBjLCBoLCBVOwogICAgY2luID4+IG4gPj4gcyA+PiBjID4+IGggPj4gVTsKICAgIGNpbiA+PiB3b3JsZDsKICAgIGNpbiA+PiBxOwogICAgdXBkU3RyaW5nKHdvcmxkKTsKICAgIHVwZFN0cmluZyhxKTsKICAgIGNvbnN0IGludCBNQVhQT1MgPSA1MDAwMDsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgVEVOOyArK2kpIG5leFtNQVhQT1NdW2ldID0gTUFYUE9TOwogICAgZm9yIChpbnQgaSA9IE1BWFBPUyAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBURU47ICsraikgewogICAgICAgICAgICBuZXhbaV1bal0gPSBuZXhbaSArIDFdW2pdOwogICAgICAgIH0KICAgICAgICBuZXhbaV1bd29ybGRbaSArIDFdXSA9IGkgKyAxOwogICAgfQogICAgc3RhdGljIGludCBpbmRpY2VzW01BWF9TVEFURVNfQ05UICogVEVOXTsKICAgIHN0YXRpYyBTdGF0ZSBfX3N0YXRlc1syXVtNQVhfU1RBVEVTX0NOVCAqIFRFTl07CiAgICBhdXRvIHN0YXRlcyA9IF9fc3RhdGVzWzBdOwogICAgYXV0byBuZXdTdGF0ZXMgPSBfX3N0YXRlc1sxXTsKICAgIGludCBzdGF0ZXNDbnQgPSAxOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBURU4gLSAxOyArK2kpIHsKICAgICAgICBzdGF0ZXNbMF0uYWRkQ29sb3IocVtpXSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IFRFTjsgKytpKSB7CiAgICAgICAgc3RhdGVzWzBdLndoZXJlSXNVbml0W2ldID0gaTsKICAgIH0KICAgIGZvciAoaW50IGkgPSBURU4gLSAxOyBpICsgMSA8IChpbnQpcS5zaXplKCk7ICsraSkgewogICAgICAgIGlmIChpID09IDkwMDApIE5PVF9MQVNUX0JPTlVTID0gMjQ7CiAgICAgICAgaWYgKGkgPT0gOTUwMCkgTk9UX0xBU1RfQk9OVVMgPSA2NDsKICAgICAgICBpZiAoaSA9PSA5OTAwKSBOT1RfTEFTVF9CT05VUyA9IDI1NjsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0YXRlc0NudDsgKytpKSB7CiAgICAgICAgICAgIGluZGljZXNbaV0gPSBpOwogICAgICAgIH0KICAgICAgICBhdXRvIGNtcCA9IFsmXShpbnQgeCwgaW50IHkpIHsgcmV0dXJuIHN0YXRlc1t4XSA8IHN0YXRlc1t5XTsgfTsKICAgICAgICBzaHVmZmxlKGluZGljZXMsIGluZGljZXMgKyBzdGF0ZXNDbnQsIGdlbik7CiAgICAgICAgc29ydChpbmRpY2VzLCBpbmRpY2VzICsgc3RhdGVzQ250LCBjbXApOwogICAgICAgIGludCBvbGRTdGF0ZXNDbnQgPSBzdGF0ZXNDbnQ7CiAgICAgICAgc3RhdGVzQ250ID0gMTsKICAgICAgICBmb3IgKGludCBqID0gMTsgaiA8IG9sZFN0YXRlc0NudDsgKytqKSB7CiAgICAgICAgICAgIGludCB4ID0gaW5kaWNlc1tqXTsKICAgICAgICAgICAgaW50IHkgPSBpbmRpY2VzW3N0YXRlc0NudCAtIDFdOwogICAgICAgICAgICBpZiAoc3RhdGVzQ250ID09IE1BWF9TVEFURVNfQ05UIHx8IHN0YXRlc1t4XSA9PSBzdGF0ZXNbeV0pIHsKICAgICAgICAgICAgICAgIGhpc3RQb29sLnB1c2hfYmFjayhzdGF0ZXNbeF0uaGlzdCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpbmRpY2VzW3N0YXRlc0NudCsrXSA9IHg7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50IG5ld1N0YXRlc0NudCA9IDA7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzdGF0ZXNDbnQ7ICsraikgewogICAgICAgICAgICBhdXRvJiBzdGF0ZSA9IHN0YXRlc1tpbmRpY2VzW2pdXTsKICAgICAgICAgICAgc3RhdGUuc2NvcmUgPSAwOwogICAgICAgICAgICBuZXdTdGF0ZXNDbnQgKz0gc3RhdGUuZ2VuZXJhdGVOZXdTdGF0ZXM8MT4oREVQVEgxX1RSSUVTLCBuZXdTdGF0ZXMgKyBuZXdTdGF0ZXNDbnQsIGkpOwogICAgICAgIH0KICAgICAgICBzdGF0ZXNDbnQgPSBuZXdTdGF0ZXNDbnQ7CiAgICAgICAgc3dhcChzdGF0ZXMsIG5ld1N0YXRlcyk7CiAgICB9CiAgICBzb3J0KHN0YXRlcywgc3RhdGVzICsgc3RhdGVzQ250KTsKICAgIGF1dG8gYmVzdFNjb3JlID0gc3RhdGVzWzBdLndoZXJlSXNVbml0W3N0YXRlc1swXS5nZXRMYXN0VW5pdCgpXTsKICAgIHZlY3RvcjxwaWk+IGFuczsKICAgIGF1dG8gaGlzdCA9IHN0YXRlc1swXS5oaXN0OwogICAgd2hpbGUgKGhpc3QgIT0gbnVsbHB0cikgewogICAgICAgIGFucy5wdXNoX2JhY2soaGlzdC0+bW92ZSk7CiAgICAgICAgaGlzdCA9IGhpc3QtPnBhcmVudDsKICAgIH0KICAgIHJldmVyc2UoYWxsKGFucykpOwogICAgZm9yIChhdXRvIHAgOiBhbnMpIHsKICAgICAgICBjb3V0IDw8IHAuZmlyc3QgPDwgJyAnIDw8IGNoYXIocC5zZWNvbmQgKyAnQScpIDw8IGVuZGw7CiAgICB9CiAgICBEQk4oYmVzdFNjb3JlKTsKICAgIENVUlRJTUUoKTsKICAgIEZSRU9VVCgic2NvcmUudHh0Iik7CiAgICBjb3V0IDw8IGJlc3RTY29yZSA8PCBlbmRsOwogICAgLy8gICAgREJOKGJlc3RTY29yZSk7CiAgICByZXR1cm4gMDsKfQo=