#include <iostream>
#include <string.h>
using namespace std;
#define DIGIT 4
#define DEPTH 10000
#define MAX 1000
typedef int bign_t[MAX+1];
#ifndef ms
#define ms(x , y) (memset(x , y , sizeof(x)))
#endif // memset
#ifndef mcp
#define mcp(x , y) (memcpy(x , y , sizeof(y)))
#endif // memcpy
#define SGN(x) ( (x)>0 ? 1 : ( (x)<0 ? -1 : 0) )
#define ABS(x) ( (x)>0 ? (x) : -(x) )
///*********************************大整数类封装*********************************************** ///
///**********************************使用说明***************************************************///
/// 1. 前 三 个 comp 函 数 和 add、sub 是 必 须 的 ///
/// 2. + - 需 要 add 和 sub ///
/// 3. * 需 要 mul ///
/// 4. / % 需 要 div ///
/// 5.length、zeronum、digit是 独 立 的 ///
/// 6.convert 需 要 mul ///
/// 7.排 列 组 合 需 要 第 四 个 comp 和 convert ///
/// 8.注 意 使 用 了 宏 定 义 ms 和 mcp ( 如 上 ) ///
/// 9.注 意 初 始 化 不 能 bign a=x; ///
/// 10.注 意 不 要 bign a;a=1212121212121212112121212121;(自己理解) ///
///**********************************************************************************************///
///****************************原始代码摘自互联网***********************************************///
///******************** 代 码 可 读 性 优 化 lc思念·落叶***************************************///
///**********************************************************************************************///
///*****************************优 化 说 明*****************************************************///
/// 1. 重 整 代 码 风 格 ///
/// 2. 比 较 运 算 部 分 代 码 重 写 ///
/// 3. 缩 减 代 码 量 ///
/// 4. 加 入 注 释 ///
/// 5. 删 除 了 一 部 分 代 码 ///
///*********************************************************************************************///
///************************** lc思念·落叶 2014-08-27 **************************************///
///*********************************************************************************************///
///以下三个 comp 函数 必须
int comp(const bign_t a , const bign_t b)
{
int i;
if (a[0]!=b[0])
return a[0]-b[0];
for (i=a[0] ; i ; i--)
if (a[i]!=b[i])
return a[i]-b[i];
return 0;
}
int comp(const bign_t a , const int b)
{
int c[12]={1};
for (c[1]=b ; c[c[0]]>=DEPTH ; c[c[0]+1]=c[c[0]]/DEPTH , c[c[0]]%=DEPTH , c[0]++);
return comp(a , c);
}
int comp(const bign_t a , const int c , const int d , const bign_t b)
{
int i , t=0 , x=-DEPTH*2;
if (b[0]-a[0]<d&&c)
return 1;
for (i=b[0] ; i>d ; i--)
{
t=t*DEPTH+a[i-d]*c-b[i];
if (t>0) return 1;
if (t<x) return 0;
}
for (i=d ; i ; i--)
{
t=t*DEPTH-b[i];
if (t>0) return 1;
if (t<x) return 0;
}
return t>0;
}
/// + - / %需要add * 不需要add
void add(bign_t a , const bign_t b)
{
int i;
for (i=1 ; i<=b[0] ; i++)
if ((a[i]+=b[i])>=DEPTH)
a[i]-=DEPTH , a[i+1]++;
if (b[0]>=a[0])
a[0]=b[0];
else
for ( ; a[i]>=DEPTH&&i<a[0] ; a[i]-=DEPTH , i++ , a[i]++);
a[0]+=(a[a[0]+1]>0);
}
void add(bign_t a , const int b)
{
int i=1;
for (a[1]+=b ; a[i]>=DEPTH&&i<a[0] ; a[i+1]+=a[i]/DEPTH , a[i]%=DEPTH , i++);
for ( ; a[a[0]]>=DEPTH ; a[a[0]+1]=a[a[0]]/DEPTH , a[a[0]]%=DEPTH , a[0]++);
}
/// + - / %需要sub
void sub(bign_t a , const bign_t b)
{
int i;
for (i=1 ; i<=b[0] ; i++)
if ((a[i]-=b[i])<0)
a[i+1]-- , a[i]+=DEPTH;
for ( ; a[i]<0 ; a[i]+=DEPTH , i++ , a[i]--);
for ( ; !a[a[0]]&&a[0]>1 ; a[0]--);
}
void sub(bign_t a , const int b)
{
int i=1;
for (a[1]-=b ; a[i]<0 ; a[i+1]+=(a[i]-DEPTH+1)/DEPTH , a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH , i++);
for ( ; !a[a[0]]&&a[0]>1 ; a[0]--);
}
void sub(bign_t a , const bign_t b , const int c , const int d)
{
int i , x=b[0]+d;
for (i=1+d ; i<=x ; i++)
if ((a[i]-=b[i-d]*c)<0)
a[i+1]+=(a[i]-DEPTH+1)/DEPTH , a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH;
for ( ; a[i]<0 ; a[i+1]+=(a[i]-DEPTH+1)/DEPTH , a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH , i++);
for ( ; !a[a[0]]&&a[0]>1 ; a[0]--);
}
/// 只有乘法需要 mul
void mul(bign_t c , const bign_t a , const bign_t b)
{
int i , j;
ms(c , 0);
for (c[0]=a[0]+b[0]-1 , i=1 ; i<=a[0] ; i++)
for (j=1 ; j<=b[0] ; j++)
if ((c[i+j-1]+=a[i]*b[j])>=DEPTH)
c[i+j]+=c[i+j-1]/DEPTH , c[i+j-1]%=DEPTH;
for (c[0]+=(c[c[0]+1]>0) ; !c[c[0]]&&c[0]>1 ; c[0]--);
}
void mul(bign_t a , const int b)
{
int i;
for (a[1]*=b , i=2 ; i<=a[0] ; i++)
{
a[i]*=b;
if (a[i-1]>=DEPTH)
a[i]+=a[i-1]/DEPTH , a[i-1]%=DEPTH;
}
for ( ; a[a[0]]>=DEPTH ; a[a[0]+1]=a[a[0]]/DEPTH , a[a[0]]%=DEPTH , a[0]++);
for ( ; !a[a[0]]&&a[0]>1 ; a[0]--);
}
void mul(bign_t b , const bign_t a , const int c , const int d)
{
int i;
ms(b , 0);
for (b[0]=a[0]+d , i=d+1 ; i<=b[0] ; i++)
if ((b[i]+=a[i-d]*c)>=DEPTH)
b[i+1]+=b[i]/DEPTH , b[i]%=DEPTH;
for ( ; b[b[0]+1] ; b[0]++ , b[b[0]+1]=b[b[0]]/DEPTH , b[b[0]]%=DEPTH);
for ( ; !b[b[0]]&&b[0]>1 ; b[0]--);
}
/// / %需要div
void div(bign_t c , bign_t a , const bign_t b)
{
int h , l , m , i;
ms(c , 0);
c[0]= (b[0]<a[0]+1) ? (a[0]-b[0]+2) : 1;
for (i=c[0] ; i ; sub(a , b , c[i]=m , i-1) , i--)
for (h=DEPTH-1 , l=0 , m=(h+l+1)>>1 ; h>l ; m=(h+l+1)>>1)
if (comp(b , m , i-1 , a)) h=m-1;
else l=m;
for ( ; !c[c[0]]&&c[0]>1 ; c[0]--);
c[0]= c[0]>1 ? c[0] : 1 ;
}
void div(bign_t a , const int b , int& c)
{
int i;
for (c=0 , i=a[0] ; i;c=c*DEPTH+a[i] , a[i]=c/b , c%=b , i--);
for ( ; !a[a[0]]&&a[0]>1 ; a[0]--);
}
int length(const bign_t a)
{
int t , ret;
for (ret=(a[0]-1)*DIGIT , t=a[a[0]] ; t ; t/=10 , ret++);
return ret>0 ? ret : 1;
}
int digit(const bign_t a , const int b)
{
int i , ret;
for (ret=a[(b-1)/DIGIT+1] , i=(b-1)%DIGIT ; i ; ret/=10 , i--);
return ret%10;
}
int zeronum(const bign_t a)
{
int ret , t;
for (ret=0 ; !a[ret+1] ; ret++);
for (t=a[ret+1] , ret*=DIGIT ; !(t%10) ; t/=10 , ret++);
return ret;
}
void convert(int* a , const int h , bign_t b)
{
int i , j , t=1;
ms(b , 0);
for (b[0]=b[1]=1 , i=2 ; i<=h ; i++)
if (a[i])
for (j=a[i] ; j ; t*=i , j--)
if (t*i>DEPTH)
mul(b , t) , t=1;
mul(b , t);
}
void comp(int* a , const int l , const int h , const int d)
{
int i , j , t;
for (i=l ; i<=h ; i++)
for (t=i , j=2 ; t>1 ; j++)
while (!(t%j))
a[j]+=d , t/=j;
}
void combination(bign_t a , int m , int n)
{
int* t=new int[m+1];
ms(t , 0);
comp(t , n+1 , m , 1);
comp(t , 2 , m-n , -1);
convert(t , m , a);
delete []t;
}
void permutation(bign_t a , int m , int n)
{
int i , t=1;
ms(a , 0);
a[0]=a[1]=1;
for (i=m-n+1 ; i<=m ; t*=i++)
if (t*i>DEPTH)
mul(a , t) , t=1;
mul(a , t);
}
int read(bign_t a , int &sgn , istream& is=cin)
{
char str[MAX*DIGIT+2] , ch , *buf;
int i , j;
ms(a , 0);
if (!(is>>str)) return 0;
buf=str , sgn=1;
if (*buf=='-') sgn=-1 , buf++;
int L=strlen(buf);
for (a[0]=L , i=a[0]/2-1 ; i>=0 ; i--)
swap(buf[i] , buf[a[0]-1-i]);
for (a[0]=(a[0]+DIGIT-1)/DIGIT , j=L ; j<a[0]*DIGIT ; buf[j++]='0');
for (i=1 ; i<=a[0] ; i++)
for (a[i]=0 , j=0 ; j<DIGIT ; j++)
a[i]=a[i]*10+buf[i*DIGIT-1-j]-'0';
for ( ; !a[a[0]]&&a[0]>1 ; a[0]--);
if (a[0]==1&&!a[1]) sgn=0;
return 1;
}
void write(const bign_t a , ostream& os=cout)
{
int i , j;
for (os<<a[i=a[0]] , i-- ; i ; i--)
for (j=DEPTH/10 ; j ; j/=10)
os<<a[i]/j%10;
}
struct bign{
bign_t num;
int sgn;
public:
inline bign()/// 必要的 生成函数 不能省略
{
ms(num , 0);
num[0]=1;
sgn=0;
}
inline int operator!()/// 应用于布尔运算 不需任何函数
{
return num[0]==1&&!num[1];
}
inline bign& operator=(const bign& a)///必须的 拷贝复制函数
{
mcp(num , a.num);
sgn=a.sgn;
return *this;
}
inline bign& operator=(const int a)///必须的 拷贝复制函数 需要add
{
ms(num , 0);
num[0]=1;
sgn=SGN(a);
add(num , sgn*a);
return *this;
}
inline bign& operator+=(const bign& a)
/// +=函数 需要 add、comp、sub
{
if(sgn==a.sgn)
add(num , a.num);
else if(sgn&&a.sgn)
{
int ret=comp(num , a.num);
if(ret>0)sub(num , a.num);
else if(ret<0)
{
bign_t t;
mcp(t , num);
mcp(num , a.num);
sub(num , t);
sgn=a.sgn;
}
else
ms(num , 0) , num[0]=1 , sgn=0;
}
else if(!sgn)
mcp(num , a.num) , sgn=a.sgn;
return *this;
}
inline bign& operator+=(const int a)
///+=函数 需要 add、comp、sub
{
if(sgn*a>0)add(num , ABS(a));
else if(sgn&&a)
{
int ret=comp(num , ABS(a));
if(ret>0)sub(num , ABS(a));
else if(ret<0)
{
bign_t t;
mcp(t , num);
ms(num , 0);
num[0]=1;
add(num , ABS(a));
sgn=-sgn;
sub(num , t);
}
else
ms(num , 0) , num[0]=1 , sgn=0;
}
else if(!sgn)
sgn=SGN(a) , add(num , ABS(a));
return *this;
}
inline bign operator+(const bign& a)
///+函数 需要+=
{
bign ret;
mcp(ret.num , num);
ret.sgn=sgn;
ret+=a;
return ret;
}
inline bign operator+(const int a)
///+函数 需要+= (直接复制上面的内容即可)
{
bign ret;
mcp(ret.num , num);
ret.sgn=sgn;
ret+=a;
return ret;
}
inline bign& operator-=(const bign& a)
///-=函数 需要 add、comp、sub
{
if(sgn*a.sgn<0)add(num , a.num);
else if(sgn&&a.sgn)
{
int ret=comp(num , a.num);
if(ret>0)sub(num , a.num);
else if(ret<0)
{
bign_t t;
mcp(t , num);
mcp(num , a.num);
sub(num , t);
sgn=-sgn;
}
else
ms(num , 0) , num[0]=1 , sgn=0;
}
else if(!sgn)
add(num , a.num) , sgn=-a.sgn;
return *this;
}
inline bign& operator-=(const int a)
///-=函数 需要 add、comp、sub
{
if(sgn*a<0)add(num , ABS(a));
else if(sgn&&a)
{
int ret=comp(num , ABS(a));
if(ret>0)sub(num , ABS(a));
else if(ret<0)
{
bign_t t;
mcp(t , num);
ms(num , 0);
num[0]=1;
add(num , ABS(a));
sub(num , t);
sgn=-sgn;
}
else ms(num , 0) , num[0]=1 , sgn=0;
}
else if(!sgn)
sgn=-SGN(a) , add(num , ABS(a));
return *this;
}
inline bign operator-(const bign& a)
///-函数 需要-=
{
bign ret;
mcp(ret.num , num);
ret.sgn=sgn;
ret-=a;
return ret;
}
inline bign operator-(const int a)
///-函数 需要-= (复制上边即可)
{
bign ret;
mcp(ret.num , num);
ret.sgn=sgn;
ret-=a;
return ret;
}
inline bign& operator*=(const bign& a)
///*= 只需mul
{
bign_t t;
mul(t , num , a.num);
mcp(num , t);
sgn*=a.sgn;
return *this;
}
inline bign& operator*=(const int a)
///*= 只需mul
{
mul(num , ABS(a));
sgn*=SGN(a);
return *this;
}
inline bign operator*(const bign& a)
///* 只需mul
{
bign ret;
mul(ret.num , num , a.num);
ret.sgn=sgn*a.sgn;
return ret;
}
inline bign operator*(const int a)
///*= 只需mul
{
bign ret;
mcp(ret.num , num);
mul(ret.num , ABS(a));
ret.sgn=sgn*SGN(a);
return ret;
}
inline bign& operator/=(const bign& a)
/// /= 只需div
{
bign_t t;
div(t , num , a.num);
mcp(num , t);
sgn=(num[0]==1&&!num[1])?0:sgn*a.sgn;
return *this;
}
inline bign& operator/=(const int a)
/// /= 只需div
{
int t;
div(num , ABS(a) , t);
sgn=(num[0]==1&&!num[1])?0:sgn*SGN(a);
return *this;
}
inline bign operator/(const bign& a)
/// / 只需div
{
bign ret;
bign_t t;
mcp(t , num);
div(ret.num , t , a.num);
ret.sgn=(ret.num[0]==1&&!ret.num[1])?0:sgn*a.sgn;
return ret;
}
inline bign operator/(const int a)
/// / 只需div
{
bign ret;
int t;
mcp(ret.num , num);
div(ret.num , ABS(a) , t);
ret.sgn=(ret.num[0]==1&&!ret.num[1])?0:sgn*SGN(a);
return ret;
}
inline bign& operator%=(const bign& a)
/// %= 只需div
{
bign_t t;
div(t , num , a.num);
if (num[0]==1&&!num[1])sgn=0;
return *this;
}
inline int operator%=(const int a)
/// %= 需div , add
{
int t;
div(num , ABS(a) , t);
ms(num , 0);
num[0]=1;
add(num , t);
return t;
}
inline bign operator%(const bign& a)
/// % 只需div
{
bign ret;
bign_t t;
mcp(ret.num , num);
div(t , ret.num , a.num);
ret.sgn=(ret.num[0]==1&&!ret.num[1])?0:sgn;
return ret;
}
inline int operator%(const int a)
/// % 需要div、add
{
bign ret;
int t;
mcp(ret.num , num);
div(ret.num , ABS(a) , t);
ms(ret.num , 0);
ret.num[0]=1;
add(ret.num , t);
return t;
}
/// ++和-- ///
inline bign& operator++(){*this+=1;return *this;}
inline bign& operator--(){*this-=1;return *this;}
///比较运算///
///需要comp///
inline int operator>(const bign& a)
{
return sgn>0 ?
(a.sgn>0 ? comp(num , a.num)>0 : 1) :
(sgn<0 ? ( a.sgn<0 ? comp(num , a.num)<0 : 0) : a.sgn<0 );
}
inline int operator>(const int a)
{
return sgn>0 ?
(a>0 ? comp(num , a)>0 : 1) :
( sgn<0 ? ( a<0 ? comp(num , -a)<0 : 0) : a<0 );
}
inline int operator>=(const bign& a)
{
return sgn>0 ?
(a.sgn>0 ? comp(num , a.num)>=0 : 1) :
(sgn<0 ? (a.sgn<0?comp(num , a.num)<=0 : 0) : a.sgn<=0);
}
inline int operator>=(const int a)
{
return sgn>0 ?
(a>0 ? comp(num , a)>=0 : 1) :
(sgn<0 ? (a<0?comp(num , -a)<=0 : 0) : a<=0);
}
inline int operator<(const bign& a)
{
return !((*this)>=a);
}
inline int operator<(const int a)
{
return !((*this)>=a);
}
inline int operator<=(const bign& a)
{
return !((*this)>a);
}
inline int operator<=(const int a)
{
return !((*this)>a);
}
inline int operator==(const bign& a)
{
return ((*this)>=a)&&((*this)<=a);
}
inline int operator==(const int a)
{
return ((*this)>=a)&&((*this)<=a);
}
inline int operator!=(const bign& a)
{
return !((*this)==a);
}
inline int operator!=(const int a)
{
return !((*this)==a);
}
/// 重载[]表示第i位上的数字(从个位(1)开始) 需要digit函数
inline int operator[](const int a)
{
return digit(num , a);
}
///重载输入输出函数 需要read、write
friend inline istream& operator>>(istream& is , bign& a)
{
read(a.num , a.sgn , is);
return is;
}
friend inline ostream& operator<<(ostream& os , const bign& a)
{
if(a.sgn<0)os<<'-';
write(a.num , os);
return os;
}
///以下函数注意使用方式 a.f(); 不要f(a);///
inline int length(){return ::length(num);}///计算位数
inline int zeronum(){return ::zeronum(num);}///计算尾零数
inline bign C(const int m , const int n){combination(num , m , n);sgn=1;return *this;}
///a=C(m , n);
inline bign P(const int m , const int n){permutation(num , m , n);sgn=1;return *this;}
///a=A(m , n);
};