import System;
import System.Globalization;
import System.Console;

class Fraction implements IFormattable {
	private var a : long;
	private var b : long;
	function Fraction() { a = 0; b = 1; }
	function Fraction(a : long) { this.a = a; b = 1; }
	function Fraction(a : long, b : long) {
		this.a = a; this.b = b;
		this.normalize();
	}
	function Fraction(f : Fraction) {
		this.a = f.a; this.b = f.b;
	}
	function get Bunsi() : long { return a; }
	function get Bunbo() { return b; }
	private function normalize() {
		var	a1 : long, b1 : long, a2 : long, f : long;
		a1 = a; b1 = b;
		f = 1;
		while(true) {
			if((a2 = a1 % b1) == 0) {
				f = b1;
				break;
			}
			if((b1 = b1 % a1) == 0) {
				f = a1;
				break;
			}
			a1 = a2;
		}
		a /= f; b /= f;
		if(b < 0) {
			a = -a;
			b = -b;
		}
	}
	function op_Assign(f : Fraction) : Fraction {
		a = f.a; b = f.b;
		return new Fraction(f);
	}
	static function op_Equality(f1 : Fraction, f2 : Fraction) : boolean {
		return f1.a == f2.a && f1.b == f2.b;
	}
	static function op_Inequality(f1 : Fraction, f2 : Fraction) : boolean {
		return f1.a != f2.a || f1.b != f2.b;
	}
	static function op_GreaterThan(f1 : Fraction, f2 : Fraction) : boolean {
		return f1.a * f2.b > f1.b * f2.a;
	}
	static function op_LessThan(f1 : Fraction, f2 : Fraction) : boolean {
		return f1.a * f2.b < f1.b * f2.a;
	}
	static function op_GreaterThanOrEqual(f1 : Fraction, f2 : Fraction) : boolean {
		return f1.a * f2.b >= f1.b * f2.a;
	}
	static function op_LessThanOrEqual(f1 : Fraction, f2 : Fraction) : boolean {
		return f1.a * f2.b <= f1.b * f2.a;
	}
	static function op_Addition(f1 : Fraction, f2 : Fraction) : Fraction {
		var result : Fraction = new Fraction(f1);
		return result.op_AdditionAssignment(f2);
	}
	static function op_Subtraction(f1 : Fraction, f2 : Fraction) : Fraction {
		var result : Fraction = new Fraction(f1);
		return result.op_SubtractionAssignment(f2);
	}
	static function op_Multiply(f1 : Fraction, f2 : Fraction) : Fraction {
		var result : Fraction = new Fraction(f1);
		return result.op_SubtractionAssignment(f2);
	}
	static function op_Division(f1 : Fraction, f2 : Fraction) : Fraction {
		var result : Fraction = new Fraction(f1);
		return result.op_DivisionAssignment(f2);
	}
	function op_AdditionAssignment(f : Fraction) : Fraction {
		a = a * f.b + b * f.a; b *= f.b;
		normalize();
		return new Fraction(this);
	}
	function op_SubtractionAssignment(f : Fraction) : Fraction {
		a = a * f.b - b * f.a; b *= f.b;
		normalize();
		return new Fraction(this);
	}
	function op_MultiplyAssignment(f : Fraction) : Fraction {
		var result : Fraction = new Fraction();
		result.a = a; result.b = f.b;
		result.normalize();
		a = f.a; normalize();
		result.a *= a; result.b *= b;
		a = result.a; b = result.b;
		return result;
	}
	function op_DivisionAssignment(f : Fraction) : Fraction {
		var result : Fraction = new Fraction();
		result.a = a; result.b = f.a;
		result.normalize();
		a = f.b; normalize();
		result.a *= a; result.b *= b;
		a = result.a; b = result.b;
		return result;
	}
	static function op_UnaryNegation(f : Fraction) : Fraction {
		var result : Fraction = new Fraction(f);
		f.a = -f.a;
		return result;
	}
	static function op_UnaryPlus(f : Fraction) : Fraction {
		var result : Fraction = new Fraction(f);
		return result;
	}
	function ToString() : String {
		if(b == 1)
			return a.ToString();
		else
			return a + "/" + b;
	}
	function ToString(format : String, ifp : IFormatProvider) : String {
		if(format == null) {
			if(b == 1)
				return a.ToString();
			else
				return a + "/" + b;
		}
		else {
			if(b == 1)
				return a.ToString(format);
			else
				return a.ToString(format) + "/" + b.ToString(format);
		}
	}
}

var f : Fraction = new Fraction(2, 6);
Console.WriteLine(f);
Console.WriteLine("{0:D2}", f);
