class="markdown_views prism-atom-one-light">
#include
using namespace std;
typedef long long ll;
const int N=10002,M=1e9;
struct NUM{
bool fl;int t;
ll a[N/9];
friend void print(NUM x){
if (!x.t){puts("0");return;}
if (!x.fl) putchar('-');
printf("%lld",x.a[--x.t]);
int t[9];
for (int i=x.t-1;i>=0;i--){
memset(t,0,sizeof(t));
for (int j=0;j<9;j++) t[j]=x.a[i]%10,x.a[i]/=10;
for (int j=8;j>=0;j--) putchar(t[j]|48);
}
puts("");
}
friend bool operator>(NUM x,NUM y){
if (x.t!=y.t) return x.t>y.t;
for (int i=x.t-1;i>=0;i--)
if (x.a[i]!=y.a[i]) return x.a[i]>y.a[i];
return 0;
}
friend NUM operator+(NUM x,NUM y){
if (x.fl==y.fl){
int i;
for (i=0;iif (i+1>=x.t) x.a[i+1]=0;
if (iif (x.a[i]>=M) x.a[i+1]++,x.a[i]-=M;
}
x.t=i;
}else{
if (y>x) swap(x,y);
for (int i=0;iif (x.a[i]<0) x.a[i]+=M,x.a[i+1]--;
}
while (x.t && !x.a[x.t-1]) x.t--;
}
return x;
}
friend NUM operator-(NUM x,NUM y){y.fl^=1;return x+y;}
friend NUM operator*(NUM x,NUM y){
NUM z;z.t=x.t+y.t;
memset(z.a,0,z.t<<3);
z.fl=x.fl==y.fl;
for (int i=0;ifor (int j=0;j1]+=z.a[i+j]/M;
z.a[i+j]%=M;
}
if (z.t && !z.a[z.t-1]) z.t--;
return z;
}
friend NUM operator*(NUM x,int y){
int i;
for (i=0;ifor (i=0;iif (i+1>=x.t) x.a[i+1]=0;
x.a[i+1]+=x.a[i]/M,x.a[i]%=M;
}
x.t=i;
return x;
}
friend NUM operator/(NUM x,int y){
ll k=0;
for (int i=x.t-1;i>=0;i--){
k=k*M+x.a[i];
x.a[i]=k/y;
k%=y;
}
while (x.t && !x.a[x.t-1]) x.t--;
return x;
}
friend NUM div(NUM x,NUM y,bool fl){
NUM z;z.fl=x.fl==y.fl;z.t=x.t-y.t+1;
if (z.t<=0){
z.t=0;
return fl?z:x;
}
memset(z.a,0,z.t<<3);
x.fl=y.fl=1;
for (int i=z.t-1;i>=0;i--){
for (int j=1<<29;j;j>>=1){
NUM tmp=y*j;bool fl=tmp.t+i<=x.t;
if (!fl) continue;
if (tmp.t+i==x.t){
for (int k=tmp.t-1;k>=0;k--)
if (x.a[k+i]!=tmp.a[k]){
fl=tmp.a[k]break;
}
if (!fl) continue;
}
z.a[i]|=j;
for (int k=0;kif (x.a[k+i]<0) x.a[k+i+1]--,x.a[k+i]+=M;
}
while (x.t && !x.a[x.t-1]) x.t--;
}
}
while (z.t && !z.a[z.t-1]) z.t--;
return fl?z:x;
}
friend NUM operator/(NUM x,NUM y){return div(x,y,1);}
friend NUM operator%(NUM x,NUM y){return div(x,y,0);}
friend NUM gcd(NUM x,NUM y){
int cnt=0;NUM T;
while (1){
if (!x.t || !y.t){
NUM p,z;p.fl=z.fl=1;
p.a[0]=2;
p.t=z.t=z.a[0]=1;
for (;cnt;cnt>>=1,p=p*p)
if (cnt&1) z=z*p;
if (x.t) return z*x;
else return z*y;
}
bool f1=0,f2=0;
if (!(x.a[0]&1)) x=x/2,f1=1;
if (!(y.a[0]&1)) y=y/2,f2=1;
if (f1 && f2) cnt++;
if (x>y) x=x-y;
else T=x,x=y-x,y=T;
}
}
};
NUM toNUM(char s[]){
ll f[10];
f[0]=1;
for (int i=1;i<10;i++) f[i]=f[i-1]*10;
NUM A;
A.t=strlen(s);A.fl=1;
memset(A.a,0,(A.t-1)/9+1<<3);
for (int i=A.t-1;i>=0;i--) A.a[(A.t-1-i)/9]+=f[(A.t-1-i)%9]*(s[i]^48);
A.t=(A.t-1)/9+1;
return A;
}