//implementation of the simplest arithmetic on rational numbers
//represented as: a b/c with sign.
//author: Michal Pilipczuk
//XIV Secondary School, Warsaw, Poland 

unit ulamki;
interface

type ulam=record
    znak:longint;
    //sign
    a:qword;
    b:qword;
    c:qword;
end;
//type of fraction

procedure wypisz(o:ulam);
//writes fraction

function app(xu:ulam):ulam;
//makes a fraction appropriate so b<c

function min(x:ulam):ulam;
//produces -q out of q

function mna(x,y:ulam):boolean;
//subfunction of next one

function mn(x,y:ulam):boolean;
//returns true if x<y

function adda(x,y:ulam):ulam;
//subfunction of next one

function add(x,y:ulam):ulam;
//adds two fractions

function multi(e,f:ulam):ulam;
//multiplicates two fractions

function kwa(e:ulam):ulam;
//returns a square of given number

implementation

procedure wypisz(o:ulam);
begin
    writeln(o.znak,' ',o.a,' ',o.b,' ',o.c);
end;


function app(xu:ulam):ulam;
var pom:ulam;
begin
    if (xu.b<xu.c) then app:=xu else
    begin
	pom:=xu;
	pom.a:=xu.a+(xu.b div xu.c);
	pom.b:=((xu.b) mod (xu.c));
	app:=pom;
    end;
end;

function min(x:ulam):ulam;
var pomi:ulam;
begin
    pomi:=x;
    pomi.znak:=pomi.znak*(-1);
    min:=pomi;
end;

function mna(x,y:ulam):boolean;
begin
    if (x.a<>y.a) then 
	mna:=(x.a<y.a)
    else
	mna:=((x.b*y.c)<(y.b*x.c));
end;

function mn(x,y:ulam):boolean;
begin
    if x.znak<>y.znak then
	mn:=(x.znak<y.znak)
    else
    begin
	if x.znak=1 then mn:=mna(x,y) else mn:=not(mna(min(x),min(y)));
    end;
end;

function adda(x,y:ulam):ulam;
var pom:ulam;
begin
    pom.znak:=1;
    pom.a:=x.a+y.a;
    pom.c:=x.c*y.c;
    pom.b:=x.b*y.c+y.b*x.c;
    pom:=app(pom);
    adda:=pom;
end;

function add(x,y:ulam):ulam;
var pom1,pom2,dox:ulam;
begin
    if ((x.znak<0) and (y.znak<0)) then add:=min(adda(min(x),min(y)))
    else
    begin
	if ((x.znak>0) and (y.znak>0)) then add:=adda(x,y)
	else
	begin
	    if x.znak<y.znak then 
	    begin 
		dox:=x;
		x:=y;
		y:=dox;	
	    end;
	    pom1:=min(y);
	    if mn(pom1,x) then
	    begin
	        pom2.znak:=1;
	        pom2.a:=x.a-pom1.a;
	        pom2.c:=x.c*pom1.c;
	        if x.b*pom1.c<pom1.b*x.c then
	        begin
		    dec(pom2.a);
		    pom2.b:=(x.b*pom1.c+pom2.c);
		    pom2.b:=(pom2.b-pom1.b*x.c);
		    add:=app(pom2);
		end
		else
		begin
		    pom2.b:=x.b*pom1.c-pom1.b*x.c;
		    add:=app(pom2);
		end;
	    end
	    else
	    begin
	        pom2.znak:=(-1);
	        pom2.a:=pom1.a-x.a;
	        pom2.c:=x.c*pom1.c;
	        if x.b*pom1.c>pom1.b*x.c then
	        begin
	    	    dec(pom2.a);
	    	    pom2.b:=(pom1.b*x.c+pom2.c);
	    	    pom2.b:=(pom2.b-x.b*pom1.c);
		    add:=app(pom2);
		end
		else
		begin
		    pom2.b:=pom1.b*x.c-x.b*pom1.c;
		    add:=app(pom2);
		end;
	    end;
	end;
    end;
end;

function multi(e,f:ulam):ulam;
var pomy,pomq2,pomq3:ulam;
begin
    pomq2.znak:=1;
    pomq3.znak:=1;
    pomq2.a:=e.a*f.a;
    pomq2.c:=f.c;
    pomq2.b:=e.a*f.b;
    pomq2:=app(pomq2);
    pomq3.a:=0;
    pomq3.c:=e.c;
    pomq3.b:=f.a*e.b;
    pomq3:=app(pomq3);
    pomy:=adda(pomq2,pomq3);
    pomy.b:=pomy.b+e.b*f.b;
    pomy.znak:=e.znak*f.znak;
    multi:=pomy;
end;

function kwa(e:ulam):ulam;
var pomq2:ulam;
begin
    pomq2.znak:=1;
    pomq2.a:=e.a*e.a;
    pomq2.c:=e.c;
    pomq2.b:=2*(e.b*e.a);
    pomq2:=app(pomq2);
    pomq2.b:=pomq2.b*pomq2.c+e.b*e.b;
    pomq2.c:=pomq2.c*pomq2.c;
    kwa:=app(pomq2);
end;

end.