#include<iostream>
#include<climits>
using namespace std;

class bad_rational{};

class rational
{
    int num;  //любое целое
    int denom;//должен быть >0
    void normalize();
public:
    rational():num(0),denom(1){}
    rational(int n):num(n),denom(1){}
    rational(int n,int d);

    int numerator() const {return num;}
    int denominator() const {return denom;}

    rational& reduce();
    rational get_reduced()const;

    // Операторы сравнения
    bool operator<  (const rational& r) const;
    bool operator<= (const rational& r) const;
    bool operator>  (const rational& r) const;
    bool operator>= (const rational& r) const;
    bool operator== (const rational& r) const;
    bool operator!= (const rational& r) const;

    // Арифметические операторы
    rational& operator+= (const rational& r);
    rational& operator-= (const rational& r);
    rational& operator*= (const rational& r);
    rational& operator/= (const rational& r);

    // Арифметические операторы с целыми параметрами
    /*rational& operator+= (int i);
    rational& operator-= (int i);
    rational& operator*= (int i);
    rational& operator/= (int i);*/

    //Присваивание целого числа
    rational& operator=(int n){num=n;denom=1;}

    friend istream& operator>> (istream& in, rational& r);
};

int gcd(int a, int b)
{
    if (a<0) a=-a;
    if (b<0) b=-b;
    while (b!=0)
    {
        int p=a%b;
        a=b;
        b=p;
    }
    return a;
}

long long gcd(long long a, long long b)
{
    if (a<0) a=-a;
    if (b<0) b=-b;
    while (b!=0)
    {
        long long p=a%b;
        a=b;
        b=p;
    }
    return a;
}

long long NOK(int a, int b)
{
    return (long long)a/gcd(a,b)*b;
}

void rational::normalize()
{
    if (denom==0) throw bad_rational();
    if (denom<0){num=-num;denom=-denom;}
}

rational::rational(int n,int d):num(n),denom(d)
{
    normalize();
}

rational& rational::reduce()
{
    int d=gcd(num,denom);
    num/=d;
    denom/=d;
    return (*this);
}

rational rational::get_reduced()const
{
    int d=gcd(num,denom);
    return rational(num/d,denom/d);
}

bool rational::operator<  (const rational& r) const
{
    return (long long)this->num*r.denom<(long long)r.num*this->denom;
}
bool rational::operator<= (const rational& r) const
{
    return (long long)this->num*r.denom<=(long long)r.num*this->denom;
}
bool rational::operator>  (const rational& r) const
{
    return (long long)this->num*r.denom>(long long)r.num*this->denom;
}
bool rational::operator>= (const rational& r) const
{
    return (long long)this->num*r.denom>=(long long)r.num*this->denom;
}
bool rational::operator== (const rational& r) const
{
    return (long long)this->num*r.denom==(long long)r.num*this->denom;
}
bool rational::operator!= (const rational& r) const
{
    return (long long)this->num*r.denom!=(long long)r.num*this->denom;
}

rational& rational::operator+= (const rational& r)
{
    long long new_denom=(long long)this->denom*r.denom;
    long long new_num=(long long)this->num*r.denom+(long long)r.num*this->denom;
    long long d=gcd(new_denom,new_num);
    new_denom/=d;
    new_num/=d;
    if (new_denom>INT_MAX || abs(new_num)>INT_MAX) throw bad_rational();
    denom=new_denom;
    num=new_num;
    return *this;
}

rational& rational::operator-= (const rational& r)
{
    long long new_denom=(long long)this->denom*r.denom;
    long long new_num=(long long)this->num*r.denom-(long long)r.num*this->denom;
    long long d=gcd(new_denom,new_num);
    new_denom/=d;
    new_num/=d;
    if (new_denom>INT_MAX || abs(new_num)>INT_MAX) throw bad_rational();
    denom=new_denom;
    num=new_num;
    return *this;
}

rational& rational::operator*= (const rational& r)
{
    return *this;
}

rational& rational::operator/= (const rational& r)
{
    return *this;
}


rational operator-(const rational& r)
{
    return rational(-r.numerator(),r.denominator());
}

rational operator+(const rational& r1,const rational& r2)
{
    rational res(r1);
    res+=r2;
    return res;
}

rational operator+(int i,const rational& r2)
{
    rational res(i);
    res+=r2;
    return res;
}

rational operator+(const rational& r1,int i)
{
    rational res(r1);
    res+=i;
    return res;
}

rational operator-(const rational& r1,const rational& r2)
{
    rational res(r1);
    res-=r2;
    return res;
}

rational operator-(int i,const rational& r2)
{
    rational res(i);
    res-=r2;
    return res;
}

rational operator-(const rational& r1,int i)
{
    rational res(r1);
    res-=i;
    return res;
}


istream& operator>> (istream& in, rational& r)
{
    in>>r.num; in.ignore(2,'/'); in>>r.denom;
    r.normalize();
}

ostream& operator<< (ostream& out, const rational& r)
{
    out <<r.numerator()<<"/"<<r.denominator();
    return out;
}

int main()
{
    rational r13(1,3), r24(2,4);
    cout <<r13 <<"+" <<r24 <<"=" <<r13+r24<<endl;
    cout <<r13 <<"-" <<r24 <<"=" <<r13-r24<<endl;
    try
    {
        rational qqq(1,2147483647), zzz(2,2147483645);
        cout <<qqq <<"+" <<zzz <<"=" <<qqq+zzz<<endl;
    }
    catch(bad_rational&)
    {
        cout <<"Bad rational obtained!"<<endl;
    }

    return 0;
}
