#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define MD 1000000007
void * wmem;
template < class S, class T> inline S min_L( S a,T b) {
return a<= b? a: b;
}
template < class T> inline void walloc1d( T ** arr, int x, void ** mem = & wmem) {
static int skip[ 16 ] = { 0 , 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 } ;
( * mem) = ( void * ) ( ( ( char * ) ( * mem) ) + skip[ ( ( unsigned long long ) ( * mem) ) & 15 ] ) ;
( * arr) = ( T* ) ( * mem) ;
( * mem) = ( ( * arr) + x) ;
}
struct mint{
static unsigned R, RR, Rinv, W, md, mdninv;
unsigned val;
mint( ) {
}
mint( int a) {
val = mulR( a) ;
}
mint( unsigned a) {
val = mulR( a) ;
}
mint( long long a) {
val = mulR( a) ;
}
mint( unsigned long long a) {
val = mulR( a) ;
}
int get_inv( long long a, int md) {
long long e, s= md, t= a, u= 1 , v= 0 ;
while ( s) {
e= t/ s;
t- = e* s;
u- = e* v;
swap( t,s) ;
swap( u,v) ;
}
if ( u< 0 ) {
u+ = md;
}
return u;
}
void setmod( unsigned m) {
int i;
unsigned t;
W = 32 ;
md = m;
R = ( 1ULL << W) % md;
RR = ( unsigned long long ) R* R % md;
switch ( m) {
case 104857601 :
Rinv = 2560000 ;
mdninv = 104857599 ;
break ;
case 998244353 :
Rinv = 232013824 ;
mdninv = 998244351 ;
break ;
case 1000000007 :
Rinv = 518424770 ;
mdninv = 2226617417U;
break ;
case 1000000009 :
Rinv = 171601999 ;
mdninv = 737024967 ;
break ;
case 1004535809 :
Rinv = 234947584 ;
mdninv = 1004535807 ;
break ;
case 1007681537 :
Rinv = 236421376 ;
mdninv = 1007681535 ;
break ;
case 1012924417 :
Rinv = 238887936 ;
mdninv = 1012924415 ;
break ;
case 1045430273 :
Rinv = 254466304 ;
mdninv = 1045430271 ;
break ;
case 1051721729 :
Rinv = 257538304 ;
mdninv = 1051721727 ;
break ;
default :
Rinv = get_inv( R, md) ;
mdninv = 0 ;
t = 0 ;
for ( i= 0 ; i< ( ( int ) W) ; i++ ) {
if ( t% 2 == 0 ) {
t+ = md;
mdninv | = ( 1U<< i) ;
}
t / = 2 ;
}
}
}
unsigned mulR( unsigned a) {
return ( unsigned long long ) a* R% md;
}
unsigned mulR( int a) {
if ( a < 0 ) {
a = a% ( ( int ) md) + ( int ) md;
}
return mulR( ( unsigned ) a) ;
}
unsigned mulR( unsigned long long a) {
return mulR( ( unsigned ) ( a% md) ) ;
}
unsigned mulR( long long a) {
a % = md;
if ( a < 0 ) {
a + = md;
}
return mulR( ( unsigned ) a) ;
}
unsigned reduce( unsigned T) {
unsigned m= T * mdninv, t= ( unsigned ) ( ( T + ( unsigned long long ) m* md) >> W) ;
if ( t >= md) {
t - = md;
}
return t;
}
unsigned reduce( unsigned long long T) {
unsigned m= ( unsigned ) T * mdninv, t= ( unsigned ) ( ( T + ( unsigned long long ) m* md) >> W) ;
if ( t >= md) {
t - = md;
}
return t;
}
unsigned get( ) {
return reduce( val) ;
}
mint & operator+ = ( mint a) {
val + = a.val ;
if ( val >= md) {
val - = md;
}
return * this ;
}
mint & operator- = ( mint a) {
if ( val < a.val ) {
val = val + md - a.val ;
}
else {
val - = a.val ;
}
return * this ;
}
mint & operator* = ( mint a) {
val = reduce( ( unsigned long long ) val* a.val ) ;
return * this ;
}
mint & operator/ = ( mint a) {
return * this * = a.inverse ( ) ;
}
mint operator+ ( mint a) {
return mint( * this ) + = a;
}
mint operator- ( mint a) {
return mint( * this ) - = a;
}
mint operator* ( mint a) {
return mint( * this ) * = a;
}
mint operator/ ( mint a) {
return mint( * this ) / = a;
}
mint operator+ ( int a) {
return mint( * this ) + = mint( a) ;
}
mint operator- ( int a) {
return mint( * this ) - = mint( a) ;
}
mint operator* ( int a) {
return mint( * this ) * = mint( a) ;
}
mint operator/ ( int a) {
return mint( * this ) / = mint( a) ;
}
mint operator+ ( long long a) {
return mint( * this ) + = mint( a) ;
}
mint operator- ( long long a) {
return mint( * this ) - = mint( a) ;
}
mint operator* ( long long a) {
return mint( * this ) * = mint( a) ;
}
mint operator/ ( long long a) {
return mint( * this ) / = mint( a) ;
}
mint operator- ( void ) {
mint res;
if ( val) {
res.val = md- val;
}
else {
res.val = 0 ;
}
return res;
}
operator bool ( void ) {
return val! = 0 ;
}
operator int ( void ) {
return get( ) ;
}
operator long long ( void ) {
return get( ) ;
}
mint inverse( ) {
int a= val, b= md, t, u= 1 , v= 0 ;
mint res;
while ( b) {
t = a / b;
a - = t * b;
swap( a, b) ;
u - = t * v;
swap( u, v) ;
}
if ( u < 0 ) {
u + = md;
}
res.val = ( unsigned long long ) u* RR % md;
return res;
}
mint pw( unsigned long long b) {
mint a( * this ) , res;
res.val = R;
while ( b) {
if ( b& 1 ) {
res * = a;
}
b >>= 1 ;
a * = a;
}
return res;
}
bool operator== ( int a) {
return mulR( a) == val;
}
bool operator! = ( int a) {
return mulR( a) ! = val;
}
}
;
mint operator+ ( int a, mint b) {
return mint( a) + = b;
}
mint operator- ( int a, mint b) {
return mint( a) - = b;
}
mint operator* ( int a, mint b) {
return mint( a) * = b;
}
mint operator/ ( int a, mint b) {
return mint( a) / = b;
}
mint operator+ ( long long a, mint b) {
return mint( a) + = b;
}
mint operator- ( long long a, mint b) {
return mint( a) - = b;
}
mint operator* ( long long a, mint b) {
return mint( a) * = b;
}
mint operator/ ( long long a, mint b) {
return mint( a) / = b;
}
int Prime_L( int N, int res[ ] , void * mem= wmem) {
bool * isprime;
const int r= 23000 ;
int a, b, i, * sf, ss= 1 , sz= 1 ;
walloc1d( & isprime, r, & mem) ;
walloc1d( & sf, r, & mem) ;
isprime = ( bool * ) mem;
sf = ( int * ) ( isprime + r) ;
N / = 2 ;
res[ 0 ] = 2 ;
b = min_L( r, N) ;
for ( i= ( 1 ) ; i< ( b) ; i++ ) {
isprime[ i] = 1 ;
}
for ( i= ( 1 ) ; i< ( b) ; i++ ) {
if ( isprime[ i] ) {
res[ sz++ ] = 2 * i+ 1 ;
sf[ ss] = 2 * i* ( i+ 1 ) ;
if ( sf[ ss] < N) {
while ( sf[ ss] < r) {
isprime[ sf[ ss] ] = 0 ;
sf[ ss] + = res[ ss] ;
}
ss++ ;
}
}
}
for ( a= r; a< N; a+ = r) {
b = min_L( a + r, N) ;
isprime - = r;
for ( i= ( a) ; i< ( b) ; i++ ) {
isprime[ i] = 1 ;
}
for ( i= ( 1 ) ; i< ( ss) ; i++ ) {
while ( sf[ i] < b) {
isprime[ sf[ i] ] = 0 ;
sf[ i] + = res[ i] ;
}
}
for ( i= ( a) ; i< ( b) ; i++ ) {
if ( isprime[ i] ) {
res[ sz++ ] = 2 * i+ 1 ;
}
}
}
return sz;
}
char memarr[ 96000000 ] ;
unsigned mint:: R , mint:: RR , mint:: Rinv , mint:: W , mint:: md , mint:: mdninv ;
#define main dummy_main
int main( ) {
wmem = memarr;
{
mint x;
x.setmod ( MD) ;
}
return 0 ;
}
#undef main
int ps;
int p[ 101 ] ;
mint fact[ 101 ] ;
class Solution{
public :
int numPrimeArrangements( int n) {
int i;
dummy_main( ) ;
ps = Prime_L( n+ 1 , p) ;
fact[ 0 ] = 1 ;
for ( i= ( 1 ) ; i< ( n+ 1 ) ; i++ ) {
fact[ i] = fact[ i- 1 ] * i;
}
return fact[ ps] * fact[ n- ps] ;
}
}
;
// cLay varsion 20190830-1
// --- original code ---
// #define main dummy_main
// {}
// #undef main
//
// int ps, p[101];
// mint fact[101];
//
// class Solution {
// public:
// int numPrimeArrangements(int n) {
// dummy_main();
// ps = Prime(n+1, p);
// fact[0] = 1;
// rep(i,1,n+1) fact[i] = fact[i-1] * i;
// return fact[ps] * fact[n-ps];
// }
// };
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiNkZWZpbmUgTUQgMTAwMDAwMDAwNwp2b2lkICp3bWVtOwp0ZW1wbGF0ZTxjbGFzcyBTLCBjbGFzcyBUPiBpbmxpbmUgUyBtaW5fTChTIGEsVCBiKXsKICByZXR1cm4gYTw9Yj9hOmI7Cn0KdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIHZvaWQgd2FsbG9jMWQoVCAqKmFyciwgaW50IHgsIHZvaWQgKiptZW0gPSAmd21lbSl7CiAgc3RhdGljIGludCBza2lwWzE2XT17MCwgMTUsIDE0LCAxMywgMTIsIDExLCAxMCwgOSwgOCwgNywgNiwgNSwgNCwgMywgMiwgMX07CiAgKCptZW0pID0gKHZvaWQqKSggKChjaGFyKikoKm1lbSkpICsgc2tpcFsoKHVuc2lnbmVkIGxvbmcgbG9uZykoKm1lbSkpICYgMTVdICk7CiAgKCphcnIpPShUKikoKm1lbSk7CiAgKCptZW0pPSgoKmFycikreCk7Cn0Kc3RydWN0IG1pbnR7CiAgc3RhdGljIHVuc2lnbmVkIFIsIFJSLCBSaW52LCBXLCBtZCwgbWRuaW52OwogIHVuc2lnbmVkIHZhbDsKICBtaW50KCl7CiAgfQogIG1pbnQoaW50IGEpewogICAgdmFsID0gbXVsUihhKTsKICB9CiAgbWludCh1bnNpZ25lZCBhKXsKICAgIHZhbCA9IG11bFIoYSk7CiAgfQogIG1pbnQobG9uZyBsb25nIGEpewogICAgdmFsID0gbXVsUihhKTsKICB9CiAgbWludCh1bnNpZ25lZCBsb25nIGxvbmcgYSl7CiAgICB2YWwgPSBtdWxSKGEpOwogIH0KICBpbnQgZ2V0X2ludihsb25nIGxvbmcgYSwgaW50IG1kKXsKICAgIGxvbmcgbG9uZyBlLCBzPW1kLCB0PWEsIHU9MSwgdj0wOwogICAgd2hpbGUocyl7CiAgICAgIGU9dC9zOwogICAgICB0LT1lKnM7CiAgICAgIHUtPWUqdjsKICAgICAgc3dhcCh0LHMpOwogICAgICBzd2FwKHUsdik7CiAgICB9CiAgICBpZih1PDApewogICAgICB1Kz1tZDsKICAgIH0KICAgIHJldHVybiB1OwogIH0KICB2b2lkIHNldG1vZCh1bnNpZ25lZCBtKXsKICAgIGludCBpOwogICAgdW5zaWduZWQgdDsKICAgIFcgPSAzMjsKICAgIG1kID0gbTsKICAgIFIgPSAoMVVMTCA8PCBXKSAlIG1kOwogICAgUlIgPSAodW5zaWduZWQgbG9uZyBsb25nKVIqUiAlIG1kOwogICAgc3dpdGNoKG0pewogICAgICBjYXNlIDEwNDg1NzYwMToKICAgICAgUmludiA9IDI1NjAwMDA7CiAgICAgIG1kbmludiA9IDEwNDg1NzU5OTsKICAgICAgYnJlYWs7CiAgICAgIGNhc2UgOTk4MjQ0MzUzOgogICAgICBSaW52ID0gMjMyMDEzODI0OwogICAgICBtZG5pbnYgPSA5OTgyNDQzNTE7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwMDAwMDAwMDc6CiAgICAgIFJpbnYgPSA1MTg0MjQ3NzA7CiAgICAgIG1kbmludiA9IDIyMjY2MTc0MTdVOwogICAgICBicmVhazsKICAgICAgY2FzZSAxMDAwMDAwMDA5OgogICAgICBSaW52ID0gMTcxNjAxOTk5OwogICAgICBtZG5pbnYgPSA3MzcwMjQ5Njc7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwMDQ1MzU4MDk6CiAgICAgIFJpbnYgPSAyMzQ5NDc1ODQ7CiAgICAgIG1kbmludiA9IDEwMDQ1MzU4MDc7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwMDc2ODE1Mzc6CiAgICAgIFJpbnYgPSAyMzY0MjEzNzY7CiAgICAgIG1kbmludiA9IDEwMDc2ODE1MzU7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwMTI5MjQ0MTc6CiAgICAgIFJpbnYgPSAyMzg4ODc5MzY7CiAgICAgIG1kbmludiA9IDEwMTI5MjQ0MTU7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwNDU0MzAyNzM6CiAgICAgIFJpbnYgPSAyNTQ0NjYzMDQ7CiAgICAgIG1kbmludiA9IDEwNDU0MzAyNzE7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwNTE3MjE3Mjk6CiAgICAgIFJpbnYgPSAyNTc1MzgzMDQ7CiAgICAgIG1kbmludiA9IDEwNTE3MjE3Mjc7CiAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICBSaW52ID0gZ2V0X2ludihSLCBtZCk7CiAgICAgIG1kbmludiA9IDA7CiAgICAgIHQgPSAwOwogICAgICBmb3IoaT0wO2k8KChpbnQpVyk7aSsrKXsKICAgICAgICBpZih0JTI9PTApewogICAgICAgICAgdCs9bWQ7CiAgICAgICAgICBtZG5pbnYgfD0gKDFVPDxpKTsKICAgICAgICB9CiAgICAgICAgdCAvPSAyOwogICAgICB9CiAgICB9CiAgfQogIHVuc2lnbmVkIG11bFIodW5zaWduZWQgYSl7CiAgICByZXR1cm4gKHVuc2lnbmVkIGxvbmcgbG9uZylhKlIlbWQ7CiAgfQogIHVuc2lnbmVkIG11bFIoaW50IGEpewogICAgaWYoYSA8IDApewogICAgICBhID0gYSUoKGludCltZCkrKGludCltZDsKICAgIH0KICAgIHJldHVybiBtdWxSKCh1bnNpZ25lZClhKTsKICB9CiAgdW5zaWduZWQgbXVsUih1bnNpZ25lZCBsb25nIGxvbmcgYSl7CiAgICByZXR1cm4gbXVsUigodW5zaWduZWQpKGElbWQpKTsKICB9CiAgdW5zaWduZWQgbXVsUihsb25nIGxvbmcgYSl7CiAgICBhICU9IG1kOwogICAgaWYoYSA8IDApewogICAgICBhICs9IG1kOwogICAgfQogICAgcmV0dXJuIG11bFIoKHVuc2lnbmVkKWEpOwogIH0KICB1bnNpZ25lZCByZWR1Y2UodW5zaWduZWQgVCl7CiAgICB1bnNpZ25lZCBtPVQgKiBtZG5pbnYsIHQ9KHVuc2lnbmVkKSgoVCArICh1bnNpZ25lZCBsb25nIGxvbmcpbSptZCkgPj4gVyk7CiAgICBpZih0ID49IG1kKXsKICAgICAgdCAtPSBtZDsKICAgIH0KICAgIHJldHVybiB0OwogIH0KICB1bnNpZ25lZCByZWR1Y2UodW5zaWduZWQgbG9uZyBsb25nIFQpewogICAgdW5zaWduZWQgbT0odW5zaWduZWQpVCAqIG1kbmludiwgdD0odW5zaWduZWQpKChUICsgKHVuc2lnbmVkIGxvbmcgbG9uZyltKm1kKSA+PiBXKTsKICAgIGlmKHQgPj0gbWQpewogICAgICB0IC09IG1kOwogICAgfQogICAgcmV0dXJuIHQ7CiAgfQogIHVuc2lnbmVkIGdldCgpewogICAgcmV0dXJuIHJlZHVjZSh2YWwpOwogIH0KICBtaW50ICZvcGVyYXRvcis9KG1pbnQgYSl7CiAgICB2YWwgKz0gYS52YWw7CiAgICBpZih2YWwgPj0gbWQpewogICAgICB2YWwgLT0gbWQ7CiAgICB9CiAgICByZXR1cm4gKnRoaXM7CiAgfQogIG1pbnQgJm9wZXJhdG9yLT0obWludCBhKXsKICAgIGlmKHZhbCA8IGEudmFsKXsKICAgICAgdmFsID0gdmFsICsgbWQgLSBhLnZhbDsKICAgIH0KICAgIGVsc2V7CiAgICAgIHZhbCAtPSBhLnZhbDsKICAgIH0KICAgIHJldHVybiAqdGhpczsKICB9CiAgbWludCAmb3BlcmF0b3IqPShtaW50IGEpewogICAgdmFsID0gcmVkdWNlKCh1bnNpZ25lZCBsb25nIGxvbmcpdmFsKmEudmFsKTsKICAgIHJldHVybiAqdGhpczsKICB9CiAgbWludCAmb3BlcmF0b3IvPShtaW50IGEpewogICAgcmV0dXJuICp0aGlzICo9IGEuaW52ZXJzZSgpOwogIH0KICBtaW50IG9wZXJhdG9yKyhtaW50IGEpewogICAgcmV0dXJuIG1pbnQoKnRoaXMpKz1hOwogIH0KICBtaW50IG9wZXJhdG9yLShtaW50IGEpewogICAgcmV0dXJuIG1pbnQoKnRoaXMpLT1hOwogIH0KICBtaW50IG9wZXJhdG9yKihtaW50IGEpewogICAgcmV0dXJuIG1pbnQoKnRoaXMpKj1hOwogIH0KICBtaW50IG9wZXJhdG9yLyhtaW50IGEpewogICAgcmV0dXJuIG1pbnQoKnRoaXMpLz1hOwogIH0KICBtaW50IG9wZXJhdG9yKyhpbnQgYSl7CiAgICByZXR1cm4gbWludCgqdGhpcykrPW1pbnQoYSk7CiAgfQogIG1pbnQgb3BlcmF0b3ItKGludCBhKXsKICAgIHJldHVybiBtaW50KCp0aGlzKS09bWludChhKTsKICB9CiAgbWludCBvcGVyYXRvciooaW50IGEpewogICAgcmV0dXJuIG1pbnQoKnRoaXMpKj1taW50KGEpOwogIH0KICBtaW50IG9wZXJhdG9yLyhpbnQgYSl7CiAgICByZXR1cm4gbWludCgqdGhpcykvPW1pbnQoYSk7CiAgfQogIG1pbnQgb3BlcmF0b3IrKGxvbmcgbG9uZyBhKXsKICAgIHJldHVybiBtaW50KCp0aGlzKSs9bWludChhKTsKICB9CiAgbWludCBvcGVyYXRvci0obG9uZyBsb25nIGEpewogICAgcmV0dXJuIG1pbnQoKnRoaXMpLT1taW50KGEpOwogIH0KICBtaW50IG9wZXJhdG9yKihsb25nIGxvbmcgYSl7CiAgICByZXR1cm4gbWludCgqdGhpcykqPW1pbnQoYSk7CiAgfQogIG1pbnQgb3BlcmF0b3IvKGxvbmcgbG9uZyBhKXsKICAgIHJldHVybiBtaW50KCp0aGlzKS89bWludChhKTsKICB9CiAgbWludCBvcGVyYXRvci0odm9pZCl7CiAgICBtaW50IHJlczsKICAgIGlmKHZhbCl7CiAgICAgIHJlcy52YWw9bWQtdmFsOwogICAgfQogICAgZWxzZXsKICAgICAgcmVzLnZhbD0wOwogICAgfQogICAgcmV0dXJuIHJlczsKICB9CiAgb3BlcmF0b3IgYm9vbCh2b2lkKXsKICAgIHJldHVybiB2YWwhPTA7CiAgfQogIG9wZXJhdG9yIGludCh2b2lkKXsKICAgIHJldHVybiBnZXQoKTsKICB9CiAgb3BlcmF0b3IgbG9uZyBsb25nKHZvaWQpewogICAgcmV0dXJuIGdldCgpOwogIH0KICBtaW50IGludmVyc2UoKXsKICAgIGludCBhPXZhbCwgYj1tZCwgdCwgdT0xLCB2PTA7CiAgICBtaW50IHJlczsKICAgIHdoaWxlKGIpewogICAgICB0ID0gYSAvIGI7CiAgICAgIGEgLT0gdCAqIGI7CiAgICAgIHN3YXAoYSwgYik7CiAgICAgIHUgLT0gdCAqIHY7CiAgICAgIHN3YXAodSwgdik7CiAgICB9CiAgICBpZih1IDwgMCl7CiAgICAgIHUgKz0gbWQ7CiAgICB9CiAgICByZXMudmFsID0gKHVuc2lnbmVkIGxvbmcgbG9uZyl1KlJSICUgbWQ7CiAgICByZXR1cm4gcmVzOwogIH0KICBtaW50IHB3KHVuc2lnbmVkIGxvbmcgbG9uZyBiKXsKICAgIG1pbnQgYSgqdGhpcyksIHJlczsKICAgIHJlcy52YWwgPSBSOwogICAgd2hpbGUoYil7CiAgICAgIGlmKGImMSl7CiAgICAgICAgcmVzICo9IGE7CiAgICAgIH0KICAgICAgYiA+Pj0gMTsKICAgICAgYSAqPSBhOwogICAgfQogICAgcmV0dXJuIHJlczsKICB9CiAgYm9vbCBvcGVyYXRvcj09KGludCBhKXsKICAgIHJldHVybiBtdWxSKGEpPT12YWw7CiAgfQogIGJvb2wgb3BlcmF0b3IhPShpbnQgYSl7CiAgICByZXR1cm4gbXVsUihhKSE9dmFsOwogIH0KfQo7Cm1pbnQgb3BlcmF0b3IrKGludCBhLCBtaW50IGIpewogIHJldHVybiBtaW50KGEpKz1iOwp9Cm1pbnQgb3BlcmF0b3ItKGludCBhLCBtaW50IGIpewogIHJldHVybiBtaW50KGEpLT1iOwp9Cm1pbnQgb3BlcmF0b3IqKGludCBhLCBtaW50IGIpewogIHJldHVybiBtaW50KGEpKj1iOwp9Cm1pbnQgb3BlcmF0b3IvKGludCBhLCBtaW50IGIpewogIHJldHVybiBtaW50KGEpLz1iOwp9Cm1pbnQgb3BlcmF0b3IrKGxvbmcgbG9uZyBhLCBtaW50IGIpewogIHJldHVybiBtaW50KGEpKz1iOwp9Cm1pbnQgb3BlcmF0b3ItKGxvbmcgbG9uZyBhLCBtaW50IGIpewogIHJldHVybiBtaW50KGEpLT1iOwp9Cm1pbnQgb3BlcmF0b3IqKGxvbmcgbG9uZyBhLCBtaW50IGIpewogIHJldHVybiBtaW50KGEpKj1iOwp9Cm1pbnQgb3BlcmF0b3IvKGxvbmcgbG9uZyBhLCBtaW50IGIpewogIHJldHVybiBtaW50KGEpLz1iOwp9CmludCBQcmltZV9MKGludCBOLCBpbnQgcmVzW10sIHZvaWQgKm1lbT13bWVtKXsKICBib29sICppc3ByaW1lOwogIGNvbnN0IGludCByPTIzMDAwOwogIGludCBhLCBiLCBpLCAqc2YsIHNzPTEsIHN6PTE7CiAgd2FsbG9jMWQoJmlzcHJpbWUsIHIsICZtZW0pOwogIHdhbGxvYzFkKCZzZiwgciwgJm1lbSk7CiAgaXNwcmltZSA9IChib29sKiltZW07CiAgc2YgPSAoaW50KikoaXNwcmltZSArIHIpOwogIE4gLz0gMjsKICByZXNbMF0gPSAyOwogIGIgPW1pbl9MKHIsIE4pOwogIGZvcihpPSgxKTtpPChiKTtpKyspewogICAgaXNwcmltZVtpXSA9IDE7CiAgfQogIGZvcihpPSgxKTtpPChiKTtpKyspewogICAgaWYoaXNwcmltZVtpXSl7CiAgICAgIHJlc1tzeisrXSA9IDIqaSsxOwogICAgICBzZltzc10gPSAyKmkqKGkrMSk7CiAgICAgIGlmKHNmW3NzXSA8IE4pewogICAgICAgIHdoaWxlKHNmW3NzXSA8IHIpewogICAgICAgICAgaXNwcmltZVtzZltzc11dID0gMDsKICAgICAgICAgIHNmW3NzXSArPSByZXNbc3NdOwogICAgICAgIH0KICAgICAgICBzcysrOwogICAgICB9CiAgICB9CiAgfQogIGZvcihhPXI7IGE8TjsgYSs9cil7CiAgICBiID1taW5fTChhICsgciwgTik7CiAgICBpc3ByaW1lIC09IHI7CiAgICBmb3IoaT0oYSk7aTwoYik7aSsrKXsKICAgICAgaXNwcmltZVtpXSA9IDE7CiAgICB9CiAgICBmb3IoaT0oMSk7aTwoc3MpO2krKyl7CiAgICAgIHdoaWxlKHNmW2ldIDwgYil7CiAgICAgICAgaXNwcmltZVtzZltpXV0gPSAwOwogICAgICAgIHNmW2ldICs9IHJlc1tpXTsKICAgICAgfQogICAgfQogICAgZm9yKGk9KGEpO2k8KGIpO2krKyl7CiAgICAgIGlmKGlzcHJpbWVbaV0pewogICAgICAgIHJlc1tzeisrXSA9IDIqaSsxOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBzejsKfQpjaGFyIG1lbWFycls5NjAwMDAwMF07CnVuc2lnbmVkIG1pbnQ6OlIsIG1pbnQ6OlJSLCBtaW50OjpSaW52LCBtaW50OjpXLCBtaW50OjptZCwgbWludDo6bWRuaW52OwojZGVmaW5lIG1haW4gZHVtbXlfbWFpbgppbnQgbWFpbigpewogIHdtZW0gPSBtZW1hcnI7CiAgewogICAgbWludCB4OwogICAgeC5zZXRtb2QoTUQpOwogIH0KICByZXR1cm4gMDsKfQojdW5kZWYgbWFpbgppbnQgcHM7CmludCBwWzEwMV07Cm1pbnQgZmFjdFsxMDFdOwpjbGFzcyBTb2x1dGlvbnsKICBwdWJsaWM6CiAgaW50IG51bVByaW1lQXJyYW5nZW1lbnRzKGludCBuKXsKICAgIGludCBpOwogICAgZHVtbXlfbWFpbigpOwogICAgcHMgPVByaW1lX0wobisxLCBwKTsKICAgIGZhY3RbMF0gPSAxOwogICAgZm9yKGk9KDEpO2k8KG4rMSk7aSsrKXsKICAgICAgZmFjdFtpXSA9IGZhY3RbaS0xXSAqIGk7CiAgICB9CiAgICByZXR1cm4gZmFjdFtwc10gKiBmYWN0W24tcHNdOwogIH0KfQo7Ci8vIGNMYXkgdmFyc2lvbiAyMDE5MDgzMC0xCgovLyAtLS0gb3JpZ2luYWwgY29kZSAtLS0KLy8gI2RlZmluZSBtYWluIGR1bW15X21haW4KLy8ge30KLy8gI3VuZGVmIG1haW4KLy8gCi8vIGludCBwcywgcFsxMDFdOwovLyBtaW50IGZhY3RbMTAxXTsKLy8gCi8vIGNsYXNzIFNvbHV0aW9uIHsKLy8gcHVibGljOgovLyAgIGludCBudW1QcmltZUFycmFuZ2VtZW50cyhpbnQgbikgewovLyAgICAgZHVtbXlfbWFpbigpOwovLyAgICAgcHMgPSBQcmltZShuKzEsIHApOwovLyAgICAgZmFjdFswXSA9IDE7Ci8vICAgICByZXAoaSwxLG4rMSkgZmFjdFtpXSA9IGZhY3RbaS0xXSAqIGk7Ci8vICAgICByZXR1cm4gZmFjdFtwc10gKiBmYWN0W24tcHNdOwovLyAgIH0KLy8gfTsK