// BEGIN CUT HERE
// END CUT HERE
#line 5 "AquaparkPuzzle.cpp"
#include <iostream>
#include <sstream>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cmath>
#include <cassert>
#define forn(i, n) for (int i = 0; i < int(n); i++)
#define forl(i, n) for (int i = 1; i <= int(n); i++)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define fore(i, l, r) for (int i = int(l); i <= int(r); i++)
#define correct(x, y, n, m) (0 <= (x) && (x) < (n) && 0 <= (y) && (y) < (m))
#define all(a) (a).begin(), (a).end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
#define mp(x, y) make_pair((x), (y))
#define ft first
#define sc second
#define isnan(a) false
#define isinf(a) false
using namespace std;
typedef long long li;
typedef long double ld;
typedef pair< int , int > pt;
template < typename X> inline X abs ( const X& a) { return a < 0 ? - a: a; }
template < typename X> inline X sqr( const X& a) { return a * a; }
const int INF = int ( 1e9 ) ;
const li INF64 = li( 1e18 ) ;
const ld EPS = 1e-9 , PI = 3.1415926535897932384626433832795 ;
class AquaparkPuzzle
{
public :
int countSchedules( int k, int m, vector < int > c) ;
} ;
int gcd( int a, int b, int & x, int & y)
{
if ( a == 0 )
{
x = 0 , y = 1 ;
return b;
}
int xx, yy, g = gcd( b % a, a, xx, yy) ;
x = yy - b / a * xx;
y = xx;
return g;
}
const int mod = 1000 * 1000 * 1000 + 7 ;
int inv( int a)
{
int x, y;
assert ( gcd( a, mod, x, y) == 1 ) ;
x % = mod;
( x < 0 ) && ( x + = mod) ;
return x;
}
const int N = 11 + 3 , K = 1000 * 1000 + 3 , EXPN = ( 1 << 11 ) + 3 , EXPN3 = 180000 ;
int pw[ N] , fact[ K] , ifact[ K] ;
int g[ EXPN] , c[ EXPN] ;
int get( int mask, int i) { return ( mask / pw[ i] ) % 3 ; }
int _set( int mask, int i, int v) { return mask - ( get( mask, i) - v) * pw[ i] ; }
int C( int n, int k)
{
if ( k < 0 || k > n) return 0 ;
int ans = int ( ( fact[ n] * 1ll * ifact[ k] ) % mod) ;
ans = int ( ( ans * 1ll * ifact[ n - k] ) % mod) ;
return ans;
}
int binPow( int a, int b)
{
int ans = 1 ;
while ( b)
{
if ( b & 1 ) ans = int ( ( ans * 1ll * a) % mod) ;
a = int ( ( a * 1ll * a) % mod) ;
b >>= 1 ;
}
return ans;
}
int n;
string get( int mask)
{
string s;
ford( i, n) s.pb ( char ( '0' + get( mask, i) ) ) ;
return s;
}
int b[ N] ;
int z[ EXPN3] [ N] ;
int AquaparkPuzzle:: countSchedules ( int k, int m, vector < int > cost)
{
pw[ 0 ] = 1 ; forl( i, N - 1 ) pw[ i] = pw[ i - 1 ] * 3 ;
fact[ 0 ] = 1 ; forl( i, K - 1 ) fact[ i] = int ( ( fact[ i - 1 ] * 1ll * i) % mod) ;
forn( i, K) ifact[ i] = inv( fact[ i] ) ;
n = sz( cost) ;
forn( mask, ( 1 << n) )
{
int s = 0 ;
forn( i, n) if ( mask & ( 1 << i) ) s + = cost[ i] ;
g[ mask] = s <= m;
}
forn( mask, ( 1 << n) )
{
c[ mask] = 0 ;
forn( msk, ( 1 << n) ) if ( ! ( mask & msk) ) c[ mask] + = g[ msk] ;
}
memset ( z, 0 , sizeof ( z) ) ;
forn( mask, pw[ n] )
{
forn( i, n) b[ i] = get( mask, i) ;
int bmsk[ 3 ] = { 0 } ;
forn( i, n) bmsk[ b[ i] ] | = ( 1 << i) ;
if ( bmsk[ 1 ] == 0 )
{
z[ mask] [ 0 ] = 1 ;
continue ;
}
int msk = bmsk[ 1 ] | bmsk[ 2 ] ;
for ( int cmsk = msk; cmsk > 0 ; cmsk = ( cmsk - 1 ) & msk)
{
if ( ( cmsk & bmsk[ 1 ] ) && g[ cmsk] )
{
int nmsk = mask;
forn( i, n) if ( b[ i] == 1 && ( cmsk & ( 1 << i) ) ) nmsk - = pw[ i] ;
int * p1 = & z[ mask] [ 1 ] ;
int * p2 = & z[ nmsk] [ 0 ] ;
forl( i, n)
{
* p1 + = * p2;
( * p1 >= mod) && ( * p1 - = mod) ;
p1++ , p2++ ;
/*int& dv = z[mask][i];
dv += z[nmsk][i - 1];
(dv >= mod) && (dv -= mod);*/
}
}
}
}
/*forn(mask, pw[n])
forn(i, n + 1)
{
ford(j, n) cerr << get(mask, j);
cerr << ' ' << i << ": " << z[mask][i] << endl;
}*/
int ans = 0 ;
forn( mask, pw[ n] )
{
forn( i, n) b[ i] = get( mask, i) ;
int bmsk[ 3 ] = { 0 } ;
forn( i, n) bmsk[ b[ i] ] | = ( 1 << i) ;
int sg = 1 ; forn( i, n) if ( b[ i] < 2 ) sg = - sg;
int sum = 0 ;
forn( i, n + 1 )
{
int cnt = C( k, i) ;
if ( cnt == 0 ) continue ;
cnt = int ( ( cnt * 1ll * z[ mask] [ i] ) % mod) ;
cnt = int ( ( cnt * 1ll * binPow( c[ bmsk[ 0 ] | bmsk[ 1 ] ] , k - i) ) % mod) ;
sum + = cnt;
( sum >= mod) && ( sum - = mod) ;
}
//cerr << get(mask) << ' ' << sum << ' ' << sg << endl;
ans + = sum * sg;
( ans < 0 ) && ( ans + = mod) ;
( ans >= mod) && ( ans - = mod) ;
}
return ans;
}
// BEGIN CUT HERE
namespace moj_harness {
int run_test_case( int ) ;
void run_test( int casenum = - 1 , bool quiet = false ) {
if ( casenum ! = - 1 ) {
if ( run_test_case( casenum) == - 1 && ! quiet) {
cerr << "Illegal input! Test case " << casenum << " does not exist." << endl;
}
return ;
}
int correct = 0 , total = 0 ;
for ( int i= 0 ;; ++ i) {
int x = run_test_case( i) ;
if ( x == - 1 ) {
if ( i >= 100 ) break ;
continue ;
}
correct + = x;
++ total;
}
if ( total == 0 ) {
cerr << "No test cases run." << endl;
} else if ( correct < total) {
cerr << "Some cases FAILED (passed " << correct << " of " << total << ")." << endl;
} else {
cerr << "All " << total << " tests passed!" << endl;
}
}
int verify_case( int casenum, const int & expected, const int & received, clock_t elapsed) {
cerr << "Example " << casenum << "... " ;
string verdict;
vector< string> info;
char buf[ 100 ] ;
if ( elapsed > CLOCKS_PER_SEC / 200 ) {
sprintf ( buf, "time %.2fs" , elapsed * ( 1.0 / CLOCKS_PER_SEC ) ) ;
info.push_back ( buf) ;
}
if ( expected == received) {
verdict = "PASSED" ;
} else {
verdict = "FAILED" ;
}
cerr << verdict;
if ( ! info.empty ( ) ) {
cerr << " (" ;
for ( int i= 0 ; i< ( int ) info.size ( ) ; ++ i) {
if ( i > 0 ) cerr << ", " ;
cerr << info[ i] ;
}
cerr << ")" ;
}
cerr << endl;
if ( verdict == "FAILED" ) {
cerr << " Expected: " << expected << endl;
cerr << " Received: " << received << endl;
}
return verdict == "PASSED" ;
}
int run_test_case( int casenum) {
switch ( casenum) {
case 0 : {
int k = 3 ;
int m = 3 ;
int c[ ] = { 1 , 2 } ;
int expected__ = 16 ;
clock_t start__ = clock ( ) ;
int received__ = AquaparkPuzzle( ) .countSchedules ( k, m, vector < int > ( c, c + ( sizeof c / sizeof c[ 0 ] ) ) ) ;
return verify_case( casenum, expected__, received__, clock ( ) - start__) ;
}
case 1 : {
int k = 3 ;
int m = 3 ;
int c[ ] = { 2 , 2 } ;
int expected__ = 0 ;
clock_t start__ = clock ( ) ;
int received__ = AquaparkPuzzle( ) .countSchedules ( k, m, vector < int > ( c, c + ( sizeof c / sizeof c[ 0 ] ) ) ) ;
return verify_case( casenum, expected__, received__, clock ( ) - start__) ;
}
case 2 : {
int k = 4 ;
int m = 3 ;
int c[ ] = { 1 , 2 , 2 } ;
int expected__ = 66 ;
clock_t start__ = clock ( ) ;
int received__ = AquaparkPuzzle( ) .countSchedules ( k, m, vector < int > ( c, c + ( sizeof c / sizeof c[ 0 ] ) ) ) ;
return verify_case( casenum, expected__, received__, clock ( ) - start__) ;
}
case 3 : {
int k = 6 ;
int m = 7 ;
int c[ ] = { 2 , 3 , 4 , 7 } ;
int expected__ = 4800 ;
clock_t start__ = clock ( ) ;
int received__ = AquaparkPuzzle( ) .countSchedules ( k, m, vector < int > ( c, c + ( sizeof c / sizeof c[ 0 ] ) ) ) ;
return verify_case( casenum, expected__, received__, clock ( ) - start__) ;
}
case 4 : {
int k = 1000 ;
int m = 20 ;
int c[ ] = { 8 , 2 , 13 , 18 , 7 , 3 } ;
int expected__ = 15681195 ;
clock_t start__ = clock ( ) ;
int received__ = AquaparkPuzzle( ) .countSchedules ( k, m, vector < int > ( c, c + ( sizeof c / sizeof c[ 0 ] ) ) ) ;
return verify_case( casenum, expected__, received__, clock ( ) - start__) ;
}
// custom cases
case 5 : {
int k = 1000000 ;
int m = 1000 ;
int c[ ] = { 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } ;
int expected__ = 5069980 ;
clock_t start__ = clock ( ) ;
int received__ = AquaparkPuzzle( ) .countSchedules ( k, m, vector < int > ( c, c + ( sizeof c / sizeof c[ 0 ] ) ) ) ;
return verify_case( casenum, expected__, received__, clock ( ) - start__) ;
}
/* case 6: {
int k = ;
int m = ;
int c[] = ;
int expected__ = ;
clock_t start__ = clock();
int received__ = AquaparkPuzzle().countSchedules(k, m, vector <int>(c, c + (sizeof c / sizeof c[0])));
return verify_case(casenum, expected__, received__, clock()-start__);
}*/
/* case 7: {
int k = ;
int m = ;
int c[] = ;
int expected__ = ;
clock_t start__ = clock();
int received__ = AquaparkPuzzle().countSchedules(k, m, vector <int>(c, c + (sizeof c / sizeof c[0])));
return verify_case(casenum, expected__, received__, clock()-start__);
}*/
default :
return - 1 ;
}
}
}
int main( int argc, char * argv[ ] ) {
if ( argc == 1 ) {
moj_harness:: run_test ( ) ;
} else {
for ( int i= 1 ; i< argc; ++ i)
moj_harness:: run_test ( atoi ( argv[ i] ) ) ;
}
}
// END CUT HERE
Ly8gQkVHSU4gQ1VUIEhFUkUKCi8vIEVORCBDVVQgSEVSRQojbGluZSA1ICJBcXVhcGFya1B1enpsZS5jcHAiCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHNzdHJlYW0+CiNpbmNsdWRlIDxzZXQ+CiNpbmNsdWRlIDxtYXA+CiNpbmNsdWRlIDxiaXRzZXQ+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8bnVtZXJpYz4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxxdWV1ZT4KI2luY2x1ZGUgPHN0YWNrPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxjdGltZT4KI2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8Y2Fzc2VydD4KCiNkZWZpbmUgZm9ybihpLCBuKSBmb3IgKGludCBpID0gMDsgaSA8IGludChuKTsgaSsrKQojZGVmaW5lIGZvcmwoaSwgbikgZm9yIChpbnQgaSA9IDE7IGkgPD0gaW50KG4pOyBpKyspCiNkZWZpbmUgZm9yZChpLCBuKSBmb3IgKGludCBpID0gaW50KG4pIC0gMTsgaSA+PSAwOyBpLS0pCiNkZWZpbmUgZm9yZShpLCBsLCByKSBmb3IgKGludCBpID0gaW50KGwpOyBpIDw9IGludChyKTsgaSsrKQojZGVmaW5lIGNvcnJlY3QoeCwgeSwgbiwgbSkgKDAgPD0gKHgpICYmICh4KSA8IChuKSAmJiAwIDw9ICh5KSAmJiAoeSkgPCAobSkpCiNkZWZpbmUgYWxsKGEpIChhKS5iZWdpbigpLCAoYSkuZW5kKCkKI2RlZmluZSBzeihhKSBpbnQoKGEpLnNpemUoKSkKI2RlZmluZSBwYihhKSBwdXNoX2JhY2soYSkKI2RlZmluZSBtcCh4LCB5KSBtYWtlX3BhaXIoKHgpLCAoeSkpCiNkZWZpbmUgZnQgZmlyc3QKI2RlZmluZSBzYyBzZWNvbmQKI2RlZmluZSBpc25hbihhKSBmYWxzZQojZGVmaW5lIGlzaW5mKGEpIGZhbHNlCgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdHlwZWRlZiBsb25nIGxvbmcgbGk7CnR5cGVkZWYgbG9uZyBkb3VibGUgbGQ7CnR5cGVkZWYgcGFpcjxpbnQsIGludD4gcHQ7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBYPiBpbmxpbmUgWCBhYnMoY29uc3QgWCYgYSkgeyByZXR1cm4gYSA8IDA/IC1hOiBhOyB9CnRlbXBsYXRlPHR5cGVuYW1lIFg+IGlubGluZSBYIHNxcihjb25zdCBYJiBhKSB7IHJldHVybiBhICogYTsgfQoKY29uc3QgaW50IElORiA9IGludCgxZTkpOwpjb25zdCBsaSBJTkY2NCA9IGxpKDFlMTgpOwpjb25zdCBsZCBFUFMgPSAxZS05LCBQSSA9IDMuMTQxNTkyNjUzNTg5NzkzMjM4NDYyNjQzMzgzMjc5NTsKCmNsYXNzIEFxdWFwYXJrUHV6emxlCnsKCXB1YmxpYzoKCWludCBjb3VudFNjaGVkdWxlcyhpbnQgaywgaW50IG0sIHZlY3RvciA8aW50PiBjKTsKfTsKCmludCBnY2QoaW50IGEsIGludCBiLCBpbnQmIHgsIGludCYgeSkKewoJaWYgKGEgPT0gMCkKCXsKCQl4ID0gMCwgeSA9IDE7CgkJcmV0dXJuIGI7Cgl9CgoJaW50IHh4LCB5eSwgZyA9IGdjZChiICUgYSwgYSwgeHgsIHl5KTsKCXggPSB5eSAtIGIgLyBhICogeHg7Cgl5ID0geHg7CglyZXR1cm4gZzsKfQoKY29uc3QgaW50IG1vZCA9IDEwMDAgKiAxMDAwICogMTAwMCArIDc7CgppbnQgaW52KGludCBhKQp7CglpbnQgeCwgeTsKCWFzc2VydChnY2QoYSwgbW9kLCB4LCB5KSA9PSAxKTsKCXggJT0gbW9kOwoJKHggPCAwKSAmJiAoeCArPSBtb2QpOwoJcmV0dXJuIHg7Cn0KCmNvbnN0IGludCBOID0gMTEgKyAzLCBLID0gMTAwMCAqIDEwMDAgKyAzLCBFWFBOID0gKDEgPDwgMTEpICsgMywgRVhQTjMgPSAxODAwMDA7CgppbnQgcHdbTl0sIGZhY3RbS10sIGlmYWN0W0tdOwppbnQgZ1tFWFBOXSwgY1tFWFBOXTsKCmludCBnZXQoaW50IG1hc2ssIGludCBpKSB7IHJldHVybiAobWFzayAvIHB3W2ldKSAlIDM7IH0KaW50IF9zZXQoaW50IG1hc2ssIGludCBpLCBpbnQgdikgeyByZXR1cm4gbWFzayAtIChnZXQobWFzaywgaSkgLSB2KSAqIHB3W2ldOyB9CgppbnQgQyhpbnQgbiwgaW50IGspCnsKCWlmIChrIDwgMCB8fCBrID4gbikgcmV0dXJuIDA7CglpbnQgYW5zID0gaW50KChmYWN0W25dICogMWxsICogaWZhY3Rba10pICUgbW9kKTsKCWFucyA9IGludCgoYW5zICogMWxsICogaWZhY3RbbiAtIGtdKSAlIG1vZCk7CglyZXR1cm4gYW5zOwp9CgppbnQgYmluUG93KGludCBhLCBpbnQgYikKewoJaW50IGFucyA9IDE7Cgl3aGlsZSAoYikKCXsKCQlpZiAoYiAmIDEpIGFucyA9IGludCgoYW5zICogMWxsICogYSkgJSBtb2QpOwoJCWEgPSBpbnQoKGEgKiAxbGwgKiBhKSAlIG1vZCk7CgkJYiA+Pj0gMTsKCX0KCXJldHVybiBhbnM7Cn0KCmludCBuOwoKc3RyaW5nIGdldChpbnQgbWFzaykKewoJc3RyaW5nIHM7Cglmb3JkKGksIG4pIHMucGIoY2hhcignMCcgKyBnZXQobWFzaywgaSkpKTsKCXJldHVybiBzOwp9CgppbnQgYltOXTsKaW50IHpbRVhQTjNdW05dOwoKaW50IEFxdWFwYXJrUHV6emxlOjpjb3VudFNjaGVkdWxlcyhpbnQgaywgaW50IG0sIHZlY3RvciA8aW50PiBjb3N0KQp7Cglwd1swXSA9IDE7IGZvcmwoaSwgTiAtIDEpIHB3W2ldID0gcHdbaSAtIDFdICogMzsKCglmYWN0WzBdID0gMTsgZm9ybChpLCBLIC0gMSkgZmFjdFtpXSA9IGludCgoZmFjdFtpIC0gMV0gKiAxbGwgKiBpKSAlIG1vZCk7Cglmb3JuKGksIEspIGlmYWN0W2ldID0gaW52KGZhY3RbaV0pOwoKCW4gPSBzeihjb3N0KTsKCWZvcm4obWFzaywgKDEgPDwgbikpCgl7CgkJaW50IHMgPSAwOwoJCWZvcm4oaSwgbikgaWYgKG1hc2sgJiAoMSA8PCBpKSkgcyArPSBjb3N0W2ldOwoJCWdbbWFza10gPSBzIDw9IG07Cgl9CgoJZm9ybihtYXNrLCAoMSA8PCBuKSkKCXsKCQljW21hc2tdID0gMDsKCQlmb3JuKG1zaywgKDEgPDwgbikpIGlmICghKG1hc2sgJiBtc2spKSBjW21hc2tdICs9IGdbbXNrXTsKCX0KCgltZW1zZXQoeiwgMCwgc2l6ZW9mKHopKTsgCglmb3JuKG1hc2ssIHB3W25dKQoJewoJCWZvcm4oaSwgbikgYltpXSA9IGdldChtYXNrLCBpKTsKCQlpbnQgYm1za1szXSA9IHsgMCB9OwoJCWZvcm4oaSwgbikgYm1za1tiW2ldXSB8PSAoMSA8PCBpKTsKCgkJaWYgKGJtc2tbMV0gPT0gMCkKCQl7CgkJCXpbbWFza11bMF0gPSAxOwoJCQljb250aW51ZTsKCQl9CgoJCWludCBtc2sgPSBibXNrWzFdIHwgYm1za1syXTsKCQlmb3IgKGludCBjbXNrID0gbXNrOyBjbXNrID4gMDsgY21zayA9IChjbXNrIC0gMSkgJiBtc2spCgkJewoJCQlpZiAoKGNtc2sgJiBibXNrWzFdKSAmJiBnW2Ntc2tdKQoJCQl7CgkJCQlpbnQgbm1zayA9IG1hc2s7CgkJCQlmb3JuKGksIG4pIGlmIChiW2ldID09IDEgJiYgKGNtc2sgJiAoMSA8PCBpKSkpIG5tc2sgLT0gcHdbaV07CgoJCQkJaW50KiBwMSA9ICZ6W21hc2tdWzFdOwoJCQkJaW50KiBwMiA9ICZ6W25tc2tdWzBdOwoJCQkJZm9ybChpLCBuKQoJCQkJewoJCQkJCSpwMSArPSAqcDI7CgkJCQkJKCpwMSA+PSBtb2QpICYmICgqcDEgLT0gbW9kKTsKCQkJCQlwMSsrLCBwMisrOwoJCQkJCS8qaW50JiBkdiA9IHpbbWFza11baV07CgkJCQkJZHYgKz0geltubXNrXVtpIC0gMV07CgkJCQkJKGR2ID49IG1vZCkgJiYgKGR2IC09IG1vZCk7Ki8KCQkJCX0KCQkJfQoJCX0KCX0KCgkvKmZvcm4obWFzaywgcHdbbl0pCgkJZm9ybihpLCBuICsgMSkKCQl7CgkJCWZvcmQoaiwgbikgY2VyciA8PCBnZXQobWFzaywgaik7CgkJCWNlcnIgPDwgJyAnIDw8IGkgPDwgIjogIiA8PCB6W21hc2tdW2ldIDw8IGVuZGw7CgkJfSovCgoJaW50IGFucyA9IDA7Cglmb3JuKG1hc2ssIHB3W25dKQoJewoJCWZvcm4oaSwgbikgYltpXSA9IGdldChtYXNrLCBpKTsKCQlpbnQgYm1za1szXSA9IHsgMCB9OwoJCWZvcm4oaSwgbikgYm1za1tiW2ldXSB8PSAoMSA8PCBpKTsKCgkJaW50IHNnID0gMTsgZm9ybihpLCBuKSBpZiAoYltpXSA8IDIpIHNnID0gLXNnOwoKCQlpbnQgc3VtID0gMDsKCQlmb3JuKGksIG4gKyAxKQoJCXsKCQkJaW50IGNudCA9IEMoaywgaSk7CgkJCWlmIChjbnQgPT0gMCkgY29udGludWU7CgkJCWNudCA9IGludCgoY250ICogMWxsICogelttYXNrXVtpXSkgJSBtb2QpOwoJCQljbnQgPSBpbnQoKGNudCAqIDFsbCAqIGJpblBvdyhjW2Jtc2tbMF0gfCBibXNrWzFdXSwgayAtIGkpKSAlIG1vZCk7CgkJCXN1bSArPSBjbnQ7CgkJCShzdW0gPj0gbW9kKSAmJiAoc3VtIC09IG1vZCk7CgkJfQoKCQkvL2NlcnIgPDwgZ2V0KG1hc2spIDw8ICcgJyA8PCBzdW0gPDwgJyAnIDw8IHNnIDw8IGVuZGw7CgkJYW5zICs9IHN1bSAqIHNnOwoJCShhbnMgPCAwKSAmJiAoYW5zICs9IG1vZCk7CgkJKGFucyA+PSBtb2QpICYmIChhbnMgLT0gbW9kKTsKCX0KCQoJcmV0dXJuIGFuczsKfQoKLy8gQkVHSU4gQ1VUIEhFUkUKbmFtZXNwYWNlIG1val9oYXJuZXNzIHsKCWludCBydW5fdGVzdF9jYXNlKGludCk7Cgl2b2lkIHJ1bl90ZXN0KGludCBjYXNlbnVtID0gLTEsIGJvb2wgcXVpZXQgPSBmYWxzZSkgewoJCWlmIChjYXNlbnVtICE9IC0xKSB7CgkJCWlmIChydW5fdGVzdF9jYXNlKGNhc2VudW0pID09IC0xICYmICFxdWlldCkgewoJCQkJY2VyciA8PCAiSWxsZWdhbCBpbnB1dCEgVGVzdCBjYXNlICIgPDwgY2FzZW51bSA8PCAiIGRvZXMgbm90IGV4aXN0LiIgPDwgZW5kbDsKCQkJfQoJCQlyZXR1cm47CgkJfQoJCQoJCWludCBjb3JyZWN0ID0gMCwgdG90YWwgPSAwOwoJCWZvciAoaW50IGk9MDs7ICsraSkgewoJCQlpbnQgeCA9IHJ1bl90ZXN0X2Nhc2UoaSk7CgkJCWlmICh4ID09IC0xKSB7CgkJCQlpZiAoaSA+PSAxMDApIGJyZWFrOwoJCQkJY29udGludWU7CgkJCX0KCQkJY29ycmVjdCArPSB4OwoJCQkrK3RvdGFsOwoJCX0KCQkKCQlpZiAodG90YWwgPT0gMCkgewoJCQljZXJyIDw8ICJObyB0ZXN0IGNhc2VzIHJ1bi4iIDw8IGVuZGw7CgkJfSBlbHNlIGlmIChjb3JyZWN0IDwgdG90YWwpIHsKCQkJY2VyciA8PCAiU29tZSBjYXNlcyBGQUlMRUQgKHBhc3NlZCAiIDw8IGNvcnJlY3QgPDwgIiBvZiAiIDw8IHRvdGFsIDw8ICIpLiIgPDwgZW5kbDsKCQl9IGVsc2UgewoJCQljZXJyIDw8ICJBbGwgIiA8PCB0b3RhbCA8PCAiIHRlc3RzIHBhc3NlZCEiIDw8IGVuZGw7CgkJfQoJfQoJCglpbnQgdmVyaWZ5X2Nhc2UoaW50IGNhc2VudW0sIGNvbnN0IGludCAmZXhwZWN0ZWQsIGNvbnN0IGludCAmcmVjZWl2ZWQsIGNsb2NrX3QgZWxhcHNlZCkgeyAKCQljZXJyIDw8ICJFeGFtcGxlICIgPDwgY2FzZW51bSA8PCAiLi4uICI7IAoJCQoJCXN0cmluZyB2ZXJkaWN0OwoJCXZlY3RvcjxzdHJpbmc+IGluZm87CgkJY2hhciBidWZbMTAwXTsKCQkKCQlpZiAoZWxhcHNlZCA+IENMT0NLU19QRVJfU0VDIC8gMjAwKSB7CgkJCXNwcmludGYoYnVmLCAidGltZSAlLjJmcyIsIGVsYXBzZWQgKiAoMS4wL0NMT0NLU19QRVJfU0VDKSk7CgkJCWluZm8ucHVzaF9iYWNrKGJ1Zik7CgkJfQoJCQoJCWlmIChleHBlY3RlZCA9PSByZWNlaXZlZCkgewoJCQl2ZXJkaWN0ID0gIlBBU1NFRCI7CgkJfSBlbHNlIHsKCQkJdmVyZGljdCA9ICJGQUlMRUQiOwoJCX0KCQkKCQljZXJyIDw8IHZlcmRpY3Q7CgkJaWYgKCFpbmZvLmVtcHR5KCkpIHsKCQkJY2VyciA8PCAiICgiOwoJCQlmb3IgKGludCBpPTA7IGk8KGludClpbmZvLnNpemUoKTsgKytpKSB7CgkJCQlpZiAoaSA+IDApIGNlcnIgPDwgIiwgIjsKCQkJCWNlcnIgPDwgaW5mb1tpXTsKCQkJfQoJCQljZXJyIDw8ICIpIjsKCQl9CgkJY2VyciA8PCBlbmRsOwoJCQoJCWlmICh2ZXJkaWN0ID09ICJGQUlMRUQiKSB7CgkJCWNlcnIgPDwgIiAgICBFeHBlY3RlZDogIiA8PCBleHBlY3RlZCA8PCBlbmRsOyAKCQkJY2VyciA8PCAiICAgIFJlY2VpdmVkOiAiIDw8IHJlY2VpdmVkIDw8IGVuZGw7IAoJCX0KCQkKCQlyZXR1cm4gdmVyZGljdCA9PSAiUEFTU0VEIjsKCX0KCglpbnQgcnVuX3Rlc3RfY2FzZShpbnQgY2FzZW51bSkgewoJCXN3aXRjaCAoY2FzZW51bSkgewoJCWNhc2UgMDogewoJCQlpbnQgayAgICAgICAgICAgICAgICAgICAgID0gMzsKCQkJaW50IG0gICAgICAgICAgICAgICAgICAgICA9IDM7CgkJCWludCBjW10gICAgICAgICAgICAgICAgICAgPSB7MSwgMn07CgkJCWludCBleHBlY3RlZF9fICAgICAgICAgICAgPSAxNjsKCgkJCWNsb2NrX3Qgc3RhcnRfXyAgICAgICAgICAgPSBjbG9jaygpOwoJCQlpbnQgcmVjZWl2ZWRfXyAgICAgICAgICAgID0gQXF1YXBhcmtQdXp6bGUoKS5jb3VudFNjaGVkdWxlcyhrLCBtLCB2ZWN0b3IgPGludD4oYywgYyArIChzaXplb2YgYyAvIHNpemVvZiBjWzBdKSkpOwoJCQlyZXR1cm4gdmVyaWZ5X2Nhc2UoY2FzZW51bSwgZXhwZWN0ZWRfXywgcmVjZWl2ZWRfXywgY2xvY2soKS1zdGFydF9fKTsKCQl9CgkJY2FzZSAxOiB7CgkJCWludCBrICAgICAgICAgICAgICAgICAgICAgPSAzOwoJCQlpbnQgbSAgICAgICAgICAgICAgICAgICAgID0gMzsKCQkJaW50IGNbXSAgICAgICAgICAgICAgICAgICA9IHsyLCAyfTsKCQkJaW50IGV4cGVjdGVkX18gICAgICAgICAgICA9IDA7CgoJCQljbG9ja190IHN0YXJ0X18gICAgICAgICAgID0gY2xvY2soKTsKCQkJaW50IHJlY2VpdmVkX18gICAgICAgICAgICA9IEFxdWFwYXJrUHV6emxlKCkuY291bnRTY2hlZHVsZXMoaywgbSwgdmVjdG9yIDxpbnQ+KGMsIGMgKyAoc2l6ZW9mIGMgLyBzaXplb2YgY1swXSkpKTsKCQkJcmV0dXJuIHZlcmlmeV9jYXNlKGNhc2VudW0sIGV4cGVjdGVkX18sIHJlY2VpdmVkX18sIGNsb2NrKCktc3RhcnRfXyk7CgkJfQoJCWNhc2UgMjogewoJCQlpbnQgayAgICAgICAgICAgICAgICAgICAgID0gNDsKCQkJaW50IG0gICAgICAgICAgICAgICAgICAgICA9IDM7CgkJCWludCBjW10gICAgICAgICAgICAgICAgICAgPSB7MSwgMiwgMn07CgkJCWludCBleHBlY3RlZF9fICAgICAgICAgICAgPSA2NjsKCgkJCWNsb2NrX3Qgc3RhcnRfXyAgICAgICAgICAgPSBjbG9jaygpOwoJCQlpbnQgcmVjZWl2ZWRfXyAgICAgICAgICAgID0gQXF1YXBhcmtQdXp6bGUoKS5jb3VudFNjaGVkdWxlcyhrLCBtLCB2ZWN0b3IgPGludD4oYywgYyArIChzaXplb2YgYyAvIHNpemVvZiBjWzBdKSkpOwoJCQlyZXR1cm4gdmVyaWZ5X2Nhc2UoY2FzZW51bSwgZXhwZWN0ZWRfXywgcmVjZWl2ZWRfXywgY2xvY2soKS1zdGFydF9fKTsKCQl9CgkJY2FzZSAzOiB7CgkJCWludCBrICAgICAgICAgICAgICAgICAgICAgPSA2OwoJCQlpbnQgbSAgICAgICAgICAgICAgICAgICAgID0gNzsKCQkJaW50IGNbXSAgICAgICAgICAgICAgICAgICA9IHsyLCAzLCA0LCA3fTsKCQkJaW50IGV4cGVjdGVkX18gICAgICAgICAgICA9IDQ4MDA7CgoJCQljbG9ja190IHN0YXJ0X18gICAgICAgICAgID0gY2xvY2soKTsKCQkJaW50IHJlY2VpdmVkX18gICAgICAgICAgICA9IEFxdWFwYXJrUHV6emxlKCkuY291bnRTY2hlZHVsZXMoaywgbSwgdmVjdG9yIDxpbnQ+KGMsIGMgKyAoc2l6ZW9mIGMgLyBzaXplb2YgY1swXSkpKTsKCQkJcmV0dXJuIHZlcmlmeV9jYXNlKGNhc2VudW0sIGV4cGVjdGVkX18sIHJlY2VpdmVkX18sIGNsb2NrKCktc3RhcnRfXyk7CgkJfQoJCWNhc2UgNDogewoJCQlpbnQgayAgICAgICAgICAgICAgICAgICAgID0gMTAwMDsKCQkJaW50IG0gICAgICAgICAgICAgICAgICAgICA9IDIwOwoJCQlpbnQgY1tdICAgICAgICAgICAgICAgICAgID0gezgsIDIsIDEzLCAxOCwgNywgM307CgkJCWludCBleHBlY3RlZF9fICAgICAgICAgICAgPSAxNTY4MTE5NTsKCgkJCWNsb2NrX3Qgc3RhcnRfXyAgICAgICAgICAgPSBjbG9jaygpOwoJCQlpbnQgcmVjZWl2ZWRfXyAgICAgICAgICAgID0gQXF1YXBhcmtQdXp6bGUoKS5jb3VudFNjaGVkdWxlcyhrLCBtLCB2ZWN0b3IgPGludD4oYywgYyArIChzaXplb2YgYyAvIHNpemVvZiBjWzBdKSkpOwoJCQlyZXR1cm4gdmVyaWZ5X2Nhc2UoY2FzZW51bSwgZXhwZWN0ZWRfXywgcmVjZWl2ZWRfXywgY2xvY2soKS1zdGFydF9fKTsKCQl9CgoJCS8vIGN1c3RvbSBjYXNlcwoKICAgICAgICBjYXNlIDU6IHsKCQkJaW50IGsgICAgICAgICAgICAgICAgICAgICA9IDEwMDAwMDA7CgkJCWludCBtICAgICAgICAgICAgICAgICAgICAgPSAxMDAwOwoJCQlpbnQgY1tdICAgICAgICAgICAgICAgICAgID0geyAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxIH07CgkJCWludCBleHBlY3RlZF9fICAgICAgICAgICAgPSA1MDY5OTgwOwoKCQkJY2xvY2tfdCBzdGFydF9fICAgICAgICAgICA9IGNsb2NrKCk7CgkJCWludCByZWNlaXZlZF9fICAgICAgICAgICAgPSBBcXVhcGFya1B1enpsZSgpLmNvdW50U2NoZWR1bGVzKGssIG0sIHZlY3RvciA8aW50PihjLCBjICsgKHNpemVvZiBjIC8gc2l6ZW9mIGNbMF0pKSk7CgkJCXJldHVybiB2ZXJpZnlfY2FzZShjYXNlbnVtLCBleHBlY3RlZF9fLCByZWNlaXZlZF9fLCBjbG9jaygpLXN0YXJ0X18pOwoJCX0KLyogICAgICBjYXNlIDY6IHsKCQkJaW50IGsgICAgICAgICAgICAgICAgICAgICA9IDsKCQkJaW50IG0gICAgICAgICAgICAgICAgICAgICA9IDsKCQkJaW50IGNbXSAgICAgICAgICAgICAgICAgICA9IDsKCQkJaW50IGV4cGVjdGVkX18gICAgICAgICAgICA9IDsKCgkJCWNsb2NrX3Qgc3RhcnRfXyAgICAgICAgICAgPSBjbG9jaygpOwoJCQlpbnQgcmVjZWl2ZWRfXyAgICAgICAgICAgID0gQXF1YXBhcmtQdXp6bGUoKS5jb3VudFNjaGVkdWxlcyhrLCBtLCB2ZWN0b3IgPGludD4oYywgYyArIChzaXplb2YgYyAvIHNpemVvZiBjWzBdKSkpOwoJCQlyZXR1cm4gdmVyaWZ5X2Nhc2UoY2FzZW51bSwgZXhwZWN0ZWRfXywgcmVjZWl2ZWRfXywgY2xvY2soKS1zdGFydF9fKTsKCQl9Ki8KLyogICAgICBjYXNlIDc6IHsKCQkJaW50IGsgICAgICAgICAgICAgICAgICAgICA9IDsKCQkJaW50IG0gICAgICAgICAgICAgICAgICAgICA9IDsKCQkJaW50IGNbXSAgICAgICAgICAgICAgICAgICA9IDsKCQkJaW50IGV4cGVjdGVkX18gICAgICAgICAgICA9IDsKCgkJCWNsb2NrX3Qgc3RhcnRfXyAgICAgICAgICAgPSBjbG9jaygpOwoJCQlpbnQgcmVjZWl2ZWRfXyAgICAgICAgICAgID0gQXF1YXBhcmtQdXp6bGUoKS5jb3VudFNjaGVkdWxlcyhrLCBtLCB2ZWN0b3IgPGludD4oYywgYyArIChzaXplb2YgYyAvIHNpemVvZiBjWzBdKSkpOwoJCQlyZXR1cm4gdmVyaWZ5X2Nhc2UoY2FzZW51bSwgZXhwZWN0ZWRfXywgcmVjZWl2ZWRfXywgY2xvY2soKS1zdGFydF9fKTsKCQl9Ki8KCQlkZWZhdWx0OgoJCQlyZXR1cm4gLTE7CgkJfQoJfQp9CiAKCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIHsKCWlmIChhcmdjID09IDEpIHsKCQltb2pfaGFybmVzczo6cnVuX3Rlc3QoKTsKCX0gZWxzZSB7CgkJZm9yIChpbnQgaT0xOyBpPGFyZ2M7ICsraSkKCQkJbW9qX2hhcm5lc3M6OnJ1bl90ZXN0KGF0b2koYXJndltpXSkpOwoJfQp9Ci8vIEVORCBDVVQgSEVSRQo=