namespace Frac
{
inline int Gcd(int a,int b)
{
int az=__builtin_ctz(a),bz=__builtin_ctz(b);
int z=min(az,bz),tmp; b>>=bz;
while(a) a>>=az,tmp=a-b,az=__builtin_ctz(tmp),b=min(a,b),a=abs(tmp);
return b<<z;
}
inline int Lcm(int a,int b)
{
return a*b/Gcd(a,b);
}
void Exgcd(int a,int b,int &x,int &y)
{
if(!b) return x=1,y=0,void();
Exgcd(b,a%b,y,x),y-=x*(a/b);
}
void Abs(int &a)
{
return a=a<0?-a:a,void();
}
struct frac
{
int nume,deno,sign;
frac(int Nume=0,int Deno=0,int Sign=0):nume(Nume),deno(Deno),sign(Sign) {}
inline frac operator = (const frac &T) {this->nume=T.nume,this->deno=T.deno,this->sign=T.sign; return *this;}
inline void Reduce()
{
int tmp=Gcd(nume,deno);
nume/=tmp,deno/=tmp;
}
inline frac operator - ()
{
return frac(nume,deno,-sign);
}
inline friend frac operator + (frac a,frac b)
{
frac res;
res.deno=Lcm(a.deno,b.deno);
if(a.sign==b.sign) res.sign=a.sign,res.nume=res.deno/a.deno*a.nume+res.deno/b.deno*b.nume;
else if(b.sign==-1) res.nume=res.deno/a.deno*a.nume-res.deno/b.deno*b.nume,res.nume<0?res.sign=-1:res.sign=1,Abs(res.nume);
else if(a.sign==-1) res.nume=res.deno/b.deno*b.nume-res.deno/a.deno*a.nume,res.nume<0?res.sign=-1:res.sign=1,Abs(res.nume);
res.Reduce();
return res;
}
inline friend frac operator - (frac a,frac b) {return a+(-b);}
inline friend frac operator * (frac a,frac b)
{
frac res;
res.nume=a.nume*b.nume,res.deno=a.deno*b.deno,res.sign=a.sign*b.sign;
res.Reduce();
return res;
}
inline friend frac operator / (frac a,frac b) {return a*(frac(b.deno,b.nume,b.sign));}
inline friend bool operator == (frac a,frac b) {return a.nume==b.nume&&a.deno==b.deno&&a.sign==b.sign;}
inline friend bool operator > (frac a,frac b)
{
if(a.sign!=b.sign) return a.sign>b.sign;
int tmp=Lcm(a.deno,b.deno);
return tmp/a.deno*a.nume>tmp/b.deno*b.nume;
}
inline friend bool operator < (frac a,frac b)
{
if(a.sign!=b.sign) return a.sign<b.sign;
int tmp=Lcm(a.deno,b.deno);
return tmp/a.deno*a.nume<tmp/b.deno*b.nume;
}
inline friend bool operator >= (frac a,frac b) {return a>b||a==b;}
inline friend bool operator <= (frac a,frac b) {return a<b||a==b;}
inline frac operator += (const frac &T) {*this=*this+T; return *this;}
inline frac operator -= (const frac &T) {*this=*this-T; return *this;}
inline frac operator *= (const frac &T) {*this=*this*T; return *this;}
inline frac operator /= (const frac &T) {*this=*this/T; return *this;}
};
inline int Inv(frac a)
{
a.nume%=a.deno;
if(a.sign==-1) a.nume=a.deno-a.nume;
int X=0,Y=0; Exgcd(a.nume,a.deno,X,Y);
return (X%a.deno+a.deno)%a.deno;
}
inline void fout(frac a)
{
if(a.deno==1) write(a.sign*a.nume,'\n');
else write(a.sign*a.nume,'/'),write(a.deno,'\n');
}
}