import std.algorithm, std.array, std.conv, std.math, std.range, std.stdio, std.typecons; struct Matrix { long a11, a12, a21, a22; void exchange_row() { swap(a11, a21), swap(a12, a22); } void exchange_column() { swap(a11, a12), swap(a21, a22); } void min_to11() { auto m = [a11, a12, a21, a22].filter!(a => a != 0).reduce!"min(a.abs, b.abs)"; if (a21.abs == m) { exchange_row(); } else if (a12.abs == m) { exchange_column(); } else if (a22.abs == m) { exchange_row(); exchange_column(); } else assert(a11.abs == m); if (a11 < 0) a11 = -a11, a21 = -a21; } // true if set to smith form bool one_step() { min_to11(); // row auto q1 = a21 / a11; a21 -= a11 * q1; a22 -= a12 * q1; // column auto q2 = a12 / a11; a12 -= a11 * q2; a22 -= a21 * q2; if (a12 == 0 && a21 == 0) { min_to11(); auto b = a11; auto q = a22 / b; auto r = a22 % b; if (r == 0) { a22 = a22.abs; return true; } a11 = r, a21 = -b, a12 = b*q, a22 = b ; } return false; } void to_smith_form() { if (a11 == 0 && a12 == 0 && a21 == 0 && a22 == 0) return; while (!one_step()) {} } } void main() { auto row1 = readln.split.to!(long[]); auto row2 = readln.split.to!(long[]); auto mat = Matrix(row1[0], row1[1], row2[0], row2[1]); mat.to_smith_form(); writeln(mat.a11, " ", mat.a22); }