using System;

public class Fraction
{
	private int numerator;
	private int denominator;

	// Tworzy ułamek na podstawie 
	// podanego licznika i mianownika
	public Fraction(int numerator, int denominator)
	{
		this.numerator = numerator;
		this.denominator = denominator;
	}

	// Przeciążony operator + przyjmuje dwa ułamki
	// i zwraca ich sumę
	public static Fraction operator +(Fraction lhs, Fraction rhs)
	{
		// Ułamki o wspólnym mianowniku można dodawać
		// dodając ich liczniki
		if (lhs.denominator == rhs.denominator)
		{
			return new Fraction(lhs.numerator + rhs.numerator,
			lhs.denominator);
		}

		// Uproszczone rozwiązania dla ułamków o różnych mianownikach
		// 1/2 + 3/4 == (1*4) + (3*2) / (2*4) == 10/8.
		// Ta technika nie przeprowadza redukcji
		int firstProduct = lhs.numerator * rhs.denominator;
		int secondProduct = rhs.numerator * lhs.denominator;
		return new Fraction(
		   firstProduct + secondProduct,
		   lhs.denominator * rhs.denominator
		   );
	}

	// Zwraca łańcuchową reprezentację ułamka
	public override string ToString()
	{
		String s = numerator.ToString() + "/" +
		denominator.ToString();
		return s;
	}
}


public class Tester
{
	public void Run()
	{
		Fraction firstFraction = new Fraction(3, 4);
		Console.WriteLine("firstFraction: {0}", firstFraction.ToString());

		Fraction secondFraction = new Fraction(2, 4);
		Console.WriteLine("secondFraction: {0}", secondFraction.ToString());

		Fraction sumOfTwoFractions = firstFraction + secondFraction;
		Console.WriteLine(
		   "firstFraction + secondFraction = sumOfTwoFractions: {0}",
		   sumOfTwoFractions.ToString());
	}

	static void Main()
	{
		Tester t = new Tester();
		t.Run();
	}
}
