unit square_lib;
{
translation of grader/square_lib.h and grader/square_lib.cpp
}

interface


function getN: longint;
function getL: longint;
function getWeight(x, y, direction : longint): longint;
procedure solution(x, y : longint);

implementation

const
   LIB_MAXN = 2003;

   LIBERRORCODE = 2947;
   LIBSOLUTION  = 2948;
   LIBQUERY     = 2942;

   LIBXOR       = 12345;


var
   LIB_queries	: longint;
   LIB_N, LIB_L	: longint;
   LIB_out	: text;

   fin	 : file of char;

procedure LIB_init; forward;

function getN : longint;
begin
   LIB_init;
   getN := LIB_N;
end; { getN }

function getL : longint;
begin
   LIB_init;
   getL := LIB_L;
end; { getL }

const INVALID_BYTE : byte = 255;
   
function charToByte(c : char):byte;
begin
   if byte(c) < byte('0') then begin
      charToByte:=INVALID_BYTE;
      exit;
   end;
   if byte(c) <= byte('9') then begin
      charToByte:=byte(c)-byte('0');
      exit;
   end;
   charToByte:=INVALID_BYTE;
end; { charToByte }

function readDigit:byte;
var c : char;
begin
   if eof(fin) then begin
      readDigit:=INVALID_BYTE;
      exit;
   end;
   read(fin, c);
   readDigit:=charToByte(c);
end;

function readInt : longint;
var res	: longint;
   b	: byte;
begin
   res:=0;
   repeat
      b:=readDigit;
   until b <> INVALID_BYTE;
   res:=0;
   repeat
      res:=res*10+b;
      b:=readDigit;
   until b = INVALID_BYTE;
   readInt:=res;
end;

function getWeight(x, y, direction : longint): longint;
var res	     : longint;
   n, offset : longint;
begin
   LIB_init();
   inc(LIB_queries);
   if (x<1) or (x>getN())
      then begin
	 writeln(LIB_out, LIBERRORCODE, ' getWeight: invalid x=', x);
	 halt(0);
      end;
   if (y<1) or (y>getN())
      then begin
	 writeln(LIB_out, LIBERRORCODE, ' getWeight: invalid y=', y);
	 halt(0);
      end;
   if (direction <> 0) and (direction <> 1)
      then begin
	 writeln(LIB_out, LIBERRORCODE, ' getWeight: invalid direction=', direction);
	 halt(0);
      end;
   if ((direction = 0) and (x = getN())) or ((direction = 1) and (y = getN()))
      then begin
	 writeln(LIB_out, LIBERRORCODE, ' getWeight: edge does not exist (', x, ', ', y, ', ', direction, ')');
	 halt(0);
      end;

   n:=getN();
   offset := 8*(4+
		(direction*(N*(N-1)))+
		((y-1)*(N-(direction xor 1)))+
		(x-1));
   seek(fin, offset);
   res:=readInt xor LIBXOR;
   writeln(LIB_out, LIBQUERY, ' ', x, ' ', y, ' ', direction, ' ', res);
   getWeight:=res;
end; { getWeight }

procedure solution(x, y	: longint);
begin
   LIB_init;
   writeln(LIB_out, LIBSOLUTION, ' ', x, ' ', y, ' ', x+y-6, ' ', LIB_queries);
   close(LIB_out);
   halt(0);
end; { solution }

var already_initialized : longint;
procedure LIB_init;
var oldfilemode	: integer;
begin
   if already_initialized <> 0
      then exit;
   already_initialized:=1;

   assign(fin, 'square.in');
   oldfilemode:=filemode;
   filemode:=0;
   {$I-}
   reset(fin);
   {$I+}
   filemode:=oldfilemode;
   if IOResult<>0
      then begin
	 writeln(LIB_out, LIBERRORCODE, ' cannot open square.in');
	 halt(0);
      end;
   LIB_N:=readInt;
   LIB_L:=readInt;
   assign(LIB_out, 'square.out');
   {$I-}
   rewrite(LIB_out);
   {$I+}
   if IOResult <> 0 then begin
      writeln(LIB_out, LIBERRORCODE, ' cannot open square.out');
      halt(0);
   end;
end;

begin
   LIB_queries := 0;
   already_initialized := 0;
   LIB_out := stdout;
end.