#include<iostream>
#include<cstdio>
#include<cstring>
#include<sstream>
//#include<time.h>
#include<stdlib.h>
using namespace std;
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
const int BIGN_MAXN=5000;
const int base=10;//oct base
const int MILLER_INDEX=100;
const int BINARY_LEN=5000;
const int NUM_STR_MAXN=5000;
//s[0]:0(0) >0(1) <0(-1) (a>b) definit condition
class bign
{
private:
int len,s[BIGN_MAXN];//s[0]signal .. s[1--n]digital
public:
bign()
{
len=0;
memset(s,0,sizeof(s));
}
~bign() {}
//visit private members
int& at(int pos)
{
if(pos>len) return s[0];//beyond the numble length ,output signal.
else return s[pos];
}
int length() const
{
return len;
}
//assignment
bign operator =(const char x[])
{
len=strlen(x);
for(int i=1; i<=len; i++) s[i]=x[len-i]-'0';
return *this;
}
bign operator =(const int x)
{
char xx[NUM_STR_MAXN];
sprintf(xx,"%d",x);
*this=xx;
return *this;
}
bign(const char x[])
{
*this=x;
}
bign(const int x)
{
*this=x;
}
//to-string
string str()const
{
string buf="";
for(int i=len; i>0; i--) buf+=(char)(s[i]+'0');
if(buf=="") buf = "0";
return buf;
}
//comparision
bool operator <(const bign& x)const
{
if(len!=x.len) return(len<x.len);
for(int i=len; i>0; i--) if(s[i]!=x.s[i]) return(s[i]<x.s[i]);
return false;
}
bool operator >(const bign& x)const
{
return x<*this;
}
bool operator ==(const bign& x)const
{
return (!(*this<x)&&(!(x<*this)));
}
bool operator !=(const bign& x)const
{
return (*this<x)||(x<*this);
}
bool operator <=(const bign& x)const
{
return !(x<*this);
}
bool operator >=(const bign& x)const
{
return !(*this<x);
}
//calculation
bign operator + (const bign& x) const
{
bign ans;
int i,cy;
int len=max(this->len, x.len)+1;//
for(i=1; i<=len; i++)
{
cy=0;
if(i<=(this->len))
cy+=this->s[i];
if(i<=x.len)
cy+=x.s[i];
ans.s[i]+=cy;
ans.s[i+1]=ans.s[i]/base;
ans.s[i]%=base;
}
if(ans.s[len]==0&&len>0) len--;
ans.len=len;
//取模
return ans;
}
bign operator +=(const bign& x)
{
*this=*this+x;
return *this;
}
bign operator - (const bign& x) const
{
bign ans=0;
int i,cy=0;
for(ans.len=len,i=1; i<=ans.len; i++)
{
ans.s[i]=s[i]-cy;
if(i<=x.len)
ans.s[i]-=x.s[i];
if(ans.s[i]<0)
{
cy=1;
ans.s[i]+=base;
}
else
{
cy=0;
}
}
while(ans.len>0&&ans.s[ans.len]==0)
ans.len--;
return ans;
}
bign operator -=(const bign& x)
{
*this=*this-x;
return *this;
}
bign operator *(const bign& x) const
{
bign ans;
int i,j;
int len=this->len+x.len;
for(i=1; i<=this->len; i++)
for(j=1; j<=x.len; j++)
ans.s[i+j-1]+=this->s[i]*x.s[j];
for(i=1; i<=len; i++)
{
ans.s[i+1]+=ans.s[i]/base;
ans.s[i]%=base;
}
while(ans.s[len]==0&&len>0) len--;
ans.len=len;
return ans;
}
bign operator *=(const bign& x)
{
*this=*this*x;
return *this;
}
bign operator /(const int x) const
{
bign ans;
if(*this<x)
{
ans=0;
ans.len=1;
}
else
{
int k=0,len=this->len;
for(int i=len; i>0; i--)
{
ans.s[i]=(k*base+this->s[i])/x;
k=(k*base+this->s[i])%x;
}
while(ans.s[len]==0&&len>0) len--;
ans.len=len;
}
return ans;
}
bign operator /=(const int x)
{
*this=*this/x;
return *this;
}
bign operator /( const bign& b) const
{
bign q,mo,bas=base,tmp,ans,mod=0;//
if(*this<b)
{
ans=0;
ans.len=1;
}
int i,lf,rg,mid;
for(i=len; i>0; i--)
{
mod*=bas;
tmp=s[i];
mod+=tmp;
for(lf=0,rg=base-1; lf<rg;)
{
mid=(lf+rg+1)/2;
q=mid;
mo=b*q;
if(mo<=mod)
lf=mid;
else
rg=mid-1;
}
ans.s[i]=lf;
mo=lf;
mod=mod-(b*mo);
}
ans.len=len;
while(ans.len>0&&ans.s[ans.len]==0)
ans.len--;
return ans;
}
bign operator /=(const bign& x)
{
*this=*this/x;
return *this;
}
bign operator %( const bign& b) const
{
bign q,mo,bas=base,tmp,ans,mod=0;
if(*this<b)
{
ans=*this;
return ans;
}
int i,lf,rg,mid;
for(i=len; i>0; i--)
{
mod*=bas;
tmp=s[i];
mod+=tmp;
for(lf=0,rg=base-1; lf<rg;)
{
mid=(lf+rg+1)/2;
q=mid;
mo=b*q;
if(mo<=mod)
lf=mid;
else
rg=mid-1;
}
ans.s[i]=lf;
mo=lf;
mod=mod-(b*mo);
}
return mod;
}
bign operator %=(const bign& x)
{
*this=*this%x;
return *this;
}
bign operator &(const bign& xx)const {
bign mid,ans=0,zero=0,one=1,two=2,x=xx,thi=*this;
int str[BINARY_LEN],str1[BINARY_LEN],str2[BINARY_LEN],len1=0,len2=0;
while(thi>zero){
if((thi%two)==one)
str1[++len1]=1;
else
str1[++len1]=0;
(thi)/=two;
}
cout<<"fuck"<<endl;
while(x>zero){
if((x%two)==one)
str2[++len2]=1;
else
str2[++len2]=0;
x/=two;
}
int i,len=min(len1,len2);
for(i=1;i<=len;i++){
str[i]=str1[i]&str2[i];
}
mid=1;
for(i=1;i<=len;i++){
if(str[i]==1)
ans+=mid;
mid*=two;
}
return ans;
}
bign operator |(const bign& xx)const {
bign mid,ans=0,zero=0,one=1,two=2,x=xx,thi=*this;
int str[BINARY_LEN],str1[BINARY_LEN],str2[BINARY_LEN],len1=0,len2=0;
while(thi>zero){
if((thi%two)==one)
str1[++len1]=1;
else
str1[++len1]=0;
(thi)/=two;
}
while(x>zero){
if((x%two)==one)
str2[++len2]=1;
else
str2[++len2]=0;
x/=two;
}
int i,len=max(len1,len2);
//cout<<len<<endl;
for(i=1;i<=len;i++){
str[i]=str1[i]|str2[i];
//cout<<str[i]<<" ";
}
mid=1;
for(i=1;i<=len;i++){
if(str[i]==1){
ans+=mid;
// cout<<"fuck"<<endl;
}
mid*=two;
}
//ans.len=len;
return ans;
}
bign operator ^(const bign& xx)const {
bign mid,ans=0,zero=0,one=1,two=2,x=xx,thi=*this;
int str[BINARY_LEN],str1[BINARY_LEN],str2[BINARY_LEN],len1=0,len2=0;
while(thi>zero){
if((thi%two)==one)
str1[++len1]=1;
else
str1[++len1]=0;
(thi)/=two;
}
while(x>zero){
if((x%two)==one)
str2[++len2]=1;
else
str2[++len2]=0;
x/=two;
}
int i,len=max(len1,len2);
//cout<<len<<endl;
for(i=1;i<=len;i++){
if(str1[i]==str2[i])
str[i]=0;
else
str[i]=1;
//cout<<str[i]<<" ";
}
mid=1;
for(i=1;i<=len;i++){
if(str[i]==1){
ans+=mid;
// cout<<"fuck"<<endl;
}
mid*=two;
}
//ans.len=len;
return ans;
}
bign operator ~()const {
bign mid,ans=0,zero=0,one=1,two=2,thi=*this;
int i,str[BINARY_LEN],len=0;
while(thi>zero){
if((thi%two)==one)
str[++len]=0;
else
str[++len]=1;
(thi)/=two;
}
mid=1;
for(i=1;i<=len;i++){
if(str[i]==1){
ans+=mid;
//cout<<"fuck"<<endl;
}
mid*=two;
}
//ans.len=len;
return ans;
}
bign operator ++()
{
bign one=1;
*this=*this+one;
return *this;
}
bign operator --()
{
bign c=1;
*this=*this-c;
return *this;
}
bign operator <<(const bign& x) const{
int i,str[BINARY_LEN],llen=0;
bign ans=0,lift=x,thi=*this;
bign mid,zero=0,one=1,two=2;
while(thi>zero){
if((thi%two)==one)
str[++llen]=1;
else
str[++llen]=0;
(thi)/=two;
}
while(lift>zero){
llen++;
for(i=llen;i>1;i--)
str[i]=str[i-1];
str[1]=0;
lift-=one;
}
mid=1;
for(i=1;i<=llen;i++){
if(str[i]==1){
ans+=mid;
}
mid*=two;
}
return ans;
}
bign operator <<=(const bign& x)
{
*this=*this<<x;
return *this;
}
bign operator >>(const bign& x) const{
int i,str[BINARY_LEN],rlen=0;
bign Rlen,ans=0,right=x,thi=*this;
bign mid,zero=0,one=1,two=2;
while(thi>zero){
if((thi%two)==one)
str[++rlen]=1;
else
str[++rlen]=0;
(thi)/=two;
}
Rlen=rlen;
if(Rlen<=right)
return ans;
else{
while(right>zero){
for(i=1;i<rlen;i++)
str[i]=str[i+1];
rlen--;
right-=one;
}
mid=1;
for(i=1;i<=rlen;i++){
if(str[i]==1){
ans+=mid;
}
mid*=two;
}
return ans;
}
}
bign operator >>=(const bign& x)
{
*this=*this>>x;
return *this;
}
};
//bign index=10000000007;
//input&output
istream& operator>>(istream& in,bign& x )
{
string s;
in >> s;
x=s.c_str();
return in;
}
ostream& operator<<(ostream& out,const bign& x)
{
return out << x.str();
}
//gcd
bign gcd(bign x,bign y)
{
bign mid,zero=0;
if((x==zero)||(y==zero))
return x>y?x:y;
for(bign t;;)
{
t=x%y;
if(t<=zero){
break;
}
x=y;
y=t;
}
return y;
}
//lcm
bign lcm(bign x,bign y)
{
bign mid=x*y;
return mid/gcd(x,y);
}
//pow
bign pow(bign x,bign n,bign mod)
{
bign mid,pw=1,zero=0,one=1;
x=x%mod;
while(n>zero)
{
//cout<<mid<<endl;
mid=n&one;
cout<<mid<<endl;
if(mid!=zero){
pw*=x;
pw%=mod;
}
x*=x;
x=x%mod;
n>>=one;
cout<<n<<endl;
}
return pw;
}
//Euclidean_gcd
void exc_gcd(bign a,bign b,bign& d,bign& x,bign& y)
{
bign mid,zero=0,index=10000000007;//
if(b<=zero)
{
d=a;
x=1;
y=0;
}
else
{
exc_gcd(b,a%b,d,y,x);
mid=(x*(a/b))%index;
if(y>=mid)
y-=mid;
else
y=(y+index-mid)%index;
}
}
//inverse
bign inv(bign a,bign n)
{
bign d,x,y,one=1,neg=-1;
exc_gcd(a,n,d,x,y);
return d==one?(x+n)%n:neg;//
}
//miller_rabin
int witness(bign a,bign n){
bign x,d=1,mid;int i=MILLER_INDEX;
bign one=1,zero=0,two=2;
for(;i>=0;i--){
x=d;
d=(d*d)%n;
mid=i;
if((d==one)&&(x!=one)&&(x!=(n-one)))
return 1;
if(((n-one)&(mid*two))>zero)
d=(d*a)%n;
}
if(d==one)
return 0;
else
return 1;
}
int miller(bign n,int s=50){
bign a,one=1,zero=0,two=2,RAND,RAND_M;
RAND_M=(int)RAND_MAX;
if(n==two)
return 1;
if((n%two)==zero)//
return 0;
int j;//
for(j=0;j<s;j++){
RAND=(int)rand();
a=((RAND*(n-two))/RAND_M)+one;
if(witness(a,n))
return 0;
}
return 1;
}