#include <bits/stdc++.h>
using namespace std;
#define MASK(i) (1LL<<(i))
#define BIT(n,i) ((n>>i)&1)
#define SQR(n) (1LL*n*n)
const int INF = 1e9 + 7 ;
template < class _, class __>
bool minimize( _ & x, const __ y) {
if ( x > y) {
x = y;
return true ;
} else return false ;
}
template < class _, class __>
bool maximize( _ & x, const __ y) {
if ( x < y) {
x = y;
return true ;
} else return false ;
}
const int N = 63 ; // Số tỉnh nước Việt Nam
const int MaxM = 35 ; // Số lượng tỉnh tối đa sau khi sáp nhập
const int Log = 16 ; // Số lượng tỉnh cần quản lí trong một trạng thái
const long long Min_Population = 1200000 ;
const int Min_Area = 6500 ;
const int Max_Area = 25000 ;
string Province[ N] = { "Lang Son" , "Quang Ninh" , "Hai Duong" , "Hai Phong" , "Cao Bang" ,
"Bac Kan" , "Thai Nguyen" , "Bac Giang" , "Bac Ninh" , "Hung Yen" ,
"Thai Binh" , "Ha Giang" , "Tuyen Quang" , "Vinh Phuc" , "Ha Noi" ,
"Ha Nam" , "Nam Dinh" , "Lao Cai" , "Yen Bai" , "Phu Tho" ,
"Hoa Binh" , "Ninh Binh" , "Lai Chau" , "Dien Bien" , "Son La" ,
"Thanh Hoa" ,"Nghe An" , "Ha Tinh" , "Quang Binh" , "Quang Tri" ,
"Hue" , "Da Nang" , "Quang Nam" , "Kom Tum" , "Quang Ngai" ,
"Gia Lai" , "Binh Dinh" , "Dak Lak" , "Phu Yen" , "Khanh Hoa" ,
"Ninh Thuan" , "Lam Dong" , "Dak Nong" , "Binh Phuoc" , "Binh Thuan" ,
"Dong Nai" , "Binh Duong" , "Tay Ninh" , "Sai Gon" , "BRVT" ,
"Long An" , "Tien Giang" , "Dong Thap" , "Ben Tre" , "Tra Vinh" ,
"Vinh Long" , "Can Tho" , "An Giang" , "Kien Giang" , "Hau Giang" ,
"Soc Trang" , "Bac Lieu" , "Ca Mau" } ;
int Real_ID[ N] = {
35 , 47 , 25 , 26 , 13 , 3 , 53 , 2 , 5 , 29 , 52 , 21 , 59 , 61 , 23 , 22 , 38 , 36 , 62 , 42 ,
28 , 40 , 33 , 17 , 50 , 54 , 39 , 24 , 44 , 48 , 55 , 14 , 45 , 32 , 46 , 20 , 10 , 15 , 43 , 30 ,
41 , 34 , 16 , 8 , 9 , 18 , 7 , 51 , 57 , 1 , 37 , 56 , 19 , 6 , 58 , 60 , 12 , 0 , 31 , 27 ,
49 , 4 , 11
} ;
vector< int > Edge[ N] = {
{ 1 , 7 , 6 , 5 , 4 } , // 0 - Lang Son
{ 3 , 2 , 7 , 0 } , // 1 - Quang Ninh
{ 1 , 3 , 7 , 8 , 9 , 10 } , // 2 - Hai Duong
{ 1 , 2 , 10 } , // 3 - Hai Phong
{ 0 , 5 , 12 , 11 } , // 4 - Cao Bang
{ 0 , 6 , 12 ,4 } , // 5 - Bac Kan
{ 0 ,7 ,14 ,13 ,12 ,5 } , // 6 - Thai Nguyen
{ 0 ,1 ,2 ,8 ,14 ,6 } , // 7 - Bac Giang
{ 7 ,2 ,9 ,14 } , // 8 - Bac Ninh
{ 8 ,2 ,10 ,15 ,14 } , // 9 - Hung Yen
{ 3 ,2 ,9 ,15 ,16 } , // 10 - Thai Binh
{ 4 ,12 ,17 } , // 11 - Ha Giang
{ 4 ,5 ,6 ,13 ,19 ,18 ,11 } , // 12 - Tuyen Quang
{ 6 ,14 ,19 ,12 } , // 13 - Vinh Phuc
{ 6 ,7 ,8 ,9 ,15 ,20 ,19 ,13 } , // 14 - Ha Noi
{ 9 ,10 ,16 ,21 ,20 ,14 } , // 15 - Ha Nam
{ 10 ,15 ,21 } , // 16 - Nam Dinh
{ 11 ,18 ,22 } , // 17 - Lao Cai
{ 12 ,19 ,24 ,22 } , // 18 - Yen Bai
{ 12 ,13 ,14 ,20 ,24 ,18 } , // 19 - Phu Tho
{ 14 ,15 ,21 ,25 ,24 ,19 } , // 20 - Hoa Binh
{ 15 ,16 ,20 ,25 } , // 21 - Ninh Binh
{ 17 ,18 ,24 } , // 22 - Lai Chau
{ 24 } , // 23 - Dien Bien
{ 23 ,22 ,18 ,19 ,20 ,25 } , // 24 - Son La
{ 21 ,20 ,24 ,26 } , // 25 - Thanh Hoa
{ 25 ,27 } , // 26 - Nghe An
{ 26 , 28 } , // 27 - Ha Tinh
{ 27 , 29 } , // 28 - Quang Binh
{ 28 , 30 } , // 29 - Quang Tri
{ 29 , 31 , 32 } , // 30 - Hue
{ 30 , 32 } , // 31 - Da Nang
{ 30 , 31 , 33 , 34 } , // 32 - Quang Nam
{ 32 , 35 } , // 33 - Kom Tum
{ 32 , 36 } , // 34 - Quang Ngai
{ 33 , 36 , 37 } , // 35 - Gia Lai
{ 34 , 35 , 38 } , // 36 - Binh Dinh
{ 35 , 38 , 41 , 42 } , // 37 - Dak Lak
{ 36 , 37 , 39 } , // 38 - Phu Yen
{ 38 , 40 , 41 } , // 39 - Khanh Hoa
{ 39 , 41 , 44 } , // 40 - Ninh Thuan
{ 37 , 39 , 40 , 42 , 44 , 43 , 45 } , // 41 - Lam Dong
{ 37 , 41 , 43 } , // 42 - Dak Nong
{ 41 , 42 , 45 , 46 , 47 } , // 43 - Binh Phuoc
{ 40 , 41 , 45 , 49 } , // 44 - Binh Thuan
{ 44 ,41 ,43 ,49 ,48 ,46 } , // 45 - Dong Nai
{ 43 ,47 ,48 ,45 } , // 46 - Binh Duong
{ 43 , 46 , 48 , 50 } , // 47 - Tay Ninh
{ 47 ,46 ,45 ,49 ,50 } , // 48 - Sai Gon
{ 44 , 45 , 48 } , // 49 - BRVT
{ 47 , 48 , 51 , 52 } , // 50 - Long An
{ 53 , 55 , 52 , 50 } , // 51 - Tien Giang
{ 50 , 51 , 55 , 56 , 57 } , // 52 - Dong Thap
{ 51 , 54 , 55 } , // 53 - Ben Tre
{ 53 , 55 , 60 } , // 54 - Tra Vinh
{ 53 , 51 , 52 , 54 , 56 , 59 , 60 } , // 55 - Vinh Long
{ 52 , 55 , 57 , 58 , 59 } , // 56 - Can Tho
{ 52 , 56 , 58 } , // 57 - An Giang
{ 56 , 57 , 59 , 61 , 62 } , // 58 - Kien Giang
{ 55 , 56 , 60 , 61 , 58 } , // 59 - Hau Giang
{ 54 , 55 , 59 , 61 } , // 60 - Soc Trang
{ 60 , 59 , 58 , 62 } , // 61 - Bac Lieu
{ 58 , 61 } // 62 - Ca Mau
} ;
/*
Khác với danh sách kề đã liệt kê ở câu 3: Một số cặp đỉnh sẽ không được coi
không kề nhauvì đường giáp ranh giữa hai tỉnh khá nhỏ.
Quãng Ngãi - Gia Lai
TP HCM - Tiền Giang
Đường đi hiểm trở
// if (IsAppear(33,ds) && IsAppear(34,ds)) return false;
// if (IsAppear(22,ds) && IsAppear(23,ds)) return false;
// if (IsAppear(18,ds) && IsAppear(11,ds)) return false;
// if (IsAppear(35,ds) && IsAppear(38,ds)) return false;
// if (IsAppear(37,ds) && IsAppear(39,ds)) return false;
*/
int Area[ N] = {
8310 , // Lang Son
6208 , // Quang Ninh
1668 , // Hai Duong
1527 , // Hai Phong
6700 , // Cao Bang
4860 , // Bac Kan
3522 , // Thai Nguyen
3896 , // Bac Giang
823 , // Bac Ninh
930 , // Hung Yen
1585 , // Thai Binh
7928 , // Ha Giang
5868 , // Tuyen Quang
1236 , // Vinh Phuc
3360 , // Ha Noi
862 , // Ha Nam
1669 , // Nam Dinh
6364 , // Lao Cai
6893 , // Yen Bai
3535 , // Phu Tho
4590 , // Hoa Binh
1412 , // Ninh Binh
9069 , // Lai Chau
9540 , // Dien Bien
14110 , // Son La
11115 , // Thanh Hoa
16486 , // Nghe An
5994 , // Ha Tinh
7999 , // Quang Binh
4701 , // Quang Tri
4947 , // Hue
1285 , // Da Nang
10575 , // Quang Nam
9677 , // Kom Tum
5155 , // Quang Ngai
15510 , // Gia Lai
6066 , // Binh Dinh
13070 , // Dak Lak
5026 , // Phu Yen
5200 , // Khanh Hoa
3356 , // Ninh Thuan
9781 , // Lam Dong
6509 , // Dak Nong
6874 , // Binh Phuoc
7943 , // Binh Thuan
5864 , // Dong Nai
2695 , // Binh Duong
4042 , // Tay Ninh
2095 , // Sai Gon
1983 , // BRVT
4495 , // Long An
2556 , // Tien Giang
3382 , // Dong Thap
2380 , // Ben Tre
2391 , // Tra Vinh
1526 , // Vinh Long
1440 , // Can Tho
3537 , // An Giang
6353 , // Kien Giang
1622 , // Hau Giang
3298 , // Soc Trang
2668 , // Bac Lieu
5275 // Ca Mau
} ;
int Population[ N] = {
813978 , // Lang Son
1393702 , // Quang Ninh
1971326 , // Hai Duong
2121841 , // Hai Phong
555809 , // Cao Bang
328609 , // Bac Kan
1361474 , // Thai Nguyen
1950615 , // Bac Giang
1543529 , // Bac Ninh
1313798 , // Hung Yen
1888184 , // Thai Binh
908263 , // Ha Giang
820054 , // Tuyen Quang
1221803 , // Vinh Phuc
8685607 , // Ha Noi
892755 , // Ha Nam
1892427 , // Nam Dinh
787066 , // Lao Cai
863338 , // Yen Bai
1540608 , // Phu Tho
892373 , // Hoa Binh
1027030 , // Ninh Binh
494626 , // Lai Chau
653422 , // Dien Bien
1327430 , // Son La
3760650 , // Thanh Hoa
3470988 , // Nghe An
1329365 , // Ha Tinh
924169 , // Quang Binh
658619 , // Quang Tri
1177624 , // Hue
1269070 , // Da Nang
1539468 , // Quang Nam
598201 , // Kom Tum
1256952 , // Quang Ngai
1630311 , // Gia Lai
1515422 , // Binh Dinh
1944821 , // Dak Lak
883298 , // Phu Yen
1267443 , // Khanh Hoa
609820 , // Ninh Thuan
1361129 , // Lam Dong
692896 , // Dak Nong
1060448 , // Binh Phuoc
1266240 , // Binh Thuan
3341716 , // Dong Nai
2858815 , // Binh Duong
1201736 , // Tay Ninh
9521886 , // Sai Gon (TP. HCM)
1192863 , // BRVT
1753041 , // Long An
1795251 , // Tien Giang
1600963 , // Dong Thap
1305281 , // Ben Tre
1022887 , // Tra Vinh
1035362 , // Vinh Long
1268514 , // Can Tho
1911002 , // An Giang
1763826 , // Kien Giang
728924 , // Hau Giang
1203705 , // Soc Trang
929439 , // Bac Lieu
1210843 // Ca Mau
} ;
int GRDP[ N] = {
50 , // Lang Son
348 , // Quang Ninh
212 , // Hai Duong
446 , // Hai Phong
25 , // Cao Bang
19 , // Bac Kan
167 , // Thai Nguyen
207 , // Bac Giang
232 , // Bac Ninh
160 , // Hung Yen
71 , // Thai Binh
36 , // Ha Giang
50 , // Tuyen Quang
173 , // Vinh Phuc
1430 , // Ha Noi
56 , // Ha Nam
113 , // Nam Dinh
77 , // Lao Cai
49 , // Yen Bai
107 , // Phu Tho
72 , // Hoa Binh
99 , // Ninh Binh
31 , // Lai Chau
32 , // Dien Bien
77 , // Son La
319 , // Thanh Hoa
217 , // Nghe An
113 , // Ha Tinh
60 , // Quang Binh
54 , // Quang Tri
80 , // Hue
151 , // Da Nang
129 , // Quang Nam
41 , // Kom Tum
133 , // Quang Ngai
111 , // Gia Lai
131 , // Binh Dinh
141 , // Dak Lak
63 , // Phu Yen
129 , // Khanh Hoa
60 , // Ninh Thuan
13 , // Lam Dong
56 , // Dak Nong
115 , // Binh Phuoc
121 , // Binh Thuan
494 , // Dong Nai
520 , // Binh Duong
124 , // Tay Ninh
1778 , // Sai Gon (TP. Ho Chi Minh)
417 , // BRVT
189 , // Long An
137 , // Tien Giang
124 , // Dong Thap
74 , // Ben Tre
97 , // Tra Vinh
84 , // Vinh Long
133 , // Can Tho
127 , // An Giang
144 , // Kien Giang
68 , // Hau Giang
80 , // Soc Trang
66 , // Bac Lieu
88 // Ca Mau
} ;
int trace[ N] [ MaxM] [ MASK( Log) ] ;
int f[ N] [ MaxM] [ MASK( Log) ] ;
int sumGRDP = 0 ;
void prepare( ) {
for ( int i= 0 ; i< N; i++ ) {
for ( int j= 0 ; j< MASK( Log) ; j++ ) {
for ( int m= 0 ; m< MaxM; m++ ) {
f[ i] [ m] [ j] = INF; // Đặt tất cả giá trị về dương vô cùng vì hàm mục tiêu là MIN
trace[ i] [ m] [ j] = 0 ;
}
}
}
f[ 0 ] [ 0 ] [ 0 ] = 0 ;
}
bool IsAppear( int u,vector< int > & ds) {
// Kiểm tra đỉnh thứ u có nằm trong cụm tỉnh [ds] không
for ( int x : ds) {
if ( x == u) return true ;
}
return false ;
}
bool Check( vector< int > ds) {
//Kiểm tra khả năng sáp nhập của cụm tỉnh [ds]
// Cao Bang không sáp nhập với tỉnh nào khác
if ( IsAppear( 4 ,ds) ) return ds.size ( ) == 1 ;
// Hà Nội sáp nhập với nhiều nhất 1 tỉnh
if ( IsAppear( 14 ,ds) ) return ds.size ( ) <= 2 ;
// Các cặp tỉnh không thể sáp nhập vì vấn đề về giao thông
// if (IsAppear(33,ds) && IsAppear(34,ds)) return false;
// if (IsAppear(22,ds) && IsAppear(23,ds)) return false;
// if (IsAppear(18,ds) && IsAppear(11,ds)) return false;
// if (IsAppear(35,ds) && IsAppear(38,ds)) return false;
// if (IsAppear(37,ds) && IsAppear(39,ds)) return false;
// Xét các điều kiện về diện tích và dân số
int Sum_Area = 0 ;
long long Sum_Population = 0 ;
for ( int x : ds) {
Sum_Area + = Area[ x] ;
Sum_Population + = Population[ x] ;
}
return Sum_Area >= Min_Area && Sum_Population >= Min_Population && Sum_Area <= Max_Area;
}
int SumGRDP( vector< int > & ds) {
int sum = 0 ;
for ( int x : ds) {
sum + = GRDP[ x] ;
}
return sum;
}
void Push( int pos,int m,int OldMask,vector< int > ds) {
// Cập nhật giá trị tối ưu và lưu vết cho trạng thái mới khi sáp nhập cụm tỉnh [ds]
if ( ! Check( ds) ) return ;
for ( int x : ds) if ( BIT( OldMask,x - pos) ) return ;
int NewMask = OldMask;
for ( int x : ds) NewMask | = MASK( x - pos) ;
if ( minimize( f[ pos] [ m+ 1 ] [ NewMask] ,f[ pos] [ m] [ OldMask] + SQR( SumGRDP( ds) ) ) ) {
trace[ pos] [ m+ 1 ] [ NewMask] = 0 ;
for ( int x : ds) trace[ pos] [ m+ 1 ] [ NewMask] | = MASK( x- pos) ;
}
}
void Update_To_Next_Province( int pos) {
//Cập nhật cửa sổ để xét tỉnh tiếp theo
for ( int m= 0 ; m< MaxM; m++ ) {
for ( int mask= 0 ; mask< MASK( Log) ; mask++ ) {
if ( BIT( mask,0 ) && f[ pos] [ m] [ mask] < INF) minimize( f[ pos+ 1 ] [ m] [ mask>> 1 ] ,f[ pos] [ m] [ mask] ) ;
}
}
}
void sol( ) {
// Quy hoạch động bitmask, duyệt theo ý tưởng đã nêu
for ( int x= 0 ; x< N; x++ ) {
for ( int m= 0 ; m< MaxM; m++ ) {
for ( int mask= 0 ; mask< MASK( Log) ; mask++ ) {
if ( BIT( mask,0 ) || f[ x] [ m] [ mask] >= INF) continue ;
Push( x,m,mask,{ x} ) ; // tỉnh x không sáp nhập
for ( int y: Edge[ x] ) {
if ( y <= x) continue ;
Push( x,m,mask,{ x,y} ) ; // tỉnh x sáp nhập với 1 tỉnh
// Tỉnh x sáp nhập với 2 tỉnh
for ( int z: Edge[ y] ) {
if ( z <= x) continue ;
Push( x,m,mask,{ x,y,z} ) ;
}
for ( int z: Edge[ x] ) {
if ( z <= x || z == y) continue ;
Push( x,m,mask,{ x,y,z} ) ;
}
}
}
}
if ( x == N - 1 ) continue ;
// Cập nhật cửa sổ tiếp theo
Update_To_Next_Province( x) ;
}
// Đặt S = sumGRDP^2
for ( int i= 0 ; i< N; i++ ) sumGRDP + = GRDP[ i] ;
int S = SQR( sumGRDP) ;
int M = 0 ; // Lượng tỉnh sao cho phương án tối ưu nhất
for ( int i= 0 ; i< MaxM; i++ ) {
if ( f[ N- 1 ] [ i] [ 1 ] >= INF) continue ; // Nếu trường hợp số tỉnh là i không có phương án thì bỏ qua
if ( M == 0 ) M = i; // Tạo cho M giá trị ban đầu
// Lấy sổ lượng tối ưu cho hàm mục tiêu giữa M và i
if ( 1LL* ( i* f[ N- 1 ] [ i] [ 1 ] - S) * SQR( M) < 1LL* ( M* f[ N- 1 ] [ M] [ 1 ] - S) * SQR( i) ) {
M = i;
}
}
// Truy vết
int pos = N- 1 ;
int mask = 1 ;
while ( M ! = 0 ) {
if ( trace[ pos] [ M] [ mask] == 0 ) {
pos-- ;
mask = mask << 1 | 1 ;
}
else {
int tmpp = trace[ pos] [ M] [ mask] ;
for ( int i= 0 ; i< Log; i++ ) {
if ( BIT( tmpp,i) ) {
cout << Province[ i+ pos] << ' ' ;
mask ^ = MASK( i) ;
}
}
M-- ;
cout << '\n ' ;
}
}
}
int main( ) {
// freopen("YeuCau_6_MoTa.out","w",stdout);
prepare( ) ;
sol( ) ;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojZGVmaW5lIE1BU0soaSkgKDFMTDw8KGkpKQojZGVmaW5lIEJJVChuLGkpICgobj4+aSkmMSkKI2RlZmluZSBTUVIobikgKDFMTCpuKm4pCgpjb25zdCBpbnQgSU5GID0gMWU5Kzc7Cgp0ZW1wbGF0ZTxjbGFzcyBfLCBjbGFzcyBfXz4KICAgIGJvb2wgbWluaW1pemUoXyAmeCwgY29uc3QgX18geSl7CiAgICAgICAgaWYoeCA+IHkpewogICAgICAgICAgICB4ID0geTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHJldHVybiBmYWxzZTsKICAgIH0KdGVtcGxhdGU8Y2xhc3MgXywgY2xhc3MgX18+CiAgICBib29sIG1heGltaXplKF8gJngsIGNvbnN0IF9fIHkpewogICAgICAgIGlmKHggPCB5KXsKICAgICAgICAgICAgeCA9IHk7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0gZWxzZSByZXR1cm4gZmFsc2U7CiAgICB9Cgpjb25zdCBpbnQgTiA9IDYzOyAvLyBT4buRIHThu4luaCBuxrDhu5tjIFZp4buHdCBOYW0KY29uc3QgaW50IE1heE0gPSAzNTsgLy8gU+G7kSBsxrDhu6NuZyB04buJbmggdOG7kWkgxJFhIHNhdSBraGkgc8OhcCBuaOG6rXAKY29uc3QgaW50IExvZyA9IDE2OyAvLyBT4buRIGzGsOG7o25nIHThu4luaCBj4bqnbiBxdeG6o24gbMOtIHRyb25nIG3hu5l0IHRy4bqhbmcgdGjDoWkKY29uc3QgbG9uZyBsb25nIE1pbl9Qb3B1bGF0aW9uID0gMTIwMDAwMDsKY29uc3QgaW50IE1pbl9BcmVhID0gNjUwMDsKY29uc3QgaW50IE1heF9BcmVhID0gMjUwMDA7CgpzdHJpbmcgUHJvdmluY2VbTl0gPSB7IkxhbmcgU29uIiwgIlF1YW5nIE5pbmgiLCAiSGFpIER1b25nIiwgIkhhaSBQaG9uZyIsICJDYW8gQmFuZyIsCiAgICAgICAgICAgICAgICAiQmFjIEthbiIsICJUaGFpIE5ndXllbiIsICJCYWMgR2lhbmciLCAiQmFjIE5pbmgiLCAiSHVuZyBZZW4iLAogICAgICAgICAgICAgICAgIlRoYWkgQmluaCIsICJIYSBHaWFuZyIsICJUdXllbiBRdWFuZyIsICJWaW5oIFBodWMiLCAiSGEgTm9pIiwKICAgICAgICAgICAgICAgICJIYSBOYW0iLCAiTmFtIERpbmgiLCAiTGFvIENhaSIsICJZZW4gQmFpIiwgIlBodSBUaG8iLAogICAgICAgICAgICAgICAgIkhvYSBCaW5oIiwgIk5pbmggQmluaCIsICJMYWkgQ2hhdSIsICJEaWVuIEJpZW4iLCAiU29uIExhIiwKICAgICAgICAgICAgICAgICJUaGFuaCBIb2EiLCJOZ2hlIEFuIiwgIkhhIFRpbmgiLCAiUXVhbmcgQmluaCIsICJRdWFuZyBUcmkiLAogICAgICAgICAgICAgICAgIkh1ZSIsICJEYSBOYW5nIiwgIlF1YW5nIE5hbSIsICJLb20gVHVtIiwgIlF1YW5nIE5nYWkiLAogICAgICAgICAgICAgICAgIkdpYSBMYWkiLCAiQmluaCBEaW5oIiwgIkRhayBMYWsiLCAiUGh1IFllbiIsICJLaGFuaCBIb2EiLAogICAgICAgICAgICAgICAgIk5pbmggVGh1YW4iLCAiTGFtIERvbmciLCAiRGFrIE5vbmciLCAiQmluaCBQaHVvYyIsICJCaW5oIFRodWFuIiwKICAgICAgICAgICAgICAgICJEb25nIE5haSIsICJCaW5oIER1b25nIiwgIlRheSBOaW5oIiwgIlNhaSBHb24iLCAiQlJWVCIsCiAgICAgICAgICAgICAgICAiTG9uZyBBbiIsICJUaWVuIEdpYW5nIiwgIkRvbmcgVGhhcCIsICJCZW4gVHJlIiwgIlRyYSBWaW5oIiwKICAgICAgICAgICAgICAgICJWaW5oIExvbmciLCAiQ2FuIFRobyIsICJBbiBHaWFuZyIsICJLaWVuIEdpYW5nIiwgIkhhdSBHaWFuZyIsCiAgICAgICAgICAgICAgICAiU29jIFRyYW5nIiwgIkJhYyBMaWV1IiwgIkNhIE1hdSJ9OwoKaW50IFJlYWxfSURbTl0gPSB7CiAgICAzNSwgNDcsIDI1LCAyNiwgMTMsIDMsIDUzLCAyLCA1LCAyOSwgNTIsIDIxLCA1OSwgNjEsIDIzLCAyMiwgMzgsIDM2LCA2MiwgNDIsCiAgICAyOCwgNDAsIDMzLCAxNywgNTAsIDU0LCAzOSwgMjQsIDQ0LCA0OCwgNTUsIDE0LCA0NSwgMzIsIDQ2LCAyMCwgMTAsIDE1LCA0MywgMzAsCiAgICA0MSwgMzQsIDE2LCA4LCA5LCAxOCwgNywgNTEsIDU3LCAxLCAzNywgNTYsIDE5LCA2LCA1OCwgNjAsIDEyLCAwLCAzMSwgMjcsCiAgICA0OSwgNCwgMTEKfTsKCnZlY3RvcjxpbnQ+IEVkZ2VbTl0gPSB7CiAgICB7MSwgNywgNiwgNSwgNH0sICAgICAgICAgICAgIC8vIDAgLSBMYW5nIFNvbgogICAgezMsIDIsIDcsIDB9LCAgICAgICAgICAgICAgICAvLyAxIC0gUXVhbmcgTmluaAogICAgezEsIDMsIDcsIDgsIDksIDEwfSwgICAgICAgICAgICAgLy8gMiAtIEhhaSBEdW9uZwogICAgezEsIDIsIDEwfSwgICAgICAgICAgICAgLy8gMyAtIEhhaSBQaG9uZwogICAgezAsIDUsIDEyLCAxMX0sICAgICAgICAgICAgICAgICAgIC8vIDQgLSBDYW8gQmFuZwogICAgezAsIDYsIDEyLDR9LCAgICAgIC8vIDUgLSBCYWMgS2FuCiAgICB7MCw3LDE0LDEzLDEyLDV9LCAvLyA2IC0gVGhhaSBOZ3V5ZW4KICAgIHswLDEsMiw4LDE0LDZ9LCAgICAgICAgICAgIC8vIDcgLSBCYWMgR2lhbmcKICAgIHs3LDIsOSwxNH0sICAgICAgIC8vIDggLSBCYWMgTmluaAogICAgezgsMiwxMCwxNSwxNH0sICAgIC8vIDkgLSBIdW5nIFllbgogICAgezMsMiw5LDE1LDE2fSwgICAgLy8gMTAgLSBUaGFpIEJpbmgKICAgIHs0LDEyLDE3fSwgICAgICAgICAgLy8gMTEgLSBIYSBHaWFuZwogICAgezQsNSw2LDEzLDE5LDE4LDExfSwgICAgLy8gMTIgLSBUdXllbiBRdWFuZwogICAgezYsMTQsMTksMTJ9LCAgLy8gMTMgLSBWaW5oIFBodWMKICAgIHs2LDcsOCw5LDE1LDIwLDE5LDEzfSwgICAgICAgICAgLy8gMTQgLSBIYSBOb2kKICAgIHs5LDEwLDE2LDIxLDIwLDE0fSwgIC8vIDE1IC0gSGEgTmFtCiAgICB7MTAsMTUsMjF9LCAvLyAxNiAtIE5hbSBEaW5oCiAgICB7MTEsMTgsMjJ9LCAgICAgICAgIC8vIDE3IC0gTGFvIENhaQogICAgezEyLDE5LDI0LDIyfSwgICAgIC8vIDE4IC0gWWVuIEJhaQogICAgezEyLDEzLDE0LDIwLDI0LDE4fSwgLy8gMTkgLSBQaHUgVGhvCiAgICB7MTQsMTUsMjEsMjUsMjQsMTl9LCAgICAgICAgIC8vIDIwIC0gSG9hIEJpbmgKICAgIHsxNSwxNiwyMCwyNX0sICAgICAgICAgICAgIC8vIDIxIC0gTmluaCBCaW5oCiAgICB7MTcsMTgsMjR9LCAgICAgLy8gMjIgLSBMYWkgQ2hhdQogICAgezI0fSwgICAgICAgICAgICAgLy8gMjMgLSBEaWVuIEJpZW4KICAgIHsyMywyMiwxOCwxOSwyMCwyNX0sIC8vIDI0IC0gU29uIExhCiAgICB7MjEsMjAsMjQsMjZ9LCAgICAgICAgICAvLyAyNSAtIFRoYW5oIEhvYQogICAgezI1LDI3fSwgICAgICAgICAgICAgICAgICAgIC8vIDI2IC0gTmdoZSBBbgogICAgezI2LCAyOH0sICAgICAgICAgICAgICAgIC8vIDI3IC0gSGEgVGluaAogICAgezI3LCAyOX0sICAgICAgICAgICAgICAgIC8vIDI4IC0gUXVhbmcgQmluaAogICAgezI4LCAzMH0sICAgICAgICAgICAgICAgIC8vIDI5IC0gUXVhbmcgVHJpCiAgICB7MjksIDMxLCAzMn0sICAgICAgICAgICAgLy8gMzAgLSBIdWUKICAgIHszMCwgMzJ9LCAgICAgICAgICAgICAgICAvLyAzMSAtIERhIE5hbmcKICAgIHszMCwgMzEsIDMzLCAzNH0sICAgICAgICAgICAgLy8gMzIgLSBRdWFuZyBOYW0KICAgIHszMiwgMzV9LCAgICAgICAgICAgIC8vIDMzIC0gS29tIFR1bQogICAgezMyLCAzNn0sICAgICAgICAvLyAzNCAtIFF1YW5nIE5nYWkKICAgIHszMywgMzYsIDM3fSwgICAgLy8gMzUgLSBHaWEgTGFpCiAgICB7MzQsIDM1LCAzOH0sICAgICAgICAgICAgLy8gMzYgLSBCaW5oIERpbmgKICAgIHszNSwgMzgsIDQxLCA0Mn0sICAgIC8vIDM3IC0gRGFrIExhawogICAgezM2LCAzNywgMzl9LCAgICAgICAgLy8gMzggLSBQaHUgWWVuCiAgICB7MzgsIDQwLCA0MX0sICAgICAgICAvLyAzOSAtIEtoYW5oIEhvYQogICAgezM5LCA0MSwgNDR9LCAgICAgICAgICAgIC8vIDQwIC0gTmluaCBUaHVhbgogICAgezM3LCAzOSwgNDAsIDQyLCA0NCwgNDMsIDQ1fSwgICAgLy8gNDEgLSBMYW0gRG9uZwogICAgezM3LCA0MSwgNDN9LCAgICAgICAgICAgIC8vIDQyIC0gRGFrIE5vbmcKICAgIHs0MSwgNDIsIDQ1LCA0NiwgNDd9LCAgICAvLyA0MyAtIEJpbmggUGh1b2MKICAgIHs0MCwgNDEsIDQ1LCA0OX0sICAgIC8vIDQ0IC0gQmluaCBUaHVhbgogICAgezQ0LDQxLDQzLDQ5LDQ4LDQ2fSwgICAgICAgIC8vIDQ1IC0gRG9uZyBOYWkKICAgIHs0Myw0Nyw0OCw0NX0sIC8vIDQ2IC0gQmluaCBEdW9uZwogICAgezQzLCA0NiwgNDgsIDUwfSwgICAgICAgIC8vIDQ3IC0gVGF5IE5pbmgKICAgIHs0Nyw0Niw0NSw0OSw1MH0sICAgICAgICAvLyA0OCAtIFNhaSBHb24KICAgIHs0NCwgNDUsIDQ4fSwgICAgLy8gNDkgLSBCUlZUCiAgICB7NDcsIDQ4LCA1MSwgNTJ9LCAgICAgICAgICAgIC8vIDUwIC0gTG9uZyBBbgogICAgezUzLCA1NSwgNTIsIDUwfSwgICAgICAgIC8vIDUxIC0gVGllbiBHaWFuZwogICAgezUwLCA1MSwgNTUsIDU2LCA1N30sICAgICAgICAvLyA1MiAtIERvbmcgVGhhcAogICAgezUxLCA1NCwgNTV9LCAgICAvLyA1MyAtIEJlbiBUcmUKICAgIHs1MywgNTUsIDYwfSwgICAgICAgICAgICAvLyA1NCAtIFRyYSBWaW5oCiAgICB7NTMsIDUxLCA1MiwgNTQsIDU2LCA1OSwgNjB9LCAgICAgICAgICAgIC8vIDU1IC0gVmluaCBMb25nCiAgICB7NTIsIDU1LCA1NywgNTgsIDU5fSwgLy8gNTYgLSBDYW4gVGhvCiAgICB7NTIsIDU2LCA1OH0sICAgIC8vIDU3IC0gQW4gR2lhbmcKICAgIHs1NiwgNTcsIDU5LCA2MSwgNjJ9LCAgICAgICAgICAgIC8vIDU4IC0gS2llbiBHaWFuZwogICAgezU1LCA1NiwgNjAsIDYxLCA1OH0sICAgIC8vIDU5IC0gSGF1IEdpYW5nCiAgICB7NTQsIDU1LCA1OSwgNjF9LCAgICAvLyA2MCAtIFNvYyBUcmFuZwogICAgezYwLCA1OSwgNTgsIDYyfSwgICAgICAgIC8vIDYxIC0gQmFjIExpZXUKICAgIHs1OCwgNjF9ICAgICAgICAgICAgICAgICAvLyA2MiAtIENhIE1hdQp9OwovKgogICAgICAgIEtow6FjIHbhu5tpIGRhbmggc8OhY2gga+G7gSDEkcOjIGxp4buHdCBrw6og4bufIGPDonUgMzogTeG7mXQgc+G7kSBj4bq3cCDEkeG7iW5oIHPhur0ga2jDtG5nIMSRxrDhu6NjIGNvaQogICAga2jDtG5nIGvhu4EgbmhhdXbDrCDEkcaw4budbmcgZ2nDoXAgcmFuaCBnaeG7r2EgaGFpIHThu4luaCBraMOhIG5o4buPLgogICAgICAgICAgICBRdcOjbmcgTmfDo2kgLSBHaWEgTGFpCiAgICAgICAgICAgIFRQIEhDTSAtIFRp4buBbiBHaWFuZwogICAgICAgIMSQxrDhu51uZyDEkWkgaGnhu4NtIHRy4bufCiAgICAgICAgICAgIC8vICAgIGlmIChJc0FwcGVhcigzMyxkcykgJiYgSXNBcHBlYXIoMzQsZHMpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIC8vICAgIGlmIChJc0FwcGVhcigyMixkcykgJiYgSXNBcHBlYXIoMjMsZHMpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIC8vICAgIGlmIChJc0FwcGVhcigxOCxkcykgJiYgSXNBcHBlYXIoMTEsZHMpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIC8vICAgIGlmIChJc0FwcGVhcigzNSxkcykgJiYgSXNBcHBlYXIoMzgsZHMpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIC8vICAgIGlmIChJc0FwcGVhcigzNyxkcykgJiYgSXNBcHBlYXIoMzksZHMpKSByZXR1cm4gZmFsc2U7CiovCgppbnQgQXJlYVtOXSA9IHsKICAgIDgzMTAsICAgLy8gTGFuZyBTb24KICAgIDYyMDgsICAgLy8gUXVhbmcgTmluaAogICAgMTY2OCwgICAvLyBIYWkgRHVvbmcKICAgIDE1MjcsICAgLy8gSGFpIFBob25nCiAgICA2NzAwLCAgIC8vIENhbyBCYW5nCiAgICA0ODYwLCAgIC8vIEJhYyBLYW4KICAgIDM1MjIsICAgLy8gVGhhaSBOZ3V5ZW4KICAgIDM4OTYsICAgLy8gQmFjIEdpYW5nCiAgICA4MjMsICAgIC8vIEJhYyBOaW5oCiAgICA5MzAsICAgIC8vIEh1bmcgWWVuCiAgICAxNTg1LCAgIC8vIFRoYWkgQmluaAogICAgNzkyOCwgICAvLyBIYSBHaWFuZwogICAgNTg2OCwgICAvLyBUdXllbiBRdWFuZwogICAgMTIzNiwgICAvLyBWaW5oIFBodWMKICAgIDMzNjAsICAgLy8gSGEgTm9pCiAgICA4NjIsICAgIC8vIEhhIE5hbQogICAgMTY2OSwgICAvLyBOYW0gRGluaAogICAgNjM2NCwgICAvLyBMYW8gQ2FpCiAgICA2ODkzLCAgIC8vIFllbiBCYWkKICAgIDM1MzUsICAgLy8gUGh1IFRobwogICAgNDU5MCwgICAvLyBIb2EgQmluaAogICAgMTQxMiwgICAvLyBOaW5oIEJpbmgKICAgIDkwNjksICAgLy8gTGFpIENoYXUKICAgIDk1NDAsICAgLy8gRGllbiBCaWVuCiAgICAxNDExMCwgIC8vIFNvbiBMYQogICAgMTExMTUsICAvLyBUaGFuaCBIb2EKICAgIDE2NDg2LCAgLy8gTmdoZSBBbgogICAgNTk5NCwgICAvLyBIYSBUaW5oCiAgICA3OTk5LCAgIC8vIFF1YW5nIEJpbmgKICAgIDQ3MDEsICAgLy8gUXVhbmcgVHJpCiAgICA0OTQ3LCAgIC8vIEh1ZQogICAgMTI4NSwgICAvLyBEYSBOYW5nCiAgICAxMDU3NSwgIC8vIFF1YW5nIE5hbQogICAgOTY3NywgICAvLyBLb20gVHVtCiAgICA1MTU1LCAgIC8vIFF1YW5nIE5nYWkKICAgIDE1NTEwLCAgLy8gR2lhIExhaQogICAgNjA2NiwgICAvLyBCaW5oIERpbmgKICAgIDEzMDcwLCAgLy8gRGFrIExhawogICAgNTAyNiwgICAvLyBQaHUgWWVuCiAgICA1MjAwLCAgIC8vIEtoYW5oIEhvYQogICAgMzM1NiwgICAvLyBOaW5oIFRodWFuCiAgICA5NzgxLCAgIC8vIExhbSBEb25nCiAgICA2NTA5LCAgIC8vIERhayBOb25nCiAgICA2ODc0LCAgIC8vIEJpbmggUGh1b2MKICAgIDc5NDMsICAgLy8gQmluaCBUaHVhbgogICAgNTg2NCwgICAvLyBEb25nIE5haQogICAgMjY5NSwgICAvLyBCaW5oIER1b25nCiAgICA0MDQyLCAgIC8vIFRheSBOaW5oCiAgICAyMDk1LCAgIC8vIFNhaSBHb24KICAgIDE5ODMsICAgLy8gQlJWVAogICAgNDQ5NSwgICAvLyBMb25nIEFuCiAgICAyNTU2LCAgIC8vIFRpZW4gR2lhbmcKICAgIDMzODIsICAgLy8gRG9uZyBUaGFwCiAgICAyMzgwLCAgIC8vIEJlbiBUcmUKICAgIDIzOTEsICAgLy8gVHJhIFZpbmgKICAgIDE1MjYsICAgLy8gVmluaCBMb25nCiAgICAxNDQwLCAgIC8vIENhbiBUaG8KICAgIDM1MzcsICAgLy8gQW4gR2lhbmcKICAgIDYzNTMsICAgLy8gS2llbiBHaWFuZwogICAgMTYyMiwgICAvLyBIYXUgR2lhbmcKICAgIDMyOTgsICAgLy8gU29jIFRyYW5nCiAgICAyNjY4LCAgIC8vIEJhYyBMaWV1CiAgICA1Mjc1ICAgIC8vIENhIE1hdQp9OwoKaW50IFBvcHVsYXRpb25bTl0gPSB7CiAgICA4MTM5NzgsICAgICAvLyBMYW5nIFNvbgogICAgMTM5MzcwMiwgICAgLy8gUXVhbmcgTmluaAogICAgMTk3MTMyNiwgICAgLy8gSGFpIER1b25nCiAgICAyMTIxODQxLCAgICAvLyBIYWkgUGhvbmcKICAgIDU1NTgwOSwgICAgIC8vIENhbyBCYW5nCiAgICAzMjg2MDksICAgICAvLyBCYWMgS2FuCiAgICAxMzYxNDc0LCAgICAvLyBUaGFpIE5ndXllbgogICAgMTk1MDYxNSwgICAgLy8gQmFjIEdpYW5nCiAgICAxNTQzNTI5LCAgICAvLyBCYWMgTmluaAogICAgMTMxMzc5OCwgICAgLy8gSHVuZyBZZW4KICAgIDE4ODgxODQsICAgIC8vIFRoYWkgQmluaAogICAgOTA4MjYzLCAgICAgLy8gSGEgR2lhbmcKICAgIDgyMDA1NCwgICAgIC8vIFR1eWVuIFF1YW5nCiAgICAxMjIxODAzLCAgICAvLyBWaW5oIFBodWMKICAgIDg2ODU2MDcsICAgIC8vIEhhIE5vaQogICAgODkyNzU1LCAgICAgLy8gSGEgTmFtCiAgICAxODkyNDI3LCAgICAvLyBOYW0gRGluaAogICAgNzg3MDY2LCAgICAgLy8gTGFvIENhaQogICAgODYzMzM4LCAgICAgLy8gWWVuIEJhaQogICAgMTU0MDYwOCwgICAgLy8gUGh1IFRobwogICAgODkyMzczLCAgICAgLy8gSG9hIEJpbmgKICAgIDEwMjcwMzAsICAgIC8vIE5pbmggQmluaAogICAgNDk0NjI2LCAgICAgLy8gTGFpIENoYXUKICAgIDY1MzQyMiwgICAgIC8vIERpZW4gQmllbgogICAgMTMyNzQzMCwgICAgLy8gU29uIExhCiAgICAzNzYwNjUwLCAgICAvLyBUaGFuaCBIb2EKICAgIDM0NzA5ODgsICAgIC8vIE5naGUgQW4KICAgIDEzMjkzNjUsICAgIC8vIEhhIFRpbmgKICAgIDkyNDE2OSwgICAgIC8vIFF1YW5nIEJpbmgKICAgIDY1ODYxOSwgICAgIC8vIFF1YW5nIFRyaQogICAgMTE3NzYyNCwgICAgLy8gSHVlCiAgICAxMjY5MDcwLCAgICAvLyBEYSBOYW5nCiAgICAxNTM5NDY4LCAgICAvLyBRdWFuZyBOYW0KICAgIDU5ODIwMSwgICAgIC8vIEtvbSBUdW0KICAgIDEyNTY5NTIsICAgIC8vIFF1YW5nIE5nYWkKICAgIDE2MzAzMTEsICAgIC8vIEdpYSBMYWkKICAgIDE1MTU0MjIsICAgIC8vIEJpbmggRGluaAogICAgMTk0NDgyMSwgICAgLy8gRGFrIExhawogICAgODgzMjk4LCAgICAgLy8gUGh1IFllbgogICAgMTI2NzQ0MywgICAgLy8gS2hhbmggSG9hCiAgICA2MDk4MjAsICAgICAvLyBOaW5oIFRodWFuCiAgICAxMzYxMTI5LCAgICAvLyBMYW0gRG9uZwogICAgNjkyODk2LCAgICAgLy8gRGFrIE5vbmcKICAgIDEwNjA0NDgsICAgIC8vIEJpbmggUGh1b2MKICAgIDEyNjYyNDAsICAgIC8vIEJpbmggVGh1YW4KICAgIDMzNDE3MTYsICAgIC8vIERvbmcgTmFpCiAgICAyODU4ODE1LCAgICAvLyBCaW5oIER1b25nCiAgICAxMjAxNzM2LCAgICAvLyBUYXkgTmluaAogICAgOTUyMTg4NiwgICAgLy8gU2FpIEdvbiAoVFAuIEhDTSkKICAgIDExOTI4NjMsICAgIC8vIEJSVlQKICAgIDE3NTMwNDEsICAgIC8vIExvbmcgQW4KICAgIDE3OTUyNTEsICAgIC8vIFRpZW4gR2lhbmcKICAgIDE2MDA5NjMsICAgIC8vIERvbmcgVGhhcAogICAgMTMwNTI4MSwgICAgLy8gQmVuIFRyZQogICAgMTAyMjg4NywgICAgLy8gVHJhIFZpbmgKICAgIDEwMzUzNjIsICAgIC8vIFZpbmggTG9uZwogICAgMTI2ODUxNCwgICAgLy8gQ2FuIFRobwogICAgMTkxMTAwMiwgICAgLy8gQW4gR2lhbmcKICAgIDE3NjM4MjYsICAgIC8vIEtpZW4gR2lhbmcKICAgIDcyODkyNCwgICAgIC8vIEhhdSBHaWFuZwogICAgMTIwMzcwNSwgICAgLy8gU29jIFRyYW5nCiAgICA5Mjk0MzksICAgICAvLyBCYWMgTGlldQogICAgMTIxMDg0MyAgICAgLy8gQ2EgTWF1Cn07CgppbnQgR1JEUFtOXSA9IHsKICAgIDUwLCAgLy8gTGFuZyBTb24KICAgIDM0OCwgLy8gUXVhbmcgTmluaAogICAgMjEyLCAvLyBIYWkgRHVvbmcKICAgIDQ0NiwgLy8gSGFpIFBob25nCiAgICAyNSwgIC8vIENhbyBCYW5nCiAgICAxOSwgIC8vIEJhYyBLYW4KICAgIDE2NywgLy8gVGhhaSBOZ3V5ZW4KICAgIDIwNywgLy8gQmFjIEdpYW5nCiAgICAyMzIsIC8vIEJhYyBOaW5oCiAgICAxNjAsIC8vIEh1bmcgWWVuCiAgICA3MSwgIC8vIFRoYWkgQmluaAogICAgMzYsICAvLyBIYSBHaWFuZwogICAgNTAsICAvLyBUdXllbiBRdWFuZwogICAgMTczLCAvLyBWaW5oIFBodWMKICAgIDE0MzAsIC8vIEhhIE5vaQogICAgNTYsICAvLyBIYSBOYW0KICAgIDExMywgLy8gTmFtIERpbmgKICAgIDc3LCAgLy8gTGFvIENhaQogICAgNDksICAvLyBZZW4gQmFpCiAgICAxMDcsIC8vIFBodSBUaG8KICAgIDcyLCAgLy8gSG9hIEJpbmgKICAgIDk5LCAgLy8gTmluaCBCaW5oCiAgICAzMSwgIC8vIExhaSBDaGF1CiAgICAzMiwgIC8vIERpZW4gQmllbgogICAgNzcsICAvLyBTb24gTGEKICAgIDMxOSwgLy8gVGhhbmggSG9hCiAgICAyMTcsIC8vIE5naGUgQW4KICAgIDExMywgLy8gSGEgVGluaAogICAgNjAsICAvLyBRdWFuZyBCaW5oCiAgICA1NCwgIC8vIFF1YW5nIFRyaQogICAgODAsICAvLyBIdWUKICAgIDE1MSwgLy8gRGEgTmFuZwogICAgMTI5LCAvLyBRdWFuZyBOYW0KICAgIDQxLCAgLy8gS29tIFR1bQogICAgMTMzLCAvLyBRdWFuZyBOZ2FpCiAgICAxMTEsIC8vIEdpYSBMYWkKICAgIDEzMSwgLy8gQmluaCBEaW5oCiAgICAxNDEsIC8vIERhayBMYWsKICAgIDYzLCAgLy8gUGh1IFllbgogICAgMTI5LCAvLyBLaGFuaCBIb2EKICAgIDYwLCAgLy8gTmluaCBUaHVhbgogICAgMTMsICAvLyBMYW0gRG9uZwogICAgNTYsICAvLyBEYWsgTm9uZwogICAgMTE1LCAvLyBCaW5oIFBodW9jCiAgICAxMjEsIC8vIEJpbmggVGh1YW4KICAgIDQ5NCwgLy8gRG9uZyBOYWkKICAgIDUyMCwgLy8gQmluaCBEdW9uZwogICAgMTI0LCAvLyBUYXkgTmluaAogICAgMTc3OCwgLy8gU2FpIEdvbiAoVFAuIEhvIENoaSBNaW5oKQogICAgNDE3LCAvLyBCUlZUCiAgICAxODksIC8vIExvbmcgQW4KICAgIDEzNywgLy8gVGllbiBHaWFuZwogICAgMTI0LCAvLyBEb25nIFRoYXAKICAgIDc0LCAgLy8gQmVuIFRyZQogICAgOTcsICAvLyBUcmEgVmluaAogICAgODQsICAvLyBWaW5oIExvbmcKICAgIDEzMywgLy8gQ2FuIFRobwogICAgMTI3LCAvLyBBbiBHaWFuZwogICAgMTQ0LCAvLyBLaWVuIEdpYW5nCiAgICA2OCwgIC8vIEhhdSBHaWFuZwogICAgODAsICAvLyBTb2MgVHJhbmcKICAgIDY2LCAgLy8gQmFjIExpZXUKICAgIDg4ICAgLy8gQ2EgTWF1Cn07CgppbnQgdHJhY2VbTl1bTWF4TV1bTUFTSyhMb2cpXTsKCmludCBmW05dW01heE1dW01BU0soTG9nKV07CgppbnQgc3VtR1JEUCA9IDA7Cgp2b2lkIHByZXBhcmUoKSB7CiAgICBmb3IgKGludCBpPTA7aTxOO2krKykgewogICAgICAgIGZvciAoaW50IGo9MDtqPE1BU0soTG9nKTtqKyspIHsKICAgICAgICAgICAgZm9yIChpbnQgbT0wO208TWF4TTttKyspIHsKICAgICAgICAgICAgICAgIGZbaV1bbV1bal0gPSBJTkY7IC8vIMSQ4bq3dCB04bqldCBj4bqjIGdpw6EgdHLhu4sgduG7gSBkxrDGoW5nIHbDtCBjw7luZyB2w6wgaMOgbSBt4bulYyB0acOqdSBsw6AgTUlOCiAgICAgICAgICAgICAgICB0cmFjZVtpXVttXVtqXSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBmWzBdWzBdWzBdID0gMDsKfQoKYm9vbCBJc0FwcGVhcihpbnQgdSx2ZWN0b3I8aW50PiAmIGRzKSAgewogICAgLy8gS2nhu4NtIHRyYSDEkeG7iW5oIHRo4bupIHUgY8OzIG7hurFtIHRyb25nIGPhu6VtIHThu4luaCBbZHNdIGtow7RuZwogICAgZm9yIChpbnQgeCA6IGRzKSB7CiAgICAgICAgaWYgKHggPT0gdSkgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0KCmJvb2wgQ2hlY2sodmVjdG9yPGludD4gZHMpIHsKLy9LaeG7g20gdHJhIGto4bqjIG7Eg25nIHPDoXAgbmjhuq1wIGPhu6dhIGPhu6VtIHThu4luaCBbZHNdCgogICAgLy8gQ2FvIEJhbmcga2jDtG5nIHPDoXAgbmjhuq1wIHbhu5tpIHThu4luaCBuw6BvIGtow6FjCiAgICBpZiAoSXNBcHBlYXIoNCxkcykpIHJldHVybiBkcy5zaXplKCkgPT0gMTsKCiAgICAvLyBIw6AgTuG7mWkgc8OhcCBuaOG6rXAgduG7m2kgbmhp4buBdSBuaOG6pXQgMSB04buJbmgKICAgIGlmIChJc0FwcGVhcigxNCxkcykpIHJldHVybiBkcy5zaXplKCkgPD0gMjsKCiAgICAvLyBDw6FjIGPhurdwIHThu4luaCBraMO0bmcgdGjhu4Mgc8OhcCBuaOG6rXAgdsOsIHbhuqVuIMSR4buBIHbhu4EgZ2lhbyB0aMO0bmcKLy8gICAgaWYgKElzQXBwZWFyKDMzLGRzKSAmJiBJc0FwcGVhcigzNCxkcykpIHJldHVybiBmYWxzZTsKLy8gICAgaWYgKElzQXBwZWFyKDIyLGRzKSAmJiBJc0FwcGVhcigyMyxkcykpIHJldHVybiBmYWxzZTsKLy8gICAgaWYgKElzQXBwZWFyKDE4LGRzKSAmJiBJc0FwcGVhcigxMSxkcykpIHJldHVybiBmYWxzZTsKLy8gICAgaWYgKElzQXBwZWFyKDM1LGRzKSAmJiBJc0FwcGVhcigzOCxkcykpIHJldHVybiBmYWxzZTsKLy8gICAgaWYgKElzQXBwZWFyKDM3LGRzKSAmJiBJc0FwcGVhcigzOSxkcykpIHJldHVybiBmYWxzZTsKCiAgICAvLyBYw6l0IGPDoWMgxJFp4buBdSBraeG7h24gduG7gSBkaeG7h24gdMOtY2ggdsOgIGTDom4gc+G7kQogICAgaW50IFN1bV9BcmVhID0gMDsKICAgIGxvbmcgbG9uZyBTdW1fUG9wdWxhdGlvbiA9IDA7CiAgICBmb3IgKGludCB4IDogZHMpIHsKICAgICAgICBTdW1fQXJlYSArPSBBcmVhW3hdOwogICAgICAgIFN1bV9Qb3B1bGF0aW9uICs9IFBvcHVsYXRpb25beF07CiAgICB9CiAgICByZXR1cm4gU3VtX0FyZWEgPj0gTWluX0FyZWEgJiYgU3VtX1BvcHVsYXRpb24gPj0gTWluX1BvcHVsYXRpb24gJiYgU3VtX0FyZWEgPD0gTWF4X0FyZWE7Cn0KCmludCBTdW1HUkRQKHZlY3RvcjxpbnQ+ICYgZHMpIHsKICAgIGludCBzdW0gPSAwOwogICAgZm9yIChpbnQgeCA6IGRzKSB7CiAgICAgICAgc3VtICs9IEdSRFBbeF07CiAgICB9CiAgICByZXR1cm4gc3VtOwp9Cgp2b2lkIFB1c2goaW50IHBvcyxpbnQgbSxpbnQgT2xkTWFzayx2ZWN0b3I8aW50PiBkcykgewovLyBD4bqtcCBuaOG6rXQgZ2nDoSB0cuG7iyB04buRaSDGsHUgdsOgIGzGsHUgduG6v3QgY2hvIHRy4bqhbmcgdGjDoWkgbeG7m2kga2hpIHPDoXAgbmjhuq1wIGPhu6VtIHThu4luaCBbZHNdCiAgICBpZiAoIUNoZWNrKGRzKSkgcmV0dXJuOwogICAgZm9yIChpbnQgeCA6IGRzKSBpZiAoQklUKE9sZE1hc2sseCAtIHBvcykpIHJldHVybjsKICAgIGludCBOZXdNYXNrID0gT2xkTWFzazsKICAgIGZvciAoaW50IHggOiBkcykgTmV3TWFzayB8PSBNQVNLKHggLSBwb3MpOwogICAgaWYgKG1pbmltaXplKGZbcG9zXVttKzFdW05ld01hc2tdLGZbcG9zXVttXVtPbGRNYXNrXSArIFNRUihTdW1HUkRQKGRzKSkpKSB7CiAgICAgICAgdHJhY2VbcG9zXVttKzFdW05ld01hc2tdID0gMDsKICAgICAgICBmb3IgKGludCB4IDogZHMpIHRyYWNlW3Bvc11bbSsxXVtOZXdNYXNrXSB8PSBNQVNLKHgtcG9zKTsKICAgIH0KfQoKdm9pZCBVcGRhdGVfVG9fTmV4dF9Qcm92aW5jZShpbnQgcG9zKSB7Ci8vQ+G6rXAgbmjhuq10IGPhu61hIHPhu5UgxJHhu4MgeMOpdCB04buJbmggdGnhur9wIHRoZW8KICAgIGZvciAoaW50IG09MDttPE1heE07bSsrKSB7CiAgICAgICAgZm9yIChpbnQgbWFzaz0wO21hc2s8TUFTSyhMb2cpO21hc2srKykgewogICAgICAgICAgICBpZiAoQklUKG1hc2ssMCkgJiYgZltwb3NdW21dW21hc2tdIDwgSU5GKSBtaW5pbWl6ZShmW3BvcysxXVttXVttYXNrPj4xXSxmW3Bvc11bbV1bbWFza10pOwogICAgICAgIH0KICAgIH0KfQoKdm9pZCBzb2woKSB7CiAgICAvLyBRdXkgaG/huqFjaCDEkeG7mW5nIGJpdG1hc2ssIGR1eeG7h3QgdGhlbyDDvSB0xrDhu59uZyDEkcOjIG7DqnUKICAgIGZvciAoaW50IHg9MDt4PE47eCsrKSB7CiAgICAgICAgZm9yIChpbnQgbT0wO208TWF4TTttKyspIHsKICAgICAgICAgICAgZm9yIChpbnQgbWFzaz0wO21hc2s8TUFTSyhMb2cpO21hc2srKykgewogICAgICAgICAgICAgICAgaWYgKEJJVChtYXNrLDApIHx8IGZbeF1bbV1bbWFza10gPj0gSU5GKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIFB1c2goeCxtLG1hc2sse3h9KTsgLy8gdOG7iW5oIHgga2jDtG5nIHPDoXAgbmjhuq1wCiAgICAgICAgICAgICAgICBmb3IgKGludCB5OkVkZ2VbeF0pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoeSA8PSB4KSBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICBQdXNoKHgsbSxtYXNrLHt4LHl9KTsgLy8gdOG7iW5oIHggc8OhcCBuaOG6rXAgduG7m2kgMSB04buJbmgKCiAgICAgICAgICAgICAgICAgICAgLy8gVOG7iW5oIHggc8OhcCBuaOG6rXAgduG7m2kgMiB04buJbmgKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCB6OkVkZ2VbeV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHogPD0geCkgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIFB1c2goeCxtLG1hc2sse3gseSx6fSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHo6RWRnZVt4XSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoeiA8PSB4IHx8IHogPT0geSkgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIFB1c2goeCxtLG1hc2sse3gseSx6fSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICh4ID09IE4gLSAxKSBjb250aW51ZTsKICAgICAgICAvLyBD4bqtcCBuaOG6rXQgY+G7rWEgc+G7lSB0aeG6v3AgdGhlbwogICAgICAgIFVwZGF0ZV9Ub19OZXh0X1Byb3ZpbmNlKHgpOwogICAgfQogICAgLy8gxJDhurd0IFMgPSBzdW1HUkRQXjIKICAgIGZvciAoaW50IGk9MDtpPE47aSsrKSBzdW1HUkRQICs9IEdSRFBbaV07CiAgICBpbnQgUyA9IFNRUihzdW1HUkRQKTsKCiAgICBpbnQgTSA9IDA7IC8vIEzGsOG7o25nIHThu4luaCBzYW8gY2hvIHBoxrDGoW5nIMOhbiB04buRaSDGsHUgbmjhuqV0CiAgICBmb3IgKGludCBpPTA7aTxNYXhNO2krKykgewogICAgICAgIGlmIChmW04tMV1baV1bMV0gPj0gSU5GKSBjb250aW51ZTsgLy8gTuG6v3UgdHLGsOG7nW5nIGjhu6NwIHPhu5EgdOG7iW5oIGzDoCBpIGtow7RuZyBjw7MgcGjGsMahbmcgw6FuIHRow6wgYuG7jyBxdWEKICAgICAgICBpZiAoTSA9PSAwKSBNID0gaTsgLy8gVOG6oW8gY2hvIE0gZ2nDoSB0cuG7iyBiYW4gxJHhuqd1CgogICAgICAgIC8vIEzhuqV5IHPhu5UgbMaw4bujbmcgdOG7kWkgxrB1IGNobyBow6BtIG3hu6VjIHRpw6p1IGdp4buvYSBNIHbDoCBpCiAgICAgICAgaWYgKDFMTCooaSpmW04tMV1baV1bMV0tUykqU1FSKE0pIDwgMUxMKihNKmZbTi0xXVtNXVsxXS1TKSpTUVIoaSkpIHsKICAgICAgICAgICAgTSA9IGk7CiAgICAgICAgfQogICAgfQoKICAgIC8vIFRydXkgduG6v3QKICAgIGludCBwb3MgPSBOLTE7CiAgICBpbnQgbWFzayA9IDE7CiAgICB3aGlsZSAoTSAhPSAwKSB7CiAgICAgICAgaWYgKHRyYWNlW3Bvc11bTV1bbWFza10gPT0gMCkgewogICAgICAgICAgICBwb3MtLTsKICAgICAgICAgICAgbWFzayA9IG1hc2sgPDwgMSB8IDE7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBpbnQgdG1wcCA9IHRyYWNlW3Bvc11bTV1bbWFza107CiAgICAgICAgICAgIGZvciAoaW50IGk9MDtpPExvZztpKyspIHsKICAgICAgICAgICAgICAgIGlmIChCSVQodG1wcCxpKSkgewogICAgICAgICAgICAgICAgICAgIGNvdXQgPDwgUHJvdmluY2VbaStwb3NdIDw8ICcgJzsKICAgICAgICAgICAgICAgICAgICBtYXNrIF49IE1BU0soaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTS0tOwogICAgICAgICAgICBjb3V0IDw8ICdcbic7CiAgICAgICAgfQogICAgfQp9CgppbnQgbWFpbigpIHsKLy8gICAgZnJlb3BlbigiWWV1Q2F1XzZfTW9UYS5vdXQiLCJ3IixzdGRvdXQpOwogICAgcHJlcGFyZSgpOwogICAgc29sKCk7Cn0K