const int MAXSIZE=1000;
struct bign
{
int len,s[MAXSIZE];
bool sign;
bign() {memset(s,0,sizeof(s));len=1;sign=1;}
bign(const char *num) {*this=num;}
bign(int num) {*this=num;}
string toStr() const
{
string res;
res = "";
for(int i=0;i<len;i++)
res=(char)(s[i]+'0')+res;
if(res=="")
res="0";
if(!sign&&res!="0")
res="-"+res;
return res;
}
friend istream &operator >> (istream &in,bign &num)
{
string str;
in>>str;
num=str;
return in;
}
friend ostream &operator << (ostream &out,bign &num)
{
out<<num.toStr();
return out;
}
bign operator = (const char *num)
{
memset(s,0,sizeof(s));
char a[1000]="";
if(num[0]!='-')
strcpy(a,num);
else
for(int i=1,tlen=strlen(num);i<tlen;i++)
a[i-1]=num[i];
sign=!(num[0]=='-');
len=strlen(a);
for(int i=0,tlen=strlen(a);i<tlen;i++)
s[i]=a[len-i-1]-'0';
return *this;
}
bign operator = (int num)
{
char temp[1000];
sprintf(temp,"%d",num);
*this=temp;
return *this;
}
bign operator = (const string num)
{
const char *tmp;
tmp=num.c_str();
*this=tmp;
return *this;
}
bool operator > (const bign &num) const {return num<*this;}
bool operator >= (const bign &num) const {return !(*this<num);}
bool operator < (const bign &num) const
{
if(sign^num.sign)
return num.sign;
if(len!=num.len)
return len<num.len;
for(int i=len-1;i>=0;i--)
if(s[i]!=num.s[i])
return sign? (s[i]<num.s[i]):(!(s[i]<num.s[i]));
return !sign;
}
bool operator <= (const bign &num) const {return !(*this>num);}
bool operator == (const bign &num) const {return !(num!=*this);}
bool operator != (const bign &num) const {return *this>num||*this<num;}
bign operator + (const bign &num) const
{
if(sign^num.sign)
{
bign tmp=sign? num:*this;
tmp.sign=1;
return sign? *this-tmp:num-tmp;
}
bign result;
result.len=0;
int temp=0;
for(int i=0;temp||i<(max(len,num.len));i++)
{
int t=s[i]+num.s[i]+temp;
result.s[result.len++]=t%10;
temp=t/10;
}
result.sign=sign;
return result;
}
bign operator ++ () {*this=*this+1; return *this;}
bign operator ++ (int) {bign old=*this; ++(*this); return old;}
bign operator += (const bign &num) {*this=*this+num; return *this;}
bign operator - (const bign &num) const
{
bign b=num,a=*this;
if(!num.sign&&!sign)
{
b.sign=1;
a.sign=1;
return b-a;
}
if(!b.sign)
{
b.sign=1;
return a+b;
}
if(!a.sign)
{
a.sign=1;
b=bign(0)-(a+b);
return b;
}
if(a<b)
{
bign c=(b-a);
c.sign=false;
return c;
}
bign result;
result.len=0;
for(int i=0,g=0;i<a.len;i++)
{
int x=a.s[i]-g;
if(i<b.len)
x-=b.s[i];
if(x>=0)
g=0;
else
{
g=1;
x+=10;
}
result.s[result.len++]=x;
}
result.clean();
return result;
}
bign operator -- () {*this=*this-1; return *this;}
bign operator -- (int) {bign old=*this; --(*this); return old;}
bign operator -= (const bign &num) {*this=*this+num; return *this;}
bign operator * (const bign &num) const
{
bign result;
result.len=len+num.len;
for(int i=0;i<len;i++)
for(int j=0;j<num.len;j++)
result.s[i+j]+=s[i]*num.s[j];
for(int i=0;i<result.len;i++)
{
result.s[i+1]+=result.s[i]/10;
result.s[i]%=10;
}
result.clean();
result.sign=!(sign^num.sign);
return result;
}
bign operator * (const int num) const {bign x=num; bign z=*this; return x*z;}
bign operator *= (const bign &num) {*this=*this*num; return *this;}
bign operator / (const bign &num) const
{
bign ans;
ans.len=len-num.len+1;
if (ans.len<0)
{
ans.len=1;
return ans;
}
bign divisor=*this,divid=num;
divisor.sign=divid.sign=1;
int k=ans.len-1;
int j=len-1;
while(k>=0)
{
while(divisor.s[j]==0)
j--;
if(k>j) k=j;
char z[1000];
memset(z,0,sizeof(z));
for(int i=j;i>=k;i--)
z[j-i]=divisor.s[i]+'0';
bign dividend=z;
if(dividend<divid) {k--;continue;}
int key=0;
while(divid*key<=dividend)
key++;
key--;
ans.s[k]=key;
bign temp=divid*key;
for(int i=0;i<k;i++)
temp=temp*10;
divisor=divisor-temp;
k--;
}
ans.clean();
ans.sign=!(sign^num.sign);
return ans;
}
bign operator /= (const bign &num) {*this=*this/num; return *this;}
bign operator % (const bign &num) const
{
bign a=*this,b=num;
a.sign=b.sign=1;
bign result,temp=a/b*b;
result=a-temp;
result.sign=sign;
return result;
}
bign factorial()const
{
bign result=1;
for(bign i=1;i<=*this;i++)
result*=i;
return result;
}
bign Sqrt()const
{
if(*this<0)return -1;
if(*this<=1)return *this;
bign l=0,r=*this,mid;
while(r-l>1)
{
mid=(l+r)/2;
if(mid*mid>*this)
r=mid;
else
l=mid;
}
return l;
}
bign pow(const bign &num) const
{
bign result=1;
for(bign i=0;i<num;i++)
result=result*(*this);
return result;
}
void clean()
{
if(len==0) len++;
while(len>1&&s[len-1]=='\0')
len--;
}
};