#include<iostream>
using namespace std;
int abs(int x) {
return x < 0 ? -x : x;
}
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
struct Fraction{
int up, down;
friend Fraction operator+(Fraction f1, Fraction f2);
friend Fraction operator-(Fraction f1, Fraction f2);
friend Fraction operator*(Fraction f1, Fraction f2);
friend Fraction operator/(Fraction f1, Fraction f2);
};
void reduction(Fraction &f) {
if (f.down < 0) {
f.up = -f.up;
f.down = -f.down;
}
if (f.up == 0) f.down = 1;
else {
int gd = gcd(abs(f.up), abs(f.down));
f.up /= gd;
f.down /= gd;
}
}
Fraction operator+(Fraction f1, Fraction f2) {
Fraction res;
// 通分算法
// int lm = lcm(abs(f1.down), abs(f2.down));
// f1.up *= (lm / f1.down);
// f2.up *= (lm / f2.down);
// f1.down = f2.down = lm;
// res.up = f1.up + f2.up;
// res.down = lm;
// 不通分,简洁算法:
res.up = f1.up * f2.down + f2.up * f1.down;
res.down = f1.down * f2.down;
reduction(res);
return res;
}
Fraction operator-(Fraction f1, Fraction f2) {
Fraction res;
res.up = f1.up * f2.down - f2.up * f1.down;
res.down = f1.down * f2.down;
reduction(res);
return res;
}
Fraction operator*(Fraction f1, Fraction f2) {
Fraction res;
res.up = f1.up * f2.up;
res.down = f1.down * f2.down;
reduction(res);
return res;
}
Fraction operator/(Fraction f1, Fraction f2) {
Fraction res;
res.up = f1.up * f2.down;
res.down = f1.down * f2.up;
reduction(res);
return res;
}
int main() {
int a, b, c, d;
cin >> a >> b >> c >> d;
// 在没有定义重载函数,结构体按顺序初始化时要用大括号{}
Fraction f1{a, b}, f2{c, d};
Fraction res = f1 / f2;
if (res.down == 0) cout << "undefined" << endl;
else if (res.down == 1) cout << res.up << endl;
else cout << res.up << " " << res.down << endl;
return 0;
}