Index: libcfa/src/fstream.cfa
===================================================================
--- libcfa/src/fstream.cfa	(revision 2233ad4f2f307ae7580e22f19484a599cead20d9)
+++ libcfa/src/fstream.cfa	(revision 65240bbf85edbcb53a5d3c3101d0486d5b11f3bb)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu May 16 08:33:28 2019
-// Update Count     : 328
+// Last Modified On : Fri Jul 12 12:03:53 2019
+// Update Count     : 344
 //
 
@@ -24,4 +24,8 @@
 #include <assert.h>
 #include <errno.h>										// errno
+
+
+//*********************************** ofstream ***********************************
+
 
 #define IO_MSG "I/O error: "
@@ -37,5 +41,5 @@
 	sepSetCur( os, sepGet( os ) );
 	sepSetTuple( os, ", " );
-}
+} // ?{}
 
 // private
@@ -56,8 +60,9 @@
 void ?{}( ofstream & os, const char * name, const char * mode ) {
 	open( os, name, mode );
-}
+} // ?{}
+
 void ?{}( ofstream & os, const char * name ) {
 	open( os, name, "w" );
-}
+} // ?{}
 
 void sepOn( ofstream & os ) { os.sepOnOff = ! getNL( os ); }
@@ -94,4 +99,11 @@
 	os.tupleSeparator[sepSize - 1] = '\0';
 } // sepSet
+
+void ends( ofstream & os ) {
+	if ( getANL( os ) ) nl( os );
+	else setPrt( os, false );							// turn off
+	if ( &os == &exit ) exit( EXIT_FAILURE );
+	if ( &os == &abort ) abort();
+} // ends
 
 int fail( ofstream & os ) {
@@ -157,15 +169,12 @@
 ofstream & serr = serrFile;
 
-// static ofstream sexitFile = { (FILE *)(&_IO_2_1_stdout_) };
-// ofstream & sexit = sexitFile;
-// static ofstream sabortFile = { (FILE *)(&_IO_2_1_stderr_) };
-// ofstream & sabort = sabortFile;
-
-void nl( ofstream & os ) {
-	if ( getANL( os ) ) (ofstream &)(nl( os ));			// implementation only
-	else setPrt( os, false );							// turn off
-}
-
-//---------------------------------------
+static ofstream exitFile = { (FILE *)(&_IO_2_1_stdout_) };
+ofstream & exit = exitFile;
+static ofstream abortFile = { (FILE *)(&_IO_2_1_stderr_) };
+ofstream & abort = abortFile;
+
+
+//*********************************** ifstream ***********************************
+
 
 // private
@@ -173,5 +182,5 @@
 	is.file = file;
 	is.nlOnOff = false;
-}
+} // ?{}
 
 // public
@@ -180,8 +189,9 @@
 void ?{}( ifstream & is, const char * name, const char * mode ) {
 	open( is, name, mode );
-}
+} // ?{}
+
 void ?{}( ifstream & is, const char * name ) {
 	open( is, name, "r" );
-}
+} // ?{}
 
 void nlOn( ifstream & os ) { os.nlOnOff = true; }
Index: libcfa/src/fstream.hfa
===================================================================
--- libcfa/src/fstream.hfa	(revision 2233ad4f2f307ae7580e22f19484a599cead20d9)
+++ libcfa/src/fstream.hfa	(revision 65240bbf85edbcb53a5d3c3101d0486d5b11f3bb)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu May 16 08:34:10 2019
-// Update Count     : 157
+// Last Modified On : Fri Jul 12 12:03:54 2019
+// Update Count     : 165
 //
 
@@ -17,4 +17,8 @@
 
 #include "iostream.hfa"
+
+
+//*********************************** ofstream ***********************************
+
 
 enum { sepSize = 16 };
@@ -56,4 +60,5 @@
 void sepSetTuple( ofstream &, const char * );
 
+void ends( ofstream & os );
 int fail( ofstream & );
 int flush( ofstream & );
@@ -69,7 +74,8 @@
 
 extern ofstream & sout, & serr;
+extern ofstream & exit, & abort;
 
-// extern ofstream & sout, & serr, & sexit, & sabort;
-// void nl( ofstream & os );
+
+//*********************************** ifstream ***********************************
 
 
Index: libcfa/src/gmp.hfa
===================================================================
--- libcfa/src/gmp.hfa	(revision 2233ad4f2f307ae7580e22f19484a599cead20d9)
+++ libcfa/src/gmp.hfa	(revision 65240bbf85edbcb53a5d3c3101d0486d5b11f3bb)
@@ -10,6 +10,6 @@
 // Created On       : Tue Apr 19 08:43:43 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Apr 20 09:01:52 2019
-// Update Count     : 24
+// Last Modified On : Fri Jul 12 12:02:55 2019
+// Update Count     : 26
 //
 
@@ -19,258 +19,260 @@
 
 #include <gmp.h>										// GNU multi-precise integers
-#include <fstream.hfa>										// sout
+#include <fstream.hfa>									// sout
 
 struct Int { mpz_t mpz; };								// wrap GMP implementation
 
-// constructor
-static inline void ?{}( Int & this ) { mpz_init( this.mpz ); }
-static inline void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); }
-static inline void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); }
-static inline void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); }
-static inline void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); }
-static inline void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); }
-static inline void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
-static inline void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
-
-// literal
-static inline Int ?`mp( signed long int init ) { return (Int){ init }; }
-static inline Int ?`mp( unsigned long int init ) { return (Int){ init }; }
-static inline Int ?`mp( const char * init ) { return (Int){ init }; }
-
-// assignment
-static inline Int ?=?( Int & lhs, Int rhs ) { mpz_set( lhs.mpz, rhs.mpz ); return lhs; }
-static inline Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; }
-static inline Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; }
-static inline Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { printf( "invalid string conversion\n" ); abort(); } return lhs; }
-
-static inline char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
-static inline short int ?=?( short int & lhs, Int rhs ) { short int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
-static inline int ?=?( int & lhs, Int rhs ) { int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
-static inline long int ?=?( long int & lhs, Int rhs ) { long int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
-static inline unsigned char ?=?( unsigned char & lhs, Int rhs ) { unsigned char val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
-static inline unsigned short int ?=?( unsigned short int & lhs, Int rhs ) { unsigned short int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
-static inline unsigned int ?=?( unsigned int & lhs, Int rhs ) { unsigned int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
-static inline unsigned long int ?=?( unsigned long int & lhs, Int rhs ) { unsigned long int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
-
-// conversions
-static inline long int narrow( Int val ) { return mpz_get_si( val.mpz ); }
-static inline unsigned long int narrow( Int val ) { return mpz_get_ui( val.mpz ); }
-
-// comparison
-static inline int ?==?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) == 0; }
-static inline int ?==?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
-static inline int ?==?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
-static inline int ?==?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
-static inline int ?==?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
-
-static inline int ?!=?( Int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
-static inline int ?!=?( Int oper1, long int oper2 ) { return ! ( oper1 == oper2 ); }
-static inline int ?!=?( long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
-static inline int ?!=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 == oper2 ); }
-static inline int ?!=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
-
-static inline int ?<?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) < 0; }
-static inline int ?<?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
-static inline int ?<?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
-static inline int ?<?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
-static inline int ?<?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
-
-static inline int ?<=?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) <= 0; }
-static inline int ?<=?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
-static inline int ?<=?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
-static inline int ?<=?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
-static inline int ?<=?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
-
-static inline int ?>?( Int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
-static inline int ?>?( Int oper1, long int oper2 ) { return ! ( oper1 <= oper2 ); }
-static inline int ?>?( long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
-static inline int ?>?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 <= oper2 ); }
-static inline int ?>?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
-
-static inline int ?>=?( Int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
-static inline int ?>=?( Int oper1, long int oper2 ) { return ! ( oper1 < oper2 ); }
-static inline int ?>=?( long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
-static inline int ?>=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 < oper2 ); }
-static inline int ?>=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
-
-// arithmetic
-static inline Int +?( Int oper ) { Int pos; mpz_set( pos.mpz, oper.mpz ); return pos; }
-static inline Int -?( Int oper ) { Int neg; mpz_neg( neg.mpz, oper.mpz ); return neg; }
-static inline Int ~?( Int oper ) { Int comp; mpz_com( comp.mpz, oper.mpz ); return comp; }
-
-static inline Int ?&?( Int oper1, Int oper2 ) { Int conjunction; mpz_and( conjunction.mpz, oper1.mpz, oper2.mpz ); return conjunction; }
-static inline Int ?&?( Int oper1, long int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
-static inline Int ?&?( long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
-static inline Int ?&?( Int oper1, unsigned long int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
-static inline Int ?&?( unsigned long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
-static inline Int ?&=?( Int & lhs, Int rhs ) { return lhs = lhs & rhs; }
-
-static inline Int ?|?( Int oper1, Int oper2 ) { Int disjunction; mpz_ior( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
-static inline Int ?|?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
-static inline Int ?|?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
-static inline Int ?|?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
-static inline Int ?|?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
-static inline Int ?|=?( Int & lhs, Int rhs ) { return lhs = lhs | rhs; }
-
-static inline Int ?^?( Int oper1, Int oper2 ) { Int disjunction; mpz_xor( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
-static inline Int ?^?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
-static inline Int ?^?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
-static inline Int ?^?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
-static inline Int ?^?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
-static inline Int ?^=?( Int & lhs, Int rhs ) { return lhs = lhs ^ rhs; }
-
-static inline Int ?+?( Int addend1, Int addend2 ) { Int sum; mpz_add( sum.mpz, addend1.mpz, addend2.mpz ); return sum; }
-static inline Int ?+?( Int addend1, long int addend2 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
-static inline Int ?+?( long int addend2, Int addend1 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
-static inline Int ?+?( Int addend1, unsigned long int addend2 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
-static inline Int ?+?( unsigned long int addend2, Int addend1 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
-static inline Int ?+=?( Int & lhs, Int rhs ) { return lhs = lhs + rhs; }
-static inline Int ?+=?( Int & lhs, long int rhs ) { return lhs = lhs + rhs; }
-static inline Int ?+=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs + rhs; }
-static inline Int ++?( Int & lhs ) { return lhs += 1; }
-static inline Int ?++( Int & lhs ) { Int ret = lhs; lhs += 1; return ret; }
-
-static inline Int ?-?( Int minuend, Int subtrahend ) { Int diff; mpz_sub( diff.mpz, minuend.mpz, subtrahend.mpz ); return diff; }
-static inline Int ?-?( Int minuend, long int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); else mpz_add_ui( diff.mpz, minuend.mpz, -subtrahend ); return diff; }
-static inline Int ?-?( long int minuend, Int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); else { mpz_add_ui( diff.mpz, subtrahend.mpz, -minuend ); mpz_neg( diff.mpz, diff.mpz ); } return diff; }
-static inline Int ?-?( Int minuend, unsigned long int subtrahend ) { Int diff; mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); return diff; }
-static inline Int ?-?( unsigned long int minuend, Int subtrahend ) { Int diff; mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); return diff; }
-static inline Int ?-=?( Int & lhs, Int rhs ) { return lhs = lhs - rhs; }
-static inline Int ?-=?( Int & lhs, long int rhs ) { return lhs = lhs - rhs; }
-static inline Int ?-=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs - rhs; }
-static inline Int --?( Int & lhs ) { return lhs -= 1; }
-static inline Int ?--( Int & lhs ) { Int ret = lhs; lhs -= 1; return ret; }
-
-static inline Int ?*?( Int multiplicator, Int multiplicand ) { Int product; mpz_mul( product.mpz, multiplicator.mpz, multiplicand.mpz ); return product; }
-static inline Int ?*?( Int multiplicator, long int multiplicand ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
-static inline Int ?*?( long int multiplicand, Int multiplicator ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
-static inline Int ?*?( Int multiplicator, unsigned long int multiplicand ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
-static inline Int ?*?( unsigned long int multiplicand, Int multiplicator ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
-static inline Int ?*=?( Int & lhs, Int rhs ) { return lhs = lhs * rhs; }
-static inline Int ?*=?( Int & lhs, long int rhs ) { return lhs = lhs * rhs; }
-static inline Int ?*=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs * rhs; }
-
-// some code for operators "/" and "%" taken from g++ gmpxx.h
-static inline Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; }
-static inline Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; }
-static inline Int ?/?( unsigned long int dividend, Int divisor ) {
-	Int quotient;
-    if ( mpz_sgn( divisor.mpz ) >= 0 ) {
-		if ( mpz_fits_ulong_p( divisor.mpz ) )
-			mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( divisor.mpz ) );
-		else
-			mpz_set_ui( quotient.mpz, 0 );
-	} else {
-		mpz_neg( quotient.mpz, divisor.mpz );
-		if ( mpz_fits_ulong_p( quotient.mpz ) ) {
-			mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( quotient.mpz ) );
+static inline {
+	// constructor
+	void ?{}( Int & this ) { mpz_init( this.mpz ); }
+	void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); }
+	void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); }
+	void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); }
+	void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); }
+	void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); }
+	void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
+	void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
+
+	// literal
+	Int ?`mp( signed long int init ) { return (Int){ init }; }
+	Int ?`mp( unsigned long int init ) { return (Int){ init }; }
+	Int ?`mp( const char * init ) { return (Int){ init }; }
+
+	// assignment
+	Int ?=?( Int & lhs, Int rhs ) { mpz_set( lhs.mpz, rhs.mpz ); return lhs; }
+	Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; }
+	Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; }
+	Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { printf( "invalid string conversion\n" ); abort(); } return lhs; }
+
+	char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
+	short int ?=?( short int & lhs, Int rhs ) { short int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
+	int ?=?( int & lhs, Int rhs ) { int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
+	long int ?=?( long int & lhs, Int rhs ) { long int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
+	unsigned char ?=?( unsigned char & lhs, Int rhs ) { unsigned char val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
+	unsigned short int ?=?( unsigned short int & lhs, Int rhs ) { unsigned short int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
+	unsigned int ?=?( unsigned int & lhs, Int rhs ) { unsigned int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
+	unsigned long int ?=?( unsigned long int & lhs, Int rhs ) { unsigned long int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
+
+	// conversions
+	long int narrow( Int val ) { return mpz_get_si( val.mpz ); }
+	unsigned long int narrow( Int val ) { return mpz_get_ui( val.mpz ); }
+
+	// comparison
+	int ?==?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) == 0; }
+	int ?==?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
+	int ?==?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
+	int ?==?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
+	int ?==?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
+
+	int ?!=?( Int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
+	int ?!=?( Int oper1, long int oper2 ) { return ! ( oper1 == oper2 ); }
+	int ?!=?( long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
+	int ?!=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 == oper2 ); }
+	int ?!=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
+
+	int ?<?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) < 0; }
+	int ?<?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
+	int ?<?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
+	int ?<?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
+	int ?<?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
+
+	int ?<=?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) <= 0; }
+	int ?<=?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
+	int ?<=?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
+	int ?<=?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
+	int ?<=?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
+
+	int ?>?( Int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
+	int ?>?( Int oper1, long int oper2 ) { return ! ( oper1 <= oper2 ); }
+	int ?>?( long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
+	int ?>?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 <= oper2 ); }
+	int ?>?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
+
+	int ?>=?( Int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
+	int ?>=?( Int oper1, long int oper2 ) { return ! ( oper1 < oper2 ); }
+	int ?>=?( long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
+	int ?>=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 < oper2 ); }
+	int ?>=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
+
+	// arithmetic
+	Int +?( Int oper ) { Int pos; mpz_set( pos.mpz, oper.mpz ); return pos; }
+	Int -?( Int oper ) { Int neg; mpz_neg( neg.mpz, oper.mpz ); return neg; }
+	Int ~?( Int oper ) { Int comp; mpz_com( comp.mpz, oper.mpz ); return comp; }
+
+	Int ?&?( Int oper1, Int oper2 ) { Int conjunction; mpz_and( conjunction.mpz, oper1.mpz, oper2.mpz ); return conjunction; }
+	Int ?&?( Int oper1, long int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
+	Int ?&?( long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
+	Int ?&?( Int oper1, unsigned long int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
+	Int ?&?( unsigned long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
+	Int ?&=?( Int & lhs, Int rhs ) { return lhs = lhs & rhs; }
+
+	Int ?|?( Int oper1, Int oper2 ) { Int disjunction; mpz_ior( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
+	Int ?|?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
+	Int ?|?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
+	Int ?|?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
+	Int ?|?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
+	Int ?|=?( Int & lhs, Int rhs ) { return lhs = lhs | rhs; }
+
+	Int ?^?( Int oper1, Int oper2 ) { Int disjunction; mpz_xor( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
+	Int ?^?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
+	Int ?^?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
+	Int ?^?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
+	Int ?^?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
+	Int ?^=?( Int & lhs, Int rhs ) { return lhs = lhs ^ rhs; }
+
+	Int ?+?( Int addend1, Int addend2 ) { Int sum; mpz_add( sum.mpz, addend1.mpz, addend2.mpz ); return sum; }
+	Int ?+?( Int addend1, long int addend2 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
+	Int ?+?( long int addend2, Int addend1 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
+	Int ?+?( Int addend1, unsigned long int addend2 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
+	Int ?+?( unsigned long int addend2, Int addend1 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
+	Int ?+=?( Int & lhs, Int rhs ) { return lhs = lhs + rhs; }
+	Int ?+=?( Int & lhs, long int rhs ) { return lhs = lhs + rhs; }
+	Int ?+=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs + rhs; }
+	Int ++?( Int & lhs ) { return lhs += 1; }
+	Int ?++( Int & lhs ) { Int ret = lhs; lhs += 1; return ret; }
+
+	Int ?-?( Int minuend, Int subtrahend ) { Int diff; mpz_sub( diff.mpz, minuend.mpz, subtrahend.mpz ); return diff; }
+	Int ?-?( Int minuend, long int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); else mpz_add_ui( diff.mpz, minuend.mpz, -subtrahend ); return diff; }
+	Int ?-?( long int minuend, Int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); else { mpz_add_ui( diff.mpz, subtrahend.mpz, -minuend ); mpz_neg( diff.mpz, diff.mpz ); } return diff; }
+	Int ?-?( Int minuend, unsigned long int subtrahend ) { Int diff; mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); return diff; }
+	Int ?-?( unsigned long int minuend, Int subtrahend ) { Int diff; mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); return diff; }
+	Int ?-=?( Int & lhs, Int rhs ) { return lhs = lhs - rhs; }
+	Int ?-=?( Int & lhs, long int rhs ) { return lhs = lhs - rhs; }
+	Int ?-=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs - rhs; }
+	Int --?( Int & lhs ) { return lhs -= 1; }
+	Int ?--( Int & lhs ) { Int ret = lhs; lhs -= 1; return ret; }
+
+	Int ?*?( Int multiplicator, Int multiplicand ) { Int product; mpz_mul( product.mpz, multiplicator.mpz, multiplicand.mpz ); return product; }
+	Int ?*?( Int multiplicator, long int multiplicand ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
+	Int ?*?( long int multiplicand, Int multiplicator ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
+	Int ?*?( Int multiplicator, unsigned long int multiplicand ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
+	Int ?*?( unsigned long int multiplicand, Int multiplicator ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
+	Int ?*=?( Int & lhs, Int rhs ) { return lhs = lhs * rhs; }
+	Int ?*=?( Int & lhs, long int rhs ) { return lhs = lhs * rhs; }
+	Int ?*=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs * rhs; }
+
+	// some code for operators "/" and "%" taken from g++ gmpxx.h
+	Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; }
+	Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; }
+	Int ?/?( unsigned long int dividend, Int divisor ) {
+		Int quotient;
+		if ( mpz_sgn( divisor.mpz ) >= 0 ) {
+			if ( mpz_fits_ulong_p( divisor.mpz ) )
+				mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( divisor.mpz ) );
+			else
+				mpz_set_ui( quotient.mpz, 0 );
+		} else {
+			mpz_neg( quotient.mpz, divisor.mpz );
+			if ( mpz_fits_ulong_p( quotient.mpz ) ) {
+				mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( quotient.mpz ) );
+				mpz_neg( quotient.mpz, quotient.mpz );
+			} else
+				mpz_set_ui( quotient.mpz, 0 );
+		} // if
+		return quotient;
+	} // ?/?
+	Int ?/?( Int dividend, long int divisor ) {
+		Int quotient;
+		if ( divisor >= 0 )
+			mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor );
+		else {
+			mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, -divisor );
 			mpz_neg( quotient.mpz, quotient.mpz );
-		} else
-			mpz_set_ui( quotient.mpz, 0 );
-	} // if
-	return quotient;
-} // ?/?
-static inline Int ?/?( Int dividend, long int divisor ) {
-	Int quotient;
-    if ( divisor >= 0 )
-		mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor );
-    else {
-		mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, -divisor );
-		mpz_neg( quotient.mpz, quotient.mpz );
-	} // if
-	return quotient;
-} // ?/?
-static inline Int ?/?( long int dividend, Int divisor ) {
-	Int quotient;
-    if ( mpz_fits_slong_p( divisor.mpz ) )
-		mpz_set_si( quotient.mpz, dividend / mpz_get_si( divisor.mpz ) );
-    else {
-        // if divisor is bigger than a long then the quotient must be zero, unless dividend==LONG_MIN and
-        // dividend==-LONG_MIN in which case the quotient is -1
-        mpz_set_si( quotient.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? -1 : 0 );
-	} // if
-	return quotient;
-} // ?/?
-static inline Int ?/=?( Int & lhs, Int rhs ) { return lhs = lhs / rhs; }
-static inline Int ?/=?( Int & lhs, long int rhs ) { return lhs = lhs / rhs; }
-static inline Int ?/=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs / rhs; }
-
-static inline [ Int, Int ] div( Int dividend, Int divisor ) { Int quotient, remainder; mpz_fdiv_qr( quotient.mpz, remainder.mpz, dividend.mpz, divisor.mpz ); return [ quotient, remainder ]; }
-static inline [ Int, Int ] div( Int dividend, unsigned long int divisor ) { Int quotient, remainder; mpz_fdiv_qr_ui( quotient.mpz, remainder.mpz, dividend.mpz, divisor ); return [ quotient, remainder ]; }
-
-static inline Int ?%?( Int dividend, Int divisor ) { Int remainder; mpz_tdiv_r( remainder.mpz, dividend.mpz, divisor.mpz ); return remainder; }
-static inline Int ?%?( Int dividend, unsigned long int divisor ) { Int remainder; mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, divisor ); return remainder; }
-static inline Int ?%?( unsigned long int dividend, Int divisor ) {
-	Int remainder;
-    if ( mpz_sgn( divisor.mpz ) >= 0 ) {
-		if ( mpz_fits_ulong_p( divisor.mpz ) )
-			mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( divisor.mpz ) );
-		else
-			mpz_set_ui( remainder.mpz, dividend );
-	} else {
-		mpz_neg( remainder.mpz, divisor.mpz );
-		if ( mpz_fits_ulong_p( remainder.mpz ) )
-			mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( remainder.mpz ) );
-		else
-			mpz_set_ui( remainder.mpz, dividend );
-	} // if
-	return remainder;
-} // ?%?
-static inline Int ?%?( Int dividend, long int divisor ) {
-	Int remainder;
-    mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, (divisor >= 0 ? divisor : -divisor));
-	return remainder;
-} // ?%?
-static inline Int ?%?( long int dividend, Int divisor ) {
-	Int remainder;
-    if ( mpz_fits_slong_p( divisor.mpz ) )
-		mpz_set_si( remainder.mpz, dividend % mpz_get_si( divisor.mpz ) );
-	else {
-		// if divisor is bigger than a long then the remainder is dividend unchanged, unless dividend==LONG_MIN and
-		// dividend==-LONG_MIN in which case the remainder is 0
-        mpz_set_si( remainder.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? 0 : dividend);
-	} // if
-	return remainder;
-} // ?%?
-static inline Int ?%=?( Int & lhs, Int rhs ) { return lhs = lhs % rhs; }
-static inline Int ?%=?( Int & lhs, long int rhs ) { return lhs = lhs % rhs; }
-static inline Int ?%=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs % rhs; }
-
-static inline Int ?<<?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_mul_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
-static inline Int ?<<=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs << shift; }
-static inline Int ?>>?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_fdiv_q_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
-static inline Int ?>>=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs >> shift; }
-
-// number functions
-static inline Int abs( Int oper ) { Int positive; mpz_abs( positive.mpz, oper.mpz ); return positive; }
-static inline Int fact( unsigned long int N ) { Int factorial; mpz_fac_ui( factorial.mpz, N ); return factorial; }
-static inline Int gcd( Int oper1, Int oper2 ) { Int gcdret; mpz_gcd( gcdret.mpz, oper1.mpz, oper2.mpz ); return gcdret; }
-static inline Int pow( Int base, unsigned long int exponent ) { Int power; mpz_pow_ui( power.mpz, base.mpz, exponent ); return power; }
-static inline Int pow( unsigned long int base, unsigned long int exponent ) { Int power; mpz_ui_pow_ui( power.mpz, base, exponent ); return power; }
-static inline void srandom( gmp_randstate_t state ) { gmp_randinit_default( state ); }
-static inline Int random( gmp_randstate_t state, mp_bitcnt_t n ) { Int rand; mpz_urandomb( rand.mpz, state, n ); return rand; }
-static inline Int random( gmp_randstate_t state, Int n ) { Int rand; mpz_urandomm( rand.mpz, state, n.mpz ); return rand; }
-static inline Int random( gmp_randstate_t state, mp_size_t max_size ) { Int rand; mpz_random( rand.mpz, max_size ); return rand; }
-static inline int sgn( Int oper ) { return mpz_sgn( oper.mpz ); }
-static inline Int sqrt( Int oper ) { Int root; mpz_sqrt( root.mpz, oper.mpz ); return root; }
-
-// I/O
-static inline forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, Int & mp ) {
- 	gmp_scanf( "%Zd", &mp );
- 	return is;
-} // ?|?
-
-static inline forall( dtype ostype | ostream( ostype ) ) {
-	ostype & ?|?( ostype & os, Int mp ) {
-		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-		gmp_printf( "%Zd", mp.mpz );
-		sepOn( os );
-		return os;
+		} // if
+		return quotient;
+	} // ?/?
+	Int ?/?( long int dividend, Int divisor ) {
+		Int quotient;
+		if ( mpz_fits_slong_p( divisor.mpz ) )
+			mpz_set_si( quotient.mpz, dividend / mpz_get_si( divisor.mpz ) );
+		else {
+			// if divisor is bigger than a long then the quotient must be zero, unless dividend==LONG_MIN and
+			// dividend==-LONG_MIN in which case the quotient is -1
+			mpz_set_si( quotient.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? -1 : 0 );
+		} // if
+		return quotient;
+	} // ?/?
+	Int ?/=?( Int & lhs, Int rhs ) { return lhs = lhs / rhs; }
+	Int ?/=?( Int & lhs, long int rhs ) { return lhs = lhs / rhs; }
+	Int ?/=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs / rhs; }
+
+	[ Int, Int ] div( Int dividend, Int divisor ) { Int quotient, remainder; mpz_fdiv_qr( quotient.mpz, remainder.mpz, dividend.mpz, divisor.mpz ); return [ quotient, remainder ]; }
+	[ Int, Int ] div( Int dividend, unsigned long int divisor ) { Int quotient, remainder; mpz_fdiv_qr_ui( quotient.mpz, remainder.mpz, dividend.mpz, divisor ); return [ quotient, remainder ]; }
+
+	Int ?%?( Int dividend, Int divisor ) { Int remainder; mpz_tdiv_r( remainder.mpz, dividend.mpz, divisor.mpz ); return remainder; }
+	Int ?%?( Int dividend, unsigned long int divisor ) { Int remainder; mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, divisor ); return remainder; }
+	Int ?%?( unsigned long int dividend, Int divisor ) {
+		Int remainder;
+		if ( mpz_sgn( divisor.mpz ) >= 0 ) {
+			if ( mpz_fits_ulong_p( divisor.mpz ) )
+				mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( divisor.mpz ) );
+			else
+				mpz_set_ui( remainder.mpz, dividend );
+		} else {
+			mpz_neg( remainder.mpz, divisor.mpz );
+			if ( mpz_fits_ulong_p( remainder.mpz ) )
+				mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( remainder.mpz ) );
+			else
+				mpz_set_ui( remainder.mpz, dividend );
+		} // if
+		return remainder;
+	} // ?%?
+	Int ?%?( Int dividend, long int divisor ) {
+		Int remainder;
+		mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, (divisor >= 0 ? divisor : -divisor));
+		return remainder;
+	} // ?%?
+	Int ?%?( long int dividend, Int divisor ) {
+		Int remainder;
+		if ( mpz_fits_slong_p( divisor.mpz ) )
+			mpz_set_si( remainder.mpz, dividend % mpz_get_si( divisor.mpz ) );
+		else {
+			// if divisor is bigger than a long then the remainder is dividend unchanged, unless dividend==LONG_MIN and
+			// dividend==-LONG_MIN in which case the remainder is 0
+			mpz_set_si( remainder.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? 0 : dividend);
+		} // if
+		return remainder;
+	} // ?%?
+	Int ?%=?( Int & lhs, Int rhs ) { return lhs = lhs % rhs; }
+	Int ?%=?( Int & lhs, long int rhs ) { return lhs = lhs % rhs; }
+	Int ?%=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs % rhs; }
+
+	Int ?<<?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_mul_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
+	Int ?<<=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs << shift; }
+	Int ?>>?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_fdiv_q_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
+	Int ?>>=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs >> shift; }
+
+	// number functions
+	Int abs( Int oper ) { Int positive; mpz_abs( positive.mpz, oper.mpz ); return positive; }
+	Int fact( unsigned long int N ) { Int factorial; mpz_fac_ui( factorial.mpz, N ); return factorial; }
+	Int gcd( Int oper1, Int oper2 ) { Int gcdret; mpz_gcd( gcdret.mpz, oper1.mpz, oper2.mpz ); return gcdret; }
+	Int pow( Int base, unsigned long int exponent ) { Int power; mpz_pow_ui( power.mpz, base.mpz, exponent ); return power; }
+	Int pow( unsigned long int base, unsigned long int exponent ) { Int power; mpz_ui_pow_ui( power.mpz, base, exponent ); return power; }
+	void srandom( gmp_randstate_t state ) { gmp_randinit_default( state ); }
+	Int random( gmp_randstate_t state, mp_bitcnt_t n ) { Int rand; mpz_urandomb( rand.mpz, state, n ); return rand; }
+	Int random( gmp_randstate_t state, Int n ) { Int rand; mpz_urandomm( rand.mpz, state, n.mpz ); return rand; }
+	Int random( gmp_randstate_t state, mp_size_t max_size ) { Int rand; mpz_random( rand.mpz, max_size ); return rand; }
+	int sgn( Int oper ) { return mpz_sgn( oper.mpz ); }
+	Int sqrt( Int oper ) { Int root; mpz_sqrt( root.mpz, oper.mpz ); return root; }
+
+	// I/O
+	forall( dtype istype | istream( istype ) )
+		istype & ?|?( istype & is, Int & mp ) {
+		gmp_scanf( "%Zd", &mp );
+		return is;
 	} // ?|?
 
-	void ?|?( ostype & os, Int mp ) {
-		(ostype)(os | mp); nl( os );
-	} // ?|?
+	forall( dtype ostype | ostream( ostype ) ) {
+		ostype & ?|?( ostype & os, Int mp ) {
+			if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+			gmp_printf( "%Zd", mp.mpz );
+			sepOn( os );
+			return os;
+		} // ?|?
+
+		void ?|?( ostype & os, Int mp ) {
+			(ostype)(os | mp); ends( os );
+		} // ?|?
+	} // distribution
 } // distribution
 
Index: libcfa/src/iostream.cfa
===================================================================
--- libcfa/src/iostream.cfa	(revision 2233ad4f2f307ae7580e22f19484a599cead20d9)
+++ libcfa/src/iostream.cfa	(revision 65240bbf85edbcb53a5d3c3101d0486d5b11f3bb)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jun 13 17:21:10 2019
-// Update Count     : 812
+// Last Modified On : Fri Jul 12 12:04:13 2019
+// Update Count     : 819
 //
 
@@ -30,5 +30,5 @@
 
 
-//*********************************** Ostream ***********************************
+//*********************************** ostream ***********************************
 
 
@@ -40,5 +40,5 @@
 	} // ?|?
 	void ?|?( ostype & os, zero_t z ) {
-		(ostype &)(os | z); nl( os );
+		(ostype &)(os | z); ends( os );
 	} // ?|?
 
@@ -49,5 +49,5 @@
 	} // ?|?
 	void ?|?( ostype & os, one_t o ) {
-		(ostype &)(os | o); nl( os );
+		(ostype &)(os | o); ends( os );
 	} // ?|?
 
@@ -58,5 +58,5 @@
 	} // ?|?
 	void ?|?( ostype & os, bool b ) {
-		(ostype &)(os | b); nl( os );
+		(ostype &)(os | b); ends( os );
 	} // ?|?
 
@@ -67,5 +67,5 @@
 	} // ?|?
 	void ?|?( ostype & os, char c ) {
-		(ostype &)(os | c); nl( os );
+		(ostype &)(os | c); ends( os );
 	} // ?|?
 
@@ -76,5 +76,5 @@
 	} // ?|?
 	void ?|?( ostype & os, signed char sc ) {
-		(ostype &)(os | sc); nl( os );
+		(ostype &)(os | sc); ends( os );
 	} // ?|?
 
@@ -85,5 +85,5 @@
 	} // ?|?
 	void ?|?( ostype & os, unsigned char usc ) {
-		(ostype &)(os | usc); nl( os );
+		(ostype &)(os | usc); ends( os );
 	} // ?|?
 
@@ -94,5 +94,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, short int si ) {
-		(ostype &)(os | si); nl( os );
+		(ostype &)(os | si); ends( os );
 	} // ?|?
 
@@ -103,5 +103,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, unsigned short int usi ) {
-		(ostype &)(os | usi); nl( os );
+		(ostype &)(os | usi); ends( os );
 	} // ?|?
 
@@ -112,5 +112,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, int i ) {
-		(ostype &)(os | i); nl( os );
+		(ostype &)(os | i); ends( os );
 	} // ?|?
 
@@ -121,5 +121,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, unsigned int ui ) {
-		(ostype &)(os | ui); nl( os );
+		(ostype &)(os | ui); ends( os );
 	} // ?|?
 
@@ -130,5 +130,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, long int li ) {
-		(ostype &)(os | li); nl( os );
+		(ostype &)(os | li); ends( os );
 	} // ?|?
 
@@ -139,5 +139,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, unsigned long int uli ) {
-		(ostype &)(os | uli); nl( os );
+		(ostype &)(os | uli); ends( os );
 	} // ?|?
 
@@ -148,5 +148,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, long long int lli ) {
-		(ostype &)(os | lli); nl( os );
+		(ostype &)(os | lli); ends( os );
 	} // ?|?
 
@@ -157,5 +157,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, unsigned long long int ulli ) {
-		(ostype &)(os | ulli); nl( os );
+		(ostype &)(os | ulli); ends( os );
 	} // ?|?
 
@@ -180,5 +180,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, float f ) {
-		(ostype &)(os | f); nl( os );
+		(ostype &)(os | f); ends( os );
 	} // ?|?
 
@@ -189,5 +189,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, double d ) {
-		(ostype &)(os | d); nl( os );
+		(ostype &)(os | d); ends( os );
 	} // ?|?
 
@@ -198,5 +198,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, long double ld ) {
-		(ostype &)(os | ld); nl( os );
+		(ostype &)(os | ld); ends( os );
 	} // ?|?
 
@@ -210,5 +210,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, float _Complex fc ) {
-		(ostype &)(os | fc); nl( os );
+		(ostype &)(os | fc); ends( os );
 	} // ?|?
 
@@ -222,5 +222,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, double _Complex dc ) {
-		(ostype &)(os | dc); nl( os );
+		(ostype &)(os | dc); ends( os );
 	} // ?|?
 
@@ -234,5 +234,5 @@
 	} // ?|?
 	void & ?|?( ostype & os, long double _Complex ldc ) {
-		(ostype &)(os | ldc); nl( os );
+		(ostype &)(os | ldc); ends( os );
 	} // ?|?
 
@@ -276,5 +276,5 @@
 	} // ?|?
 	void ?|?( ostype & os, const char * str ) {
-		(ostype &)(os | str); nl( os );
+		(ostype &)(os | str); ends( os );
 	} // ?|?
 
@@ -305,5 +305,5 @@
 	} // ?|?
 	void ?|?( ostype & os, const void * p ) {
-		(ostype &)(os | p); nl( os );
+		(ostype &)(os | p); ends( os );
 	} // ?|?
 
@@ -315,5 +315,5 @@
 	void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
 		(ostype &)(manip( os ));
-		if ( getPrt( os ) ) nl( os );					// something printed ?
+		if ( getPrt( os ) ) ends( os );					// something printed ?
 		setPrt( os, false );							// turn off
 	} // ?|?
@@ -335,9 +335,4 @@
 	} // nl
 
-	void nl( ostype & os ) {
-		if ( getANL( os ) ) (ostype &)(nl( os ));		// implementation only
-		else setPrt( os, false );						// turn off
-	} // nl
-
 	ostype & nonl( ostype & os ) {
 		setPrt( os, false );							// turn off
@@ -386,10 +381,10 @@
 	} // ?|?
 	void ?|?( ostype & os, T arg, Params rest ) {
-		// (ostype &)(?|?( os, arg, rest )); nl( os );
+		// (ostype &)(?|?( os, arg, rest )); ends( os );
 		(ostype &)(os | arg);							// print first argument
 		sepSetCur( os, sepGetTuple( os ) );				// switch to tuple separator
 		(ostype &)(os | rest);							// print remaining arguments
 		sepSetCur( os, sepGet( os ) );					// switch to regular separator
-		nl( os );
+		ends( os );
 	} // ?|?
 } // distribution
@@ -408,7 +403,7 @@
 } // distribution
 
-//*********************************** Manipulators ***********************************
-
-//*********************************** Integral ***********************************
+//*********************************** manipulators ***********************************
+
+//*********************************** integral ***********************************
 
 static const char * shortbin[] = { "0", "1", "10", "11", "100", "101", "110", "111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
@@ -478,5 +473,5 @@
 		return os; \
 	} /* ?|? */ \
-	void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
+	void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
 } // distribution
 
@@ -492,5 +487,5 @@
 IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
 
-//*********************************** Floating Point ***********************************
+//*********************************** floating point ***********************************
 
 #define PrintWithDP2( os, format, val, ... ) \
@@ -541,5 +536,5 @@
 		return os; \
 	} /* ?|? */ \
-	void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
+	void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
 } // distribution
 
@@ -547,5 +542,5 @@
 FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
 
-//*********************************** Character ***********************************
+//*********************************** character ***********************************
 
 forall( dtype ostype | ostream( ostype ) ) {
@@ -576,8 +571,8 @@
 		return os;
 	} // ?|?
-	void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); nl( os ); }
+	void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); ends( os ); }
 } // distribution
 
-//*********************************** C String ***********************************
+//*********************************** C string ***********************************
 
 forall( dtype ostype | ostream( ostype ) ) {
@@ -621,9 +616,9 @@
 		return os;
 	} // ?|?
-	void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); nl( os ); }
+	void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); ends( os ); }
 } // distribution
 
 
-//*********************************** Istream ***********************************
+//*********************************** istream ***********************************
 
 
@@ -771,5 +766,5 @@
 } // distribution
 
-//*********************************** Manipulators ***********************************
+//*********************************** manipulators ***********************************
 
 forall( dtype istype | istream( istype ) )
Index: libcfa/src/iostream.hfa
===================================================================
--- libcfa/src/iostream.hfa	(revision 2233ad4f2f307ae7580e22f19484a599cead20d9)
+++ libcfa/src/iostream.hfa	(revision 65240bbf85edbcb53a5d3c3101d0486d5b11f3bb)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jun 13 17:20:21 2019
-// Update Count     : 325
+// Last Modified On : Fri Jul 12 12:08:38 2019
+// Update Count     : 334
 //
 
@@ -19,5 +19,5 @@
 
 
-//*********************************** Ostream ***********************************
+//*********************************** ostream ***********************************
 
 
@@ -47,4 +47,5 @@
 	void sepSetTuple( ostype &, const char * );			// set tuple separator to string (15 character maximum)
 
+	void ends( ostype & os );							// end of output statement
 	int fail( ostype & );
 	int flush( ostype & );
@@ -98,6 +99,6 @@
 	void ?|?( ostype &, unsigned long long int );
 
-	ostype & ?|?( ostype &, float ); // FIX ME: should not be required
-	void ?|?( ostype &, float ); // FIX ME: should not be required
+	ostype & ?|?( ostype &, float );
+	void ?|?( ostype &, float );
 	ostype & ?|?( ostype &, double );
 	void ?|?( ostype &, double );
@@ -126,5 +127,4 @@
 	void ?|?( ostype &, ostype & (*)( ostype & ) );
 	ostype & nl( ostype & );
-	void nl( ostype & );
 	ostype & nonl( ostype & );
 	ostype & sep( ostype & );
@@ -150,5 +150,5 @@
 } // distribution
 
-//*********************************** Manipulators ***********************************
+//*********************************** manipulators ***********************************
 
 forall( otype T )
@@ -169,5 +169,5 @@
 }; // _Ostream_Manip
 
-//*********************************** Integral ***********************************
+//*********************************** integral ***********************************
 
 // See 6.7.9. 19) The initialization shall occur in initializer list order, each initializer provided for a particular
@@ -207,5 +207,5 @@
 IntegralFMTDecl( unsigned long long int, 'u' )
 
-//*********************************** Floating Point ***********************************
+//*********************************** floating point ***********************************
 
 // Default suffix for values with no fraction is "."
@@ -236,5 +236,5 @@
 FloatingPointFMTDecl( long double )
 
-//*********************************** Character ***********************************
+//*********************************** character ***********************************
 
 static inline {
@@ -253,5 +253,5 @@
 } // ?|?
 
-//*********************************** C String ***********************************
+//*********************************** C string ***********************************
 
 static inline {
@@ -272,5 +272,5 @@
 
 
-//*********************************** Istream ***********************************
+//*********************************** istream ***********************************
 
 
@@ -326,5 +326,5 @@
 } // distribution
 
-//*********************************** Manipulators ***********************************
+//*********************************** manipulators ***********************************
 
 struct _Istream_Cstr {
@@ -403,5 +403,5 @@
 
 
-//*********************************** Time ***********************************
+//*********************************** time ***********************************
 
 
Index: libcfa/src/rational.cfa
===================================================================
--- libcfa/src/rational.cfa	(revision 2233ad4f2f307ae7580e22f19484a599cead20d9)
+++ libcfa/src/rational.cfa	(revision 65240bbf85edbcb53a5d3c3101d0486d5b11f3bb)
@@ -10,6 +10,6 @@
 // Created On       : Wed Apr  6 17:54:28 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Mar 28 17:33:03 2019
-// Update Count     : 181
+// Last Modified On : Fri Jul 12 12:02:36 2019
+// Update Count     : 183
 //
 
@@ -167,5 +167,5 @@
 
 		void ?|?( ostype & os, Rational(RationalImpl) r ) {
-			(ostype &)(os | r); nl( os );
+			(ostype &)(os | r); ends( os );
 		} // ?|?
 	} // distribution
Index: libcfa/src/time.cfa
===================================================================
--- libcfa/src/time.cfa	(revision 2233ad4f2f307ae7580e22f19484a599cead20d9)
+++ libcfa/src/time.cfa	(revision 65240bbf85edbcb53a5d3c3101d0486d5b11f3bb)
@@ -10,6 +10,6 @@
 // Created On       : Tue Mar 27 13:33:14 2018
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Dec 23 22:57:48 2018
-// Update Count     : 57
+// Last Modified On : Fri Jul 12 12:03:19 2019
+// Update Count     : 59
 //
 
@@ -37,5 +37,5 @@
 		if ( ns != 0 ) {								// some ?
 			char buf[16];
-			(ostype &)(os | nanomsd( ns, buf ));			// print nanoseconds
+			(ostype &)(os | nanomsd( ns, buf ));		// print nanoseconds
 		} // if
 		return os;
@@ -43,5 +43,5 @@
 
 	void ?|?( ostype & os, Duration dur ) with( dur ) {
-		(ostype &)(os | dur); nl( os );
+		(ostype &)(os | dur); ends( os );
 	} // ?|?
 } // distribution
@@ -150,10 +150,10 @@
 		long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN;	// compute nanoseconds
 		if ( ns == 0 ) {								// none ?
-			(ostype &)(os | buf);							// print date/time/year
+			(ostype &)(os | buf);						// print date/time/year
 		} else {
 			buf[19] = '\0';								// truncate to "Wed Jun 30 21:49:08"
 			char buf2[16];
 			nanomsd( ns, buf2 );						// compute nanoseconds
-			(ostype &)(os | buf | buf2 | ' ' | &buf[20]);	// print date/time, nanoseconds and year
+			(ostype &)(os | buf | buf2 | ' ' | &buf[20]); // print date/time, nanoseconds and year
 		} // if
 		return os;
@@ -161,5 +161,5 @@
 
 	void ?|?( ostype & os, Time time ) with( time ) {
-		(ostype &)(os | time); nl( os );
+		(ostype &)(os | time); ends( os );
 	} // ?|?
 } // distribution
