[pari-sage] 01/03: Imported Upstream version 2.8-2771-gb70b447

Tobias Hansen thansen at moszumanska.debian.org
Tue Aug 9 15:26:21 UTC 2016


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository pari-sage.

commit 77b7a8e2d24db24ded3b61a2c14dcbbc7977c06a
Author: Tobias Hansen <thansen at debian.org>
Date:   Tue Aug 9 15:08:54 2016 +0000

    Imported Upstream version 2.8-2771-gb70b447
---
 AUTHORS                                            |    1 +
 CHANGES                                            |   92 +-
 COMPAT                                             |   10 +-
 config/Makefile.SH                                 |   14 +-
 config/version                                     |    2 +-
 doc/develop.tex                                    |   37 +-
 doc/gphelp.1                                       |    7 +
 doc/gphelp.in                                      |   42 +-
 doc/refcard.tex                                    |    2 +-
 doc/translations                                   |    3 -
 doc/usersFUNCS.tex                                 |   92 +-
 doc/usersch2.tex                                   |   10 +-
 doc/usersch3.tex                                   | 1252 +++++++---
 doc/usersch4.tex                                   |    6 +-
 doc/usersch5.tex                                   |  382 ++-
 doc/usersch6.tex                                   |   11 +-
 doc/usersch7.tex                                   |    2 +
 doc/usersch8.tex                                   |   59 +-
 misc/xgp                                           |   18 +-
 src/basemath/F2x.c                                 |  857 ++++++-
 src/basemath/F2xqE.c                               |   59 +-
 src/basemath/FF.c                                  |  226 +-
 src/basemath/Flx.c                                 |  408 +++-
 src/basemath/FlxqE.c                               |   80 +-
 src/basemath/FpE.c                                 |  262 +-
 src/basemath/FpV.c                                 |   16 +-
 src/basemath/FpX.c                                 |  296 ++-
 src/basemath/FpXQX_factor.c                        | 1356 +++++++++++
 src/basemath/FpXX.c                                |  434 +++-
 src/basemath/FpX_factor.c                          |  854 +------
 src/basemath/Hensel.c                              |   50 +-
 src/basemath/QX_factor.c                           |   46 +-
 src/basemath/RgV.c                                 |    6 +-
 src/basemath/RgX.c                                 |   59 +-
 src/basemath/ZG.c                                  |   55 +-
 src/basemath/alglin1.c                             |   32 +-
 src/basemath/alglin2.c                             |    6 +-
 src/basemath/alglin3.c                             |   15 +-
 src/basemath/arith1.c                              |  284 ++-
 src/basemath/arith2.c                              |  130 +-
 src/basemath/base1.c                               |  112 +-
 src/basemath/base2.c                               |   33 +-
 src/basemath/base5.c                               |  335 ++-
 src/basemath/bb_group.c                            |   24 +-
 src/basemath/bibli1.c                              |    4 +-
 src/basemath/bibli2.c                              |   19 +-
 src/basemath/buch1.c                               |    6 +-
 src/basemath/buch2.c                               |  110 +-
 src/basemath/buch3.c                               |   11 +-
 src/basemath/buch4.c                               |   10 +-
 src/basemath/crvwtors.c                            |   10 +-
 src/basemath/dirichlet.c                           |   15 +-
 src/basemath/ellanal.c                             |   78 +-
 src/basemath/elliptic.c                            |   94 +-
 src/basemath/ellisog.c                             |   12 +-
 src/basemath/ellpadicL.c                           |  190 --
 src/basemath/ellsea.c                              |  593 +++--
 src/basemath/elltors.c                             |    2 +-
 src/basemath/galconj.c                             |   39 +-
 src/basemath/gen1.c                                |    2 +-
 src/basemath/gen2.c                                |   17 +-
 src/basemath/gen3.c                                |   48 +-
 src/basemath/hnf_snf.c                             |   42 +-
 src/basemath/hyperell.c                            |  132 +-
 src/basemath/lfun.c                                |  340 ++-
 src/basemath/lfunutils.c                           |  588 +++--
 src/basemath/map.c                                 |   60 +-
 src/basemath/mellininv.c                           |   27 +-
 src/basemath/modsym.c                              | 1586 ++++++++----
 src/basemath/nffactor.c                            |  105 +-
 src/basemath/polarit1.c                            |   34 +-
 src/basemath/polarit2.c                            |   68 +-
 src/basemath/polarit3.c                            |  232 +-
 src/basemath/polclass.c                            |   16 +-
 src/basemath/polmodular.c                          |   42 +-
 src/basemath/prime.c                               |   37 +-
 src/basemath/qfisom.c                              |   45 +-
 src/basemath/random.c                              |   20 +-
 src/basemath/rootpol.c                             |  408 ++--
 src/basemath/subcyclo.c                            |    2 +-
 src/basemath/trans1.c                              |   79 +-
 src/basemath/trans2.c                              |  158 +-
 src/basemath/trans3.c                              |  439 ++--
 src/desc/deftune                                   |    7 +
 src/desc/doc_make                                  |    3 +-
 src/desc/gen_proto                                 |    1 +
 src/funclist                                       |  197 +-
 src/functions/default/factor_add_primes            |    4 +-
 src/functions/elliptic_curves/ellmoddegree         |    2 +-
 .../elliptic_curves/ellnonsingularmultiple         |    5 +-
 src/functions/elliptic_curves/ellpadicL            |  149 +-
 src/functions/elliptic_curves/genus2red            |    2 +-
 .../elliptic_curves/hyperellpadicfrobenius         |    7 +-
 src/functions/gp2c_internal/_norange               |    5 +
 src/functions/l_functions/lfun                     |    8 +-
 src/functions/l_functions/lfunabelianrelinit       |    2 +-
 src/functions/l_functions/lfuncheckfeq             |    2 +-
 src/functions/l_functions/lfunconductor            |    2 +-
 src/functions/l_functions/lfuncost                 |    4 +
 src/functions/l_functions/lfundiv                  |    2 +-
 src/functions/l_functions/lfungenus2               |   15 +
 src/functions/l_functions/lfunhardy                |    2 +-
 src/functions/l_functions/lfuninit                 |    2 +-
 src/functions/l_functions/lfunlambda               |    2 +-
 src/functions/l_functions/lfunmfpeters             |   17 +-
 src/functions/l_functions/lfunmfspec               |    2 +-
 src/functions/l_functions/lfunmul                  |    2 +-
 src/functions/l_functions/lfunorderzero            |    2 +-
 src/functions/l_functions/lfunrootres              |    2 +-
 src/functions/l_functions/lfunsymsqspec            |    2 +-
 src/functions/l_functions/lfuntheta                |    2 +-
 src/functions/l_functions/lfunthetainit            |    2 +-
 src/functions/l_functions/lfunzeros                |    2 +-
 src/functions/linear_algebra/qfisominit            |   12 +-
 src/functions/linear_algebra/vecsort               |    5 +-
 src/functions/modular_forms/msfromell              |   39 -
 .../msatkinlehner                                  |    2 +-
 .../{modular_forms => modular_symbols}/mscuspidal  |    2 +-
 .../mseisenstein                                   |    2 +-
 .../{modular_forms => modular_symbols}/mseval      |    2 +-
 .../{modular_forms => modular_symbols}/msfromcusp  |    2 +-
 src/functions/modular_symbols/msfromell            |   50 +
 src/functions/modular_symbols/msfromhecke          |   41 +
 src/functions/modular_symbols/msgetlevel           |    7 +
 src/functions/modular_symbols/msgetsign            |   15 +
 src/functions/modular_symbols/msgetweight          |   12 +
 .../{modular_forms => modular_symbols}/mshecke     |    2 +-
 .../{modular_forms => modular_symbols}/msinit      |    2 +-
 .../{modular_forms => modular_symbols}/msissymbol  |    2 +-
 .../{modular_forms => modular_symbols}/msnew       |    2 +-
 src/functions/modular_symbols/msomseval            |   19 +
 src/functions/modular_symbols/mspadicL             |  103 +
 src/functions/modular_symbols/mspadicinit          |   46 +
 src/functions/modular_symbols/mspadicmoments       |   41 +
 src/functions/modular_symbols/mspadicseries        |   79 +
 .../{modular_forms => modular_symbols}/mspathgens  |    2 +-
 .../{modular_forms => modular_symbols}/mspathlog   |    2 +-
 .../msqexpansion                                   |    2 +-
 .../{modular_forms => modular_symbols}/mssplit     |   12 +-
 .../{modular_forms => modular_symbols}/msstar      |    2 +-
 src/functions/modular_symbols/mstooms              |   67 +
 src/functions/number_fields/bnfnarrow              |    9 +-
 src/functions/number_fields/bnrgaloisapply         |    2 +-
 src/functions/number_fields/bnrinit                |   10 +-
 src/functions/number_fields/galoissubcyclo         |    2 +-
 src/functions/number_fields/galoissubfields        |    6 +-
 src/functions/number_fields/ideallistarch          |    2 +-
 src/functions/number_fields/idealpow               |    2 +-
 src/functions/number_fields/idealprincipalunits    |    2 +-
 src/functions/number_fields/nfbasis                |    4 +-
 src/functions/number_fields/nfcertify              |   13 +-
 src/functions/number_fields/nfeltdiveuc            |    2 +-
 src/functions/number_fields/nfeltdivrem            |    2 +-
 src/functions/number_fields/nfeltmod               |    2 +-
 src/functions/number_fields/nfgaloisconj           |   16 +-
 src/functions/number_fields/nfhnf                  |    2 +-
 src/functions/number_fields/nfnewprec              |   11 +-
 src/functions/number_fields/nfsplitting            |   16 +-
 src/functions/number_fields/polredabs              |   26 +-
 src/functions/number_fields/rnfeltabstorel         |   25 +-
 src/functions/number_fields/rnfeltdown             |   33 +-
 src/functions/number_fields/rnfelttrace            |    4 +-
 src/functions/number_fields/rnfeltup               |   18 +-
 src/functions/number_fields/rnfidealprimedec       |   30 +
 src/functions/number_fields/rnfidealreltoabs       |   53 +-
 src/functions/number_fields/rnfidealup             |   45 +-
 src/functions/number_fields/rnfinit                |   18 +-
 src/functions/number_theoretical/chareval          |   12 +-
 src/functions/number_theoretical/ispower           |    3 +-
 src/functions/number_theoretical/issquare          |   11 +
 src/functions/number_theoretical/qfbnupow          |    2 +-
 src/functions/number_theoretical/ramanujantau      |    4 +-
 src/functions/number_theoretical/znconreychar      |    2 +-
 src/functions/polynomials/polcoeff                 |    4 +-
 src/functions/polynomials/pollead                  |    2 +-
 src/functions/polynomials/polmodular               |   49 +-
 src/functions/polynomials/polresultant             |    8 +-
 src/functions/polynomials/polrootsreal             |    2 +-
 src/functions/polynomials/polsturm                 |   14 +-
 src/functions/programming/alias                    |    2 +-
 src/functions/programming/for                      |    5 +-
 src/functions/programming/forprime                 |    6 +-
 src/functions/programming/forstep                  |    7 +-
 src/functions/programming/parfor                   |    4 +-
 src/functions/programming/parforprime              |    4 +-
 src/functions/sums/intnumgauss                     |    4 +-
 src/functions/sums/solvestep                       |    7 +-
 src/functions/sums/sumalt                          |    6 +-
 src/functions/sums/sumnum                          |    2 +-
 src/functions/sums/sumpos                          |    2 +-
 src/functions/transcendental/eint1                 |    2 +-
 src/functions/transcendental/gammamellininv        |    2 +-
 src/functions/transcendental/gammamellininvinit    |    2 +-
 src/gp/gp.c                                        |    1 +
 src/gp/gp_init.h                                   |   12 +-
 src/gp/highlvl.h                                   |   58 +-
 src/gp/texmacs.c                                   |    2 +-
 src/graph/plotport.c                               |    4 +-
 src/headers/paridecl.h                             |  286 ++-
 src/headers/pariinl.h                              |   29 +-
 src/headers/pariold.h                              |   12 +-
 src/headers/paripriv.h                             |   17 +-
 src/headers/paristio.h                             |    3 +-
 src/headers/parisys.h                              |   16 -
 src/headers/paritune.h                             |   14 +
 src/kernel/gmp/mp.c                                |    2 +-
 src/kernel/gmp/tune.h                              |   14 +
 src/kernel/none/mp.c                               |    2 +-
 src/kernel/none/tune-gen.h                         |    7 +
 src/kernel/none/tune.h                             |   14 +
 src/language/anal.c                                |  302 +--
 src/language/compile.c                             |   18 +-
 src/language/default.h                             |   90 +-
 src/language/es.c                                  |  191 +-
 src/language/eval.c                                |   18 +-
 src/language/gplib.c                               |   32 +-
 src/language/hash.c                                |   15 +-
 src/language/init.c                                |   60 +-
 src/language/init.h                                | 1229 +++++-----
 src/language/intnum.c                              |   12 +-
 src/language/parse.c                               | 2548 +++++++++++---------
 src/language/parse.h                               |  121 +-
 src/language/parse.y                               |    7 +-
 src/language/sumiter.c                             |   51 +-
 src/language/tree.h                                |    2 +-
 src/modules/algebras.c                             |  139 +-
 src/modules/genus2red.c                            |    8 +-
 src/modules/krasner.c                              |    2 +-
 src/modules/kummer.c                               |   14 +-
 src/modules/mpqs.c                                 |    2 +-
 src/modules/stark.c                                |    4 +-
 src/modules/subfield.c                             |   10 +-
 src/mt/mpi.c                                       |   18 +-
 src/test/32/algebras                               | 1798 +++-----------
 src/test/32/bnr                                    |    7 +-
 src/test/32/charpoly                               |    1 +
 src/test/32/chinese                                |    8 +-
 src/test/32/compat                                 |   63 +-
 src/test/32/digits                                 |    7 +-
 src/test/32/div                                    |    8 +-
 src/test/32/ell                                    |   68 +-
 src/test/32/ellanal                                |    6 +-
 src/test/32/ellpadic                               |   13 +-
 src/test/32/ellweilpairing                         |   24 +-
 src/test/32/equal                                  |    1 +
 src/test/32/err                                    |   12 +-
 src/test/32/factorff                               |   97 +
 src/test/32/factormod                              |   16 +-
 src/test/32/ff                                     |  130 +-
 src/test/32/gamma                                  |   39 +-
 src/test/32/gcdext                                 |    3 +
 src/test/32/help                                   |   23 +-
 src/test/32/hyperell                               |    3 +-
 src/test/32/incgam                                 |   63 +-
 src/test/32/ispower                                |   18 +-
 src/test/32/iterator                               |   18 +
 src/test/32/lfun                                   |   70 +-
 src/test/32/lfuntype                               |  413 ++--
 src/test/32/lift                                   |   10 +-
 src/test/32/list                                   |    4 +-
 src/test/32/map                                    |    6 +
 src/test/32/member                                 |    8 +-
 src/test/32/modsym                                 |  140 +-
 src/test/32/mspadic                                |  309 +++
 src/test/32/nf                                     |   10 +-
 src/test/32/nfhilbert                              |   16 +-
 src/test/32/nfields                                |    2 +-
 src/test/32/nfsplitting                            |    6 +-
 src/test/32/padic                                  |    4 +-
 src/test/32/parallel                               |    1 +
 src/test/32/polred                                 |    3 +-
 src/test/32/qfisom                                 |    4 +-
 src/test/32/ramanujantau                           |    6 +-
 src/test/32/ranges                                 |    5 +
 src/test/32/rfrac                                  |    3 +-
 src/test/32/rnf                                    |  121 +-
 src/test/32/rnfkummer                              |    6 +-
 src/test/32/rootsreal                              |   23 +-
 src/test/32/ser                                    |    4 +-
 src/test/32/sqrtn                                  |    1 +
 src/test/32/trans                                  |    4 +-
 src/test/in/algebras                               |    2 -
 src/test/in/bnr                                    |    9 +
 src/test/in/charpoly                               |    1 +
 src/test/in/chinese                                |    4 +-
 src/test/in/digits                                 |    5 +
 src/test/in/ell                                    |    6 +-
 src/test/in/ellff                                  |   15 +
 src/test/in/ellpadic                               |   34 +-
 src/test/in/ellweilpairing                         |   47 +-
 src/test/in/equal                                  |    2 +
 src/test/in/err                                    |    3 +
 src/test/in/factorff                               |   55 +
 src/test/in/factormod                              |   14 +-
 src/test/in/ff                                     |   27 +-
 src/test/in/gamma                                  |    8 +
 src/test/in/gcdext                                 |    3 +
 src/test/in/hyperell                               |   12 +
 src/test/in/incgam                                 |   26 +-
 src/test/in/ispower                                |   17 +
 src/test/in/iterator                               |    4 +
 src/test/in/lfun                                   |   36 +-
 src/test/in/lfuntype                               |   10 +-
 src/test/in/lift                                   |    2 +-
 src/test/in/map                                    |    8 +
 src/test/in/modsym                                 |   97 +-
 src/test/in/mspadic                                |  167 ++
 src/test/in/nf                                     |    5 +
 src/test/in/nfields                                |    2 +-
 src/test/in/nfsplitting                            |    3 +
 src/test/in/padic                                  |    5 +
 src/test/in/parallel                               |    3 +-
 src/test/in/polred                                 |    1 +
 src/test/in/qfisom                                 |    3 +
 src/test/in/ramanujantau                           |    4 +
 src/test/in/ranges                                 |    5 +
 src/test/in/rfrac                                  |    2 +
 src/test/in/rnf                                    |   17 +-
 src/test/in/rootsreal                              |   28 +
 src/test/in/ser                                    |    3 +
 src/test/in/sqrtn                                  |    1 +
 src/test/in/trans                                  |    2 +-
 src/test/tune.c                                    |   75 +-
 323 files changed, 15307 insertions(+), 9807 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 8a4b8f4..218e92e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -112,6 +112,7 @@ JM = Jerome Milan
 JS = Juhana Sadeharju
 KO = Kiyoshi Ohgishi
 KPN= Klaus-Peter Nischke
+KR = Kevin Ryde
 LG = Louis Granboulan
 LGr= Loic Grenie
 LM = Lorenz Minder
diff --git a/CHANGES b/CHANGES
index e3ded87..930757b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -177,16 +177,42 @@ BA128- nfsubfields could fail [#1758]
   131- chinese([]) -> '1' instead of Mod(0,1)
   132- m1=Mod(0,1);m2=Mod(1,x^2+1); chinese(m1,m2) -> m1; chinese(m2,m1) -> m2
        [instead of error]
-  133- O(1) == O(x) returned 0 [#1765]
-  134- nfrootsof1(polcyclo(85)) -> 85 instead of 170 [#1766]
-  135- at \p19, polroots((x+1)^2 * (x-1)^7 * (x^2-x+1)^5 * 1.0) -> SEGV [#1767]
-BA136- ellsea returned the trace instead of the cardinal as documented.
-BA137- ellsea(,,1)  could return a wrong result [#1768]
-  138- rnfconductor: sanity checks were not taken into account
-MC139- memory leak in pari_close: sopath not freed
-HC140- incgam(30,60) < 0. More generally, wrong results for s >> 1 [#1689]
-HC141- excessive loss of accuracy in incgam, incgamc, eint1
-  142- isprimepower(30011^(3*17)) returned 0
+  133- nfrootsof1(polcyclo(85)) -> 85 instead of 170 [#1766]
+  134- at \p19, polroots((x+1)^2 * (x-1)^7 * (x^2-x+1)^5 * 1.0) -> SEGV [#1767]
+BA135- ellsea returned the trace instead of the cardinal as documented.
+BA136- ellsea(,,1)  could return a wrong result [#1768]
+  137- rnfconductor: sanity checks were not taken into account
+MC138- memory leak in pari_close: sopath not freed
+HC139- incgam(30,60) < 0. More generally, wrong results for s >> 1 [#1689]
+HC140- excessive loss of accuracy in incgam, incgamc, eint1
+  141- isprimepower(30011^(3*17)) returned 0
+  142- a = Mod(1,x); z = Mod(0,Pol(1)); chinese(a, z) works
+       but chinese(a, simplify(z)) failed
+BA143- [mpi] interrupt/alarm could caused a crash
+BA144- [mpi] relinking empty t_LIST caused a crash
+  145- ispower(t_POL) didn't work in small characteristic [#1779]; make it work
+       over finite fields
+BA146- my(s=1,a=0);forstep(i=1,20,s,s++;a+=i);a -> wrong result
+KR147- gphelp -detex: accented letters counted as 1 char for line splitting
+       but rendered as 2
+  148- sqrt(0) -> loss of accuracy (sqrtn was correct)
+  149- nfgaloisconj(t_POL T) was unnecessary slow when large divisors
+       of disc(T) were internally detected (and subsequently ignored)
+BA150- elltatepairing could return wrong results [#1784]
+  151- padicappr(x^3+1,-2+O(2^5)) -> SEGV [mod a root mod p] [#1793]
+  152- K = bnrinit(bnfinit(y^2-5),[1,[1,1]]); bnrdisc(K) -> wrong [#1804]
+  153- ellztopoint(ellinit([-1,0]), I) -> wrong result [#1800]
+       Potentially affected all elliptic functions (ellwp,ellzeta,ellsigma)
+       at real or pure imaginary arguments.
+  154- gamma(2+x) did not start with an exact 1, unlike gamma(1+x).
+       lngamma(2+x) didn't have valuation 1
+  155- gamma(t_INT+x) at large accuracy and seriesprecision was very slow,
+       even for small t_INTs (same for lngamma and psi). E.g. at \p1000
+       gamma(1000+x+O(x^100))
+  156- a=Mod(y,y^2+1); Mod(a, x^2-2) == a returned 0 [#1806]
+  157- x \/ y did not conform to documentation when either x or y was a
+       t_REAL. E.g. 28/10 \/ 1 == 3 but 2.8 \/ 1 == 2. Now both return 3 [#1811]
+BA158- digits(N,B) with 31/63 bit B could return wrong result
 
   Added
     1- add optional argument to sumdigits to specify the base
@@ -198,7 +224,8 @@ BA  5- [libpari] New functions family RgXn: new functions RgXnV_red_shallow,
        RgXn_powers, RgX_RgXnV_eval, RgX_RgXn_eval, RgXn_reverse, RgXn_inv,
        RgXn_exp
 BA  6- [libpari] New functions Flv_inv
-BA  7- [libpari] New functions Flx_Flv_eval, Flv_FlvV_polint
+BA  7- [libpari] New functions Flx_Flv_eval, Flv_Flm_polint,
+                               FpX_FpV_eval, FpV_FpM_polint
 WH  8- [libpari] New low-level functions get_Fl_inv, remll_pre
 BA  9- [libpari] New low-level functions Fl_sqr_pre, Fl_mul_pre, remlll_pre,
        Fl_powu_pre, Fl_sqrt_pre, divll_pre, random_Fle_pre
@@ -245,7 +272,7 @@ BA 43- GP function powers and libpari function gpowers
    44- flag LLL_COMPATIBLE for LLL routines [ use 64-bit compatible accuracies
        only ]
 BA 45- [libpari] functions FpX_Frobenius, FpX_matFrobenius, Flx_Frobenius,
-       Flx_matFrobenius, ZpX_Frobenius
+       Flx_matFrobenius, ZpX_Frobenius, F2x_Frobenius, F2x_matFrobenius
    46- [libpari] function ser_isexactzero
 BA 47- [libpari] functions ZV_chinese, Z_ZV_mod, Z_nv_mod, nmV_chinese_center
 BA 48- GP function fromdigits
@@ -400,6 +427,26 @@ SCh152- [mingw+pthread]: default nbthreads support
    154- optional argument 'tab' to teichmuller(x)
    155- [GP] function chareval, charmul, chardiv, zncharinduce, zncharisodd
    156- [libpari] Flm_intersect
+   157- [libpari] ggamma1m1
+   158- allow ispower(t_POLMOD representing a finite field element)
+   159- [libpari] Fq_ispower, FqX_ispower, RgX_deflate_order, Fq_to_FF,
+        FqX_to_FFX
+   160- [libpari] Z2_sqrt, divisorsu_fact, usumdiv_fact, usumdivk_fact
+   161- gphelp -detex: new flag -utf8 to allow utf-8 encoding in output, e.g.
+        render \'{e} as é (the actual eight-bit char) instead of 'e
+   162- GP function msfromhecke, msgetlevel, msgetweight, msgetsign
+BA 163- qfisominit: allow to pass the matrix of minimal vectors [#1656]
+   164- [libpari] GENtostr_raw
+BA 165- [libpari] FlxqX_halfgcd, FpXQX_halfgcd
+   166- issquare(t_POLMOD of t_INTMOD) assuming a finite field
+   167- RgXn_powu, RgXn_powu_i
+   168- [libpari] is_real_t, R_abs, R_abs_shallow
+BA 169- [libpari] F2xX, F2xqX, F2xqXQ family functions
+   170- GP function rnfidealprimedec
+BA 171- [libpari] get_FpX_algebra, get_FpXQ_algebra,  get_FpXQX_algebra,
+                  get_FlxqXQ_algebra, get_FpXQXQ_algebra, get_Rg_algebra
+   172- E/Qp: Added Mazur-Tate-Teitelbaum's L invariant to E.tate
+BA 173- [libpari] ZpXQ_div, ZpXQX_divrem, ZpXQX_digits
 
   Changed
     1- make log(+/-I) return (+/-)Pi/2*I with gen_0 real part [#1556]
@@ -510,6 +557,26 @@ BA 61- [libpari] concat, concat1 renamed to gconcat, gconcat1
    66- improved p-adic log at high accuracy (O(sqrt(padicprec)) algorithm
        instead of O(padicprec))
    67- allow genus2red to handle (rational) non integral models
+KR 68- new version of misc/xgp
+BA 69- rename Flc_Fl_mul -> Flv_Fl_mul, Flc_Fl_div -> Flv_Fl_div,
+       RgC_to_Flc to RgV_to_Flv, F2c_to_Flc to F2v_to_Flv
+   70- rename leading_term -> leading_coeff, constant_term -> constant_coeff
+   71- improve gamma(a+O(x))
+BA 72- Z_to_Flx now takes a shifted variable number, as Fl_to_Flx.
+BA 73- improve hash_GEN to reduce # of collisions (change glue)
+   74- added explicit ways to attach an absolute nf to a rnf structure,
+       allowing rnf functions to return objects in standard notation (e.g.
+       ideals in HNF instead of as a vector of t_POLMOD generators).
+       Add optional flag to rnfeltabstorel, rnfeltdown, rnfeltup,
+       rnfidealreltoabs, rnfinit
+BA 75- rename FlxqX_pow to FlxqX_powu
+   76- polredabs([T,listP]) no longer returns 0 if the attached order cannot
+       be proven to be maximal: it computes the expected canonical polynomial
+       in all cases, which can be very slow. Always use polredbest() if you
+       don't require a canonical output.
+   77- polredabs(T) now internally uses the polredabs([T,listP]) strategy,
+       making it much faster in favourable cases, while still always returning
+       a canonical defining polynomial.
 
 Removed
    1- deprecated functions nfbasis0, nfdisc0, factorpadic0
@@ -536,3 +603,4 @@ BA 7- divide_conquer_prod: use gen_product instead
       is needed. [#368, #1647]
 BA10- [libpari] FpXQX_rem_Barrett, FpXQX_divrem_Barrett: use FpXQX_get_red
 BA11- [libpari] FlxqX_rem_Barrett: use FlxqX_get_red
+BA12- [libpari] RgX_RgM_eval_col
diff --git a/COMPAT b/COMPAT
index 249759b..253e37f 100644
--- a/COMPAT
+++ b/COMPAT
@@ -58,6 +58,10 @@ This file lists the incompatible changes between Version 2.x and older versions
     as an analog to zetak(). Or directly lfun(x^2+1, s) if a single value
     is needed. [closes #368, #1647]
   - rnfconductor now returns [cond, bnr, H] instead of [cond, bnr.clgp, H]
+  - polredabs([T,listP]) no longer returns 0 if the attached order cannot
+     be proven to be maximal: it computes the expected canonical polynomial
+     in all cases, which can be very slow. Always use polredbest() if you
+     don't require a canonical output.
 
 * Specific to the PARI library:
 ===============================
@@ -84,7 +88,11 @@ This file lists the incompatible changes between Version 2.x and older versions
     nucomp(x,n) is nucomp(x,n,NULL).
   - divide_conquer_assoc renamed to gen_product, divide_conquer_prod removed
   - rename concat to gconcat, concat1 to gconcat1
-
+  - rename Flc_Fl_mul -> Flv_Fl_mul, Flc_Fl_div -> Flv_Fl_div,
+       RgC_to_Flc to RgV_to_Flv, F2c_to_Flc to F2v_to_Flv
+  - rename leading_term -> leading_coeff, constant_term -> constant_coeff
+  - Z_to_Flx now takes a shifted variable number, as Fl_to_Flx.
+  - rename FlxqX_pow to FlxqX_powu
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%% VERSION 2.6 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   - eval() no longer evaluates its arguments in "permissive" mode: eval("1a")
diff --git a/config/Makefile.SH b/config/Makefile.SH
index e7eea3d..27d446a 100644
--- a/config/Makefile.SH
+++ b/config/Makefile.SH
@@ -342,6 +342,8 @@ gp-sta: $add_funclist \$(OBJS) \$(OBJSGP)
 	\$(LD) -o \$@ \$(LDFLAGS) \$(OBJS) \$(OBJSGP) \$(RUNPTH) \$(RLLIBS) \$(PLOTLIBS) \$(STA_LIBS)
 	$postconfig gp-sta
 
+clean_pari_ps::
+	@-\$(RM) pari.ps
 cleantest:
 	\$(RM) *.dif gp.out io-testfile pari.ps
 cleanobj:
@@ -523,17 +525,17 @@ parimt.h: $src/mt/$thread_engine.h
 mpinl.h: parilvl0.h parilvl1.h
 	cat parilvl0.h parilvl1.h > mpinl.h
 
-bench: $exec
+bench: $exec clean_pari_ps
 	@\$(DOTEST) $test_basic
-dobench::
+dobench:: clean_pari_ps
 	@\$(DOTEST) $test_basic
-test-all: $exec
+test-all: $exec clean_pari_ps
 	@\$(DOTEST) $test_extra
-dotest-all::
+dotest-all:: clean_pari_ps
 	@\$(DOTEST) $test_extra
-dyntest-all: gp-dyn
+dyntest-all: gp-dyn clean_pari_ps
 	@env dotestSUF=dyn make test-all
-statest-all: gp-sta
+statest-all: gp-sta clean_pari_ps
 	@env dotestSUF=sta make test-all
 
 dotest-env::
diff --git a/config/version b/config/version
index 20a5d94..0ee68b9 100644
--- a/config/version
+++ b/config/version
@@ -11,7 +11,7 @@ patch='0'
 version_code=`expr $VersionMajor \\* 65536 + $VersionMinor \\* 256 + $patch`
 
 # Status: alpha, beta, released, development. Rewritten by config/settar !
-stat='development git-61b65cc'
+stat='development git-b70b447'
 
 # soname of stable libpari.so is libpari.so.$soname_num
 status="$stat"
diff --git a/doc/develop.tex b/doc/develop.tex
index 1a6db32..0f1f431 100644
--- a/doc/develop.tex
+++ b/doc/develop.tex
@@ -112,7 +112,7 @@ variables defined in the scope the closure was defined. To access it, use
 \subsec{Debugging information in closure}\label{se:dbgclosure}
 
 Every \typ{CLOSURE} object \kbd{z} has a component \kbd{dbg=z[5]}
-which which hold extra data needed for error-reporting and debugging.
+which hold extra data needed for error-reporting and debugging.
 The object \kbd{dbg} is a \typ{VEC} with $3$ components:
 
 \kbd{dbg[1]} is a \typ{VECSMALL} of the same length than \kbd{z[3]}. For each
@@ -392,7 +392,7 @@ Theses functions handle groups of rank at most $2$ equipped with a family of
 bilinear pairings which behave like the Weil pairing on elliptic curves over
 finite field.
 
-The function \kbd{pairorder(E, P, Q, m, F)} must return the order of of the $m$-pairing
+The function \kbd{pairorder(E, P, Q, m, F)} must return the order of the $m$-pairing
 of $P$ and $Q$, both of order dividing $m$, where $F$ is the factorisation matrix
 of a multiple of $m$.
 
@@ -504,6 +504,7 @@ struct bb_algebra
 {
   GEN (*red)(void *E, GEN x);
   GEN (*add)(void *E, GEN x, GEN y);
+  GEN (*sub)(void *E, GEN x, GEN y);
   GEN (*mul)(void *E, GEN x, GEN y);
   GEN (*sqr)(void *E, GEN x);
   GEN (*one)(void *E);
@@ -518,6 +519,8 @@ forms, but only \kbd{add} is allowed to return a non canonical form.
 
 \kbd{add(E,x,y)} returns the sum $x+y$.
 
+\kbd{sub(E,x,y)} returns the difference $x-y$.
+
 \kbd{mul(E,x,y)} returns the product $x\*y$.
 
 \kbd{sqr(E,x)} returns the square $x^2$.
@@ -554,7 +557,23 @@ accuracies, and thus have different weights.
 
 \subsec{Functions returning black box algebras}
 
+\fun{const struct bb_algebra *}{get_FpX_algebra}{void **E, GEN p, long v}
+return the algebra of polynomials over $\F_p$ in variable $v$.
+
+\fun{const struct bb_algebra *}{get_FpXQ_algebra}{void **E, GEN T, GEN p}
+return the algebra $\F_p[X]/(T(X))$.
+
+\fun{const struct bb_algebra *}{get_FpXQX_algebra}{void **E, GEN T, GEN p, long v}
+return the algebra of polynomials over $\F_p[X]/(T(X))$ in variable $v$.
+
+\fun{const struct bb_algebra *}{get_FlxqXQ_algebra}{void **E, GEN S, GEN T, ulong p}
+return the algebra $\F_p[X,Y]/(S(X,Y),T(X))$ (for \kbd{ulong} $p$).
+
+\fun{const struct bb_algebra *}{get_FpXQXQ_algebra}{void **E, GEN S, GEN T, GEN p}
+return the algebra $\F_p[X,Y]/(S(X,Y),T(X))$.
+
 \fun{const struct bb_algebra *}{get_Rg_algebra}{void}
+return the generic algebra.
 
 \section{Black box ring}
 
@@ -831,6 +850,20 @@ signal \kbd{sig}, using \tet{sigaction} with flag \tet{SA_NODEFER}. If
 \kbd{sigaction} is not available use \tet{signal}. If even the latter is not
 available, just return \tet{SIG_IGN}. Use \tet{sigaction}.
 
+\section{Embedded GP interpretor}
+These function provide a simplified interface to embed a GP
+interpretor in a program.
+
+\fun{void}{gp_embedded_init}{long rsize, long vsize}
+Initialize the GP interpretor (like \kbd{pari\_init} does) with
+\kbd{parisize=rsize} \kbd{rsize} and \kbd{parisizemax=vsize}.
+
+\fun{char *}{gp_embedded}{const char *s}
+Evaluate the string \kbd{s} with GP and return the result as a string,
+in a format similar to what GP displays (with the history index).
+The resulting string is allocated on the PARI stack, so subsequent call
+to \kbd{gp\_embedded} will destroy it.
+
 \chapter{Regression tests, benches}
 
 This chapter documents how to write an automated test module, say \kbd{fun},
diff --git a/doc/gphelp.1 b/doc/gphelp.1
index 4136fd9..234a951 100644
--- a/doc/gphelp.1
+++ b/doc/gphelp.1
@@ -7,6 +7,7 @@ gphelp \- GP-PARI online help script
 .IR file ]
 [-raw]
 [-detex]
+[-utf8]
 [-k]
 [-ch
 .IR c1 ]
@@ -125,6 +126,12 @@ mode. The TeX file is converted to readable screen output that is directly
 written to the terminal; don't use tex or xdvi.
 
 .TP
+.BI \-utf8
+In
+.B detex
+mode, use UTF-8 encoding for characters, .e.g. use é (é) instead of 'e.
+
+.TP
 .BI \-k
 Switch to
 .B apropos
diff --git a/doc/gphelp.in b/doc/gphelp.in
index 88b5160..3eed6be 100755
--- a/doc/gphelp.in
+++ b/doc/gphelp.in
@@ -33,6 +33,7 @@
 #  -to_pod file		convert file to POD (should be the only args)
 #
 #  -to_dumbpod file	same, but without nested formating
+#  -utf8  in detex mode, use UFT-8 encoding for output
 #
 # Granted environment variables (override):
 #  GPTMPDIR: where temporary files will go (/tmp by default).
@@ -83,7 +84,7 @@ sub help {
 }
 
 sub options {
-  $raw = $detex = $fromgp = $apropos = 0;
+  $utf8 = $raw = $detex = $fromgp = $apropos = 0;
   $ch = $cb = $cu = '';
   while ($_ = $ARGV[0])
   {
@@ -99,6 +100,8 @@ sub options {
       { $detex = 1; }
     elsif ($_ eq "-raw")
       { $raw = $detex = 1; }
+    elsif ($_ eq "-utf8")
+      { $utf8 = 1; }
     elsif ($_ eq "-color_help" || $_ eq "-ch")
       { $ch = &color(shift(@ARGV)); }
     elsif ($_ eq "-color_bold" || $_ eq "-cb")
@@ -546,8 +549,14 @@ sub split_words { my ($txt) = @_;
     s/\Q$tr{nbrk}/ /g;
     my ($w) = $_;
     # these codes will be replaced by 1 character
-    s/\@\[(obr|cbr|ouml|uuml|agrav|eacute|ldollar|lt|gt|\{|\})]/\@/g;
-    s/\@\[pm]/+\/-/g;
+    s/\@\[(obr|cbr|ldollar|lt|gt|\{|\})]/\@/g;
+    if ($utf8)
+    { s/\@\[(ouml|uuml|agrav|aacute|eacute|pm)]/\@/g; } # one char
+    else
+    {
+      s/\@\[(ouml|uuml|agrav|aacute|eacute)]/\@\@/g;  # two chars
+      s/\@\[pm]/+\/-/g; # three chars
+    }
     # the rest will be replaced by zero-width characters
     s/\@\[\w+\]//g;
     my ($l) = length($_);
@@ -666,7 +675,7 @@ sub detex {
 # We use the special char @ to transmit special sequences
 sub inittr {
   @ou = qw( dollar nbrk startbold endbold startcode endcode
-	    obr cbr uuml ouml agrave eacute
+	    obr cbr uuml ouml agrave aacute eacute
 	    startpodcode endpodcode startlink endlink
 	    startbcode endbcode startbi endbi startit endit
 	    startword endword startlword endlword pm empty gt lt podleader );
@@ -709,6 +718,7 @@ sub inittr {
 	  uuml => 'E<uuml>',
 	  eacute => 'E<eacute>',
 	  agrave => 'E<agrave>',
+	  aacute => 'E<aacute>',
 	  empty => 'Z<>',
 	  podleader => '=',
 	);
@@ -760,6 +770,7 @@ sub basic_subst {
   s/\\(~|tilde)/~/g;
 
   s/\\(equiv)(?![a-zA-Z])/ = /g;
+  s/\\'a/$tr{aacute}/; s/\\'\{a\}/$tr{aacute}/;
   s/\\`a/$tr{agrave}/; s/\\`\{a\}/$tr{agrave}/;
   s/\\"o/$tr{ouml}/;   s/\\"\{o\}/$tr{ouml}/;
   s/\\"u/$tr{uuml}/;   s/\\"\{u\}/$tr{uuml}/;
@@ -1173,16 +1184,29 @@ sub TeXprint {
   local($_) = $_[0];
   s/\@\[obr\]/{/g;
   s/\@\[cbr\]/}/g;
-  s/\@\[ouml\]/"o/g;
-  s/\@\[uuml\]/"u/g;
-  s/\@\[agrave\]/`a/g;
-  s/\@\[eacute\]/'e/g;
+  if ($utf8)
+  {
+    s/\@\[ouml\]/ö/g;
+    s/\@\[uuml\]/ü/g;
+    s/\@\[aacute\]/á/g;
+    s/\@\[agrave\]/à/g;
+    s/\@\[eacute\]/é/g;
+    s/\@\[pm\]/±/g;
+  }
+  else
+  {
+    s/\@\[ouml\]/"o/g;
+    s/\@\[uuml\]/"u/g;
+    s/\@\[aacute\]/'a/g;
+    s/\@\[agrave\]/`a/g;
+    s/\@\[eacute\]/'e/g;
+    s/\@\[pm\]/+\/-/g;
+  }
   s/\@\[ldollar\]/\$/g;
   s/\@\[end(bold|code|bcode|bi|it)\]/$ch/g;
   s/\@\[start(bold|code|bcode|bi)\]/$cb/g;
   s/\@\[startit\]/$cu/g;
   s/\@\[(dollar|empty|endl?word|endpodcode|startl?word|startpodcode)\]//g;
-  s/\@\[pm\]/+\/-/g;
   s/\@\[lt\]/</g;
   s/\@\[gt\]/>/g;
   s/\\([\{\}])/$1/g;
diff --git a/doc/refcard.tex b/doc/refcard.tex
index d3f2bf1..85b0e91 100644
--- a/doc/refcard.tex
+++ b/doc/refcard.tex
@@ -478,7 +478,7 @@ $\bullet$ All domains:
 \li{$\bullet$ $E$ defined over $\QQ_p$}{}
 \beginindentedkeys
 \li{residual characteristic}{E.p}
-\li{If $|j|_p>1$: Tate's $[u^2, u, q, [a,b]]$}{E.tate}
+\li{If $|j|_p>1$: Tate's $[u^2, u, q, [a,b], {\cal L}]$}{E.tate}
 \endindentedkeys
 \li{$\bullet$ $E$ defined over $\FF_q$}{}
 \beginindentedkeys
diff --git a/doc/translations b/doc/translations
index 2cfbb94..1b4b1fd 100644
--- a/doc/translations
+++ b/doc/translations
@@ -43,7 +43,6 @@ intmod          @Integermods at 2
 FRAC            @Rational numbers at 2
 fraction        @Rational numbers at 2
 rational        @Rational numbers at 2
-FRACN           @Rational numbers at 2
 COMPLEX         @Complex numbers at 2
 complex         @Complex numbers at 2
 PADIC           @$p$-adic numbers at 2
@@ -56,8 +55,6 @@ POL             @Polynomials at 2
 polynomial      @Polynomials at 2
 SER             @Power series at 2
 RFRAC           @Rational functions at 2
-RFRACN          @Rational functions at 2
-RFRACN          @Rational functions at 2
 QFR             @Binary quadratic forms of positive or negative discriminant at 2
 QFI             @Binary quadratic forms of positive or negative discriminant at 2
 VEC             @Row and column vectors at 2
diff --git a/doc/usersFUNCS.tex b/doc/usersFUNCS.tex
index 67aa516..721ab22 100644
--- a/doc/usersFUNCS.tex
+++ b/doc/usersFUNCS.tex
@@ -257,14 +257,13 @@ The library syntax is \fun{GEN}{gmod}{GEN x, GEN y}
 for $x$ \kbd{\%} $y$.
 
 \subseckbd{\pow} The expression $x\hbox{\kbd{\pow}}n$ is \idx{powering}.
-If the exponent is an integer, then exact operations are performed using
-binary (left-shift) powering techniques. In particular, in this case $x$
-cannot be a vector or matrix unless it is a square matrix (invertible
-if the exponent is negative). If $x$ is a $p$-adic number, its
+
+\item If the exponent $n$ is an integer, then exact operations are performed
+using binary (left-shift) powering techniques. If $x$ is a $p$-adic number, its
 precision will increase if $v_p(n) > 0$. Powering a binary quadratic form
-(types \typ{QFI} and \typ{QFR}) returns a reduced representative of the
-class, provided the input is reduced. In particular, $x\hbox{\kbd{\pow}}1$ is
-identical to $x$.
+(types \typ{QFI} and \typ{QFR}) returns a representative of the class, which is
+always reduced if the input was. (In particular, \kbd{x \pow 1} returns $x$
+itself, whether it is reduced or not.)
 
 PARI is able to rewrite the multiplication $x * x$ of two \emph{identical}
 objects as $x^2$, or $\kbd{sqr}(x)$. Here, identical means the operands are
@@ -272,11 +271,12 @@ two different labels referencing the same chunk of memory; no equality test
 is performed. This is no longer true when more than two arguments are
 involved.
 
-If the exponent is not of type integer, this is treated as a transcendental
-function (see \secref{se:trans}), and in particular has the effect of
-componentwise powering on vector or matrices.
+\item If the exponent $n$ is not an integer, powering is treated as the
+transcendental function $\exp(n\log x)$, and in particular acts
+componentwise on vector or matrices, even square matrices ! (See
+\secref{se:trans}.)
 
-As an exception, if the exponent is a rational number $p/q$ and $x$ an
+\item As an exception, if the exponent is a rational number $p/q$ and $x$ an
 integer modulo a prime or a $p$-adic number, return a solution $y$ of
 $y^q=x^p$ if it exists. Currently, $q$ must not have large prime factors.
 Beware that
@@ -291,8 +291,8 @@ Beware that
 %4 = Mod(1, 19)  /* Mod(7,19) is just another cubic root */
 @eprog
 
-If the exponent is a negative integer, an \idx{inverse} must be computed.
-For non-invertible \typ{INTMOD}, this will fail and implicitly exhibit a
+\item If the exponent is a negative integer, an \idx{inverse} must be computed.
+For non-invertible \typ{INTMOD} $x$, this will fail and implicitly exhibit a
 non trivial factor of the modulus:
 \bprog
 ? Mod(4,6)^(-1)
@@ -306,36 +306,53 @@ complicated operations modulo an integer $N$ whose factorization is
 unknown. Either the computation succeeds and all is well, or a factor $d$
 is discovered and the computation may be restarted modulo $d$ or $N/d$.
 
-For non-invertible \typ{POLMOD}, this will fail without exhibiting a
-factor.
+For non-invertible \typ{POLMOD} $x$, the behaviour is the same:
 \bprog
 ? Mod(x^2, x^3-x)^(-1)
   ***   at top-level: Mod(x^2,x^3-x)^(-1)
   ***                               ^-----
-  *** _^_: non-invertible polynomial in RgXQ_inv.
-? a = Mod(3,4)*y^3 + Mod(1,4); b = y^6+y^5+y^4+y^3+y^2+y+1;
-? Mod(a, b)^(-1);
+  *** _^_: impossible inverse in RgXQ_inv: Mod(x^2, x^3 - x).
+ at eprog\noindent Note that the underlying algorihm (subresultant) assumes
+the base ring is a domain:
+\bprog
+? a = Mod(3*y^3+1, 4); b = y^6+y^5+y^4+y^3+y^2+y+1; c = Mod(a,b);
+? c^(-1)
   ***   at top-level: Mod(a,b)^(-1)
   ***                         ^-----
-  *** _^_: impossible inverse modulo: Mod(0, 4).
+  *** _^_: impossible inverse modulo: Mod(2, 4).
 @eprog\noindent
-In fact the latter polynomial is invertible, but the algorithm used
-(subresultant) assumes the base ring is a domain. If it is not the case,
-as here for $\Z/4\Z$, a result will be correct but chances are an error
+In fact $c$ is invertible, but $\Z/4\Z$ is not a domain and the algorithm
+fails. It is possible for the algorithm to succeed in such situations
+and any returned result will be correct, but chances are an error
 will occur first. In this specific case, one should work with $2$-adics.
-In general, one can try the following approach
+In general, one can also try the following approach
 \bprog
 ? inversemod(a, b) =
-{ my(m);
+{ my(m, v = variable(b));
   m = polsylvestermatrix(polrecip(a), polrecip(b));
   m = matinverseimage(m, matid(#m)[,1]);
-  Polrev( vecextract(m, Str("..", poldegree(b))), variable(b) )
+  Polrev(m[1..poldegree(b)], v);
 }
 ? inversemod(a,b)
 %2 = Mod(2,4)*y^5 + Mod(3,4)*y^3 + Mod(1,4)*y^2 + Mod(3,4)*y + Mod(2,4)
 @eprog\noindent
-This is not guaranteed to work either since it must invert pivots. See
-\secref{se:linear_algebra}.
+This is not guaranteed to work either since \kbd{matinverseimage} must also
+invert pivots. See \secref{se:linear_algebra}.
+
+For a \typ{MAT} $x$, the matrix is expected to be square and invertible, except
+in the special case \kbd{x\pow(-1)} which returns a left inverse if one exists
+(rectangular $x$ with full column rank).
+\bprog
+? x = Mat([1;2])
+%1 =
+[1]
+
+[2]
+
+? x^(-1)
+%2 =
+[1 0]
+ at eprog
 
 The library syntax is \fun{GEN}{gpow}{GEN x, GEN n, long prec}
 for $x\hbox{\kbd{\pow}}n$.
@@ -714,12 +731,15 @@ is real, it is the first component.
 
 \item \tet{omega}: $[\omega_1,\omega_2]$, periods forming a basis of the
 complex lattice defining $E$. The first component $\omega_1$ is the
-(positive) real period, in other words the integral of $dx/(2y+a_1x+a_3)$
+(positive) real period, in other words the integral of the N\'eron
+differential $dx/(2y+a_1x+a_3)$
 over the connected component of the identity component of $E(\R)$.
 The second component $\omega_2$ is a complex period, such that
 $\tau=\dfrac{\omega_1}{\omega_2}$ belongs to Poincar\'e's
 half-plane (positive imaginary part); not necessarily to the standard
-fundamental domain.
+fundamental domain. It is normalized so that $\Im(\omega_2) < 0$
+and either $\Re(\omega_2) = 0$, when \kbd{E.disc > 0} ($E(\R)$ has two connected
+components), or $\Re(\omega_2) = \omega_1/2$
 
 \item \tet{eta} is a row vector containing the quasi-periods $\eta_1$ and
 $\eta_2$ such that $\eta_i = 2\zeta(\omega_i/2)$, where $\zeta$ is the
@@ -758,15 +778,17 @@ root $e_1$ of the right hand side $g(x)$ of the associated $b$-model $Y^2
 = g(x)$. The point $(e_1,0)$ corresponds to $-1 \in \bar{\Q}_p^*/q^\Z$
 under the Tate parametrization.
 
-\item \tet{tate} returns $[u^2,u,q,[a,b]]$ in the notation of Henniart-Mestre
+\item \tet{tate} returns $[u^2,u,q,[a,b],L]$ in the notation of Henniart-Mestre
 (CRAS t. 308, p.~391--395, 1989): $q$ is as above, $u\in \Q_p(\sqrt{-c_6})$
 is such that $\phi^* dx/(2y + a_1x+a3) = u dt/t$, where $\phi: E_q\to E$
 is an isomorphism (well defined up to sign) and $dt/t$ is the canonical
 invariant differential on the Tate curve; $u^2\in\Q_p$ does not depend on
 $\phi$. (Technicality: if $u\not\in\Q_p$, it is stored as a quadratic
 \typ{POLMOD}.)
-Finally, $[a,b]$ satisfy $4u^2 b \cdot \text{agm}(\sqrt{a/b},1)^2 = 1$
+The parameters $[a,b]$ satisfy $4u^2 b \cdot \text{agm}(\sqrt{a/b},1)^2 = 1$
 as in Theorem~2 (\emph{loc.~cit.}).
+Finally, $L$ is Mazur-Tate-Teitelbaum's ${\cal L}$-invariant, equal
+to $\log_p q / v_p(q)$.
 
 \subsubsec{Curves over $\F_q$}
 
@@ -1106,7 +1128,11 @@ $L$-function:
 
 %SECTION: l_functions
 
-\section{Functions related to modular forms and modular symbols}
+\section{Functions related to modular forms}
+
+%SECTION: modular_forms
+
+\section{Functions related to modular symbols}
 
 Let $\Delta := \text{Div}^0(\P^1(\Q))$ be the abelian group of divisors of
 degree $0$ on the rational projective line. The standard $\text{GL}(2,\Q)$
@@ -1136,7 +1162,7 @@ old modular symbols, etc.) is given by a structure allowing quick projection
 and restriction of linear operators; its first component is a matrix whose
 columns  form  an $F$-basis  of the subspace.
 
-%SECTION: modular_forms
+%SECTION: modular_symbols
 
 \section{Functions related to general number fields}
 
diff --git a/doc/usersch2.tex b/doc/usersch2.tex
index e13dd1f..33b8834 100644
--- a/doc/usersch2.tex
+++ b/doc/usersch2.tex
@@ -2235,7 +2235,7 @@ in string context:
 \+&\tet{trap} (first argument)\cr
 \+&\tet{whatnow}\cr
 
-\subsec{Useful examples} The function \kbd{Str} converts its arguments into
+\subsec{Useful example} The function \kbd{Str} converts its arguments into
 strings and concatenate them. Coupled with \tet{eval}, it is very powerful.
 The following example creates generic matrices\sidx{generic
 matrix}\sidx{matrix}:
@@ -2245,14 +2245,6 @@ matrix}\sidx{matrix}:
 %1 =
 [x11 + m11 x12 + m12 x13 + m13]
 [x21 + m21 x22 + m22 x23 + m23]
- at eprog\noindent
-
-Two last examples: \kbd{hist(10,20)} returns all \idx{history} entries from
-\kbd{\%10} to \kbd{\%20} neatly packed into a single
-vector; \kbd{histlast(10)} returns the last $10$ history entries:
-\bprog
-  hist(a,b) = vector(b-a+1, i, eval(Str("%", a-1+i)))
-  histlast(n) = vector(n, i, eval(Str("%", %#-i+1)))
 @eprog
 
 \section{Errors and error recovery}
diff --git a/doc/usersch3.tex b/doc/usersch3.tex
index 6a0f32e..4bff6ac 100644
--- a/doc/usersch3.tex
+++ b/doc/usersch3.tex
@@ -257,14 +257,13 @@ The library syntax is \fun{GEN}{gmod}{GEN x, GEN y}
 for $x$ \kbd{\%} $y$.
 
 \subseckbd{\pow} The expression $x\hbox{\kbd{\pow}}n$ is \idx{powering}.
-If the exponent is an integer, then exact operations are performed using
-binary (left-shift) powering techniques. In particular, in this case $x$
-cannot be a vector or matrix unless it is a square matrix (invertible
-if the exponent is negative). If $x$ is a $p$-adic number, its
+
+\item If the exponent $n$ is an integer, then exact operations are performed
+using binary (left-shift) powering techniques. If $x$ is a $p$-adic number, its
 precision will increase if $v_p(n) > 0$. Powering a binary quadratic form
-(types \typ{QFI} and \typ{QFR}) returns a reduced representative of the
-class, provided the input is reduced. In particular, $x\hbox{\kbd{\pow}}1$ is
-identical to $x$.
+(types \typ{QFI} and \typ{QFR}) returns a representative of the class, which is
+always reduced if the input was. (In particular, \kbd{x \pow 1} returns $x$
+itself, whether it is reduced or not.)
 
 PARI is able to rewrite the multiplication $x * x$ of two \emph{identical}
 objects as $x^2$, or $\kbd{sqr}(x)$. Here, identical means the operands are
@@ -272,11 +271,12 @@ two different labels referencing the same chunk of memory; no equality test
 is performed. This is no longer true when more than two arguments are
 involved.
 
-If the exponent is not of type integer, this is treated as a transcendental
-function (see \secref{se:trans}), and in particular has the effect of
-componentwise powering on vector or matrices.
+\item If the exponent $n$ is not an integer, powering is treated as the
+transcendental function $\exp(n\log x)$, and in particular acts
+componentwise on vector or matrices, even square matrices ! (See
+\secref{se:trans}.)
 
-As an exception, if the exponent is a rational number $p/q$ and $x$ an
+\item As an exception, if the exponent is a rational number $p/q$ and $x$ an
 integer modulo a prime or a $p$-adic number, return a solution $y$ of
 $y^q=x^p$ if it exists. Currently, $q$ must not have large prime factors.
 Beware that
@@ -291,8 +291,8 @@ Beware that
 %4 = Mod(1, 19)  /* Mod(7,19) is just another cubic root */
 @eprog
 
-If the exponent is a negative integer, an \idx{inverse} must be computed.
-For non-invertible \typ{INTMOD}, this will fail and implicitly exhibit a
+\item If the exponent is a negative integer, an \idx{inverse} must be computed.
+For non-invertible \typ{INTMOD} $x$, this will fail and implicitly exhibit a
 non trivial factor of the modulus:
 \bprog
 ? Mod(4,6)^(-1)
@@ -306,36 +306,53 @@ complicated operations modulo an integer $N$ whose factorization is
 unknown. Either the computation succeeds and all is well, or a factor $d$
 is discovered and the computation may be restarted modulo $d$ or $N/d$.
 
-For non-invertible \typ{POLMOD}, this will fail without exhibiting a
-factor.
+For non-invertible \typ{POLMOD} $x$, the behaviour is the same:
 \bprog
 ? Mod(x^2, x^3-x)^(-1)
   ***   at top-level: Mod(x^2,x^3-x)^(-1)
   ***                               ^-----
-  *** _^_: non-invertible polynomial in RgXQ_inv.
-? a = Mod(3,4)*y^3 + Mod(1,4); b = y^6+y^5+y^4+y^3+y^2+y+1;
-? Mod(a, b)^(-1);
+  *** _^_: impossible inverse in RgXQ_inv: Mod(x^2, x^3 - x).
+ at eprog\noindent Note that the underlying algorihm (subresultant) assumes
+the base ring is a domain:
+\bprog
+? a = Mod(3*y^3+1, 4); b = y^6+y^5+y^4+y^3+y^2+y+1; c = Mod(a,b);
+? c^(-1)
   ***   at top-level: Mod(a,b)^(-1)
   ***                         ^-----
-  *** _^_: impossible inverse modulo: Mod(0, 4).
+  *** _^_: impossible inverse modulo: Mod(2, 4).
 @eprog\noindent
-In fact the latter polynomial is invertible, but the algorithm used
-(subresultant) assumes the base ring is a domain. If it is not the case,
-as here for $\Z/4\Z$, a result will be correct but chances are an error
+In fact $c$ is invertible, but $\Z/4\Z$ is not a domain and the algorithm
+fails. It is possible for the algorithm to succeed in such situations
+and any returned result will be correct, but chances are an error
 will occur first. In this specific case, one should work with $2$-adics.
-In general, one can try the following approach
+In general, one can also try the following approach
 \bprog
 ? inversemod(a, b) =
-{ my(m);
+{ my(m, v = variable(b));
   m = polsylvestermatrix(polrecip(a), polrecip(b));
   m = matinverseimage(m, matid(#m)[,1]);
-  Polrev( vecextract(m, Str("..", poldegree(b))), variable(b) )
+  Polrev(m[1..poldegree(b)], v);
 }
 ? inversemod(a,b)
 %2 = Mod(2,4)*y^5 + Mod(3,4)*y^3 + Mod(1,4)*y^2 + Mod(3,4)*y + Mod(2,4)
 @eprog\noindent
-This is not guaranteed to work either since it must invert pivots. See
-\secref{se:linear_algebra}.
+This is not guaranteed to work either since \kbd{matinverseimage} must also
+invert pivots. See \secref{se:linear_algebra}.
+
+For a \typ{MAT} $x$, the matrix is expected to be square and invertible, except
+in the special case \kbd{x\pow(-1)} which returns a left inverse if one exists
+(rectangular $x$ with full column rank).
+\bprog
+? x = Mat([1;2])
+%1 =
+[1]
+
+[2]
+
+? x^(-1)
+%2 =
+[1 0]
+ at eprog
 
 The library syntax is \fun{GEN}{gpow}{GEN x, GEN n, long prec}
 for $x\hbox{\kbd{\pow}}n$.
@@ -2177,7 +2194,7 @@ The library syntax is \fun{GEN}{bernfrac}{long x}.
 %2 = x^3 - 3/2*x^2 + 1/2*x
 @eprog
 
-The library syntax is \fun{GEN}{bernpol}{long n, long v  = -1}, where \kbd{v } is a variable number.
+The library syntax is \fun{GEN}{bernpol}{long n, long v = -1}, where \kbd{v} is a variable number.
 
 \subsec{bernreal$(x)$}\kbdsidx{bernreal}\label{se:bernreal}
 Bernoulli number\sidx{Bernoulli numbers}
@@ -2279,7 +2296,7 @@ If $n$ is present, we must have $x > 0$; the function returns the
 $n$-dimensional vector $[\kbd{eint1}(x),\dots,\kbd{eint1}(nx)]$. Contrary to
 other transcendental functions, and to the default case ($n$ omitted), the
 values are correct up to a bounded \emph{absolute}, rather than relative,
-error $10^-n$, where $n$ is \kbd{precision}$(x)$ if $x$ is a \typ{REAL}
+error $10^{-n}$, where $n$ is \kbd{precision}$(x)$ if $x$ is a \typ{REAL}
 and defaults to \kbd{realprecision} otherwise. (In the most important
 application, to the computation of $L$-functions via approximate functional
 equations, those values appear as weights in long sums and small individual
@@ -2392,7 +2409,7 @@ The alternative shortcut
   gammamellininv(gammamellininvinit(A,m), t)
 @eprog\noindent is available.
 
-The library syntax is \fun{GEN}{gammamellininv_bitprec}{GEN G, GEN t, long m, long bitprec}.
+The library syntax is \fun{GEN}{gammamellininv}{GEN G, GEN t, long m, long bitprec}.
 
 \subsec{gammamellininvasymp$(A,n,\{m=0\})$}\kbdsidx{gammamellininvasymp}\label{se:gammamellininvasymp}
 Return the first $n$ terms of the asymptotic expansion at infinity
@@ -2440,7 +2457,7 @@ $ 4\pi z \exp(-\pi z^2)(2\pi z^2 - 3)$:
 %3 = -1.4693679385278593850 E-39
 @eprog
 
-The library syntax is \fun{GEN}{gammamellininvinit_bitprec}{GEN A, long m, long bitprec}.
+The library syntax is \fun{GEN}{gammamellininvinit}{GEN A, long m, long bitprec}.
 
 \subsec{hyperu$(a,b,x)$}\kbdsidx{hyperu}\label{se:hyperu}
 $U$-confluent hypergeometric function with
@@ -3151,7 +3168,7 @@ Also available is
 be a vector of elementary divisors and $a, b$ are compatible characters
 (no checks).
 
-\subsec{chareval$(G,\var{chi}, x, \{z\}))$}\kbdsidx{chareval}\label{se:chareval}
+\subsec{chareval$(G, \var{chi}, x, \{z\}))$}\kbdsidx{chareval}\label{se:chareval}
 Let $G$ be an abelian group structure affording a discrete logarithm
 method, e.g $G = \kbd{idealstar}(,N)$ for $(\Z/N\Z)^*$ or a \kbd{bnr}
 structure, let $x$ be an element of $G$ and let \var{chi} be a character of
@@ -3164,12 +3181,12 @@ let $\chi: G \to K^*$ be a character of finite order and let $o$ be a
 multiple of the character order such that $\chi(n) = \zeta^{c(n)}$ for some
 fixed $\zeta\in K^*$ of multiplicative order $o$ and a unique morphism $c: G
 \to (\Z/o\Z,+)$. Our usual convention is to write
-   $$G = (\Z/o_1\Z) g_1 \oplus \cdots \oplus (\Z/o_d\Z) g_d$$
+$$G = (\Z/o_1\Z) g_1 \oplus \cdots \oplus (\Z/o_d\Z) g_d$$
 for some generators $(g_i)$ of respective order $d_i$, where the group has
 exponent $o := \text{lcm}_i o_i$. Since $\zeta^o = 1$, the vector $(c_i)$ in
 $\prod (\Z/o_i\Z)$ defines a character $\chi$ on $G$ via $\chi(g_i) =
 \zeta^{c_i (o/o_i)}$ for all $i$. Classical Dirichlet characters have values
- in $K = \C$ and we can take $\zeta = \exp(2i\pi/o)$.
+in $K = \C$ and we can take $\zeta = \exp(2i\pi/o)$.
 
 \misctitle{Note on Dirichlet characters}
 In the special case where \var{bid} is attached to $G = (\Z/q\Z)^*$
@@ -4163,7 +4180,8 @@ The library syntax is \fun{long}{ispolygonal}{GEN x, GEN s, GEN *N = NULL}.
 
 \subsec{ispower$(x,\{k\},\{\&n\})$}\kbdsidx{ispower}\label{se:ispower}
 If $k$ is given, returns true (1) if $x$ is a $k$-th power, false
-(0) if not.
+(0) if not. What it means to be a $k$-th power depends on the type of
+$x$; see \tet{issquare} for details.
 
 If $k$ is omitted, only integers and fractions are allowed for $x$ and the
 function returns the maximal $k \geq 2$ such that $x = n^k$ is a perfect
@@ -4317,6 +4335,16 @@ directly odd and even-power monomials) or we assume that $2$ is invertible
 and check whether squaring the truncated power series for the square root
 yields the original input.
 
+For \typ{POLMOD} $x$, we only support \typ{POLMOD}s of \typ{INTMOD}s
+encoding finite fields, assuming without checking that the intmod modulus
+$p$ is prime and that the polmod modulus is irreducible modulo $p$.
+\bprog
+? issquare(Mod(Mod(2,3), x^2+1), &n)
+%1 = 1
+? n
+%2 = Mod(Mod(2, 3)*x, Mod(1, 3)*x^2 + Mod(1, 3))
+ at eprog
+
 The library syntax is \fun{long}{issquareall}{GEN x, GEN *n = NULL}.
 Also available is \fun{long}{issquare}{GEN x}. Deprecated
 GP-specific functions \fun{GEN}{gissquare}{GEN x} and
@@ -4689,7 +4717,7 @@ if set, $L$ should be equal to \kbd{sqrtnint(abs(D)>>2,4)}, where $D < 0$ is
 the discriminant of $x$.
 
 The current implementation is slower than the generic routine for small
-discriminant $D$, and becomes faster for $D \approx 2^45$.
+discriminant $D$, and becomes faster for $D \approx 2^{45}$.
 
 The library syntax is \fun{GEN}{nupow}{GEN x, GEN n, GEN L = NULL}.
 
@@ -4924,7 +4952,7 @@ pseudo prime $a \leq p \leq b$ is returned; if no prime exists in the
 interval, the function will run into an infinite loop. If the upper bound
 is less than $2^{64}$ the pseudo prime returned is a proven prime.
 
-The library syntax is \fun{GEN}{randomprime}{GEN N  = NULL}.
+The library syntax is \fun{GEN}{randomprime}{GEN N = NULL}.
 
 \subsec{removeprimes$(\{x=[\,]\})$}\kbdsidx{removeprimes}\label{se:removeprimes}
 Removes the primes listed in $x$ from
@@ -5580,12 +5608,15 @@ is real, it is the first component.
 
 \item \tet{omega}: $[\omega_1,\omega_2]$, periods forming a basis of the
 complex lattice defining $E$. The first component $\omega_1$ is the
-(positive) real period, in other words the integral of $dx/(2y+a_1x+a_3)$
+(positive) real period, in other words the integral of the N\'eron
+differential $dx/(2y+a_1x+a_3)$
 over the connected component of the identity component of $E(\R)$.
 The second component $\omega_2$ is a complex period, such that
 $\tau=\dfrac{\omega_1}{\omega_2}$ belongs to Poincar\'e's
 half-plane (positive imaginary part); not necessarily to the standard
-fundamental domain.
+fundamental domain. It is normalized so that $\Im(\omega_2) < 0$
+and either $\Re(\omega_2) = 0$, when \kbd{E.disc > 0} ($E(\R)$ has two connected
+components), or $\Re(\omega_2) = \omega_1/2$
 
 \item \tet{eta} is a row vector containing the quasi-periods $\eta_1$ and
 $\eta_2$ such that $\eta_i = 2\zeta(\omega_i/2)$, where $\zeta$ is the
@@ -5624,15 +5655,17 @@ root $e_1$ of the right hand side $g(x)$ of the associated $b$-model $Y^2
 = g(x)$. The point $(e_1,0)$ corresponds to $-1 \in \bar{\Q}_p^*/q^\Z$
 under the Tate parametrization.
 
-\item \tet{tate} returns $[u^2,u,q,[a,b]]$ in the notation of Henniart-Mestre
+\item \tet{tate} returns $[u^2,u,q,[a,b],L]$ in the notation of Henniart-Mestre
 (CRAS t. 308, p.~391--395, 1989): $q$ is as above, $u\in \Q_p(\sqrt{-c_6})$
 is such that $\phi^* dx/(2y + a_1x+a3) = u dt/t$, where $\phi: E_q\to E$
 is an isomorphism (well defined up to sign) and $dt/t$ is the canonical
 invariant differential on the Tate curve; $u^2\in\Q_p$ does not depend on
 $\phi$. (Technicality: if $u\not\in\Q_p$, it is stored as a quadratic
 \typ{POLMOD}.)
-Finally, $[a,b]$ satisfy $4u^2 b \cdot \text{agm}(\sqrt{a/b},1)^2 = 1$
+The parameters $[a,b]$ satisfy $4u^2 b \cdot \text{agm}(\sqrt{a/b},1)^2 = 1$
 as in Theorem~2 (\emph{loc.~cit.}).
+Finally, $L$ is Mazur-Tate-Teitelbaum's ${\cal L}$-invariant, equal
+to $\log_p q / v_p(q)$.
 
 \subsubsec{Curves over $\F_q$}
 
@@ -5709,7 +5742,7 @@ time = 104 ms.
 %3 = 10.3910994007158041387518505103609170697263563756570092797 at com$[\dots]$
 @eprog
 
-The library syntax is \fun{GEN}{ellL1_bitprec}{GEN e, long r , long bitprec}.
+The library syntax is \fun{GEN}{ellL1_bitprec}{GEN e, long r, long bitprec}.
 
 \subsec{elladd$(E,\var{z1},\var{z2})$}\kbdsidx{elladd}\label{se:elladd}
 Sum of the points $z1$ and $z2$ on the
@@ -6015,7 +6048,7 @@ power series:
 %3 = t + O(t^11)
 @eprog
 
-The library syntax is \fun{GEN}{ellformalexp}{GEN E, long precdl, long n  = -1}, where \kbd{n } is a variable number.
+The library syntax is \fun{GEN}{ellformalexp}{GEN E, long precdl, long n = -1}, where \kbd{n} is a variable number.
 
 \subsec{ellformallog$(E, \{n = \var{seriesprecision}\}, \{v = 't\})$}\kbdsidx{ellformallog}\label{se:ellformallog}
 The formal elliptic logarithm is a series $L$ in $t K[[t]]$
@@ -6030,7 +6063,7 @@ from the formal group of $E$ to the additive formal group.
 %3 = O(t^8)
 @eprog
 
-The library syntax is \fun{GEN}{ellformallog}{GEN E, long precdl, long n  = -1}, where \kbd{n } is a variable number.
+The library syntax is \fun{GEN}{ellformallog}{GEN E, long precdl, long n = -1}, where \kbd{n} is a variable number.
 
 \subsec{ellformalpoint$(E, \{n = \var{seriesprecision}\}, \{v = 'x\})$}\kbdsidx{ellformalpoint}\label{se:ellformalpoint}
 If $E$ is an elliptic curve, return the coordinates $x(t), y(t)$ in the
@@ -6050,7 +6083,7 @@ series, whose coefficients are in $\Z[a_1,a_2,a_3,a_4,a_6]$.
 %4 = [x^-2 - 1/2*x^4 + O(x^5), -x^-3 + 1/2*x^3 + O(x^4)]
 @eprog
 
-The library syntax is \fun{GEN}{ellformalpoint}{GEN E, long precdl, long n  = -1}, where \kbd{n } is a variable number.
+The library syntax is \fun{GEN}{ellformalpoint}{GEN E, long precdl, long n = -1}, where \kbd{n} is a variable number.
 
 \subsec{ellformalw$(E, \{n = \var{seriesprecision}\}, \{t = 'x\})$}\kbdsidx{ellformalw}\label{se:ellformalw}
 Return the formal power series $w$ associated to the elliptic curve $E$,
@@ -6064,7 +6097,7 @@ coefficients of $w$ belong to $\Z[a_1,a_2,a_3,a_4,a_6]$.
 %1 = t^3 + 3*t^4 + 11*t^5 + 35*t^6 + 101*t^7 + O(t^8)
 @eprog
 
-The library syntax is \fun{GEN}{ellformalw}{GEN E, long precdl, long n  = -1}, where \kbd{n } is a variable number.
+The library syntax is \fun{GEN}{ellformalw}{GEN E, long precdl, long n = -1}, where \kbd{n} is a variable number.
 
 \subsec{ellfromeqn$(P)$}\kbdsidx{ellfromeqn}\label{se:ellfromeqn}
 Given a genus $1$ plane curve, defined by the affine equation $f(x,y) = 0$,
@@ -6420,7 +6453,7 @@ functions $[f, g, h]$ such that the isogeny $E \to E/G$ is given by $(x,y)
 %4 = [[0,0,0,-15,22], [x^3+2*x^2+4*x+3, y*x^3+3*y*x^2-2*y, x+1]]
 @eprog
 
-The library syntax is \fun{GEN}{ellisogeny}{GEN E, GEN G, long only_image , long x  = -1, long y  = -1}, where \kbd{x }, \kbd{y } are variable numbers.
+The library syntax is \fun{GEN}{ellisogeny}{GEN E, GEN G, long only_image, long x = -1, long y = -1}, where \kbd{x}, \kbd{y} are variable numbers.
 
 \subsec{ellisogenyapply$(f, g)$}\kbdsidx{ellisogenyapply}\label{se:ellisogenyapply}
 Given an isogeny of elliptic curves $f:E'\to E$ (being the result of a call
@@ -6625,7 +6658,7 @@ $e$ being an elliptic curve defined over $\Q$ output by \kbd{ellinit},
  the Manin constant. Return $[D, err]$, where $D$ is a rational number and
  err is exponent of the truncation error.
 
-The library syntax is \fun{GEN}{ellmoddegree_bitprec}{GEN e, long bitprec}.
+The library syntax is \fun{GEN}{ellmoddegree}{GEN e, long bitprec}.
 
 \subsec{ellmodulareqn$(N,\{x\},\{y\})$}\kbdsidx{ellmodulareqn}\label{se:ellmodulareqn}
 Return a vector [\kbd{eqn},$t$] where \kbd{eqn} is a modular equation of
@@ -6786,64 +6819,108 @@ $x$-coordinate.
 
 The library syntax is \fun{GEN}{ellordinate}{GEN E, GEN x, long prec}.
 
-\subsec{ellpadicL$(E, p, n, \{r = 0\}, \{D\}, \{\var{char}\})$}\kbdsidx{ellpadicL}\label{se:ellpadicL}
-The $p$-adic $L$ function is defined on the set of continuous characters
- of $\text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$, identified to $\Z_p^*$
- via the cyclotomic character $\chi_p$ with values in $\overline{\Q_p}^*$.
- Denote by $\tau:\Z_p^*\to\Z_p^*$ the Teichm\"uller character.
-
- When $E$ has good supersingular reduction, the $L$ function takes its
- values in $\Q_p \otimes H^1_{dR}(E/\Q)$ and satisfies
- $$(1-p^{-1} F)^{-2} L_p(E, \tau^0)= (L(E,1) / \Omega) \cdot \omega$$
- where $F$ is the Frobenius, $L(E,1)$ is the value of the complex $L$
- function at $1$, $\omega$ is the N\'eron differential
- and $\Omega$ its associated period on $E(\R)$. Here, $\tau^0$ represents
- the trivial character.
-
- The derivative is taken at $s=1$ along $\langle\chi_p^s\rangle$.
- In other words, the function $L_p$ is defined as
- $\int_{\Z_p^*} d \mu$ for a certain $p$-adic distribution $\mu$ on
- $\Z_p^*$, and we have
-  $$L_p^{(r)}(E, \tau^0) = \int_{\Z_p^*} \log_p^r(a) d\mu(a).$$
- The function returns the components of $L_p{(r)}(E,\tau^0)$ in
- the basis $(\omega, F(\omega))$.
- \smallskip
-
- When $E$ has ordinary good reduction, this method only defines
- the projection of $L_p(E,\tau^0)$ on the $\alpha$-eigenspace,
- where $\alpha$ is the unit eigenvalue for $F$. This is what the function
- returns. This value satisfies
- $$(1- \alpha^{-1})^{-2} L_{p,\alpha}(E,\tau^0)= L(E,1) / \Omega.$$
-
- \bprog
- ? cxL(e) = bestappr( ellL1(e,0) / e.omega[1] );
-
- ? e = ellinit("17a1"); p=3; \\ supersingular
- ? L = ellpadicL(e,p,4);
- ? F = [0,-p;1,ellap(e,p)]; \\ Frobenius matrix in the basis (omega,F(omega)
- ? (1-p^(-1)*F)^-2 * L~ / cxL(e)
- %5 = [1 + O(3^4), O(3^4)]~
-
- ? p=5; ap = ellap(e,p); \\ ordinary
- ? L = ellpadicL(e,p,4);
- ? al = padicappr(x^2 - ap*x + p, ap + O(p^7))[1];
- ? (1-al^(-1))^(-2) * L / cxL(e)
- %10 = 1 + O(5^4)
-
- ? e = ellinit("116a1"); p=3; \\ supersingular
- ? L = ellpadicL(e,p,4);
- ? F = [0,-p; 1,ellap(e,p)];
- ? (1-p^(-1)*F)^-2*L~ / cxL(e)
- %15 = [1 + O(3^4), O(3^5)]~
-
- ? e = ellinit("26b1"); p=3;
- ? L = ellpadicL(e,p,4);
- ? F = [0,-p;1,ellap(e,p)];
- ? (1-p^(-1)*F)^-2*L~ / cxL(e)
- %20 = [1 + O(3^4), O(3^5)]~
- @eprog
-
-The library syntax is \fun{GEN}{ellpadicL}{GEN E, GEN p, long n, long r , GEN D = NULL, GEN char = NULL}.
+\subsec{ellpadicL$(E, p, n, \{s = 0\}, \{r = 0\}, \{D = 1\})$}\kbdsidx{ellpadicL}\label{se:ellpadicL}
+Returns the value (or $r$-th derivative) on a character $\chi^s$ of
+$\Z_p^*$ of the $p$-adic $L$-function of the elliptic curve $E/\Q$, twisted by
+$D$, given modulo $p^n$.
+
+\misctitle{Characters} The set of continuous characters of
+$\text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$ is identified to $\Z_p^*$ via the
+cyclotomic character $\chi$ with values in $\overline{\Q_p}^*$. Denote by
+$\tau:\Z_p^*\to\Z_p^*$ the Teichm\"uller character, with values
+in the $(p-1)$-th roots of $1$ for $p\neq 2$, and $\{-1,1\}$ for $p = 2$;
+finally, let
+$\langle\chi\rangle =\chi \tau^{-1}$, with values in $1 + 2p\Z_p$.
+In GP, the continuous character of
+$\text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$ given by $\langle\chi\rangle^{s_1}
+\tau^{s_2}$ is represented by the pair of integers $s=(s_1,s_2)$, with $s_1
+\in \Z_p$ and $s_2 \bmod p-1$ for $p > 2$, (resp. mod $2$ for $p = 2$); $s$
+may be also an integer, representing $(s,s)$ or $\chi^s$.
+
+\misctitle{The $p$-adic $L$ function}
+The $p$-adic $L$ function $L_p$ is defined on the set of continuous
+characters of $\text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$, as $\int_{\Z_p^*}
+\chi^s d \mu$ for a certain $p$-adic distribution $\mu$ on $\Z_p^*$. The
+derivative is given by
+$$L_p^{(r)}(E, \chi^s) = \int_{\Z_p^*} \log_p^r(a) \chi^s(a) d\mu(a).$$
+More precisely:
+
+\item When $E$ has good supersingular reduction, $L_p$ takes its
+values in $\Q_p \otimes H^1_{dR}(E/\Q)$ and satisfies
+$$(1-p^{-1} F)^{-2} L_p(E, \chi^0)= (L(E,1) / \Omega) \cdot \omega$$
+where $F$ is the Frobenius, $L(E,1)$ is the value of the complex $L$
+function at $1$, $\omega$ is the N\'eron differential
+and $\Omega$ the attached period on $E(\R)$. Here, $\chi^0$ represents
+the trivial character.
+
+The function returns the components of $L_p^{(r)}(E,\chi^s)$ in
+the basis $(\omega, F(\omega))$.
+
+\item When $E$ has ordinary good reduction, this method only defines
+the projection of $L_p(E,\chi^s)$ on the $\alpha$-eigenspace,
+where $\alpha$ is the unit eigenvalue for $F$. This is what the function
+returns. We have
+$$(1- \alpha^{-1})^{-2} L_{p,\alpha}(E,\chi^0)= L(E,1) / \Omega.$$
+
+Two supersingular examples:
+\bprog
+? cxL(e) = bestappr( ellL1(e) / e.omega[1] );
+
+? e = ellinit("17a1"); p=3; \\ supersingular, a3 = 0
+? L = ellpadicL(e,p,4);
+? F = [0,-p;1,ellap(e,p)]; \\ Frobenius matrix in the basis (omega,F(omega))
+? (1-p^(-1)*F)^-2 * L / cxL(e)
+%5 = [1 + O(3^5), O(3^5)]~ \\ [1,0]~
+
+? e = ellinit("116a1"); p=3; \\ supersingular, a3 != 0~
+? L = ellpadicL(e,p,4);
+? F = [0,-p; 1,ellap(e,p)];
+? (1-p^(-1)*F)^-2*L~ / cxL(e)
+%9 = [1 + O(3^4), O(3^5)]~
+ at eprog
+
+Good ordinary reduction:
+\bprog
+? e = ellinit("17a1"); p=5; ap = ellap(e,p)
+%1 = -2 \\ ordinary
+? L = ellpadicL(e,p,4)
+%2 = 4 + 3*5 + 4*5^2 + 2*5^3 + O(5^4)
+? al = padicappr(x^2 - ap*x + p, ap + O(p^7))[1];
+? (1-al^(-1))^(-2) * L / cxL(e)
+%4 = 1 + O(5^4)
+ at eprog
+
+Twist and Teichm\"uller:
+\bprog
+? e = ellinit("17a1"); p=5; \\ ordinary
+\\ 2nd derivative at \tau^1, twist by -7
+? ellpadicL(e, p, 4, [0,1], 2, -7)
+%2 = 2*5^2 + 5^3 + O(5^4)
+ at eprog
+
+This function is a special case of \tet{mspadicL}, and it also appears
+as the first term of \tet{mspadicseries}:
+\bprog
+? e = ellinit("17a1"); p=5;
+? L = ellpadicL(e,p,4)
+%2 = 4 + 3*5 + 4*5^2 + 2*5^3 + O(5^4)
+? [M,phi] = msfromell(e, 1);
+? Mp = mspadicinit(M, p, 4);
+? mu = mspadicmoments(Mp, phi);
+? mspadicL(mu)
+%6 = 4 + 3*5 + 4*5^2 + 2*5^3 + 2*5^4 + 5^5 + O(5^6)
+? mspadicseries(mu)
+%7 = (4 + 3*5 + 4*5^2 + 2*5^3 + 2*5^4 + 5^5 + O(5^6))
+      + (3 + 3*5 + 5^2 + 5^3 + O(5^4))*x
+      + (2 + 3*5 + 5^2 + O(5^3))*x^2
+      + (3 + 4*5 + 4*5^2 + O(5^3))*x^3
+      + (3 + 2*5 + O(5^2))*x^4 + O(x^5)
+ at eprog\noindent These are more cumbersome than \kbd{ellpadicL} but allow to
+compute at different characters, or successive derivatives, or to
+twist by a quadratic character essentially for the cost of a single call to
+\kbd{ellpadicL} due to precomputations.
+
+The library syntax is \fun{GEN}{ellpadicL}{GEN E, GEN p, long n, GEN s = NULL, long r, GEN D = NULL}.
 
 \subsec{ellpadicfrobenius$(E,p,n)$}\kbdsidx{ellpadicfrobenius}\label{se:ellpadicfrobenius}
 If $p>2$ is a prime and $E$ is a elliptic curve on $\Q$ with good
@@ -6995,7 +7072,7 @@ The output of this function is meant to be used as the first argument
 given to ellwp, ellzeta, ellsigma or elleisnum. Quasi-periods are
 needed by ellzeta and ellsigma only.
 
-The library syntax is \fun{GEN}{ellperiods}{GEN w, long flag , long prec}.
+The library syntax is \fun{GEN}{ellperiods}{GEN w, long flag, long prec}.
 
 \subsec{ellpointtoz$(E,P)$}\kbdsidx{ellpointtoz}\label{se:ellpointtoz}
 If $E/\C \simeq \C/\Lambda$ is a complex elliptic curve ($\Lambda =
@@ -7311,7 +7388,7 @@ divisors of the discriminant.
 
 \noindent This function was rewritten from an implementation of Liu's
 algorithm by Cohen and Liu (1994), \kbd{genus2reduction-0.3}, see
-\url{http://www.math.u-bordeaux1.fr/~liu/G2R/}.
+\url{http://www.math.u-bordeaux.fr/~liu/G2R/}.
 
 \misctitle{CAVEAT} The function interface may change: for the
 time being, it returns $[N,\var{FaN}, T, V]$
@@ -7426,14 +7503,14 @@ The library syntax is \fun{GEN}{hyperellcharpoly}{GEN X}.
 Let $X$ be the curve defined by $y^2=Q(x)$, where  $Q$ is a polynomial of
 degree $d$ over $\Q$ and $p\ge d$ a prime such that $X$ has good reduction
 at $p$ return the matrix of the Frobenius endomorphism $\varphi$ on the
-crystalline module $D_p(E) = \Q_p \otimes H^1_{dR}(E/\Q)$ with respect to the
+crystalline module $D_p(X) = \Q_p \otimes H^1_{dR}(X/\Q)$ with respect to the
 basis of the given model $(\omega, x\*\omega,\ldots,x^{g-1}\*\omega)$, where
 $\omega = dx/(2\*y)$ is the invariant differential, where $g$ is the genus of
 $X$ (either $d=2\*g+1$ or $d=2\*g+2$).  The characteristic polynomial of
 $\varphi$ is the numerator of the zeta-function of the reduction of the curve
 $X$ modulo $p$. The matrix is computed to absolute $p$-adic precision $p^n$.
 
-The library syntax is \fun{GEN}{hyperellpadicfrobenius}{GEN Q, long p}.
+The library syntax is \fun{GEN}{hyperellpadicfrobenius}{GEN Q, ulong p, long n}.
 %SECTION: elliptic_curves
 
 \section{Functions related to $L$-functions}
@@ -7766,7 +7843,7 @@ decimal digits at a time.
 %8 = 0.79316043335650611601389756527435211412  \\ simple zero
 @eprog
 
-The library syntax is \fun{GEN}{lfun0_bitprec}{GEN L, GEN s, long D, long bitprec}.
+The library syntax is \fun{GEN}{lfun0}{GEN L, GEN s, long D, long bitprec}.
 
 \subsec{lfunabelianrelinit$(\var{bnfL},\var{bnfK},\var{polrel},\var{sdom},\{\var{der}=0\})$}\kbdsidx{lfunabelianrelinit}\label{se:lfunabelianrelinit}
 Returns the \kbd{Linit} structure associated to the Dedekind zeta function
@@ -7789,7 +7866,7 @@ Returns the \kbd{Linit} structure associated to the Dedekind zeta function
  is more efficient than a direct computation. The difference becomes drastic
  as the absolute degree increases while the subfield degree remains constant.
 
-The library syntax is \fun{GEN}{lfunabelianrelinit_bitprec}{GEN bnfL, GEN bnfK, GEN polrel, GEN sdom, long der, long bitprec}.
+The library syntax is \fun{GEN}{lfunabelianrelinit}{GEN bnfL, GEN bnfK, GEN polrel, GEN sdom, long der, long bitprec}.
 
 \subsec{lfunan$(L,n)$}\kbdsidx{lfunan}\label{se:lfunan}
 Compute the first $n$ terms of the Dirichlet series attached to the
@@ -7880,7 +7957,7 @@ large it will be computed with a large absolute error)
  *** lfuncheckfeq: precision too low in lfuncheckfeq.
 @eprog
 
-The library syntax is \fun{long}{lfuncheckfeq_bitprec}{GEN L, GEN t = NULL, long bitprec}.
+The library syntax is \fun{long}{lfuncheckfeq}{GEN L, GEN t = NULL, long bitprec}.
 
 \subsec{lfunconductor$(L,\{\var{ab}=[1,{10000}]\},\{\fl=0\})$}\kbdsidx{lfunconductor}\label{se:lfunconductor}
 Compute the conductor of the given $L$-function
@@ -7948,7 +8025,7 @@ Compute the conductor of the given $L$-function
  %7 = [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, -1, -1]
  @eprog
 
-The library syntax is \fun{GEN}{lfunconductor_bitprec}{GEN L, GEN ab = NULL, long 10000], long bitprec}.
+The library syntax is \fun{GEN}{lfunconductor}{GEN L, GEN ab = NULL, long 10000], long bitprec}.
 
 \subsec{lfuncost$(L,\{\var{sdom}\},\{\var{der}=0\})$}\kbdsidx{lfuncost}\label{se:lfuncost}
 Estimate the cost of running
@@ -8005,6 +8082,10 @@ components above. Note that the actual cost is much lower than the a priori
 cost in this case.
 
 The library syntax is \fun{GEN}{lfuncost0}{GEN L, GEN sdom = NULL, long der, long bitprec}.
+Also available is
+\fun{GEN}{lfuncost}{GEN L, GEN dom, long der, long bitprec}
+when $L$ is \emph{not} an \kbd{Linit}; the return value is a \typ{VECSMALL}
+in this case.
 
 \subsec{lfuncreate$(\var{obj})$}\kbdsidx{lfuncreate}\label{se:lfuncreate}
 This low-level routine creates \tet{Ldata} structures, needed by
@@ -8106,7 +8187,7 @@ Creates the \kbd{Ldata} structure (without initialization) corresponding
 complex numbers $z$: the construction may not create new poles, nor increase
 the order of existing ones.
 
-The library syntax is \fun{GEN}{lfundiv}{GEN L1, GEN L2, long prec}.
+The library syntax is \fun{GEN}{lfundiv}{GEN L1, GEN L2, long bitprec}.
 
 \subsec{lfunetaquo$(M)$}\kbdsidx{lfunetaquo}\label{se:lfunetaquo}
 Returns the \kbd{Ldata} structure associated to the $L$ function
@@ -8123,6 +8204,15 @@ associated to Ramanujan's $\Delta$ function is encoded as follows
 
 The library syntax is \fun{GEN}{lfunetaquo}{GEN M}.
 
+\subsec{lfungenus2$(F)$}\kbdsidx{lfungenus2}\label{se:lfungenus2}
+Returns the \kbd{Ldata} structure associated to the $L$ function
+associated to the genus-2 curve defined by $y^2=F(x)$ or
+$y^2+Q(x)\*y=P(x)$ if $F=[P,Q]$.
+Currently, the model needs to be minimal at 2, and if the conductor
+is even, its valuation at $2$ might be incorrect (a warning is issued).
+
+The library syntax is \fun{GEN}{lfungenus2}{GEN F}.
+
 \subsec{lfunhardy$(L,t)$}\kbdsidx{lfunhardy}\label{se:lfunhardy}
 Variant of the Hardy $Z$-function given by \kbd{L}, used for
 plotting or locating zeros of $L(k/2+it)$ on the critical line.
@@ -8150,7 +8240,7 @@ applications since thousands of values are computed. Make sure to initialize
 up to the maximal $t$ needed: otherwise expect to see many warnings for
 unsufficient initialization and suffer major slowdowns.
 
-The library syntax is \fun{GEN}{lfunhardy_bitprec}{GEN L, GEN t, long bitprec}.
+The library syntax is \fun{GEN}{lfunhardy}{GEN L, GEN t, long bitprec}.
 
 \subsec{lfuninit$(L,\var{sdom},\{\var{der}=0\})$}\kbdsidx{lfuninit}\label{se:lfuninit}
 Initalization function for all functions linked to the
@@ -8182,7 +8272,7 @@ domain that you need.
 ? L = lfuninit(L0, [100]); \\ same as above !
 @eprog
 
-The library syntax is \fun{GEN}{lfuninit0_bitprec}{GEN L, GEN sdom, long der, long bitprec}.
+The library syntax is \fun{GEN}{lfuninit0}{GEN L, GEN sdom, long der, long bitprec}.
 
 \subsec{lfunlambda$(L,s,\{D=0\})$}\kbdsidx{lfunlambda}\label{se:lfunlambda}
 Compute the completed $L$-function $\Lambda(s) = N^{s/2}\gamma(s)L(s)$,
@@ -8194,14 +8284,20 @@ latter if many values are to be computed.
 The result is given with absolute error less than $2^{-B}|\gamma(s)N^{s/2}|$,
 where $B = \text{realbitprecision}$.
 
-The library syntax is \fun{GEN}{lfunlambda0_bitprec}{GEN L, GEN s, long D, long bitprec}.
+The library syntax is \fun{GEN}{lfunlambda0}{GEN L, GEN s, long D, long bitprec}.
 
 \subsec{lfunmfpeters$(L)$}\kbdsidx{lfunmfpeters}\label{se:lfunmfpeters}
 \kbd{L} corresponding to a normalized eigenform but {\bf not}
- to the output of \kbd{lfunsymsq}, returns the Petersson square of the
- form, computed using the symmetric square.
+to the output of \kbd{lfunsymsq}, returns the Petersson square of the
+form, computed using the symmetric square.
+\bprog
+? e = ellinit([-2,1]);
+? L = lfuncreate(e);
+? lfunmfpeters(L) * (2*Pi)^2 / e.area
+%2 = 0.99999999999999999999999999999999999999
+ at eprog
 
-The library syntax is \fun{GEN}{lfunmfpeters_bitprec}{GEN L, long bitprec}.
+The library syntax is \fun{GEN}{lfunmfpeters}{GEN L, long bitprec}.
 
 \subsec{lfunmfspec$(L)$}\kbdsidx{lfunmfspec}\label{se:lfunmfspec}
 Returns \kbd{[valeven,valodd,omminus,omplus]},
@@ -8210,20 +8306,20 @@ Returns \kbd{[valeven,valodd,omminus,omplus]},
  \kbd{omplus} the corresponding real numbers $\omega^-$ and $\omega^+$
  normalized in a noncanonical way. For the moment, only for modular forms of even weight.
 
-The library syntax is \fun{GEN}{lfunmfspec_bitprec}{GEN L, long bitprec}.
+The library syntax is \fun{GEN}{lfunmfspec}{GEN L, long bitprec}.
 
 \subsec{lfunmul$(\var{L1},\var{L2})$}\kbdsidx{lfunmul}\label{se:lfunmul}
 Creates the \kbd{Ldata} structure (without initialization) corresponding
  to the product of the Dirichlet series given by \kbd{L1} and
  \kbd{L2}.
 
-The library syntax is \fun{GEN}{lfunmul}{GEN L1, GEN L2, long prec}.
+The library syntax is \fun{GEN}{lfunmul}{GEN L1, GEN L2, long bitprec}.
 
 \subsec{lfunorderzero$(L)$}\kbdsidx{lfunorderzero}\label{se:lfunorderzero}
 Computes the order of the possible zero of the $L$-function at the
 center $k/2$ of the critical strip; return $0$ if $L(k/2)$ does not vanish.
 
-The library syntax is \fun{long}{lfunorderzero_bitprec}{GEN L, long bitprec}.
+The library syntax is \fun{long}{lfunorderzero}{GEN L, long bitprec}.
 
 \subsec{lfunqf$(Q)$}\kbdsidx{lfunqf}\label{se:lfunqf}
 Returns the \kbd{Ldata} structure associated to the $\Theta$ function
@@ -8258,7 +8354,7 @@ the function determines the root number,
 \item or at most a single pole is allowed: the function computes both
 the root number and the residue ($0$ if no pole).
 
-The library syntax is \fun{GEN}{lfunrootres_bitprec}{GEN data, long bitprec}.
+The library syntax is \fun{GEN}{lfunrootres}{GEN data, long bitprec}.
 
 \subsec{lfunsymsq$(L,\{\var{known}=[\,]\})$}\kbdsidx{lfunsymsq}\label{se:lfunsymsq}
 Creates the \kbd{Ldata} corresponding to the symmetric square of the modular
@@ -8284,7 +8380,7 @@ The library syntax is \fun{GEN}{lfunsymsq}{GEN L, GEN known = NULL, long prec}.
  output by \kbd{lfunmfspec}).
  For the moment, only for modular forms of even weight.
 
-The library syntax is \fun{GEN}{lfunsymsqspec_bitprec}{GEN L, long bitprec}.
+The library syntax is \fun{GEN}{lfunsymsqspec}{GEN L, long bitprec}.
 
 \subsec{lfuntheta$(\var{data},t,\{m=0\})$}\kbdsidx{lfuntheta}\label{se:lfuntheta}
 Compute the value of the $m$-th derivative
@@ -8302,7 +8398,7 @@ $f(\tau)=\sum_{n\ge0}a(n)q^n$ with $q=\exp(2\pi i\tau)$, we have
 $\Theta(t)=2(f(it/\sqrt{N})-a(0))$. Note that an easy theorem on modular
 forms implies that $a(0)$ can be recovered by the formula $a(0)=-L(f,0)$.
 
-The library syntax is \fun{GEN}{lfuntheta_bitprec}{GEN data, GEN t, long m, long bitprec}.
+The library syntax is \fun{GEN}{lfuntheta}{GEN data, GEN t, long m, long bitprec}.
 
 \subsec{lfunthetacost$(L,\{\var{tdom}\},\{m=0\})$}\kbdsidx{lfunthetacost}\label{se:lfunthetacost}
 Estimates the cost of running
@@ -8375,7 +8471,7 @@ The initialization is equivalent to
 ? lfunthetainit(L, [abs(t), arg(t)])
 @eprog
 
-The library syntax is \fun{GEN}{lfunthetainit_bitprec}{GEN L, GEN tdom = NULL, long m, long bitprec}.
+The library syntax is \fun{GEN}{lfunthetainit}{GEN L, GEN tdom = NULL, long m, long bitprec}.
 
 \subsec{lfunzeros$(L,\var{lim},\{\var{divz}=8\})$}\kbdsidx{lfunzeros}\label{se:lfunzeros}
 \kbd{lim} being either an upper limit or a real interval, computes an
@@ -8395,10 +8491,13 @@ larger than the default (= 8).
 possibly on the real axis at $s = k/2$ and that there are no poles in the
 search interval.
 
-The library syntax is \fun{GEN}{lfunzeros_bitprec}{GEN L, GEN lim, long divz, long bitprec}.
+The library syntax is \fun{GEN}{lfunzeros}{GEN L, GEN lim, long divz, long bitprec}.
 %SECTION: l_functions
 
-\section{Functions related to modular forms and modular symbols}
+\section{Functions related to modular forms}
+
+
+\section{Functions related to modular symbols}
 
 Let $\Delta := \text{Div}^0(\P^1(\Q))$ be the abelian group of divisors of
 degree $0$ on the rational projective line. The standard $\text{GL}(2,\Q)$
@@ -8614,17 +8713,28 @@ Let $E/\Q$ be an elliptic curve of conductor $N$. For $\varepsilon =
 $H^1_c(X_0(N),\Q)^\varepsilon$  associated to
 $E$. For all primes $p$ not dividing $N$ we have
 $T_p(x^\varepsilon) =  a_p x^\varepsilon$, where $a_p = p+1-\#E(\F_p)$.
-For each choice of sign, this defines a unique symbol up to multiplication by
-a constant and we normalize it so that the associated $p$-adic measure yields
-the $p$-adic $L$-function. Namely, we have
-$$ x^\varepsilon([0]-[\infty]) = L(E,1) / \Omega,$$
-for $\Omega$ the real period of $E$ (this defines $x^{\pm}$ unless $L(E,1)=0$).
-Furthermore, for all fundamental discriminants $d$ coprime to $2N$ such
-that $\varepsilon \cdot d > 0$ and $L(E^{(d)},1) \neq 0$, we also have
-$$\sum_{0\leq a<|d|} (d|a) x^\varepsilon([a/|d|]-[\infty])
-   = L(E^{(d)},1) / \Omega_d,$$
-where $(d|a)$ is the Kronecker symbol and $\Omega_d$ is the real
-period of the twist $E^{(d)}$.
+
+Let $\Omega^+ = \kbd{E.omega[1]}$ be the real period of $E$
+(integration of the N\'eron differential $dx/(2y+a_1x+a3)$ on the connected
+component of $E(\R)$, i.e.~the generator of $H_1(E,\Z)^+$) normalized by
+$\Omega^+>0$. Let $i\Omega^-$ the integral on a generator of $H_1(E,\Z)^-$ with
+$\Omega^- \in \R_{>0}$. If $c_\infty$ is the number of connected
+components of $E(\R)$, $\Omega^-$ is equal to
+$(-2/c_\infty) \times \kbd{imag(E.omega[2])}$.
+The complex modular symbol is defined by
+$$F: \delta \to  2i\pi \int_{\delta} f(z) dz$$
+The modular symbols $x^\varepsilon$ are normalized so that
+$ F = x^+ \Omega^+ + x^- i\Omega^-$.
+In particular, we have
+$$ x^+([0]-[\infty]) = L(E,1) / \Omega^+,$$
+which defines $x^{\pm}$ unless $L(E,1)=0$.
+Furthermore, for all fundamental discriminants $D$ such
+that $\varepsilon \cdot D > 0$, we also have
+$$\sum_{0\leq a<|D|} (D|a) x^\varepsilon([a/|D|]-[\infty])
+   = L(E,(D|.),1) / \Omega^{\varepsilon},$$
+where $(D|.)$ is the Kronecker symbol.
+The period $\Omega^-$ is also $2/c_\infty \times$ the real period
+of the twist $E^{(-4)} = \kbd{elltwist(E,-4)}$.
 
 This function returns the pair $[M, x]$, where $M$ is
 \kbd{msinit}$(N,2)$ and $x$ is $x^{\var{sign}}$ as above when $\var{sign}=
@@ -8639,12 +8749,79 @@ of the fixed basis of $\text{Hom}_G(\Delta,\Q)$ chosen in $M$).
 ? [M,x]= msfromell(E);
 ? x    \\ both x^+ and x^-
 %5 = [[1/5, -1/2, -1/2]~, [0, 1/2, -1/2]~]
-? p = 101; (mshecke(M,p) - ellap(E,p))*x[1]
-%4 = [0, 0, 0]~ \\ true at all primes; same for x[2]
+? p = 23; (mshecke(M,p) - ellap(E,p))*x[1]
+%6 = [0, 0, 0]~ \\ true at all primes, including p = 11; same for x[2]
 @eprog
 
 The library syntax is \fun{GEN}{msfromell}{GEN E, long sign}.
 
+\subsec{msfromhecke$(M, v, \{H\})$}\kbdsidx{msfromhecke}\label{se:msfromhecke}
+Given a msinit $M$ and a vector $v$ of pairs $[p, P]$ (where $p$ is prime
+and $P$ is a polynomial with integer coefficients), return a basis of all
+modular symbols such that $P(T_p)(s) = 0$. If $H$ is present, it must
+be a Hecke-stable subspace and we restrict to $s \in H$. When $T_p$ has
+a rational eigenvalue and $P(x) = x-a_p$ has degree $1$, we also accept the
+integer $a_p$ instead of $P$.
+\bprog
+? E = ellinit([0,-1,1,-10,-20]) \\11a1
+? ellap(E,2)
+%2 = -2
+? ellap(E,3)
+%3 = -1
+? M = msinit(11,2);
+? S = msfromhecke(M, [[2,-2],[3,-1]])
+%5 =
+[ 1  1]
+
+[-5  0]
+
+[ 0 -5]
+? mshecke(M, 2, S)
+%6 =
+[-2  0]
+
+[ 0 -2]
+
+? M = msinit(23,4);
+? S = msfromhecke(M, [[5, x^4-14*x^3-244*x^2+4832*x-19904]]);
+? factor( charpoly(mshecke(M,5,S)) )
+%9 =
+[x^4 - 14*x^3 - 244*x^2 + 4832*x - 19904 2]
+ at eprog
+
+The library syntax is \fun{GEN}{msfromhecke}{GEN M, GEN v, GEN H = NULL}.
+
+\subsec{msgetlevel$(M)$}\kbdsidx{msgetlevel}\label{se:msgetlevel}
+$M$ being a full modular symbol space, as given by \kbd{msinit}, return
+its level $N$.
+
+The library syntax is \fun{long}{msgetlevel}{GEN M}.
+
+\subsec{msgetsign$(M)$}\kbdsidx{msgetsign}\label{se:msgetsign}
+$M$ being a full modular symbol space, as given by \kbd{msinit}, return
+its sign: $\pm1$ or 0 (unset).
+\bprog
+? M = msinit(11,4, 1);
+? msgetsign(M)
+%2 = 1
+? M = msinit(11,4);
+? msgetsign(M)
+%4 = 0
+ at eprog
+
+The library syntax is \fun{long}{msgetsign}{GEN M}.
+
+\subsec{msgetweight$(M)$}\kbdsidx{msgetweight}\label{se:msgetweight}
+$M$ being a full modular symbol space, as given by \kbd{msinit}, return
+its weight $k$.
+\bprog
+? M = msinit(11,4);
+? msgetweight(M)
+%2 = 4
+ at eprog
+
+The library syntax is \fun{long}{msgetweight}{GEN M}.
+
 \subsec{mshecke$(M,p,\{H\})$}\kbdsidx{mshecke}\label{se:mshecke}
 $M$ being a full modular symbol space, as given by \kbd{msinit},
 $p$ being a prime number, and $H$ being a Hecke-stable subspace ($M$ if
@@ -8734,6 +8911,270 @@ a $\Q$-basis of the subspace.
 
 The library syntax is \fun{GEN}{msnew}{GEN M}.
 
+\subsec{msomseval$(\var{Mp}, \var{PHI}, \var{path})$}\kbdsidx{msomseval}\label{se:msomseval}
+Return the vectors of moments of the $p$-adic distribution attached
+to the path \kbd{path} by the overconvergent modular symbol \kbd{PHI}.
+\bprog
+? M = msinit(3,6,1);
+? Mp= mspadicinit(M,5,10);
+? phi = [5,-3,-1]~;
+? msissymbol(M,phi)
+%4 = 1
+? PHI = mstooms(Mp,phi);
+? ME = msomseval(Mp,PHI,[oo, 0]);
+ at eprog
+
+The library syntax is \fun{GEN}{msomseval}{GEN Mp, GEN PHI, GEN path}.
+
+\subsec{mspadicL$(\var{mu}, \{s = 0\}, \{r = 0\})$}\kbdsidx{mspadicL}\label{se:mspadicL}
+Returns the value (or $r$-th derivative)
+on a character $\chi^s$ of $\Z_p^*$ of the $p$-adic $L$-function
+attached to \kbd{mu}.
+
+Let $\Phi$ be the $p$-adic distribution-valued overconvergent symbol
+attached to a modular symbol $\phi$ for $\Gamma_0(N)$ (eigenvector for
+$T_N(p)$ for the eigenvalue $a_p$). Then $L_p(\Phi,\chi^s)=L_p(\mu,s)$ is the
+$p$-adic $L$ function defined by
+$$L_p(\Phi,\chi^s)= \int_{\Z_p^*} \chi^s(z) d\mu(z)$$
+where $\mu$ is the distribution on $\Z_p^*$ defined by the restriction of
+$\Phi([\infty]-[0])$ to $\Z_p^*$. The $r$-th derivative is taken in
+direction $\langle \chi\rangle$:
+$$L_p^{(r)}(\Phi,\chi^s)= \int_{\Z_p^*} \chi^s(z) (\log z)^r d\mu(z).$$
+In the argument list,
+
+\item \kbd{mu} is as returned by \tet{mspadicmoments} (distributions
+attached to $\Phi$ by restriction to discs $a + p^\nu\Z_p$, $(a,p)=1$).
+
+\item $s=[s_1,s_2]$ with $s_1 \in \Z \subset \Z_p$ and $s_2 \bmod p-1$ or
+$s_2 \bmod 2$ for $p=2$, encoding the $p$-adic character $\chi^s := \langle
+\chi \rangle^{s_1} \tau^{s_2}$; here $\chi$ is the cyclotomic character from
+$\text{Gal}(\Q_p(\mu_{p^\infty})/\Q_p)$ to $\Z_p^*$, and $\tau$ is the
+Teichm\"uller character (for $p>2$ and the character of order 2 on
+$(\Z/4\Z)^*$ if $p=2$); for convenience, the character $[s,s]$ can also be
+represented by the integer $s$.
+
+When $a_p$ is a $p$-adic unit, $L_p$ takes its values in $\Q_p$.
+When $a_p$ is not a unit, it takes its values in the
+two-dimensional $\Q_p$-vector space $D_{cris}(M(\phi))$ where $M(\phi)$ is
+the ``motive'' attached to $\phi$, and we return the two $p$-adic components
+with respect to some fixed $\Q_p$-basis.
+\bprog
+? M = msinit(3,6,1); phi=[5, -3, -1]~;
+? msissymbol(M,phi)
+%2 = 1
+? Mp = mspadicinit(M, 5, 4);
+? mu = mspadicmoments(Mp, phi); \\ no twist
+\\ End of initializations
+
+? mspadicL(mu,0) \\ L_p(chi^0)
+%5 = 5 + 2*5^2 + 2*5^3 + 2*5^4 + ...
+? mspadicL(mu,1) \\ L_p(chi), zero for parity reasons
+%6 = [O(5^13)]~
+? mspadicL(mu,2) \\ L_p(chi^2)
+%7 = 3 + 4*5 + 4*5^2 + 3*5^5 + ...
+? mspadicL(mu,[0,2]) \\ L_p(tau^2)
+%8 = 3 + 5 + 2*5^2 + 2*5^3 + ...
+? mspadicL(mu, [1,0]) \\ L_p(<chi>)
+%9 = 3*5 + 2*5^2 + 5^3 + 2*5^7 + 5^8 + 5^10 + 2*5^11 + O(5^13)
+? mspadicL(mu,0,1) \\ L_p'(chi^0)
+%10 = 2*5 + 4*5^2 + 3*5^3 + ...
+? mspadicL(mu, 2, 1) \\ L_p'(chi^2)
+%11 = 4*5 + 3*5^2 + 5^3 + 5^4 + ...
+ at eprog
+
+Now several quadratic twists: \tet{mstooms} is indicated.
+\bprog
+? PHI = mstooms(Mp,phi);
+? mu = mspadicmoments(Mp, PHI, 12); \\ twist by 12
+? mspadicL(mu)
+%14 = 5 + 5^2 + 5^3 + 2*5^4 + ...
+? mu = mspadicmoments(Mp, PHI, 8); \\ twist by 8
+? mspadicL(mu)
+%16 = 2 + 3*5 + 3*5^2 + 2*5^4 + ...
+? mu = mspadicmoments(Mp, PHI, -3); \\ twist by -3 < 0
+? mspadicL(mu)
+%18 = O(5^13) \\ always 0, phi is in the + part and D < 0
+ at eprog
+
+One can locate interesting symbols of level $N$ and weight $k$ with
+\kbd{msnew} and \kbd{mssplit}. Note that instead of a symbol, one can
+input a 1-dimensional Hecke-subspace from \kbd{mssplit}: the function will
+automatically use the underlying basis vector.
+\bprog
+? M=msinit(5,4,1); \\ M_4(Gamma_0(5))^+
+? L = mssplit(M, msnew(M)); \\ list of irreducible Hecke-subspaces
+? phi = L[1]; \\ one Galois orbit of newforms
+? #phi[1] \\... this one is rational
+%4 = 1
+? Mp = mspadicinit(M, 3, 4);
+? mu = mspadicmoments(Mp, phi);
+? mspadicL(mu)
+%7 = 1 + 3 + 3^3 + 3^4 + 2*3^5 + 3^6 + O(3^9)
+
+? M = msinit(11,8, 1); \\ M_8(Gamma_0(11))^+
+? Mp = mspadicinit(M, 3, 4);
+? L = mssplit(M, msnew(M));
+? phi = L[1]; #phi[1] \\ ... this one is two-dimensional
+%11 = 2
+? mu = mspadicmoments(Mp, phi);
+ ***   at top-level: mu=mspadicmoments(Mp,ph
+ ***                    ^--------------------
+ *** mspadicmoments: incorrect type in mstooms [dim_Q (eigenspace) > 1]
+ at eprog
+
+The library syntax is \fun{GEN}{mspadicL}{GEN mu, GEN s = NULL, long r}.
+
+\subsec{mspadicinit$(M, p, n, \{\fl\})$}\kbdsidx{mspadicinit}\label{se:mspadicinit}
+$M$ being a full modular symbol space, as given by \kbd{msinit}, and $p$
+a prime, initialize technical data needed to compute with overconvergent
+modular symbols, modulo $p^n$. If $\fl$ is unset, allow
+all symbols; else initialize only for a restricted range of symbols
+depending on $\fl$: if $\fl = 0$ restrict to ordinary symbols, else
+restrict to symbols $\phi$ such that $T_p(\phi) = a_p \phi$,
+with $v_p(a_p) \geq \fl$, which is faster as $\fl$ increases.
+(The fastest initialization is obtained for $\fl = 0$ where we only allow
+ordinary symbols.) For supersingular eigensymbols, such that $p\mid a_p$, we
+must further assume that $p$ does not divide the level.
+\bprog
+? E = ellinit("11a1");
+? [M,phi] = msfromell(E,1);
+? ellap(E,3)
+%3 = -1
+? Mp = mspadicinit(M, 3, 10, 0); \\ commit to ordinary symbols
+? PHI = mstooms(Mp,phi);
+ at eprog
+
+If we restrict the range of allowed symbols with \fl (for faster
+initialization), exceptions will occur if $v_p(a_p)$ violates this bound:
+\bprog
+? E = ellinit("15a1");
+? [M,phi] = msfromell(E,1);
+? ellap(E,7)
+%3 = 0
+? Mp = mspadicinit(M,7,5,0); \\ restrict to ordinary symbols
+? PHI = mstooms(Mp,phi)
+***   at top-level: PHI=mstooms(Mp,phi)
+***                     ^---------------
+*** mstooms: incorrect type in mstooms [v_p(ap) > mspadicinit flag] (t_VEC).
+? Mp = mspadicinit(M,7,5); \\ no restriction
+? PHI = mstooms(Mp,phi);
+ at eprog\noindent This function uses $O(N^2(n+k)^2p)$ memory, where $N$ is the
+level of $M$.
+
+The library syntax is \fun{GEN}{mspadicinit}{GEN M, long p, long n, long flag}.
+
+\subsec{mspadicmoments$(\var{Mp}, \var{PHI}, \{D = 1\})$}\kbdsidx{mspadicmoments}\label{se:mspadicmoments}
+Given \kbd{Mp} from \kbd{mspadicinit}, an overconvergent
+eigensymbol \kbd{PHI} from \kbd{mstooms} and a fundamental discriminant
+$D$ coprime to $p$,
+let $\kbd{PHI}^D$ denote the twisted symbol. This function computes
+the distribution $\mu = \kbd{PHI}^D([0] - \infty]) \mid \Z_p^*$ restricted
+to $\Z_p^*$. More precisely, it returns
+the moments of the $p-1$ distributions $\kbd{PHI}^D([0]-[\infty])
+\mid (a + p\Z_p)$, $0 < a < p$.
+We also allow \kbd{PHI} to be given as a classical
+symbol, which is then lifted to an overconvergent symbol by \kbd{mstooms};
+but this is wasteful if more than one twist is later needed.
+
+The returned data $\mu$ ($p$-adic distributions attached to \kbd{PHI})
+can then be used in \tet{mspadicL} or \tet{mspadicseries}.
+This precomputation allows to quickly compute derivatives of different
+orders or values at different characters.
+\bprog
+? M = msinit(3,6, 1);
+? phi = [5,-3,-1]~;
+? msissymbol(M, phi)
+%3 = 1
+? p = 5; mshecke(M,p) * phi  \\ eigenvector of T_5, a_5 = 6
+%4 = [30, -18, -6]~
+? Mp = mspadicinit(M, p, 10, 0); \\ restrict to ordinary symbols, mod p^10
+? PHI = mstooms(Mp, phi);
+? mu = mspadicmoments(Mp, PHI);
+? mspadicL(mu)
+%8 = 5 + 2*5^2 + 2*5^3 + ...
+? mu = mspadicmoments(Mp, PHI, 12); \\ twist by 12
+? mspadicL(mu)
+%10 = 5 + 5^2 + 5^3 + 2*5^4 + ...
+ at eprog
+
+The library syntax is \fun{GEN}{mspadicmoments}{GEN Mp, GEN PHI, long D}.
+
+\subsec{mspadicseries$(\var{mu}, \{i=0\})$}\kbdsidx{mspadicseries}\label{se:mspadicseries}
+Let $\Phi$ be the $p$-adic distribution-valued overconvergent symbol
+attached to a modular symbol $\phi$ for $\Gamma_0(N)$ (eigenvector for
+$T_N(p)$ for the eigenvalue $a_p$).
+If $\mu$ is the distribution on $\Z_p^*$ defined by the restriction of
+$\Phi([\infty]-[0])$ to $\Z_p^*$, let
+$$\hat{L}_p(\mu,\tau^{i})(x)
+  = \int_{\Z_p^*} \tau^i(t) (1+x)^{\log_p(t)/\log_p(u)}d\mu(t)$$
+Here, $\tau$ is the Teichm\"uller character and $u$ is a specific
+multiplicative generator of $1+2p\Z_p$. (Namely $1+p$ if $p>2$ or $5$
+if $p=2$.) To explain
+the formula, let $G_\infty := \text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$,
+let $\chi:G_\infty\to \Z_p^*$ be the cyclotomic character (isomorphism)
+and $\gamma$ the element of $G_\infty$ such that $\chi(\gamma)=u$;
+then
+$\chi(\gamma)^{\log_p(t)/\log_p(u)}= \langle t \rangle$.
+
+The $p$-padic precision of individual terms is maximal given the precision of
+the overconvergent symbol $\mu$.
+\bprog
+? [M,phi] = msfromell(ellinit("17a1"),1);
+? Mp = mspadicinit(M, 5,7);
+? mu = mspadicmoments(Mp, phi,1); \\ overconvergent symbol
+? mspadicseries(mu)
+%4 = (4 + 3*5 + 4*5^2 + 2*5^3 + 2*5^4 + 5^5 + 4*5^6 + 3*5^7 + O(5^9)) \
+ + (3 + 3*5 + 5^2 + 5^3 + 2*5^4 + 5^6 + O(5^7))*x \
+ + (2 + 3*5 + 5^2 + 4*5^3 + 2*5^4 + O(5^5))*x^2 \
+ + (3 + 4*5 + 4*5^2 + O(5^3))*x^3 \
+ + (3 + O(5))*x^4 + O(x^5)
+ at eprog\noindent
+An example with non-zero Teichm\"uller:
+\bprog
+? [M,phi] = msfromell(ellinit("11a1"),1);
+? Mp = mspadicinit(M, 3,10);
+? mu = mspadicmoments(Mp, phi,1);
+? mspadicseries(mu, 2)
+%4 = (2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + 3^7 + 3^10 + 3^11 + O(3^12)) \
+ + (1 + 3 + 2*3^2 + 3^3 + 3^5 + 2*3^6 + 2*3^8 + O(3^9))*x \
+ + (1 + 2*3 + 3^4 + 2*3^5 + O(3^6))*x^2 \
+ + (3 + O(3^2))*x^3 + O(x^4)
+ at eprog\noindent
+Supersingular example (not checked)
+\bprog
+? E = ellinit("17a1"); ellap(E,3)
+%1 = 0
+? [M,phi] = msfromell(E,1);
+? Mp = mspadicinit(M, 3,7);
+? mu = mspadicmoments(Mp, phi,1);
+? mspadicseries(mu)
+%5 = [(2*3^-1 + 1 + 3 + 3^2 + 3^3 + 3^4 + 3^5 + 3^6 + O(3^7)) \
+ + (2 + 3^3 + O(3^5))*x \
+ + (1 + 2*3 + O(3^2))*x^2 + O(x^3),\
+ (3^-1 + 1 + 3 + 3^2 + 3^3 + 3^4 + 3^5 + 3^6 + O(3^7)) \
+ + (1 + 2*3 + 2*3^2 + 3^3 + 2*3^4 + O(3^5))*x \
+ + (3^-2 + 3^-1 + O(3^2))*x^2 + O(3^-2)*x^3 + O(x^4)]
+ at eprog\noindent
+Example with a twist:
+\bprog
+? E = ellinit("11a1");
+? [M,phi] = msfromell(E,1);
+? Mp = mspadicinit(M, 3,10);
+? mu = mspadicmoments(Mp, phi,5); \\ twist by 5
+? L = mspadicseries(mu)
+%5 = (2*3^2 + 2*3^4 + 3^5 + 3^6 + 2*3^7 + 2*3^10 + O(3^12)) \
+ + (2*3^2 + 2*3^6 + 3^7 + 3^8 + O(3^9))*x \
+ + (3^3 + O(3^6))*x^2 + O(3^2)*x^3 + O(x^4)
+? mspadicL(mu)
+%6 = [2*3^2 + 2*3^4 + 3^5 + 3^6 + 2*3^7 + 2*3^10 + O(3^12)]~
+? ellpadicL(E,3,10,,5)
+%7 = 2 + 2*3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^6 + 2*3^7 + O(3^10)
+? mspadicseries(mu,1) \\ must be 0
+%8 = O(3^12) + O(3^9)*x + O(3^6)*x^2 + O(3^2)*x^3 + O(x^4)
+ at eprog
+
+The library syntax is \fun{GEN}{mspadicseries}{GEN mu, long i}.
+
 \subsec{mspathgens$(M)$}\kbdsidx{mspathgens}\label{se:mspathgens}
 Let $\Delta:=\text{Div}^0(\P^1(\Q))$.
 Let $M$ being a full modular symbol space, as given by \kbd{msinit},
@@ -8840,11 +9281,12 @@ a symbol $s$, provided it is a Hecke eigenvector:
 
 The library syntax is \fun{GEN}{msqexpansion}{GEN M, GEN projH, long precdl}.
 
-\subsec{mssplit$(M,H)$}\kbdsidx{mssplit}\label{se:mssplit}
+\subsec{mssplit$(M,H,\{\var{dimlim}\})$}\kbdsidx{mssplit}\label{se:mssplit}
 $M$ being a full modular symbol space, as given by \kbd{msinit}$(N,k,1)$
 or $\kbd{msinit}(N,k,-1)$
 and $H$ being a Hecke-stable subspace of \kbd{msnew}$(M)$, split $H$ into
-Hecke-simple subspaces.
+Hecke-simple subspaces. If \kbd{dimlim} is present and positive, restrict to
+subspaces of dimension $\leq \kbd{dimlim}$.
 A subspace is given by a structure allowing quick projection and restriction
 of linear operators; its first component is a matrix with integer
 coefficients whose columns form a $\Q$-basis of the subspace.
@@ -8864,7 +9306,7 @@ coefficients whose columns form a $\Q$-basis of the subspace.
 we printed the polynomials defining the said fields, as well as the first
 5 Fourier coefficients (at the infinite cusp) of one such form.
 
-The library syntax is \fun{GEN}{mssplit}{GEN M, GEN H}.
+The library syntax is \fun{GEN}{mssplit}{GEN M, GEN H, long dimlim}.
 
 \subsec{msstar$(M,\{H\})$}\kbdsidx{msstar}\label{se:msstar}
 $M$ being a full modular symbol space, as given by \kbd{msinit},
@@ -8878,7 +9320,69 @@ acting on the (stable) subspace $H$ ($M$ if omitted).
 @eprog
 
 The library syntax is \fun{GEN}{msstar}{GEN M, GEN H = NULL}.
-%SECTION: modular_forms
+
+\subsec{mstooms$(\var{Mp}, \var{phi})$}\kbdsidx{mstooms}\label{se:mstooms}
+Given \kbd{Mp} from \kbd{mspadicinit}, lift the (classical) eigen symbol
+\kbd{phi} to a $p$-adic distribution-valued overconvergent symbol in the
+sense of Pollack and Stevens. More precisely, let $\phi$ belong to the space
+$W$ of modular symbols of level $N$, $v_p(N) \leq 1$, and weight $k$ which is
+an eigenvector for the Hecke operator $T_N(p)$ for a non-zero eigenvalue
+$a_p$ and let $N_0 = \text{lcm}(N,p)$.
+
+Under the action of $T_{N_0}(p)$, $\phi$ generates a subspace $W_\phi$ of
+dimension $1$ (if $p\mid N$) or $2$ (if $p$ does not divide $N$) in the
+space of modular symbols of level $N_0$.
+
+Let $V_p=[p,0;0,1]$ and $C_p=[a_p,p^{k-1};-1,0]$.
+When $p \not\mid N$ and $a_p$ is divisible by $p$, \kbd{mstooms}
+returns the lift $\Phi$ of $(\phi,\phi|_k V_p)$ such that
+ $$T_{N_0}(p) \Phi = C_p \Phi$$
+
+When $p \not\mid N$ and $a_p$ is not divisible by $p$, \kbd{mstooms}
+returns the lift $\Phi$ of $\phi - \alpha^{-1} \phi|_k V_p$
+which is an eigenvector of $T_{N_0}(p)$ for the unit eigenvalue
+where $\alpha^2 - a_p \alpha + p^{k-1}=0$.
+
+The resulting overconvergent eigensymbol can then be used in
+\tet{mspadicmoments}, then \tet{mspadicL} or \tet{mspadicseries}.
+\bprog
+? M = msinit(3,6, 1); p = 5;
+? Tp = mshecke(M, p); factor(charpoly(Tp))
+%2 =
+[x - 3126 2]
+
+[   x - 6 1]
+? phi = matker(Tp - 6)[,1] \\ generator of p-Eigenspace, a_p = 6
+%3 = [5, -3, -1]~
+? Mp = mspadicinit(M, p, 10, 0); \\ restrict to ordinary symbols, mod p^10
+? PHI = mstooms(Mp, phi);
+? mu = mspadicmoments(Mp, PHI);
+? mspadicL(mu)
+%7 = 5 + 2*5^2 + 2*5^3 + ...
+ at eprog
+A non ordinary symbol.
+\bprog
+? M = msinit(4,6,1); p = 3;
+? Tp = mshecke(M, p); factor(charpoly(Tp))
+%2 =
+[x - 244 3]
+
+[ x + 12 1]
+? phi = matker(Tp + 12)[,1] \\ a_p = -12 is divisible by p = 3
+%3 = [-1/32, -1/4, -1/32, 1]~
+? msissymbol(M,phi)
+%4 = 1
+? Mp = mspadicinit(M,3,5,0);
+? PHI = mstooms(Mp,phi);
+ ***   at top-level: PHI=mstooms(Mp,phi)
+ ***                     ^---------------
+ *** mstooms: incorrect type in mstooms [v_p(ap) > mspadicinit flag] (t_VEC).
+? Mp = mspadicinit(M,3,5,1);
+? PHI = mstooms(Mp,phi);
+ at eprog
+
+The library syntax is \fun{GEN}{mstooms}{GEN Mp, GEN phi}.
+%SECTION: modular_symbols
 
 \section{Functions related to general number fields}
 
@@ -9309,7 +9813,7 @@ no longer needed:
 %4 = 1
 @eprog
 
-The library syntax is \fun{long}{bnfcertify0}{GEN bnf, long flag }.
+The library syntax is \fun{long}{bnfcertify0}{GEN bnf, long flag}.
 Also available is  \fun{GEN}{bnfcertify}{GEN bnf} ($\fl=0$).
 
 \subsec{bnfcompress$(\var{bnf})$}\kbdsidx{bnfcompress}\label{se:bnfcompress}
@@ -9576,15 +10080,16 @@ low. (Re-run the command at \bs g1 or higher to see such diagnostics.)
 The library syntax is \fun{GEN}{bnfisunit}{GEN bnf, GEN x}.
 
 \subsec{bnfnarrow$(\var{bnf})$}\kbdsidx{bnfnarrow}\label{se:bnfnarrow}
-$\var{bnf}$ being as output by
-\kbd{bnfinit}, computes the narrow class group of $\var{bnf}$. The output is
+\var{bnf} being as output by
+\kbd{bnfinit}, computes the narrow class group of \var{bnf}. The output is
 a 3-component row vector $v$ analogous to the corresponding class group
-component \kbd{\var{bnf}.clgp} (\kbd{\var{bnf}[8][1]}): the first component
+component \kbd{\var{bnf}.clgp}: the first component
 is the narrow class number \kbd{$v$.no}, the second component is a vector
 containing the SNF\sidx{Smith normal form} cyclic components \kbd{$v$.cyc} of
 the narrow class group, and the third is a vector giving the generators of
 the corresponding \kbd{$v$.gen} cyclic groups. Note that this function is a
-special case of \kbd{bnrinit}.
+special case of \kbd{bnrinit}; the \var{bnf} need not contain fundamental
+units.
 
 The library syntax is \fun{GEN}{buchnarrow}{GEN bnf}.
 
@@ -9892,11 +10397,11 @@ When $aut$ is a polynomial or an algebraic number,
 
 \subsec{bnrinit$(\var{bnf},f,\{\fl=0\})$}\kbdsidx{bnrinit}\label{se:bnrinit}
 $\var{bnf}$ is as
-output by \kbd{bnfinit}, $f$ is a modulus, initializes data linked to
-the ray class group structure corresponding to this module, a so-called
-\kbd{bnr} structure. One can input the associated \var{bid} with generators
-for $f$ instead of the module itself, saving some time.
-(As in \tet{idealstar}, the finite part of the conductor may be given
+output by \kbd{bnfinit} (including fundamental units), $f$ is a modulus,
+initializes data linked to the ray class group structure corresponding to
+this module, a so-called \kbd{bnr} structure. One can input the associated
+\var{bid} with generators for $f$ instead of the module itself, saving some
+time. (As in \tet{idealstar}, the finite part of the conductor may be given
 by a factorization into prime ideals, as produced by \tet{idealfactor}.)
 
 The following member functions are available
@@ -10359,7 +10864,7 @@ particular, if the infinite place does not divide the module, e.g if $m$ is
 an integer, then it is not a subgroup of $(\Z/n\Z)^*$, but of its quotient by
 $\{\pm 1\}$.
 
-If $fl=0$, compute a polynomial (in the variable \var{v}) defining the
+If $fl=0$, compute a polynomial (in the variable \var{v}) defining
 the subfield of $\Q(\zeta_n)$ fixed by the subgroup \var{H} of $(\Z/n\Z)^*$.
 
 If $fl=1$, compute only the conductor of the abelian extension, as a module.
@@ -10383,12 +10888,12 @@ conductor $n\infty$.
 
 The library syntax is \fun{GEN}{galoissubcyclo}{GEN N, GEN H = NULL, long fl, long v = -1}, where \kbd{v} is a variable number.
 
-\subsec{galoissubfields$(G,\{\var{flags}=0\},\{v\})$}\kbdsidx{galoissubfields}\label{se:galoissubfields}
+\subsec{galoissubfields$(G,\{\fl=0\},\{v\})$}\kbdsidx{galoissubfields}\label{se:galoissubfields}
 Outputs all the subfields of the Galois group \var{G}, as a vector.
 This works by applying \kbd{galoisfixedfield} to all subgroups. The meaning of
-the flag \var{fl} is the same as for \kbd{galoisfixedfield}.
+\var{flag} is the same as for \kbd{galoisfixedfield}.
 
-The library syntax is \fun{GEN}{galoissubfields}{GEN G, long flags, long v = -1}, where \kbd{v} is a variable number.
+The library syntax is \fun{GEN}{galoissubfields}{GEN G, long flag, long v = -1}, where \kbd{v} is a variable number.
 
 \subsec{galoissubgroups$(G)$}\kbdsidx{galoissubgroups}\label{se:galoissubgroups}
 Outputs all the subgroups of the Galois group \kbd{gal}. A subgroup is a
@@ -10624,7 +11129,7 @@ The extended ideal returned in \kbd{\%6} is the trivial ideal $1$, extended
 with a principal generator given in factored form. We use \tet{nffactorback}
 to recover it in standard form.
 
-The library syntax is \fun{GEN}{idealfactorback}{GEN nf, GEN f, GEN e = NULL, long flag }.
+The library syntax is \fun{GEN}{idealfactorback}{GEN nf, GEN f, GEN e = NULL, long flag}.
 
 \subsec{idealfrobenius$(\var{nf},\var{gal},\var{pr})$}\kbdsidx{idealfrobenius}\label{se:idealfrobenius}
 Let $K$ be the number field defined by $nf$ and assume $K/\Q$ be a
@@ -10912,7 +11417,7 @@ ideal\sidx{ideal (extended)}, its principal part is suitably
 updated: i.e. raising $[I,t]$ to the $k$-th power, yields $[I^k, t^k]$.
 
 If $\fl$ is non-zero, reduce the result using \kbd{idealred}, \emph{throughout
-the (binary) powering process}; in particular, this is \emph{not} the same as
+the (binary) powering process}; in particular, this is \emph{not} the same
 as $\kbd{idealpow}(\var{nf},x,k)$ followed by reduction.
 
 The library syntax is \fun{GEN}{idealpow0}{GEN nf, GEN x, GEN k, long flag}.
@@ -10977,7 +11482,7 @@ multiplicative group of the residue field.
 ? P = idealprimedec(K,2)[1];
 ? G = idealprincipalunits(K, P, 20);
 ? G.cyc
-[512, 256, 4]   \\ Z/512 x Z/256 x Z/4
+%4 = [512, 256, 4]   \\ Z/512 x Z/256 x Z/4
 ? G.gen
 %5 = [[-1, -2]~, 1021, [0, -1]~] \\ minimal generators of given order
 @eprog
@@ -11266,8 +11771,8 @@ of integers or a single integer.
 
 \item Matrix: we assume that it is a two-column matrix of a
 (partial) factorization of $D$; namely the first column contains
-\emph{primes} and the second one the valuation of $D$ at each of these
-primes.
+distinct \emph{primes} and the second one the valuation of $D$ at each of
+these primes.
 
 \item Integer $B$: this is replaced by the vector of primes up to $B$. Note
 that the function will use at least $O(B)$ time: a small value, about
@@ -11372,13 +11877,14 @@ $\var{nf}$ being as output by
 \kbd{nfinit}, checks whether the integer basis is known unconditionally.
 This is in particular useful when the argument to \kbd{nfinit} was of the
 form $[T, \kbd{listP}]$, specifying a finite list of primes when
-$p$-maximality had to be proven.
+$p$-maximality had to be proven, or a list of coprime integers to which
+Buchmann-Lenstra algorithm was to be applied.
 
-The function returns a vector of composite integers. If this vector is
-empty, then \kbd{nf.zk} and \kbd{nf.disc} are correct. Otherwise, the
-result is dubious. In order to obtain a certified result, one must
-completely factor each of the given integers, then \kbd{addprime} each of
-them, then check whether \kbd{nfdisc(nf.pol)} is equal to \kbd{nf.disc}.
+The function returns a vector of coprime composite integers. If this vector
+is empty, then \kbd{nf.zk} and \kbd{nf.disc} are correct. Otherwise, the
+result is dubious. In order to obtain a certified result, one must completely
+factor each of the given integers, then \kbd{addprime} each of their prime
+factors, then check whether \kbd{nfdisc(nf.pol)} is equal to \kbd{nf.disc}.
 
 The library syntax is \fun{GEN}{nfcertify}{GEN nf}.
 
@@ -11784,12 +12290,16 @@ This routine can only compute $\Q$-automorphisms, but it may be used to get
 $K$-automorphism for any base field $K$ as follows:
 \bprog
 rnfgaloisconj(nfK, R) = \\ K-automorphisms of L = K[X] / (R)
-{ my(polabs, N);
-  R *= Mod(1, nfK.pol);             \\ convert coeffs to polmod elts of K
-  polabs = rnfequation(nfK, R);
-  N = nfgaloisconj(polabs) % R;     \\ Q-automorphisms of L
-  \\ select the ones that fix K
-  select(s->subst(R, variable(R), Mod(s,R)) == 0, N);
+{
+  my(polabs, N,al,S, ala,k, vR);
+  R *= Mod(1, nfK.pol); \\ convert coeffs to polmod elts of K
+  vR = variable(R);
+  al = Mod(variable(nfK.pol),nfK.pol);
+  [polabs,ala,k] = rnfequation(nfK, R, 1);
+  Rt = if(k==0,R,subst(R,vR,vR-al*k));
+  N = nfgaloisconj(polabs) % Rt; \\ Q-automorphisms of L
+  S = select(s->subst(Rt, vR, Mod(s,Rt)) == 0, N);
+  if (k==0, S, apply(s->subst(s,vR,vR+k*al)-k*al,S));
 }
 K  = nfinit(y^2 + 7);
 rnfgaloisconj(K, x^4 - y*x^3 - 3*x^2 + y*x + 1)  \\ K-automorphisms of L
@@ -11851,7 +12361,7 @@ quadratic Hilbert symbol).
 \subsec{nfhnf$(\var{nf},x,\{\fl=0\})$}\kbdsidx{nfhnf}\label{se:nfhnf}
 Given a pseudo-matrix $(A,I)$, finds a
 pseudo-basis $(B,J)$ in \idx{Hermite normal form} of the module it generates.
-If $\fl$ is non-zero, also return the transfomation matrix $U$ such that
+If $\fl$ is non-zero, also return the transformation matrix $U$ such that
 $AU = [0|B]$.
 
 The library syntax is \fun{GEN}{nfhnf0}{GEN nf, GEN x, long flag}.
@@ -12076,13 +12586,14 @@ The library syntax is \fun{GEN}{nfmodprinit}{GEN nf, GEN pr}.
 \subsec{nfnewprec$(\var{nf})$}\kbdsidx{nfnewprec}\label{se:nfnewprec}
 Transforms the number field $\var{nf}$
 into the corresponding data using current (usually larger) precision. This
-function works as expected if $\var{nf}$ is in fact a $\var{bnf}$ (update
-$\var{bnf}$ to current precision) but may be quite slow (many generators of
-principal ideals have to be computed).
+function works as expected if \var{nf} is in fact a \var{bnf} or a \var{bnr}
+(update structure to current precision) but may be quite slow: many
+generators of principal ideals have to be computed; note that in this latter
+case, the \var{bnf} must contain fundamental units.
 
 The library syntax is \fun{GEN}{nfnewprec}{GEN nf, long prec}.
-See also \fun{GEN}{bnfnewprec}{GEN bnf, long prec}
-and \fun{GEN}{bnrnewprec}{GEN bnr, long prec}.
+See also \fun{GEN}{bnfnewprec}{GEN bnf, long prec} and
+\fun{GEN}{bnrnewprec}{GEN bnr, long prec}.
 
 \subsec{nfroots$(\{\var{nf}\},x)$}\kbdsidx{nfroots}\label{se:nfroots}
 Roots of the polynomial $x$ in the
@@ -12183,9 +12694,10 @@ inputs to the residue field using \kbd{nfM\_to\_FqM}, then work there.
 
 \subsec{nfsplitting$(\var{nf},\{d\})$}\kbdsidx{nfsplitting}\label{se:nfsplitting}
 Defining polynomial over~$\Q$ for the splitting field of \var{nf};
-if $d$ is given, it must be the degree of the splitting field. Instead
-of~\kbd{nf}, it is possible to input an irreducible defining polynomial
-for~\kbd{nf}, but in general this is less efficient.
+if $d$ is given, it must be a multiple of the splitting field degree.
+Instead of~\kbd{nf}, it is possible to input a defining (irreducible)
+polynomial $T$ for~\kbd{nf}, but in general this is less efficient.
+
 \bprog
 ? K = nfinit(x^3-2);
 ? nfsplitting(K)
@@ -12198,8 +12710,13 @@ Specifying the degree of the splitting field can make the computation faster.
 \bprog
 ? nfsplitting(x^17-123);
 time = 3,607 ms.
+? poldegree(%)
+%2 = 272
 ? nfsplitting(x^17-123,272);
 time = 150 ms.
+? nfsplitting(x^17-123,273);
+ *** nfsplitting: Warning: ignoring incorrect degree bound 273
+time = 3,611 ms.
 @eprog
 \noindent
 The complexity of the algorithm is polynomial in the degree $d$ of the
@@ -12434,19 +12951,19 @@ isomorphic number fields will yield the same $P$. All $T$ accepted by
 \tet{nfinit} are also allowed here, e.g. non-monic polynomials, or pairs
 \kbd{[T, listP]} specifying that a non-maximal order may be used.
 
-\misctitle{Warning 1} Using a \typ{POL} $T$ requires fully factoring the
-discriminant of $T$, which may be very hard. The format \kbd{[T, listP]}
-computes only a suborder of the maximal order and replaces this part of the
-algorithm by a polynomial time computation. In that case the polynomial $P$
-is a priori no longer canonical, and it may happen that it does not have
-minimal $T_2$ norm. The routine attempts to certify the result independently
-of this order computation (as per \tet{nfcertify}: we try to prove that the
-order is maximal); if it fails, the routine returns $0$ instead of $P$.
-In order to force an output in that case as well, you may either use
-\tet{polredbest}, or \kbd{polredabs(,16)}, or
-\bprog
-  polredabs([T, nfbasis([T, listP])])
- at eprog\noindent (In all three cases, the result is no longer canonical.)
+\misctitle{Warning 1} Using a \typ{POL} $T$ requires computing
+and fully factoring the discriminant $d_K$ of the maximal order which may be
+very hard. You can use the format \kbd{[T, listP]}, where \kbd{listP}
+encodes a list of known coprime divisors of $\disc(T)$ (see \kbd{??nfbasis}),
+to help the routine, thereby replacing this part of the algorithm by a
+polynomial time computation But this may only compute a suborder of the
+maximal order, when the divisors are not squarefree or do not include all
+primes dividing $d_K$. The routine attempts to certify the result
+independently of this order computation as per \tet{nfcertify}: we try to
+prove that the computed order is maximal. If the certification fails,
+the routine then fully factors the integers returned by \kbd{nfcertify}.
+You can use \tet{polredbest} or \kbd{polredabs(,16)} to avoid this
+factorization step; in both cases, the result is no longer canonical.
 
 \misctitle{Warning 2} Apart from the factorization of the discriminant of
 $T$, this routine runs in polynomial time for a \emph{fixed} degree.
@@ -12714,10 +13231,13 @@ $\var{nf}$ \emph{must} be of lower priority than that of \var{pol}, see
 The library syntax is \fun{GEN}{rnfdiscf}{GEN nf, GEN pol}.
 
 \subsec{rnfeltabstorel$(\var{rnf},x)$}\kbdsidx{rnfeltabstorel}\label{se:rnfeltabstorel}
-$\var{rnf}$ being a relative
-number field extension $L/K$ as output by \kbd{rnfinit} and $x$ being an
+Let $\var{rnf}$ be a relative
+number field extension $L/K$ as output by \kbd{rnfinit} and let $x$ be an
 element of $L$ expressed as a polynomial modulo the absolute equation
-\kbd{\var{rnf}.pol}, computes $x$ as an element of the relative extension
+\kbd{\var{rnf}.pol}, or in terms of the absolute $\Z$-basis for $\Z_L$
+if \var{rnf} contains one (as in \kbd{rnfinit(nf,pol,1)}, or after
+a call to \kbd{nfinit(rnf)}).
+Computes $x$ as an element of the relative extension
 $L/K$ as a polmod with polmod coefficients.
 \bprog
 ? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
@@ -12725,39 +13245,58 @@ $L/K$ as a polmod with polmod coefficients.
 %2 = x^4 + 1
 ? rnfeltabstorel(L, Mod(x, L.pol))
 %3 = Mod(x, x^2 + Mod(-y, y^2 + 1))
-? rnfeltabstorel(L, Mod(2, L.pol))
-%4 = 2
+? rnfeltabstorel(L, 1/3)
+%4 = 1/3
 ? rnfeltabstorel(L, Mod(x, x^2-y))
- ***   at top-level: rnfeltabstorel(L,Mod
+%5 = Mod(x, x^2 + Mod(-y, y^2 + 1))
+
+? rnfeltabstorel(L, [0,0,0,1]~) \\ Z_L not initialized yet
+ ***   at top-level: rnfeltabstorel(L,[0,
  ***                 ^--------------------
- *** rnfeltabstorel: inconsistent moduli in rnfeltabstorel: x^2-y != x^4+1
+ *** rnfeltabstorel: incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).
+? nfinit(L); \\ initialize now
+? rnfeltabstorel(L, [0,0,0,1]~)
+%6 = Mod(Mod(y, y^2 + 1)*x, x^2 + Mod(-y, y^2 + 1))
 @eprog
 
 The library syntax is \fun{GEN}{rnfeltabstorel}{GEN rnf, GEN x}.
 
-\subsec{rnfeltdown$(\var{rnf},x)$}\kbdsidx{rnfeltdown}\label{se:rnfeltdown}
+\subsec{rnfeltdown$(\var{rnf},x,\{\fl=0\})$}\kbdsidx{rnfeltdown}\label{se:rnfeltdown}
 $\var{rnf}$ being a relative number
 field extension $L/K$ as output by \kbd{rnfinit} and $x$ being an element of
-$L$ expressed as a polynomial or polmod with polmod coefficients, computes
-$x$ as an element of $K$ as a polmod, assuming $x$ is in $K$ (otherwise a
-domain error occurs).
+$L$ expressed as a polynomial or polmod with polmod coefficients (or as a
+\typ{COL} on \kbd{nfinit(rnf).zk}), computes
+$x$ as an element of $K$ as a \typ{POLMOD} if $\fl = 0$ and as a \typ{COL}
+otherwise. If $x$ is not in $K$, a domain error occurs.
 \bprog
 ? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
 ? L.pol
 %2 = x^4 + 1
 ? rnfeltdown(L, Mod(x^2, L.pol))
 %3 = Mod(y, y^2 + 1)
+? rnfeltdown(L, Mod(x^2, L.pol), 1)
+%4 = [0, 1]~
 ? rnfeltdown(L, Mod(y, x^2-y))
-%4 = Mod(y, y^2 + 1)
-? rnfeltdown(L, Mod(y,K.pol))
 %5 = Mod(y, y^2 + 1)
+? rnfeltdown(L, Mod(y,K.pol))
+%6 = Mod(y, y^2 + 1)
 ? rnfeltdown(L, Mod(x, L.pol))
  ***   at top-level: rnfeltdown(L,Mod(x,x
  ***                 ^--------------------
  *** rnfeltdown: domain error in rnfeltdown: element not in the base field
- at eprog
-
-The library syntax is \fun{GEN}{rnfeltdown}{GEN rnf, GEN x}.
+? rnfeltdown(L, Mod(y, x^2-y), 1) \\ as a t_COL
+%7 = [0, 1]~
+? rnfeltdown(L, [0,1,0,0]~) \\ not allowed without absolute nf struct
+  *** rnfeltdown: incorrect type in rnfeltdown (t_COL).
+? nfinit(L); \\ add absolute nf structure to L
+? rnfeltdown(L, [0,1,0,0]~) \\ now OK
+%8 = Mod(y, y^2 + 1)
+ at eprog\noindent If we had started with
+\kbd{L = rnfinit(K, x\pow2-y, 1)}, then the final would have worked directly.
+
+The library syntax is \fun{GEN}{rnfeltdown0}{GEN rnf, GEN x, long flag}.
+Also available is
+\fun{GEN}{rnfeltdown}{GEN rnf, GEN x} ($\fl = 0$).
 
 \subsec{rnfeltnorm$(\var{rnf},x)$}\kbdsidx{rnfeltnorm}\label{se:rnfeltnorm}
 $\var{rnf}$ being a relative number field extension $L/K$ as output by
@@ -12797,7 +13336,7 @@ The library syntax is \fun{GEN}{rnfeltreltoabs}{GEN rnf, GEN x}.
 \subsec{rnfelttrace$(\var{rnf},x)$}\kbdsidx{rnfelttrace}\label{se:rnfelttrace}
 $\var{rnf}$ being a relative number field extension $L/K$ as output by
 \kbd{rnfinit} and $x$ being an element of $L$, returns the relative trace
-$N_{L/K}(x)$ as an element of $K$.
+$Tr_{L/K}(x)$ as an element of $K$.
 \bprog
 ? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
 ? rnfelttrace(L, Mod(x, L.pol))
@@ -12809,11 +13348,12 @@ $N_{L/K}(x)$ as an element of $K$.
 
 The library syntax is \fun{GEN}{rnfelttrace}{GEN rnf, GEN x}.
 
-\subsec{rnfeltup$(\var{rnf},x)$}\kbdsidx{rnfeltup}\label{se:rnfeltup}
+\subsec{rnfeltup$(\var{rnf},x,\{\fl=0\})$}\kbdsidx{rnfeltup}\label{se:rnfeltup}
 $\var{rnf}$ being a relative number field extension $L/K$ as output by
 \kbd{rnfinit} and $x$ being an element of $K$, computes $x$ as an element of
-the absolute extension $L/\Q$ as a polynomial modulo the absolute equation
-\kbd{\var{rnf}.pol}.
+the absolute extension $L/\Q$. As a \typ{POLMOD} modulo \kbd{\var{rnf}.pol}
+if $\fl = 0$ and as a \typ{COL} on the absolute field integer basis if
+$\fl = 1$.
 \bprog
 ? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
 ? L.pol
@@ -12824,9 +13364,13 @@ the absolute extension $L/\Q$ as a polynomial modulo the absolute equation
 %4 = Mod(x^2, x^4 + 1)
 ? rnfeltup(L, [1,2]~) \\ in terms of K.zk
 %5 = Mod(2*x^2 + 1, x^4 + 1)
+? rnfeltup(L, y, 1) \\ in terms of nfinit(L).zk
+%6 = [0, 1, 0, 0]~
+? rnfeltup(L, [1,2]~, 1)
+%7 = [1, 2, 0, 0]~
 @eprog
 
-The library syntax is \fun{GEN}{rnfeltup}{GEN rnf, GEN x}.
+The library syntax is \fun{GEN}{rnfeltup0}{GEN rnf, GEN x, long flag}.
 
 \subsec{rnfequation$(\var{nf},\var{pol},\{\fl=0\})$}\kbdsidx{rnfequation}\label{se:rnfequation}
 Given a number field
@@ -12971,25 +13515,68 @@ norm of $x$ as an ideal of $K$ in HNF.
 
 The library syntax is \fun{GEN}{rnfidealnormrel}{GEN rnf, GEN x}.
 
-\subsec{rnfidealreltoabs$(\var{rnf},x)$}\kbdsidx{rnfidealreltoabs}\label{se:rnfidealreltoabs}
+\subsec{rnfidealprimedec$(\var{rnf},\var{pr})$}\kbdsidx{rnfidealprimedec}\label{se:rnfidealprimedec}
+Let \var{rnf} be a relative number
+field extension $L/K$ as output by \kbd{rnfinit}, and \kbd{pr} a maximal
+ideal of $K$ (\kbd{prid}), this function completes the \var{rnf}
+with a \var{nf} structure attached to $L$ (see \secref{se:rnfinit})
+and returns the prime ideal decomposition of \kbd{pr} in $L/K$.
+\bprog
+? K = nfinit(y^2+1); rnf = rnfinit(K, x^3+y+1);
+? P = idealprimedec(K, 2)[1];
+? S = rnfidealprimedec(rnf, P);
+? #S
+%4 = 1
+ at eprog
+The argument \kbd{pr} is also allowed to be a prime number $p$, in which
+case we return a pair of vectors \kbd{[SK,SL]}, where \kbd{SK} contains
+the primes of $K$ above $p$ and \kbd{SL}$[i]$ is the vector of primes of $L$
+above \kbd{SK}$[i]$.
+\bprog
+? [SK,SL] = rnfidealprimedec(rnf, 5);
+? [#SK, vector(#SL,i,#SL[i])]
+%6 = [2, [2, 2]]
+ at eprog
+
+The library syntax is \fun{GEN}{rnfidealprimedec}{GEN rnf, GEN pr}.
+
+\subsec{rnfidealreltoabs$(\var{rnf},x,\{\fl=0\})$}\kbdsidx{rnfidealreltoabs}\label{se:rnfidealreltoabs}
 Let $\var{rnf}$ be a relative
 number field extension $L/K$ as output by \kbd{rnfinit} and let $x$ be a
 relative ideal, given as a $\Z_K$-module by a pseudo matrix $[A,I]$.
-This function returns the ideal $x$ as an absolute ideal of $L/\Q$ in
-the form of a $\Z$-basis, given by a vector of polynomials (modulo
-\kbd{rnf.pol}).
-
-The reason why we do not return the customary HNF in terms of a fixed
-$\Z$-basis for $\Z_L$ is precisely that no such basis has been explicitly
-specified. On the other hand, if you already computed an (absolute) \kbd{nf}
-structure \kbd{Labs} associated to $L$, then
+This function returns the ideal $x$ as an absolute ideal of $L/\Q$.
+If $\fl = 0$, the result is given by a vector of \typ{POLMOD}s modulo
+\kbd{rnf.pol} forming a $\Z$-basis; if $\fl = 1$, it is given in HNF in terms
+of the fixed $\Z$-basis for $\Z_L$, see \secref{se:rnfinit}.
 \bprog
-  xabs = rnfidealreltoabs(L, x);
-  xLabs = mathnf(matalgtobasis(Labs, xabs));
- at eprog\noindent computes a traditional HNF \kbd{xLabs} for $x$ in terms of
-the fixed $\Z$-basis \kbd{Labs.zk}.
+? K = nfinit(y^2+1); rnf = rnfinit(K, x^2-y);
+? P = idealprimedec(K,2)[1];
+? P = rnfidealup(rnf, P)
+%3 = [2, x^2 + 1, 2*x, x^3 + x]
+? Prel = rnfidealhnf(rnf, P)
+%4 = [[1, 0; 0, 1], [[2, 1; 0, 1], [2, 1; 0, 1]]]
+? rnfidealreltoabs(rnf,Prel)
+%5 = [2, x^2 + 1, 2*x, x^3 + x]
+? rnfidealreltoabs(rnf,Prel,1)
+%6 =
+[2 1 0 0]
+
+[0 1 0 0]
 
-The library syntax is \fun{GEN}{rnfidealreltoabs}{GEN rnf, GEN x}.
+[0 0 2 1]
+
+[0 0 0 1]
+ at eprog
+The reason why we do not return by default ($\fl = 0$) the customary HNF in
+terms of a fixed $\Z$-basis for $\Z_L$ is precisely because
+a \var{rnf} does not contain such a basis by default. Completing the
+structure so that it contains a \var{nf} structure for $L$ is polynomial
+time but costly when the absolute degree is large, thus it is not done by
+default. Note that setting $\fl = 1$ will complete the \var{rnf}.
+
+The library syntax is \fun{GEN}{rnfidealreltoabs0}{GEN rnf, GEN x, long flag}.
+Also available is
+\fun{GEN}{rnfidealreltoabs}{GEN rnf, GEN x} ($\fl = 0$).
 
 \subsec{rnfidealtwoelt$(\var{rnf},x)$}\kbdsidx{rnfidealtwoelt}\label{se:rnfidealtwoelt}
 $\var{rnf}$ being a relative
@@ -13000,26 +13587,40 @@ coefficients.
 
 The library syntax is \fun{GEN}{rnfidealtwoelement}{GEN rnf, GEN x}.
 
-\subsec{rnfidealup$(\var{rnf},x)$}\kbdsidx{rnfidealup}\label{se:rnfidealup}
+\subsec{rnfidealup$(\var{rnf},x,\{\fl=0\})$}\kbdsidx{rnfidealup}\label{se:rnfidealup}
 Let $\var{rnf}$ be a relative number
 field extension $L/K$ as output by \kbd{rnfinit} and let $x$ be an ideal of
 $K$. This function returns the ideal $x\Z_L$ as an absolute ideal of $L/\Q$,
-in the form of a $\Z$-basis, given by a vector of polynomials (modulo
-\kbd{rnf.pol}).
-
-The reason why we do not return the customary HNF in terms of a fixed
-$\Z$-basis for $\Z_L$ is precisely that no such basis has been explicitly
-specified. On the other hand, if you already computed an (absolute) \var{nf}
-structure \kbd{Labs} associated to $L$, then
+in the form of a $\Z$-basis. If $\fl = 0$, the result is given by a vector of
+polynomials (modulo \kbd{rnf.pol}); if $\fl = 1$, it is given in HNF in terms
+of the fixed $\Z$-basis for $\Z_L$, see \secref{se:rnfinit}.
 \bprog
-  xabs = rnfidealup(L, x);
-  xLabs = mathnf(matalgtobasis(Labs, xabs));
- at eprog\noindent computes a traditional HNF \kbd{xLabs} for $x$ in terms of
-the fixed $\Z$-basis \kbd{Labs.zk}.
+? K = nfinit(y^2+1); rnf = rnfinit(K, x^2-y);
+? P = idealprimedec(K,2)[1];
+? rnfidealup(rnf, P)
+%3 = [2, x^2 + 1, 2*x, x^3 + x]
+? rnfidealup(rnf, P,1)
+%4 =
+[2 1 0 0]
+
+[0 1 0 0]
 
-The library syntax is \fun{GEN}{rnfidealup}{GEN rnf, GEN x}.
+[0 0 2 1]
 
-\subsec{rnfinit$(\var{nf},\var{pol})$}\kbdsidx{rnfinit}\label{se:rnfinit}
+[0 0 0 1]
+ at eprog
+The reason why we do not return by default ($\fl = 0$) the customary HNF in
+terms of a fixed $\Z$-basis for $\Z_L$ is precisely because
+a \var{rnf} does not contain such a basis by default. Completing the
+structure so that it contains a \var{nf} structure for $L$ is polynomial
+time but costly when the absolute degree is large, thus it is not done by
+default. Note that setting $\fl = 1$ will complete the \var{rnf}.
+
+The library syntax is \fun{GEN}{rnfidealup0}{GEN rnf, GEN x, long flag}.
+Also available is
+ \fun{GEN}{rnfidealup}{GEN rnf, GEN x} ($\fl = 0$).
+
+\subsec{rnfinit$(\var{nf},\var{pol},\{\fl=0\})$}\kbdsidx{rnfinit}\label{se:rnfinit}
 $\var{nf}$ being a number field in \kbd{nfinit}
 format considered as base field, and \var{pol} a polynomial defining a relative
 extension over $\var{nf}$, this computes data to work in the
@@ -13029,19 +13630,23 @@ relative extension. The main variable of \var{pol} must be of higher priority
 
 The result is a row vector, whose components are technical. In the following
 description, we let $K$ be the base field defined by $\var{nf}$ and $L/K$
-the large field associated to the \var{rnf}. Furthermore, we let
+the extension attached to the \var{rnf}. Furthermore, we let
 $m = [K:\Q]$ the degree of the base field, $n = [L:K]$ the relative degree,
 $r_1$ and $r_2$ the number of real and complex places of $K$. Access to this
 information via \emph{member functions} is preferred since the specific
 data organization specified below will change in the future.
 
-Note that a subsequent \kbd{nfinit}$(\var{rnf})$ will explicitly add an
-\kbd{nf} structure associated to $L$ to \var{rnf} (and return it as well).
+If $\fl = 1$, add an \var{nf} structure attached to $L$ to \var{rnf}.
 This is likely to be very expensive if the absolute degree $mn$ is large,
 but fixes an integer basis for $\Z_L$ as a $\Z$-module and allows to input
 and output elements of $L$ in absolute form: as \typ{COL} for elements,
 as \typ{MAT} in HNF for ideals, as \kbd{prid} for prime ideals. Without such
 a call, elements of $L$ are represented as \typ{POLMOD}, etc.
+Note that a subsequent \kbd{nfinit}$(\var{rnf})$ will also explicitly
+add such a component, and so will the following functions \kbd{rnfidealmul},
+\kbd{rnfidealtwoelt}, \kbd{rnfidealprimedec}, \kbd{rnfidealup} (with flag 1)
+and \kbd{rnfidealreltoabs} (with flag 1). The absolute \var{nf} structure
+attached to $L$ can be recovered using \kbd{nfinit(rnf)}.
 
 $\var{rnf}[1]$(\kbd{rnf.pol}) contains the relative polynomial \var{pol}.
 
@@ -13103,7 +13708,9 @@ to store further information about the field as it becomes available (which
 is rarely needed, hence would be too expensive to compute during the initial
 \kbd{rnfinit} call).
 
-The library syntax is \fun{GEN}{rnfinit}{GEN nf, GEN pol}.
+The library syntax is \fun{GEN}{rnfinit0}{GEN nf, GEN pol, long flag}.
+Also available is
+\fun{GEN}{rnfinit}{GEN nf,GEN pol} ($\fl = 0$).
 
 \subsec{rnfisabelian$(\var{nf},T)$}\kbdsidx{rnfisabelian}\label{se:rnfisabelian}
 $T$ being a relative polynomial with coefficients
@@ -13973,7 +14580,7 @@ representing an $L$-basis ${\cal B}$ of $A$ expressed on the $\Z$-basis of
 ${\cal O}_0$, and a \typ{MAT} representing the $\Z$-basis of ${\cal O}_0$
 expressed on ${\cal B}$. This data is accessed with \kbd{algsplittingdata}.
 
-The library syntax is \fun{GEN}{alginit}{GEN B, GEN C, long v = -1, long flag }, where \kbd{v} is a variable number.
+The library syntax is \fun{GEN}{alginit}{GEN B, GEN C, long v = -1, long flag}, where \kbd{v} is a variable number.
 
 \subsec{alginv$(\var{al},x)$}\kbdsidx{alginv}\label{se:alginv}
 Given an element $x$ in \var{al}, computes its inverse $x^{-1}$ in the
@@ -14170,7 +14777,7 @@ without testing it.
 %13 = 0
 @eprog
 
-The library syntax is \fun{GEN}{algissimple}{GEN al, long ss }.
+The library syntax is \fun{GEN}{algissimple}{GEN al, long ss}.
 
 \subsec{algissplit$(\var{al},\{\var{pl}\})$}\kbdsidx{algissplit}\label{se:algissplit}
 Given a central simple algebra \var{al} output by \tet{alginit}, test
@@ -14982,7 +15589,7 @@ Weber-$f$ function, and if $inv$ is 5, use $\gamma_2 =
 x^7 - x^6 + x^5 + 3*x^3 - x^2 + 3*x + 1
 @eprog
 
-The library syntax is \fun{GEN}{polclass}{GEN D, long inv , long x  = -1}, where \kbd{x } is a variable number.
+The library syntax is \fun{GEN}{polclass}{GEN D, long inv, long x = -1}, where \kbd{x} is a variable number.
 
 \subsec{polcoeff$(x,n,\{v\})$}\kbdsidx{polcoeff}\label{se:polcoeff}
 Coefficient of degree $n$ of the polynomial $x$, with respect to the
@@ -15011,7 +15618,7 @@ evaluated case, the algorithm assumes that $a^d - 1$ is either $0$ or
 invertible, for all $d\mid n$. If this is not the case (the base ring has
 zero divisors), use \kbd{subst(polcyclo(n),x,a)}.
 
-The library syntax is \fun{GEN}{polcyclo_eval}{long n, GEN a  = NULL}.
+The library syntax is \fun{GEN}{polcyclo_eval}{long n, GEN a = NULL}.
 The variant \fun{GEN}{polcyclo}{long n, long v} returns the $n$-th
 cyclotomic polynomial in variable $v$.
 
@@ -15193,27 +15800,39 @@ The library syntax is \fun{GEN}{pollegendre_eval}{long n, GEN a = NULL}.
 To obtain the $n$-th Legendre polynomial in variable $v$,
 use \fun{GEN}{pollegendre}{long n, long v}.
 
-\subsec{polmodular$(L, \{\var{inv} = 0\}, \{x = 'x\}, \{y = 'y\}, \{\var{compute\_derivs} = 0\})$}\kbdsidx{polmodular}\label{se:polmodular}
+\subsec{polmodular$(L, \{\var{inv} = 0\}, \{x = 'x\}, \{y = 'y\}, \{\var{derivs} = 0\})$}\kbdsidx{polmodular}\label{se:polmodular}
 Return the modular polynomial of level $L$ in variables $x$ and $y$
-for the modular function specified by $inv$.  If $inv$ is 0 (the
-default), use the modular f$j$ function, if $inv$ is 1 use the
-Weber-$f$ function, and if $inv$ is 5 use $\gamma_2 =
+for the modular function specified by \kbd{inv}.  If \kbd{inv} is 0 (the
+default), use the modular $j$ function, if \kbd{inv} is 1 use the
+Weber-$f$ function, and if \kbd{inv} is 5 use $\gamma_2 =
 \sqrt[3]{j}$. If $x$ is given as \kbd{Mod(j, p)} or an element $j$ of
-a prime finite field, then return the modular polynomial of level $L$
-evaluated at $j$ modulo $p$.  If $j$ is from a finite field and
-\var{compute\_derivs} is non-zero, then return a triple where the
+a finite field (as a \typ{FFELT}), then return the modular polynomial of
+level $L$ evaluated at $j$.  If $j$ is from a finite field and
+\kbd{derivs} is non-zero, then return a triple where the
 last two elements are the first and second derivatives of the modular
 polynomial evaluated at $j$.
 \bprog
 ? polmodular(3)
-%1 = x^4 + (-y^3 + 2232*y^2 - 1069956*y + 36864000)*x^3 + [...]
-? polmodular(11, 1, , 'J)
-x^12 - J^11*x^11 + 11*J^9*x^9 - 44*J^7*x^7 + 88*J^5*x^5 - 88*J^3*x^3 + 32*J*x + J^12
-? polmodular(11, 5, 7*ffgen(19)^0, 'j)
-j^12 + j^11 + 7*j^10 + 5*j^9 + 11*j^8 + 10*j^7 + 18*j^6 + 2*j^5 + j^4 + 18*j^3 + 13*j^2 + 11*j + 1
- at eprog
-
-The library syntax is \fun{GEN}{polmodular}{long L, long inv , GEN x  = NULL, long y  = -1, long compute_derivs }, where \kbd{y } is a variable number.
+%1 = x^4 + (-y^3 + 2232*y^2 - 1069956*y + 36864000)*x^3 + ...
+? polmodular(7, 1, , 'J)
+%2 = x^8 - J^7*x^7 + 7*J^4*x^4 - 8*J*x + J^8
+? polmodular(7, 5, 7*ffgen(19)^0, 'j)
+%3 = j^8 + 4*j^7 + 4*j^6 + 8*j^5 + j^4 + 12*j^2 + 18*j + 18
+? polmodular(7, 5, Mod(7,19), 'j)
+%4 = Mod(1, 19)*j^8 + Mod(4, 19)*j^7 + Mod(4, 19)*j^6 + ...
+
+? u = ffgen(5)^0; T = polmodular(3,0,,'j)*u;
+? polmodular(3, 0, u,'j,1)
+%6 = [j^4 + 3*j^2 + 4*j + 1, 3*j^2 + 2*j + 4, 3*j^3 + 4*j^2 + 4*j + 2]
+? subst(T,x,u)
+%7 = j^4 + 3*j^2 + 4*j + 1
+? subst(T',x,u)
+%8 = 3*j^2 + 2*j + 4
+? subst(T'',x,u)
+%9 = 3*j^3 + 4*j^2 + 4*j + 2
+ at eprog
+
+The library syntax is \fun{GEN}{polmodular}{long L, long inv, GEN x = NULL, long y = -1, long derivs}, where \kbd{y} is a variable number.
 Also available are
 
 \fun{GEN}{polmodular_ZXX}{long L, long inv, long xvar, long yvar}
@@ -15223,9 +15842,9 @@ which returns a bivariate polynomial in variables \kbd{xvar} and
 \fun{GEN}{polmodular_ZM}{long L, long inv} which returns a matrix of
 coefficients, and
 
-\fun{GEN}{Fp_polmodular_evalx}{long L, long inv, GEN J, GEN P, long
-v, int compute_derivs} which returns the modular polynomial evaluated
-at $J$ modulo $P$ in the variable $v$ (if \kbd{compute\_derivs} is
+\fun{GEN}{Fp_polmodular_evalx}{long L, long inv, GEN J, GEN P, long v,
+int derivs} which returns the modular polynomial evaluated
+at $J$ modulo $P$ in the variable $v$ (if \kbd{derivs} is
 non-zero, returns a vector containing the modular polynomial and its
 first and second derivatives, all evaluated at $J$ modulo $P$).
 
@@ -15243,7 +15862,7 @@ otherwise. The algorithm assumes the base ring is a domain. If you also need
 the $u$ and $v$ such that $x*u + y*v = \text{Res}(x,y)$, use the
 \tet{polresultantext} function.
 
-If $\fl=0$ (default), uses the the algorithm best suited to the inputs,
+If $\fl=0$ (default), uses the algorithm best suited to the inputs,
 either the \idx{subresultant algorithm} (Lazard/Ducos variant, generic case),
 a modular algorithm (inputs in $\Q[X]$) or Sylvester's matrix (inexact
 inputs).
@@ -15341,7 +15960,7 @@ to that closed interval.
 The algorithm used is a modification of Uspensky's method (relying on
 Descartes's rule of sign), following Rouillier and Zimmerman ``Efficient
 isolation of a polynomial real roots''
-(\url{http://hal.inria.fr/inria-00072518/}. Barring bugs, it is guaranteed
+(\url{http://hal.inria.fr/inria-00072518/}). Barring bugs, it is guaranteed
 to converge and to give the roots to the required accuracy.
 
 \misctitle{Remark} If the polynomial $T$ is of the
@@ -15375,7 +15994,19 @@ may be wrong due to round-off errors.
 %4 = 3
 ? polsturm(T, [1, Pi])  \\ Pi inexact: not recommended !
 %5 = 3
- at eprog
+? polsturm(T*1., [0, 4])  \\ T*1. inexact: not recommended !
+%6 = 3
+? polsturm(T^2, [0, 4])  \\ not squarefree
+ ***   at top-level: polsturm(T^2,[0,4])
+ ***                 ^-------------------
+ *** polsturm: domain error in polsturm: issquarefree(pol) = 0
+? polsturm((T*1.)^2, [0, 4])  \\ not squarefree AND inexact
+ ***   at top-level: polsturm((T*1.)^2,[0
+ ***                 ^--------------------
+ *** polsturm: precision too low in polsturm.
+ at eprog\noindent In the last example, the input polynomial is not
+squarefree but there is no way to ascertain it from the given
+floating point approximation: we get a precision error in this case.
 %\syn{NO}
 
 The library syntax is \fun{long}{RgX_sturmpart}{GEN T, GEN ab} or
@@ -16896,7 +17527,7 @@ The library syntax is \fun{GEN}{qfisom0}{GEN G, GEN H, GEN fl = NULL}.
 Also available is \fun{GEN}{qfisom}{GEN G, GEN H, GEN fl}
 where $G$ is a vector of \kbd{zm}, and $H$ is a \kbd{zm}.
 
-\subsec{qfisominit$(G,\{\var{fl}\})$}\kbdsidx{qfisominit}\label{se:qfisominit}
+\subsec{qfisominit$(G,\{\var{fl}\},\{m\})$}\kbdsidx{qfisominit}\label{se:qfisominit}
 $G$ being a square and symmetric matrix with integer entries representing a
 positive definite quadratic form, return an \kbd{isom} structure allowing to
 compute isomorphisms between $G$ and other quadratic forms faster.
@@ -16912,10 +17543,12 @@ computation faster or slower. The components are
 
 \item \kbd{fl[2]} Maximum level of Bacher polynomials to use.
 
-Since this function computes the minimal vectors, it can become very lengthy
-as the dimension of $G$ grows.
+If present, $m$ must be the set of vectors of norm up to the maximal of the
+diagonal entry of $G$, either as a matrix or as given by \kbd{qfminim}.
+Otherwise this function computes the minimal vectors so it become very
+lengthy as the dimension of $G$ grows.
 
-The library syntax is \fun{GEN}{qfisominit0}{GEN G, GEN fl = NULL}.
+The library syntax is \fun{GEN}{qfisominit0}{GEN G, GEN fl = NULL, GEN m = NULL}.
 Also available is
 \fun{GEN}{qfisominit}{GEN F, GEN fl}
 where $F$ is a vector of \kbd{zm}.
@@ -17189,7 +17822,7 @@ $$(3x^2 - 10xy - 3y^2)^2  + (-5x^2 - 6xy + 5y^2)^2 -34(x^2 + y^2)^2 = 0.$$
 %4 = 0
 @eprog
 
-The library syntax is \fun{GEN}{qfparam}{GEN G, GEN sol, long flag }.
+The library syntax is \fun{GEN}{qfparam}{GEN G, GEN sol, long flag}.
 
 \subsec{qfperfection$(G)$}\kbdsidx{qfperfection}\label{se:qfperfection}
 $G$ being a square and symmetric matrix with
@@ -17710,7 +18343,7 @@ $S = M[1] / (1+A[1]z+B[1]z^2/(1+A[2]z+B[2]z^2/(1+...1/(1+A[lim/2]z))))$.
 Does not work if any coefficient of $M$ vanishes, nor for series for
 which certain partial denominators vanish.
 
-The library syntax is \fun{GEN}{contfracinit}{GEN M, long lim }.
+The library syntax is \fun{GEN}{contfracinit}{GEN M, long lim}.
 
 \subsec{derivnum$(X=a,\var{expr})$}\kbdsidx{derivnum}\label{se:derivnum}
 Numerical derivation of \var{expr} with respect to $X$ at $X=a$.
@@ -18136,8 +18769,8 @@ integer $n$ in which case we call
 and change variables rather than increasing $n$ too much:
 \bprog
 ? f(x) = 1/(1+x^2);
-? a = 0; b = 100;
-? intnumgauss(x=0,1, f(x)) + intnumgauss(x=1,1/b, f(1/x)*(-1/x^2)) - atan(100)
+? b = 100;
+? intnumgauss(x=0,1, f(x)) + intnumgauss(x=1,1/b, f(1/x)*(-1/x^2)) - atan(b)
 %3 = -1.0579449157400587572 E-37
 @eprog
 
@@ -18403,8 +19036,9 @@ zeros found;
 \item 2: refine the splitting until at least one zero is found
 (may loop indefinitely if there are no zeros);
 
-\item 4: do a multiplicative search (we must have $a > 0$ and $\var{step} > 1$), otherwise
-an additive search; \var{step} is the multiplicative or additive step.
+\item 4: do a multiplicative search (we must have $a > 0$ and $\var{step} >
+1$), otherwise an additive search; \var{step} is the multiplicative or
+additive step.
 
 \item 8: refine the splitting until at least one zero is very close to an
 integer.
@@ -18413,7 +19047,7 @@ integer.
 ? solvestep(X=0,10,1,sin(X^2),1)
 %1 = 1.7724538509055160272981674833411451828
 ? solvestep(X=1,12,2,besselj(4,X),4)
-%2 = [7.5883424345038043850696300079856174174, 11.064709488501184882718322290192246095]
+%2 = [7.588342434..., 11.064709488...]
 @eprog\noindent
 
 \synt{solvestep}{void *E,GEN (*eval)(void*,GEN),GEN a,GEN b,GEN step,long flag,long prec}.
@@ -18442,8 +19076,8 @@ Numerical summation of the series \var{expr}, which should be an
 $a$. Use an algorithm of Cohen, Villegas and Zagier (\emph{Experiment. Math.}
 {\bf 9} (2000), no.~1, 3--12).
 
-If $\fl=0$, assuming that that the $a_k$ are the moments of a positive
-measure on $[0,1]$, the relative error is $O(3+\sqrt8)^(-n)$ after using
+If $\fl=0$, assuming that the $a_k$ are the moments of a positive
+measure on $[0,1]$, the relative error is $O(3+\sqrt8)^{-n}$ after using
 $a_k$ for $k\leq n$. If \kbd{realprecision} is $p$, we thus set
 $n = \log(10)p/\log(3+\sqrt8)\approx 1.3 p$; besides the time needed to
 compute the $a_k$, $k\leq n$, the algorithm overhead is negligible: time
@@ -18452,7 +19086,7 @@ $O(p^2)$ and space $O(p)$.
 If $\fl=1$, use a variant with more complicated polynomials, see
 \tet{polzagier}. If the $a_k$ are the moments of $w(x)dx$ where $w$
 (or only $xw(x^2)$) is a smooth function extending analytically to the whole
-complex plane, convergence is in $O(14.4^(-n))$. If $xw(x^2)$ extends
+complex plane, convergence is in $O(14.4^{-n})$. If $xw(x^2)$ extends
 analytically to a smaller region, we still have exponential convergence,
 with worse constants. Usually faster when the computation of $a_k$ is
 expensive. If \kbd{realprecision} is $p$, we thus set
@@ -18592,7 +19226,7 @@ when the function $f$ is expensive to evaluate, though:
 ? sumnum(n = 1, lngamma(1+1/n)/n, tab);
 time = 14,180 ms.
 
-? sumnummonien(n = 1, lngamma(1+1/n)/n, tabmon); \\ fewer function evaluations!
+? sumnummonien(n = 1, lngamma(1+1/n)/n, tabmon); \\ fewer evaluations
 time = 717 ms.
 @eprog
 
@@ -18801,7 +19435,7 @@ time = 40 ms.
 %5 = -5.562684646268003458 E-309  \\ identical result
 @eprog
 
-The library syntax is \fun{GEN}{sumnummonieninit}{GEN asymp = NULL, GEN w = NULL, GEN n0  = NULL, long prec}.
+The library syntax is \fun{GEN}{sumnummonieninit}{GEN asymp = NULL, GEN w = NULL, GEN n0 = NULL, long prec}.
 
 \subsec{sumpos$(X=a,\var{expr},\{\fl=0\})$}\kbdsidx{sumpos}\label{se:sumpos}
 Numerical summation of the series \var{expr}, which must be a series of
@@ -18822,7 +19456,7 @@ If $\fl=1$, use \kbd{sumalt}$(,1)$ instead of \kbd{sumalt}$(,0)$, see
 rigorous use, but allowing to compute fewer series terms.
 
 To reach accuracy $10^{-p}$, both algorithms require $O(p^2)$ space;
-furthermore, assuming the terms decrease polynomially (in $O(n^-C)$), both
+furthermore, assuming the terms decrease polynomially (in $O(n^{-C})$), both
 need to compute $O(p^2)$ terms. The \kbd{sumpos}$(,1)$ variant has a smaller
 implied constant (roughly 1.5 times smaller). Since the \kbd{sumalt}$(,1)$
 overhead is now small compared to the time needed to compute series terms,
@@ -19323,7 +19957,9 @@ it can be used in the break loop.
 \subsec{for$(X=a,b,\var{seq})$}\kbdsidx{for}\label{se:for}
 Evaluates \var{seq}, where
 the formal variable $X$ goes from $a$ to $b$. Nothing is done if $a>b$.
-$a$ and $b$ must be in $\R$.
+$a$ and $b$ must be in $\R$. If $b$ is set to \kbd{+oo}, the loop will not
+stop; it is expected that the caller will break out of the loop itself at some
+point, using \kbd{break} or \kbd{return}.
 
 \subsec{forcomposite$(n=a,\{b\},\var{seq})$}\kbdsidx{forcomposite}\label{se:forcomposite}
 Evaluates \var{seq},
@@ -19458,9 +20094,9 @@ larger than $p$, at the end of each iteration. Nothing is done if $a>b$.
 ? forprime(p = 4, 10, print(p))
 5
 7
- at eprog\noindent Omitting $b$ means we will run through all primes $\geq a$,
-starting an infinite loop; it is expected that the user will break out of
-the loop himself at some point, using \kbd{break} or \kbd{return}.
+ at eprog\noindent Setting $b$ to \kbd{+oo} means we will run through all primes
+$\geq a$, starting an infinite loop; it is expected that the caller will break
+out of the loop itself at some point, using \kbd{break} or \kbd{return}.
 
 Note that the value of $p$ cannot be modified within \var{seq}:
 \bprog
@@ -19485,7 +20121,9 @@ successive steps are used in the order they appear in $s$.
 13
 17
 19
- at eprog
+ at eprog\noindent Setting $b$ to \kbd{+oo} will start an infinite loop; it is
+expected that the caller will break out of the loop itself at some point,
+using \kbd{break} or \kbd{return}.
 
 \subsec{forsubgroup$(H=G,\{\var{bound}\},\var{seq})$}\kbdsidx{forsubgroup}\label{se:forsubgroup}
 Evaluates \var{seq} for
@@ -19938,10 +20576,10 @@ it right away.
 \misctitle{Caveat} It is not possible to set a new alarm \emph{within}
 another \kbd{alarm} code: the new timer erases the parent one.
 
-The library syntax is \fun{GEN}{gp_alarm}{long s , GEN code = NULL}.
+The library syntax is \fun{GEN}{gp_alarm}{long s, GEN code = NULL}.
 
 \subsec{alias$(\var{newsym},\var{sym})$}\kbdsidx{alias}\label{se:alias}
-Defines the symbol \var{newsym} as an alias for the the symbol \var{sym}:
+Defines the symbol \var{newsym} as an alias for the symbol \var{sym}:
 \bprog
 ? alias("det", "matdet");
 ? det([1,2;3,4])
@@ -21340,7 +21978,7 @@ The library syntax is \fun{GEN}{pareval}{GEN x}.
 \subsec{parfor$(i=a,\{b\},\var{expr1},\{r\},\{\var{expr2}\})$}\kbdsidx{parfor}\label{se:parfor}
 Evaluates in parallel the expression \kbd{expr1} in the formal
 argument $i$ running from $a$ to $b$.
-If $b$ is omitted, the loop runs indefinitely.
+If $b$ is set to \kbd{+oo}, the loop runs indefinitely.
 If $r$ and \kbd{expr2} are present, the expression \kbd{expr2} in the
 formal variables $r$ and $i$ is evaluated with $r$ running through all
 the different results obtained for \kbd{expr1} and $i$ takes the
@@ -21393,7 +22031,7 @@ Behaves exactly as \kbd{parfor}, but loops only over prime values $p$.
 Precisely, the functions evaluates in parallel the expression \kbd{expr1}
 in the formal
 argument $p$ running through the primes from $a$ to $b$.
-If $b$ is omitted, the loop runs indefinitely.
+If $b$ is set to \kbd{+oo}, the loop runs indefinitely.
 If $r$ and \kbd{expr2} are present, the expression \kbd{expr2} in the
 formal variables $r$ and $p$ is evaluated with $r$ running through all
 the different results obtained for \kbd{expr1} and $p$ takes the
@@ -21422,7 +22060,7 @@ parallel.  If \fl is $1$, return the indices of those elements (indirect
 selection) The function \kbd{f} must not access global variables or
 variables declared with local(), and must be free of side effects.
 
-The library syntax is \fun{GEN}{parselect}{GEN f, GEN A, long flag }.
+The library syntax is \fun{GEN}{parselect}{GEN f, GEN A, long flag}.
 
 \subsec{parsum$(i=a,b,\var{expr},\{x\})$}\kbdsidx{parsum}\label{se:parsum}
 Sum of expression \var{expr}, initialized at $x$, the formal parameter
@@ -21566,8 +22204,8 @@ The default value is \kbd{0} (no echo).
 
 \subsec{factor\_add\_primes}\kbdsidx{def,factor_add_primes}\label{se:def,factor_add_primes}
 This toggle is either 1 (on) or 0 (off). If on,
-the integer factorization machinery calls \tet{addprimes} on primes
-factor that were difficult to find (larger than $2^24$), so they are
+the integer factorization machinery calls \tet{addprimes} on prime
+factors that were difficult to find (larger than $2^{24}$), so they are
 automatically tried first in other factorizations. If a routine is performing
 (or has performed) a factorization and is interrupted by an error or via
 Control-C, this lets you recover the prime factors already found. The
diff --git a/doc/usersch4.tex b/doc/usersch4.tex
index a2a1d4c..de25ce1 100644
--- a/doc/usersch4.tex
+++ b/doc/usersch4.tex
@@ -1224,7 +1224,7 @@ even if \kbd{z} is not a real number.
 \kbd{z} is neither real nor integer (a rational number for instance).
 
 The real zero is characterized by having its sign equal to 0. If \kbd{z} is
-not equal to~0, then is is represented as $2^e M$, where $e$ is the exponent,
+not equal to~0, then it is represented as $2^e M$, where $e$ is the exponent,
 and $M\in [1, 2[$ is the mantissa of $z$, whose digits are stored in
 $\kbd{z[2]},\dots, \kbd{z[lg(z)-1]}$.
 
@@ -1366,8 +1366,8 @@ The components \kbd{z[2]}, \kbd{z[3]},\dots \kbd{z[lg(z)-1]} point to the
 coefficients of the polynomial \emph{in ascending order}, with \kbd{z[2]}
 being the constant term and so on.
 
-For a \typ{POL} of non-zero sign, \tet{degpol}, \tet{leading_term},
-\tet{constant_term}, return its degree, and a pointer to the leading,
+For a \typ{POL} of non-zero sign, \tet{degpol}, \tet{leading_coeff},
+\tet{constant_coeff}, return its degree, and a pointer to the leading,
 resp. constant, coefficient with respect to the main variable. Note that no
 copy is made on the PARI stack so the returned value is not safe for a basic
 \kbd{gerepile} call. Applied to any other type than \typ{POL}, the result is
diff --git a/doc/usersch5.tex b/doc/usersch5.tex
index d3cecce..0ebcdff 100644
--- a/doc/usersch5.tex
+++ b/doc/usersch5.tex
@@ -143,6 +143,16 @@ Reset the current stack to its default size \kbd{parisize},
 destroying its content. Used to recover memory after a
 computation that enlarged the stack.
 
+\fun{void}{paristack_newrsize}{ulong newsize}
+(do not return) library version of \kbd{default(parisize,"newsize")}.
+Set the default \kbd{parisize} to \kbd{newsize} (or double \kbd{parisize} if
+\kbd{newsize=0} and call \kbd{cb\_pari\_err\_recover(-1)}.
+
+\fun{void}{parivstack_resize}{ulong newsize}
+(do not return) library version of \kbd{default(parisizemax,"newsize")}.
+Set the default \kbd{parisizemax} to \kbd{newsize}
+and calls \kbd{cb\_pari\_err\_recover(-1)}.
+
 \subsec{Notions specific to the GP interpreter}
 
 An \kbd{entree} is the generic object associated to an identifier (a name)
@@ -738,6 +748,9 @@ or \typ{REAL}.
 \fun{int}{is_rational_t}{long t} \kbd{true} iff \kbd{t} is \typ{INT}
 or \typ{FRAC}.
 
+\fun{int}{is_real_t}{long t} \kbd{true} iff \kbd{t} is \typ{INT}
+or \typ{REAL} or \typ{FRAC}.
+
 \fun{int}{is_vec_t}{long t} \kbd{true} iff \kbd{t} is \typ{VEC}
 or \typ{COL}.
 
@@ -779,11 +792,11 @@ and otherwise of the \kbd{n}-th component of~\kbd{x}.
 \noindent On the contrary, the following routines return the address of a
 \kbd{GEN} component. No copy is made on the stack:
 
-\fun{GEN}{constant_term}{GEN x} returns the address of the constant
+\fun{GEN}{constant_coeff}{GEN x} returns the address of the constant
 coefficient of \typ{POL}~\kbd{x}. By convention, a $0$ polynomial (whose
 \kbd{sign} is $0$) has \kbd{gen\_0} constant term.
 
-\fun{GEN}{leading_term}{GEN x} returns the address of the leading coefficient
+\fun{GEN}{leading_coeff}{GEN x} returns the address of the leading coefficient
 of \typ{POL}~\kbd{x}, i.e. the coefficient of largest index stored in the
 array representing $x$. This may be an inexact $0$. By convention, return
 \kbd{gen\_0} if the coefficient array is empty.
@@ -1034,6 +1047,10 @@ constructor underlying \kbd{cgetg}, which calls \kbd{new\_chunk} then sets
 the first code word. It works by simply returning the address
 \kbd{((GEN)avma) - n}, after checking that it is larger than \kbd{(GEN)bot}.
 
+\fun{void}{new_chunk_resize}{size_t x} this function is called by
+\kbd{new\_chunk} when the PARI stack overflows. There is no need to call it
+manually. It will either extend the stack or report an \kbd{e\_STACK} error.
+
 \fun{char*}{stack_malloc}{size_t n} allocates memory on the stack for $n$
 chars (\emph{not} $n$ \kbd{GEN}s). This is faster than using \kbd{malloc},
 and easier to use in most situations when temporary storage is needed. In
@@ -1549,7 +1566,8 @@ can be efficiently evaluated using the \kbd{closure\_eval}$xxx$ functions.
 %
 \+& \kbd{f} &  Fake \kbd{*long}. C function requires a pointer but we
 do not use the resulting \kbd{long}\cr
-\+& \kbd{p} &  real precision (default \kbd{realprecision})\cr
+\+& \kbd{b} &  current real precision in bits \cr
+\+& \kbd{p} &  current real precision in words \cr
 \+& \kbd{P} &  series precision (default \kbd{seriesprecision},
  global variable \kbd{precdl} for the library)\cr
 \+& \kbd{C} &  lexical context (internal, for \kbd{eval},
@@ -1595,16 +1613,18 @@ special notations are available:
 \+&\kbd{D\&}& optional \kbd{*GEN}, send \kbd{NULL} if argument omitted.\cr
 \+&&\quad The argument must be prefixed by \kbd{\&}.\cr
 
-\+&\kbd{Dr}& optional raw string, send \kbd{NULL} if argument omitted.\cr
+\+&\kbd{DI}, \kbd{DE}& optional closure, send \kbd{NULL} if argument omitted.\cr
 
-\+&\kbd{Ds}& optional \kbd{char *}, send \kbd{NULL} if argument omitted.\cr
+\+&\kbd{DP}& optional \kbd{long}, send \kbd{precdl} if argument omitted.\cr
 
 \+&\kbd{DV}& optional \kbd{*entree}, send \kbd{NULL} if argument omitted.\cr
 
-\+&\kbd{DI}, \kbd{DE}& optional closure, send \kbd{NULL} if argument omitted.\cr
-
 \+&\kbd{Dn}& optional variable number, $-1$ if omitted.\cr
 
+\+&\kbd{Dr}& optional raw string, send \kbd{NULL} if argument omitted.\cr
+
+\+&\kbd{Ds}& optional \kbd{char *}, send \kbd{NULL} if argument omitted.\cr
+
 \misctitle{Hardcoded limit} C functions using more than 20 arguments are not
 supported. Use vectors if you really need that many parameters.
 
@@ -2228,18 +2248,19 @@ to $1$.
 Assumes that $\kbd{prec} > 2$.
 
 \fun{long}{itos}{GEN x} converts the \typ{INT}~\kbd{x} to a \kbd{long} if
-possible, otherwise raise an exception.
+possible, otherwise raise an exception. We consider the conversion
+to be possible if and only if $|x| \leq \kbd{LONG\_MAX}$, i.e. $|x| < 2^{63}$
+on a 64-bit architecture. Since the range is symetric, the output of
+\kbd{itos} can safely be negated.
 
 \fun{long}{itos_or_0}{GEN x} converts the \typ{INT}~\kbd{x} to a \kbd{long} if
 possible, otherwise return $0$.
 
-\fun{int}{is_bigint}{GEN n} true if \kbd{itos(n)} would succeed.
-
-\fun{int}{is_bigint_lg}{GEN n, long l} true if \kbd{itos(n)} would succeed.
-Assumes \kbd{lgefint(n)} is equal to \kbd{l}.
+\fun{int}{is_bigint}{GEN n} true if \kbd{itos(n)} would give an error.
 
 \fun{ulong}{itou}{GEN x} converts the \typ{INT}~\kbd{|x|} to an \kbd{ulong} if
-possible, otherwise raise an exception.
+possible, otherwise raise an exception. The conversion is possible if
+and only if $\kbd{lgefint}(x) \leq 3$.
 
 \fun{long}{itou_or_0}{GEN x} converts the \typ{INT}~\kbd{|x|} to an
 \kbd{ulong} if possible, otherwise return $0$.
@@ -2424,6 +2445,11 @@ proper \kbd{GEN}), return the integer $\sum_{i = 1}^l x[i] 2^{l-i}$, as a
 \fun{ulong}{bits_to_u}{GEN v, long l} same as \tet{bits_to_int}, where
 $l < \tet{BITS_IN_LONG}$, so we can return an \kbd{ulong}.
 
+\fun{GEN}{fromdigitsu}{GEN x, GEN B}
+given a \typ{VECSMALL} $x$ of length $l$ and a \typ{INT} $B$,
+return the integer $\sum_{i = 1}^l x[i] B^{i-1}$, as a \typ{INT},
+where the \kbd{x[i]} are seen as unsigned integers.
+
 \fun{GEN}{fromdigits_2k}{GEN x, long k} converse of \tet{binary_2k};
 given a \typ{VEC} $x$ of length $l$ and a positive \kbd{long} $k$,
 where each $x[i]$ is a \typ{INT} with $0\leq x[i] < 2^k$, return the
@@ -3347,6 +3373,9 @@ discriminant $D$ such that $d=D*f^2$ and set \kbd{*pt\_f} to $f$
 \fun{GEN}{divisorsu}{ulong n}, returns the divisors of $n$ in a
 \typ{VECSMALL}, sorted by increasing order.
 
+\fun{ulong}{divisorsu_fact}{GEN fa}, as \kbd{divisorsu(n)}
+where \kbd{fa} is \kbd{factoru(n)}.
+
 \fun{long}{omegau}{ulong n} returns the number of prime divisors of $n > 0$.
 
 \fun{long}{uissquarefree}{ulong n} returns $1$ if \kbd{n}
@@ -3361,6 +3390,9 @@ discriminant, and $0$ otherwise.
 \fun{long}{unegisfundamental}{ulong x} return $1$ if $-x$ is a fundamental
 discriminant, and $0$ otherwise.
 
+\fun{long}{sisfundamental}{long x} return $1$ if $x$ is a fundamental
+discriminant, and $0$ otherwise.
+
 \fun{int}{uis_357_power}{ulong x, ulong *pt, ulong *mask} as \tet{is_357_power}
 for \kbd{ulong} $x$.
 
@@ -3380,6 +3412,12 @@ compositeness test (it thus may be prime or composite), and $0$ otherwise
 \fun{GEN}{usumdivkvec}{ulong n, GEN K} $K$ being a \typ{VECSMALL} of
 positive integers. Returns the vector of \kbd{sumdivk}$(n, K[i])$.
 
+\fun{GEN}{usumdiv_fact}{GEN fa}, sum of divisors of \kbd{ulong} $n$, where
+\kbd{fa} is \kbd{factoru(n)}.
+
+\fun{GEN}{usumdivk_fact}{GEN fa, ulong k}, sum of $k$-th powers of divisors
+of \kbd{ulong} $n$, where \kbd{fa} is \kbd{factoru(n)}.
+
 \fun{GEN}{hilbertii}{GEN x, GEN y, GEN p}, returns the Hilbert symbol
 $(x,y)$ at the prime $p$ (\kbd{NULL} for the place at infinity); $x$ and $y$
 are \typ{INT}s.
@@ -3678,6 +3716,9 @@ $x$ and $y$ (assumed to have the same length).
 \fun{GEN}{FpV_dotsquare}{GEN x, GEN p} scalar product of $x$ with itself.
 has \typ{INT} entries.
 
+\fun{GEN}{FpV_factorback}{GEN L, GEN e, GEN p} given an \kbd{FpV} $L$
+and a \kbd{ZV} $e$ of the same length, return $\prod_i L_i^{e_i}$ modulo $p$.
+
 \subsubsec{\kbd{Fp}-linear algebra} The implementations are not
 asymptotically efficient ($O(n^3)$ standard algorithms).
 
@@ -3796,19 +3837,19 @@ pseudo inverse of $p$.
 \fun{void}{Flm_Fl_mul_inplace}{GEN x, ulong y, ulong p} replaces
 the \kbd{Flm} \kbd{x} by $\kbd{x}*\kbd{y}$.
 
-\fun{GEN}{Flc_Fl_mul}{GEN x, ulong y, ulong p} multiplies the \kbd{Flv}
+\fun{GEN}{Flv_Fl_mul}{GEN x, ulong y, ulong p} multiplies the \kbd{Flv}
 \kbd{x} by \kbd{y}.
 
-\fun{void}{Flc_Fl_mul_inplace}{GEN x, ulong y, ulong p} replaces
+\fun{void}{Flv_Fl_mul_inplace}{GEN x, ulong y, ulong p} replaces
 the \kbd{Flc} \kbd{x} by $\kbd{x}*\kbd{y}$.
 
-\fun{void}{Flc_Fl_mul_part_inplace}{GEN x, ulong y, ulong p, long l}
+\fun{void}{Flv_Fl_mul_part_inplace}{GEN x, ulong y, ulong p, long l}
 multiplies $x[1..l]$ by $y$ modulo $p$. In place.
 
-\fun{GEN}{Flc_Fl_div}{GEN x, ulong y, ulong p} divides the \kbd{Flv}
+\fun{GEN}{Flv_Fl_div}{GEN x, ulong y, ulong p} divides the \kbd{Flv}
 \kbd{x} by \kbd{y}.
 
-\fun{void}{Flc_Fl_div_inplace}{GEN x, ulong y, ulong p} replaces
+\fun{void}{Flv_Fl_div_inplace}{GEN x, ulong y, ulong p} replaces
 the \kbd{Flv} \kbd{x} by $\kbd{x}/\kbd{y}$.
 
 \fun{void}{Flc_lincomb1_inplace}{GEN X, GEN Y, ulong v, ulong q}
@@ -4000,6 +4041,9 @@ identity matrix.
 \fun{GEN}{zero_F2v}{long n} creates a \kbd{F2v} with \kbd{n} components set to
 $0$.
 
+\fun{GEN}{const_F2v}{long n} creates a \kbd{F2v} with \kbd{n} components set to
+$1$.
+
 \fun{GEN}{F2v_ei}{long n, long i} creates a \kbd{F2v} with \kbd{n} components
 set to $0$, but for the $i$-th one, which is set to $1$ ($i$-th vector in the
 canonical basis).
@@ -4012,7 +4056,7 @@ all columns.
 \fun{GEN}{zero_F2m_copy}{long m, long n} creates a \kbd{F2m} with \kbd{m} x
 \kbd{n} components set to $0$.
 
-\fun{GEN}{F2c_to_Flc}{GEN x}
+\fun{GEN}{F2v_to_Flv}{GEN x}
 
 \fun{GEN}{F2c_to_ZC}{GEN x}
 
@@ -4246,6 +4290,9 @@ work with any non-zero \typ{INT} but is not efficient in this case).
 \fun{GEN}{FpX_eval}{GEN x, GEN y, GEN p} evaluates the \kbd{FpX}~\kbd{x}
 at the \kbd{Fp}~\kbd{y}. The result is an~\kbd{Fp}.
 
+\fun{GEN}{FpX_FpV_multieval}{GEN P, GEN v, GEN p} returns the vector
+$[P(v[1]),\ldots,P(v[n])]$ as a \kbd{FpV}.
+
 \fun{GEN}{FpX_dotproduct}{GEN x, GEN y, GEN p} return the scalar product
 $\sum_{i\geq 0} x_i\*y_i$ of the coefficients of $x$ and $y$.
 
@@ -4265,11 +4312,22 @@ returns an \kbd{FpX}, congruent to \kbd{x} mod \kbd{Tx} and to \kbd{y} mod
 \kbd{Ty}. Assumes \kbd{Tx} and \kbd{Ty} are coprime, and \kbd{Tz = Tx * Ty}
 or \kbd{NULL} (in which case it is computed within).
 
-\fun{GEN}{FpV_polint}{GEN x, GEN y, GEN p} returns the \kbd{FpX}
+\fun{GEN}{FpV_polint}{GEN x, GEN y, GEN p, long v} returns the \kbd{FpX}
 interpolation polynomial with value \kbd{y[i]} at \kbd{x[i]}. Assumes lengths
 are the same, components are \typ{INT}s, and the \kbd{x[i]} are distinct
 modulo \kbd{p}.
 
+\fun{GEN}{FpV_FpM_polint}{GEN x, GEN V, GEN p, long v} equivalent (but
+faster) to applying \kbd{FpV\_polint(x,$\ldots$)} to all the elements of the
+vector $V$ (thus, returns a \kbd{FpXV}).
+
+\fun{GEN}{FpV_invVandermonde}{GEN L, GEN d, GEN p} $L$ being a \kbd{FpV}
+of length $n$, return the inverse $M$ of the Vandermonde matrix associated to
+the elements of $L$, eventually multiplied by \kbd{d} if it is not
+\kbd{NULL}. If $A$ is a \kbd{FpV} and $B=M\*A$, then the polynomial
+$P=\sum_{i=1}^n B[i]\*X^{i-1}$ verifies $P(L[i])=d\*A[i]$ for
+$1 \leq i \leq n$.
+
 \fun{int}{FpX_is_squarefree}{GEN f, GEN p} returns $1$ if the
 \kbd{FpX}~\kbd{f} is squarefree, $0$ otherwise.
 
@@ -4508,8 +4566,13 @@ Allow $T = \kbd{NULL}$ (discrete log over $\F_p$), otherwise
 assume that \kbd{T} is irreducible mod \kbd{p}.
 
 \fun{int}{Fq_issquare}{GEN x, GEN T, GEN p} returns $1$ if $x$ is a square
-and $0$ otherwise. Assumes that \kbd{T} is irreducible mod \kbd{p}. $T =
-\kbd{NULL}$ is forbidden unless $x$ is an \kbd{Fp}.
+and $0$ otherwise. Assumes that \kbd{T} is irreducible mod \kbd{p} and that
+$p$ is prime; $T = \kbd{NULL}$ is forbidden unless $x$ is an \kbd{Fp}.
+
+\fun{long}{Fq_ispower}{GEN x, GEN n, GEN T, GEN p} returns $1$ is $x$
+is a $n$-th power and $0$ otherwise. Assumes that \kbd{T} is irreducible mod
+\kbd{p} and that $p$ is prime; $T = \kbd{NULL}$ is forbidden unless $x$ is an
+\kbd{Fp}.
 
 \fun{GEN}{Fq_sqrt}{GEN x, GEN T, GEN p} returns a square root of \kbd{x}.
 Return \kbd{NULL} if \kbd{x} is not a square.
@@ -4621,6 +4684,9 @@ by the \kbd{Fp}~\kbd{y}.
 \fun{GEN}{FpXX_mulu}{GEN x, GEN y, GEN p} multiplies the \kbd{FpXX}~\kbd{x}
 by the scalar \kbd{y}.
 
+\fun{GEN}{FpXX_deriv}{GEN P, GEN p} differentiates \kbd{P} with respect of
+the main variable.
+
 \fun{GEN}{FpXY_eval}{GEN Q, GEN y, GEN x, GEN p} $Q$ being an \kbd{FpXY},
 i.e.~a \typ{POL} with \kbd{Fp} or \kbd{FpX} coefficients representing an
 element of $\F_p[X][Y]$. Returns the \kbd{Fp} $Q(x,y)$.
@@ -4682,6 +4748,8 @@ enforce strict consistency, which would not imply any efficiency gain.)
 returns $x\*y$ assuming the result is monic of the same degree as $x$ (in
 particular $y\neq 0$).
 
+\fun{GEN}{FpXQX_normalize}{GEN z, GEN T, GEN p}
+
 \fun{GEN}{FqX_normalize}{GEN z, GEN T, GEN p} divides the \kbd{FqX}~\kbd{z}
 by its leading term. The leading coefficient becomes $1$ as a \typ{INT}.
 
@@ -4768,6 +4836,8 @@ the \kbd{FpXQX} $y$, namely a lift of $1/\kbd{polrecip}(y)+O(x^{\deg(y)-1})$.
 
 \fun{GEN}{FpXQX_extgcd}{GEN x, GEN y, GEN T, GEN p, GEN *ptu, GEN *ptv}
 
+\fun{GEN}{FpXQX_halfgcd}{GEN x, GEN y, GEN T, GEN p}
+
 \fun{GEN}{FpXQX_FpXQXQ_eval}{GEN f,GEN x,GEN S, GEN T,GEN p} returns
 $\kbd{f}(\kbd{x})$.
 
@@ -4844,6 +4914,12 @@ $\sigma(Y)=a[2]\pmod{S(X,Y),T(X)}$, returns the vector
 $[\sigma^n(X),\sigma^n(Y),b\sigma(b)\ldots\sigma^{n-1}(b)]$
 where $b=a[3]$.
 
+\fun{GEN}{FpXQXQV_auttrace}{GEN a, long n, GEN S, GEN T, GEN p}
+$\sigma$ being the automorphism defined by $\sigma(X)=a[1]\pmod{T(X)}$,
+$\sigma(Y)=a[2]\pmod{S(X,Y),T(X)}$, returns the vector
+$[\sigma^n(X),\sigma^n(Y),b+\sigma(b)+\ldots+\sigma^{n-1}(b)]$
+where $b=a[3]$.
+
 % FqXQ
 
 \fun{GEN}{FqXQ_add}{GEN x, GEN y, GEN S, GEN T, GEN p}, \kbd{x}, \kbd{y} and
@@ -4889,13 +4965,21 @@ of degree $\kbd{n} > 0$ over $\F_p$, in variable \kbd{v}.
 
 \fun{int}{FqX_is_squarefree}{GEN P, GEN T, GEN p}
 
-\fun{GEN}{FqX_roots}{GEN x, GEN T, GEN p} return the roots of \kbd{x} in
+\fun{GEN}{FpXQX_roots}{GEN x, GEN T, GEN p} return the roots of \kbd{x} in
 $\F_p[X]/(T)$. Assumes \kbd{p} is prime and \kbd{T} irreducible in $\F_p[X]$.
 
-\fun{GEN}{FqX_factor}{GEN x, GEN T, GEN p} same output convention as
+\fun{GEN}{FqX_roots}{GEN x, GEN T, GEN p} same but allow $\kbd{T} = \kbd{NULL}$.
+
+\fun{GEN}{FpXQX_factor}{GEN x, GEN T, GEN p} same output convention as
 \kbd{FpX\_factor}. Assumes \kbd{p} is prime and \kbd{T} irreducible
 in $\F_p[X]$.
 
+\fun{GEN}{FqX_factor}{GEN x, GEN T, GEN p} same but allow $\kbd{T} = \kbd{NULL}$.
+
+\fun{long}{FqX_ispower}{GEN f, ulong k, GEN T, GEN p, GEN *pt} return
+returns 1 if \kbd{FqX} $f$ is a $K$-th power Return $0$
+otherwise. If \kbd{py} is not \kbd{NULL}, set it to $g$ such that $g^K = f$.
+
 \fun{GEN}{FpX_factorff}{GEN P, GEN T, GEN p}. Assumes \kbd{p} prime
 and \kbd{T} irreducible in $\F_p[X]$. Factor the \kbd{FpX} \kbd{P}
 over the finite field $\F_p[Y]/(T(Y))$. See \kbd{FpX\_factorff\_irred}
@@ -4956,7 +5040,7 @@ $A(X)^{(q-1)/2}\pmod{S(X)}$ over the finite field $\F_q$ defined by $T$
 and $p$, thus $q=p^n$ where $n$ is the degree of $T$.
 
 \subsec{\kbd{Flx}} Let \kbd{p} an understood \kbd{ulong}, assumed to be
-prime, to be given the the function arguments; an \kbd{Fl} is an \kbd{ulong}
+prime, to be given the function arguments; an \kbd{Fl} is an \kbd{ulong}
 belonging to $[0,\kbd{p}-1]$, an \kbd{Flx}~\kbd{z} is a \typ{VECSMALL}
 representing a polynomial with small integer coefficients. Specifically
 \kbd{z[0]} is the usual codeword, \kbd{z[1] = evalvarn($v$)} for some
@@ -5013,6 +5097,9 @@ and $y$ are equal, and 0~(false) otherwise.
 
 \fun{GEN}{Flx_sub}{GEN x, GEN y, ulong p}
 
+\fun{GEN}{Flx_halve}{GEN x, ulong p} returns $z$ such that $2\*z = x$ modulo
+$p$ assuming such $z$ exists.
+
 \fun{GEN}{Flx_mul}{GEN x, GEN y, ulong p}
 
 \fun{GEN}{Flx_Fl_mul}{GEN y, ulong x, ulong p}
@@ -5081,6 +5168,8 @@ $(X^n - 1, p)$. Shallow function.
 \fun{GEN}{Flx_factorff_irred}{GEN P, GEN Q, ulong p} as
 \tet{FpX_factorff_irred}.
 
+\fun{GEN}{Flx_rootsff}{GEN P, GEN T, ulong p} as \tet{FpX_rootsff}.
+
 \fun{GEN}{Flx_ffisom}{GEN P,GEN Q,ulong l} as \tet{FpX_ffisom}.
 
 \subsubsec{Miscellaneous operations}
@@ -5144,7 +5233,7 @@ assuming $pi$ is the pseudo inverse of $p$.
 the vector $[1,a,\dots,a^n]$, where $n$ is the degree of $P$, return $P(a)$,
 assuming $pi$ is the pseudo inverse of $p$.
 
-\fun{ulong}{Flx_Flv_multieval}{GEN P, GEN v, ulong y, ulong p} returns the vector
+\fun{GEN}{Flx_Flv_multieval}{GEN P, GEN v, ulong p} returns the vector
 $[P(v[1]),\ldots,P(v[n])]$ as a \kbd{Flv}.
 
 \fun{ulong}{Flx_dotproduct}{GEN x, GEN y, ulong p} returns the scalar product
@@ -5186,7 +5275,7 @@ as \kbd{FpX\_ffintersect}
 \fun{GEN}{Flv_polint}{GEN x, GEN y, ulong p, long sv} as \kbd{FpV\_polint},
 returning an \kbd{Flx} in variable $v$.
 
-\fun{GEN}{Flv_FlvV_polint}{GEN x, GEN V, ulong p, long sv} equivalent (but
+\fun{GEN}{Flv_Flm_polint}{GEN x, GEN V, ulong p, long sv} equivalent (but
 faster) to applying \kbd{Flv\_polint(x,$\ldots$)} to all the elements of the
 vector $V$ (thus, returns a \kbd{FlxV}).
 
@@ -5308,6 +5397,9 @@ its factorization.
 \fun{GEN}{polx_FlxX}{long vX, long sx} returns the variable $X$ as a
 degree~1~\typ{POL} with \kbd{Flx} coefficients in the variable $x$.
 
+\fun{long}{FlxY_degreex}{GEN P} return the degree of $P$ with respect to
+the secondary variable.
+
 \fun{GEN}{FlxX_add}{GEN P, GEN Q, ulong p}
 
 \fun{GEN}{FlxX_sub}{GEN P, GEN Q, ulong p}
@@ -5327,6 +5419,9 @@ degree~1~\typ{POL} with \kbd{Flx} coefficients in the variable $x$.
 \fun{GEN}{FlxY_Flx_div}{GEN x, GEN y, ulong p} divides the coefficients of $x$
 by $y$ using \kbd{Flx\_div}.
 
+\fun{GEN}{FlxX_deriv}{GEN P, ulong p} returns the derivative of \kbd{P} with
+respect to the main variable.
+
 \fun{GEN}{FlxY_evalx}{GEN P, ulong z, ulong p} $P$ being an \kbd{FlxY}, returns
 the \kbd{Flx} $P(z,Y)$, where $Y$ is the main variable of $P$.
 
@@ -5343,9 +5438,9 @@ $pi$ is the pseudo inverse of $p$.
 of $P$ in $X$ and \kbd{yp} being the vector $[1,y,\dots,y^m]$, where $m$ is larger or equal to the degree of $P$ in $Y$ return $P(x,y)$, assuming
 $pi$ is the pseudo inverse of $p$.
 
-\fun{GEN}{FlxY_Flxq_evalx}{GEN x, GEN y, ulong p} as \kbd{FpXY\_FpXQ\_evalx}.
+\fun{GEN}{FlxY_Flxq_evalx}{GEN x, GEN y, GEN T, ulong p} as \kbd{FpXY\_FpXQ\_evalx}.
 
-\fun{GEN}{FlxY_FlxqV_evalx}{GEN x, GEN y, ulong p} as \kbd{FpXY\_FpXQV\_evalx}.
+\fun{GEN}{FlxY_FlxqV_evalx}{GEN x, GEN V, GEN T, ulong p} as \kbd{FpXY\_FpXQV\_evalx}.
 
 \fun{GEN}{FlxX_renormalize}{GEN x, long l}, as \kbd{normalizepol}, where
 $\kbd{l} = \kbd{lg(x)}$, in place.
@@ -5416,7 +5511,7 @@ particular $U\neq 0$).
 
 \fun{GEN}{FlxqX_sqr}{GEN x, GEN T, ulong p}
 
-\fun{GEN}{FlxqX_pow}{GEN x, long n, GEN T, ulong p}
+\fun{GEN}{FlxqX_powu}{GEN x, ulong n, GEN T, ulong p}
 
 \fun{GEN}{FlxqX_divrem}{GEN x, GEN y, GEN T, ulong p, GEN *pr}
 
@@ -5431,8 +5526,9 @@ greatest common divisor of $x$  and $y$.
 
 \fun{GEN}{FlxqX_extgcd}{GEN x, GEN y, GEN T, ulong p, GEN *ptu, GEN *ptv}
 
-\fun{GEN}{FlxqXV_prod}{GEN V, GEN T, ulong p}
+\fun{GEN}{FlxqX_halfgcd}{GEN x, GEN y, GEN T, ulong p}, see \kbd{FpX\_halfgcd}.
 
+\fun{GEN}{FlxqXV_prod}{GEN V, GEN T, ulong p}
 
 \fun{GEN}{FlxqX_safegcd}{GEN P, GEN Q, GEN T, ulong p} Returns the \emph{monic}
 GCD of $P$ and $Q$ if Euclid's algorithm succeeds and \kbd{NULL} otherwise. In
@@ -5445,6 +5541,12 @@ occur).
 \fun{GEN}{FlxqXQ_halfFrobenius}{GEN A, GEN S, GEN T, GEN p}, as
 \kbd{FpXQXQ\_halfFrobenius}
 
+\fun{GEN}{F2xqX_roots}{GEN x, GEN T} return the roots of \kbd{x} in
+$\F_2[X]/(T)$. Assumes \kbd{T} irreducible in $\F_2[X]$.
+
+\fun{GEN}{FlxqX_roots}{GEN x, GEN T, ulong p} return the roots of \kbd{x} in
+$\F_p[X]/(T)$. Assumes \kbd{p} is prime and \kbd{T} irreducible in $\F_p[X]$.
+
 \fun{long}{FlxqX_nbroots}{GEN S, GEN T, GEN p}, as \kbd{FpX\_nbroots}.
 
 \fun{GEN}{FlxqX_FlxqXQ_eval}{GEN Q, GEN x, GEN S, GEN T, ulong p} as
@@ -5467,6 +5569,8 @@ occur).
 
 \fun{GEN}{FlxqXQ_pow}{GEN x, GEN n, GEN S, GEN T, ulong p}
 
+\fun{GEN}{FlxqXQ_powu}{GEN x, ulong n, GEN S, GEN T, ulong p}
+
 \fun{GEN}{FlxqXQ_powers}{GEN x, long n, GEN S, GEN T, ulong p}
 
 \fun{GEN}{FlxqXQ_matrix_pow}{GEN x, long n, long m, GEN S, GEN T, ulong p}
@@ -5494,6 +5598,8 @@ $0$.
 
 \fun{void}{F2x_set}{GEN x, long i} sets the coefficient $i\ge 0$ of $x$ to $1$.
 
+\fun{GEN}{F2x_copy}{GEN x}
+
 \fun{GEN}{Flx_to_F2x}{GEN x}
 
 \fun{GEN}{Z_to_F2x}{GEN x, long v}
@@ -5502,8 +5608,6 @@ $0$.
 
 \fun{GEN}{F2v_to_F2x}{GEN x, long sv}
 
-\fun{GEN}{ZXX_to_F2xX}{GEN x, long v}
-
 \fun{GEN}{F2x_to_Flx}{GEN x}
 
 \fun{GEN}{F2x_to_ZX}{GEN x}
@@ -5517,6 +5621,9 @@ $1$.
 
 \fun{GEN}{polx_F2x}{long sv} returns the variable $v$ as degree~1~\kbd{F2x}.
 
+\fun{GEN}{monomial_F2x}{long d, long sv} returns the \kbd{F2x}
+$X^d$ in variable $v$.
+
 \fun{GEN}{random_F2x}{long d, long sv} returns a random \kbd{F2x}
 in variable \kbd{v}, of degree less than~\kbd{d}.
 
@@ -5569,6 +5676,10 @@ and $0$ otherwise.
 \fun{GEN}{F2x_sqrt}{GEN x} returns the squareroot of $x$, assuming $x$ is a
 square of a \kbd{F2x}.
 
+\fun{GEN}{F2x_Frobenius}{GEN T}
+
+\fun{GEN}{F2x_matFrobenius}{GEN T}
+
 \fun{GEN}{F2x_factor}{GEN f}
 
 \subsec{\kbd{F2xq}} See \kbd{FpXQ} operations.
@@ -5637,6 +5748,88 @@ $a=\sigma(X)$ where $\sigma$ is an automorphism of the algebra $\F_2[X]/T(X)$.
 
 \fun{GEN}{matid_F2xqM}{long n, GEN T}
 
+\subsec{\kbd{F2xX}}. See \kbd{FpXX} operations.
+
+\fun{GEN}{ZXX_to_F2xX}{GEN x, long v}
+
+\fun{GEN}{FlxX_to_F2xX}{GEN x}
+
+\fun{GEN}{F2xX_to_ZXX}{GEN B}
+
+\fun{GEN}{F2xX_renormalize}{GEN x, long lx}
+
+\fun{long}{F2xY_degreex}{GEN P} return the degree of $P$ with respect to
+the secondary variable.
+
+\fun{GEN}{pol1_F2xX}{long v, long sv}
+
+\fun{GEN}{polx_F2xX}{long v, long sv}
+
+\fun{GEN}{F2xX_add}{GEN x, GEN y}
+
+\fun{GEN}{F2xX_F2x_mul}{GEN x, GEN y}
+
+\fun{GEN}{F2xX_deriv}{GEN P} returns the derivative of \kbd{P} with respect to
+the main variable.
+
+\fun{GEN}{Kronecker_to_F2xqX}{GEN z, GEN T}
+
+\fun{GEN}{F2xX_to_Kronecker}{GEN z, GEN T}
+
+\fun{GEN}{F2xY_F2xq_evalx}{GEN x, GEN y, GEN T} as \kbd{FpXY\_FpXQ\_evalx}.
+
+\fun{GEN}{F2xY_F2xqV_evalx}{GEN x, GEN V, GEN T} as \kbd{FpXY\_FpXQV\_evalx}.
+
+\subsec{\kbd{F2xqX}}. See \kbd{FlxqX} operations.
+
+\fun{GEN}{random_F2xqX}{long d, long v, GEN T, ulong p} returns a random
+\kbd{F2xqX} in variable \kbd{v}, of degree less than~\kbd{d}.
+
+\fun{GEN}{F2xqX_red}{GEN z, GEN T}
+
+\fun{GEN}{F2xqX_normalize}{GEN z, GEN T}
+
+\fun{GEN}{F2xqX_F2xq_mul}{GEN P, GEN U, GEN T}
+
+\fun{GEN}{F2xqX_F2xq_mul_to_monic}{GEN P, GEN U, GEN T}
+
+\fun{GEN}{F2xqX_mul}{GEN x, GEN y, GEN T}
+
+\fun{GEN}{F2xqX_sqr}{GEN x, GEN T}
+
+\fun{GEN}{F2xqX_rem}{GEN x, GEN y, GEN T}
+
+\fun{GEN}{F2xqX_div}{GEN x, GEN y, GEN T}
+
+\fun{GEN}{F2xqX_divrem}{GEN x, GEN y, GEN T, GEN *pr}
+
+\fun{GEN}{F2xqX_gcd}{GEN x, GEN y, GEN T}
+
+\fun{GEN}{F2xqX_F2xqXQ_eval}{GEN Q, GEN x, GEN S, GEN T} as
+\kbd{FpX\_FpXQ\_eval}.
+
+\fun{GEN}{F2xqX_F2xqXQV_eval}{GEN P, GEN V, GEN S, GEN T} as
+\kbd{FpX\_FpXQV\_eval}.
+
+\subsec{\kbd{F2xqXQ}}. See \kbd{FlxqXQ} operations.
+
+\fun{GEN}{F2xqXQ_mul}{GEN x, GEN y, GEN S, GEN T}
+
+\fun{GEN}{F2xqXQ_sqr}{GEN x, GEN S, GEN T}
+
+\fun{GEN}{F2xqXQ_pow}{GEN x, GEN n, GEN S, GEN T}
+
+\fun{GEN}{F2xqXQ_powers}{GEN x, long n, GEN S, GEN T}
+
+\fun{GEN}{F2xqXQV_autpow}{GEN a, long n, GEN S, GEN T}
+as \kbd{FpXQXQV\_autpow}
+
+\fun{GEN}{F2xqXQV_auttrace}{GEN a, long n, GEN S, GEN T}
+$\sigma$ being the automorphism defined by $\sigma(X)=a[1]\pmod{T(X)}$,
+$\sigma(Y)=a[2]\pmod{S(X,Y),T(X)}$, returns the vector
+$[\sigma^n(X),\sigma^n(Y),b+\sigma(b)+\ldots+\sigma^{n-1}(b)]$
+where $b=a[3]$.
+
 \subsec{Functions returning objects with \typ{INTMOD} coefficients}
 
 Those functions are mostly needed for interface reasons: \typ{INTMOD}s should
@@ -5877,7 +6070,11 @@ The functions is not stack clean if one coefficients of $M$ is negative
 \subsec{Zp}
 
 \fun{GEN}{Zp_sqrt}{GEN b, GEN p, long e} $b$ and $p$ being \typ{INT}s, with $p$
-a odd prime, returns a \typ{INT} $a$ such that $a^2 \equiv b \mod p^e$.
+a prime (possibly $2$), returns a \typ{INT} $a$ such that $a^2 \equiv b \mod
+p^e$.
+
+\fun{GEN}{Z2_sqrt}{GEN b, long e} $b$ being a \typ{INT}s
+returns a \typ{INT} $a$ such that $a^2 \equiv b \mod 2^e$.
 
 \fun{GEN}{Zp_sqrtlift}{GEN b, GEN a, GEN p, long e} let
 $a,b,p$ be \typ{INT}s, with $p > 1$ odd, such that $a^2\equiv b\mod p$.
@@ -5961,7 +6158,7 @@ $$ (f\Z_p[X] + g\Z_p[X])\cap \Z_p. $$
 Return the reduced resultant modulo $p^m$.
 
 \fun{GEN}{ZpX_reduced_resultant_fast}{GEN f, GEN g, GEN p, long M} $f$
-a monic \kbd{ZX}, $g$ a \kbd{ZX}, $p$ a prime. Returns the
+a monic \kbd{ZX}, $g$ a \kbd{ZX}, $p$ a prime. Returns
 the $p$-adic reduced resultant of $f$ and $g$ modulo $p^M$. This function
 computes resultants for a sequence of increasing $p$-adic accuracies
 (up to $M$ $p$-adic digits), returning as soon as it obtains a non-zero
@@ -5979,6 +6176,11 @@ $A\*b \equiv 1 \mod (p^e, T)$.  Special case of \tet{ZpXQ_liftroot}.
 $p$ be a prime \typ{INT} and $b$ be a \kbd{FpXQ} (modulo $T, p^e$).
 Returns an \kbd{FpXQ} $A$ such that $A\*b \equiv 1 \mod (p^e, T)$.
 
+\fun{GEN}{ZpXQ_div}{GEN a, GEN b, GEN T, GEN q, GEN p, long e} let
+$p$ be a prime \typ{INT} and $a$ and $b$ be a \kbd{FpXQ} (modulo $T, p^e$).
+Returns an \kbd{FpXQ} $c$ such that $c\*b \equiv a \mod (p^e, T)$.
+The parameter $q$ must be equal to $p^e$.
+
 \fun{GEN}{ZpXQ_sqrtnlift}{GEN b, GEN n, GEN a, GEN T, GEN p, long e} let
 $n,p$ be \typ{INT}s, with $n,p > 1$ and $p$ coprime to $n$, and $a,b$
 be \kbd{FpXQ}s (modulo $T$) such that $a^n \equiv b \mod (p,T)$.
@@ -6022,6 +6224,12 @@ returns the foots of $f$ as \tet{ZpXQX_liftroot}, where $v$ is the valuation
 of the content of $f'$ and it is required that $v_p(f(a))>v$ and
 $v_p(f'(a))=v$.
 
+\fun{GEN}{ZpXQX_divrem}{GEN x, GEN Sp, GEN T, GEN q, GEN p, long e, GEN *pr}
+As \kbd{FpXQX\_divrem}. The parameter $q$ must be equal to $p^e$.
+
+\fun{GEN}{ZpXQX_digits}{GEN x, GEN B, GEN T, GEN q, GEN p, long e}
+As \kbd{FpXQX\_digits}. The parameter $q$ must be equal to $p^e$.
+
 \subsec{Other $p$-adic functions}
 
 \fun{GEN}{ZpM_echelon}{GEN M, long early_abort, GEN p, GEN pm} given a
@@ -6168,7 +6376,7 @@ repeatedly called on the vector's coefficients.
 \fun{GEN}{ZXXT_to_FlxXT}{GEN V, ulong p, long v}, as \kbd{ZXX\_to\_FlxX},
 repeatedly called on the tree leaves.
 
-\fun{GEN}{RgC_to_Flc}{GEN x, ulong p} reduce the \typ{VEC}/\typ{COL}
+\fun{GEN}{RgV_to_Flv}{GEN x, ulong p} reduce the \typ{VEC}/\typ{COL}
 $x$ modulo $p$, yielding a \typ{VECSMALL}.
 
 \fun{GEN}{RgM_to_Flm}{GEN x, ulong p} reduce the \typ{MAT} $x$ modulo $p$.
@@ -6206,8 +6414,15 @@ to coefficient in Flx.
 \fun{GEN}{FlxX_to_ZXX}{GEN B}, converts an \kbd{FlxX} to a polynomial with
 \kbd{ZX} or \typ{INT} coefficients (repeated calls to \kbd{Flx\_to\_ZX}).
 
+\fun{GEN}{FlxXC_to_ZXXC}{GEN B}, converts an \kbd{FlxXC} to a \typ{COL} with
+\kbd{ZXX} coefficients (repeated calls to \kbd{FlxX\_to\_ZXX}).
+
+\fun{GEN}{FlxXM_to_ZXXM}{GEN B}, converts an \kbd{FlxXM} to a \typ{MAT} with
+\kbd{ZXX} coefficients (repeated calls to \kbd{FlxX\_to\_ZXX}).
+
 \fun{GEN}{FlxC_to_ZXC}{GEN x}, converts a vector of \kbd{Flx} to a column
 vector of polynomials with \typ{INT} coefficients (repeated calls to
+
 \kbd{Flx\_to\_ZX}).
 
 \fun{GEN}{FlxV_to_ZXV}{GEN x}, as above but return a \typ{VEC}.
@@ -6280,8 +6495,9 @@ Multiply a multiprecision object by a single-precision one.
 scalar \kbd{Flx}. Assume that \kbd{evx = evalvarn(vx)} for some variable
 number \kbd{vx}.
 
-\fun{GEN}{Z_to_Flx}{GEN x, ulong p, long v} converts a \typ{INT} to a scalar
-polynomial in variable $v$.
+\fun{GEN}{Z_to_Flx}{GEN x, ulong p, long sv} converts a \typ{INT} to a scalar
+\kbd{Flx} polynomial. Assume that \kbd{sv = evalvarn(v)} for some variable
+number \kbd{v}.
 
 \fun{GEN}{Flx_to_Flv}{GEN x, long n} converts from \kbd{Flx} to \kbd{Flv}
 with \kbd{n} components (assumed larger than the number of coefficients of
@@ -6329,6 +6545,10 @@ with \kbd{n} components (assumed larger than the number of coefficients of
 vector of polynomials with \typ{INT} coefficients (repeated calls to
 \kbd{F2x\_to\_ZX}).
 
+\fun{GEN}{F2xC_to_FlxC}{GEN x}
+
+\fun{GEN}{FlxC_to_F2xC}{GEN x}
+
 \fun{GEN}{F2xV_to_F2m}{GEN v, long n} \kbd{F2x\_to\_F2v} to each polynomial
 to get an \kbd{F2m} with \kbd{n} rows.
 
@@ -8017,10 +8237,13 @@ $P$, i.e. $X^{\deg P} P(1/X)$.
 form $Q(X^d)$, return $Q$. Shallow function, not suitable for
 \kbd{gerepileupto}.
 
+\fun{long}{RgX_deflate_order}{GEN P} given a non-constant polynomial
+$P$, returns the largest exponent $d$ such that $P$ is of the form $P(x^d)$
+(use \kbd{gequal0} to check whether coefficients are 0).
+
 \fun{long}{RgX_deflate_max}{GEN P, long *d} given a non-constant polynomial
-$P$, sets \kbd{d} to the largest exponent such that $P$ is of the form
-$P(x^d)$ (use \kbd{gequal0} to check whether coefficients are 0). Returns
-\kbd{RgX\_deflate(P,d)}. Shallow function.
+$P$, sets \kbd{d} to \kbd{RgX\_deflate\_order(P)} and
+returns \kbd{RgX\_deflate(P,d)}. Shallow function.
 
 \fun{GEN}{RgX_inflate}{GEN P, long d} return $P(X^d)$. Shallow function, not
 suitable for \kbd{gerepileupto}.
@@ -8261,13 +8484,19 @@ Karatsuba algorithm (Mulders, Hanrot-Zimmermann variant).
 where $a$ is a \typ{POL} in the variable $X$ and $n \geq 0$. Uses
 Karatsuba algorithm (Mulders, Hanrot-Zimmermann variant).
 
-\fun{GEN}{RgXn_inv}{GEN a, long n} returns $a^-1$ modulo $X^n$,
+\fun{GEN}{RgXn_inv}{GEN a, long n} returns $a^{-1}$ modulo $X^n$,
 where $a$ is a \typ{POL} in the variable $X$ and $n \geq 0$. Uses
 Newton-Raphson algorithm.
 
 \fun{GEN}{RgXn_powers}{GEN x, long m, long n} returns $[\kbd{x}^0,
 \dots, \kbd{x}^\kbd{m}]$ modulo $X^n$ as a \typ{VEC} of \kbd{RgXn}s.
 
+\fun{GEN}{RgXn_powu}{GEN x, ulong m, long n} returns $x^m$ modulo
+$X^n$.
+
+\fun{GEN}{RgXn_powu_i}{GEN x, ulong m, long n} as \tet{RgXn_powu},
+not memory clean.
+
 \fun{GEN}{RgXn_exp}{GEN a, long n} returns $exp(a)$ modulo $X^n$, assuming
 $a = 0 \mod{X}$. Uses Hanrot-Zimmermann algorithm.
 
@@ -9392,6 +9621,9 @@ Here are a few basic comparison functions, to be used with \kbd{cmp\_nodata}:
 \fun{int}{ZV_cmp}{GEN x, GEN y} compare two \kbd{ZV}, which we assume have
 the same length (lexicographic order).
 
+\fun{int}{cmp_Flx}{GEN x, GEN y} compare two \kbd{Flx}, which we assume
+have the same main variable (lexicographic order).
+
 \fun{int}{cmp_RgX}{GEN x, GEN y} compare two polynomials, which we assume
 have the same main variable (lexicographic order). The coefficients are
 compared using \kbd{gcmp}.
@@ -9427,7 +9659,8 @@ vector whose components are the true Euclidean quotient and remainder
 of \kbd{x} and~\kbd{y}.
 
 \fun{GEN}{gdivent[z]}{GEN x, GEN y[, GEN z]} yields the true Euclidean
-quotient of \kbd{x} and the \typ{INT} or \typ{POL}~\kbd{y}.
+quotient of \kbd{x} and the \typ{INT} or \typ{POL}~\kbd{y}, as per
+the \kbd{\bs} GP operator.
 
 \fun{GEN}{gdiventsg}{long s, GEN y[, GEN z]}, as \kbd{gdivent}
 except that \kbd{x} is a \kbd{long}.
@@ -9436,10 +9669,10 @@ except that \kbd{x} is a \kbd{long}.
 except that \kbd{y} is a \kbd{long}.
 
 \fun{GEN}{gmod[z]}{GEN x, GEN y[, GEN z]} yields the remainder of \kbd{x}
-modulo the \typ{INT} or \typ{POL}~\kbd{y}. A \typ{REAL} or \typ{FRAC} \kbd{y}
-is also allowed, in which case the remainder is the unique real $r$ such that
-$0 \leq r < |\kbd{y}|$ and $\kbd{y} = q\kbd{x} + r$ for some (in fact unique)
-integer $q$.
+modulo the \typ{INT} or \typ{POL}~\kbd{y}, as per the \kbd{\%} GP operator.
+A \typ{REAL} or \typ{FRAC} \kbd{y} is also allowed, in which case the
+remainder is the unique real $r$ such that $0 \leq r < |\kbd{y}|$ and
+$\kbd{y} = q\kbd{x} + r$ for some (in fact unique) integer $q$.
 
 \fun{GEN}{gmodsg}{long s, GEN y[, GEN z]} as \kbd{gmod}, except \kbd{x} is
 a \kbd{long}.
@@ -9469,9 +9702,10 @@ scalars, treated as polynomials of degree $0$.
 \kbd{y} may also be scalars, treated as polynomials of degree $0$.
 
 
-\fun{GEN}{gdivround}{GEN x, GEN y} if \kbd{x} and \kbd{y} are \typ{INT},
-as \kbd{diviiround}. Operate componentwise if \kbd{x} is
-a \typ{COL}, \typ{VEC} or \typ{MAT}. Otherwise as \key{gdivent}.
+\fun{GEN}{gdivround}{GEN x, GEN y} if \kbd{x} and \kbd{y} are real
+(\typ{INT}, \typ{REAL}, \typ{FRAC}), return the rounded Euclidean quotient of
+$x$ and $y$ as per the \kbd{\bs/} GP operator. Operate componentwise if
+\kbd{x} is a \typ{COL}, \typ{VEC} or \typ{MAT}. Otherwise as \key{gdivent}.
 
 \fun{GEN}{centermod_i}{GEN x, GEN y, GEN y2}, as \kbd{centermodii},
 componentwise.
@@ -9778,7 +10012,7 @@ root computation can be skipped.
 
 \fun{GEN}{gnorml1}{GEN x, long prec} The norm of a scalar is its complex
 modulus, the norm of a recursive type is the sum of the norms of its components.
-For polynomials, vectors or matrices of complex numbers one recovers the
+For polynomials, vectors or matrices of complex numbers one recovers
 the usual $L^1$ norm. One must include a real precision \kbd{prec} in case
 the inputs include \typ{COMPLEX} or \typ{QUAD} with exact rational components:
 a square root must be computed and we must choose an accuracy.
@@ -9834,9 +10068,6 @@ square matrix $x$.
 the evaluation $\kbd{f}(\kbd{x})$, assuming that \kbd{V} was computed by
 $\kbd{FpXQ\_powers}(\kbd{x}, n)$ for some $n>1$.
 
-\fun{GEN}{RgX_RgM_eval_col}{GEN q, GEN x, long c} evaluates the \typ{POL} $q$
-at the square matrix $x$ but only returns the \kbd{c}-th column of the result.
-
 \fun{GEN}{qfeval}{GEN q, GEN x} evaluates the quadratic form
 $q$ (symmetric matrix) at $x$ (column vector of compatible dimensions).
 
@@ -9866,6 +10097,15 @@ copy of $|x|$, in particular returns $x$ itself when $x \geq 0$, and
 
 \fun{GEN}{sqrfrac}{GEN x} returns the square of the \typ{FRAC} $x$.
 
+\section{Real numbers}
+
+\fun{GEN}{R_abs}{GEN x} $x$ being a \typ{INT}, a \typ{REAL} or a
+\typ{FRAC}, returns $|x|$.
+
+\fun{GEN}{R_abs_shallow}{GEN x} $x$ being a \typ{INT}, a \typ{REAL} or a
+\typ{FRAC}, returns a shallow copy of $|x|$, in particular returns $x$ itself
+when $x \geq 0$, and \kbd{gneg($x$)} otherwise.
+
 \section{Complex numbers}
 
 \fun{GEN}{imag}{GEN x} returns a copy of the imaginary part of \kbd{x}.
@@ -10044,6 +10284,16 @@ finite field $\F_p/(T)$, where $T$ is a \kbd{ZX}, assumed to be irreducible
 modulo $p$, or \kbd{NULL} in which case the routine acts as \tet{p_to_FF(p,0)}.
 No checks.
 
+\fun{GEN}{Fq_to_FF}{GEN x, GEN ff} returns a \typ{FFELT} equal to $x$
+in the finite field defined by the \typ{FFELT} \kbd{ff}, where
+$x$ is an \kbd{Fq} (either a \typ{INT} or a \kbd{ZX}: a \typ{POL} with
+\typ{INT} coefficients). No checks.
+
+\fun{GEN}{FqX_to_FFX}{GEN x, GEN ff} given an \kbd{FqX} $x$,
+return the polynomial with \typ{FFELT} coefficients obtained by
+applying \tet{Fq_to_FF} coefficientwise. No checks, and no normalization
+if the leading coefficient maps to $0$.
+
 \fun{GEN}{FF_1}{GEN a} returns the unity in the definition field of the
 \typ{FFELT} element \kbd{a}.
 
@@ -10275,6 +10525,9 @@ of $\zeta(aj + b)$, $j = 0, 1, \dots, N-1$, where $a$ and $b$ are real
 numbers (of arbitrary type, although \typ{INT} is treated more efficiently)
 and $b > 1$.
 
+\fun{GEN}{ggamma1m1}{GEN x, long prec} return $\Gamma(1+x) - 1$ assuming
+$|x| < 1$. Guard against cancellation when $x$ is small.
+
 \noindent A few variants on sin and cos:
 
 \fun{void}{mpsincos}{GEN x, GEN *s, GEN *c} sets $s$ and $c$ to
@@ -10493,7 +10746,7 @@ to $i$.
 \fun{long}{group_order}{GEN grp} returns the order of the small group
 \var{grp} (which is the product of the relative orders).
 
-\fun{long}{group_isabelian}{GEN grp} returns $1$ the the small group
+\fun{long}{group_isabelian}{GEN grp} returns $1$ if the small group
 \var{grp} is Abelian, else $0$.
 
 \fun{GEN}{group_abelianHNF}{GEN grp, GEN elts} if \var{grp} is not Abelian,
@@ -10513,15 +10766,15 @@ small group $G$, returns $1$ if $H$ is normal in $G$, else $0$.
 $0$ else. This is mainly to deal with the idiosyncrasy of the format.
 
 \fun{GEN}{group_leftcoset}{GEN G, GEN g} where $G$ is a small group and $g$ a
-permutation of the same domain, the the left coset $gG$ as a vector of
+permutation of the same domain, the left coset $gG$ as a vector of
 permutations.
 
 \fun{GEN}{group_rightcoset}{GEN G, GEN g} where $G$ is a small group and $g$ a
-permutation of the same domain, the the right coset $Gg$  as a vector of
+permutation of the same domain, the right coset $Gg$  as a vector of
 permutations.
 
 \fun{long}{group_perm_normalize}{GEN G, GEN g} where $G$ is a small group and
-$g$ a permutation of the same domain, return $1$ if $gGg^-1=G$, else $0$.
+$g$ a permutation of the same domain, return $1$ if $gGg^{-1}=G$, else $0$.
 
 \fun{GEN}{group_quotient}{GEN G, GEN H}, where $G$ is a small group and
 $H$ is a subgroup of $G$, returns the quotient map $G\rightarrow G/H$
@@ -10601,10 +10854,13 @@ string.
 significant digits to print), converts $x$ to a malloc'ed string. Simple
 variant of \tet{pari_sprintf}.
 
-\fun{char*}{GENtostr_unquoted}{GEN x} as \tet{GENtostr} with the following
-differences: 1) a \typ{STR} $x$ is printed without enclosing quotes
-(to be used by \kbd{print}); 2) the result is allocated on the stack
-and \emph{must not} be freed.
+\fun{char*}{GENtostr_raw}{GEN x} as \tet{GENtostr} with the following
+differences: 1) the output format is \tet{f_RAW}; 2) the result is allocated
+on the stack and \emph{must not} be freed.
+
+\fun{char*}{GENtostr_unquoted}{GEN x} as \tet{GENtostr_raw} with the following
+additional difference: a \typ{STR} $x$ is printed without enclosing quotes
+(to be used by \kbd{print}.
 
 \fun{char*}{GENtoTeXstr}{GEN x}, as \kbd{GENtostr}, except that
 \tet{f_TEX} overrides the output format from \kbd{GP\_DATA->fmt}.
@@ -10844,7 +11100,7 @@ a symbolic link exists, regardless of where it points to.
 
 \subsec{Temporary files}
 
-PARI has its own idea of the system temp directory derived from from an
+PARI has its own idea of the system temp directory derived from an
 environment variable (\kbd{\$GPTMPDIR}, else \kbd{\$TMPDIR}), or the first
 writable directory among \kbd{/tmp}, \kbd{/var/tmp} and \kbd{.}.
 
diff --git a/doc/usersch6.tex b/doc/usersch6.tex
index 0fd28fc..87e74cd 100644
--- a/doc/usersch6.tex
+++ b/doc/usersch6.tex
@@ -1271,6 +1271,7 @@ the $T_2$ quadratic form as returned by \tet{nf_get_Gtwist}, and we return
 a small element $a$ in the lattice $(x,T_2)$. This is used to implement
 \tet{idealred}.
 
+
 \fun{GEN}{idealpseudomin_nonscalar}{GEN x, GEN G}. As \tet{idealpseudomin},
 but we insist of returning a non-scalar $a$ (\kbd{ZV\_isscalar} is false), if
 the dimension of $x$ is $> 1$.
@@ -1278,6 +1279,10 @@ the dimension of $x$ is $> 1$.
 In the interpretation where $x$ defines an integral ideal on a fixed $\Z_K$
 basis whose first element is $1$, this means that $a$ is not rational.
 
+\fun{GEN}{idealpseudored}{GEN x, GEN G}. As \tet{idealpseudomin} but we
+return the full reduced $\Z$-basis of $x$ as a \typ{MAT} instead of a single
+vector.
+
 \fun{GEN}{idealred_elt}{GEN nf, GEN x} shortcut for
 \bprog
   idealpseudomin(x, nf_get_roundG(nf))
@@ -1747,7 +1752,7 @@ Pollig-Hellman algorithm, then either Shanks (small $o$) or Pollard rho
 discrete log functions, the preferred format being \kbd{[ord, fa]}
 (\typ{INT} and its factorization).
 
-\fun{GEN}{qfi_Shanks}{GEN a, GEN g, long n} given given a \typ{QFI} $a$ and
+\fun{GEN}{qfi_Shanks}{GEN a, GEN g, long n} given a \typ{QFI} $a$ and
 assuming that the \typ{QFI} $g$ has (small) order $n$, compute an integer $k$
 such that $a^k = g$. Return \kbd{cgetg(1, t\_VEC)} if there are no solutions.
 Directly uses Shanks algorithm, which is inefficient when $n$ is composite.
@@ -2481,7 +2486,7 @@ basis elements; used by \kbd{algtrace}.
 
 \fun{void}{checkhasse}{GEN nf, GEN hi, GEN hf, long n}
 
-\fun{long}{cyclicrelfrob}{GEN rnf, GEN nf2, GEN auts, GEN pr}
+\fun{long}{cyclicrelfrob}{GEN rnf, GEN auts, GEN pr}
 
 \fun{GEN}{hassecoprime}{GEN hi, GEN hf, long n}
 
@@ -2489,7 +2494,7 @@ basis elements; used by \kbd{algtrace}.
 
 \fun{GEN}{hassewedderburn}{GEN hi, GEN hf, long n}
 
-\fun{long}{localhasse}{GEN rnf, GEN nf2, GEN cnd, GEN pl, GEN auts, GEN b, long k}
+\fun{long}{localhasse}{GEN rnf, GEN cnd, GEN pl, GEN auts, GEN b, long k}
 
 \fun{GEN}{nfgwkummer}{GEN nf, GEN Lpr, GEN Ld, GEN pl, long var}
 
diff --git a/doc/usersch7.tex b/doc/usersch7.tex
index f1a6741..04762ea 100644
--- a/doc/usersch7.tex
+++ b/doc/usersch7.tex
@@ -221,6 +221,8 @@ reduction (Tate curves):
 
 \fun{GEN}{ellQp_ab}{GEN E, long prec} returns $[a,b]$.
 
+\fun{GEN}{ellQp_L}{GEN E, long prec} returns the ${\cal L}$-invariant $L$.
+
 \fun{GEN}{ellQp_root}{GEN E, long prec} returns $e_1$.
 
 \subsubsec{Curves over a finite field $\F_q$}
diff --git a/doc/usersch8.tex b/doc/usersch8.tex
index 8e3d5bb..8ae26e7 100644
--- a/doc/usersch8.tex
+++ b/doc/usersch8.tex
@@ -92,75 +92,36 @@
 
 \section{Variants of GP functions}
 
-\fun{GEN}{lfun}{GEN ldata, GEN s, long prec}
-
-\fun{GEN}{lfun_bitprec}{GEN ldata, GEN s, long bitprec}
-
-\fun{GEN}{lfun0_bitprec}{GEN ldata, GEN s, long der, long bitprec}
-
-\fun{long}{lfuncheckfeq_bitprec}{GEN data, GEN t0, long bitprec}
-
-\fun{GEN}{lfunhardy_bitprec}{GEN ldata, GEN t, long bitprec}
-
-\fun{GEN}{lfuninit_bitprec}{GEN ldata, GEN dom, long der, long bitprec}
+\fun{GEN}{lfun}{GEN ldata, GEN s, long bitprec}
 
 \fun{GEN}{lfuninit}{GEN ldata, GEN dom, long der, long bitprec}
 
-\fun{GEN}{lfuninit0_bitprec}{GEN ldata, GEN dom, long der, long bitprec}
-
 \fun{GEN}{lfuninit_make}{long t, GEN ldata, GEN molin, GEN domain}
 
-\fun{GEN}{lfunlambda}{GEN ldata, GEN s, long prec}
-
-\fun{GEN}{lfunlambda_bitprec}{GEN ldata, GEN s, long bitprec}
-
-\fun{GEN}{lfunlambda0_bitprec}{GEN ldata, GEN s, long der, long bitprec}
-
-\fun{long}{lfunorderzero_bitprec}{GEN ldata, long bitprec}
-
-\fun{GEN}{lfunrootno}{GEN data, long prec}
-
-\fun{GEN}{lfunrootno_bitprec}{GEN data, long bitprec}
-
-\fun{GEN}{lfunrootres_bitprec}{GEN data, long bitprec}
-
-\fun{GEN}{lfuntheta_bitprec}{GEN data, GEN t, long m, long bitprec}
-
-\fun{GEN}{lfunthetainit_bitprec}{GEN ldata, GEN tdom, long m, long bitprec}
+\fun{GEN}{lfunlambda}{GEN ldata, GEN s, long bitprec}
 
 \fun{long}{lfunthetacost}{GEN ldata, GEN tdom, long m, long bitprec}:
  \kbd{lfunthetacost0} when the first argument is known to be an \kbd{Ldata}.
 
-
 \fun{GEN}{lfunthetacheckinit}{GEN data, GEN tinf, long m, long *ptbitprec, long fl}
 
-\fun{GEN}{lfunzeros_bitprec}{GEN ldata, GEN lim, long divz, long bitprec}
+\fun{GEN}{lfunrootno}{GEN data, long bitprec}
 
-\fun{GEN}{lfunabelianrelinit_bitprec}{GEN bnfabs, GEN bnf, GEN polrel, GEN dom, long der, long bitprec}
+\fun{GEN}{lfunzetakinit}{GEN pol, GEN dom, long der, long flag, long bitprec}
 
-\fun{GEN}{lfunzetakinit}{GEN pol, GEN dom, long der, long flag, long prec}
+\fun{GEN}{lfunellmfpeters}{GEN E, long bitprec}
 
-\fun{GEN}{lfunzetakinit_bitprec}{GEN pol, GEN dom, long der, long flag, long bitprec}
+\fun{GEN}{ellanalyticrank}{GEN E, long prec} DEPRECATED.
 
-\fun{GEN}{lfunmfpeters_bitprec}{GEN ldata, long bitprec}
-
-\fun{GEN}{lfunellmfpeters_bitprec}{GEN E, long bitprec}
-
-\fun{GEN}{ellanalyticrank_bitprec}{GEN E, long bitprec}
-
-\fun{GEN}{ellL1_bitprec}{GEN E, long bitprec}
-
-\fun{GEN}{ellmoddegree_bitprec}{GEN E, long bitprec}
+\fun{GEN}{ellL1}{GEN E, long prec} DEPRECATED.
 
 \section{Inverse Mellin transforms of Gamma products}
 
-\fun{GEN}{gammamellininv_bitprec}{GEN Vga, GEN s, long m, long bitprec}
-
-\fun{GEN}{gammamellininvinit_bitprec}{GEN Vga, long m, long bitprec}
+\fun{GEN}{gammamellininv}{GEN Vga, GEN s, long m, long bitprec}
 
-\fun{GEN}{gammamellininvrt}{GEN K, GEN x, long prec}
+\fun{GEN}{gammamellininvinit}{GEN Vga, long m, long bitprec}
 
-\fun{GEN}{gammamellininvrt_bitprec}{GEN K, GEN s, long bitprec}
+\fun{GEN}{gammamellininvrt}{GEN K, GEN s, long bitprec}
 
 \fun{double}{dbllambertW0}{double a}
 
diff --git a/misc/xgp b/misc/xgp
old mode 100644
new mode 100755
index 640e394..309296f
--- a/misc/xgp
+++ b/misc/xgp
@@ -1,12 +1,20 @@
 #!/bin/sh
 #
 # A simple-minded script to launch gp in an xterm. The application name is
-# set to "gp". You can use it to have specific X resources, to tell your
-# window manager to use the icon pari.xbm, etc.
+# set to "gp". You can use it to have specific X resources for the xterm, or
+# tell your window manager specific preferences, etc.
 #
-# set correct paths below
+# iconHint resource is in xterm post Oct 2012.  Earlier xterm should ignore.
+# xterm will seek pari-gp.xpm in current directory (not good but normally
+# harmless) and xterm's configured system location like /usr/share/pixmaps.
+# If GP is installed somewhere different than xterm then a full path could
+# be used.  If missing then xterm quietly uses its default icon.
+#
+# set correct paths if necessary
 xterm="xterm"
-gp="/usr/local/bin/gp"
+gp="gp"
 
 $xterm -geometry 80x40 -sl 2000 -sb \
-       -name gp -title PARI/GP -rw -e $gp &
+       -name gp -title PARI/GP -rw \
+       -xrm XTerm.iconHint:pari-gp \
+       -e $gp &
diff --git a/src/basemath/F2x.c b/src/basemath/F2x.c
index 90d4d59..169d7f8 100644
--- a/src/basemath/F2x.c
+++ b/src/basemath/F2x.c
@@ -47,6 +47,16 @@ F2x_degree(GEN x)
 }
 
 GEN
+monomial_F2x(long d, long vs)
+{
+  long l=nbits2lg(d+1);
+  GEN z = zero_zv(l-1);
+  z[1] = vs;
+  F2x_set(z,d);
+  return z;
+}
+
+GEN
 F2x_to_ZX(GEN x)
 {
   long l=3+F2x_degree(x);
@@ -60,15 +70,6 @@ F2x_to_ZX(GEN x)
 }
 
 GEN
-F2xC_to_ZXC(GEN v)
-{
-  long j, N = lg(v);
-  GEN y = cgetg(N, t_COL);
-  for (j=1; j<N; j++) gel(y,j) = F2x_to_ZX(gel(v,j));
-  return y;
-}
-
-GEN
 F2x_to_Flx(GEN x)
 {
   long l=3+F2x_degree(x);
@@ -176,7 +177,8 @@ Rg_to_F2xq(GEN x, GEN T)
       if (is_const_t(ta)) return Rg_to_F2(a)? pol1_F2x(v): pol0_F2x(v);
       b = RgX_to_F2x(b); if (b[1] != v) break;
       a = RgX_to_F2x(a); if (F2x_equal(b,T)) return a;
-      return F2x_rem(a, T);
+      if (lgpol(F2x_rem(b,T))==0) return F2x_rem(a, T);
+      break;
     case t_POL:
       x = RgX_to_F2x(x);
       if (x[1] != v) break;
@@ -234,7 +236,15 @@ F2x_addspec(GEN x, GEN y, long lx, long ly)
 
   if (ly>lx) swapspec(x,y, lx,ly);
   lz = lx+2; z = cgetg(lz, t_VECSMALL) + 2;
-  for (i=0; i<ly; i++) z[i] = x[i]^y[i];
+  for (i=0; i<ly-3; i+=4)
+  {
+    z[i] = x[i]^y[i];
+    z[i+1] = x[i+1]^y[i+1];
+    z[i+2] = x[i+2]^y[i+2];
+    z[i+3] = x[i+3]^y[i+3];
+  }
+  for (; i<ly; i++)
+    z[i] = x[i]^y[i];
   for (   ; i<lx; i++) z[i] = x[i];
   z -= 2; return F2x_renormalize(z, lz);
 }
@@ -256,6 +266,106 @@ F2x_1_add(GEN y)
   return z;
 }
 
+INLINE void
+F2x_addshiftipspec(GEN x, GEN y, long ny, ulong db)
+{
+  long i;
+  if (db)
+  {
+    ulong dc=BITS_IN_LONG-db;
+    ulong r=0, yi;
+    for(i=0; i<ny-3; i+=4)
+    {
+      yi = uel(y,i);   x[i]   ^= (yi<<db)|r; r = yi>>dc;
+      yi = uel(y,i+1); x[i+1] ^= (yi<<db)|r; r = yi>>dc;
+      yi = uel(y,i+2); x[i+2] ^= (yi<<db)|r; r = yi>>dc;
+      yi = uel(y,i+3); x[i+3] ^= (yi<<db)|r; r = yi>>dc;
+    }
+    for(  ; i<ny; i++)
+    {
+      ulong yi = uel(y,i); x[i] ^= (yi<<db)|r; r = yi>>dc;
+    }
+    if (r) x[i] ^= r;
+  }
+  else
+  {
+    for(i=0; i<ny-3; i+=4)
+    {
+      x[i]   ^= y[i];
+      x[i+1] ^= y[i+1];
+      x[i+2] ^= y[i+2];
+      x[i+3] ^= y[i+3];
+    }
+    for(   ; i<ny; i++)
+      x[i] ^= y[i];
+  }
+}
+
+INLINE void
+F2x_addshiftip(GEN x, GEN y, ulong d)
+{
+  ulong db, dl=dvmduBIL(d, &db);
+  F2x_addshiftipspec(x+2+dl, y+2, lgpol(y), db);
+}
+
+static GEN
+F2x_mul1(ulong x, ulong y)
+{
+  ulong x1=(x&HIGHMASK)>>BITS_IN_HALFULONG;
+  ulong x2=x&LOWMASK;
+  ulong y1=(y&HIGHMASK)>>BITS_IN_HALFULONG;
+  ulong y2=y&LOWMASK;
+  ulong r1,r2,rr;
+  GEN z;
+  ulong i;
+  rr=r1=r2=0UL;
+  if (x2)
+    for(i=0;i<BITS_IN_HALFULONG;i++)
+      if (x2&(1UL<<i))
+      {
+        r2^=y2<<i;
+        rr^=y1<<i;
+      }
+  if (x1)
+    for(i=0;i<BITS_IN_HALFULONG;i++)
+      if (x1&(1UL<<i))
+      {
+        r1^=y1<<i;
+        rr^=y2<<i;
+      }
+  r2^=(rr&LOWMASK)<<BITS_IN_HALFULONG;
+  r1^=(rr&HIGHMASK)>>BITS_IN_HALFULONG;
+  z=cgetg((r1?4:3),t_VECSMALL);
+  z[2]=r2;
+  if (r1) z[3]=r1;
+  return z;
+}
+
+static GEN
+F2x_mulspec_basecase(GEN x, GEN y, long nx, long ny)
+{
+  long l, i, j;
+  GEN z;
+  l = nx + ny;
+  z = zero_Flv(l+1);
+  for(i=0; i < ny-1; i++)
+  {
+    GEN zi = z+2+i;
+    ulong yi = uel(y,i);
+    if (yi)
+      for(j=0; j < BITS_IN_LONG; j++)
+        if (yi&(1UL<<j)) F2x_addshiftipspec(zi,x,nx,j);
+  }
+  {
+    GEN zi = z+2+i;
+    ulong yi = uel(y,i);
+    long c = BITS_IN_LONG-bfffo(yi);
+    for(j=0; j < c; j++)
+      if (yi&(1UL<<j)) F2x_addshiftipspec(zi,x,nx,j);
+  }
+  return F2x_renormalize(z, l+2);
+}
+
 static GEN
 F2x_addshift(GEN x, GEN y, long d)
 {
@@ -301,39 +411,6 @@ F2x_shiftip(pari_sp av, GEN x, long v)
   avma = (pari_sp)y; return y;
 }
 
-static GEN
-F2x_mul1(ulong x, ulong y)
-{
-  ulong x1=(x&HIGHMASK)>>BITS_IN_HALFULONG;
-  ulong x2=x&LOWMASK;
-  ulong y1=(y&HIGHMASK)>>BITS_IN_HALFULONG;
-  ulong y2=y&LOWMASK;
-  ulong r1,r2,rr;
-  GEN z;
-  ulong i;
-  rr=r1=r2=0UL;
-  if (x2)
-    for(i=0;i<BITS_IN_HALFULONG;i++)
-      if (x2&(1UL<<i))
-      {
-        r2^=y2<<i;
-        rr^=y1<<i;
-      }
-  if (x1)
-    for(i=0;i<BITS_IN_HALFULONG;i++)
-      if (x1&(1UL<<i))
-      {
-        r1^=y1<<i;
-        rr^=y2<<i;
-      }
-  r2^=(rr&LOWMASK)<<BITS_IN_HALFULONG;
-  r1^=(rr&HIGHMASK)>>BITS_IN_HALFULONG;
-  z=cgetg((r1?4:3),t_VECSMALL);
-  z[2]=r2;
-  if (r1) z[3]=r1;
-  return z;
-}
-
 /* fast product (Karatsuba) of polynomials a,b. These are not real GENs, a+2,
  * b+2 were sent instead. na, nb = number of terms of a, b.
  * Only c, c0, c1, c2 are genuine GEN.
@@ -351,7 +428,10 @@ F2x_mulspec(GEN a, GEN b, long na, long nb)
   if (!nb) return pol0_F2x(0);
 
   av = avma;
-  if (na <=1) return F2x_shiftip(av,F2x_mul1(*a,*b),v);
+  if (na == 1)
+    return F2x_shiftip(av, F2x_mul1(*a,*b), v);
+  if (na < F2x_MUL_KARATSUBA_LIMIT)
+    return F2x_shiftip(av, F2x_mulspec_basecase(a, b, na, nb), v);
   i=(na>>1); n0=na-i; na=i;
   a0=a+n0; n0a=n0;
   while (n0a && !a[n0a-1]) n0a--;
@@ -467,27 +547,6 @@ F2x_sqrt(GEN x)
   return F2x_renormalize(z, lz);
 }
 
-INLINE void
-F2x_addshiftip(GEN x, GEN y, ulong d)
-{
-  ulong db, dl=dvmduBIL(d, &db);
-  long i, ly = lg(y);
-  if (db)
-  {
-    ulong dc=BITS_IN_LONG-db;
-    ulong r=0;
-    for(i=2; i<ly; i++)
-    {
-      x[i+dl] ^= (((ulong)y[i])<<db)|r;
-      r = ((ulong)y[i])>>dc;
-    }
-    if (r) x[i+dl] ^= r;
-  }
-  else
-    for(i=2; i<ly; i++)
-      x[i+dl] ^= y[i];
-}
-
 static GEN
 F2x_shiftneg(GEN y, ulong d)
 {
@@ -549,7 +608,7 @@ F2x_rem(GEN x, GEN y)
   long lx=lg(x);
   dy = F2x_degree(y); if (!dy) return pol0_F2x(x[1]);
   dx = F2x_degree_lg(x,lx);
-  x  = vecsmall_copy(x);
+  x  = F2x_copy(x);
   while (dx>=dy)
   {
     F2x_addshiftip(x,y,dx-dy);
@@ -570,7 +629,7 @@ F2x_divrem(GEN x, GEN y, GEN *pr)
   if (pr == ONLY_REM) return F2x_rem(x, y);
   if (!dy)
   {
-    z = vecsmall_copy(x);
+    z = F2x_copy(x);
     if (pr && pr != ONLY_DIVIDES) *pr = pol0_F2x(vs);
     return z;
   }
@@ -578,13 +637,13 @@ F2x_divrem(GEN x, GEN y, GEN *pr)
   dz = dx-dy;
   if (dz < 0)
   {
-    if (pr == ONLY_DIVIDES) return dx < 0? vecsmall_copy(x): NULL;
+    if (pr == ONLY_DIVIDES) return dx < 0? F2x_copy(x): NULL;
     z = pol0_F2x(vs);
-    if (pr) *pr = vecsmall_copy(x);
+    if (pr) *pr = F2x_copy(x);
     return z;
   }
   z = zero_zv(lg(x)-lg(y)+2); z[1] = vs;
-  x = vecsmall_copy(x);
+  x = F2x_copy(x);
   while (dx>=dy)
   {
     F2x_set(z,dx-dy);
@@ -607,7 +666,7 @@ F2x_valrem(GEN x, GEN *Z)
 {
   long v, v2, i, l=lg(x);
   GEN y;
-  if (l==2) { *Z = leafcopy(x); return LONG_MAX; }
+  if (l==2) { *Z = F2x_copy(x); return LONG_MAX; }
   for (i=2; i<l && x[i]==0; i++) /*empty*/;
   v = i-2;
   v2 = (i < l)? vals(x[i]): 0;
@@ -638,8 +697,8 @@ F2x_deflate(GEN x, long d)
 {
   GEN y;
   long i,id, dy, dx = F2x_degree(x);
-  if (d <= 1) return Flx_copy(x);
-  if (dx < 0) return leafcopy(x);
+  if (d <= 1) return F2x_copy(x);
+  if (dx < 0) return F2x_copy(x);
   dy = dx/d; /* dy+1 coefficients + 1 extra word for variable */
   y = zero_zv(nbits2lg(dy+1)-1); y[1] = x[1];
   for (i=id=0; i<=dy; i++,id+=d)
@@ -654,7 +713,7 @@ F2x_even_odd(GEN p, GEN *pe, GEN *po)
   long n = F2x_degree(p), n0, n1, i;
   GEN p0, p1;
 
-  if (n <= 0) { *pe = leafcopy(p); *po = pol0_F2x(p[1]); return; }
+  if (n <= 0) { *pe = F2x_copy(p); *po = pol0_F2x(p[1]); return; }
 
   n0 = (n>>1)+1; n1 = n+1 - n0; /* n1 <= n0 <= n1+1 */
   p0 = zero_zv(nbits2lg(n0+1)-1); p0[1] = p[1];
@@ -842,7 +901,7 @@ F2xq_pow(GEN x, GEN n, GEN pol)
 
   if (!signe(n)) return pol1_F2x(x[1]);
   if (is_pm1(n)) /* +/- 1 */
-    return (signe(n) < 0)? F2xq_inv(x,pol): vecsmall_copy(x);
+    return (signe(n) < 0)? F2xq_inv(x,pol): F2x_copy(x);
 
   if (signe(n) < 0) x = F2xq_inv(x,pol);
   y = gen_pow(x, n, (void*)pol, &_F2xq_sqr, &_F2xq_mul);
@@ -857,7 +916,7 @@ F2xq_powu(GEN x, ulong n, GEN pol)
   switch(n)
   {
     case 0: return pol1_F2x(x[1]);
-    case 1: return vecsmall_copy(x);
+    case 1: return F2x_copy(x);
     case 2: return F2xq_sqr(x,pol);
   }
   y = gen_powu(x, n, (void*)pol, &_F2xq_sqr, &_F2xq_mul);
@@ -878,7 +937,21 @@ F2xq_matrix_pow(GEN y, long n, long m, GEN P)
   return F2xV_to_F2m(F2xq_powers(y,m-1,P),n);
 }
 
-static struct bb_algebra F2xq_algebra = { _F2xq_red,_F2xq_add,_F2xq_mul,_F2xq_sqr,_F2xq_one,_F2xq_zero};
+GEN
+F2x_Frobenius(GEN T)
+{
+  return F2xq_sqr(polx_F2x(T[1]), T);
+}
+
+GEN
+F2x_matFrobenius(GEN T)
+{
+  long n = F2x_degree(T);
+  return F2xq_matrix_pow(F2x_Frobenius(T), n, n, T);
+}
+
+static struct bb_algebra F2xq_algebra = { _F2xq_red, _F2xq_add, _F2xq_add,
+              _F2xq_mul, _F2xq_sqr, _F2xq_one, _F2xq_zero};
 
 GEN
 F2x_F2xqV_eval(GEN Q, GEN x, GEN T)
@@ -924,7 +997,7 @@ F2xq_conjvec(GEN x, GEN T)
 {
   long i, l = F2x_degree(T);
   GEN z = cgetg(l,t_COL);
-  gel(z,1) = vecsmall_copy(x);
+  gel(z,1) = F2x_copy(x);
   for (i=2; i<l; i++) gel(z,i) = F2xq_sqr(gel(z,i-1), T);
   return z;
 }
@@ -1341,7 +1414,7 @@ F2xq_Artin_Schreier(GEN a, GEN T)
   if (lg(Q)!=2) return NULL;
   Q = gel(Q,1);
   Q[1] = T[1];
-  return gerepileuptoleaf(ltop, Q);
+  return gerepileuptoleaf(ltop, F2x_renormalize(Q, lg(Q)));
 }
 
 GEN
@@ -1361,7 +1434,7 @@ F2xq_sqrt(GEN a, GEN T)
   pari_sp av = avma;
   long n = F2x_degree(T);
   GEN sqx;
-  if (n==1) return leafcopy(a);
+  if (n==1) return F2x_copy(a);
   if (n==2) return F2xq_sqr(a,T);
   sqx = F2xq_autpow(mkF2(4, T[1]), n-1, T);
   return gerepileuptoleaf(av, F2x_is_x(a)? sqx: F2xq_sqrt_fast(a,sqx,T));
@@ -1419,29 +1492,9 @@ gener_F2xq(GEN T, GEN *po)
   return g;
 }
 
-GEN
-ZXX_to_F2xX(GEN B, long v)
-{
-  long lb=lg(B);
-  long i;
-  GEN b=cgetg(lb,t_POL);
-  b[1]=evalsigne(1)|(((ulong)B[1])&VARNBITS);
-  for (i=2; i<lb; i++)
-    switch (typ(gel(B,i)))
-    {
-    case t_INT:
-      gel(b,i) = Z_to_F2x(gel(B,i), v);
-      break;
-    case t_POL:
-      gel(b,i) = ZX_to_F2x(gel(B,i));
-      break;
-    }
-  return FlxX_renormalize(b, lb);
-}
-
 static GEN
 _F2xq_neg(void *E, GEN x)
-{ (void) E; return vecsmall_copy(x); }
+{ (void) E; return F2x_copy(x); }
 
 static GEN
 _F2xq_rmul(void *E, GEN x, GEN y)
@@ -1551,7 +1604,7 @@ F2m_to_mod(GEN z)
 }
 
 GEN
-F2c_to_Flc(GEN x)
+F2v_to_Flv(GEN x)
 {
   long l=x[1]+1;
   GEN  z=cgetg(l, t_VECSMALL);
@@ -1567,7 +1620,7 @@ F2m_to_Flm(GEN z)
 {
   long i, l = lg(z);
   GEN x = cgetg(l,t_MAT);
-  for (i=1; i<l; i++) gel(x,i) = F2c_to_Flc(gel(z,i));
+  for (i=1; i<l; i++) gel(x,i) = F2v_to_Flv(gel(z,i));
   return x;
 }
 
@@ -1646,6 +1699,16 @@ Flm_to_F2m(GEN x)
   return y;
 }
 
+GEN
+const_F2v(long m)
+{
+  long i, l = nbits2lg(m);
+  GEN c = cgetg(l, t_VECSMALL);
+  for (i = 2; i <= l; i++) c[i] = -1;
+  if (remsBIL(m)) c[l] = (1UL<<remsBIL(m))-1UL;
+  return c;
+}
+
 /* Allow lg(y)<lg(x) */
 void
 F2v_add_inplace(GEN x, GEN y)
@@ -1674,6 +1737,33 @@ F2v_add_inplace(GEN x, GEN y)
 /* F2xV are t_VEC with F2x coefficients. */
 
 GEN
+FlxC_to_F2xC(GEN x)
+{
+  long i, l=lg(x);
+  GEN z = cgetg(l,t_COL);
+  for (i=1; i<l ; i++) gel(z,i) = Flx_to_F2x(gel(x,i));
+  return z;
+}
+
+GEN
+F2xC_to_FlxC(GEN x)
+{
+  long i, l=lg(x);
+  GEN z = cgetg(l,t_COL);
+  for (i=1; i<l ; i++) gel(z,i) = F2x_to_Flx(gel(x,i));
+  return z;
+}
+
+GEN
+F2xC_to_ZXC(GEN v)
+{
+  long j, N = lg(v);
+  GEN y = cgetg(N, t_COL);
+  for (j=1; j<N; j++) gel(y,j) = F2x_to_ZX(gel(v,j));
+  return y;
+}
+
+GEN
 F2xV_to_F2m(GEN v, long n)
 {
   long j, N = lg(v);
@@ -1681,3 +1771,562 @@ F2xV_to_F2m(GEN v, long n)
   for (j=1; j<N; j++) gel(y,j) = F2x_to_F2v(gel(v,j), n);
   return y;
 }
+
+/***********************************************************************/
+/**                                                                   **/
+/**                             F2xX                                  **/
+/**                                                                   **/
+/***********************************************************************/
+
+GEN
+F2xX_renormalize(GEN /*in place*/ x, long lx)
+{ return FlxX_renormalize(x, lx); }
+
+GEN
+pol1_F2xX(long v, long sv) { return pol1_FlxX(v, sv); }
+
+GEN
+polx_F2xX(long v, long sv) { return polx_FlxX(v, sv); }
+
+long
+F2xY_degreex(GEN b)
+{
+  long deg = 0, i;
+  if (!signe(b)) return -1;
+  for (i = 2; i < lg(b); ++i)
+    deg = maxss(deg, F2x_degree(gel(b, i)));
+  return deg;
+}
+
+GEN
+FlxX_to_F2xX(GEN B)
+{
+  long lb=lg(B);
+  long i;
+  GEN b=cgetg(lb,t_POL);
+  b[1]=evalsigne(1)|(((ulong)B[1])&VARNBITS);
+  for (i=2; i<lb; i++)
+    gel(b,i) = Flx_to_F2x(gel(B,i));
+  return F2xX_renormalize(b, lb);
+}
+
+GEN
+ZXX_to_F2xX(GEN B, long v)
+{
+  long lb=lg(B);
+  long i;
+  GEN b=cgetg(lb,t_POL);
+  b[1]=evalsigne(1)|(((ulong)B[1])&VARNBITS);
+  for (i=2; i<lb; i++)
+    switch (typ(gel(B,i)))
+    {
+    case t_INT:
+      gel(b,i) = Z_to_F2x(gel(B,i), v);
+      break;
+    case t_POL:
+      gel(b,i) = ZX_to_F2x(gel(B,i));
+      break;
+    }
+  return F2xX_renormalize(b, lb);
+}
+
+GEN
+F2xX_to_ZXX(GEN B)
+{
+  long i, lb = lg(B);
+  GEN b = cgetg(lb,t_POL);
+  for (i=2; i<lb; i++)
+  {
+    GEN c = gel(B,i);
+    gel(b,i) = lgpol(c) ?  F2x_equal1(c) ? gen_1 : F2x_to_ZX(c) : gen_0;
+  }
+  b[1] = B[1]; return b;
+}
+
+GEN
+F2xX_deriv(GEN z)
+{
+  long i,l = lg(z)-1;
+  GEN x;
+  if (l < 2) l = 2;
+  x = cgetg(l, t_POL); x[1] = z[1];
+  for (i=2; i<l; i++) gel(x,i) = odd(i) ? pol0_F2x(mael(z,i+1,1)): gel(z,i+1);
+  return F2xX_renormalize(x,l);
+}
+
+GEN
+F2xX_add(GEN x, GEN y)
+{
+  long i,lz;
+  GEN z;
+  long lx=lg(x);
+  long ly=lg(y);
+  if (ly>lx) swapspec(x,y, lx,ly);
+  lz = lx; z = cgetg(lz, t_POL); z[1]=x[1];
+  for (i=2; i<ly; i++) gel(z,i) = F2x_add(gel(x,i), gel(y,i));
+  for (   ; i<lx; i++) gel(z,i) = F2x_copy(gel(x,i));
+  return F2xX_renormalize(z, lz);
+}
+
+GEN
+F2xX_F2x_mul(GEN P, GEN U)
+{
+  long i, lP = lg(P);
+  GEN res = cgetg(lP,t_POL);
+  res[1] = P[1];
+  for(i=2; i<lP; i++)
+    gel(res,i) = F2x_mul(U,gel(P,i));
+  return F2xX_renormalize(res, lP);
+}
+
+GEN
+F2xY_F2xqV_evalx(GEN P, GEN x, GEN T)
+{
+  long i, lP = lg(P);
+  GEN res = cgetg(lP,t_POL);
+  res[1] = P[1];
+  for(i=2; i<lP; i++)
+    gel(res,i) = F2x_F2xqV_eval(gel(P,i), x, T);
+  return F2xX_renormalize(res, lP);
+}
+
+GEN
+F2xY_F2xq_evalx(GEN P, GEN x, GEN T)
+{
+  pari_sp av = avma;
+  long n = brent_kung_optpow(F2x_degree(T)-1,lgpol(P),1);
+  GEN xp = F2xq_powers(x, n, T);
+  return gerepileupto(av, F2xY_F2xqV_evalx(P, xp, T));
+}
+
+GEN
+F2xX_to_Kronecker(GEN P, long d)
+{
+  long i, k, N = 2*d + 1;
+  long dP = degpol(P);
+  long l = nbits2nlong(N*dP+d+1);
+  GEN x = zero_zv(l+1);
+  for (k=i=0; i<=dP; i++, k+=N)
+  {
+    GEN c = gel(P,i+2);
+    F2x_addshiftip(x, c, k);
+  }
+  x[1] = P[1]&VARNBITS; return F2x_renormalize(x, l+2);
+}
+
+static GEN
+F2x_slice(GEN x, long n, long d)
+{
+  ulong ib, il=dvmduBIL(n, &ib);
+  ulong db, dl=dvmduBIL(d, &db);
+  long lN = dl+2+(db?1:0);
+  GEN t = cgetg(lN,t_VECSMALL);
+  t[1] = x[1];
+  if (ib)
+  {
+    ulong i, ic = BITS_IN_LONG-ib;
+    ulong r = uel(x,2+il)>>ib;
+    for(i=0; i<dl; i++)
+    {
+      uel(t,2+i) = (uel(x,3+il+i)<<ic)|r;
+      r = uel(x,3+il+i)>>ib;
+    }
+    if (db)
+      uel(t,2+i) = (uel(x,3+il+i)<<ic)|r;
+  }
+  else
+  {
+    long i;
+    for(i=2; i<lN; i++)
+      uel(t,i) = uel(x,il+i);
+  }
+  if (db) uel(t,lN-1) &= (1UL<<db)-1;
+  return F2x_renormalize(t, lN);
+}
+
+GEN
+Kronecker_to_F2xqX(GEN z, GEN T)
+{
+  long lz = F2x_degree(z)+1;
+  long i, j, N = F2x_degree(T)*2 + 1;
+  long lx = lz / (N-2);
+  GEN x = cgetg(lx+3,t_POL);
+  x[1] = z[1];
+  for (i=0, j=2; i<lz; i+=N, j++)
+  {
+    GEN t = F2x_slice(z,i,minss(lz-i,N));
+    t[1] = T[1];
+    gel(x,j) = F2x_rem(t, T);
+  }
+  return F2xX_renormalize(x, j);
+}
+
+/***********************************************************************/
+/**                                                                   **/
+/**                             F2xqX                                 **/
+/**                                                                   **/
+/***********************************************************************/
+
+GEN
+random_F2xqX(long d1, long v, GEN T)
+{
+  long dT = F2x_degree(T), vT = T[1];
+  long i, d = d1+2;
+  GEN y = cgetg(d,t_POL); y[1] = evalsigne(1) | evalvarn(v);
+  for (i=2; i<d; i++) gel(y,i) = random_F2x(dT, vT);
+  return FlxX_renormalize(y,d);
+}
+
+GEN
+F2xqX_red(GEN z, GEN T)
+{
+  GEN res;
+  long i, l = lg(z);
+  res = cgetg(l,t_POL); res[1] = z[1];
+  for(i=2;i<l;i++) gel(res,i) = F2x_rem(gel(z,i),T);
+  return F2xX_renormalize(res,l);
+}
+
+GEN
+F2xqX_F2xq_mul(GEN P, GEN U, GEN T)
+{
+  long i, lP = lg(P);
+  GEN res = cgetg(lP,t_POL);
+  res[1] = P[1];
+  for(i=2; i<lP; i++)
+    gel(res,i) = F2xq_mul(U,gel(P,i), T);
+  return F2xX_renormalize(res, lP);
+}
+
+GEN
+F2xqX_F2xq_mul_to_monic(GEN P, GEN U, GEN T)
+{
+  long i, lP = lg(P);
+  GEN res = cgetg(lP,t_POL);
+  res[1] = P[1];
+  for(i=2; i<lP-1; i++) gel(res,i) = F2xq_mul(U,gel(P,i), T);
+  gel(res,lP-1) = pol1_F2x(T[1]);
+  return F2xX_renormalize(res, lP);
+}
+
+GEN
+F2xqX_normalize(GEN z, GEN T)
+{
+  GEN p1 = leading_coeff(z);
+  if (!lgpol(z) || (!degpol(p1) && p1[1] == 1)) return z;
+  return F2xqX_F2xq_mul_to_monic(z, F2xq_inv(p1,T), T);
+}
+
+GEN
+F2xqX_mul(GEN x, GEN y, GEN T)
+{
+  pari_sp ltop=avma;
+  GEN z,kx,ky;
+  kx= F2xX_to_Kronecker(x, F2x_degree(T));
+  ky= F2xX_to_Kronecker(y, F2x_degree(T));
+  z = F2x_mul(ky, kx);
+  z = Kronecker_to_F2xqX(z,T);
+  return gerepileupto(ltop,z);
+}
+
+GEN
+F2xqX_sqr(GEN x, GEN T)
+{
+  long d = degpol(x), l = 2*d+3;
+  GEN z;
+  if (!signe(x)) return pol_0(varn(x));
+  z = cgetg(l,t_POL);
+  z[1] = x[1];
+  if (d > 0)
+  {
+    GEN u = pol0_F2x(T[1]);
+    long i,j;
+    for (i=2,j=2; i<d+2; i++,j+=2)
+    {
+      gel(z, j) = F2xq_sqr(gel(x, i), T);
+      gel(z, j+1) = u;
+    }
+  }
+  gel(z, 2+2*d) = F2xq_sqr(gel(x, 2+d), T);
+  return FlxX_renormalize(z, l);
+}
+
+GEN
+F2xqX_divrem(GEN x, GEN y, GEN T, GEN *pr)
+{
+  long vx, dx, dy, dz, i, j, sx, lr;
+  pari_sp av0, av, tetpil;
+  GEN z,p1,rem,lead;
+
+  if (!signe(y)) pari_err_INV("F2xqX_divrem",y);
+  vx=varn(x); dy=degpol(y); dx=degpol(x);
+  if (dx < dy)
+  {
+    if (pr)
+    {
+      av0 = avma; x = F2xqX_red(x, T);
+      if (pr == ONLY_DIVIDES) { avma=av0; return signe(x)? NULL: pol_0(vx); }
+      if (pr == ONLY_REM) return x;
+      *pr = x;
+    }
+    return pol_0(vx);
+  }
+  lead = leading_term(y);
+  if (!dy) /* y is constant */
+  {
+    if (pr && pr != ONLY_DIVIDES)
+    {
+      if (pr == ONLY_REM) return pol_0(vx);
+      *pr = pol_0(vx);
+    }
+    if (F2x_equal1(lead)) return gcopy(x);
+    av0 = avma; x = F2xqX_F2xq_mul(x,F2xq_inv(lead,T),T);
+    return gerepileupto(av0,x);
+  }
+  av0 = avma; dz = dx-dy;
+  lead = F2x_equal1(lead)? NULL: gclone(F2xq_inv(lead,T));
+  avma = av0;
+  z = cgetg(dz+3,t_POL); z[1] = x[1];
+  x += 2; y += 2; z += 2;
+
+  p1 = gel(x,dx); av = avma;
+  gel(z,dz) = lead? gerepileupto(av, F2xq_mul(p1,lead, T)): leafcopy(p1);
+  for (i=dx-1; i>=dy; i--)
+  {
+    av=avma; p1=gel(x,i);
+    for (j=i-dy+1; j<=i && j<=dz; j++)
+      p1 = F2x_add(p1, F2x_mul(gel(z,j),gel(y,i-j)));
+    if (lead) p1 = F2x_mul(p1, lead);
+    tetpil=avma; gel(z,i-dy) = gerepile(av,tetpil,F2x_rem(p1,T));
+  }
+  if (!pr) { if (lead) gunclone(lead); return z-2; }
+
+  rem = (GEN)avma; av = (pari_sp)new_chunk(dx+3);
+  for (sx=0; ; i--)
+  {
+    p1 = gel(x,i);
+    for (j=0; j<=i && j<=dz; j++)
+      p1 = F2x_add(p1, F2x_mul(gel(z,j),gel(y,i-j)));
+    tetpil=avma; p1 = F2x_rem(p1, T); if (lgpol(p1)) { sx = 1; break; }
+    if (!i) break;
+    avma=av;
+  }
+  if (pr == ONLY_DIVIDES)
+  {
+    if (lead) gunclone(lead);
+    if (sx) { avma=av0; return NULL; }
+    avma = (pari_sp)rem; return z-2;
+  }
+  lr=i+3; rem -= lr;
+  rem[0] = evaltyp(t_POL) | evallg(lr);
+  rem[1] = z[-1];
+  p1 = gerepile((pari_sp)rem,tetpil,p1);
+  rem += 2; gel(rem,i) = p1;
+  for (i--; i>=0; i--)
+  {
+    av=avma; p1 = gel(x,i);
+    for (j=0; j<=i && j<=dz; j++)
+      p1 = F2x_add(p1, F2x_mul(gel(z,j),gel(y,i-j)));
+    tetpil=avma; gel(rem,i) = gerepile(av,tetpil, F2x_rem(p1, T));
+  }
+  rem -= 2;
+  if (lead) gunclone(lead);
+  if (!sx) (void)F2xX_renormalize(rem, lr);
+  if (pr == ONLY_REM) return gerepileupto(av0,rem);
+  *pr = rem; return z-2;
+}
+
+GEN
+F2xqX_rem(GEN x, GEN S, GEN T)
+{
+  GEN y = S;
+  long dy = degpol(y), dx = degpol(x), d = dx-dy;
+  if (d < 0) return F2xqX_red(x, T);
+  return F2xqX_divrem(x,y, T, ONLY_REM);
+}
+
+GEN
+F2xqX_gcd(GEN a, GEN b, GEN T)
+{
+  pari_sp av = avma, av0=avma;
+  while (signe(b))
+  {
+    GEN c;
+    if (gc_needed(av0,2))
+    {
+      if (DEBUGMEM>1) pari_warn(warnmem,"F2xqX_gcd (d = %ld)",degpol(b));
+      gerepileall(av0,2, &a,&b);
+    }
+    av = avma; c = F2xqX_rem(a, b, T); a=b; b=c;
+  }
+  avma = av; return a;
+}
+
+/***********************************************************************/
+/**                                                                   **/
+/**                             F2xqXQ                                **/
+/**                                                                   **/
+/***********************************************************************/
+
+GEN
+F2xqXQ_mul(GEN x, GEN y, GEN S, GEN T) {
+  return F2xqX_rem(F2xqX_mul(x,y,T),S,T);
+}
+
+GEN
+F2xqXQ_sqr(GEN x, GEN S, GEN T) {
+  return F2xqX_rem(F2xqX_sqr(x,T),S,T);
+}
+
+struct _F2xqXQ {
+  GEN T, S;
+};
+
+static GEN
+_F2xqXQ_add(void *data, GEN x, GEN y) {
+  (void) data;
+  return F2xX_add(x,y);
+}
+static GEN
+_F2xqXQ_cmul(void *data, GEN P, long a, GEN x) {
+  (void) data;
+  return F2xX_F2x_mul(x,gel(P,a+2));
+}
+static GEN
+_F2xqXQ_red(void *data, GEN x) {
+  struct _F2xqXQ *d = (struct _F2xqXQ*) data;
+  return F2xqX_red(x, d->T);
+}
+static GEN
+_F2xqXQ_mul(void *data, GEN x, GEN y) {
+  struct _F2xqXQ *d = (struct _F2xqXQ*) data;
+  return F2xqXQ_mul(x,y, d->S,d->T);
+}
+static GEN
+_F2xqXQ_sqr(void *data, GEN x) {
+  struct _F2xqXQ *d = (struct _F2xqXQ*) data;
+  return F2xqXQ_sqr(x, d->S,d->T);
+}
+static GEN
+_F2xqXQ_zero(void *data) {
+  struct _F2xqXQ *d = (struct _F2xqXQ*) data;
+  return pol_0(varn(d->S));
+}
+static GEN
+_F2xqXQ_one(void *data) {
+  struct _F2xqXQ *d = (struct _F2xqXQ*) data;
+  return pol1_F2xX(varn(d->S),d->T[1]);
+}
+
+static struct bb_algebra F2xqXQ_algebra = { _F2xqXQ_red,
+ _F2xqXQ_add, _F2xqXQ_add, _F2xqXQ_mul,_F2xqXQ_sqr,_F2xqXQ_one,_F2xqXQ_zero };
+
+GEN
+F2xqXQ_pow(GEN x, GEN n, GEN S, GEN T)
+{
+  struct _F2xqXQ D;
+  long s = signe(n);
+  if (!s) return pol1_F2xX(varn(S), T[1]);
+  if (s < 0) pari_err_IMPL("F2xqXQ_inv");
+  if (is_pm1(n)) return s < 0 ? x : gcopy(x);
+  if (degpol(x)>=degpol(S)) x = F2xqX_rem(x,S,T);
+  D.S = S; D.T = T;
+  return gen_pow(x, n, (void*)&D, &_F2xqXQ_sqr, &_F2xqXQ_mul);
+}
+
+GEN
+F2xqXQ_powers(GEN x, long l, GEN S, GEN T)
+{
+  struct _F2xqXQ D;
+  int use_sqr = 2*degpol(x) >= degpol(S);
+  D.S = S; D.T = T;
+  return gen_powers(x, l, use_sqr, (void*)&D, &_F2xqXQ_sqr, &_F2xqXQ_mul,&_F2xqXQ_one);
+}
+
+GEN
+F2xqX_F2xqXQV_eval(GEN P, GEN V, GEN S, GEN T)
+{
+  struct _F2xqXQ D;
+  D.S = S; D.T = T;
+  return gen_bkeval_powers(P, degpol(P), V, (void*)&D, &F2xqXQ_algebra,
+                                                   _F2xqXQ_cmul);
+}
+
+GEN
+F2xqX_F2xqXQ_eval(GEN Q, GEN x, GEN S, GEN T)
+{
+  struct _F2xqXQ D;
+  int use_sqr = 2*degpol(x) >= degpol(S);
+  D.S = S; D.T = T;
+  return gen_bkeval(Q, degpol(Q), x, use_sqr, (void*)&D, &F2xqXQ_algebra,
+                                                    _F2xqXQ_cmul);
+}
+
+static GEN
+F2xqXQ_autpow_sqr(void * E, GEN x)
+{
+  struct _F2xqXQ *D = (struct _F2xqXQ *)E;
+  GEN T = D->T;
+  GEN phi = gel(x,1), S = gel(x,2);
+  long n = brent_kung_optpow(F2x_degree(T)-1,lgpol(S)+1,1);
+  GEN V = F2xq_powers(phi, n, T);
+  GEN phi2 = F2x_F2xqV_eval(phi, V, T);
+  GEN Sphi = F2xY_F2xqV_evalx(S, V, T);
+  GEN S2 = F2xqX_F2xqXQ_eval(Sphi, S, D->S, T);
+  return mkvec2(phi2, S2);
+}
+
+static GEN
+F2xqXQ_autpow_mul(void * E, GEN x, GEN y)
+{
+  struct _F2xqXQ *D = (struct _F2xqXQ *)E;
+  GEN T = D->T;
+  GEN phi1 = gel(x,1), S1 = gel(x,2);
+  GEN phi2 = gel(y,1), S2 = gel(y,2);
+  long n = brent_kung_optpow(F2x_degree(T)-1,lgpol(S1)+1,1);
+  GEN V = F2xq_powers(phi2, n, T);
+  GEN phi3 = F2x_F2xqV_eval(phi1,V,T);
+  GEN Sphi = F2xY_F2xqV_evalx(S1,V,T);
+  GEN S3 = F2xqX_F2xqXQ_eval(Sphi, S2, D->S, T);
+  return mkvec2(phi3, S3);
+}
+
+GEN
+F2xqXQV_autpow(GEN aut, long n, GEN S, GEN T)
+{
+  struct _F2xqXQ D;
+  D.S = S; D.T = T;
+  return gen_powu(aut,n,&D,F2xqXQ_autpow_sqr,F2xqXQ_autpow_mul);
+}
+
+static GEN
+F2xqXQ_auttrace_mul(void *E, GEN x, GEN y)
+{
+  struct _F2xqXQ *D = (struct _F2xqXQ *) E;
+  GEN T = D->T;
+  GEN phi1 = gel(x,1), S1 = gel(x,2), a1 = gel(x,3);
+  GEN phi2 = gel(y,1), S2 = gel(y,2), a2 = gel(y,3);
+  long n2 = brent_kung_optpow(F2x_degree(T)-1, lgpol(S1)+lgpol(a1)+1, 1);
+  GEN V2 = F2xq_powers(phi2, n2, T);
+  GEN phi3 = F2x_F2xqV_eval(phi1, V2, T);
+  GEN Sphi = F2xY_F2xqV_evalx(S1, V2, T);
+  GEN aphi = F2xY_F2xqV_evalx(a1, V2, T);
+  long n = brent_kung_optpow(maxss(degpol(Sphi),degpol(aphi)),2,1);
+  GEN V = F2xqXQ_powers(S2, n, D->S, T);
+  GEN S3 = F2xqX_F2xqXQV_eval(Sphi, V, D->S, T);
+  GEN aS = F2xqX_F2xqXQV_eval(aphi, V, D->S, T);
+  GEN a3 = F2xX_add(aS, a2);
+  return mkvec3(phi3, S3, a3);
+}
+
+static GEN
+F2xqXQ_auttrace_sqr(void *E, GEN x)
+{ return F2xqXQ_auttrace_mul(E, x, x); }
+
+GEN
+F2xqXQV_auttrace(GEN aut, long n, GEN S, GEN T)
+{
+  struct _F2xqXQ D;
+  D.S = S; D.T = T;
+  return gen_powu(aut,n,&D,F2xqXQ_auttrace_sqr,F2xqXQ_auttrace_mul);
+}
diff --git a/src/basemath/F2xqE.c b/src/basemath/F2xqE.c
index 0df67c3..1aae80b 100644
--- a/src/basemath/F2xqE.c
+++ b/src/basemath/F2xqE.c
@@ -322,9 +322,47 @@ F2xqE_log(GEN a, GEN b, GEN o, GEN a2, GEN T)
 static GEN
 F2xqE_vert(GEN P, GEN Q, GEN T)
 {
+  long vT = T[1];
   if (ell_is_inf(P))
     return pol1_F2x(T[1]);
-  return F2x_add(gel(Q, 1), gel(P, 1));
+  if (!F2x_equal(gel(Q, 1), gel(P, 1)))
+    return F2x_add(gel(Q, 1), gel(P, 1));
+  if (lgpol(gel(Q, 1))) return pol1_F2x(vT);
+  return F2xq_inv(gel(Q,2), T);
+}
+
+static GEN
+F2xqE_Miller_line(GEN R, GEN Q, GEN slope, GEN a, GEN T)
+{
+  long vT = T[1];
+  GEN x = gel(Q, 1), y = gel(Q, 2);
+  GEN tmp1 = F2x_add(x, gel(R, 1));
+  GEN tmp2 = F2x_add(F2xq_mul(tmp1, slope, T), gel(R, 2));
+  GEN s1, s2, ix;
+  if (!F2x_equal(y, tmp2))
+    return F2x_add(y, tmp2);
+  if (lgpol(x) == 0) return pol1_F2x(vT);
+  if (typ(a)==t_VEC)
+  {
+    GEN a4 = gel(a,2), a3i = gel(a,3);
+    s1 = F2xq_mul(F2x_add(a4, F2xq_sqr(x, T)), a3i, T);
+    if (!F2x_equal(s1, slope))
+      return F2x_add(s1, slope);
+    s2 = F2xq_mul(F2x_add(x, F2xq_sqr(s1, T)), a3i, T);
+    if (lgpol(s2)) return s2;
+    return zv_copy(a3i);
+  } else
+  {
+    GEN a2 = a ;
+    ix = F2xq_inv(x, T);
+    s1 = F2x_add(x, F2xq_mul(y, ix, T));
+    if (!F2x_equal(s1, slope))
+      return F2x_add(s1, slope);
+    s2 =F2x_add(a2, F2x_add(F2xq_sqr(s1,T), s1));
+    if (!F2x_equal(s2, x))
+      return  F2x_add(pol1_F2x(vT), F2xq_mul(s2, ix, T));
+    return ix;
+  }
 }
 
 /* Computes the equation of the line tangent to R and returns its
@@ -344,11 +382,9 @@ F2xqE_tangent_update(GEN R, GEN Q, GEN a2, GEN T, GEN *pt_R)
     *pt_R = ellinf();
     return F2xqE_vert(R, Q, T);
   } else {
-    GEN slope = NULL, tmp1, tmp2;
+    GEN slope;
     *pt_R = F2xqE_dbl_slope(R, a2, T, &slope);
-    tmp1 = F2x_add(gel(Q, 1), gel(R, 1));
-    tmp2 = F2x_add(F2xq_mul(tmp1, slope, T), gel(R,2));
-    return F2x_add(gel(Q, 2), tmp2);
+    return F2xqE_Miller_line(R, Q, slope, a2, T);
   }
 }
 
@@ -379,11 +415,9 @@ F2xqE_chord_update(GEN R, GEN P, GEN Q, GEN a2, GEN T, GEN *pt_R)
       return F2xqE_vert(R, Q, T);
     }
   } else {
-    GEN slope = NULL, tmp1, tmp2;
+    GEN slope;
     *pt_R = F2xqE_add_slope(P, R, a2, T, &slope);
-    tmp1  = F2xq_mul(F2x_add(gel(Q, 1), gel(R, 1)), slope, T);
-    tmp2  = F2x_add(tmp1, gel(R, 2));
-    return F2x_add(gel(Q, 2), tmp2);
+    return F2xqE_Miller_line(R, Q, slope, a2, T);
   }
 }
 
@@ -440,7 +474,6 @@ F2xqE_Miller(GEN Q, GEN P, GEN m, GEN a2, GEN T)
   g1 = pol1_F2x(T[1]);
   v = gen_pow(mkvec3(g1,g1,Q), m, (void*)&d, F2xqE_Miller_dbl, F2xqE_Miller_add);
   num = gel(v,1); denom = gel(v,2);
-  if (!lgpol(num) || !lgpol(denom)) { avma = ltop; return NULL; }
   return gerepileupto(ltop, F2xq_div(num, denom, T));
 }
 
@@ -452,9 +485,7 @@ F2xqE_weilpairing(GEN P, GEN Q, GEN m, GEN a2, GEN T)
   if (ell_is_inf(P) || ell_is_inf(Q) || F2x_equal(P,Q))
     return pol1_F2x(T[1]);
   num    = F2xqE_Miller(P, Q, m, a2, T);
-  if (!num) return pol1_F2x(T[1]);
   denom  = F2xqE_Miller(Q, P, m, a2, T);
-  if (!denom) { avma=ltop; return pol1_F2x(T[1]); }
   result = F2xq_div(num, denom, T);
   return gerepileupto(ltop, result);
 }
@@ -462,11 +493,9 @@ F2xqE_weilpairing(GEN P, GEN Q, GEN m, GEN a2, GEN T)
 GEN
 F2xqE_tatepairing(GEN P, GEN Q, GEN m, GEN a2, GEN T)
 {
-  GEN num;
   if (ell_is_inf(P) || ell_is_inf(Q))
     return pol1_F2x(T[1]);
-  num = F2xqE_Miller(P, Q, m, a2, T);
-  return num? num: pol1_F2x(T[1]);
+  return F2xqE_Miller(P, Q, m, a2, T);
 }
 
 /***********************************************************************/
diff --git a/src/basemath/FF.c b/src/basemath/FF.c
index 7e017dd..40f0693 100644
--- a/src/basemath/FF.c
+++ b/src/basemath/FF.c
@@ -20,6 +20,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 /**                                                                     **/
 /*************************************************************************/
 
+/*************************************************************************/
+/**                                                                     **/
+/**                   Low-level constructors                            **/
+/**                                                                     **/
+/*************************************************************************/
+
 INLINE void
 _getFF(GEN x, GEN *T, GEN *p, ulong *pp)
 {
@@ -66,6 +72,132 @@ mkFF_i(GEN x, GEN r)
   return _mkFF_i(x,z,r);
 }
 
+/*************************************************************************/
+/**                                                                     **/
+/**                   medium-level constructors                         **/
+/**                                                                     **/
+/*************************************************************************/
+
+static GEN
+Z_to_raw(GEN x, GEN ff)
+{
+  ulong pp;
+  GEN T, p;
+  _getFF(ff,&T,&p,&pp);
+  switch(ff[1])
+  {
+  case t_FF_FpXQ:
+    return scalarpol(x, varn(T));
+  case t_FF_F2xq:
+    return Z_to_F2x(x,varn(T));
+  default:
+    return Z_to_Flx(x,pp,T[1]);
+  }
+}
+
+static GEN
+Rg_to_raw(GEN x, GEN ff)
+{
+  long tx = typ(x);
+  switch(tx)
+  {
+  case t_INT: case t_FRAC: case t_PADIC: case t_INTMOD:
+    return Z_to_raw(Rg_to_Fp(x, FF_p_i(ff)), ff);
+  case t_FFELT:
+    if (!FF_samefield(x,ff))
+      pari_err_MODULUS("Rg_to_raw",x,ff);
+    return gel(x,2);
+  }
+  pari_err_TYPE("Rg_to_raw",x);
+  return NULL; /* not reached */
+}
+
+static GEN
+FFX_to_raw(GEN x, GEN ff)
+{
+  long i, lx;
+  GEN y = cgetg_copy(x,&lx);
+  y[1] = x[1];
+  for(i=2; i<lx; i++)
+    gel(y, i) = Rg_to_raw(gel(x, i), ff);
+  return y;
+}
+
+static GEN
+FFC_to_raw(GEN x)
+{
+  long i, lx;
+  GEN y = cgetg_copy(x,&lx);
+  for(i=1; i<lx; i++)
+    gel(y, i) = gel(gel(x, i), 2);
+  return y;
+}
+
+static GEN
+FFM_to_raw(GEN x)
+{
+  long i, lx;
+  GEN y = cgetg_copy(x,&lx);
+  for(i=1; i<lx; i++)
+    gel(y, i) = FFC_to_raw(gel(x, i));
+  return y;
+}
+
+/* in place */
+static GEN
+raw_to_FFC(GEN x, GEN ff)
+{
+  long i, lx = lg(x);
+  for (i=1; i<lx; i++) gel(x,i) = mkFF_i(ff, gel(x,i));
+  return x;
+}
+
+/* in place */
+static GEN
+raw_to_FFM(GEN x, GEN ff)
+{
+  long i, lx = lg(x);
+  for (i=1; i<lx; i++) gel(x,i) = raw_to_FFC(gel(x,i), ff);
+  return x;
+}
+
+GEN
+Fq_to_FF(GEN x, GEN ff)
+{
+  ulong pp;
+  GEN r, T, p, z=_initFF(ff,&T,&p,&pp);
+  int is_int = typ(x)==t_INT;
+  switch(ff[1])
+  {
+  case t_FF_FpXQ:
+    r= is_int ? scalarpol(x, varn(T)): x;
+    break;
+  case t_FF_F2xq:
+    r= is_int ? Z_to_F2x(x,T[1]): ZX_to_F2x(x);
+    break;
+  default:
+    r= is_int ? Z_to_Flx(x,pp,T[1]): ZX_to_Flx(x,pp);
+  }
+  setvarn(r, varn(T)); /* paranoia */
+  return _mkFF_i(ff,z,r);
+}
+
+/* in place */
+static GEN
+to_FFX(GEN x, GEN ff)
+{
+  long i, lx = lg(x);
+  if (typ(x) != t_POL) pari_err_TYPE("to_FFX",x);
+  for (i=2; i<lx; i++) gel(x,i) = Fq_to_FF(gel(x,i), ff);
+  return x;
+}
+
+/*************************************************************************/
+/**                                                                     **/
+/**                   Public functions                                  **/
+/**                                                                     **/
+/*************************************************************************/
+
 /* Return true if x and y are defined in the same field */
 int
 FF_samefield(GEN x, GEN y)
@@ -1366,61 +1498,37 @@ FF_elltatepairing(GEN E, GEN P, GEN Q, GEN m)
   return _mkFF(fg,z,r);
 }
 
-static GEN
-to_FF(GEN x, GEN ff)
+GEN
+FFX_roots(GEN Pf, GEN ff)
 {
+  pari_sp av = avma;
+  GEN r,T,p;
   ulong pp;
-  GEN r, T, p, z=_initFF(ff,&T,&p,&pp);
-  int is_int = typ(x)==t_INT;
+  GEN P = FFX_to_raw(Pf, ff);
+  _getFF(ff,&T,&p,&pp);
   switch(ff[1])
   {
   case t_FF_FpXQ:
-    r= is_int ? scalarpol(x, varn(T)): x;
+    r = FpXQX_roots(P, T, p);
     break;
   case t_FF_F2xq:
-    r= is_int ? Z_to_F2x(x,T[1]): ZX_to_F2x(x);
+    r = F2xqX_roots(P, T);
     break;
   default:
-    r= is_int ? Z_to_Flx(x,pp,T[1]): ZX_to_Flx(x,pp);
+    r = FlxqX_roots(P, T, pp);
   }
-  setvarn(r, varn(T)); /* paranoia */
-  return _mkFF_i(ff,z,r);
-}
-
-/* in place */
-static GEN
-to_FFX(GEN x, GEN ff)
-{
-  long i, lx = lg(x);
-  if (typ(x) != t_POL) pari_err_TYPE("to_FFX",x);
-  for (i=2; i<lx; i++) gel(x,i) = to_FF(gel(x,i), ff);
-  return x;
-}
-/* in place */
-static GEN
-to_FFC(GEN x, GEN ff)
-{
-  long i, lx = lg(x);
-  for (i=1; i<lx; i++) gel(x,i) = to_FF(gel(x,i), ff);
-  return x;
-}
-
-/* in place */
-static GEN
-raw_to_FFC(GEN x, GEN ff)
-{
-  long i, lx = lg(x);
-  for (i=1; i<lx; i++) gel(x,i) = mkFF_i(ff, gel(x,i));
-  return x;
+  r = raw_to_FFC(r, ff);
+  return gerepilecopy(av, r);
 }
 
-/* in place */
-static GEN
-raw_to_FFM(GEN x, GEN ff)
+GEN
+FqX_to_FFX(GEN x, GEN ff)
 {
-  long i, lx = lg(x);
-  for (i=1; i<lx; i++) gel(x,i) = raw_to_FFC(gel(x,i), ff);
-  return x;
+  long i, lx;
+  GEN y =  cgetg_copy(x,&lx);
+  y[1] = x[1];
+  for (i=2; i<lx; i++) gel(y,i) = Fq_to_FF(gel(x,i), ff);
+  return y;
 }
 
 /* P vector of t_POL, E t_VECSMALL of exponents, ff a t_FFELT. Update elts of
@@ -1482,22 +1590,10 @@ FFX_factor(GEN P, GEN x)
   pari_sp av=avma;
 
   P = FFX_init_fix_varn(P, x, &T, &p);
-  r = FqX_factor(P, T,p);
+  r = FpXQX_factor(P, T,p);
   return to_FF_fact(vP, gel(r,1),gel(r,2), x,av);
 }
 
-/* Roots of P over the field of definition of x */
-GEN
-FFX_roots(GEN P, GEN x)
-{
-  GEN r, T, p;
-  pari_sp av=avma;
-
-  P = FFX_init_fix_varn(P, x, &T, &p);
-  r = FqX_roots(P, T,p);
-  return gerepilecopy(av, to_FFC(r, x));
-}
-
 GEN
 ffgen(GEN T, long v)
 {
@@ -1713,26 +1809,6 @@ RgM_is_FFM(GEN x, GEN *ff)
 }
 
 static GEN
-FFC_to_raw(GEN x)
-{
-  long i, lx;
-  GEN y = cgetg_copy(x,&lx);
-  for(i=1; i<lx; i++)
-    gel(y, i) = gmael(x, i, 2);
-  return y;
-}
-
-static GEN
-FFM_to_raw(GEN x)
-{
-  long i, lx;
-  GEN y = cgetg_copy(x,&lx);
-  for(i=1; i<lx; i++)
-    gel(y, i) = FFC_to_raw(gel(x, i));
-  return y;
-}
-
-static GEN
 FqC_to_FpXQC(GEN x, GEN T, GEN p)
 {
   long i, lx;
diff --git a/src/basemath/Flx.c b/src/basemath/Flx.c
index 9906b87..a48fe01 100644
--- a/src/basemath/Flx.c
+++ b/src/basemath/Flx.c
@@ -212,9 +212,9 @@ monomial_Flx(ulong a, long d, long vs)
 }
 
 GEN
-Z_to_Flx(GEN x, ulong p, long v)
+Z_to_Flx(GEN x, ulong p, long sv)
 {
-  long sv = evalvarn(v), u = umodiu(x,p);
+  long u = umodiu(x,p);
   return u? mkvecsmall2(sv, u): pol0_Flx(sv);
 }
 
@@ -315,7 +315,8 @@ Rg_to_Flxq(GEN x, GEN T, ulong p)
       if (is_const_t(ta)) return Fl_to_Flx(Rg_to_Fl(a, p), v);
       b = RgX_to_Flx(b, p); if (b[1] != v) break;
       a = RgX_to_Flx(a, p); if (Flx_equal(b,T)) return a;
-      return Flx_rem(a, T, p);
+      if (lgpol(Flx_rem(b,T,p))==0) return Flx_rem(a, T, p);
+      break;
     case t_POL:
       x = RgX_to_Flx(x,p);
       if (x[1] != v) break;
@@ -1066,6 +1067,16 @@ Flx_powu(GEN x, ulong n, ulong p)
   }
 }
 
+GEN
+Flx_halve(GEN y, ulong p)
+{
+  GEN z;
+  long i, l;
+  z = cgetg_copy(y, &l); z[1] = y[1];
+  for(i=2; i<l; i++) uel(z,i) = Fl_halve(uel(y,i), p);
+  return z;
+}
+
 static GEN
 Flx_recipspec(GEN x, long l, long n)
 {
@@ -2288,7 +2299,7 @@ static GEN
 Flv_producttree(GEN xa, ulong p, long vs)
 {
   long n = lg(xa)-1;
-  long m = expu(n-1)+1;
+  long m = n==1 ? 1: expu(n-1)+1;
   GEN T = cgetg(m+1, t_VEC), t;
   long i, j, k;
   t = cgetg(((n+1)>>1)+1, t_VEC);
@@ -2351,6 +2362,7 @@ Flx_Flv_multieval_tree(GEN P, GEN xa, GEN T, ulong p)
 static GEN
 FlvV_polint_tree(GEN T, GEN R, GEN xa, GEN ya, ulong p, long vs)
 {
+  pari_sp av = avma;
   long m = lg(T)-1, n = lg(ya)-1;
   long i,j,k;
   GEN Tp = cgetg(m+1, t_VEC);
@@ -2376,7 +2388,7 @@ FlvV_polint_tree(GEN T, GEN R, GEN xa, GEN ya, ulong p, long vs)
     if (k==n) gel(t, j) = gel(v, k);
     gel(Tp, i) = t;
   }
-  return gmael(Tp,m,1);
+  return gerepileuptoleaf(av, gmael(Tp,m,1));
 }
 
 GEN
@@ -2399,7 +2411,7 @@ Flv_polint(GEN xa, GEN ya, ulong p, long vs)
 }
 
 GEN
-Flv_FlvV_polint(GEN xa, GEN ya, ulong p, long vs)
+Flv_Flm_polint(GEN xa, GEN ya, ulong p, long vs)
 {
   pari_sp av = avma;
   GEN T = Flv_producttree(xa, p, vs);
@@ -2410,7 +2422,7 @@ Flv_FlvV_polint(GEN xa, GEN ya, ulong p, long vs)
   GEN M = cgetg(l+1, t_VEC);
   for (i=1; i<=l; i++)
     gel(M,i) = FlvV_polint_tree(T, R, xa, gel(ya,i), p, vs);
-  return gerepilecopy(av, M);
+  return gerepileupto(av, M);
 }
 
 /***********************************************************************/
@@ -2451,6 +2463,10 @@ _Flxq_add(void *E, GEN x, GEN y)
 { struct _Flxq *s = (struct _Flxq *)E;
   return Flx_add(x,y,s->p); }
 static GEN
+_Flxq_sub(void *E, GEN x, GEN y)
+{ struct _Flxq *s = (struct _Flxq *)E;
+  return Flx_sub(x,y,s->p); }
+static GEN
 _Flxq_sqr(void *data, GEN x)
 {
   struct _Flxq *D = (struct _Flxq*)data;
@@ -2573,7 +2589,8 @@ Flx_matFrobenius(GEN T, ulong p)
   return Flxq_matrix_pow(Flx_Frobenius(T, p), n, n, T, p);
 }
 
-static struct bb_algebra Flxq_algebra = { _Flxq_red,_Flxq_add,_Flxq_mul,_Flxq_sqr,_Flxq_one,_Flxq_zero};
+static struct bb_algebra Flxq_algebra = { _Flxq_red, _Flxq_add, _Flxq_sub,
+              _Flxq_mul, _Flxq_sqr, _Flxq_one, _Flxq_zero};
 
 GEN
 Flx_FlxqV_eval(GEN Q, GEN x, GEN T, ulong p)
@@ -3439,6 +3456,16 @@ polx_FlxX(long v, long sv)
   gel(z,3) = pol1_Flx(sv); return z;
 }
 
+long
+FlxY_degreex(GEN b)
+{
+  long deg = -1, i;
+  if (!signe(b)) return -1;
+  for (i = 2; i < lg(b); ++i)
+    deg = maxss(deg, degpol(gel(b, i)));
+  return deg;
+}
+
 /*Lift coefficient of B to constant Flx, to give a FlxY*/
 GEN
 Fly_to_FlxY(GEN B, long sv)
@@ -3481,6 +3508,26 @@ FlxX_to_ZXX(GEN B)
   b[1] = B[1]; return b;
 }
 
+GEN
+FlxXC_to_ZXXC(GEN B)
+{
+  long i, l = lg(B);
+  GEN z = cgetg(l, t_COL);
+  for (i=1; i<l; i++)
+    gel(z,i) = FlxX_to_ZXX(gel(B,i));
+  return z;
+}
+
+GEN
+FlxXM_to_ZXXM(GEN B)
+{
+  long i, l = lg(B);
+  GEN z = cgetg(l, t_MAT);
+  for (i=1; i<l; i++)
+    gel(z,i) = FlxXC_to_ZXXC(gel(B,i));
+  return z;
+}
+
 /* Note: v is used _only_ for the t_INT. It must match
  * the variable of any t_POL coefficients. */
 GEN
@@ -3494,7 +3541,7 @@ ZXX_to_FlxX(GEN B, ulong p, long v)
     switch (typ(gel(B,i)))
     {
     case t_INT:
-      gel(b,i) = Z_to_Flx(gel(B,i), p, v);
+      gel(b,i) = Z_to_Flx(gel(B,i), p, evalvarn(v));
       break;
     case t_POL:
       gel(b,i) = ZX_to_Flx(gel(B,i), p);
@@ -3687,6 +3734,17 @@ FlxX_double(GEN x, ulong p)
   return FlxX_renormalize(z, lx);
 }
 
+GEN
+FlxX_deriv(GEN z, ulong p)
+{
+  long i,l = lg(z)-1;
+  GEN x;
+  if (l < 2) l = 2;
+  x = cgetg(l, t_POL); x[1] = z[1];
+  for (i=2; i<l; i++) gel(x,i) = Flx_mulu(gel(z,i+1), (ulong) i-1, p);
+  return FlxX_renormalize(x,l);
+}
+
 static GEN
 FlxX_subspec(GEN x, GEN y, ulong p, long lx, long ly)
 {
@@ -3994,7 +4052,7 @@ FlxqX_Flxq_mul_to_monic(GEN P, GEN U, GEN T, ulong p)
 GEN
 FlxqX_normalize(GEN z, GEN T, ulong p)
 {
-  GEN p1 = leading_term(z);
+  GEN p1 = leading_coeff(z);
   if (!lgpol(z) || (!degpol(p1) && p1[1] == 1)) return z;
   return FlxqX_Flxq_mul_to_monic(z, Flxq_inv(p1,T,p), T,p);
 }
@@ -4020,7 +4078,7 @@ FlxqX_divrem_basecase(GEN x, GEN y, GEN T, ulong p, GEN *pr)
     }
     return pol_0(vx);
   }
-  lead = leading_term(y);
+  lead = leading_coeff(y);
   if (!dy) /* y is constant */
   {
     if (pr && pr != ONLY_DIVIDES)
@@ -4325,19 +4383,232 @@ FlxqX_rem(GEN x, GEN S, GEN T, ulong p)
   }
 }
 
+static GEN
+FlxqX_halfgcd_basecase(GEN a, GEN b, GEN T, ulong p)
+{
+  pari_sp av=avma;
+  GEN u,u1,v,v1;
+  long vx = varn(a);
+  long n = lgpol(a)>>1;
+  u1 = v = pol_0(vx);
+  u = v1 = pol1_FlxX(vx, get_Flx_var(T));
+  while (lgpol(b)>n)
+  {
+    GEN r, q = FlxqX_divrem(a,b, T, p, &r);
+    a = b; b = r; swap(u,u1); swap(v,v1);
+    u1 = FlxX_sub(u1, FlxqX_mul(u, q, T, p), p);
+    v1 = FlxX_sub(v1, FlxqX_mul(v, q ,T, p), p);
+    if (gc_needed(av,2))
+    {
+      if (DEBUGMEM>1) pari_warn(warnmem,"FlxqX_halfgcd (d = %ld)",degpol(b));
+      gerepileall(av,6, &a,&b,&u1,&v1,&u,&v);
+    }
+  }
+  return gerepilecopy(av, mkmat2(mkcol2(u,u1), mkcol2(v,v1)));
+}
+static GEN
+FlxqX_addmulmul(GEN u, GEN v, GEN x, GEN y, GEN T, ulong p)
+{
+  return FlxX_add(FlxqX_mul(u, x, T, p),FlxqX_mul(v, y, T, p), p);
+}
+
+static GEN
+FlxqXM_FlxqX_mul2(GEN M, GEN x, GEN y, GEN T, ulong p)
+{
+  GEN res = cgetg(3, t_COL);
+  gel(res, 1) = FlxqX_addmulmul(gcoeff(M,1,1), gcoeff(M,1,2), x, y, T, p);
+  gel(res, 2) = FlxqX_addmulmul(gcoeff(M,2,1), gcoeff(M,2,2), x, y, T, p);
+  return res;
+}
+
+static GEN
+FlxqXM_mul2(GEN A, GEN B, GEN T, ulong p)
+{
+  GEN A11=gcoeff(A,1,1),A12=gcoeff(A,1,2), B11=gcoeff(B,1,1),B12=gcoeff(B,1,2);
+  GEN A21=gcoeff(A,2,1),A22=gcoeff(A,2,2), B21=gcoeff(B,2,1),B22=gcoeff(B,2,2);
+  GEN M1 = FlxqX_mul(FlxX_add(A11,A22, p), FlxX_add(B11,B22, p), T, p);
+  GEN M2 = FlxqX_mul(FlxX_add(A21,A22, p), B11, T, p);
+  GEN M3 = FlxqX_mul(A11, FlxX_sub(B12,B22, p), T, p);
+  GEN M4 = FlxqX_mul(A22, FlxX_sub(B21,B11, p), T, p);
+  GEN M5 = FlxqX_mul(FlxX_add(A11,A12, p), B22, T, p);
+  GEN M6 = FlxqX_mul(FlxX_sub(A21,A11, p), FlxX_add(B11,B12, p), T, p);
+  GEN M7 = FlxqX_mul(FlxX_sub(A12,A22, p), FlxX_add(B21,B22, p), T, p);
+  GEN T1 = FlxX_add(M1,M4, p), T2 = FlxX_sub(M7,M5, p);
+  GEN T3 = FlxX_sub(M1,M2, p), T4 = FlxX_add(M3,M6, p);
+  retmkmat2(mkcol2(FlxX_add(T1,T2, p), FlxX_add(M2,M4, p)),
+            mkcol2(FlxX_add(M3,M5, p), FlxX_add(T3,T4, p)));
+}
+
+/* Return [0,1;1,-q]*M */
+static GEN
+FlxqX_FlxqXM_qmul(GEN q, GEN M, GEN T, ulong p)
+{
+  GEN u, v, res = cgetg(3, t_MAT);
+  u = FlxX_sub(gcoeff(M,1,1), FlxqX_mul(gcoeff(M,2,1), q, T, p), p);
+  gel(res,1) = mkcol2(gcoeff(M,2,1), u);
+  v = FlxX_sub(gcoeff(M,1,2), FlxqX_mul(gcoeff(M,2,2), q, T, p), p);
+  gel(res,2) = mkcol2(gcoeff(M,2,2), v);
+  return res;
+}
+
+static GEN
+matid2_FlxXM(long v, long sv)
+{
+  retmkmat2(mkcol2(pol1_FlxX(v, sv),pol_0(v)),
+            mkcol2(pol_0(v),pol1_FlxX(v, sv)));
+}
+
+static GEN
+FlxqX_halfgcd_split(GEN x, GEN y, GEN T, ulong p)
+{
+  pari_sp av=avma;
+  GEN R, S, V;
+  GEN y1, r, q;
+  long l = lgpol(x), n = l>>1, k;
+  if (lgpol(y)<=n) return matid2_FlxXM(varn(x),T[1]);
+  R = FlxqX_halfgcd(RgX_shift_shallow(x,-n),RgX_shift_shallow(y,-n), T, p);
+  V = FlxqXM_FlxqX_mul2(R,x,y, T, p); y1 = gel(V,2);
+  if (lgpol(y1)<=n) return gerepilecopy(av, R);
+  q = FlxqX_divrem(gel(V,1), y1, T, p, &r);
+  k = 2*n-degpol(y1);
+  S = FlxqX_halfgcd(RgX_shift_shallow(y1,-k), RgX_shift_shallow(r,-k), T, p);
+  return gerepileupto(av, FlxqXM_mul2(S,FlxqX_FlxqXM_qmul(q,R, T, p), T, p));
+}
+
+/* Return M in GL_2(Fp[X]) such that:
+if [a',b']~=M*[a,b]~ then degpol(a')>= (lgpol(a)>>1) >degpol(b')
+*/
+
+static GEN
+FlxqX_halfgcd_i(GEN x, GEN y, GEN T, ulong p)
+{
+  if (lg(x)<=FlxqX_HALFGCD_LIMIT) return FlxqX_halfgcd_basecase(x, y, T, p);
+  return FlxqX_halfgcd_split(x, y, T, p);
+}
+
 GEN
-FlxqX_gcd(GEN x, GEN y, GEN T, ulong p)
+FlxqX_halfgcd(GEN x, GEN y, GEN T, ulong p)
 {
-  GEN a,b,c;
-  pari_sp av0, av=avma;
+  pari_sp av = avma;
+  GEN M,q,r;
+  if (!signe(x))
+  {
+    long v = varn(x), vT = get_Flx_var(T);
+    retmkmat2(mkcol2(pol_0(v),pol1_FlxX(v,vT)),
+        mkcol2(pol1_FlxX(v,vT),pol_0(v)));
+  }
+  if (degpol(y)<degpol(x)) return FlxqX_halfgcd_i(x, y, T, p);
+  q = FlxqX_divrem(y, x, T, p, &r);
+  M = FlxqX_halfgcd_i(x, r, T, p);
+  gcoeff(M,1,1) = FlxX_sub(gcoeff(M,1,1), FlxqX_mul(q, gcoeff(M,1,2), T, p), p);
+  gcoeff(M,2,1) = FlxX_sub(gcoeff(M,2,1), FlxqX_mul(q, gcoeff(M,2,2), T, p), p);
+  return gerepilecopy(av, M);
+}
 
-  a = FlxqX_red(x, T, p); av0 = avma;
-  b = FlxqX_red(y, T, p);
+static GEN
+FlxqX_gcd_basecase(GEN a, GEN b, GEN T, ulong p)
+{
+  pari_sp av = avma, av0=avma;
   while (signe(b))
   {
-    av0 = avma; c = FlxqX_rem(a,b,T,p); a=b; b=c;
+    GEN c;
+    if (gc_needed(av0,2))
+    {
+      if (DEBUGMEM>1) pari_warn(warnmem,"FlxqX_gcd (d = %ld)",degpol(b));
+      gerepileall(av0,2, &a,&b);
+    }
+    av = avma; c = FlxqX_rem(a, b, T, p); a=b; b=c;
+  }
+  avma = av; return a;
+}
+
+GEN
+FlxqX_gcd(GEN x, GEN y, GEN T, ulong p)
+{
+  pari_sp av = avma;
+  x = FlxqX_red(x, T, p);
+  y = FlxqX_red(y, T, p);
+  if (!signe(x)) return gerepileupto(av, y);
+  while (lg(y)>FlxqX_GCD_LIMIT)
+  {
+    GEN c;
+    if (lgpol(y)<=(lgpol(x)>>1))
+    {
+      GEN r = FlxqX_rem(x, y, T, p);
+      x = y; y = r;
+    }
+    c = FlxqXM_FlxqX_mul2(FlxqX_halfgcd(x,y, T, p), x, y, T, p);
+    x = gel(c,1); y = gel(c,2);
+    gerepileall(av,2,&x,&y);
+  }
+  return gerepileupto(av, FlxqX_gcd_basecase(x, y, T, p));
+}
+
+static GEN
+FlxqX_extgcd_basecase(GEN a, GEN b, GEN T, ulong p, GEN *ptu, GEN *ptv)
+{
+  pari_sp av=avma;
+  GEN u,v,d,d1,v1;
+  long vx = varn(a);
+  d = a; d1 = b;
+  v = pol_0(vx); v1 = pol1_FlxX(vx, get_Flx_var(T));
+  while (signe(d1))
+  {
+    GEN r, q = FlxqX_divrem(d, d1, T, p, &r);
+    v = FlxX_sub(v,FlxqX_mul(q,v1,T, p),p);
+    u=v; v=v1; v1=u;
+    u=r; d=d1; d1=u;
+    if (gc_needed(av,2))
+    {
+      if (DEBUGMEM>1) pari_warn(warnmem,"FlxqX_extgcd (d = %ld)",degpol(d));
+      gerepileall(av,5, &d,&d1,&u,&v,&v1);
+    }
+  }
+  if (ptu) *ptu = FlxqX_div(FlxX_sub(d,FlxqX_mul(b,v, T, p), p), a, T, p);
+  *ptv = v; return d;
+}
+
+static GEN
+FlxqX_extgcd_halfgcd(GEN x, GEN y, GEN T, ulong p, GEN *ptu, GEN *ptv)
+{
+  pari_sp av=avma;
+  GEN u,v,R = matid2_FlxXM(varn(x), get_Flx_var(T));
+  while (lg(y)>FlxqX_EXTGCD_LIMIT)
+  {
+    GEN M, c;
+    if (lgpol(y)<=(lgpol(x)>>1))
+    {
+      GEN r, q = FlxqX_divrem(x, y, T, p, &r);
+      x = y; y = r;
+      R = FlxqX_FlxqXM_qmul(q, R, T, p);
+    }
+    M = FlxqX_halfgcd(x,y, T, p);
+    c = FlxqXM_FlxqX_mul2(M, x,y, T, p);
+    R = FlxqXM_mul2(M, R, T, p);
+    x = gel(c,1); y = gel(c,2);
+    gerepileall(av,3,&x,&y,&R);
   }
-  avma = av0; return gerepileupto(av, a);
+  y = FlxqX_extgcd_basecase(x,y, T, p, &u,&v);
+  if (ptu) *ptu = FlxqX_addmulmul(u,v,gcoeff(R,1,1),gcoeff(R,2,1), T, p);
+  *ptv = FlxqX_addmulmul(u,v,gcoeff(R,1,2),gcoeff(R,2,2), T, p);
+  return y;
+}
+
+/* x and y in Z[Y][X], return lift(gcd(x mod T,p, y mod T,p)). Set u and v st
+ * ux + vy = gcd (mod T,p) */
+GEN
+FlxqX_extgcd(GEN x, GEN y, GEN T, ulong p, GEN *ptu, GEN *ptv)
+{
+  GEN d;
+  pari_sp ltop=avma;
+  x = FlxqX_red(x, T, p);
+  y = FlxqX_red(y, T, p);
+  if (lg(y)>FlxqX_EXTGCD_LIMIT)
+    d = FlxqX_extgcd_halfgcd(x, y, T, p, ptu, ptv);
+  else
+    d = FlxqX_extgcd_basecase(x, y, T, p, ptu, ptv);
+  gerepileall(ltop,ptu?3:2,&d,ptv,ptu);
+  return d;
 }
 
 GEN
@@ -4350,7 +4621,7 @@ FlxqX_safegcd(GEN P, GEN Q, GEN T, ulong p)
   btop = avma;
   for(;;)
   {
-    U = Flxq_invsafe(leading_term(Q), T, p);
+    U = Flxq_invsafe(leading_coeff(Q), T, p);
     if (!U) { avma = ltop; return NULL; }
     Q = FlxqX_Flxq_mul_to_monic(Q,U,T,p);
     P = FlxqX_rem(P,Q,T,p);
@@ -4365,27 +4636,6 @@ FlxqX_safegcd(GEN P, GEN Q, GEN T, ulong p)
   return gerepileupto(ltop, Q);
 }
 
-GEN
-FlxqX_extgcd(GEN a, GEN b, GEN T, ulong p, GEN *ptu, GEN *ptv)
-{
-  GEN q, r, u, v, d, d1, v1;
-  long vx = varn(a);
-  pari_sp ltop=avma;
-
-  d = a; d1 = b; v = pol_0(vx); v1 = pol1_FlxX(vx,get_Flx_var(T));
-  while (signe(d1))
-  {
-    q = FlxqX_divrem(d,d1,T,p, &r);
-    v = FlxX_sub(v, FlxqX_mul(q,v1, T,p), p);
-    u=v; v=v1; v1=u;
-    u=r; d=d1; d1=u;
-  }
-  if (ptu) *ptu = FlxqX_div(FlxX_sub(d, FlxqX_mul(b,v, T,p), p), a, T,p);
-  *ptv = v;
-  gerepileall(ltop,ptu?3:2,&d,ptv,ptu);
-  return d;
-}
-
 struct _FlxqX {ulong p; GEN T;};
 static GEN _FlxqX_mul(void *data,GEN a,GEN b)
 {
@@ -4399,7 +4649,7 @@ static GEN _FlxqX_sqr(void *data,GEN a)
 }
 
 GEN
-FlxqX_pow(GEN V, long n, GEN T, ulong p)
+FlxqX_powu(GEN V, ulong n, GEN T, ulong p)
 {
   struct _FlxqX d; d.p=p; d.T=T;
   return gen_powu(V, n, (void*)&d, &_FlxqX_sqr, &_FlxqX_mul);
@@ -4697,55 +4947,72 @@ FlxqXQ_div(GEN x, GEN y, GEN S, GEN T, ulong p) {
   return FlxqXQ_mul(x, FlxqXQ_inv(y,S,T,p),S,T,p);
 }
 
-typedef struct {
+struct _FlxqXQ {
   GEN T, S;
   ulong p;
-} FlxqXQ_muldata;
+};
 static GEN
 _FlxqXQ_add(void *data, GEN x, GEN y) {
-  FlxqXQ_muldata *d = (FlxqXQ_muldata*) data;
+  struct _FlxqXQ *d = (struct _FlxqXQ*) data;
   return FlxX_add(x,y, d->p);
 }
 static GEN
+_FlxqXQ_sub(void *data, GEN x, GEN y) {
+  struct _FlxqXQ *d = (struct _FlxqXQ*) data;
+  return FlxX_sub(x,y, d->p);
+}
+static GEN
 _FlxqXQ_cmul(void *data, GEN P, long a, GEN x) {
-  FlxqXQ_muldata *d = (FlxqXQ_muldata*) data;
+  struct _FlxqXQ *d = (struct _FlxqXQ*) data;
   return FlxX_Flx_mul(x,gel(P,a+2), d->p);
 }
 static GEN
 _FlxqXQ_red(void *data, GEN x) {
-  FlxqXQ_muldata *d = (FlxqXQ_muldata*) data;
+  struct _FlxqXQ *d = (struct _FlxqXQ*) data;
   return FlxqX_red(x, d->T, d->p);
 }
 static GEN
 _FlxqXQ_mul(void *data, GEN x, GEN y) {
-  FlxqXQ_muldata *d = (FlxqXQ_muldata*) data;
+  struct _FlxqXQ *d = (struct _FlxqXQ*) data;
   return FlxqXQ_mul(x,y, d->S,d->T, d->p);
 }
 static GEN
 _FlxqXQ_sqr(void *data, GEN x) {
-  FlxqXQ_muldata *d = (FlxqXQ_muldata*) data;
+  struct _FlxqXQ *d = (struct _FlxqXQ*) data;
   return FlxqXQ_sqr(x, d->S,d->T, d->p);
 }
 
 static GEN
 _FlxqXQ_one(void *data) {
-  FlxqXQ_muldata *d = (FlxqXQ_muldata*) data;
-  return pol1_FlxX(varn(d->S),d->T[1]);
+  struct _FlxqXQ *d = (struct _FlxqXQ*) data;
+  return pol1_FlxX(get_FlxqX_var(d->S),get_Flx_var(d->T));
 }
 
 static GEN
 _FlxqXQ_zero(void *data) {
-  FlxqXQ_muldata *d = (FlxqXQ_muldata*) data;
-  return pol_0(varn(d->S));
+  struct _FlxqXQ *d = (struct _FlxqXQ*) data;
+  return pol_0(get_FlxqX_var(d->S));
 }
 
-static struct bb_algebra FlxqXQ_algebra = { _FlxqXQ_red,_FlxqXQ_add,_FlxqXQ_mul,_FlxqXQ_sqr,_FlxqXQ_one,_FlxqXQ_zero };
+static struct bb_algebra FlxqXQ_algebra = { _FlxqXQ_red, _FlxqXQ_add,
+       _FlxqXQ_sub, _FlxqXQ_mul, _FlxqXQ_sqr, _FlxqXQ_one, _FlxqXQ_zero };
+
+const struct bb_algebra *
+get_FlxqXQ_algebra(void **E, GEN S, GEN T, ulong p)
+{
+  GEN z = new_chunk(sizeof(struct _FlxqXQ));
+  struct _FlxqXQ *e = (struct _FlxqXQ *) z;
+  e->T = Flx_get_red(T, p);
+  e->S = FlxqX_get_red(S, e->T, p);
+  e->p  = p; *E = (void*)e;
+  return &FlxqXQ_algebra;
+}
 
 /* x over Fq, return lift(x^n) mod S */
 GEN
 FlxqXQ_pow(GEN x, GEN n, GEN S, GEN T, ulong p)
 {
-  FlxqXQ_muldata D;
+  struct _FlxqXQ D;
   long s = signe(n);
   if (!s) return pol1_FlxX(get_FlxqX_var(S),get_Flx_var(T));
   if (s < 0) x = FlxqXQ_inv(x,S,T,p);
@@ -4759,10 +5026,27 @@ FlxqXQ_pow(GEN x, GEN n, GEN S, GEN T, ulong p)
   return gen_pow(x, n, (void*)&D, &_FlxqXQ_sqr, &_FlxqXQ_mul);
 }
 
+/* x over Fq, return lift(x^n) mod S */
+GEN
+FlxqXQ_powu(GEN x, ulong n, GEN S, GEN T, ulong p)
+{
+  struct _FlxqXQ D;
+  switch(n)
+  {
+    case 0: return pol1_FlxX(get_FlxqX_var(S),get_Flx_var(T));
+    case 1: return gcopy(x);
+    case 2: return FlxqXQ_sqr(x, S, T, p);
+  }
+  T = Flx_get_red(T, p);
+  S = FlxqX_get_red(S, T, p);
+  D.S = S; D.T = T; D.p = p;
+  return gen_powu(x, n, (void*)&D, &_FlxqXQ_sqr, &_FlxqXQ_mul);
+}
+
 GEN
 FlxqXQ_powers(GEN x, long l, GEN S, GEN T, ulong p)
 {
-  FlxqXQ_muldata D;
+  struct _FlxqXQ D;
   int use_sqr = 2*degpol(x) >= get_FlxqX_degree(S);
   T = Flx_get_red(T, p);
   S = FlxqX_get_red(S, T, p);
@@ -4779,7 +5063,7 @@ FlxqXQ_matrix_pow(GEN y, long n, long m, GEN S, GEN T, ulong p)
 GEN
 FlxqX_FlxqXQV_eval(GEN P, GEN V, GEN S, GEN T, ulong p)
 {
-  FlxqXQ_muldata D;
+  struct _FlxqXQ D;
   T = Flx_get_red(T, p);
   S = FlxqX_get_red(S, T, p);
   D.S=S; D.T=T; D.p=p;
@@ -4790,7 +5074,7 @@ FlxqX_FlxqXQV_eval(GEN P, GEN V, GEN S, GEN T, ulong p)
 GEN
 FlxqX_FlxqXQ_eval(GEN Q, GEN x, GEN S, GEN T, ulong p)
 {
-  FlxqXQ_muldata D;
+  struct _FlxqXQ D;
   int use_sqr = 2*degpol(x) >= degpol(S);
   T = Flx_get_red(T, p);
   S = FlxqX_get_red(S, T, p);
@@ -4802,7 +5086,7 @@ FlxqX_FlxqXQ_eval(GEN Q, GEN x, GEN S, GEN T, ulong p)
 static GEN
 FlxqXQ_autpow_sqr(void * E, GEN x)
 {
-  FlxqXQ_muldata *D = (FlxqXQ_muldata *)E;
+  struct _FlxqXQ *D = (struct _FlxqXQ *)E;
   GEN T = D->T;
   ulong p = D->p;
   GEN phi = gel(x,1), S = gel(x,2);
@@ -4817,7 +5101,7 @@ FlxqXQ_autpow_sqr(void * E, GEN x)
 static GEN
 FlxqXQ_autpow_mul(void * E, GEN x, GEN y)
 {
-  FlxqXQ_muldata *D = (FlxqXQ_muldata *)E;
+  struct _FlxqXQ *D = (struct _FlxqXQ *)E;
   GEN T = D->T;
   ulong p = D->p;
   GEN phi1 = gel(x,1), S1 = gel(x,2);
@@ -4833,7 +5117,7 @@ FlxqXQ_autpow_mul(void * E, GEN x, GEN y)
 GEN
 FlxqXQV_autpow(GEN aut, long n, GEN S, GEN T, ulong p)
 {
-  FlxqXQ_muldata D;
+  struct _FlxqXQ D;
   T = Flx_get_red(T, p);
   S = FlxqX_get_red(S, T, p);
   D.S=S; D.T=T; D.p=p;
@@ -4843,7 +5127,7 @@ FlxqXQV_autpow(GEN aut, long n, GEN S, GEN T, ulong p)
 static GEN
 FlxqXQ_autsum_mul(void *E, GEN x, GEN y)
 {
-  FlxqXQ_muldata *D = (FlxqXQ_muldata *)E;
+  struct _FlxqXQ *D = (struct _FlxqXQ *)E;
   GEN T = D->T;
   ulong p = D->p;
   GEN phi1 = gel(x,1), S1 = gel(x,2), a1 = gel(x,3);
@@ -4869,7 +5153,7 @@ FlxqXQ_autsum_sqr(void * T, GEN x)
 GEN
 FlxqXQV_autsum(GEN aut, long n, GEN S, GEN T, ulong p)
 {
-  FlxqXQ_muldata D;
+  struct _FlxqXQ D;
   T = Flx_get_red(T, p);
   S = FlxqX_get_red(S, T, p);
   D.S=S; D.T=T; D.p=p;
diff --git a/src/basemath/FlxqE.c b/src/basemath/FlxqE.c
index 941b670..5417efd 100644
--- a/src/basemath/FlxqE.c
+++ b/src/basemath/FlxqE.c
@@ -320,11 +320,46 @@ FlxqE_log(GEN a, GEN b, GEN o, GEN a4, GEN T, ulong p)
 /* Derived from APIP from and by Jerome Milan, 2012 */
 
 static GEN
-FlxqE_vert(GEN P, GEN Q, GEN T, ulong p)
+FlxqE_vert(GEN P, GEN Q, GEN a4, GEN T, ulong p)
 {
+  long vT = get_Flx_var(T);
+  GEN df;
   if (ell_is_inf(P))
-    return pol1_Flx(get_Flx_var(T));
-  return Flx_sub(gel(Q, 1), gel(P, 1), p);
+    return pol1_Flx(vT);
+  if (!Flx_equal(gel(Q, 1), gel(P, 1)))
+    return Flx_sub(gel(Q, 1), gel(P, 1), p);
+  if (lgpol(gel(P,2))!=0) return pol1_Flx(vT);
+  df = typ(a4)==t_VEC ? Flxq_mul(gel(P,1), Flx_mulu(gel(a4, 1), 2, p), T, p)
+                      : a4;
+  return Flxq_inv(Flx_add(Flx_mulu(Flxq_sqr(gel(P,1), T, p), 3, p),
+                          df, p), T, p);
+}
+
+static GEN
+FlxqE_Miller_line(GEN R, GEN Q, GEN slope, GEN a4, GEN T, ulong p)
+{
+  long vT = get_Flx_var(T);
+  GEN x = gel(Q, 1), y = gel(Q, 2);
+  GEN tmp1 = Flx_sub(x, gel(R, 1), p);
+  GEN tmp2 = Flx_add(Flxq_mul(tmp1, slope, T, p), gel(R, 2), p);
+  if (!Flx_equal(y, tmp2))
+    return Flx_sub(y, tmp2, p);
+  if (lgpol(y) == 0)
+    return pol1_Flx(vT);
+  else
+  {
+    GEN s1, s2, a2 = typ(a4)==t_VEC ? gel(a4,1): NULL;
+    GEN y2i = Flxq_inv(Flx_mulu(y, 2, p), T, p);
+    GEN df = a2 ? Flxq_mul(x, Flx_mulu(a2, 2, p), T, p): a4;
+    GEN x3, ddf;
+    s1 = Flxq_mul(Flx_add(Flx_mulu(Flxq_sqr(x, T, p), 3, p), df, p), y2i, T, p);
+    if (!Flx_equal(s1, slope))
+      return Flx_sub(s1, slope, p);
+    x3 = Flx_mulu(x, 3, p);
+    ddf = a2 ? Flx_add(x3, a2, p): x3;
+    s2 = Flxq_mul(Flx_sub(ddf, Flxq_sqr(s1, T, p), p), y2i, T, p);
+    return lgpol(s2)!=0 ? s2: y2i;
+  }
 }
 
 /* Computes the equation of the line tangent to R and returns its
@@ -342,13 +377,11 @@ FlxqE_tangent_update(GEN R, GEN Q, GEN a4, GEN T, ulong p, GEN *pt_R)
   else if (!lgpol(gel(R,2)))
   {
     *pt_R = ellinf();
-    return FlxqE_vert(R, Q, T, p);
+    return FlxqE_vert(R, Q, a4, T, p);
   } else {
-    GEN slope, tmp1, tmp2;
+    GEN slope;
     *pt_R = FlxqE_dbl_slope(R, a4, T, p, &slope);
-    tmp1 = Flx_sub(gel(Q, 1), gel(R, 1), p);
-    tmp2 = Flx_add(Flxq_mul(tmp1, slope, T, p), gel(R,2), p);
-    return Flx_sub(gel(Q, 2), tmp2, p);
+    return FlxqE_Miller_line(R, Q, slope, a4, T, p);
   }
 }
 
@@ -362,12 +395,12 @@ FlxqE_chord_update(GEN R, GEN P, GEN Q, GEN a4, GEN T, ulong p, GEN *pt_R)
   if (ell_is_inf(R))
   {
     *pt_R = gcopy(P);
-    return FlxqE_vert(P, Q, T, p);
+    return FlxqE_vert(P, Q, a4, T, p);
   }
   else if (ell_is_inf(P))
   {
     *pt_R = gcopy(R);
-    return FlxqE_vert(R, Q, T, p);
+    return FlxqE_vert(R, Q, a4, T, p);
   }
   else if (Flx_equal(gel(P, 1), gel(R, 1)))
   {
@@ -376,14 +409,12 @@ FlxqE_chord_update(GEN R, GEN P, GEN Q, GEN a4, GEN T, ulong p, GEN *pt_R)
     else
     {
       *pt_R = ellinf();
-      return FlxqE_vert(R, Q, T, p);
+      return FlxqE_vert(R, Q, a4, T, p);
     }
   } else {
-    GEN slope, tmp1, tmp2;
+    GEN slope;
     *pt_R = FlxqE_add_slope(P, R, a4, T, p, &slope);
-    tmp1  = Flxq_mul(Flx_sub(gel(Q, 1), gel(R, 1), p), slope, T, p);
-    tmp2  = Flx_add(tmp1, gel(R, 2), p);
-    return Flx_sub(gel(Q, 2), tmp2, p);
+    return FlxqE_Miller_line(R, Q, slope, a4, T, p);
   }
 }
 
@@ -409,7 +440,7 @@ FlxqE_Miller_dbl(void* E, GEN d)
   GEN point = gel(d,3);
   line = FlxqE_tangent_update(point, P, a4, T, p, &point);
   num  = Flxq_mul(num, line, T, p);
-  v = FlxqE_vert(point, P, T, p);
+  v = FlxqE_vert(point, P, a4, T, p);
   denom = Flxq_mul(denom, v, T, p);
   return mkvec3(num, denom, point);
 }
@@ -427,7 +458,7 @@ FlxqE_Miller_add(void* E, GEN va, GEN vb)
   GEN denom = Flxq_mul(da, db, T, p);
   line = FlxqE_chord_update(pa, pb, P, a4, T, p, &point);
   num  = Flxq_mul(num, line, T, p);
-  v = FlxqE_vert(point, P, T, p);
+  v = FlxqE_vert(point, P, a4, T, p);
   denom = Flxq_mul(denom, v, T, p);
   return mkvec3(num, denom, point);
 }
@@ -443,7 +474,6 @@ FlxqE_Miller(GEN Q, GEN P, GEN m, GEN a4, GEN T, ulong p)
   g1 = pol1_Flx(get_Flx_var(T));
   v = gen_pow(mkvec3(g1,g1,Q), m, (void*)&d, FlxqE_Miller_dbl, FlxqE_Miller_add);
   num = gel(v,1); denom = gel(v,2);
-  if (!lgpol(num) || !lgpol(denom)) { avma = ltop; return NULL; }
   return gerepileupto(ltop, Flxq_div(num, denom, T, p));
 }
 
@@ -455,9 +485,7 @@ FlxqE_weilpairing(GEN P, GEN Q, GEN m, GEN a4, GEN T, ulong p)
   if (ell_is_inf(P) || ell_is_inf(Q) || Flx_equal(P,Q))
     return pol1_Flx(get_Flx_var(T));
   num    = FlxqE_Miller(P, Q, m, a4, T, p);
-  if (!num) return pol1_Flx(get_Flx_var(T));
   denom  = FlxqE_Miller(Q, P, m, a4, T, p);
-  if (!denom) {avma = ltop; return pol1_Flx(get_Flx_var(T)); }
   result = Flxq_div(num, denom, T, p);
   if (mpodd(m))
     result  = Flx_neg(result, p);
@@ -467,11 +495,9 @@ FlxqE_weilpairing(GEN P, GEN Q, GEN m, GEN a4, GEN T, ulong p)
 GEN
 FlxqE_tatepairing(GEN P, GEN Q, GEN m, GEN a4, GEN T, ulong p)
 {
-  GEN num;
   if (ell_is_inf(P) || ell_is_inf(Q))
     return pol1_Flx(get_Flx_var(T));
-  num = FlxqE_Miller(P, Q, m, a4, T, p);
-  return num? num: pol1_Flx(get_Flx_var(T));
+  return FlxqE_Miller(P, Q, m, a4, T, p);
 }
 
 static GEN
@@ -793,7 +819,7 @@ getc2(GEN act, GEN X, GEN T, GEN q, ulong p, long N)
   GEN xp = FpXQ_powers(X,n,T,q);
   GEN P  = FpX_FpXQV_eval(A1, xp, T, q);
   GEN Q  = FpX_FpXQV_eval(A2, xp, T, q);
-  return FpXQ_mul(P,ZpXQ_inv(Q,T,utoi(p),N),T,q);
+  return ZpXQ_div(P, Q, T, q, utoi(p), N);
 }
 
 struct _ZpXQ_norm
@@ -925,7 +951,7 @@ get_norm(GEN a4, GEN a6, GEN T, ulong p, long N)
   else
   {
     GEN P = mkpoln(4, pol1_Flx(sv), pol0_Flx(sv), a4, a6);
-    a = gel(FlxqX_pow(P,p>>1,T,p),2+p-1);
+    a = gel(FlxqX_powu(P,p>>1,T,p),2+p-1);
   }
   return Zp_sqrtnlift(gen_1,subss(p,1),utoi(Flxq_norm(a,T,p)),utoi(p), N);
 }
@@ -1144,7 +1170,7 @@ get_H1(GEN A41, GEN A61, GEN T2, ulong p)
 {
   GEN q = utoi(p), T = FpXT_red(T2,q);
   GEN pol = FpXQ_elldivpol(FpX_red(A41,q),FpX_red(A61,q),p,T,q);
-  return FqX_normalize(RgX_deflate(pol,p),T,q);
+  return FpXQX_normalize(RgX_deflate(pol,p),T,q);
 }
 
 static GEN
@@ -1503,7 +1529,7 @@ Flxq_ellcard_Kedlaya(GEN a4, GEN a6, GEN T, ulong p)
   GEN N = ZpXQM_prodFrobenius(M, Tp, utoi(p), e);
   GEN q = powuu(p, e);
   GEN tp = Fq_add(gcoeff(N,1,1), gcoeff(N,2,2), Tp, q);
-  GEN t = Fp_center(typ(tp)==t_INT ? tp: leading_term(tp), q, shifti(q,-1));
+  GEN t = Fp_center(typ(tp)==t_INT ? tp: leading_coeff(tp), q, shifti(q,-1));
   return gerepileupto(av, subii(addis(powuu(p, n), 1), t));
 }
 
diff --git a/src/basemath/FpE.c b/src/basemath/FpE.c
index 6a2858f..ea8243c 100644
--- a/src/basemath/FpE.c
+++ b/src/basemath/FpE.c
@@ -296,11 +296,36 @@ FpE_log(GEN a, GEN b, GEN o, GEN a4, GEN p)
 /* Derived from APIP from and by Jerome Milan, 2012 */
 
 static GEN
-FpE_vert(GEN P, GEN Q, GEN p)
+FpE_vert(GEN P, GEN Q, GEN a4, GEN p)
 {
   if (ell_is_inf(P))
     return gen_1;
-  return Fp_sub(gel(Q, 1), gel(P, 1), p);
+  if (!equalii(gel(Q, 1), gel(P, 1)))
+    return Fp_sub(gel(Q, 1), gel(P, 1), p);
+  if (signe(gel(P,2))!=0) return gen_1;
+  return Fp_inv(Fp_add(Fp_mulu(Fp_sqr(gel(P,1),p), 3, p), a4, p), p);
+}
+
+static GEN
+FpE_Miller_line(GEN R, GEN Q, GEN slope, GEN a4, GEN p)
+{
+  GEN x = gel(Q, 1), y = gel(Q, 2);
+  GEN tmp1 = Fp_sub(x, gel(R, 1), p);
+  GEN tmp2 = Fp_add(Fp_mul(tmp1, slope, p), gel(R,2), p);
+  if (!equalii(y, tmp2))
+    return Fp_sub(y, tmp2, p);
+  if (signe(y) == 0)
+    return gen_1;
+  else
+  {
+    GEN s1, s2;
+    GEN y2i = Fp_inv(Fp_mulu(y, 2, p), p);
+    s1 = Fp_mul(Fp_add(Fp_mulu(Fp_sqr(x, p), 3, p), a4, p), y2i, p);
+    if (!equalii(s1, slope))
+      return Fp_sub(s1, slope, p);
+    s2 = Fp_mul(Fp_sub(Fp_mulu(x, 3, p), Fp_sqr(s1, p), p), y2i, p);
+    return signe(s2)!=0 ? s2: y2i;
+  }
 }
 
 /* Computes the equation of the line tangent to R and returns its
@@ -318,13 +343,11 @@ FpE_tangent_update(GEN R, GEN Q, GEN a4, GEN p, GEN *pt_R)
   else if (signe(gel(R,2)) == 0)
   {
     *pt_R = ellinf();
-    return FpE_vert(R, Q, p);
+    return FpE_vert(R, Q, a4, p);
   } else {
-    GEN slope, tmp1, tmp2;
+    GEN slope;
     *pt_R = FpE_dbl_slope(R, a4, p, &slope);
-    tmp1 = Fp_sub(gel(Q, 1), gel(R, 1), p);
-    tmp2 = Fp_add(Fp_mul(tmp1, slope, p), gel(R,2), p);
-    return Fp_sub(gel(Q, 2), tmp2, p);
+    return FpE_Miller_line(R, Q, slope, a4, p);
   }
 }
 
@@ -338,12 +361,12 @@ FpE_chord_update(GEN R, GEN P, GEN Q, GEN a4, GEN p, GEN *pt_R)
   if (ell_is_inf(R))
   {
     *pt_R = gcopy(P);
-    return FpE_vert(P, Q, p);
+    return FpE_vert(P, Q, a4, p);
   }
   else if (ell_is_inf(P))
   {
     *pt_R = gcopy(R);
-    return FpE_vert(R, Q, p);
+    return FpE_vert(R, Q, a4, p);
   }
   else if (equalii(gel(P, 1), gel(R, 1)))
   {
@@ -351,14 +374,12 @@ FpE_chord_update(GEN R, GEN P, GEN Q, GEN a4, GEN p, GEN *pt_R)
       return FpE_tangent_update(R, Q, a4, p, pt_R);
     else {
       *pt_R = ellinf();
-      return FpE_vert(R, Q, p);
+      return FpE_vert(R, Q, a4, p);
     }
   } else {
-    GEN slope, tmp1, tmp2;
+    GEN slope;
     *pt_R = FpE_add_slope(P, R, a4, p, &slope);
-    tmp1  = Fp_mul(Fp_sub(gel(Q, 1), gel(R, 1), p), slope, p);
-    tmp2  = Fp_add(tmp1, gel(R, 2), p);
-    return Fp_sub(gel(Q, 2), tmp2, p);
+    return FpE_Miller_line(R, Q, slope, a4, p);
   }
 }
 
@@ -382,7 +403,7 @@ FpE_Miller_dbl(void* E, GEN d)
   GEN point = gel(d,3);
   line = FpE_tangent_update(point, P, a4, p, &point);
   num  = Fp_mul(num, line, p);
-  v = FpE_vert(point, P, p);
+  v = FpE_vert(point, P, a4, p);
   denom = Fp_mul(denom, v, p);
   return mkvec3(num, denom, point);
 }
@@ -399,7 +420,7 @@ FpE_Miller_add(void* E, GEN va, GEN vb)
   GEN denom = Fp_mul(da, db, p);
   line = FpE_chord_update(pa, pb, P, a4, p, &point);
   num  = Fp_mul(num, line, p);
-  v = FpE_vert(point, P, p);
+  v = FpE_vert(point, P, a4, p);
   denom = Fp_mul(denom, v, p);
   return mkvec3(num, denom, point);
 }
@@ -414,7 +435,6 @@ FpE_Miller(GEN Q, GEN P, GEN m, GEN a4, GEN p)
   d.a4 = a4; d.p = p; d.P = P;
   v = gen_pow(mkvec3(gen_1,gen_1,Q), m, (void*)&d, FpE_Miller_dbl, FpE_Miller_add);
   num = gel(v,1); denom = gel(v,2);
-  if (!signe(num) || !signe(denom)) { avma = ltop; return NULL; }
   return gerepileupto(ltop, Fp_div(num, denom, p));
 }
 
@@ -426,9 +446,7 @@ FpE_weilpairing(GEN P, GEN Q, GEN m, GEN a4, GEN p)
   if (ell_is_inf(P) || ell_is_inf(Q) || ZV_equal(P,Q))
     return gen_1;
   num    = FpE_Miller(P, Q, m, a4, p);
-  if (!num) return gen_1;
   denom  = FpE_Miller(Q, P, m, a4, p);
-  if (!denom) { avma = ltop; return gen_1; }
   result = Fp_div(num, denom, p);
   if (mpodd(m))
     result  = Fp_neg(result, p);
@@ -438,11 +456,9 @@ FpE_weilpairing(GEN P, GEN Q, GEN m, GEN a4, GEN p)
 GEN
 FpE_tatepairing(GEN P, GEN Q, GEN m, GEN a4, GEN p)
 {
-  GEN num;
   if (ell_is_inf(P) || ell_is_inf(Q))
     return gen_1;
-  num = FpE_Miller(P, Q, m, a4, p);
-  return num? num: gen_1;
+  return FpE_Miller(P, Q, m, a4, p);
 }
 
 /***********************************************************************/
@@ -481,8 +497,8 @@ Fp_ellj_get_CM(GEN jn, GEN jd, GEN p)
   CHECK(-28, 16581375);
   CHECK(-43, -884736000);
 #ifdef LONG_IS_64BIT
-  CHECK(-67, -147197952000);
-  CHECK(-163, -262537412640768000);
+  CHECK(-67, -147197952000L);
+  CHECK(-163, -262537412640768000L);
 #else
   if (u2_is_CMj(0x00000022UL,0x45ae8000UL,jn,jd,p)) return -67;
   if (u2_is_CMj(0x03a4b862UL,0xc4b40000UL,jn,jd,p)) return -163;
@@ -553,7 +569,7 @@ jissupersingular(GEN j, GEN S, GEN p)
   long max_path_len = expi(p)+1;
   GEN Phi2 = FpXX_red(polmodular_ZXX(2,0,0,1), p);
   GEN Phi2_j = FqXY_evalx(Phi2, j, S, p);
-  GEN roots = FqX_roots(Phi2_j, S, p);
+  GEN roots = FpXQX_roots(Phi2_j, S, p);
   long nbroots = lg(roots)-1;
   int res = 1;
 
@@ -1529,11 +1545,39 @@ FpXQE_log(GEN a, GEN b, GEN o, GEN a4, GEN T, GEN p)
 /* Derived from APIP from and by Jerome Milan, 2012 */
 
 static GEN
-FpXQE_vert(GEN P, GEN Q, GEN T, GEN p)
+FpXQE_vert(GEN P, GEN Q, GEN a4, GEN T, GEN p)
 {
+  long vT = get_FpX_var(T);
   if (ell_is_inf(P))
     return pol_1(get_FpX_var(T));
-  return FpX_sub(gel(Q, 1), gel(P, 1), p);
+  if (!ZX_equal(gel(Q, 1), gel(P, 1)))
+    return FpX_sub(gel(Q, 1), gel(P, 1), p);
+  if (signe(gel(P,2))!=0) return pol_1(vT);
+  return FpXQ_inv(FpX_add(FpX_mulu(FpXQ_sqr(gel(P,1), T, p), 3, p),
+                  a4, p), T, p);
+}
+
+static GEN
+FpXQE_Miller_line(GEN R, GEN Q, GEN slope, GEN a4, GEN T, GEN p)
+{
+  long vT = get_FpX_var(T);
+  GEN x = gel(Q, 1), y = gel(Q, 2);
+  GEN tmp1  = FpX_sub(x, gel(R, 1), p);
+  GEN tmp2  = FpX_add(FpXQ_mul(tmp1, slope, T, p), gel(R, 2), p);
+  if (!ZX_equal(y, tmp2))
+    return FpX_sub(y, tmp2, p);
+  if (signe(y) == 0)
+    return pol_1(vT);
+  else
+  {
+    GEN s1, s2;
+    GEN y2i = FpXQ_inv(FpX_mulu(y, 2, p), T, p);
+    s1 = FpXQ_mul(FpX_add(FpX_mulu(FpXQ_sqr(x, T, p), 3, p), a4, p), y2i, T, p);
+    if (!ZX_equal(s1, slope))
+      return FpX_sub(s1, slope, p);
+    s2 = FpXQ_mul(FpX_sub(FpX_mulu(x, 3, p), FpXQ_sqr(s1, T, p), p), y2i, T, p);
+    return signe(s2)!=0 ? s2: y2i;
+  }
 }
 
 /* Computes the equation of the line tangent to R and returns its
@@ -1551,13 +1595,11 @@ FpXQE_tangent_update(GEN R, GEN Q, GEN a4, GEN T, GEN p, GEN *pt_R)
   else if (!signe(gel(R,2)))
   {
     *pt_R = ellinf();
-    return FpXQE_vert(R, Q, T, p);
+    return FpXQE_vert(R, Q, a4, T, p);
   } else {
-    GEN slope, tmp1, tmp2;
+    GEN slope;
     *pt_R = FpXQE_dbl_slope(R, a4, T, p, &slope);
-    tmp1 = FpX_sub(gel(Q, 1), gel(R, 1), p);
-    tmp2 = FpX_add(FpXQ_mul(tmp1, slope, T, p), gel(R,2), p);
-    return FpX_sub(gel(Q, 2), tmp2, p);
+    return FpXQE_Miller_line(R, Q, slope, a4, T, p);
   }
 }
 
@@ -1571,12 +1613,12 @@ FpXQE_chord_update(GEN R, GEN P, GEN Q, GEN a4, GEN T, GEN p, GEN *pt_R)
   if (ell_is_inf(R))
   {
     *pt_R = gcopy(P);
-    return FpXQE_vert(P, Q, T, p);
+    return FpXQE_vert(P, Q, a4, T, p);
   }
   else if (ell_is_inf(P))
   {
     *pt_R = gcopy(R);
-    return FpXQE_vert(R, Q, T, p);
+    return FpXQE_vert(R, Q, a4, T, p);
   }
   else if (ZX_equal(gel(P, 1), gel(R, 1)))
   {
@@ -1585,14 +1627,12 @@ FpXQE_chord_update(GEN R, GEN P, GEN Q, GEN a4, GEN T, GEN p, GEN *pt_R)
     else
     {
       *pt_R = ellinf();
-      return FpXQE_vert(R, Q, T, p);
+      return FpXQE_vert(R, Q, a4, T, p);
     }
   } else {
-    GEN slope, tmp1, tmp2;
+    GEN slope;
     *pt_R = FpXQE_add_slope(P, R, a4, T, p, &slope);
-    tmp1  = FpXQ_mul(FpX_sub(gel(Q, 1), gel(R, 1), p), slope, T, p);
-    tmp2  = FpX_add(tmp1, gel(R, 2), p);
-    return FpX_sub(gel(Q, 2), tmp2, p);
+    return FpXQE_Miller_line(R, Q, slope, a4, T, p);
   }
 }
 
@@ -1618,7 +1658,7 @@ FpXQE_Miller_dbl(void* E, GEN d)
   GEN point = gel(d,3);
   line = FpXQE_tangent_update(point, P, a4, T, p, &point);
   num  = FpXQ_mul(num, line, T, p);
-  v = FpXQE_vert(point, P, T, p);
+  v = FpXQE_vert(point, P, a4, T, p);
   denom = FpXQ_mul(denom, v, T, p);
   return mkvec3(num, denom, point);
 }
@@ -1636,7 +1676,7 @@ FpXQE_Miller_add(void* E, GEN va, GEN vb)
   GEN denom = FpXQ_mul(da, db, T, p);
   line = FpXQE_chord_update(pa, pb, P, a4, T, p, &point);
   num  = FpXQ_mul(num, line, T, p);
-  v = FpXQE_vert(point, P, T, p);
+  v = FpXQE_vert(point, P, a4, T, p);
   denom = FpXQ_mul(denom, v, T, p);
   return mkvec3(num, denom, point);
 }
@@ -1652,7 +1692,6 @@ FpXQE_Miller(GEN Q, GEN P, GEN m, GEN a4, GEN T, GEN p)
   g1 = pol_1(get_FpX_var(T));
   v = gen_pow(mkvec3(g1,g1,Q), m, (void*)&d, FpXQE_Miller_dbl, FpXQE_Miller_add);
   num = gel(v,1); denom = gel(v,2);
-  if (!signe(num) || !signe(denom)) { avma = ltop; return NULL; }
   return gerepileupto(ltop, FpXQ_div(num, denom, T, p));
 }
 
@@ -1664,9 +1703,7 @@ FpXQE_weilpairing(GEN P, GEN Q, GEN m, GEN a4, GEN T, GEN p)
   if (ell_is_inf(P) || ell_is_inf(Q) || ZXV_equal(P,Q))
     return pol_1(get_FpX_var(T));
   num    = FpXQE_Miller(P, Q, m, a4, T, p);
-  if (!num) return pol_1(get_FpX_var(T));
   denom  = FpXQE_Miller(Q, P, m, a4, T, p);
-  if (!denom) { avma = ltop; return pol_1(get_FpX_var(T)); }
   result = FpXQ_div(num, denom, T, p);
   if (mpodd(m))
     result  = FpX_neg(result, p);
@@ -1676,11 +1713,9 @@ FpXQE_weilpairing(GEN P, GEN Q, GEN m, GEN a4, GEN T, GEN p)
 GEN
 FpXQE_tatepairing(GEN P, GEN Q, GEN m, GEN a4, GEN T, GEN p)
 {
-  GEN num;
   if (ell_is_inf(P) || ell_is_inf(Q))
     return pol_1(get_FpX_var(T));
-  num = FpXQE_Miller(P, Q, m, a4, T, p);
-  return num? num: pol_1(get_FpX_var(T));
+  return FpXQE_Miller(P, Q, m, a4, T, p);
 }
 
 /***********************************************************************/
@@ -1717,7 +1752,7 @@ FpXQ_elljissupersingular(GEN j, GEN T, GEN p)
   GEN S;
   int res;
 
-  if (degpol(j) <= 0) return Fp_elljissupersingular(constant_term(j), p);
+  if (degpol(j) <= 0) return Fp_elljissupersingular(constant_coeff(j), p);
   if (cmpiu(p, 5) <= 0) return 0; /* j != 0*/
 
   /* Set S so that FF_p[T]/(S) is isomorphic to FF_{p^2}: */
@@ -1732,7 +1767,7 @@ FpXQ_elljissupersingular(GEN j, GEN T, GEN p)
     if (degpol(j_sum) > 0) { avma = ltop; return 0; /* j not in Fp^2 */ }
     j_prod = FpXQ_mul(j, j_pow_p, T, p);
     if (degpol(j_prod) > 0 ) { avma = ltop; return 0; /* j not in Fp^2 */ }
-    j_sum = constant_term(j_sum); j_prod = constant_term(j_prod);
+    j_sum = constant_coeff(j_sum); j_prod = constant_coeff(j_prod);
     S = mkpoln(3, gen_1, Fp_neg(j_sum, p), j_prod);
     setvarn(S, var);
     j = pol_x(var);
@@ -1838,14 +1873,14 @@ FpXQ_ellcard(GEN a4, GEN a6, GEN T, GEN p)
   long n = get_FpX_degree(T);
   GEN q = powiu(p, n), r, J;
   if (degpol(a4)<=0 && degpol(a6)<=0)
-    r = Fp_ffellcard(constant_term(a4),constant_term(a6),q,n,p);
+    r = Fp_ffellcard(constant_coeff(a4),constant_coeff(a6),q,n,p);
   else if (lgefint(p)==3)
   {
     ulong pp = p[2];
     r =  Flxq_ellcard(ZX_to_Flx(a4,pp),ZX_to_Flx(a6,pp),ZX_to_Flx(T,pp),pp);
   }
   else if (degpol(J=FpXQ_ellj(a4,a6,T,p))<=0)
-    r = FpXQ_ellcardj(a4,a6,constant_term(J),T,q,p,n);
+    r = FpXQ_ellcardj(a4,a6,constant_coeff(J),T,q,p,n);
   else
     r = Fq_ellcard_SEA(a4, a6, q, T, p, 0);
   return gerepileuptoint(av, r);
@@ -1889,129 +1924,4 @@ FpXQ_ellgens(GEN a4, GEN a6, GEN ch, GEN D, GEN m, GEN T, GEN p)
   return gerepilecopy(av, P);
 }
 
-/***********************************************************************/
-/**                                                                   **/
-/**                      n-division polynomial                        **/
-/**                                                                   **/
-/***********************************************************************/
-
-struct divpol_red
-{
-  GEN h, T, p;
-};
-
-INLINE GEN
-_red(GEN x, struct divpol_red *r)
-{ return r->h ? FqX_rem(x,r->h,r->T,r->p): gcopy(x); }
-
-INLINE GEN
-_rsqr(GEN x, struct divpol_red *r)
-{
-  GEN h=r->h, T=r->T, p=r->p;
-  return h ? FqXQ_sqr(x,h,T,p): FqX_sqr(x,T,p);
-}
-
-INLINE GEN
-_rmul(GEN x, GEN y, struct divpol_red *r)
-{
-  GEN h=r->h, T=r->T, p=r->p;
-  return h ? FqXQ_mul(x,y,h,T,p): FqX_mul(x,y,T,p);
-}
-
-static GEN divpol(GEN t, GEN a4, GEN a6, GEN r2, long n, struct divpol_red *r);
-
-static GEN
-divpol_f2(GEN t, GEN a4, GEN a6, GEN r2, long n, struct divpol_red *r)
-{
-  if (gmael(t,2,n)) return gmael(t,2,n);
-  if (n<=2) return scalarpol(gen_1,0);
-  gmael(t,2,n) = _rsqr(divpol(t,a4,a6,r2,n,r),r);
-  return gmael(t,2,n);
-}
-
-static GEN
-divpol_ff(GEN t, GEN a4, GEN a6, GEN r2, long n, struct divpol_red *r)
-{
-  if(gmael(t,3,n)) return gmael(t,3,n);
-  if (n<=4) return divpol(t,a4,a6,r2,n,r);
-  gmael(t,3,n) = _rmul(divpol(t,a4,a6,r2,n,r), divpol(t,a4,a6,r2,n-2,r),r);
-  return gmael(t,3,n);
-}
-
-static GEN
-divpol(GEN t, GEN a4, GEN a6, GEN r2, long n, struct divpol_red *r)
-{
-  long m = n/2;
-  GEN res;
-  GEN T=r->T, p=r->p;
-  if (gmael(t,1,n)) return gmael(t,1,n);
-  switch(n)
-  {
-  case 1:
-  case 2:
-    res = scalarpol(gen_1,0);
-    break;
-  case 3:
-    res = _red(mkpoln(5, utoi(3), gen_0, Fq_mulu(a4, 6, T, p),
-          Fq_mulu(a6, 12, T, p), Fq_neg(Fq_sqr(a4, T, p), T, p)), r);
-    break;
-  case 4:
-    {
-      GEN a42 = Fq_sqr(a4, T, p);
-      res = _red(FqX_mulu(mkpoln(7, gen_1, gen_0, Fq_mulu(a4, 5, T, p),
-              Fq_mulu(a6, 20, T, p), Fq_Fp_mul(a42,stoi(-5), T, p),
-              Fq_Fp_mul(Fq_mul(a4, a6, T, p), stoi(-4), T, p),
-              Fq_sub(Fq_Fp_mul(Fq_sqr(a6, T, p), stoi(-8), T, p),
-                Fq_mul(a4,a42, T, p), T, p)), 2, T, p), r);
-    }
-    break;
-  default:
-    if (odd(n))
-      if (odd(m))
-        res = FqX_sub(_rmul(divpol_ff(t,a4,a6,r2,m+2,r),
-              divpol_f2(t,a4,a6,r2,m,r), r),
-            _rmul(r2,  _rmul(divpol_ff(t,a4,a6,r2,m+1,r),
-                divpol_f2(t,a4,a6,r2,m+1,r), r), r), T, p);
-      else
-        res = FqX_sub(_rmul(r2, _rmul(divpol_ff(t,a4,a6,r2,m+2,r),
-                divpol_f2(t,a4,a6,r2,m,r), r), r),
-            _rmul(divpol_ff(t,a4,a6,r2,m+1,r),
-              divpol_f2(t,a4,a6,r2,m+1,r), r), T, p);
-    else
-      res = FqX_sub(_rmul(divpol_ff(t,a4,a6,r2,m+2,r),
-            divpol_f2(t,a4,a6,r2,m-1,r), r),
-          _rmul(divpol_ff(t,a4,a6,r2,m,r),
-            divpol_f2(t,a4,a6,r2,m+1,r), r), T, p);
-  }
-  gmael(t,1,n) = res;
-  return res;
-}
-
-/*Computes the n-division polynomial modulo the polynomial h \in Fq[x] */
-GEN
-Fq_elldivpolmod(GEN a4, GEN a6, long n, GEN h, GEN T, GEN p)
-{
-  struct divpol_red r;
-  pari_sp ltop = avma;
-  GEN t, rhs, r2;
-  if (n == 0) return scalarpol(gen_0,0);
-  if (n <= 2) return scalarpol(gen_1,0);
-  r.h=h; r.T=T;
-  r.p=p;
-  t  = mkvec3(const_vec(n, NULL),const_vec(n, NULL),const_vec(n, NULL));
-  rhs = FqX_mulu(_red(mkpoln(4, gen_1, gen_0, a4, a6), &r), 4, T, p);
-  r2 = _rsqr(rhs,&r);
-  return gerepilecopy(ltop, divpol(t,a4,a6,r2,n,&r));
-}
-
-GEN
-FpXQ_elldivpol(GEN a4, GEN a6, long n, GEN T, GEN p)
-{
-  return Fq_elldivpolmod(a4,a6,n,NULL,T,p);
-}
 
-GEN
-Fp_elldivpol(GEN a4, GEN a6, long n, GEN p)
-{
-  return Fq_elldivpolmod(a4,a6,n,NULL,NULL,p);
-}
diff --git a/src/basemath/FpV.c b/src/basemath/FpV.c
index 84bb5a4..1ec9629 100644
--- a/src/basemath/FpV.c
+++ b/src/basemath/FpV.c
@@ -260,7 +260,7 @@ FpC_Fp_mul(GEN x, GEN y, GEN p)
   return z;
 }
 GEN
-Flc_Fl_mul(GEN x, ulong y, ulong p)
+Flv_Fl_mul(GEN x, ulong y, ulong p)
 {
   long i, l = lg(x);
   GEN z = cgetg(l, t_VECSMALL);
@@ -268,14 +268,14 @@ Flc_Fl_mul(GEN x, ulong y, ulong p)
   return z;
 }
 GEN
-Flc_Fl_div(GEN x, ulong y, ulong p)
+Flv_Fl_div(GEN x, ulong y, ulong p)
 {
-  return Flc_Fl_mul(x, Fl_inv(y, p), p);
+  return Flv_Fl_mul(x, Fl_inv(y, p), p);
 }
 void
-Flc_Fl_div_inplace(GEN x, ulong y, ulong p)
+Flv_Fl_div_inplace(GEN x, ulong y, ulong p)
 {
-  Flc_Fl_mul_inplace(x, Fl_inv(y, p), p);
+  Flv_Fl_mul_inplace(x, Fl_inv(y, p), p);
 }
 GEN
 FpM_Fp_mul(GEN X, GEN c, GEN p) {
@@ -294,14 +294,14 @@ FpM_Fp_mul(GEN X, GEN c, GEN p) {
 
 /* x *= y */
 void
-Flc_Fl_mul_part_inplace(GEN x, ulong y, ulong p, long l)
+Flv_Fl_mul_part_inplace(GEN x, ulong y, ulong p, long l)
 {
   long i;
   for (i=1;i<=l;i++) x[i] = Fl_mul(x[i], y, p);
 }
 void
-Flc_Fl_mul_inplace(GEN x, ulong y, ulong p)
-{ Flc_Fl_mul_part_inplace(x, y, p, lg(x)-1); }
+Flv_Fl_mul_inplace(GEN x, ulong y, ulong p)
+{ Flv_Fl_mul_part_inplace(x, y, p, lg(x)-1); }
 
 /* set y *= x */
 void
diff --git a/src/basemath/FpX.c b/src/basemath/FpX.c
index f507790..530f3ec 100644
--- a/src/basemath/FpX.c
+++ b/src/basemath/FpX.c
@@ -111,7 +111,7 @@ FpXT_red(GEN z, GEN p)
 GEN
 FpX_normalize(GEN z, GEN p)
 {
-  GEN p1 = leading_term(z);
+  GEN p1 = leading_coeff(z);
   if (lg(z) == 2 || equali1(p1)) return z;
   return FpX_Fp_mul_to_monic(z, Fp_inv(p1,p), p);
 }
@@ -290,6 +290,7 @@ FpX_mulu(GEN y, ulong x,GEN p)
 {
   GEN z;
   long i, l;
+  x = umodui(x, p);
   if (!x) return zeropol(varn(y));
   z = cgetg_copy(y, &l); z[1] = y[1];
   for(i=2; i<l; i++) gel(z,i) = Fp_mulu(gel(y,i), x, p);
@@ -324,17 +325,30 @@ FpX_Fp_mul_to_monic(GEN y,GEN x,GEN p)
   gel(z,l-1) = gen_1; return z;
 }
 
-static GEN
-_FpX_sqr(void * E, GEN x) { return FpX_sqr(x, (GEN) E); }
+struct _FpXQ {
+  GEN T, p, aut;
+};
 
 static GEN
-_FpX_mul(void * E, GEN x, GEN y) { return FpX_mul(x, y, (GEN) E); }
+_FpX_sqr(void *data, GEN x)
+{
+  struct _FpXQ *D = (struct _FpXQ*)data;
+  return FpX_sqr(x, D->p);
+}
+static GEN
+_FpX_mul(void *data, GEN x, GEN y)
+{
+  struct _FpXQ *D = (struct _FpXQ*)data;
+  return FpX_mul(x,y, D->p);
+}
 
 GEN
 FpX_powu(GEN x, ulong n, GEN p)
 {
+  struct _FpXQ D;
   if (n==0) return pol_1(varn(x));
-  return gen_powu(x, n, (void *)p, _FpX_sqr, _FpX_mul);
+  D.p = p;
+  return gen_powu(x, n, (void *)&D, _FpX_sqr, _FpX_mul);
 }
 
 GEN
@@ -369,7 +383,7 @@ FpX_divrem_basecase(GEN x, GEN y, GEN p, GEN *pr)
     }
     return pol_0(vx);
   }
-  lead = leading_term(y);
+  lead = leading_coeff(y);
   if (!dy) /* y is constant */
   {
     if (pr && pr != ONLY_DIVIDES)
@@ -463,9 +477,16 @@ FpX_div_by_X_x(GEN a, GEN x, GEN p, GEN *r)
 }
 
 static GEN
-_FpX_divrem(void * E, GEN x, GEN y, GEN *r) { return FpX_divrem(x, y, (GEN) E, r); }
+_FpX_divrem(void * E, GEN x, GEN y, GEN *r)
+{
+  struct _FpXQ *D = (struct _FpXQ*) E;
+  return FpX_divrem(x, y, D->p, r);
+}
 static GEN
-_FpX_add(void * E, GEN x, GEN y) { return FpX_add(x, y, (GEN) E); }
+_FpX_add(void * E, GEN x, GEN y) {
+  struct _FpXQ *D = (struct _FpXQ*) E;
+  return FpX_add(x, y, D->p);
+}
 
 static struct bb_ring FpX_ring = { _FpX_add,_FpX_mul,_FpX_sqr };
 
@@ -473,8 +494,11 @@ GEN
 FpX_digits(GEN x, GEN T, GEN p)
 {
   pari_sp av = avma;
+  struct _FpXQ D;
   long d = degpol(T), n = (lgpol(x)+d-1)/d;
-  GEN z = gen_digits(x,T,n,(void *)p, &FpX_ring, _FpX_divrem);
+  GEN z;
+  D.p = p;
+  z = gen_digits(x,T,n,(void *)&D, &FpX_ring, _FpX_divrem);
   return gerepileupto(av, z);
 }
 
@@ -482,7 +506,10 @@ GEN
 FpX_fromdigits(GEN x, GEN T, GEN p)
 {
   pari_sp av = avma;
-  GEN z = gen_fromdigits(x,T,(void *)p, &FpX_ring);
+  struct _FpXQ D;
+  GEN z;
+  D.p = p;
+  z = gen_fromdigits(x,T,(void *)&D, &FpX_ring);
   return gerepileupto(av, z);
 }
 
@@ -541,14 +568,22 @@ FpXM_FpX_mul2(GEN M, GEN x, GEN y, GEN p)
   return res;
 }
 
-/*TODO: implement Strassen 7 multiplications formula (p is large) */
 static GEN
-FpXM_mul2(GEN M, GEN N, GEN p)
-{
-  GEN res = cgetg(3, t_MAT);
-  gel(res, 1) = FpXM_FpX_mul2(M,gcoeff(N,1,1),gcoeff(N,2,1),p);
-  gel(res, 2) = FpXM_FpX_mul2(M,gcoeff(N,1,2),gcoeff(N,2,2),p);
-  return res;
+FpXM_mul2(GEN A, GEN B, GEN p)
+{
+  GEN A11=gcoeff(A,1,1),A12=gcoeff(A,1,2), B11=gcoeff(B,1,1),B12=gcoeff(B,1,2);
+  GEN A21=gcoeff(A,2,1),A22=gcoeff(A,2,2), B21=gcoeff(B,2,1),B22=gcoeff(B,2,2);
+  GEN M1 = FpX_mul(FpX_add(A11,A22, p), FpX_add(B11,B22, p), p);
+  GEN M2 = FpX_mul(FpX_add(A21,A22, p), B11, p);
+  GEN M3 = FpX_mul(A11, FpX_sub(B12,B22, p), p);
+  GEN M4 = FpX_mul(A22, FpX_sub(B21,B11, p), p);
+  GEN M5 = FpX_mul(FpX_add(A11,A12, p), B22, p);
+  GEN M6 = FpX_mul(FpX_sub(A21,A11, p), FpX_add(B11,B12, p), p);
+  GEN M7 = FpX_mul(FpX_sub(A12,A22, p), FpX_add(B21,B22, p), p);
+  GEN T1 = FpX_add(M1,M4, p), T2 = FpX_sub(M7,M5, p);
+  GEN T3 = FpX_sub(M1,M2, p), T4 = FpX_add(M3,M6, p);
+  retmkmat2(mkcol2(FpX_add(T1,T2, p), FpX_add(M2,M4, p)),
+            mkcol2(FpX_add(M3,M5, p), FpX_add(T3,T4, p)));
 }
 
 /* Return [0,1;1,-q]*M */
@@ -685,7 +720,7 @@ FpX_gcd_check(GEN x, GEN y, GEN p)
   b = FpX_red(y, p);
   while (signe(b))
   {
-    GEN lead = leading_term(b);
+    GEN lead = leading_coeff(b);
     GEN g = gcdii(lead,p);
     if (!equali1(g)) return gerepileuptoint(av,g);
     c = FpX_rem(a,b,p); a=b; b=c;
@@ -918,7 +953,7 @@ FpX_disc(GEN x, GEN p)
   pari_sp av = avma;
   GEN L, D = FpX_resultant(x, FpX_deriv(x,p), p);
   if (!D || !signe(D)) return gen_0;
-  L = leading_term(x); if (!equali1(L)) D = Fp_div(D,L,p);
+  L = leading_coeff(x); if (!equali1(L)) D = Fp_div(D,L,p);
   if (degpol(x) & 2) D = Fp_neg(D,p);
   return gerepileuptoint(av, D);
 }
@@ -926,7 +961,9 @@ FpX_disc(GEN x, GEN p)
 GEN
 FpXV_prod(GEN V, GEN p)
 {
-  return gen_product(V, (void *)p, &_FpX_mul);
+  struct _FpXQ D;
+  D.p = p;
+  return gen_product(V, (void *)&D, &_FpX_mul);
 }
 
 GEN
@@ -1240,6 +1277,168 @@ FpX_rem(GEN x, GEN T, GEN p)
   }
 }
 
+static GEN
+deg2pol_shallow(GEN x2, GEN x1, GEN x0, long v)
+{
+  GEN x = cgetg(5,t_POL);
+  x[1] = evalsigne(1) | evalvarn(v);
+  gel(x,2) = x0;
+  gel(x,3) = x1;
+  gel(x,4) = x2;
+  return normalizepol_lg(x,5);
+}
+
+static GEN
+FpV_producttree(GEN xa, GEN p, long vs)
+{
+  long n = lg(xa)-1;
+  long m = n==1 ? 1: expu(n-1)+1;
+  GEN T = cgetg(m+1, t_VEC), t;
+  long i, j, k;
+  t = cgetg(((n+1)>>1)+1, t_VEC);
+  for (j=1, k=1; k<n; j++, k+=2)
+    gel(t, j) = deg2pol_shallow(gen_1,
+                Fp_neg(Fp_add(gel(xa,k), gel(xa,k+1), p), p),
+                Fp_mul(gel(xa,k), gel(xa,k+1), p), vs);
+  if (k==n) gel(t, j) = deg1pol(gen_1, Fp_neg(gel(xa,k), p), vs);
+  gel(T,1) = t;
+  for (i=2; i<=m; i++)
+  {
+    GEN u = gel(T, i-1);
+    long n = lg(u)-1;
+    t = cgetg(((n+1)>>1)+1, t_VEC);
+    for (j=1, k=1; k<n; j++, k+=2)
+      gel(t, j) = FpX_mul(gel(u, k), gel(u, k+1), p);
+    if (k==n) gel(t, j) = gel(u, k);
+    gel(T, i) = t;
+  }
+  return T;
+}
+
+static GEN
+FpX_FpV_multieval_tree(GEN P, GEN xa, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  long i,j,k;
+  long m = lg(T)-1, n = lg(xa)-1;
+  GEN t;
+  GEN Tp = cgetg(m+1, t_VEC);
+  gel(Tp, m) = mkvec(P);
+  for (i=m-1; i>=1; i--)
+  {
+    GEN u = gel(T, i);
+    GEN v = gel(Tp, i+1);
+    long n = lg(u)-1;
+    t = cgetg(n+1, t_VEC);
+    for (j=1, k=1; k<n; j++, k+=2)
+    {
+      gel(t, k)   = FpX_rem(gel(v, j), gel(u, k), p);
+      gel(t, k+1) = FpX_rem(gel(v, j), gel(u, k+1), p);
+    }
+    if (k==n) gel(t, k) = gel(v, j);
+    gel(Tp, i) = t;
+  }
+  {
+    GEN R = cgetg(n+1, t_VEC);
+    GEN u = gel(T, i+1);
+    GEN v = gel(Tp, i+1);
+    long l = lg(u)-1;
+    for (j=1, k=1; j<=l; j++)
+    {
+      long c, d = degpol(gel(u,j));
+      for (c=1; c<=d; c++, k++)
+        gel(R,k) = FpX_eval(gel(v, j), gel(xa,k), p);
+    }
+    return gerepileupto(av, R);
+  }
+}
+
+static GEN
+FpVV_polint_tree(GEN T, GEN R, GEN xa, GEN ya, GEN p, long vs)
+{
+  pari_sp av = avma;
+  long m = lg(T)-1, n = lg(ya)-1;
+  long i,j,k;
+  GEN Tp = cgetg(m+1, t_VEC);
+  GEN t = cgetg(lg(gel(T,1)), t_VEC);
+  for (j=1, k=1; k<n; j++, k+=2)
+  {
+    GEN a = Fp_mul(gel(ya,k), gel(R,k), p), b = Fp_mul(gel(ya,k+1), gel(R,k+1), p);
+    gel(t, j) = deg1pol(Fp_add(a, b, p),
+                Fp_neg(Fp_add(Fp_mul(gel(xa,k), b, p ),
+                              Fp_mul(gel(xa,k+1), a, p), p), p), vs);
+  }
+  if (k==n) gel(t, j) = scalarpol(Fp_mul(gel(ya,k), gel(R,k), p), vs);
+  gel(Tp, 1) = t;
+  for (i=2; i<=m; i++)
+  {
+    GEN u = gel(T, i-1);
+    GEN t = cgetg(lg(gel(T,i)), t_VEC);
+    GEN v = gel(Tp, i-1);
+    long l = lg(v)-1;
+    for (j=1, k=1; k<l; j++, k+=2)
+      gel(t, j) = FpX_add(ZX_mul(gel(u, k), gel(v, k+1)),
+                          ZX_mul(gel(u, k+1), gel(v, k)), p);
+    if (k==l) gel(t, j) = gel(v, k);
+    gel(Tp, i) = t;
+  }
+  return gerepilecopy(av, gmael(Tp,m,1));
+}
+
+GEN
+FpX_FpV_multieval(GEN P, GEN xa, GEN p)
+{
+  pari_sp av = avma;
+  GEN T = FpV_producttree(xa, p, P[1]);
+  return gerepileupto(av, FpX_FpV_multieval_tree(P, xa, T, p));
+}
+
+GEN
+FpV_polint(GEN xa, GEN ya, GEN p, long vs)
+{
+  pari_sp av = avma;
+  GEN T = FpV_producttree(xa, p, vs);
+  long m = lg(T)-1;
+  GEN P = FpX_deriv(gmael(T, m, 1), p);
+  GEN R = FpV_inv(FpX_FpV_multieval_tree(P, xa, T, p), p);
+  return gerepileupto(av, FpVV_polint_tree(T, R, xa, ya, p, vs));
+}
+
+GEN
+FpV_FpM_polint(GEN xa, GEN ya, GEN p, long vs)
+{
+  pari_sp av = avma;
+  GEN T = FpV_producttree(xa, p, vs);
+  long m = lg(T)-1, l = lg(ya)-1;
+  long i;
+  GEN P = FpX_deriv(gmael(T, m, 1), p);
+  GEN R = FpV_inv(FpX_FpV_multieval_tree(P, xa, T, p), p);
+  GEN M = cgetg(l+1, t_VEC);
+  for (i=1; i<=l; i++)
+    gel(M,i) = FpVV_polint_tree(T, R, xa, gel(ya,i), p, vs);
+  return gerepileupto(av, M);
+}
+
+GEN
+FpV_invVandermonde(GEN L, GEN den, GEN p)
+{
+  pari_sp av = avma;
+  long i, n = lg(L);
+  GEN M, R;
+  GEN tree = FpV_producttree(L, p, 0);
+  long m = lg(tree)-1;
+  GEN T = gmael(tree, m, 1);
+  R = FpV_inv(FpX_FpV_multieval_tree(FpX_deriv(T, p), L, tree, p), p);
+  if (den) R = FpC_Fp_mul(R, den, p);
+  M = cgetg(n, t_MAT);
+  for (i = 1; i < n; i++)
+  {
+    GEN P = FpX_Fp_mul(FpX_div_by_X_x(T, gel(L,i), p, NULL), gel(R,i), p);
+    gel(M,i) = RgX_to_RgC(P, n-1);
+  }
+  return gerepilecopy(av, M);
+}
+
 /***********************************************************************/
 /**                                                                   **/
 /**                              FpXQ                                 **/
@@ -1297,10 +1496,6 @@ FpXQ_div(GEN x,GEN y,GEN T,GEN p)
   return gerepileupto(av, FpXQ_mul(x,FpXQ_inv(y,T,p),T,p));
 }
 
-struct _FpXQ {
-  GEN T, p, aut;
-};
-
 static GEN
 _FpXQ_add(void *data, GEN x, GEN y)
 {
@@ -1308,6 +1503,12 @@ _FpXQ_add(void *data, GEN x, GEN y)
   return ZX_add(x, y);
 }
 static GEN
+_FpXQ_sub(void *data, GEN x, GEN y)
+{
+  (void) data;
+  return ZX_sub(x, y);
+}
+static GEN
 _FpXQ_cmul(void *data, GEN P, long a, GEN x)
 {
   (void) data;
@@ -1344,7 +1545,31 @@ _FpXQ_red(void *data, GEN x)
   return FpX_red(x,D->p);
 }
 
-static struct bb_algebra FpXQ_algebra = { _FpXQ_red,_FpXQ_add,_FpXQ_mul,_FpXQ_sqr,_FpXQ_one,_FpXQ_zero };
+static struct bb_algebra FpXQ_algebra = { _FpXQ_red, _FpXQ_add, _FpXQ_sub,
+       _FpXQ_mul, _FpXQ_sqr, _FpXQ_one, _FpXQ_zero };
+
+const struct bb_algebra *
+get_FpXQ_algebra(void **E, GEN T, GEN p)
+{
+  GEN z = new_chunk(sizeof(struct _FpXQ));
+  struct _FpXQ *e = (struct _FpXQ *) z;
+  e->T = FpX_get_red(T, p);
+  e->p  = p; *E = (void*)e;
+  return &FpXQ_algebra;
+}
+
+static struct bb_algebra FpX_algebra = { _FpXQ_red, _FpXQ_add, _FpXQ_sub,
+       _FpX_mul, _FpX_sqr, _FpXQ_one, _FpXQ_zero };
+
+const struct bb_algebra *
+get_FpX_algebra(void **E, GEN p, long v)
+{
+  GEN z = new_chunk(sizeof(struct _FpXQ));
+  struct _FpXQ *e = (struct _FpXQ *) z;
+  e->T = pol_x(v);
+  e->p  = p; *E = (void*)e;
+  return &FpX_algebra;
+}
 
 /* x,pol in Z[X], p in Z, n in Z, compute lift(x^n mod (p, pol)) */
 GEN
@@ -1683,6 +1908,21 @@ Fq_issquare(GEN x, GEN T, GEN p)
   return (T && ! odd(get_FpX_degree(T))) || Fp_issquare(x, p);
 }
 
+long
+Fq_ispower(GEN x, GEN K, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  long d;
+  GEN Q;
+  if (!T) return Fp_ispower(x,K,p);
+  d = get_FpX_degree(T);
+  if (!umodui(d, K)) return 1;
+  Q = subiu(powiu(p,d), 1);
+  Q = diviiexact(Q, gcdii(Q, K));
+  d = gequal1(Fq_pow(x, Q, T,p));
+  avma = av; return d;
+}
+
 /* discrete log in FpXQ for a in Fp^*, g in FpXQ^* of order ord */
 GEN
 Fp_FpXQ_log(GEN a, GEN g, GEN o, GEN T, GEN p)
@@ -1708,7 +1948,7 @@ Fp_FpXQ_log(GEN a, GEN g, GEN o, GEN T, GEN p)
       q = diviiexact(ord,ordp);
       g = FpXQ_pow(g,q,T,p);
     }
-    g = constant_term(g);
+    g = constant_coeff(g);
   }
   n_q = Fp_log(a,g,op,p);
   if (lg(n_q)==1) return gerepileuptoleaf(av, n_q);
@@ -1742,7 +1982,7 @@ _FpXQ_easylog(void *E, GEN a, GEN g, GEN ord)
 {
   struct _FpXQ *s=(struct _FpXQ*) E;
   if (degpol(a)) return NULL;
-  return Fp_FpXQ_log(constant_term(a),g,ord,s->T,s->p);
+  return Fp_FpXQ_log(constant_coeff(a),g,ord,s->T,s->p);
 }
 
 static const struct bb_group FpXQ_star={_FpXQ_mul,_FpXQ_pow,_FpXQ_rand,hash_GEN,ZX_equal,ZX_equal1,_FpXQ_easylog};
@@ -1873,7 +2113,7 @@ FpXQ_norm(GEN x, GEN TB, GEN p)
   pari_sp av = avma;
   GEN T = get_FpX_mod(TB);
   GEN y = FpX_resultant(T, x, p);
-  GEN L = leading_term(T);
+  GEN L = leading_coeff(T);
   if (gequal1(L) || signe(x)==0) return y;
   return gerepileupto(av, Fp_div(y, Fp_pows(L, degpol(x), p), p));
 }
diff --git a/src/basemath/FpXQX_factor.c b/src/basemath/FpXQX_factor.c
new file mode 100644
index 0000000..8d7888a
--- /dev/null
+++ b/src/basemath/FpXQX_factor.c
@@ -0,0 +1,1356 @@
+/* Copyright (C) 2016  The PARI group.
+
+This file is part of the PARI/GP package.
+
+PARI/GP is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation. It is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY WHATSOEVER.
+
+Check the License for details. You should have received a copy of it, along
+with the package; see the file 'COPYING'. If not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
+
+#include "pari.h"
+#include "paripriv.h"
+
+/***********************************************************************/
+/**                                                                   **/
+/**               Factorisation over finite fields                    **/
+/**                                                                   **/
+/***********************************************************************/
+
+static GEN
+to_Fq(GEN x, GEN T, GEN p)
+{
+  long i, lx, tx = typ(x);
+  GEN y;
+
+  if (tx == t_INT)
+    y = mkintmod(x,p);
+  else
+  {
+    if (tx != t_POL) pari_err_TYPE("to_Fq",x);
+    lx = lg(x);
+    y = cgetg(lx,t_POL); y[1] = x[1];
+    for (i=2; i<lx; i++) gel(y,i) = mkintmod(gel(x,i), p);
+  }
+  return mkpolmod(y, T);
+}
+
+static GEN
+to_Fq_pol(GEN x, GEN T, GEN p)
+{
+  long i, lx = lg(x);
+  for (i=2; i<lx; i++) gel(x,i) = to_Fq(gel(x,i),T,p);
+  return x;
+}
+
+static GEN
+to_Fq_fact(GEN P, GEN E, GEN T, GEN p, pari_sp av)
+{
+  GEN y, u, v;
+  long j, l = lg(P), nbf = lg(P);
+
+  u = cgetg(nbf,t_COL);
+  v = cgetg(nbf,t_COL);
+  for (j=1; j<l; j++)
+  {
+    gel(u,j) = simplify_shallow(gel(P,j)); /* may contain pols of degree 0 */
+    gel(v,j) = utoi(uel(E,j));
+  }
+  y = gerepilecopy(av, mkmat2(u, v));
+  u = gel(y,1);
+  p = icopy(p);
+  T = FpX_to_mod(T, p);
+  for (j=1; j<nbf; j++) gel(u,j) = to_Fq_pol(gel(u,j), T,p);
+  return y;
+}
+static GEN
+to_FqC(GEN P, GEN T, GEN p, pari_sp av)
+{
+  GEN u;
+  long j, l = lg(P), nbf = lg(P);
+
+  u = cgetg(nbf,t_COL);
+  for (j=1; j<l; j++)
+    gel(u,j) = simplify_shallow(gel(P,j)); /* may contain pols of degree 0 */
+  u = gerepilecopy(av, u);
+  p = icopy(p);
+  T = FpX_to_mod(T, p);
+  for (j=1; j<nbf; j++) gel(u,j) = to_Fq(gel(u,j), T,p);
+  return u;
+}
+
+GEN
+FlxqXQ_halfFrobenius(GEN a, GEN S, GEN T, ulong p)
+{
+  long vT = get_Flx_var(T);
+  GEN xp = Flx_Frobenius(T, p);
+  GEN Xp = FlxqXQ_powu(polx_FlxX(get_FlxqX_var(S), vT), p, S, T, p);
+  GEN ap2 = FlxqXQ_powu(a,p>>1, S, T, p);
+  GEN V = FlxqXQV_autsum(mkvec3(xp, Xp, ap2), get_Flx_degree(T), S, T, p);
+  return gel(V,3);
+}
+
+GEN
+FpXQXQ_halfFrobenius(GEN a, GEN S, GEN T, GEN p)
+{
+  if (lgefint(p)==3)
+  {
+    ulong pp = p[2];
+    long v = get_FpX_var(T);
+    GEN Tp = ZXT_to_FlxT(T,pp), Sp = ZXXT_to_FlxXT(S, pp, v);
+    return FlxX_to_ZXX(FlxqXQ_halfFrobenius(ZXX_to_FlxX(a,pp,v),Sp,Tp,pp));
+  }
+  else
+  {
+    GEN xp, Xp, ap2, V;
+    T = FpX_get_red(T, p);
+    S = FpXQX_get_red(S, T, p);
+    xp = FpX_Frobenius(T, p);
+    Xp = FpXQXQ_pow(pol_x(get_FpXQX_var(S)), p, S, T, p);
+    ap2 = FpXQXQ_pow(a,shifti(p,-1), S, T, p);
+    V = FpXQXQV_autsum(mkvec3(xp,Xp,ap2), get_FpX_degree(T), S, T, p);
+    return gel(V,3);
+  }
+}
+
+GEN
+FlxqX_Frobenius(GEN S, GEN T, ulong p)
+{
+  pari_sp av = avma;
+  long n = get_Flx_degree(T), vT = get_Flx_var(T);
+  GEN X  = polx_FlxX(get_FlxqX_var(S), vT);
+  GEN xp = Flx_Frobenius(T, p);
+  GEN Xp = FlxqXQ_powu(X, p, S, T, p);
+  GEN Xq = gel(FlxqXQV_autpow(mkvec2(xp,Xp), n, S, T, p), 2);
+  return gerepilecopy(av, Xq);
+}
+
+GEN
+FpXQX_Frobenius(GEN S, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  long n = get_FpX_degree(T);
+  GEN X  = pol_x(get_FpXQX_var(S));
+  GEN xp = FpX_Frobenius(T, p);
+  GEN Xp = FpXQXQ_pow(X, p, S, T, p);
+  GEN Xq = gel(FpXQXQV_autpow(mkvec2(xp,Xp), n, S, T, p), 2);
+  return gerepilecopy(av, Xq);
+}
+
+static GEN
+FqX_Frobenius_powers(GEN S, GEN T, GEN p)
+{
+  long N = get_FpXQX_degree(S);
+  if (lgefint(p)==3)
+  {
+    ulong pp = p[2];
+    GEN Tp = ZXT_to_FlxT(T, pp), Sp = ZXXT_to_FlxXT(S, pp, get_FpX_var(T));
+    GEN Xq = FlxqX_Frobenius(Sp, Tp, pp);
+    return FlxqXQ_powers(Xq, N-1, Sp, Tp, pp);
+  } else
+  {
+    GEN Xq = FpXQX_Frobenius(S, T, p);
+    return FpXQXQ_powers(Xq, N-1, S, T, p);
+  }
+}
+
+static GEN
+FqX_Frobenius_eval(GEN x, GEN V, GEN S, GEN T, GEN p)
+{
+  if (lgefint(p)==3)
+  {
+    ulong pp = p[2];
+    long v = get_FpX_var(T);
+    GEN Tp = ZXT_to_FlxT(T, pp), Sp = ZXXT_to_FlxXT(S, pp, v);
+    GEN xp = ZXX_to_FlxX(x, pp, v);
+    return FlxX_to_ZXX(FlxqX_FlxqXQV_eval(xp, V, Sp, Tp, pp));
+  }
+  else
+    return FpXQX_FpXQXQV_eval(x, V, S, T, p);
+}
+
+static GEN
+FpXQX_split_part(GEN f, GEN T, GEN p)
+{
+  long n = degpol(f);
+  GEN z, X = pol_x(varn(f));
+  if (n <= 1) return f;
+  f = FpXQX_red(f, T, p);
+  z = FpXQX_Frobenius(f, T, p);
+  z = FpXX_sub(z, X , p);
+  return FpXQX_gcd(z, f, T, p);
+}
+
+static GEN
+FlxqX_split_part(GEN f, GEN T, ulong p)
+{
+  long n = degpol(f);
+  GEN z, Xq, X = polx_FlxX(varn(f),get_Flx_var(T));
+  if (n <= 1) return f;
+  f = FlxqX_red(f, T, p);
+  Xq = FlxqX_Frobenius(f, T, p);
+  z = FlxX_sub(Xq, X , p);
+  return FlxqX_gcd(z, f, T, p);
+}
+
+long
+FpXQX_nbroots(GEN f, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  GEN z;
+  if(lgefint(p)==3)
+  {
+    ulong pp=p[2];
+    z = FlxqX_split_part(ZXX_to_FlxX(f,pp,varn(T)),ZXT_to_FlxT(T,pp),pp);
+  }
+  else
+    z = FpXQX_split_part(f, T, p);
+  avma = av; return degpol(z);
+}
+
+long
+FqX_nbroots(GEN f, GEN T, GEN p)
+{ return T ? FpXQX_nbroots(f, T, p): FpX_nbroots(f, p); }
+
+long
+FlxqX_nbroots(GEN f, GEN T, ulong p)
+{
+  pari_sp av = avma;
+  GEN z = FlxqX_split_part(f, T, p);
+  avma = av; return degpol(z);
+}
+
+GEN
+FlxqX_Berlekamp_ker(GEN S, GEN T, ulong p)
+{
+  pari_sp ltop=avma;
+  long j, N = get_FlxqX_degree(S);
+  GEN Xq = FlxqX_Frobenius(S,T,p);
+  GEN Q  = FlxqXQ_matrix_pow(Xq,N,N,S,T,p);
+  for (j=1; j<=N; j++)
+    gcoeff(Q,j,j) = Flx_Fl_add(gcoeff(Q,j,j), p-1, p);
+  return gerepileupto(ltop, FlxqM_ker(Q,T,p));
+}
+
+GEN
+FpXQX_Berlekamp_ker(GEN S, GEN T, GEN p)
+{
+  if (lgefint(p)==3)
+  {
+    ulong pp=p[2];
+    long v = get_FpX_var(T);
+    GEN Tp = ZXT_to_FlxT(T,pp), Sp = ZXX_to_FlxX(S,pp,v);
+    return FlxM_to_ZXM(FlxqX_Berlekamp_ker(Sp, Tp, pp));
+  } else
+  {
+    pari_sp ltop=avma;
+    long j,N = get_FpXQX_degree(S);
+    GEN Xq = FpXQX_Frobenius(S,T,p);
+    GEN Q  = FpXQXQ_matrix_pow(Xq,N,N,S,T,p);
+    for (j=1; j<=N; j++)
+      gcoeff(Q,j,j) = Fq_sub(gcoeff(Q,j,j), gen_1, T, p);
+    return gerepileupto(ltop, FqM_ker(Q,T,p));
+  }
+}
+
+long
+FpXQX_nbfact(GEN u, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  GEN vker = FpXQX_Berlekamp_ker(u, T, p);
+  avma = av; return lg(vker)-1;
+}
+
+long
+FqX_nbfact(GEN u, GEN T, GEN p)
+{
+  return T ? FpX_nbfact(u, p): FpXQX_nbfact(u, T, p);
+}
+
+#define set_irred(i) { if ((i)>ir) swap(t[i],t[ir]); ir++;}
+
+long
+FqX_split_Berlekamp(GEN *t, GEN T, GEN p)
+{
+  GEN u = *t, a,b,vker,pol;
+  long vu = varn(u), vT = varn(T), dT = degpol(T);
+  long d, i, ir, L, la, lb;
+  T = FpX_get_red(T, p);
+  vker = FpXQX_Berlekamp_ker(u,T,p);
+  vker = RgM_to_RgXV(vker,vu);
+  d = lg(vker)-1;
+  ir = 0;
+  /* t[i] irreducible for i < ir, still to be treated for i < L */
+  for (L=1; L<d; )
+  {
+    pol= scalarpol(random_FpX(dT,vT,p),vu);
+    for (i=2; i<=d; i++)
+      pol = FqX_add(pol, FqX_Fq_mul(gel(vker,i),
+                                    random_FpX(dT,vT,p), T, p), T, p);
+    pol = FpXQX_red(pol,T,p);
+    for (i=ir; i<L && L<d; i++)
+    {
+      a = t[i]; la = degpol(a);
+      if (la == 1) { set_irred(i); }
+      else
+      {
+        pari_sp av = avma;
+        b = FqX_rem(pol, a, T,p);
+        if (degpol(b)<=0) { avma=av; continue; }
+        b = FpXQXQ_halfFrobenius(b, a,T,p);
+        if (degpol(b)<=0) { avma=av; continue; }
+        gel(b,2) = Fq_sub(gel(b,2), gen_1,T,p);
+        b = FqX_gcd(a,b, T,p); lb = degpol(b);
+        if (lb && lb < la)
+        {
+          b = FpXQX_normalize(b, T,p);
+          t[L] = FqX_div(a,b,T,p);
+          t[i]= b; L++;
+        }
+        else avma = av;
+      }
+    }
+  }
+  return d;
+}
+
+/* split into r factors of degree d */
+static void
+FqX_split(GEN *t, long d, GEN q, GEN S, GEN T, GEN p)
+{
+  GEN u = *t;
+  long l, v, is2, cnt, dt = degpol(u), dT = degpol(T);
+  pari_sp av;
+  pari_timer ti;
+  GEN w,w0;
+
+  if (dt == d) return;
+  v = varn(*t);
+  if (DEBUGLEVEL > 6) timer_start(&ti);
+  av = avma; is2 = equaliu(p, 2);
+  for(cnt = 1;;cnt++, avma = av)
+  { /* splits *t with probability ~ 1 - 2^(1-r) */
+    w = w0 = random_FpXQX(dt,v, T,p);
+    if (degpol(w) <= 0) continue;
+    for (l=1; l<d; l++) /* sum_{0<i<d} w^(q^i), result in (F_q)^r */
+      w = RgX_add(w0, FqX_Frobenius_eval(w, S, u, T, p));
+    w = FpXQX_red(w, T,p);
+    if (is2)
+    {
+      w0 = w;
+      for (l=1; l<dT; l++) /* sum_{0<i<k} w^(2^i), result in (F_2)^r */
+      {
+        w = FqX_rem(FqX_sqr(w,T,p), *t, T,p);
+        w = FpXX_red(RgX_add(w0,w), p);
+      }
+    }
+    else
+    {
+      w = FpXQXQ_halfFrobenius(w, *t, T, p);
+      /* w in {-1,0,1}^r */
+      if (degpol(w) <= 0) continue;
+      gel(w,2) = gadd(gel(w,2), gen_1);
+    }
+    w = FqX_gcd(*t,w, T,p); l = degpol(w);
+    if (l && l != dt) break;
+  }
+  w = gerepileupto(av,FpXQX_normalize(w,T,p));
+  if (DEBUGLEVEL > 6)
+    err_printf("[FqX_split] splitting time: %ld (%ld trials)\n",
+               timer_delay(&ti),cnt);
+  l /= d; t[l] = FqX_div(*t,w, T,p); *t = w;
+  FqX_split(t+l,d,q,S,T,p);
+  FqX_split(t  ,d,q,S,T,p);
+}
+
+/*******************************************************************/
+/*                                                                 */
+/*                  FACTOR USING TRAGER'S TRICK                    */
+/*                                                                 */
+/*******************************************************************/
+static GEN
+FqX_frobinv_inplace(GEN F, GEN T, GEN p)
+{
+  if (T)
+  {
+    GEN frobinv = powiu(p, degpol(T)-1);
+    long i, l = lg(F);
+    for (i=2; i<l; i++) gel(F,i) = Fq_pow(gel(F,i), frobinv, T,p);
+  }
+  return F;
+}
+static GEN
+FqX_frob_deflate(GEN f, GEN T, GEN p)
+{ return FqX_frobinv_inplace(RgX_deflate(f, itos(p)), T, p); }
+
+static long
+isabsolutepol(GEN f)
+{
+  long i, l = lg(f);
+  for(i=2; i<l; i++)
+  {
+    GEN c = gel(f,i);
+    if (typ(c) == t_POL && degpol(c) > 0) return 0;
+  }
+  return 1;
+}
+
+static void
+add(GEN z, GEN g, long d) { vectrunc_append(z, mkvec2(utoipos(d), g)); }
+/* return number of roots of u; assume deg u >= 0 */
+long
+FqX_split_deg1(GEN *pz, GEN u, GEN T, GEN p)
+{
+  long dg, N = degpol(u);
+  GEN v, S, g, X, z = vectrunc_init(N+1);
+
+  *pz = z;
+  if (N == 0) return 0;
+  if (N == 1) return 1;
+  v = X = pol_x(varn(u));
+  S = FqX_Frobenius_powers(u, T, p);
+  vectrunc_append(z, S);
+  v = FqX_Frobenius_eval(v, S, u, T, p);
+  g = FqX_gcd(FpXX_sub(v,X,p),u, T,p);
+  dg = degpol(g);
+  if (dg > 0) add(z, FpXQX_normalize(g,T,p), dg);
+  return dg;
+}
+
+/* return number of factors; z not properly initialized if deg(u) <= 1 */
+long
+FqX_split_by_degree(GEN *pz, GEN u, GEN T, GEN p)
+{
+  long nb = 0, d, dg, N = degpol(u);
+  GEN v, S, g, X, z = vectrunc_init(N+1);
+
+  *pz = z;
+  if (N <= 1) return 1;
+  v = X = pol_x(varn(u));
+  S = FqX_Frobenius_powers(u, T, p);
+  vectrunc_append(z, S);
+  for (d=1; d <= N>>1; d++)
+  {
+    v = FqX_Frobenius_eval(v, S, u, T, p);
+    g = FqX_gcd(FpXX_sub(v,X,p),u, T,p);
+    dg = degpol(g); if (dg <= 0) continue;
+    /* all factors of g have degree d */
+    add(z, FpXQX_normalize(g, T,p), dg / d); nb += dg / d;
+    N -= dg;
+    if (N)
+    {
+      u = FqX_div(u,g, T,p);
+      v = FqX_rem(v,u, T,p);
+    }
+  }
+  if (N) { add(z, FpXQX_normalize(u, T,p), 1); nb++; }
+  return nb;
+}
+
+static GEN
+FqX_split_equal(GEN L, GEN S, GEN T, GEN p)
+{
+  long n = itos(gel(L,1));
+  GEN u = gel(L,2), z = cgetg(n + 1, t_COL);
+  gel(z,1) = u;
+  FqX_split((GEN*)(z+1), degpol(u) / n, powiu(p, degpol(T)), S, T, p);
+  return z;
+}
+GEN
+FqX_split_roots(GEN z, GEN T, GEN p, GEN pol)
+{
+  GEN S = gel(z,1), L = gel(z,2), rep = FqX_split_equal(L, S, T, p);
+  if (pol) rep = shallowconcat(rep, FqX_div(pol, gel(L,2), T,p));
+  return rep;
+}
+GEN
+FqX_split_all(GEN z, GEN T, GEN p)
+{
+  GEN S = gel(z,1), rep = cgetg(1, t_VEC);
+  long i, l = lg(z);
+  for (i = 2; i < l; i++)
+    rep = shallowconcat(rep, FqX_split_equal(gel(z,i), S, T, p));
+  return rep;
+}
+
+/* not memory-clean, as Flx_factorff_i, returning only linear factors */
+static GEN
+Flx_rootsff_i(GEN P, GEN T, ulong p)
+{
+  GEN V, F = gel(Flx_factor(P,p), 1);
+  long i, lfact = 1, nmax = lgpol(P), n = lg(F), dT = get_Flx_degree(T);
+
+  V = cgetg(nmax,t_COL);
+  for(i=1;i<n;i++)
+  {
+    GEN R, Fi = gel(F,i);
+    long di = degpol(Fi), j, r;
+    if (dT % di) continue;
+    R = Flx_factorff_irred(gel(F,i),T,p);
+    r = lg(R);
+    for (j=1; j<r; j++,lfact++)
+      gel(V,lfact) = Flx_neg(gmael(R,j, 2), p);
+  }
+  setlg(V,lfact);
+  gen_sort_inplace(V, (void*) &cmp_Flx, &cmp_nodata, NULL);
+  return V;
+}
+GEN
+Flx_rootsff(GEN P, GEN T, ulong p)
+{
+  pari_sp av = avma;
+  return gerepilecopy(av, Flx_rootsff_i(P, T, p));
+}
+
+/* dummy implementation */
+static GEN
+F2x_rootsff_i(GEN P, GEN T)
+{
+  return FlxC_to_F2xC(Flx_rootsff_i(F2x_to_Flx(P), F2x_to_Flx(T), 2UL));
+}
+
+/* not memory-clean, as FpX_factorff_i, returning only linear factors */
+static GEN
+FpX_rootsff_i(GEN P, GEN T, GEN p)
+{
+  GEN V, F;
+  long i, lfact, nmax, n, dT;
+  if (lgefint(p)==3)
+  {
+    ulong pp = p[2];
+    GEN V = Flx_rootsff_i(ZX_to_Flx(P,pp), ZXT_to_FlxT(T,pp), pp);
+    return FlxC_to_ZXC(V);
+  }
+  F = gel(FpX_factor(P,p), 1);
+  lfact = 1; nmax = lgpol(P); n = lg(F); dT = get_FpX_degree(T);
+
+  V = cgetg(nmax,t_COL);
+  for(i=1;i<n;i++)
+  {
+    GEN R, Fi = gel(F,i);
+    long di = degpol(Fi), j, r;
+    if (dT % di) continue;
+    R = FpX_factorff_irred(gel(F,i),T,p);
+    r = lg(R);
+    for (j=1; j<r; j++,lfact++)
+      gel(V,lfact) = Fq_to_FpXQ(Fq_neg(gmael(R,j, 2), T, p), T, p);
+  }
+  setlg(V,lfact);
+  gen_sort_inplace(V, (void*) &cmp_RgX, &cmp_nodata, NULL);
+  return V;
+}
+GEN
+FpX_rootsff(GEN P, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  return gerepilecopy(av, FpX_rootsff_i(P, T, p));
+}
+
+static GEN
+F2xqX_quad_roots(GEN P, GEN T)
+{
+  GEN b= gel(P,3), c = gel(P,2);
+  if (lgpol(b))
+  {
+    GEN z, d = F2xq_div(c, F2xq_sqr(b,T),T);
+    if (F2xq_trace(d,T))
+      return cgetg(1, t_COL);
+    z = F2xq_mul(b, F2xq_Artin_Schreier(d, T), T);
+    return mkcol2(z, F2x_add(b, z));
+  }
+  else
+    return mkcol(F2xq_sqrt(c, T));
+}
+
+/* Assume p>2 and x monic */
+static GEN
+FlxqX_quad_roots(GEN x, GEN T, ulong p)
+{
+  GEN s, D, nb, b = gel(x,3), c = gel(x,2);
+  D = Flx_sub(Flxq_sqr(b,T,p), Flx_mulu(c,4,p), p);
+  nb = Flx_neg(b,p);
+  if (lgpol(D)==0)
+    return mkcol(Flx_halve(nb, p));
+  s = Flxq_sqrt(D,T,p);
+  if (!s) return cgetg(1, t_COL);
+  s = Flx_halve(Flx_add(s,nb,p),p);
+  return mkcol2(s, Flx_sub(nb,s,p));
+}
+
+static GEN
+FpXQX_quad_roots(GEN x, GEN T, GEN p)
+{
+  GEN s, D, nb, b = gel(x,3), c = gel(x,2);
+  if (equaliu(p, 2))
+  {
+    GEN f2 = ZXX_to_F2xX(x, get_FpX_var(T));
+    s = F2xqX_quad_roots(f2, ZX_to_F2x(get_FpX_mod(T)));
+    return F2xC_to_ZXC(s);
+  }
+  D = Fq_sub(Fq_sqr(b,T,p), Fq_Fp_mul(c,utoi(4),T,p), T,p);
+  nb = Fq_neg(b,T,p);
+  if (signe(D)==0)
+    return mkcol(Fq_to_FpXQ(Fq_halve(nb,T, p),T,p));
+  s = Fq_sqrt(D,T,p);
+  if (!s) return cgetg(1, t_COL);
+  s = Fq_halve(Fq_add(s,nb,T,p),T, p);
+  return mkcol2(Fq_to_FpXQ(s,T,p), Fq_to_FpXQ(Fq_sub(nb,s,T,p),T,p));
+}
+
+static GEN
+F2xqX_Frobenius_deflate(GEN S, GEN T)
+{
+  GEN F = RgX_deflate(S, 2);
+  long i, l = lg(F);
+  for (i=2; i<l; i++)
+    gel(F,i) = F2xq_sqrt(gel(F,i), T);
+  return F;
+}
+
+static GEN
+F2xX_to_F2x(GEN x)
+{
+  long l=nbits2lg(lgpol(x));
+  GEN z=cgetg(l,t_VECSMALL);
+  long i,j,k;
+  z[1]=x[1];
+  for(i=2, k=1,j=BITS_IN_LONG;i<lg(x);i++,j++)
+  {
+    if (j==BITS_IN_LONG)
+    {
+      j=0; k++; z[k]=0;
+    }
+    if (lgpol(gel(x,i)))
+      z[k]|=1UL<<j;
+  }
+  return F2x_renormalize(z,l);
+}
+
+static GEN
+F2xqX_easyroots(GEN f, GEN T)
+{
+  if (F2xY_degreex(f) <= 0) return F2x_rootsff_i(F2xX_to_F2x(f), T);
+  if (degpol(f)==1) return mkcol(constant_coeff(f));
+  if (degpol(f)==2) return F2xqX_quad_roots(f,T);
+  return NULL;
+}
+
+/* Adapted from Shoup NTL */
+static GEN
+F2xqX_factor_squarefree(GEN f, GEN T)
+{
+  pari_sp av = avma;
+  GEN r, t, v, tv;
+  long q, n = degpol(f);
+  GEN u = const_vec(n+1, pol1_F2xX(varn(f),T[1]));
+  for(q = 1;;q *= 2)
+  {
+    r = F2xqX_gcd(f, F2xX_deriv(f), T);
+    t = F2xqX_div(f, r, T);
+    if (degpol(t) > 0)
+    {
+      long j;
+      for(j = 1;;j++)
+      {
+        v = F2xqX_gcd(r, t, T);
+        tv = F2xqX_div(t, v, T);
+        if (degpol(tv) > 0)
+          gel(u, j*q) = F2xqX_normalize(tv, T);
+        if (degpol(v) <= 0) break;
+        r = F2xqX_div(r, v, T);
+        t = v;
+      }
+      if (degpol(r) == 0) break;
+    }
+    f = F2xqX_Frobenius_deflate(r, T);
+  }
+  return gerepilecopy(av, u);
+}
+
+static void
+F2xqX_roots_edf(GEN Sp, GEN xp, GEN Xp, GEN T, GEN V, long idx)
+{
+  pari_sp btop;
+  long n = degpol(Sp);
+  GEN S, f, ff;
+  GEN R = F2xqX_easyroots(Sp, T);
+  if (R)
+  {
+    long i, l = lg(R)-1;
+    for (i=0; i<l; i++)
+      gel(V, idx+i) = gel(R,1+i);
+    return;
+  }
+  S = Sp;
+  Xp = F2xqX_rem(Xp, S, T);
+  btop = avma;
+  while (1)
+  {
+    GEN a = random_F2xqX(degpol(Sp), varn(Sp), T);
+    GEN R = gel(F2xqXQV_auttrace(mkvec3(xp, Xp, a), F2x_degree(T), S, T), 3);
+    f = F2xqX_gcd(R, Sp, T);
+    if (degpol(f) > 0 && degpol(f) < n) break;
+    avma = btop;
+  }
+  f = gerepileupto(btop, F2xqX_normalize(f, T));
+  ff = F2xqX_div(Sp, f, T);
+  F2xqX_roots_edf(f, xp, Xp, T, V, idx);
+  F2xqX_roots_edf(ff,xp, Xp, T, V, idx+degpol(f));
+}
+
+static GEN
+F2xqXQ_Frobenius(GEN xp, GEN Xp, GEN f, GEN T)
+{
+  ulong dT = F2x_degree(T), df = degpol(f);
+  if (dT >= expu(dT)*usqrt(df))
+    return gel(F2xqXQV_autpow(mkvec2(xp, Xp), dT, f, T), 2);
+  else
+    return F2xqXQ_pow(pol_x(varn(f)), int2n(dT), f, T);
+}
+
+static GEN
+F2xqX_roots_ddf(GEN f, GEN xp, GEN T)
+{
+  GEN X, Xp, Xq, g, V;
+  long n;
+  GEN R = F2xqX_easyroots(f, T);
+  if (R) return R;
+  X  = pol_x(varn(f));
+  Xp = F2xqXQ_sqr(X, f, T);
+  Xq = F2xqXQ_Frobenius(xp, Xp, f, T);
+  g = F2xqX_gcd(F2xX_add(Xq, X), f, T);
+  n = degpol(g);
+  if (n==0) return cgetg(1, t_COL);
+  g = F2xqX_normalize(g, T);
+  V = cgetg(n+1,t_COL);
+  F2xqX_roots_edf(g, xp, Xp, T, V, 1);
+  return V;
+}
+static GEN
+F2xqX_roots_i(GEN S, GEN T)
+{
+  GEN xp, F, M, V, R;
+  long i, j, s, l;
+  S = F2xqX_red(S, T);
+  if (!signe(S)) pari_err_ROOTS0("F2xqX_roots");
+  if (degpol(S)==0) return cgetg(1, t_COL);
+  S = F2xqX_normalize(S, T);
+  R = F2xqX_easyroots(S, T);
+  if (R) return gen_sort(R, (void*) &cmp_Flx, &cmp_nodata);
+  xp = F2x_Frobenius(T);
+  V = F2xqX_factor_squarefree(S, T);
+  l = lg(V);
+  for (s=0, i=1; i < l; i++)
+    s += !!degpol(gel(V,i));
+  F = cgetg(s+1, t_VEC);
+  for (i=1, j=1; i < l; i++)
+    if (degpol(gel(V,i)))
+      gel(F, j++) = F2xqX_roots_ddf(gel(V,i), xp, T);
+  M = shallowconcat1(F);
+  gen_sort_inplace(M, (void*) &cmp_Flx, &cmp_nodata, NULL);
+  return M;
+}
+
+static GEN
+FlxX_to_Flx(GEN f)
+{
+  long i, l = lg(f);
+  GEN V = cgetg(l, t_VECSMALL);
+  V[1] = ((ulong)f[1])&VARNBITS;
+  for(i=2; i<l; i++)
+    V[i] = lgpol(gel(f,i)) ? mael(f,i,2): 0L;
+  return V;
+}
+
+static GEN
+FlxqX_easyroots(GEN f, GEN T, ulong p)
+{
+  if (FlxY_degreex(f) <= 0) return Flx_rootsff_i(FlxX_to_Flx(f), T, p);
+  if (degpol(f)==1) return mkcol(Flx_neg(constant_coeff(f), p));
+  if (degpol(f)==2) return FlxqX_quad_roots(f,T,p);
+  return NULL;
+}
+
+static GEN
+FlxqX_invFrobenius(GEN xp, GEN T, ulong p)
+{
+  return Flxq_autpow(xp, get_Flx_degree(T)-1, T, p);
+}
+
+static GEN
+FlxqX_Frobenius_deflate(GEN S, GEN ixp, GEN T, ulong p)
+{
+  GEN F = RgX_deflate(S, p);
+  long i, l = lg(F);
+  if (typ(ixp)==t_INT)
+    for (i=2; i<l; i++)
+      gel(F,i) = Flxq_pow(gel(F,i), ixp, T, p);
+  else
+  {
+    long n = brent_kung_optpow(get_Flx_degree(T)-1, l-2, 1);
+    GEN V = Flxq_powers(ixp, n, T, p);
+    for (i=2; i<l; i++)
+      gel(F,i) = Flx_FlxqV_eval(gel(F,i), V, T, p);
+  }
+  return F;
+}
+
+/* Adapted from Shoup NTL */
+static GEN
+FlxqX_factor_squarefree(GEN f, GEN xp, GEN T, ulong p)
+{
+  pari_sp av = avma;
+  GEN r, t, v, tv;
+  long q, n = degpol(f);
+  GEN u = const_vec(n+1, pol1_FlxX(varn(f),get_Flx_var(T)));
+  GEN ixp = NULL;
+  for(q = 1;;q *= p)
+  {
+    r = FlxqX_gcd(f, FlxX_deriv(f, p), T, p);
+    t = FlxqX_div(f, r, T, p);
+    if (degpol(t) > 0)
+    {
+      long j;
+      for(j = 1;;j++)
+      {
+        v = FlxqX_gcd(r, t, T, p);
+        tv = FlxqX_div(t, v, T, p);
+        if (degpol(tv) > 0)
+          gel(u, j*q) = FlxqX_normalize(tv, T, p);
+        if (degpol(v) <= 0) break;
+        r = FlxqX_div(r, v, T, p);
+        t = v;
+      }
+      if (degpol(r) == 0) break;
+    }
+    if (!ixp) ixp = FlxqX_invFrobenius(xp, T, p);
+    f = FlxqX_Frobenius_deflate(r, ixp, T, p);
+  }
+  return gerepilecopy(av, u);
+}
+
+static void
+FlxqX_roots_edf(GEN Sp, GEN xp, GEN Xp, GEN T, ulong p, GEN V, long idx)
+{
+  pari_sp btop;
+  long n = degpol(Sp);
+  GEN S, f, ff;
+  long vT = get_Flx_var(T), dT = get_Flx_degree(T);
+  GEN R = FlxqX_easyroots(Sp, T, p);
+  if (R)
+  {
+    long i, l = lg(R)-1;
+    for (i=0; i<l; i++)
+      gel(V, idx+i) = gel(R,1+i);
+    return;
+  }
+  S = FlxqX_get_red(Sp, T, p);
+  Xp = FlxqX_rem(Xp, S, T, p);
+  btop = avma;
+  while (1)
+  {
+    GEN a = deg1pol(pol1_Flx(vT), random_Flx(dT, vT, p), varn(Sp));
+    GEN ap2 = FlxqXQ_powu(a, p>>1, S, T, p);
+    GEN R = gel(FlxqXQV_autsum(mkvec3(xp, Xp, ap2), get_Flx_degree(T), S, T, p), 3);
+    f = FlxqX_gcd(FlxX_Flx_add(R, Flx_neg(pol1_Flx(vT), p), p), Sp, T, p);
+    if (degpol(f) > 0 && degpol(f) < n) break;
+    avma = btop;
+  }
+  f = gerepileupto(btop, FlxqX_normalize(f, T, p));
+  ff = FlxqX_div(Sp, f, T, p);
+  FlxqX_roots_edf(f, xp, Xp, T, p, V, idx);
+  FlxqX_roots_edf(ff,xp, Xp, T, p, V, idx+degpol(f));
+}
+
+static GEN
+FlxqX_roots_ddf(GEN f, GEN xp, GEN T, ulong p)
+{
+  GEN X, Xp, Xq, g, V;
+  long n, dT = get_Flx_degree(T);
+  GEN R = FlxqX_easyroots(f, T, p);
+  if (R) return R;
+  X  = pol_x(varn(f));
+  Xp = FlxqXQ_powu(X, p, f, T, p);
+  Xq = gel(FlxqXQV_autpow(mkvec2(xp, Xp), dT, f, T, p), 2);
+  g = FlxqX_gcd(FlxX_sub(Xq, X, p), f, T, p);
+  n = degpol(g);
+  if (n==0) return cgetg(1, t_COL);
+  g = FlxqX_normalize(g, T, p);
+  V = cgetg(n+1,t_COL);
+  FlxqX_roots_edf(g, xp, Xp, T, p, V, 1);
+  return V;
+}
+
+/* do not handle p==2 */
+static GEN
+FlxqX_roots_i(GEN S, GEN T, ulong p)
+{
+  GEN xp, F, M, V, R;
+  long i, j, s, l;
+  S = FlxqX_red(S, T, p);
+  if (!signe(S)) pari_err_ROOTS0("FlxqX_roots");
+  if (degpol(S)==0) return cgetg(1, t_COL);
+  S = FlxqX_normalize(S, T, p);
+  R = FlxqX_easyroots(S, T, p);
+  if (R) return gen_sort(R, (void*) &cmp_Flx, &cmp_nodata);
+  xp = Flx_Frobenius(T, p);
+  V = FlxqX_factor_squarefree(S, xp, T, p);
+  l = lg(V);
+  for (s=0, i=1; i < l; i++)
+    s += !!degpol(gel(V,i));
+  F = cgetg(s+1, t_VEC);
+  for (i=1, j=1; i < l; i++)
+    if (degpol(gel(V,i)))
+      gel(F, j++) = FlxqX_roots_ddf(gel(V,i), xp, T, p);
+  M = shallowconcat1(F);
+  gen_sort_inplace(M, (void*) &cmp_Flx, &cmp_nodata, NULL);
+  return M;
+}
+
+static GEN
+FpXQX_easyroots(GEN f, GEN T, GEN p)
+{
+  if (isabsolutepol(f)) return FpX_rootsff_i(simplify_shallow(f), T, p);
+  if (degpol(f)==1) return mkcol(Fq_to_FpXQ(Fq_neg(constant_coeff(f),T,p),T,p));
+  if (degpol(f)==2) return FpXQX_quad_roots(f,T,p);
+  return NULL;
+}
+
+/* Adapted from Shoup NTL */
+static GEN
+FpXQX_factor_squarefree(GEN f, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  GEN r, t, v, tv;
+  long j, n = degpol(f);
+  GEN u = const_vec(n+1, pol_1(varn(f)));
+  r = FpXQX_gcd(f, FpXX_deriv(f, p), T, p);
+  t = FpXQX_div(f, r, T, p);
+  for (j = 1;;j++)
+  {
+    v = FpXQX_gcd(r, t, T, p);
+    tv = FpXQX_div(t, v, T, p);
+    if (degpol(tv) > 0)
+      gel(u, j) = FpXQX_normalize(tv, T, p);
+    if (degpol(v) <= 0) break;
+    r = FpXQX_div(r, v, T, p);
+    t = v;
+  }
+  return gerepilecopy(av, u);
+}
+
+static void
+FpXQX_roots_edf(GEN Sp, GEN xp, GEN Xp, GEN T, GEN p, GEN V, long idx)
+{
+  pari_sp btop;
+  long n = degpol(Sp);
+  GEN S, f, ff;
+  long vT = get_FpX_var(T), dT = get_FpX_degree(T);
+  GEN R = FpXQX_easyroots(Sp, T, p);
+  if (R)
+  {
+    long i, l = lg(R)-1;
+    for (i=0; i<l; i++)
+      gel(V, idx+i) = gel(R,1+i);
+    return;
+  }
+  S = FpXQX_get_red(Sp, T, p);
+  Xp = FpXQX_rem(Xp, S, T, p);
+  btop = avma;
+  while (1)
+  {
+    GEN a = deg1pol(pol_1(vT), random_FpX(dT, vT, p), varn(Sp));
+    GEN ap2 = FpXQXQ_pow(a, shifti(p,-1), S, T, p);
+    GEN R = gel(FpXQXQV_autsum(mkvec3(xp, Xp, ap2), get_FpX_degree(T), S, T, p), 3);
+    f = FpXQX_gcd(FqX_Fq_add(R, FpX_neg(pol_1(vT), p), T, p), Sp, T, p);
+    if (degpol(f) > 0 && degpol(f) < n) break;
+    avma = btop;
+  }
+  f = gerepileupto(btop, FpXQX_normalize(f, T, p));
+  ff = FpXQX_div(Sp, f, T, p);
+  FpXQX_roots_edf(f, xp, Xp, T, p, V, idx);
+  FpXQX_roots_edf(ff,xp, Xp, T, p, V, idx+degpol(f));
+}
+
+static GEN
+FpXQX_roots_ddf(GEN f, GEN xp, GEN T, GEN p)
+{
+  GEN X, Xp, Xq, g, V;
+  long n, dT = get_FpX_degree(T);
+  GEN R = FpXQX_easyroots(f, T, p);
+  if (R) return R;
+  X  = pol_x(varn(f));
+  Xp = FpXQXQ_pow(X, p, f, T, p);
+  Xq = gel(FpXQXQV_autpow(mkvec2(xp, Xp), dT, f, T, p), 2);
+  g = FpXQX_gcd(FpXX_sub(Xq, X, p), f, T, p);
+  n = degpol(g);
+  if (n==0) return cgetg(1, t_COL);
+  g = FpXQX_normalize(g, T, p);
+  V = cgetg(n+1,t_COL);
+  FpXQX_roots_edf(g, xp, Xp, T, p, V, 1);
+  return V;
+}
+
+/* do not handle small p */
+static GEN
+FpXQX_roots_i(GEN S, GEN T, GEN p)
+{
+  GEN xp, F, M, V, R;
+  long i, j, s, l;
+  if (lgefint(p)==3)
+  {
+    ulong pp = p[2];
+    if (pp == 2)
+    {
+      GEN V = F2xqX_roots_i(ZXX_to_F2xX(S,get_FpX_var(T)), ZX_to_F2x(get_FpX_mod(T)));
+      return F2xC_to_ZXC(V);
+    }
+    else
+    {
+      GEN V = FlxqX_roots_i(ZXX_to_FlxX(S,pp,get_FpX_var(T)), ZXT_to_FlxT(T,pp), pp);
+      return FlxC_to_ZXC(V);
+    }
+  }
+  S = FpXQX_red(S, T, p);
+  if (!signe(S)) pari_err_ROOTS0("FpXQX_roots");
+  if (degpol(S)==0) return cgetg(1, t_COL);
+  S = FpXQX_normalize(S, T, p);
+  R = FpXQX_easyroots(S, T, p);
+  if (R) return gen_sort(R, (void*) &cmp_RgX, &cmp_nodata);
+  xp = FpX_Frobenius(T, p);
+  V = FpXQX_factor_squarefree(S, T, p);
+  l = lg(V);
+  for (s=0, i=1; i < l; i++)
+    s += !!degpol(gel(V,i));
+  F = cgetg(s+1, t_VEC);
+  for (i=1, j=1; i < l; i++)
+    if (degpol(gel(V,i)))
+      gel(F, j++) = FpXQX_roots_ddf(gel(V,i), xp, T, p);
+  M = shallowconcat1(F);
+  gen_sort_inplace(M, (void*) &cmp_RgX, &cmp_nodata, NULL);
+  return M;
+}
+
+GEN
+F2xqX_roots(GEN x, GEN T)
+{
+  pari_sp av = avma;
+  return gerepilecopy(av, F2xqX_roots_i(x, T));
+}
+
+GEN
+FlxqX_roots(GEN x, GEN T, ulong p)
+{
+  pari_sp av = avma;
+  if (p==2)
+  {
+    GEN V = F2xqX_roots_i(FlxX_to_F2xX(x), Flx_to_F2x(get_Flx_mod(T)));
+    return gerepileupto(av, F2xC_to_FlxC(V));
+  }
+  return gerepilecopy(av, FlxqX_roots_i(x, T, p));
+}
+
+GEN
+FpXQX_roots(GEN x, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  return gerepilecopy(av, FpXQX_roots_i(x, T, p));
+}
+
+static long
+FqX_sqf_split(GEN *t0, GEN q, GEN T, GEN p)
+{
+  GEN *t = t0, u = *t, v, S, g, X;
+  long d, dg, N = degpol(u);
+
+  if (N == 1) return 1;
+  v = X = pol_x(varn(u));
+  S = FqX_Frobenius_powers(u, T, p);
+  for (d=1; d <= N>>1; d++)
+  {
+    v = FqX_Frobenius_eval(v, S, u, T, p);
+    g = FpXQX_normalize(FqX_gcd(FpXX_sub(v,X,p),u, T,p),T,p);
+    dg = degpol(g); if (dg <= 0) continue;
+
+    /* all factors of g have degree d */
+    *t = g;
+    FqX_split(t, d, q, S, T, p);
+    t += dg / d;
+    N -= dg;
+    if (N)
+    {
+      u = FqX_div(u,g, T,p);
+      v = FqX_rem(v,u, T,p);
+    }
+  }
+  if (N) *t++ = u;
+  return t - t0;
+}
+
+/* not memory-clean */
+static GEN
+FpX_factorff_i(GEN P, GEN T, GEN p)
+{
+  GEN V, E, F = FpX_factor(P,p);
+  long i, lfact = 1, nmax = lgpol(P), n = lgcols(F);
+
+  V = cgetg(nmax,t_VEC);
+  E = cgetg(nmax,t_VECSMALL);
+  for(i=1;i<n;i++)
+  {
+    GEN R = FpX_factorff_irred(gmael(F,1,i),T,p), e = gmael(F,2,i);
+    long j, r = lg(R);
+    for (j=1; j<r; j++,lfact++)
+    {
+      gel(V,lfact) = gel(R,j);
+      gel(E,lfact) = e;
+    }
+  }
+  setlg(V,lfact);
+  setlg(E,lfact); return sort_factor_pol(mkvec2(V,E), cmp_RgX);
+}
+GEN
+FpX_factorff(GEN P, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  return gerepilecopy(av, FpX_factorff_i(P, T, p));
+}
+
+/* assumes varncmp (varn(T), varn(f)) > 0 */
+static GEN
+FpXQX_factor_i(GEN f, GEN T, GEN p)
+{
+  long pg, j, k, e, N, lfact, pk, d = degpol(f);
+  GEN E, f2, f3, df1, df2, g1, u, q, t;
+
+  switch(d)
+  {
+    case -1: retmkmat2(mkcolcopy(f), mkvecsmall(1));
+    case 0: return trivial_fact();
+  }
+  T = FpX_normalize(T, p);
+  f = FpXQX_normalize(f, T, p);
+  if (isabsolutepol(f)) return FpX_factorff_i(simplify_shallow(f), T, p);
+  if (degpol(f)==2)
+  {
+    long v = varn(f);
+    GEN r = FpXQX_quad_roots(f,T,p);
+    switch(lg(r)-1)
+    {
+    case 0:
+      return mkvec2(mkcolcopy(f), mkvecsmall(1));
+    case 1:
+      return mkvec2(mkcol(deg1pol_shallow(gen_1, Fq_neg(gel(r,1), T, p), v)),
+                    mkvecsmall(2));
+    case 2:
+      {
+        GEN f1 = deg1pol_shallow(gen_1, Fq_neg(gel(r,1), T, p), v);
+        GEN f2 = deg1pol_shallow(gen_1, Fq_neg(gel(r,2), T, p), v);
+        t = mkcol2(f1, f2); E = mkvecsmall2(1, 1);
+        sort_factor_pol(mkvec2(t, E), cmp_RgX);
+        return mkvec2(t, E);
+      }
+    }
+  }
+
+  pg = itos_or_0(p);
+  df2  = NULL; /* gcc -Wall */
+  t = cgetg(d+1,t_VEC);
+  E = cgetg(d+1, t_VECSMALL);
+
+  q = powiu(p, degpol(T));
+  e = lfact = 1;
+  pk = 1;
+  f3 = NULL;
+  df1 = FqX_deriv(f, T, p);
+  for(;;)
+  {
+    long nb0;
+    while (!signe(df1))
+    { /* needs d >= p: pg = 0 can't happen  */
+      pk *= pg; e = pk;
+      f = FqX_frob_deflate(f, T, p);
+      df1 = FqX_deriv(f, T, p); f3 = NULL;
+    }
+    f2 = f3? f3: FqX_gcd(f,df1, T,p);
+    if (!degpol(f2)) u = f;
+    else
+    {
+      g1 = FqX_div(f,f2, T,p);
+      df2 = FqX_deriv(f2, T,p);
+      if (gequal0(df2)) { u = g1; f3 = f2; }
+      else
+      {
+        f3 = FqX_gcd(f2,df2, T,p);
+        u = degpol(f3)? FqX_div(f2, f3, T,p): f2;
+        u = FqX_div(g1, u, T,p);
+      }
+    }
+    /* u is square-free (product of irreducibles of multiplicity e) */
+    N = degpol(u);
+    if (N) {
+      nb0 = lfact;
+      gel(t,lfact) = FpXQX_normalize(u, T,p);
+      if (N == 1) lfact++;
+      else
+      {
+        if (!equaliu(p,2))
+          lfact += FqX_split_Berlekamp(&gel(t,lfact), T, p);
+        else
+          lfact += FqX_sqf_split(&gel(t,lfact), q, T, p);
+      }
+      for (j = nb0; j < lfact; j++) E[j] = e;
+    }
+
+    if (!degpol(f2)) break;
+    f = f2; df1 = df2; e += pk;
+  }
+  setlg(t, lfact);
+  setlg(E, lfact);
+  for (j=1; j<lfact; j++) gel(t,j) = FpXQX_normalize(gel(t,j), T,p);
+  (void)sort_factor_pol(mkvec2(t, E), cmp_RgX);
+  k = 1;
+  for (j = 2; j < lfact; j++)
+  {
+    if (RgX_equal(gel(t,j), gel(t,k)))
+      E[k] += E[j];
+    else
+    { /* new factor */
+      k++;
+      E[k] = E[j];
+      gel(t,k) = gel(t,j);
+    }
+  }
+  setlg(t, k+1);
+  setlg(E, k+1); return mkvec2(t, E);
+}
+
+long
+FqX_ispower(GEN f, ulong k, GEN T, GEN p, GEN *pt)
+{
+  pari_sp av = avma;
+  long v, w;
+  ulong pp;
+  GEN lc, F;
+
+  if (degpol(f) % k) return 0;
+  lc = leading_coeff(f);
+  lc = Fq_sqrtn(lc, stoi(k), T, p, NULL);
+  if (!lc) { av = avma; return 0; }
+  pp = itou_or_0(p);
+  f = FqX_normalize(f, T, p);
+  v = pp? u_lvalrem(k,pp,&k): 0;
+  if (v)
+  {
+    long i;
+    w = u_lval(RgX_deflate_order(f), pp);
+    if (w < v) { avma = av; return 0; }
+    /* deflate as much as possible using frobenius, unless k reduced to 1 */
+    if (k == 1) w = v;
+    f = RgX_deflate(f, upowuu(pp,w));
+    if (T) for (i = 0; i < w; i++) f = FqX_frobinv_inplace(f, T, p);
+    w -= v;
+  }
+  else
+    w = 0;
+  /* k coprime to p; true f we're testing is f^(p^w) */
+  if (k == 1)
+    F = f;
+  else
+  {
+    ulong pow = upowuu(pp,w);
+    F = pt? pol_1(varn(f)): NULL;
+    while (degpol(f) > 0)
+    {
+      GEN gk, g, df = FqX_deriv(f, T, p);
+      long v;
+      if (!signe(df)) { pow *= pp; f = FqX_frob_deflate(f, T, p); continue; }
+      g = FqX_div(f, FqX_normalize(FqX_gcd(f,df,T,p),T,p), T,p);
+      /* g | f is squarefree,monic; remove (g^k)^oo from f */
+      gk = FqX_powu(g, k, T,p);
+      v = 0;
+      for(v = 0;; v++)
+      {
+        GEN q = FqX_divrem(f, gk, T,p, ONLY_DIVIDES);
+        if (!q) break;
+        f = q;
+      }
+      /* some factor from g remains in f ? */
+      if (!v || degpol(FqX_gcd(f,g,T,p))) { avma = av; return 0; }
+      if (F) F = FqX_mul(F, FqX_powu(g, v*pow, T,p), T,p);
+    }
+  }
+  if (pt) *pt = gerepileupto(av, FqX_Fq_mul(F, lc, T,p));
+  return 1;
+}
+
+static void
+ffcheck(pari_sp *av, GEN *f, GEN *T, GEN p)
+{
+  long v;
+  if (typ(*T)!=t_POL) pari_err_TYPE("factorff",*T);
+  if (typ(*f)!=t_POL) pari_err_TYPE("factorff",*f);
+  if (typ(p)!=t_INT) pari_err_TYPE("factorff",p);
+  v = varn(*T);
+  if (varncmp(v, varn(*f)) <= 0)
+    pari_err_PRIORITY("factorff", *T, "<=", varn(*f));
+  *T = RgX_to_FpX(*T, p); *av = avma;
+  *f = RgX_to_FqX(*f, *T,p);
+}
+GEN
+factorff(GEN f, GEN p, GEN T)
+{
+  pari_sp av;
+  GEN z;
+  if (!p || !T)
+  {
+    long pa, t;
+    if (typ(f) != t_POL) pari_err_TYPE("factorff",f);
+    T = p = NULL;
+    t = RgX_type(f, &p, &T, &pa);
+    if (t != t_FFELT) pari_err_TYPE("factorff",f);
+    return FFX_factor(f,T);
+  }
+  ffcheck(&av, &f, &T, p); z = FpXQX_factor_i(f, T, p);
+  return to_Fq_fact(gel(z,1),gel(z,2), T,p, av);
+}
+GEN
+polrootsff(GEN f, GEN p, GEN T)
+{
+  pari_sp av;
+  GEN z;
+  if (!p || !T)
+  {
+    long pa, t;
+    if (typ(f) != t_POL) pari_err_TYPE("polrootsff",f);
+    T = p = NULL;
+    t = RgX_type(f, &p, &T, &pa);
+    if (t != t_FFELT) pari_err_TYPE("polrootsff",f);
+    return FFX_roots(f,T);
+  }
+  ffcheck(&av, &f, &T, p); z = FpXQX_roots_i(f, T, p);
+  return to_FqC(z, T,p, av);
+}
+
+/* factorization of x modulo (T,p). Assume x already reduced */
+GEN
+FpXQX_factor(GEN x, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  return gerepilecopy(av, FpXQX_factor_i(x, T, p));
+}
+
+long
+FqX_is_squarefree(GEN P, GEN T, GEN p)
+{
+  pari_sp av = avma;
+  GEN z = FqX_gcd(P, FqX_deriv(P, T, p), T, p);
+  avma = av;
+  return degpol(z)==0;
+}
+
+/* See also: Isomorphisms between finite field and relative
+ * factorization in polarit3.c */
diff --git a/src/basemath/FpXX.c b/src/basemath/FpXX.c
index fe5fa77..a7e6fb1 100644
--- a/src/basemath/FpXX.c
+++ b/src/basemath/FpXX.c
@@ -152,6 +152,23 @@ FpXX_mulu(GEN P, ulong u, GEN p)
   return FpXX_renormalize(res,lP);
 }
 
+GEN
+FpXX_deriv(GEN P, GEN p)
+{
+  long i, l = lg(P)-1;
+  GEN res;
+
+  if (l < 3) return pol_0(varn(P));
+  res = cgetg(l, t_POL);
+  res[1] = P[1];
+  for (i=2; i<l ; i++)
+  {
+    GEN x = gel(P,i+1);
+    gel(res,i) = typ(x)==t_INT? Fp_mulu(x,i-1,p): FpX_mulu(x,i-1,p);
+  }
+  return FpXX_renormalize(res, l);
+}
+
 /*******************************************************************/
 /*                                                                 */
 /*                             (Fp[X]/(Q))[Y]                      */
@@ -365,7 +382,7 @@ FpXQX_divrem_basecase(GEN x, GEN y, GEN T, GEN p, GEN *pr)
     }
     return pol_0(vx);
   }
-  lead = leading_term(y);
+  lead = leading_coeff(y);
   if (!dy) /* y is constant */
   {
     if (pr && pr != ONLY_DIVIDES)
@@ -378,23 +395,6 @@ FpXQX_divrem_basecase(GEN x, GEN y, GEN T, GEN p, GEN *pr)
     return gerepileupto(av0,x);
   }
   av0 = avma; dz = dx-dy;
-  if (lgefint(p) == 3)
-  { /* assume ab != 0 mod p */
-    {
-      GEN *gptr[2];
-      GEN a, b, t;
-      ulong pp = to_FlxqX(x, y, T, p, &a, &b, &t);
-      z = FlxqX_divrem(a,b,t,pp,pr);
-      tetpil=avma;
-      z = FlxX_to_ZXX(z);
-      if (pr && pr != ONLY_DIVIDES && pr != ONLY_REM)
-        *pr = FlxX_to_ZXX(*pr);
-      else return gerepile(av0,tetpil,z);
-      gptr[0]=pr; gptr[1]=&z;
-      gerepilemanysp(av0,tetpil,gptr,2);
-      return z;
-    }
-  }
   lead = gequal1(lead)? NULL: gclone(Fq_inv(lead,T,p));
   avma = av0;
   z = cgetg(dz+3,t_POL); z[1] = x[1];
@@ -448,25 +448,229 @@ FpXQX_divrem_basecase(GEN x, GEN y, GEN T, GEN p, GEN *pr)
   *pr = rem; return z-2;
 }
 
+static GEN
+FpXQX_halfgcd_basecase(GEN a, GEN b, GEN T, GEN p)
+{
+  pari_sp av=avma;
+  GEN u,u1,v,v1;
+  long vx = varn(a);
+  long n = lgpol(a)>>1;
+  u1 = v = pol_0(vx);
+  u = v1 = pol_1(vx);
+  while (lgpol(b)>n)
+  {
+    GEN r, q = FpXQX_divrem(a,b, T, p, &r);
+    a = b; b = r; swap(u,u1); swap(v,v1);
+    u1 = FpXX_sub(u1, FpXQX_mul(u, q, T, p), p);
+    v1 = FpXX_sub(v1, FpXQX_mul(v, q ,T, p), p);
+    if (gc_needed(av,2))
+    {
+      if (DEBUGMEM>1) pari_warn(warnmem,"FpXQX_halfgcd (d = %ld)",degpol(b));
+      gerepileall(av,6, &a,&b,&u1,&v1,&u,&v);
+    }
+  }
+  return gerepilecopy(av, mkmat2(mkcol2(u,u1), mkcol2(v,v1)));
+}
+static GEN
+FpXQX_addmulmul(GEN u, GEN v, GEN x, GEN y, GEN T, GEN p)
+{
+  return FpXX_add(FpXQX_mul(u, x, T, p),FpXQX_mul(v, y, T, p), p);
+}
+
+static GEN
+FpXQXM_FpXQX_mul2(GEN M, GEN x, GEN y, GEN T, GEN p)
+{
+  GEN res = cgetg(3, t_COL);
+  gel(res, 1) = FpXQX_addmulmul(gcoeff(M,1,1), gcoeff(M,1,2), x, y, T, p);
+  gel(res, 2) = FpXQX_addmulmul(gcoeff(M,2,1), gcoeff(M,2,2), x, y, T, p);
+  return res;
+}
+
+static GEN
+FpXQXM_mul2(GEN A, GEN B, GEN T, GEN p)
+{
+  GEN A11=gcoeff(A,1,1),A12=gcoeff(A,1,2), B11=gcoeff(B,1,1),B12=gcoeff(B,1,2);
+  GEN A21=gcoeff(A,2,1),A22=gcoeff(A,2,2), B21=gcoeff(B,2,1),B22=gcoeff(B,2,2);
+  GEN M1 = FpXQX_mul(FpXX_add(A11,A22, p), FpXX_add(B11,B22, p), T, p);
+  GEN M2 = FpXQX_mul(FpXX_add(A21,A22, p), B11, T, p);
+  GEN M3 = FpXQX_mul(A11, FpXX_sub(B12,B22, p), T, p);
+  GEN M4 = FpXQX_mul(A22, FpXX_sub(B21,B11, p), T, p);
+  GEN M5 = FpXQX_mul(FpXX_add(A11,A12, p), B22, T, p);
+  GEN M6 = FpXQX_mul(FpXX_sub(A21,A11, p), FpXX_add(B11,B12, p), T, p);
+  GEN M7 = FpXQX_mul(FpXX_sub(A12,A22, p), FpXX_add(B21,B22, p), T, p);
+  GEN T1 = FpXX_add(M1,M4, p), T2 = FpXX_sub(M7,M5, p);
+  GEN T3 = FpXX_sub(M1,M2, p), T4 = FpXX_add(M3,M6, p);
+  retmkmat2(mkcol2(FpXX_add(T1,T2, p), FpXX_add(M2,M4, p)),
+            mkcol2(FpXX_add(M3,M5, p), FpXX_add(T3,T4, p)));
+}
+/* Return [0,1;1,-q]*M */
+static GEN
+FpXQX_FpXQXM_qmul(GEN q, GEN M, GEN T, GEN p)
+{
+  GEN u, v, res = cgetg(3, t_MAT);
+  u = FpXX_sub(gcoeff(M,1,1), FpXQX_mul(gcoeff(M,2,1), q, T, p), p);
+  gel(res,1) = mkcol2(gcoeff(M,2,1), u);
+  v = FpXX_sub(gcoeff(M,1,2), FpXQX_mul(gcoeff(M,2,2), q, T, p), p);
+  gel(res,2) = mkcol2(gcoeff(M,2,2), v);
+  return res;
+}
+
+static GEN
+matid2_FpXQXM(long v)
+{
+  retmkmat2(mkcol2(pol_1(v),pol_0(v)),
+            mkcol2(pol_0(v),pol_1(v)));
+}
+
+static GEN
+FpXQX_halfgcd_split(GEN x, GEN y, GEN T, GEN p)
+{
+  pari_sp av=avma;
+  GEN R, S, V;
+  GEN y1, r, q;
+  long l = lgpol(x), n = l>>1, k;
+  if (lgpol(y)<=n) return matid2_FpXQXM(varn(x));
+  R = FpXQX_halfgcd(RgX_shift_shallow(x,-n),RgX_shift_shallow(y,-n), T, p);
+  V = FpXQXM_FpXQX_mul2(R,x,y, T, p); y1 = gel(V,2);
+  if (lgpol(y1)<=n) return gerepilecopy(av, R);
+  q = FpXQX_divrem(gel(V,1), y1, T, p, &r);
+  k = 2*n-degpol(y1);
+  S = FpXQX_halfgcd(RgX_shift_shallow(y1,-k), RgX_shift_shallow(r,-k), T, p);
+  return gerepileupto(av, FpXQXM_mul2(S,FpXQX_FpXQXM_qmul(q,R, T, p), T, p));
+}
+
+/* Return M in GL_2(Fp[X]) such that:
+if [a',b']~=M*[a,b]~ then degpol(a')>= (lgpol(a)>>1) >degpol(b')
+*/
+
+static GEN
+FpXQX_halfgcd_i(GEN x, GEN y, GEN T, GEN p)
+{
+  if (lg(x)<=FpXQX_HALFGCD_LIMIT) return FpXQX_halfgcd_basecase(x, y, T, p);
+  return FpXQX_halfgcd_split(x, y, T, p);
+}
+
 GEN
-FpXQX_gcd(GEN P, GEN Q, GEN T, GEN p)
+FpXQX_halfgcd(GEN x, GEN y, GEN T, GEN p)
 {
-  pari_sp av=avma, av0;
-  GEN R;
+  pari_sp av = avma;
+  GEN M,q,r;
+  if (lgefint(p)==3)
+  {
+    ulong pp = to_FlxqX(x, y, T, p, &x, &y, &T);
+    M = FlxXM_to_ZXXM(FlxqX_halfgcd(x, y, T, pp));
+  }
+  else
+  {
+    if (!signe(x))
+    {
+      long v = varn(x);
+      retmkmat2(mkcol2(pol_0(v),pol_1(v)),
+                mkcol2(pol_1(v),pol_0(v)));
+    }
+    if (degpol(y)<degpol(x)) return FpXQX_halfgcd_i(x, y, T, p);
+    q = FpXQX_divrem(y, x, T, p, &r);
+    M = FpXQX_halfgcd_i(x, r, T, p);
+    gcoeff(M,1,1) = FpXX_sub(gcoeff(M,1,1), FpXQX_mul(q, gcoeff(M,1,2), T, p), p);
+    gcoeff(M,2,1) = FpXX_sub(gcoeff(M,2,1), FpXQX_mul(q, gcoeff(M,2,2), T, p), p);
+  }
+  return gerepilecopy(av, M);
+}
+
+static GEN
+FpXQX_gcd_basecase(GEN a, GEN b, GEN T, GEN p)
+{
+  pari_sp av = avma, av0=avma;
+  while (signe(b))
+  {
+    GEN c;
+    if (gc_needed(av0,2))
+    {
+      if (DEBUGMEM>1) pari_warn(warnmem,"FpXQX_gcd (d = %ld)",degpol(b));
+      gerepileall(av0,2, &a,&b);
+    }
+    av = avma; c = FpXQX_rem(a, b, T, p); a=b; b=c;
+  }
+  avma = av; return a;
+}
+
+GEN
+FpXQX_gcd(GEN x, GEN y, GEN T, GEN p)
+{
+  pari_sp av = avma;
   if (lgefint(p) == 3)
   {
     GEN Pl, Ql, Tl, U;
-    ulong pp = to_FlxqX(P, Q, T, p, &Pl, &Ql, &Tl);
+    ulong pp = to_FlxqX(x, y, T, p, &Pl, &Ql, &Tl);
     U  = FlxqX_gcd(Pl, Ql, Tl, pp);
     return gerepileupto(av, FlxX_to_ZXX(U));
   }
-  P = FpXX_red(P, p); av0 = avma;
-  Q = FpXX_red(Q, p);
-  while (signe(Q))
+  x = FpXQX_red(x, T, p);
+  y = FpXQX_red(y, T, p);
+  if (!signe(x)) return gerepileupto(av, y);
+  while (lg(y)>FpXQX_GCD_LIMIT)
+  {
+    GEN c;
+    if (lgpol(y)<=(lgpol(x)>>1))
+    {
+      GEN r = FpXQX_rem(x, y, T, p);
+      x = y; y = r;
+    }
+    c = FpXQXM_FpXQX_mul2(FpXQX_halfgcd(x,y, T, p), x, y, T, p);
+    x = gel(c,1); y = gel(c,2);
+    gerepileall(av,2,&x,&y);
+  }
+  return gerepileupto(av, FpXQX_gcd_basecase(x, y, T, p));
+}
+
+static GEN
+FpXQX_extgcd_basecase(GEN a, GEN b, GEN T, GEN p, GEN *ptu, GEN *ptv)
+{
+  pari_sp av=avma;
+  GEN u,v,d,d1,v1;
+  long vx = varn(a);
+  d = a; d1 = b;
+  v = pol_0(vx); v1 = pol_1(vx);
+  while (signe(d1))
   {
-    av0 = avma; R = FpXQX_rem(P,Q,T,p); P=Q; Q=R;
+    GEN r, q = FpXQX_divrem(d, d1, T, p, &r);
+    v = FpXX_sub(v,FpXQX_mul(q,v1,T, p),p);
+    u=v; v=v1; v1=u;
+    u=r; d=d1; d1=u;
+    if (gc_needed(av,2))
+    {
+      if (DEBUGMEM>1) pari_warn(warnmem,"FpXQX_extgcd (d = %ld)",degpol(d));
+      gerepileall(av,5, &d,&d1,&u,&v,&v1);
+    }
   }
-  avma = av0; return gerepileupto(av, P);
+  if (ptu) *ptu = FpXQX_div(FpXX_sub(d,FpXQX_mul(b,v, T, p), p), a, T, p);
+  *ptv = v; return d;
+}
+
+static GEN
+FpXQX_extgcd_halfgcd(GEN x, GEN y, GEN T, GEN p, GEN *ptu, GEN *ptv)
+{
+  pari_sp av=avma;
+  GEN u,v,R = matid2_FpXQXM(varn(x));
+  while (lg(y)>FpXQX_EXTGCD_LIMIT)
+  {
+    GEN M, c;
+    if (lgpol(y)<=(lgpol(x)>>1))
+    {
+      GEN r, q = FpXQX_divrem(x, y, T, p, &r);
+      x = y; y = r;
+      R = FpXQX_FpXQXM_qmul(q, R, T, p);
+    }
+    M = FpXQX_halfgcd(x,y, T, p);
+    c = FpXQXM_FpXQX_mul2(M, x,y, T, p);
+    R = FpXQXM_mul2(M, R, T, p);
+    x = gel(c,1); y = gel(c,2);
+    gerepileall(av,3,&x,&y,&R);
+  }
+  y = FpXQX_extgcd_basecase(x,y, T, p, &u,&v);
+  if (ptu) *ptu = FpXQX_addmulmul(u,v,gcoeff(R,1,1),gcoeff(R,2,1), T, p);
+  *ptv = FpXQX_addmulmul(u,v,gcoeff(R,1,2),gcoeff(R,2,2), T, p);
+  return y;
 }
 
 /* x and y in Z[Y][X], return lift(gcd(x mod T,p, y mod T,p)). Set u and v st
@@ -474,8 +678,7 @@ FpXQX_gcd(GEN P, GEN Q, GEN T, GEN p)
 GEN
 FpXQX_extgcd(GEN x, GEN y, GEN T, GEN p, GEN *ptu, GEN *ptv)
 {
-  GEN a, b, q, r, u, v, d, d1, v1;
-  long vx = varn(x);
+  GEN d;
   pari_sp ltop=avma;
   if (lgefint(p) == 3)
   {
@@ -488,18 +691,12 @@ FpXQX_extgcd(GEN x, GEN y, GEN T, GEN p, GEN *ptu, GEN *ptv)
   }
   else
   {
-    a = FpXQX_red(x, T, p);
-    b = FpXQX_red(y, T, p);
-    d = a; d1 = b; v = pol_0(vx); v1 = pol_1(vx);
-    while (signe(d1))
-    {
-      q = FpXQX_divrem(d,d1,T,p, &r);
-      v = FpXX_sub(v, FpXQX_mul(q,v1, T,p), p);
-      u=v; v=v1; v1=u;
-      u=r; d=d1; d1=u;
-    }
-    if (ptu) *ptu = FpXQX_div(FpXX_sub(d, FpXQX_mul(b,v, T,p), p),a, T,p);
-    *ptv = v;
+    x = FpXQX_red(x, T, p);
+    y = FpXQX_red(y, T, p);
+    if (lg(y)>FpXQX_EXTGCD_LIMIT)
+      d = FpXQX_extgcd_halfgcd(x, y, T, p, ptu, ptv);
+    else
+      d = FpXQX_extgcd_basecase(x, y, T, p, ptu, ptv);
   }
   gerepileall(ltop,ptu?3:2,&d,ptv,ptu);
   return d;
@@ -722,6 +919,21 @@ FpXQX_divrem(GEN x, GEN S, GEN T, GEN p, GEN *pr)
   GEN B, y = get_FpXQX_red(S, &B);
   long dy = degpol(y), dx = degpol(x), d = dx-dy;
   if (pr==ONLY_REM) return FpXQX_rem(x, y, T, p);
+  if (lgefint(p) == 3)
+  {
+    GEN a, b, t, z;
+    pari_sp tetpil, av = avma;
+    ulong pp = to_FlxqX(x, y, T, p, &a, &b, &t);
+    z = FlxqX_divrem(a, b, t, pp, pr);
+    if (pr == ONLY_DIVIDES && !z) { avma = av; return NULL; }
+    tetpil=avma;
+    z = FlxX_to_ZXX(z);
+    if (pr && pr != ONLY_DIVIDES && pr != ONLY_REM)
+      *pr = FlxX_to_ZXX(*pr);
+    else return gerepile(av, tetpil, z);
+    gerepileallsp(av,tetpil,2, pr, &z);
+    return z;
+  }
   if (!B && d+3 < FpXQX_DIVREM_BARRETT_LIMIT)
     return FpXQX_divrem_basecase(x,y,T,p,pr);
   else
@@ -742,6 +954,15 @@ FpXQX_rem(GEN x, GEN S, GEN T, GEN p)
   GEN B, y = get_FpXQX_red(S, &B);
   long dy = degpol(y), dx = degpol(x), d = dx-dy;
   if (d < 0) return FpXQX_red(x, T, p);
+  if (lgefint(p) == 3)
+  {
+    pari_sp av = avma;
+    GEN a, b, t, z;
+    ulong pp = to_FlxqX(x, y, T, p, &a, &b, &t);
+    z = FlxqX_rem(a, b, t, pp);
+    z = FlxX_to_ZXX(z);
+    return gerepileupto(av, z);
+  }
   if (!B && d+3 < FpXQX_REM_BARRETT_LIMIT)
     return FpXQX_divrem_basecase(x,y, T, p, ONLY_REM);
   else
@@ -777,24 +998,27 @@ FpXQX_div_by_X_x(GEN a, GEN x, GEN T, GEN p, GEN *r)
   return z;
 }
 
-struct _FpXQX { GEN T,p; };
+struct _FpXQXQ {
+  GEN T, S;
+  GEN p;
+};
 
 static GEN _FpXQX_mul(void *data, GEN a,GEN b)
 {
-  struct _FpXQX *d=(struct _FpXQX*)data;
+  struct _FpXQXQ *d=(struct _FpXQXQ*)data;
   return FpXQX_mul(a,b,d->T,d->p);
 }
 
 static GEN _FpXQX_sqr(void *data, GEN a)
 {
-  struct _FpXQX *d=(struct _FpXQX*)data;
+  struct _FpXQXQ *d=(struct _FpXQXQ*)data;
   return FpXQX_sqr(a, d->T, d->p);
 }
 
 GEN
 FpXQX_powu(GEN x, ulong n, GEN T, GEN p)
 {
-  struct _FpXQX D;
+  struct _FpXQXQ D;
   if (n==0) return pol_1(varn(x));
   D.T = T; D.p = p;
   return gen_powu(x, n, (void *)&D, _FpXQX_sqr, _FpXQX_mul);
@@ -814,9 +1038,8 @@ FpXQXV_prod(GEN V, GEN T, GEN p)
   }
   else
   {
-    struct _FpXQX d;
-    d.p=p;
-    d.T=T;
+    struct _FpXQXQ d;
+    d.T=T; d.p=p;
     return gen_product(V, (void*)&d, &_FpXQX_mul);
   }
 }
@@ -824,17 +1047,23 @@ FpXQXV_prod(GEN V, GEN T, GEN p)
 static GEN
 _FpXQX_divrem(void * E, GEN x, GEN y, GEN *r)
 {
-  struct _FpXQX *d = (struct _FpXQX *) E;
+  struct _FpXQXQ *d = (struct _FpXQXQ *) E;
   return FpXQX_divrem(x, y, d->T, d->p, r);
 }
 
 static GEN
 _FpXQX_add(void * E, GEN x, GEN y)
 {
-  struct _FpXQX *d = (struct _FpXQX *) E;
+  struct _FpXQXQ *d = (struct _FpXQXQ *) E;
   return FpXX_add(x, y, d->p);
 }
 
+static GEN
+_FpXQX_sub(void * E, GEN x, GEN y) {
+  struct _FpXQXQ *d = (struct _FpXQXQ*) E;
+  return FpXX_sub(x,y, d->p);
+}
+
 static struct bb_ring FpXQX_ring = { _FpXQX_add, _FpXQX_mul, _FpXQX_sqr };
 
 GEN
@@ -843,7 +1072,7 @@ FpXQX_digits(GEN x, GEN B, GEN T, GEN p)
   pari_sp av = avma;
   long d = degpol(B), n = (lgpol(x)+d-1)/d;
   GEN z;
-  struct _FpXQX D;
+  struct _FpXQXQ D;
   D.T = T; D.p = p;
   z = gen_digits(x, B, n, (void *)&D, &FpXQX_ring, _FpXQX_divrem);
   return gerepileupto(av, z);
@@ -853,7 +1082,7 @@ GEN
 FpXQX_fromdigits(GEN x, GEN B, GEN T, GEN p)
 {
   pari_sp av = avma;
-  struct _FpXQX D;
+  struct _FpXQXQ D;
   GEN z;
   D.T = T; D.p = p;
   z = gen_fromdigits(x,B,(void *)&D, &FpXQX_ring);
@@ -1020,51 +1249,68 @@ FpXQXQ_div(GEN x,GEN y,GEN S, GEN T,GEN p)
   return gerepileupto(av, FpXQXQ_mul(x, FpXQXQ_inv(y,S,T,p),S,T,p));
 }
 
-typedef struct {
-  GEN T, S;
-  GEN p;
-} FpXQXQ_muldata;
-static GEN
-_FpXQXQ_add(void *data, GEN x, GEN y) {
-  FpXQXQ_muldata *d = (FpXQXQ_muldata*) data;
-  return FpXX_add(x,y, d->p);
-}
 static GEN
 _FpXQXQ_cmul(void *data, GEN P, long a, GEN x) {
-  FpXQXQ_muldata *d = (FpXQXQ_muldata*) data;
+  struct _FpXQXQ *d = (struct _FpXQXQ*) data;
   GEN y = gel(P,a+2);
   return typ(y)==t_INT ? FpXX_Fp_mul(x,y, d->p):
                          FpXX_FpX_mul(x,y,d->p);
 }
 static GEN
 _FpXQXQ_red(void *data, GEN x) {
-  FpXQXQ_muldata *d = (FpXQXQ_muldata*) data;
+  struct _FpXQXQ *d = (struct _FpXQXQ*) data;
   return FpXQX_red(x, d->T, d->p);
 }
 static GEN
 _FpXQXQ_mul(void *data, GEN x, GEN y) {
-  FpXQXQ_muldata *d = (FpXQXQ_muldata*) data;
+  struct _FpXQXQ *d = (struct _FpXQXQ*) data;
   return FpXQXQ_mul(x,y, d->S,d->T, d->p);
 }
 static GEN
 _FpXQXQ_sqr(void *data, GEN x) {
-  FpXQXQ_muldata *d = (FpXQXQ_muldata*) data;
+  struct _FpXQXQ *d = (struct _FpXQXQ*) data;
   return FpXQXQ_sqr(x, d->S,d->T, d->p);
 }
 
 static GEN
 _FpXQXQ_one(void *data) {
-  FpXQXQ_muldata *d = (FpXQXQ_muldata*) data;
+  struct _FpXQXQ *d = (struct _FpXQXQ*) data;
   return pol_1(get_FpXQX_var(d->S));
 }
 
 static GEN
 _FpXQXQ_zero(void *data) {
-  FpXQXQ_muldata *d = (FpXQXQ_muldata*) data;
+  struct _FpXQXQ *d = (struct _FpXQXQ*) data;
   return pol_0(get_FpXQX_var(d->S));
 }
 
-static struct bb_algebra FpXQXQ_algebra = { _FpXQXQ_red,_FpXQXQ_add,_FpXQXQ_mul,_FpXQXQ_sqr,_FpXQXQ_one,_FpXQXQ_zero };
+static struct bb_algebra FpXQXQ_algebra = { _FpXQXQ_red, _FpXQX_add,
+       _FpXQX_sub, _FpXQXQ_mul, _FpXQXQ_sqr, _FpXQXQ_one, _FpXQXQ_zero };
+
+const struct bb_algebra *
+get_FpXQXQ_algebra(void **E, GEN S, GEN T, GEN p)
+{
+  GEN z = new_chunk(sizeof(struct _FpXQXQ));
+  struct _FpXQXQ *e = (struct _FpXQXQ *) z;
+  e->T = FpX_get_red(T, p);
+  e->S = FpXQX_get_red(S, e->T, p);
+  e->p  = p; *E = (void*)e;
+  return &FpXQXQ_algebra;
+}
+
+static struct bb_algebra FpXQX_algebra = { _FpXQXQ_red, _FpXQX_add,
+       _FpXQX_sub, _FpXQX_mul, _FpXQX_sqr, _FpXQXQ_one, _FpXQXQ_zero };
+
+const struct bb_algebra *
+get_FpXQX_algebra(void **E, GEN T, GEN p, long v)
+{
+  GEN z = new_chunk(sizeof(struct _FpXQXQ));
+  struct _FpXQXQ *e = (struct _FpXQXQ *) z;
+  e->T = FpX_get_red(T, p);
+  e->S = pol_x(v);
+  e->p  = p; *E = (void*)e;
+  return &FpXQX_algebra;
+}
 
 /* x over Fq, return lift(x^n) mod S */
 GEN
@@ -1072,7 +1318,7 @@ FpXQXQ_pow(GEN x, GEN n, GEN S, GEN T, GEN p)
 {
   pari_sp ltop = avma;
   GEN y;
-  FpXQXQ_muldata D;
+  struct _FpXQXQ D;
   long s = signe(n);
   if (!s) return pol_1(varn(x));
   if (is_pm1(n)) /* +/- 1 */
@@ -1098,7 +1344,7 @@ FpXQXQ_pow(GEN x, GEN n, GEN S, GEN T, GEN p)
 GEN
 FpXQXQ_powers(GEN x, long l, GEN S, GEN T, GEN p)
 {
-  FpXQXQ_muldata D;
+  struct _FpXQXQ D;
   int use_sqr = 2*degpol(x) >= get_FpXQX_degree(S);
   T = FpX_get_red(T, p);
   S = FpXQX_get_red(S, T, p);
@@ -1115,7 +1361,7 @@ FpXQXQ_matrix_pow(GEN y, long n, long m, GEN S, GEN T, GEN p)
 GEN
 FpXQX_FpXQXQV_eval(GEN P, GEN V, GEN S, GEN T, GEN p)
 {
-  FpXQXQ_muldata D;
+  struct _FpXQXQ D;
   T = FpX_get_red(T, p);
   S = FpXQX_get_red(S, T, p);
   D.S=S; D.T=T; D.p=p;
@@ -1126,7 +1372,7 @@ FpXQX_FpXQXQV_eval(GEN P, GEN V, GEN S, GEN T, GEN p)
 GEN
 FpXQX_FpXQXQ_eval(GEN Q, GEN x, GEN S, GEN T, GEN p)
 {
-  FpXQXQ_muldata D;
+  struct _FpXQXQ D;
   int use_sqr = 2*degpol(x) >= get_FpXQX_degree(S);
   T = FpX_get_red(T, p);
   S = FpXQX_get_red(S, T, p);
@@ -1138,7 +1384,7 @@ FpXQX_FpXQXQ_eval(GEN Q, GEN x, GEN S, GEN T, GEN p)
 static GEN
 FpXQXQ_autpow_sqr(void * E, GEN x)
 {
-  FpXQXQ_muldata *D = (FpXQXQ_muldata *)E;
+  struct _FpXQXQ *D = (struct _FpXQXQ *)E;
   GEN T = D->T, p = D->p;
   GEN phi = gel(x,1), S = gel(x,2);
   long n = brent_kung_optpow(get_FpX_degree(T)-1,lgpol(S)+1,1);
@@ -1152,7 +1398,7 @@ FpXQXQ_autpow_sqr(void * E, GEN x)
 static GEN
 FpXQXQ_autpow_mul(void * E, GEN x, GEN y)
 {
-  FpXQXQ_muldata *D = (FpXQXQ_muldata *)E;
+  struct _FpXQXQ *D = (struct _FpXQXQ *)E;
   GEN T = D->T, p = D->p;
   GEN phi1 = gel(x,1), S1 = gel(x,2);
   GEN phi2 = gel(y,1), S2 = gel(y,2);
@@ -1167,7 +1413,7 @@ FpXQXQ_autpow_mul(void * E, GEN x, GEN y)
 GEN
 FpXQXQV_autpow(GEN aut, long n, GEN S, GEN T, GEN p)
 {
-  FpXQXQ_muldata D;
+  struct _FpXQXQ D;
   T = FpX_get_red(T, p);
   S = FpXQX_get_red(S, T, p);
   D.S=S; D.T=T; D.p=p;
@@ -1175,9 +1421,43 @@ FpXQXQV_autpow(GEN aut, long n, GEN S, GEN T, GEN p)
 }
 
 static GEN
+FpXQXQ_auttrace_mul(void *E, GEN x, GEN y)
+{
+  struct _FpXQXQ *D = (struct _FpXQXQ *) E;
+  GEN T = D->T, p = D->p;
+  GEN phi1 = gel(x,1), S1 = gel(x,2), a1 = gel(x,3);
+  GEN phi2 = gel(y,1), S2 = gel(y,2), a2 = gel(y,3);
+  long n2 = brent_kung_optpow(get_FpX_degree(T)-1, lgpol(S1)+lgpol(a1)+1, 1);
+  GEN V2 = FpXQ_powers(phi2, n2, T, p);
+  GEN phi3 = FpX_FpXQV_eval(phi1, V2, T, p);
+  GEN Sphi = FpXY_FpXQV_evalx(S1, V2, T, p);
+  GEN aphi = FpXY_FpXQV_evalx(a1, V2, T, p);
+  long n = brent_kung_optpow(maxss(degpol(Sphi),degpol(aphi)),2,1);
+  GEN V = FpXQXQ_powers(S2, n, D->S, T, p);
+  GEN S3 = FpXQX_FpXQXQV_eval(Sphi, V, D->S, T, p);
+  GEN aS = FpXQX_FpXQXQV_eval(aphi, V, D->S, T, p);
+  GEN a3 = FpXX_add(aS, a2, p);
+  return mkvec3(phi3, S3, a3);
+}
+
+static GEN
+FpXQXQ_auttrace_sqr(void *E, GEN x)
+{ return FpXQXQ_auttrace_mul(E, x, x); }
+
+GEN
+FpXQXQV_auttrace(GEN aut, long n, GEN S, GEN T, GEN p)
+{
+  struct _FpXQXQ D;
+  T = FpX_get_red(T, p);
+  S = FpXQX_get_red(S, T, p);
+  D.S=S; D.T=T; D.p=p;
+  return gen_powu(aut,n,&D,FpXQXQ_auttrace_sqr,FpXQXQ_auttrace_mul);
+}
+
+static GEN
 FpXQXQ_autsum_mul(void *E, GEN x, GEN y)
 {
-  FpXQXQ_muldata *D = (FpXQXQ_muldata *) E;
+  struct _FpXQXQ *D = (struct _FpXQXQ *) E;
   GEN T = D->T, p = D->p;
   GEN phi1 = gel(x,1), S1 = gel(x,2), a1 = gel(x,3);
   GEN phi2 = gel(y,1), S2 = gel(y,2), a2 = gel(y,3);
@@ -1201,7 +1481,7 @@ FpXQXQ_autsum_sqr(void * T, GEN x)
 GEN
 FpXQXQV_autsum(GEN aut, long n, GEN S, GEN T, GEN p)
 {
-  FpXQXQ_muldata D;
+  struct _FpXQXQ D;
   T = FpX_get_red(T, p);
   S = FpXQX_get_red(S, T, p);
   D.S=S; D.T=T; D.p=p;
diff --git a/src/basemath/FpX_factor.c b/src/basemath/FpX_factor.c
index 224d5f3..ef184cd 100644
--- a/src/basemath/FpX_factor.c
+++ b/src/basemath/FpX_factor.c
@@ -654,11 +654,10 @@ F2x_Berlekamp_ker(GEN u)
 {
   pari_sp ltop=avma;
   long j,N = F2x_degree(u);
-  GEN Q, XP;
+  GEN Q;
   pari_timer T;
   timer_start(&T);
-  XP = F2xq_sqr(polx_F2x(u[1]),u);
-  Q  = F2xq_matrix_pow(XP,N,N,u);
+  Q = F2x_matFrobenius(u);
   for (j=1; j<=N; j++)
     F2m_flip(Q,j,j);
   if(DEBUGLEVEL>=9) timer_printf(&T,"Berlekamp matrix");
@@ -2310,20 +2309,6 @@ FpX_split_Berlekamp(GEN *t, GEN p)
   return d;
 }
 
-GEN
-FqX_deriv(GEN f, /*unused*/GEN T, GEN p) {
-  (void)T; return FpXX_red(RgX_deriv(f), p);
-}
-
-long
-FqX_is_squarefree(GEN P, GEN T, GEN p)
-{
-  pari_sp av = avma;
-  GEN z = FqX_gcd(P, FqX_deriv(P, T, p), T, p);
-  avma = av;
-  return degpol(z)==0;
-}
-
 static GEN
 F2x_Berlekamp_i(GEN f, long flag)
 {
@@ -2569,838 +2554,3 @@ factormod0(GEN f, GEN p, long flag)
   }
   return NULL; /* not reached */
 }
-
-/*******************************************************************/
-/*                                                                 */
-/*                     FACTORIZATION IN F_q                        */
-/*                                                                 */
-/*******************************************************************/
-static GEN
-to_Fq(GEN x, GEN T, GEN p)
-{
-  long i, lx, tx = typ(x);
-  GEN y;
-
-  if (tx == t_INT)
-    y = mkintmod(x,p);
-  else
-  {
-    if (tx != t_POL) pari_err_TYPE("to_Fq",x);
-    lx = lg(x);
-    y = cgetg(lx,t_POL); y[1] = x[1];
-    for (i=2; i<lx; i++) gel(y,i) = mkintmod(gel(x,i), p);
-  }
-  return mkpolmod(y, T);
-}
-
-static GEN
-to_Fq_pol(GEN x, GEN T, GEN p)
-{
-  long i, lx = lg(x);
-  for (i=2; i<lx; i++) gel(x,i) = to_Fq(gel(x,i),T,p);
-  return x;
-}
-
-static GEN
-to_Fq_fact(GEN P, GEN E, GEN T, GEN p, pari_sp av)
-{
-  GEN y, u, v;
-  long j, l = lg(P), nbf = lg(P);
-
-  u = cgetg(nbf,t_COL);
-  v = cgetg(nbf,t_COL);
-  for (j=1; j<l; j++)
-  {
-    gel(u,j) = simplify_shallow(gel(P,j)); /* may contain pols of degree 0 */
-    gel(v,j) = utoi(uel(E,j));
-  }
-  y = gerepilecopy(av, mkmat2(u, v));
-  u = gel(y,1);
-  p = icopy(p);
-  T = FpX_to_mod(T, p);
-  for (j=1; j<nbf; j++) gel(u,j) = to_Fq_pol(gel(u,j), T,p);
-  return y;
-}
-static GEN
-to_FqC(GEN P, GEN T, GEN p, pari_sp av)
-{
-  GEN u;
-  long j, l = lg(P), nbf = lg(P);
-
-  u = cgetg(nbf,t_COL);
-  for (j=1; j<l; j++)
-    gel(u,j) = simplify_shallow(gel(P,j)); /* may contain pols of degree 0 */
-  u = gerepilecopy(av, u);
-  p = icopy(p);
-  T = FpX_to_mod(T, p);
-  for (j=1; j<nbf; j++) gel(u,j) = to_Fq(gel(u,j), T,p);
-  return u;
-}
-
-GEN
-FlxqXQ_halfFrobenius(GEN a, GEN S, GEN T, ulong p)
-{
-  long vT = get_Flx_var(T);
-  GEN xp = Flx_Frobenius(T, p);
-  GEN Xp = FlxqXQ_pow(polx_FlxX(get_FlxqX_var(S), vT), utoi(p), S, T, p);
-  GEN ap2 = FlxqXQ_pow(a,utoi(p>>1), S, T, p);
-  GEN V = FlxqXQV_autsum(mkvec3(xp, Xp, ap2), get_Flx_degree(T), S, T, p);
-  return gel(V,3);
-}
-
-GEN
-FpXQXQ_halfFrobenius(GEN a, GEN S, GEN T, GEN p)
-{
-  if (lgefint(p)==3)
-  {
-    ulong pp = p[2];
-    long v = get_FpX_var(T);
-    GEN Tp = ZXT_to_FlxT(T,pp), Sp = ZXXT_to_FlxXT(S, pp, v);
-    return FlxX_to_ZXX(FlxqXQ_halfFrobenius(ZXX_to_FlxX(a,pp,v),Sp,Tp,pp));
-  }
-  else
-  {
-    GEN xp, Xp, ap2, V;
-    T = FpX_get_red(T, p);
-    S = FpXQX_get_red(S, T, p);
-    xp = FpX_Frobenius(T, p);
-    Xp = FpXQXQ_pow(pol_x(get_FpXQX_var(S)), p, S, T, p);
-    ap2 = FpXQXQ_pow(a,shifti(p,-1), S, T, p);
-    V = FpXQXQV_autsum(mkvec3(xp,Xp,ap2), get_FpX_degree(T), S, T, p);
-    return gel(V,3);
-  }
-}
-
-GEN
-FlxqX_Frobenius(GEN S, GEN T, ulong p)
-{
-  pari_sp av = avma;
-  long n = get_Flx_degree(T), vT = get_Flx_var(T);
-  GEN X  = polx_FlxX(get_FlxqX_var(S), vT);
-  GEN xp = Flx_Frobenius(T, p);
-  GEN Xp = FlxqXQ_pow(X, utoi(p), S, T, p);
-  GEN Xq = gel(FlxqXQV_autpow(mkvec2(xp,Xp), n, S, T, p), 2);
-  return gerepilecopy(av, Xq);
-}
-
-GEN
-FpXQX_Frobenius(GEN S, GEN T, GEN p)
-{
-  pari_sp av = avma;
-  long n = get_FpX_degree(T);
-  GEN X  = pol_x(get_FpXQX_var(S));
-  GEN xp = FpX_Frobenius(T, p);
-  GEN Xp = FpXQXQ_pow(X, p, S, T, p);
-  GEN Xq = gel(FpXQXQV_autpow(mkvec2(xp,Xp), n, S, T, p), 2);
-  return gerepilecopy(av, Xq);
-}
-
-static GEN
-FqX_Frobenius_powers(GEN S, GEN T, GEN p)
-{
-  long N = get_FpXQX_degree(S);
-  if (lgefint(p)==3)
-  {
-    ulong pp = p[2];
-    GEN Tp = ZXT_to_FlxT(T, pp), Sp = ZXXT_to_FlxXT(S, pp, get_FpX_var(T));
-    GEN Xq = FlxqX_Frobenius(Sp, Tp, pp);
-    return FlxqXQ_powers(Xq, N-1, Sp, Tp, pp);
-  } else
-  {
-    GEN Xq = FpXQX_Frobenius(S, T, p);
-    return FpXQXQ_powers(Xq, N-1, S, T, p);
-  }
-}
-
-static GEN
-FqX_Frobenius_eval(GEN x, GEN V, GEN S, GEN T, GEN p)
-{
-  if (lgefint(p)==3)
-  {
-    ulong pp = p[2];
-    long v = get_FpX_var(T);
-    GEN Tp = ZXT_to_FlxT(T, pp), Sp = ZXXT_to_FlxXT(S, pp, v);
-    GEN xp = ZXX_to_FlxX(x, pp, v);
-    return FlxX_to_ZXX(FlxqX_FlxqXQV_eval(xp, V, Sp, Tp, pp));
-  }
-  else
-    return FpXQX_FpXQXQV_eval(x, V, S, T, p);
-}
-
-static GEN
-FpXQX_split_part(GEN f, GEN T, GEN p)
-{
-  long n = degpol(f);
-  GEN z, X = pol_x(varn(f));
-  if (n <= 1) return f;
-  f = FpXQX_red(f, T, p);
-  z = FpXQX_Frobenius(f, T, p);
-  z = FpXX_sub(z, X , p);
-  return FpXQX_gcd(z, f, T, p);
-}
-
-static GEN
-FlxqX_split_part(GEN f, GEN T, ulong p)
-{
-  long n = degpol(f);
-  GEN z, Xq, X = polx_FlxX(varn(f),get_Flx_var(T));
-  if (n <= 1) return f;
-  f = FlxqX_red(f, T, p);
-  Xq = FlxqX_Frobenius(f, T, p);
-  z = FlxX_sub(Xq, X , p);
-  return FlxqX_gcd(z, f, T, p);
-}
-
-long
-FpXQX_nbroots(GEN f, GEN T, GEN p)
-{
-  pari_sp av = avma;
-  GEN z;
-  if(lgefint(p)==3)
-  {
-    ulong pp=p[2];
-    z = FlxqX_split_part(ZXX_to_FlxX(f,pp,varn(T)),ZXT_to_FlxT(T,pp),pp);
-  }
-  else
-    z = FpXQX_split_part(f, T, p);
-  avma = av; return degpol(z);
-}
-
-long
-FqX_nbroots(GEN f, GEN T, GEN p)
-{ return T ? FpXQX_nbroots(f, T, p): FpX_nbroots(f, p); }
-
-long
-FlxqX_nbroots(GEN f, GEN T, ulong p)
-{
-  pari_sp av = avma;
-  GEN z = FlxqX_split_part(f, T, p);
-  avma = av; return degpol(z);
-}
-
-GEN
-FlxqX_Berlekamp_ker(GEN S, GEN T, ulong p)
-{
-  pari_sp ltop=avma;
-  long j, N = get_FlxqX_degree(S);
-  GEN Xq = FlxqX_Frobenius(S,T,p);
-  GEN Q  = FlxqXQ_matrix_pow(Xq,N,N,S,T,p);
-  for (j=1; j<=N; j++)
-    gcoeff(Q,j,j) = Flx_Fl_add(gcoeff(Q,j,j), p-1, p);
-  return gerepileupto(ltop, FlxqM_ker(Q,T,p));
-}
-
-GEN
-FpXQX_Berlekamp_ker(GEN S, GEN T, GEN p)
-{
-  if (lgefint(p)==3)
-  {
-    ulong pp=p[2];
-    long v = get_FpX_var(T);
-    GEN Tp = ZXT_to_FlxT(T,pp), Sp = ZXX_to_FlxX(S,pp,v);
-    return FlxM_to_ZXM(FlxqX_Berlekamp_ker(Sp, Tp, pp));
-  } else
-  {
-    pari_sp ltop=avma;
-    long j,N = get_FpXQX_degree(S);
-    GEN Xq = FpXQX_Frobenius(S,T,p);
-    GEN Q  = FpXQXQ_matrix_pow(Xq,N,N,S,T,p);
-    for (j=1; j<=N; j++)
-      gcoeff(Q,j,j) = Fq_sub(gcoeff(Q,j,j), gen_1, T, p);
-    return gerepileupto(ltop, FqM_ker(Q,T,p));
-  }
-}
-
-long
-FpXQX_nbfact(GEN u, GEN T, GEN p)
-{
-  pari_sp av = avma;
-  GEN vker = FpXQX_Berlekamp_ker(u, T, p);
-  avma = av; return lg(vker)-1;
-}
-
-long
-FqX_nbfact(GEN u, GEN T, GEN p)
-{
-  return T ? FpX_nbfact(u, p): FpXQX_nbfact(u, T, p);
-}
-
-long
-FqX_split_Berlekamp(GEN *t, GEN T, GEN p)
-{
-  GEN u = *t, a,b,vker,pol;
-  long vu = varn(u), vT = varn(T), dT = degpol(T);
-  long d, i, ir, L, la, lb;
-  T = FpX_get_red(T, p);
-  vker = FpXQX_Berlekamp_ker(u,T,p);
-  vker = RgM_to_RgXV(vker,vu);
-  d = lg(vker)-1;
-  ir = 0;
-  /* t[i] irreducible for i < ir, still to be treated for i < L */
-  for (L=1; L<d; )
-  {
-    pol= scalarpol(random_FpX(dT,vT,p),vu);
-    for (i=2; i<=d; i++)
-      pol = FqX_add(pol, FqX_Fq_mul(gel(vker,i),
-                                    random_FpX(dT,vT,p), T, p), T, p);
-    pol = FpXQX_red(pol,T,p);
-    for (i=ir; i<L && L<d; i++)
-    {
-      a = t[i]; la = degpol(a);
-      if (la == 1) { set_irred(i); }
-      else
-      {
-        pari_sp av = avma;
-        b = FqX_rem(pol, a, T,p);
-        if (degpol(b)<=0) { avma=av; continue; }
-        b = FpXQXQ_halfFrobenius(b, a,T,p);
-        if (degpol(b)<=0) { avma=av; continue; }
-        gel(b,2) = Fq_sub(gel(b,2), gen_1,T,p);
-        b = FqX_gcd(a,b, T,p); lb = degpol(b);
-        if (lb && lb < la)
-        {
-          b = FqX_normalize(b, T,p);
-          t[L] = FqX_div(a,b,T,p);
-          t[i]= b; L++;
-        }
-        else avma = av;
-      }
-    }
-  }
-  return d;
-}
-
-/* split into r factors of degree d */
-static void
-FqX_split(GEN *t, long d, GEN q, GEN S, GEN T, GEN p)
-{
-  GEN u = *t;
-  long l, v, is2, cnt, dt = degpol(u), dT = degpol(T);
-  pari_sp av;
-  pari_timer ti;
-  GEN w,w0;
-
-  if (dt == d) return;
-  v = varn(*t);
-  if (DEBUGLEVEL > 6) timer_start(&ti);
-  av = avma; is2 = equaliu(p, 2);
-  for(cnt = 1;;cnt++, avma = av)
-  { /* splits *t with probability ~ 1 - 2^(1-r) */
-    w = w0 = random_FpXQX(dt,v, T,p);
-    if (degpol(w) <= 0) continue;
-    for (l=1; l<d; l++) /* sum_{0<i<d} w^(q^i), result in (F_q)^r */
-      w = RgX_add(w0, FqX_Frobenius_eval(w, S, u, T, p));
-    w = FpXQX_red(w, T,p);
-    if (is2)
-    {
-      w0 = w;
-      for (l=1; l<dT; l++) /* sum_{0<i<k} w^(2^i), result in (F_2)^r */
-      {
-        w = FqX_rem(FqX_sqr(w,T,p), *t, T,p);
-        w = FpXX_red(RgX_add(w0,w), p);
-      }
-    }
-    else
-    {
-      w = FpXQXQ_halfFrobenius(w, *t, T, p);
-      /* w in {-1,0,1}^r */
-      if (degpol(w) <= 0) continue;
-      gel(w,2) = gadd(gel(w,2), gen_1);
-    }
-    w = FqX_gcd(*t,w, T,p); l = degpol(w);
-    if (l && l != dt) break;
-  }
-  w = gerepileupto(av,FqX_normalize(w,T,p));
-  if (DEBUGLEVEL > 6)
-    err_printf("[FqX_split] splitting time: %ld (%ld trials)\n",
-               timer_delay(&ti),cnt);
-  l /= d; t[l] = FqX_div(*t,w, T,p); *t = w;
-  FqX_split(t+l,d,q,S,T,p);
-  FqX_split(t  ,d,q,S,T,p);
-}
-
-/*******************************************************************/
-/*                                                                 */
-/*                  FACTOR USING TRAGER'S TRICK                    */
-/*                                                                 */
-/*******************************************************************/
-static GEN
-FqX_frob_deflate(GEN f, GEN T, GEN p)
-{
-  GEN F = RgX_deflate(f, itos(p)), frobinv = powiu(p, degpol(T)-1);
-  long i, l = lg(F);
-  for (i=2; i<l; i++) gel(F,i) = Fq_pow(gel(F,i), frobinv, T,p);
-  return F;
-}
-/* Factor _sqfree_ polynomial a on the finite field Fp[X]/(T). Assumes
- * varncmp (varn(T), varn(A)) > 0 */
-static GEN
-FqX_split_Trager(GEN A, GEN T, GEN p)
-{
-  GEN c = NULL, P, u, fa, n;
-  long lx, i, k;
-
-  u = A;
-  n = NULL;
-  for (k = 0; cmpui(k, p) < 0; k++)
-  {
-    GEN U;
-    c = deg1pol_shallow(stoi(k) , gen_0, varn(T));
-    U = FqX_translate(u, c, T, p);
-    n = FpX_FpXY_resultant(T, U, p);
-    if (FpX_is_squarefree(n, p)) break;
-    n = NULL;
-  }
-  if (!n) return NULL;
-  if (DEBUGLEVEL>4) err_printf("FqX_split_Trager: choosing k = %ld\n",k);
-  /* n guaranteed to be squarefree */
-  fa = FpX_factor(n, p); fa = gel(fa,1); lx = lg(fa);
-  if (lx == 2) return mkcol(A); /* P^k, P irreducible */
-
-  P = cgetg(lx,t_COL);
-  c = FpX_neg(c,p);
-  for (i=lx-1; i>1; i--)
-  {
-    GEN F = FqX_translate(gel(fa,i), c, T, p);
-    F = FqX_normalize(FqX_gcd(u, F, T, p), T, p);
-    if (typ(F) != t_POL || degpol(F) == 0)
-      pari_err_IRREDPOL("FqX_split_Trager [modulus]",T);
-    u = FqX_div(u, F, T, p);
-    gel(P,i) = F;
-  }
-  gel(P,1) = u; return P;
-}
-
-static long
-isabsolutepol(GEN f)
-{
-  long i, l = lg(f);
-  for(i=2; i<l; i++)
-  {
-    GEN c = gel(f,i);
-    if (typ(c) == t_POL && degpol(c) > 0) return 0;
-  }
-  return 1;
-}
-
-static void
-add(GEN z, GEN g, long d) { vectrunc_append(z, mkvec2(utoipos(d), g)); }
-/* return number of roots of u; assume deg u >= 0 */
-long
-FqX_split_deg1(GEN *pz, GEN u, GEN T, GEN p)
-{
-  long dg, N = degpol(u);
-  GEN v, S, g, X, z = vectrunc_init(N+1);
-
-  *pz = z;
-  if (N == 0) return 0;
-  if (N == 1) return 1;
-  v = X = pol_x(varn(u));
-  S = FqX_Frobenius_powers(u, T, p);
-  vectrunc_append(z, S);
-  v = FqX_Frobenius_eval(v, S, u, T, p);
-  g = FqX_gcd(FpXX_sub(v,X,p),u, T,p);
-  dg = degpol(g);
-  if (dg > 0) add(z, FqX_normalize(g,T,p), dg);
-  return dg;
-}
-
-/* return number of factors; z not properly initialized if deg(u) <= 1 */
-long
-FqX_split_by_degree(GEN *pz, GEN u, GEN T, GEN p)
-{
-  long nb = 0, d, dg, N = degpol(u);
-  GEN v, S, g, X, z = vectrunc_init(N+1);
-
-  *pz = z;
-  if (N <= 1) return 1;
-  v = X = pol_x(varn(u));
-  S = FqX_Frobenius_powers(u, T, p);
-  vectrunc_append(z, S);
-  for (d=1; d <= N>>1; d++)
-  {
-    v = FqX_Frobenius_eval(v, S, u, T, p);
-    g = FqX_gcd(FpXX_sub(v,X,p),u, T,p);
-    dg = degpol(g); if (dg <= 0) continue;
-    /* all factors of g have degree d */
-    add(z, FqX_normalize(g, T,p), dg / d); nb += dg / d;
-    N -= dg;
-    if (N)
-    {
-      u = FqX_div(u,g, T,p);
-      v = FqX_rem(v,u, T,p);
-    }
-  }
-  if (N) { add(z, FqX_normalize(u, T,p), 1); nb++; }
-  return nb;
-}
-
-/* see roots_from_deg1() */
-static GEN
-FqXC_roots_from_deg1(GEN x, GEN T, GEN p)
-{
-  long i,l = lg(x);
-  GEN r = cgetg(l,t_COL);
-  for (i=1; i<l; i++) { GEN P = gel(x,i); gel(r,i) = Fq_neg(gel(P,2), T, p); }
-  return r;
-}
-
-static GEN
-FqX_split_equal(GEN L, GEN S, GEN T, GEN p)
-{
-  long n = itos(gel(L,1));
-  GEN u = gel(L,2), z = cgetg(n + 1, t_COL);
-  gel(z,1) = u;
-  FqX_split((GEN*)(z+1), degpol(u) / n, powiu(p, degpol(T)), S, T, p);
-  return z;
-}
-GEN
-FqX_split_roots(GEN z, GEN T, GEN p, GEN pol)
-{
-  GEN S = gel(z,1), L = gel(z,2), rep = FqX_split_equal(L, S, T, p);
-  if (pol) rep = shallowconcat(rep, FqX_div(pol, gel(L,2), T,p));
-  return rep;
-}
-GEN
-FqX_split_all(GEN z, GEN T, GEN p)
-{
-  GEN S = gel(z,1), rep = cgetg(1, t_VEC);
-  long i, l = lg(z);
-  for (i = 2; i < l; i++)
-    rep = shallowconcat(rep, FqX_split_equal(gel(z,i), S, T, p));
-  return rep;
-}
-
-/* not memory-clean, as FpX_factorff_i, returning only linear factors */
-static GEN
-FpX_rootsff_i(GEN P, GEN T, GEN p)
-{
-  GEN V, F = gel(FpX_factor(P,p), 1);
-  long i, lfact = 1, nmax = lgpol(P), n = lg(F), dT = degpol(T);
-
-  V = cgetg(nmax,t_COL);
-  for(i=1;i<n;i++)
-  {
-    GEN R, Fi = gel(F,i);
-    long di = degpol(Fi), j, r;
-    if (dT % di) continue;
-    R = FpX_factorff_irred(gel(F,i),T,p);
-    r = lg(R);
-    for (j=1; j<r; j++,lfact++)
-      gel(V,lfact) = Fq_neg(gmael(R,j, 2), T, p);
-  }
-  setlg(V,lfact);
-  gen_sort_inplace(V, (void*) &cmp_RgX, &cmp_nodata, NULL);
-  return V;
-}
-GEN
-FpX_rootsff(GEN P, GEN T, GEN p)
-{
-  pari_sp av = avma;
-  return gerepilecopy(av, FpX_rootsff_i(P, T, p));
-}
-
-static GEN
-F2xqX_quad_roots(GEN P, GEN T)
-{
-  GEN b= gel(P,3), c = gel(P,2);
-  if (degpol(b)>=0)
-  {
-    GEN z, d = F2xq_div(c, F2xq_sqr(b,T),T);
-    if (F2xq_trace(d,T))
-      return cgetg(1, t_COL);
-    z = F2xq_mul(b, F2xq_Artin_Schreier(d, T), T);
-    return mkcol2(z, F2x_add(b, z));
-  }
-  else
-    return mkcol(F2xq_sqrt(c, T));
-}
-
-static GEN
-FqX_quad_roots(GEN x, GEN T, GEN p)
-{
-  GEN s, D, nb, b = gel(x,3), c = gel(x,2);
-  if (equaliu(p, 2))
-  {
-    GEN f2 = ZXX_to_F2xX(x, get_FpX_var(T));
-    s = F2xqX_quad_roots(f2, ZX_to_F2x(get_FpX_mod(T)));
-    return F2xC_to_ZXC(s);
-  }
-  D = Fq_sub(Fq_sqr(b,T,p), Fq_Fp_mul(c,utoi(4),T,p), T,p);
-  nb = Fq_neg(b,T,p);
-  if (signe(D)==0)
-    return mkcol(Fq_halve(nb,T, p));
-  s = Fq_sqrt(D,T,p);
-  if (!s) return cgetg(1, t_COL);
-  s = Fq_halve(Fq_add(s,nb,T,p),T, p);
-  return mkcol2(s,Fq_sub(nb,s,T,p));
-}
-
-static GEN
-FqX_roots_i(GEN f, GEN T, GEN p)
-{
-  GEN R;
-  f = FqX_normalize(f, T, p);
-  if (!signe(f)) pari_err_ROOTS0("FqX_roots");
-  if (isabsolutepol(f))
-  {
-    f = simplify_shallow(f);
-    if (typ(f) == t_INT) return cgetg(1, t_COL);
-    return FpX_rootsff_i(f, T, p);
-  }
-  if (degpol(f)==2)
-    return gen_sort(FqX_quad_roots(f,T,p), (void*) &cmp_RgX, &cmp_nodata);
-  switch( FqX_split_deg1(&R, f, T, p) )
-  {
-  case 0: return cgetg(1, t_COL);
-  case 1: if (lg(R) == 1) { R = mkvec(f); break; }
-            /* fall through */
-  default: R = FqX_split_roots(R, T, p, NULL);
-  }
-  R = FqXC_roots_from_deg1(R, T, p);
-  gen_sort_inplace(R, (void*) &cmp_RgX, &cmp_nodata, NULL);
-  return R;
-}
-
-GEN
-FqX_roots(GEN x, GEN T, GEN p)
-{
-  pari_sp av = avma;
-  if (!T) return FpX_roots(x, p);
-  return gerepileupto(av, FqX_roots_i(x, T, p));
-}
-
-static long
-FqX_sqf_split(GEN *t0, GEN q, GEN T, GEN p)
-{
-  GEN *t = t0, u = *t, v, S, g, X;
-  long d, dg, N = degpol(u);
-
-  if (N == 1) return 1;
-  v = X = pol_x(varn(u));
-  S = FqX_Frobenius_powers(u, T, p);
-  for (d=1; d <= N>>1; d++)
-  {
-    v = FqX_Frobenius_eval(v, S, u, T, p);
-    g = FqX_normalize(FqX_gcd(FpXX_sub(v,X,p),u, T,p),T,p);
-    dg = degpol(g); if (dg <= 0) continue;
-
-    /* all factors of g have degree d */
-    *t = g;
-    FqX_split(t, d, q, S, T, p);
-    t += dg / d;
-    N -= dg;
-    if (N)
-    {
-      u = FqX_div(u,g, T,p);
-      v = FqX_rem(v,u, T,p);
-    }
-  }
-  if (N) *t++ = u;
-  return t - t0;
-}
-
-/* not memory-clean */
-static GEN
-FpX_factorff_i(GEN P, GEN T, GEN p)
-{
-  GEN V, E, F = FpX_factor(P,p);
-  long i, lfact = 1, nmax = lgpol(P), n = lgcols(F);
-
-  V = cgetg(nmax,t_VEC);
-  E = cgetg(nmax,t_VECSMALL);
-  for(i=1;i<n;i++)
-  {
-    GEN R = FpX_factorff_irred(gmael(F,1,i),T,p), e = gmael(F,2,i);
-    long j, r = lg(R);
-    for (j=1; j<r; j++,lfact++)
-    {
-      gel(V,lfact) = gel(R,j);
-      gel(E,lfact) = e;
-    }
-  }
-  setlg(V,lfact);
-  setlg(E,lfact); return sort_factor_pol(mkvec2(V,E), cmp_RgX);
-}
-GEN
-FpX_factorff(GEN P, GEN T, GEN p)
-{
-  pari_sp av = avma;
-  return gerepilecopy(av, FpX_factorff_i(P, T, p));
-}
-
-/* assumes varncmp (varn(T), varn(f)) > 0 */
-static GEN
-FqX_factor_i(GEN f, GEN T, GEN p)
-{
-  long pg, j, k, e, N, lfact, pk, d = degpol(f);
-  GEN E, f2, f3, df1, df2, g1, u, q, t;
-
-  switch(d)
-  {
-    case -1: retmkmat2(mkcolcopy(f), mkvecsmall(1));
-    case 0: return trivial_fact();
-  }
-  T = FpX_normalize(T, p);
-  f = FqX_normalize(f, T, p);
-  if (isabsolutepol(f)) return FpX_factorff_i(simplify_shallow(f), T, p);
-  if (degpol(f)==2)
-  {
-    long v = varn(f);
-    GEN r = FqX_quad_roots(f,T,p);
-    switch(lg(r)-1)
-    {
-    case 0:
-      return mkvec2(mkcolcopy(f), mkvecsmall(1));
-    case 1:
-      return mkvec2(mkcol(deg1pol_shallow(gen_1, Fq_neg(gel(r,1), T, p), v)),
-                    mkvecsmall(2));
-    case 2:
-      {
-        GEN f1 = deg1pol_shallow(gen_1, Fq_neg(gel(r,1), T, p), v);
-        GEN f2 = deg1pol_shallow(gen_1, Fq_neg(gel(r,2), T, p), v);
-        t = mkcol2(f1, f2); E = mkvecsmall2(1, 1);
-        sort_factor_pol(mkvec2(t, E), cmp_RgX);
-        return mkvec2(t, E);
-      }
-    }
-  }
-
-  pg = itos_or_0(p);
-  df2  = NULL; /* gcc -Wall */
-  t = cgetg(d+1,t_VEC);
-  E = cgetg(d+1, t_VECSMALL);
-
-  q = powiu(p, degpol(T));
-  e = lfact = 1;
-  pk = 1;
-  f3 = NULL;
-  df1 = FqX_deriv(f, T, p);
-  for(;;)
-  {
-    long nb0;
-    while (!signe(df1))
-    { /* needs d >= p: pg = 0 can't happen  */
-      pk *= pg; e = pk;
-      f = FqX_frob_deflate(f, T, p);
-      df1 = FqX_deriv(f, T, p); f3 = NULL;
-    }
-    f2 = f3? f3: FqX_gcd(f,df1, T,p);
-    if (!degpol(f2)) u = f;
-    else
-    {
-      g1 = FqX_div(f,f2, T,p);
-      df2 = FqX_deriv(f2, T,p);
-      if (gequal0(df2)) { u = g1; f3 = f2; }
-      else
-      {
-        f3 = FqX_gcd(f2,df2, T,p);
-        u = degpol(f3)? FqX_div(f2, f3, T,p): f2;
-        u = FqX_div(g1, u, T,p);
-      }
-    }
-    /* u is square-free (product of irreducibles of multiplicity e) */
-    N = degpol(u);
-    if (N) {
-      nb0 = lfact;
-      gel(t,lfact) = FqX_normalize(u, T,p);
-      if (N == 1) lfact++;
-      else
-      {
-        if (!equaliu(p,2))
-          lfact += FqX_split_Berlekamp(&gel(t,lfact), T, p);
-        else
-        {
-          GEN P = FqX_split_Trager(gel(t,lfact), T, p);
-          if (P) {
-            for (j = 1; j < lg(P); j++) gel(t,lfact++) = gel(P,j);
-          } else {
-            if (DEBUGLEVEL) pari_warn(warner, "FqX_split_Trager failed!");
-            lfact += FqX_sqf_split(&gel(t,lfact), q, T, p);
-          }
-        }
-      }
-      for (j = nb0; j < lfact; j++) E[j] = e;
-    }
-
-    if (!degpol(f2)) break;
-    f = f2; df1 = df2; e += pk;
-  }
-  setlg(t, lfact);
-  setlg(E, lfact);
-  for (j=1; j<lfact; j++) gel(t,j) = FqX_normalize(gel(t,j), T,p);
-  (void)sort_factor_pol(mkvec2(t, E), cmp_RgX);
-  k = 1;
-  for (j = 2; j < lfact; j++)
-  {
-    if (RgX_equal(gel(t,j), gel(t,k)))
-      E[k] += E[j];
-    else
-    { /* new factor */
-      k++;
-      E[k] = E[j];
-      gel(t,k) = gel(t,j);
-    }
-  }
-  setlg(t, k+1);
-  setlg(E, k+1); return mkvec2(t, E);
-}
-
-static void
-ffcheck(pari_sp *av, GEN *f, GEN *T, GEN p)
-{
-  long v;
-  if (typ(*T)!=t_POL) pari_err_TYPE("factorff",*T);
-  if (typ(*f)!=t_POL) pari_err_TYPE("factorff",*f);
-  if (typ(p)!=t_INT) pari_err_TYPE("factorff",p);
-  v = varn(*T);
-  if (varncmp(v, varn(*f)) <= 0)
-    pari_err_PRIORITY("factorff", *T, "<=", varn(*f));
-  *T = RgX_to_FpX(*T, p); *av = avma;
-  *f = RgX_to_FqX(*f, *T,p);
-}
-GEN
-factorff(GEN f, GEN p, GEN T)
-{
-  pari_sp av;
-  GEN z;
-  if (!p || !T)
-  {
-    long pa, t;
-    if (typ(f) != t_POL) pari_err_TYPE("factorff",f);
-    T = p = NULL;
-    t = RgX_type(f, &p, &T, &pa);
-    if (t != t_FFELT) pari_err_TYPE("factorff",f);
-    return FFX_factor(f,T);
-  }
-  ffcheck(&av, &f, &T, p); z = FqX_factor_i(f, T, p);
-  return to_Fq_fact(gel(z,1),gel(z,2), T,p, av);
-}
-GEN
-polrootsff(GEN f, GEN p, GEN T)
-{
-  pari_sp av;
-  GEN z;
-  if (!p || !T)
-  {
-    long pa, t;
-    if (typ(f) != t_POL) pari_err_TYPE("polrootsff",f);
-    T = p = NULL;
-    t = RgX_type(f, &p, &T, &pa);
-    if (t != t_FFELT) pari_err_TYPE("polrootsff",f);
-    return FFX_roots(f,T);
-  }
-  ffcheck(&av, &f, &T, p); z = FqX_roots_i(f, T, p);
-  return to_FqC(z, T,p, av);
-}
-
-/* factorization of x modulo (T,p). Assume x already reduced */
-GEN
-FqX_factor(GEN x, GEN T, GEN p)
-{
-  pari_sp av = avma;
-  if (!T) return FpX_factor(x, p);
-  return gerepilecopy(av, FqX_factor_i(x, T, p));
-}
-/* See also: Isomorphisms between finite field and relative
- * factorization in polarit3.c */
diff --git a/src/basemath/Hensel.c b/src/basemath/Hensel.c
index daee59a..590a589 100644
--- a/src/basemath/Hensel.c
+++ b/src/basemath/Hensel.c
@@ -586,8 +586,11 @@ Zp_sqrtlift(GEN b, GEN a, GEN p, long e)
 GEN
 Zp_sqrt(GEN x, GEN p, long e)
 {
-  pari_sp av = avma;
-  GEN z = Fp_sqrt(Fp_red(x, p), p);
+  pari_sp av;
+  GEN z;
+  if (equaliu(p,2)) return Z2_sqrt(x,e);
+  av = avma;
+  z = Fp_sqrt(Fp_red(x, p), p);
   if (!z) return NULL;
   if (e > 1) z = Zp_sqrtlift(x, z, p, e);
   return gerepileuptoint(av, z);
@@ -771,6 +774,49 @@ ZpXQ_inv(GEN a, GEN T, GEN p, long e)
   return gerepileupto(av, ZpXQ_invlift(a, ai, T, p, e));
 }
 
+GEN
+ZpXQ_div(GEN a, GEN b, GEN T, GEN q, GEN p, long e)
+{
+  return FpXQ_mul(a, ZpXQ_inv(b, T, p, e), T, q);
+}
+
+GEN
+ZpXQX_divrem(GEN x, GEN Sp, GEN T, GEN q, GEN p, long e, GEN *pr)
+{
+  pari_sp av = avma;
+  GEN S = get_FpXQX_mod(Sp);
+  GEN b = leading_coeff(S), bi;
+  GEN S2, Q;
+  if (typ(b)==t_INT) return FpXQX_divrem(x, Sp, T, q, pr);
+  bi = ZpXQ_inv(b, T, p, e);
+  S2 = FqX_Fq_mul_to_monic(S, bi, T, q);
+  Q = FpXQX_divrem(x, S2, T, q, pr);
+  if (pr==ONLY_DIVIDES && !Q) { avma = av; return NULL; }
+  if (pr==ONLY_REM || pr==ONLY_DIVIDES) return gerepileupto(av, Q);
+  Q = FpXQX_FpXQ_mul(Q, bi, T, q);
+  gerepileall(av, 2, &Q, pr);
+  return Q;
+}
+
+GEN
+ZpXQX_digits(GEN x, GEN B, GEN T, GEN q, GEN p, long e)
+{
+  pari_sp av = avma;
+  GEN b = leading_coeff(B), bi;
+  GEN B2, P, V, W;
+  long i, lV;
+  if (typ(b)==t_INT) return FpXQX_digits(x, B, T, q);
+  bi = ZpXQ_inv(b, T, p, e);
+  B2 = FqX_Fq_mul_to_monic(B, bi, T, q);
+  V = FpXQX_digits(x, B2, T, q);
+  lV = lg(V)-1;
+  P = FpXQ_powers(bi, lV-1, T, q);
+  W = cgetg(lV+1, t_VEC);
+  for(i=1; i<=lV; i++)
+    gel(W, i) = FpXQX_FpXQ_mul(gel(V,i), gel(P, i), T, q);
+  return gerepileupto(av, W);
+}
+
 struct _ZpXQ_sqrtn
 {
   GEN T, a, n, ai;
diff --git a/src/basemath/QX_factor.c b/src/basemath/QX_factor.c
index b299bb9..6c1d1ce 100644
--- a/src/basemath/QX_factor.c
+++ b/src/basemath/QX_factor.c
@@ -106,7 +106,7 @@ static GEN
 Mignotte_bound(GEN S)
 {
   long i, d = degpol(S);
-  GEN C, N2, t, binlS, lS = leading_term(S), bin = vecbinome(d-1);
+  GEN C, N2, t, binlS, lS = leading_coeff(S), bin = vecbinome(d-1);
 
   N2 = sqrtr(RgX_fpnorml2(S,DEFAULTPREC));
   binlS = is_pm1(lS)? bin: ZC_Z_mul(bin, lS);
@@ -143,7 +143,7 @@ Beauzamy_bound(GEN S)
   /* s = [S]_2^2 */
   C = powruhalf(stor(3,prec), 3 + 2*d); /* 3^{3/2 + d} */
   C = divrr(mulrr(C, s), mulur(4*d, mppi(prec)));
-  lS = absi(leading_term(S));
+  lS = absi(leading_coeff(S));
   return mulir(lS, sqrtr(C));
 }
 
@@ -184,7 +184,7 @@ cmbf(GEN pol, GEN famod, GEN bound, GEN p, long a, long b,
   GEN fa       = cgetg(lfamod+1, t_VEC);
 
   *pmaxK = cmbf_maxK(lfamod);
-  lc = absi(leading_term(pol));
+  lc = absi(leading_coeff(pol));
   if (is_pm1(lc)) lc = NULL;
   lcpol = lc? ZX_Z_mul(pol, lc): pol;
 
@@ -263,11 +263,11 @@ nextK:
       y = lc;
       for (i=1; i<=K; i++)
       {
-        GEN q = constant_term(gel(famod,ind[i]));
+        GEN q = constant_coeff(gel(famod,ind[i]));
         if (y) q = mulii(y, q);
         y = centermodii(q, pa, pas2);
       }
-      if (!signe(y) || remii(constant_term(lcpol), y) != gen_0)
+      if (!signe(y) || remii(constant_coeff(lcpol), y) != gen_0)
       {
         if (DEBUGLEVEL>3) err_printf("T");
         avma = av; goto NEXT;
@@ -295,7 +295,7 @@ nextK:
       gel(fa,cnt++) = y;
       /* fix up pol */
       pol = q;
-      if (lc) pol = Q_div_to_int(pol, leading_term(y));
+      if (lc) pol = Q_div_to_int(pol, leading_coeff(y));
       for (i=j=k=1; i <= lfamod; i++)
       { /* remove used factors */
         if (j <= K && i == ind[j]) j++;
@@ -312,7 +312,7 @@ nextK:
       if (lfamod < 2*K) goto END;
       i = 1; curdeg = deg[ind[1]];
       bound = factor_bound(pol);
-      if (lc) lc = absi(leading_term(pol));
+      if (lc) lc = absi(leading_coeff(pol));
       lcpol = lc? ZX_Z_mul(pol, lc): pol;
       if (DEBUGLEVEL>3)
         err_printf("\nfound factor %Ps\nremaining modular factor(s): %ld\n",
@@ -335,7 +335,7 @@ END:
   *done = 1;
   if (degpol(pol) > 0)
   { /* leftover factor */
-    if (signe(leading_term(pol)) < 0) pol = ZX_neg(pol);
+    if (signe(leading_coeff(pol)) < 0) pol = ZX_neg(pol);
     if (lfamod >= 2*K) *done = 0;
 
     setlg(famod, lfamod+1);
@@ -383,7 +383,7 @@ shifteval(GEN Q, long n)
 static GEN
 root_bound(GEN P0)
 {
-  GEN Q = leafcopy(P0), lP = absi(leading_term(Q)), x,y,z;
+  GEN Q = leafcopy(P0), lP = absi(leading_coeff(Q)), x,y,z;
   long k, d = degpol(Q);
 
   /* P0 = lP x^d + Q, deg Q < d */
@@ -457,7 +457,7 @@ chk_factors(GEN P, GEN M_L, GEN bound, GEN famod, GEN pa)
 
   r  = lg(piv)-1;
   list = cgetg(r+1, t_VEC);
-  lt = absi(leading_term(pol));
+  lt = absi(leading_coeff(pol));
   if (is_pm1(lt)) lt = NULL;
   ltpol = lt? ZX_Z_mul(pol, lt): pol;
   paov2 = shifti(pa,-1);
@@ -473,8 +473,8 @@ chk_factors(GEN P, GEN M_L, GEN bound, GEN famod, GEN pa)
 
     if (lt)
     {
-      pol = ZX_Z_divexact(pol, leading_term(y));
-      lt = absi(leading_term(pol));
+      pol = ZX_Z_divexact(pol, leading_coeff(y));
+      lt = absi(leading_coeff(pol));
       ltpol = ZX_Z_mul(pol, lt);
     }
     else
@@ -532,7 +532,7 @@ LLL_cmbf(GEN P, GEN famod, GEN p, GEN pa, GEN bound, long a, long rec)
   pari_sp av, av2;
   long ti_LLL = 0, ti_CF  = 0;
 
-  lP = absi(leading_term(P));
+  lP = absi(leading_coeff(P));
   if (is_pm1(lP)) lP = NULL;
   Br = root_bound(P);
   if (lP) Br = mulii(lP, Br);
@@ -714,7 +714,7 @@ combine_factors(GEN target, GEN famod, GEN p, long klim)
 
   A = factor_bound(target);
 
-  la = absi(leading_term(target));
+  la = absi(leading_coeff(target));
   B = mului(n, sqri(mulii(la, root_bound(target)))); /* = bound for S_2 */
 
   (void)cmbf_precs(p, A, B, &a, &b, &pa, &pb);
@@ -802,7 +802,7 @@ DDF_roots(GEN A)
   pp = pick_prime(A, 1, &T);
   if (!pp) return cgetg(1,t_VEC); /* no root */
   p = utoipos(pp);
-  lc = leading_term(A);
+  lc = leading_coeff(A);
   if (is_pm1(lc))
   { lc = NULL; lcpol = A; }
   else
@@ -823,11 +823,11 @@ DDF_roots(GEN A)
     if (! (q = ZX_divides(lcpol, y)) ) continue;
 
     lcpol = q;
-    r = negi( constant_term(y) );
+    r = negi( constant_coeff(y) );
     if (lc) {
       r = gdiv(r,lc);
       lcpol = Q_primpart(lcpol);
-      lc = absi_shallow( leading_term(lcpol) );
+      lc = absi_shallow( leading_coeff(lcpol) );
       if (is_pm1(lc)) lc = NULL; else lcpol = ZX_Z_mul(lcpol, lc);
     }
     gel(z,m++) = r;
@@ -910,7 +910,7 @@ ZX_squff(GEN f, GEN *ex)
   GEN T, V, P, e;
   long i, k, n, val;
 
-  if (signe(leading_term(f)) < 0) f = gneg_i(f);
+  if (signe(leading_coeff(f)) < 0) f = gneg_i(f);
   val = ZX_valrem(f, &f);
   n = 1 + degpol(f); if (val) n++;
   e = cgetg(n,t_VECSMALL);
@@ -1074,7 +1074,7 @@ ZX_gcd_all(GEN A, GEN B, GEN *Anew)
   ltop = avma;
 
   n = 1 + minss(degpol(A), degpol(B)); /* > degree(gcd) */
-  g = gcdii(leading_term(A), leading_term(B)); /* multiple of lead(gcd) */
+  g = gcdii(leading_coeff(A), leading_coeff(B)); /* multiple of lead(gcd) */
   if (is_pm1(g)) {
     g = NULL;
     Ag = A;
@@ -1287,9 +1287,9 @@ ZXQ_mul_by_X(GEN t, GEN T)
   GEN lt;
   t = RgX_shift_shallow(t, 1);
   if (degpol(t) < degpol(T)) return t;
-  lt = leading_term(t);
+  lt = leading_coeff(t);
   if (is_pm1(lt)) return signe(lt) > 0 ? ZX_sub(t, T): ZX_add(t, T);
-  return ZX_sub(t, ZX_Z_mul(T, leading_term(t)));
+  return ZX_sub(t, ZX_Z_mul(T, leading_coeff(t)));
 }
 /* f a product of Phi_n, all n odd; deg f > 1. Is it irreducible ? */
 static long
@@ -1355,7 +1355,7 @@ BD_iscyclo(GEN f)
 
   if (issquareall(f1, &f2))
   {
-    GEN lt = leading_term(f2);
+    GEN lt = leading_coeff(f2);
     long c;
     if (signe(lt) < 0) f2 = ZX_neg(f2);
     c = BD_iscyclo(f2);
@@ -1384,7 +1384,7 @@ poliscycloprod(GEN f)
   long i, d = degpol(f);
   if (typ(f) != t_POL) pari_err_TYPE("poliscycloprod",f);
   if (!RgX_is_ZX(f)) return 0;
-  if (!equali1(leading_term(f)) || !is_pm1(constant_term(f))) return 0;
+  if (!equali1(leading_coeff(f)) || !is_pm1(constant_coeff(f))) return 0;
   if (d < 2) return (d == 1);
   if ( degpol(ZX_gcd_all(f, ZX_deriv(f), &f)) )
   {
diff --git a/src/basemath/RgV.c b/src/basemath/RgV.c
index f27b4d2..c449b11 100644
--- a/src/basemath/RgV.c
+++ b/src/basemath/RgV.c
@@ -642,6 +642,9 @@ static GEN
 _RgM_add(void *E, GEN x, GEN y) { (void)E; return RgM_add(x, y); }
 
 static GEN
+_RgM_sub(void *E, GEN x, GEN y) { (void)E; return RgM_sub(x, y); }
+
+static GEN
 _RgM_cmul(void *E, GEN P, long a, GEN x) { (void)E; return RgM_Rg_mul(x,gel(P,a+2)); }
 
 static GEN
@@ -659,7 +662,8 @@ _RgM_zero(void *E) { long *n = (long*) E; return zeromat(*n,*n); }
 static GEN
 _RgM_red(void *E, GEN x) { (void)E; return x; }
 
-static struct bb_algebra RgM_algebra = { _RgM_red,_RgM_add,_RgM_mul,_RgM_sqr,_RgM_one,_RgM_zero };
+static struct bb_algebra RgM_algebra = { _RgM_red, _RgM_add, _RgM_sub,
+       _RgM_mul, _RgM_sqr, _RgM_one, _RgM_zero };
 
 /* generates the list of powers of x of degree 0,1,2,...,l*/
 GEN
diff --git a/src/basemath/RgX.c b/src/basemath/RgX.c
index d5c4b78..54e4645 100644
--- a/src/basemath/RgX.c
+++ b/src/basemath/RgX.c
@@ -111,6 +111,8 @@ _gen_nored(void *E, GEN x) { (void)E; return x; }
 static GEN
 _gen_add(void *E, GEN x, GEN y) { (void)E; return gadd(x, y); }
 static GEN
+_gen_sub(void *E, GEN x, GEN y) { (void)E; return gsub(x, y); }
+static GEN
 _gen_mul(void *E, GEN x, GEN y) { (void)E; return gmul(x, y); }
 static GEN
 _gen_sqr(void *E, GEN x) { (void)E; return gsqr(x); }
@@ -119,8 +121,8 @@ _gen_one(void *E) { (void)E; return gen_1; }
 static GEN
 _gen_zero(void *E) { (void)E; return gen_0; }
 
-static struct bb_algebra Rg_algebra = { _gen_nored,_gen_add,_gen_mul,_gen_sqr,
-                                        _gen_one,_gen_zero };
+static struct bb_algebra Rg_algebra = { _gen_nored, _gen_add, _gen_sub,
+              _gen_mul, _gen_sqr,_gen_one,_gen_zero };
 
 static GEN
 _gen_cmul(void *E, GEN P, long a, GEN x)
@@ -719,12 +721,16 @@ RgXY_swap(GEN x, long n, long w)
 }
 
 long
-RgXY_degreex(GEN bpol)
+RgXY_degreex(GEN b)
 {
-  long deg = 0, i;
-  if (!signe(bpol)) return -1;
-  for (i = 2; i < lg(bpol); ++i)
-    deg = maxss(deg, degpol(gel(bpol, i)));
+  long deg = -1, i;
+  if (!signe(b)) return -1;
+  for (i = 2; i < lg(b); ++i)
+  {
+    GEN bi = gel(b, i);
+    if (typ(bi) == t_POL)
+      deg = maxss(deg, degpol(bi));
+  }
   return deg;
 }
 
@@ -1709,7 +1715,7 @@ RgXQX_divrem(GEN x, GEN y, GEN T, GEN *pr)
     }
     return pol_0(vx);
   }
-  lead = leading_term(y);
+  lead = leading_coeff(y);
   if (!dy) /* y is constant */
   {
     if (pr && pr != ONLY_DIVIDES)
@@ -1797,7 +1803,7 @@ ZXQX_dvd(GEN x, GEN y, GEN T)
   if (typ(y_lead) == t_POL) y_lead = gel(y_lead, 2); /* t_INT */
   /* if monic, no point in using pseudo-division */
   if (gequal1(y_lead)) return signe(RgXQX_rem(x, y, T)) == 0;
-  T_ismonic = gequal1(leading_term(T));
+  T_ismonic = gequal1(leading_coeff(T));
   dx = degpol(x);
   if (dx < dy) return !signe(x);
   (void)new_chunk(2);
@@ -2044,6 +2050,8 @@ RgXQX_sqr(GEN x, GEN T)
 static GEN
 _add(void *data, GEN x, GEN y) { (void)data; return RgX_add(x, y); }
 static GEN
+_sub(void *data, GEN x, GEN y) { (void)data; return RgX_sub(x, y); }
+static GEN
 _sqr(void *data, GEN x) { return RgXQ_sqr(x, (GEN)data); }
 static GEN
 _mul(void *data, GEN x, GEN y) { return RgXQ_mul(x,y, (GEN)data); }
@@ -2056,7 +2064,8 @@ _zero(void *data) { return pol_0(varn((GEN)data)); }
 static GEN
 _red(void *data, GEN x) { (void)data; return gcopy(x); }
 
-static struct bb_algebra RgXQ_algebra = { _red,_add,_mul,_sqr,_one,_zero };
+static struct bb_algebra RgXQ_algebra = { _red, _add, _sub,
+              _mul, _sqr, _one, _zero };
 
 GEN
 RgX_RgXQV_eval(GEN Q, GEN x, GEN T)
@@ -2096,7 +2105,8 @@ _zeroXn(void *data) {
   struct modXn *S = (struct modXn*)data;
   return pol_0(S->v);
 }
-static struct bb_algebra RgXn_algebra = { _red,_add, _mulXn,_sqrXn, _oneXn,_zeroXn };
+static struct bb_algebra RgXn_algebra = { _red, _add, _sub, _mulXn, _sqrXn,
+                                          _oneXn, _zeroXn };
 
 GEN
 RgXn_powers(GEN x, long m, long n)
@@ -2109,6 +2119,21 @@ RgXn_powers(GEN x, long m, long n)
 }
 
 GEN
+RgXn_powu_i(GEN x, ulong m, long n)
+{
+  struct modXn S;
+  S.v = varn(x); S.n = n;
+  return gen_powu_i(x, m, (void*)&S,_sqrXn,_mulXn);
+}
+GEN
+RgXn_powu(GEN x, ulong m, long n)
+{
+  struct modXn S;
+  S.v = varn(x); S.n = n;
+  return gen_powu(x, m, (void*)&S,_sqrXn,_mulXn);
+}
+
+GEN
 RgX_RgXnV_eval(GEN Q, GEN x, long n)
 {
   struct modXn S;
@@ -2307,9 +2332,15 @@ QXQ_powers(GEN a, long n, GEN T)
 static GEN
 do_QXQ_eval(GEN v, long imin, GEN a, GEN T)
 {
-  long l, i, m = degpol(T);
-  GEN dz, z = Q_remove_denom(QXQ_powers(a, m-1, T), &dz);
+  long l, i, m = 0;
+  GEN dz, z;
   GEN V = cgetg_copy(v, &l);
+  for (i = imin; i < l; i++)
+  {
+    GEN c = gel(v, i);
+    if (typ(c) == t_POL) m = maxss(m, degpol(c));
+  }
+  z = Q_remove_denom(QXQ_powers(a, m, T), &dz);
   for (i = 1; i < imin; i++) V[i] = v[i];
   for (i = imin; i < l; i++)
   {
@@ -2351,7 +2382,7 @@ RgXQ_norm(GEN x, GEN T)
   GEN L, y;
 
   av = avma; y = resultant(T, x);
-  L = leading_term(T);
+  L = leading_coeff(T);
   if (gequal1(L) || !signe(x)) return y;
   return gerepileupto(av, gdiv(y, gpowgs(L, dx)));
 }
diff --git a/src/basemath/ZG.c b/src/basemath/ZG.c
index 6c3b5de..dd6e475 100644
--- a/src/basemath/ZG.c
+++ b/src/basemath/ZG.c
@@ -89,24 +89,45 @@ ZG_mul(GEN x, GEN y)
   }
   return z;
 }
-#if 0
-static GEN
-ZGV_add(GEN x, GEN y)
+GEN
+ZGC_add_sparse(GEN x, GEN y)
 {
-  long i, l;
-  GEN v = cgetg_copy(x, &l);
-  for (i = 1; i < l; i++) gel(v,i) = ZG_add(gel(x,i), gel(y,i));
-  return v;
+  GEN xi = gel(x,1), xv = gel(x,2);
+  GEN yi = gel(y,1), yv = gel(y,2);
+  long i = 1, j = 1, k = 1, lx = lg(xi), ly = lg(yi), l = lx+ly-1;
+  GEN zi = cgetg(l, t_VECSMALL), zv = cgetg(l, t_VEC);
+  while (i < lx && j < ly)
+  {
+    if      (xi[i] < yi[j]) { zi[k] = xi[i]; gel(zv,k) = gel(xv,i); i++; }
+    else if (xi[i] > yi[j]) { zi[k] = yi[j]; gel(zv,k) = gel(yv,j); j++; }
+    else { zi[k] = xi[i]; gel(zv,k) = ZG_add(gel(xv,i),gel(yv,j)); i++; j++; }
+    k++;
+  }
+  for(; i < lx; i++,k++) { zi[k] = xi[i]; gel(zv,k) = gel(xv,i); }
+  for(; j < ly; j++,k++) { zi[k] = yi[j]; gel(zv,k) = gel(yv,j); }
+  setlg(zi,k);
+  setlg(zv,k); return mkvec2(zi, zv);
 }
-static GEN
-ZGV_sub(GEN x, GEN y)
+GEN
+ZGM_add_sparse(GEN x, GEN y)
 {
-  long i, l;
-  GEN v = cgetg_copy(x, &l);
-  for (i = 1; i < l; i++) gel(v,i) = ZG_sub(gel(x,i), gel(y,i));
-  return v;
+  long j, l;
+  GEN z = cgetg_copy(x, &l);
+  for (j = 1; j < l; j++) gel(z,j) = ZGC_add_sparse(gel(x,j), gel(y,j));
+  return z;
+}
+void
+ZGC_add_inplace(GEN x, GEN y)
+{
+  long i, l = lg(x);
+  for (i = 1; i < l; i++) gel(x,i) = ZG_add(gel(x,i), gel(y,i));
+}
+void
+ZGM_add_inplace(GEN x, GEN y)
+{
+  long j, l = lg(x);
+  for (j = 1; j < l; j++) ZGC_add_inplace(gel(x,j), gel(y,j));
 }
-#endif
 GEN
 ZG_G_mul(GEN x, GEN y)
 {
@@ -129,6 +150,12 @@ G_ZG_mul(GEN x, GEN y)
   for (i = 1; i < l; i++) gel(z,i) = gmul(x, gel(Y,i));
   return ZG_normalize( mkmat2(z, shallowcopy(gel(y,2))) );
 }
+void
+ZGC_G_mul_inplace(GEN v, GEN x)
+{
+  long i, l = lg(v);
+  for (i = 1; i < l; i++) gel(v,i) = ZG_G_mul(gel(v,i), x);
+}
 GEN
 ZGC_G_mul(GEN v, GEN x)
 {
diff --git a/src/basemath/alglin1.c b/src/basemath/alglin1.c
index 83a32b9..ee19092 100644
--- a/src/basemath/alglin1.c
+++ b/src/basemath/alglin1.c
@@ -454,10 +454,7 @@ F2m_ker_sp(GEN x, long deplin)
   m = mael(x,1,1); r=0;
 
   d = cgetg(n+1, t_VECSMALL);
-  c = zero_F2v(m);
-  l = lg(c)-1;
-  for (i = 2; i <= l; i++) c[i] = -1;
-  if (remsBIL(m)) c[l] = (1uL<<remsBIL(m))-1uL;
+  c = const_F2v(m); l = lg(c)-1;
   for (k=1; k<=n; k++)
   {
     GEN xk = gel(x,k);
@@ -858,10 +855,7 @@ F2m_gauss_pivot(GEN x, long *rr)
   m = mael(x,1,1); r=0;
 
   d = cgetg(n+1, t_VECSMALL);
-  c = zero_F2v(m);
-  l = lg(c)-1;
-  for (i = 2; i <= l; i++) c[i] = -1;
-  if (remsBIL(m)) c[l] = (1uL<<remsBIL(m))-1uL;
+  c = const_F2v(m); l = lg(c)-1;
   for (k=1; k<=n; k++)
   {
     GEN xk = gel(x,k);
@@ -1548,7 +1542,7 @@ is_modular_solve(GEN a, GEN b, GEN *u)
         if (a) a = F2c_to_mod(a);
         break;
       default:
-        b = RgC_to_Flc(b, pp);
+        b = RgV_to_Flv(b, pp);
         a = Flm_Flc_gauss(a,b,pp);
         if (a) a = Flc_to_mod(a, pp);
         break;
@@ -1609,7 +1603,7 @@ RgM_solve(GEN a, GEN b)
     GEN u = gcoeff(a,1,1), v = gcoeff(a,1,2);
     GEN w = gcoeff(a,2,1), x = gcoeff(a,2,2);
     GEN D = gsub(gmul(u,x), gmul(v,w)), ainv;
-    if (gcmp0(D)) return NULL;
+    if (gequal0(D)) return NULL;
     ainv = mkmat2(mkcol2(x, gneg(w)), mkcol2(gneg(v), u));
     ainv = gmul(ainv, ginv(D));
     if (b) ainv = gmul(ainv, b);
@@ -2252,9 +2246,9 @@ ZM_gauss(GEN a, GEN b0)
   elim = expi(delta)+1;
   av2 = avma;
 #ifdef LONG_IS_64BIT
-  p = 1000000000000000000;
+  p = 1000000000000000000UL;
 #else
-  p = 1000000000;
+  p = 1000000000UL;
 #endif
   for(;;)
   {
@@ -2290,6 +2284,7 @@ ZM_inv(GEN M, GEN dM)
   long lM = lg(M), stable = 0;
   int negate = 0;
   forprime_t S;
+  pari_timer ti;
 
   if (lM == 1) return cgetg(1,t_MAT);
 
@@ -2304,6 +2299,7 @@ ZM_inv(GEN M, GEN dM)
   init_modular(&S);
   av2 = avma;
   H = NULL;
+  if (DEBUGLEVEL>5) timer_start(&ti);
   while ((p = u_forprime_next(&S)))
   {
     ulong dMp;
@@ -2331,7 +2327,7 @@ ZM_inv(GEN M, GEN dM)
     }
     else
       stable = ZM_incremental_CRT(&H, Hp, &q, p);
-    if (DEBUGLEVEL>5) err_printf("inverse mod %ld (stable=%ld)\n", p,stable);
+    if (DEBUGLEVEL>5) timer_printf(&ti, "ZM_inv mod %lu (stable=%ld)", p,stable);
     if (stable) {/* DONE ? */
       if (dM != gen_1)
       { if (ZM_isscalar(ZM_mul(M, H), dM)) break; }
@@ -2383,7 +2379,7 @@ ZM_inv_ratlift(GEN M, GEN *pden)
       ZM_incremental_CRT(&H, Hp, &q, p);
     B = sqrti(shifti(q,-1));
     Hr = FpM_ratlift(H,q,B,B,NULL);
-    if (DEBUGLEVEL>5) err_printf("ZM_inv mod %ld (ratlift=%ld)\n", p,!!Hr);
+    if (DEBUGLEVEL>5) err_printf("ZM_inv mod %lu (ratlift=%ld)\n", p,!!Hr);
     if (Hr) {/* DONE ? */
       GEN Hl = Q_remove_denom(Hr, pden);
       if (*pden)
@@ -3027,7 +3023,7 @@ RgM_RgC_invimage(GEN A, GEN y)
       if (x) x = F2c_to_mod(x);
       break;
     default:
-      y = RgC_to_Flc(y,pp);
+      y = RgV_to_Flv(y,pp);
       x = Flm_Flc_invimage(A, y, pp);
       if (x) x = Flc_to_mod(x,pp);
     }
@@ -3094,7 +3090,7 @@ Flm_Flc_invimage(GEN A, GEN y, ulong p)
   if (!t) { avma = av; return NULL; }
 
   setlg(x,l); t = Fl_inv(Fl_neg(t,p),p);
-  if (t!=1) x = Flc_Fl_mul(x, t, p);
+  if (t!=1) x = Flv_Fl_mul(x, t, p);
   return gerepileuptoleaf(av, x);
 }
 GEN
@@ -3113,7 +3109,7 @@ F2m_F2c_invimage(GEN A, GEN y)
 
   x = gel(M,i);
   if (!F2v_coeff(x,l)) { avma = av; return NULL; }
-  x[1]--; /* remove last coord */
+  F2v_clear(x, x[1]); x[1]--; /* remove last coord */
   return gerepileuptoleaf(av, x);
 }
 
@@ -3718,7 +3714,7 @@ RgMs_structelim_col(GEN M, long nbcol, long nbrow, GEN A, GEN *p_col, GEN *p_row
 void
 RgMs_structelim(GEN M, long nbrow, GEN A, GEN *p_col, GEN *p_row)
 {
-  return RgMs_structelim_col(M, lg(M)-1, nbrow, A, p_col, p_row);
+  RgMs_structelim_col(M, lg(M)-1, nbrow, A, p_col, p_row);
 }
 
 /*******************************************************************/
diff --git a/src/basemath/alglin2.c b/src/basemath/alglin2.c
index d4f4284..7eb5ab5 100644
--- a/src/basemath/alglin2.c
+++ b/src/basemath/alglin2.c
@@ -145,7 +145,7 @@ easychar(GEN x, long v)
     case t_POLMOD:
     {
       GEN A = gel(x,2), T = gel(x,1);
-      if (RgX_is_QX(A) && RgX_is_ZX(T))
+      if (typ(A)==t_POL && RgX_is_QX(A) && RgX_is_ZX(T))
         return QXQ_charpoly(A, T, v);
       else
         return RgXQ_charpoly(A, T, v);
@@ -422,7 +422,7 @@ transD(GEN M, GEN P, long a, long b, long j)
   long l, n;
   GEN k = gcoeff(M,a,b), ki;
 
-  if (gcmp1(k)) return;
+  if (gequal1(k)) return;
   ki = ginv(k); n = lg(M)-1;
   for(l=1; l<=n; l++)
     if (l!=j)
@@ -693,7 +693,7 @@ easymin(GEN x, long v)
   dR=RgX_deriv(R);
   if (!lgpol(dR)) {avma=ltop; return NULL;}
   G=RgX_gcd(R,dR);
-  G=RgX_Rg_div(G,leading_term(G));
+  G=RgX_Rg_div(G,leading_coeff(G));
   return gerepileupto(ltop, RgX_div(R,G));
 }
 
diff --git a/src/basemath/alglin3.c b/src/basemath/alglin3.c
index 239fa45..794e6bd 100644
--- a/src/basemath/alglin3.c
+++ b/src/basemath/alglin3.c
@@ -350,21 +350,21 @@ static long
 vecslice_parse_arg(long lA, long *y1, long *y2, long *skip)
 {
   *skip=0;
-  if (!*y1)
+  if (*y1==LONG_MAX)
   {
-    if (*y2)
+    if (*y2!=LONG_MAX)
     {
       if (*y2<0) *y2 += lA;
-      if (*y2<=0 || *y2>=lA)
+      if (*y2<0 || *y2==LONG_MAX || *y2>=lA)
         pari_err_DIM("_[..]");
       *skip=*y2;
     }
     *y1 = 1; *y2 = lA-1;
   }
-  else if (!*y2) *y2 = *y1;
-  if (*y1<0) *y1 += lA;
+  else if (*y2==LONG_MAX) *y2 = *y1;
+  if (*y1<=0) *y1 += lA;
   if (*y2<0) *y2 += lA;
-  if (*y1<=0 || *y1>*y2 || *y2>=lA) pari_err_DIM("_[..]");
+  if (*y1<=0 || *y1>*y2+1 || *y2>=lA) pari_err_DIM("_[..]");
   return *y2 - *y1 + 2 - !!*skip;
 }
 
@@ -441,7 +441,8 @@ matslice0(GEN A, long x1, long x2, long y1, long y2)
 {
   GEN B;
   long i, lB, lA = lg(A), t, skip, rskip, rlB;
-  long is_col = y1 && !y2, is_row = x1 && !x2;
+  long is_col = y1!=LONG_MAX && y2==LONG_MAX;
+  long is_row = x1!=LONG_MAX && x2==LONG_MAX;
   GEN (*slice)(GEN A, long t, long lB, long y1, long skip);
   if (typ(A)!=t_MAT) pari_err_TYPE("_[_.._,_.._]",A);
   lB = vecslice_parse_arg(lA, &y1, &y2, &skip);
diff --git a/src/basemath/arith1.c b/src/basemath/arith1.c
index aba84cd..a228ada 100644
--- a/src/basemath/arith1.c
+++ b/src/basemath/arith1.c
@@ -752,6 +752,27 @@ END:
   return 1;
 }
 
+static long
+polmodispower(GEN x, GEN K, GEN *pt)
+{
+  pari_sp av = avma;
+  GEN p = NULL, T = NULL;
+  if (Rg_is_FpXQ(x, &T,&p) && p)
+  {
+    x = liftall_shallow(x);
+    if (!Fq_ispower(x, K, T, p)) { avma = av; return 0; }
+    if (!pt) { avma = av; return 1; }
+    x = Fq_sqrtn(x, K, T,p, NULL);
+    if (typ(x) == t_INT)
+      x = Fp_to_mod(x,p);
+    else
+      x = mkpolmod(FpX_to_mod(x,p), FpX_to_mod(T,p));
+    *pt = gerepilecopy(av, x); return 1;
+  }
+  pari_err_IMPL("ispower for general t_POLMOD");
+  return 0;
+}
+
 long
 issquareall(GEN x, GEN *pt)
 {
@@ -769,6 +790,8 @@ issquareall(GEN x, GEN *pt)
           || !Z_issquareall(gel(x,2), &gel(F,2))) { avma = av; return 0; }
       *pt = F; return 1;
 
+    case t_POLMOD:
+      return polmodispower(x, gen_2, pt);
     case t_POL: return polissquareall(x,pt);
     case t_RFRAC: av = avma;
       F = cgetg(3, t_RFRAC);
@@ -827,6 +850,9 @@ issquare(GEN x)
           (v==2 && mod4(a) != 1)) return 0;
       return 1;
 
+    case t_POLMOD:
+      return polmodispower(x, gen_2, NULL);
+
     case t_POL:
       return polissquareall(x,NULL);
 
@@ -895,7 +921,7 @@ static long
 polispower(GEN x, GEN K, GEN *pt)
 {
   pari_sp av;
-  long v, k = itos(K);
+  long v, d, k = itos(K);
   GEN y, a, b;
 
   if (!signe(x))
@@ -905,18 +931,53 @@ polispower(GEN x, GEN K, GEN *pt)
   }
   if (degpol(x) % k) return 0; /* degree not multiple of k */
   av = avma;
+  y = NULL; /*-Wall*/
   v = RgX_valrem(x, &x);
   if (v % k) return 0;
+  v /= k;
   a = gel(x,2); b = NULL;
   if (!ispower(a, K, &b)) { avma = av; return 0; }
-  if (degpol(x))
-  {
-    x = RgX_Rg_div(x,a);
+  d = degpol(x);
+  if (d)
+  {
+    GEN p = characteristic(x);
+    a = leading_coeff(x);
+    if (!ispower(a, K, &b)) { avma = av; return 0; }
+    x = RgX_normalize(x);
+    if (signe(p))
+    {
+      GEN T0, T = NULL;
+      if (!BPSW_isprime(p))
+        pari_err_IMPL("ispower in non-prime characteristic");
+      if (RgX_is_FpXQX(x,&T,&p))
+      { /* over Fq */
+        T0 = T;
+        if (T && typ(T) == t_FFELT) T = FF_mod(T);
+        x = RgX_to_FqX(x,T,p);
+        if (!FqX_ispower(x, k, T,p, pt)) { avma = av; return 0; }
+        if (pt)
+        {
+          y = *pt;
+          if (!T) y = FpX_to_mod(y, p);
+          else if (typ(T0) == t_FFELT)
+            y = FqX_to_FFX(y, T0);
+          else
+          {
+            T = FpX_to_mod(T, p);
+            y = gmul(y, gmodulsg(1,T));
+          }
+        }
+        goto END;
+      }
+      if (cmpii(p,K) <= 0)
+        pari_err_IMPL("ispower(general t_POL) in small characteristic");
+    }
     y = gtrunc(gsqrtn(RgX_to_ser(x,lg(x)), K, NULL, 0));
     if (!RgX_equal(powgi(y, K), x)) { avma = av; return 0; }
   }
   else
     y = pol_1(varn(x));
+END:
   if (pt)
   {
     if (!gequal1(a))
@@ -924,7 +985,8 @@ polispower(GEN x, GEN K, GEN *pt)
       if (!b) b = gsqrtn(a, K, NULL, DEFAULTPREC);
       y = gmul(b,y);
     }
-    *pt = v? gerepilecopy(av, RgX_shift_shallow(y, v/k)): gerepileupto(av, y);
+    if (v) y = RgX_shift_shallow(y, v);
+    *pt = gerepilecopy(av, y);
   }
   else avma = av;
   return 1;
@@ -1001,6 +1063,16 @@ Zn_issquare(GEN d, GEN fn)
   return 1;
 }
 
+static long
+Qp_ispower(GEN x, GEN K, GEN *pt)
+{
+  pari_sp av = avma;
+  GEN z = Qp_sqrtn(x, K, NULL);
+  if (!z) { avma = av; return 0; }
+  if (pt) *pt = z;
+  return 1;
+}
+
 long
 ispower(GEN x, GEN K, GEN *pt)
 {
@@ -1032,11 +1104,9 @@ ispower(GEN x, GEN K, GEN *pt)
       return FF_ispower(x, K, pt);
 
     case t_PADIC:
-      z = Qp_sqrtn(x, K, NULL);
-      if (!z) return 0;
-      if (pt) *pt = z;
-      return 1;
-
+      return Qp_ispower(x, K, pt);
+    case t_POLMOD:
+      return polmodispower(x, K, pt);
     case t_POL:
       return polispower(x, K, pt);
     case t_RFRAC: {
@@ -1061,10 +1131,9 @@ ispower(GEN x, GEN K, GEN *pt)
         return 0;
       if (pt) *pt = gsqrtn(x, K, NULL, DEFAULTPREC);
       return 1;
-
-    default: pari_err_TYPE("ispower",x);
-    return 0; /* not reached */
   }
+  pari_err_TYPE("ispower",x);
+  return 0; /* not reached */
 }
 
 long
@@ -2174,6 +2243,16 @@ gen_chinese(GEN x, GEN(*f)(GEN,GEN))
   return z;
 }
 
+/* x t_INTMOD, y t_POLMOD; promote x to t_POLMOD mod Pol(x.mod) then
+ * call chinese: makes Mod(0,1) a better "neutral" element */
+static GEN
+chinese_intpol(GEN x,GEN y)
+{
+  pari_sp av = avma;
+  GEN z = mkpolmod(gel(x,2), scalarpol_shallow(gel(x,1), varn(gel(y,1))));
+  return gerepileupto(av, chinese(z, y));
+}
+
 GEN
 chinese1(GEN x) { return gen_chinese(x,chinese); }
 
@@ -2181,12 +2260,13 @@ GEN
 chinese(GEN x, GEN y)
 {
   pari_sp av;
-  long tx = typ(x);
+  long tx = typ(x), ty;
   GEN z,p1,p2,d,u,v;
 
   if (!y) return chinese1(x);
   if (gidentical(x,y)) return gcopy(x);
-  if (tx == typ(y)) switch(tx)
+  ty = typ(y);
+  if (tx == ty) switch(tx)
   {
     case t_POLMOD:
     {
@@ -2237,6 +2317,8 @@ chinese(GEN x, GEN y)
       return z;
     }
   }
+  if (tx == t_POLMOD && ty == t_INTMOD) return chinese_intpol(y,x);
+  if (ty == t_POLMOD && tx == t_INTMOD) return chinese_intpol(x,y);
   pari_err_OP("chinese",x,y);
   return NULL; /* not reached */
 }
@@ -2725,6 +2807,19 @@ Fl_powers(ulong x, long n, ulong p)
  **                                                                  **
  **********************************************************************/
 
+static GEN
+Fp_dblsqr(GEN x, GEN N)
+{
+  GEN z = shifti(Fp_sqr(x, N), 1);
+  return cmpii(z, N) >= 0? subii(z, N): z;
+}
+
+typedef struct muldata {
+  GEN (*sqr)(void * E, GEN x);
+  GEN (*mul)(void * E, GEN x, GEN y);
+  GEN (*mul2)(void * E, GEN x);
+} muldata;
+
 /* modified Barrett reduction with one fold */
 /* See Fast Modular Reduction, W. Hasenplaugh, G. Gaubatz, V. Gopal, ARITH 18 */
 
@@ -2760,93 +2855,110 @@ Fp_rem_mBarrett(GEN a, GEN B, long s, GEN N)
 INLINE ulong
 init_montdata(GEN N) { return (ulong) -invmod2BIL(mod2BIL(N)); }
 
-typedef struct muldata {
+struct montred
+{
   GEN N;
-  GEN iM;
-  ulong inv, s;
-  GEN (*res)(struct muldata *,GEN);
-  GEN (*mul2)(struct muldata *,GEN);
-} muldata;
+  ulong inv;
+};
 
 /* Montgomery reduction */
 static GEN
-_montred(muldata *D, GEN x)
+_sqr_montred(void * E, GEN x)
 {
-  return red_montgomery(x, D->N, D->inv);
-}
-
-static GEN
-_remii(muldata *D, GEN x) { return remii(x, D->N); }
-
-static GEN
-_remiibar(muldata *D, GEN x) {
-#if DEBUG
-  GEN r = Fp_rem_mBarrett(x, D->iM, D->s, D->N);
-  if (cmpii(r, D->N) >= 0) pari_err_BUG("Rp_rem_mBarrett");
-  return r;
-#else
-  return Fp_rem_mBarrett(x, D->iM, D->s, D->N);
-#endif
+  struct montred * D = (struct montred *) E;
+  return red_montgomery(sqri(x), D->N, D->inv);
 }
 
-/* 2x mod N */
+/* Montgomery reduction */
 static GEN
-_muli2red(muldata *D, GEN x)
+_mul_montred(void * E, GEN x, GEN y)
 {
-  GEN z = shifti(x,1);
-  return (cmpii(z,D->N) >= 0)? subii(z,D->N): z;
+  struct montred * D = (struct montred *) E;
+  return red_montgomery(mulii(x, y), D->N, D->inv);
 }
+
 static GEN
-_muli2montred(muldata *D, GEN x)
+_mul2_montred(void * E, GEN x)
 {
-  GEN z = _muli2red(D,x);
+  struct montred * D = (struct montred *) E;
+  GEN z = shifti(_sqr_montred(E, x), 1);
   long l = lgefint(D->N);
-  while (lgefint(z) > l) z = subii(z,D->N);
+  while (lgefint(z) > l) z = subii(z, D->N);
   return z;
 }
+
+static GEN
+_sqr_remii(void* N, GEN x)
+{ return remii(sqri(x), (GEN) N); }
+
 static GEN
-_mul(void *data, GEN x, GEN y)
+_mul_remii(void* N, GEN x, GEN y)
+{ return remii(mulii(x, y), (GEN) N); }
+
+static GEN
+_mul2_remii(void* N, GEN x)
+{ return Fp_dblsqr(x, (GEN) N); }
+
+struct redbarrett
+{
+  GEN iM, N;
+  long s;
+};
+
+static GEN
+_sqr_remiibar(void *E, GEN x)
 {
-  muldata *D = (muldata *)data;
-  return D->res(D, mulii(x,y));
+  struct redbarrett * D = (struct redbarrett *) E;
+  return Fp_rem_mBarrett(sqri(x), D->iM, D->s, D->N);
 }
+
 static GEN
-_sqr(void *data, GEN x)
+_mul_remiibar(void *E, GEN x, GEN y)
 {
-  muldata *D = (muldata *)data;
-  return D->res(D, sqri(x));
+  struct redbarrett * D = (struct redbarrett *) E;
+  return Fp_rem_mBarrett(mulii(x, y), D->iM, D->s, D->N);
 }
+
 static GEN
-_m2sqr(void *data, GEN x)
+_mul2_remiibar(void *E, GEN x)
 {
-  muldata *D = (muldata *)data;
-  return D->mul2(D, D->res(D, sqri(x)));
+  struct redbarrett * D = (struct redbarrett *) E;
+  return Fp_dblsqr(x, D->N);
 }
 
 static long
-Fp_select_red(GEN *y, ulong k, GEN N, long lN, muldata *D)
+Fp_select_red(GEN *y, ulong k, GEN N, long lN, muldata *D, void **pt_E)
 {
-  D->N = N;
   if (lN >= Fp_POW_BARRETT_LIMIT && (k==0 || ((double)k)*expi(*y) > 2 + expi(N)))
   {
-    D->mul2 = &_muli2red;
-    D->res = &_remiibar;
-    D->s = 1+(expi(N)>>1);
-    D->iM = Fp_invmBarrett(N, D->s);
+    struct redbarrett * E = (struct redbarrett *) stack_malloc(sizeof(struct redbarrett));
+    D->sqr = &_sqr_remiibar;
+    D->mul = &_mul_remiibar;
+    D->mul2 = &_mul2_remiibar;
+    E->N = N;
+    E->s = 1+(expi(N)>>1);
+    E->iM = Fp_invmBarrett(N, E->s);
+    *pt_E = (void*) E;
     return 0;
   }
   else if (mod2(N) && lN < Fp_POW_REDC_LIMIT)
   {
+    struct montred * E = (struct montred *) stack_malloc(sizeof(struct montred));
     *y = remii(shifti(*y, bit_accuracy(lN)), N);
-    D->mul2 = &_muli2montred;
-    D->res = &_montred;
-    D->inv = init_montdata(N);
+    D->sqr = &_sqr_montred;
+    D->mul = &_mul_montred;
+    D->mul2 = &_mul2_montred;
+    E->N = N;
+    E->inv = init_montdata(N);
+    *pt_E = (void*) E;
     return 1;
   }
   else
   {
-    D->mul2 = &_muli2red;
-    D->res = &_remii;
+    D->sqr = &_sqr_remii;
+    D->mul = &_mul_remii;
+    D->mul2 = &_mul2_remii;
+    *pt_E = (void*) N;
     return 0;
   }
 }
@@ -2856,7 +2968,8 @@ Fp_powu(GEN A, ulong k, GEN N)
 {
   long lN = lgefint(N), sA;
   int base_is_2, use_montgomery;
-  muldata  D;
+  muldata D;
+  void *E;
   pari_sp av;
 
   if (lN == 3) {
@@ -2879,15 +2992,15 @@ Fp_powu(GEN A, ulong k, GEN N)
 
   /* TODO: Move this out of here and use for general modular computations */
   av = avma;
-  use_montgomery = Fp_select_red(&A, k, N, lN, &D);
+  use_montgomery = Fp_select_red(&A, k, N, lN, &D, &E);
   if (base_is_2)
-    A = gen_powu_fold_i(A, k, (void*)&D, &_sqr, &_m2sqr);
+    A = gen_powu_fold_i(A, k, E, D.sqr, D.mul2);
   else
-    A = gen_powu_i(A, k, (void*)&D, &_sqr, &_mul);
+    A = gen_powu_i(A, k, E, D.sqr, D.mul);
   if (use_montgomery)
   {
-    A = _montred(&D, A);
-    if (cmpii(A,N) >= 0) A = subii(A,N);
+    A = red_montgomery(A, N, ((struct montred *) E)->inv);
+    if (cmpii(A, N) >= 0) A = subii(A,N);
     if (sA) A = subii(N, A);
   }
   return gerepileuptoint(av, A);
@@ -2917,7 +3030,8 @@ Fp_pow(GEN A, GEN K, GEN N)
   long t,s, lN = lgefint(N), sA;
   int base_is_2, use_montgomery;
   GEN y;
-  muldata  D;
+  muldata D;
+  void *E;
 
   s = signe(K);
   if (!s)
@@ -2972,14 +3086,14 @@ Fp_pow(GEN A, GEN K, GEN N)
   }
 
   /* TODO: Move this out of here and use for general modular computations */
-  use_montgomery = Fp_select_red(&y, 0UL, N, lN, &D);
+  use_montgomery = Fp_select_red(&y, 0UL, N, lN, &D, &E);
   if (base_is_2)
-    y = gen_pow_fold_i(y, K, (void*)&D, &_sqr, &_m2sqr);
+    y = gen_pow_fold_i(y, K, E, D.sqr, D.mul2);
   else
-    y = gen_pow_i(y, K, (void*)&D, &_sqr, &_mul);
+    y = gen_pow_i(y, K, E, D.sqr, D.mul);
   if (use_montgomery)
   {
-    y = _montred(&D,y);
+    y = red_montgomery(y, N, ((struct montred *) E)->inv);
     if (cmpii(y,N) >= 0) y = subii(y,N);
     if (sA) y = subii(N, y);
   }
@@ -3633,6 +3747,10 @@ unegisfundamental(ulong x)
   }
 }
 long
+sisfundamental(long x)
+{ return x < 0? unegisfundamental((ulong)(-x)): uposisfundamental(x); }
+
+long
 Z_isfundamental(GEN x)
 {
   long r;
@@ -4515,7 +4633,7 @@ qfi_Shanks(GEN a, GEN g, long n)
   a = redimag(a);
   g = redimag(g);
 
-  rt_n = sqrt(n);
+  rt_n = sqrt((double)n);
   c = n / rt_n;
   c = (c * rt_n < n + 1) ? c + 1 : c;
 
@@ -5072,7 +5190,7 @@ tauprime(GEN p)
   return gerepileupto(av, subii(mulii(powiu(p,3),T), addsi(1, gmulsg(128, s))));
 }
 
-/* Ramanujan tau function */
+/* Ramanujan tau function, return 0 for <= 0 */
 GEN
 ramanujantau(GEN n)
 {
@@ -5080,7 +5198,17 @@ ramanujantau(GEN n)
   GEN T, F, P, E;
   long j, lP;
 
-  if (!(F = check_arith_pos(n,"ramanujantau"))) F = Z_factor(n);
+  if (!(F = check_arith_all(n,"ramanujantau")))
+  {
+    if (signe(n) <= 0) return gen_0;
+    F = Z_factor(n);
+  }
+  else
+  {
+    P = gel(F,1);
+    if (lg(P) == 1 || signe(gel(P,1)) <= 0) return gen_0;
+  }
+
   P = gel(F,1);
   E = gel(F,2); lP = lg(P);
   T = gen_1;
diff --git a/src/basemath/arith2.c b/src/basemath/arith2.c
index a8f7b27..b647e1e 100644
--- a/src/basemath/arith2.c
+++ b/src/basemath/arith2.c
@@ -893,24 +893,25 @@ divisors(GEN n)
 }
 
 GEN
-divisorsu(ulong n)
+divisorsu_fact(GEN P, GEN E)
 {
-  pari_sp av = avma;
-  long i, j, l;
-  ulong nbdiv;
-  GEN d, t, t1, t2, t3, P, e, fa = factoru(n);
-
-  P = gel(fa,1); l = lg(P);
-  e = gel(fa,2);
-  nbdiv = 1;
-  for (i=1; i<l; i++) nbdiv *= 1+e[i];
+  long i, j, l = lg(P);
+  ulong nbdiv = 1;
+  GEN d, t, t1, t2, t3;
+  for (i=1; i<l; i++) nbdiv *= 1+E[i];
   d = t = cgetg(nbdiv+1,t_VECSMALL);
   *++d = 1;
   for (i=1; i<l; i++)
-    for (t1=t,j=e[i]; j; j--,t1=t2)
+    for (t1=t,j=E[i]; j; j--,t1=t2)
       for (t2=d, t3=t1; t3<t2; ) *(++d) = *(++t3) * P[i];
-  vecsmall_sort(t);
-  return gerepileupto(av, t);
+  vecsmall_sort(t); return t;
+}
+GEN
+divisorsu(ulong n)
+{
+  pari_sp av = avma;
+  GEN fa = factoru(n);
+  return gerepileupto(av, divisorsu_fact(gel(fa,1), gel(fa,2)));
 }
 
 static GEN
@@ -1180,10 +1181,6 @@ euler_sumdiv(GEN q, long v)
   for (; v > 1; v--) u = addui(1, mulii(q, u));
   return u;
 }
-static GEN
-u_euler_sumdivk(ulong p, long v, long k) { return euler_sumdiv(powuu(p,k), v); }
-static GEN
-euler_sumdivk(GEN p, long v, long k) { return euler_sumdiv(powiu(p,k), v); }
 
 static GEN
 sumdiv_aux(GEN F)
@@ -1192,31 +1189,28 @@ sumdiv_aux(GEN F)
   long i, l = lg(P);
   x = cgetg(l, t_VEC);
   for (i=1; i<l; i++) gel(x,i) = euler_sumdiv(gel(P,i), itou(gel(E,i)));
-  return x;
+  return ZV_prod(x);
 }
 GEN
 sumdiv(GEN n)
 {
   pari_sp av = avma;
-  GEN F, P, E;
-  long i, l;
+  GEN F, v;
 
   if ((F = check_arith_non0(n,"sumdiv")))
   {
     F = clean_Z_factor(F);
-    P = sumdiv_aux(F);
+    v = sumdiv_aux(F);
   }
   else if (lgefint(n) == 3)
   {
     if (n[2] == 1) return gen_1;
     F = factoru(n[2]);
-    P = gel(F,1);
-    E = gel(F,2); l = lg(P);
-    for (i=1; i<l; i++) gel(P,i) = u_euler_sumdiv(P[i], E[i]);
+    v = usumdiv_fact(F);
   }
   else
-    P = sumdiv_aux(absi_factor(n));
-  return gerepileuptoint(av, ZV_prod(P));
+    v = sumdiv_aux(absi_factor(n));
+  return gerepileuptoint(av, v);
 }
 
 static GEN
@@ -1225,15 +1219,15 @@ sumdivk_aux(GEN F, long k)
   GEN x, P = gel(F,1), E = gel(F,2);
   long i, l = lg(P);
   x = cgetg(l, t_VEC);
-  for (i=1; i<l; i++) gel(x,i) = euler_sumdivk(gel(P,i), gel(E,i)[2], k);
-  return x;
+  for (i=1; i<l; i++) gel(x,i) = euler_sumdiv(powiu(gel(P,i),k), gel(E,i)[2]);
+  return ZV_prod(x);
 }
 GEN
 sumdivk(GEN n, long k)
 {
   pari_sp av = avma;
-  GEN E, F, P;
-  long i, l, k1;
+  GEN F, v;
+  long k1;
 
   if (!k) return numdiv(n);
   if (k == 1) return sumdiv(n);
@@ -1243,39 +1237,37 @@ sumdivk(GEN n, long k)
   if ((F = check_arith_non0(n,"sumdivk")))
   {
     F = clean_Z_factor(F);
-    P = sumdivk_aux(F,k);
+    v = sumdivk_aux(F,k);
   }
   else if (lgefint(n) == 3)
   {
     if (n[2] == 1) return gen_1;
     F = factoru(n[2]);
-    P = gel(F,1);
-    E = gel(F,2); l = lg(P);
-    for (i=1; i<l; i++) gel(P,i) = u_euler_sumdivk(P[i], E[i], k);
+    v = usumdivk_fact(F,k);
   }
   else
-    P = sumdivk_aux(absi_factor(n), k);
-  P = ZV_prod(P);
-  if (k1 > 0) return gerepileuptoint(av, P);
-  return gerepileupto(av, gdiv(P, powiu(n,k)));
+    v = sumdivk_aux(absi_factor(n), k);
+  if (k1 > 0) return gerepileuptoint(av, v);
+  return gerepileupto(av, gdiv(v, powiu(n,k)));
 }
 
-/* K t_VECSMALL of k >= 0 */
 GEN
-usumdivkvec(ulong n, GEN K)
+usumdiv_fact(GEN f)
 {
-  pari_sp av = avma;
-  GEN F = factoru(n), P = gel(F,1), E = gel(F,2), Z, S;
-  long i,j, l = lg(P), lK = lg(K);
-  Z = cgetg(l, t_VEC);
-  S = cgetg(lK, t_VEC);
-  for (j=1; j<lK; j++)
-  {
-    long k = K[j];
-    for (i=1; i<l; i++) gel(Z,i) = u_euler_sumdivk(P[i], E[i], k);
-    gel(S,j) = ZV_prod(Z);
-  }
-  return gerepilecopy(av, S);
+  GEN P = gel(f,1), E = gel(f,2);
+  long i, l = lg(P);
+  GEN v = cgetg(l, t_VEC);
+  for (i=1; i<l; i++) gel(v,i) = u_euler_sumdiv(P[i],E[i]);
+  return ZV_prod(v);
+}
+GEN
+usumdivk_fact(GEN f, ulong k)
+{
+  GEN P = gel(f,1), E = gel(f,2);
+  long i, l = lg(P);
+  GEN v = cgetg(l, t_VEC);
+  for (i=1; i<l; i++) gel(v,i) = euler_sumdiv(powuu(P[i],k),E[i]);
+  return ZV_prod(v);
 }
 
 long
@@ -1490,24 +1482,48 @@ digits(GEN x, GEN B)
     (void)new_chunk(3*lz); /* HACK */
     z = zero_zv(lz);
     digits_dacsmall(x,vB,lz,(ulong*)(z+1));
-    avma = av; return vecsmall_to_vec(z);
+    avma = av; return Flv_to_ZV(z);
   }
 }
 
+static GEN
+fromdigitsu_dac(GEN x, GEN vB, long i, long l)
+{
+  GEN a, b;
+  long m = l>>1;
+  if (l==1) return utoi(uel(x,i));
+  if (l==2) return addumului(uel(x,i), uel(x,i+1), gel(vB, m));
+  a = fromdigitsu_dac(x, vB, i, m);
+  b = fromdigitsu_dac(x, vB, i+m, l-m);
+  return addii(a, mulii(b, gel(vB, m)));
+}
+
+GEN
+fromdigitsu(GEN x, GEN B)
+{
+  pari_sp av = avma;
+  long n = lg(x)-1;
+  GEN vB, z;
+  if (n==0) return gen_0;
+  vB = get_vB(B, n, NULL, &Z_ring);
+  z = fromdigitsu_dac(x, vB, 1, n);
+  return gerepileuptoint(av, z);
+}
+
 GEN
 fromdigits(GEN x, GEN B)
 {
   pari_sp av = avma;
   if (typ(x)!=t_VEC || !RgV_is_ZV(x)) pari_err_TYPE("fromdigits",x);
+  if (lg(x)==1) return gen_0;
   B = check_basis(B);
-  if (lg(x)==1) { avma = av; return gen_0; }
   if (Z_ispow2(B))
     return fromdigits_2k(x, expi(B));
   x = vecreverse(x);
-  return gerepileupto(av, gen_fromdigits(x, B, NULL, &Z_ring));
+  return gerepileuptoint(av, gen_fromdigits(x, B, NULL, &Z_ring));
 }
 
-static ulong DS[] ={
+static const ulong digsum[] ={
   0,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,10,2,3,4,5,6,7,8,9,10,11,3,4,5,6,7,8,
   9,10,11,12,4,5,6,7,8,9,10,11,12,13,5,6,7,8,9,10,11,12,13,14,6,7,8,9,10,11,
   12,13,14,15,7,8,9,10,11,12,13,14,15,16,8,9,10,11,12,13,14,15,16,17,9,10,11,
@@ -1552,7 +1568,7 @@ ulong
 sumdigitsu(ulong n)
 {
   ulong s = 0;
-  while (n) { s += DS[n % 1000]; n /= 1000; }
+  while (n) { s += digsum[n % 1000]; n /= 1000; }
   return s;
 }
 
diff --git a/src/basemath/base1.c b/src/basemath/base1.c
index c468801..0854ab3 100644
--- a/src/basemath/base1.c
+++ b/src/basemath/base1.c
@@ -340,7 +340,7 @@ GEN
 ZX_primitive_to_monic(GEN pol, GEN *pL)
 {
   long i,j, n = degpol(pol);
-  GEN lc = leading_term(pol), L, fa, P, E, a, POL;
+  GEN lc = leading_coeff(pol), L, fa, P, E, a, POL;
 
   if (is_pm1(lc))
   {
@@ -1619,28 +1619,31 @@ nfbasic_to_nf(nfbasic_t *T, GEN ro, long prec)
 static GEN
 primes_certify(GEN dK, GEN dKP)
 {
-  pari_sp av = avma;
   long i, l = lg(dKP);
-  GEN v, D = dK;
+  GEN v, w, D = dK;
   v = vectrunc_init(l);
+  w = vectrunc_init(l);
   for (i = 1; i < l; i++)
   {
     GEN p = gel(dKP,i);
-    if (!isprime(p)) vectrunc_append(v, p);
+    vectrunc_append(isprime(p)? w: v, p);
     (void)Z_pvalrem(D, p, &D);
   }
   if (!is_pm1(D))
   {
     if (signe(D) < 0) D = negi(D);
-    if (!isprime(D)) vectrunc_append(v, D);
+    vectrunc_append(isprime(D)? w: v, D);
   }
-  fixlg(v, lg(v)); return gerepilecopy(av, v);
+  return mkvec2(v,w);
 }
 GEN
 nfcertify(GEN nf)
 {
+  pari_sp av = avma;
+  GEN vw;
   nf = checknf(nf);
-  return primes_certify(nf_get_disc(nf), nf_get_ramified_primes(nf));
+  vw = primes_certify(nf_get_disc(nf), nf_get_ramified_primes(nf));
+  return gerepilecopy(av, gel(vw,1));
 }
 
 #if 0 /* used to check benches between HNF nf.zk and LLL-reduced nf.zk */
@@ -1949,58 +1952,72 @@ nfbasic_init(GEN x, long flag, nfbasic_t *T)
   T->index = index;
 }
 
-/* Initialize the number field defined by the polynomial x (in variable v)
- * flag & nf_RED:     try a polred first.
- * flag & nf_ORIG
- *    do a polred and return [nfinit(x), Mod(a,red)], where
- *    Mod(a,red) = Mod(v,x) (i.e return the base change). */
+void
+nfinit_step1(nfbasic_t *T, GEN x, long flag)
+{
+  nfbasic_init(x, flag, T);
+  if (!ZX_is_irred(T->x)) pari_err_IRREDPOL("nfinit",x);
+}
+
 GEN
-nfinitall(GEN x, long flag, long prec)
+nfinit_step2(nfbasic_t *T, long flag, long prec)
 {
-  const pari_sp av = avma;
   GEN nf, unscale;
-  nfbasic_t T;
 
-  if (checkrnf_i(x)) return check_and_build_nfabs(x, prec);
-  nfbasic_init(x, flag, &T);
-  if (!ZX_is_irred(T.x)) pari_err_IRREDPOL("nfinit",x);
-  if (!equali1(leading_term(T.x0)) && !(flag & nf_RED))
+  if (!(flag & nf_RED) && !equali1(leading_coeff(T->x0)))
   {
     pari_warn(warner,"non-monic polynomial. Result of the form [nf,c]");
     flag |= nf_RED | nf_ORIG;
   }
-  unscale = T.unscale;
+  unscale = T->unscale;
   if (!(flag & nf_RED) && !isint1(unscale))
   { /* implies lc(x0) = 1 and L := 1/unscale is integral */
-    long d = degpol(T.x0);
+    long d = degpol(T->x0);
     GEN L = ginv(unscale); /* x = L^(-deg(x)) x0(L X) */
     GEN f= powiu(L, (d*(d-1)) >> 1);
-    T.x = T.x0; /* restore original user-supplied x0, unscale data */
-    T.unscale = gen_1;
-    T.dx    = gmul(T.dx, sqri(f));
-    T.bas   = RgXV_unscale(T.bas, unscale);
-    T.index = gmul(T.index, f);
+    T->x = T->x0; /* restore original user-supplied x0, unscale data */
+    T->unscale = gen_1;
+    T->dx    = gmul(T->dx, sqri(f));
+    T->bas   = RgXV_unscale(T->bas, unscale);
+    T->index = gmul(T->index, f);
   }
-  nfbasic_add_disc(&T); /* more expensive after set_LLL_basis */
+  nfbasic_add_disc(T); /* more expensive after set_LLL_basis */
   if (flag & nf_RED)
   {
     GEN ro, rev;
     /* lie to polred: more efficient to update *after* modreverse, than to
      * unscale in the polred subsystem */
-    T.unscale = gen_1;
-    rev = nfpolred(&T, &ro);
-    nf = nfbasic_to_nf(&T, ro, prec);
+    T->unscale = gen_1;
+    rev = nfpolred(T, &ro);
+    nf = nfbasic_to_nf(T, ro, prec);
     if (flag & nf_ORIG)
     {
-      if (!rev) rev = pol_x(varn(T.x)); /* no improvement */
+      if (!rev) rev = pol_x(varn(T->x)); /* no improvement */
       if (!isint1(unscale)) rev = RgX_Rg_div(rev, unscale);
-      nf = mkvec2(nf, mkpolmod(rev, T.x));
+      nf = mkvec2(nf, mkpolmod(rev, T->x));
     }
-    T.unscale = unscale; /* restore */
+    T->unscale = unscale; /* restore */
   } else {
-    GEN ro; set_LLL_basis(&T, &ro, 0.99);
-    nf = nfbasic_to_nf(&T, ro, prec);
+    GEN ro; set_LLL_basis(T, &ro, 0.99);
+    nf = nfbasic_to_nf(T, ro, prec);
   }
+  return nf;
+}
+/* Initialize the number field defined by the polynomial x (in variable v)
+ * flag & nf_RED:     try a polred first.
+ * flag & nf_ORIG
+ *    do a polred and return [nfinit(x), Mod(a,red)], where
+ *    Mod(a,red) = Mod(v,x) (i.e return the base change). */
+GEN
+nfinitall(GEN x, long flag, long prec)
+{
+  const pari_sp av = avma;
+  nfbasic_t T;
+  GEN nf;
+
+  if (checkrnf_i(x)) return check_and_build_nfabs(x, prec);
+  nfinit_step1(&T, x, flag);
+  nf = nfinit_step2(&T, flag, prec);
   return gerepilecopy(av, nf);
 }
 
@@ -2265,10 +2282,9 @@ remove_duplicates(GEN P, GEN A)
       k++;
       x = gel(P,i); a = gel(A,i);
     }
-  gel(A,k) = a;
-  gel(P,k) = x;
-  l = k+1; setlg(A,l); setlg(P,l);
-  avma = av;
+  l = k+1;
+  gel(A,k) = a; setlg(A,l);
+  gel(P,k) = x; setlg(P,l); avma = av;
 }
 
 static long
@@ -2491,7 +2507,7 @@ polredord(GEN x)
   x = Q_primpart(x); RgX_check_ZX(x,"polredord");
   n = degpol(x); if (n <= 0) pari_err_CONSTPOL("polredord");
   if (n == 1) return gerepilecopy(av, mkvec(x));
-  lt = leading_term(x); vx = varn(x);
+  lt = leading_coeff(x); vx = varn(x);
   if (is_pm1(lt))
   {
     if (signe(lt) < 0) x = ZX_neg(x);
@@ -2753,7 +2769,7 @@ polredabs0(GEN x, long flag)
   GEN y, a, u;
   nfbasic_t T;
 
-  nfbasic_init(x, flag & nf_PARTIALFACT, &T);
+  nfbasic_init(x, nf_PARTIALFACT, &T);
   x = T.x; vx = varn(x);
 
   if (degpol(x) == 1)
@@ -2766,8 +2782,18 @@ polredabs0(GEN x, long flag)
   else
   {
     GEN v;
-    if (!(flag & nf_PARTIALFACT)
-        && T.dKP && lg(primes_certify(T.dK, T.dKP)) != 1) return gen_0;
+    if (!(flag & nf_PARTIALFACT) && T.dKP)
+    {
+      GEN vw = primes_certify(T.dK, T.dKP);
+      v = gel(vw,1); l = lg(v);
+      if (l != 1)
+      { /* fix integral basis */
+        GEN w = gel(vw,2);
+        for (i = 1; i < l; i++)
+          w = ZV_union_shallow(w, gel(Z_factor(gel(v,i)),1));
+        nfbasic_init(mkvec2(x,w), 0, &T);
+      }
+    }
     v = polredabs_aux(&T, &u);
     y = gel(v,1);
     a = gel(v,2); l = lg(a);
diff --git a/src/basemath/base2.c b/src/basemath/base2.c
index 42ca8ed..60ca920 100644
--- a/src/basemath/base2.c
+++ b/src/basemath/base2.c
@@ -89,7 +89,7 @@ set_disc(nfmaxord_t *S)
   long d;
   if (S->T0 == S->T) return ZX_disc(S->T);
   d = degpol(S->T0);
-  l0 = leading_term(S->T0);
+  l0 = leading_coeff(S->T0);
   L = S->unscale;
   if (typ(L) == t_FRAC && absi_cmp(gel(L,1), gel(L,2)) < 0)
     dT = ZX_disc(S->T); /* more efficient */
@@ -660,13 +660,13 @@ get_maxord(nfmaxord_t *S, GEN T0, long flag)
     if (E[i] <= 1) { O = shallowconcat(O, gen_1); continue; }
     av = avma;
     pari_CATCH(CATCH_ALL) {
-      GEN N, u, ERR = pari_err_last();
+      GEN N, u, err = pari_err_last();
       long l;
-      switch(err_get_num(ERR))
+      switch(err_get_num(err))
       {
         case e_INV:
         {
-          GEN p, x = err_get_compo(ERR, 2);
+          GEN p, x = err_get_compo(err, 2);
           if (typ(x) == t_INTMOD)
           { /* caught false prime, update factorization */
             p = gcdii(gel(x,1), gel(x,2));
@@ -700,7 +700,7 @@ get_maxord(nfmaxord_t *S, GEN T0, long flag)
           }
           break;
         }
-        default: pari_err(0, ERR);
+        default: pari_err(0, err);
           return NULL;
       }
       l = lg(u);
@@ -1620,10 +1620,10 @@ getprime(decomp_t *S, GEN phi, GEN chip, GEN nup, long *Lp, long *Ep,
   GEN z, chin, q, qp;
   long r, s;
 
-  if (phi && dvdii(constant_term(chip), S->psc))
+  if (phi && dvdii(constant_coeff(chip), S->psc))
   {
     chip = mycaract(S, S->chi, phi, S->pmf, S->prc);
-    if (dvdii(constant_term(chip), S->pmf))
+    if (dvdii(constant_coeff(chip), S->pmf))
       chip = ZXQ_charpoly(phi, S->chi, varn(chip));
   }
   if (degpol(nup) == 1)
@@ -3039,7 +3039,7 @@ rnfdedekind_i(GEN nf, GEN P, GEN pr, long vdisc, long only_maximal)
 
   if (vdisc < 0) pari_err_TYPE("rnfdedekind [non integral pol]", P);
   if (vdisc == 1) return NULL; /* pr-maximal */
-  if (!only_maximal && !gequal1(leading_term(P)))
+  if (!only_maximal && !gequal1(leading_coeff(P)))
     pari_err_IMPL( "the full Dedekind criterion in the non-monic case");
   /* either monic OR only_maximal = 1 */
   m = degpol(P);
@@ -3091,7 +3091,7 @@ rnfdedekind_i(GEN nf, GEN P, GEN pr, long vdisc, long only_maximal)
       break;
   }
   k = nfX_to_FqX(k, nf, modpr);
-  k  = FqX_normalize(FqX_gcd(FqX_gcd(g,h,  T,p), k, T,p), T,p);
+  k = FqX_normalize(FqX_gcd(FqX_gcd(g,h,  T,p), k, T,p), T,p);
   d = degpol(k);  /* <= m */
   if (!d) return NULL; /* pr-maximal */
   if (only_maximal) return gen_0; /* not maximal */
@@ -3423,7 +3423,7 @@ rnfallbase(GEN nf, GEN *ppol, GEN *pD, GEN *pd, GEN *pf)
 
   nf = checknf(nf); nfT = nf_get_pol(nf);
   pol = RgX_nffix("rnfallbase", nfT,pol,0);
-  if (!gequal1(leading_term(pol)))
+  if (!gequal1(leading_coeff(pol)))
     pari_err_IMPL("non-monic relative polynomials");
 
   n = degpol(pol);
@@ -3753,7 +3753,11 @@ nfcompositum(GEN nf, GEN A, GEN B, long flag)
   if (degpol(A)<=0 || degpol(B)<=0) pari_err_CONSTPOL("polcompositum");
   v = varn(A);
   if (varn(B) != v) pari_err_VAR("polcompositum", A,B);
-  if (nf && v == varn(nf_get_pol(nf))) pari_err_PRIORITY("polcompositum", nf, "==",  v);
+  if (nf)
+  {
+    nf = checknf(nf);
+    if (v == nf_get_varn(nf)) pari_err_PRIORITY("polcompositum", nf, "==",  v);
+  }
   same = (A == B || RgX_equal(A,B));
   A = compositum_fix(nf,A);
   if (!same) B = compositum_fix(nf,B);
@@ -3859,7 +3863,7 @@ nfsplitting(GEN T, GEN D)
   d = degpol(T);
   if (d<=1) return pol_x(0);
   if (!K) {
-    if (!isint1(leading_term(T))) K = T = polredbest(T,0);
+    if (!isint1(leading_coeff(T))) K = T = polredbest(T,0);
     K = T;
   }
   if (D)
@@ -3882,6 +3886,11 @@ nfsplitting(GEN T, GEN D)
     F = rnfequation(K,Q);
     if (degpol(F) == d) break;
   }
+  if (umodiu(D,degpol(F)))
+  {
+    char *sD = itostr(D);
+    pari_warn(warner,stack_strcat("ignoring incorrect degree bound ",sD));
+  }
   (void)delete_var();
   setvarn(F,v);
   return gerepilecopy(av, F);
diff --git a/src/basemath/base5.c b/src/basemath/base5.c
index 869dcdb..0b3a861 100644
--- a/src/basemath/base5.c
+++ b/src/basemath/base5.c
@@ -71,10 +71,10 @@ rnfeltreltoabs(GEN rnf,GEN x)
       }
       x = polmod_nffix(f,rnf,x,0);
       if (typ(x) == t_POLMOD) return rnfeltup(rnf,x);
-      retmkpolmod(eltreltoabs(rnf_get_map(rnf), x), RgX_copy(pol));
+      retmkpolmod(eltreltoabs(rnf_get_map(rnf), x), ZX_copy(pol));
     case t_POL:
       if (varn(x) == rnf_get_nfvarn(rnf)) return rnfeltup(rnf,x);
-      retmkpolmod(eltreltoabs(rnf_get_map(rnf), x), RgX_copy(pol));
+      retmkpolmod(eltreltoabs(rnf_get_map(rnf), x), ZX_copy(pol));
   }
   pari_err_TYPE(f,x); return NULL;
 }
@@ -103,10 +103,11 @@ rnfeltabstorel(GEN rnf,GEN x)
 {
   const char *f = "rnfeltabstorel";
   pari_sp av = avma;
-  GEN pol, T, P;
+  GEN pol, T, P, NF;
   checkrnf(rnf);
   T = rnf_get_nfpol(rnf);
   P = rnf_get_pol(rnf);
+  pol = rnf_get_polabs(rnf);
   switch(typ(x))
   {
     case t_INT: return icopy(x);
@@ -115,27 +116,28 @@ rnfeltabstorel(GEN rnf,GEN x)
       if (RgX_equal_var(P, gel(x,1)))
       {
         x = polmod_nffix(f, rnf, x, 0);
+        P = QXQX_to_mod_shallow(P,T);
         return gerepilecopy(av, mkpolmod(x,P));
       }
       if (RgX_equal_var(T, gel(x,1))) { x = Rg_nffix(f, T, x, 0); goto END; }
-      pol = rnf_get_polabs(rnf);
       if (!RgX_equal_var(pol, gel(x,1))) pari_err_MODULUS(f, gel(x,1),pol);
-      x = gel(x,2);
-      switch(typ(x))
-      {
-        case t_INT: return icopy(x);
-        case t_FRAC: return gcopy(x);
-        case t_POL: break;
-        default: pari_err_TYPE(f, x);
-      }
-      break;
-    case t_POL:
-      pol = rnf_get_polabs(rnf);
-      break;
+      x = gel(x,2); break;
+    case t_POL: break;
+    case t_COL:
+      NF = obj_check(rnf, rnf_NFABS);
+      if (!NF) pari_err_TYPE("rnfeltabstorel, apply nfinit(rnf)",x);
+      x = nf_to_scalar_or_alg(NF,x); break;
     default:
       pari_err_TYPE(f,x);
       return NULL;
   }
+  switch(typ(x))
+  {
+    case t_INT: return icopy(x);
+    case t_FRAC: return gcopy(x);
+    case t_POL: break;
+    default: pari_err_TYPE(f, x);
+  }
   if (!RgX_is_QX(x)) pari_err_TYPE(f,x);
   if (varn(x) != varn(pol))
   {
@@ -208,13 +210,11 @@ rnf_basM(GEN rnf)
   return M;
 }
 
-const long NFABS = 1;
-
 static GEN
-rnfnfabs(GEN rnf, long prec)
+mknfabs(GEN rnf, long prec)
 {
   GEN nf, pol, bas;
-  if ((nf = obj_check(rnf,NFABS)))
+  if ((nf = obj_check(rnf,rnf_NFABS)))
   {
     if (nf_get_prec(nf) < prec) nf = nfnewprec_shallow(nf,prec);
     return nf;
@@ -225,9 +225,34 @@ rnfnfabs(GEN rnf, long prec)
   return nfinit(mkvec2(pol, bas), nf_get_prec(nf));
 }
 
+static GEN
+mkupdown(GEN rnf)
+{
+  GEN NF = obj_check(rnf, rnf_NFABS), M, zknf, czknf;
+  long i, m;
+  rnf_get_nfzk(rnf, &zknf, &czknf);
+  if (isint1(czknf)) czknf = NULL;
+  m = lg(zknf)-1; M = cgetg(m+1, t_MAT);
+  gel(M,1) = vec_ei(nf_get_degree(NF), 1);
+  for (i = 2; i <= m; i++)
+  {
+    GEN c = poltobasis(NF, gel(zknf,i));
+    if (czknf) c = gmul(c, czknf);
+    gel(M,i) = c;
+  }
+  return Qevproj_init(M);
+}
 GEN
 check_and_build_nfabs(GEN rnf, long prec)
-{ return obj_checkbuild_prec(rnf, NFABS, &rnfnfabs, &nf_get_prec, prec); }
+{
+  GEN NF = obj_checkbuild_prec(rnf, rnf_NFABS, &mknfabs, &nf_get_prec, prec);
+  (void)obj_checkbuild(rnf, rnf_MAPS, &mkupdown);
+  return NF;
+}
+
+void
+rnfcomplete(GEN rnf)
+{ (void)check_and_build_nfabs(rnf, nf_get_prec(rnf_get_nf(rnf))); }
 
 void
 nf_nfzk(GEN nf, GEN rnfeq, GEN *zknf, GEN *czknf)
@@ -239,19 +264,19 @@ nf_nfzk(GEN nf, GEN rnfeq, GEN *zknf, GEN *czknf)
 }
 
 GEN
-rnfinit(GEN nf, GEN polrel)
+rnfinit0(GEN nf, GEN polrel, long flag)
 {
   pari_sp av = avma;
-  GEN rnf, bas, D,d,f, B, rnfeq, basnf,cobasnf;
+  GEN rnf, bas, D,d,f, B, rnfeq, zknf,czknf;
   nf = checknf(nf);
   bas = rnfallbase(nf,&polrel, &D,&d, &f);
   B = matbasistoalg(nf,gel(bas,1));
   gel(bas,1) = lift_if_rational( RgM_to_RgXV(B,varn(polrel)) );
   rnfeq = nf_rnfeq(nf,polrel);
-  nf_nfzk(nf, rnfeq, &basnf, &cobasnf);
-  rnf = obj_init(11, 1);
+  nf_nfzk(nf, rnfeq, &zknf, &czknf);
+  rnf = obj_init(11, 2);
   gel(rnf,1) = polrel;
-  gel(rnf,2) = mkvec2(basnf, cobasnf);
+  gel(rnf,2) = mkvec2(zknf, czknf);
   gel(rnf,3) = mkvec2(D, d);
   gel(rnf,4) = f;
   gel(rnf,5) = cgetg(1, t_VEC); /* dummy */
@@ -261,22 +286,56 @@ rnfinit(GEN nf, GEN polrel)
   gel(rnf,9) = typ(f) == t_INT? gen_1: RgM_det_triangular(f);
   gel(rnf,10)= nf;
   gel(rnf,11)= rnfeq;
-  return gerepilecopy(av, rnf);
+  rnf = gerepilecopy(av, rnf);
+  if (flag) rnfcomplete(rnf);
+  return rnf;
 }
+GEN
+rnfinit(GEN nf, GEN T) { return rnfinit0(nf,T,0); }
 
 GEN
-rnfeltup(GEN rnf, GEN x)
+rnfeltup0(GEN rnf, GEN x, long flag)
 {
   pari_sp av = avma;
-  GEN zknf, czknf;
+  GEN zknf, czknf, nf, NF, POL;
+  long tx = typ(x);
   checkrnf(rnf);
-  if (typ(x) == t_POLMOD && RgX_equal_var(gel(x,1), rnf_get_polabs(rnf)))
-    return gcopy(x);
-  rnf_get_nfzk(rnf, &zknf, &czknf);
-  x = nfeltup(rnf_get_nf(rnf), x, zknf, czknf);
-  if (typ(x) == t_POL) x = mkpolmod(x, rnf_get_polabs(rnf));
+  if (flag) rnfcomplete(rnf);
+  NF = obj_check(rnf,rnf_NFABS);
+  POL = rnf_get_polabs(rnf);
+  if (tx == t_POLMOD && RgX_equal_var(gel(x,1), POL))
+  {
+    if (flag) x = nf_to_scalar_or_basis(NF,x);
+    return gerepilecopy(av, x);
+  }
+  if (NF && tx == t_COL && lg(x)-1 == nf_get_degree(NF))
+  {
+    x = flag? nf_to_scalar_or_basis(NF,x)
+            : mkpolmod(nf_to_scalar_or_alg(NF,x), POL);
+    return gerepilecopy(av, x);
+  }
+  nf = rnf_get_nf(rnf);
+  if (NF)
+  {
+    GEN d, proj;
+    x = nf_to_scalar_or_basis(nf, x);
+    if (typ(x) != t_COL) return gerepilecopy(av, x);
+    proj = obj_check(rnf,rnf_MAPS);
+    x = Q_remove_denom(x,&d);
+    x = ZM_ZC_mul(gel(proj,1), x);
+    if (d) x = gdiv(x,d);
+    if (!flag) x = basistoalg(NF,x);
+  }
+  else
+  {
+    rnf_get_nfzk(rnf, &zknf, &czknf);
+    x = nfeltup(nf, x, zknf, czknf);
+    if (typ(x) == t_POL) x = mkpolmod(x, POL);
+  }
   return gerepilecopy(av, x);
 }
+GEN
+rnfeltup(GEN rnf, GEN x) { return rnfeltup0(rnf,x,0); }
 
 GEN
 nfeltup(GEN nf, GEN x, GEN zknf, GEN czknf)
@@ -294,34 +353,82 @@ nfeltup(GEN nf, GEN x, GEN zknf, GEN czknf)
 static void
 fail(const char *f, GEN x)
 { pari_err_DOMAIN(f,"element","not in", strtoGENstr("the base field"),x); }
+/* x t_COL of length degabs */
+static GEN
+eltdown(GEN rnf, GEN x, long flag)
+{
+  GEN z,y, d, proj = obj_check(rnf,rnf_MAPS);
+  GEN M= gel(proj,1), iM=gel(proj,2), diM=gel(proj,3), perm=gel(proj,4);
+  x = Q_remove_denom(x,&d);
+  if (!RgV_is_ZV(x)) pari_err_TYPE("rnfeltdown", x);
+  y = ZM_ZC_mul(iM, vecpermute(x, perm));
+  z = ZM_ZC_mul(M,y);
+  if (!isint1(diM)) z = ZC_Z_mul(z,diM);
+  if (!ZV_equal(z,x)) fail("rnfeltdown",x);
+
+  d = mul_denom(d, diM);
+  if (d) y = gdiv(y,d);
+  if (!flag) y = basistoalg(rnf_get_nf(rnf), y);
+  return y;
+}
 GEN
-rnfeltdown(GEN rnf,GEN x)
+rnfeltdown0(GEN rnf, GEN x, long flag)
 {
   const char *f = "rnfeltdown";
   pari_sp av = avma;
-  GEN z, T;
+  GEN z, T, NF, nf;
   long v;
 
   checkrnf(rnf);
-  T = rnf_get_nfpol(rnf);
+  NF = obj_check(rnf,rnf_NFABS);
+  nf = rnf_get_nf(rnf);
+  T = nf_get_pol(nf);
   v = varn(T);
   switch(typ(x))
   { /* directly belonging to base field ? */
     case t_INT: return icopy(x);
     case t_FRAC:return gcopy(x);
     case t_POLMOD:
-      if (RgX_equal_var(gel(x,1), rnf_get_polabs(rnf))) break;
+      if (RgX_equal_var(gel(x,1), rnf_get_polabs(rnf)))
+      {
+        if (degpol(T) == 1)
+        {
+          x = simplify_shallow(liftpol_shallow(gel(x,2)));
+          if (typ(x) != t_POL) return gerepilecopy(av,x);
+        }
+        break;
+      }
       x = polmod_nffix(f,rnf,x,0);
       /* x was defined mod the relative polynomial & non constant => fail */
       if (typ(x) == t_POL) fail(f,x);
+      if (flag) x = nf_to_scalar_or_basis(nf,x);
       return gerepilecopy(av, x);
 
     case t_POL:
       if (varn(x) != v) break;
       x = Rg_nffix(f,T,x,0);
+      if (flag) x = nf_to_scalar_or_basis(nf,x);
       return gerepilecopy(av, x);
+    case t_COL:
+    {
+      long n = lg(x)-1;
+      if (n == degpol(T) && RgV_is_QV(x))
+      {
+        if (RgV_isscalar(x)) return gcopy(gel(x,1));
+        if (!flag) return gcopy(x);
+        return basistoalg(nf,x);
+      }
+      if (NF) break;
+    }
+    default: pari_err_TYPE(f, x);
   }
   /* x defined mod the absolute equation */
+  if (NF)
+  {
+    x = nf_to_scalar_or_basis(NF, x);
+    if (typ(x) == t_COL) x = eltdown(rnf,x,flag);
+    return gerepilecopy(av, x);
+  }
   z = rnfeltabstorel(rnf,x);
   switch(typ(z))
   {
@@ -337,6 +444,8 @@ rnfeltdown(GEN rnf,GEN x)
   }
   return gerepilecopy(av, z);
 }
+GEN
+rnfeltdown(GEN rnf, GEN x) { return rnfeltdown0(rnf,x,0); }
 
 /* vector of rnf elt -> matrix of nf elts */
 static GEN
@@ -360,7 +469,7 @@ rnfprincipaltohnf(GEN rnf,GEN x)
 
 /* pseudo-basis for the 0 ideal */
 static GEN
-rnfideal0() { retmkvec2(cgetg(1,t_MAT),cgetg(1,t_VEC)); }
+rnfideal0(void) { retmkvec2(cgetg(1,t_MAT),cgetg(1,t_VEC)); }
 
 GEN
 rnfidealhnf(GEN rnf, GEN x)
@@ -378,6 +487,7 @@ rnfidealhnf(GEN rnf, GEN x)
 
     case t_VEC:
       if (lg(x) == 3 && typ(gel(x,1)) == t_MAT) return nfhnf(nf, x);
+    case t_MAT:
       return rnfidealabstorel(rnf, x);
 
     case t_POLMOD: case t_POL: case t_COL:
@@ -429,29 +539,48 @@ rnfidealnormabs(GEN rnf, GEN id)
   return gerepileupto(av, gmul(z, gel(rnf,9)));
 }
 
-GEN
-rnfidealreltoabs(GEN rnf,GEN x)
+static GEN
+rnfidealreltoabs_i(GEN rnf, GEN x)
 {
-  pari_sp av = avma;
   long i, l;
   GEN w;
-
   x = rnfidealhnf(rnf,x);
   w = gel(x,1); l = lg(w); settyp(w, t_VEC);
   for (i=1; i<l; i++) gel(w,i) = lift_intern( rnfbasistoalg(rnf, gel(w,i)) );
+  return modulereltoabs(rnf, x);
+}
+GEN
+rnfidealreltoabs(GEN rnf, GEN x)
+{
+  pari_sp av = avma; x = rnfidealreltoabs_i(rnf,x);
   return gerepilecopy(av, modulereltoabs(rnf, x));
 }
+GEN
+rnfidealreltoabs0(GEN rnf, GEN x, long flag)
+{
+  pari_sp av = avma;
+  long i, l;
+  GEN NF;
+
+  x = rnfidealreltoabs_i(rnf, x);
+  if (!flag) return gerepilecopy(av,x);
+  rnfcomplete(rnf);
+  NF = obj_check(rnf,rnf_NFABS);
+  l = lg(x); settyp(x, t_MAT);
+  for (i=1; i<l; i++) gel(x,i) = algtobasis(NF, gel(x,i));
+  return gerepileupto(av, idealhnf(NF,x));
+}
 
 GEN
 rnfidealabstorel(GEN rnf, GEN x)
 {
-  long N, j;
+  long N, j, tx = typ(x);
   pari_sp av = avma;
   GEN A, I, invbas;
 
   checkrnf(rnf);
   invbas = rnf_get_invzk(rnf);
-  if (typ(x) != t_VEC) pari_err_TYPE("rnfidealabstorel",x);
+  if (tx != t_VEC && tx != t_MAT) pari_err_TYPE("rnfidealabstorel",x);
   N = lg(x)-1;
   if (N != rnf_get_absdegree(rnf))
   {
@@ -474,6 +603,28 @@ rnfidealdown(GEN rnf,GEN x)
 {
   pari_sp av = avma;
   GEN I;
+  if (typ(x) == t_MAT)
+  {
+    GEN d;
+    x = Q_remove_denom(x,&d);
+    if (RgM_is_ZM(x))
+    {
+      GEN NF = obj_check(rnf,rnf_NFABS);
+      if (NF)
+      {
+        GEN z, proj = obj_check(rnf,rnf_MAPS), ZK = gel(proj,1);
+        long i, lz, l;
+        x = idealhnf(NF,x);
+        if (lg(x) == 1) { avma = av; return cgetg(1,t_MAT); }
+        z = ZM_lll(shallowconcat(ZK,x), 0.99, LLL_KER);
+        lz = lg(z); l = lg(ZK);
+        for (i = 1; i < lz; i++) setlg(gel(z,i), l);
+        z = ZM_hnfmodid(z, gcoeff(x,1,1));
+        if (d) z = gdiv(z,d);
+        return gerepileupto(av, z);
+      }
+    }
+  }
   x = rnfidealhnf(rnf,x); I = gel(x,2);
   if (lg(I) == 1) { avma = av; return cgetg(1,t_MAT); }
   return gerepilecopy(av, gel(I,1));
@@ -485,17 +636,50 @@ rnfidealup(GEN rnf,GEN x)
 {
   pari_sp av = avma;
   long i, n;
-  GEN nf, bas, bas2, I;
+  GEN nf, bas, bas2, I, x2;
 
   checkrnf(rnf); nf = rnf_get_nf(rnf);
   n = rnf_get_degree(rnf);
   bas = rnf_get_zk(rnf); bas2 = gel(bas,2);
 
   (void)idealtyp(&x, &I); /* I is junk */
+  x2 = idealtwoelt(nf,x);
   I = cgetg(n+1,t_VEC);
-  for (i=1; i<=n; i++) gel(I,i) = idealmul(nf,x,gel(bas2,i));
+  for (i=1; i<=n; i++)
+  {
+    GEN c = gel(bas2,i), d;
+    if (typ(c) == t_MAT)
+    {
+      c = Q_remove_denom(c,&d);
+      c = idealmul_HNF(nf,c,x2);
+      if (d) c = gdiv(c,d);
+    }
+    else
+      c = idealmul(nf,c,x);
+    gel(I,i) = c;
+  }
   return gerepilecopy(av, modulereltoabs(rnf, mkvec2(gel(bas,1), I)));
 }
+GEN
+rnfidealup0(GEN rnf,GEN x, long flag)
+{
+  pari_sp av = avma;
+  GEN NF, nf, proj, d, x2;
+
+  if (!flag) return rnfidealup(rnf,x);
+  checkrnf(rnf); nf = rnf_get_nf(rnf);
+  rnfcomplete(rnf);
+  proj = obj_check(rnf,rnf_MAPS);
+  NF = obj_check(rnf,rnf_NFABS);
+
+  (void)idealtyp(&x, &d); /* d is junk */
+  x2 = idealtwoelt(nf,x);
+  x2 = Q_remove_denom(x2,&d);
+  gel(x2,2) = ZM_ZC_mul(gel(proj,1),gel(x2,2));
+  x2 = idealhnf_two(NF, x2);
+  if (d) x2 = gdiv(x2,d);
+  return gerepileupto(av, x2);
+}
 
 /* x a relative HNF => vector of 2 generators (relative polmods) */
 GEN
@@ -504,8 +688,9 @@ rnfidealtwoelement(GEN rnf, GEN x)
   pari_sp av = avma;
   GEN y, cy, z, NF;
 
-  y = rnfidealreltoabs(rnf,x);
-  NF = check_and_build_nfabs(rnf, nf_get_prec(rnf_get_nf(rnf)));
+  y = rnfidealreltoabs_i(rnf,x);
+  rnfcomplete(rnf);
+  NF = obj_check(rnf,rnf_NFABS);
   y = matalgtobasis(NF, y); settyp(y, t_MAT);
   y = Q_primitive_part(y, &cy);
   y = ZM_hnf(y);
@@ -535,6 +720,54 @@ rnfidealmul(GEN rnf,GEN x,GEN y)
   return gerepileupto(av, nfhnf(nf,z));
 }
 
+static GEN
+rnfidealprimedec_1(GEN rnf, GEN L, GEN SL, GEN prK)
+{
+  GEN v, piL = rnfeltup0(rnf, pr_get_gen(prK), 1);
+  long i, c, l;
+  if (typ(piL) != t_COL) return SL; /* p inert in K/Q */
+  v = cgetg_copy(SL, &l);
+  for (i = c = 1; i < l; i++)
+  {
+    GEN P = gel(SL,i);
+    if (ZC_prdvd(L, piL, P)) gel(v,c++) = P;
+  }
+  setlg(v, c); return v;
+}
+GEN
+rnfidealprimedec(GEN rnf, GEN pr)
+{
+  pari_sp av = avma;
+  GEN p, z, NF, nf, SL;
+  checkrnf(rnf);
+  rnfcomplete(rnf);
+  NF = obj_check(rnf,rnf_NFABS);
+  nf = rnf_get_nf(rnf);
+  if (typ(pr) == t_INT)
+  {
+    p = pr;
+    pr = NULL;
+  }
+  else
+  {
+    checkprid(pr);
+    p = pr_get_p(pr);
+  }
+  SL = idealprimedec(NF, p);
+  if (pr)
+    z = rnfidealprimedec_1(rnf, NF, SL, pr);
+  else
+  {
+    GEN vK = idealprimedec(nf, p), vL;
+    long l = lg(vK), i;
+    vL = cgetg(l, t_VEC);
+    for (i = 1; i < l; i++)
+      gel(vL,i) = rnfidealprimedec_1(rnf, NF, SL, gel(vK,i));
+    z = mkvec2(vK, vL);
+  }
+  return gerepilecopy(av, z);
+}
+
 GEN
 rnfequationall(GEN A, GEN B, long *pk, GEN *pLPRS)
 {
@@ -554,7 +787,7 @@ rnfequationall(GEN A, GEN B, long *pk, GEN *pLPRS)
     pari_err_DOMAIN("rnfequation","issquarefree(B)","=",gen_0,B);
 
   *pk = 0; C = ZX_ZXY_resultant_all(A, B, pk, pLPRS);
-  if (gsigne(leading_term(C)) < 0) C = RgX_neg(C);
+  if (gsigne(leading_coeff(C)) < 0) C = RgX_neg(C);
   *pk = -*pk; return Q_primpart(C);
 }
 
@@ -963,7 +1196,7 @@ rnfpolred(GEN nf, GEN pol, long prec)
     newpol = Q_primpart(newpol);
 
     (void)nfgcd_all(newpol, RgX_deriv(newpol), nfpol, nf_get_index(nf), &newpol);
-    L = leading_term(newpol);
+    L = leading_coeff(newpol);
     gel(w,j) = (typ(L) == t_POL)? RgXQX_div(newpol, L, nfpol)
                                 : RgX_Rg_div(newpol, L);
   }
diff --git a/src/basemath/bb_group.c b/src/basemath/bb_group.c
index 7eecd4d..441f1d3 100644
--- a/src/basemath/bb_group.c
+++ b/src/basemath/bb_group.c
@@ -125,7 +125,7 @@ leftright_binary_powu(GEN x, ulong n, void *E, GEN (*sqr)(void*,GEN),
   GEN  y;
   int j;
 
-  if (n == 1) return gcopy(x);
+  if (n == 1) return x;
   y = x; j = 1+bfffo(n);
   /* normalize, i.e set highest bit to 1 (we know n != 0) */
   n<<=j; j = BITS_IN_LONG-j;
@@ -148,7 +148,7 @@ gen_powu_i(GEN x, ulong n, void *E, GEN (*sqr)(void*,GEN),
                                     GEN (*mul)(void*,GEN,GEN))
 {
   long l;
-  if (n == 1) return gcopy(x);
+  if (n == 1) return x;
   l = expu(n);
   if (l<=8)
     return leftright_binary_powu(x, n, E, sqr, mul);
@@ -197,7 +197,7 @@ gen_powu_fold_i(GEN x, ulong n, void *E, GEN  (*sqr)(void*,GEN),
   GEN y;
   int j;
 
-  if (n == 1) return gcopy(x);
+  if (n == 1) return x;
   y = x; j = 1+bfffo(n);
   /* normalize, i.e set highest bit to 1 (we know n != 0) */
   n<<=j; j = BITS_IN_LONG-j;
@@ -235,11 +235,17 @@ gen_pow_fold_i(GEN x, GEN N, void *E, GEN (*sqr)(void*,GEN),
     GEN nd = int_MSW(N), y = x;
     ulong n = *nd;
     long i;
-    int j = 1+bfffo(n);
+    int j;
     pari_sp av = avma;
 
-    /* normalize, i.e set highest bit to 1 (we know n != 0) */
-    n<<=j; j = BITS_IN_LONG-j;
+    if (n == 1)
+      j = 0;
+    else
+    {
+      j = 1+bfffo(n); /* < BIL */
+      /* normalize, i.e set highest bit to 1 (we know n != 0) */
+      n <<= j; j = BITS_IN_LONG - j;
+    }
     /* first bit is now implicit */
     for (i=ln-2;;)
     {
@@ -291,15 +297,17 @@ gen_product(GEN x, void *data, GEN (*mul)(void *,GEN,GEN))
 {
   pari_sp ltop;
   long i,k,lx = lg(x);
+  pari_timer ti;
+  if (DEBUGLEVEL>7) timer_start(&ti);
 
   if (lx == 1) return gen_1;
   if (lx == 2) return gcopy(gel(x,1));
   x = leafcopy(x); k = lx;
-  ltop=avma;
+  ltop = avma;
   while (k > 2)
   {
     if (DEBUGLEVEL>7)
-      err_printf("prod: remaining objects %ld\n",k-1);
+      timer_printf(&ti,"gen_product: remaining objects %ld",k-1);
     lx = k; k = 1;
     for (i=1; i<lx-1; i+=2)
       gel(x,k++) = mul(data,gel(x,i),gel(x,i+1));
diff --git a/src/basemath/bibli1.c b/src/basemath/bibli1.c
index 23fa204..5259122 100644
--- a/src/basemath/bibli1.c
+++ b/src/basemath/bibli1.c
@@ -507,7 +507,7 @@ static void
 choose_params(GEN P, GEN N, GEN X, GEN B, long *pdelta, long *pt)
 {
   long d = degpol(P);
-  GEN P0 = leading_term(P);
+  GEN P0 = leading_coeff(P);
   double logN = gtodouble(glog(N, DEFAULTPREC));
   double tau, beta, rho;
   long delta, t;
@@ -879,7 +879,7 @@ algdep0(GEN x, long n, long bit)
     y = lindep2(y, bit);
   if (lg(y) == 1) pari_err(e_DOMAIN,"algdep", "degree(x)",">", stoi(n), x);
   y = RgV_to_RgX(y, 0);
-  if (signe(leading_term(y)) > 0) return gerepilecopy(av, y);
+  if (signe(leading_coeff(y)) > 0) return gerepilecopy(av, y);
   return gerepileupto(av, ZX_neg(y));
 }
 
diff --git a/src/basemath/bibli2.c b/src/basemath/bibli2.c
index 356179b..eba1dec 100644
--- a/src/basemath/bibli2.c
+++ b/src/basemath/bibli2.c
@@ -1673,9 +1673,12 @@ gen_cmp_RgX(void *data, GEN x, GEN y)
 static int
 cmp_RgX_Rg(GEN x, GEN y)
 {
-  long lx = lg(x);
-  if (lx > 3) return  1;
-  if (lx < 3) return -1;
+  long lx = lgpol(x), ly;
+  if (lx > 1) return  1;
+  ly = gequal0(y) ? 0:1;
+  if (lx > ly) return  1;
+  if (lx < ly) return -1;
+  if (lx==0) return 0;
   return gcmp(gel(x,2), y);
 }
 int
@@ -1692,6 +1695,16 @@ cmp_RgX(GEN x, GEN y)
   return gen_cmp_RgX((void*)&gcmp,x,y);
 }
 
+int
+cmp_Flx(GEN x, GEN y)
+{
+  long i, lx = lg(x), ly = lg(y);
+  if (lx > ly) return  1;
+  if (lx < ly) return -1;
+  for (i=lx-1; i>1; i--)
+    if (uel(x,i) != uel(y,i)) return uel(x,i)<uel(y,i)? -1: 1;
+  return 0;
+}
 /********************************************************************/
 /**                   MERGE & SORT FACTORIZATIONS                  **/
 /********************************************************************/
diff --git a/src/basemath/buch1.c b/src/basemath/buch1.c
index 86338db..9a6c4fd 100644
--- a/src/basemath/buch1.c
+++ b/src/basemath/buch1.c
@@ -327,7 +327,7 @@ compute_invresquad(GRHcheck_t *S)
   GEN invres = real_1(DEFAULTPREC);
   GRHprime_t *pr = S->primes;
   long i = S->nprimes, LIMC = GRH_last_prime(S)+diffptr[i]-1; /* nextprime(p+1)-1*/
-  double limp = log(LIMC) / 2;
+  double limp = log((double)LIMC) / 2;
   for (; i > 0; pr++, i--)
   {
     long s = (long)pr->dec;
@@ -402,8 +402,8 @@ quadGRHchk(GEN D, GRHcheck_t *S, ulong LIMC)
     if (M > 1)
     {
       double inv1_q = 1 / (1-q);
-      A *= (1 - pow(q, M)) * inv1_q;
-      B *= (1 - pow(q, M)*(M+1 - M*q)) * inv1_q * inv1_q;
+      A *= (1 - pow(q, (double) M)) * inv1_q;
+      B *= (1 - pow(q, (double) M)*(M+1 - M*q)) * inv1_q * inv1_q;
     }
     if ((long)pr->dec>0) { SA += 2*A;SB += 2*B; } else { SA += A; SB += B; }
   }
diff --git a/src/basemath/buch2.c b/src/basemath/buch2.c
index 4f5ea85..b1e73a3 100644
--- a/src/basemath/buch2.c
+++ b/src/basemath/buch2.c
@@ -477,7 +477,6 @@ get_fs(GEN nf, GEN P, GEN index, ulong p)
   { /* easy case: p does not divide index */
     GEN F = Flx_degfact(ZX_to_Flx(P,p), p);
     fs = gel(F,1); l = lg(fs);
-    ns = gel(F,2); /*to be overwritten*/
   }
   else
   {
@@ -485,8 +484,8 @@ get_fs(GEN nf, GEN P, GEN index, ulong p)
     l = lg(F);
     fs = cgetg(l, t_VECSMALL);
     for (j = 1; j < l; j++) fs[j] = pr_get_f(gel(F,j));
-    ns = cgetg(l, t_VECSMALL);
   }
+  ns = cgetg(l, t_VECSMALL);
   f = fs[1]; n = 1;
   for (j = 2, k = 1; j < l; j++)
     if (fs[j] == f)
@@ -547,12 +546,12 @@ tailresback(long LIMC, double LIMC2, double LIMC3, long R1, long R2, double rK,
 static double
 tailres(long R1, long R2, double al2K, double rKm, double rKM, double r1Km, double r1KM, double r2Km, double r2KM, long LIMC)
 {
-  const double logLIMC = log(LIMC), logLIMC2 = logLIMC*logLIMC;
+  const double logLIMC = log((double)LIMC), logLIMC2 = logLIMC*logLIMC;
   const double logLIMC3 = logLIMC*logLIMC2;
   const double E1 = rtodbl(eint1(dbltor(logLIMC/2), DEFAULTPREC));
   const double LIMC2 = LIMC*LIMC, LIMC3 = LIMC*LIMC2;
   return
-    al2K*((33*logLIMC2+22*logLIMC+8)/(8*logLIMC3*sqrt(LIMC))+15*E1/16)
+    al2K*((33*logLIMC2+22*logLIMC+8)/(8*logLIMC3*sqrt((double)LIMC))+15*E1/16)
      + maxdd(
             tailresback(LIMC,LIMC2,LIMC3,R1,R2,rKm,r1KM,r2Km,logLIMC,logLIMC2,logLIMC3),
             tailresback(LIMC,LIMC2,LIMC3,R1,R2,rKM,r1Km,r2KM,logLIMC,logLIMC2,logLIMC3)
@@ -629,10 +628,10 @@ compute_invres(GRHcheck_t *S, long LIMC)
   double loginvres = 0.;
   GRHprime_t *pr;
   long i;
-  double logLIMC = log(LIMC);
+  double logLIMC = log((double)LIMC);
   double logLIMC2 = logLIMC*logLIMC, denc;
   double c0, c1, c2;
-  denc = 1/(pow(LIMC, 3) * logLIMC * logLIMC2);
+  denc = 1/(pow((double)LIMC, 3.) * logLIMC * logLIMC2);
   c2 = (    logLIMC2 + 3 * logLIMC / 2 + 1) * denc;
   denc *= LIMC;
   c1 = (3 * logLIMC2 + 4 * logLIMC     + 2) * denc;
@@ -660,8 +659,8 @@ compute_invres(GRHcheck_t *S, long LIMC)
       loginvres += 1/(k * NPk);
     }
     addpsi = limp;
-    addpsi1 = p *(pow(p , limp)-1)/(p -1);
-    addpsi2 = p2*(pow(p2, limp)-1)/(p2-1);
+    addpsi1 = p *(pow((double)p , (double)limp)-1)/(p -1);
+    addpsi2 = p2*(pow((double)p2, (double)limp)-1)/(p2-1);
     j = lg(fs);
     while (--j > 0)
     {
@@ -669,7 +668,7 @@ compute_invres(GRHcheck_t *S, long LIMC)
       double NP, NP2, addinvres;
       f = fs[j]; if (f > limp) continue;
       nb = ns[j];
-      NP = pow(p, f);
+      NP = pow((double)p, (double)f);
       addinvres = 1/NP;
       kmax = limp / f;
       for (k = 2, NPk = NP; k <= kmax; k++)
@@ -680,8 +679,8 @@ compute_invres(GRHcheck_t *S, long LIMC)
       NP2 = NP*NP;
       loginvres -= nb * addinvres;
       addpsi -= nb * f * kmax;
-      addpsi1 -= nb*(f*NP *(pow(NP ,kmax)-1)/(NP -1));
-      addpsi2 -= nb*(f*NP2*(pow(NP2,kmax)-1)/(NP2-1));
+      addpsi1 -= nb*(f*NP *(pow(NP ,(double)kmax)-1)/(NP -1));
+      addpsi2 -= nb*(f*NP2*(pow(NP2,(double)kmax)-1)/(NP2-1));
     }
     loginvres -= (addpsi*c0 - addpsi1*c1 + addpsi2*c2)*logp;
   }
@@ -803,7 +802,7 @@ FBgen(FB_t *F, GEN nf, long N, ulong C1, ulong C2, GRHcheck_t *S)
 static int
 GRHchk(GEN nf, GRHcheck_t *S, ulong LIMC)
 {
-  double logC = log((ulong)LIMC), SA = 0, SB = 0;
+  double logC = log((double)LIMC), SA = 0, SB = 0;
   GRHprime_t *pr = S->primes;
 
   cache_prime_dec(S, LIMC, nf);
@@ -823,13 +822,13 @@ GRHchk(GEN nf, GRHcheck_t *S, ulong LIMC)
       double logNP, q, A, B;
       if (f > logCslogp) break;
       logNP = f * pr->logp;
-      q = 1/sqrt(upowuu(p, f));
+      q = 1/sqrt((double)upowuu(p, f));
       A = logNP * q; B = logNP * A; M = (long)(logCslogp/f);
       if (M > 1)
       {
         double inv1_q = 1 / (1-q);
-        A *= (1 - pow(q, M)) * inv1_q;
-        B *= (1 - pow(q, M)*(M+1 - M*q)) * inv1_q * inv1_q;
+        A *= (1 - pow(q, (double)M)) * inv1_q;
+        B *= (1 - pow(q, (double)M)*(M+1 - M*q)) * inv1_q * inv1_q;
       }
       nb = ns[j];
       SA += nb * A;
@@ -1120,7 +1119,7 @@ getfu(GEN nf, GEN *ptA, long *pte, long prec)
       gel(A,j) = RgC_neg(gel(A,j));
       u = v;
     }
-    if (gsigne(leading_term(u)) < 0)
+    if (gsigne(leading_coeff(u)) < 0)
     {
       gel(A,j) = RgC_add(gel(A,j), vec);
       u = RgX_neg(u);
@@ -3827,8 +3826,8 @@ automorphism_matrices(GEN nf, GEN *invp, GEN *cycp)
   for (l = 1; l <= nauts; l++)
   {
     GEN aut = gel(auts, l);
-    if (degpol(aut) == 1 && isint1(leading_term(aut)) &&
-        isintzero(constant_term(aut)))
+    if (degpol(aut) == 1 && isint1(leading_coeff(aut)) &&
+        isintzero(constant_coeff(aut)))
     {
       swap(gel(auts, l), gel(auts, nauts));
       break;
@@ -3936,6 +3935,7 @@ Buchall_param(GEN P, double cbach, double cbach2, long nbrelpid, long flun, long
   long MAXDEPSIZESFB, MAXDEPSFB;
   long nreldep, sfb_trials, need, old_need, precdouble = 0, precadd = 0;
   long done_small, small_fail, fail_limit, squash_index, small_norm_prec;
+  long flag_nfinit = 0;
   double LOGD, LOGD2, lim;
   GEN computed = NULL, zu, nf, M_sn, D, A, W, R, h, PERM, fu = NULL /*-Wall*/;
   GEN small_multiplier;
@@ -3943,6 +3943,7 @@ Buchall_param(GEN P, double cbach, double cbach2, long nbrelpid, long flun, long
   GEN auts, cyclic;
   const char *precpb = NULL;
   int FIRST = 1, class1 = 0;
+  nfbasic_t nfT;
   RELCACHE_t cache;
   FB_t F;
   GRHcheck_t GRHcheck;
@@ -3951,35 +3952,60 @@ Buchall_param(GEN P, double cbach, double cbach2, long nbrelpid, long flun, long
   if (DEBUGLEVEL) timer_start(&T);
   P = get_nfpol(P, &nf);
   if (nf)
+  {
     PRECREG = nf_get_prec(nf);
+    D = nf_get_disc(nf);
+  }
   else
   {
     PRECREG = maxss(prec, MEDDEFAULTPREC);
-    nf = nfinit(P, PRECREG);
-    if (lg(nf)==3) { /* P non-monic and nfinit CHANGEd it ? */
-      pari_warn(warner,"non-monic polynomial. Change of variables discarded");
-      nf = gel(nf,1);
-      P = nf_get_pol(nf);
+    nfinit_step1(&nfT, P, 0);
+    D = nfT.dK;
+    if (!equali1(leading_coeff(nfT.x0)))
+    {
+      pari_warn(warner,"non-monic polynomial in bnfinit, using polredbest");
+      flag_nfinit = nf_RED;
     }
   }
   N = degpol(P);
-  if (N <= 1) return gerepilecopy(av0, Buchall_deg1(nf));
+  if (N <= 1)
+  {
+    if (!nf) nf = nfinit_step2(&nfT, flag_nfinit, PRECREG);
+    return gerepilecopy(av0, Buchall_deg1(nf));
+  }
+  D = absi(D);
+  LOGD = dbllog2(D) * LOG2;
+  LOGD2 = LOGD*LOGD;
+  LIMCMAX = (long)(12.*LOGD2);
+  /* In small_norm, LLL reduction produces v0 in I such that
+   *     T2(v0) <= (4/3)^((n-1)/2) NI^(2/n) disc(K)^(1/n)
+   * We consider v with T2(v) <= BMULT * T2(v0)
+   * Hence Nv <= ((4/3)^((n-1)/2) * BMULT / n)^(n/2) NI sqrt(disc(K)).
+   * NI <= LIMCMAX^2 */
+  small_norm_prec = nbits2prec( BITS_IN_LONG +
+    (N/2. * ((N-1)/2.*log(4./3) + log(BMULT/(double)N))
+     + 2*log((double) LIMCMAX) + LOGD/2) / LOG2 ); /* enough to compute norms */
+  if (small_norm_prec > PRECREG) PRECREG = small_norm_prec;
+  if (!nf)
+    nf = nfinit_step2(&nfT, flag_nfinit, PRECREG);
+  else if (nf_get_prec(nf) < PRECREG)
+    nf = nfnewprec_shallow(nf, PRECREG);
+  M_sn = nf_get_M(nf);
+  if (PRECREG > small_norm_prec) M_sn = gprec_w(M_sn, small_norm_prec);
+
   zu = rootsof1(nf);
   gel(zu,2) = nf_to_scalar_or_alg(nf, gel(zu,2));
-  if (DEBUGLEVEL) timer_printf(&T, "nfinit & rootsof1");
 
   auts = automorphism_matrices(nf, &F.invs, &cyclic);
-  if (DEBUGLEVEL) timer_printf(&T, "automorphisms");
   F.embperm = automorphism_perms(nf_get_M(nf), auts, cyclic, N);
-  if (DEBUGLEVEL) timer_printf(&T, "complex embedding permutations");
 
   nf_get_sign(nf, &R1, &R2); RU = R1+R2;
   compute_vecG(nf, &F, minss(RU, 9));
-  if (DEBUGLEVEL) timer_printf(&T, "weighted G matrices");
-  D = absi(nf_get_disc(nf));
-  if (DEBUGLEVEL) err_printf("R1 = %ld, R2 = %ld\nD = %Ps\n",R1,R2, D);
-  LOGD = dbllog2(D) * LOG2;
-  LOGD2 = LOGD*LOGD;
+  if (DEBUGLEVEL)
+  {
+    timer_printf(&T, "nfinit & rootsof1");
+    err_printf("R1 = %ld, R2 = %ld\nD = %Ps\n",R1,R2, D);
+  }
   if (LOGD < 20.) /* tiny disc, Minkowski *may* be smaller than Bach */
   {
     lim = exp(-N + R2 * log(4/M_PI) + LOGD/2) * sqrt(2*M_PI*N);
@@ -3997,7 +4023,6 @@ Buchall_param(GEN P, double cbach, double cbach2, long nbrelpid, long flun, long
   cache.base = NULL; F.subFB = NULL; F.LP = NULL;
   init_GRHcheck(&GRHcheck, N, R1, LOGD);
   high = low = LIMC0 = maxss((long)(cbach2*LOGD2), 1);
-  LIMCMAX = (long)(12.*LOGD2);
   while (!GRHchk(nf, &GRHcheck, high))
   {
     low = high;
@@ -4056,25 +4081,6 @@ START:
   FBgen(&F, nf, N, LIMC, LIMC2, &GRHcheck);
   if (!F.KC) goto START;
   av = avma;
- /* In small_norm, LLL reduction produces v0 in I such that
-  *     T2(v0) <= (4/3)^((n-1)/2) NI^(2/n) disc(K)^(1/n)
-  * We consider v with T2(v) <= BMULT * T2(v0)
-  * Hence Nv <= ((4/3)^((n-1)/2) * BMULT / n)^(n/2) NI sqrt(disc(K)).
-  * NI <= LIMC2^2 */
-  small_norm_prec = nbits2prec( BITS_IN_LONG + (long)ceil(
-    (N/2. * ((N-1)/2.*log(4./3) + log(BMULT/(double)N)) + 2*log(LIMC2) + LOGD/2)
-      / LOG2)); /* enough to compute norms */
-  if (small_norm_prec > PRECREG)
-  {
-    GEN nf0 = nf;
-    PRECREG = small_norm_prec;
-    nf = gclone( nfnewprec_shallow(nf, PRECREG) );
-    if (precdouble) gunclone(nf0);
-    precdouble++;
-  }
-  M_sn = nf_get_M(nf);
-  if (small_norm_prec < PRECREG) M_sn = gprec_w(M_sn, small_norm_prec);
-  else if (precdouble) M_sn = gcopy(M_sn);
   subFBgen(&F,nf,auts,cyclic,lim < 0? LIMC2: mindd(lim,LIMC2),MINSFB);
   if (DEBUGLEVEL)
   {
diff --git a/src/basemath/buch3.c b/src/basemath/buch3.c
index 85ea080..279207b 100644
--- a/src/basemath/buch3.c
+++ b/src/basemath/buch3.c
@@ -1527,7 +1527,7 @@ rnfnormgroup_i(GEN bnr, GEN polrel)
   nf = bnf_get_nf(bnf);
   cnd = gel(bnr_get_mod(bnr), 1);
   polrel = RgX_nffix("rnfnormgroup", nf_get_pol(nf),polrel,1);
-  if (!gequal1(leading_term(polrel)))
+  if (!gequal1(leading_coeff(polrel)))
     pari_err_IMPL("rnfnormgroup for non-monic polynomials");
 
   degrel = degpol(polrel);
@@ -1701,7 +1701,7 @@ rnfconductor(GEN bnf, GEN polrel)
 
 /* Given a number field bnf=bnr[1], a ray class group structure bnr, and a
  * subgroup H (HNF form) of the ray class group, compute [n, r1, dk]
- * associated to H (cf. discrayall). If flcond = 1, abort (return gen_0) if
+ * associated to H. If flcond = 1, abort (return gen_0) if
  * module is not the conductor If flrel = 0, compute only N(dk) instead of
  * the ideal dk proper */
 static GEN
@@ -2497,10 +2497,9 @@ subgroupcond(GEN bnr, GEN indexbound)
   if (indexbound && typ(indexbound) != t_VEC)
   { /* sort by increasing index if not single value */
     long i, l = lg(li);
-    GEN p1, perm, lidet = cgetg(l,t_VEC);
-    for (i=1; i<l; i++) gel(lidet,i) = ZM_det_triangular(gel(li,i));
-    perm = indexsort(lidet); p1 = li; li = cgetg(l,t_VEC);
-    for (i=1; i<l; i++) li[i] = p1[perm[l-i]];
+    GEN D = cgetg(l,t_VEC);
+    for (i=1; i<l; i++) gel(D,i) = ZM_det_triangular(gel(li,i));
+    li = vecreverse( vecpermute(li, indexsort(D)) );
   }
   return gerepilecopy(av,li);
 }
diff --git a/src/basemath/buch4.c b/src/basemath/buch4.c
index 79b6a58..8d9f609 100644
--- a/src/basemath/buch4.c
+++ b/src/basemath/buch4.c
@@ -310,14 +310,14 @@ nf_hyperell_locally_soluble(GEN nf,GEN T,GEN pr)
   if (equaliu(pr_get_p(pr), 2))
   { /* tough case */
     zinit = Idealstar(nf, idealpows(nf,pr,1+2*pr_get_e(pr)), nf_INIT);
-    if (psquare2nf(nf,constant_term(T),pr,zinit)) return 1;
-    if (psquare2nf(nf, leading_term(T),pr,zinit)) return 1;
+    if (psquare2nf(nf,constant_coeff(T),pr,zinit)) return 1;
+    if (psquare2nf(nf, leading_coeff(T),pr,zinit)) return 1;
   }
   else
   {
     zinit = zkmodprinit(nf, pr);
-    if (psquarenf(nf,constant_term(T),pr,zinit)) return 1;
-    if (psquarenf(nf, leading_term(T),pr,zinit)) return 1;
+    if (psquarenf(nf,constant_coeff(T),pr,zinit)) return 1;
+    if (psquarenf(nf, leading_coeff(T),pr,zinit)) return 1;
   }
   repr = repres(nf,pr);
   if (zpsolnf(nf,T,pr,0,gen_1,gen_0,repr,zinit)) { avma=av; return 1; }
@@ -705,7 +705,7 @@ rnfisnorminit(GEN T, GEN relpol, int galois)
   if (!nf) nf = bnf_get_nf(bnf);
 
   relpol = get_bnfpol(relpol, &bnfabs, &nfabs);
-  if (!gequal1(leading_term(relpol))) pari_err_IMPL("non monic relative equation");
+  if (!gequal1(leading_coeff(relpol))) pari_err_IMPL("non monic relative equation");
   drel = degpol(relpol);
   if (drel <= 2) galois = 1;
 
diff --git a/src/basemath/crvwtors.c b/src/basemath/crvwtors.c
index f973d51..ff376cd 100644
--- a/src/basemath/crvwtors.c
+++ b/src/basemath/crvwtors.c
@@ -67,7 +67,7 @@ map_X1_points(
 
   X1_c = zxX_to_FlxX(X1->crv, p);
   xdeg = degpol(X1_c);
-  ydeg = RgXY_degreex(X1_c);
+  ydeg = FlxY_degreex(X1_c);
 
   rn_pol = zxX_to_FlxX(X1->r_num, p);
   rd_pol = zxX_to_FlxX(X1->r_den, p);
@@ -79,10 +79,10 @@ map_X1_points(
   xdeg = maxss(xdeg, degpol(sn_pol));
   xdeg = maxss(xdeg, degpol(sd_pol));
 
-  ydeg = maxss(ydeg, RgXY_degreex(rn_pol));
-  ydeg = maxss(ydeg, RgXY_degreex(rd_pol));
-  ydeg = maxss(ydeg, RgXY_degreex(sn_pol));
-  ydeg = maxss(ydeg, RgXY_degreex(sd_pol));
+  ydeg = maxss(ydeg, FlxY_degreex(rn_pol));
+  ydeg = maxss(ydeg, FlxY_degreex(rd_pol));
+  ydeg = maxss(ydeg, FlxY_degreex(sn_pol));
+  ydeg = maxss(ydeg, FlxY_degreex(sd_pol));
 
   rn = cgetg(ncurves + 1, t_VECSMALL);
   rd = cgetg(ncurves + 1, t_VECSMALL);
diff --git a/src/basemath/dirichlet.c b/src/basemath/dirichlet.c
index 15b6fa2..5c95ebd 100644
--- a/src/basemath/dirichlet.c
+++ b/src/basemath/dirichlet.c
@@ -26,20 +26,19 @@ err_direuler(GEN x)
 static long
 dirmuleuler_small(GEN V, GEN v, long n, ulong p, GEN s)
 {
-  long d = lg(s)-2, b = lg(V)-1;
-  long i,j;
-  long m = n;
-  long q = 1;
+  long i, j, m = n, d = lg(s)-2;
+  ulong q = 1, b = lg(V)-1;
   for (i=1, q=p; i<=d; i++, q*=p)
   {
     GEN aq = gel(s,i+1);
     if (gequal0(aq)) continue;
     for(j=1; j<=m; j++)
     {
-      long nj = v[j]*q;
-      GEN Vj = gel(V,v[j]);
-      if (nj > b) continue;
-      gel(V,nj) = gmul(aq, Vj);
+      ulong nj;
+      LOCAL_HIREMAINDER;
+      nj = mulll(uel(v,j), q);
+      if (hiremainder || nj > b) continue;
+      gel(V,nj) = gmul(aq, gel(V,v[j]));
       v[++n] = nj;
     }
   }
diff --git a/src/basemath/ellanal.c b/src/basemath/ellanal.c
index 4fbe41a..26bacce 100644
--- a/src/basemath/ellanal.c
+++ b/src/basemath/ellanal.c
@@ -90,7 +90,7 @@ gen_BG_rec(void *E, bg_fun *fun, struct bg_data *bg)
   forprime_t S;
   (void)forprime_init(&S, utoipos(bg->p[lp]+1), bg->bnd);
   av2 = avma;
-  if(DEBUGLEVEL)
+  if (DEBUGLEVEL)
     err_printf("1st stage, using recursion for p <= %ld\n", bg->p[lp]);
   for (i = 1; i <= lp; i++)
   {
@@ -155,7 +155,7 @@ logboundG0(long e, double aY)
   double cla, loggam;
   cla = 1 + 1/sqrt(aY);
   if (e) cla = ( cla + 1/(2*aY) ) / (2*sqrt(aY));
-  loggam = (e) ? log(2)-aY : -aY + log( log( 1+1/aY) );
+  loggam = (e) ? LOG2-aY : -aY + log( log( 1+1/aY) );
   return log(cla) + loggam;
 }
 
@@ -170,7 +170,7 @@ param_points(GEN N, double Y, double tmax, long bprec, long *cprec, long *L,
   *cprec = nbits2prec(ceil(D / LOG2) + 5);
   a = 2 * M_PI / sqrt(gtodouble(N));
   aY = a * cos(M_PI/2*Y);
-  logM = log(4) + logboundG0(w+1, aY) + tmax * Y * M_PI/2;
+  logM = 2*LOG2 + logboundG0(w+1, aY) + tmax * Y * M_PI/2;
   *h = ( 2 * M_PI * M_PI / 2 * Y ) / ( D + logM );
   X = log( D / a);
   *L = ceil( X / *h);
@@ -252,7 +252,7 @@ baby_size(GEN rbnd, long Ks, long prec)
   for (s = 0, i = 1; i < l; ++i)
     s += rbnd[i];
   m = 2*s*prec + 3*l + s;
-  if (DEBUGLEVEL > 0)
+  if (DEBUGLEVEL)
     err_printf("ellL1: BG_add: %ld words, ellan: %ld words\n", m, Ks);
   return m;
 }
@@ -992,13 +992,13 @@ heegner_try_point(GEN E, GEN lambdas, GEN ht, GEN z, long prec)
   {
     GEN logd = shiftr(gsub(rh, gel(lambdas, i)), -1);
     GEN d, approxd = gexp(logd, prec);
-    if (DEBUGLEVEL > 1)
+    if (DEBUGLEVEL > 2)
       err_printf("Trying lambda number %ld, logd=%Ps, approxd=%Ps\n", i, logd, approxd);
     d = grndtoi(approxd, &eps);
     if (signe(d) > 0 && eps<-10)
     {
       GEN X, ylist, d2 = sqri(d), approxn = mulir(d2, x);
-      if (DEBUGLEVEL > 1) err_printf("approxn=%Ps  eps=%ld\n", approxn,eps);
+      if (DEBUGLEVEL > 2) err_printf("approxn=%Ps  eps=%ld\n", approxn,eps);
       X = gdiv(ground(approxn), d2);
       ylist = ellordinate(E, X, prec);
       if (lg(ylist) > 1)
@@ -1007,7 +1007,7 @@ heegner_try_point(GEN E, GEN lambdas, GEN ht, GEN z, long prec)
         GEN hp = ghell(E,P,prec);
         if (cmprr(hp, shiftr(ht,1)) < 0 && cmprr(hp, shiftr(ht,-1)) > 0)
           return P;
-        if (DEBUGLEVEL > 0)
+        if (DEBUGLEVEL)
           err_printf("found non-Heegner point %Ps\n", P);
       }
     }
@@ -1022,12 +1022,12 @@ heegner_find_point(GEN e, GEN om, GEN ht, GEN z1, long k, long prec)
   pari_sp av = avma;
   long m;
   GEN Ore = gel(om, 1), Oim = gel(om, 2);
-  if (DEBUGLEVEL > 0)
+  if (DEBUGLEVEL)
     err_printf("%ld*%ld multipliers to test\n",k,lg(lambdas)-1);
   for (m = 0; m < k; m++)
   {
     GEN P, z2 = divru(addrr(z1, mulsr(m, Ore)), k);
-    if (DEBUGLEVEL > 1)
+    if (DEBUGLEVEL > 2)
       err_printf("Trying multiplier %ld\n",m);
     P = heegner_try_point(e, lambdas, ht, z2, prec);
     if (P) return P;
@@ -1172,6 +1172,9 @@ listheegner(GEN N, GEN faN4, GEN listQ, GEN D)
     gel(L, k) = mkvec3(t, stoi(lg(Lk) - 2), Q);
     if (!ymin || gcmp(y, ymin) < 0) ymin = y;
   }
+  if (DEBUGLEVEL > 1)
+    err_printf("Disc %Ps : N*ymin = %Pg\n", D,
+                           gmul(gsqrt(ymin, DEFAULTPREC),N));
   return gerepilecopy(av, mkvec3(ymin, L, D));
 }
 
@@ -1203,7 +1206,6 @@ heegner_find_disc(GEN *points, GEN *coefs, long *pind, GEN E,
     pari_sp av = avma;
     GEN list, listD = listDisc(faN4, bad, d);
     long k, l = lg(listD);
-    if (DEBUGLEVEL) err_printf("List of discriminants...%Ps\n", listD);
     list = cgetg(l, t_VEC);
     for (k = 1; k < l; ++k)
       gel(list, k) = listheegner(N, faN4, listQ, stoi(listD[k]));
@@ -1222,7 +1224,7 @@ heegner_find_disc(GEN *points, GEN *coefs, long *pind, GEN E,
         mulf = ltwist1(E, D, bprec+expo(indmultD));
         if (DEBUGLEVEL) timer_printf(&ti,"ellL1twist");
         indr = mulrr(indmultD, mulf);
-        if (DEBUGLEVEL>=1) err_printf("Disc = %Ps, Index^2 = %Ps\n", D, indr);
+        if (DEBUGLEVEL) err_printf("Disc = %Ps, Index^2 = %Ps\n", D, indr);
         if (signe(indr)>0 && expo(indr) >= -1) /* indr >=.5 */
         {
           long e, i, l;
@@ -1246,7 +1248,7 @@ heegner_find_disc(GEN *points, GEN *coefs, long *pind, GEN E,
             if (!equali1(z)) c *= 2;
             cfs[i] = c;
           }
-          if (DEBUGLEVEL == 1)
+          if (DEBUGLEVEL)
             err_printf("N = %Ps, ymin*N = %Ps\n",N,
                        gmul(gsqrt(gel(Lk, 1), prec),N));
           *coefs = cfs; *points = pts; return;
@@ -1322,62 +1324,18 @@ ellheegner(GEN E)
 
 /* Modular degree */
 
-/* From Christophe Delaunay, http://delaunay.perso.math.cnrs.fr/these.pdf */
-static GEN
-elldiscfix(GEN E, GEN Et, GEN D)
-{
-  GEN N = ellQ_get_N(E), Nt = ellQ_get_N(Et);
-  GEN P = gel(Z_factor(absi(D)), 1);
-  GEN f = gen_1;
-  long i, l = lg(P);
-  for (i=1; i < l; i++)
-  {
-    GEN r, p = gel(P,i);
-    long v = Z_pval(N, p), vt = Z_pval(Nt, p);
-    if (v <= vt) continue;
-    /* v > vt */
-    if (equaliu(p, 2))
-    {
-      if (vt == 0 && v >= 4)
-        r = shifti(subsi(9, sqri(ellap(Et, p))), v-3);  /* 9=(2+1)^2 */
-      else if (vt == 1)
-        r = gmul2n(utoipos(3), v-3);  /* not in Z if v=2 */
-      else if (vt >= 2)
-        r = int2n(v-vt);
-      else
-        r = gen_1; /* vt = 0, 1 <= v <= 3 */
-    }
-    else if (vt >= 1)
-      r = gdiv(subis(sqri(p), 1), p);
-    else
-      r = gdiv(mulii(subis(p, 1), subii(sqri(addis(p, 1)), sqri(ellap(Et, p)))), p);
-    f = gmul(f, r);
-  }
-  return f;
-}
-
 /* Modular degree of elliptic curve e over Q, assuming Manin constant = 1
    (otherwise multiply by square of Manin constant). */
 GEN
-ellmoddegree_bitprec(GEN e, long bitprec)
+ellmoddegree(GEN e, long bitprec)
 {
   pari_sp ltop = avma;
   long prec = nbits2prec(bitprec);
   GEN E = ellminimalmodel(e, NULL);
-  GEN D = ellminimaltwistcond(E);
-  GEN Etr = ellinit(elltwist(E, D), NULL, prec);
-  GEN Et = ellminimalmodel(Etr, NULL);
-  GEN nor = lfunellmfpeters_bitprec(Et, bitprec);
-  GEN degt = gdiv(gmul(nor, sqrr(Pi2n(1,prec))), member_area(E));
-  GEN deg = gmul(degt, elldiscfix(E, Et, D));
+  GEN nor = lfunellmfpeters(E, bitprec);
+  GEN deg = gdiv(gmul(nor, sqrr(Pi2n(1, prec))), member_area(E));
   GEN degr = bestappr(deg, int2n(bitprec>>1));
   long err = gexpo(gsub(gen_1, gdiv(deg,degr)));
-  obj_free(Etr); obj_free(Et); obj_free(E);
+  obj_free(E);
   return gerepilecopy(ltop, mkvec2(degr, stoi(err)));
 }
-
-GEN
-ellmoddegree(GEN e, long prec)
-{
-  return ellmoddegree_bitprec(e, prec2nbits(prec));
-}
diff --git a/src/basemath/elliptic.c b/src/basemath/elliptic.c
index bf6a490..2951225 100644
--- a/src/basemath/elliptic.c
+++ b/src/basemath/elliptic.c
@@ -95,7 +95,7 @@ point_to_a4a6_Fl(GEN E, GEN P, ulong p, ulong *pa4)
 {
   ulong c4 = Rg_to_Fl(ell_get_c4(E),p);
   *pa4 = Fl_c4_to_a4(c4, p);
-  return Fle_changepointinv(RgC_to_Flc(P,p), a4a6_ch_Fl(E,p), p);
+  return Fle_changepointinv(RgV_to_Flv(P,p), a4a6_ch_Fl(E,p), p);
 }
 
 void
@@ -593,7 +593,7 @@ base_ring(GEN x, GEN *pp, long *prec)
           case t_INTMOD: chk_p(p, FF_p_i(q)); /* fall through */
           case t_FRAC:   t = t_FFELT; p = q; break;
           case t_FFELT:
-            if (!FF_samefield(p,q)) pari_err_MODULUS("ellinit", p,q);
+            if (!FF_samefield(p,q) && FF_f(q)>1) pari_err_MODULUS("ellinit", p,q);
             break;
           default: pari_err_TYPE("elliptic curve base_ring", x);
         }
@@ -1085,12 +1085,12 @@ ch_Qp(GEN E, GEN e, GEN w)
   }
   if ((S = obj_check(e, Qp_TATE)))
   {
-    GEN U2 = gel(S,1), U = gel(S,2), Q = gel(S,3), AB = gel(S,4);
+    GEN U2 = gel(S,1), U = gel(S,2), Q = gel(S,3), AB = gel(S,4), L = gel(S,5);
     if (!u2) u2 = gsqr(u);
     U2 = gmul(U2, u2);
     U = gmul(U, u);
     AB = gdiv(AB, u2);
-    obj_insert_shallow(E, Qp_TATE, mkvec4(U2,U,Q,AB));
+    obj_insert_shallow(E, Qp_TATE, mkvec5(U2,U,Q,AB,L));
   }
   return E;
 }
@@ -1391,7 +1391,6 @@ ellminimaltwist(GEN e)
   c6 = ell_get_c6(E);
   disc = ell_get_disc(E);
   ellQ_get_Nfa(E, &N, &M);
-  obj_free(E);
   F = gel(M, 1); lF = lg(F);
   for(i=1; i < lF; i++)
   {
@@ -1419,6 +1418,7 @@ ellminimaltwist(GEN e)
           D = mulis(D, -8);
     }
   }
+  obj_free(E);
   return gerepileuptoleaf(av, D);
 }
 
@@ -2184,8 +2184,9 @@ static GEN
 doellQp_Tate_uniformization(GEN E, long prec0)
 {
   GEN p = ellQp_get_p(E), j = ell_get_j(E);
-  GEN u, u2, q, x1, a, b, d, s, t;
-  long v, prec = prec0+2;
+  GEN L, u, u2, q, x1, a, b, d, s, t;
+  long v, prec = prec0+3;
+  int split = -1; /* unknown */
 
   if (Q_pval(j, p) >= 0) pari_err_DOMAIN(".tate", "v_p(j)", ">=", gen_0, j);
 START:
@@ -2195,22 +2196,32 @@ START:
   if (v > 0) { prec += v; goto START; }
   x1 = gmul2n(d,-2);
   u2 = do_padic_agm(&x1,NULL,a,b);
+  if (split < 0) split = issquare(u2);
 
   t = gaddsg(1, ginv(gmul2n(gmul(u2,x1),1)));
   s = Qp_sqrt(gsubgs(gsqr(t), 1));
   q = gadd(t,s);
   if (gequal0(q)) q = gsub(t,s);
   v = prec0 - precp(q);
+  if (split)
+  { /* we want log q at precision prec0 */
+    GEN q0 = leafcopy(q); setvalp(q0, 0);
+    v +=  valp(gsubgs(q0,1));
+  }
   if (v > 0) { prec += v; goto START; }
   if (valp(q) < 0) q = ginv(q);
-  if (issquare(u2))
+  if (split)
+  {
     u = Qp_sqrt(u2);
+    L = gdivgs(Qp_log(q), valp(q));
+  }
   else
   {
     GEN T = mkpoln(3, gen_1, gen_0, gneg(u2));
     u = mkpolmod(pol_x(0), T);
+    L = gen_1;
   }
-  return mkvec4(u2, u, q, mkvec2(a, b));
+  return mkvec5(u2, u, q, mkvec2(a, b), L);
 }
 GEN
 ellQp_Tate_uniformization(GEN E, long prec)
@@ -2227,6 +2238,9 @@ ellQp_q(GEN E, long prec)
 GEN
 ellQp_ab(GEN E, long prec)
 { GEN T = ellQp_Tate_uniformization(E, prec); return gel(T,4); }
+GEN
+ellQp_L(GEN E, long prec)
+{ GEN T = ellQp_Tate_uniformization(E, prec); return gel(T,5); }
 
 static GEN
 zellQp(GEN E, GEN z, long prec)
@@ -2674,9 +2688,14 @@ ellpadicheight(GEN e, GEN p, long v0, GEN P)
   { /* P not in kernel of reduction mod p */
     GEN m, X, Pp, Ep = ellinit_Fp(E, p);
     long w = v+2;
-    if (!Ep) pari_err(e_MISC,"ellpadicheight: bad reduction");
     Pp = RgV_to_FpV(P, p);
-    m = ellorder(Ep, Pp, NULL);
+    if (Ep)
+      m = ellorder(Ep, Pp, NULL);
+    else
+    {
+      m = ellcard(E, p); /* E has bad reduction at p */
+      if (equalii(m, p)) pari_err_TYPE("ellpadicheight: additive reduction", E);
+    }
     g = mulii(g,m);
     for(;;)
     {
@@ -2810,12 +2829,12 @@ typedef struct {
   GEN w1,w2,tau; /* original basis for L = <w1,w2> = w2 <1,tau> */
   GEN W1,W2,Tau; /* new basis for L = <W1,W2> = W2 <1,tau> */
   GEN a,b,c,d; /* t_INT; tau in F = h/Sl2, tau = g.t, g=[a,b;c,d] in SL(2,Z) */
-  GEN z,Z; /* z/w2 defined mod <1,tau>, Z = z + x*tau + y reduced mod <1,tau> */
+  GEN z,Z; /* z/w2 defined mod <1,tau>, Z = z/w2 + x*tau+y reduced mod <1,tau>*/
   GEN x,y; /* t_INT */
   int swap; /* 1 if we swapped w1 and w2 */
   int some_q_is_real; /* exp(2iPi g.tau) for some g \in SL(2,Z) */
   int some_z_is_real; /* z + xw1 + yw2 is real for some x,y \in Z */
-  int some_z_is_pure_imag; /* z + xw1 + yw2 = it, t \in R */
+  int some_z_is_pure_imag; /* z + xw1 + yw2 in i*R */
   int q_is_real; /* exp(2iPi tau) \in R */
   int abs_u_is_1; /* |exp(2iPi Z)| = 1 */
   long prec; /* precision(Z) */
@@ -2891,6 +2910,13 @@ red_modSL2(ellred_t *T, long prec)
   p = precision(T->Tau); if (!p) p = prec;
   T->prec = p;
 }
+/* is z real or pure imaginary ? */
+static void
+check_complex(GEN z, int *real, int *imag)
+{
+  if (typ(z) != t_COMPLEX) *real = 1;
+  else if (isexactzero(gel(z,1))) *imag = 1;
+}
 static void
 reduce_z(GEN z, ellred_t *T)
 {
@@ -2913,12 +2939,18 @@ reduce_z(GEN z, ellred_t *T)
   if (signe(T->x)) Z = gsub(Z, gmul(T->x,T->Tau));
   T->y = ground(real_i(Z));
   if (signe(T->y)) Z = gsub(Z, T->y);
-  if (typ(Z) != t_COMPLEX)
-    T->some_z_is_real = T->abs_u_is_1 = 1;
-  else if (typ(z) != t_COMPLEX)
-    T->some_z_is_real = 1;
-  else if (isexactzero(gel(z,1)) || isexactzero(gel(Z,1)))
-    T->some_z_is_pure_imag = 1;
+  if (typ(Z) != t_COMPLEX) T->abs_u_is_1 = 1;
+  /* Z = - y - x tau + z/W2, x,y integers */
+  check_complex(z, &(T->some_z_is_real), &(T->some_z_is_pure_imag));
+  if (!T->some_z_is_real && !T->some_z_is_pure_imag)
+  {
+    int W2real = 0, W2imag = 0;
+    check_complex(T->W2,&W2real,&W2imag);
+    if (W2real)
+      check_complex(Z, &(T->some_z_is_real), &(T->some_z_is_pure_imag));
+    else if (W2imag)
+      check_complex(Z, &(T->some_z_is_pure_imag), &(T->some_z_is_real));
+  }
   p = precision(Z);
   if (gequal0(Z) || (p && gexpo(Z) < 5 - prec2nbits(p)))
     Z = NULL; /*z in L*/
@@ -3208,7 +3240,11 @@ ellwpnum_all(GEN e, GEN z, long flall, long prec)
   if (yp)
   {
     yp = gmul(u, gmul(gmul(u1,u2),yp));/* yp *= u (2i pi / w2)^3 */
-    if (T.some_q_is_real && T.some_z_is_real) yp = real_i(yp);
+    if (T.some_q_is_real)
+    {
+      if (T.some_z_is_real) yp = real_i(yp);
+      else if (T.some_z_is_pure_imag) yp = mkcomplex(gen_0, imag_i(yp));
+    }
     y = mkvec2(y, gmul2n(yp,-1));
   }
   return gerepilecopy(av, y);
@@ -3384,10 +3420,8 @@ ellzeta(GEN w, GEN z, long prec0)
   if (et) y = gadd(y,et);
   if (T.some_q_is_real)
   {
-    if (T.some_z_is_real)
-      y = real_i(y);
-    else if (T.some_z_is_pure_imag)
-      gel(y,1) = gen_0;
+    if (T.some_z_is_real) y = real_i(y);
+    else if (T.some_z_is_pure_imag) gel(y,1) = gen_0;
   }
   return gerepilecopy(av, y);
 }
@@ -3480,10 +3514,8 @@ ellsigma(GEN w, GEN z, long flag, long prec0)
     y = gmul(y, gexp(y1,prec));
     if (T.some_q_is_real)
     {
-      if (T.some_z_is_real)
-        y = real_i(y);
-      else if (T.some_z_is_pure_imag)
-        gel(y,1) = gen_0;
+      if (T.some_z_is_real) y = real_i(y);
+      else if (T.some_z_is_pure_imag) gel(y,1) = gen_0;
     }
   }
   return gerepilecopy(av, y);
@@ -5032,8 +5064,8 @@ ellQ_get_CM(GEN e)
     case  16581375: CM = -28; break;
     case -884736000: CM = -43; break;
 #ifdef LONG_IS_64BIT
-    case -147197952000: CM = -67; break;
-    case -262537412640768000: CM = -163; break;
+    case -147197952000L: CM = -67; break;
+    case -262537412640768000L: CM = -163; break;
 #endif
   }
   return CM;
@@ -5112,7 +5144,7 @@ anellsmall(GEN e, long n0)
   if (n0 <= 0) return cgetg(1,t_VEC);
   if (n >= LGBITS)
     pari_err_IMPL( stack_sprintf("ellan for n >= %lu", LGBITS) );
-  SQRTn = (ulong)sqrt(n);
+  SQRTn = usqrt(n);
   CM = ellQ_get_CM(e);
 
   an = const_vecsmall(n, LONG_MAX);
diff --git a/src/basemath/ellisog.c b/src/basemath/ellisog.c
index d07671b..a20a183 100644
--- a/src/basemath/ellisog.c
+++ b/src/basemath/ellisog.c
@@ -286,7 +286,7 @@ contrib_weierstrass_pt(GEN E, GEN h, long only_image, long vx, long vy)
   GEN p = ellbasechar(E);
   GEN a1 = ell_get_a1(E);
   GEN a3 = ell_get_a3(E);
-  GEN x0 = gneg(constant_term(h)); /* h = x - x0 */
+  GEN x0 = gneg(constant_coeff(h)); /* h = x - x0 */
   GEN b = gadd(gmul(a1,x0), a3);
   GEN y0, Q, t, w, t1, t2, f, g;
 
@@ -501,9 +501,9 @@ isogeny_from_kernel_poly(GEN E, GEN kerp, long only_image, long vx, long vy)
   /* isogeny degree: 2*degpol(kerp)+1-degpol(kerh) */
   m = degpol(kerq);
 
-  kerp = RgX_Rg_div(kerp, leading_term(kerp));
-  kerq = RgX_Rg_div(kerq, leading_term(kerq));
-  kerh = RgX_Rg_div(kerh, leading_term(kerh));
+  kerp = RgX_Rg_div(kerp, leading_coeff(kerp));
+  kerq = RgX_Rg_div(kerq, leading_coeff(kerq));
+  kerh = RgX_Rg_div(kerh, leading_coeff(kerh));
   switch(degpol(kerh))
   {
   case 0:
@@ -571,8 +571,8 @@ ellisogeny(GEN E, GEN G, long only_image, long vx, long vy)
     z = isogeny_from_kernel_point(E, G, only_image, vx, vy);
     break;
   case t_POL:
-    if (varncmp(vy, gvar(constant_term(G))) >= 0)
-      pari_err_PRIORITY("ellisogeny", constant_term(G), ">=", vy);
+    if (varncmp(vy, gvar(constant_coeff(G))) >= 0)
+      pari_err_PRIORITY("ellisogeny", constant_coeff(G), ">=", vy);
     z = isogeny_from_kernel_poly(E, G, only_image, vx, vy);
     break;
   default:
diff --git a/src/basemath/ellpadicL.c b/src/basemath/ellpadicL.c
deleted file mode 100644
index 23614f4..0000000
--- a/src/basemath/ellpadicL.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/* $Id$
-
-Copyright (C) 2011  The PARI group.
-
-This file is part of the PARI/GP package.
-
-PARI/GP is free software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the Free Software
-Foundation. It is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY WHATSOEVER.
-
-Check the License for details. You should have received a copy of it, along
-with the package; see the file 'COPYING'. If not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "pari.h"
-#include "paripriv.h"
-
-/** Batch p-adic logarithms **/
-
-/* a/b mod q */
-static GEN
-divmodulo(GEN a, ulong b, ulong p, GEN q)
-{
-  long v = u_lvalrem(b, p, &b);
-  if (v) a = divis(a, upowuu(p,v));
-  /* a/b is now a p-integer */
-  return Fp_div(a, utoipos(b), q);
-}
-
-/* to compute log_p(a) mod q = p^n, p < 2^31 */
-static GEN
-initQplog(long p, GEN q, long n)
-{
-  long i, nn, nt;
-  GEN a, C;
-  for(nn = n, nt = n + 1; nn >= p; nn /= p) nt++;
-  if (p == 2)
-    while(3 * (nt - 1) > u_lval(nt-1, p) + n) nt--;
-  else
-    while(nt > u_lval(nt-1, p) + n) nt--;
-
-  C = cgetg(nt, t_VEC);
-  /* [ (-1)^k-1 p^k / (k*(p-1)) ] k=1..nt
-   * [ (-1)^k-1 2^3k / (2*k) ]    k=1..nt if p = 2*/
-  for(i = 1, a = utoipos(p); i < nt; i++, a = mulis(a, -p))
-    gel(C,i) = divmodulo(a, i * (p==2? 2: p-1), p, q);
-  return C;
-}
-
-/* compute log_p(a), 'a' a p-unit, C = initQplog(p,q,n), q = p^n */
-static GEN
-logp(GEN C, GEN a, ulong p, GEN q)
-{
-  long i, nt = lg(C);
-  ulong av = avma;
-  GEN b, res;
-
-  if (p == 2)
-    b = Fp_sqr(modii(a,q), q);
-  else
-    b = Fp_powu(a, p-1, q);
-  /* now b = 1 mod p, compute (b-1) / p = euclidean quotient */
-  b = divis(b, p);
-  res = Fp_mul(b, gel(C,nt-1), q);
-  for(i = nt-2; i > 0; i--)
-    res = Fp_mul(addii(res, gel(C,i)), b, q);
-  return gerepileuptoint(av, res);
-}
-
-/** p-adic L function **/
-
-/* W an msinit, xpm the normalized modylar symbol attached to E/Q, D > 0.
- * Assume |D p^m| < MAX_ULONG, m > 0 */
-static GEN
-loopLpn(GEN W, GEN xpm, ulong D, ulong p, long m, long R, GEN q)
-{
-  pari_sp av;
-  ulong a;
-  GEN q1 = diviuexact(q,p);
-  GEN Dq1= mului(D,q1), Dq = muliu(Dq1,p);
-  GEN u = gen_0, v = gen_0, nc = icopy(gen_1);
-  GEN c = mkfrac(nc, Dq), c1 = mkfrac(nc, Dq1);
-  GEN C = R? initQplog(p, q, m): NULL;
-  ulong A = itou(shifti(Dq,-1));
-
-  av = avma;
-  for (a = 1; a <= A; a++)
-  {
-    GEN logpR, x,x1;
-    long s;
-    if (a % p == 0 || !(s = krouu(D,a))) continue;
-    nc[2] = (long)a;
-    x = Q_xpm(W,xpm, c); /* xpm(a / Dq) */
-    x1= Q_xpm(W,xpm, c1);/* xpm(a / D(q/p)) */
-    if (!signe(x) && !signe(x1)) continue;
-    if (R)
-    {
-      logpR = logp(C, nc, p, q);
-      if (R != 1) logpR = Fp_powu(logpR, R, q);
-      x = mulii(x, logpR);
-      x1= mulii(x1,logpR);
-    }
-    if (s < 0) { u = subii(u, x); v= subii(v,x1); }
-    else       { u = addii(u, x); v= addii(v,x1); }
-    if (gc_needed(av,2))
-    {
-      if (DEBUGMEM>1)
-        pari_warn(warnmem,"loopLp: a = %ld / %ld (%%%.1f)",a,A,
-                  a/(double)A*100);
-      gerepileall(av, 2, &u,&v);
-    }
-  }
-  return mkvec2(u,v);
-}
-
-/* p coprime to ap, return unit root of x^2 - ap*x + p^(k-1), accuracy p^n */
-GEN
-ms_unit_eigenvalue(GEN ap, long k, GEN p, long n)
-{
-  GEN sqrtD, D = subii(sqri(ap), shifti(powiu(p,k-1),2));
-  if (equaliu(p,2)) n++;
-  sqrtD = Zp_sqrtlift(D, ap, p, n); /* congruent to ap mod p */
-  return gmul2n(gadd(ap, cvtop(sqrtD,p,n)), -1);
-}
-
-/* TODO: C corresponds to Teichmuller, currently allways NULL */
-GEN
-ellpadicL(GEN E, GEN pp, long n, long r, GEN DD, GEN C)
-{
-  pari_sp av = avma;
-  GEN ap, scale, L, W, xpm, NE;
-  ulong p, D;
-
-  if (DD && !Z_isfundamental(DD))
-    pari_err_DOMAIN("ellpadicL", "isfundamental(D)", "=", gen_0, DD);
-  if (DD && signe(DD) <= 0) pari_err_DOMAIN("ellpadicL", "D", "<=", gen_0, DD);
-  if (typ(pp) != t_INT) pari_err_TYPE("ellpadicL",pp);
-  if (cmpis(pp,2) < 0) pari_err_PRIME("ellpadicL",pp);
-  if (n <= 0) pari_err_DOMAIN("ellpadicL","precision","<=",gen_0,stoi(n));
-  if (r < 0) pari_err_DOMAIN("ellpadicL","r","<",gen_0,stoi(r));
-
-  (void)C; /* TODO */
-  W = msfromell(E, 1);
-  xpm = gel(W,2);
-  W = gel(W,1);
-  p = itou(pp);
-  D = DD? itou(DD): 1;
-  NE = ellQ_get_N(E);
-  if (dvdii(NE, sqri(pp)))
-    pari_err_IMPL("ellpadicL [additive reduction at p]");
-
-  xpm = Q_primitive_part(xpm,&scale);
-  if (!scale) scale = gen_1;
-  n -= Q_pval(scale, pp);
-  scale = cvtop(scale, pp, n);
-
-  ap = ellap(E,pp);
-  if (umodiu(ap,p))
-  { /* ordinary */
-    long N = n+2;
-    GEN pn = powuu(p, N);
-    GEN u,v, uv = loopLpn(W,xpm, D, p,N,r,pn); /* correct mod p^n */
-    GEN al = ginv( ms_unit_eigenvalue(ap, 2, pp, n) );
-    al = gel(al,4); /* lift to Z */
-    u = modii(gel(uv,1), pn);
-    if (umodiu(ellQ_get_N(E), p))
-    {
-      v = modii(gel(uv,2), pn);
-      L = Fp_sub(u, Fp_mul(v,al,pn), pn);
-    }
-    else /* p | N */
-      L = u;
-
-    L = Fp_mul(L, Fp_powu(al, N, pn), pn);
-    if (!signe(L)) L = zeropadic_shallow(pp, n);
-  }
-  else
-  { /* supersingular */
-    GEN _0 = zeropadic_shallow(pp, n);
-    long N = signe(ap)? 2*n+3: 2*n+1;
-    GEN uv = loopLpn(W,xpm, D, p,N,r,powiu(pp,N)), u = gel(uv,1), v = gel(uv,2);
-    GEN M = mkmat2(mkcol2(gen_0, gen_m1), gdivgs(mkcol2(gen_1,ap),p));
-    L = RgV_RgM_mul(mkvec2(u,gdivgs(v,-p)), gpowgs(M,N));
-    u = gadd(gel(L,1), _0);
-    v = gadd(gel(L,2), _0);
-    L = mkvec2(u,v);
-  }
-  return gerepileupto(av, gmul(L, gmul2n(scale,1)));
-}
diff --git a/src/basemath/ellsea.c b/src/basemath/ellsea.c
index b404a42..5bec73e 100644
--- a/src/basemath/ellsea.c
+++ b/src/basemath/ellsea.c
@@ -40,12 +40,6 @@ pari_init_seadata(void)  { modular_eqn = NULL; }
 void
 pari_close_seadata(void) { if (modular_eqn) gunclone(modular_eqn); }
 
-static int
-FqX_equal(GEN x, GEN y) { return gequal(x,y); }
-
-static int
-FlxX_equal(GEN x, GEN y) { return gequal(x,y); }
-
 static char *
 seadata_filename(ulong ell)
 { return stack_sprintf("%s/seadata/sea%ld", pari_datadir, ell); }
@@ -142,6 +136,257 @@ ellmodulareqn(long ell, long vx, long vy)
   return gerepilecopy(av,mkvec2(meqn.eq, stoi(meqn.type=='A')));
 }
 
+/***********************************************************************/
+/**                                                                   **/
+/**                      n-division polynomial                        **/
+/**                                                                   **/
+/***********************************************************************/
+
+static GEN divpol(GEN t, GEN r2, long n, void *E, const struct bb_algebra *ff);
+
+static GEN
+divpol_f2(GEN t, GEN r2, long n, void *E, const struct bb_algebra *ff)
+{
+  if (n==0) return ff->zero(E);
+  if (n<=2) return ff->one(E);
+  if (gmael(t,2,n)) return gmael(t,2,n);
+  gmael(t,2,n) = gclone(ff->sqr(E,divpol(t,r2,n,E,ff)));
+  return gmael(t,2,n);
+}
+
+static GEN
+divpol_ff(GEN t, GEN r2, long n, void *E, const struct bb_algebra *ff)
+{
+  if (n<=2) return ff->zero(E);
+  if (gmael(t,3,n)) return gmael(t,3,n);
+  if (n<=4) return divpol(t,r2,n,E,ff);
+  gmael(t,3,n) = gclone(ff->mul(E,divpol(t,r2,n,E,ff), divpol(t,r2,n-2,E,ff)));
+  return gmael(t,3,n);
+}
+
+static GEN
+divpol(GEN t, GEN r2, long n, void *E, const struct bb_algebra *ff)
+{
+  long m = n/2;
+  pari_sp av = avma;
+  GEN res;
+  if (n==0) return ff->zero(E);
+  if (gmael(t,1,n)) return gmael(t,1,n);
+  switch(n)
+  {
+  case 1:
+  case 2:
+    res = ff->one(E);
+    break;
+  default:
+    if (odd(n))
+      if (odd(m))
+        res = ff->sub(E, ff->mul(E, divpol_ff(t,r2,m+2,E,ff),
+                                    divpol_f2(t,r2,m,E,ff)),
+                         ff->mul(E, r2,
+                                    ff->mul(E,divpol_ff(t,r2,m+1,E,ff),
+                                              divpol_f2(t,r2,m+1,E,ff))));
+      else
+        res = ff->sub(E, ff->mul(E, r2,
+                                    ff->mul(E, divpol_ff(t,r2,m+2,E,ff),
+                                               divpol_f2(t,r2,m,E,ff))),
+                         ff->mul(E, divpol_ff(t,r2,m+1,E,ff),
+                                    divpol_f2(t,r2,m+1,E,ff)));
+    else
+      res = ff->sub(E, ff->mul(E, divpol_ff(t,r2,m+2,E,ff),
+                                  divpol_f2(t,r2,m-1,E,ff)),
+                       ff->mul(E, divpol_ff(t,r2,m,E,ff),
+                                  divpol_f2(t,r2,m+1,E,ff)));
+  }
+  res = ff->red(E, res);
+  gmael(t,1,n) = gclone(res);
+  avma = av;
+  return gmael(t,1,n);
+}
+
+static void
+divpol_free(GEN t)
+{
+  long i, l = lg(t);
+  for (i=1; i<l; i++)
+  {
+    if (gmael(t,1,i)) gunclone(gmael(t,1,i));
+    if (gmael(t,2,i)) gunclone(gmael(t,2,i));
+    if (gmael(t,3,i)) gunclone(gmael(t,3,i));
+  }
+}
+
+static GEN
+Flxq_elldivpol34(long n, GEN a4, GEN a6, GEN S, GEN T, ulong p)
+{
+  GEN res;
+  long vs = T[1];
+  switch(n)
+  {
+  case 3:
+    res = mkpoln(5, Fl_to_Flx(3%p,vs), pol0_Flx(vs), Flx_mulu(a4, 6, p),
+                    Flx_mulu(a6, 12, p), Flx_neg(Flxq_sqr(a4, T, p), p));
+    break;
+  case 4:
+    {
+      GEN a42 = Flxq_sqr(a4, T, p);
+      res = mkpoln(7, pol1_Flx(vs), pol0_Flx(vs), Flx_mulu(a4, 5, p),
+          Flx_mulu(a6, 20, p), Flx_mulu(a42,p-5, p),
+          Flx_mulu(Flxq_mul(a4, a6, T, p), p-4, p),
+          Flx_sub(Flx_mulu(Flxq_sqr(a6, T, p), p-8%p, p),
+            Flxq_mul(a4, a42, T, p), p));
+      res = FlxX_double(res, p);
+    }
+    break;
+    default:
+      pari_err_BUG("Flxq_elldivpol34"); return NULL;
+  }
+  setvarn(res, get_FlxqX_var(S));
+  return FlxqX_rem(res, S, T, p);
+}
+
+static GEN
+Fq_elldivpol34(long n, GEN a4, GEN a6, GEN S, GEN T, GEN p)
+{
+  GEN res;
+  switch(n)
+  {
+  case 3:
+    res = mkpoln(5, utoi(3), gen_0, Fq_mulu(a4, 6, T, p),
+        Fq_mulu(a6, 12, T, p), Fq_neg(Fq_sqr(a4, T, p), T, p));
+    break;
+  case 4:
+    {
+      GEN a42 = Fq_sqr(a4, T, p);
+      res = mkpoln(7, gen_1, gen_0, Fq_mulu(a4, 5, T, p),
+          Fq_mulu(a6, 20, T, p), Fq_Fp_mul(a42,stoi(-5), T, p),
+          Fq_Fp_mul(Fq_mul(a4, a6, T, p), stoi(-4), T, p),
+          Fq_sub(Fq_Fp_mul(Fq_sqr(a6, T, p), stoi(-8), T, p),
+            Fq_mul(a4,a42, T, p), T, p));
+      res = FqX_mulu(res, 2, T, p);
+    }
+    break;
+    default:
+      pari_err_BUG("Fq_elldivpol34"); return NULL;
+  }
+  if (S)
+  {
+    setvarn(res, get_FpXQX_var(S));
+    res = FqX_rem(res, S, T, p);
+  }
+  return res;
+}
+
+static GEN
+rhs(GEN a4, GEN a6, long v)
+{
+  GEN RHS = mkpoln(4, gen_1, gen_0, a4, a6);
+  setvarn(RHS, v);
+  return RHS;
+}
+
+struct divpolmod_red
+{
+  const struct bb_algebra *ff;
+  void *E;
+  GEN t, r2;
+};
+
+static void
+divpolmod_init(struct divpolmod_red *d, GEN D3, GEN D4, GEN RHS, long n,
+               void *E, const struct bb_algebra *ff)
+{
+  long k = n+2;
+  d->ff = ff; d->E = E;
+  d->t  = mkvec3(const_vec(k, NULL),const_vec(k, NULL),const_vec(k, NULL));
+  if (k>=3) gmael(d->t,1,3) = gclone(D3);
+  if (k>=4) gmael(d->t,1,4) = gclone(D4);
+  d->r2 = ff->sqr(E, RHS);
+}
+
+static void
+Fq_elldivpolmod_init(struct divpolmod_red *d, GEN a4, GEN a6, long n, GEN h, GEN T, GEN p)
+{
+  void *E;
+  const struct bb_algebra *ff;
+  GEN RHS, D3 = NULL, D4 = NULL;
+  long v = h ? get_FpXQX_var(h): 0;
+  D3 = n>=0 ? Fq_elldivpol34(3, a4, a6, h, T, p): NULL;
+  D4 = n>=1 ? Fq_elldivpol34(4, a4, a6, h, T, p): NULL;
+  RHS = rhs(a4, a6, v);
+  RHS = h ? FqX_rem(RHS, h, T, p): RHS;
+  RHS = FqX_mulu(RHS, 4, T, p);
+  ff = h ? T ? get_FpXQXQ_algebra(&E, h, T, p): get_FpXQ_algebra(&E, h, p):
+           T ? get_FpXQX_algebra(&E, T, p, v): get_FpX_algebra(&E, p, v);
+  divpolmod_init(d, D3, D4, RHS, n, E, ff);
+}
+
+static void
+Flxq_elldivpolmod_init(struct divpolmod_red *d, GEN a4, GEN a6, long n, GEN h, GEN T, ulong p)
+{
+  void *E;
+  const struct bb_algebra *ff;
+  GEN RHS, D3 = NULL, D4 = NULL;
+  D3 = n>=0 ? Flxq_elldivpol34(3, a4, a6, h, T, p): NULL;
+  D4 = n>=1 ? Flxq_elldivpol34(4, a4, a6, h, T, p): NULL;
+  RHS = FlxX_Fl_mul(FlxqX_rem(rhs(a4, a6, get_FlxqX_var(h)), h, T, p), 4, p);
+  ff = get_FlxqXQ_algebra(&E, h, T, p);
+  divpolmod_init(d, D3, D4, RHS, n, E, ff);
+}
+
+/*Computes the n-division polynomial modulo the polynomial h \in Fq[x] */
+GEN
+Fq_elldivpolmod(GEN a4, GEN a6, long n, GEN h, GEN T, GEN p)
+{
+  struct divpolmod_red d;
+  pari_sp ltop = avma;
+  GEN res;
+  Fq_elldivpolmod_init(&d, a4, a6, n, h, T, p);
+  res = gcopy(divpol(d.t,d.r2,n,d.E,d.ff));
+  divpol_free(d.t);
+  return gerepileupto(ltop, res);
+}
+
+GEN
+FpXQ_elldivpol(GEN a4, GEN a6, long n, GEN T, GEN p)
+{
+  return Fq_elldivpolmod(a4,a6,n,NULL,T,p);
+}
+
+GEN
+Fp_elldivpol(GEN a4, GEN a6, long n, GEN p)
+{
+  return Fq_elldivpolmod(a4,a6,n,NULL,NULL,p);
+}
+
+static GEN
+Fq_ellyn(struct divpolmod_red *d, long k)
+{
+  pari_sp av = avma;
+  void *E = d->E;
+  const struct bb_algebra *ff = d->ff;
+  if (k==1) return mkvec2(ff->one(E), ff->one(E));
+  else
+  {
+    GEN t = d->t, r2 = d->r2;
+    GEN pn2 = divpol(t,r2,k-2,E,ff);
+    GEN pp2 = divpol(t,r2,k+2,E,ff);
+    GEN pn12 = divpol_f2(t,r2,k-1,E,ff);
+    GEN pp12 = divpol_f2(t,r2,k+1,E,ff);
+    GEN on = ff->red(E,ff->sub(E, ff->mul(E,pp2,pn12), ff->mul(E,pn2,pp12)));
+    GEN f  = divpol(t,r2,k,E,ff);
+    GEN f2 = divpol_f2(t,r2,k,E,ff);
+    GEN f3 = ff->mul(E,f,f2);
+    if (!odd(k)) f3 = ff->mul(E,f3,r2);
+    return gerepilecopy(av,mkvec2(on, f3));
+  }
+}
+
+static void
+Fq_elldivpolmod_close(struct divpolmod_red *d)
+{
+  divpol_free(d->t);
+}
 static GEN
 Fq_elldivpol2(GEN a4, GEN a6, GEN T, GEN p)
 {
@@ -288,273 +533,118 @@ Zq_ellj(GEN a4, GEN a6, GEN T, GEN p, GEN pp, long e)
 /*                              EIGENVALUE                                  */
 /****************************************************************************/
 
-struct eigen_ellinit
-{
-  GEN a4, h, T, p;
-  GEN RHS, DRHS, X12, Gy, nGy, O;
-  ulong pp;
-};
-
-static void
-init_eigen(struct eigen_ellinit *Edat, GEN a4, GEN a6, GEN h, GEN T, GEN p)
-{
-  pari_sp ltop = avma;
-  GEN RHS  = FqX_rem(mkpoln(4, gen_1, gen_0, a4, a6), h, T, p);
-  GEN DRHS = FqX_rem(mkpoln(3, utoi(3), gen_0, a4), h, T, p);
-  GEN lambda = FqXQ_div(DRHS, FqX_mulu(RHS, 4, T, p), h, T, p);
-  GEN C = FqX_sub(FqXQ_mul(lambda, DRHS, h, T, p), monomial(gen_2,1,0), T, p);
-  GEN D = FqXQ_mul(FqX_mulu(lambda, 2, T, p),FqX_sub(pol_x(0), C, T, p), h, T, p);
-  GEN X12 = mkvec2(C, FqX_Fq_add(D, gen_m1, T, p));
-  GEN Gy = T ? FpXQXQ_halfFrobenius(RHS, h, T, p):
-               FpXQ_pow(RHS, shifti(p, -1), h, p);
-  GEN nGy = FqX_neg(Gy, T, p);
-  gerepileall(ltop, 5, &RHS, &DRHS, &X12, &Gy, &nGy);
-  Edat->a4    = gcopy(a4);
-  Edat->h     = gcopy(h);
-  Edat->T     = T;
-  Edat->p     = p;
-  Edat->pp    = 0;
-  Edat->RHS   = RHS;
-  Edat->DRHS  = DRHS;
-  Edat->X12   = X12;
-  Edat->Gy    = Gy;
-  Edat->nGy   = nGy;
-  Edat->O     = mkvec2(pol_x(0), pol_1(0));
-}
-
-static void
-init_eigenu(struct eigen_ellinit *Edat, GEN a4, GEN a6, GEN h, GEN T, ulong p)
-{
-  pari_sp ltop = avma;
-  long vT = get_Flx_var(T);
-  GEN g1 = pol1_Flx(vT), g0 = pol0_Flx(vT);
-  GEN RHS  = FlxqX_rem(mkpoln(4, g1, g0, a4, a6), h, T, p);
-  GEN DRHS = FlxqX_rem(mkpoln(3, Fl_to_Flx(3, T[1]), g0, a4), h, T, p);
-  GEN lambda = FlxqXQ_div(DRHS, FlxX_Fl_mul(RHS, 4, p), h, T, p);
-  GEN C = FlxX_sub(FlxqXQ_mul(lambda, DRHS, h, T, p), monomial(Fl_to_Flx(2,vT),1,0), p);
-  GEN D = FlxqXQ_mul(FlxX_double(lambda, p),FlxX_sub(pol_x(0), C, p), h, T, p);
-  GEN X12 = mkvec2(C, FlxX_Flx_add(D, Fl_to_Flx(p-1,vT), p));
-  GEN Gy = FlxqXQ_halfFrobenius(RHS,h,T,p);
-  GEN nGy = FlxX_neg(Gy, p);
-  GEN O = mkvec2(monomial(g1,1,0), monomial(g1,0,0));
-  gerepileall(ltop, 6, &RHS, &DRHS, &X12, &Gy, &nGy, &O);
-  Edat->a4    = gcopy(a4);
-  Edat->h     = gcopy(h);
-  Edat->T     = T;
-  Edat->p     = NULL;
-  Edat->pp    = p;
-  Edat->RHS   = RHS;
-  Edat->DRHS  = DRHS;
-  Edat->X12   = X12;
-  Edat->Gy    = Gy;
-  Edat->nGy   = nGy;
-  Edat->O     = O;
-}
-static GEN
-eigen_elldbl(void *E, GEN P)
-{
-  pari_sp ltop = avma;
-  struct eigen_ellinit *Edat=(struct eigen_ellinit *)E;
-  GEN T = Edat->T, p = Edat->p, h = Edat->h, x, y;
-  if (ell_is_inf(P)) return gcopy(P);
-  x = gel(P,1), y = gel(P,2);
-  if (FqX_equal(x, pol_x(0)) && FqX_equal(y, pol_1(0)))
-    return Edat->X12;
-  else
-  {
-    GEN t1 = FqX_Fq_add(FqX_mulu(FqXQ_sqr(x,h,T,p),3,T, p), Edat->a4, T, p);
-    GEN t2 = FqXQ_mul(FqX_mulu(y, 2, T, p), Edat->RHS, h, T, p);
-    GEN lambda = FqXQ_div(t1, t2, h, T, p);
-    GEN C = FqX_sub(FqXQ_mul(FqXQ_sqr(lambda, h, T, p), Edat->RHS, h, T, p),
-                    FqX_mulu(x, 2, T, p), T, p);
-    GEN D = FqX_sub(FqXQ_mul(lambda, FqX_sub(x, C, T, p), h, T, p), y, T, p);
-    return gerepilecopy(ltop, mkvec2(C,D));
-  }
-}
-
-/* Returns the addition of [P[1], P[2]*Y] and of [Q[1], Q[2]*Y]
- * Computations are done modulo Y^2 - (X^3 + a4X + a6)
- * An inversion is equivalent to 4M, so that this function requires about 7M
- * which is the same as with the method using ell-division polynomials
- * Working in mixed projective coordinates would require 11M */
-static GEN
-eigen_elladd(void *E, GEN P, GEN Q)
-{
-  pari_sp ltop = avma;
-  struct eigen_ellinit *Edat=(struct eigen_ellinit *)E;
-  GEN Px, Py, Qx, Qy;
-  GEN T = Edat->T, p = Edat->p, h = Edat->h, lambda, C, D;
-  if (ell_is_inf(P)) return gcopy(Q);
-  if (ell_is_inf(Q)) return gcopy(P);
-  Px = gel(P,1); Py = gel(P,2);
-  Qx = gel(Q,1); Qy = gel(Q,2);
-  if (FqX_equal(Px, Qx))
-  {
-    if (FqX_equal(Py, Qy))
-      return eigen_elldbl(E, P);
-    else
-      return ellinf();
-  }
-  lambda = FqXQ_div(FqX_sub(Py, Qy, T, p), FqX_sub(Px, Qx, T, p), h, T, p);
-  C = FqX_sub(FqX_sub(FqXQ_mul(FqXQ_sqr(lambda, h, T, p), Edat->RHS, h, T, p), Px, T, p), Qx, T, p);
-  D = FqX_sub(FqXQ_mul(lambda, FqX_sub(Px, C, T, p), h, T, p), Py, T, p);
-  return gerepilecopy(ltop, mkvec2(C,D));
-}
-
-static GEN
-eigenu_elldbl(void *E, GEN P)
-{
-  pari_sp ltop = avma;
-  struct eigen_ellinit *Edat=(struct eigen_ellinit *)E;
-  GEN T = Edat->T, h = Edat->h, x, y;
-  long vT = get_Flx_var(T);
-  ulong p = Edat->pp;
-  if (ell_is_inf(P)) return gcopy(P);
-  x = gel(P,1), y = gel(P,2);
-  if (FlxX_equal(x, monomial(pol1_Flx(vT),1,0)) && FlxX_equal(y, monomial(pol1_Flx(vT),0,0)))
-    return Edat->X12;
-  else
-  {
-    GEN t1 = FlxX_Flx_add(FlxX_triple(FlxqXQ_sqr(x,h,T,p),p), Edat->a4, p);
-    GEN t2 = FlxqXQ_mul(FlxX_double(y, p), Edat->RHS, h, T, p);
-    GEN lambda = FlxqXQ_div(t1, t2, h, T, p);
-    GEN C = FlxX_sub(FlxqXQ_mul(FlxqXQ_sqr(lambda, h, T, p), Edat->RHS, h, T, p),
-                     FlxX_double(x, p), p);
-    GEN D = FlxX_sub(FlxqXQ_mul(lambda, FlxX_sub(x, C, p), h, T, p), y, p);
-    return gerepilecopy(ltop, mkvec2(C,D));
-  }
-}
-
-/* Returns the addition of [P[1], P[2]*Y] and of [Q[1], Q[2]*Y]
- * Computations are done modulo Y^2 - (X^3 + a4X + a6)
- * An inversion is equivalent to 4M, so that this function requires about 7M
- * which is the same as with the method using ell-division polynomials
- * Working in mixed projective coordinates would require 11M */
 static GEN
-eigenu_elladd(void *E, GEN P, GEN Q)
+Fq_to_Flx(GEN a4, GEN T, ulong p)
 {
-  pari_sp ltop = avma;
-  struct eigen_ellinit *Edat=(struct eigen_ellinit *)E;
-  GEN Px, Py, Qx, Qy;
-  GEN T = Edat->T, h = Edat->h, lambda, C, D;
-  ulong p = Edat->pp;
-  if (ell_is_inf(P)) return gcopy(Q);
-  if (ell_is_inf(Q)) return gcopy(P);
-  Px = gel(P,1); Py = gel(P,2);
-  Qx = gel(Q,1); Qy = gel(Q,2);
-  if (FlxX_equal(Px, Qx))
-  {
-    if (FlxX_equal(Py, Qy))
-      return eigenu_elldbl(E, P);
-    else
-      return ellinf();
-  }
-  lambda = FlxqXQ_div(FlxX_sub(Py, Qy, p), FlxX_sub(Px, Qx, p), h, T, p);
-  C = FlxX_sub(FlxX_sub(FlxqXQ_mul(FlxqXQ_sqr(lambda, h, T, p), Edat->RHS, h, T, p), Px, p), Qx, p);
-  D = FlxX_sub(FlxqXQ_mul(lambda, FlxX_sub(Px, C, p), h, T, p), Py, p);
-  return gerepilecopy(ltop, mkvec2(C,D));
+  return typ(a4)==t_INT ? Z_to_Flx(a4, p, get_Flx_var(T)): ZX_to_Flx(a4, p);
 }
 
 static GEN
-eigen_ellmulu(struct eigen_ellinit *E, GEN z, ulong n)
+Flxq_find_eigen_Frobenius(GEN a4, GEN a6, GEN h, GEN T, ulong p)
 {
-  pari_sp av = avma;
-  if (!n || ell_is_inf(z)) return mkvec(gen_0);
-  if (n == 1) return gcopy(z);
-  if (E->pp)
-    return gerepileupto(av, gen_powu(z, n, E, &eigenu_elldbl, &eigenu_elladd));
-  else
-    return gerepileupto(av, gen_powu(z, n, E, &eigen_elldbl, &eigen_elladd));
+  long v = get_FlxqX_var(h);
+  GEN RHS = FlxqX_rem(rhs(a4, a6, v), h, T, p);
+  return FlxqXQ_halfFrobenius(RHS, h, T, p);
 }
 
 static GEN
-Fq_to_Flx(GEN a4, GEN T, ulong p)
+Fq_find_eigen_Frobenius(GEN a4, GEN a6, GEN h, GEN T, GEN p)
 {
-  return typ(a4)==t_INT ? Z_to_Flx(a4, p, get_FpX_var(T)): ZX_to_Flx(a4, p);
+  long v = T ? get_FpXQX_var(h): get_FpX_var(h);
+  GEN RHS  = FqX_rem(rhs(a4, a6, v), h, T, p);
+  return T ? FpXQXQ_halfFrobenius(RHS, h, T, p):
+             FpXQ_pow(RHS, shifti(p, -1), h, p);
 }
-
 /*Finds the eigenvalue of the Frobenius given E, ell odd prime, h factor of the
  *ell-division polynomial, p and tr the possible values for the trace
  *(useful for primes with one root)*/
 static ulong
-find_eigen_value(GEN a4, GEN a6, ulong ell, GEN h, GEN T, GEN p, GEN tr)
+find_eigen_value_oneroot(GEN a4, GEN a6, ulong ell, GEN tr, GEN h, GEN T, GEN p)
 {
   pari_sp ltop = avma;
-  GEN BP, Dr;
   ulong t;
-  struct eigen_ellinit Edat;
-  ulong pp = T ?itou_or_0(p): 0;
-  if (pp)
-  {
-    GEN Tp = ZXT_to_FlxT(T, pp);
-    GEN hp  = ZXXT_to_FlxXT(h, pp, get_FpX_var(T));
-    init_eigenu(&Edat, Fq_to_Flx(a4, T, pp), Fq_to_Flx(a6, T, pp),
-        FlxqX_get_red(hp, Tp, pp), Tp, pp);
-  }
-  else
-    init_eigen(&Edat, a4, a6, FqX_get_red(h, T, p), T, p);
-  Dr = BP = Edat.O;
-  /*[Gx,Gy], BP, Dr are not points on the curve. */
-  /*To obtain the corresponding points, multiply the y-coordinates by Y */
-  if (!tr)
-  {
-    pari_sp btop = avma;
-    for (t = 1; t <= (ell>>1); t++)
-    {
-      if (gequal(gel(Dr,2), Edat.Gy))  { avma = ltop; return t; }
-      if (gequal(gel(Dr,2), Edat.nGy)) { avma = ltop; return ell-t; }
-      Dr = pp ? eigenu_elladd(&Edat, Dr, BP): eigen_elladd(&Edat, Dr, BP);
-      Dr = gerepileupto(btop, Dr);
-    }
-  }
-  else
+  struct divpolmod_red d;
+  GEN f, Dy, Gy;
+  h = FqX_get_red(h, T, p);
+  Gy = Fq_find_eigen_Frobenius(a4, a6, h, T, p);
+  t = Fl_div(tr[1], 2, ell);
+  if (t < (ell>>1)) t = ell - t;
+  Fq_elldivpolmod_init(&d, a4, a6, t, h, T, p);
+  f = Fq_ellyn(&d, t);
+  Dy = FqXQ_mul(Gy, gel(f,2), h, T, p);
+  if (!gequal(gel(f,1), Dy)) t = ell-t;
+  Fq_elldivpolmod_close(&d);
+  avma = ltop; return t;
+}
+
+static ulong
+Flxq_find_eigen_value_power(GEN a4, GEN a6, ulong ell, long k, ulong lambda,
+                            GEN h, GEN T, ulong p)
+{
+  pari_sp ltop = avma;
+  ulong t, ellk1 = upowuu(ell, k-1), ellk = ell*ellk1;
+  pari_timer ti;
+  struct divpolmod_red d;
+  GEN Gy;
+  timer_start(&ti);
+  h = FlxqX_get_red(h, T, p);
+  Gy = Flxq_find_eigen_Frobenius(a4, a6, h, T, p);
+  if (DEBUGLEVEL>2) err_printf(" (%ld ms)",timer_delay(&ti));
+  Flxq_elldivpolmod_init(&d, a4, a6, ellk, h, T, p);
+  for (t = lambda; t < ellk; t += ellk1)
   {
-    t = Fl_div(tr[1], 2, ell);
-    if (t < (ell>>1)) t = ell - t;
-    Dr = eigen_ellmulu(&Edat, BP, t);
-    if (gequal(gel(Dr,2), Edat.Gy)) { avma = ltop; return t; }
-    if (gequal(gel(Dr,2), Edat.nGy)) { avma = ltop; return ell - t; }
+    GEN f = Fq_ellyn(&d, t);
+    GEN Dr = FlxqXQ_mul(Gy, gel(f,2), h, T, p);
+    if (varn(gel(f,1))!=varn(Dr)) pari_err_BUG("find_eigen_value_power");
+    if (gequal(gel(f,1), Dr)) break;
+    if (gequal(gel(f,1), FlxX_neg(Dr,p))) { t = ellk-t; break; }
   }
-  pari_err_BUG("find_eigen_value"); return 0; /* NOT REACHED */
+  if (DEBUGLEVEL>2) err_printf(" (%ld ms)",timer_delay(&ti));
+  Fq_elldivpolmod_close(&d);
+  avma = ltop; return t;
 }
 
 /*Finds the eigenvalue of the Frobenius modulo ell^k given E, ell, k, h factor
  *of the ell-division polynomial, lambda the previous eigen value and p */
 static ulong
-find_eigen_value_power(GEN a4, GEN a6, ulong ell, long k, GEN h, ulong lambda, GEN T, GEN p)
+Fq_find_eigen_value_power(GEN a4, GEN a6, ulong ell, long k, ulong lambda, GEN h, GEN T, GEN p)
 {
   pari_sp ltop = avma;
-  pari_sp btop;
-  struct eigen_ellinit Edat;
-  GEN BP, Dr, Gy, nGy;
-  /*[Gx,Gy], BP, Dr are not points on the curve. */
-  /*To obtain the corresponding points, multiply the y-coordinates by Y */
   ulong t, ellk1 = upowuu(ell, k-1), ellk = ell*ellk1;
-  ulong pp = T ?itou_or_0(p): 0;
-  if (pp)
+  pari_timer ti;
+  struct divpolmod_red d;
+  GEN Gy;
+  timer_start(&ti);
+  h = FqX_get_red(h, T, p);
+  Gy = Fq_find_eigen_Frobenius(a4, a6, h, T, p);
+  if (DEBUGLEVEL>2) err_printf(" (%ld ms)",timer_delay(&ti));
+  Fq_elldivpolmod_init(&d, a4, a6, ellk, h, T, p);
+  for (t = lambda; t < ellk; t += ellk1)
   {
-    GEN Tp = ZXT_to_FlxT(T, pp);
-    GEN hp  = ZXXT_to_FlxXT(h, pp, get_FpX_var(T));
-    init_eigenu(&Edat, Fq_to_Flx(a4, T, pp), Fq_to_Flx(a6, T, pp),
-        FlxqX_get_red(hp, Tp, pp), Tp, pp);
+    GEN f = Fq_ellyn(&d, t);
+    GEN Dr = FqXQ_mul(Gy, gel(f,2), h, T, p);
+    if (varn(gel(f,1))!=varn(Dr)) pari_err_BUG("find_eigen_value_power");
+    if (gequal(gel(f,1), Dr)) break;
+    if (gequal(gel(f,1), FqX_neg(Dr,T,p))) { t = ellk-t; break; }
   }
-  else
-    init_eigen(&Edat, a4, a6, FqX_get_red(h, T, p), T, p);
-  BP = eigen_ellmulu(&Edat, Edat.O, ellk1);
-  Dr = eigen_ellmulu(&Edat, Edat.O, lambda);
-  Gy = Edat.Gy; nGy = Edat.nGy;
+  if (DEBUGLEVEL>2) err_printf(" (%ld ms)",timer_delay(&ti));
+  Fq_elldivpolmod_close(&d);
+  avma = ltop; return t;
+}
 
-  btop = avma;
-  for (t = 0; t < ellk; t += ellk1)
+static ulong
+find_eigen_value_power(GEN a4, GEN a6, ulong ell, long k, ulong lambda, GEN hq, GEN T, GEN p)
+{
+  ulong pp = itou_or_0(p);
+  if (pp && T)
   {
-    if (gequal(gel(Dr,2), Gy))  { avma = ltop; return t+lambda; }
-    if (gequal(gel(Dr,2), nGy)) { avma = ltop; return ellk-(t+lambda); }
-    Dr = pp ? eigenu_elladd(&Edat, Dr, BP): eigen_elladd(&Edat, Dr, BP);
-    if (gc_needed(btop, 1))
-      Dr = gerepileupto(btop, Dr);
+    GEN a4p = ZX_to_Flx(a4, pp);
+    GEN a6p = ZX_to_Flx(a6, pp);
+    GEN hp = ZXXT_to_FlxXT(hq, pp,varn(a4));
+    GEN Tp = ZXT_to_FlxT(T, pp);
+    return Flxq_find_eigen_value_power(a4p, a6p, ell, k, lambda, hp, Tp, pp);
   }
-  pari_err_BUG("find_eigen_value_power");
-  return 0; /* NOT REACHED */
+  return Fq_find_eigen_value_power(a4, a6, ell, k, lambda, hq, T, p);
 }
 
 /*Finds the kernel polynomial h, dividing the ell-division polynomial from the
@@ -1056,7 +1146,7 @@ Flxq_study_eqn(long ell, GEN mpoly, GEN T, ulong p, long *pt_dG, long *pt_r)
     *pt_r = (ell + 1)/s;
     return NULL;
   }
-  return G;
+  return gel(FlxqX_roots(G, T, p), 1);
 }
 
 static GEN
@@ -1085,8 +1175,7 @@ FpXQ_study_eqn(long ell, GEN mpoly, GEN T, GEN p, long *pt_dG, long *pt_r)
     GEN Tp = ZXT_to_FlxT(T,pp);
     GEN mpolyp = ZXX_to_FlxX(mpoly,pp,get_FpX_var(T));
     G = Flxq_study_eqn(ell, mpolyp, Tp, pp, pt_dG, pt_r);
-    if (!G) return NULL;
-    G = FlxX_to_ZXX(G);
+    return G ? Flx_to_ZX(G): NULL;
   }
   else
   {
@@ -1100,8 +1189,8 @@ FpXQ_study_eqn(long ell, GEN mpoly, GEN T, GEN p, long *pt_dG, long *pt_r)
       *pt_r = (ell + 1)/s;
       return NULL;
     }
+    return gel(FpXQX_roots(G, T, p), 1);
   }
-  return gel(FqX_roots(G, T, p), 1);
 }
 
 /* Berlekamp variant */
@@ -1146,7 +1235,7 @@ find_trace_Elkies_power(GEN a4, GEN a6, ulong ell, long k, struct meqn *MEQN, GE
   ulong lambda, ellk = upowuu(ell, k), pellk = umodiu(q, ellk);
   long cnt;
 
-  if (DEBUGLEVEL) { err_printf("Trace mod %ld", ell); }
+  if (DEBUGLEVEL) { err_printf("mod %ld", ell); }
   Eba4 = a4;
   Eba6 = a6;
   tmp = find_isogenous(a4,a6, ell, MEQN, g, T, p);
@@ -1155,7 +1244,8 @@ find_trace_Elkies_power(GEN a4, GEN a6, ulong ell, long k, struct meqn *MEQN, GE
   Eca6 =  gel(tmp, 2);
   kpoly = gel(tmp, 3);
   Ib = pol_x(0);
-  lambda = find_eigen_value(a4, a6, ell, kpoly, T, p, tr);
+  lambda = tr ? find_eigen_value_oneroot(a4, a6, ell, tr, kpoly, T, p):
+                find_eigen_value_power(a4, a6, ell, 1, 1, kpoly, T, p);
   if (DEBUGLEVEL>1) err_printf(" [%ld ms]", timer_delay(ti));
   if (smallfact && ell>smallfact)
   {
@@ -1170,7 +1260,7 @@ find_trace_Elkies_power(GEN a4, GEN a6, ulong ell, long k, struct meqn *MEQN, GE
     if (DEBUGLEVEL) err_printf(", %Ps", powuu(ell, cnt));
     tmp = find_kernel_power(Eba4, Eba6, Eca4, Eca6, ell, MEQN, kpoly, Ib, T, p);
     if (!tmp) { avma = ltop; return NULL; }
-    lambda = find_eigen_value_power(a4, a6, ell, cnt, gel(tmp,3), lambda, T, p);
+    lambda = find_eigen_value_power(a4, a6, ell, cnt, lambda, gel(tmp,3), T, p);
     Eba4 = Eca4;
     Eba6 = Eca6;
     Eca4 = gel(tmp,1);
@@ -1251,7 +1341,7 @@ find_trace(GEN a4, GEN a6, GEN j, ulong ell, GEN q, GEN T, GEN p, long *ptr_kt,
   struct meqn MEQN;
   pari_timer ti;
 
-  kt = maxss((long)(log(expi(q)*LOG2)/log(ell)), 1);
+  kt = maxss((long)(log(expi(q)*LOG2)/log((double)ell)), 1);
   if (DEBUGLEVEL)
   { err_printf("SEA: Prime %5ld ", ell); timer_start(&ti); }
   (void) get_modular_eqn(&MEQN, ell, vx, vy);
@@ -1719,8 +1809,9 @@ get_FqE_group(void ** pt_E, GEN a4, GEN a6, GEN T, GEN p)
   else if (lgefint(p)==3)
   {
     ulong pp = uel(p,2);
-    return get_FlxqE_group(pt_E, Fq_to_Flx(a4, T, pp), Fq_to_Flx(a6, T, pp),
-                           ZXT_to_FlxT(T,pp),pp);
+    GEN Tp = ZXT_to_FlxT(T,pp);
+    return get_FlxqE_group(pt_E, Fq_to_Flx(a4, Tp, pp), Fq_to_Flx(a6, Tp, pp),
+                           Tp, pp);
   }
   return get_FpXQE_group(pt_E,a4,a6,T,p);
 }
@@ -1749,7 +1840,7 @@ Fq_ellcard_SEA(GEN a4, GEN a6, GEN q, GEN T, GEN p, long smallfact)
     return T ? FpXQ_ellcard(Fq_to_FpXQ(a4, T, p), Fq_to_FpXQ(a6, T, p), T, p)
              : Fp_ellcard(a4, a6, p);
   /*First compute the trace modulo 2 */
-  switch(FqX_nbroots(mkpoln(4, gen_1, gen_0, a4, a6), T, p))
+  switch(FqX_nbroots(rhs(a4, a6, 0), T, p))
   {
   case 3: /* bonus time: 4 | #E(Fq) = q+1 - t */
     i = mod4(q)+1; if (i > 2) i -= 4;
diff --git a/src/basemath/elltors.c b/src/basemath/elltors.c
index 605c780..b82033f 100644
--- a/src/basemath/elltors.c
+++ b/src/basemath/elltors.c
@@ -404,7 +404,7 @@ static GEN
 tor2(GEN E, GEN x) { return mkvec2(x, gmul2n(gneg(ec_h_evalx(E,x)), -1)); }
 
 static GEN
-ptor0()
+ptor0(void)
 { return mkvec2(mkvec(gen_1),cgetg(1,t_VEC)); }
 static GEN
 ptor1(long p, long n, GEN P)
diff --git a/src/basemath/galconj.c b/src/basemath/galconj.c
index 4d4490b..862f272 100644
--- a/src/basemath/galconj.c
+++ b/src/basemath/galconj.c
@@ -32,7 +32,7 @@ static int is2sparse(GEN x)
 static GEN
 galoisconj1(GEN nf)
 {
-  GEN x = get_nfpol(nf, &nf), y, z;
+  GEN x = get_nfpol(nf, &nf), f = nf? nf : x, y, z;
   long i, lz, v = varn(x), nbmax;
   pari_sp av = avma;
   RgX_check_ZX(x, "nfgaloisconj");
@@ -50,9 +50,8 @@ galoisconj1(GEN nf)
     gel(res,2) = pol_x(v);
     return res;
   }
-  y = x;
   x = leafcopy(x); setvarn(x, fetch_var_higher());
-  z = nfroots(y, x); lz = lg(z);
+  z = nfroots(f, x); lz = lg(z);
   y = cgetg(lz, t_COL);
   for (i = 1; i < lz; i++)
   {
@@ -242,13 +241,14 @@ vandermondeinverse(GEN L, GEN T, GEN den, GEN prep)
   long i, n = lg(L)-1;
   GEN M, P;
   if (!prep) prep = vandermondeinverseprep(L);
+  if (den && !equali1(den)) T = RgX_Rg_mul(T,den);
   M = cgetg(n+1, t_MAT);
   for (i = 1; i <= n; i++)
   {
     P = RgX_Rg_div(RgX_div_by_X_x(T, gel(L,i), NULL), gel(prep,i));
     gel(M,i) = RgX_to_RgC(P,n);
   }
-  return den? gerepileupto(ltop, gmul(den, M)): gerepilecopy(ltop, M);
+  return gerepilecopy(ltop, M);
 }
 
 /* #r = r1 + r2 */
@@ -1084,29 +1084,6 @@ fixedfieldinclusion(GEN O, GEN PL)
   return S;
 }
 
-/*Usually mod > den so there is no need to reduce it.*/
-GEN
-vandermondeinversemod(GEN L, GEN T, GEN den, GEN mod)
-{
-  pari_sp av;
-  long i, n = lg(L);
-  GEN P, Tp, M = cgetg(n, t_MAT);
-  av = avma;
-  Tp = gclone(FpX_deriv(T,mod)); /*clone*/
-  avma = av;
-  for (i = 1; i < n; i++)
-  {
-    GEN z;
-    av = avma;
-    z = Fp_inv(FpX_eval(Tp, gel(L,i),mod),mod);
-    z = Fp_mul(den,z,mod);
-    P = FpX_Fp_mul(FpX_div_by_X_x(T, gel(L,i), mod, NULL), z, mod);
-    gel(M,i) = gerepilecopy(av, RgX_to_RgC(P, n-1));
-  }
-  gunclone(Tp); /*unclone*/
-  return M;
-}
-
 /* Polynomial associated to a vector of conjugates. Not stack clean */
 static GEN
 vectopol(GEN v, GEN M, GEN den , GEN mod, GEN mod2, long x)
@@ -1988,7 +1965,7 @@ galoisgenfixedfield(GEN Tp, GEN Pmod, GEN V, GEN ip, struct galois_borne *gb)
     }
     else if (Pgb.valabs < gb->valabs)
       PL = FpC_red(PL, Pgb.ladicabs);
-    PM = vandermondeinversemod(PL, P, Pden, Pgb.ladicabs);
+    PM = FpV_invVandermonde(PL, Pden, Pgb.ladicabs);
     PG = galoisgen(P, PL, PM, Pden, &Pgb, &Pga);
     if (PG == gen_0) return NULL;
     lP = lg(gel(PG,1));
@@ -2242,8 +2219,8 @@ galoisconj4_main(GEN T, GEN den, long flag)
   if (DEBUGLEVEL >= 1) timer_printf(&ti, "galoisborne()");
   L = ZpX_roots(T, gb.l, gb.valabs);
   if (DEBUGLEVEL >= 1) timer_printf(&ti, "ZpX_roots");
-  M = vandermondeinversemod(L, T, den, gb.ladicabs);
-  if (DEBUGLEVEL >= 1) timer_printf(&ti, "vandermondeinversemod()");
+  M = FpV_invVandermonde(L, den, gb.ladicabs);
+  if (DEBUGLEVEL >= 1) timer_printf(&ti, "FpV_invVandermonde()");
   if (n == 1)
   {
     G = cgetg(3, t_VEC);
@@ -2517,7 +2494,7 @@ galoisfixedfield(GEN gal, GEN perm, long flag, long y)
       L  = ZpX_liftroots(T, L, Pgb.l, Pgb.valabs);
       mod = Pgb.ladicabs; mod2 = shifti(mod,-1);
     }
-    PM = vandermondeinversemod(PL, P, Pden, mod);
+    PM = FpV_invVandermonde(PL, Pden, mod);
     if (y < 0) y = 1;
     if (varncmp(y, vT) <= 0)
       pari_err_PRIORITY("galoisfixedfield", T, "<=", y);
diff --git a/src/basemath/gen1.c b/src/basemath/gen1.c
index 1fe4646..b5095fe 100644
--- a/src/basemath/gen1.c
+++ b/src/basemath/gen1.c
@@ -228,7 +228,7 @@ rfrac_denom_mul_scal(GEN d, GEN y)
   GEN D = RgX_Rg_mul(d, y);
   if (lg(D) != lg(d))
   { /* try to generate a meaningful diagnostic */
-    D = gdiv(leading_term(d), y); /* should fail */
+    D = gdiv(leading_coeff(d), y); /* should fail */
     pari_err_INV("gred_rfrac", y); /* better than nothing */
   }
   return D;
diff --git a/src/basemath/gen2.c b/src/basemath/gen2.c
index b79a96d..32c24e6 100644
--- a/src/basemath/gen2.c
+++ b/src/basemath/gen2.c
@@ -1047,6 +1047,7 @@ gequal(GEN x, GEN y)
         av = avma; i = gequal0(gsub(x,y)); avma = av;
         return i;
       case t_POLMOD:
+        if (varn(gel(x,1)) != varn(gel(y,1))) break;
         return gequal(gel(x,2),gel(y,2)) && RgX_equal_var(gel(x,1),gel(y,1));
       case t_POL:
         return polequal(x,y);
@@ -2547,7 +2548,7 @@ normalize(GEN x)
   if (lx == 2) { setsigne(x,0); return x; }
   if (lx == 3) {
     z = gel(x,2);
-    if (!gcmp0(z)) { setsigne(x,1); return x; }
+    if (!gequal0(z)) { setsigne(x,1); return x; }
     if (isrationalzero(z)) return zeroser(vx,vp+1);
     if (isexactzero(z)) {
       /* dangerous case: already normalized ? */
@@ -2669,21 +2670,25 @@ gsigne(GEN x)
 static void
 ensure_nb(GEN L, long l)
 {
-  long nmax = list_nmax(L);
-  GEN v;
+  long nmax = list_nmax(L), i, lw;
+  GEN v, w;
   if (l <= nmax) return;
   if (nmax)
   {
     nmax <<= 1;
     if (l > nmax) nmax = l;
-    v = (GEN)pari_realloc(list_data(L), (nmax+1) * sizeof(long));
+    w = list_data(L); lw = lg(w);
+    v = newblock(nmax+1);
+    v[0] = w[0];
+    for (i=1; i < lw; i++) gel(v,i) = gel(w, i);
+    killblock(w);
   }
   else /* unallocated */
   {
     nmax = 32;
     if (list_data(L))
       pari_err(e_MISC, "store list in variable before appending elements");
-    v = (GEN)pari_malloc((nmax+1) * sizeof(long));
+    v = newblock(nmax+1);
     v[0] = evaltyp(t_VEC) | _evallg(1);
   }
   list_data(L) = v;
@@ -2699,7 +2704,7 @@ listkill(GEN L)
     GEN v = list_data(L);
     long i, l = lg(v);
     for (i=1; i<l; i++) gunclone_deep(gel(v,i));
-    pari_free(v);
+    killblock(v);
     L[1] = evaltyp(list_typ(L));
     list_data(L) = NULL;
   }
diff --git a/src/basemath/gen3.c b/src/basemath/gen3.c
index 8ff590b..bd98389 100644
--- a/src/basemath/gen3.c
+++ b/src/basemath/gen3.c
@@ -712,13 +712,9 @@ gmod(GEN x, GEN y)
         default: pari_err_TYPE2("%",x,y);
       }
     case t_REAL: case t_FRAC:
-      switch(tx)
-      {
-        case t_INT: case t_REAL: case t_FRAC:
-          av = avma;
-          return gerepileupto(av, gadd(x, gneg(gmul(_quot(x,y),y))));
-        default: pari_err_TYPE2("%",x,y);
-      }
+      if (!is_real_t(tx)) pari_err_TYPE2("%",x,y);
+      av = avma;
+      return gerepileupto(av, gadd(x, gneg(gmul(_quot(x,y),y))));
   }
   pari_err_TYPE2("%",x,y);
   return NULL; /* not reached */
@@ -1008,13 +1004,13 @@ gdivround(GEN x, GEN y)
 
   if (tx==t_INT && ty==t_INT) return diviiround(x,y);
   av = avma;
-  if (is_rational_t(tx) && is_rational_t(ty))
+  if (is_real_t(tx) && is_real_t(ty))
   { /* same as diviiround but less efficient */
     pari_sp av1;
     int fl;
     q = quotrem(x,y,&r);
     av1 = avma;
-    fl = gcmp(gmul2n(Q_abs_shallow(r),1), Q_abs_shallow(y));
+    fl = gcmp(gmul2n(R_abs_shallow(r),1), R_abs_shallow(y));
     avma = av1; cgiv(r);
     if (fl >= 0) /* If 2*|r| >= |y| */
     {
@@ -1174,7 +1170,7 @@ gsubst_expr(GEN expr, GEN from, GEN to)
 GEN
 gsubstpol(GEN x, GEN T, GEN y)
 {
-  if (typ(T) == t_POL && RgX_is_monomial(T) && gequal1(leading_term(T)))
+  if (typ(T) == t_POL && RgX_is_monomial(T) && gequal1(leading_coeff(T)))
   { /* T = t^d */
     long d = degpol(T), v = varn(T);
     pari_sp av = avma;
@@ -1185,9 +1181,8 @@ gsubstpol(GEN x, GEN T, GEN y)
   return gsubst_expr(x,T,y);
 }
 
-/* assume x non-constant */
-static long
-checkdeflate(GEN x)
+long
+RgX_deflate_order(GEN x)
 {
   ulong d = 0, i, lx = (ulong)lg(x);
   for (i=3; i<lx; i++)
@@ -1226,7 +1221,7 @@ serdeflate(GEN x, long v, long d)
   if (lx == 2) return zeroser(v, V / d);
   y = ser2pol_i(x, lx);
   dy = degpol(y);
-  if (V % d != 0 || (dy > 0 && checkdeflate(y) % d != 0))
+  if (V % d != 0 || (dy > 0 && RgX_deflate_order(y) % d != 0))
   {
     const char *s = stack_sprintf("valuation(x) %% %ld", d);
     pari_err_DOMAIN("gdeflate", s, "!=", gen_0,x);
@@ -1244,7 +1239,7 @@ poldeflate(GEN x, long v, long d)
   if (varncmp(vx, v) > 0 || degpol(x) <= 0) return gcopy(x);
   av = avma;
   /* x non-constant */
-  if (checkdeflate(x) % d != 0) return NULL;
+  if (RgX_deflate_order(x) % d != 0) return NULL;
   return gerepilecopy(av, RgX_deflate(x,d));
 }
 static GEN
@@ -1292,26 +1287,11 @@ gdeflate(GEN x, long v, long d)
 GEN
 RgX_deflate_max(GEN x, long *m)
 {
-  *m = checkdeflate(x);
+  *m = RgX_deflate_order(x);
   return RgX_deflate(x, *m);
 }
 
 GEN
-RgX_RgM_eval_col(GEN x, GEN M, long c)
-{
-  long i, n = lg(M)-1, lc = lg(x)-1;
-  GEN z;
-  if (signe(x)==0) return zerocol(n);
-  z = Rg_col_ei(gel(x, lc), n, c);
-  for (i=lc-1; i>=2; i--)
-  {
-    z = RgM_RgC_mul(M, z);
-    gel(z,c) = gadd(gel(z,c), gel(x, i));
-  }
-  return z;
-}
-
-GEN
 gsubst(GEN x, long v, GEN y)
 {
   long tx = typ(x), ty = typ(y), lx = lg(x), ly = lg(y);
@@ -1999,9 +1979,9 @@ integ(GEN x, long v)
       if (!gequal(gmul(s,b), gmul(a,gsqr(d)))) err_intformal(x);
       if (typ(y)==t_RFRAC && lg(gel(y,1)) == lg(gel(y,2)))
       {
-        GEN p2 = leading_term(gel(y,2));
+        GEN p2 = leading_coeff(gel(y,2));
         p1 = gel(y,1);
-        if (typ(p1) == t_POL && varn(p1) == vx) p1 = leading_term(p1);
+        if (typ(p1) == t_POL && varn(p1) == vx) p1 = leading_coeff(p1);
         y = gsub(y, gdiv(p1,p2));
       }
       return gerepileupto(av,y);
@@ -3237,7 +3217,7 @@ _rfraccoeff(GEN x, long n, long v)
   Q = (vq == v)? q: swap_vars(q, v);
   if (!RgX_is_monomial(Q)) pari_err_TYPE("polcoeff", x);
   n += degpol(Q);
-  return gdiv(_polcoeff(P, n, v), leading_term(Q));
+  return gdiv(_polcoeff(P, n, v), leading_coeff(Q));
 }
 
 GEN
diff --git a/src/basemath/hnf_snf.c b/src/basemath/hnf_snf.c
index 4f2e3cb..c48f3d0 100644
--- a/src/basemath/hnf_snf.c
+++ b/src/basemath/hnf_snf.c
@@ -715,7 +715,7 @@ gbezout_step(GEN *pa, GEN *pb, GEN *pu, GEN *pv, long vx)
   { /* possible accuracy problem */
     GEN D = RgX_gcd_simple(a,b);
     if (degpol(D)) {
-      D = RgX_Rg_div(D, leading_term(D));
+      D = RgX_Rg_div(D, leading_coeff(D));
       a = RgX_div(a, D);
       b = RgX_div(b, D);
       d = RgX_extgcd(a,b, pu,pv); /* retry now */
@@ -814,12 +814,12 @@ ZM_reduce(GEN A, GEN U, long i, long j0)
 static GEN
 RgX_normalize_all(GEN T, GEN *pd)
 {
-  GEN d = leading_term(T);
+  GEN d = leading_coeff(T);
   while (gequal0(d) || ( typ(d) == t_REAL && lg(d) == 3
                        && gexpo(T) - expo(d) > (long)BITS_IN_LONG)) {
      T = normalizepol_lg(T, lg(T)-1);
      if (!signe(T)) { *pd = gen_1; return T; }
-     d = leading_term(T);
+     d = leading_coeff(T);
   }
   *pd = d;
   return RgX_Rg_div(T, d);
@@ -1105,7 +1105,7 @@ zlm_echelon(GEN x, long early_abort, ulong p, ulong pm)
     /* pivot has valuation vmin */
     umin %= q;
     if (umin != 1)
-      Flc_Fl_mul_part_inplace(gel(x,def), Fl_inv(umin,q), pm, i-1);
+      Flv_Fl_mul_part_inplace(gel(x,def), Fl_inv(umin,q), pm, i-1);
     ucoeff(x, i, def) = pvmin = upowuu(p, vmin);
     for (j = def-1; j; j--)
     { /* zero x[i, 1..def-1] using x[i,def] = pvmin */
@@ -1194,11 +1194,11 @@ ZM_hnfmodall_i(GEN x, GEN dm, long flag)
         if (lgefint(gel(p2,k)) > LDM[k])
           gel(p2,k) = centermodii(gel(p2,k), gel(dm,k),gel(dm2,k));
       }
-      if (gc_needed(av,1))
-      {
-        if (DEBUGMEM>1) pari_warn(warnmem,"ZM_hnfmod[1]. i=%ld",i);
-        x = gerepilecopy(av, x);
-      }
+    }
+    if (gc_needed(av,1))
+    {
+      if (DEBUGMEM>1) pari_warn(warnmem,"ZM_hnfmod[1]. i=%ld",i);
+      x = gerepilecopy(av, x);
     }
     if (moddiag && !signe(gcoeff(x,i,def)))
     { /* missing pivot on line i, insert column */
@@ -1236,11 +1236,11 @@ ZM_hnfmodall_i(GEN x, GEN dm, long flag)
         ZC_elem(a, gcoeff(x,j,j), x, NULL, li,j);
         FpV_red_part_ipvec(gel(x,li), dm, j-1);
         FpV_red_part_ipvec(gel(x,j),  dm, j-1);
-        if (gc_needed(av,1))
-        {
-          if (DEBUGMEM>1) pari_warn(warnmem,"ZM_hnfmod[2]. i=%ld", i);
-          x = gerepilecopy(av, x);
-        }
+      }
+      if (gc_needed(av,1))
+      {
+        if (DEBUGMEM>1) pari_warn(warnmem,"ZM_hnfmod[2]. i=%ld", i);
+        x = gerepilecopy(av, x);
       }
     }
   }
@@ -1279,11 +1279,11 @@ ZM_hnfmodall_i(GEN x, GEN dm, long flag)
       p1 = gel(x,j);
       for (k=1; k<i; k++)
         if (lgefint(gel(p1,k)) > LDM[k]) gel(p1,k) = remii(gel(p1,k), gel(dm,i));
-      if (gc_needed(av,1))
-      {
-        if (DEBUGMEM>1) pari_warn(warnmem,"ZM_hnfmod[3]. i=%ld", i);
-        gerepileall(av, 2, &x, &dm); diag = gcoeff(x,i,i);
-      }
+    }
+    if (gc_needed(av,1))
+    {
+      if (DEBUGMEM>1) pari_warn(warnmem,"ZM_hnfmod[3]. i=%ld", i);
+      gerepileall(av, 2, &x, &dm); diag = gcoeff(x,i,i);
     }
   }
   return x;
@@ -1749,7 +1749,7 @@ ZM_hnfperm(GEN A, GEN *ptU, GEN *ptperm)
     }
     if (gc_needed(av1,1))
     {
-      if (DEBUGMEM>1) pari_warn(warnmem,"hnfperm");
+      if (DEBUGMEM>1) pari_warn(warnmem,"hnfperm, k=%ld",k);
       gerepileall(av1, U? 2: 1, &A, &U);
     }
   }
@@ -1954,7 +1954,7 @@ hnf_invimage(GEN A, GEN b)
   long n = lg(A)-1, m, i, k;
   GEN u, r;
 
-  if (!n) return NULL;
+  if (!n) return lg(b)==1? cgetg(1,t_COL):NULL;
   m = nbrows(A); /* m >= n */
   u = cgetg(n+1, t_COL);
   for (i = n, k = m; k > 0; k--)
diff --git a/src/basemath/hyperell.c b/src/basemath/hyperell.c
index 8588193..d4007a0 100644
--- a/src/basemath/hyperell.c
+++ b/src/basemath/hyperell.c
@@ -182,7 +182,7 @@ ZpXXQ_frob(GEN S, GEN U, GEN V, long k, GEN T, ulong p, long e)
     gel(R,2) = gel(M, i+1);
     if (degpol(R) < dT) continue;
     B = FpX_add(FpX_mulu(T, 2*i, q), Tp1, q);
-    c = frac_to_Fp(leading_term(R), leading_term(B), q);
+    c = frac_to_Fp(leading_coeff(R), leading_coeff(B), q);
     R = FpX_sub(R, FpX_Fp_mul(B, c, q), q);
     if (gc_needed(av2,1))
     {
@@ -192,7 +192,7 @@ ZpXXQ_frob(GEN S, GEN U, GEN V, long k, GEN T, ulong p, long e)
   }
   if (degpol(R)==dT-1)
   {
-    GEN c = frac_to_Fp(leading_term(R), leading_term(Tp), q);
+    GEN c = frac_to_Fp(leading_coeff(R), leading_coeff(Tp), q);
     R = FpX_sub(R, FpX_Fp_mul(Tp, c, q), q);
     return gerepileupto(av, R);
   } else
@@ -306,7 +306,7 @@ ZlX_hyperellpadicfrobenius(GEN H, ulong p, long n)
   N = n + logint(stoi(2*n), stoi(p), NULL);
   pN1 = powuu(p,N+1);
   Q = RgX_to_FpX(H, pN1);
-  if (dvdiu(leading_term(Q),p)) is_sing(H, p);
+  if (dvdiu(leading_coeff(Q),p)) is_sing(H, p);
   setvarn(Q,1);
   if (DEBUGLEVEL>1) timer_start(&ti);
   s = revdigits(FpX_digits(RgX_inflate(Q, p), Q, pN1));
@@ -343,7 +343,7 @@ INLINE GEN
 FpXXX_renormalize(GEN x, long lx)  { return ZXX_renormalize(x,lx); }
 
 static GEN
-FpXQXXQ_red(GEN F, GEN S, GEN T, GEN p)
+ZpXQXXQ_red(GEN F, GEN S, GEN T, GEN q, GEN p, long e)
 {
   pari_sp av = avma;
   long i, dF = degpol(F);
@@ -353,37 +353,37 @@ FpXQXXQ_red(GEN F, GEN S, GEN T, GEN p)
   C = pol_0(varn(S));
   for(i=dF; i>0; i--)
   {
-    GEN Fi = FpXX_add(C, gel(F,i+2), p);
-    GEN R, Q = FpXQX_divrem(Fi, S, T, p, &R);
+    GEN Fi = FpXX_add(C, gel(F,i+2), q);
+    GEN R, Q = ZpXQX_divrem(Fi, S, T, q, p, e, &R);
     gel(A,i+2) = R;
     C = Q;
   }
-  gel(A,2) = FpXX_add(C, gel(F,2), p);
+  gel(A,2) = FpXX_add(C, gel(F,2), q);
   A[1] = F[1];
   return gerepilecopy(av, FpXXX_renormalize(A,dF+3));
 }
 
 static GEN
-FpXQXXQ_sqr(GEN x, GEN S, GEN T, GEN p)
+ZpXQXXQ_sqr(GEN x, GEN S, GEN T, GEN q, GEN p, long e)
 {
   pari_sp av = avma;
   GEN z, kx;
   long n = degpol(S);
   kx = ZXX_to_Kronecker(x, n);
-  z = Kronecker_to_ZXX(FpXQX_sqr(kx, T, p), n, varn(S));
-  return gerepileupto(av, FpXQXXQ_red(z, S, T, p));
+  z = Kronecker_to_ZXX(FpXQX_sqr(kx, T, q), n, varn(S));
+  return gerepileupto(av, ZpXQXXQ_red(z, S, T, q, p, e));
 }
 
 static GEN
-FpXQXXQ_mul(GEN x, GEN y, GEN S, GEN T, GEN p)
+ZpXQXXQ_mul(GEN x, GEN y, GEN S, GEN T, GEN q, GEN p, long e)
 {
   pari_sp av = avma;
   GEN z, kx, ky;
   long n = degpol(S);
   kx = ZXX_to_Kronecker(x, n);
   ky = ZXX_to_Kronecker(y, n);
-  z = Kronecker_to_ZXX(FpXQX_mul(ky, kx, T, p), n, varn(S));
-  return gerepileupto(av, FpXQXXQ_red(z, S, T, p));
+  z = Kronecker_to_ZXX(FpXQX_mul(ky, kx, T, q), n, varn(S));
+  return gerepileupto(av, ZpXQXXQ_red(z, S, T, q, p, e));
 }
 
 static GEN
@@ -416,7 +416,7 @@ ZpXQXXQ_invsqrt(GEN F, GEN S, GEN T, ulong p, long e)
   ulong mask;
   long v = varn(F), n=1;
   pari_timer ti;
-  GEN a = pol_1(v);
+  GEN a = pol_1(v), pp = utoi(p);
   if (DEBUGLEVEL>1) timer_start(&ti);
   if (e <= 1) return gerepilecopy(av, a);
   mask = quadratic_prec_mask(e);
@@ -429,10 +429,10 @@ ZpXQXXQ_invsqrt(GEN F, GEN S, GEN T, ulong p, long e)
     mask >>= 1;
     q = powuu(p,n); q2 = powuu(p,n2);
     av3 = avma;
-    f = RgX_sub(FpXQXXQ_mul(F, FpXQXXQ_sqr(a, S, T, q), S, T, q), pol_1(v));
+    f = RgX_sub(ZpXQXXQ_mul(F, ZpXQXXQ_sqr(a, S, T, q, pp, n), S, T, q, pp, n), pol_1(v));
     fq = gerepileupto(av3, RgX_Rg_divexact(f, q2));
     q22 = shifti(addis(q2,1),-1);
-    afq = FpXXX_Fp_mul(FpXQXXQ_mul(a, fq, S, T, q2), q22, q2);
+    afq = FpXXX_Fp_mul(ZpXQXXQ_mul(a, fq, S, T, q2, pp, n2), q22, q2);
     a = RgX_sub(a, RgX_Rg_mul(afq, q2));
     if (gc_needed(av2,1))
     {
@@ -444,10 +444,10 @@ ZpXQXXQ_invsqrt(GEN F, GEN S, GEN T, ulong p, long e)
 }
 
 static GEN
-frac_to_Fq(GEN a, GEN b, GEN T, GEN p)
+frac_to_Fq(GEN a, GEN b, GEN T, GEN q, GEN p, long e)
 {
   GEN d = gcdii(ZX_content(a), ZX_content(b));
-  return FpXQ_div(ZX_Z_divexact(a, d), ZX_Z_divexact(b, d), T, p);
+  return ZpXQ_div(ZX_Z_divexact(a, d), ZX_Z_divexact(b, d), T, q, p, e);
 }
 
 static GEN
@@ -455,7 +455,7 @@ ZpXQXXQ_frob(GEN F, GEN U, GEN V, long k, GEN S, GEN T, ulong p, long e)
 {
   pari_sp av = avma, av2;
   long i, pr = degpol(F), dS = degpol(S), v = varn(T);
-  GEN q = powuu(p,e);
+  GEN q = powuu(p,e), pp = utoi(p);
   GEN Sp = RgX_deriv(S), Sp1 = RgX_shift_shallow(Sp, 1);
   GEN M = gel(F,pr+2), R;
   av2 = avma;
@@ -463,7 +463,7 @@ ZpXQXXQ_frob(GEN F, GEN U, GEN V, long k, GEN S, GEN T, ulong p, long e)
   {
     GEN A, B, H, Bc;
     ulong v, r;
-    H = FpXQX_divrem(FpXQX_mul(V, M, T, q), S, T, q, &B);
+    H = ZpXQX_divrem(FpXQX_mul(V, M, T, q), S, T, q, utoi(p), e, &B);
     A = FpXX_add(FpXQX_mul(U, M, T, q), FpXQX_mul(H, Sp, T, q),q);
     v = u_lvalrem(2*i+1,p,&r);
     Bc = RgX_deriv(B);
@@ -486,7 +486,7 @@ ZpXQXXQ_frob(GEN F, GEN U, GEN V, long k, GEN S, GEN T, ulong p, long e)
     gel(R,2) = gel(M, i+1);
     if (degpol(R) < dS) continue;
     B = FpXX_add(FpXX_mulu(S, 2*i, q), Sp1, q);
-    c = frac_to_Fq(to_ZX(leading_term(R),v), to_ZX(leading_term(B),v), T, q);
+    c = frac_to_Fq(to_ZX(leading_coeff(R),v), to_ZX(leading_coeff(B),v), T, q, pp, e);
     R = FpXX_sub(R, FpXQX_FpXQ_mul(B, c, T, q), q);
     if (gc_needed(av2,1))
     {
@@ -496,7 +496,7 @@ ZpXQXXQ_frob(GEN F, GEN U, GEN V, long k, GEN S, GEN T, ulong p, long e)
   }
   if (degpol(R)==dS-1)
   {
-    GEN c = frac_to_Fq(to_ZX(leading_term(R),v), to_ZX(leading_term(Sp),v), T, q);
+    GEN c = frac_to_Fq(to_ZX(leading_coeff(R),v), to_ZX(leading_coeff(Sp),v), T, q, pp, e);
     R = FpXX_sub(R, FpXQX_FpXQ_mul(Sp, c, T, q), q);
     return gerepileupto(av, R);
   } else
@@ -505,16 +505,16 @@ ZpXQXXQ_frob(GEN F, GEN U, GEN V, long k, GEN S, GEN T, ulong p, long e)
 
 
 static GEN
-Fq_diff_red(GEN s, GEN A, long m, GEN S, GEN T, GEN p)
+Fq_diff_red(GEN s, GEN A, long m, GEN S, GEN T, GEN q, GEN p, long e)
 {
   long v, n;
   GEN Q, sQ, qS;
   pari_timer ti;
   if (DEBUGLEVEL>1) timer_start(&ti);
-  Q = revdigits(FpXQX_digits(A, S, T, p));
+  Q = revdigits(ZpXQX_digits(A, S, T, q, p, e));
   n = degpol(Q);
   if (DEBUGLEVEL>1) timer_printf(&ti,"reddigits");
-  sQ = FpXQXXQ_mul(s,Q,S,T,p);
+  sQ = ZpXQXXQ_mul(s, Q, S, T, q, p, e);
   if (DEBUGLEVEL>1) timer_printf(&ti,"redmul");
   qS = RgX_shift_shallow(sQ,m-n);
   v = ZX_val(sQ);
@@ -524,8 +524,8 @@ Fq_diff_red(GEN s, GEN A, long m, GEN S, GEN T, GEN p)
     GEN rS = cgetg(l+1,t_VEC);
     for (i = l-1; i >=0 ; i--)
       gel(rS,i+1) = gel(sQ, 1+v+l-i);
-    rS = FpXQX_fromdigits(rS,S,T,p);
-    gel(qS,2) = FpXX_add(FpXQX_mul(rS, S, T, p), gel(qS, 2), p);
+    rS = FpXQX_fromdigits(rS,S,T,q);
+    gel(qS,2) = FpXX_add(FpXQX_mul(rS, S, T, q), gel(qS, 2), q);
     if (DEBUGLEVEL>1) timer_printf(&ti,"redadd");
   }
   return qS;
@@ -558,7 +558,7 @@ ZXX_to_FpXC(GEN x, long N, GEN p, long v)
     GEN xi = gel(x, i);
     gel(z,i) = typ(xi)==t_INT? scalarpol(Fp_red(xi, p), v): FpX_red(xi, p);
   }
-  for (   ; i<l ; i++)
+  for (   ; i<=N ; i++)
     gel(z,i) = pol_0(v);
   return z;
 }
@@ -567,8 +567,8 @@ GEN
 ZlXQX_hyperellpadicfrobenius(GEN H, GEN T, ulong p, long n)
 {
   pari_sp av = avma;
-  long k, N, i, d;
-  GEN xp, F, s, q, Q, pN1, U, V;
+  long k, N, i, d, N1;
+  GEN xp, F, s, q, Q, pN1, U, V, pp;
   pari_timer ti;
   if (typ(H) != t_POL) pari_err_TYPE("hyperellpadicfrobenius",H);
   if (p == 2) is_sing(H, 2);
@@ -577,19 +577,20 @@ ZlXQX_hyperellpadicfrobenius(GEN H, GEN T, ulong p, long n)
     pari_err_CONSTPOL("hyperellpadicfrobenius");
   if (n < 1)
     pari_err_DOMAIN("hyperellpadicfrobenius","n","<", gen_1, utoi(n));
-  k = get_basis(p, d);
-  N = n + logint(stoi(2*n), stoi(p), NULL);
-  q = powuu(p,n); pN1 = powuu(p,N+1); T = FpX_get_red(T, pN1);
+  k = get_basis(p, d); pp = utoi(p);
+  N = n + logint(stoi(2*n), pp, NULL);
+  q = powuu(p,n); N1 = N+1;
+  pN1 = powuu(p,N1); T = FpX_get_red(T, pN1);
   Q = RgX_to_FqX(H, T, pN1);
-  if (signe(FpX_red(to_ZX(leading_term(Q),varn(Q)),utoi(p)))==0) is_sing(H, p);
+  if (signe(FpX_red(to_ZX(leading_coeff(Q),varn(Q)),pp))==0) is_sing(H, p);
   if (DEBUGLEVEL>1) timer_start(&ti);
-  xp = ZpX_Frobenius(T, utoi(p), N+1);
+  xp = ZpX_Frobenius(T, pp, N1);
   s = RgX_inflate(FpXY_FpXQ_evalx(Q, xp, T, pN1), p);
-  s = revdigits(FpXQX_digits(s, Q, T, pN1));
+  s = revdigits(ZpXQX_digits(s, Q, T, pN1, pp, N1));
   if (DEBUGLEVEL>1) timer_printf(&ti,"s1");
   s = ZpXQXXQ_invsqrt(s, Q, T, p, N);
   if (k==3)
-    s = FpXQXXQ_mul(s, FpXQXXQ_sqr(s, Q, T, pN1), Q, T, pN1);
+    s = ZpXQXXQ_mul(s, ZpXQXXQ_sqr(s, Q, T, pN1, pp, N1), Q, T, pN1, pp, N1);
   if (DEBUGLEVEL>1) timer_printf(&ti,"invsqrt");
   Fq_get_UV(&U, &V, Q, T, p, N+1);
   if (DEBUGLEVEL>1) timer_printf(&ti,"get_UV");
@@ -598,9 +599,9 @@ ZlXQX_hyperellpadicfrobenius(GEN H, GEN T, ulong p, long n)
   {
     pari_sp av2 = avma;
     GEN M, D;
-    D = Fq_diff_red(s, monomial(utoi(p),p*i-1,1),(k*p-1)>>1, Q, T, pN1);
+    D = Fq_diff_red(s, monomial(pp,p*i-1,1),(k*p-1)>>1, Q, T, pN1, pp, N1);
     if (DEBUGLEVEL>1) timer_printf(&ti,"red");
-    M = ZpXQXXQ_frob(D, U, V, (k - 1)>>1, Q, T, p, N + 1);
+    M = ZpXQXXQ_frob(D, U, V, (k - 1)>>1, Q, T, p, N1);
     if (DEBUGLEVEL>1) timer_printf(&ti,"frob");
     gel(F, i) = gerepileupto(av2, ZXX_to_FpXC(M, d-1, q, varn(T)));
   }
@@ -722,12 +723,34 @@ Flx_genus2charpoly_naive(GEN H, ulong p)
   return mkvecsmalln(6, 0UL, p*p, a*p, (b+2*c+a*a)>>1, a, 1UL);
 }
 
+static GEN
+charpoly_funceq(GEN P, GEN q)
+{
+  long i, l, g = degpol(P)>>1;
+  GEN Q = cgetg_copy(P, &l);
+  Q[1] = P[1];
+  for (i=0; i<=g; i++)
+    gel(Q, i+2) = mulii(gel(P, 2*g-i+2), powiu(q, g-i));
+  for (; i<=2*g; i++)
+    gel(Q, i+2) = icopy(gel(P, i+2));
+  return Q;
+}
+
+static long
+hyperell_Weil_bound(GEN q, long g, GEN p)
+{
+  pari_sp av = avma;
+  GEN w = mulii(binomialuu(2*g,g),sqrtint(shifti(powiu(q, g),2)));
+  long e = logint(w, p, NULL);
+  avma = av; return e;
+}
+
 GEN
 hyperellcharpoly(GEN PQ)
 {
   pari_sp av = avma;
-  GEN H, M, R, T=NULL, pp=NULL;
-  long d, n, eps = 0;
+  GEN H, M, R, T=NULL, pp=NULL, q;
+  long d, g, n, eps = 0;
   ulong p;
   if (is_vec_t(typ(PQ)) && lg(PQ)==3)
     H = gadd(gsqr(gel(PQ, 2)), gmul2n(gel(PQ, 1), 2));
@@ -757,37 +780,42 @@ hyperellcharpoly(GEN PQ)
       }
     }
     H = RgX_to_FpX(H, pp);
-    d = degpol(H);
-    if (p > 2 && ((d == 5 && p < 20000) || (d == 6 && p < 45000)))
+    d = degpol(H); g = (d-1)>>1;
+    if (p > 2 && ((d == 5 && p < 17500) || (d == 6 && p < 24500)))
     {
       GEN Hp = ZX_to_Flx(H, p);
       if (!Flx_is_squarefree(Hp, p)) is_sing(H, p);
       R = zx_to_ZX(Flx_genus2charpoly_naive(Hp, p));
       return gerepileupto(av, R);
     }
-    n = (d>>1) + 1; eps = odd(d)? 0: Fp_issquare(leading_term(H), pp);
+    n = hyperell_Weil_bound(pp, g, pp);
+    eps = odd(d)? 0: Fp_issquare(leading_coeff(H), pp);
     M = hyperellpadicfrobenius(H, p, n);
     R = centerlift(carberkowitz(M, 0));
+    q = pp;
   }
   else
   {
     int fixvar;
     T = typ(T)==t_FFELT? FF_mod(T): RgX_to_FpX(T, pp);
+    q = powuu(p, degpol(T));
     fixvar = (varncmp(varn(T),varn(H)) <= 0);
     if (fixvar) setvarn(T, fetch_var());
     H = RgX_to_FpXQX(H, T, pp);
-    d = degpol(H); eps = odd(d)? 0: Fq_issquare(leading_term(H), T, pp);
-    n = ((degpol(T)*d)>>1) + 1;
+    d = degpol(H); eps = odd(d)? 0: Fq_issquare(leading_coeff(H), T, pp);
+    g = (d-1)>>1;
+    n = hyperell_Weil_bound(q, g, pp);
     M = nfhyperellpadicfrobenius(H, T, p, n);
-    R = centerlift(liftpol_shallow(carberkowitz(M, 0)));
+    R = simplify_shallow(centerlift(liftpol_shallow(carberkowitz(M, 0))));
     if (fixvar) (void)delete_var();
   }
   if (!odd(d))
   {
-    GEN q = get_basis(p, d) == 3 ? gen_1 : T ? powuu(p, degpol(T)): pp;
-    GEN v, Rx = RgX_div_by_X_x(R, eps? q: negi(q), &v);
-    if (signe(v)) pari_err_BUG("hyperellcharpoly");
-    return gerepilecopy(av, Rx);
+    GEN b = get_basis(p, d) == 3 ? gen_1 : q;
+    GEN pn = powuu(p, n);
+    R = FpX_div_by_X_x(R, eps? b: negi(b), pn, NULL);
+    R = FpX_center(R, pn, shifti(pn,-1));
   }
-  return gerepileupto(av, R);
+  R = charpoly_funceq(R, q);
+  return gerepilecopy(av, R);
 }
diff --git a/src/basemath/lfun.c b/src/basemath/lfun.c
index 0a4cd40..313bef0 100644
--- a/src/basemath/lfun.c
+++ b/src/basemath/lfun.c
@@ -517,13 +517,13 @@ lfunrtoR(GEN ldata, long prec)
 
 /* thetainit using {an: n <= L} */
 static GEN
-lfunthetainit0_bitprec(GEN ldata, GEN tdom, GEN vecan, long m,
+lfunthetainit0(GEN ldata, GEN tdom, GEN vecan, long m,
     long bitprec, long extrabit)
 {
   long prec = nbits2prec(bitprec);
   GEN tech, N = ldata_get_conductor(ldata);
   GEN Vga = ldata_get_gammavec(ldata);
-  GEN K = gammamellininvinit_bitprec(Vga, m, bitprec + extrabit);
+  GEN K = gammamellininvinit(Vga, m, bitprec + extrabit);
   GEN R = lfunrtoR(ldata, prec);
   if (!tdom) tdom = gen_1;
   if (typ(tdom) != t_VEC)
@@ -544,11 +544,11 @@ lfunthetainit_i(GEN data, GEN tdom, long m, long bitprec)
   GEN ldata = lfunmisc_to_ldata_shallow(data);
   long L = lfunthetacost(ldata, tdom, m, bitprec);
   GEN vecan = ldata_vecan(ldata_get_an(ldata), L, nbits2prec(bitprec));
-  return lfunthetainit0_bitprec(ldata, tdom, vecan, m, bitprec, 32);
+  return lfunthetainit0(ldata, tdom, vecan, m, bitprec, 32);
 }
 
 GEN
-lfunthetainit_bitprec(GEN ldata, GEN tdom, long m, long bitprec)
+lfunthetainit(GEN ldata, GEN tdom, long m, long bitprec)
 {
   pari_sp av = avma;
   GEN S = lfunthetainit_i(ldata, tdom? tdom: gen_1, m, bitprec);
@@ -556,12 +556,6 @@ lfunthetainit_bitprec(GEN ldata, GEN tdom, long m, long bitprec)
 }
 
 GEN
-lfunthetainit(GEN ldata, GEN tdom, long m, long prec)
-{
-  return lfunthetainit_bitprec(ldata, tdom, m, prec2nbits(prec));
-}
-
-GEN
 lfunan(GEN ldata, long L, long prec)
 {
   pari_sp av = avma;
@@ -719,7 +713,7 @@ theta1(GEN vecan, long limt, GEN t, GEN al, long prec)
   GEN vexp = gsqrpowers(q, limt), S = gen_0;
   pari_sp av = avma;
   long n;
-  if (gcmp0(al))
+  if (gequal0(al))
     for (n = 1; n <= limt; ++n)
     {
       GEN an = gel(vecan, n);
@@ -727,7 +721,7 @@ theta1(GEN vecan, long limt, GEN t, GEN al, long prec)
       S = gadd(S, gmul(an, gel(vexp, n)));
       if (gc_needed(av, 3)) S = gerepileupto(av, S);
     }
-  else if (gcmp1(al))
+  else if (gequal1(al))
   {
     for (n = 1; n <= limt; ++n)
     {
@@ -755,9 +749,9 @@ theta1(GEN vecan, long limt, GEN t, GEN al, long prec)
 }
 
 /* If m > 0, compute m-th derivative of theta(t) = theta0(t/sqrt(N))
- * with absolute error 2^-bitprec */
+ * with absolute error 2^-bitprec; theta(t)=\sum_{n\ge1}a(n)K(nt/N^(1/2)) */
 GEN
-lfuntheta_bitprec(GEN data, GEN t, long m, long bitprec)
+lfuntheta(GEN data, GEN t, long m, long bitprec)
 {
   pari_sp ltop = avma;
   long limt, d;
@@ -797,18 +791,13 @@ lfuntheta_bitprec(GEN data, GEN t, long m, long bitprec)
       if (gequal0(an)) continue;
       nt = gmul(gel(vroots,n), t);
       if (m) an = gmul(an, powuu(n, m));
-      S = gadd(S, gmul(an, gammamellininvrt_bitprec(K, nt, bitprecnew)));
+      S = gadd(S, gmul(an, gammamellininvrt(K, nt, bitprecnew)));
     }
     if (m) S = gdiv(S, gpowgs(sqN, m));
     return gerepileupto(ltop, S);
   }
 }
 
-/* theta(t)=\sum_{n\ge1}a(n)K(nt/N^(1/2)) */
-GEN
-lfuntheta(GEN data, GEN t, long m, long prec)
-{ return lfuntheta_bitprec(data, t, m, prec2nbits(prec)); }
-
 /*******************************************************************/
 /* Second part: Computation of L-Functions.                        */
 /*******************************************************************/
@@ -825,7 +814,7 @@ lfunparams(GEN ldata, long der, long bitprec, struct lfunp *S)
   const long derprec = (der > 1)? dbllog2(mpfact(der)): 0; /* log2(der!) */
   GEN Vga, N, L;
   long k, k1, d, m, M, flag, nmax;
-  double a, E, hd, Ep, d2, suma, maxs, mins, sub;
+  double a, E, hd, Ep, d2, suma, maxs, mins, sub, B0,B1, Lestimate, Mestimate;
 
   Vga = ldata_get_gammavec(ldata);
   S->d = d = lg(Vga)-1; d2 = d/2.;
@@ -873,30 +862,34 @@ lfunparams(GEN ldata, long der, long bitprec, struct lfunp *S)
   M = 1000;
   L = cgetg(M+2, t_VECSMALL);
   a = S->k1 + S->A;
+
+  B0 = 5 + S->E - S->sub + S->logC + S->k1*S->logN2; /* 5 extra bits */
+  B1 = S->hd * (S->MAXs - S->k1);
+  Lestimate = dblcoro526(a + S->MAXs - 2./d, d/2.,
+    S->E - S->sub + S->logC - log(2*M_PI*S->hd) + S->MAXs*S->logN2);
+  Mestimate = (log(Lestimate) + S->logN2) / S->hd;
   nmax = 0;
   flag = 0;
   for (m = 0;; m++)
   {
-    double mh = m*S->hd, H = S->logN2-mh;
-    double B = S->E + maxdd(mh*S->MAXs - S->sub, 0) + S->k1*H + S->logC;
-    double x = dblcoro526(a, d/2., B);
-    long n = floor(x*exp(H) + 0.5); /* 0.5: fudge factor */
+    double x, H = S->logN2 - m*S->hd, B = B0 + m*B1;
+    long n;
+    if (B < 0) B = 0;
+    x = dblcoro526(a, d/2., B);
+    n = floor(x*exp(H)); /* 0.5: fudge factor */
     if (n > nmax) nmax = n;
-    if (m > M)
-    {
-      M *= 2;
-      L = vecsmall_lengthen(L,M+2);
-    }
+    if (m > M) { M *= 2; L = vecsmall_lengthen(L,M+2); }
     L[m+1] = n;
-    if (n == 0) { if (++flag == 2) break; } else flag = 0;
+    if (n == 0) { if (++flag > 2 && m > Mestimate) break; } else flag = 0;
   }
-  if (m < 4) /* can happen for tiny bitprec */
+  /* can happen for tiny bitprec */
+  if (m < 4) { nmax = 1; L[1] = 1; m = 1; }
+  else
   {
-    m = 4;
-    nmax = 1;
-    L[1] = 1;
+    m -= 2;
+    while (!L[m]) m--;
   }
-  S->M = m-2; setlg(L, S->M+1);
+  setlg(L, m+1); S->M = m;
   S->L = L;
   S->nmax = nmax;
 
@@ -983,7 +976,7 @@ lfuninit_vecc(GEN theta, GEN h, struct lfunp *S)
       if (!p) continue; /* a_{n 2^v} = 0 for all v in range */
       t2d = mpmul(gel(vroots, n), gel(peh2d,m+1)); /*(n exp(mh)/sqrt(N))^(2/d)*/
       neval++;
-      kmn = gammamellininvrt_bitprec(K, t2d, p);
+      kmn = gammamellininvrt(K, t2d, p);
       for (mm=m,nn=n; mm>=0 && nn <= L[mm+1]; nn<<=1,mm-=m0)
         gmael(vK,mm+1,nn) = kmn;
     }
@@ -1149,7 +1142,7 @@ lfun_init_theta(GEN ldata, GEN eno, struct lfunp *S)
   }
   an = ldata_vecan(ldata_get_an(ldata), L, S->precmax);
   lfunparams2(ldata, an, S);
-  return lfunthetainit0_bitprec(ldata, tdom, an, 0, S->Dmax, 0);
+  return lfunthetainit0(ldata, tdom, an, 0, S->Dmax, 0);
 }
 
 GEN
@@ -1170,32 +1163,30 @@ lfuncost0(GEN L, GEN dom, long der, long bitprec)
   pari_sp av = avma;
   GEN C;
 
-  if (is_linit(L) && linit_get_type(L) == t_LDESC_PRODUCT)
+  if (is_linit(L))
   {
     GEN tech = linit_get_tech(L);
     GEN domain = lfun_get_domain(tech);
-    GEN v = lfunprod_get_fact(linit_get_tech(L));
-    GEN F = gel(v,1);
-    long i, l = lg(F);
     dom = domain_get_dom(domain);
     der = domain_get_der(domain);
     bitprec = domain_get_bitprec(domain);
-    C = cgetg(l, t_VEC);
-    for (i = 1; i < l; ++i)
-      gel(C, i) = zv_to_ZV( lfuncost(gel(F,i), dom, der, bitprec) );
-    C = gerepilecopy(av, C);
-  }
-  else
-  {
-    if (!dom) pari_err_TYPE("lfuncost [missing s domain]", L);
-    C = lfuncost(L,dom,der,bitprec);
-    C = gerepileupto(av, zv_to_ZV(C));
+    if (linit_get_type(L) == t_LDESC_PRODUCT)
+    {
+      GEN v = lfunprod_get_fact(linit_get_tech(L)), F = gel(v,1);
+      long i, l = lg(F);
+      C = cgetg(l, t_VEC);
+      for (i = 1; i < l; ++i)
+        gel(C, i) = zv_to_ZV( lfuncost(gel(F,i), dom, der, bitprec) );
+      return gerepileupto(av, C);
+    }
   }
-  return C;
+  if (!dom) pari_err_TYPE("lfuncost [missing s domain]", L);
+  C = lfuncost(L,dom,der,bitprec);
+  return gerepileupto(av, zv_to_ZV(C));
 }
 
 GEN
-lfuninit_bitprec(GEN lmisc, GEN dom, long der, long bitprec)
+lfuninit(GEN lmisc, GEN dom, long der, long bitprec)
 {
   pari_sp ltop = avma;
   GEN R, h, theta, ldata, qk, poqk, pol, eno, r, vecc, domain, molin;
@@ -1216,7 +1207,7 @@ lfuninit_bitprec(GEN lmisc, GEN dom, long der, long bitprec)
   if (ldata_get_type(ldata)==t_LFUN_NF)
   {
     GEN T = gel(ldata_get_an(ldata), 2);
-    return lfunzetakinit_bitprec(T, dom, der, 0, bitprec);
+    return lfunzetakinit(T, dom, der, 0, bitprec);
   }
   k = ldata_get_k(ldata);
   parse_dom(k, dom, &S);
@@ -1239,7 +1230,7 @@ lfuninit_bitprec(GEN lmisc, GEN dom, long der, long bitprec)
     R = theta_get_R(linit_get_tech(theta));
   else
   {
-    GEN v = lfunrootres_bitprec(theta, S.D);
+    GEN v = lfunrootres(theta, S.D);
     ldata = shallowcopy(ldata);
     gel(ldata, 6) = gel(v,3);
     r = gel(v,1);
@@ -1265,24 +1256,12 @@ lfuninit_bitprec(GEN lmisc, GEN dom, long der, long bitprec)
 }
 
 GEN
-lfuninit(GEN lmisc, GEN dom, long der, long prec)
-{
-  return lfuninit_bitprec(lmisc, dom, der, prec2nbits(prec));
-}
-
-GEN
-lfuninit0_bitprec(GEN lmisc, GEN dom, long der, long bitprec)
+lfuninit0(GEN lmisc, GEN dom, long der, long bitprec)
 {
-  GEN z = lfuninit_bitprec(lmisc, dom, der, bitprec);
+  GEN z = lfuninit(lmisc, dom, der, bitprec);
   return z == lmisc? gcopy(z): z;
 }
 
-GEN
-lfuninit0(GEN lmisc, GEN dom, long der, long prec)
-{
-  return lfuninit0_bitprec(lmisc, dom, der, prec2nbits(prec));
-}
-
 /* If s is a pole of Lambda, return polar part at s; else return NULL */
 static GEN
 lfunpoleresidue(GEN R, GEN s)
@@ -1398,14 +1377,14 @@ get_domain(GEN s, GEN *dom, long *der)
 /* assume lmisc is an linit, s went through get_domain and s/bitprec belong
  * to domain */
 static GEN
-lfunlambda_bitprec_OK(GEN linit, GEN s, long bitprec)
+lfunlambda_OK(GEN linit, GEN s, long bitprec)
 {
   GEN eno, ldata, tech, h, pol;
   GEN S, S0 = NULL, k2;
   long prec;
 
   if (linit_get_type(linit) == t_LDESC_PRODUCT)
-    return lfun_genproduct(linit, s, bitprec, lfunlambda_bitprec_OK);
+    return lfun_genproduct(linit, s, bitprec, lfunlambda_OK);
   ldata = linit_get_ldata(linit);
   eno = ldata_get_rootno(ldata);
   tech = linit_get_tech(linit);
@@ -1436,55 +1415,57 @@ lfunlambda_bitprec_OK(GEN linit, GEN s, long bitprec)
   return gprec_w(gmul(S,h), nbits2prec(bitprec));
 }
 GEN
-lfunlambda_bitprec(GEN lmisc, GEN s, long bitprec)
+lfunlambda(GEN lmisc, GEN s, long bitprec)
 {
   pari_sp av = avma;
   GEN linit, dom, z;
   long der;
   s = get_domain(s, &dom, &der);
-  linit = lfuninit_bitprec(lmisc, dom, der, bitprec);
-  z = lfunlambda_bitprec_OK(linit,s,bitprec);
+  linit = lfuninit(lmisc, dom, der, bitprec);
+  z = lfunlambda_OK(linit,s,bitprec);
   return gerepilecopy(av, z);
 }
-GEN
-lfunlambda(GEN lmisc, GEN s, long prec)
-{ return lfunlambda_bitprec(lmisc, s, prec2nbits(prec)); }
 
 /* assume lmisc is an linit, s went through get_domain and s/bitprec belong
  * to domain */
 static GEN
-lfun_bitprec_OK(GEN linit, GEN s, long bitprec)
+lfun_OK(GEN linit, GEN s, long bitprec)
 {
-  GEN N, gas, S, FVga, res;
+  GEN N, gas, S, FVga, res, ss = s;
   long prec = nbits2prec(bitprec);
 
   FVga = lfun_get_factgammavec(linit_get_tech(linit));
-  S = lfunlambda_bitprec_OK(linit, s, bitprec);
-  gas = gammafactproduct(FVga, s, prec);
+  S = lfunlambda_OK(linit, s, bitprec);
+  if (typ(S)==t_SER && typ(s)!=t_SER)
+  {
+    long d = fracgammadegree(gel(FVga,1));
+    ss = deg1ser_shallow(gen_1, s, varn(S), lg(S)+d-2);
+  }
+  gas = gammafactproduct(FVga, ss, prec);
   N = ldata_get_conductor(linit_get_ldata(linit));
-  res = gdiv(S, gmul(gpow(N, gdivgs(s, 2), prec), gas));
+  res = gdiv(S, gmul(gpow(N, gdivgs(ss, 2), prec), gas));
   if (typ(s)!=t_SER && typ(res)==t_SER)
   {
     long v = valp(res);
     if (v > 0) return gen_0;
     if (v == 0) res = gel(res, 2);
+    else
+      setlg(res, minss(lg(res), 2-v));
   }
   return gprec_w(res, prec);
 }
+
 GEN
-lfun_bitprec(GEN lmisc, GEN s, long bitprec)
+lfun(GEN lmisc, GEN s, long bitprec)
 {
   pari_sp av = avma;
   GEN linit, dom, z;
   long der;
   s = get_domain(s, &dom, &der);
-  linit = lfuninit_bitprec(lmisc, dom, der, bitprec);
-  z = lfun_bitprec_OK(linit,s,bitprec);
+  linit = lfuninit(lmisc, dom, der, bitprec);
+  z = lfun_OK(linit,s,bitprec);
   return gerepilecopy(av, z);
 }
-GEN
-lfun(GEN lmisc, GEN s, long prec)
-{ return lfun_bitprec(lmisc, s, prec2nbits(prec)); }
 
 /* given a t_SER a+x*s(x), return x*s(x), shallow */
 static GEN
@@ -1553,13 +1534,13 @@ lfunlambdaord(GEN linit, GEN s)
 
 /* derivative of order m > 0 of L (flag = 0) or Lambda (flag = 1) */
 static GEN
-lfunderiv_bitprec(GEN lmisc, long m, GEN s, long flag, long bitprec)
+lfunderiv(GEN lmisc, long m, GEN s, long flag, long bitprec)
 {
   pari_sp ltop = avma;
   GEN res, S = NULL, linit, dom;
   long der, prec = nbits2prec(bitprec);
   s = get_domain(s, &dom, &der);
-  linit = lfuninit_bitprec(lmisc, dom, der + m, bitprec);
+  linit = lfuninit(lmisc, dom, der + m, bitprec);
   if (typ(s) == t_SER)
   {
     long v, l = lg(s)-1;
@@ -1575,8 +1556,8 @@ lfunderiv_bitprec(GEN lmisc, long m, GEN s, long flag, long bitprec)
     /* HACK: pretend lfuninit was done to right accuracy */
     s = deg1ser_shallow(gen_1, s, 0, m+1+ex);
   }
-  res = flag ? lfunlambda_bitprec_OK(linit, s, bitprec):
-               lfun_bitprec_OK(linit, s, bitprec);
+  res = flag ? lfunlambda_OK(linit, s, bitprec):
+               lfun_OK(linit, s, bitprec);
   if (S)
     res = gsubst(derivnser(res, m), varn(S), S);
   else if (typ(res)==t_SER)
@@ -1592,31 +1573,21 @@ lfunderiv_bitprec(GEN lmisc, long m, GEN s, long flag, long bitprec)
 }
 
 GEN
-lfunlambda0_bitprec(GEN lmisc, GEN s, long der, long bitprec)
-{
-  return der ? lfunderiv_bitprec(lmisc, der, s, 1, bitprec):
-               lfunlambda_bitprec(lmisc, s, bitprec);
-}
-
-GEN
-lfunlambda0(GEN lmisc, GEN s, long der, long prec)
+lfunlambda0(GEN lmisc, GEN s, long der, long bitprec)
 {
-  return lfunlambda0_bitprec(lmisc, s, der, prec2nbits(prec));
+  return der ? lfunderiv(lmisc, der, s, 1, bitprec):
+               lfunlambda(lmisc, s, bitprec);
 }
 
 GEN
-lfun0_bitprec(GEN lmisc, GEN s, long der, long bitprec)
+lfun0(GEN lmisc, GEN s, long der, long bitprec)
 {
-  return der ? lfunderiv_bitprec(lmisc, der, s, 0, bitprec):
-               lfun_bitprec(lmisc, s, bitprec);
+  return der ? lfunderiv(lmisc, der, s, 0, bitprec):
+               lfun(lmisc, s, bitprec);
 }
 
 GEN
-lfun0(GEN lmisc, GEN s, long der, long prec)
-{ return lfun0_bitprec(lmisc, s, der, prec2nbits(prec)); }
-
-GEN
-lfunhardy_bitprec(GEN lmisc, GEN t, long bitprec)
+lfunhardy(GEN lmisc, GEN t, long bitprec)
 {
   pari_sp ltop = avma;
   long prec = nbits2prec(bitprec), k, d;
@@ -1633,7 +1604,7 @@ lfunhardy_bitprec(GEN lmisc, GEN t, long bitprec)
   k = ldata_get_k(ldata);
   d = ldata_get_degree(ldata);
   dom = mkvec3(dbltor(k/2.), gen_0, gabs(t,LOWDEFAULTPREC));
-  linit = lfuninit_bitprec(lmisc, dom, 0, bitprec);
+  linit = lfuninit(lmisc, dom, 0, bitprec);
   tech = linit_get_tech(linit);
   w2 = lfun_get_w2(tech);
   k2 = lfun_get_k2(tech);
@@ -1644,16 +1615,10 @@ lfunhardy_bitprec(GEN lmisc, GEN t, long bitprec)
   prec = precision(argz);
   a = gsub(gmulsg(d, gmul(t, gmul2n(argz,-1))),
            gmul(expot,glog(gnorm(z),prec)));
-  h = mulreal(lfunlambda_bitprec_OK(linit, z, bitprec), w2);
+  h = mulreal(lfunlambda_OK(linit, z, bitprec), w2);
   return gerepileupto(ltop, gmul(h, gexp(a, prec)));
 }
 
-GEN
-lfunhardy(GEN lmisc, GEN s, long prec)
-{
-  return lfunhardy_bitprec(lmisc, s, prec2nbits(prec));
-}
-
 /* L = log(t); return  \sum_{i = 0}^{v-1}  R[-i-1] L^i/i! */
 static GEN
 theta_pole_contrib(GEN R, long v, GEN L)
@@ -1686,7 +1651,7 @@ theta_add_polar_part(GEN S, GEN R, GEN t, long prec)
  * number are compatible with the functional equation at t0 and 1/t0.
  * Different from lfunrootres. */
 long
-lfuncheckfeq_bitprec(GEN lmisc, GEN t0, long bitprec)
+lfuncheckfeq(GEN lmisc, GEN t0, long bitprec)
 {
   GEN ldata, theta, t0i, S0, S0i, w, eno;
   long e, k, prec;
@@ -1697,7 +1662,7 @@ lfuncheckfeq_bitprec(GEN lmisc, GEN t0, long bitprec)
     GEN v = lfunprod_get_fact(linit_get_tech(lmisc)), F = gel(v,1);
     long i, b = -bitprec, l = lg(F);
     for (i = 1; i < l; i++)
-      b = maxss(b, lfuncheckfeq_bitprec(gel(F,i), t0, bitprec));
+      b = maxss(b, lfuncheckfeq(gel(F,i), t0, bitprec));
     return b;
   }
   av = avma;
@@ -1719,10 +1684,10 @@ lfuncheckfeq_bitprec(GEN lmisc, GEN t0, long bitprec)
   ldata = linit_get_ldata(theta);
   k = ldata_get_k(ldata);
   if (!ldata_isreal(ldata))
-    S0 = gconj(lfuntheta_bitprec(theta, gconj(t0), 0, bitprec));
+    S0 = gconj(lfuntheta(theta, gconj(t0), 0, bitprec));
   else
-    S0 = lfuntheta_bitprec(theta, t0, 0, bitprec);
-  S0i = lfuntheta_bitprec(theta, t0i, 0, bitprec);
+    S0 = lfuntheta(theta, t0, 0, bitprec);
+  S0i = lfuntheta(theta, t0i, 0, bitprec);
 
   eno = ldata_get_rootno(ldata);
   if (ldata_get_residue(ldata))
@@ -1735,29 +1700,25 @@ lfuncheckfeq_bitprec(GEN lmisc, GEN t0, long bitprec)
       { /* inefficient since theta not needed; no need to optimize for this
            (artificial) query [e.g. lfuncheckfeq(t_POL)] */
         GEN T = gel(ldata_get_an(ldata), 2);
-        GEN L = lfunzetakinit_bitprec(T,zerovec(3),0,0,bitprec);
-        long e = lfuncheckfeq_bitprec(L,t0,bitprec);
+        GEN L = lfunzetakinit(T,zerovec(3),0,0,bitprec);
+        long e = lfuncheckfeq(L,t0,bitprec);
         avma = av; return e;
       }
-      v = lfunrootres_bitprec(theta, bitprec);
+      v = lfunrootres(theta, bitprec);
       r = gel(v,1);
       if (gequal0(eno)) eno = gel(v,3);
       R = lfunrtoR_i(ldata, r, eno, nbits2prec(bitprec));
     }
     S0i = theta_add_polar_part(S0i, R, t0, prec);
   }
-  if (gcmp0(S0i) || gcmp0(S0)) pari_err_PREC("lfuncheckfeq");
+  if (gequal0(S0i) || gequal0(S0)) pari_err_PREC("lfuncheckfeq");
   w = gdiv(S0i, gmul(S0, gpowgs(t0, k)));
   /* missing rootno: guess it */
-  if (gequal0(eno)) eno = lfunrootno_bitprec(theta, bitprec);
+  if (gequal0(eno)) eno = lfunrootno(theta, bitprec);
   e = gexpo(gsub(w, eno));
   avma = av; return e;
 }
 
-long
-lfuncheckfeq(GEN data, GEN t0, long prec)
-{ return lfuncheckfeq_bitprec(data, t0, prec2nbits(prec)); }
-
 /*******************************************************************/
 /*       Compute root number and residues                          */
 /*******************************************************************/
@@ -1773,7 +1734,7 @@ ropm1(GEN eno, long prec)
 /* theta for t=1/sqrt(2) and t2==2t simultaneously, saving 25% of the work.
  * Assume correct initialization (no thetacheck) */
 static void
-lfunthetaspec_bitprec(GEN linit, long bitprec, GEN *pv, GEN *pv2)
+lfunthetaspec(GEN linit, long bitprec, GEN *pv, GEN *pv2)
 {
   pari_sp av = avma;
   GEN t, Vga, an, K, ldata, thetainit, v, v2, vroots;
@@ -1787,8 +1748,8 @@ lfunthetaspec_bitprec(GEN linit, long bitprec, GEN *pv, GEN *pv2)
   {
     GEN v2 = sqrtr(real2n(1, nbits2prec(bitprec)));
     GEN v = shiftr(v2,-1);
-    *pv = lfuntheta_bitprec(linit, v,  0, bitprec);
-    *pv2= lfuntheta_bitprec(linit, v2, 0, bitprec);
+    *pv = lfuntheta(linit, v,  0, bitprec);
+    *pv2= lfuntheta(linit, v2, 0, bitprec);
     return;
   }
   an = RgV_kill0( theta_get_an(thetainit) );
@@ -1809,7 +1770,7 @@ lfunthetaspec_bitprec(GEN linit, long bitprec, GEN *pv, GEN *pv2)
 
     if (!a) continue;
     tn = gmul(t, gel(vroots,n));
-    Kn = gammamellininvrt_bitprec(K, tn, bitprec);
+    Kn = gammamellininvrt(K, tn, bitprec);
     v = gadd(v, gmul(a,Kn));
   }
   /* v += \sum_{n <= L, n even} a_n K(nt), v2 = \sum_{n <= L/2} a_n K(2n t) */
@@ -1819,7 +1780,7 @@ lfunthetaspec_bitprec(GEN linit, long bitprec, GEN *pv, GEN *pv2)
 
     if (!a && !a2) continue;
     t2n = gmul(t, gel(vroots,2*n));
-    K2n = gammamellininvrt_bitprec(K, t2n, bitprec);
+    K2n = gammamellininvrt(K, t2n, bitprec);
     if (a) v2 = gadd(v2, gmul(a, K2n));
     if (a2) v = gadd(v,  gmul(a2,K2n));
   }
@@ -1854,7 +1815,7 @@ get_eno(GEN R, long k, GEN t, GEN v, GEN vi, long vx, long bitprec)
 /* Return w using theta(1/t) - w t^k \bar{theta}(t) = polar_part(t,w).
  * The full Taylor development of L must be known */
 GEN
-lfunrootno_bitprec(GEN linit, long bitprec)
+lfunrootno(GEN linit, long bitprec)
 {
   GEN ldata, t, eno, v, vi, R;
   long k, prec = nbits2prec(bitprec), vx = fetch_var();
@@ -1867,11 +1828,11 @@ lfunrootno_bitprec(GEN linit, long bitprec)
   R = ldata_get_residue(ldata)? lfunrtoR_eno(ldata, pol_x(vx), prec)
                               : cgetg(1, t_VEC);
   t = gen_1;
-  v = lfuntheta_bitprec(linit, t, 0, bitprec);
+  v = lfuntheta(linit, t, 0, bitprec);
   eno = get_eno(R,k,t,v,v, vx, bitprec);
   if (!eno)
   { /* t = sqrt(2), vi = theta(1/t), v = theta(t) */
-    lfunthetaspec_bitprec(linit, bitprec, &vi, &v);
+    lfunthetaspec(linit, bitprec, &vi, &v);
     t = sqrtr(utor(2, prec));
     eno = get_eno(R,k,t,v,vi, vx, bitprec);
   }
@@ -1879,16 +1840,13 @@ lfunrootno_bitprec(GEN linit, long bitprec)
   while (!eno)
   {
     t = addsr(1, shiftr(utor(pari_rand(), prec), -66)); /* in [1,1.25[ */
-    v = lfuntheta_bitprec(linit, t, 0, bitprec);
-    vi= lfuntheta_bitprec(linit, ginv(t), 0, bitprec);
+    v = lfuntheta(linit, t, 0, bitprec);
+    vi= lfuntheta(linit, ginv(t), 0, bitprec);
     eno = get_eno(R,k,t,v,vi, vx, bitprec);
     avma = av;
   }
   delete_var(); return ropm1(eno,prec);
 }
-GEN
-lfunrootno(GEN L, long prec)
-{ return lfunrootno_bitprec(L, prec2nbits(prec)); }
 
 static int
 residues_known(GEN r)
@@ -1902,7 +1860,7 @@ residues_known(GEN r)
 /* Find root number and/or residues when L-function coefficients and
    conductor are known. For the moment at most a single residue allowed. */
 GEN
-lfunrootres_bitprec(GEN data, long bitprec)
+lfunrootres(GEN data, long bitprec)
 {
   pari_sp ltop = avma;
   GEN w, r, R, a, b, c, d, e, f, dete, th1, th2;
@@ -1915,7 +1873,7 @@ lfunrootres_bitprec(GEN data, long bitprec)
   if (r && typ(r) != t_VEC) r = mkvec(mkvec2(stoi(k), simple_pole(r)));
   if (!r || residues_known(r))
   {
-    w = lfunrootno_bitprec(data, bitprec);
+    w = lfunrootno(data, bitprec);
     if (!r)
       r = R = gen_0;
     else
@@ -1930,11 +1888,11 @@ lfunrootres_bitprec(GEN data, long bitprec)
   w = ldata_get_rootno(ldata);
   if (ldata_isreal(ldata) && gequalm1(w))
   {
-    GEN R = lfuntheta_bitprec(linit, gen_1, 0, bitprec);
+    GEN R = lfuntheta(linit, gen_1, 0, bitprec);
     r = Rtor(be, R, ldata, prec);
     return gerepilecopy(ltop, mkvec3(r, R, gen_m1));
   }
-  lfunthetaspec_bitprec(linit, bitprec, &v2, &v);
+  lfunthetaspec(linit, bitprec, &v2, &v);
   if (gequalgs(gmulsg(2, be), k)) pari_err_IMPL("pole at k/2 in lfunrootres");
   if (gequalgs(be, k))
   {
@@ -1956,8 +1914,8 @@ lfunrootres_bitprec(GEN data, long bitprec)
   else
   { /* Now residue unknown, r = [[be,0]], and w unknown. */
     t0  = mkfrac(stoi(11),stoi(10));
-    th1 = lfuntheta_bitprec(linit, t0,  0, bitprec);
-    th2 = lfuntheta_bitprec(linit, ginv(t0), 0, bitprec);
+    th1 = lfuntheta(linit, t0,  0, bitprec);
+    th2 = lfuntheta(linit, ginv(t0), 0, bitprec);
     tbe = gpow(t0, gmulsg(2, be), prec);
     tkbe = gpow(t0, gsubsg(k, be), prec);
     tk2 = gpowgs(t0, k);
@@ -1972,10 +1930,6 @@ lfunrootres_bitprec(GEN data, long bitprec)
   return gerepilecopy(ltop, mkvec3(r, R, ropm1(w, prec)));
 }
 
-GEN
-lfunrootres(GEN data, long prec)
-{ return lfunrootres_bitprec(data, prec2nbits(prec)); }
-
 /*******************************************************************/
 /*                           Zeros                                 */
 /*******************************************************************/
@@ -1989,13 +1943,13 @@ lfunhardyzeros(void *E, GEN t)
 {
   struct lhardyz_t *S = (struct lhardyz_t*)E;
   long prec = S->prec;
-  GEN h = lfunhardy_bitprec(S->linit, t, S->bitprec);
+  GEN h = lfunhardy(S->linit, t, S->bitprec);
   if (typ(h) == t_REAL && realprec(h) < prec) h = gprec_w(h, prec);
   return h;
 }
 
 static GEN
-lfuncenterinit_bitprec(GEN lmisc, double h, long bitprec)
+lfuncenterinit(GEN lmisc, double h, long bitprec)
 {
   GEN ldata = lfunmisc_to_ldata_shallow(lmisc);
   long k = ldata_get_k(ldata);
@@ -2006,11 +1960,11 @@ lfuncenterinit_bitprec(GEN lmisc, double h, long bitprec)
     if (sdomain_isincl(k, dom, lfun_get_dom(tech))) return lmisc;
   }
   /* initialize for zero of order <= 4 */
-  return lfuninit_bitprec(ldata, dom, 4, bitprec);
+  return lfuninit(ldata, dom, 4, bitprec);
 }
 
 long
-lfunorderzero_bitprec(GEN lmisc, long bitprec)
+lfunorderzero(GEN lmisc, long bitprec)
 {
   pari_sp ltop = avma;
   GEN eno, ldata, linit, k2;
@@ -2020,10 +1974,10 @@ lfunorderzero_bitprec(GEN lmisc, long bitprec)
   {
     GEN M = gmael(linit_get_tech(lmisc), 2,1);
     long i;
-    for (c=0,i=1; i < lg(M); i++) c += lfunorderzero_bitprec(gel(M,i), bitprec);
+    for (c=0,i=1; i < lg(M); i++) c += lfunorderzero(gel(M,i), bitprec);
     return c;
   }
-  linit = lfuncenterinit_bitprec(lmisc, 0, bitprec);
+  linit = lfuncenterinit(lmisc, 0, bitprec);
   ldata = linit_get_ldata(linit);
   eno = ldata_get_rootno(ldata);
   G = -bitprec/2;
@@ -2036,38 +1990,34 @@ lfunorderzero_bitprec(GEN lmisc, long bitprec)
   k = ldata_get_k(ldata);
   k2 = gdivgs(stoi(k), 2);
   for (c = c0;; c += st)
-    if (gexpo(lfun0_bitprec(linit, k2, c, bitprec)) > G) break;
+    if (gexpo(lfun0(linit, k2, c, bitprec)) > G) break;
   avma = ltop; return c;
 }
 
-long
-lfunorderzero(GEN ldata, long prec)
-{ return lfunorderzero_bitprec(ldata, prec2nbits(prec)); }
-
 GEN
-lfunzeros_bitprec(GEN ldata, GEN lim, long divz, long bitprec)
+lfunzeros(GEN ldata, GEN lim, long divz, long bitprec)
 {
   pari_sp ltop = avma;
   GEN ldataf, linit, N, pi2, cN, pi2div, w, T, Vga, h1, h2;
   long i, d, W, NEWD, precinit, ct, s, prec = nbits2prec(bitprec);
   double maxt;
+  GEN maxtr, maxtr1;
   struct lhardyz_t S;
 
-  h1 = gen_0;
   if (typ(lim) == t_VEC)
   {
-    if (lg(lim) != 3) pari_err_TYPE("lfunzeros",lim);
-    h1 = gel(lim,1);
-    h2 = gel(lim,2);
-    maxt = maxdd(fabs(gtodouble(h1)), fabs(gtodouble(h2)));
+    if (lg(lim) != 3 || gcmp(gel(lim,1),gel(lim,2)) >= 0
+                     || gcmp(gel(lim,1),gen_0) <= 0)
+      pari_err_TYPE("lfunzeros",lim);
+    h1 = gel(lim,1); h2 = gel(lim,2);
   }
   else
   {
-    h2 = lim;
-    maxt = fabs(gtodouble(h2));
+    if (gcmp(lim,gen_0) <= 0)
+      pari_err_TYPE("lfunzeros",lim);
+    h1 = gen_0; h2 = lim;
   }
-  if (!is_rational_t(typ(h1))) h1 = bestappr(h1, int2n(64));
-  if (!is_rational_t(typ(h2))) h2 = bestappr(h2, int2n(64));
+  maxt = gtodouble(h2);
 
   if (is_linit(ldata) && linit_get_type(ldata) == t_LDESC_PRODUCT)
   {
@@ -2075,10 +2025,10 @@ lfunzeros_bitprec(GEN ldata, GEN lim, long divz, long bitprec)
     long l = lg(M);
     v = cgetg(l, t_VEC);
     for (i = 1; i < l; i++)
-      gel(v,i) = lfunzeros_bitprec(gel(M,i), lim, divz, bitprec);
+      gel(v,i) = lfunzeros(gel(M,i), lim, divz, bitprec);
     return gerepileupto(ltop, vecsort0(shallowconcat1(v), NULL, 0));
   }
-  S.linit = linit = lfuncenterinit_bitprec(ldata, maxt, bitprec);
+  S.linit = linit = lfuncenterinit(ldata, maxt + 1, bitprec);
   S.bitprec = bitprec;
   S.prec = prec;
   ldataf = linit_get_ldata(linit);
@@ -2098,7 +2048,7 @@ lfunzeros_bitprec(GEN ldata, GEN lim, long divz, long bitprec)
     GEN r = ldata_get_residue(ldataf);
     if (!r || gequal0(r))
     {
-      ct = lfunorderzero_bitprec(linit, bitprec);
+      ct = lfunorderzero(linit, bitprec);
       if (ct) T = real2n(-prec2nbits(prec)/(2*ct), prec);
     }
   }
@@ -2106,7 +2056,8 @@ lfunzeros_bitprec(GEN ldata, GEN lim, long divz, long bitprec)
   W = 100 + ct; w = cgetg(W+1,t_VEC);
   for (i=1; i<=ct; i++) gel(w,i) = gen_0;
   s = gsigne(lfunhardyzeros(&S, T));
-  while (gcmpgs(T, maxt) < 0)
+  maxtr = h2; maxtr1 = gaddsg(1, maxtr);
+  while (gcmp(T, maxtr1) < 0)
   {
     pari_sp av = avma;
     GEN T0 = T, z;
@@ -2119,13 +2070,13 @@ lfunzeros_bitprec(GEN ldata, GEN lim, long divz, long bitprec)
       else
         L = cN;
       T = gadd(T, gdiv(pi2div, L));
-      if (gcmpgs(T, maxt) > 0) goto END;
+      if (gcmp(T, maxtr1) > 0) goto END;
       s0 = gsigne(lfunhardyzeros(&S, T));
       if (s0 != s) { s = s0; break; }
     }
     T = gerepileupto(av, T);
     z = zbrent(&S, lfunhardyzeros, T0, T, prec);
-    if (gcmpgs(z, maxt) > 0) break;
+    if (gcmp(z, maxtr) > 0) break;
     if (typ(z) == t_REAL) z  = rtor(z, precinit);
     /* room for twice as many zeros */
     if (ct >= W) { W *= 2; w = vec_lengthen(w, W); }
@@ -2135,10 +2086,6 @@ END:
   setlg(w, ct+1); return gerepilecopy(ltop, w);
 }
 
-GEN
-lfunzeros(GEN ldata, GEN lim, long divz, long prec)
-{ return lfunzeros_bitprec(ldata, lim, divz, prec2nbits(prec)); }
-
 /*******************************************************************/
 /*       Guess conductor                                           */
 /*******************************************************************/
@@ -2164,8 +2111,8 @@ wrap1(void *E, GEN M)
   *(S->psqrtM) = gsqrt(M, prec);
 
   tk = gpowgs(t, S->k);
-  p1 = lfuntheta_bitprec(data, t, 0, bitprec);
-  p1inv = lfuntheta_bitprec(data, ginv(t), 0, bitprec);
+  p1 = lfuntheta(data, t, 0, bitprec);
+  p1inv = lfuntheta(data, ginv(t), 0, bitprec);
   return glog(gabs(gmul(tk, gdiv(p1, p1inv)), prec), prec);
 }
 
@@ -2187,10 +2134,10 @@ wrap2(void *E, GEN M)
   *(S->pM) = M;
   *(S->psqrtM) = gsqrt(M, prec);
 
-  p1 = lfuntheta_bitprec(data, t1, 0, bitprec);
-  p2 = lfuntheta_bitprec(data, t2, 0, bitprec);
-  p1inv = lfuntheta_bitprec(data, ginv(t1), 0, bitprec);
-  p2inv = lfuntheta_bitprec(data, ginv(t2), 0, bitprec);
+  p1 = lfuntheta(data, t1, 0, bitprec);
+  p2 = lfuntheta(data, t2, 0, bitprec);
+  p1inv = lfuntheta(data, ginv(t1), 0, bitprec);
+  p2inv = lfuntheta(data, ginv(t2), 0, bitprec);
   t1k = gpowgs(t1, k);
   t2k = gpowgs(t2, k);
   R = theta_get_R(thetainit);
@@ -2260,7 +2207,7 @@ parse_maxcond(GEN maxcond, GEN *pm, GEN *pM)
 }
 
 GEN
-lfunconductor_bitprec(GEN data, GEN maxcond, long flag, long bitprec)
+lfunconductor(GEN data, GEN maxcond, long flag, long bitprec)
 {
   struct huntcond_t S;
   pari_sp ltop = avma;
@@ -2290,10 +2237,3 @@ lfunconductor_bitprec(GEN data, GEN maxcond, long flag, long bitprec)
   v = solvestep((void*)&S, eval, m, M, gen_2, 14, nbits2prec(bitprec));
   return gerepilecopy(ltop, checkconductor(v, bitprec/2, flag));
 }
-
-GEN
-lfunconductor(GEN data, GEN maxcond, long flag, long prec)
-{
-  return lfunconductor_bitprec(data, maxcond, flag, prec2nbits(prec));
-}
-
diff --git a/src/basemath/lfunutils.c b/src/basemath/lfunutils.c
index d46e499..7021310 100644
--- a/src/basemath/lfunutils.c
+++ b/src/basemath/lfunutils.c
@@ -97,7 +97,7 @@ lfunconvolinv(GEN a1, GEN a2)
 { return tag(mkvec2(a1,a2), t_LFUN_DIV); }
 
 static GEN
-lfunmulpoles(GEN ldata1, GEN ldata2, long prec)
+lfunmulpoles(GEN ldata1, GEN ldata2, long bitprec)
 {
   long k = ldata_get_k(ldata1), l, j;
   GEN r1 = ldata_get_residue(ldata1);
@@ -119,13 +119,13 @@ lfunmulpoles(GEN ldata1, GEN ldata2, long prec)
   for (j = 1; j < l; j++)
   {
     GEN be = gel(r1,j);
-    GEN z1 = lfun(ldata1,be,prec), z2 = lfun(ldata2,be,prec);
+    GEN z1 = lfun(ldata1,be,bitprec), z2 = lfun(ldata2,be,bitprec);
     if (typ(z1) == t_SER && typ(z2) == t_SER)
     { /* pole of both, recompute to needed seriesprecision */
       long e = valp(z1) + valp(z2);
       GEN b = RgX_to_ser(deg1pol_shallow(gen_1, be, 0), 3-e);
-      z1 = lfun(ldata1,b,prec);
-      z2 = lfun(ldata2,b,prec);
+      z1 = lfun(ldata1,b,bitprec);
+      z2 = lfun(ldata2,b,bitprec);
     }
     gel(r,j) = mkvec2(be, gmul(z1, z2));
   }
@@ -133,7 +133,7 @@ lfunmulpoles(GEN ldata1, GEN ldata2, long prec)
 }
 
 GEN
-lfunmul(GEN ldata1, GEN ldata2, long prec)
+lfunmul(GEN ldata1, GEN ldata2, long bitprec)
 {
   pari_sp ltop = avma;
   GEN r, N, Vga, sd, eno, a1a2, LD;
@@ -143,7 +143,7 @@ lfunmul(GEN ldata1, GEN ldata2, long prec)
   k = ldata_get_k(ldata1);
   if (ldata_get_k(ldata2) != k)
     pari_err_OP("lfunmul [weight]",ldata1, ldata2);
-  r = lfunmulpoles(ldata1, ldata2, prec);
+  r = lfunmulpoles(ldata1, ldata2, bitprec);
   N = gmul(ldata_get_conductor(ldata1), ldata_get_conductor(ldata2));
   Vga = vecsort0(gconcat(ldata_get_gammavec(ldata1), ldata_get_gammavec(ldata2)), NULL, 0);
   eno = gmul(ldata_get_rootno(ldata1), ldata_get_rootno(ldata2));
@@ -155,7 +155,7 @@ lfunmul(GEN ldata1, GEN ldata2, long prec)
 }
 
 static GEN
-lfundivpoles(GEN ldata1, GEN ldata2, long prec)
+lfundivpoles(GEN ldata1, GEN ldata2, long bitprec)
 {
   long k = ldata_get_k(ldata1), i, j, l;
   GEN r1 = ldata_get_residue(ldata1);
@@ -170,7 +170,7 @@ lfundivpoles(GEN ldata1, GEN ldata2, long prec)
   for (i = j = 1; j < l; j++)
   {
     GEN be = gel(r1,j);
-    GEN z = gdiv(lfun(ldata1,be,prec), lfun(ldata2,be,prec));
+    GEN z = gdiv(lfun(ldata1,be,bitprec), lfun(ldata2,be,bitprec));
     if (valp(z) < 0) gel(r,i++) = mkvec2(be, z);
   }
   if (i == 1) return NULL;
@@ -178,7 +178,7 @@ lfundivpoles(GEN ldata1, GEN ldata2, long prec)
 }
 
 GEN
-lfundiv(GEN ldata1, GEN ldata2, long prec)
+lfundiv(GEN ldata1, GEN ldata2, long bitprec)
 {
   pari_sp ltop = avma;
   GEN r, N, v, v1, v2, sd, eno, a1a2, LD;
@@ -188,7 +188,7 @@ lfundiv(GEN ldata1, GEN ldata2, long prec)
   k = ldata_get_k(ldata1);
   if (ldata_get_k(ldata2) != k)
     pari_err_OP("lfundiv [weight]",ldata1, ldata2);
-  r = lfundivpoles(ldata1, ldata2, prec);
+  r = lfundivpoles(ldata1, ldata2, bitprec);
   N = gdiv(ldata_get_conductor(ldata1), ldata_get_conductor(ldata2));
   if (typ(N) != t_INT) pari_err_OP("lfundiv [conductor]",ldata1, ldata2);
   a1a2 = lfunconvolinv(ldata_get_an(ldata1), ldata_get_an(ldata2));
@@ -228,8 +228,8 @@ lfunzeta(void)
   return zet;
 }
 static GEN
-lfunzetainit_bitprec(GEN dom, long der, long bitprec)
-{ return lfuninit_bitprec(lfunzeta(), dom, der, bitprec); }
+lfunzetainit(GEN dom, long der, long bitprec)
+{ return lfuninit(lfunzeta(), dom, der, bitprec); }
 
 static GEN
 vecan_Kronecker(GEN D, long n)
@@ -396,7 +396,8 @@ vecan_chigen(GEN an, long n, long prec)
         if (check && idealval(nf, N, pr)) continue;
         ch = chigeneval(isprincipalray(bnr,pr), nchi, z, prec);
         q = itou(pr_norm(pr));
-        for (k = q; k <= (ulong)n; k += q)
+        gel(v, q) = gadd(gel(v, q), ch);
+        for (k = 2*q; k <= (ulong)n; k += q)
           gel(v, k) = gaddmul(gel(v, k), ch, gel(v, k/q));
       }
     }
@@ -528,7 +529,7 @@ lfunzetak(GEN T)
 
 /* bnf = NULL: base field = Q */
 GEN
-lfunabelianrelinit_bitprec(GEN nfabs, GEN bnf, GEN polrel, GEN dom, long der, long bitprec)
+lfunabelianrelinit(GEN nfabs, GEN bnf, GEN polrel, GEN dom, long der, long bitprec)
 {
   pari_sp ltop = avma;
   GEN cond, chi, cnj, res, bnr, M, domain;
@@ -549,7 +550,7 @@ lfunabelianrelinit_bitprec(GEN nfabs, GEN bnf, GEN polrel, GEN dom, long der, lo
   for (i = 1; i < l; ++i)
   {
     GEN L = lfunchigen(bnr, gel(chi,i));
-    gel(res, i) = lfuninit_bitprec(L, dom, der, bitprec);
+    gel(res, i) = lfuninit(L, dom, der, bitprec);
   }
   if (v >= 0) delete_var();
   M = mkvec3(res, const_vecsmall(l-1, 1), cnj);
@@ -557,12 +558,6 @@ lfunabelianrelinit_bitprec(GEN nfabs, GEN bnf, GEN polrel, GEN dom, long der, lo
   return gerepilecopy(ltop, lfuninit_make(t_LDESC_PRODUCT, lfunzetak_i(nfabs), M, domain));
 }
 
-GEN
-lfunabelianrelinit(GEN nfabs, GEN bnf, GEN polrel, GEN dom, long der, long prec)
-{
-  return lfunabelianrelinit_bitprec(nfabs, bnf, polrel, dom, der, prec2nbits(prec));
-}
-
 /*****************************************************************/
 /*                 Dedekind zeta functions                       */
 /*****************************************************************/
@@ -571,7 +566,7 @@ dirzetak0(GEN nf, ulong N)
 {
   GEN vect, c, c2, T = nf_get_pol(nf), index = nf_get_index(nf);
   pari_sp av = avma, av2;
-  const ulong SQRTN = (ulong)(sqrt(N) + 1e-3);
+  const ulong SQRTN = usqrt(N);
   ulong i, p, lx;
   long court[] = {evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3),0};
   forprime_t S;
@@ -659,97 +654,91 @@ lfunproduct(GEN ldata, GEN linit1, GEN linit2, GEN domain)
   return lfuninit_make(t_LDESC_PRODUCT, ldata, M3, domain);
 }
 
-/* Initialization without assuming Artin's conjecture. */
 static GEN
-lfunzetaKinit_bitprec(GEN T, GEN dom, long der, long bitprec)
+lfunzetakinit_raw(GEN T, GEN dom, long der, long bitprec)
 {
   pari_sp ltop = avma;
   GEN ldata = lfunzetak_i(T);
-  return gerepileupto(ltop, lfuninit_bitprec(ldata, dom, der, bitprec));
+  return gerepileupto(ltop, lfuninit(ldata, dom, der, bitprec));
 }
 
-/* From now on we assume the Artin conjecture that z_K(s) is divisible by
-* z_k(s) for all subfields k of K. The output is always a d-component
-* vector of lfuninits (including d=1), of which we must take the product.
-* nf is a true nf */
 static GEN
-lfunzetaKQinit_bitprec(GEN nf, GEN dom, long der, long bitprec)
-{
-  pari_sp ltop = avma;
-  GEN an, Vga, ldata, N, LKQ, LQ, domain, T = nf_get_pol(nf);
-  long r1, r2;
-
-  LQ = lfunzetainit_bitprec(dom, der, bitprec);
-  if (degpol(T) == 1) return LQ;
-  N = absi(nf_get_disc(nf));
-  nf_get_sign(nf,&r1,&r2);
-  Vga = vec01(r1+r2-1,r2);
-  an = tag(mkvec2(tag(nf, t_LFUN_NF), tag(gen_1, t_LFUN_ZETA)), t_LFUN_DIV);
-  ldata = mkvecn(6, an, gen_0, Vga, gen_1, N, gen_1);
-  LKQ = lfuninit_bitprec(ldata, dom, der, bitprec); /* zeta_K/zeta */
-  domain = mkvec2(dom, mkvecsmall2(der, bitprec));
-  return gerepilecopy(ltop, lfunproduct(lfunzetak_i(nf), LKQ, LQ, domain));
-}
-
-/* nf is a true nf */
-static GEN
-lfunzetaKkinit_bitprec(GEN nf, GEN dom, long der, long bitprec)
+lfunzetakinit_quotient(GEN nf, GEN polk, GEN dom, long der, long bitprec)
 {
   pari_sp av = avma;
-  GEN an, nfs, polk, nfk, Vga, ldata, N, Lk, LKk, domain;
-  long r1k, r2k, r1, r2, nsub;
+  GEN ak, an, nfk, Vga, ldata, N, Lk, LKk, domain;
+  long r1k, r2k, r1, r2;
 
-  nfs = nfsubfields(nf, 0);
-  nsub = lg(nfs)-1;
-  if (nsub <= 2)
-    return gerepilecopy(av, lfunzetaKQinit_bitprec(nf, dom, der, bitprec));
   nf_get_sign(nf,&r1,&r2);
-  polk = gel(gel(nfs, nsub-1), 1); /* k largest strict subfield, != Q */
   nfk = nfinit(polk, nbits2prec(bitprec));
-  Lk = lfunzetakinit_bitprec(nfk, dom, der, 0, bitprec); /* zeta_k */
+  Lk = lfunzetakinit(nfk, dom, der, 0, bitprec); /* zeta_k */
   nf_get_sign(nfk,&r1k,&r2k);
   Vga = vec01((r1+r2) - (r1k+r2k), r2-r2k);
   N = absi(diviiexact(nf_get_disc(nf), nf_get_disc(nfk)));
-  an = tag(mkvec2(tag(nf,t_LFUN_NF), tag(nfk,t_LFUN_NF)), t_LFUN_DIV);
+  ak = nf_get_degree(nf)==1 ? tag(gen_1, t_LFUN_ZETA): tag(nfk, t_LFUN_NF);
+  an = tag(mkvec2(tag(nf,t_LFUN_NF), ak), t_LFUN_DIV);
   ldata = mkvecn(6, an, gen_0, Vga, gen_1, N, gen_1);
-  LKk = lfuninit_bitprec(ldata, dom, der, bitprec); /* zeta_K/zeta_k */
+  LKk = lfuninit(ldata, dom, der, bitprec); /* zeta_K/zeta_k */
   domain = mkvec2(dom, mkvecsmall2(der, bitprec));
   return gerepilecopy(av, lfunproduct(lfunzetak_i(nf), Lk, LKk, domain));
 }
 
-/* If flag=0 (default), assume zeta_K divisible by zeta_k for all
-   subfields k of K. If flag=1, only assume zeta_K divisible by zeta.
-   If flag=2, do not assume anything. If flag=4, assume K/Q is abelian.
-   If flag<0, do not assume anything and the output is the same as lfuninit,
-   so can be used directly. */
-GEN
-lfunzetakinit_bitprec(GEN NF, GEN dom, long der, long flag, long bitprec)
+static GEN
+subgroups_largestabelian(GEN S)
 {
-  GEN nf = checknf(NF), T = nf_get_pol(nf);
-  if (degpol(T) == 1) return lfunzetainit_bitprec(dom, der, bitprec);
-  if (flag < 0)
-    flag = 2;
-  else if (flag != 4)
-  {
-    long v = fetch_var();
-    if (rnfisabelian(pol_x(v), T)) flag = 4;
-    delete_var();
-  }
-  switch(flag)
+  long i, n = 0, l = lg (S);
+  GEN M = NULL;
+  for(i = 1; i < l; i++)
   {
-    case 0: return lfunzetaKkinit_bitprec(nf, dom, der, bitprec);
-    case 1: return lfunzetaKQinit_bitprec(nf, dom, der, bitprec);
-    case 2: return lfunzetaKinit_bitprec(NF, dom, der, bitprec);
-    case 4: return lfunabelianrelinit_bitprec(nf, NULL, T, dom, der, bitprec);
+    GEN Si = gel(S,i);
+    long o = group_order(Si);
+    if (o > n && group_isabelian(Si))
+    {
+      n = o;
+      M = Si;
+    }
   }
-  pari_err_FLAG("lfunzetakinit");
-  return NULL;
+  return M;
+}
+
+
+/* If flag=0 (default), assume Artin conjecture */
+
+static GEN
+lfunzetakinit_Galois(GEN nf, GEN G, GEN dom, long der, long bitprec)
+{
+  GEN S, H, P, F, R, bnf;
+  GEN T = nf_get_pol(nf);
+  long v = varn(T);
+  GEN grp = galois_group(G);
+  if (group_isabelian(grp))
+    return lfunabelianrelinit(nf, NULL, T, dom, der, bitprec);
+  S = group_subgroups(grp);
+  H = subgroups_largestabelian(S);
+  if (v==0) { v=1; nf = gsubst(nf, 0, pol_x(v)); }
+  else G = gsubst(G, v, pol_x(0));
+  F = galoisfixedfield(G, H, 2, v);
+  P = gel(F,1), R = gmael(F,3,1);
+  setvarn(P, v);
+  bnf = Buchall(P, 0, nbits2prec(bitprec));
+  return lfunabelianrelinit(nf, bnf, R, dom, der, bitprec);
 }
 
 GEN
-lfunzetakinit(GEN pol, GEN dom, long der, long flag, long prec)
-{
-  return lfunzetakinit_bitprec(pol, dom, der, flag, prec2nbits(prec));
+lfunzetakinit(GEN NF, GEN dom, long der, long flag, long bitprec)
+{
+  GEN nf = checknf(NF);
+  GEN G, nfs, sbg;
+  long lf, d = nf_get_degree(nf);
+  if (d == 1) return lfunzetainit(dom, der, bitprec);
+  G = galoisinit(nf, NULL);
+  if (!isintzero(G))
+    return lfunzetakinit_Galois(nf, G, dom, der, bitprec);
+  nfs = nfsubfields(nf, 0); lf = lg(nfs)-1;
+  sbg = gmael(nfs,lf-1,1);
+  if (flag && d > 4*degpol(sbg))
+    return lfunzetakinit_raw(nf, dom, der, bitprec);
+  return lfunzetakinit_quotient(nf, sbg, dom, der, bitprec);
 }
 
 /***************************************************************/
@@ -771,7 +760,7 @@ lfunell(GEN e)
 }
 
 GEN
-lfunmfspec_bitprec(GEN lmisc, long bitprec)
+lfunmfspec(GEN lmisc, long bitprec)
 {
   pari_sp ltop = avma;
   GEN Vga, linit, ldataf, veven, vodd, om, op, eps, dom;
@@ -784,7 +773,7 @@ lfunmfspec_bitprec(GEN lmisc, long bitprec)
       && sdomain_isincl(k, dom, lfun_get_dom(linit_get_tech(lmisc))))
     linit = lmisc;
   else
-    linit = lfuninit_bitprec(ldataf, dom, 0, bitprec);
+    linit = lfuninit(ldataf, dom, 0, bitprec);
   Vga = ldata_get_gammavec(ldataf);
   if (!ldata_isreal(ldataf) || !gequal(Vga, mkvec2(gen_0,gen_1)))
     pari_err_TYPE("lfunmfspec", lmisc);
@@ -792,10 +781,8 @@ lfunmfspec_bitprec(GEN lmisc, long bitprec)
   k2 = k/2;
   vodd = cgetg(k2+1, t_VEC);
   veven = cgetg(k2, t_VEC);
-  for (j = 1; j <= k2; ++j)
-    gel(vodd,j) = lfunlambda_bitprec(linit, stoi(2*j-1), bitprec);
-  for (j = 1; j < k2; ++j)
-    gel(veven,j) = lfunlambda_bitprec(linit, stoi(2*j), bitprec);
+  for (j=1; j <= k2; ++j) gel(vodd,j) = lfunlambda(linit, stoi(2*j-1), bitprec);
+  for (j=1; j < k2; ++j) gel(veven,j) = lfunlambda(linit, stoi(2*j), bitprec);
   if (k > 2)
   {
     om = gel(veven,1);
@@ -814,12 +801,6 @@ lfunmfspec_bitprec(GEN lmisc, long bitprec)
   return gerepilecopy(ltop, mkvec4(veven, vodd, om, op));
 }
 
-GEN
-lfunmfspec(GEN lmisc, long prec)
-{
-  return lfunmfspec_bitprec(lmisc, prec2nbits(prec));
-}
-
 /* Symmetric square of a Hecke eigenform, cuspform. Assume ldata is the ldata
 of such a cusp form. Find the ldata of its symmetric square, and in particular
 the conductor and bad Euler factors. */
@@ -911,7 +892,7 @@ ellsymsq_badp(GEN c4, GEN c6, GEN p, long e, long *pb)
 static GEN
 ellsymsq(void *D, GEN p)
 {
-  GEN E = gel((GEN)D, 2);
+  GEN E = (GEN)D;
   GEN T, ap = sqri(ellap(E, p));
   long e = Z_pval(ellQ_get_N(E), p);
   if (e)
@@ -919,8 +900,7 @@ ellsymsq(void *D, GEN p)
     if (e == 1)
       T = deg1pol_shallow(negi(ap),gen_1,0);
     else
-    { /* N.B. Could get 'a' from veceul = D[1]: vector of pairs [p,a], e >= 2,
-       * but cheaper to rederive */
+    {
       GEN c4 = ell_get_c4(E);
       GEN c6 = ell_get_c6(E);
       long junk, a = ellsymsq_badp(c4, c6, p, e, &junk);
@@ -944,12 +924,12 @@ vecan_ellsymsq(GEN an, long n)
 { GEN nn = stoi(n); return direuler((void*)an, &ellsymsq, gen_2, nn, nn); }
 
 static GEN
-lfunsymsqfind_ell(GEN e)
+lfunellsymsqmintwist(GEN e)
 {
   pari_sp av = avma;
-  GEN B, N, Nfa, P, E, V, c4, c6;
+  GEN B, N, Nfa, P, E, V, c4, c6, ld;
   long i, l, k;
-
+  checkell_Q(e);
   e = ellminimalmodel(e, NULL);
   ellQ_get_Nfa(e, &N, &Nfa);
   c4 = ell_get_c4(e);
@@ -968,7 +948,9 @@ lfunsymsqfind_ell(GEN e)
     gel(V,k++) = mkvec2(p, stoi(a));
   }
   setlg(V, k);
-  return gerepilecopy(av, mkvec2(sqri(B), V));
+  ld = mkvecn(6, tag(e, t_LFUN_SYMSQ_ELL), gen_0,
+                 mkvec3(gen_0, gen_0, gen_1), stoi(3), sqri(B), gen_1);
+  return gerepilecopy(av, mkvec2(ld, V));
 }
 
 /* Find conductor and missing Euler factors in symmetric square.
@@ -1044,7 +1026,7 @@ lfunsymsqfind(GEN ldata, long flall/*=0*/, long prec)
       forvec_init(&iter2, vforexptmp, 0);
       while ((vexp = forvec_next(&iter2)))
       {
-        GEN V = cgetg(i2, t_VEC), M2 = sqri(diviiexact(N,M)), L;
+        GEN V = cgetg(i2, t_COL), M2 = sqri(diviiexact(N,M)), L;
         long m;
         for (m = 1; m < i2; m++)
         {
@@ -1054,7 +1036,7 @@ lfunsymsqfind(GEN ldata, long flall/*=0*/, long prec)
         veceul = shallowconcat(P1, V);
         L = mkvecn(6, tag(mkvec2(veceul, ldata), t_LFUN_SYMSQ),
               gen_0, mkvec3(stoi(2-k), gen_0, gen_1), stoi(2*k-1), M2, gen_1);
-        if (lfuncheckfeq_bitprec(L, NULL, bitprec)  < -bitprec/2)
+        if (lfuncheckfeq(L, NULL, bitprec)  < -bitprec/2)
         {
           GEN z = mkvec2(M2, lexsort(veceul));
           if (!flall) return gerepilecopy(ltop, z);
@@ -1088,28 +1070,12 @@ lfunsymsq(GEN ldata, GEN known, long prec)
   return gerepilecopy(ltop, L);
 }
 
-static GEN
-lfunellsymsq(GEN E)
-{
-  pari_sp ltop = avma;
-  long k = 2;
-  GEN ld, known, N, V;
-  checkell_Q(E);
-  E = ellanal_globalred(E, NULL);
-  known = lfunsymsqfind_ell(E);
-  N = gel(known,1);
-  V = gel(known,2);
-  ld = mkvecn(6, tag(mkvec2(V, E), t_LFUN_SYMSQ_ELL), gen_0,
-                 mkvec3(stoi(2-k), gen_0, gen_1), stoi(2*k-1), N, gen_1);
-  return gerepilecopy(ltop, ld);
-}
-
 static long
 lfunissymsq(GEN Vga)
 { return (lg(Vga) == 4) && lfunisvgaell(mkvec2(gel(Vga,2), gel(Vga,3)), 0); }
 
 GEN
-lfunsymsqspec_bitprec(GEN lmisc, long bitprec)
+lfunsymsqspec(GEN lmisc, long bitprec)
 {
   pari_sp ltop = avma;
   GEN veven, vpi, om2, M, Vga, ldata;
@@ -1139,7 +1105,7 @@ lfunsymsqspec_bitprec(GEN lmisc, long bitprec)
     case 1: /* now ldata is a symsq */
       k = ldata_get_k(ldata);
       dom = mkvec3(dbltor((k+1)/2.), dbltor(3*(k+1)/4.), gen_0);
-      ldata = lfuninit_bitprec(ldata, dom, 0, bitprec);
+      ldata = lfuninit(ldata, dom, 0, bitprec);
       break;
     default:
       ldata = lmisc;
@@ -1148,29 +1114,23 @@ lfunsymsqspec_bitprec(GEN lmisc, long bitprec)
   /* Warning: k is the weight of the symmetric square, not of the form. */
   l1 = (k+1)/4;
   veven = cgetg(l1+1, t_VEC);
-  om2 = greal(lfunlambda_bitprec(ldata, stoi((k+1)/2), bitprec));
+  om2 = greal(lfunlambda(ldata, stoi((k+1)/2), bitprec));
   vpi = gpowers(mppi(prec), l1); /* could be powersshift(,om2) */
   gel(veven,1) = gen_1;
   M = int2n(bitprec/4);
   for (j = 2; j <= l1; ++j)
   {
-    GEN Lj = greal(lfunlambda_bitprec(ldata, stoi(2*j + (k-3)/2), bitprec));
+    GEN Lj = greal(lfunlambda(ldata, stoi(2*j + (k-3)/2), bitprec));
     Lj = gdiv(Lj, gmul(gel(vpi,j), om2));
     gel(veven, j) = bestappr(Lj, M);
   }
   return gerepilecopy(ltop, mkvec2(veven, om2));
 }
 
-GEN
-lfunsymsqspec(GEN lmisc, long prec)
-{
-  return lfunsymsqspec_bitprec(lmisc, prec2nbits(prec));
-}
-
 static GEN
 mfpeters(GEN ldata2, GEN fudge, GEN N, long k, long bitprec)
 {
-  GEN t, L = greal(lfun_bitprec(ldata2, stoi(k), bitprec));
+  GEN t, L = greal(lfun(ldata2, stoi(k), bitprec));
   long prec = nbits2prec(bitprec);
   t = powrs(mppi(prec), k+1); shiftr_inplace(t, 2*k-1); /* Pi/2 * (4Pi)^k */
   return gmul(gdiv(gmul(mulii(N,mpfact(k-1)), fudge), t), L);
@@ -1178,7 +1138,7 @@ mfpeters(GEN ldata2, GEN fudge, GEN N, long k, long bitprec)
 /* Petersson square of modular form. ldata must be the
    data of the modular form itself. */
 GEN
-lfunmfpeters_bitprec(GEN ldata, long bitprec)
+lfunmfpeters(GEN ldata, long bitprec)
 {
   pari_sp av = avma;
   GEN ldata2, veceuler, N, fudge = gen_1;
@@ -1194,32 +1154,355 @@ lfunmfpeters_bitprec(GEN ldata, long bitprec)
   veceuler = gmael3(ldata2, 1, 2, 1);
   for (j = 1; j < lg(veceuler); ++j)
   {
-    GEN v = gel(veceuler, j), p = gel(v,1), q = powis(p,1-k), s = gel(v,2);
-    if (dvdii(N, sqri(p))) fudge = gmul(fudge, gaddsg(1, gmul(s, q)));
+    GEN v = gel(veceuler, j), p = gel(v,1), s = gel(v,2);
+    if (dvdii(N, sqri(p))) fudge = gmul(fudge, gsubsg(1, gdiv(s, powiu(p,k))));
   }
   return gerepileupto(av, mfpeters(ldata2,fudge,N,k,bitprec));
 }
 
-GEN
-lfunmfpeters(GEN ldata, long prec)
-{ return lfunmfpeters_bitprec(ldata, prec2nbits(prec)); }
-
-GEN
-lfunellmfpeters_bitprec(GEN E, long bitprec)
+/* Assume E to be twist-minimal */
+static GEN
+lfunellmfpetersmintwist(GEN E, long bitprec)
 {
   pari_sp av = avma;
-  GEN ldata2, veceuler, N = ellQ_get_N(E), fudge = gen_1;
+  GEN symsq, veceuler, N = ellQ_get_N(E), fudge = gen_1;
   long j, k = 2;
-
-  ldata2 = lfunellsymsq(E);
-  veceuler = gmael3(ldata2, 1, 2, 1);
+  symsq = lfunellsymsqmintwist(E);
+  veceuler = gel(symsq,2);
   for (j = 1; j < lg(veceuler); j++)
   {
     GEN v = gel(veceuler,j), p = gel(v,1), q = powis(p,1-k);
     long s = signe(gel(v,2));
     if (s) fudge = gmul(fudge, s==1 ? gaddsg(1, q): gsubsg(1, q));
   }
-  return gerepileupto(av, mfpeters(ldata2,fudge,N,k,bitprec));
+  return gerepileupto(av, mfpeters(gel(symsq,1),fudge,N,k,bitprec));
+}
+
+/* From Christophe Delaunay, http://delaunay.perso.math.cnrs.fr/these.pdf */
+static GEN
+elldiscfix(GEN E, GEN Et, GEN D)
+{
+  GEN N = ellQ_get_N(E), Nt = ellQ_get_N(Et);
+  GEN P = gel(Z_factor(absi(D)), 1);
+  GEN f = gen_1;
+  long i, l = lg(P);
+  for (i=1; i < l; i++)
+  {
+    GEN r, p = gel(P,i);
+    long v = Z_pval(N, p), vt = Z_pval(Nt, p);
+    if (v <= vt) continue;
+    /* v > vt */
+    if (equaliu(p, 2))
+    {
+      if (vt == 0 && v >= 4)
+        r = shifti(subsi(9, sqri(ellap(Et, p))), v-3);  /* 9=(2+1)^2 */
+      else if (vt == 1)
+        r = gmul2n(utoipos(3), v-3);  /* not in Z if v=2 */
+      else if (vt >= 2)
+        r = int2n(v-vt);
+      else
+        r = gen_1; /* vt = 0, 1 <= v <= 3 */
+    }
+    else if (vt >= 1)
+      r = gdiv(subis(sqri(p), 1), p);
+    else
+      r = gdiv(mulii(subis(p, 1), subii(sqri(addis(p, 1)), sqri(ellap(Et, p)))), p);
+    f = gmul(f, r);
+  }
+  return f;
+}
+
+GEN
+lfunellmfpeters(GEN E, long bitprec)
+{
+  pari_sp ltop = avma;
+  long prec = nbits2prec(bitprec);
+  GEN D = ellminimaltwistcond(E);
+  GEN Etr = ellinit(elltwist(E, D), NULL, prec);
+  GEN Et = ellminimalmodel(Etr, NULL);
+  GEN nor = lfunellmfpetersmintwist(Et, bitprec);
+  GEN nor2 = gmul(nor, elldiscfix(E, Et, D));
+  obj_free(Etr); obj_free(Et);
+  return gerepilecopy(ltop, nor2);
+}
+
+/*************************************************************/
+/*               genus 2 curves                              */
+/*************************************************************/
+
+static GEN
+dirgenus2(void *E, GEN p)
+{
+  pari_sp av = avma;
+  GEN Q = (GEN) E;
+  GEN f = RgX_recip(hyperellcharpoly(gmul(Q,gmodulo(gen_1, p))));
+  return gerepileupto(av, ginv(f));
+}
+
+static GEN
+vecan_genus2(GEN an, long L)
+{
+  GEN Q = gel(an,1), bad = gel(an, 2);
+  return direuler_bad((void*)Q, dirgenus2, gen_2, stoi(L), NULL, bad);
+}
+
+static GEN
+genus2_redmodel(GEN P, GEN p)
+{
+  GEN M = FpX_factor(P, p);
+  GEN F = gel(M,1), E = gel(M,2);
+  long i, k, r = lg(F);
+  GEN U = scalarpol(leading_coeff(P), varn(P));
+  GEN G = cgetg(r, t_COL);
+  for (i=1, k=0; i<r; i++)
+  {
+    if (E[i]>1)
+      gel(G,++k) = gel(F,i);
+    if (odd(E[i]))
+      U = FpX_mul(U, gel(F,i), p);
+  }
+  setlg(G,++k);
+  return mkvec2(G,U);
+}
+
+static GEN
+oneminusxd(long d)
+{
+  return gsub(gen_1, monomial(gen_1, d, 0));
+}
+
+static GEN
+ellfromeqncharpoly(GEN P, GEN Q, GEN p)
+{
+  long v;
+  GEN E, F, t, y;
+  v = fetch_var();
+  y = pol_x(v);
+  F = gsub(gadd(ZX_sqr(y), gmul(y, Q)), P);
+  E = ellinit(ellfromeqn(F), p, DEFAULTPREC);
+  delete_var();
+  t = ellap(E, p);
+  obj_free(E);
+  return mkpoln(3, gen_1, negi(t), p);
+}
+
+static GEN
+genus2_eulerfact(GEN P, GEN p)
+{
+  pari_sp av = avma;
+  GEN Pp = FpX_red(P, p);
+  GEN GU = genus2_redmodel(Pp, p);
+  long d = 6-degpol(Pp), v = d/2, w = odd(d);
+  GEN abe, tor;
+  GEN ki, kp = pol_1(0), kq = pol_1(0);
+  GEN F = gel(GU,1), Q = gel(GU,2);
+  long dQ = degpol(Q), lF = lg(F)-1;
+
+  abe = dQ >= 5 ? RgX_recip(hyperellcharpoly(gmul(Q,gmodulo(gen_1,p))))
+      : dQ >= 3 ? RgX_recip(ellfromeqncharpoly(Q,gen_0,p))
+                : pol_1(0);
+  ki = dQ > 0 ? oneminusxd(1)
+              : Fp_issquare(gel(Q,2),p) ? ZX_sqr(oneminusxd(1))
+                                        : oneminusxd(2);
+  if (lF)
+  {
+    long i;
+    for(i=1; i <= lF; i++)
+    {
+      GEN Fi = gel(F, i);
+      long d = degpol(Fi);
+      GEN e = FpX_rem(Q, Fi, p);
+      GEN kqf = lgpol(e)==0 ? oneminusxd(d):
+                FpXQ_issquare(e, Fi, p) ? ZX_sqr(oneminusxd(d))
+                                          : oneminusxd(2*d);
+      kp = gmul(kp, oneminusxd(d));
+      kq = gmul(kq, kqf);
+    }
+  }
+  if (v)
+  {
+    GEN kqoo = w==1 ? oneminusxd(1):
+               Fp_issquare(leading_coeff(Q), p)? ZX_sqr(oneminusxd(1))
+                                              : oneminusxd(2);
+    kp = gmul(kp, oneminusxd(1));
+    kq = gmul(kq, kqoo);
+  }
+  tor = RgX_div(ZX_mul(oneminusxd(1), kq), ZX_mul(ki, kp));
+  return gerepileupto(av, ZX_mul(abe, tor));
+}
+
+static GEN
+F2x_genus2_find_trans(GEN P, GEN Q, GEN F)
+{
+  pari_sp av = avma;
+  long i, d = F2x_degree(F), v = P[1];
+  GEN M, C, V;
+  M = cgetg(d+1, t_MAT);
+  for (i=1; i<=d; i++)
+  {
+    GEN Mi = F2x_rem(F2x_add(F2x_shift(Q,i-1), monomial_F2x(2*i-2,v)), F);
+    gel(M,i) = F2x_to_F2v(Mi, d);
+  }
+  C = F2x_to_F2v(F2x_rem(P, F), d);
+  V = F2m_F2c_invimage(M, C);
+  return gerepileuptoleaf(av, F2v_to_F2x(V, v));
+}
+
+static GEN
+F2x_genus2_trans(GEN P, GEN Q, GEN H)
+{
+  return F2x_add(P,F2x_add(F2x_mul(H,Q), F2x_sqr(H)));
+}
+
+static GEN
+F2x_genus_redoo(GEN P, GEN Q, long k)
+{
+  if (F2x_degree(P)==2*k)
+  {
+    long c = F2x_coeff(P,2*k-1), dQ = F2x_degree(Q);
+    if ((dQ==k-1 && c==1) || (dQ<k-1 && c==0))
+     return F2x_genus2_trans(P, Q, monomial_F2x(k, P[1]));
+  }
+  return P;
+}
+
+static GEN
+F2x_pseudodisc(GEN P, GEN Q)
+{
+  GEN dP = F2x_deriv(P), dQ = F2x_deriv(Q);
+  return F2x_gcd(Q, F2x_add(F2x_mul(P, F2x_sqr(dQ)), F2x_sqr(dP)));
+}
+
+static GEN
+F2x_genus_red(GEN P, GEN Q)
+{
+  long dP, dQ;
+  GEN F, FF;
+  P = F2x_genus_redoo(P, Q, 3);
+  P = F2x_genus_redoo(P, Q, 2);
+  P = F2x_genus_redoo(P, Q, 1);
+  dP = F2x_degree(P);
+  dQ = F2x_degree(Q);
+  FF = F = F2x_pseudodisc(P,Q);
+  while(F2x_degree(F)>0)
+  {
+    GEN M = gel(F2x_factor(F),1);
+    long i, l = lg(M);
+    for(i=1; i<l; i++)
+    {
+      GEN R = F2x_sqr(gel(M,i));
+      GEN H = F2x_genus2_find_trans(P, Q, R);
+      P = F2x_div(F2x_genus2_trans(P, Q, H), R);
+      Q = F2x_div(Q, gel(M,i));
+    }
+    F = F2x_pseudodisc(P, Q);
+  }
+  return mkvec4(P,Q,FF,mkvecsmall2(dP,dQ));
+}
+
+/* Number of solutions of x^2+b*x+c */
+static long
+F2xqX_quad_nbroots(GEN b, GEN c, GEN T)
+{
+  if (lgpol(b) > 0)
+  {
+    GEN d = F2xq_div(c, F2xq_sqr(b, T), T);
+    return F2xq_trace(d, T)? 0: 2;
+  }
+  else
+    return 1;
+}
+
+static GEN
+genus2_redmodel2(GEN P)
+{
+  GEN Q = pol_0(varn(P));
+  GEN P2 = ZX_to_F2x(P);
+  while (F2x_issquare(P2))
+  {
+    GEN H = F2x_to_ZX(F2x_sqrt(P2));
+    GEN P1 = ZX_sub(P, ZX_sqr(H));
+    GEN Q1 = ZX_add(Q, ZX_mulu(H, 2));
+    if ((signe(P1)==0 ||  ZX_lval(P1,2)>=2)
+     && (signe(Q1)==0 ||  ZX_lval(Q1,2)>=1))
+    {
+      P = ZX_shifti(P1, -2);
+      Q = ZX_shifti(Q1, -1);
+      P2= ZX_to_F2x(P);
+    } else break;
+  }
+  return mkvec2(P,Q);
+}
+
+static GEN
+genus2_eulerfact2(GEN PQ)
+{
+  pari_sp av = avma;
+  GEN V = F2x_genus_red(ZX_to_F2x(gel(PQ, 1)), ZX_to_F2x(gel(PQ, 2)));
+  GEN P = gel(V, 1), Q = gel(V, 2);
+  GEN F = gel(V, 3), v = gel(V, 4);
+  GEN abe, tor;
+  GEN ki, kp = pol_1(0), kq = pol_1(0);
+  long dP = F2x_degree(P), dQ = F2x_degree(Q), d = maxss(dP, 2*dQ);
+  if (!lgpol(F)) return pol_1(0);
+  ki = dQ!=0 || dP>0 ? oneminusxd(1):
+      dP==-1 ? ZX_sqr(oneminusxd(1)): oneminusxd(2);
+  abe = d>=5? RgX_recip(hyperellcharpoly(gmul(PQ,gmodulss(1,2)))):
+        d>=3? RgX_recip(ellfromeqncharpoly(F2x_to_ZX(P), F2x_to_ZX(Q), gen_2)):
+        pol_1(0);
+  if (lgpol(F))
+  {
+    GEN M = gel(F2x_factor(F), 1);
+    long i, lF = lg(M)-1;
+    for(i=1; i <= lF; i++)
+    {
+      GEN Fi = gel(M, i);
+      long d = F2x_degree(Fi);
+      long nb  = F2xqX_quad_nbroots(F2x_rem(Q, Fi), F2x_rem(P, Fi), Fi);
+      GEN kqf = nb==1 ? oneminusxd(d):
+                nb==2 ? ZX_sqr(oneminusxd(d))
+                      : oneminusxd(2*d);
+      kp = gmul(kp, oneminusxd(d));
+      kq = gmul(kq, kqf);
+    }
+  }
+  if (maxss(v[1],2*v[2])<5)
+  {
+    GEN kqoo = v[1]>2*v[2] ? oneminusxd(1):
+               v[1]<2*v[2] ? ZX_sqr(oneminusxd(1))
+                           : oneminusxd(2);
+    kp = gmul(kp, oneminusxd(1));
+    kq = gmul(kq, kqoo);
+  }
+  tor = RgX_div(ZX_mul(oneminusxd(1),kq), ZX_mul(ki, kp));
+  return gerepileupto(av, ZX_mul(abe, tor));
+}
+
+GEN
+lfungenus2(GEN G)
+{
+  pari_sp ltop = avma;
+  GEN Ldata;
+  GEN gr = genus2red(G, NULL);
+  GEN N  = gel(gr, 1), M = gel(gr, 2), Q = gel(gr, 3), L = gel(gr, 4);
+  GEN PQ = genus2_redmodel2(Q);
+  GEN e;
+  long i, lL = lg(L), ram2;
+  ram2 = equaliu(gmael(M,1,1),2);
+  if (ram2 && equalis(gmael(M,2,1),-1))
+    pari_warn(warner,"unknown valuation of conductor at 2");
+  e = cgetg(lL+(ram2?0:1), t_VEC);
+  gel(e,1) = mkvec2(gen_2, ram2 ? genus2_eulerfact2(PQ)
+           : RgX_recip(hyperellcharpoly(gmul(PQ,gmodulss(1,2)))));
+  for(i = ram2? 2: 1; i < lL; i++)
+  {
+    GEN Li = gel(L, i);
+    GEN p = gel(Li, 1);
+    gel(e, ram2 ? i: i+1) = mkvec2(p, genus2_eulerfact(Q,p));
+  }
+  Ldata = mkvecn(6, tag(mkvec2(Q,e), t_LFUN_GENUS2),
+      gen_0, mkvec4(gen_0, gen_0, gen_1, gen_1), gen_2, N, gen_0);
+  return gerepilecopy(ltop, Ldata);
 }
 
 /*************************************************************/
@@ -1573,18 +1856,18 @@ GEN
 lfunartin(GEN N, GEN G, GEN M, long o)
 {
   pari_sp ltop = avma;
-  GEN m, bc, R, V, aut, Ldata;
+  GEN bc, R, V, aut, Ldata;
   long i, l;
   N = checknf(N);
   checkgal(G);
   if (!is_vec_t(typ(M))) pari_err_TYPE("lfunartin",M);
+  M = gmul(M, gmodulo(gen_1, polcyclo(o, gvar(M))));
   R = artin_repfromgens(G,M);
   l = lg(R)-1;
   bc = artin_badprimes(N,G,R);
-  m = gmodulo(gen_1, polcyclo(o, gvar(R)));
   V = cgetg(l+1, t_VEC);
   for (i = 1; i <= l; ++i)
-    gel(V, i) = RgX_recip(charpoly(gmul(gel(R, i), m), 0));
+    gel(V, i) = RgX_recip(charpoly(gel(R, i), 0));
   aut = nfgaloispermtobasis(N, G);
   Ldata = mkvecn(6, tag(mkcol6(N, G, V, aut, gel(bc, 2), stoi(o)), t_LFUN_ARTIN),
       gen_1, artin_gamma(N, G, R), gen_1, gel(bc,1), gen_0);
@@ -1684,6 +1967,7 @@ ldata_vecan(GEN van, long L, long prec)
     case t_LFUN_MUL: an = vecan_mul(an, L, prec); break;
     case t_LFUN_SYMSQ: an = vecan_symsq(an, L, prec); break;
     case t_LFUN_SYMSQ_ELL: an = vecan_ellsymsq(an, L); break;
+    case t_LFUN_GENUS2: an = vecan_genus2(an, L); break;
     default: pari_err_TYPE("ldata_vecan", van);
   }
   if (DEBUGLEVEL >= 2) timer_printf(&ti, "ldata_vecan");
diff --git a/src/basemath/map.c b/src/basemath/map.c
index e97fdf7..224773a 100644
--- a/src/basemath/map.c
+++ b/src/basemath/map.c
@@ -17,13 +17,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 #define tvalue(i)  gmael(t,(i),1)
 #define tleft(i)   mael3(t,(i),2,1)
 #define tright(i)  mael3(t,(i),2,2)
+#define theight(i) mael3(t,(i),2,3)
 
 static GEN
 treesearch(GEN T, GEN x, long mode)
 {
   long i = 1;
   GEN t = list_data(T);
-  if (!t) return NULL;
+  if (!t || lg(t)==1) return NULL;
   while(i)
   {
     long c = mode == 0 ? cmp_universal(x, tvalue(i)):
@@ -73,7 +74,7 @@ treekeys(GEN T, long mode)
   long n = 0;
   GEN t = list_data(T);
   GEN V;
-  if (!t) return cgetg(1, t_VEC);
+  if (!t || lg(t)==1) return cgetg(1, t_VEC);
   V = cgetg(lg(t), t_VEC);
   treekeys_r(t, 1, V, &n, mode);
   return V;
@@ -94,7 +95,7 @@ treekeys_i(GEN T, long mode)
   long n = 0;
   GEN t = list_data(T);
   GEN V;
-  if (!t) return cgetg(1, t_VEC);
+  if (!t || lg(t)==1) return cgetg(1, t_VEC);
   V = cgetg(lg(t), t_VEC);
   treekeys_i_r(t, 1, V, &n, mode);
   return V;
@@ -117,7 +118,7 @@ treemat(GEN T)
   long n = 0;
   GEN t = list_data(T);
   GEN V;
-  if (!t) return cgetg(1, t_MAT);
+  if (!t || lg(t)==1) return cgetg(1, t_MAT);
   V = cgetg(3, t_MAT);
   gel(V,1) = cgetg(lg(t), t_COL);
   gel(V,2) = cgetg(lg(t), t_COL);
@@ -142,7 +143,7 @@ treemat_i(GEN T)
   long n = 0;
   GEN t = list_data(T);
   GEN V;
-  if (!t) return cgetg(1, t_MAT);
+  if (!t || lg(t)==1) return cgetg(1, t_MAT);
   V = cgetg(3, t_MAT);
   gel(V,1) = cgetg(lg(t), t_COL);
   gel(V,2) = cgetg(lg(t), t_COL);
@@ -150,6 +151,34 @@ treemat_i(GEN T)
   return V;
 }
 
+static void
+treemap_i_r(GEN t, long i, long a, long c, GEN p, GEN M)
+{
+  long b = (a+c)>>1;
+  GEN x = mkvec2(gcopy(gmael(M, 1, p[b])), gcopy(gmael(M, 2, p[b])));
+  if (a == c)
+    gel(t, i) = mkvec2(x, mkvecsmall3(0, 0, 1));
+  else if (a+1 == c)
+  {
+    treemap_i_r(t, i+1, a+1, c, p, M);
+    gel(t, i) = mkvec2(x, mkvecsmall3(0, i+1, theight(i+1) + 1));
+  }
+  else
+  {
+    long l = i+1, r = l + b - a, h;
+    treemap_i_r(t, l, a, b-1, p, M);
+    treemap_i_r(t, r, b+1, c, p, M);
+    h = maxss(theight(l), theight(r))+1;
+    gel(t, i) = mkvec2(x, mkvecsmall3(l, r, h));
+  }
+}
+
+static void
+treemap_i(GEN t, GEN p, GEN M)
+{
+  treemap_i_r(t, 1, 1, lg(p)-1, p, M);
+}
+
 #define value(i)  gmael(list_data(T),(i),1)
 #define left(i)   mael3(list_data(T),(i),2,1)
 #define right(i)  mael3(list_data(T),(i),2,2)
@@ -215,7 +244,7 @@ static long
 treeinsert_r(GEN T, GEN x, long i, long *d, long mode)
 {
   long b, c;
-  if (i==0 || !list_data(T))
+  if (i==0 || !list_data(T) || lg(list_data(T))==1)
     return new_leaf(T, x);
   c = mode == 0 ? cmp_universal(x, value(i)):
                   cmp_universal(gel(x,1), gel(value(i),1));
@@ -271,7 +300,7 @@ static long
 treedelete_r(GEN T, GEN x, long i, long mode, long *dead)
 {
   long b, c;
-  if (i==0 || !list_data(T))
+  if (i==0 || !list_data(T) || lg(list_data(T))==1)
     return -1;
   c = mode == 0 ? cmp_universal(x, value(i)):
                   cmp_universal(x, gel(value(i),1));
@@ -447,13 +476,18 @@ gtomap(GEN x)
   {
   case t_MAT:
     {
-      long i, n, l = lg(x);
-      GEN M = listcreate_typ(t_LIST_MAP);
-      if (l == 1) return M;
+      long n, l = lg(x);
+      GEN M, p;
+      if (l == 1 || lgcols(x)==1) return listcreate_typ(t_LIST_MAP);
       if (l != 3) pari_err_TYPE("Map",x);
-      n = lgcols(x);
-      for (i=1; i < n; i++)
-        mapput(M, gcoeff(x,i,1), gcoeff(x,i,2));
+      p = gen_indexsort_uniq(gel(x,1),(void*)&cmp_universal, cmp_nodata);
+      if (lg(p) != lgcols(x))
+        pari_err_DOMAIN("Map","x","is not",strtoGENstr("one-to-one"),x);
+      n = lg(p)-1;
+      M = cgetg(3, t_LIST);
+      M[1] = evaltyp(t_LIST_MAP)|evallg(n);
+      list_data(M) = cgetg(n+1, t_VEC);
+      treemap_i(list_data(M), p, x);
       return M;
     }
   default:
diff --git a/src/basemath/mellininv.c b/src/basemath/mellininv.c
index 029f75a..83959a5 100644
--- a/src/basemath/mellininv.c
+++ b/src/basemath/mellininv.c
@@ -68,7 +68,7 @@ static double
 lemma526_i(double ac, double c, double t, double B)
 {
   double D = -B/ac;
-  if (D < 0)
+  if (D <= 0)
   {
     double x = pow(t, c);
     if (D > -100)
@@ -98,7 +98,7 @@ lemma526_i(double ac, double c, double t, double B)
 }
 /* b > 0, c > 0, B > 0; solve x^a exp(-b x^(1/c)) < e^(-B) */
 double
-dbllemma526(double a, double b, double c, long B)
+dbllemma526(double a, double b, double c, double B)
 {
   double ac;
   if (!a) return pow(B/b, c);
@@ -107,7 +107,7 @@ dbllemma526(double a, double b, double c, long B)
 }
 /* Same, special case b/c = 2Pi, the only one needed: for c = d/2 */
 double
-dblcoro526(double a, double c, long B)
+dblcoro526(double a, double c, double B)
 {
   if (!a) return pow(B/(2*M_PI*c), c);
   return lemma526_i(a*c, c, a/(2*M_PI), B);
@@ -180,12 +180,12 @@ Kderivsmallinit(GEN Vga, long m, long bitprec)
   for (j=1; j <= N; j++)
   {
     GEN C, c, mjj = gel(mj,j), pr = gen_1, t = gen_1;
-    long i, k, n, ljj = lj[j], precdl = ljj+3;
+    long i, k, n, ljj = lj[j], lprecdl = ljj+3;
     for (i=1; i <= d; i++)
     {
       GEN a = gmul2n(gadd(mjj, gel(Vga,i)), -1);
       GEN u = deg1pol_shallow(ghalf, a, 0);
-      pr = gmul(pr, ggamma(RgX_to_ser(u, precdl), prec));
+      pr = gmul(pr, ggamma(RgX_to_ser(u, lprecdl), prec));
       t = gmul(t, u);
     }
     c = cgetg(limn+2,t_COL);
@@ -535,7 +535,7 @@ ishankelspec(GEN Vga, GEN M)
 
 /* Initialize data for computing m-th derivative of inverse Mellin */
 GEN
-gammamellininvinit_bitprec(GEN Vga, long m, long bitprec)
+gammamellininvinit(GEN Vga, long m, long bitprec)
 {
   pari_sp ltop = avma;
   GEN A2, M, VS, VL, cd;
@@ -574,16 +574,13 @@ gammamellininvinit_bitprec(GEN Vga, long m, long bitprec)
   VL = mkvec3(mkvec2(M, stoi(status)), cd, A2);
   return gerepilecopy(ltop, mkvec5(dbltor(tmax), Vga, stoi(m), VS, VL));
 }
-GEN
-gammamellininvinit(GEN Vga, long m, long prec)
-{ return gammamellininvinit_bitprec(Vga, m, prec2nbits(prec)); }
 
 /* Compute m-th derivative of inverse Mellin at s2d = s^(d/2) using
  * initialization data. Use Taylor expansion at 0 for |s2d| < tmax, and
  * asymptotic expansion at oo otherwise. WARNING: assume that accuracy
  * has been increased according to tmax by the CALLING program. */
 GEN
-gammamellininvrt_bitprec(GEN K, GEN s2d, long bitprec)
+gammamellininvrt(GEN K, GEN s2d, long bitprec)
 {
   GEN tmax = gel(K,1);
   if (dblmodulus(s2d) < rtodbl(tmax))
@@ -591,21 +588,18 @@ gammamellininvrt_bitprec(GEN K, GEN s2d, long bitprec)
   else
     return Kderivlarge(K, NULL, s2d, bitprec);
 }
-GEN
-gammamellininvrt(GEN K, GEN s2d, long prec)
-{ return gammamellininvrt_bitprec(K, s2d, prec2nbits(prec)); }
 
 /* Compute inverse Mellin at s. K from gammamellininv OR a Vga, in which
  * case the initialization data is computed. */
 GEN
-gammamellininv_bitprec(GEN K, GEN s, long m, long bitprec)
+gammamellininv(GEN K, GEN s, long m, long bitprec)
 {
   pari_sp av = avma;
   GEN z, s2d, tmax;
   long d;
   if (!is_vec_t(typ(K))) pari_err_TYPE("gammamellininvinit",K);
   if (lg(K) != 6 || !is_vec_t(typ(gel(K,2))))
-    K = gammamellininvinit_bitprec(K, m, bitprec);
+    K = gammamellininvinit(K, m, bitprec);
   tmax = gel(K,1);
   d = lg(gel(K,2))-1;
   s2d = gpow(s, gdivgs(gen_2, d), nbits2prec(bitprec));
@@ -615,6 +609,3 @@ gammamellininv_bitprec(GEN K, GEN s, long m, long bitprec)
     z = Kderivlarge(K, s, s2d, bitprec);
   return gerepileupto(av, z);
 }
-GEN
-gammamellininv(GEN Vga, GEN s, long m, long prec)
-{ return gammamellininv_bitprec(Vga, s, m, prec2nbits(prec)); }
diff --git a/src/basemath/modsym.c b/src/basemath/modsym.c
index 1082b0e..5b31c0c 100644
--- a/src/basemath/modsym.c
+++ b/src/basemath/modsym.c
@@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  * http://www.math.mcgill.ca/darmon/programs/shp/shp.html */
 static GEN mskinit(ulong N, long k, long sign);
 static GEN mshecke_i(GEN W, ulong p);
-static GEN ZGl2Q_star(GEN v);
+static GEN ZSl2_star(GEN v);
 static GEN getMorphism(GEN W1, GEN W2, GEN v);
 static GEN voo_act_Gl2Q(GEN g, long k);
 
@@ -83,6 +83,13 @@ msk_get_star(GEN W) { return gmael(W,2,2); }
 static GEN
 msk_get_starproj(GEN W) { return gmael(W,2,3); }
 
+long
+msgetlevel(GEN W) { checkms(W); return ms_get_N(W); }
+long
+msgetweight(GEN W) { checkms(W); return msk_get_weight(W); }
+long
+msgetsign(GEN W) { checkms(W); return msk_get_sign(W); }
+
 void
 checkms(GEN W)
 {
@@ -203,12 +210,15 @@ inithashmsymbols(ulong N, GEN symbols)
 #endif
 
 /** Helper functions for Sl2(Z) / Gamma_0(N) **/
+/* [a,b;c,d] */
+static GEN
+mkmat22(GEN a, GEN b, GEN c, GEN d) { retmkmat2(mkcol2(a,c),mkcol2(b,d)); }
 /* M a 2x2 ZM in SL2(Z) */
 static GEN
 SL2_inv(GEN M)
 {
   GEN a=gcoeff(M,1,1), b=gcoeff(M,1,2), c=gcoeff(M,2,1), d=gcoeff(M,2,2);
-  return mkmat2(mkcol2(d, negi(c)), mkcol2(negi(b), a));
+  return mkmat22(d,negi(b), negi(c),a);
 }
 /* M a 2x2 zm in SL2(Z) */
 static GEN
@@ -468,6 +478,10 @@ Qevproj_init(GEN M)
   iM = ZM_inv_ratlift(MM, &diM);
   return mkvec4(M, iM, diM, perm);
 }
+static int
+is_Qevproj(GEN x)
+{ return typ(x) == t_VEC && lg(x) == 5 && typ(gel(x,1)) == t_MAT; }
+
 /* same with typechecks */
 static GEN
 Qevproj_init0(GEN M)
@@ -536,10 +550,25 @@ cmp_dim(void *E, GEN a, GEN b)
   return k? ((k > 0)? 1: -1): 0;
 }
 
+/* FIXME: could use ZX_roots for deglim = 1 */
+static GEN
+ZX_factor_limit(GEN T, long deglim, long *pl)
+{
+  GEN fa = ZX_factor(T), P, E;
+  long i, l;
+  P = gel(fa,1); *pl = l = lg(P);
+  if (deglim <= 0) return fa;
+  E = gel(fa,2);
+  for (i = 1; i < l; i++)
+    if (degpol(gel(P,i)) > deglim) break;
+  setlg(P,i);
+  setlg(E,i); return fa;
+}
+
 /* Decompose the subspace H (Qevproj format) in simple subspaces.
  * Eg for H = msnew */
 static GEN
-mssplit_i(GEN W, GEN H)
+mssplit_i(GEN W, GEN H, long deglim)
 {
   ulong p, N = ms_get_N(W);
   long first, dim;
@@ -554,15 +583,12 @@ mssplit_i(GEN W, GEN H)
   while ((p = u_forprime_next(&S)))
   {
     GEN T;
-    long n, j, lV;
+    long j, lV;
     if (N % p == 0) continue;
-    if (T1 && T2)
-    {
+    if (T1 && T2) {
       T = RgM_add(T1,T2);
       T2 = NULL;
-    }
-    else
-    {
+    } else {
       T2 = T1;
       T1 = T = mshecke(W, p, NULL);
     }
@@ -570,14 +596,13 @@ mssplit_i(GEN W, GEN H)
     for (j = first; j < lV; j++)
     {
       pari_sp av = avma;
+      long lP;
       GEN Vj = gel(V,j), P = gel(Vj,1);
       GEN TVj = Qevproj_apply(T, Vj); /* c T | V_j */
-      GEN ch = QM_charpoly_ZX(TVj), fa = ZX_factor(ch), F, E;
-      long k;
-      F = gel(fa, 1);
-      E = gel(fa, 2);
-      n = lg(F)-1;
-      if (n == 1)
+      GEN ch = QM_charpoly_ZX(TVj), fa = ZX_factor_limit(ch,deglim, &lP);
+      GEN F = gel(fa, 1), E = gel(fa, 2);
+      long k, lF = lg(F);
+      if (lF == 2 && lP == 2)
       {
         if (isint1(gel(E,1)))
         { /* simple subspace */
@@ -587,24 +612,25 @@ mssplit_i(GEN W, GEN H)
         else
           avma = av;
       }
+      else if (lF == 1) /* discard V[j] */
+      { swap(gel(V,j), gel(V,lg(V)-1)); setlg(V, lg(V)-1); }
       else
       { /* can split Vj */
         GEN pows;
         long D = 1;
-        for (k = 1; k <= n; k++)
+        for (k = 1; k < lF; k++)
         {
           long d = degpol(gel(F,k));
           if (d > D) D = d;
         }
         /* remove V[j] */
         swap(gel(V,j), gel(V,lg(V)-1)); setlg(V, lg(V)-1);
-        pows = RgM_powers(TVj, minss((long)2*sqrt(D), D));
-        for (k = 1; k <= n; k++)
+        pows = RgM_powers(TVj, minss((long)2*sqrt((double)D), D));
+        for (k = 1; k < lF; k++)
         {
           GEN f = gel(F,k);
-          GEN M = RgX_RgMV_eval(f, pows); /* f(TVj) */
-          GEN K = QM_ker(M);
-          GEN p = Q_primpart( RgM_mul(P, K) );
+          GEN K = QM_ker( RgX_RgMV_eval(f, pows)) ; /* Ker f(TVj) */
+          GEN p = Q_primpart_basis( RgM_mul(P, K) );
           vectrunc_append(V, Qevproj_init(p));
           if (lg(K) == 2 || isint1(gel(E,k)))
           { /* simple subspace */
@@ -624,14 +650,14 @@ mssplit_i(GEN W, GEN H)
   return NULL;
 }
 GEN
-mssplit(GEN W, GEN H)
+mssplit(GEN W, GEN H, long deglim)
 {
   pari_sp av = avma;
   checkms(W);
   if (!msk_get_sign(W))
     pari_err_DOMAIN("mssplit","abs(sign)","!=",gen_1,gen_0);
   H = Qevproj_init0(H);
-  return gerepilecopy(av, mssplit_i(W,H));
+  return gerepilecopy(av, mssplit_i(W,H,deglim));
 }
 
 /* proV = Qevproj_init of a Hecke simple subspace, return [ a_n, n <= B ] */
@@ -678,7 +704,7 @@ msqexpansion_i(GEN W, GEN proV, ulong B)
   iM = ZM_inv_ratlift(Tiv, &diM);
   if (dTiv) diM = gdiv(diM, dTiv);
   L = const_vec(B,NULL);
-  sqrtB = (ulong)sqrt(B);
+  sqrtB = usqrt(B);
   gel(L,1) = d > 1? mkpolmod(gen_1,ch): gen_1;
   for (p = 2; p <= B; p++)
   {
@@ -797,10 +823,9 @@ NP_matrix_extra(ulong M, ulong p)
 static GEN
 WQ_matrix(long N, long Q)
 {
-  long M = N/Q;
-  long w,z, d = cbezout(Q, -M, &w, &z);
+  long w,z, d = cbezout(Q, N/Q, &w, &z);
   if (d != 1) return NULL;
-  return mat2(Q,1,N*z,Q*w);
+  return mat2(Q,1,-N*z,Q*w);
 }
 
 GEN
@@ -1142,7 +1167,7 @@ insert_E(GEN path, PS_sets_t *S, GEN p1N)
 }
 
 static GEN
-cusp_infinity() { return mkvecsmall2(1,0); }
+cusp_infinity(void) { return mkvecsmall2(1,0); }
 
 static void
 form_E_F_T(ulong N, GEN p1N, GEN *pC, PS_sets_t *S)
@@ -1222,9 +1247,9 @@ form_E_F_T(ulong N, GEN p1N, GEN *pC, PS_sets_t *S)
   setlg(S->E2_in_terms_of_E1, E2->nb+1);
 }
 
-/* v = \sum n_i g_i, return \sum n_i g_i^(-1) */
+/* v = \sum n_i g_i, g_i in Sl(2,Z), return \sum n_i g_i^(-1) */
 static GEN
-ZGl2Q_star(GEN v)
+ZSl2_star(GEN v)
 {
   long i, l;
   GEN w, G;
@@ -1239,13 +1264,11 @@ ZGl2Q_star(GEN v)
   }
   return ZG_normalize(mkmat2(w, gel(v,2)));
 }
-static GEN
-ZGl2QC_star(GEN v)
+static void
+ZSl2C_star_inplace(GEN v)
 {
-  long i, l;
-  GEN w = cgetg_copy(v, &l);
-  for (i = 1; i < l; i++) gel(w,i) = ZGl2Q_star(gel(v,i));
-  return w;
+  long i, l = lg(v);
+  for (i = 1; i < l; i++) gel(v,i) = ZSl2_star(gel(v,i));
 }
 
 /* Input: h = set of unimodular paths, p1N = P^1(Z/NZ) = Gamma_0(N)\PSL2(Z)
@@ -1392,7 +1415,7 @@ msinit_N(ulong N)
   GEN C, vecF, vecT2, vecT31;
   ulong r, s, width;
   long nball, nbgen, nbp1N = p1_size(p1N);
-  GEN TAU = mkmat2(mkcol2(gen_0,gen_1), mkcol2(gen_m1,gen_m1)); /*[0,-1;1,-1]*/
+  GEN TAU = mkmat22(gen_0,gen_m1, gen_1,gen_m1); /*[0,-1;1,-1]*/
   GEN W, W2, singlerel, annT2, annT31;
   GEN F_index;
   hashtable *F, *T2, *T31, *T32, *E1, *E2;
@@ -1455,7 +1478,7 @@ msinit_N(ulong N)
     long c = itos(gel(data,1));
     GEN u = gel(data,2); /* E2[s] = u * E1[c], u = - [gamma] */
     GEN gamma = gcoeff(u,1,1);
-    gel(singlerel, c) = mkmat2(mkcol2(gen_1,gamma),mkcol2(gen_1,gen_m1));
+    gel(singlerel, c) = mkmat22(gen_1,gen_1, gamma,gen_m1);
   }
   for (r = E1->nb + 1; r <= width; r++) gel(singlerel, r) = gen_1;
 
@@ -1466,7 +1489,7 @@ msinit_N(ulong N)
   {
     GEN w = gel(vecT2,r);
     GEN gamma = gamma_equiv_matrix(vecreverse(w), w);
-    gel(annT2, r) = mkmat2(mkcol2(gen_1,gamma), mkcol2(gen_1,gen_1));
+    gel(annT2, r) = mkmat22(gen_1,gen_1, gamma,gen_1);
   }
 
   /* form the 3-torsion relations */
@@ -1550,8 +1573,7 @@ voo_act_Gl2Q(GEN g, long k)
 }
 
 struct m_act {
-  long dim, k;
-  long p;
+  long dim, k, p;
   GEN q;
 };
 
@@ -1580,29 +1602,55 @@ RgX_act_Gl2Q(GEN g, long k)
 }
 /* z in Z[Gl2(Q)], return the matrix of z acting on V */
 static GEN
-act_ZGl2Q(GEN z, struct m_act *T, GEN(*act)(struct m_act*,GEN))
+act_ZGl2Q(GEN z, struct m_act *T, GEN(*act)(struct m_act*,GEN), hashtable *H)
 {
-  long l, j;
   GEN S = NULL, G, E;
+  pari_sp av;
+  long l, j;
+  /* paranoia: should'n t occur */
   if (typ(z) == t_INT) return scalarmat_shallow(z, T->dim);
   G = gel(z,1); l = lg(G);
   E = gel(z,2);
+  if (H)
+  { /* First pass, identify matrices in Sl_2 to convert to operators;
+     * insert operators in hashtable. This allows GC in 2nd pass */
+    for (j = 1; j < l; j++)
+    {
+      GEN g = gel(G,j);
+      if (typ(g) != t_INT)
+      {
+        ulong hash = H->hash(g);
+        hashentry *e = hash_search2(H,g,hash);
+        if (!e) hash_insert2(H,g,act(T,g),hash);
+      }
+    }
+  }
+  av = avma;
   for (j = 1; j < l; j++)
   {
     GEN M, g = gel(G,j), n = gel(E,j);
-    if (typ(g) == t_INT)
-      M = scalarmat_shallow(n, T->dim);
+    if (typ(g) == t_INT) /* = 1 */
+      M = n; /* n*Id_dim */
     else
     {
-      M = act(T, g);
+      if (H)
+        M = (GEN)hash_search(H,g)->val; /*search succeeds because of 1st pass*/
+      else
+        M = act(T,g);
       if (is_pm1(n))
-      { if (signe(n) < 0) M = RgM_neg(M);
-      } else
+      { if (signe(n) < 0) M = RgM_neg(M); }
+      else
         M = RgM_Rg_mul(M, n);
     }
-    S = j == 1? M: RgM_add(S, M);
+    if (!S) { S = M; continue; }
+    S = gadd(S, M);
+    if (gc_needed(av,1))
+    {
+      if(DEBUGMEM>1) pari_warn(warnmem,"act_ZGl2Q, j = %ld",j);
+      S = gerepileupto(av, S);
+    }
   }
-  return S;
+  return gerepilecopy(av, S);
 }
 static GEN
 _RgX_act_Gl2Q(struct m_act *S, GEN z) { return RgX_act_Gl2Q(z, S->k); }
@@ -1613,18 +1661,17 @@ RgX_act_ZGl2Q(GEN z, long k)
   struct m_act T;
   T.k = k;
   T.dim = k-1;
-  return act_ZGl2Q(z, &T, _RgX_act_Gl2Q);
+  return act_ZGl2Q(z, &T, _RgX_act_Gl2Q, NULL);
 }
 
-/* Given a vector of elements in Z[G], return it as vector of operators on V
- * (given by t_MAT) */
-static GEN
-ZGl2QC_to_act(struct m_act *S, GEN(*act)(struct m_act*,GEN), GEN v)
+/* Given a sparse vector of elements in Z[G], convert it to a (sparse) vector
+ * of operators on V (given by t_MAT) */
+static void
+ZGl2QC_to_act(struct m_act *S, GEN(*act)(struct m_act*,GEN), GEN v, hashtable *H)
 {
-  long i, l;
-  GEN w = cgetg_copy(v, &l);
-  for (i = 1; i < l; i++) gel(w,i) = act_ZGl2Q(gel(v,i), S, act);
-  return w;
+  GEN val = gel(v,2);
+  long i, l = lg(val);
+  for (i = 1; i < l; i++) gel(val,i) = act_ZGl2Q(gel(val,i), S, act, H);
 }
 
 /* For all V[i] in Z[\Gamma], find the P such that  P . V[i]^* = 0;
@@ -1636,7 +1683,7 @@ ZGV_tors(GEN V, long k)
   GEN v = cgetg(l, t_VEC);
   for (i = 1; i < l; i++)
   {
-    GEN a = ZGl2Q_star(gel(V,i));
+    GEN a = ZSl2_star(gel(V,i));
     gel(v,i) = ZM_ker(RgX_act_ZGl2Q(a,k));
   }
   return v;
@@ -1754,13 +1801,12 @@ M2_log(GEN W, GEN M)
   s = signe(D);
   if (!s) return V;
   if (is_pm1(D))
-  { /* shortcut, not need to apply Manin's trick */
+  { /* shortcut, no need to apply Manin's trick */
     if (s < 0) {
       b = negi(b);
       d = negi(d);
     }
-    M = mkmat2(mkcol2(a,c), mkcol2(b,d));
-    M = Gamma0N_decompose(W, M, &index);
+    M = Gamma0N_decompose(W, mkmat22(a,b, c,d), &index);
     treat_index(W, M, index, V);
   }
   else
@@ -1770,7 +1816,7 @@ M2_log(GEN W, GEN M)
     (void)bezout(a,c,&u,&v);
     B = addii(mulii(b,u), mulii(d,v));
     /* [u,v;-c,a] [a,b; c,d] = [1,B; 0,D], i.e. M = U [1,B;0,D] */
-    U = mkmat2(mkcol2(a, c), mkcol2(negi(v),u));
+    U = mkmat22(a,negi(v), c,u);
 
     /* {1/0 -> B/D} as \sum g_i, g_i unimodular paths */
     PQ = ZV_allpnqn( gboundcf(gdiv(B,D), 0) );
@@ -1876,14 +1922,6 @@ path_to_M2(GEN p)
 
 /* Expresses path p as \sum x_i g_i, where the g_i are our distinguished
  * generators and x_i \in Z[\Gamma]. Returns [x_1,...,x_n] */
-static GEN
-mspathlog_i(GEN W, GEN p)
-{ return M2_log(W, path_to_M2(p)); }
-/* in case the action is trivial: v += mspathlog(path) */
-static void
-mspathlog_i_trivial(GEN v, GEN W, GEN p)
-{ M2_log_trivial(v, W, path_to_M2(p)); }
-
 GEN
 mspathlog(GEN W, GEN p)
 {
@@ -1915,24 +1953,23 @@ mspathlog_trivial(GEN W, GEN p)
 /** HECKE OPERATORS **/
 /* [a,b;c,d] * cusp */
 static GEN
-cusp_mul(GEN cusp, long a, long b, long c, long d)
+cusp_mul(long a, long b, long c, long d, GEN cusp)
 {
   long x = cusp[1], y = cusp[2];
   long A = a*x+b*y, B = c*x+d*y, u = cgcd(A,B);
   if (u != 1) { A /= u; B /= u; }
-  return mkvecsmall2(A, B);
+  return mkcol2s(A, B);
 }
+/* f in Gl2(Q), act on path (zm), return path_to_M2(f.path) */
 static GEN
-path_mul(GEN path, long a, long b, long c, long d)
+Gl2Q_act_path(GEN f, GEN path)
 {
-  GEN c1 = cusp_mul(gel(path,1), a,b,c,d);
-  GEN c2 = cusp_mul(gel(path,2), a,b,c,d);
-  return mkpath(c1,c2);
+  long a = coeff(f,1,1), b = coeff(f,1,2);
+  long c = coeff(f,2,1), d = coeff(f,2,2);
+  GEN c1 = cusp_mul(a,b,c,d, gel(path,1));
+  GEN c2 = cusp_mul(a,b,c,d, gel(path,2));
+  return mkmat2(c1,c2);
 }
-/* f in Gl2(Q), act on path (zm) */
-static GEN
-Gl2Q_act_path(GEN f, GEN path)
-{ return path_mul(path, coeff(f,1,1),coeff(f,1,2),coeff(f,2,1),coeff(f,2,2)); }
 
 static GEN
 init_act_trivial(GEN W) { return zerocol(ms_get_nbE1(W)); }
@@ -1944,126 +1981,154 @@ static GEN
 getMorphism_trivial(GEN WW1, GEN WW2, GEN v)
 {
   GEN W1 = get_ms(WW1), W2 = get_ms(WW2);
-  GEN section = ms_get_section(W2), G = gel(W2,5);
+  GEN section = ms_get_section(W2), gen = ms_get_genindex(W2);
   long j, lv, d2 = ms_get_nbE1(W2);
   GEN T = cgetg(d2+1, t_MAT);
   if (typ(v) != t_VEC) v = mkvec(v);
   lv = lg(v);
   for (j = 1; j <= d2; j++)
   {
-    long l, e = G[j]; /* path-index of E1-element */
-    GEN w = gel(section, e); /* path_to_zm() */
+    GEN w = gel(section, gen[j]);
     GEN t = init_act_trivial(W1);
-    for (l = 1; l < lv; l++)
-      mspathlog_i_trivial(t, W1, Gl2Q_act_path(gel(v,l), w));
+    long l;
+    for (l = 1; l < lv; l++) M2_log_trivial(t, W1, Gl2Q_act_path(gel(v,l), w));
     gel(T,j) = t;
   }
   return shallowtrans(T);
 }
 
+static GEN
+RgV_sparse(GEN v, GEN *pind)
+{
+  long i, l, k;
+  GEN w = cgetg_copy(v,&l), ind = cgetg(l, t_VECSMALL);
+  for (i = k = 1; i < l; i++)
+  {
+    GEN c = gel(v,i);
+    if (typ(c) == t_INT) continue;
+    gel(w,k) = c; ind[k] = i; k++;
+  }
+  setlg(w,k); setlg(ind,k);
+  *pind = ind; return w;
+}
+
+static hashtable *
+Gl2act_cache(long dim) { return set_init(dim*10); }
+
 /* f zm/ZM in Gl_2(Q), acts from the left on Delta, which is generated by
  * (g_i) as Z[Gamma1]-module, and by (G_i) as Z[Gamma2]-module.
  * We have f.G_j = \sum_i \lambda_{i,j} g_i,   \lambda_{i,j} in Z[Gamma1]
- *
  * For phi in Hom_Gamma1(D,V), g in D, phi | f is in Hom_Gamma2(D,V) and
  *  (phi | f)(G_j) = phi(f.G_j) | f
  *                 = phi( \sum_i \lambda_{i,j} g_i ) | f
  *                 = \sum_i phi(g_i) | (\lambda_{i,j}^* f)
- *                 = \sum_i phi(g_i) | \mu_{i,j}
- * Return the \mu_{i,j} matrix as operators on V (t_MAT) */
+ *                 = \sum_i phi(g_i) | \mu_{i,j}(f)
+ * More generally
+ *  (\sum_k (phi |v_k))(G_j) = \sum_i phi(g_i) | \Mu_{i,j}
+ * with \Mu_{i,j} = \sum_k \mu{i,j}(v_k)
+ * Return the \Mu_{i,j} matrix as vector of sparse columns of operators on V */
 static GEN
-init_dual_act_f(GEN f, GEN W1, GEN W2, struct m_act *S,
-                GEN(*act)(struct m_act*,GEN))
+init_dual_act(GEN v, GEN W1, GEN W2, struct m_act *S,
+              GEN(*act)(struct m_act *,GEN))
 {
   GEN section = ms_get_section(W2), gen = ms_get_genindex(W2);
   /* HACK: the actions we consider in dimension 1 are trivial and in
    * characteristic != 2, 3 => torsion generators are 0
    * [satisfy e.g. (1+gamma).g = 0 => \phi(g) | 1+gamma  = 0 => \phi(g) = 0 */
-  long j, dim = S->dim == 1? ms_get_nbE1(W2): lg(gen)-1;
-  GEN T = cgetg(dim+1, t_MAT), F;
-  if (typ(gel(f,1)) == t_VEC)
-  {
-    F = f;
-    f = ZM_to_zm(F);
-  }
-  else
-    F = zm_to_ZM(f);
-  /* f zm = F ZM */
+  long j, lv, dim = S->dim == 1? ms_get_nbE1(W2): lg(gen)-1;
+  GEN T = cgetg(dim+1, t_VEC);
+  hashtable *H = Gl2act_cache(dim);
+
+  if (typ(v) != t_VEC) v = mkvec(v);
+  lv = lg(v);
   for (j = 1; j <= dim; j++)
   {
     pari_sp av = avma;
     GEN w = gel(section, gen[j]); /* path_to_zm( E1/T2/T3 element ) */
-    GEN l = mspathlog_i(W1, Gl2Q_act_path(f, w)); /* lambda_{i,j} */
-    l = ZGl2QC_star(l); /* lambda_{i,j}^* */
-    l = ZGC_G_mul(l, F); /* mu_{i,j} */
-    l = ZGl2QC_to_act(S, act, l);
-    gel(T,j) = gerepilecopy(av, l); /* as operators on V */
+    GEN t = NULL;
+    long k;
+    for (k = 1; k < lv; k++)
+    {
+      GEN ind, L, F, tk, f = gel(v,k);
+      if (typ(gel(f,1)) == t_VECSMALL) F = zm_to_ZM(f);
+      else { F = f; f = ZM_to_zm(F); }
+      /* f zm = F ZM */
+      L = M2_log(W1, Gl2Q_act_path(f,w)); /* L[i] = lambda_{i,j} */
+      L = RgV_sparse(L,&ind);
+      ZSl2C_star_inplace(L); /* L[i] = lambda_{i,j}^* */
+      if (!ZM_isidentity(F)) ZGC_G_mul_inplace(L, F);
+      tk = mkvec2(ind,L); /* L[i] = mu_{i,j}(v[k]) */
+      t = t? ZGC_add_sparse(t, tk): tk;
+    }
+    gel(T,j) = gerepilecopy(av, t);
   }
+  for(j = 1; j <= dim; j++) ZGl2QC_to_act(S, act, gel(T,j), H);
   return T;
 }
+
+/* modular symbol given by phi[j] = \phi(G_j)
+ * \sum L[i]*phi[i], L a sparse column of operators */
 static GEN
-init_dual_act(GEN v, GEN W1, GEN W2, struct m_act *S,
-              GEN(*act)(struct m_act *,GEN))
+dense_act_col(GEN col, GEN phi)
 {
-  long i, lv;
-  GEN L;
-  if (typ(v) != t_VEC) v = mkvec(v);
-  lv = lg(v); L = cgetg(lv, t_MAT);
-  for (i = 1; i < lv; i++)
-    gel(L,i) = init_dual_act_f(gel(v,i), W1, W2, S, act);
-  return L;
+  GEN s = NULL, colind = gel(col,1), colval = gel(col,2);
+  long i, l = lg(colind), lphi = lg(phi);
+  for (i = 1; i < l; i++)
+  {
+    long a = colind[i];
+    GEN t;
+    if (a >= lphi) break; /* happens if k=2: torsion generator t omitted */
+    t = gel(phi, a); /* phi(G_a) */
+    t = RgM_RgC_mul(gel(colval,i), t);
+    s = s? RgC_add(s, t): t;
+  }
+  return s;
 }
-
+/* modular symbol given by \phi( G[ind[j]] ) = val[j]
+ * \sum L[i]*phi[i], L a sparse column of operators */
+static GEN
+sparse_act_col(GEN col, GEN phi)
+{
+  GEN s = NULL, colind = gel(col,1), colval = gel(col,2);
+  GEN ind = gel(phi,2), val = gel(phi,3);
+  long a, l = lg(ind);
+  for (a = 1; a < l; a++)
+  {
+    GEN t = gel(val, a); /* phi(G_i) */
+    long i = zv_search(colind, ind[a]);
+    if (!i) continue;
+    t = RgM_RgC_mul(gel(colval,i), t);
+    s = s? RgC_add(s, t): t;
+  }
+  return s;
+}
+static int
+phi_sparse(GEN phi) { return typ(gel(phi,1)) == t_VECSMALL; }
 /* phi in Hom_Gamma1(Delta, V), return the matrix whose colums are the
  *   \sum_i phi(g_i) | \mu_{i,j} = (phi|f)(G_j),
  * see init_dual_act. */
 static GEN
-dual_act(GEN mu, GEN phi)
+dual_act(long dimV, GEN act, GEN phi)
 {
-  long l = lg(mu), lphi = lg(phi), a, i, j;
-  GEN v;
-  if (lphi == 4 && typ(gel(phi,1)) == t_VECSMALL)
-  { /* sparse representation [ind,pols], phi(G_ind[a]) = pols[a] */
-    GEN ind = gel(phi,2), pols = gel(phi,3);
-    v = cgetg(l, t_MAT);
-    for (j = 1; j < l; j++)
-    {
-      GEN T = NULL;
-      for (a = 1; a < lg(ind); a++)
-      {
-        GEN t = gel(pols, a); /* phi(G_i) */
-        i = ind[a];
-        t = RgM_RgC_mul(gcoeff(mu,i,j), t);
-        T = T? RgC_add(T, t): t;
-      }
-      gel(v,j) = T;
-    }
-  }
-  else
-  { /* dense representation [pols], phi(G_i) = pols[i] */
-    v = cgetg(l, t_VEC);
-    for (j = 1; j < l; j++)
-    {
-      GEN T = NULL;
-      for (i = 1; i < lphi; i++)
-      {
-        GEN t = gel(phi, i); /* phi(G_i) */
-        t = RgM_RgC_mul(gcoeff(mu,i,j), t);
-        T = T? RgC_add(T, t): t;
-      }
-      gel(v,j) = T;
-    }
+  long l = lg(act), j;
+  GEN v = cgetg(l, t_MAT);
+  GEN (*ACT)(GEN,GEN) = phi_sparse(phi)? sparse_act_col: dense_act_col;
+  for (j = 1; j < l; j++)
+  {
+    pari_sp av = avma;
+    GEN s = ACT(gel(act,j), phi);
+    gel(v,j) = s? gerepileupto(av,s): zerocol(dimV);
   }
   return v;
 }
 
-/* phi in Hom(Delta, V), phi(G_k) = vecT[k]. Write phi as
+/* \phi in Hom(Delta, V), \phi(G_k) = phi[k]. Write \phi as
  *   \sum_{i,j} mu_{i,j} phi_{i,j}, mu_{i,j} in Q */
 static GEN
-getMorphism_basis(GEN W, GEN vecT)
+getMorphism_basis(GEN W, GEN phi)
 {
   GEN basis = msk_get_basis(W);
-  long i, j, r, lvecT = lg(vecT), dim = lg(basis)-1;
+  long i, j, r, lvecT = lg(phi), dim = lg(basis)-1;
   GEN st = msk_get_st(W);
   GEN link = msk_get_link(W);
   GEN invphiblock = msk_get_invphiblock(W);
@@ -2073,14 +2138,14 @@ getMorphism_basis(GEN W, GEN vecT)
   {
     GEN Tr, L;
     if (r == s) continue;
-    Tr = gel(vecT,r); /* Phi(G_r), r != 1,s */
+    Tr = gel(phi,r); /* Phi(G_r), r != 1,s */
     L = gel(link, r);
     Q = ZC_apply_dinv(gel(invphiblock,r), Tr);
     /* write Phi(G_r) as sum_{a,b} mu_{a,b} Phi_{a,b}(G_r) */
     for (j = 1; j < lg(L); j++) gel(R, L[j]) = gel(Q,j);
   }
   Ls = gel(link, s);
-  T1 = gel(vecT,1); /* Phi(G_1) */
+  T1 = gel(phi,1); /* Phi(G_1) */
   gel(R, Ls[t]) = mu_st = gel(T1, 1);
 
   T0 = NULL;
@@ -2098,7 +2163,7 @@ getMorphism_basis(GEN W, GEN vecT)
       T0 = T0? RgC_add(T0, z): z; /* += mu_{i,j} Phi_{i,j} (G_s) */
     }
   }
-  Ts = gel(vecT,s); /* Phi(G_s) */
+  Ts = gel(phi,s); /* Phi(G_s) */
   if (T0) Ts = RgC_sub(Ts, T0);
   /* solve \sum_{j!=t} mu_{s,j} Phi_{s,j}(G_s) = Ts */
   Q = ZC_apply_dinv(gel(invphiblock,s), Ts);
@@ -2128,7 +2193,7 @@ ZGl2Q_act_s(GEN b, GEN a, long k)
   }
   else
   {
-    b = RgX_act_ZGl2Q(ZGl2Q_star(b), k);
+    b = RgX_act_ZGl2Q(ZSl2_star(b), k);
     switch(typ(a))
     {
       case t_POL:
@@ -2167,18 +2232,18 @@ checksymbol(GEN W, GEN s)
     a = ZGl2Q_act_s(gel(singlerel,i), a, k);
     t = t? gadd(t, a): a;
   }
-  if (!gcmp0(t)) return 0;
+  if (!gequal0(t)) return 0;
   for (i = 1; i <= nbT2; i++)
   {
     GEN a = gel(s,i + nbE1);
     a = ZGl2Q_act_s(gel(annT2,i), a, k);
-    if (!gcmp0(a)) return 0;
+    if (!gequal0(a)) return 0;
   }
   for (i = 1; i <= nbT31; i++)
   {
     GEN a = gel(s,i + nbE1 + nbT2);
     a = ZGl2Q_act_s(gel(annT31,i), a, k);
-    if (!gcmp0(a)) return 0;
+    if (!gequal0(a)) return 0;
   }
   return 1;
 }
@@ -2215,21 +2280,19 @@ msissymbol(GEN W, GEN s)
   return checksymbol(W,s);
 }
 #if DEBUG
-/* phi_i(G_j) */
+/* phi is a sparse symbol from msk_get_basis, return phi(G_j) */
 static GEN
-eval_phii_Gj(GEN W, long i, long j)
+phi_Gj(GEN W, GEN phi, long j)
 {
-  GEN basis = msk_get_basis(W), b = gel(basis,i);
-  GEN ind = gel(b,2), pols = gel(b,3);
-  long s;
-  for (s = 1; s < lg(ind); s++)
-    if (ind[s] == j) return gel(pols,s);
-  return zerocol(lg(gel(pols,1))-1);
+  GEN ind = gel(phi,2), pols = gel(phi,3);
+  long i = vecsmall_isin(ind,j);
+  return i? gel(pols,i): NULL;
 }
 /* check that \sum d_i phi_i(G_j)  = T_j for all j */
 static void
 checkdec(GEN W, GEN D, GEN T)
 {
+  GEN B = msk_get_basis(W);
   long i, j;
   if (!checksymbol(W,T)) pari_err_BUG("checkdec");
   for (j = 1; j < lg(T); j++)
@@ -2237,9 +2300,9 @@ checkdec(GEN W, GEN D, GEN T)
     GEN S = gen_0;
     for (i = 1; i < lg(D); i++)
     {
-      GEN d = gel(D,i);
-      if (gcmp0(d)) continue;
-      S = gadd(S, gmul(d, eval_phii_Gj(W, i, j)));
+      GEN d = gel(D,i), v = phi_Gj(W, gel(B,i), j);
+      if (!v || gequal0(d)) continue;
+      S = gadd(S, gmul(d, v));
     }
     /* S = \sum_i d_i phi_i(G_j) */
     if (!gequal(S, gel(T,j)))
@@ -2254,28 +2317,19 @@ static GEN
 getMorphism(GEN W1, GEN W2, GEN v)
 {
   struct m_act S;
-  GEN basis1, M, act;
-  long k, i, a, dim1, lv;
-  k = msk_get_weight(W1);
+  GEN B1, M, act;
+  long a, l, k = msk_get_weight(W1);
   if (k == 2) return getMorphism_trivial(W1,W2,v);
-  basis1 = msk_get_basis(W1);
-  dim1 = lg(basis1)-1;
-  M = cgetg(dim1+1, t_MAT);
   S.k = k;
   S.dim = k-1;
   act = init_dual_act(v,W1,W2,&S, _RgX_act_Gl2Q);
-  lv = lg(act);
-  for (a = 1; a <= dim1; a++)
+  B1 = msk_get_basis(W1);
+  l = lg(B1); M = cgetg(l, t_MAT);
+  for (a = 1; a < l; a++)
   {
     pari_sp av = avma;
-    GEN phi = gel(basis1, a), D, T = NULL;
-    for (i = 1; i < lv; i++)
-    {
-      GEN t = dual_act(gel(act,i), phi);
-      T = T? gerepileupto(av, RgM_add(T,t)): t;
-    }
-    /* T = (phi|op)(G_1,...,G_d2) */
-    D = getMorphism_basis(W2, T);
+    GEN phi = dual_act(S.dim, act, gel(B1,a));
+    GEN D = getMorphism_basis(W2, phi);
 #if DEBUG
     checkdec(W2,D,T);
 #endif
@@ -2283,45 +2337,9 @@ getMorphism(GEN W1, GEN W2, GEN v)
   }
   return M;
 }
-/* return op(phi), op = \sum_i [act[i]] */
-static GEN
-getMorphism_single(GEN phi, GEN act)
-{
-  pari_sp av = avma;
-  long i, lv = lg(act);
-  GEN T = NULL;
-  for (i = 1; i < lv; i++)
-  {
-    GEN t = dual_act(gel(act,i), phi);
-    T = T? gerepileupto(av, RgV_add(T,t)): t;
-  }
-  if (!T) T = zerovec(lg(phi)-1);
-  return T; /* = (phi|op)(G_1,...,G_d2) */
-}
-/* return op(phi), op = sum \chi_D(i) act[i] */
-static GEN
-getMorphism_single_twist(GEN phi, GEN act, long D)
-{
-  pari_sp av = avma;
-  long i, lv = lg(act);
-  GEN T = NULL;
-  for (i = 1; i < lv; i++)
-  {
-    GEN t;
-    long s = kross(i,D);
-    if (!s) continue;
-    t = dual_act(gel(act,i), phi);
-    if (!T)
-      T = s>0? t: RgV_neg(t);
-    else
-      T = gerepileupto(av, s > 0? RgV_add(T,t): RgV_sub(T,t));
-  }
-  if (!T) T = zerovec(lg(phi)-1);
-  return T; /* = (phi|op)(G_1,...,G_d2) */
-}
-
 static GEN
 msendo(GEN W, GEN v) { return getMorphism(W, W, v); }
+
 static GEN
 endo_project(GEN W, GEN e, GEN H)
 {
@@ -2370,17 +2388,12 @@ msatkinlehner(GEN W, long Q, GEN H)
   if (Q <= 0) pari_err_DOMAIN("msatkinlehner","Q","<=",gen_0,stoi(Q));
   w = msatkinlehner_i(W,Q);
   w = endo_project(W,w,H);
-  if (k > 2 && Q != 1)
-    w = RgM_Rg_div(w, powuu(Q,(k-2)>>1));
+  if (k > 2 && Q != 1) w = RgM_Rg_div(w, powuu(Q,(k-2)>>1));
   return gerepilecopy(av, w);
 }
 
 static GEN
-msstar_i(GEN W)
-{
-  GEN v = mat2(-1,0,0,1);
-  return msendo(W,v);
-}
+msstar_i(GEN W) { return msendo(W, mat2(-1,0,0,1)); }
 GEN
 msstar(GEN W, GEN H)
 {
@@ -2431,7 +2444,7 @@ msfromcusp_trivial(GEN W, GEN c)
   GEN section = ms_get_section(W), gen = ms_get_genindex(W);
   GEN S = ms_get_hashcusps(W);
   long j, ic = cusp_index(c, S), l = ms_get_nbE1(W)+1;
-  GEN vecT = cgetg(l, t_COL);
+  GEN phi = cgetg(l, t_COL);
   for (j = 1; j < l; j++)
   {
     GEN vj, g = gel(section, gen[j]); /* path_to_zm(generator) */
@@ -2442,14 +2455,14 @@ msfromcusp_trivial(GEN W, GEN c)
       vj = (i2 == ic)?  gen_0: gen_1;
     else
       vj = (i2 == ic)? gen_m1: gen_0;
-    gel(vecT, j) = vj;
+    gel(phi, j) = vj;
   }
-  return vecT;
+  return phi;
 }
 static GEN
 msfromcusp_i(GEN W, GEN c)
 {
-  GEN section, gen, S, vecT;
+  GEN section, gen, S, phi;
   long j, ic, l, k = msk_get_weight(W);
   if (k == 2) return msfromcusp_trivial(W, c);
   k = msk_get_weight(W);
@@ -2458,7 +2471,7 @@ msfromcusp_i(GEN W, GEN c)
   S = ms_get_hashcusps(W);
   ic = cusp_index(c, S);
   l = lg(gen);
-  vecT = cgetg(l, t_COL);
+  phi = cgetg(l, t_COL);
   for (j = 1; j < l; j++)
   {
     GEN vj = NULL, g = gel(section, gen[j]); /* path_to_zm(generator) */
@@ -2472,9 +2485,9 @@ msfromcusp_i(GEN W, GEN c)
       vj = vj? gsub(vj, s): gneg(s);
     }
     if (!vj) vj = zerocol(k-1);
-    gel(vecT, j) = vj;
+    gel(phi, j) = vj;
   }
-  return getMorphism_basis(W, vecT);
+  return getMorphism_basis(W, phi);
 }
 GEN
 msfromcusp(GEN W, GEN c)
@@ -2579,7 +2592,7 @@ RgMV_find_non_zero_last_row(long offset, GEN V)
     for (j = 1; j < l; j++)
     {
       GEN a = gcoeff(M, n, j);
-      if (!gcmp0(a) && (!m || absi_cmp(a, m) < 0))
+      if (!gequal0(a) && (!m || absi_cmp(a, m) < 0))
       {
         m = a; lasti = i; lastj = j;
         if (is_pm1(m)) goto END;
@@ -2632,6 +2645,7 @@ get_phi_ij(long i,long j,long n, long s,long t,GEN P_st,GEN Q_st,GEN d_st,
       ind = mkvecsmall3(1, i, s);
       pols = mkvec3(c, a, b); /* image of g_1, g_i, g_s */
     }
+    pols = Q_primpart(pols);
   }
   return mkvec3(mkvecsmall3(i,j,n), ind, pols);
 }
@@ -2656,7 +2670,7 @@ mskinit_nontrivial(GEN WN, long k)
   GEN annT2 = gel(WN,8), annT31 = gel(WN,9), singlerel = gel(WN,10);
   GEN link, basis, monomials, invphiblock;
   long nbE1 = ms_get_nbE1(WN);
-  GEN dinv = Delta_inv(ZG_neg( ZGl2Q_star(gel(singlerel,1)) ), k);
+  GEN dinv = Delta_inv(ZG_neg( ZSl2_star(gel(singlerel,1)) ), k);
   GEN p1 = cgetg(nbE1+1, t_VEC), remove;
   GEN p2 = ZGV_tors(annT2, k);
   GEN p3 = ZGV_tors(annT31, k);
@@ -2667,7 +2681,7 @@ mskinit_nontrivial(GEN WN, long k)
   for (i = 2; i <= nbE1; i++) /* skip 1st element = (\gamma_oo-1)g_oo */
   {
     GEN z = gel(singlerel, i);
-    gel(p1, i) = RgX_act_ZGl2Q(ZGl2Q_star(z), k);
+    gel(p1, i) = RgX_act_ZGl2Q(ZSl2_star(z), k);
   }
   remove = RgMV_find_non_zero_last_row(nbE1, gentor);
   if (!remove) remove = RgMV_find_non_zero_last_row(0, p1);
@@ -2684,7 +2698,8 @@ mskinit_nontrivial(GEN WN, long k)
    * allowed values for phi(g_i): with basis (P^{i,j}) given by the monomials
    * x^(j-1) y^{k-2-(j-1)}, j = 1 .. k-1
    * (g_i in E_1) or the solution of the torsion equations (1 + gamma)P = 0
-   * (g_i in T2) or (1 + gamma + gamma^2)P = 0 (g_i in T31).
+   * (g_i in T2) or (1 + gamma + gamma^2)P = 0 (g_i in T31). All such P
+   * are chosen in Z[x,y] with Q_content 1.
    *
    * The Manin relation (singlerel) is of the form \sum_i \lambda_i g_i = 0,
    * where \lambda_i = 1 if g_i in T2 or T31, and \lambda_i = (1 - \gamma_i)
@@ -2708,7 +2723,8 @@ mskinit_nontrivial(GEN WN, long k)
    *   g_s -> - d_{i,j} P_{s,t}
    * If i = s, j != t
    *   g_i -> d_{s,t} P_{i,j} - d_{i,j} P_{s,t}
-   * And everything else to 0. */
+   * And everything else to 0. Again we normalize the phi_{i,j} such that
+   * their image has content 1. */
   monomials = matid(k-1); /* represent the monomials x^{k-2}, ... , y^{k-2} */
   if (s <= nbE1) /* in E1 */
   {
@@ -2813,7 +2829,7 @@ msinit(GEN N, GEN K, long sign)
 
 /* W = msinit, xpm modular symbol attached to elliptic curve E;
  * c t_FRAC; image of <oo->c> */
-GEN
+static GEN
 Q_xpm(GEN W, GEN xpm, GEN c)
 {
   pari_sp av = avma;
@@ -2911,15 +2927,6 @@ mseval(GEN W, GEN s, GEN p)
   return gerepilecopy(av, s);
 }
 
-static GEN
-twistcurve(GEN e, GEN D)
-{
-  GEN D2 = sqri(D);
-  GEN a4 = mulii(mulsi(-27, D2), ell_get_c4(e));
-  GEN a6 = mulii(mulsi(-54, mulii(D, D2)), ell_get_c6(e));
-  return ellinit(mkvec2(a4,a6),NULL,DEFAULTPREC);
-}
-
 /* sum_{a <= |D|} (D/a)*xpm(E,a/|D|) */
 static GEN
 get_X(GEN W, GEN xpm, long D)
@@ -2940,58 +2947,95 @@ get_X(GEN W, GEN xpm, long D)
   }
   return t;
 }
-/* quotient of the Neron periods of E^(d) and E, divided by sqrt(d) */
-static long
-get_alpha_d(GEN E, long d)
-{
-  if (odd(d)) return 1;
-  if (!mpodd(ell_get_c4(E))) return 2; /* additive reduction at 2 */
-  /* reduction not additive */
-  return (d % 8 == 0 && !mpodd(ell_get_a1(E)))? 2: 1;
-}
-/* write L(E,1) = Q*w1, return the rational Q */
+/* E of rank 0, minimal model; write L(E,1) = Q*w1(E) != 0 and return the
+ * rational Q; tam = product of all Tamagawa (incl. c_oo(E)). */
 static GEN
-get_Q(GEN E)
+get_Q(GEN E, GEN tam)
 {
-  GEN L, N, tam, T, n, w1;
+  GEN L, T, sha, w1 = gel(ellR_omega(E,DEFAULTPREC), 1);
   long ex, t, t2;
-  E = ellanal_globalred_all(E, NULL, &N, &tam);
-  T = elltors(E); t = itos(gel(T,1)); t2 = t*t;
-  w1 = gel(ellR_omega(E,DEFAULTPREC), 1);
 
-  /* |Sha| = n^2 */
+  T = elltors(E); t = itos(gel(T,1)); t2 = t*t;
   L = ellL1(E, 0, DEFAULTPREC);
-  n = sqrtr(divrr(mulru(L, t2), mulri(w1,tam)));
-  n = grndtoi(n, &ex);
+  sha = divrr(mulru(L, t2), mulri(w1,tam)); /* integral = |Sha| by BSD */
+  sha = sqri( grndtoi(sqrtr(sha), &ex) ); /* |Sha| is a square */
   if (ex > -5) pari_err_BUG("msfromell (can't compute analytic |Sha|)");
-  return gdivgs(mulii(tam,sqri(n)), t2);
+  return gdivgs(mulii(tam,sha), t2);
 }
 
-/* Let C such that C*L(E,1)_{xpm} = L(E,1) / w1; return C * xpm */
+/* E given by a minimal model; D != 0. Compare Euler factor of L(E,(D/.),1)
+ * with L(E^D,1). Return
+ *   \prod_{p|D} (p-a_p(E)+eps_{E}(p)) / p,
+ * where eps(p) = 0 if p | N_E and 1 otherwise */
 static GEN
-ell_get_scale(GEN E, GEN W, GEN xpm, long s)
+get_Euler(GEN E, long D)
 {
-  GEN Q, X = NULL;
-  long d, N = ms_get_N(W);
+  GEN t = gen_1, P = gel(factoru(labs(D)), 1);
+  GEN Delta = ell_get_disc(E); /* same prime divisors as N_E */
+  long i, l = lg(P);
+  for (i=1; i<l; i++)
+  {
+    long p = P[i];
+    long b = p - itos(ellap(E,utoipos(p))) + (dvdiu(Delta,p)?0L:1L);
+    t = gdivgs(gmulgs(t, b), p);
+  }
+  return t;
+}
 
+/* E given by a minimal model, xpm in the sign(D) part with the same
+ * eigenvalues as E (unique up to multiplication with a rational).
+ * Let X(D) = \sum_{a <= |D|} (D/a) * xpm(E, a/|D|)
+ * Return the rational correction factor A such that
+ *   A * X(D) = L(E, (D/.), 1) / \Omega(E^D)
+ * for fundamental D (such that E^D has rank 0 otherwise both sides vanish). */
+static GEN
+ell_get_scale_d(GEN E, GEN W, GEN xpm, long D)
+{
+  GEN cb, N, Q, tam, u, Ed, X = get_X(W, xpm, D);
+
+  if (!signe(X)) return NULL;
+  if (D == 1)
+    Ed = E;
+  else
+    Ed = ellinit(elltwist(E, stoi(D)), NULL, DEFAULTPREC);
+  Ed = ellanal_globalred_all(Ed, &cb, &N, &tam);
+  Q =  get_Q(Ed, tam);
+  if (cb)
+  { /* \tilde{u} in Pal's "Periods of quadratic twists of elliptic curves" */
+    u = gel(cb,1); /* Omega(E^D_min) = u * Omega(E^D) */
+    if (cmpiu(Q_denom(u), 2) > 0) pari_err_BUG("msfromell [ell_get_scale]");
+    Q = gmul(Q,u);
+  }
+  /* L(E^D,1) = Q * w1(E^D_min) */
+  Q = gmul(Q, get_Euler(Ed, D));
+  if (D != 1) obj_free(Ed);
+  /* L(E^D,1) / Omega(E^D) = Q. Divide by X to get A */
+  return gdiv(Q, X);
+}
+
+/* Let W = msinit(conductor(E), 2), xpm a modular symbol with the same
+ * eigenvalues as L_E. There exist a unique C such that
+ *   C*L(E,(D/.),1)_{xpm} = L(E,(D/.),1) / w1(E_D) != 0, for all D fundamental,
+ * sign(D) = s, and such that E_D has rank 0. Return the normalized symbol
+ * C * xpm */
+static GEN
+ell_get_scale(GEN E, GEN W, GEN xpm, long s)
+{
+  long d;
   xpm = Q_primpart(xpm);
   /* find D = s*d such that twist by D has rank 0 */
   for (d = 1; d < LONG_MAX; d++)
   {
     pari_sp av = avma;
-    if (cgcd(N, d) != 1) continue;
-    if (s < 0)
-    { if (!unegisfundamental(d)) continue; }
-    else
-    { if (!uposisfundamental(d)) continue; }
-    X = get_X(W, xpm, s < 0? -d: d);
-    if (signe(X)) break;
+    GEN C;
+    long D = s > 0? d: -d;
+    if (!sisfundamental(D)) continue;
+    C = ell_get_scale_d(E, W, xpm, D);
+    if (C) return RgC_Rg_mul(xpm, C);
     avma = av;
   }
-  if (d == LONG_MAX) pari_err_BUG("msfromell (no suitable twist)");
-  if (s < 0) d = -d;
-  Q = get_Q(twistcurve(E, stoi(d)));
-  return RgC_Rg_mul(xpm, gdiv(gmulsg(get_alpha_d(E,d), Q), X));
+  pari_err_BUG("msfromell (no suitable twist)");
+  return NULL;
 }
 
 GEN
@@ -3061,69 +3105,132 @@ msfromell(GEN E, long sign)
   return gerepilecopy(av, mkvec2(W, x));
 }
 
+GEN
+msfromhecke(GEN W, GEN v, GEN H)
+{
+  pari_sp av = avma;
+  long i, l = lg(v);
+  GEN K = NULL;
+  checkms(W);
+  if (typ(v) != t_VEC) pari_err_TYPE("msfromhecke",v);
+  for (i = 1; i < l; i++)
+  {
+    GEN K2, T, p, P, c = gel(v,i);
+    if (typ(c) != t_VEC || lg(c) != 3) pari_err_TYPE("msfromhecke",v);
+    p = gel(c,1);
+    if (typ(p) != t_INT) pari_err_TYPE("msfromhecke",v);
+    P = gel(c,2);
+    switch(typ(P))
+    {
+      case t_INT:
+        P = deg1pol_shallow(gen_1, negi(P), 0);
+        break;
+      case t_POL:
+        if (RgX_is_ZX(P)) break;
+      default:
+        pari_err_TYPE("msfromhecke",v);
+    };
+    T = mshecke(W, itos(p), H);
+    T = Q_primpart(RgX_RgM_eval(P, T));
+    if (K) T = ZM_mul(T,K);
+    K2 = ZM_ker(T);
+    if (!K) K = K2;
+    else if (lg(K2) < lg(K)) K = ZM_mul(K,K2);
+  }
+  return gerepilecopy(av, K);
+}
+
 /* OVERCONVERGENT MODULAR SYMBOLS */
 
+static GEN
+mspadic_get_Wp(GEN W) { return gel(W,1); }
+static GEN
+mspadic_get_Tp(GEN W) { return gel(W,2); }
+static GEN
+mspadic_get_bin(GEN W) { return gel(W,3); }
+static GEN
+mspadic_get_actUp(GEN W) { return gel(W,4); }
+static GEN
+mspadic_get_q(GEN W) { return gel(W,5); }
+static long
+mspadic_get_p(GEN W) { return gel(W,6)[1]; }
+static long
+mspadic_get_n(GEN W) { return gel(W,6)[2]; }
+static long
+mspadic_get_flag(GEN W) { return gel(W,6)[3]; }
+static GEN
+mspadic_get_M(GEN W) { return gel(W,7); }
+static GEN
+mspadic_get_C(GEN W) { return gel(W,8); }
+static long
+mspadic_get_weight(GEN W) { return msk_get_weight(mspadic_get_Wp(W)); }
+
+void
+checkmspadic(GEN W)
+{
+  if (typ(W) != t_VEC || lg(W) != 9) pari_err_TYPE("checkmspadic",W);
+  checkms(mspadic_get_Wp(W));
+}
+
 /* f in M_2(Z) \cap GL_2(Q), p \nmid a [ and for the result to mean anything
  * p | c, but not needed here]. Return the matrix M in M_D(Z), D = M+k-1
  * such that, if v = \int x^i d mu, i < D, is a vector of D moments of mu,
  * then M * v is the vector of moments of mu | f  mod p^D */
 static GEN
-moments_act(struct m_act*S, GEN f)
+moments_act(struct m_act *S, GEN f)
 {
-  long k = S->k, D = S->dim;
+  pari_sp av = avma;
+  long j, k = S->k, D = S->dim;
   GEN a = gcoeff(f,1,1), b = gcoeff(f,1,2);
   GEN c = gcoeff(f,2,1), d = gcoeff(f,2,2);
-  GEN u,z, q = S->q, den = deg1pol(c,a,0), num = deg1pol(d,b,0);
-  GEN mat = cgetg(D+1, t_MAT);
-  long j;
-
-  u = RgXn_inv(gmodulo(den, q), D);
-  u = RgXn_mul(num, u, D); /* = (b+dx) / (a+cx) mod (q,x^D) */
-  z = gpowgs(den, k-2); /* (a+cx)^(k-2) */
-  u = liftint_shallow(u);
+  GEN u,z,C, q = S->q, mat = cgetg(D+1, t_MAT);
+
+  a = modii(a,q);
+  z = FpX_powu(deg1pol(c,a,0), k-2, q); /* (a+cx)^(k-2) */
+  /* u := (b+dx) / (a+cx) mod (q,x^D) = (b/a +d/a*x) / (1 - (-c/a)*x) */
+  if (!equali1(a))
+  {
+    GEN ai = Fp_inv(a,q);
+    b = Fp_mul(b,ai,q);
+    c = Fp_mul(c,ai,q);
+    d = Fp_mul(d,ai,q);
+  }
+  u = cgetg(D+2,t_POL); u[1] = evalsigne(1)|evalvarn(0);
+  gel(u, 2) = gen_1;
+  gel(u, 3) = C = Fp_neg(c,q);
+  for (j = 4; j < D+2; j++) gel(u,j) = Fp_mul(gel(u,j-1), C, q);
+  u = FpX_red(RgXn_mul(deg1pol(d,b,0), u, D), q);
   for (j = 1; j <= D; j++)
   {
-    z = FpX_red(z, q);
     gel(mat,j) = RgX_to_RgC(z, D); /* (a+cx)^(k-2) * ((b+dx)/(a+cx))^(j-1) */
-    if (j != D) z = RgXn_mul(z, u, D);
+    if (j != D) z = FpX_red(RgXn_mul(z, u, D), q);
   }
-  return shallowtrans(mat);
+  return gerepilecopy(av, shallowtrans(mat));
 }
 
 static GEN
-init_moments_act(GEN W1, GEN W2, long p, long M, GEN q, GEN v)
+init_moments_act(GEN W, long p, long n, GEN q, GEN v)
 {
   struct m_act S;
-  long k = msk_get_weight(W2);
+  long k = msk_get_weight(W);
   S.p = p;
   S.k = k;
   S.q = q;
-  S.dim = M+k-1;
-  return init_dual_act(v,W1,W2,&S, moments_act);
+  S.dim = n+k-1;
+  return init_dual_act(v,W,W,&S, moments_act);
 }
 
 static void
-clean_tail(GEN phi, long c, GEN q, long flag)
+clean_tail(GEN phi, long c, GEN q)
 {
   long a, l = lg(phi);
-  GEN den;
-  if (flag)
-  {
-    phi = Q_remove_denom(phi, &den);
-    if (!den)
-      flag = 0;
-    else
-      q = mulii(q, den);
-  }
   for (a = 1; a < l; a++)
   {
     GEN P = FpV_red(gel(phi,a), q); /* phi(G_a) = vector of moments */
     long j, lP = lg(P);
     for (j = c; j < lP; j++) gel(P,j) = gen_0; /* reset garbage to 0 */
-    if (flag) P = gdiv(P, den);
     gel(phi,a) = P;
   }
-
 }
 /* concat z to all phi[i] */
 static GEN
@@ -3162,58 +3269,52 @@ red_mod_FilM(GEN phi, ulong p, long k, long flag)
   return v;
 }
 
+/* denom(C) | p^(2(k-1) - v_p(ap)) */
 static GEN
-oms_supersingular(GEN phi, GEN W, long p, long M, GEN C)
+oms_dim2(GEN W, GEN phi, GEN C, GEN ap)
 {
-  long t, i, k = msk_get_weight(W);
+  long t, i, k = mspadic_get_weight(W);
+  long p = mspadic_get_p(W), n = mspadic_get_n(W);
   GEN phi1 = gel(phi,1), phi2 = gel(phi,2);
-  GEN v = Up_matrices(p), q = powuu(p, k*M);
-  GEN act = init_moments_act(W, W, p, M, q, v);
-  GEN ap = gcoeff(C,1,1), a,b,c,d;
+  GEN v, q = mspadic_get_q(W);
+  GEN act = mspadic_get_actUp(W);
 
   t = signe(ap)? Z_lval(ap,p) : k-1;
-  C = ginv(ZM_sqr(C));
-  a = gcoeff(C,1,1);
-  b = gcoeff(C,1,2);
-  c = gcoeff(C,2,1);
-  d = gcoeff(C,2,2);
-
-  phi1 = concat2(phi1, zerovec(M));
-  phi2 = concat2(phi2, zerovec(M));
-  for (i = 1; i <= M; i++)
-  {
-    GEN z;
-    phi1 = getMorphism_single(phi1, act);
-    phi1 = getMorphism_single(phi1, act);
-
-    phi2 = getMorphism_single(phi2, act);
-    phi2 = getMorphism_single(phi2, act);
-    z = phi1;
-    phi1 = gadd(gmul(a, z), gmul(b, phi2));
-    phi2 = gadd(gmul(c, z), gmul(d, phi2));
-
-    clean_tail(phi1, k + i*t, q, 1);
-    clean_tail(phi2, k + i*t, q, 1);
-  }
-  phi1 = red_mod_FilM(phi1, p, k, 1);
-  phi2 = red_mod_FilM(phi2, p, k, 1);
+  phi1 = concat2(phi1, zerovec(n));
+  phi2 = concat2(phi2, zerovec(n));
+  for (i = 1; i <= n; i++)
+  {
+    phi1 = dual_act(k-1, act, phi1);
+    phi1 = dual_act(k-1, act, phi1);
+    clean_tail(phi1, k + i*t, q);
+
+    phi2 = dual_act(k-1, act, phi2);
+    phi2 = dual_act(k-1, act, phi2);
+    clean_tail(phi2, k + i*t, q);
+  }
+  C = gpowgs(C,n);
+  v = RgM_RgC_mul(C, mkcol2(phi1,phi2));
+  phi1 = red_mod_FilM(gel(v,1), p, k, 1);
+  phi2 = red_mod_FilM(gel(v,2), p, k, 1);
   return mkvec2(phi1,phi2);
 }
 
+/* flag = 0 iff alpha is a p-unit */
 static GEN
-oms_ordinary(GEN W, GEN phi, GEN alpha, long p, long M)
+oms_dim1(GEN W, GEN phi, GEN alpha, long flag)
 {
-  long i, k = msk_get_weight(W);
-  GEN q = powuu(p,M);
-  GEN act = init_moments_act(W, W, p, M, q, Up_matrices(p));
-  phi = concat2(phi, zerovec(M));
-  for (i = 1; i <= M; i++)
+  long i, k = mspadic_get_weight(W);
+  long p = mspadic_get_p(W), n = mspadic_get_n(W);
+  GEN q = mspadic_get_q(W);
+  GEN act = mspadic_get_actUp(W);
+  phi = concat2(phi, zerovec(n));
+  for (i = 1; i <= n; i++)
   {
-    phi = getMorphism_single(phi, act);
-    clean_tail(phi, k + i, q, 0);
+    phi = dual_act(k-1, act, phi);
+    clean_tail(phi, k + i, q);
   }
-  phi = gmul(lift(gpowgs(alpha,M)), phi);
-  phi = red_mod_FilM(phi, p, k, 0);
+  phi = gmul(lift(gpowgs(alpha,n)), phi);
+  phi = red_mod_FilM(phi, p, k, flag);
   return mkvec(phi);
 }
 
@@ -3249,100 +3350,235 @@ RgXC_to_moments(GEN v, GEN bin)
   return w;
 }
 
-/* assume O[2] is integral, den is the cancelled denominator or NULL */
+/* W an mspadic, assume O[2] is integral, den is the cancelled denominator
+ * or NULL, L = log(path) */
 static GEN
-omseval_int(GEN O, GEN path, GEN den)
+omseval_int(struct m_act *S, GEN PHI, GEN L, hashtable *H)
+{
+  long a, lphi;
+  GEN ind, v = cgetg_copy(PHI, &lphi);
+
+  L = RgV_sparse(L,&ind);
+  ZSl2C_star_inplace(L); /* lambda_{i,j}^* */
+  L = mkvec2(ind,L);
+  ZGl2QC_to_act(S, moments_act, L, H); /* as operators on V */
+  for (a = 1; a < lphi; a++)
+  {
+    GEN T = dense_act_col(L, gel(PHI,a));
+    if (T) T = FpC_red(T,S->q); else T = zerocol(S->dim);
+    gel(v,a) = T;
+  }
+  return v;
+}
+
+GEN
+msomseval(GEN W, GEN phi, GEN path)
 {
   struct m_act S;
-  GEN v, L, W, PHI, data, q, act, T = NULL;
-  long p, n, a, k, lvec;
+  pari_sp av = avma;
+  GEN v, Wp;
+  long n, vden;
+  checkmspadic(W);
+  if (typ(phi) != t_COL || lg(phi) != 4)  pari_err_TYPE("msomseval",phi);
+  vden = itos(gel(phi,2));
+  phi = gel(phi,1);
+  n = mspadic_get_n(W);
+  Wp= mspadic_get_Wp(W);
+  S.k = mspadic_get_weight(W);
+  S.p = mspadic_get_p(W);
+  S.q = powuu(S.p, n+vden);
+  S.dim = n + S.k - 1;
+  v = omseval_int(&S, phi, mspathlog(Wp,path), NULL);
+  return gerepilecopy(av, v);
+}
+/* W = msinit(N,k,...); if flag < 0 or flag >= k-1, allow all symbols;
+ * else commit to v_p(a_p) <= flag (ordinary if flag = 0)*/
+GEN
+mspadicinit(GEN W, long p, long n, long flag)
+{
+  pari_sp av = avma;
+  long a, N, k;
+  GEN P, C, M, bin, Wp, Tp, q, pn, actUp, teich, pas;
 
-  W = gel(O,1); /* possibly in level N*p */
+  checkms(W);
+  N = ms_get_N(W);
   k = msk_get_weight(W);
-  PHI = gel(O,2);
-  data = gel(O,3);
-  p = itos(gel(data,3));
-  n = itos(gel(data,4));
-  L = M2_log(W, path);
-
-  q = powuu(p,n);
-  if (den) q = mulii(q,den);
-  S.p = p;
-  S.k = k;
-  S.q = q;
-  S.dim = n+k-1;
+  if (flag < 0) flag = 1; /* worst case */
+  else if (flag >= k) flag = k-1;
 
-  v = cgetg_copy(PHI, &lvec);
-  L = ZGl2QC_star(L); /* lambda_{i,j}^* */
-  act = ZGl2QC_to_act(&S, moments_act, L); /* as operators on V */
-  for (a = 1; a < lvec; a++)
+  bin = vecbinome(k-2);
+  Tp = mshecke(W, p, NULL);
+  if (N % p == 0)
   {
-    GEN phi = gel(PHI,a);
-    long i;
-    for (i = 1; i < lg(phi); i ++)
+    if ((N/p) % p == 0) pari_err_IMPL("mspadicinit when p^2 | N");
+    /* a_p != 0 */
+    Wp = W;
+    M = gen_0;
+    flag = (k-2) / 2; /* exact valuation */
+    /* will multiply by matrix with denominator p^(k-2)/2 in mspadicint.
+     * Except if p = 2 (multiply by alpha^2) */
+    if (p == 2) n += k-2; else n += (k-2)/2;
+    pn = powuu(p,n);
+    /* For accuracy mod p^n, oms_dim1 require p^(k/2*n) */
+    q = powiu(pn, k/2);
+  }
+  else
+  { /* p-stabilize */
+    long s = msk_get_sign(W);
+    GEN M1, M2;
+
+    Wp = mskinit(N*p, k, s);
+    M1 = getMorphism(W, Wp, mat2(1,0,0,1));
+    M2 = getMorphism(W, Wp, mat2(p,0,0,1));
+    if (s)
     {
-      GEN t = RgM_RgC_mul(gel(act,i), gel(phi,i));
-      T = T? gadd(T,t): t;
+      GEN SW = msk_get_starproj(W), SWp = msk_get_starproj(Wp);
+      M1 = Qevproj_apply2(M1, SW, SWp);
+      M2 = Qevproj_apply2(M2, SW, SWp);
     }
-    gel(v,a) = FpC_red(T,q);
+    M = mkvec2(M1,M2);
+    n += Z_lval(Q_denom(M), p); /*den. introduced by p-stabilization*/
+    /* in supersingular case: will multiply by matrix with denominator p^k
+     * in mspadicint. Except if p = 2 (multiply by alpha^2) */
+    if (flag) { if (p == 2) n += 2*k-2; else n += k; }
+    pn = powuu(p,n);
+    /* For accuracy mod p^n, supersingular require p^((2k-1-v_p(a_p))*n) */
+    if (flag) /* k-1 also takes care of a_p = 0. Worst case v_p(a_p) = flag */
+      q = powiu(pn, 2*k-1 - flag);
+    else
+      q = pn;
   }
-  return v;
+  actUp = init_moments_act(Wp, p, n, q, Up_matrices(p));
+
+  if (p == 2) C = gen_0;
+  else
+  {
+    pas = matpascal(n);
+    teich = teichmullerinit(p, n+1);
+    P = gpowers(utoipos(p), n);
+    C = cgetg(p, t_VEC);
+    for (a = 1; a < p; a++)
+    { /* powb[j+1] = ((a - w(a)) / p)^j mod p^n */
+      GEN powb = Fp_powers(diviuexact(subui(a, gel(teich,a)), p), n, pn);
+      GEN Ca = cgetg(n+2, t_VEC);
+      long j, r, ai = Fl_inv(a, p); /* a^(-1) */
+      gel(C,a) = Ca;
+      for (j = 0; j <= n; j++)
+      {
+        GEN Caj = cgetg(j+2, t_VEC);
+        GEN atij = gel(teich, Fl_powu(ai,j,p));/* w(a)^(-j) = w(a^(-j) mod p) */
+        gel(Ca,j+1) = Caj;
+        for (r = 0; r <= j; r++)
+        {
+          GEN c = Fp_mul(gcoeff(pas,j+1,r+1), gel(powb, j-r+1), pn);
+          c = Fp_mul(c,atij,pn); /* binomial(j,r)*b^(j-r)*w(a)^(-j) mod p^n */
+          gel(Caj,r+1) = mulii(c, gel(P,j+1)); /* p^j * c mod p^(n+j) */
+        }
+      }
+    }
+  }
+  return gerepilecopy(av, mkvecn(8, Wp,Tp, bin, actUp, q,
+                                 mkvecsmall3(p,n,flag), M, C));
 }
 
-GEN
-omseval(GEN O, GEN path)
+#if 0
+/* assume phi an ordinary OMS */
+static GEN
+omsactgl2(GEN W, GEN phi, GEN M)
+{
+  GEN q, Wp, act;
+  long p, k, n;
+  checkmspadic(W);
+  Wp = mspadic_get_Wp(W);
+  p = mspadic_get_p(W);
+  k = mspadic_get_weight(W);
+  n = mspadic_get_n(W);
+  q = mspadic_get_q(W);
+  act = init_moments_act(Wp, p, n, q, M);
+  phi = gel(phi,1);
+  return dual_act(k-1, act, gel(phi,1));
+}
+#endif
+
+static GEN
+eigenvalue(GEN T, GEN x)
 {
-  pari_sp av = avma;
-  GEN den, v, PHI = gel(O,2);
-  PHI = Q_remove_denom(PHI, &den);
-  if (den)
+  long i, l = lg(x);
+  for (i = 1; i < l; i++)
+    if (!isintzero(gel(x,i))) break;
+  if (i == l) pari_err_DOMAIN("mstooms", "phi", "=", gen_0, x);
+  return gdiv(RgMrow_RgC_mul(T,x,i), gel(x,i));
+}
+
+/* p coprime to ap, return unit root of x^2 - ap*x + p^(k-1), accuracy p^n */
+static GEN
+ms_unit_eigenvalue(GEN ap, long k, GEN p, long n)
+{
+  GEN sqrtD, D = subii(sqri(ap), shifti(powiu(p,k-1),2));
+  if (equaliu(p,2))
   {
-    O = leafcopy(O);
-    gel(O,2) = PHI;
+    n++; sqrtD = Zp_sqrt(D, p, n);
+    if (mod4(sqrtD) != mod4(ap)) sqrtD = negi(sqrtD);
   }
-  v = omseval_int(O, path, den);
-  return den? gerepileupto(av, gdiv(v,den)): gerepilecopy(av, v);
+  else
+    sqrtD = Zp_sqrtlift(D, ap, p, n);
+  /* sqrtD = ap (mod p) */
+  return gmul2n(gadd(ap, cvtop(sqrtD,p,n)), -1);
 }
+
 /* W = msinit(N,k,...); phi = T_p/U_p - eigensymbol */
 GEN
-mstooms(GEN W, GEN phi, long p, long n)
+mstooms(GEN W, GEN phi)
 {
   pari_sp av = avma;
-  long N = ms_get_N(W), k = msk_get_weight(W);
-  GEN bin = vecbinome(k-2), T, gp;
-  GEN c, alpha, ap, phi0;
+  GEN Wp, bin, Tp, c, alpha, ap, phi0, M;
+  long k, p, vden;
+
+  checkmspadic(W);
+  if (typ(phi) != t_COL)
+  {
+    if (!is_Qevproj(phi)) pari_err_TYPE("mstooms",phi);
+    phi = gel(phi,1);
+    if (lg(phi) != 2) pari_err_TYPE("mstooms [dim_Q (eigenspace) > 1]",phi);
+    phi = gel(phi,1);
+  }
+
+  Wp = mspadic_get_Wp(W);
+  Tp = mspadic_get_Tp(W);
+  bin = mspadic_get_bin(W);
+  k = msk_get_weight(Wp);
+  p = mspadic_get_p(W);
+  M = mspadic_get_M(W);
 
   phi = Q_remove_denom(phi, &c);
-  phi = Qevproj_init0(phi);
-  T = mshecke(W, p,  phi);
-  ap = gcoeff(T,1,1);
-  phi = gmael(phi,1,1); /* t_COL, modular symbol in term of W's basis */
-  gp = utoipos(p);
+  ap = eigenvalue(Tp, phi);
+  vden = c? Z_lvalrem(c, p, &c): 0;
 
-  if (N % p == 0)
-  {
-    if (!umodiu(ap, p)) pari_err_IMPL("mspadicmoments when p | a_p");
+  if (typ(M) == t_INT)
+  { /* p | N */
+    GEN c1;
     alpha = ap;
     alpha = ginv(alpha);
-    phi0 = mseval(W, phi, NULL);
+    phi0 = mseval(Wp, phi, NULL);
     phi0 = RgXC_to_moments(phi0, bin);
-    phi = oms_ordinary(W, phi0, alpha, p, n);
+    phi0 = Q_remove_denom(phi0, &c1);
+    if (c1) { vden += Z_lvalrem(c1, p, &c1); c = mul_denom(c,c1); }
+    if (umodiu(ap,p)) /* p \nmid a_p */
+      phi = oms_dim1(W, phi0, alpha, 0);
+    else
+    {
+      phi = oms_dim1(W, phi0, alpha, 1);
+      phi = Q_remove_denom(phi, &c1);
+      if (c1) { vden += Z_lvalrem(c1, p, &c1); c = mul_denom(c,c1); }
+    }
   }
   else
   { /* p-stabilize */
-    long s = msk_get_sign(W);
-    GEN Wp = mskinit(N*p, k, s);
-    GEN M1, M2, phi1, phi2, c1, c2;
+    GEN M1, M2, phi1, phi2, c1;
+    if (typ(M) != t_VEC || lg(M) != 3) pari_err_TYPE("mstooms",W);
+    M1 = gel(M,1);
+    M2 = gel(M,2);
 
-    /* FIXME: compute image of unique symbol, not whole basis
-     * + represent phi[12] as G_i -> P_i not in terms of basis */
-    M1 = getMorphism(W, Wp, mat2(1,0,0,1));
-    M2 = getMorphism(W, Wp, mat2(p,0,0,1));
-    if (s)
-    {
-      M1 = Qevproj_apply2(M1, msk_get_starproj(W), msk_get_starproj(Wp));
-      M2 = Qevproj_apply2(M2, msk_get_starproj(W), msk_get_starproj(Wp));
-    }
     phi1 = RgM_RgC_mul(M1, phi);
     phi2 = RgM_RgC_mul(M2, phi);
     phi1 = mseval(Wp, phi1, NULL);
@@ -3350,109 +3586,471 @@ mstooms(GEN W, GEN phi, long p, long n)
 
     phi1 = RgXC_to_moments(phi1, bin);
     phi2 = RgXC_to_moments(phi2, bin);
-
-    phi1 = Q_remove_denom(phi1, &c1);
-    phi2 = Q_remove_denom(phi2, &c2);
-    c = mul_denom(c,mul_denom(c1,c2));
-    if (c1 && c2)
-    {
-      GEN d = gcdii(c1,c2);
-      c = diviiexact(c, d); /* lcm(c1,c2) */
-      phi1 = gmul(phi1, diviiexact(c,c1));
-      phi2 = gmul(phi2, diviiexact(c,c2));
-    }
-    /* all polynomials multiplied by c */
-    W = Wp;
+    phi = Q_remove_denom(mkvec2(phi1,phi2), &c1);
+    phi1 = gel(phi,1);
+    phi2 = gel(phi,2);
+    if (c1) { vden += Z_lvalrem(c1, p, &c1); c = mul_denom(c,c1); }
+    /* all polynomials multiplied by c p^vden */
     if (umodiu(ap, p))
     {
-      alpha = ms_unit_eigenvalue(ap, k, gp, n);
+      alpha = ms_unit_eigenvalue(ap, k, utoipos(p), mspadic_get_n(W));
       alpha = ginv(alpha);
       phi0 = gsub(phi1, gmul(lift(alpha),phi2));
-      phi = oms_ordinary(W, phi0, alpha, p, n);
+      phi = oms_dim1(W, phi0, alpha, 0);
     }
     else
-    { /* p | ap */
-      alpha = mkmat2(mkcol2(ap, powuu(p, k-1)), mkcol2(gen_m1,gen_0));
-      phi = oms_supersingular(mkvec2(phi1,phi2),W,p,n, alpha);
+    { /* p | ap, alpha = [a_p, -1; p^(k-1), 0] */
+      long flag = mspadic_get_flag(W);
+      if (!flag || (signe(ap) && Z_lval(ap,p) < flag))
+        pari_err_TYPE("mstooms [v_p(ap) > mspadicinit flag]", phi);
+      alpha = mkmat22(ap,gen_m1, powuu(p, k-1),gen_0);
       alpha = ginv(alpha);
+      phi = oms_dim2(W, mkvec2(phi1,phi2), gsqr(alpha), ap);
+      phi = Q_remove_denom(phi, &c1);
+      if (c1) { vden += Z_lvalrem(c1, p, &c1); c = mul_denom(c,c1); }
     }
   }
-  if (!c) c = gen_1;
-  return gerepilecopy(av, mkvec3(W,phi, mkvec4(c,alpha,stoi(p),stoi(n))));
+  if (vden) c = mul_denom(c, powuu(p,vden));
+  if (p == 2) alpha = gsqr(alpha);
+  if (c) alpha = gdiv(alpha,c);
+  if (typ(alpha) == t_MAT)
+  { /* express in basis (omega,-p phi(omega)) */
+    gcoeff(alpha,2,1) = gdivgs(gcoeff(alpha,2,1), -p);
+    gcoeff(alpha,2,2) = gdivgs(gcoeff(alpha,2,2), -p);
+    /* at the end of mspadicint we shall multiply result by [1,0;0,-1/p]*alpha
+     * vden + k is the denominator of this matrix */
+  }
+  /* phi is integral-valued */
+  return gerepilecopy(av, mkcol3(phi, stoi(vden), alpha));
 }
 
+/* HACK: the v[j] have different lengths */
 static GEN
-twist_matrices(long D)
+FpVV_dotproduct(GEN v, GEN w, GEN p)
 {
-  long i, aD = labs(D);
-  GEN v = cgetg(aD+1, t_VEC);
-  for (i = 1; i <= aD; i++) gel(v,i) = mat2(aD, i-1, 0, aD);
-  return v;
+  long j, l = lg(v);
+  GEN T = cgetg(l, t_VEC);
+  for (j = 1; j < l; j++) gel(T,j) = FpV_dotproduct(gel(v,j),w,p);
+  return T;
 }
 
-/* W = msinit(N), phi eigensymbol, p \nmid D. Return C(x) mod FilM */
+/* \int (-4z)^j given \int z^j */
+static GEN
+twistmoment_minus(GEN v)
+{
+  long i, l;
+  GEN w = cgetg_copy(v, &l);
+  for (i = 1; i < l; i++)
+  {
+    GEN c = gel(v,i);
+    if (i > 1) c = gmul2n(c, (i-1)<<1);
+    gel(w,i) = odd(i)? c: gneg(c);
+  }
+  return w;
+}
+/* \int (4z)^j given \int z^j */
+static GEN
+twistmoment_plus(GEN v)
+{
+  long i, l;
+  GEN w = cgetg_copy(v, &l);
+  for (i = 1; i < l; i++)
+  {
+    GEN c = gel(v,i);
+    if (i > 1) c = gmul2n(c, (i-1)<<1);
+    gel(w,i) = c;
+  }
+  return w;
+}
+/* W an mspadic, phi eigensymbol, p \nmid D. Return C(x) mod FilM */
 GEN
-mspadicmoments(GEN W, GEN phi, long p, long n, long D)
+mspadicmoments(GEN W, GEN PHI, long D)
 {
   pari_sp av = avma;
-  long a, b, lvec, k = msk_get_weight(W);
-  GEN v, den, PHI, bin, gp = stoi(p), pn, O, P, data, teich;
-
-  O = mstooms(W, phi, p, n);
-  W = gel(O,1); /* possibly in level N*p */
-  PHI = gel(O,2);
-  gel(O,2) = Q_remove_denom(PHI, &den);
-  data = gel(O,3);
-
-  bin = matpascal(n);
-  P = gpowers(gp, n);
-  pn = gel(P, n+1);
-  if (den) pn = gmul(pn, den);
-  teich = teichmullerinit(p, den? n + Z_lval(den, p): n);
+  long la, ia, b, lphi, aD = labs(D), pp, p, k, n, vden;
+  GEN Wp, Dact, Dk, v, C, gp, pn, phi;
+  struct m_act S;
+  hashtable *H;
+
+  checkmspadic(W);
+  Wp = mspadic_get_Wp(W);
+  p = mspadic_get_p(W);
+  k = mspadic_get_weight(W);
+  n = mspadic_get_n(W);
+  C = mspadic_get_C(W);
+  if (typ(PHI) != t_COL || lg(PHI) != 4 || typ(gel(PHI,1)) != t_VEC)
+    PHI = mstooms(W, PHI);
+  vden = itos( gel(PHI,2) );
+  phi = gel(PHI,1);
+  if (p == 2)
+  { la = 3; pp = 4; }
+  else
+  { la = p; pp = p; }
+  v = cgetg_copy(phi, &lphi);
+  for (b = 1; b < lphi; b++) gel(v,b) = cgetg(la, t_VEC);
+  pn = powuu(p, n + vden);
+  gp = utoipos(p);
+
+  S.p = p;
+  S.k = k;
+  S.q = pn;
+  S.dim = n+k-1;
+
+  Dact = NULL;
+  Dk = NULL;
   if (D != 1)
   {
-    GEN act = init_moments_act(W, W, p, n, pn, twist_matrices(D));
-    GEN Dk = Fp_pows(stoi(D), 2-k, pn);
-    long i, l = lg(PHI);
-    for (i = 1; i < l; i++)
+    GEN gaD = utoi(aD);
+    if (!sisfundamental(D)) pari_err_TYPE("mspadicmoments", stoi(D));
+    if (D % p == 0) pari_err_DOMAIN("mspadicmoments", "p","|", stoi(D), gp);
+    Dact = cgetg(aD, t_VEC);
+    for (b = 1; b < aD; b++)
     {
-      GEN t = getMorphism_single_twist(gel(PHI,i), act, D);
-      if (k != 2) t = gmul(t, Dk);
-      gel(PHI,i) = red_mod_FilM(t, p, k, 1);
+      GEN z = NULL;
+      if (ugcd(b,aD) == 1)
+        z = moments_act(&S, mkmat22(gaD,utoipos(b), gen_0,gaD));
+      gel(Dact,b) = z;
     }
+    if (k != 2) Dk = Fp_pows(stoi(D), 2-k, pn);
   }
 
-  v = cgetg_copy(PHI, &lvec);
-  for (b = 1; b < lvec; b++) gel(v,b) = cgetg(p, t_VEC);
-  for (a = 1; a < p; a++)
+  H = Gl2act_cache(ms_get_nbgen(Wp));
+
+  for (ia = 1; ia < la; ia++)
   {
-    GEN powa, path, vca, ga = utoipos(a);
-    powa = Fp_powers(subsi(a, gel(teich,a)), n, pn);
-    path = mkmat2(mkcol2(gen_1,gen_0), mkcol2(ga, gp));
-    vca = omseval_int(O, path, den);
-    /* ca[r+1] = c_r(a/p) = \Phi([a/p] - [oo])(z^r) */
-    for (b = 1; b < lg(vca); b++)
+    GEN path, vca;
+    long i, a = ia;
+    if (p == 2 && a == 2) a = -1;
+    if (Dact) /* twist by D */
     {
-      GEN t = cgetg(n+2, t_VEC), ca = gel(vca,b);
-      long j;
-      gmael(v,b,a) = t;
-      for (j = 0; j <= n; j++)
+      long c;
+      vca = const_vec(lphi-1,NULL);
+      for (b = 1; b < aD; b++)
       {
-        GEN s = gen_0;
-        long r;
-        for (r = 0; r <= j; r++)
+        long s = kross(D, b);
+        GEN z, T;
+        if (!s) continue;
+        z = addii(mulss(a, aD), muluu(pp, b));
+        /* oo -> a/pp + pp/|D|*/
+        path = mkmat22(gen_1,z, gen_0,muluu(pp, aD));
+        T = omseval_int(&S, phi, M2_log(Wp,path), H);
+        for (c = 1; c < lphi; c++)
         {
-          GEN C = gcoeff(bin,j+1,r+1);
-          C = mulii(C, gel(P,r+1));
-          C = Fp_mul(C, gel(powa, j-r+1), pn);
-          C = Fp_mul(C, gel(ca,r+1), pn);
-          s = addii(s, C);
+          z = FpM_FpC_mul(gel(Dact,b), gel(T,c), pn);
+          if (s < 0) ZV_neg_inplace(z);
+          gel(vca, c) = gel(vca,c)? ZC_add(gel(vca,c), z): z;
         }
-        /* \sum_{0<=r<=j} binomial(j,r)*p^r*(a-w(a))^(j-r)*c_r(a/p) */
-        gel(t, j+1) = modii(s, pn);
       }
+      if (Dk) for(c = 1; c < lphi; c++)
+        gel(vca,c) = FpC_Fp_mul(gel(vca,c), Dk, pn);
+    }
+    else
+    {
+      path = mkmat22(gen_1,stoi(a), gen_0, utoipos(pp));
+      vca = omseval_int(&S, phi, M2_log(Wp,path), H);
+    }
+    if (p != 2)
+    {
+      GEN Ca = gel(C,a);
+      for (i = 1; i < lphi; i++)
+        gmael(v,i,a) = FpVV_dotproduct(Ca, gel(vca,i), pn);
+    }
+    else
+    {
+      if (ia == 1) /* \tilde{a} = 1 */
+      { for (i = 1; i < lphi; i++) gel(vca,i) = twistmoment_plus(gel(vca,i)); }
+      else /* \tilde{a} = -1 */
+      { for (i = 1; i < lphi; i++) gel(vca,i) = twistmoment_minus(gel(vca,i)); }
+      for (i = 1; i < lphi; i++) gmael(v,i,ia) = gel(vca,i);
+    }
+  }
+  return gerepilecopy(av, mkvec3(v, gel(PHI,3), mkvecsmall4(p,n+vden,n,D)));
+}
+static void
+checkoms(GEN v)
+{
+  if (typ(v) != t_VEC || lg(v) != 4 || typ(gel(v,1)) != t_VEC
+      || typ(gel(v,3))!=t_VECSMALL)
+    pari_err_TYPE("checkoms [apply mspadicmoments]", v);
+}
+static long
+oms_get_p(GEN oms) { return gel(oms,3)[1]; }
+static long
+oms_get_n(GEN oms) { return gel(oms,3)[2]; }
+static long
+oms_get_n0(GEN oms) { return gel(oms,3)[3]; }
+static long
+oms_get_D(GEN oms) { return gel(oms,3)[4]; }
+static int
+oms_is_supersingular(GEN oms) { GEN v = gel(oms,1); return lg(v) == 3; }
+
+/* sum(j = 1, n, (-1)^(j+1)/j * x^j) */
+static GEN
+log1x(long n)
+{
+  long i, l = n+3;
+  GEN v = cgetg(l, t_POL);
+  v[1] = evalvarn(0)|evalsigne(1); gel(v,2) = gen_0;
+  for (i = 3; i < l; i++) gel(v,i) = ginv(stoi(odd(i)? i-2: 2-i));
+  return v;
+}
+
+/* S = (1+x)^zk log(1+x)^logj (mod x^(n+1)) */
+static GEN
+xlog1x(long n, long zk, long logj, long *pteich)
+{
+  GEN S = logj? RgXn_powu_i(log1x(n), logj, n+1): NULL;
+  if (zk)
+  {
+    GEN L = deg1pol_shallow(gen_1, gen_1, 0); /* x+1 */
+    *pteich += zk;
+    if (zk < 0) { L = RgXn_inv(L,n+1); zk = -zk; }
+    if (zk != 1) L = RgXn_powu_i(L, zk, n+1);
+    S = S? RgXn_mul(S, L, n+1): L;
+  }
+  return S;
+}
+
+/* oms from mspadicmoments; integrate teichmuller^i * S(x) [S = NULL: 1]*/
+static GEN
+mspadicint(GEN oms, long teichi, GEN S)
+{
+  pari_sp av = avma;
+  long p = oms_get_p(oms), n = oms_get_n(oms), n0 = oms_get_n0(oms);
+  GEN vT = gel(oms,1), alpha = gel(oms,2), gp = utoipos(p);
+  long loss = S? Z_lval(Q_denom(S), p): 0;
+  long nfinal = minss(n-loss, n0);
+  long i, la, l = lg(vT);
+  GEN res = cgetg(l, t_COL), teich = NULL;
+
+  if (S) S = RgX_to_RgC(S,lg(gmael(vT,1,1))-1);
+  if (p == 2)
+  {
+    la = 3; /* corresponds to [1,-1] */
+    teichi &= 1;
+  }
+  else
+  {
+    la = p; /* corresponds to [1,2,...,p-1] */
+    teichi = smodss(teichi, p-1);
+    if (teichi) teich = teichmullerinit(p, n);
+  }
+  for (i=1; i<l; i++)
+  {
+    pari_sp av2 = avma;
+    GEN s = gen_0, T = gel(vT,i);
+    long ia;
+    for (ia = 1; ia < la; ia++)
+    { /* Ta[j+1] correct mod p^n */
+      GEN Ta = gel(T,ia), v = S? RgV_dotproduct(Ta, S): gel(Ta,1);
+      if (teichi && ia != 1)
+      {
+        if (p != 2)
+          v = gmul(v, gel(teich, Fl_powu(ia,teichi,p)));
+        else
+          if (teichi) v = gneg(v);
+      }
+      s = gadd(s, v);
     }
+    s = gadd(s, zeropadic(gp,nfinal));
+    gel(res,i) = gerepileupto(av2, s);
   }
-  if (den) v = gdiv(v, den);
-  return gerepilecopy(av, mkvec2(v, data));
+  return gerepileupto(av, gmul(alpha, res));
 }
+/* integrate P = polynomial in log(x); vlog[j+1] = mspadicint(0,log(1+x)^j) */
+static GEN
+mspadicint_RgXlog(GEN P, GEN vlog)
+{
+  long i, d = degpol(P);
+  GEN s = gmul(gel(P,2), gel(vlog,1));
+  for (i = 1; i <= d; i++) s = gadd(s, gmul(gel(P,i+2), gel(vlog,i+1)));
+  return s;
+};
+
+/* oms from mspadicmoments */
+GEN
+mspadicseries(GEN oms, long teichi)
+{
+  pari_sp av = avma;
+  GEN S, L, X, vlog, s, s2, u, logu, bin;
+  long j, p, m, n, step, stop;
+  checkoms(oms);
+  n = oms_get_n0(oms);
+  if (n < 1)
+  {
+    s = zeroser(0,0);
+    if (oms_is_supersingular(oms)) s = mkvec2(s,s);
+    return gerepilecopy(av, s);
+  }
+  p = oms_get_p(oms);
+  vlog = cgetg(n+1, t_VEC);
+  step = p == 2? 2: 1;
+  stop = 0;
+  S = NULL;
+  L = log1x(n);
+  for (j = 0; j < n; j++)
+  {
+    if (j) stop += step + u_lval(j,p); /* = step*j + v_p(j!) */
+    if (stop >= n) break;
+    /* S = log(1+x)^j */
+    gel(vlog,j+1) = mspadicint(oms,teichi,S);
+    S = S? RgXn_mul(S, L, n+1): L;
+  }
+  m = j;
+  u = utoipos(p == 2? 5: 1+p);
+  logu = glog(cvtop(u, utoipos(p), 4*m), 0);
+  X = gdiv(pol_x(0), logu);
+  s = cgetg(m+1, t_VEC);
+  s2 = oms_is_supersingular(oms)? cgetg(m+1, t_VEC): NULL;
+  bin = pol_1(0);
+  for (j = 0; j < m; j++)
+  { /* bin = binomial(x/log(1+p+O(p^(4*n))), j) mod x^m */
+    GEN a, v = mspadicint_RgXlog(bin, vlog);
+    int done = 1;
+    gel(s,j+1) = a = gel(v,1);
+    if (!gequal0(a) || valp(a) > 0) done = 0; else setlg(s,j+1);
+    if (s2)
+    {
+      gel(s2,j+1) = a = gel(v,2);
+      if (!gequal0(a) || valp(a) > 0) done = 0; else setlg(s2,j+1);
+    }
+    if (done || j == m-1) break;
+    bin = RgXn_mul(bin, gdivgs(gsubgs(X, j), j+1), m);
+  }
+  s = gtoser(s,0,lg(s)-1);
+  if (s2) { s2 = gtoser(s2,0,lg(s2)-1); s = mkvec2(s, s2); }
+  if (kross(oms_get_D(oms), p) >= 0) return gerepilecopy(av, s);
+  return gerepileupto(av, gneg(s));
+}
+static void
+parse_chi(GEN s, GEN *s1, GEN *s2)
+{
+  if (!s) *s1 = *s2 = gen_0;
+  else switch(typ(s))
+  {
+    case t_INT: *s1 = *s2 = s; break;
+    case t_VEC:
+      if (lg(s) == 3)
+      {
+        *s1 = gel(s,1);
+        *s2 = gel(s,2);
+        if (typ(*s1) == t_INT && typ(*s2) == t_INT) break;
+      }
+    default: pari_err_TYPE("mspadicL",s);
+             *s1 = *s2 = NULL;
+  }
+}
+/* oms from mspadicmoments
+ * r-th derivative of L(f,chi^s,psi) in direction <chi>
+   - s \in Z_p \times \Z/(p-1)\Z, s-> chi^s=<\chi>^s_1 omega^s_2)
+   - Z -> Z_p \times \Z/(p-1)\Z par s-> (s, s mod p-1).
+ */
+GEN
+mspadicL(GEN oms, GEN s, long r)
+{
+  pari_sp av = avma;
+  GEN s1, s2, z, S;
+  long p, n, teich;
+  checkoms(oms);
+  p = oms_get_p(oms);
+  n = oms_get_n(oms);
+  parse_chi(s, &s1,&s2);
+  teich = umodiu(subii(s2,s1), p==2? 2: p-1);
+  S = xlog1x(n, itos(s1), r, &teich);
+  z = mspadicint(oms, teich, S);
+  if (lg(z) == 2) z = gel(z,1);
+  if (kross(oms_get_D(oms), p) < 0) z = gneg(z);
+  return gerepilecopy(av, z);
+}
+
+GEN
+ellpadicL(GEN E, GEN pp, long n, GEN s, long r, GEN DD)
+{
+  pari_sp av = avma;
+  GEN L, W, Wp, xpm, NE, s1,s2, oms, den;
+  long sign, D;
+  ulong p;
+
+  if (DD && !Z_isfundamental(DD))
+    pari_err_DOMAIN("ellpadicL", "isfundamental(D)", "=", gen_0, DD);
+  if (typ(pp) != t_INT) pari_err_TYPE("ellpadicL",pp);
+  if (cmpis(pp,2) < 0) pari_err_PRIME("ellpadicL",pp);
+  if (n <= 0) pari_err_DOMAIN("ellpadicL","precision","<=",gen_0,stoi(n));
+  if (r < 0) pari_err_DOMAIN("ellpadicL","r","<",gen_0,stoi(r));
+  parse_chi(s, &s1,&s2);
+  if (!DD) { sign = 1; D = 1; }
+  else
+  {
+    sign = signe(DD); D = itos(DD);
+    if (!sign) pari_err_DOMAIN("ellpadicL", "D", "=", gen_0, DD);
+  }
+  if (mpodd(s2)) sign = -sign;
+  W = msfromell(E, sign);
+  xpm = gel(W,2);
+  W = gel(W,1);
+
+  p = itou(pp);
+  NE = ellQ_get_N(E);
+  if (dvdii(NE, sqri(pp))) pari_err_IMPL("additive reduction in ellpadicL");
+
+  xpm = Q_remove_denom(xpm,&den);
+  if (!den) den = gen_1;
+  n += Z_lval(den, p);
+
+  Wp = mspadicinit(W, p, n, umodiu(ellap(E,pp),p)? 0: 1);
+  oms = mspadicmoments(Wp, xpm, D);
+  L = mspadicL(oms, s, r);
+  return gerepileupto(av, gdiv(L,den));
+}
+
+#if 0
+GEN
+test(void)
+{
+  GEN W, Wp, xpm, den;
+  ulong p;
+
+  GEN E = ellinit(strtoGENstr("11a1"), NULL, DEFAULTPREC);
+  GEN pp = stoi(11);
+  long n = 15;
+  if (typ(pp) != t_INT) pari_err_TYPE("ellpadicL",pp);
+  if (n <= 0) pari_err_DOMAIN("ellpadicL","precision","<=",gen_0,stoi(n));
+  W = msfromell(E, 1);
+  xpm = gel(W,2);
+  W = gel(W,1);
+
+  p = itou(pp);
+
+  xpm = Q_remove_denom(xpm,&den);
+
+  Wp = mspadicinit(W, p, n, umodiu(ellap(E,pp),p)? 0: 1);
+  GEN XPM = mstooms(Wp, xpm);
+
+  struct m_act S;
+  S.p = p;
+  S.k = 2;
+  S.q = powuu(p,n);
+  S.dim = n+1;
+
+  GEN g1 = mkmat22(gen_1, gen_0, gen_0, gen_1);
+  GEN g2 = mkmat22(gen_0, gen_1, gen_1, stoi(3));
+  GEN g3 = mkmat22(gen_1, gen_1, stoi(3), gen_2);
+
+  GEN phi1 = msomseval(Wp, XPM, g1);
+  GEN phi2 = msomseval(Wp, XPM, g2);
+  GEN phi3 = msomseval(Wp, XPM, g3);
+  phi1 = gel(phi1,1);
+  phi2 = gel(phi2,1);
+  phi3 = gel(phi3,1);
+  GEN M1 = ginv(mkmat22(gen_1,gen_1, gen_0,gen_1));
+  GEN M2 = ginv(mkmat22(stoi(7),stoi(-2), stoi(11),stoi(-3)));
+  GEN M3 = ginv(mkmat22(stoi(8),stoi(-3), stoi(11),stoi(-4)));
+
+  GEN O1 = moments_act(&S, M1);
+  GEN O2 = moments_act(&S, M2);
+  GEN O3 = moments_act(&S, M3);
+
+  GEN t = gadd(phi3, gadd(phi1,phi2));
+  GEN T = gadd(gmul(O3, phi3), gadd(gmul(O1, phi1),gmul(O2, phi2)));
+}
+#endif
diff --git a/src/basemath/nffactor.c b/src/basemath/nffactor.c
index a424788..0365202 100644
--- a/src/basemath/nffactor.c
+++ b/src/basemath/nffactor.c
@@ -162,8 +162,8 @@ nfgcd_all(GEN P, GEN Q, GEN T, GEN den, GEN *Pnew)
   if (!signe(Q)) { if (Pnew) *Pnew = pol_1(vT);   return gcopy(P); }
   /*Compute denominators*/
   if (!den) den = ZX_disc(T);
-  lP = leading_term(P);
-  lQ = leading_term(Q);
+  lP = leading_coeff(P);
+  lQ = leading_coeff(Q);
   if ( !((typ(lP)==t_INT && is_pm1(lP)) || (typ(lQ)==t_INT && is_pm1(lQ))) )
     den = mulii(den, gcdii(ZX_resultant(lP, T), ZX_resultant(lQ, T)));
 
@@ -175,7 +175,7 @@ nfgcd_all(GEN P, GEN Q, GEN T, GEN den, GEN *Pnew)
     if (!p) pari_err_OVERFLOW("nfgcd [ran out of primes]");
     /*Discard primes dividing disc(T) or lc(PQ) */
     if (!umodiu(den, p)) continue;
-    if (DEBUGLEVEL>5) err_printf("nfgcd: p=%d\n",p);
+    if (DEBUGLEVEL>5) err_printf("nfgcd: p=%lu\n",p);
     /*Discard primes when modular gcd does not exist*/
     if ((R = FlxqX_safegcd(ZXX_to_FlxX(P,p,vT),
                            ZXX_to_FlxX(Q,p,vT),
@@ -269,7 +269,7 @@ nffactormod(GEN nf, GEN x, GEN pr)
 static GEN
 QXQX_normalize(GEN P, GEN T)
 {
-  GEN P0 = leading_term(P);
+  GEN P0 = leading_coeff(P);
   long t = typ(P0);
   if (t == t_POL)
   {
@@ -284,7 +284,7 @@ QXQX_normalize(GEN P, GEN T)
 static GEN
 RgX_int_normalize(GEN P)
 {
-  GEN P0 = leading_term(P);
+  GEN P0 = leading_coeff(P);
   /* cater for t_POL */
   if (typ(P0) == t_POL)
   {
@@ -303,39 +303,49 @@ static GEN
 proper_nf(GEN nf)
 { return (lg(nf) == 3)? gel(nf,1): nf; }
 
+/* if *pnf = NULL replace if by a "quick" K = nfinit(T), ensuring maximality
+ * by small primes only. Return a multiplicative bound for the denominator of
+ * algebraic integers in Z_K in terms of K.zk */
 static GEN
 fix_nf(GEN *pnf, GEN *pT, GEN *pA)
 {
-  GEN den = gen_1;
-  if (!*pnf)
-  {
-    GEN fa, P, q, D, T = *pT;
-    GEN nf, NF = nfinitall(T, nf_PARTIALFACT, DEFAULTPREC);
-    *pnf = nf = proper_nf(NF);
-    if (nf != NF) { /* t_POL defining base field changed (not monic) */
-      long i, l;
-      GEN A = *pA, a = cgetg_copy(A, &l);
-      GEN rev = gel(NF,2), pow, dpow;
-
-      *pT = T = nf_get_pol(nf); /* need to update T */
-      pow = QXQ_powers(lift_intern(rev), degpol(T)-1, T);
-      pow = Q_remove_denom(pow, &dpow);
-      a[1] = A[1];
-      for (i=2; i<l; i++) {
-        GEN c = gel(A,i);
-        if (typ(c) == t_POL) c = QX_ZXQV_eval(c, pow, dpow);
-        gel(a,i) = c;
-      }
-      *pA = Q_primpart(a); /* need to update A */
+  GEN nf, NF, fa, P, Q, q, D, T = *pT;
+  long i, l;
+
+  if (*pnf) return gen_1;
+  NF = nfinitall(T, nf_PARTIALFACT, DEFAULTPREC);
+  *pnf = nf = proper_nf(NF);
+  if (nf != NF) { /* t_POL defining base field changed (not monic) */
+    GEN A = *pA, a = cgetg_copy(A, &l);
+    GEN rev = gel(NF,2), pow, dpow;
+
+    *pT = T = nf_get_pol(nf); /* need to update T */
+    pow = QXQ_powers(lift_intern(rev), degpol(T)-1, T);
+    pow = Q_remove_denom(pow, &dpow);
+    a[1] = A[1];
+    for (i=2; i<l; i++) {
+      GEN c = gel(A,i);
+      if (typ(c) == t_POL) c = QX_ZXQV_eval(c, pow, dpow);
+      gel(a,i) = c;
     }
+    *pA = Q_primpart(a); /* need to update A */
+  }
 
-    D = nf_get_disc(nf);
-    if (is_pm1(D)) return gen_1;
-    fa = absi_factor_limit(D, 0);
-    P = gel(fa,1); q = gel(P, lg(P)-1);
-    if (!BPSW_psp(q)) den = q; /* nf_get_disc(nf) may be incorrect */
+  D = nf_get_disc(nf);
+  if (is_pm1(D)) return gen_1;
+  fa = absi_factor_limit(D, 0);
+  P = gel(fa,1); q = gel(P, lg(P)-1);
+  if (BPSW_psp(q)) return gen_1;
+  /* nf_get_disc(nf) may be incorrect */
+  P = nf_get_ramified_primes(nf);
+  l = lg(P);
+  Q = q; q = gen_1;
+  for (i = 1; i < l; i++)
+  {
+    GEN p = gel(P,i);
+    if (Z_pvalrem(Q, p, &Q) && !BPSW_psp(p)) q = mulii(q, p);
   }
-  return den;
+  return q;
 }
 
 /* set B = A/gcd(A,A'), squarefree */
@@ -348,7 +358,7 @@ get_nfsqff_data(GEN *pnf, GEN *pT, GEN *pA, GEN *pB, GEN *ptbad)
   {
     *pnf = T;
     bad = den = ZX_disc(T);
-    if (is_pm1(leading_term(T))) den = indexpartial(T, den);
+    if (is_pm1(leading_coeff(T))) den = indexpartial(T, den);
   }
   else
   {
@@ -528,7 +538,7 @@ fact_from_sqff(GEN rep, GEN A, GEN B, GEN y, GEN T, GEN bad)
     }
     else
     { /* compute valuations mod a prime of degree 1 (avoid coeff explosion) */
-      GEN quo, p, r, Bp, lb = leading_term(B), E = cgetalloc(t_VECSMALL,n+1);
+      GEN quo, p, r, Bp, lb = leading_coeff(B), E = cgetalloc(t_VECSMALL,n+1);
       pari_sp av1 = avma;
       ulong pp;
       long j;
@@ -649,7 +659,7 @@ arch_for_T2_prec(GEN G, GEN x, long prec)
 static GEN
 nf_Mignotte_bound(GEN nf, GEN polbase)
 {
-  GEN G = nf_get_G(nf), lS = leading_term(polbase); /* t_INT */
+  GEN G = nf_get_G(nf), lS = leading_coeff(polbase); /* t_INT */
   GEN p1, C, N2, matGS, binlS, bin;
   long prec, i, j, d = degpol(polbase), n = nf_get_degree(nf), r1 = nf_get_r1(nf);
 
@@ -735,7 +745,7 @@ PRECPB:
     remake_GM(nf, &F, prec); G = F.G;
     if (DEBUGLEVEL>1) pari_warn(warnprec, "nf_factor_bound", prec);
   }
-  lt = leading_term(polbase);
+  lt = leading_coeff(polbase);
   s = mulri(s, muliu(sqri(lt), n));
   C = powruhalf(stor(3,DEFAULTPREC), 3 + 2*d); /* 3^{3/2 + d} */
   return divrr(mulrr(C, s), mulur(d, mppi(DEFAULTPREC)));
@@ -793,9 +803,8 @@ static GEN
 L2_bound(GEN nf, GEN den)
 {
   GEN M, L, prep, T = nf_get_pol(nf), tozk = nf_get_invzk(nf);
-  long prec;
-
-  prec = nbits2prec(bit_accuracy(ZX_max_lg(T)) + bit_accuracy(ZM_max_lg(tozk)));
+  long bit = bit_accuracy(ZX_max_lg(T)) + bit_accuracy(ZM_max_lg(tozk));
+  long prec = nbits2prec(bit + degpol(T));
   (void)initgaloisborne(nf, den, prec, &L, &prep, NULL);
   M = vandermondeinverse(L, RgX_gtofp(T,prec), den, prep);
   return RgM_fpnorml2(RgM_mul(tozk,M), DEFAULTPREC);
@@ -946,7 +955,7 @@ static void
 init_div_data(div_data *D, GEN pol, nflift_t *L)
 {
   GEN C = mul_content(L->topowden, L->dn);
-  GEN C2lt, Clt, lc = leading_term(pol), lt = is_pm1(lc)? NULL: absi(lc);
+  GEN C2lt, Clt, lc = leading_coeff(pol), lt = is_pm1(lc)? NULL: absi(lc);
   if (C)
   {
     GEN C2 = sqri(C);
@@ -1387,7 +1396,7 @@ nf_LLL_cmbf(nfcmbf_t *T, long rec)
   long ti_LLL = 0, ti_CF = 0;
   pari_timer ti2, TI;
 
-  lP = absi(leading_term(P));
+  lP = absi(leading_coeff(P));
   if (is_pm1(lP)) lP = NULL;
 
   n0 = lg(famod) - 1;
@@ -1653,7 +1662,7 @@ nf_pick_prime(long ct, GEN nf, GEN polbase, long fl,
   pari_timer ti_pr;
 
   if (DEBUGLEVEL>3) timer_start(&ti_pr);
-  *lt  = leading_term(polbase); /* t_INT */
+  *lt  = leading_coeff(polbase); /* t_INT */
   if (gequal1(*lt)) *lt = NULL;
   *pr = NULL;
   *Fa = NULL;
@@ -1701,6 +1710,9 @@ nf_pick_prime(long ct, GEN nf, GEN polbase, long fl,
       if (fl == FACTORS) return anbf; /* irreducible */
       if (!anbf) return 0; /* no root */
     }
+    if (DEBUGLEVEL>3)
+      err_printf("%3ld %s at prime\n  %Ps\nTime: %ld\n",
+                 anbf, fl == FACTORS?"factors": "roots", apr, timer_delay(&ti_pr));
 
     if (!nbf || anbf < nbf
              || (anbf == nbf && pr_get_f(apr) > pr_get_f(*pr)))
@@ -1711,9 +1723,6 @@ nf_pick_prime(long ct, GEN nf, GEN polbase, long fl,
       *Fa = fa;
     }
     else avma = av2;
-    if (DEBUGLEVEL>3)
-      err_printf("%3ld %s at prime\n  %Ps\nTime: %ld\n",
-                 anbf, fl == FACTORS?"factors": "roots", apr, timer_delay(&ti_pr));
     if (--ct <= 0) break;
   }
   if (!nbf) pari_err_OVERFLOW("nf_pick_prime [ran out of primes]");
@@ -1733,7 +1742,7 @@ nfsqff_trager(GEN u, GEN T, GEN dent)
   fa = ZX_DDF(Q_primpart(n)); lx = lg(fa);
   if (lx == 2) return mkcol(u);
 
-  tmonic = is_pm1(leading_term(T));
+  tmonic = is_pm1(leading_coeff(T));
   P = cgetg(lx,t_COL);
   x0 = deg1pol_shallow(stoi(-k), gen_0, varn(T));
   mx0 = deg1pol_shallow(stoi(k), gen_0, varn(T));
@@ -1763,7 +1772,7 @@ polfnf(GEN a, GEN T)
 
   if (typ(a)!=t_POL) pari_err_TYPE("polfnf",a);
   if (typ(T)!=t_POL) pari_err_TYPE("polfnf",T);
-  T = Q_primpart(T); tmonic = is_pm1(leading_term(T));
+  T = Q_primpart(T); tmonic = is_pm1(leading_coeff(T));
   RgX_check_ZX(T,"polfnf");
   A = Q_primpart( QXQX_normalize(RgX_nffix("polfnf",T,a,1), T) );
   dA = degpol(A);
@@ -2050,7 +2059,7 @@ guess_roots(GEN nf)
     old = nbroots;
     nbroots = nbroots? gcdii(pf_1, nbroots): pf_1;
     if (DEBUGLEVEL>5)
-      err_printf("p=%ld; gcf(f(P/p))=%ld; nbroots | %Ps",p, gcdf, nbroots);
+      err_printf("p=%lu; gcf(f(P/p))=%ld; nbroots | %Ps",p, gcdf, nbroots);
     /* if same result go on else reset the stop counter [c] */
     if (old && equalii(nbroots,old))
     { if (!is_bigint(nbroots) && ++c > B) break; }
diff --git a/src/basemath/polarit1.c b/src/basemath/polarit1.c
index 78a9e91..bc1bff6 100644
--- a/src/basemath/polarit1.c
+++ b/src/basemath/polarit1.c
@@ -265,7 +265,7 @@ static GEN
 ZX_to_ZpX_normalized(GEN x, GEN p, GEN pr, long r)
 {
   long i, lx = lg(x);
-  GEN z, lead = leading_term(x);
+  GEN z, lead = leading_coeff(x);
 
   if (gequal1(lead)) return ZX_to_ZpX(x, p, pr, r);
   (void)Z_pvalrem(lead, p, &lead); lead = Fp_inv(lead, pr);
@@ -340,20 +340,20 @@ ZX_Zp_root(GEN f, GEN a, GEN p, long prec)
   setlg(z,j); return z;
 }
 
-/* a t_PADIC, return vector of p-adic roots of f equal to a (mod p)
- * We assume 1) f(a) = 0 mod p,
- *           2) leading coeff prime to p. */
+/* a t_PADIC, return vector of p-adic roots of f equal to a (mod p) */
 GEN
 Zp_appr(GEN f, GEN a)
 {
   pari_sp av = avma;
-  long prec;
-  GEN z, p;
-  p = gel(a,2); prec = gequal0(a)? valp(a): precp(a);
+  GEN z, p = gel(a,2);
+  long prec = gequal0(a)? valp(a): precp(a);
+
   f = QpX_to_ZX(f, p);
   if (degpol(f) <= 0) pari_err_CONSTPOL("Zp_appr");
   (void)ZX_gcd_all(f, ZX_deriv(f), &f);
-  z = ZX_Zp_root(f, gtrunc(a), p, prec);
+  a = padic_to_Q(a);
+  if (signe(FpX_eval(f,a,p))) { avma = av; return cgetg(1,t_COL); }
+  z = ZX_Zp_root(f, a, p, prec);
   return gerepilecopy(av, ZV_to_ZpV(z, p, prec));
 }
 /* vector of p-adic roots of the ZX f, leading term prime to p. Shallow */
@@ -379,12 +379,12 @@ ZX_Zp_roots(GEN f, GEN p, long prec)
 static GEN
 pnormalize(GEN f, GEN p, long prec, long n, GEN *plead, long *pprec, int *prev)
 {
-  *plead = leading_term(f);
+  *plead = leading_coeff(f);
   *pprec = prec;
   *prev = 0;
   if (!is_pm1(*plead))
   {
-    long v = Z_pval(*plead,p), v1 = Z_pval(constant_term(f),p);
+    long v = Z_pval(*plead,p), v1 = Z_pval(constant_coeff(f),p);
     if (v1 < v)
     {
       *prev = 1; f = RgX_recip_shallow(f);
@@ -443,6 +443,7 @@ getprec(GEN x, long *pprec, GEN *pp)
     for (i = lg(x)-1; i>1; i--) scalar_getprec(gel(x,i), pprec, pp);
 }
 
+/* assume f(a) = 0 (mod T,p) */
 static GEN
 ZXY_ZpQ_root(GEN f, GEN a, GEN T, GEN p, long prec)
 {
@@ -456,7 +457,7 @@ ZXY_ZpQ_root(GEN f, GEN a, GEN T, GEN p, long prec)
   f = RgX_unscale(RgXQX_translate(f, a, T), p);
   f = RgX_Rg_div(f, powiu(p, gvaluation(f,p)));
   z = cgetg(degpol(f)+1,t_COL);
-  R = FqX_roots(FqX_red(f,T,p), T, p); lR = lg(R);
+  R = FpXQX_roots(FqX_red(f,T,p), T, p); lR = lg(R);
   for(j=i=1; i<lR; i++)
   {
     GEN u = ZXY_ZpQ_root(f, gel(R,i), T, p, prec-1);
@@ -466,7 +467,7 @@ ZXY_ZpQ_root(GEN f, GEN a, GEN T, GEN p, long prec)
 }
 
 /* a belongs to finite extension of Q_p, return all roots of f equal to a
- * mod p. We assume f(a) = 0 (mod p) [mod 4 if p=2] */
+ * mod p. Don't assume f(a) = 0 (mod p) */
 GEN
 padicappr(GEN f, GEN a)
 {
@@ -483,7 +484,8 @@ padicappr(GEN f, GEN a)
   if (gequal0(f)) pari_err_ROOTS0("padicappr");
   z = RgX_gcd(f, RgX_deriv(f));
   if (degpol(z) > 0) f = RgX_div(f,z);
-  T = gel(a,1); a = gel(a,2);
+  T = gel(a,1);
+  a = gel(a,2);
   p = NULL; prec = LONG_MAX;
   getprec(a, &prec, &p);
   getprec(T, &prec, &p); if (!p) pari_err_TYPE("padicappr",T);
@@ -491,6 +493,8 @@ padicappr(GEN f, GEN a)
   if (typ(a) != t_POL) a = scalarpol_shallow(a, varn(T));
   a = ZpX_to_ZX(a,p);
   T = QpX_to_ZX(T,p);
+  if (!gequal0(FqX_eval(FqX_red(f,T,p), a, T,p))) /* check f(a) = 0 (mod p,T) */
+  { avma = av; return cgetg(1,t_COL); }
   z = ZXY_ZpQ_root(f, a, T, p, prec);
   return gerepilecopy(av, ZXV_to_ZpXQV(z, T, p, prec));
 }
@@ -523,7 +527,7 @@ expo_is_squarefree(GEN e)
   return 1;
 }
 
-/* assume f a ZX with leading_term 1, degree > 0 */
+/* assume f a ZX with leading_coeff 1, degree > 0 */
 GEN
 ZX_monic_factorpadic(GEN f, GEN p, long prec)
 {
@@ -589,7 +593,7 @@ factorpadic(GEN f,GEN p,long r)
   if (!signe(f)) return prime_fact(f);
   if (n == 0) return trivial_fact();
 
-  f = QpX_to_ZX(f, p); (void)Z_pvalrem(leading_term(f), p, &lt);
+  f = QpX_to_ZX(f, p); (void)Z_pvalrem(leading_coeff(f), p, &lt);
   f = pnormalize(f, p, r, n-1, &lead, &pr, &reverse);
   y = ZX_monic_factorpadic(f, p, pr);
   P = gel(y,1); l = lg(P);
diff --git a/src/basemath/polarit2.c b/src/basemath/polarit2.c
index 36d2ed7..0d091ea 100644
--- a/src/basemath/polarit2.c
+++ b/src/basemath/polarit2.c
@@ -954,12 +954,8 @@ gauss_gcd(GEN x, GEN y)
 }
 
 static int
-is_rational(GEN x) { long t = typ(x); return is_rational_t(t); }
-static int
 c_is_rational(GEN x)
-{
-  return (is_rational(gel(x,1)) && is_rational(gel(x,2)));
-}
+{ return is_rational_t(typ(gel(x,1))) && is_rational_t(typ(gel(x,2))); }
 static GEN
 c_zero_gcd(GEN c)
 {
@@ -1391,7 +1387,7 @@ fix_lcm(GEN x)
       break;
     case t_POL:
       if (lg(x) <= 2) break;
-      t = leading_term(x);
+      t = leading_coeff(x);
       if (typ(t) == t_INT && signe(t) < 0) x = gneg(x);
   }
   return x;
@@ -1983,7 +1979,7 @@ subres_step(GEN *u, GEN *v, GEN *g, GEN *h, GEN *uze, GEN *um1, long *signh)
   GEN u0, c, r, q = RgX_pseudodivrem(*u,*v, &r);
   long du, dv, dr, degq;
 
-  if (gequal0(leading_term(r))) r = RgX_renormalize(r);
+  if (gequal0(leading_coeff(r))) r = RgX_renormalize(r);
   dr = lg(r); if (!signe(r)) { *u = NULL; return 0; }
   du = degpol(*u);
   dv = degpol(*v);
@@ -2003,7 +1999,7 @@ subres_step(GEN *u, GEN *v, GEN *g, GEN *h, GEN *uze, GEN *um1, long *signh)
   *um1 = *uze;
   *uze = u0; /* uze <- lead(v)^(degq + 1) * um1 - q * uze */
 
-  *u = *v; c = *g; *g  = leading_term(*u);
+  *u = *v; c = *g; *g  = leading_coeff(*u);
   switch(degq)
   {
     case 0: break;
@@ -2038,8 +2034,8 @@ subresext_i(GEN x, GEN y, GEN *U, GEN *V)
   if (varn(x) != varn(y))
     return varncmp(varn(x), varn(y)) < 0? scalar_res(x,y,U,V)
                                         : scalar_res(y,x,V,U);
-  if (gequal0(leading_term(x))) x = RgX_renormalize(x);
-  if (gequal0(leading_term(y))) y = RgX_renormalize(y);
+  if (gequal0(leading_coeff(x))) x = RgX_renormalize(x);
+  if (gequal0(leading_coeff(y))) y = RgX_renormalize(y);
   dx = degpol(x);
   dy = degpol(y);
   signh = 1;
@@ -2110,7 +2106,7 @@ zero_extgcd(GEN y, GEN *U, GEN *V, long vx)
 static int
 must_negate(GEN x)
 {
-  GEN t = leading_term(x);
+  GEN t = leading_coeff(x);
   switch(typ(t))
   {
     case t_INT: case t_REAL:
@@ -2301,7 +2297,7 @@ reductum_lg(GEN x, long lx)
 static GEN
 nextSousResultant(GEN P, GEN Q, GEN Z, GEN s)
 {
-  GEN p0, q0, h0, TMP, H, A, z0 = leading_term(Z);
+  GEN p0, q0, h0, TMP, H, A, z0 = leading_coeff(Z);
   long p, q, j, lP, lQ;
   pari_sp av;
 
@@ -2374,7 +2370,7 @@ RgX_resultant_all(GEN P, GEN Q, GEN *sol)
   P = primitive_part(P, &cP);
   Q = primitive_part(Q, &cQ);
   av2 = avma;
-  s = gpowgs(leading_term(Q),delta);
+  s = gpowgs(leading_coeff(Q),delta);
   if (both_odd(dP, dQ)) sig = -sig;
   Z = Q;
   Q = RgX_pseudorem(P, Q);
@@ -2382,7 +2378,7 @@ RgX_resultant_all(GEN P, GEN Q, GEN *sol)
   while(degpol(Q) > 0)
   {
     delta = degpol(P) - degpol(Q); /* > 0 */
-    Z = Lazard2(Q, leading_term(Q), s, delta);
+    Z = Lazard2(Q, leading_coeff(Q), s, delta);
     if (both_odd(degpol(P), degpol(Q))) sig = -sig;
     Q = nextSousResultant(P, Q, Z, s);
     P = Z;
@@ -2391,10 +2387,10 @@ RgX_resultant_all(GEN P, GEN Q, GEN *sol)
       if(DEBUGMEM>1) pari_warn(warnmem,"resultant_all, degpol Q = %ld",degpol(Q));
       gerepileall(av2,2,&P,&Q);
     }
-    s = leading_term(P);
+    s = leading_coeff(P);
   }
   if (!signe(Q)) { avma = av; return RgX_get_0(Q); }
-  s = Lazard(leading_term(Q), s, degpol(P));
+  s = Lazard(leading_coeff(Q), s, degpol(P));
   if (sig == -1) s = gneg(s);
   if (cP) s = gmul(s, gpowgs(cP,dQ));
   if (cQ) s = gmul(s, gpowgs(cQ,dP));
@@ -2593,7 +2589,7 @@ RgXQ_charpoly(GEN x, GEN T, long v)
   /* test for silly input: x mod (deg 0 polynomial) */
   if (typ(ch) != t_POL) { avma = av; return pol_1(v); }
 
-  L = leading_term(ch);
+  L = leading_coeff(ch);
   if (!gequal1(L)) ch = RgX_Rg_div(ch, L);
   return gerepileupto(av, ch);
 }
@@ -2626,7 +2622,7 @@ rnfcharpoly(GEN nf, GEN Q, GEN x, long v)
   if (typ(x) != t_POL) return caract_const(av, x, v, dQ);
   /* x a t_POL in variable vQ */
   if (degpol(x) >= dQ) x = RgX_rem(x, Q);
-  if (dQ <= 1) return caract_const(av, constant_term(x), v, 1);
+  if (dQ <= 1) return caract_const(av, constant_coeff(x), v, 1);
   return gerepilecopy(av, lift_if_rational( RgXQ_charpoly(x, Q, v) ));
 }
 
@@ -2751,7 +2747,7 @@ RgX_gcd(GEN x, GEN y)
       }
       if (DEBUGLEVEL > 9) err_printf("RgX_gcd: dr = %ld\n", degpol(r));
       du = lg(u); dv = lg(v); degq = du-dv;
-      u = v; p1 = g; g = leading_term(u);
+      u = v; p1 = g; g = leading_coeff(u);
       switch(degq)
       {
         case 0: break;
@@ -2801,7 +2797,7 @@ RgX_disc_aux(GEN x)
     D = RgX_resultant_all(x, y, NULL);
     if (D == gen_0) return RgX_get_0(y);
   }
-  L = leading_term(x); if (!gequal1(L)) D = gdiv(D,L);
+  L = leading_coeff(x); if (!gequal1(L)) D = gdiv(D,L);
   if (dx & 2) D = gneg(D);
   return D;
 }
@@ -2904,22 +2900,19 @@ sturmpart_i(GEN x, GEN a, GEN b)
   t = typ(x);
   if (t != t_POL)
   {
-    if (t == t_INT || t == t_REAL || t == t_FRAC) return 0;
+    if (is_real_t(t)) return 0;
     pari_err_TYPE("sturm",x);
   }
-  s=lg(x); if (s==3) return 0;
+  s = lg(x); if (s==3) return 0;
   u = primpart(x);
   integral = RgX_is_ZX(u);
+  if (integral && !ZX_is_squarefree(u))
+    pari_err_DOMAIN("polsturm","issquarefree(pol)","=",gen_0,u);
   if (!b && a && typ(a) == t_VEC && lg(a) == 3)
   { /* new format */
     if (integral && exact_sturm(gel(a,1)) && exact_sturm(gel(a,2)))
-    {
-      if (!ZX_is_squarefree(u))
-        pari_err_DOMAIN("polsturm","issquarefree(pol)","=",gen_0,u);
       return ZX_sturmpart(u, a);
-    }
     /* but can't use new function; convert to old form */
-    integral = 0;
     b = gel(a,2);
     if (typ(b) == t_INFINITY)
     {
@@ -2933,20 +2926,15 @@ sturmpart_i(GEN x, GEN a, GEN b)
       a = NULL;
     }
   }
-  if (integral)
+  else if (integral)
   {
-    if (!a) a = mkmoo();
-    if (!b) b = mkoo();
-    if (exact_sturm(a) && exact_sturm(b))
-    {
-      if (!ZX_is_squarefree(u))
-        pari_err_DOMAIN("polsturm","issquarefree(pol)","=",gen_0,u);
-      return ZX_sturmpart(u, mkvec2(a,b));
-    }
+    GEN A = a? a: mkmoo();
+    GEN B = b? b: mkoo();
+    if (exact_sturm(A) && exact_sturm(B)) return ZX_sturmpart(u, mkvec2(A,B));
   }
   /* legacy code: should only be used if we have a t_REAL somewhere; and even
    * then, the calling program should be changed */
-  sl = gsigne(leading_term(u));
+  sl = gsigne(leading_coeff(u));
   t = a? gsigne(poleval(u,a)): (odd(s)? sl: -sl);
   if (s==4)
   {
@@ -2975,8 +2963,8 @@ sturmpart_i(GEN x, GEN a, GEN b)
     GEN p1, r = RgX_pseudorem(u,v);
     long du=lg(u), dv=lg(v), dr=lg(r), degq=du-dv;
 
-    if (dr<=2) pari_err_DOMAIN("polsturm","issquarefree(pol)","=",gen_0,x);
-    if (gsigne(leading_term(v)) > 0 || degq&1) r=gneg_i(r);
+    if (dr<=2) pari_err_PREC("polsturm");
+    if (gsigne(leading_coeff(v)) > 0 || degq&1) r=gneg_i(r);
     sl = gsigne(gel(r,dr-1));
     sr = b? gsigne(poleval(r,b)): sl;
     if (sr)
@@ -2992,7 +2980,7 @@ sturmpart_i(GEN x, GEN a, GEN b)
     }
     if (dr==3) return r1;
 
-    u=v; p1 = g; g = gabs(leading_term(u),DEFAULTPREC);
+    u=v; p1 = g; g = gabs(leading_coeff(u),DEFAULTPREC);
     switch(degq)
     {
       case 0: break;
diff --git a/src/basemath/polarit3.c b/src/basemath/polarit3.c
index 50d2f6d..ab4a047 100644
--- a/src/basemath/polarit3.c
+++ b/src/basemath/polarit3.c
@@ -259,7 +259,8 @@ Rg_to_FpXQ(GEN x, GEN T, GEN p)
       if (is_const_t(ta)) return scalar_ZX(Rg_to_Fp(a, p), v);
       b = RgX_to_FpX(b, p); if (varn(b) != v) break;
       a = RgX_to_FpX(a, p); if (ZX_equal(b,get_FpX_mod(T))) return a;
-      return FpX_rem(a, T, p);
+      if (signe(FpX_rem(b,T,p))==0) return FpX_rem(a, T, p);
+      break;
     case t_POL:
       if (varn(x) != v) break;
       return FpX_rem(RgX_to_FpX(x,p), T, p);
@@ -307,7 +308,7 @@ RgM_to_FpM(GEN x, GEN p)
   return z;
 }
 GEN
-RgC_to_Flc(GEN x, ulong p)
+RgV_to_Flv(GEN x, ulong p)
 {
   long l = lg(x), i;
   GEN a = cgetg(l, t_VECSMALL);
@@ -319,7 +320,7 @@ RgM_to_Flm(GEN x, ulong p)
 {
   long l, i;
   GEN a = cgetg_copy(x, &l);
-  for (i=1; i<l; i++) gel(a,i) = RgC_to_Flc(gel(x,i), p);
+  for (i=1; i<l; i++) gel(a,i) = RgV_to_Flv(gel(x,i), p);
   return a;
 }
 
@@ -385,12 +386,11 @@ FqX_Fq_mul_to_monic(GEN P, GEN U, GEN T, GEN p)
 }
 
 GEN
-FqX_normalize(GEN z, GEN T, GEN p)
+FpXQX_normalize(GEN z, GEN T, GEN p)
 {
   GEN lc;
-  if (!T) return FpX_normalize(z,p);
   if (lg(z) == 2) return z;
-  lc = leading_term(z);
+  lc = leading_coeff(z);
   if (typ(lc) == t_POL)
   {
     if (lg(lc) > 3) /* non-constant */
@@ -693,7 +693,7 @@ Fq_sqrtn(GEN x, GEN n, GEN T, GEN p, GEN *zeta)
           return Fp_sqrtn(x,n,p,zeta);
       }
     }
-    x = scalarpol_shallow(x, get_FpX_var(T));
+    x = scalarpol(x, get_FpX_var(T)); /* left on stack */
   }
   return FpXQ_sqrtn(x,n,T,p,zeta);
 }
@@ -882,7 +882,7 @@ GEN
 FqV_to_FlxV(GEN v, GEN T, GEN pp)
 {
   long j, N = lg(v);
-  long vT = varn(T);
+  long vT = evalvarn(get_FpX_var(T));
   ulong p = pp[2];
   GEN y = cgetg(N, t_VEC);
   for (j=1; j<N; j++)
@@ -895,7 +895,7 @@ GEN
 FqC_to_FlxC(GEN v, GEN T, GEN pp)
 {
   long j, N = lg(v);
-  long vT = get_FpX_var(T);
+  long vT = evalvarn(get_FpX_var(T));
   ulong p = pp[2];
   GEN y = cgetg(N, t_COL);
   for (j=1; j<N; j++)
@@ -1115,11 +1115,11 @@ Flx_intersect_ker(GEN P, GEN MA, GEN U, ulong p)
   ib0 = Fl_inv(Fl_neg(U[2], p), p);
   R = cgetg(r+1,t_MAT);
   gel(R,1) = gel(A,1);
-  gel(R,r) = Flm_Flc_mul(MA, Flc_Fl_mul(gel(A,1),ib0, p), p);
+  gel(R,r) = Flm_Flc_mul(MA, Flv_Fl_mul(gel(A,1),ib0, p), p);
   for(i=r-1; i>1; i--)
   {
     gel(R,i) = Flm_Flc_mul(MA,gel(R,i+1),p);
-    Flv_add_inplace(gel(R,i), Flc_Fl_mul(gel(R,r), U[i+2], p), p);
+    Flv_add_inplace(gel(R,i), Flv_Fl_mul(gel(R,r), U[i+2], p), p);
   }
   return gerepileupto(ltop, Flm_to_FlxX(Flm_transpose(R),vp,vu));
 }
@@ -1771,116 +1771,6 @@ Flx_resultant_all(GEN a, GEN b, long *C0, long *C1, GEN dglist, ulong p)
   avma = av; return res;
 }
 
-/* u P(X) + v P(-X) */
-static GEN
-pol_comp(GEN P, GEN u, GEN v)
-{
-  long i, l = lg(P);
-  GEN y = cgetg(l, t_POL);
-  for (i=2; i<l; i++)
-  {
-    GEN t = gel(P,i);
-    gel(y,i) = gequal0(t)? gen_0:
-                         (i&1)? gmul(t, gsub(u,v)) /*  odd degree */
-                              : gmul(t, gadd(u,v));/* even degree */
-  }
-  y[1] = P[1]; return normalizepol_lg(y,l);
-}
-
-GEN
-polint_triv(GEN xa, GEN ya)
-{
-  GEN P = NULL, Q = roots_to_pol(xa,0);
-  long i, n = lg(xa);
-  pari_sp av = avma;
-  for (i=1; i<n; i++)
-  {
-    GEN T, dP, r;
-    if (gequal0(gel(ya,i))) continue;
-    T = RgX_div_by_X_x(Q, gel(xa,i), NULL);
-    r = poleval(T, gel(xa,i));
-    if (i < n-1 && absi_equal(gel(xa,i), gel(xa,i+1)))
-    { /* x_i = -x_{i+1} */
-      dP = pol_comp(gdiv(T, r), gel(ya,i), gel(ya,i+1));
-      i++;
-    }
-    else
-      dP = gdiv(gmul(gel(ya,i), T), r);
-    P = P? gadd(P, dP): dP;
-    if (gc_needed(av,2))
-    {
-      if (DEBUGMEM>1) pari_warn(warnmem,"polint_triv2 (i = %ld)",i);
-      P = gerepileupto(av, P);
-    }
-  }
-  return P? P: pol_0(0);
-}
-
-GEN
-FpV_polint(GEN xa, GEN ya, GEN p, long v)
-{
-  GEN inv,T,dP, P = NULL, Q = FpV_roots_to_pol(xa, p, v);
-  long i, n = lg(xa);
-  pari_sp av = avma;
-  for (i=1; i<n; i++)
-  {
-    if (!signe(gel(ya,i))) continue;
-    T = FpX_div_by_X_x(Q, gel(xa,i), p, NULL);
-    inv = Fp_inv(FpX_eval(T,gel(xa,i), p), p);
-    if (i < n-1 && equalii(addii(gel(xa,i), gel(xa,i+1)), p))
-    {
-      dP = pol_comp(T, Fp_mul(gel(ya,i),  inv,p),
-                       Fp_mul(gel(ya,i+1),inv,p));
-      i++; /* x_i = -x_{i+1} */
-    }
-    else
-      dP = FpX_Fp_mul(T, Fp_mul(gel(ya,i),inv,p), p);
-    P = P? FpX_add(P, dP, p): dP;
-    if (gc_needed(av,2))
-    {
-      if (DEBUGMEM>1) pari_warn(warnmem,"FpV_polint");
-      P = gerepileupto(av, P);
-    }
-  }
-  return P? P: pol_0(v);
-}
-
-static void
-Flv_polint_all(GEN xa, GEN ya, GEN C0, GEN C1, ulong p,
-               GEN *pHp, GEN *pH0p, GEN *pH1p)
-{
-  GEN T,Q = Flv_roots_to_pol(xa, p, 0);
-  GEN dP  = NULL,  P = NULL;
-  GEN dP0 = NULL, P0= NULL;
-  GEN dP1 = NULL, P1= NULL;
-  long i, n = lg(xa);
-  ulong inv;
-  for (i=1; i<n; i++)
-  {
-    T = Flx_div_by_X_x(Q, xa[i], p, NULL);
-    inv = Fl_inv(Flx_eval(T,xa[i], p), p);
-
-    if (ya[i])
-    {
-      dP = Flx_Fl_mul(T, Fl_mul(ya[i],inv,p), p);
-      P = P ? Flx_add(P , dP , p): dP;
-    }
-    if (C0[i])
-    {
-      dP0= Flx_Fl_mul(T, Fl_mul(C0[i],inv,p), p);
-      P0= P0? Flx_add(P0, dP0, p): dP0;
-    }
-    if (C1[i])
-    {
-      dP1= Flx_Fl_mul(T, Fl_mul(C1[i],inv,p), p);
-      P1= P1? Flx_add(P1, dP1, p): dP1;
-    }
-  }
-  *pHp  = (P ? P : zero_Flx(0));
-  *pH0p = (P0? P0: zero_Flx(0));
-  *pH1p = (P1? P1: zero_Flx(0));
-}
-
 /* Q a vector of polynomials representing B in Fp[X][Y], evaluate at X = x,
  * Return 0 in case of degree drop. */
 static GEN
@@ -1888,7 +1778,7 @@ FlxY_evalx_drop(GEN Q, ulong x, ulong p)
 {
   GEN z;
   long i, lb = lg(Q);
-  ulong leadz = Flx_eval(leading_term(Q), x, p);
+  ulong leadz = Flx_eval(leading_coeff(Q), x, p);
   long vs=mael(Q,2,1);
   if (!leadz) return zero_Flx(vs);
 
@@ -1958,7 +1848,7 @@ ZX_ZXY_ResBound(GEN A, GEN B, GEN dB)
   avma = av; return (i <= 0)? 1: 1 + (ulong)i;
 }
 
-/* return Res(a(Y), b(n,Y)) over Fp. la = leading_term(a) [for efficiency] */
+/* return Res(a(Y), b(n,Y)) over Fp. la = leading_coeff(a) [for efficiency] */
 static ulong
 Flx_FlxY_eval_resultant(GEN a, GEN b, ulong n, ulong p, ulong la)
 {
@@ -2064,7 +1954,7 @@ FlxX_resultant(GEN u, GEN v, ulong p, long sx)
     r = FlxX_pseudorem(u,v,p); dr = lg(r);
     if (dr == 2) { avma = av; return zero_Flx(sx); }
     du = degpol(u); dv = degpol(v); degq = du-dv;
-    u = v; p1 = g; g = leading_term(u);
+    u = v; p1 = g; g = leading_coeff(u);
     switch(degq)
     {
       case 0: break;
@@ -2152,8 +2042,8 @@ FpX_FpXY_resultant(GEN a, GEN b, GEN p)
     return Flx_to_ZX(x);
   }
   db = RgXY_degreex(b);
-  dres = degpol(a)*db;
-  la = leading_term(a);
+  dres = degpol(a)*degpol(b);
+  la = leading_coeff(a);
   x = cgetg(dres+2, t_VEC);
   y = cgetg(dres+2, t_VEC);
  /* Evaluate at dres+ 1 points: 0 (if dres even) and +/- n, so that P_n(X) =
@@ -2291,6 +2181,7 @@ INIT:
     b = ZXX_to_FlxX(B, p, varn(A));
     if (LERS)
     {
+      GEN Hi;
       if (degpol(a) < degA || lg(b) < lb) continue; /* p | lc(A)lc(B) */
       if (checksqfree)
       { /* find degree list for generic Euclidean Remainder Sequence */
@@ -2321,7 +2212,8 @@ INIT:
         x[++i] = n; y[i] = Flx_resultant_all(a, ev, C0+i, C1+i, dglist, p);
         if (!C1[i]) i--; /* C1(i) = 0. No way to recover C0(i) */
       }
-      Flv_polint_all(x,y,C0,C1, p, &Hp, &H0p, &H1p);
+      Hi = Flv_Flm_polint(x, mkvec3(y,C0,C1), p, 0);
+      Hp = gel(Hi,1); H0p = gel(Hi,2); H1p = gel(Hi,3);
     }
     else
     {
@@ -2435,7 +2327,7 @@ ZXQ_charpoly_sqf(GEN A, GEN T, long *lambda, long v)
   }
   R = ZX_ZXY_rnfequation(T, deg1pol_shallow(gen_1, gneg_i(A), 0), lambda);
   if (delvar) (void)delete_var();
-  setvarn(R, v); a = leading_term(T);
+  setvarn(R, v); a = leading_coeff(T);
   if (!gequal1(a)) R = gdiv(R, powiu(a, dA));
   return gerepileupto(av, R);
 }
@@ -2549,29 +2441,22 @@ ZX_resultant_prime(GEN a, GEN b, GEN dB, long degA, long degB, ulong p)
 
 /* If B=NULL, assume B=A' */
 static GEN
-ZX_resultant_slice(GEN A, GEN B, GEN dB, ulong p, long n, ulong *plast, GEN *mod)
+ZX_resultant_slice(GEN A, GEN B, GEN dB, GEN P, GEN *mod)
 {
   pari_sp av = avma;
-  long degA, degB, i;
-  GEN H, P, T;
+  long degA, degB, i, n = lg(P)-1;
+  GEN H, T;
 
   degA = degpol(A);
   degB = B ? degpol(B): degA - 1;
   if (n == 1)
   {
-    ulong Hp;
+    ulong Hp, p = uel(P,1);
     GEN a, b;
-    if (dB) while (umodiu(dB, p)==0) p = unextprime(p+1);
     a = ZX_to_Flx(A, p), b = B ? ZX_to_Flx(B, p): NULL;
     Hp = ZX_resultant_prime(a, b, dB, degA, degB, p);
     avma = av;
-    *plast = unextprime(p+1); *mod = utoi(p); return utoi(Hp);
-  }
-  P = cgetg(n+1, t_VECSMALL);
-  for (i=1; i <= n; i++, p = unextprime(p+1))
-  {
-    if (dB && umodiu(dB, p)==0) { i--; continue; }
-    P[i] = p;
+    *mod = utoi(p); return utoi(Hp);
   }
   T = ZV_producttree(P);
   A = ZX_nv_mod_tree(A, P, T);
@@ -2583,11 +2468,34 @@ ZX_resultant_slice(GEN A, GEN B, GEN dB, ulong p, long n, ulong *plast, GEN *mod
     GEN a = gel(A, i), b = B ? gel(B, i): NULL;
     H[i] = ZX_resultant_prime(a, b, dB, degA, degB, p);
   }
-  H = ZV_chinese_tree(H, P, T, mod); *plast=p;
+  H = ZV_chinese_tree(H, P, T, mod);
   gerepileall(av, 2, &H, mod);
   return H;
 }
 
+GEN
+ZX_resultant_worker(GEN P, GEN A, GEN B, GEN dB)
+{
+  GEN V = cgetg(3, t_VEC);
+  if (isintzero(B)) B = NULL;
+  if (isintzero(dB)) dB = NULL;
+  gel(V,1) = ZX_resultant_slice(A,B,dB,P,&gel(V,2));
+  return V;
+}
+
+static GEN
+primelist_disc(ulong *p, long n, GEN dB)
+{
+  GEN P = cgetg(n+1, t_VECSMALL);
+  long i;
+  for (i=1; i <= n; i++, *p = unextprime(*p+1))
+  {
+    if (dB && umodiu(dB, *p)==0) { i--; continue; }
+    P[i] = *p;
+  }
+  return P;
+}
+
 /* Res(A, B/dB), assuming the A,B in Z[X] and result is integer */
 /* if B=NULL, take B = A' */
 GEN
@@ -2627,20 +2535,39 @@ ZX_resultant_all(GEN A, GEN B, GEN dB, ulong bound)
     B = NULL;
   m = minss(degpol(A)+(B ? degpol(B): 0), n);
   if (m == 1)
-    H = ZX_resultant_slice(A, B, dB, p, n, &p, &mod);
+  {
+    GEN P = primelist_disc(&p, n, dB);
+    H = ZX_resultant_slice(A, B, dB, P, &mod);
+  }
   else
   {
-    long i, s = n/m, r = n - m*s;
+    long i, s = n/m, r = n - m*s, di = 0;
+    GEN worker = strtoclosure("_ZX_resultant_worker", 3, A, B?B:gen_0, dB?dB:gen_0);
+    struct pari_mt pt;
+    long pending;
     if (DEBUGLEVEL > 4)
       err_printf("ZX_resultant: bound 2^%ld, nb primes: %ld\n",bound, n);
     H = cgetg(m+1+!!r, t_VEC); P = cgetg(m+1+!!r, t_VEC);
-    for (i=1; i<=m; i++)
+    mt_queue_start(&pt, worker);
+    for (i=1; i<=m || pending; i++)
     {
-      gel(H, i) = ZX_resultant_slice(A, B, dB, p, s, &p, &gel(P, i));
-      if (DEBUGLEVEL>5) err_printf("%ld%% ",100*i/m);
+      GEN done;
+      mt_queue_submit(&pt, i, i<=m ? mkvec(primelist_disc(&p, s, dB)): NULL);
+      done = mt_queue_get(&pt, NULL, &pending);
+      if (done)
+      {
+        di++;
+        gel(H, di) = gel(done,1);
+        gel(P, di) = gel(done,2);
+        if (DEBUGLEVEL>5) err_printf("%ld%% ",100*di/m);
+      }
     }
+    mt_queue_end(&pt);
     if (r)
-      gel(H, i) = ZX_resultant_slice(A, B, dB, p, r, &p, &gel(P, i));
+    {
+      GEN Pr = primelist_disc(&p, r, dB);
+      gel(H, m+1) = ZX_resultant_slice(A, B, dB, Pr, &gel(P, m+1));
+    }
     H = ZV_chinese(H, P, &mod);
     if (DEBUGLEVEL>5) err_printf("done\n");
   }
@@ -2683,7 +2610,7 @@ QXQ_intnorm(GEN A, GEN B)
     R = ZX_resultant_all(B, A, gel(c,2), 0);
   }
   if (n && !equali1(n)) R = mulii(R, powiu(n, dB));
-  lB = leading_term(B);
+  lB = leading_coeff(B);
   if (!equali1(lB)) R = diviiexact(R, powiu(lB, dA));
   return gerepileuptoint(av, R);
 }
@@ -2698,7 +2625,7 @@ QXQ_norm(GEN A, GEN B)
   A = Q_primitive_part(A, &c);
   R = ZX_resultant(B, A);
   if (c) R = gmul(R, gpowgs(c, dB));
-  lB = leading_term(B);
+  lB = leading_coeff(B);
   if (!equali1(lB)) R = gdiv(R, gpowgs(lB, dA));
   return gerepileupto(av, R);
 }
@@ -2712,7 +2639,7 @@ ZX_disc_all(GEN x, ulong bound)
   long s, d = degpol(x);
   if (d <= 1) return d ? gen_1: gen_0;
   s = (d & 2) ? -1: 1;
-  l = leading_term(x);
+  l = leading_coeff(x);
   R = ZX_resultant_all(x, NULL, NULL, bound);
   if (is_pm1(l))
   { if (signe(l) < 0) s = -s; }
@@ -2740,13 +2667,14 @@ QXQ_inv(GEN A, GEN B)
   ulong p;
   pari_sp av2, av = avma;
   forprime_t S;
-
+  pari_timer ti;
   if (is_scalar_t(typ(A))) return scalarpol(ginv(A), varn(B));
   /* A a QX, B a ZX */
   if (degpol(A) < 15) return RgXQ_inv(A,B);
   A = Q_primitive_part(A, &D);
   /* A, B in Z[X] */
   init_modular(&S);
+  if (DEBUGLEVEL>5) timer_start(&ti);
   av2 = avma; U = NULL;
   while ((p = u_forprime_next(&S)))
   {
@@ -2764,7 +2692,7 @@ QXQ_inv(GEN A, GEN B)
       V = ZX_init_CRT(Vp,p,varn(A));
       q = utoipos(p); continue;
     }
-    if (DEBUGLEVEL>5) err_printf("QXQ_inv: mod %ld (bound 2^%ld)", p,expi(q));
+    if (DEBUGLEVEL>5) timer_printf(&ti,"QXQ_inv: mod %ld (bound 2^%ld)", p,expi(q));
     qp = muliu(q,p);
     stable = ZX_incremental_CRT_raw(&U, Up, q,qp, p)
            & ZX_incremental_CRT_raw(&V, Vp, q,qp, p);
diff --git a/src/basemath/polclass.c b/src/basemath/polclass.c
index 135c024..a792978 100644
--- a/src/basemath/polclass.c
+++ b/src/basemath/polclass.c
@@ -422,7 +422,7 @@ classno_wrapper(long D)
   pari_sp av = avma;
   GEN clsgp;
   ulong h;
-  clsgp = quadclassunit0(stoi(D), 0, 0, DEFAULTPREC);
+  clsgp = quadclassunit0(stoi(D), 0, NULL, DEFAULTPREC);
   h = itou(gel(clsgp, 1));
   avma = av;
   return h;
@@ -443,7 +443,7 @@ classno_wrapper(long D)
 INLINE double
 logfac(long n)
 {
-  return n * log(n) - (double) n +
+  return n * log((double) n) - (double) n +
     log((double) n * (1.0 + 4.0 * n * (1.0 + 2.0 * n))) / 6.0 +
     HALFLOGPI;
 }
@@ -581,7 +581,7 @@ select_classpoly_prime_pool(
     t_min[i] = 2;
 
   /* maximum possible trace = sqrt(2^BIL - D) */
-  t_size_lim = 2.0 * sqrt((1UL << (BITS_IN_LONG - 2)) - (((ulong)-D) >> 2));
+  t_size_lim = 2.0 * sqrt((double)((1UL << (BITS_IN_LONG - 2)) - (((ulong)-D) >> 2)));
 
   av = avma;
   for (z = -D / (2.0 * hurwitz); ; z *= delta + 1.0) {
@@ -601,7 +601,7 @@ select_classpoly_prime_pool(
 
       if ( ! is_smooth_enough(&vfactors, v))
         continue;
-      H = hclassno_wrapper(m_vsqr_D, 0);
+      H = hclassno_wrapper(m_vsqr_D, NULL);
 
       /* t <= 2 sqrt(p) and p <= z H(-v^2 D) and
        *
@@ -610,7 +610,7 @@ select_classpoly_prime_pool(
        * This last term is v * hurwitz * hurwitz_ratio_bound. */
 
       max_p = z * v * hurwitz * hurwitz_ratio_bound;
-      t_max = 2.0 * mindd(sqrt((1UL << (BITS_IN_LONG - 2)) - (m_vsqr_D >> 2)),
+      t_max = 2.0 * mindd(sqrt((double)((1UL << (BITS_IN_LONG - 2)) - (m_vsqr_D >> 2))),
                           sqrt(max_p));
       for (t = t_min[v]; t <= t_max; ++t) {
         ulong possible_4p = t * t + m_vsqr_D;
@@ -702,7 +702,7 @@ select_classpoly_primes(
 
   /* FIXME: Apply torsion constraints */
   /* FIXME: Rank elts of res according to cost/benefit ratio */
-  prime_pool = gen_sort(prime_pool, 0, primecmp);
+  prime_pool = gen_sort(prime_pool, NULL, primecmp);
 
   prime_bits = 0.0;
   biggest_p = gel(prime_pool, 1)[1];
@@ -754,7 +754,7 @@ oneroot_of_classpoly(ulong *j_endo, int *endo_cert, ulong j, norm_eqn_t ne, GEN
     u_levels[i] = z_lval(ne->u, gel(factw, 1)[i]);
   vdepths = gel(factw, 2);
 
-  L_bound = maxdd(log(-ne->D), (double)ne->v);
+  L_bound = maxdd(log((double) -ne->D), (double)ne->v);
 
   /* Iterate over the primes L dividing w */
   for (i = 1; i <= nfactors; ++i) {
@@ -1232,7 +1232,7 @@ polclass0(long D, long inv, long xvar, GEN *db)
 
   /* Prepopulate *db with all the modpolys we might need */
   /* TODO: Clean this up; in particular, note that u is factored later on. */
-  maxL = maxdd(log(-D), (double)biggest_v); /* This comes from L_bound in oneroot_of_classpoly() above */
+  maxL = maxdd(log((double) -D), (double)biggest_v); /* This comes from L_bound in oneroot_of_classpoly() above */
   if (u > 1) {
     for (L = 2; L <= maxL; L = unextprime(L + 1))
       if ( ! (u % L))
diff --git a/src/basemath/polmodular.c b/src/basemath/polmodular.c
index a0c751a..4fdb167 100644
--- a/src/basemath/polmodular.c
+++ b/src/basemath/polmodular.c
@@ -32,7 +32,7 @@ inv_level(long inv)
   case INV_F:
     return 6;
   default:
-    pari_err_BUG("inv_level");
+    pari_err_IMPL("this polmodular type");
   }
   return 0;
 }
@@ -1033,7 +1033,7 @@ find_noniso_L_isogenous_curve(
 
     /* b. Generate random point P on E of order L */
     avma = av;
-    pt = find_L_tors_point(0, a4, a6, p, pi, n, L, val);
+    pt = find_L_tors_point(NULL, a4, a6, p, pi, n, L, val);
   }
 
   avma = ltop;
@@ -1285,7 +1285,7 @@ interpolate_coeffs(GEN phi_modp, ulong p, GEN j_invs, GEN coeff_mat)
 {
   pari_sp av = avma;
   long i;
-  GEN pols = Flv_FlvV_polint(j_invs, coeff_mat, p, 0);
+  GEN pols = Flv_Flm_polint(j_invs, coeff_mat, p, 0);
   for (i = 1; i < lg(pols); ++i) {
     GEN pol = gel(pols, i);
     long k, maxk = lg(pol);
@@ -1642,7 +1642,7 @@ dinfo_to_vinfo(const modpoly_disc_info *dinfo)
 GEN
 polmodular_worker(ulong p, ulong t,
                   ulong L, GEN hilb, GEN factu, GEN vne, GEN vinfo,
-                  GEN J, long compute_derivs, GEN j_powers, GEN fdb)
+                  long compute_derivs, GEN j_powers, GEN fdb)
 {
   pari_sp av = avma;
   GEN modpoly_modp;
@@ -1652,7 +1652,7 @@ polmodular_worker(ulong p, ulong t,
   vne_to_ne(ne, vne);
   norm_eqn_update(ne, t, p, L);
   modpoly_modp = polmodular_split_p_Flm(L, hilb, factu, ne, fdb, &dinfo);
-  if (J != gen_0) {
+  if (!isintzero(j_powers)) {
     modpoly_modp = eval_modpoly_modp(modpoly_modp, j_powers, ne, compute_derivs);
     modpoly_modp = gerepileupto(av, modpoly_modp);
   }
@@ -1767,7 +1767,7 @@ polmodular0_generic_ZM(long L, long inv, GEN *db)
   D = simple_find_disc(L, inv, L0);
   ht = modpoly_height_bound(L, inv);
   H = polclass0(D, INV_J, 0, db);
-  mp = polmodular0_ZM(L, INV_J, 0, 0, 0, db);
+  mp = polmodular0_ZM(L, INV_J, NULL, NULL, 0, db);
 
   /* TODO: Use sparsity factor N = ceil((L + 1)/s) + 1 ?  Probably not
    * worth the increase in complexity. */
@@ -1870,7 +1870,7 @@ polmodular0_ZM(
 
     D = dinfo->D1;
     DK = dinfo->D0;
-    cond = sqrt(D / DK);
+    cond = sqrt((double)(D / DK));
     factu = factoru(cond);
     dbg_printf(1)("Selected discriminant D = %ld = %ld^2 * %ld.\n",
                   D, cond, DK);
@@ -1891,9 +1891,9 @@ polmodular0_ZM(
       compute_derivs = !!compute_derivs;
       j_powers = Fp_powers(J, L + 1, Q);
     }
-    worker = strtoclosure("_polmodular_worker", 9, utoi(L), hilb, factu, ne_to_vne(ne),
+    worker = strtoclosure("_polmodular_worker", 8, utoi(L), hilb, factu, ne_to_vne(ne),
         dinfo_to_vinfo(dinfo),
-        J? J : gen_0, stoi(compute_derivs), j_powers, *db);
+        stoi(compute_derivs), j_powers, *db);
     mt_queue_start(&pt, worker);
     for (i = 0; i < dinfo->nprimes || pending; ++i)
     {
@@ -1937,7 +1937,7 @@ polmodular_ZM(long L, long inv)
     pari_err_IMPL("composite level");
 
   db = polmodular_db_init(inv);
-  Phi = polmodular0_ZM(L, inv, 0, 0, 0, &db);
+  Phi = polmodular0_ZM(L, inv, NULL, NULL, 0, &db);
   gunclone_deep(db);
 
   return Phi;
@@ -2026,7 +2026,7 @@ polmodular(long L, long inv, GEN x, long v, long compute_derivs)
     J = FF_to_FpXQ_i(x);
     if (degpol(J) > 0)
       pari_err_DOMAIN("polmodular", "x", "not in prime subfield ", gen_0, x);
-    J = constant_term(J);
+    J = constant_coeff(J);
     P = FF_p_i(x);
     one = p_to_FF(P, 0);
   } else {
@@ -2174,16 +2174,16 @@ typedef GEN (*phi_fn)(void);
 static GEN
 bad_level(void)
 {
-  return (GEN)0;
+  return (GEN)NULL;
 }
 
 static const phi_fn INTERNAL_MODPOLY_DB[6][3] = {
   {   phi2_ZV,   phi3_ZV,   phi5_ZV }, /* INV_J */
   { bad_level, bad_level, phi5_f_ZV }, /* INV_F */
-  { bad_level, bad_level,         0 }, /* INV_F2 */
-  { bad_level, bad_level,         0 }, /* INV_F3 */
-  { bad_level, bad_level,         0 }, /* INV_F4 */
-  {         0, bad_level,         0 }  /* INV_G2 */
+  { bad_level, bad_level,      NULL }, /* INV_F2 */
+  { bad_level, bad_level,      NULL }, /* INV_F3 */
+  { bad_level, bad_level,      NULL }, /* INV_F4 */
+  {      NULL, bad_level,      NULL }  /* INV_G2 */
 };
 
 static GEN
@@ -2206,7 +2206,7 @@ polmodular_small_ZM(long L, long inv, GEN *db)
 
   if (f == bad_level) {
     pari_err_BUG("polmodular_small_ZM");
-  } else if (f == 0) {
+  } else if (f == NULL) {
     mp = polmodular0_generic_ZM(L, inv, db);
   } else {
     mp = sympol_to_ZM(f(), L);
@@ -2237,7 +2237,7 @@ modpoly_height_bound(long L, long inv)
   int hf;
 
   /* proven bound (in bits), derived from: 6l*log(l)+16*l+13*sqrt(l)*log(l) */
-  nbits = 6.0*L*log2(L)+16/LOG2*L+8.0*sqrt(L)*log2(L);
+  nbits = 6.0*L*log2(L)+16/LOG2*L+8.0*sqrt((double)L)*log2(L);
   /* alternative proven bound (in bits), derived from: 6l*log(l)+17*l */
   nbits2 = 6.0*L*log2(L)+17/LOG2*L;
   if ( nbits2 < nbits ) nbits = nbits2;
@@ -2767,7 +2767,7 @@ modpoly_pickD(
       if (D0_bits + 2*j*p_bits + 2*L_bits + (twofactor && (q & 1) ? 2.0 : 0.0) > (BITS_IN_LONG - 1))
         continue;
 
-      if ( ! check_generators(&n1, 0, D1, h1, n0, d, L0, L1))
+      if ( ! check_generators(&n1, NULL, D1, h1, n0, d, L0, L1))
         continue;
 
       if (n1 < h1) {
@@ -2852,7 +2852,7 @@ modpoly_pickD(
       Dinfo.cost = cost;
       Dinfo.inv = inv;
 
-      if ( ! modpoly_pickD_primes (0, 0, 0, 0, 0, &Dinfo.bits, minbits, &Dinfo))
+      if ( ! modpoly_pickD_primes (NULL, NULL, 0, NULL, 0, &Dinfo.bits, minbits, &Dinfo))
         continue;
       dbg_printf(2)("Best D2=%ld, D1=%ld, D0=%ld with s=%ld^%ld, L1=%ld, "
                  "n1=%ld, n2=%ld, cost ratio %.2f, bits=%ld\n",
@@ -3338,7 +3338,7 @@ discriminant_with_classno_at_least(
       h = itos(classno(stoi(bestD[i].D1)));
       avma = av;
       err_printf("  D = %ld, h = %ld, u = %ld, L0 = %ld, L1 = %ld, n1 = %ld, n2 = %ld, cost = %ld\n",
-          bestD[i].D1, h, (long)sqrt(bestD[i].D1 / bestD[i].D0), bestD[i].L0, bestD[i].L1,
+          bestD[i].D1, h, (long)sqrt((double)(bestD[i].D1 / bestD[i].D0)), bestD[i].L0, bestD[i].L1,
           bestD[i].n1, bestD[i].n2, bestD[i].cost);
     }
     err_printf("(off target by %.1f%%, cost ratio: %.1f)\n",
diff --git a/src/basemath/prime.c b/src/basemath/prime.c
index 7803a8b..efe1290 100644
--- a/src/basemath/prime.c
+++ b/src/basemath/prime.c
@@ -260,23 +260,29 @@ LucasMod(GEN n, ulong P, GEN N)
   pari_sp av = avma;
   GEN nd = int_MSW(n);
   ulong m = *nd;
-  long i, j = 1+bfffo(m);
+  long i, j;
   GEN v = utoipos(P), v1 = utoipos(P*P - 2);
 
-  m <<= j; j = BITS_IN_LONG - j;
+  if (m == 1)
+    j = 0;
+  else
+  {
+    j = 1+bfffo(m); /* < BIL */
+    m <<= j; j = BITS_IN_LONG - j;
+  }
   for (i=lgefint(n)-2;;) /* cf. leftright_pow */
   {
     for (; j; m<<=1,j--)
     { /* v = v_k, v1 = v_{k+1} */
       if (m&HIGHBIT)
       { /* set v = v_{2k+1}, v1 = v_{2k+2} */
-        v = subis(mulii(v,v1), (long)P);
-        v1= subis(sqri(v1), 2);
+        v = subiu(mulii(v,v1), P);
+        v1= subiu(sqri(v1), 2);
       }
       else
       {/* set v = v_{2k}, v1 = v_{2k+1} */
-        v1= subis(mulii(v,v1), (long)P);
-        v = subis(sqri(v), 2);
+        v1= subiu(mulii(v,v1), P);
+        v = subiu(sqri(v), 2);
       }
       v = modii(v, N);
       v1= modii(v1,N);
@@ -298,10 +304,13 @@ LucasMod(GEN n, ulong P, GEN N)
 static ulong
 u_LucasMod(ulong n, ulong P, ulong N)
 {
-  long j = 1 + bfffo(n);
-  ulong v = P, v1 = P*P - 2, mP = N - P, m2 = N - 2, m = n << j;
+  ulong v, v1, mP, m2, m;
+  long j;
 
-  j = BITS_IN_LONG - j;
+  if (n == 1) return P;
+  j = 1 + bfffo(n); /* < BIL */
+  v = P; v1 = P*P - 2; mP = N - P; m2 = N - 2;
+  m = n<<j; j = BITS_IN_LONG - j;
   for (; j; m<<=1,j--)
   { /* v = v_k, v1 = v_{k+1} */
     if (m & HIGHBIT)
@@ -822,11 +831,11 @@ static struct {
   {  4000000483UL,189961831},
   {  4222234741UL,200000000},
 #if BITS_IN_LONG == 64
-  { 11037271757,  500000000},
-  { 22801763489, 1000000000},
-  { 47055833459, 2000000000},
-  {122430513841, 5000000000},
-  {200000000507, 8007105083},
+  { 11037271757UL,  500000000L},
+  { 22801763489UL, 1000000000L},
+  { 47055833459UL, 2000000000L},
+  {122430513841UL, 5000000000L},
+  {200000000507UL, 8007105083L},
 #endif
 };
 static const int prime_table_len = numberof(prime_table);
diff --git a/src/basemath/qfisom.c b/src/basemath/qfisom.c
index 3201984..d5a2362 100644
--- a/src/basemath/qfisom.c
+++ b/src/basemath/qfisom.c
@@ -1157,12 +1157,12 @@ zm_maxdiag(GEN A)
 }
 
 static GEN
-init_qfauto(GEN F, GEN U, long max, struct qfauto *qf, GEN norm)
+init_qfauto(GEN F, GEN U, long max, struct qfauto *qf, GEN norm, GEN minvec)
 {
   long i, j, k;
   GEN W, v;
-  GEN M = minim(zm_to_ZM(gel(F,1)), stoi(max), NULL);
-  GEN V = ZM_to_zm_canon(gel(M, 3));
+  GEN M = minvec? minvec: gel(minim(zm_to_ZM(gel(F,1)), stoi(max), NULL), 3);
+  GEN V = ZM_to_zm_canon(M);
   long n = lg(V)-1, f = lg(F)-1, dim = lg(gel(F,1))-1;
   for (i = 1; i <= n; ++i)
   {
@@ -1484,7 +1484,7 @@ qfisom_bestmat(GEN A, long *pt_max)
 
 static GEN
 init_qfisom(GEN F, struct fingerprint *fp, struct qfcand *cand,
-                   struct qfauto *qf, GEN flags, long *max)
+                   struct qfauto *qf, GEN flags, long *max, GEN minvec)
 {
   GEN U, A, norm;
   if (is_qfisom(F))
@@ -1500,10 +1500,25 @@ init_qfisom(GEN F, struct fingerprint *fp, struct qfcand *cand,
     if (lg(F)<2) pari_err_TYPE("qfisom",F);
     A = gel(F,1);
     if (lg(A)<2) pari_err_TYPE("qfisom",A);
-    U = qfisom_bestmat(A, max);
-    if (DEBUGLEVEL) err_printf("QFIsom: max=%ld\n",*max);
-    if (U) F = zmV_apply_zm(F, gel(U,1));
-    norm = init_qfauto(F, U, *max, qf, NULL);
+    if (!minvec)
+    {
+      U = qfisom_bestmat(A, max);
+      if (DEBUGLEVEL) err_printf("QFIsom: max=%ld\n",*max);
+      if (U) F = zmV_apply_zm(F, gel(U,1));
+    } else
+    {
+      *max = zm_maxdiag(A); U = NULL;
+      if (typ(minvec)==t_VEC && lg(minvec)==4 && typ(gel(minvec,2))==t_INT)
+      {
+        long n = itos(gel(minvec,2));
+        if (n != *max)
+          pari_err_DOMAIN("qfisominit","m[2]","!=",stoi(*max),stoi(n));
+        minvec = gel(minvec, 3);
+      }
+      if (typ(minvec)!=t_MAT || lg(gel(minvec,1))!=lg(A))
+        pari_err_TYPE("qfisominit",minvec);
+    }
+    norm = init_qfauto(F, U, *max, qf, NULL, minvec);
     fingerprint(fp, qf);
     if (DEBUGLEVEL) err_printf("QFIsom: fp=%Ps\n",fp->diag);
     init_flags(cand, A, fp, qf, flags);
@@ -1520,7 +1535,7 @@ qfauto(GEN F, GEN flags)
   struct qfcand cand;
   struct qfauto qf;
   long max;
-  (void)init_qfisom(F, &fp, &cand, &qf, flags, &max);
+  (void)init_qfisom(F, &fp, &cand, &qf, flags, &max, NULL);
   init_qfgroup(&G, &fp, &qf);
   autom(&G, &qf, &fp, &cand);
   return gerepilecopy(av, gen_group(&G, qf.U));
@@ -1715,14 +1730,14 @@ isometry(struct qfauto *qf, struct qfauto *qff, struct fingerprint *fp, GEN G,
 }
 
 GEN
-qfisominit(GEN F, GEN flags)
+qfisominit(GEN F, GEN flags, GEN minvec)
 {
   pari_sp av = avma;
   struct fingerprint fp;
   struct qfauto qf;
   struct qfcand cand;
   long max;
-  GEN norm = init_qfisom(F, &fp, &cand, &qf, flags, &max);
+  GEN norm = init_qfisom(F, &fp, &cand, &qf, flags, &max, minvec);
   return gerepilecopy(av, mkvec5(F, norm,
                           mkvecn(qf.U?6:5, qf.F, qf.V, qf.W, qf.v, utoi(qf.p), qf.U),
                           mkvec3(fp.diag, fp.per, fp.e),
@@ -1731,12 +1746,12 @@ qfisominit(GEN F, GEN flags)
 }
 
 GEN
-qfisominit0(GEN x, GEN flags)
+qfisominit0(GEN x, GEN flags, GEN minvec)
 {
   pari_sp av = avma;
   GEN F = qf_to_zmV(x);
   if (!F) pari_err_TYPE("qfisom",x);
-  return gerepileupto(av, qfisominit(F, flags));
+  return gerepileupto(av, qfisominit(F, flags, minvec));
 }
 
 GEN
@@ -1748,8 +1763,8 @@ qfisom(GEN F, GEN FF, GEN flags)
   struct qfauto qf, qff;
   struct qfcand cand;
   long max;
-  GEN norm = init_qfisom(F, &fp, &cand, &qf, flags, &max);
-  init_qfauto(FF, NULL, max, &qff, norm);
+  GEN norm = init_qfisom(F, &fp, &cand, &qf, flags, &max, NULL);
+  init_qfauto(FF, NULL, max, &qff, norm, NULL);
   if (lg(qf.W)!=lg(qff.W)
       || !zvV_equal(vecvecsmall_sort(qf.W), vecvecsmall_sort(qff.W)))
     { avma=av; return gen_0; }
diff --git a/src/basemath/random.c b/src/basemath/random.c
index daab291..f471612 100644
--- a/src/basemath/random.c
+++ b/src/basemath/random.c
@@ -223,23 +223,21 @@ randomi(GEN N)
 GEN
 random_F2x(long d, long vs)
 {
-  long i, l = nbits2lg(d+1), n = l-1;
+  ulong db, dl = dvmduBIL(d,&db);
+  long i, l = 2 + dl + !!db;
   GEN y = cgetg(l,t_VECSMALL); y[1] = vs;
 #ifdef LONG_IS_64BIT
-  for (i=2; i<=n; i++) y[i] = rand64();
+  for (i=2; i<l; i++) uel(y,i) = rand64();
 #else
-  for (i=2; i<=n; i++)
+  for (i=2; i<l-1; i+=2)
   {
     u64 v = rand64();
-    y[i] = v & 0xFFFFFFFFUL;
-    i++;
-    if (i > n) break;
-    y[i] = v>>32;
-    i++;
-    if (i > n) { v = rand64(); break; }
+    uel(y,i)   = (ulong) v;
+    uel(y,i+1) = (ulong) (v>>32);
   }
+  if (i<l) uel(y,i) = (ulong) rand64();
 #endif
-  y[n] &= (1UL<<remsBIL(d))-1UL;
+  if (db) uel(y,l-1) &= ((1UL<<db)-1UL);
   return F2x_renormalize(y,l);
 }
 
@@ -262,7 +260,7 @@ static GEN
 polrandom(GEN N) /* assume N!=0 */
 {
   long i, d = lg(N);
-  GEN z = leading_term(N);
+  GEN z = leading_coeff(N);
   GEN y = cgetg(d,t_POL);
   y[1] = evalsigne(1) | evalvarn(varn(N));
   for (i=2; i<d; i++) gel(y,i) = genrand(z);
diff --git a/src/basemath/rootpol.c b/src/basemath/rootpol.c
index c5433a0..e1b80ef 100644
--- a/src/basemath/rootpol.c
+++ b/src/basemath/rootpol.c
@@ -1923,7 +1923,7 @@ all_roots(GEN p, long bit)
   long bit0,  bit2, i, e, h, n = degpol(p);
   pari_sp av;
 
-  pd = RgX_deflate_max(p, &h); lc = leading_term(pd);
+  pd = RgX_deflate_max(p, &h); lc = leading_coeff(pd);
   e = (long)(2 * fujiwara_bound(pd)); if (e < 0) e = 0;
   bit0 = bit + gexpo(pd) - gexpo(lc) + (long)log2(n/h)+1+e;
   bit2 = bit0; e = 0;
@@ -1935,7 +1935,7 @@ all_roots(GEN p, long bit)
     q[1] = evalsigne(1)|evalvarn(0);
     m = split_complete(q,bit2,roots_pol);
     roots_pol = fix_roots(roots_pol, &m, h, bit2);
-    q = mygprec_special(p,bit2); lc = leading_term(q);
+    q = mygprec_special(p,bit2); lc = leading_coeff(q);
     q[1] = evalsigne(1)|evalvarn(0);
     if (h > 1) m = gmul(m,lc);
 
@@ -2185,32 +2185,34 @@ QX_complex_roots(GEN p, long l)
 /********************************************************************/
 
 /* Count sign changes in the coefficients of (x+1)^deg(P)*P(1/(x+1))
- * The inversion is implicit (we take coefficients backwards) */
+ * The inversion is implicit (we take coefficients backwards). Roots of P
+ * at 0 and 1 (mapped to oo and 0) are ignored here and must be dealt with
+ * by the caller */
 static long
-X2XP1(GEN P, long deg, GEN *Premapped)
+X2XP1(GEN P, long deg, int *root1, GEN *Premapped)
 {
-  pari_sp av = avma;
+  const pari_sp av = avma;
   GEN v = shallowcopy(P);
-  long i, j, vlim, nb, s, s2;
-  char flag;
+  long i, j, vlim, nb, s;
 
-  vlim = deg+2;
-  nb = 0;
-  i = 0;
-  do
+  for (i = 0, vlim = deg+2;;)
   {
     for (j = 2; j < vlim; j++) gel(v, j+1) = addii(gel(v, j), gel(v, j+1));
     s = -signe(gel(v, vlim));
-    vlim--;
-    i++;
+    vlim--; i++; if (s) break;
+  }
+  if (vlim == deg+1) *root1 = 0;
+  else
+  {
+    *root1 = 1;
+    if (Premapped) setlg(v, vlim + 2);
   }
-  while (!s);
-  if (vlim != deg + 1 && Premapped) setlg(v, vlim + 2);
 
-  for (; i <= deg - 1; i++)
+  nb = 0;
+  for (; i < deg; i++)
   {
-    s2 = -signe(gel(v, 2));
-    flag = (s2 == s);
+    long s2 = -signe(gel(v, 2));
+    int flag = (s2 == s);
     for (j = 2; j < vlim; j++)
     {
       gel(v, j+1) = addii(gel(v, j), gel(v, j+1));
@@ -2218,25 +2220,22 @@ X2XP1(GEN P, long deg, GEN *Premapped)
     }
     if (s == signe(gel(v, vlim)))
     {
-      nb++;
-      if (nb >= 2) { avma = av; return 2; }
+      if (++nb >= 2) { avma = av; return 2; }
       s = -s;
     }
+    /* if flag is set there will be no further sign changes */
+    if (flag && (!Premapped || !nb)) goto END;
+    vlim--;
     if (gc_needed(av, 3))
     {
       if (!Premapped) setlg(v, vlim);
       v = gerepileupto(av, v);
       if (DEBUGMEM > 1) pari_warn(warnmem, "X2XP1");
     }
-    if (flag && !Premapped) goto END;
-    vlim--;
   }
   if (s == signe(gel(v, vlim))) nb++;
 END:
-  if (Premapped && nb == 1)
-    *Premapped = gerepileupto(av, v);
-  else
-    avma = av;
+  if (Premapped && nb == 1) *Premapped = v; else avma = av;
   return nb;
 }
 
@@ -2253,6 +2252,8 @@ _gen_nored(void *E, GEN x) { (void)E; return x; }
 static GEN
 _mp_add(void *E, GEN x, GEN y) { (void)E; return mpadd(x, y); }
 static GEN
+_mp_sub(void *E, GEN x, GEN y) { (void)E; return mpsub(x, y); }
+static GEN
 _mp_mul(void *E, GEN x, GEN y) { (void)E; return mpmul(x, y); }
 static GEN
 _mp_sqr(void *E, GEN x) { (void)E; return mpsqr(x); }
@@ -2261,44 +2262,46 @@ _gen_one(void *E) { (void)E; return gen_1; }
 static GEN
 _gen_zero(void *E) { (void)E; return gen_0; }
 
-static struct bb_algebra mp_algebra = { _gen_nored,_mp_add,_mp_mul,_mp_sqr,_gen_one,_gen_zero };
+static struct bb_algebra mp_algebra = { _gen_nored, _mp_add, _mp_sub,
+                         _mp_mul, _mp_sqr, _gen_one, _gen_zero };
 
 static GEN
 _mp_cmul(void *E, GEN P, long a, GEN x) {(void)E; return mpmul(gel(P,a+2), x);}
 
-/* Split the polynom P in two parts, each with unique sign.
- * Moreover compute the two parts of the derivative of P. */
+/* Split the polynom P in two parts, whose coeffs have constant sign:
+ * P(X) = X^D*Pp + Pm. Also compute the two parts of the derivative of P,
+ * Pprimem = Pm', Pprimep = X*Pp'+ D*Pp => P' = X^(D-1)*Pprimep + Pprimem;
+ * Pprimep[i] = (i+D) Pp[i]. Return D */
 static long
-split_polynoms(GEN P, long deg, long s0, GEN *Pp, GEN *Pm, GEN *Pprimep, GEN *Pprimem)
-{
-  long i, degneg, v = evalvarn(varn(P));
-  for(i=1; i <= deg; i++) if (signe(gel(P, i+2)) != s0) break;
-  degneg = i;
-  *Pm = cgetg(degneg + 2, t_POL);
-  (*Pm)[1] = v;
-  *Pprimem = cgetg(degneg + 1, t_POL);
-  (*Pprimem)[1] = v;
-  for(i=0; i < degneg; i++)
-  {
-    GEN elt = gel(P, i+2);
-    gel(*Pm, i+2) = elt;
-    if (i) gel(*Pprimem, i+1) = mului(i, elt);
-  }
-  *Pp = cgetg(deg - degneg + 3, t_POL);
-  (*Pp)[1] = v;
-  *Pprimep = cgetg(deg - degneg + 3, t_POL);
-  (*Pprimep)[1] = v;
-  for(i=degneg; i <= deg; i++)
-  {
-    GEN elt = gel(P, i+2);
-    gel(*Pp, i+2-degneg) = elt;
-    gel(*Pprimep, i+2-degneg) = mului(i, elt);
-  }
-  *Pm = normalizepol_lg(*Pm, degneg+2);
-  *Pprimem = normalizepol_lg(*Pprimem, degneg+1);
-  *Pp = normalizepol_lg(*Pp, deg-degneg+3);
-  *Pprimep = normalizepol_lg(*Pprimep, deg-degneg+3);
-  return degpol(*Pm) + 1;
+split_pols(GEN P, GEN *pPp, GEN *pPm, GEN *pPprimep, GEN *pPprimem)
+{
+  long i, D, dP = degpol(P), s0 = signe(gel(P,2));
+  GEN Pp, Pm, Pprimep, Pprimem;
+  for(i=1; i <= dP; i++)
+    if (signe(gel(P, i+2)) == -s0) break;
+  D = i;
+  Pm = cgetg(D + 2, t_POL);
+  Pprimem = cgetg(D + 1, t_POL);
+  Pp = cgetg(dP-D + 3, t_POL);
+  Pprimep = cgetg(dP-D + 3, t_POL);
+  Pm[1] = Pp[1] = Pprimem[1] = Pprimep[1] = P[1];
+  for(i=0; i < D; i++)
+  {
+    GEN c = gel(P, i+2);
+    gel(Pm, i+2) = c;
+    if (i) gel(Pprimem, i+1) = mului(i, c);
+  }
+  for(; i <= dP; i++)
+  {
+    GEN c = gel(P, i+2);
+    gel(Pp, i+2-D) = c;
+    gel(Pprimep, i+2-D) = mului(i, c);
+  }
+  *pPm = normalizepol_lg(Pm, D+2);
+  *pPprimem = normalizepol_lg(Pprimem, D+1);
+  *pPp = normalizepol_lg(Pp, dP-D+3);
+  *pPprimep = normalizepol_lg(Pprimep, dP-D+3);
+  return dP - degpol(*pPp);
 }
 
 static GEN
@@ -2310,21 +2313,33 @@ bkeval_single_power(long d, GEN V)
 }
 
 static GEN
-splitpoleval(GEN Pp, GEN Pm, GEN pows, long deg, long degneg, long bitprec)
+splitpoleval(GEN Pp, GEN Pm, GEN pows, long D, long bitprec)
 {
-  GEN vp = gen_bkeval_powers(Pp, deg-degneg, pows, NULL, &mp_algebra, _mp_cmul);
-  GEN vm = gen_bkeval_powers(Pm, degneg-1, pows, NULL, &mp_algebra, _mp_cmul);
-  GEN xa = bkeval_single_power(degneg, pows);
+  GEN vp = gen_bkeval_powers(Pp, degpol(Pp), pows, NULL, &mp_algebra, _mp_cmul);
+  GEN vm = gen_bkeval_powers(Pm, degpol(Pm), pows, NULL, &mp_algebra, _mp_cmul);
+  GEN xa = bkeval_single_power(D, pows);
   GEN r;
+  if (!signe(vp)) return vm;
   vp = gmul(vp, xa);
   r = gadd(vp, vm);
-  if (expo(vp) - (signe(r) ? expo(r) : 0) > prec2nbits(realprec(vp)) - bitprec)
+  if (gexpo(vp) - (signe(r)? gexpo(r): 0) > prec2nbits(realprec(vp)) - bitprec)
     return NULL;
   return r;
 }
 
-/* Newton for polynom P. One solution between 0 and infinity, P' has also at
- * most one zero. P is almost certainly without zero coefficients. */
+/* optimized Cauchy bound for P = X^D*Pp + Pm, D > deg(Pm) */
+static GEN
+splitcauchy(GEN Pp, GEN Pm, long prec)
+{
+  GEN S = gel(Pp,2), A = gel(Pm,2);
+  long i, lPm = lg(Pm), lPp = lg(Pp);
+  for (i=3; i < lPm; i++) { GEN c = gel(Pm,i); if (absi_cmp(A, c) < 0) A = c; }
+  for (i=3; i < lPp; i++) S = addii(S, gel(Pp, i));
+  return subsr(1, rdivii(A, S, prec)); /* 1 + |Pm|_oo / |Pp|_1 */
+}
+
+/* Newton for polynom P, P(0)!=0, with unique sign change => one root in ]0,oo[
+ * P' has also at most one zero there */
 static GEN
 polsolve(GEN P, long bitprec)
 {
@@ -2332,47 +2347,30 @@ polsolve(GEN P, long bitprec)
   GEN Pp, Pm, Pprimep, Pprimem, pows;
   GEN Pprime, Pprime2;
   GEN ra, rb, rc, rcold = NULL, Pc, Ppc;
-  long deg = degpol(P), degneg, rt;
+  long deg = degpol(P), D, rt;
   long s0, cprec = DEFAULTPREC, prec = nbits2prec(bitprec);
   long bitaddprec, addprec;
   long expoold = LONG_MAX, iter;
   if (deg == 1)
-  {
-    ra = negr(divrr(itor(gel(P, 2), bitprec), itor(gel(P, 3), bitprec)));
-    return gerepileuptoleaf(av, ra);
-  }
-  Pprime = ZX_deriv(P); Pprime2 = ZX_deriv(Pprime);
+    return gerepileuptoleaf(av, rdivii(negi(gel(P,2)), gel(P,3), prec));
+  Pprime = ZX_deriv(P);
+  Pprime2 = ZX_deriv(Pprime);
   bitaddprec = 1 + 2*expu(deg); addprec = nbits2prec(bitaddprec);
+  D = split_pols(P, &Pp, &Pm, &Pprimep, &Pprimem); /* P = X^D*Pp + Pm */
   s0 = signe(gel(P, 2));
-  degneg = split_polynoms(P, deg, s0, &Pp, &Pm, &Pprimep, &Pprimem);
-  rt = maxss(degneg, brent_kung_optpow(maxss(deg-degneg, degneg-1), 2, 1));
+  rt = maxss(D, brent_kung_optpow(maxss(degpol(Pp), degpol(Pm)), 2, 1));
+  rb = splitcauchy(Pp, Pm, DEFAULTPREC);
+  for(;;)
   {
-    /* Optimized Cauchy bound */
-    GEN summin = gen_0, absmaj;
-    long i;
-
-    absmaj = gel(P, 2);
-    for(i=1; i < degneg; i++)
-    {
-      GEN elt = gel(P, i+2);
-      if (absi_cmp(absmaj, elt) < 0) absmaj = elt;
-    }
-    summin = gel(P, i+2);
-    while (++i <= deg) summin = addii(summin, gel(P, i+2));
-    rb = subsr(1, rdivii(absmaj, summin, cprec));
-    do
-    {
-      pows = gen_powers(rb, rt, 1, NULL, _mp_sqr, _mp_mul, _gen_one);
-      Pc = splitpoleval(Pp, Pm, pows, deg, degneg, bitaddprec);
-      if (!Pc) { cprec++; rb = rtor(rb, cprec); continue; }
-      if (signe(Pc) != s0) break;
-      shiftr_inplace(rb,1);
-    }
-    while (1);
+    pows = gen_powers(rb, rt, 1, NULL, _mp_sqr, _mp_mul, _gen_one);
+    Pc = splitpoleval(Pp, Pm, pows, D, bitaddprec);
+    if (!Pc) { cprec++; rb = rtor(rb, cprec); continue; }
+    if (signe(Pc) != s0) break;
+    shiftr_inplace(rb,1);
   }
   ra = NULL;
   iter = 0;
-  while (1)
+  for(;;)
   {
     GEN wdth;
     iter++;
@@ -2383,7 +2381,7 @@ polsolve(GEN P, long bitprec)
     do
     {
       pows = gen_powers(rc, rt, 1, NULL, _mp_sqr, _mp_mul, _gen_one);
-      Pc = splitpoleval(Pp, Pm, pows, deg, degneg, bitaddprec+2);
+      Pc = splitpoleval(Pp, Pm, pows, D, bitaddprec+2);
       if (Pc) break;
       cprec++; rc = rtor(rc, cprec);
     } while (1);
@@ -2406,16 +2404,16 @@ polsolve(GEN P, long bitprec)
   }
   rc = rb;
   iter = 0;
-  while (1)
+  for(;;)
   {
     long exponew;
     GEN dist;
     iter++;
     rcold = rc;
     pows = gen_powers(rc, rt, 1, NULL, _mp_sqr, _mp_mul, _gen_one);
-    Ppc = splitpoleval(Pprimep, Pprimem, pows, deg-1, degneg-1, bitaddprec+4);
+    Ppc = splitpoleval(Pprimep, Pprimem, pows, D-1, bitaddprec+4);
     if (Ppc)
-      Pc = splitpoleval(Pp, Pm, pows, deg, degneg, bitaddprec+4);
+      Pc = splitpoleval(Pp, Pm, pows, D, bitaddprec+4);
     if (!Ppc || !Pc)
     {
       if (cprec >= prec+addprec)
@@ -2425,7 +2423,7 @@ polsolve(GEN P, long bitprec)
       rc = rtor(rc, cprec); /* Backtrack one step */
       continue;
     }
-    dist = divrr(Pc, Ppc);
+    dist = typ(Ppc) == t_REAL? divrr(Pc, Ppc): divri(Pc, Ppc);
     rc = subrr(rc, dist);
     if (cmprr(ra, rc) > 0 || cmprr(rb, rc) < 0)
     {
@@ -2440,16 +2438,14 @@ polsolve(GEN P, long bitprec)
     {
       if (cprec >= prec+addprec) break;
       cprec = minss(2*cprec, prec+addprec);
-      rc = rtor(rc, cprec);
-      continue;
+      rc = rtor(rc, cprec); continue;
     }
     if (exponew > expoold - 2)
     {
       if (cprec >= prec+addprec) break;
       cprec = minss(2*cprec, prec+addprec);
       rc = rtor(rc, cprec);
-      expoold = LONG_MAX;
-      continue;
+      expoold = LONG_MAX; continue;
     }
     expoold = exponew;
   }
@@ -2457,15 +2453,12 @@ polsolve(GEN P, long bitprec)
 }
 
 static GEN
-usp(GEN Q0, long deg, long *nb_donep, long flag, long bitprec)
+usp(GEN Q0, long deg, long flag, long bitprec)
 {
-  pari_sp av;
-  GEN Q, sol;
-  long nb_todo, nbr = 0, ind, deg0, indf, i, k, nb, j;
-  long listsize = 64, nb_done = 0;
-  GEN c, Lc, Lk;
+  const pari_sp av = avma;
+  GEN Q, sol, c, Lc, Lk;
+  long listsize = 64, nbr = 0, nb_todo, ind, deg0, indf, i, k, nb;
 
-  av = avma;
 
   sol = const_col(deg, gen_0);
   deg0 = deg;
@@ -2474,12 +2467,14 @@ usp(GEN Q0, long deg, long *nb_donep, long flag, long bitprec)
   c = gen_0;
   k = Lk[1] = 0;
   ind = 1; indf = 2;
-  Q = gcopy(Q0);
+  Q = leafcopy(Q0);
 
   nb_todo = 1;
   while (nb_todo)
   {
     GEN nc = gel(Lc, ind), Qremapped;
+    pari_sp av2;
+    int root1;
     if (Lk[ind] == k + 1)
     {
       deg0 = deg;
@@ -2497,74 +2492,72 @@ usp(GEN Q0, long deg, long *nb_donep, long flag, long bitprec)
     nb_todo--;
 
     if (equalii(gel(Q, 2), gen_0))
-    {
-      GEN newsol = gmul2n(c, -k);
+    { /* Q(0) = 0 */
+      GEN s = gmul2n(c, -k);
+      long j;
       for (j = 1; j <= nbr; j++)
-        if (gequal(gel(sol, j), newsol)) break;
-      if (j > nbr) gel(sol, ++nbr) = newsol;
+        if (gequal(gel(sol, j), s)) break;
+      if (j > nbr) gel(sol, ++nbr) = s;
 
       deg0--;
       for (j = 2; j <= deg0 + 2; j++) gel(Q, j) = gel(Q, j+1);
       setlg(Q, j);
     }
 
-    nb = X2XP1(Q, deg0, flag == 1 ? &Qremapped : NULL);
-    nb_done++;
+    av2 = avma;
+    nb = X2XP1(Q, deg0, &root1, flag == 1 ? &Qremapped : NULL);
 
-    switch (nb)
+    if      (nb == 0) /* no root in this open interval */;
+    else if (nb == 1) /* exactly one root */
     {
-      case 0:
-        break;
-      case 1:
-        switch(flag)
+      GEN s = gen_0;
+      if (flag == 0)
+        s = mkvec2(gmul2n(c,-k), gmul2n(addiu(c,1),-k));
+      else if (flag == 1) /* Caveat: Qremapped is the reciprocal polynomial */
+      {
+        s = polsolve(Qremapped, bitprec+1);
+        s = divrr(s, addsr(1, s));
+        s = gmul2n(addir(c, s), -k);
+        s = rtor(s, nbits2prec(bitprec));
+      }
+      gel(sol, ++nbr) = gerepileupto(av2, s);
+    }
+    else
+    { /* unknown, add two nodes to refine */
+      if (indf + 2 > listsize)
+      {
+        if (ind>1)
         {
-        case 0:
+          for (i = ind; i < indf; i++)
           {
-            GEN low, hi;
-            low = gmul2n(c, -k);
-            hi  = gmul2n(addiu(c,1), -k);
-            gel(sol, ++nbr) = mkvec2(low, hi);
+            gel(Lc, i-ind+1) = gel(Lc, i);
+            Lk[i-ind+1] = Lk[i];
           }
-          break;
-        case 1:
-          { /* Caveat emptor: Qremapped is the reciprocal polynomial */
-            GEN sr = polsolve(Qremapped, bitprec+1);
-            sr = divrr(sr, addsr(1, sr));
-            sr = gmul2n(addir(c, sr), -k);
-            gel(sol, ++nbr) = rtor(sr, nbits2prec(bitprec));
-          }
-          break;
-        default:
-          gel(sol, ++nbr) = gen_0;
+          indf -= ind-1;
+          ind = 1;
         }
-      break;
-
-      default:
         if (indf + 2 > listsize)
         {
-          if (ind>1)
-          {
-            for (i = ind; i < indf; i++)
-            {
-              gel(Lc, i-ind+1) = gel(Lc, i);
-              Lk[i-ind+1] = Lk[i];
-            }
-          indf -= ind-1; ind = 1;
-          }
-          if (indf + 2 > listsize)
-          {
-            listsize *= 2;
-            Lc = vec_lengthen(Lc, listsize);
-            Lk = vecsmall_lengthen(Lk, listsize);
-          }
-          for (i = indf; i <= listsize; i++) gel(Lc, i) = gen_0;
+          listsize *= 2;
+          Lc = vec_lengthen(Lc, listsize);
+          Lk = vecsmall_lengthen(Lk, listsize);
         }
-        nc = shifti(c, 1);
-        gel(Lc, indf) = nc;
-        gel(Lc, indf + 1) = addis(nc, 1);
-        Lk[indf] = Lk[indf + 1] = k + 1;
-        indf += 2;
-        nb_todo += 2;
+        for (i = indf; i <= listsize; i++) gel(Lc, i) = gen_0;
+      }
+      nc = shifti(c, 1);
+      gel(Lc, indf) = nc;
+      gel(Lc, indf + 1) = addiu(nc, 1);
+      Lk[indf] = Lk[indf + 1] = k + 1;
+      indf += 2;
+      nb_todo += 2;
+    }
+    if (root1)
+    { /* Q(1) = 0 */
+      GEN s = gmul2n(addiu(c,1), -k);
+      long j;
+      for (j = 1; j <= nbr; j++)
+        if (gequal(gel(sol, j), s)) break;
+      if (j > nbr) gel(sol, ++nbr) = s;
     }
 
     if (gc_needed(av, 2))
@@ -2575,7 +2568,6 @@ usp(GEN Q0, long deg, long *nb_donep, long flag, long bitprec)
   }
 
   setlg(sol, nbr+1);
-  *nb_donep += nb_done;
   return gerepilecopy(av, sol);
 }
 
@@ -2590,13 +2582,23 @@ ZX_Uspensky_cst_pol(long nbz, long flag, long bitprec)
   }
 }
 
+/* ZX_Uspensky(P, [a,a], flag) */
+static GEN
+ZX_Uspensky_equal(GEN P, GEN a, long flag)
+{
+  if (typ(a) != t_INFINITY && gequal0(poleval(P, a)))
+    return flag <= 1 ? mkcol(a): gen_1;
+  else
+    return flag <= 1 ? cgetg(1, t_COL) : gen_0;
+}
+
 GEN
 ZX_Uspensky(GEN P, GEN ab, long flag, long bitprec)
 {
   pari_sp av = avma;
   GEN a, b, sol = NULL, Pcur;
   double fb;
-  long nbz, deg, nb_done = 0;
+  long nbz, deg;
 
   deg = degpol(P);
   if (deg == 0) return flag <= 1 ? cgetg(1, t_COL) : gen_0;
@@ -2622,11 +2624,7 @@ ZX_Uspensky(GEN P, GEN ab, long flag, long bitprec)
   switch (gcmp(a, b))
   {
     case 1: avma = av; return flag <= 1 ? cgetg(1, t_COL) : gen_0;
-    case 0:
-      if (typ(a) != t_INFINITY && gequal0(poleval(P, a)))
-      { avma = av; return flag <= 1 ? mkcolcopy(a): gen_1; }
-      else
-      { avma = av; return flag <= 1 ? cgetg(1, t_COL) : gen_0; }
+    case 0: return gerepilecopy(av, ZX_Uspensky_equal(P, a, flag));
   }
   nbz = ZX_valrem(P, &Pcur);
   deg -= nbz;
@@ -2660,26 +2658,22 @@ ZX_Uspensky(GEN P, GEN ab, long flag, long bitprec)
   if (typ(a) == t_INFINITY && typ(b) != t_INFINITY && gsigne(b))
   {
     fb = fujiwara_bound_real(Pcur, -1);
-    if (fb > -pariINFINITY)
-      a = negi(int2n((long)ceil(fb)));
-    else
-      a = gen_0;
+    if (fb > -pariINFINITY) a = negi(int2n((long)ceil(fb))); else a = gen_0;
   }
   if (typ(b) == t_INFINITY && typ(a) != t_INFINITY && gsigne(a))
   {
     fb = fujiwara_bound_real(Pcur, 1);
-    if (fb > -pariINFINITY)
-      b = int2n((long)ceil(fb));
-    else
-      b = gen_0;
+    if (fb > -pariINFINITY) b = int2n((long)ceil(fb)); else b = gen_0;
   }
 
   if (typ(a) != t_INFINITY && typ(b) != t_INFINITY)
   {
+    GEN den, diff, unscaledres, co, Pdiv, ascaled;
     pari_sp av1;
-    GEN den = lcmii(denom(a), denom(b)), diff, unscaledres, co, Pdiv;
-    GEN ascaled;
     long i;
+    if (gequal(a,b)) /* can occur if one of a,b was initially a t_INFINITY */
+      return gerepilecopy(av, ZX_Uspensky_equal(P, a, flag));
+    den = lcmii(Q_denom(a), Q_denom(b));
     if (!is_pm1(den))
     {
       Pcur = ZX_rescale(Pcur, den);
@@ -2712,7 +2706,7 @@ ZX_Uspensky(GEN P, GEN ab, long flag, long bitprec)
     }
     else
       avma = av1;
-    unscaledres = usp(Pcur, deg, &nb_done, flag, bitprec);
+    unscaledres = usp(Pcur, deg, flag, bitprec);
     if (flag <= 1)
     {
       for (i = 1; i < lg(unscaledres); i++)
@@ -2739,20 +2733,19 @@ ZX_Uspensky(GEN P, GEN ab, long flag, long bitprec)
     long bp = (long)ceil(fb);
     if (bp < 0) bp = 0;
     Pcurp = ZX_unscale2n(Pcur, bp);
-    unscaledres = usp(Pcurp, deg, &nb_done, flag, bitprec);
+    unscaledres = usp(Pcurp, deg, flag, bitprec);
     if (flag <= 1)
-      sol = gconcat(sol, gmul2n(unscaledres, bp));
+      sol = shallowconcat(sol, gmul2n(unscaledres, bp));
     else
-      nbz += lg(unscaledres) - 1;
+      nbz += lg(unscaledres)-1;
   }
   if (typ(a) == t_INFINITY && (fb=fujiwara_bound_real(Pcur,-1)) > -pariINFINITY)
   {
     GEN Pcurm, unscaledres;
     long i, bm = (long)ceil(fb);
     if (bm < 0) bm = 0;
-    Pcurm = ZX_unscale(Pcur, gen_m1);
-    Pcurm = ZX_unscale2n(Pcurm, bm);
-    unscaledres = usp(Pcurm,deg,&nb_done,flag,bitprec);
+    Pcurm = ZX_unscale2n(ZX_unscale(Pcur, gen_m1), bm);
+    unscaledres = usp(Pcurm, deg, flag, bitprec);
     if (flag <= 1)
     {
       for (i = 1; i < lg(unscaledres); i++)
@@ -2761,15 +2754,11 @@ ZX_Uspensky(GEN P, GEN ab, long flag, long bitprec)
         if (typ(z) == t_VEC) swap(gel(z, 1), gel(z, 2));
         gel(unscaledres, i) = z;
       }
-      sol = gconcat(unscaledres, sol);
+      sol = shallowconcat(unscaledres, sol);
     }
     else
-      nbz += lg(unscaledres) - 1;
+      nbz += lg(unscaledres)-1;
   }
-
-  if (DEBUGLEVEL > 4)
-    err_printf("ZX_Uspensky: Number of visited nodes: %d\n", nb_done);
-
   if (flag >= 2) return utoi(nbz);
   if (flag)
     sol = sort(sol);
@@ -2813,7 +2802,7 @@ realroots(GEN P, GEN ab, long prec)
   pari_sp av = avma;
   long nrr = 0;
   GEN sol = NULL, fa, ex;
-  long i, j, k;
+  long i, j, v;
 
   ab = check_ab(ab);
   if (typ(P) != t_POL) return rootsdeg0(P);
@@ -2824,36 +2813,32 @@ realroots(GEN P, GEN ab, long prec)
   }
   P = Q_primpart(P);
   if (!RgX_is_ZX(P)) pari_err_TYPE("realroots",P);
+  v = ZX_valrem(P,&P);
+  if (v && (!ab || (gsigne(gel(ab,1)) <= 0 && gsigne(gel(ab,2)) >= 0)))
+    sol = const_col(v, real_0(prec));
   fa = ZX_squff(P, &ex);
   for (i = 1; i < lg(fa); i++)
   {
     GEN Pi = gel(fa, i), soli, soli2 = NULL;
-    long n, nrri = 0, h, nbz;
+    long n, nrri = 0, h;
     if (ab)
       h = 1;
     else
       Pi = RgX_deflate_max(Pi, &h);
-    if (!signe(gel(Pi, 2)))
-    {
-      Pi = RgX_shift_shallow(Pi, -1);
-      nbz = 1;
-    }
-    else
-      nbz = 0;
     soli = ZX_Uspensky(Pi, h%2 ? ab: gen_0, 1, prec2nbits(prec));
     n = lg(soli);
     if (!(h % 2)) soli2 = cgetg(n, t_COL);
     for (j = 1; j < n; j++)
     {
-      GEN elt = gel(soli, j);
+      GEN elt = gel(soli, j); /* != 0 */
       if (typ(elt) != t_REAL)
       {
-        nrri++;
+        nrri++; if (h > 1 && !(h % 2)) nrri++;
         elt = gtofp(elt, prec);
         gel(soli, j) = elt;
       }
       if (h > 1)
-      { /* note: elt != 0 because we are square free */
+      {
         GEN r;
         if (h == 2)
           r = sqrtr(elt);
@@ -2869,18 +2854,17 @@ realroots(GEN P, GEN ab, long prec)
       }
     }
     if (!(h % 2)) soli = shallowconcat(soli, soli2);
-    if (nbz) soli = shallowconcat(soli, real_0(prec));
-    for (k = 1; k <= ex[i]; k++)
-      sol = sol ? shallowconcat(sol, soli) : soli;
+    if (ex[i] > 1) soli = shallowconcat1( const_vec(ex[i], soli) );
+    sol = sol? shallowconcat(sol, soli): soli;
     nrr += ex[i]*nrri;
   }
+  if (!sol) { avma = av; return cgetg(1,t_COL); }
 
   if (DEBUGLEVEL > 4)
   {
     err_printf("Number of real roots: %d\n", lg(sol)-1);
     err_printf(" -- of which 2-integral: %ld\n", nrr);
   }
-
   return gerepileupto(av, sort(sol));
 }
 
diff --git a/src/basemath/subcyclo.c b/src/basemath/subcyclo.c
index 7169d6c..6b43314 100644
--- a/src/basemath/subcyclo.c
+++ b/src/basemath/subcyclo.c
@@ -520,7 +520,7 @@ galoiscyclo(long n, long v)
   gel(grp,1) = polcyclo(n,v);
   gel(grp,2) = mkvec3(stoi(l), stoi(val), icopy(le));
   gel(grp,3) = gcopy(L);
-  gel(grp,4) = vandermondeinversemod(L, gel(grp,1), gen_1, le);
+  gel(grp,4) = FpV_invVandermonde(L,  NULL, le);
   gel(grp,5) = gen_1;
   gel(grp,6) = gcopy(elts);
   gel(grp,7) = gcopy(gel(G,1));
diff --git a/src/basemath/trans1.c b/src/basemath/trans1.c
index ef979f1..9c1d523 100644
--- a/src/basemath/trans1.c
+++ b/src/basemath/trans1.c
@@ -158,9 +158,9 @@ pi_ramanujan(long prec)
 
   nmax = (long)(1 + prec2nbits(prec)/alpha2);
 #ifdef LONG_IS_64BIT
-  D = utoipos(10939058860032000); /* C^3/24 */
+  D = utoipos(10939058860032000UL); /* C^3/24 */
 #else
-  D = uutoi(2546948,495419392);
+  D = uutoi(2546948UL,495419392UL);
 #endif
   abpq_init(&S, nmax);
   S.a[0] = utoipos(A);
@@ -1237,30 +1237,36 @@ grootsof1(long N, long prec)
 /**                        RACINE CARREE                           **/
 /**                                                                **/
 /********************************************************************/
-/* assume x unit, precp(x) = pp > 3 */
-static GEN
-sqrt_2adic(GEN x, long pp)
+/* assume x unit, e = precp(x) */
+GEN
+Z2_sqrt(GEN x, long e)
 {
-  GEN z = mod16(x)==(signe(x)>=0?1:15)?gen_1: utoipos(3);
-  long zp;
+  ulong r = signe(x)>=0?mod16(x):16-mod16(x);
+  GEN z;
+  long ez;
   pari_sp av;
 
-  if (pp == 4) return z;
-  zp = 3; /* number of correct bits in z (compared to sqrt(x)) */
-
-  av = avma;
+  switch(e)
+  {
+    case 1: return gen_1;
+    case 2: return (r & 3UL) == 1? gen_1: NULL;
+    case 3: return (r & 7UL) == 1? gen_1: NULL;
+    case 4: if (r == 1) return gen_1;
+            else return (r == 9)? utoipos(3): NULL;
+    default: if ((r&7UL) != 1) return NULL;
+  }
+  av = avma; z = (r==1)? gen_1: utoipos(3);
+  ez = 3; /* number of correct bits in z (compared to sqrt(x)) */
   for(;;)
   {
     GEN mod;
-    zp = (zp<<1) - 1;
-    if (zp > pp) zp = pp;
-    mod = int2n(zp);
-    z = addii(z, remi2n(mulii(x, Fp_inv(z,mod)), zp));
+    ez = (ez<<1) - 1;
+    if (ez > e) ez = e;
+    mod = int2n(ez);
+    z = addii(z, remi2n(mulii(x, Fp_inv(z,mod)), ez));
     z = shifti(z, -1); /* (z + x/z) / 2 */
-    if (pp == zp) return z;
-
-    if (zp < pp) zp--;
-
+    if (e == ez) return gerepileuptoint(av, z);
+    if (ez < e) ez--;
     if (gc_needed(av,2))
     {
       if (DEBUGMEM > 1) pari_warn(warnmem,"Qp_sqrt");
@@ -1270,34 +1276,6 @@ sqrt_2adic(GEN x, long pp)
 }
 
 /* x unit defined modulo p^e, e > 0 */
-static GEN
-Up_sqrt(GEN x, GEN p, long e)
-{
-  pari_sp av = avma;
-  if (equaliu(p,2))
-  {
-    long r = signe(x)>=0?mod8(x):8-mod8(x);
-    if (e <= 3)
-    {
-      switch(e) {
-      case 1: break;
-      case 2: if ((r&3) == 1) break;
-              return NULL;
-      case 3: if (r == 1) break;
-              return NULL;
-      }
-      return gen_1;
-    }
-    else
-    {
-      if (r != 1) return NULL;
-      return gerepileuptoint(av, sqrt_2adic(x, e));
-    }
-  }
-  else
-    return Zp_sqrt(x, p, e);
-}
-
 GEN
 Qp_sqrt(GEN x)
 {
@@ -1312,7 +1290,7 @@ Qp_sqrt(GEN x)
   mod = gel(x,3);
   z   = gel(x,4); /* lift to t_INT */
   e >>= 1;
-  z = Up_sqrt(z, p, pp);
+  z = Zp_sqrt(z, p, pp);
   if (!z) return NULL;
   if (equaliu(p,2))
   {
@@ -1349,7 +1327,7 @@ Zn_sqrt(GEN d, GEN fn)
     else
     {
       if (odd(v)) return NULL;
-      bp = Up_sqrt(r, p, e-v);
+      bp = Zp_sqrt(r, p, e-v);
       if (!bp)    return NULL;
       if (v) bp = mulii(bp, powiu(p, v>>1L));
     }
@@ -1413,6 +1391,9 @@ gsqrt(GEN x, long prec)
 
   switch(typ(x))
   {
+    case t_INT:
+      if (!signe(x)) return real_0(prec); /* no loss of accuracy */
+      x = itor(x,prec); /* fall through */
     case t_REAL: return sqrtr(x);
 
     case t_INTMOD:
diff --git a/src/basemath/trans2.c b/src/basemath/trans2.c
index ee58ca7..b988ef8 100644
--- a/src/basemath/trans2.c
+++ b/src/basemath/trans2.c
@@ -825,14 +825,14 @@ mpbern(long nb, long prec)
     /* Not cached, must compute */
     /* huge accuracy ? May as well compute exactly */
     if (n_is_small && (prec == LONG_MAX ||
-                       2*n * log(2*n) < prec2nbits_mul(prec, LOG2)))
+                       2*n * log((double)2*n) < prec2nbits_mul(prec, LOG2)))
       S = bernfrac_using_zeta(2*n);
     else
     {
 #ifdef LONG_IS_64BIT
-      const ulong mul_overflow = 3037000500;
+      const ulong mul_overflow = 3037000500UL;
 #else
-      const ulong mul_overflow = 46341;
+      const ulong mul_overflow = 46341UL;
 #endif
       ulong u = 8, v = 5, a = n-1, b = 2*n-3;
       n_is_small = 0;
@@ -1484,6 +1484,22 @@ Qp_gamma(GEN x)
   return Qp_gamma_Dwork(x, itos(p));
 }
 
+/* gamma(1+x) - 1, |x| < 1 is "small" */
+GEN
+ggamma1m1(GEN x, long prec) { return gexpm1(lngamma1(x, prec), prec); }
+
+/* lngamma(y) with 0 constant term, using (lngamma y)' = y' psi(y) */
+static GEN
+serlngamma0(GEN y, long prec)
+{
+  GEN t;
+  if (valp(y)) pari_err_DOMAIN("lngamma","valuation", "!=", gen_0, y);
+  t = derivser(y);
+  /* don't compute psi if y'=0 */
+  if (signe(t)) t = gmul(t, gpsi(y,prec));
+  return integser(t);
+}
+
 GEN
 ggamma(GEN x, long prec)
 {
@@ -1533,29 +1549,27 @@ ggamma(GEN x, long prec)
     case t_PADIC: return Qp_gamma(x);
     default:
       av = avma; if (!(y = toser_i(x))) break;
+      if (lg(y) == 2) pari_err_DOMAIN("gamma", "argument", "=", gen_0,y);
       /* exp(lngamma) */
-      if (valp(y)>0 || lg(y) == 2)
+      if (valp(y) > 0 || lg(y) == 2)
         z = gdiv(gexp(glngamma(gaddgs(y,1),prec),prec),y);
       else
-      { /* use fun eq. to avoid log singularity of lngamma at negative ints */
-        GEN Y = y, y0 = gel(y,2), t = ground(y0), pi = NULL;
-        if (gequal(y0, t) && typ(t) == t_INT && signe(t) < 0)
-        {
-          pi = mppi(prec);
-          Y = gsubsg(1, y);
-          y0= subsi(1, y0);
+      {
+        GEN Y = y, y0 = simplify_shallow(gel(y,2));
+        z = NULL;
+        if (isint(y0, &y0))
+        { /* fun eq. avoids log singularity of lngamma at negative ints */
+          if (signe(y0) < 0) { Y = gsubsg(1, y); y0 = subsi(1, y0); }
+          if (cmpiu(y0, 50) < 0) z = mpfact(itos(y0)-1); /* more precise */
         }
-        z = glngamma(Y,prec);
-        if (!valp(z))
+        if (!z) z = ggamma(y0,prec);
+        z = gmul(z, gexp(serlngamma0(Y,prec),prec));
+        if (Y != y)
         {
-          z = serchop0(z);
-          z = gmul(ggamma(y0,prec), gexp(z,prec));
-        }
-        else
-          z = gexp(z,prec);
-        if (pi)
-          z = gdiv(mpodd(t)? negr(pi): pi,
+          GEN pi = mppi(prec);
+          z = gdiv(mpodd(y0)? pi: negr(pi),
                    gmul(z, gsin(gmul(pi,serchop0(y)), prec)));
+        }
       }
       return gerepileupto(av, z);
   }
@@ -1579,7 +1593,7 @@ GEN
 glngamma(GEN x, long prec)
 {
   pari_sp av = avma;
-  GEN y, p1;
+  GEN y, y0, t;
 
   switch(typ(x))
   {
@@ -1613,11 +1627,13 @@ glngamma(GEN x, long prec)
 
     default:
       if (!(y = toser_i(x))) break;
-      if (valp(y)) pari_err_DOMAIN("lngamma","valuation", "!=", gen_0, x);
-      /* (lngamma y)' = y' psi(y) */
-      p1 = integser(gmul(derivser(y), gpsi(y, prec)));
-      if (!gequal1(gel(y,2))) p1 = gadd(p1, glngamma(gel(y,2),prec));
-      return gerepileupto(av, p1);
+      if (lg(y) == 2) pari_err_DOMAIN("lngamma", "argument", "=", gen_0,y);
+      t = serlngamma0(y,prec);
+      y0 = simplify_shallow(gel(y,2));
+      /* no constant term if y0 = 1 or 2 */
+      if (!isint(y0,&y0) || signe(y0) <= 0 || cmpiu(y0,2) > 2)
+        t = gadd(t, glngamma(y0,prec));
+      return gerepileupto(av, t);
 
     case t_PADIC: return gerepileupto(av, Qp_log(Qp_gamma(x)));
   }
@@ -1716,7 +1732,7 @@ cxpsi(GEN s0, long prec)
   avma = av; return affc_fixlg(z, res);
 }
 
-/* psi(1+x) + O(x^n), x = pol_x(v) */
+/* n > 0; return psi(1+x) + O(x^n), x = pol_x(v) */
 static GEN
 serpsi1(long n, long v, long prec)
 {
@@ -1741,16 +1757,14 @@ tr(GEN T, GEN z0, long L)
   GEN s = RgX_to_ser(RgX_translate(T, z0), L+3);
   setvarn(s, 0); return s;
 }
-/* psi(z0+x) + O(x^n) */
+/* z0 a complex number with Re(z0) > 1/2; return psi(z0+x) + O(x^L)
+ * using Luke's rational approximation for psi(x) */
 static GEN
 serpsiz0(GEN z0, long L, long v, long prec)
 {
   pari_sp av;
   GEN A,A1,A2, B,B1,B2, Q;
   long n;
-
-  if (equali1(z0)) return serpsi1(L, v, prec);
-  /* otherwise use Luke's rational approximations for psi(x) */
   n = gprecision(z0); if (n) prec = n;
   z0 = gtofp(z0, prec + EXTRAPRECWORD);
   /* Start from n = 3; in Luke's notation, A2 := A_{n-2}, A1 := A_{n-1},
@@ -1803,12 +1817,42 @@ serpsiz0(GEN z0, long L, long v, long prec)
   setvarn(Q, v);
   return gadd(negr(mpeuler(prec)), Q);
 }
+/* sum (-1)^k*H(m,k)x^k + O(x^L); L > 0;
+ * H(m,k) = (-1)^{k * \delta_{m > 0}} sum_{1<=i<m} 1/i^(k+1) */
+static GEN
+Hseries(long m, long L, long v, long prec)
+{
+  long i, k, bit, l = L+3, M = m < 0? 1-m: m;
+  pari_sp av = avma;
+  GEN H = cgetg(l, t_SER);
+  H[1] = evalsigne(1)|evalvarn(v)|evalvalp(0);
+  prec++;
+  bit = -prec2nbits(prec);
+  for(k = 2; k < l; k++) gel(H,k) = gen_1; /* i=1 */
+  for (i = 2; i < M; i++)
+  {
+    GEN ik = invr(utor(i, prec));
+    for (k = 2; k < l; k++)
+    {
+      if (k > 2) { ik = divru(ik, i); if (expo(ik) < bit) break; }
+      gel(H,k) = gadd(gel(H,k), ik);
+    }
+    if (gc_needed(av,3))
+    {
+      if(DEBUGMEM>1) pari_warn(warnmem,"Hseries, i = %ld/%ld", i,M);
+      H = gerepilecopy(av, H);
+    }
+  }
+  if (m > 0)
+    for (k = 3; k < l; k+=2) togglesign_safe(&gel(H,k));
+  return H;
+}
+
 static GEN
 serpsi(GEN y, long prec)
 {
-  GEN Q, z0, Y;
+  GEN Q = NULL, z0, Y = y, Y2;
   long L = lg(y)-2, v  = varn(y), vy = valp(y);
-  int reflect;
 
   if (!L) pari_err_DOMAIN("psi", "argument", "=", gen_0,y);
   if (vy < 0) pari_err_DOMAIN("psi", "series valuation", "<", gen_0,y);
@@ -1816,22 +1860,42 @@ serpsi(GEN y, long prec)
     z0 = gen_0;
   else
   {
-    GEN t;
     z0 = simplify_shallow(gel(y,2));
-    t = ground(z0);
-    if (gequal(t,z0)) z0 = t;
-  }
-  reflect = (gcmp(real_i(z0),ghalf) < 0); /* use reflection formula */
-  if (reflect) { z0 = gsubsg(1,z0); Y = gsubsg(1,y); } else Y = y;
-  Q = serpsiz0(z0, L, v, prec);
-  Q = gsubst(Q, v, serchop0(Y)); /* psi(Y) */
-  if (reflect)
-  { /* psi(y) = psi(Y) + Pi cotan(Pi Y) = psi(Y) - Pi cotan(Pi y) */
+    (void)isint(z0, &z0);
+  }
+  if (typ(z0) == t_INT && !is_bigint(z0))
+  {
+    long m = itos(z0);
+    if (cmpiu(muluu(prec2nbits(prec),L), labs(m)) > 0)
+    { /* psi(m+x) = psi(1+x) + sum_{1 <= i < m} 1/(i+x) for m > 0
+                    psi(1+x) - sum_{0 <= i < -m} 1/(i+x) for m <= 0 */
+      GEN H = NULL;
+      if (m <= 0) L--; /* lose series accuracy due to 1/x term */
+      if (L)
+      {
+        Q = serpsi1(L, v, prec);
+        if (m && m != 1) { H = Hseries(m, L, v, prec); Q = gadd(Q, H); }
+        if (m <= 0) Q = gsub(Q, ginv(pol_x(v)));
+      }
+      else
+      {
+        Q = scalarser(gen_m1, v, 1);
+        setvalp(Q,-1);
+      }
+    }
+  }
+  if (!Q)
+  { /* use psi(1-y)=psi(y)+Pi*cotan(Pi*y) ? */
+    if (gcmp(real_i(z0),ghalf) < 0) { z0 = gsubsg(1,z0); Y = gsubsg(1,y); }
+    Q = serpsiz0(z0, L, v, prec);
+  }
+  Y2 = serchop0(Y); if (signe(Y2)) Q = gsubst(Q, v, Y2);
+  /* psi(z0 + Y2) = psi(Y) */
+  if (Y != y)
+  { /* psi(y) = psi(Y) + Pi cotan(Pi Y) */
     GEN pi = mppi(prec);
-    if (equali1(z0))
-      Q = gsub(Q, gmul(pi, gcotan(gmul(pi,y), prec)));
-    else
-      Q = gadd(Q, gmul(pi, gcotan(gmul(pi,Y), prec)));
+    if (typ(z0) == t_INT) Y = Y2; /* in this case cotan(Pi*Y2) = cotan(Pi*Y) */
+    Q = gadd(Q, gmul(pi, gcotan(gmul(pi,Y), prec)));
   }
   return Q;
 }
diff --git a/src/basemath/trans3.c b/src/basemath/trans3.c
index c084873..e2f28b7 100644
--- a/src/basemath/trans3.c
+++ b/src/basemath/trans3.c
@@ -21,6 +21,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 #include "paripriv.h"
 
 #define HALF_E 1.3591409 /* Exponential / 2 */
+static const long EXTRAPREC =
+#ifdef LONG_IS_64BIT
+  1;
+#else
+  2;
+#endif
 
 /***********************************************************************/
 /**                                                                   **/
@@ -677,7 +683,32 @@ incgam_0(GEN x, GEN expx)
   }
 }
 
-#if 0
+/* real(z*log(z)-z) */
+static double
+mygamma(double x, double y)
+{
+  if (x == 0.) return -(M_PI/2)*fabs(y);
+  return (x/2)*log(x*x+y*y)-x-y*atan(y/x);
+}
+
+/* x^s exp(-x) */
+static GEN
+expmx_xs(GEN s, GEN x, GEN logx, long prec)
+{
+  GEN z;
+  long ts = typ(s);
+  if (ts == t_INT || (ts == t_FRAC && equaliu(gel(s,2), 2)))
+    z = gmul(gexp(gneg(x), prec), gpow(x, s, prec));
+  else
+    z = gexp(gsub(gmul(s, logx? logx: glog(x,prec+EXTRAPREC)), x), prec);
+  return z;
+}
+
+/* Not yet: doesn't work at low accuracy
+#define INCGAM_CF
+*/
+
+#ifdef INCGAM_CF
 /* Is s very close to a non-positive integer ? */
 static int
 isgammapole(GEN s, long bitprec)
@@ -697,9 +728,8 @@ isgammapole(GEN s, long bitprec)
 static GEN
 incgam_cf(GEN s, GEN x, double mx, long prec)
 {
-  GEN x_s, y, S;
-  long n, i, LS, bitprec = prec2nbits(prec);
-  pari_sp av = avma, av2;
+  GEN ms, y, S;
+  long n, i, j, LS, bitprec = prec2nbits(prec);
   double rs, is, m;
 
   if (typ(s) == t_COMPLEX)
@@ -712,52 +742,57 @@ incgam_cf(GEN s, GEN x, double mx, long prec)
     rs = gtodouble(s);
     is = 0.;
   }
-
   if (isgammapole(s, bitprec)) LS = 0;
   else
   {
-    GEN ss = gprec_w(s, LOWDEFAULTPREC);
-    double bit,  LGS = gtodouble(real_i(glngamma(ss, LOWDEFAULTPREC)));
+    double bit,  LGS = mygamma(rs,is);
     LS = LGS <= 0 ? 0: ceil(LGS);
     bit = (LGS - (rs-1)*log(mx) + mx)/LOG2;
     if (bit > 0)
     {
-      prec = nbits2prec(bitprec + (long)bit);
-      s = gprec_w(s, prec);
-      x = gprec_w(x, prec);
+      prec += nbits2extraprec((long)bit);
+      x = gtofp(x, prec);
+      if (isinexactreal(s)) s = gtofp(s, prec);
     }
   }
   /* |ln(2*gamma(s)*sin(s*Pi))| <= ln(2) + |lngamma(s)| + |Im(s)*Pi|*/
-  m = (bitprec*LOG2 + LS + LOG2 + fabs(is)*M_PI + mx)/4;
-  n = (long)(1+m*m/mx);
-  if (typ(s) == t_INT) /* y = x^(s-1) exp(-x) */
-    y = gmul(gexp(gneg(x), prec), powgi(x,subis(s,1)));
+  m = bitprec*LOG2 + LS + LOG2 + fabs(is)*M_PI + mx;
+  if (rs < 1) m += (1 - rs)*log(mx);
+  m /= 4;
+  n = (long)(1 + m*m/mx);
+  y = expmx_xs(gsubgs(s,1), x, NULL, prec);
+  if (rs >= 0 && bitprec >= 512)
+  {
+    GEN A = cgetg(n+1, t_VEC), B = cgetg(n+1, t_VEC);
+    ms = gsubsg(1, s);
+    for (j = 1; j <= n; ++j)
+    {
+      gel(A,j) = ms;
+      gel(B,j) = gmulsg(j, gsubgs(s,j));
+      ms = gaddgs(ms, 2);
+    }
+    S = contfraceval_inv(mkvec2(A,B), x, -1);
+  }
   else
-    y = gexp(gsub(gmul(gsubgs(s,1), glog(x, prec)), x), prec);
-  x_s = gsub(x, s);
-  av2 = avma;
-  S = gdiv(gsubgs(s,n), gaddgs(x_s,n<<1));
-  for (i=n-1; i >= 1; i--)
   {
-    S = gdiv(gsubgs(s,i), gadd(gaddgs(x_s,i<<1),gmulsg(i,S)));
-    if (gc_needed(av2,3))
+    GEN x_s = gsub(x, s);
+    pari_sp av2 = avma;
+    S = gdiv(gsubgs(s,n), gaddgs(x_s,n<<1));
+    for (i=n-1; i >= 1; i--)
     {
-      if(DEBUGMEM>1) pari_warn(warnmem,"incgam_cf");
-      S = gerepileupto(av2, S);
+      S = gdiv(gsubgs(s,i), gadd(gaddgs(x_s,i<<1),gmulsg(i,S)));
+      if (gc_needed(av2,3))
+      {
+        if(DEBUGMEM>1) pari_warn(warnmem,"incgam_cf");
+        S = gerepileupto(av2, S);
+      }
     }
+    S = gaddgs(S,1);
   }
-  return gerepileupto(av, gmul(y, gaddsg(1,S)));
+  return gmul(y, S);
 }
 #endif
 
-/* real(z*log(z)-z) */
-static double
-mygamma(double x, double y)
-{
-  if (x == 0.) return -(M_PI/2)*fabs(y);
-  return (x/2)*log(x*x+y*y)-x-y*atan(y/x);
-}
-
 static double
 findextraincgam(GEN s, GEN x)
 {
@@ -769,11 +804,7 @@ findextraincgam(GEN s, GEN x)
   if (xr < 0)
   {
     long ex = gexpo(x);
-    if (ex > 0 && ex > gexpo(s))
-    {
-      double X = dblmodulus(x);
-      exd = X*log(X);
-    }
+    if (ex > 0 && ex > gexpo(s)) exd = sqrt(Nx)*log(Nx)/2; /* |x| log |x| */
   }
   if (D <= 0.) return exd;
   n = (long)(sqrt(D)-sig);
@@ -783,29 +814,29 @@ findextraincgam(GEN s, GEN x)
 
 /* use exp(-x) * (x^s/s) * sum_{k >= 0} x^k / prod(i=1, k, s+i) */
 static GEN
-incgamc_i(GEN s, GEN x, double *ptexd, long prec)
+incgamc_i(GEN s, GEN x, long *ptexd, long prec)
 {
   GEN S, t, y;
-  long l, n, i;
-  double exd;
+  long l, n, i, exd;
   pari_sp av = avma, av2;
 
-  if (typ(x) != t_REAL) x = gtofp(x, prec);
   if (gequal0(x))
   {
     if (ptexd) *ptexd = 0.;
-    return gcopy(x);
+    return gtofp(x, prec);
   }
   l = precision(x);
+  if (!l) l = prec;
   n = -prec2nbits(l)-1;
-  exd = findextraincgam(s, x);
+  exd = (long)findextraincgam(s, x);
   if (ptexd) *ptexd = exd;
   if (exd > 0)
   {
-    long p = l + (long)nbits2extraprec(exd);
+    long p = l + nbits2extraprec(exd);
     x = gtofp(x, p);
     if (isinexactreal(s)) s = gtofp(s, p);
   }
+  else x = gtofp(x, l+EXTRAPREC);
   av2 = avma;
   S = gdiv(x, gaddsg(1,s));
   t = gaddsg(1, S);
@@ -819,18 +850,13 @@ incgamc_i(GEN s, GEN x, double *ptexd, long prec)
       gerepileall(av2, 2, &S, &t);
     }
   }
-  if (typ(s)==t_INT)
-    y = gmul(gexp(gneg(x), prec), powgi(x,s));
-  else
-    y = gexp(gsub(gmul(s, glog(x, prec)), x), prec);
+  y = expmx_xs(s, x, NULL, prec);
   return gerepileupto(av, gmul(gdiv(y,s), t));
 }
 
 GEN
 incgamc(GEN s, GEN x, long prec)
-{
-  return incgamc_i(s, x, NULL, prec);
-}
+{ return incgamc_i(s, x, NULL, prec); }
 
 /* incgamma using asymptotic expansion:
  *   exp(-x)x^(s-1)(1 + (s-1)/x + (s-1)(s-2)/x^2 + ...) */
@@ -839,12 +865,14 @@ incgam_asymp(GEN s, GEN x, long prec)
 {
   pari_sp av = avma, av2;
   GEN S, q, cox, invx;
-  long oldeq = LONG_MAX, eq, esx, j, flint = 0;
+  long oldeq = LONG_MAX, eq, esx, j;
+  int flint = (typ(s) == t_INT && signe(s) > 0);
+
+  x = gtofp(x,prec+EXTRAPREC);
   invx = ginv(x);
   esx = -prec2nbits(prec);
   av2 = avma;
-  if (typ(s) == t_INT && signe(s) > 0) flint = 1;
-  q = gmul(gsubgs(s, 1), invx);
+  q = gmul(gsubgs(s,1), invx);
   S = gaddgs(q, 1);
   for (j = 2;; j++)
   {
@@ -854,14 +882,12 @@ incgam_asymp(GEN s, GEN x, long prec)
       if (eq > oldeq) { avma = av; return NULL; } /* regressing, abort */
       oldeq = eq;
     }
-    q = gmul(q, gmul(gsubgs(s, j), invx));
+    q = gmul(q, gmul(gsubgs(s,j), invx));
     S = gadd(S, q);
     if (gc_needed(av2, 1)) gerepileall(av2, 2, &S, &q);
   }
-  if (typ(s) == t_INT) /* exp(-x) x^(s-1) */
-    cox = gmul(gexp(gneg(x), prec), powgi(x, subis(s, 1)));
-  else
-    cox = gexp(gsub(gmul(gsubgs(s, 1), glog(x,prec)), x), prec);
+  if (DEBUGLEVEL > 2) err_printf("incgam: using asymp\n");
+  cox = expmx_xs(gsubgs(s,1), x, NULL, prec);
   return gerepileupto(av, gmul(cox, S));
 }
 
@@ -874,7 +900,7 @@ incgam_asymp_partial(GEN s, GEN x, GEN gasx, long n, long prec)
   pari_sp av;
   GEN S, q, cox, invx, s1 = gsubgs(s, 1), sprod;
   long j;
-  cox = gexp(gsub(gmul(s1, glog(x,prec)), x), prec);
+  cox = expmx_xs(s1, x, NULL, prec);
   if (n == 1) return gadd(cox, gmul(s1, gasx));
   invx = ginv(x);
   av = avma;
@@ -894,14 +920,21 @@ incgam_asymp_partial(GEN s, GEN x, GEN gasx, long n, long prec)
 static GEN
 incgamspec(GEN s, GEN x, GEN g, long prec)
 {
-  pari_sp av = avma;
-  GEN q, S, cox, P, sk, S1, S2, S3, F2, F3, logx, mx;
-  long esk, n, k = itos(ground(gneg(real_i(s))));
+  GEN q, S, cox = gen_0, P, sk, S1, S2, S3, F3, logx, mx;
+  long n, esk, k = itos(ground(gneg(real_i(s)))), E;
 
-  sk = gaddgs(s, k);
+  if (k && gexpo(x) > 0)
+  {
+    GEN xk = gdivgs(x, k);
+    long bitprec = prec2nbits(prec);
+    double mx = (gexpo(xk) > bitprec)? bitprec*LOG2: log(dblmodulus(xk));
+    prec += nbits2extraprec((long)k*(mx + 1)/LOG2);
+    if (isinexactreal(s)) s = gtofp(s, prec);
+  }
+  x = gtofp(x, maxss(precision(x), prec) + EXTRAPREC);
+  sk = gaddgs(s, k); /* |Re(sk)| <= 1/2 */
   logx = glog(x, prec);
   mx = gneg(x);
-  cox = gexp(gadd(mx, gmul(s, logx)), prec); /* x^s exp(-x) */
   if (k == 0) { S = gen_0; P = gen_1; }
   else
   {
@@ -914,45 +947,43 @@ incgamspec(GEN s, GEN x, GEN g, long prec)
       S = gadd(S, q);
       P = gmul(P, sj);
     }
+    cox = expmx_xs(s, x, logx, prec); /* x^s exp(-x) */
     S = gmul(S, gneg(cox));
   }
   if (k && gequal0(sk))
-    return gerepileupto(av, gadd(S, gdiv(eint1(x, prec), P)));
-
+    return gadd(S, gdiv(eint1(x, prec), P));
   esk = gexpo(sk);
   if (esk > -7)
   {
     GEN a, b, PG = gmul(sk, P);
     if (g) g = gmul(g, PG);
     a = incgam0(gaddgs(sk,1), x, g, prec);
+    if (k == 0) cox = expmx_xs(s, x, logx, prec);
     b = gmul(gpowgs(x, k), cox);
-    return gerepileupto(av, gadd(S, gdiv(gsub(a, b), PG)));
-  }
-  else if (2*esk > -prec2nbits(prec) - 4)
-  {
-    if (typ(sk) != t_REAL) sk = gtofp(sk, prec);
-    S1 = gdiv(gexpm1(glngamma(gaddgs(sk, 1), prec), prec), sk);
-    F3 = gexpm1(gmul(sk, logx), prec);
-    F2 = gneg(gdiv(F3, sk));
-    F3 = gaddsg(1, F3);
-  }
-  else
-  {
-    GEN EUL = mpeuler(prec);
-    S1 = gadd(negr(EUL), gmul(gdivgs(sk, 2), addrr(szeta(2,prec), sqrr(EUL))));
-    F2 = gmul(gneg(logx), gaddsg(1, gmul(gdivgs(sk, 2), logx)));
-    F3 = gexp(gmul(sk, logx), prec);
-  }
-  S2 = gmul(F2, gadd(gexp(mx, prec),
-                     gdiv(incgamc(gaddgs(sk,1), x, prec), F3)));
-  S3 = gdiv(x, gaddsg(1,sk));
-  q = x; n = 1;
-  while (gexpo(q) > -prec2nbits(prec))
-  {
-    n++; q = gmul(q, gdivgs(mx, n));
+    return gadd(S, gdiv(gsub(a, b), PG));
+  }
+  E = prec2nbits(prec) + 1;
+  if (gexpo(x) > 0)
+  {
+    long X = (long)(dblmodulus(x)/LOG2);
+    prec += 2*nbits2extraprec(X);
+    x = gtofp(x, prec); mx = gneg(x);
+    logx = glog(x, prec); sk = gtofp(sk, prec);
+    E += X;
+  }
+  if (isinexactreal(sk)) sk = gtofp(sk, prec+EXTRAPREC);
+  /* |sk| < 2^-7 is small, guard against cancellation */
+  F3 = gexpm1(gmul(sk, logx), prec);
+  /* ( gamma(1+sk) - exp(sk log(x))) ) / sk */
+  S1 = gdiv(gsub(ggamma1m1(sk, prec+EXTRAPREC), F3), sk);
+  q = x; S3 = gdiv(x, gaddsg(1,sk));
+  for (n = 2; gexpo(q) - gexpo(S3) > -E; ++n)
+  {
+    q = gmul(q, gdivgs(mx, n));
     S3 = gadd(S3, gdiv(q, gaddsg(n, sk)));
   }
-  return gerepileupto(av, gadd(S, gdiv(gadd(gadd(S1, S2), S3), P)));
+  S2 = gadd(gadd(S1, S3), gmul(F3, S3));
+  return gadd(S, gdiv(S2, P));
 }
 
 #if 0
@@ -985,9 +1016,9 @@ GEN
 incgam0(GEN s, GEN x, GEN g, long prec)
 {
   pari_sp av;
-  long E, es, l, n;
-  double mx, exd;
-  GEN z, rs;
+  long E, l;
+  double mx;
+  GEN z, rs, is;
 
   if (gequal0(x)) return g? gcopy(g): ggamma(s,prec);
   if (gequal0(s)) return eint1(x, prec);
@@ -995,23 +1026,36 @@ incgam0(GEN s, GEN x, GEN g, long prec)
   l = precision(s);
   if (!l) l = prec;
   E = prec2nbits(l) + 1;
-  if (typ(x) != t_REAL) x = gtofp(x, l);
   /* avoid overflow in dblmodulus */
   if (gexpo(x) > E) mx = E; else mx = dblmodulus(x);
   /* use asymptotic expansion */
-  if (4*mx > 3*E || (typ(s) == t_INT && signe(s) > 0))
-  {
-    z = incgam_asymp(s, x, l);
-    if (z)
+  if ((4*mx > 3*E || (typ(s) == t_INT && signe(s) > 0))
+      && (z = incgam_asymp(s, x, l))) return z;
+  rs = real_i(s);
+  is = imag_i(s);
+#ifdef INCGAM_CF
+  /* Can one use continued fraction ? */
+  if (gequal0(is) && gequal0(imag_i(x)) && gsigne(x) > 0)
+  {
+    double sd = gtodouble(rs), LB, UB;
+    double xd = gtodouble(real_i(x));
+    if (sd > 0) {
+      LB = 15 + 0.1205*E;
+      UB = 5 + 0.752*E;
+    } else {
+      LB = -6 + 0.1205*E;
+      UB = 5 + 0.752*E + fabs(sd)/54.;
+    }
+    if (xd >= LB && xd <= UB)
     {
-      if (DEBUGLEVEL > 2) err_printf("incgam: using asymp\n");
-      return z;
+      if (DEBUGLEVEL > 2) err_printf("incgam: using continued fraction\n");
+      return gerepileupto(av, incgam_cf(s, x, xd, prec));
     }
   }
-  rs = real_i(s);
+#endif
   if (gsigne(rs) > 0 && gexpo(rs) >= -1)
   { /* use complementary incomplete gamma */
-    es = gexpo(s);
+    long n, egs, exd, precg, es = gexpo(s);
     if (es < 0) {
       l += nbits2extraprec(-es) + 1;
       x = gtofp(x, l);
@@ -1026,26 +1070,37 @@ incgam0(GEN s, GEN x, GEN g, long prec)
       return gerepileupto(av, incgam_asymp_partial(s, x, gasx, n, prec));
     }
     if (DEBUGLEVEL > 2) err_printf("incgam: using power series 1\n");
-    if (!g) g = ggamma(s,l);
-    es = -gexpo(g);
-    if (es < 0) {
-      l += nbits2extraprec(-es) + 1;
+    /* egs ~ expo(gamma(s)) */
+    precg = g? precision(g): 0;
+    egs = g? gexpo(g): (long)(mygamma(gtodouble(rs), gtodouble(is)) / LOG2);
+    if (egs > 0) {
+      l += nbits2extraprec(egs) + 1;
       x = gtofp(x, l);
       if (isinexactreal(s)) s = gtofp(s, l);
-      g = NULL;
+      if (precg < l) g = NULL;
     }
     z = incgamc_i(s, x, &exd, l);
     if (exd > 0)
     {
-      l += (long)nbits2extraprec(exd);
+      l += nbits2extraprec(exd);
       if (isinexactreal(s)) s = gtofp(s, l);
-      g = NULL;
+      if (precg < l) g = NULL;
     }
-    if (!g) g = ggamma(s,l);
+    else
+    { /* gamma(s) negligible ? Compute to lower accuracy */
+      long e = gexpo(z) - egs;
+      if (e > 3)
+      {
+        E -= e;
+        if (E <= 0) g = gen_0; else if (!g) g = ggamma(s, nbits2prec(E));
+      }
+    }
+    /* worry about possible cancellation */
+    if (!g) g = ggamma(s, maxss(l,precision(z)));
     return gerepileupto(av, gsub(g,z));
   }
   if (DEBUGLEVEL > 2) err_printf("incgam: using power series 2\n");
-  return gerepilecopy(av, incgamspec(s, x, g, l));
+  return gerepileupto(av, incgamspec(s, x, g, l));
 }
 
 GEN
@@ -1064,36 +1119,32 @@ mpeint1(GEN x, GEN expx)
 static GEN
 cxeint1(GEN x, long prec)
 {
-  pari_sp av = avma;
-  GEN q, S1, S2, S3, mx;
+  pari_sp av = avma, av2;
+  GEN q, S3;
+  GEN run, z, H;
   long n, E = prec2nbits(prec) + 1, ex = gexpo(x);
 
-  if (ex > E || 4*dblmodulus(x) > 3*E)
-  {
-    GEN z = incgam_asymp(gen_0, x, prec);
-    if (z)
-    {
-      if (DEBUGLEVEL > 2) err_printf("eint1: using asymp\n");
-      return z;
-    }
-  }
+  if ((ex > E || 4*dblmodulus(x) > 3*E)
+      && (z = incgam_asymp(gen_0, x, prec))) return z;
   if (ex > 0)
   { /* take cancellation into account, log2(\sum |x|^n / n!) = |x| / log(2) */
-    double X = dblmodulus(x);
-    prec += nbits2extraprec(X / LOG2);
-    x = gtofp(x, prec);
-    E += (long)(X/LOG2);
+    double dbx = dblmodulus(x);
+    long X = (long)((dbx + log(dbx))/LOG2 + 10);
+    prec += nbits2extraprec(X);
+    x = gtofp(x, prec); E += X;
   }
   if (DEBUGLEVEL > 2) err_printf("eint1: using power series\n");
-  S1 = negr(mpeuler(prec));
-  S2 = gneg(glog(x, prec));
-  q = S3 = x; n = 1; mx = gneg(x);
-  while (gexpo(q) - gexpo(S3) > -E)
+  run = real_1(prec);
+  av2 = avma;
+  S3 = z = q = H = run;
+  for (n = 2; gexpo(q) - gexpo(S3) >= -E; n++)
   {
-    n++; q = gmul(q, gdivgs(mx, n));
-    S3 = gadd(S3, gdivgs(q, n));
+    H = addrr(H, divru(run, n)); /* H = sum_{k<=n} 1/k */
+    z = gdivgs(gmul(x,z), n);   /* z = x^(n-1)/n! */
+    q = gmul(z, H); S3 = gadd(S3, q);
+    if ((n & 0x1ff) == 0) gerepileall(av2, 4, &z, &q, &S3, &H);
   }
-  return gerepileupto(av, gadd(gadd(S1, S2), S3));
+  return gerepileupto(av, gsub(gmul(x, gdiv(S3, gexp(x, prec))), gadd(glog(x, prec), mpeuler(prec))));
 }
 
 GEN
@@ -1103,9 +1154,11 @@ eint1(GEN x, long prec)
   pari_sp av;
   GEN p1, t, S, y, res;
 
-  if (typ(x) != t_REAL) {
-    x = gtofp(x, prec);
-    if (typ(x) != t_REAL) return cxeint1(x, prec);
+  switch(typ(x))
+  {
+    case t_COMPLEX: return cxeint1(x, prec);
+    case t_REAL: break;
+    default: x = gtofp(x, prec);
   }
   if (signe(x) >= 0) return mpeint1(x,NULL);
   /* rewritten from code contributed by Manfred Radimersky */
@@ -1113,7 +1166,8 @@ eint1(GEN x, long prec)
   av = avma;
   l  = realprec(x);
   n  = prec2nbits(l);
-  y  = negr(x);
+  y  = rtor(x, l + EXTRAPREC);
+  setsigne(y,1);
   if (cmprs(y, (3*n)/4) < 0) {
     p1 = t = S = y;
     for (i = 2; expo(t) - expo(S) >= -n; i++) {
@@ -1122,10 +1176,10 @@ eint1(GEN x, long prec)
       S = addrr(S, t);
     }
     y  = addrr(S, addrr(logr_abs(x), mpeuler(l)));
-  } else { /* asymptotic expansion */
+  } else { /* ~incgam_asymp: asymptotic expansion */
     p1 = t = invr(y);
     S = addrs(t, 1);
-    for (i = 2; expo(t) - expo(S) >= -n; i++) {
+    for (i = 2; expo(t) >= -n; i++) {
       t = mulrr(p1, mulru(t, i));
       S = addrr(S, t);
     }
@@ -1214,8 +1268,8 @@ mpveceint1(GEN C, GEN eC, long N)
   if (Nmin == N) { avma = av0; return w; }
 
   DL = prec2nbits_mul(prec, LOG2) + 5;
-  jmin = ceil(DL/log(N)) + 1;
-  jmax = ceil(DL/log(Nmin)) + 1;
+  jmin = ceil(DL/log((double)N)) + 1;
+  jmax = ceil(DL/log((double)Nmin)) + 1;
   v = sum_jall(C, jmax, prec);
   en = powrs(eC, -N); /* exp(-N C) */
   affrr(incgam_0(mulru(C,N), invr(en)), gel(w,N));
@@ -1316,7 +1370,7 @@ gerfc(GEN x, long prec)
     */
     /* NOT gsubsg(2, ...) : would create a result of
      * huge accuracy if re(x)>>1, rounded to 2 by subsequent affc_fixlg... */
-    z = gsub(real2n(1,prec+EXTRAPRECWORD), gerfc(gneg(x), prec));
+    z = gsub(real2n(1,prec+EXTRAPREC), gerfc(gneg(x), prec));
   }
   avma = av; return affc_fixlg(z, res);
 }
@@ -1420,7 +1474,7 @@ inv_szeta_euler(long n, double lba, long prec)
   if (n > prec2nbits(prec)) return real_1(prec);
 
   if (!lba) lba = prec2nbits_mul(prec, LOG2);
-  D = exp((lba - log(n-1)) / (n-1));
+  D = exp((lba - log((double)(n-1))) / (n-1));
   lim = 1 + (ulong)ceil(D);
   if (lim < 3) return subir(gen_1,real2n(-n,prec));
   res = cgetr(prec); incrprec(prec);
@@ -1431,7 +1485,7 @@ inv_szeta_euler(long n, double lba, long prec)
   av2 = avma; A = n / LOG2;
   while ((p = u_forprime_next(&S)))
   {
-    long l = prec2nbits(prec) - (long)floor(A * log(p)) - BITS_IN_LONG;
+    long l = prec2nbits(prec) - (long)floor(A * log((double)p)) - BITS_IN_LONG;
     GEN h;
 
     if (l < BITS_IN_LONG) l = BITS_IN_LONG;
@@ -1477,7 +1531,7 @@ bernfrac_using_zeta(long n)
     if (uisprime(p)) d = muliu(d, p);
   }
   /* 1.712086 = ??? */
-  t = log( gtodouble(d) ) + (n + 0.5) * log(n) - n*(1+log2PI) + 1.712086;
+  t = log( gtodouble(d) ) + (n + 0.5) * log((double)n) - n*(1+log2PI) + 1.712086;
   u = t / LOG2; prec = nbits2prec((long)ceil(u) + BITS_IN_LONG);
   iz = inv_szeta_euler(n, t, prec);
   a = roundr( mulir(d, bernreal_using_zeta(n, iz, prec)) );
@@ -1492,7 +1546,7 @@ bernreal_use_zeta(long k, long prec)
     GEN B = gel(bernzone,(k>>1)+1);
     if (typ(B) != t_REAL || realprec(B) >= prec) return 0;
   }
-  return (k * (log(k) - 2.83) > prec2nbits_mul(prec, LOG2));
+  return (k * (log((double)k) - 2.83) > prec2nbits_mul(prec, LOG2));
 }
 
 /* Return B_n */
@@ -1516,7 +1570,7 @@ bernreal(long n, long prec)
     if (realprec(B) >= prec) return rtor(B, prec);
   }
   /* not cached, must compute */
-  if (n * log(n) > prec2nbits_mul(prec, LOG2))
+  if (n * log((double)n) > prec2nbits_mul(prec, LOG2))
     B = storeB = bernreal_using_zeta(n, NULL, prec);
   else
   {
@@ -1701,7 +1755,7 @@ czeta(GEN s0, long prec)
   GEN sim, *tab, tabn, funeq_factor = NULL;
   ulong p, sqn;
   long i, nn, lim, lim2, ct;
-  pari_sp av0 = avma, av, av2;
+  pari_sp av0 = avma, av;
   pari_timer T;
   forprime_t S;
 
@@ -1769,10 +1823,9 @@ czeta(GEN s0, long prec)
   /* compute 1 + 2^-s + ... + n^-s = P(2^-s) using Horner's scheme */
   for (i=ct; i > 1; i--)
   {
+    pari_sp av2 = avma;
     long j;
-    av2 = avma;
-    for (j=tabn[i]+1; j<=tabn[i-1]; j++)
-      sim = gadd(sim, n_s(2*j+1, tab));
+    for (j=tabn[i]+1; j<=tabn[i-1]; j++) sim = gadd(sim, n_s(2*j+1, tab));
     sim = gerepileupto(av2, sim);
     y = gadd(sim, gmul(tab[2],y));
   }
@@ -1784,6 +1837,7 @@ czeta(GEN s0, long prec)
   tes = bernreal(lim2, prec);
   {
     GEN s1, s2, s3, s4, s5;
+    pari_sp av2;
     s1 = gsub(gmul2n(s,1), unr);
     s2 = gmul(s, gsub(s,unr));
     s3 = gmul2n(invn2,3);
@@ -2882,19 +2936,75 @@ aut_factor(GEN U, GEN z)
 }
 #endif
 
+/* eta(q) = 1 + \sum_{n>0} (-1)^n * (q^(n(3n-1)/2) + q^(n(3n+1)/2)) */
+static GEN
+ser_eta(long prec)
+{
+  GEN e = cgetg(prec+2, t_SER), ed = e+2;
+  long n, j;
+  e[1] = evalsigne(1)|_evalvalp(0)|evalvarn(0);
+  gel(ed,0) = gen_1;
+  for (n = 1; n < prec; n++) gel(ed,n) = gen_0;
+  for (n = 1, j = 0; n < prec; n++)
+  {
+    GEN s;
+    j += 3*n-2; /* = n*(3*n-1) / 2 */;
+    if (j >= prec) break;
+    s = odd(n)? gen_m1: gen_1;
+    gel(ed, j) = s;
+    if (j+n >= prec) break;
+    gel(ed, j+n) = s;
+  }
+  return e;
+}
+
+static GEN
+coeffEu(ulong n)
+{
+  pari_sp av = avma;
+  return gerepileuptoint(av, mului(65520, usumdivk_fact(factoru(n+1),11)));
+}
+/* E12 = 1 + q*E/691 */
+static GEN
+ser_E(long prec)
+{
+  GEN e = cgetg(prec+2, t_SER), ed = e+2;
+  long n;
+  e[1] = evalsigne(1)|_evalvalp(0)|evalvarn(0);
+  gel(ed,0) = utoipos(65520);
+  for (n = 1; n < prec; n++) gel(ed,n) = coeffEu(n);
+  return e;
+}
+/* j = E12/Delta + 432000/691, E12 = 1 + q*E/691 */
+static GEN
+ser_j2(long prec, long v)
+{
+  pari_sp av = avma;
+  GEN iD = gpowgs(ginv(ser_eta(prec)), 24); /* q/Delta */
+  GEN J = gmul(ser_E(prec), iD);
+  setvalp(iD,-1); /* now 1/Delta */
+  J = gadd(gdivgs(J, 691), iD);
+  J = gerepileupto(av, J);
+  if (prec > 1) gel(J,3) = utoipos(744);
+  setvarn(J,v); return J;
+}
+
 /* j(q) = \sum_{n >= -1} c(n)q^n,
  * \sum_{n = -1}^{N-1} c(n) (-10n \sigma_3(N-n) + 21 \sigma_5(N-n))
  * = c(N) (N+1)/24 */
 static GEN
 ser_j(long prec, long v)
 {
-  GEN j, J, K = mkvecsmall2(3,5), S = cgetg(prec+1, t_VEC);
+  GEN j, J, S3, S5;
   long i, n;
+  if (prec > 64) return ser_j2(prec, v);
+  S3 = cgetg(prec+1, t_VEC);
+  S5 = cgetg(prec+1,t_VEC);
   for (n = 1; n <= prec; n++)
   {
-    GEN s = usumdivkvec(n, K);
-    gel(s,2) = mului(21, gel(s,2));
-    gel(S,n) = s;
+    GEN fa = factoru(n);
+    gel(S3,n) = mului(10, usumdivk_fact(fa,3));
+    gel(S5,n) = mului(21, usumdivk_fact(fa,5));
   }
   J = cgetg(prec+2, t_SER),
   J[1] = evalvarn(v)|evalsigne(1)|evalvalp(-1);
@@ -2905,12 +3015,12 @@ ser_j(long prec, long v)
   for (n = 2; n < prec; n++)
   {
     pari_sp av = avma;
-    GEN c, s = gel(S,n+1), s3 = gel(s,1), s5 = gel(s,2);
-    c = addii(mului(10, s3), s5);
+    GEN c, s3 = gel(S3,n+1), s5 = gel(S5,n+1);
+    c = addii(s3, s5);
     for (i = 0; i < n; i++)
     {
-      s = gel(S,n-i); s3 = gel(s,1); s5 = gel(s,2);
-      c = addii(c, mulii(gel(j,i), addii(mulsi(-10*i,s3), s5)));
+      s3 = gel(S3,n-i); s5 = gel(S5,n-i);
+      c = addii(c, mulii(gel(j,i), subii(s5, mului(i,s3))));
     }
     gel(j,n) = gerepileuptoint(av, diviuexact(muliu(c,24), n+1));
   }
@@ -3027,11 +3137,6 @@ double_eta_quotient(GEN a, GEN w, GEN D, long p, long q, GEN pq, GEN sqrtD)
 
 typedef struct { GEN u; long v, t; } cxanalyze_t;
 
-/* typ(x) = t_INT, t_FRAC or t_REAL */
-INLINE GEN
-R_abs_shallow(GEN x)
-{ return (typ(x) == t_FRAC)? absfrac_shallow(x): mpabs_shallow(x); }
-
 /* Check whether a t_COMPLEX, t_REAL or t_INT z != 0 can be written as
  * z = u * 2^(v/2) * exp(I Pi/4 t), u > 0, v = 0,1 and -3 <= t <= 4.
  * Allow z t_INT/t_REAL to simplify handling of eta_correction() output */
@@ -3452,7 +3557,7 @@ serlambertW(GEN y, long prec)
   n = lg(y)-3;
   y0 = gel(y,2);
   for (val = 1; val < n; val++)
-    if (!gcmp0(polcoeff0(y, val, vy))) break;
+    if (!gequal0(polcoeff0(y, val, vy))) break;
   if (v < 0) pari_err_DOMAIN("lambertw","valuation", "<", gen_0, y);
   if (val >= n)
   {
diff --git a/src/desc/deftune b/src/desc/deftune
index 47f633a..8a744a8 100644
--- a/src/desc/deftune
+++ b/src/desc/deftune
@@ -2,6 +2,7 @@
 AGM_ATAN_LIMIT                     159      89      56      60
 DIVRR_GMP_LIMIT                     -1       4      -1       4
 EXPNEWTON_LIMIT                     66     197      66      66
+F2x_MUL_KARATSUBA_LIMIT             23      23      15      15
 Flx_BARRETT_QUARTMULII_LIMIT       244      20      29      23
 Flx_BARRETT_HALFMULII_LIMIT        244      23      29      21
 Flx_BARRETT_KARATSUBA_LIMIT        905     905    2561    1172
@@ -33,6 +34,9 @@ Flx_SQR_SQRI2_LIMIT               4139     470       8       7
 Flx_SQR_SQRI_LIMIT                1276       5       5       5
 FlxqX_BARRETT_LIMIT                 17      17      17      17
 FlxqX_DIVREM_BARRETT_LIMIT          46      46      46      46
+FlxqX_EXTGCD_LIMIT                  44      44      44      44
+FlxqX_GCD_LIMIT                   2544    1289     796     470
+FlxqX_HALFGCD_LIMIT                427      89     191      60
 FlxqX_INVBARRETT_LIMIT              22      22      22      22
 FlxqX_REM_BARRETT_LIMIT             48      48      48      48
 FpX_BARRETT_LIMIT                  144      44      85      38
@@ -44,6 +48,9 @@ FpX_INVBARRETT_LIMIT               337     121     254     111
 FpX_REM_BARRETT_LIMIT              306     127     306     111
 FpXQX_BARRETT_LIMIT                 12      12      12      12
 FpXQX_DIVREM_BARRETT_LIMIT          30      30      30      30
+FpXQX_EXTGCD_LIMIT                  28      28      34      28
+FpXQX_GCD_LIMIT                    254     182     254     191
+FpXQX_HALFGCD_LIMIT                 48      35      56      35
 FpXQX_INVBARRETT_LIMIT              40      40      40      40
 FpXQX_REM_BARRETT_LIMIT             30      30      30      30
 Fp_POW_BARRETT_LIMIT                97      11     101     127
diff --git a/src/desc/doc_make b/src/desc/doc_make
index 4104c6f..aaccfb0 100755
--- a/src/desc/doc_make
+++ b/src/desc/doc_make
@@ -64,7 +64,7 @@ sub library_syntax { my ($fun, $args) = @_;
   my ($Variant) = $fun->{Variant};
   my (@proto) = split(//, $fun->{Prototype});
   $args =~ s/[{}&]//g;
-  $args =~ s/=[^,\)]*//g; # delete default values
+  $args =~ s/ *=[^,\)]*//g; # delete default values
   my (@ARGS) = split(/[,^] */, $args); # ^ for O(p^e)
   my ($type) = "GEN";
   my (@vars)=();
@@ -76,6 +76,7 @@ sub library_syntax { my ($fun, $args) = @_;
     if ($c eq 'v') { $type = "void"; next; }
 
     if ($c =~ /^[GWIJE]$/) {$args .= ", GEN " . shift(@ARGS); next;}
+    if ($c eq 'U') {$args .= ", ulong " . shift(@ARGS); next;}
     if ($c eq 'L') {$args .= ", long " . shift(@ARGS); next;}
     if ($c eq 'n') {my ($v) = shift(@ARGS); push @vars,"\\kbd{$v}";
                     $args .= ", long " . $v; next;}
diff --git a/src/desc/gen_proto b/src/desc/gen_proto
index 2159636..ffd94a8 100755
--- a/src/desc/gen_proto
+++ b/src/desc/gen_proto
@@ -13,6 +13,7 @@ $i = 1;
   'elliptic_curves'       => $i++,
   'l_functions'           => $i++,
   'modular_forms'         => $i++,
+  'modular_symbols'       => $i++,
   'number_fields'         => $i++,
   'algebras'              => $i++,
   'polynomials'           => $i++,
diff --git a/src/funclist b/src/funclist
index 97fae0a..adb68a5 100644
--- a/src/funclist
+++ b/src/funclist
@@ -130,7 +130,7 @@
 1705281810 307 ../functions/default/debugfiles
 2013652512 591 ../functions/default/debugmem
 2315543353 465 ../functions/default/echo
-3483503147 774 ../functions/default/factor_add_primes
+3269179051 776 ../functions/default/factor_add_primes
 3740185017 672 ../functions/default/factor_proven
 3860891309 1410 ../functions/default/format
 1870636521 1003 ../functions/default/graphcolormap
@@ -208,14 +208,14 @@
 1621101605 661 ../functions/elliptic_curves/elllseries
 904157268 782 ../functions/elliptic_curves/ellminimalmodel
 306104160 1066 ../functions/elliptic_curves/ellminimaltwist
-1894955704 608 ../functions/elliptic_curves/ellmoddegree
+2699075377 600 ../functions/elliptic_curves/ellmoddegree
 1775278007 2358 ../functions/elliptic_curves/ellmodulareqn
 2371457085 1054 ../functions/elliptic_curves/ellmul
 2235217918 190 ../functions/elliptic_curves/ellneg
-906417652 664 ../functions/elliptic_curves/ellnonsingularmultiple
+48954240 876 ../functions/elliptic_curves/ellnonsingularmultiple
 1314089142 1876 ../functions/elliptic_curves/ellorder
 712202039 307 ../functions/elliptic_curves/ellordinate
-2633873018 2527 ../functions/elliptic_curves/ellpadicL
+939820263 4282 ../functions/elliptic_curves/ellpadicL
 1034758728 905 ../functions/elliptic_curves/ellpadicfrobenius
 2311743566 2684 ../functions/elliptic_curves/ellpadicheight
 1688216667 687 ../functions/elliptic_curves/ellpadicheightmatrix
@@ -237,9 +237,9 @@
 471737010 547 ../functions/elliptic_curves/ellxn
 36981238 1480 ../functions/elliptic_curves/ellzeta
 1222568733 758 ../functions/elliptic_curves/ellztopoint
-1108829748 5712 ../functions/elliptic_curves/genus2red
+151618971 5711 ../functions/elliptic_curves/genus2red
 4179269820 731 ../functions/elliptic_curves/hyperellcharpoly
-778024654 995 ../functions/elliptic_curves/hyperellpadicfrobenius
+1622426669 1038 ../functions/elliptic_curves/hyperellpadicfrobenius
 1668730040 123 ../functions/gp2c/DEBUGLEVEL
 673657102 528 ../functions/gp2c/clone
 4282475994 385 ../functions/gp2c/copy
@@ -254,6 +254,7 @@
 2727635652 193 ../functions/gp2c_internal/_gerepileall
 1155278703 344 ../functions/gp2c_internal/_gerepileupto
 2948757155 90 ../functions/gp2c_internal/_maxprime
+151582740 76 ../functions/gp2c_internal/_norange
 1798325487 181 ../functions/gp2c_internal/_prec
 1600216421 227 ../functions/gp2c_internal/_stack_lim
 667601403 171 ../functions/gp2c_internal/_strtoclosure
@@ -289,31 +290,32 @@
 3542751079 547 ../functions/graphic/psdraw
 3906960811 340 ../functions/graphic/psploth
 1699338007 340 ../functions/graphic/psplothraw
-3021290093 1970 ../functions/l_functions/lfun
-2298028950 1457 ../functions/l_functions/lfunabelianrelinit
+1789425436 1938 ../functions/l_functions/lfun
+152536408 1449 ../functions/l_functions/lfunabelianrelinit
 806210895 545 ../functions/l_functions/lfunan
 2557898792 2254 ../functions/l_functions/lfunartin
-3858839136 2042 ../functions/l_functions/lfuncheckfeq
-3248225208 3059 ../functions/l_functions/lfunconductor
-580631040 3029 ../functions/l_functions/lfuncost
+3807748260 2034 ../functions/l_functions/lfuncheckfeq
+3051969946 3051 ../functions/l_functions/lfunconductor
+3385260052 3209 ../functions/l_functions/lfuncost
 3298334011 5314 ../functions/l_functions/lfuncreate
-2893319589 543 ../functions/l_functions/lfundiv
+823680928 543 ../functions/l_functions/lfundiv
 186816096 665 ../functions/l_functions/lfunetaquo
-794736811 1520 ../functions/l_functions/lfunhardy
-1422163266 1940 ../functions/l_functions/lfuninit
-1514381101 716 ../functions/l_functions/lfunlambda
-2359720101 456 ../functions/l_functions/lfunmfpeters
-1178782275 754 ../functions/l_functions/lfunmfspec
-2866794685 375 ../functions/l_functions/lfunmul
-1215984438 363 ../functions/l_functions/lfunorderzero
+2817288033 630 ../functions/l_functions/lfungenus2
+4042997556 1512 ../functions/l_functions/lfunhardy
+3251605581 1932 ../functions/l_functions/lfuninit
+1264553451 708 ../functions/l_functions/lfunlambda
+2168687543 591 ../functions/l_functions/lfunmfpeters
+2749849014 746 ../functions/l_functions/lfunmfspec
+2085012415 375 ../functions/l_functions/lfunmul
+647070854 355 ../functions/l_functions/lfunorderzero
 658397838 723 ../functions/l_functions/lfunqf
-3344193896 1340 ../functions/l_functions/lfunrootres
+3229069669 1332 ../functions/l_functions/lfunrootres
 2485468510 1241 ../functions/l_functions/lfunsymsq
-3318840500 1051 ../functions/l_functions/lfunsymsqspec
-2269768036 1254 ../functions/l_functions/lfuntheta
+4055546552 1043 ../functions/l_functions/lfunsymsqspec
+3125763161 1246 ../functions/l_functions/lfuntheta
 3132007391 1551 ../functions/l_functions/lfunthetacost
-2321745562 1631 ../functions/l_functions/lfunthetainit
-2676672360 1302 ../functions/l_functions/lfunzeros
+1308696408 1623 ../functions/l_functions/lfunthetainit
+2457380232 1294 ../functions/l_functions/lfunzeros
 3346047431 2741 ../functions/linear_algebra/algdep
 1562845233 2766 ../functions/linear_algebra/charpoly
 123003544 2471 ../functions/linear_algebra/concat
@@ -363,7 +365,7 @@
 3205643715 970 ../functions/linear_algebra/qfbil
 1943199810 1227 ../functions/linear_algebra/qfgaussred
 2089217354 1080 ../functions/linear_algebra/qfisom
-1265479323 1173 ../functions/linear_algebra/qfisominit
+2710066504 1332 ../functions/linear_algebra/qfisominit
 4164538816 878 ../functions/linear_algebra/qfjacobi
 2738765226 3148 ../functions/linear_algebra/qflll
 2571047474 1825 ../functions/linear_algebra/qflllgram
@@ -385,7 +387,7 @@
 2343012690 397 ../functions/linear_algebra/trace
 1009255636 2824 ../functions/linear_algebra/vecextract
 3204283581 1552 ../functions/linear_algebra/vecsearch
-2127481713 4246 ../functions/linear_algebra/vecsort
+3556999692 4210 ../functions/linear_algebra/vecsort
 1210136160 289 ../functions/linear_algebra/vecsum
 3631831174 1145 ../functions/linear_algebra/vector
 2820295330 518 ../functions/linear_algebra/vectorsmall
@@ -437,21 +439,31 @@
 2066290395 90 ../functions/member_functions/tufu
 1665968088 171 ../functions/member_functions/zk
 2924685257 142 ../functions/member_functions/zkst
-626242422 853 ../functions/modular_forms/msatkinlehner
-3791420813 894 ../functions/modular_forms/mscuspidal
-2763530206 783 ../functions/modular_forms/mseisenstein
-4168406 1964 ../functions/modular_forms/mseval
-3320155070 1596 ../functions/modular_forms/msfromcusp
-836139128 1837 ../functions/modular_forms/msfromell
-65474601 982 ../functions/modular_forms/mshecke
-4228701829 1382 ../functions/modular_forms/msinit
-132317707 742 ../functions/modular_forms/msissymbol
-2465050845 620 ../functions/modular_forms/msnew
-2508813533 1968 ../functions/modular_forms/mspathgens
-682780557 1090 ../functions/modular_forms/mspathlog
-1334231303 1390 ../functions/modular_forms/msqexpansion
-1713575565 1199 ../functions/modular_forms/mssplit
-3206775694 569 ../functions/modular_forms/msstar
+392458493 855 ../functions/modular_symbols/msatkinlehner
+4232348790 896 ../functions/modular_symbols/mscuspidal
+3476219910 785 ../functions/modular_symbols/mseisenstein
+3310687634 1966 ../functions/modular_symbols/mseval
+3288086334 1598 ../functions/modular_symbols/msfromcusp
+267174405 2304 ../functions/modular_symbols/msfromell
+751059125 1197 ../functions/modular_symbols/msfromhecke
+3907684130 270 ../functions/modular_symbols/msgetlevel
+3236382025 389 ../functions/modular_symbols/msgetsign
+4113320004 338 ../functions/modular_symbols/msgetweight
+1072597889 984 ../functions/modular_symbols/mshecke
+2644129809 1384 ../functions/modular_symbols/msinit
+3746705917 744 ../functions/modular_symbols/msissymbol
+2274810889 622 ../functions/modular_symbols/msnew
+1638841703 563 ../functions/modular_symbols/msomseval
+2744970779 4138 ../functions/modular_symbols/mspadicL
+3864018702 1963 ../functions/modular_symbols/mspadicinit
+3874371292 1718 ../functions/modular_symbols/mspadicmoments
+2182473339 3180 ../functions/modular_symbols/mspadicseries
+996937537 1970 ../functions/modular_symbols/mspathgens
+2868710319 1092 ../functions/modular_symbols/mspathlog
+282750073 1392 ../functions/modular_symbols/msqexpansion
+1370797056 1376 ../functions/modular_symbols/mssplit
+2452679244 571 ../functions/modular_symbols/msstar
+1610833853 2492 ../functions/modular_symbols/mstooms
 817575908 1451 ../functions/number_fields/bnfcertify
 654416520 1799 ../functions/number_fields/bnfcompress
 1086935842 498 ../functions/number_fields/bnfdecodemodule
@@ -461,7 +473,7 @@
 2045850218 2757 ../functions/number_fields/bnfisprincipal
 1025672292 530 ../functions/number_fields/bnfissunit
 3277737232 1587 ../functions/number_fields/bnfisunit
-3303533017 819 ../functions/number_fields/bnfnarrow
+145391792 842 ../functions/number_fields/bnfnarrow
 30185140 954 ../functions/number_fields/bnfsignunit
 2219572014 1154 ../functions/number_fields/bnfsunit
 228098176 2890 ../functions/number_fields/bnrL1
@@ -472,9 +484,9 @@
 4147486906 228 ../functions/number_fields/bnrconductorofchar
 1501183023 1493 ../functions/number_fields/bnrdisc
 3292276537 2779 ../functions/number_fields/bnrdisclist
-3847585707 452 ../functions/number_fields/bnrgaloisapply
+966581475 453 ../functions/number_fields/bnrgaloisapply
 2171187845 1024 ../functions/number_fields/bnrgaloismatrix
-2365653780 2218 ../functions/number_fields/bnrinit
+278298340 2248 ../functions/number_fields/bnrinit
 4177597782 643 ../functions/number_fields/bnrisconductor
 3589985364 1386 ../functions/number_fields/bnrisgalois
 4098267331 1306 ../functions/number_fields/bnrisprincipal
@@ -490,8 +502,8 @@
 474428460 542 ../functions/number_fields/galoisisabelian
 3491431523 559 ../functions/number_fields/galoisisnormal
 999481307 869 ../functions/number_fields/galoispermtopol
-415883189 2573 ../functions/number_fields/galoissubcyclo
-1739582821 432 ../functions/number_fields/galoissubfields
+1148948717 2569 ../functions/number_fields/galoissubcyclo
+952516268 423 ../functions/number_fields/galoissubfields
 4087525432 813 ../functions/number_fields/galoissubgroups
 4041888397 1330 ../functions/number_fields/idealadd
 2595771256 868 ../functions/number_fields/idealaddtoone
@@ -506,15 +518,15 @@
 2234579433 753 ../functions/number_fields/idealintersect
 3755090162 414 ../functions/number_fields/idealinv
 4061325327 2136 ../functions/number_fields/ideallist
-1520685324 1746 ../functions/number_fields/ideallistarch
+1006101289 1743 ../functions/number_fields/ideallistarch
 1687206224 1326 ../functions/number_fields/ideallog
 1577350712 385 ../functions/number_fields/idealmin
 1406519120 1275 ../functions/number_fields/idealmul
 2213617432 214 ../functions/number_fields/idealnorm
 3621386739 392 ../functions/number_fields/idealnumden
-590254486 900 ../functions/number_fields/idealpow
+4065231807 897 ../functions/number_fields/idealpow
 915123701 2333 ../functions/number_fields/idealprimedec
-1421736270 775 ../functions/number_fields/idealprincipalunits
+1772416220 780 ../functions/number_fields/idealprincipalunits
 3582609430 1715 ../functions/number_fields/idealramgroups
 477008975 2910 ../functions/number_fields/idealred
 2665258819 2632 ../functions/number_fields/idealstar
@@ -525,18 +537,18 @@
 370962582 1543 ../functions/number_fields/modreverse
 923642746 645 ../functions/number_fields/newtonpoly
 3047290607 580 ../functions/number_fields/nfalgtobasis
-1234825328 5182 ../functions/number_fields/nfbasis
+454214344 5191 ../functions/number_fields/nfbasis
 2678625060 569 ../functions/number_fields/nfbasistoalg
-1941191205 887 ../functions/number_fields/nfcertify
+951961803 996 ../functions/number_fields/nfcertify
 3535461212 3367 ../functions/number_fields/nfcompositum
 1793444342 342 ../functions/number_fields/nfdetint
 4093129155 1539 ../functions/number_fields/nfdisc
 2893425002 219 ../functions/number_fields/nfeltadd
 3704437998 223 ../functions/number_fields/nfeltdiv
-64595969 403 ../functions/number_fields/nfeltdiveuc
+398571300 403 ../functions/number_fields/nfeltdiveuc
 2739572936 524 ../functions/number_fields/nfeltdivmodpr
-2441182165 345 ../functions/number_fields/nfeltdivrem
-1301142194 423 ../functions/number_fields/nfeltmod
+4187029147 345 ../functions/number_fields/nfeltdivrem
+3820883555 423 ../functions/number_fields/nfeltmod
 1895398557 223 ../functions/number_fields/nfeltmul
 366144574 521 ../functions/number_fields/nfeltmulmodpr
 1405889410 145 ../functions/number_fields/nfeltnorm
@@ -550,10 +562,10 @@
 2121867352 818 ../functions/number_fields/nffactorback
 358369482 1049 ../functions/number_fields/nffactormod
 4237468325 2219 ../functions/number_fields/nfgaloisapply
-3907195035 2623 ../functions/number_fields/nfgaloisconj
+251114798 2758 ../functions/number_fields/nfgaloisconj
 439705912 1918 ../functions/number_fields/nfgrunwaldwang
 624126709 736 ../functions/number_fields/nfhilbert
-1057485554 774 ../functions/number_fields/nfhnf
+2030576849 775 ../functions/number_fields/nfhnf
 868333029 539 ../functions/number_fields/nfhnfmod
 3981551268 7883 ../functions/number_fields/nfinit
 1575169407 243 ../functions/number_fields/nfisideal
@@ -561,17 +573,17 @@
 1085970401 276 ../functions/number_fields/nfisisom
 2783715111 448 ../functions/number_fields/nfkermodpr
 3646082924 433 ../functions/number_fields/nfmodprinit
-987402003 612 ../functions/number_fields/nfnewprec
+426574234 698 ../functions/number_fields/nfnewprec
 770708172 1418 ../functions/number_fields/nfroots
 967762132 1587 ../functions/number_fields/nfrootsof1
 118612559 1423 ../functions/number_fields/nfsnf
 1005488227 839 ../functions/number_fields/nfsolvemodpr
-2560370022 1150 ../functions/number_fields/nfsplitting
+2509030408 1308 ../functions/number_fields/nfsplitting
 2732061843 972 ../functions/number_fields/nfsubfields
 2177394093 4011 ../functions/number_fields/polcompositum
 1565615061 4266 ../functions/number_fields/polgalois
 754868682 1743 ../functions/number_fields/polred
-1630097175 4003 ../functions/number_fields/polredabs
+551009513 4099 ../functions/number_fields/polredabs
 2588514985 2291 ../functions/number_fields/polredbest
 2107242093 512 ../functions/number_fields/polredord
 2575474898 466 ../functions/number_fields/poltschirnhaus
@@ -583,12 +595,12 @@
 4170135272 3512 ../functions/number_fields/rnfdedekind
 2250737713 235 ../functions/number_fields/rnfdet
 3226307783 779 ../functions/number_fields/rnfdisc
-2002861846 882 ../functions/number_fields/rnfeltabstorel
-3119689782 909 ../functions/number_fields/rnfeltdown
+2260430731 1249 ../functions/number_fields/rnfeltabstorel
+996578469 1545 ../functions/number_fields/rnfeltdown
 2065307501 537 ../functions/number_fields/rnfeltnorm
 4001592359 757 ../functions/number_fields/rnfeltreltoabs
-1118338923 516 ../functions/number_fields/rnfelttrace
-3421948390 667 ../functions/number_fields/rnfeltup
+1730923846 518 ../functions/number_fields/rnfelttrace
+3701299304 950 ../functions/number_fields/rnfeltup
 1247525550 2180 ../functions/number_fields/rnfequation
 3457630168 562 ../functions/number_fields/rnfhnfbasis
 2122805497 1497 ../functions/number_fields/rnfidealabstorel
@@ -597,10 +609,11 @@
 2972910198 410 ../functions/number_fields/rnfidealmul
 1270402441 572 ../functions/number_fields/rnfidealnormabs
 190446714 445 ../functions/number_fields/rnfidealnormrel
-3520786573 993 ../functions/number_fields/rnfidealreltoabs
+2361069887 1184 ../functions/number_fields/rnfidealprimedec
+2302778415 1646 ../functions/number_fields/rnfidealreltoabs
 3572608050 463 ../functions/number_fields/rnfidealtwoelt
-460503870 915 ../functions/number_fields/rnfidealup
-3156349714 4388 ../functions/number_fields/rnfinit
+2417690823 1420 ../functions/number_fields/rnfidealup
+3871839096 4758 ../functions/number_fields/rnfinit
 3000009520 440 ../functions/number_fields/rnfisabelian
 301910451 511 ../functions/number_fields/rnfisfree
 788695769 2247 ../functions/number_fields/rnfisnorm
@@ -622,7 +635,7 @@
 590656338 526 ../functions/number_theoretical/binomial
 3185714399 1470 ../functions/number_theoretical/charconj
 3427307069 1803 ../functions/number_theoretical/chardiv
-2778805733 2839 ../functions/number_theoretical/chareval
+2575637678 3267 ../functions/number_theoretical/chareval
 4033284932 1618 ../functions/number_theoretical/charker
 1012723684 1801 ../functions/number_theoretical/charmul
 779895998 1401 ../functions/number_theoretical/charorder
@@ -656,13 +669,13 @@
 514753190 536 ../functions/number_theoretical/hilbert
 1861985508 377 ../functions/number_theoretical/isfundamental
 4121111175 479 ../functions/number_theoretical/ispolygonal
-179939414 1208 ../functions/number_theoretical/ispower
+1125156021 1304 ../functions/number_theoretical/ispower
 2327997766 484 ../functions/number_theoretical/ispowerful
 1505640347 2566 ../functions/number_theoretical/isprime
 1951470040 472 ../functions/number_theoretical/isprimepower
 2311445093 1562 ../functions/number_theoretical/ispseudoprime
 137991166 889 ../functions/number_theoretical/ispseudoprimepower
-1582139366 1518 ../functions/number_theoretical/issquare
+2795650729 1851 ../functions/number_theoretical/issquare
 389293029 301 ../functions/number_theoretical/issquarefree
 3038253040 442 ../functions/number_theoretical/istotient
 756622456 758 ../functions/number_theoretical/kronecker
@@ -683,7 +696,7 @@
 3695050800 431 ../functions/number_theoretical/qfbcompraw
 1940983238 339 ../functions/number_theoretical/qfbhclassno
 1449052717 868 ../functions/number_theoretical/qfbnucomp
-1508381386 557 ../functions/number_theoretical/qfbnupow
+558791724 559 ../functions/number_theoretical/qfbnupow
 3393949890 338 ../functions/number_theoretical/qfbpowraw
 3859788640 639 ../functions/number_theoretical/qfbprimeform
 760904670 1434 ../functions/number_theoretical/qfbred
@@ -697,7 +710,7 @@
 376107392 612 ../functions/number_theoretical/quadray
 3392391708 376 ../functions/number_theoretical/quadregulator
 426124966 575 ../functions/number_theoretical/quadunit
-1682666654 973 ../functions/number_theoretical/ramanujantau
+3624678218 982 ../functions/number_theoretical/ramanujantau
 1182031813 521 ../functions/number_theoretical/randomprime
 3397278150 476 ../functions/number_theoretical/removeprimes
 405726717 467 ../functions/number_theoretical/sigma
@@ -708,7 +721,7 @@
 1567067073 613 ../functions/number_theoretical/sumdigits
 3427912235 1761 ../functions/number_theoretical/zncharinduce
 302092918 804 ../functions/number_theoretical/zncharisodd
-819782973 3204 ../functions/number_theoretical/znconreychar
+4259953555 3205 ../functions/number_theoretical/znconreychar
 1342888531 1670 ../functions/number_theoretical/znconreyconductor
 437310249 1172 ../functions/number_theoretical/znconreyexp
 4038022128 3063 ../functions/number_theoretical/znconreylog
@@ -739,7 +752,7 @@
 2143739774 1841 ../functions/polynomials/padicfields
 2394852716 1226 ../functions/polynomials/polchebyshev
 2712207725 629 ../functions/polynomials/polclass
-56811805 1157 ../functions/polynomials/polcoeff
+678454772 1159 ../functions/polynomials/polcoeff
 3865942159 896 ../functions/polynomials/polcyclo
 3980671021 912 ../functions/polynomials/polcyclofactors
 4086899069 742 ../functions/polynomials/poldegree
@@ -752,17 +765,17 @@
 1007436899 437 ../functions/polynomials/poliscyclo
 4075425120 497 ../functions/polynomials/poliscycloprod
 2559408188 460 ../functions/polynomials/polisirreducible
-4266292747 609 ../functions/polynomials/pollead
+1042964227 610 ../functions/polynomials/pollead
 693228044 460 ../functions/polynomials/pollegendre
-3964930825 1976 ../functions/polynomials/polmodular
+3905088352 2248 ../functions/polynomials/polmodular
 803988097 240 ../functions/polynomials/polrecip
-1033208739 1192 ../functions/polynomials/polresultant
+2440423267 1325 ../functions/polynomials/polresultant
 3717931312 827 ../functions/polynomials/polresultantext
 2456631457 760 ../functions/polynomials/polroots
 3629305914 706 ../functions/polynomials/polrootsmod
 943111125 1016 ../functions/polynomials/polrootspadic
-1194699357 1682 ../functions/polynomials/polrootsreal
-3506598208 1229 ../functions/polynomials/polsturm
+1485719917 1683 ../functions/polynomials/polrootsreal
+1898161014 1878 ../functions/polynomials/polsturm
 2495767096 741 ../functions/polynomials/polsubcyclo
 1076716398 656 ../functions/polynomials/polsylvestermatrix
 368684839 285 ../functions/polynomials/polsym
@@ -781,7 +794,7 @@
 3300553752 136 ../functions/programming/_eval_mnemonic
 3140964717 1110 ../functions/programming/addhelp
 455356863 1926 ../functions/programming/alarm
-164541180 1843 ../functions/programming/alias
+783261713 1839 ../functions/programming/alias
 2788866922 4567 ../functions/programming/allocatemem
 3731392400 1596 ../functions/programming/apply
 1649867724 490 ../functions/programming/break
@@ -797,13 +810,13 @@
 3990237234 391 ../functions/programming/extern
 81173858 448 ../functions/programming/externstr
 996397508 680 ../functions/programming/fold
-1154955545 285 ../functions/programming/for
+1255961472 499 ../functions/programming/for
 1548115268 1490 ../functions/programming/forcomposite
 1930174191 1067 ../functions/programming/fordiv
 3117670499 1243 ../functions/programming/forell
 3742891725 2400 ../functions/programming/forpart
-523389040 2355 ../functions/programming/forprime
-4097689279 583 ../functions/programming/forstep
+3688771296 2368 ../functions/programming/forprime
+2633877607 807 ../functions/programming/forstep
 3286177718 2061 ../functions/programming/forsubgroup
 1709670923 1664 ../functions/programming/forvec
 1907835141 413 ../functions/programming/getabstime
@@ -837,8 +850,8 @@
 1218387207 521 ../functions/programming/next
 315903861 794 ../functions/programming/parapply
 407023495 541 ../functions/programming/pareval
-1090038910 2896 ../functions/programming/parfor
-1026623267 1237 ../functions/programming/parforprime
+3165113240 2908 ../functions/programming/parfor
+2649126709 1249 ../functions/programming/parforprime
 3140741283 891 ../functions/programming/parforvec
 325469141 592 ../functions/programming/parselect
 2300142208 700 ../functions/programming/parsum
@@ -877,7 +890,7 @@
 4129426728 853 ../functions/sums/intcirc
 902570078 3367 ../functions/sums/intfuncinit
 2707919828 11921 ../functions/sums/intnum
-1608062557 1461 ../functions/sums/intnumgauss
+909253658 1452 ../functions/sums/intnumgauss
 3935972398 1257 ../functions/sums/intnumgaussinit
 324700532 2520 ../functions/sums/intnuminit
 2779074491 2930 ../functions/sums/intnumromb
@@ -886,17 +899,17 @@
 238922829 499 ../functions/sums/prodeuler
 204042442 902 ../functions/sums/prodinf
 1616562532 713 ../functions/sums/solve
-612303806 1297 ../functions/sums/solvestep
+716781834 1249 ../functions/sums/solvestep
 1209900028 648 ../functions/sums/sum
-1049110964 3336 ../functions/sums/sumalt
+2099191006 3331 ../functions/sums/sumalt
 2396474070 511 ../functions/sums/sumdiv
 3260846671 413 ../functions/sums/sumdivmult
 3870625566 1157 ../functions/sums/suminf
-369465132 5048 ../functions/sums/sumnum
+3484624669 5038 ../functions/sums/sumnum
 179885008 999 ../functions/sums/sumnuminit
 3576641612 961 ../functions/sums/sumnummonien
 89272281 3543 ../functions/sums/sumnummonieninit
-3661026317 2149 ../functions/sums/sumpos
+2889985823 2151 ../functions/sums/sumpos
 655643124 1286 ../functions/symbolic_operators/add
 3353925834 892 ../functions/symbolic_operators/adde
 2224582694 150 ../functions/symbolic_operators/and
@@ -970,16 +983,16 @@
 3039924894 124 ../functions/transcendental/cotan
 1591771947 149 ../functions/transcendental/cotanh
 3749138764 232 ../functions/transcendental/dilog
-1358921222 1230 ../functions/transcendental/eint1
+1947572737 1232 ../functions/transcendental/eint1
 2742925928 351 ../functions/transcendental/erfc
 1932581236 1106 ../functions/transcendental/eta
 162213116 389 ../functions/transcendental/exp
 1493676057 991 ../functions/transcendental/expm1
 283840075 815 ../functions/transcendental/gamma
 2489052783 171 ../functions/transcendental/gammah
-663162355 653 ../functions/transcendental/gammamellininv
+2185461905 645 ../functions/transcendental/gammamellininv
 1838130584 1133 ../functions/transcendental/gammamellininvasymp
-4231723788 1496 ../functions/transcendental/gammamellininvinit
+3209774203 1488 ../functions/transcendental/gammamellininvinit
 1703809654 306 ../functions/transcendental/hyperu
 2351714423 626 ../functions/transcendental/incgam
 1394040053 409 ../functions/transcendental/incgamc
diff --git a/src/functions/default/factor_add_primes b/src/functions/default/factor_add_primes
index 2050596..fe91e20 100644
--- a/src/functions/default/factor_add_primes
+++ b/src/functions/default/factor_add_primes
@@ -5,8 +5,8 @@ C-Name: sd_factor_add_primes
 Prototype:
 Help:
 Doc: this toggle is either 1 (on) or 0 (off). If on,
- the integer factorization machinery calls \tet{addprimes} on primes
- factor that were difficult to find (larger than $2^24$), so they are
+ the integer factorization machinery calls \tet{addprimes} on prime
+ factors that were difficult to find (larger than $2^{24}$), so they are
  automatically tried first in other factorizations. If a routine is performing
  (or has performed) a factorization and is interrupted by an error or via
  Control-C, this lets you recover the prime factors already found. The
diff --git a/src/functions/elliptic_curves/ellmoddegree b/src/functions/elliptic_curves/ellmoddegree
index 92ee3d2..5841371 100644
--- a/src/functions/elliptic_curves/ellmoddegree
+++ b/src/functions/elliptic_curves/ellmoddegree
@@ -1,6 +1,6 @@
 Function: ellmoddegree
 Section: elliptic_curves
-C-Name: ellmoddegree_bitprec
+C-Name: ellmoddegree
 Prototype: Gb
 Help: ellmoddegree(e): e being an elliptic curve defined over Q output by
   ellinit, compute the modular degree of e divided by the square of the
diff --git a/src/functions/elliptic_curves/ellnonsingularmultiple b/src/functions/elliptic_curves/ellnonsingularmultiple
index 2c442e0..1048d51 100644
--- a/src/functions/elliptic_curves/ellnonsingularmultiple
+++ b/src/functions/elliptic_curves/ellnonsingularmultiple
@@ -2,7 +2,10 @@ Function: ellnonsingularmultiple
 Section: elliptic_curves
 C-Name: ellnonsingularmultiple
 Prototype: GG
-Help: ellnonsingularmultiple(E,P):
+Help: ellnonsingularmultiple(E,P): given E/Q and P in E(Q), returns the pair
+ [R,n] where n is the least positive integer such that R = [n]P has
+ everywhere good reduction. More precisely, its image in a minimal model
+ is everywhere non-singular.
 Doc: given an elliptic curve $E/\Q$ (more precisely, a model defined over $\Q$
  of a curve) and a rational point $P \in E(\Q)$, returns the pair $[R,n]$,
  where $n$ is the least positive integer such that $R := [n]P$ has good
diff --git a/src/functions/elliptic_curves/ellpadicL b/src/functions/elliptic_curves/ellpadicL
index 592438a..ee5eb92 100644
--- a/src/functions/elliptic_curves/ellpadicL
+++ b/src/functions/elliptic_curves/ellpadicL
@@ -1,64 +1,107 @@
 Function: ellpadicL
 Section: elliptic_curves
 C-Name: ellpadicL
-Prototype: GGLD0,L,DGDG
-Help: ellpadicL(E, p, n, {r = 0}, {D}, {char}): returns the value
-  on a character of the derivative of order r of the L-function of
-  the elliptic curve E (twisted by D > 0, if present). For the moment, only
-  the case of the trivial character is implemented
-Doc:
-  The $p$-adic $L$ function is defined on the set of continuous characters
-  of $\text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$, identified to $\Z_p^*$
-  via the cyclotomic character $\chi_p$ with values in $\overline{\Q_p}^*$.
-  Denote by $\tau:\Z_p^*\to\Z_p^*$ the Teichm\"uller character.
+Prototype: GGLDGD0,L,DG
+Help: ellpadicL(E, p, n, {s = 0}, {r = 0}, {D = 1}): returns the value
+ on a character of Z_p^* represented by an integer s or a vector [s1,s2]
+ of the derivative of order r of the p-adic L-function of
+ the elliptic curve E (twisted by D, if present).
+Doc: Returns the value (or $r$-th derivative) on a character $\chi^s$ of
+ $\Z_p^*$ of the $p$-adic $L$-function of the elliptic curve $E/\Q$, twisted by
+ $D$, given modulo $p^n$.
 
-  When $E$ has good supersingular reduction, the $L$ function takes its
-  values in $\Q_p \otimes H^1_{dR}(E/\Q)$ and satisfies
-  $$(1-p^{-1} F)^{-2} L_p(E, \tau^0)= (L(E,1) / \Omega) \cdot \omega$$
-  where $F$ is the Frobenius, $L(E,1)$ is the value of the complex $L$
-  function at $1$, $\omega$ is the N\'eron differential
-  and $\Omega$ its associated period on $E(\R)$. Here, $\tau^0$ represents
-  the trivial character.
+ \misctitle{Characters} The set of continuous characters of
+ $\text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$ is identified to $\Z_p^*$ via the
+ cyclotomic character $\chi$ with values in $\overline{\Q_p}^*$. Denote by
+ $\tau:\Z_p^*\to\Z_p^*$ the Teichm\"uller character, with values
+ in the $(p-1)$-th roots of $1$ for $p\neq 2$, and $\{-1,1\}$ for $p = 2$;
+ finally, let
+ $\langle\chi\rangle =\chi \tau^{-1}$, with values in $1 + 2p\Z_p$.
+ In GP, the continuous character of
+ $\text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$ given by $\langle\chi\rangle^{s_1}
+ \tau^{s_2}$ is represented by the pair of integers $s=(s_1,s_2)$, with $s_1
+ \in \Z_p$ and $s_2 \bmod p-1$ for $p > 2$, (resp. mod $2$ for $p = 2$); $s$
+ may be also an integer, representing $(s,s)$ or $\chi^s$.
 
-  The derivative is taken at $s=1$ along $\langle\chi_p^s\rangle$.
-  In other words, the function $L_p$ is defined as
-  $\int_{\Z_p^*} d \mu$ for a certain $p$-adic distribution $\mu$ on
-  $\Z_p^*$, and we have
-   $$L_p^{(r)}(E, \tau^0) = \int_{\Z_p^*} \log_p^r(a) d\mu(a).$$
-  The function returns the components of $L_p{(r)}(E,\tau^0)$ in
-  the basis $(\omega, F(\omega))$.
-  \smallskip
+ \misctitle{The $p$-adic $L$ function}
+ The $p$-adic $L$ function $L_p$ is defined on the set of continuous
+ characters of $\text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$, as $\int_{\Z_p^*}
+ \chi^s d \mu$ for a certain $p$-adic distribution $\mu$ on $\Z_p^*$. The
+ derivative is given by
+ $$L_p^{(r)}(E, \chi^s) = \int_{\Z_p^*} \log_p^r(a) \chi^s(a) d\mu(a).$$
+ More precisely:
 
-  When $E$ has ordinary good reduction, this method only defines
-  the projection of $L_p(E,\tau^0)$ on the $\alpha$-eigenspace,
-  where $\alpha$ is the unit eigenvalue for $F$. This is what the function
-  returns. This value satisfies
-  $$(1- \alpha^{-1})^{-2} L_{p,\alpha}(E,\tau^0)= L(E,1) / \Omega.$$
+ \item When $E$ has good supersingular reduction, $L_p$ takes its
+ values in $\Q_p \otimes H^1_{dR}(E/\Q)$ and satisfies
+ $$(1-p^{-1} F)^{-2} L_p(E, \chi^0)= (L(E,1) / \Omega) \cdot \omega$$
+ where $F$ is the Frobenius, $L(E,1)$ is the value of the complex $L$
+ function at $1$, $\omega$ is the N\'eron differential
+ and $\Omega$ the attached period on $E(\R)$. Here, $\chi^0$ represents
+ the trivial character.
 
-  \bprog
-  ? cxL(e) = bestappr( ellL1(e,0) / e.omega[1] );
+ The function returns the components of $L_p^{(r)}(E,\chi^s)$ in
+ the basis $(\omega, F(\omega))$.
 
-  ? e = ellinit("17a1"); p=3; \\ supersingular
-  ? L = ellpadicL(e,p,4);
-  ? F = [0,-p;1,ellap(e,p)]; \\ Frobenius matrix in the basis (omega,F(omega)
-  ? (1-p^(-1)*F)^-2 * L~ / cxL(e)
-  %5 = [1 + O(3^4), O(3^4)]~
+ \item When $E$ has ordinary good reduction, this method only defines
+ the projection of $L_p(E,\chi^s)$ on the $\alpha$-eigenspace,
+ where $\alpha$ is the unit eigenvalue for $F$. This is what the function
+ returns. We have
+ $$(1- \alpha^{-1})^{-2} L_{p,\alpha}(E,\chi^0)= L(E,1) / \Omega.$$
 
-  ? p=5; ap = ellap(e,p); \\ ordinary
-  ? L = ellpadicL(e,p,4);
-  ? al = padicappr(x^2 - ap*x + p, ap + O(p^7))[1];
-  ? (1-al^(-1))^(-2) * L / cxL(e)
-  %10 = 1 + O(5^4)
+ Two supersingular examples:
+ \bprog
+ ? cxL(e) = bestappr( ellL1(e) / e.omega[1] );
 
-  ? e = ellinit("116a1"); p=3; \\ supersingular
-  ? L = ellpadicL(e,p,4);
-  ? F = [0,-p; 1,ellap(e,p)];
-  ? (1-p^(-1)*F)^-2*L~ / cxL(e)
-  %15 = [1 + O(3^4), O(3^5)]~
+ ? e = ellinit("17a1"); p=3; \\ supersingular, a3 = 0
+ ? L = ellpadicL(e,p,4);
+ ? F = [0,-p;1,ellap(e,p)]; \\ Frobenius matrix in the basis (omega,F(omega))
+ ? (1-p^(-1)*F)^-2 * L / cxL(e)
+ %5 = [1 + O(3^5), O(3^5)]~ \\ [1,0]~
 
-  ? e = ellinit("26b1"); p=3;
-  ? L = ellpadicL(e,p,4);
-  ? F = [0,-p;1,ellap(e,p)];
-  ? (1-p^(-1)*F)^-2*L~ / cxL(e)
-  %20 = [1 + O(3^4), O(3^5)]~
-  @eprog
+ ? e = ellinit("116a1"); p=3; \\ supersingular, a3 != 0~
+ ? L = ellpadicL(e,p,4);
+ ? F = [0,-p; 1,ellap(e,p)];
+ ? (1-p^(-1)*F)^-2*L~ / cxL(e)
+ %9 = [1 + O(3^4), O(3^5)]~
+ @eprog
+
+ Good ordinary reduction:
+ \bprog
+ ? e = ellinit("17a1"); p=5; ap = ellap(e,p)
+ %1 = -2 \\ ordinary
+ ? L = ellpadicL(e,p,4)
+ %2 = 4 + 3*5 + 4*5^2 + 2*5^3 + O(5^4)
+ ? al = padicappr(x^2 - ap*x + p, ap + O(p^7))[1];
+ ? (1-al^(-1))^(-2) * L / cxL(e)
+ %4 = 1 + O(5^4)
+ @eprog
+
+ Twist and Teichm\"uller:
+ \bprog
+ ? e = ellinit("17a1"); p=5; \\ ordinary
+ \\ 2nd derivative at \tau^1, twist by -7
+ ? ellpadicL(e, p, 4, [0,1], 2, -7)
+ %2 = 2*5^2 + 5^3 + O(5^4)
+ @eprog
+
+ This function is a special case of \tet{mspadicL}, and it also appears
+ as the first term of \tet{mspadicseries}:
+ \bprog
+ ? e = ellinit("17a1"); p=5;
+ ? L = ellpadicL(e,p,4)
+ %2 = 4 + 3*5 + 4*5^2 + 2*5^3 + O(5^4)
+ ? [M,phi] = msfromell(e, 1);
+ ? Mp = mspadicinit(M, p, 4);
+ ? mu = mspadicmoments(Mp, phi);
+ ? mspadicL(mu)
+ %6 = 4 + 3*5 + 4*5^2 + 2*5^3 + 2*5^4 + 5^5 + O(5^6)
+ ? mspadicseries(mu)
+ %7 = (4 + 3*5 + 4*5^2 + 2*5^3 + 2*5^4 + 5^5 + O(5^6))
+       + (3 + 3*5 + 5^2 + 5^3 + O(5^4))*x
+       + (2 + 3*5 + 5^2 + O(5^3))*x^2
+       + (3 + 4*5 + 4*5^2 + O(5^3))*x^3
+       + (3 + 2*5 + O(5^2))*x^4 + O(x^5)
+ @eprog\noindent These are more cumbersome than \kbd{ellpadicL} but allow to
+ compute at different characters, or successive derivatives, or to
+ twist by a quadratic character essentially for the cost of a single call to
+ \kbd{ellpadicL} due to precomputations.
diff --git a/src/functions/elliptic_curves/genus2red b/src/functions/elliptic_curves/genus2red
index 1bea4ce..3797b1f 100644
--- a/src/functions/elliptic_curves/genus2red
+++ b/src/functions/elliptic_curves/genus2red
@@ -19,7 +19,7 @@ Doc: Let $P$ be a polynomial with rational coefficients.
 
  \noindent This function was rewritten from an implementation of Liu's
  algorithm by Cohen and Liu (1994), \kbd{genus2reduction-0.3}, see
- \url{http://www.math.u-bordeaux1.fr/~liu/G2R/}.
+ \url{http://www.math.u-bordeaux.fr/~liu/G2R/}.
 
  \misctitle{CAVEAT} The function interface may change: for the
  time being, it returns $[N,\var{FaN}, T, V]$
diff --git a/src/functions/elliptic_curves/hyperellpadicfrobenius b/src/functions/elliptic_curves/hyperellpadicfrobenius
index 15f264e..be5511e 100644
--- a/src/functions/elliptic_curves/hyperellpadicfrobenius
+++ b/src/functions/elliptic_curves/hyperellpadicfrobenius
@@ -3,13 +3,14 @@ Section: elliptic_curves
 C-Name: hyperellpadicfrobenius
 Prototype: GUL
 Help: hyperellpadicfrobenius(Q,p,n): Q being a  rational polynomial of degree
- d, return the matrix of the Frobenius at p>=d in the standard
- basis of H^1_dR(E) to absolute p-adic precision p^n.
+ d and X being the curve defined by y^2=Q(x), return the matrix of the
+ Frobenius at p>=d in the standard basis of H^1_dR(X) to absolute p-adic
+ precision p^n.
 Doc:
  Let $X$ be the curve defined by $y^2=Q(x)$, where  $Q$ is a polynomial of
  degree $d$ over $\Q$ and $p\ge d$ a prime such that $X$ has good reduction
  at $p$ return the matrix of the Frobenius endomorphism $\varphi$ on the
- crystalline module $D_p(E) = \Q_p \otimes H^1_{dR}(E/\Q)$ with respect to the
+ crystalline module $D_p(X) = \Q_p \otimes H^1_{dR}(X/\Q)$ with respect to the
  basis of the given model $(\omega, x\*\omega,\ldots,x^{g-1}\*\omega)$, where
  $\omega = dx/(2\*y)$ is the invariant differential, where $g$ is the genus of
  $X$ (either $d=2\*g+1$ or $d=2\*g+2$).  The characteristic polynomial of
diff --git a/src/functions/gp2c_internal/_norange b/src/functions/gp2c_internal/_norange
new file mode 100644
index 0000000..d2b5a23
--- /dev/null
+++ b/src/functions/gp2c_internal/_norange
@@ -0,0 +1,5 @@
+Function: _norange
+Class: gp2c_internal
+Description:
+ ():small    LONG_MAX
+
diff --git a/src/functions/l_functions/lfun b/src/functions/l_functions/lfun
index 951d2b1..2301804 100644
--- a/src/functions/l_functions/lfun
+++ b/src/functions/l_functions/lfun
@@ -1,14 +1,14 @@
 Function: lfun
 Section: l_functions
-C-Name: lfun0_bitprec
+C-Name: lfun0
 Prototype: GGD0,L,b
 Help: lfun(L,s,{D=0}): compute the L-function value L(s), or
  if D is set, the derivative of order D at s. L is either an
  Lmath, an Ldata or an Linit.
 Description:
- (gen,gen):gen:prec       lfun_bitprec($1, $2, $bitprec)
- (gen,gen,?0):gen:prec    lfun_bitprec($1, $2, $bitprec)
- (gen,gen,small):gen:prec lfun0_bitprec($1, $2, $3, $bitprec)
+ (gen,gen):gen:prec       lfun($1, $2, $bitprec)
+ (gen,gen,?0):gen:prec    lfun($1, $2, $bitprec)
+ (gen,gen,small):gen:prec lfun0($1, $2, $3, $bitprec)
 Doc: compute the L-function value $L(s)$, or if \kbd{D} is set, the
  derivative of order \kbd{D} at $s$. The parameter
  \kbd{L} is either an Lmath, an Ldata (created by \kbd{lfuncreate}, or an
diff --git a/src/functions/l_functions/lfunabelianrelinit b/src/functions/l_functions/lfunabelianrelinit
index 74cbdec..194d687 100644
--- a/src/functions/l_functions/lfunabelianrelinit
+++ b/src/functions/l_functions/lfunabelianrelinit
@@ -1,6 +1,6 @@
 Function: lfunabelianrelinit
 Section: l_functions
-C-Name: lfunabelianrelinit_bitprec
+C-Name: lfunabelianrelinit
 Prototype: GGGGD0,L,b
 Help: lfunabelianrelinit(bnfL,bnfK,polrel,sdom,{der=0}): returns the
   Linit structure associated to the Dedekind zeta function of the number field
diff --git a/src/functions/l_functions/lfuncheckfeq b/src/functions/l_functions/lfuncheckfeq
index 4dea355..a11e18a 100644
--- a/src/functions/l_functions/lfuncheckfeq
+++ b/src/functions/l_functions/lfuncheckfeq
@@ -1,6 +1,6 @@
 Function: lfuncheckfeq
 Section: l_functions
-C-Name: lfuncheckfeq_bitprec
+C-Name: lfuncheckfeq
 Prototype: lGDGb
 Help: lfuncheckfeq(L,{t}): given an L-function (Lmath, Ldata or Linit),
  check whether the functional equation is satisfied. If the function has
diff --git a/src/functions/l_functions/lfunconductor b/src/functions/l_functions/lfunconductor
index cf8d6fc..1b7af46 100644
--- a/src/functions/l_functions/lfunconductor
+++ b/src/functions/l_functions/lfunconductor
@@ -1,6 +1,6 @@
 Function: lfunconductor
 Section: l_functions
-C-Name: lfunconductor_bitprec
+C-Name: lfunconductor
 Prototype: GDGD0,L,b
 Help: lfunconductor(L,{ab=[1,10000]},{flag=0}): give the conductor
   of the given L-function; ab = [a,b] is the interval where we expect
diff --git a/src/functions/l_functions/lfuncost b/src/functions/l_functions/lfuncost
index f90f5cb..dd4f8b8 100644
--- a/src/functions/l_functions/lfuncost
+++ b/src/functions/l_functions/lfuncost
@@ -59,3 +59,7 @@ Doc: estimate the cost of running
  For a total of three $L$-functions evaluations, which explains the three
  components above. Note that the actual cost is much lower than the a priori
  cost in this case.
+Variant: Also available is
+ \fun{GEN}{lfuncost}{GEN L, GEN dom, long der, long bitprec}
+ when $L$ is \emph{not} an \kbd{Linit}; the return value is a \typ{VECSMALL}
+ in this case.
diff --git a/src/functions/l_functions/lfundiv b/src/functions/l_functions/lfundiv
index 2b3fa71..13002eb 100644
--- a/src/functions/l_functions/lfundiv
+++ b/src/functions/l_functions/lfundiv
@@ -1,7 +1,7 @@
 Function: lfundiv
 Section: l_functions
 C-Name: lfundiv
-Prototype: GGp
+Prototype: GGb
 Help: lfundiv(L1,L2): creates the Ldata structure (without
   initialization) corresponding to the quotient of the Dirichlet series
   given by L1 and L2.
diff --git a/src/functions/l_functions/lfungenus2 b/src/functions/l_functions/lfungenus2
new file mode 100644
index 0000000..b1b5117
--- /dev/null
+++ b/src/functions/l_functions/lfungenus2
@@ -0,0 +1,15 @@
+Function: lfungenus2
+Section: l_functions
+C-Name: lfungenus2
+Prototype: G
+Help: lfungenus2(F): returns the Ldata structure associated to the
+ L-function associated to the genus-2 curve defined by y^2=F(x)
+ or y^2+Q(x)*y=P(x) if F=[P,Q].
+ Currently, only odd conductors are supported, and the model needs to
+ be minimal at 2.
+Doc: returns the \kbd{Ldata} structure associated to the $L$ function
+ associated to the genus-2 curve defined by $y^2=F(x)$ or
+ $y^2+Q(x)\*y=P(x)$ if $F=[P,Q]$.
+ Currently, the model needs to be minimal at 2, and if the conductor
+ is even, its valuation at $2$ might be incorrect (a warning is issued).
+
diff --git a/src/functions/l_functions/lfunhardy b/src/functions/l_functions/lfunhardy
index fd4f042..bbe2925 100644
--- a/src/functions/l_functions/lfunhardy
+++ b/src/functions/l_functions/lfunhardy
@@ -1,6 +1,6 @@
 Function: lfunhardy
 Section: l_functions
-C-Name: lfunhardy_bitprec
+C-Name: lfunhardy
 Prototype: GGb
 Help: lfunhardy(L,t): Variant of the Hardy L-function corresponding to
  L, used for plotting on the critical line, see ??lfunhardy for the precise
diff --git a/src/functions/l_functions/lfuninit b/src/functions/l_functions/lfuninit
index 7dc145f..beed912 100644
--- a/src/functions/l_functions/lfuninit
+++ b/src/functions/l_functions/lfuninit
@@ -1,6 +1,6 @@
 Function: lfuninit
 Section: l_functions
-C-Name: lfuninit0_bitprec
+C-Name: lfuninit0
 Prototype: GGD0,L,b
 Help: lfuninit(L,sdom,{der=0}): precompute data
  for evaluating the L-function given by 'L' (and its derivatives
diff --git a/src/functions/l_functions/lfunlambda b/src/functions/l_functions/lfunlambda
index 6f0f90c..93c31db 100644
--- a/src/functions/l_functions/lfunlambda
+++ b/src/functions/l_functions/lfunlambda
@@ -1,6 +1,6 @@
 Function: lfunlambda
 Section: l_functions
-C-Name: lfunlambda0_bitprec
+C-Name: lfunlambda0
 Prototype: GGD0,L,b
 Help: lfunlambda(L,s,{D=0}): compute the completed L function Lambda(s),
  or if D is set, the derivative of order D at s. L is either
diff --git a/src/functions/l_functions/lfunmfpeters b/src/functions/l_functions/lfunmfpeters
index f382f58..222c0df 100644
--- a/src/functions/l_functions/lfunmfpeters
+++ b/src/functions/l_functions/lfunmfpeters
@@ -1,11 +1,16 @@
 Function: lfunmfpeters
 Section: l_functions
-C-Name: lfunmfpeters_bitprec
+C-Name: lfunmfpeters
 Prototype: Gb
 Help: lfunmfpeters(L): L corresponding to a normalized
-  eigenform but NOT to the output of lfunsymsq, returns the Petersson
-  square of the form, computed using the symmetric square.
+ eigenform but NOT to the output of lfunsymsq, returns the Petersson
+ square of the form, computed using the symmetric square.
 Doc: \kbd{L} corresponding to a normalized eigenform but {\bf not}
-  to the output of \kbd{lfunsymsq}, returns the Petersson square of the
-  form, computed using the symmetric square.
-
+ to the output of \kbd{lfunsymsq}, returns the Petersson square of the
+ form, computed using the symmetric square.
+ \bprog
+ ? e = ellinit([-2,1]);
+ ? L = lfuncreate(e);
+ ? lfunmfpeters(L) * (2*Pi)^2 / e.area
+ %2 = 0.99999999999999999999999999999999999999
+ @eprog
diff --git a/src/functions/l_functions/lfunmfspec b/src/functions/l_functions/lfunmfspec
index 0116314..dcc905a 100644
--- a/src/functions/l_functions/lfunmfspec
+++ b/src/functions/l_functions/lfunmfspec
@@ -1,6 +1,6 @@
 Function: lfunmfspec
 Section: l_functions
-C-Name: lfunmfspec_bitprec
+C-Name: lfunmfspec
 Prototype: Gb
 Help: lfunmfspec(L): L corresponding to a modular form, returns
   [valeven,valodd,omminus,omplus], where valeven (resp., valodd) is the vector
diff --git a/src/functions/l_functions/lfunmul b/src/functions/l_functions/lfunmul
index a5dd7d2..c303fd3 100644
--- a/src/functions/l_functions/lfunmul
+++ b/src/functions/l_functions/lfunmul
@@ -1,7 +1,7 @@
 Function: lfunmul
 Section: l_functions
 C-Name: lfunmul
-Prototype: GGp
+Prototype: GGb
 Help: lfunmul(L1,L2): creates the Ldata structure (without
   initialization) corresponding to the product of the Dirichlet series
   given by L1 and L2.
diff --git a/src/functions/l_functions/lfunorderzero b/src/functions/l_functions/lfunorderzero
index 1991990..16e8976 100644
--- a/src/functions/l_functions/lfunorderzero
+++ b/src/functions/l_functions/lfunorderzero
@@ -1,6 +1,6 @@
 Function: lfunorderzero
 Section: l_functions
-C-Name: lfunorderzero_bitprec
+C-Name: lfunorderzero
 Prototype: lGb
 Help: lfunorderzero(L): computes the order of the possible zero
  of the L-function at the center k/2 of the critical strip.
diff --git a/src/functions/l_functions/lfunrootres b/src/functions/l_functions/lfunrootres
index 9c4ffcc..54f685d 100644
--- a/src/functions/l_functions/lfunrootres
+++ b/src/functions/l_functions/lfunrootres
@@ -1,6 +1,6 @@
 Function: lfunrootres
 Section: l_functions
-C-Name: lfunrootres_bitprec
+C-Name: lfunrootres
 Prototype: Gb
 Help: lfunrootres(data): given the Ldata associated to an L-function (or the
  output of lfunthetainit), compute the root number and the
diff --git a/src/functions/l_functions/lfunsymsqspec b/src/functions/l_functions/lfunsymsqspec
index b8c1613..4088b52 100644
--- a/src/functions/l_functions/lfunsymsqspec
+++ b/src/functions/l_functions/lfunsymsqspec
@@ -1,6 +1,6 @@
 Function: lfunsymsqspec
 Section: l_functions
-C-Name: lfunsymsqspec_bitprec
+C-Name: lfunsymsqspec
 Prototype: Gb
 Help: lfunsymsqspec(L): Ldata corresponding either to a normalized
   eigenform or to the output of lfunsymsq, returns [val, om2], where val
diff --git a/src/functions/l_functions/lfuntheta b/src/functions/l_functions/lfuntheta
index 0c7faf3..03f12ad 100644
--- a/src/functions/l_functions/lfuntheta
+++ b/src/functions/l_functions/lfuntheta
@@ -1,6 +1,6 @@
 Function: lfuntheta
 Section: l_functions
-C-Name: lfuntheta_bitprec
+C-Name: lfuntheta
 Prototype: GGD0,L,b
 Help: lfuntheta(data,t,{m=0}): compute the value of the m-th derivative
  at t of the theta function associated to the L-function given by data.
diff --git a/src/functions/l_functions/lfunthetainit b/src/functions/l_functions/lfunthetainit
index 5e5343c..f89c254 100644
--- a/src/functions/l_functions/lfunthetainit
+++ b/src/functions/l_functions/lfunthetainit
@@ -1,6 +1,6 @@
 Function: lfunthetainit
 Section: l_functions
-C-Name: lfunthetainit_bitprec
+C-Name: lfunthetainit
 Prototype: GDGD0,L,b
 Help: lfunthetainit(L,{tdom},{m=0}): precompute data for evaluating
   the m-th derivative of theta functions with argument in domain tdom
diff --git a/src/functions/l_functions/lfunzeros b/src/functions/l_functions/lfunzeros
index 45322cd..3807806 100644
--- a/src/functions/l_functions/lfunzeros
+++ b/src/functions/l_functions/lfunzeros
@@ -1,6 +1,6 @@
 Function: lfunzeros
 Section: l_functions
-C-Name: lfunzeros_bitprec
+C-Name: lfunzeros
 Prototype: GGD8,L,b
 Help: lfunzeros(L,lim,{divz=8}): lim being
  either an upper limit or a real interval, computes an ordered list of
diff --git a/src/functions/linear_algebra/qfisominit b/src/functions/linear_algebra/qfisominit
index 46a791d..5ef89c9 100644
--- a/src/functions/linear_algebra/qfisominit
+++ b/src/functions/linear_algebra/qfisominit
@@ -1,9 +1,9 @@
 Function: qfisominit
 Section: linear_algebra
 C-Name: qfisominit0
-Prototype: GDG
-Help: qfisominit(G,{fl}): G being a square and symmetric matrix representing an
- integral positive definite quadratic form, this function return a structure
+Prototype: GDGDG
+Help: qfisominit(G,{fl},{m}): G being a square and symmetric matrix representing an
+ integral positive definite quadratic form, this function returns a structure
  allowing to compute isomorphisms between G and other quadratic form faster.
 Doc:
  $G$ being a square and symmetric matrix with integer entries representing a
@@ -21,8 +21,10 @@ Doc:
 
  \item \kbd{fl[2]} Maximum level of Bacher polynomials to use.
 
- Since this function computes the minimal vectors, it can become very lengthy
- as the dimension of $G$ grows.
+ If present, $m$ must be the set of vectors of norm up to the maximal of the
+ diagonal entry of $G$, either as a matrix or as given by \kbd{qfminim}.
+ Otherwise this function computes the minimal vectors so it become very
+ lengthy as the dimension of $G$ grows.
 Variant: Also available is
  \fun{GEN}{qfisominit}{GEN F, GEN fl}
  where $F$ is a vector of \kbd{zm}.
diff --git a/src/functions/linear_algebra/vecsort b/src/functions/linear_algebra/vecsort
index 4408b3a..9600ffd 100644
--- a/src/functions/linear_algebra/vecsort
+++ b/src/functions/linear_algebra/vecsort
@@ -6,9 +6,8 @@ Help: vecsort(x,{cmpf},{flag=0}): sorts the vector of vectors (or matrix) x in
  ascending order, according to the comparison function cmpf, if not omitted.
  (If cmpf is an integer, sort according to the value of the k-th component
  of each entry.) Binary digits of flag (if present) mean: 1: indirect sorting,
- return the permutation instead of the permuted vector, 2: sort using
- lexicographic order, 4: use descending instead of ascending order, 8: remove
- duplicate entries.
+ return the permutation instead of the permuted vector, 4: use descending
+ instead of ascending order, 8: remove duplicate entries.
 Description:
  (vecsmall,?gen):vecsmall       vecsort0($1, $2, 0)
  (vecsmall,?gen,small):vecsmall vecsort0($1, $2, $3)
diff --git a/src/functions/modular_forms/msfromell b/src/functions/modular_forms/msfromell
deleted file mode 100644
index bfdcee9..0000000
--- a/src/functions/modular_forms/msfromell
+++ /dev/null
@@ -1,39 +0,0 @@
-Function: msfromell
-Section: modular_forms
-C-Name: msfromell
-Prototype: GD0,L,
-Help: msfromell(E, {sign=0}): return the [M, x], where M is msinit(N,2)
- and x is the modular symbol in M associated to the elliptic curve E/Q.
-Doc: Let $E/\Q$ be an elliptic curve of conductor $N$. For $\varepsilon =
- \pm1$, we define the (cuspidal, new) modular symbol $x^\varepsilon$ in
- $H^1_c(X_0(N),\Q)^\varepsilon$  associated to
- $E$. For all primes $p$ not dividing $N$ we have
- $T_p(x^\varepsilon) =  a_p x^\varepsilon$, where $a_p = p+1-\#E(\F_p)$.
- For each choice of sign, this defines a unique symbol up to multiplication by
- a constant and we normalize it so that the associated $p$-adic measure yields
- the $p$-adic $L$-function. Namely, we have
- $$ x^\varepsilon([0]-[\infty]) = L(E,1) / \Omega,$$
- for $\Omega$ the real period of $E$ (this defines $x^{\pm}$ unless $L(E,1)=0$).
- Furthermore, for all fundamental discriminants $d$ coprime to $2N$ such
- that $\varepsilon \cdot d > 0$ and $L(E^{(d)},1) \neq 0$, we also have
- $$\sum_{0\leq a<|d|} (d|a) x^\varepsilon([a/|d|]-[\infty])
-    = L(E^{(d)},1) / \Omega_d,$$
- where $(d|a)$ is the Kronecker symbol and $\Omega_d$ is the real
- period of the twist $E^{(d)}$.
-
- This function returns the pair $[M, x]$, where $M$ is
- \kbd{msinit}$(N,2)$ and $x$ is $x^{\var{sign}}$ as above when $\var{sign}=
- \pm1$, and $x = [x^+,x^-]$ when \var{sign} is $0$.
- The modular symbols $x^\pm$ are given as a \typ{COL} (in terms
- of the fixed basis of $\text{Hom}_G(\Delta,\Q)$ chosen in $M$).
- \bprog
- ? E=ellinit([0,-1,1,-10,-20]);  \\ X_0(11)
- ? [M,xp]= msfromell(E,1);
- ? xp
- %3 = [1/5, -1/2, -1/2]~
- ? [M,x]= msfromell(E);
- ? x    \\ both x^+ and x^-
- %5 = [[1/5, -1/2, -1/2]~, [0, 1/2, -1/2]~]
- ? p = 101; (mshecke(M,p) - ellap(E,p))*x[1]
- %4 = [0, 0, 0]~ \\ true at all primes; same for x[2]
- @eprog
diff --git a/src/functions/modular_forms/msatkinlehner b/src/functions/modular_symbols/msatkinlehner
similarity index 97%
rename from src/functions/modular_forms/msatkinlehner
rename to src/functions/modular_symbols/msatkinlehner
index 8d95ab8..12df9ab 100644
--- a/src/functions/modular_forms/msatkinlehner
+++ b/src/functions/modular_symbols/msatkinlehner
@@ -1,5 +1,5 @@
 Function: msatkinlehner
-Section: modular_forms
+Section: modular_symbols
 C-Name: msatkinlehner
 Prototype: GLDG
 Help: msatkinlehner(M,Q,{H}): Let M be a full modular symbol space of level N,
diff --git a/src/functions/modular_forms/mscuspidal b/src/functions/modular_symbols/mscuspidal
similarity index 97%
rename from src/functions/modular_forms/mscuspidal
rename to src/functions/modular_symbols/mscuspidal
index e068319..140486c 100644
--- a/src/functions/modular_forms/mscuspidal
+++ b/src/functions/modular_symbols/mscuspidal
@@ -1,5 +1,5 @@
 Function: mscuspidal
-Section: modular_forms
+Section: modular_symbols
 C-Name: mscuspidal
 Prototype: GD0,L,
 Help: mscuspidal(M, {flag=0}): M being a full modular symbol space, as given
diff --git a/src/functions/modular_forms/mseisenstein b/src/functions/modular_symbols/mseisenstein
similarity index 96%
rename from src/functions/modular_forms/mseisenstein
rename to src/functions/modular_symbols/mseisenstein
index 2705fe4..a692c84 100644
--- a/src/functions/modular_forms/mseisenstein
+++ b/src/functions/modular_symbols/mseisenstein
@@ -1,5 +1,5 @@
 Function: mseisenstein
-Section: modular_forms
+Section: modular_symbols
 C-Name: mseisenstein
 Prototype: G
 Help: mseisenstein(M): M being a full modular symbol space, as given by msinit,
diff --git a/src/functions/modular_forms/mseval b/src/functions/modular_symbols/mseval
similarity index 98%
rename from src/functions/modular_forms/mseval
rename to src/functions/modular_symbols/mseval
index 680230c..4e11f24 100644
--- a/src/functions/modular_forms/mseval
+++ b/src/functions/modular_symbols/mseval
@@ -1,5 +1,5 @@
 Function: mseval
-Section: modular_forms
+Section: modular_symbols
 C-Name: mseval
 Prototype: GGDG
 Help: mseval(M,s,{p}): M being a full modular symbol space, as given by
diff --git a/src/functions/modular_forms/msfromcusp b/src/functions/modular_symbols/msfromcusp
similarity index 98%
rename from src/functions/modular_forms/msfromcusp
rename to src/functions/modular_symbols/msfromcusp
index 2602f3f..d1373dc 100644
--- a/src/functions/modular_forms/msfromcusp
+++ b/src/functions/modular_symbols/msfromcusp
@@ -1,5 +1,5 @@
 Function: msfromcusp
-Section: modular_forms
+Section: modular_symbols
 C-Name: msfromcusp
 Prototype: GG
 Help: msfromcusp(M, c): returns the modular symbol associated to the cusp
diff --git a/src/functions/modular_symbols/msfromell b/src/functions/modular_symbols/msfromell
new file mode 100644
index 0000000..efad626
--- /dev/null
+++ b/src/functions/modular_symbols/msfromell
@@ -0,0 +1,50 @@
+Function: msfromell
+Section: modular_symbols
+C-Name: msfromell
+Prototype: GD0,L,
+Help: msfromell(E, {sign=0}): return the [M, x], where M is msinit(N,2)
+ and x is the modular symbol in M associated to the elliptic curve E/Q.
+Doc: Let $E/\Q$ be an elliptic curve of conductor $N$. For $\varepsilon =
+ \pm1$, we define the (cuspidal, new) modular symbol $x^\varepsilon$ in
+ $H^1_c(X_0(N),\Q)^\varepsilon$  associated to
+ $E$. For all primes $p$ not dividing $N$ we have
+ $T_p(x^\varepsilon) =  a_p x^\varepsilon$, where $a_p = p+1-\#E(\F_p)$.
+
+ Let $\Omega^+ = \kbd{E.omega[1]}$ be the real period of $E$
+ (integration of the N\'eron differential $dx/(2y+a_1x+a3)$ on the connected
+ component of $E(\R)$, i.e.~the generator of $H_1(E,\Z)^+$) normalized by
+ $\Omega^+>0$. Let $i\Omega^-$ the integral on a generator of $H_1(E,\Z)^-$ with
+ $\Omega^- \in \R_{>0}$. If $c_\infty$ is the number of connected
+ components of $E(\R)$, $\Omega^-$ is equal to
+ $(-2/c_\infty) \times \kbd{imag(E.omega[2])}$.
+ The complex modular symbol is defined by
+ $$F: \delta \to  2i\pi \int_{\delta} f(z) dz$$
+ The modular symbols $x^\varepsilon$ are normalized so that
+ $ F = x^+ \Omega^+ + x^- i\Omega^-$.
+ In particular, we have
+ $$ x^+([0]-[\infty]) = L(E,1) / \Omega^+,$$
+ which defines $x^{\pm}$ unless $L(E,1)=0$.
+ Furthermore, for all fundamental discriminants $D$ such
+ that $\varepsilon \cdot D > 0$, we also have
+ $$\sum_{0\leq a<|D|} (D|a) x^\varepsilon([a/|D|]-[\infty])
+    = L(E,(D|.),1) / \Omega^{\varepsilon},$$
+ where $(D|.)$ is the Kronecker symbol.
+ The period $\Omega^-$ is also $2/c_\infty \times$ the real period
+ of the twist $E^{(-4)} = \kbd{elltwist(E,-4)}$.
+
+ This function returns the pair $[M, x]$, where $M$ is
+ \kbd{msinit}$(N,2)$ and $x$ is $x^{\var{sign}}$ as above when $\var{sign}=
+ \pm1$, and $x = [x^+,x^-]$ when \var{sign} is $0$.
+ The modular symbols $x^\pm$ are given as a \typ{COL} (in terms
+ of the fixed basis of $\text{Hom}_G(\Delta,\Q)$ chosen in $M$).
+ \bprog
+ ? E=ellinit([0,-1,1,-10,-20]);  \\ X_0(11)
+ ? [M,xp]= msfromell(E,1);
+ ? xp
+ %3 = [1/5, -1/2, -1/2]~
+ ? [M,x]= msfromell(E);
+ ? x    \\ both x^+ and x^-
+ %5 = [[1/5, -1/2, -1/2]~, [0, 1/2, -1/2]~]
+ ? p = 23; (mshecke(M,p) - ellap(E,p))*x[1]
+ %6 = [0, 0, 0]~ \\ true at all primes, including p = 11; same for x[2]
+ @eprog
diff --git a/src/functions/modular_symbols/msfromhecke b/src/functions/modular_symbols/msfromhecke
new file mode 100644
index 0000000..82b06a5
--- /dev/null
+++ b/src/functions/modular_symbols/msfromhecke
@@ -0,0 +1,41 @@
+Function: msfromhecke
+Section: modular_symbols
+C-Name: msfromhecke
+Prototype: GGDG
+Help: msfromhecke(M, v, {H}): given a msinit M and a vector v
+ of pairs [p, P] (where p is prime and P is a polynomial with integer
+ coefficients), return a basis of all modular symbols such that
+ P(Tp) * s = 0. If H is present, it must be a Hecke-stable subspace
+ and we restrict to s in H.
+Doc: given a msinit $M$ and a vector $v$ of pairs $[p, P]$ (where $p$ is prime
+ and $P$ is a polynomial with integer coefficients), return a basis of all
+ modular symbols such that $P(T_p)(s) = 0$. If $H$ is present, it must
+ be a Hecke-stable subspace and we restrict to $s \in H$. When $T_p$ has
+ a rational eigenvalue and $P(x) = x-a_p$ has degree $1$, we also accept the
+ integer $a_p$ instead of $P$.
+ \bprog
+ ? E = ellinit([0,-1,1,-10,-20]) \\11a1
+ ? ellap(E,2)
+ %2 = -2
+ ? ellap(E,3)
+ %3 = -1
+ ? M = msinit(11,2);
+ ? S = msfromhecke(M, [[2,-2],[3,-1]])
+ %5 =
+ [ 1  1]
+
+ [-5  0]
+
+ [ 0 -5]
+ ? mshecke(M, 2, S)
+ %6 =
+ [-2  0]
+
+ [ 0 -2]
+
+ ? M = msinit(23,4);
+ ? S = msfromhecke(M, [[5, x^4-14*x^3-244*x^2+4832*x-19904]]);
+ ? factor( charpoly(mshecke(M,5,S)) )
+ %9 =
+ [x^4 - 14*x^3 - 244*x^2 + 4832*x - 19904 2]
+ @eprog
diff --git a/src/functions/modular_symbols/msgetlevel b/src/functions/modular_symbols/msgetlevel
new file mode 100644
index 0000000..49b2ffc
--- /dev/null
+++ b/src/functions/modular_symbols/msgetlevel
@@ -0,0 +1,7 @@
+Function: msgetlevel
+Section: modular_symbols
+C-Name: msgetlevel
+Prototype: lG
+Help: msgetlevel(M): M being a full modular symbol space, as given by msinit, return its level N.
+Doc: $M$ being a full modular symbol space, as given by \kbd{msinit}, return
+ its level $N$.
diff --git a/src/functions/modular_symbols/msgetsign b/src/functions/modular_symbols/msgetsign
new file mode 100644
index 0000000..bcc8f2d
--- /dev/null
+++ b/src/functions/modular_symbols/msgetsign
@@ -0,0 +1,15 @@
+Function: msgetsign
+Section: modular_symbols
+C-Name: msgetsign
+Prototype: lG
+Help: msgetsign(M): M being a full modular symbol space, as given by msinit, return its sign.
+Doc: $M$ being a full modular symbol space, as given by \kbd{msinit}, return
+ its sign: $\pm1$ or 0 (unset).
+ \bprog
+ ? M = msinit(11,4, 1);
+ ? msgetsign(M)
+ %2 = 1
+ ? M = msinit(11,4);
+ ? msgetsign(M)
+ %4 = 0
+ @eprog
diff --git a/src/functions/modular_symbols/msgetweight b/src/functions/modular_symbols/msgetweight
new file mode 100644
index 0000000..f5cc37a
--- /dev/null
+++ b/src/functions/modular_symbols/msgetweight
@@ -0,0 +1,12 @@
+Function: msgetweight
+Section: modular_symbols
+C-Name: msgetweight
+Prototype: lG
+Help: msgetweight(M): M being a full modular symbol space, as given by msinit, return its weight k.
+Doc: $M$ being a full modular symbol space, as given by \kbd{msinit}, return
+ its weight $k$.
+ \bprog
+ ? M = msinit(11,4);
+ ? msgetweight(M)
+ %2 = 4
+ @eprog
diff --git a/src/functions/modular_forms/mshecke b/src/functions/modular_symbols/mshecke
similarity index 97%
rename from src/functions/modular_forms/mshecke
rename to src/functions/modular_symbols/mshecke
index 33431d6..fb85fe9 100644
--- a/src/functions/modular_forms/mshecke
+++ b/src/functions/modular_symbols/mshecke
@@ -1,5 +1,5 @@
 Function: mshecke
-Section: modular_forms
+Section: modular_symbols
 C-Name: mshecke
 Prototype: GLDG
 Help: mshecke(M,p,{H}): M being a full modular symbol space, as given by msinit,
diff --git a/src/functions/modular_forms/msinit b/src/functions/modular_symbols/msinit
similarity index 98%
rename from src/functions/modular_forms/msinit
rename to src/functions/modular_symbols/msinit
index 258e296..78c6480 100644
--- a/src/functions/modular_forms/msinit
+++ b/src/functions/modular_symbols/msinit
@@ -1,5 +1,5 @@
 Function: msinit
-Section: modular_forms
+Section: modular_symbols
 C-Name: msinit
 Prototype: GGD0,L,
 Help: msinit(G, V, {sign=0}): given G a finite index subgroup of SL(2,Z)
diff --git a/src/functions/modular_forms/msissymbol b/src/functions/modular_symbols/msissymbol
similarity index 96%
rename from src/functions/modular_forms/msissymbol
rename to src/functions/modular_symbols/msissymbol
index ab87f4f..2e395fe 100644
--- a/src/functions/modular_forms/msissymbol
+++ b/src/functions/modular_symbols/msissymbol
@@ -1,5 +1,5 @@
 Function: msissymbol
-Section: modular_forms
+Section: modular_symbols
 C-Name: msissymbol
 Prototype: lGG
 Help: msissymbol(M,s): M being a full modular symbol space, as given by msinit,
diff --git a/src/functions/modular_forms/msnew b/src/functions/modular_symbols/msnew
similarity index 95%
rename from src/functions/modular_forms/msnew
rename to src/functions/modular_symbols/msnew
index a75b4db..41f9d03 100644
--- a/src/functions/modular_forms/msnew
+++ b/src/functions/modular_symbols/msnew
@@ -1,5 +1,5 @@
 Function: msnew
-Section: modular_forms
+Section: modular_symbols
 C-Name: msnew
 Prototype: G
 Help: msnew(M): M being a full modular symbol space, as given by msinit,
diff --git a/src/functions/modular_symbols/msomseval b/src/functions/modular_symbols/msomseval
new file mode 100644
index 0000000..fae78aa
--- /dev/null
+++ b/src/functions/modular_symbols/msomseval
@@ -0,0 +1,19 @@
+Function: msomseval
+Section: modular_symbols
+C-Name: msomseval
+Prototype: GGG
+Help: msomseval(Mp, PHI, path):
+ return the vectors of moments of the p-adic distribution attached
+ to the path 'path' via the overconvergent modular symbol 'PHI'
+Doc:return the vectors of moments of the $p$-adic distribution attached
+ to the path \kbd{path} by the overconvergent modular symbol \kbd{PHI}.
+ \bprog
+ ? M = msinit(3,6,1);
+ ? Mp= mspadicinit(M,5,10);
+ ? phi = [5,-3,-1]~;
+ ? msissymbol(M,phi)
+ %4 = 1
+ ? PHI = mstooms(Mp,phi);
+ ? ME = msomseval(Mp,PHI,[oo, 0]);
+ @eprog
+
diff --git a/src/functions/modular_symbols/mspadicL b/src/functions/modular_symbols/mspadicL
new file mode 100644
index 0000000..aa4a93f
--- /dev/null
+++ b/src/functions/modular_symbols/mspadicL
@@ -0,0 +1,103 @@
+Function: mspadicL
+Section: modular_symbols
+C-Name: mspadicL
+Prototype: GDGD0,L,
+Help: mspadicL(mu, {s = 0}, {r = 0}): given
+ mu from mspadicmoments (p-adic distributions attached to an
+ overconvergent symbol PHI) returns the value on a
+ character of Z_p^* represented by s of the derivative of order r of the
+ p-adic L-function attached to PHI.
+Doc: Returns the value (or $r$-th derivative)
+ on a character $\chi^s$ of $\Z_p^*$ of the $p$-adic $L$-function
+ attached to \kbd{mu}.
+
+ Let $\Phi$ be the $p$-adic distribution-valued overconvergent symbol
+ attached to a modular symbol $\phi$ for $\Gamma_0(N)$ (eigenvector for
+ $T_N(p)$ for the eigenvalue $a_p$). Then $L_p(\Phi,\chi^s)=L_p(\mu,s)$ is the
+ $p$-adic $L$ function defined by
+ $$L_p(\Phi,\chi^s)= \int_{\Z_p^*} \chi^s(z) d\mu(z)$$
+ where $\mu$ is the distribution on $\Z_p^*$ defined by the restriction of
+ $\Phi([\infty]-[0])$ to $\Z_p^*$. The $r$-th derivative is taken in
+ direction $\langle \chi\rangle$:
+ $$L_p^{(r)}(\Phi,\chi^s)= \int_{\Z_p^*} \chi^s(z) (\log z)^r d\mu(z).$$
+ In the argument list,
+
+ \item \kbd{mu} is as returned by \tet{mspadicmoments} (distributions
+ attached to $\Phi$ by restriction to discs $a + p^\nu\Z_p$, $(a,p)=1$).
+
+ \item $s=[s_1,s_2]$ with $s_1 \in \Z \subset \Z_p$ and $s_2 \bmod p-1$ or
+ $s_2 \bmod 2$ for $p=2$, encoding the $p$-adic character $\chi^s := \langle
+ \chi \rangle^{s_1} \tau^{s_2}$; here $\chi$ is the cyclotomic character from
+ $\text{Gal}(\Q_p(\mu_{p^\infty})/\Q_p)$ to $\Z_p^*$, and $\tau$ is the
+ Teichm\"uller character (for $p>2$ and the character of order 2 on
+ $(\Z/4\Z)^*$ if $p=2$); for convenience, the character $[s,s]$ can also be
+ represented by the integer $s$.
+
+ When $a_p$ is a $p$-adic unit, $L_p$ takes its values in $\Q_p$.
+ When $a_p$ is not a unit, it takes its values in the
+ two-dimensional $\Q_p$-vector space $D_{cris}(M(\phi))$ where $M(\phi)$ is
+ the ``motive'' attached to $\phi$, and we return the two $p$-adic components
+ with respect to some fixed $\Q_p$-basis.
+ \bprog
+ ? M = msinit(3,6,1); phi=[5, -3, -1]~;
+ ? msissymbol(M,phi)
+ %2 = 1
+ ? Mp = mspadicinit(M, 5, 4);
+ ? mu = mspadicmoments(Mp, phi); \\ no twist
+ \\ End of initializations
+
+ ? mspadicL(mu,0) \\ L_p(chi^0)
+ %5 = 5 + 2*5^2 + 2*5^3 + 2*5^4 + ...
+ ? mspadicL(mu,1) \\ L_p(chi), zero for parity reasons
+ %6 = [O(5^13)]~
+ ? mspadicL(mu,2) \\ L_p(chi^2)
+ %7 = 3 + 4*5 + 4*5^2 + 3*5^5 + ...
+ ? mspadicL(mu,[0,2]) \\ L_p(tau^2)
+ %8 = 3 + 5 + 2*5^2 + 2*5^3 + ...
+ ? mspadicL(mu, [1,0]) \\ L_p(<chi>)
+ %9 = 3*5 + 2*5^2 + 5^3 + 2*5^7 + 5^8 + 5^10 + 2*5^11 + O(5^13)
+ ? mspadicL(mu,0,1) \\ L_p'(chi^0)
+ %10 = 2*5 + 4*5^2 + 3*5^3 + ...
+ ? mspadicL(mu, 2, 1) \\ L_p'(chi^2)
+ %11 = 4*5 + 3*5^2 + 5^3 + 5^4 + ...
+ @eprog
+
+ Now several quadratic twists: \tet{mstooms} is indicated.
+ \bprog
+ ? PHI = mstooms(Mp,phi);
+ ? mu = mspadicmoments(Mp, PHI, 12); \\ twist by 12
+ ? mspadicL(mu)
+ %14 = 5 + 5^2 + 5^3 + 2*5^4 + ...
+ ? mu = mspadicmoments(Mp, PHI, 8); \\ twist by 8
+ ? mspadicL(mu)
+ %16 = 2 + 3*5 + 3*5^2 + 2*5^4 + ...
+ ? mu = mspadicmoments(Mp, PHI, -3); \\ twist by -3 < 0
+ ? mspadicL(mu)
+ %18 = O(5^13) \\ always 0, phi is in the + part and D < 0
+ @eprog
+
+ One can locate interesting symbols of level $N$ and weight $k$ with
+ \kbd{msnew} and \kbd{mssplit}. Note that instead of a symbol, one can
+ input a 1-dimensional Hecke-subspace from \kbd{mssplit}: the function will
+ automatically use the underlying basis vector.
+ \bprog
+ ? M=msinit(5,4,1); \\ M_4(Gamma_0(5))^+
+ ? L = mssplit(M, msnew(M)); \\ list of irreducible Hecke-subspaces
+ ? phi = L[1]; \\ one Galois orbit of newforms
+ ? #phi[1] \\... this one is rational
+ %4 = 1
+ ? Mp = mspadicinit(M, 3, 4);
+ ? mu = mspadicmoments(Mp, phi);
+ ? mspadicL(mu)
+ %7 = 1 + 3 + 3^3 + 3^4 + 2*3^5 + 3^6 + O(3^9)
+
+ ? M = msinit(11,8, 1); \\ M_8(Gamma_0(11))^+
+ ? Mp = mspadicinit(M, 3, 4);
+ ? L = mssplit(M, msnew(M));
+ ? phi = L[1]; #phi[1] \\ ... this one is two-dimensional
+ %11 = 2
+ ? mu = mspadicmoments(Mp, phi);
+  ***   at top-level: mu=mspadicmoments(Mp,ph
+  ***                    ^--------------------
+  *** mspadicmoments: incorrect type in mstooms [dim_Q (eigenspace) > 1]
+ @eprog
diff --git a/src/functions/modular_symbols/mspadicinit b/src/functions/modular_symbols/mspadicinit
new file mode 100644
index 0000000..cc80c67
--- /dev/null
+++ b/src/functions/modular_symbols/mspadicinit
@@ -0,0 +1,46 @@
+Function: mspadicinit
+Section: modular_symbols
+C-Name: mspadicinit
+Prototype: GLLD-1,L,
+Help: mspadicinit(M, p, n, {flag}): M being a full modular symbol space,
+ as given by msinit and a prime p, initialize
+ technical data needed to compute with overconvergent modular symbols
+ (modulo p^n). If flag is unset, allow all symbols; if flag = 0, restrict
+ to ordinary symbols; else initialize for symbols phi such that
+ Tp(phi) = a_p * phi, with v_p(a_p) >= flag.
+
+Doc: $M$ being a full modular symbol space, as given by \kbd{msinit}, and $p$
+ a prime, initialize technical data needed to compute with overconvergent
+ modular symbols, modulo $p^n$. If $\fl$ is unset, allow
+ all symbols; else initialize only for a restricted range of symbols
+ depending on $\fl$: if $\fl = 0$ restrict to ordinary symbols, else
+ restrict to symbols $\phi$ such that $T_p(\phi) = a_p \phi$,
+ with $v_p(a_p) \geq \fl$, which is faster as $\fl$ increases.
+ (The fastest initialization is obtained for $\fl = 0$ where we only allow
+ ordinary symbols.) For supersingular eigensymbols, such that $p\mid a_p$, we
+ must further assume that $p$ does not divide the level.
+ \bprog
+ ? E = ellinit("11a1");
+ ? [M,phi] = msfromell(E,1);
+ ? ellap(E,3)
+ %3 = -1
+ ? Mp = mspadicinit(M, 3, 10, 0); \\ commit to ordinary symbols
+ ? PHI = mstooms(Mp,phi);
+ @eprog
+
+ If we restrict the range of allowed symbols with \fl (for faster
+ initialization), exceptions will occur if $v_p(a_p)$ violates this bound:
+ \bprog
+ ? E = ellinit("15a1");
+ ? [M,phi] = msfromell(E,1);
+ ? ellap(E,7)
+ %3 = 0
+ ? Mp = mspadicinit(M,7,5,0); \\ restrict to ordinary symbols
+ ? PHI = mstooms(Mp,phi)
+ ***   at top-level: PHI=mstooms(Mp,phi)
+ ***                     ^---------------
+ *** mstooms: incorrect type in mstooms [v_p(ap) > mspadicinit flag] (t_VEC).
+ ? Mp = mspadicinit(M,7,5); \\ no restriction
+ ? PHI = mstooms(Mp,phi);
+ @eprog\noindent This function uses $O(N^2(n+k)^2p)$ memory, where $N$ is the
+ level of $M$.
diff --git a/src/functions/modular_symbols/mspadicmoments b/src/functions/modular_symbols/mspadicmoments
new file mode 100644
index 0000000..13ddb54
--- /dev/null
+++ b/src/functions/modular_symbols/mspadicmoments
@@ -0,0 +1,41 @@
+Function: mspadicmoments
+Section: modular_symbols
+C-Name: mspadicmoments
+Prototype: GGD1,L,
+Help: mspadicmoments(Mp, PHI, {D = 1}): given Mp from mspadicinit, an
+ overconvergent eigensymbol PHI, and optionally a fundamental discriminant
+ D coprime to p, return the moments of the p-1 distributions
+ PHI^D([0]-[oo]) | (a + pZp), 0 < a < p. To be used by mspadicL and
+ mspadicseries
+Doc: given \kbd{Mp} from \kbd{mspadicinit}, an overconvergent
+ eigensymbol \kbd{PHI} from \kbd{mstooms} and a fundamental discriminant
+ $D$ coprime to $p$,
+ let $\kbd{PHI}^D$ denote the twisted symbol. This function computes
+ the distribution $\mu = \kbd{PHI}^D([0] - \infty]) \mid \Z_p^*$ restricted
+ to $\Z_p^*$. More precisely, it returns
+ the moments of the $p-1$ distributions $\kbd{PHI}^D([0]-[\infty])
+ \mid (a + p\Z_p)$, $0 < a < p$.
+ We also allow \kbd{PHI} to be given as a classical
+ symbol, which is then lifted to an overconvergent symbol by \kbd{mstooms};
+ but this is wasteful if more than one twist is later needed.
+
+ The returned data $\mu$ ($p$-adic distributions attached to \kbd{PHI})
+ can then be used in \tet{mspadicL} or \tet{mspadicseries}.
+ This precomputation allows to quickly compute derivatives of different
+ orders or values at different characters.
+ \bprog
+ ? M = msinit(3,6, 1);
+ ? phi = [5,-3,-1]~;
+ ? msissymbol(M, phi)
+ %3 = 1
+ ? p = 5; mshecke(M,p) * phi  \\ eigenvector of T_5, a_5 = 6
+ %4 = [30, -18, -6]~
+ ? Mp = mspadicinit(M, p, 10, 0); \\ restrict to ordinary symbols, mod p^10
+ ? PHI = mstooms(Mp, phi);
+ ? mu = mspadicmoments(Mp, PHI);
+ ? mspadicL(mu)
+ %8 = 5 + 2*5^2 + 2*5^3 + ...
+ ? mu = mspadicmoments(Mp, PHI, 12); \\ twist by 12
+ ? mspadicL(mu)
+ %10 = 5 + 5^2 + 5^3 + 2*5^4 + ...
+ @eprog
diff --git a/src/functions/modular_symbols/mspadicseries b/src/functions/modular_symbols/mspadicseries
new file mode 100644
index 0000000..b6feaec
--- /dev/null
+++ b/src/functions/modular_symbols/mspadicseries
@@ -0,0 +1,79 @@
+Function: mspadicseries
+Section: modular_symbols
+C-Name: mspadicseries
+Prototype: GD0,L,
+Help: mspadicseries(mu, {i=0}): given mu from mspadicmoments,
+ returns the attached p-adic series with maximal p-adic precision, depending
+ on the precision of M (i-th Teichmueller component, if present).
+Doc: Let $\Phi$ be the $p$-adic distribution-valued overconvergent symbol
+ attached to a modular symbol $\phi$ for $\Gamma_0(N)$ (eigenvector for
+ $T_N(p)$ for the eigenvalue $a_p$).
+ If $\mu$ is the distribution on $\Z_p^*$ defined by the restriction of
+ $\Phi([\infty]-[0])$ to $\Z_p^*$, let
+ $$\hat{L}_p(\mu,\tau^{i})(x)
+   = \int_{\Z_p^*} \tau^i(t) (1+x)^{\log_p(t)/\log_p(u)}d\mu(t)$$
+ Here, $\tau$ is the Teichm\"uller character and $u$ is a specific
+ multiplicative generator of $1+2p\Z_p$. (Namely $1+p$ if $p>2$ or $5$
+ if $p=2$.) To explain
+ the formula, let $G_\infty := \text{Gal}(\Q(\mu_{p^{\infty}})/ \Q)$,
+ let $\chi:G_\infty\to \Z_p^*$ be the cyclotomic character (isomorphism)
+ and $\gamma$ the element of $G_\infty$ such that $\chi(\gamma)=u$;
+ then
+ $\chi(\gamma)^{\log_p(t)/\log_p(u)}= \langle t \rangle$.
+
+ The $p$-padic precision of individual terms is maximal given the precision of
+ the overconvergent symbol $\mu$.
+ \bprog
+ ? [M,phi] = msfromell(ellinit("17a1"),1);
+ ? Mp = mspadicinit(M, 5,7);
+ ? mu = mspadicmoments(Mp, phi,1); \\ overconvergent symbol
+ ? mspadicseries(mu)
+ %4 = (4 + 3*5 + 4*5^2 + 2*5^3 + 2*5^4 + 5^5 + 4*5^6 + 3*5^7 + O(5^9)) \
+  + (3 + 3*5 + 5^2 + 5^3 + 2*5^4 + 5^6 + O(5^7))*x \
+  + (2 + 3*5 + 5^2 + 4*5^3 + 2*5^4 + O(5^5))*x^2 \
+  + (3 + 4*5 + 4*5^2 + O(5^3))*x^3 \
+  + (3 + O(5))*x^4 + O(x^5)
+ @eprog\noindent
+ An example with non-zero Teichm\"uller:
+ \bprog
+ ? [M,phi] = msfromell(ellinit("11a1"),1);
+ ? Mp = mspadicinit(M, 3,10);
+ ? mu = mspadicmoments(Mp, phi,1);
+ ? mspadicseries(mu, 2)
+ %4 = (2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + 3^7 + 3^10 + 3^11 + O(3^12)) \
+  + (1 + 3 + 2*3^2 + 3^3 + 3^5 + 2*3^6 + 2*3^8 + O(3^9))*x \
+  + (1 + 2*3 + 3^4 + 2*3^5 + O(3^6))*x^2 \
+  + (3 + O(3^2))*x^3 + O(x^4)
+ @eprog\noindent
+ Supersingular example (not checked)
+ \bprog
+ ? E = ellinit("17a1"); ellap(E,3)
+ %1 = 0
+ ? [M,phi] = msfromell(E,1);
+ ? Mp = mspadicinit(M, 3,7);
+ ? mu = mspadicmoments(Mp, phi,1);
+ ? mspadicseries(mu)
+ %5 = [(2*3^-1 + 1 + 3 + 3^2 + 3^3 + 3^4 + 3^5 + 3^6 + O(3^7)) \
+  + (2 + 3^3 + O(3^5))*x \
+  + (1 + 2*3 + O(3^2))*x^2 + O(x^3),\
+  (3^-1 + 1 + 3 + 3^2 + 3^3 + 3^4 + 3^5 + 3^6 + O(3^7)) \
+  + (1 + 2*3 + 2*3^2 + 3^3 + 2*3^4 + O(3^5))*x \
+  + (3^-2 + 3^-1 + O(3^2))*x^2 + O(3^-2)*x^3 + O(x^4)]
+ @eprog\noindent
+ Example with a twist:
+ \bprog
+ ? E = ellinit("11a1");
+ ? [M,phi] = msfromell(E,1);
+ ? Mp = mspadicinit(M, 3,10);
+ ? mu = mspadicmoments(Mp, phi,5); \\ twist by 5
+ ? L = mspadicseries(mu)
+ %5 = (2*3^2 + 2*3^4 + 3^5 + 3^6 + 2*3^7 + 2*3^10 + O(3^12)) \
+  + (2*3^2 + 2*3^6 + 3^7 + 3^8 + O(3^9))*x \
+  + (3^3 + O(3^6))*x^2 + O(3^2)*x^3 + O(x^4)
+ ? mspadicL(mu)
+ %6 = [2*3^2 + 2*3^4 + 3^5 + 3^6 + 2*3^7 + 2*3^10 + O(3^12)]~
+ ? ellpadicL(E,3,10,,5)
+ %7 = 2 + 2*3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^6 + 2*3^7 + O(3^10)
+ ? mspadicseries(mu,1) \\ must be 0
+ %8 = O(3^12) + O(3^9)*x + O(3^6)*x^2 + O(3^2)*x^3 + O(x^4)
+ @eprog
diff --git a/src/functions/modular_forms/mspathgens b/src/functions/modular_symbols/mspathgens
similarity index 98%
rename from src/functions/modular_forms/mspathgens
rename to src/functions/modular_symbols/mspathgens
index 2fd7436..688d48b 100644
--- a/src/functions/modular_forms/mspathgens
+++ b/src/functions/modular_symbols/mspathgens
@@ -1,5 +1,5 @@
 Function: mspathgens
-Section: modular_forms
+Section: modular_symbols
 C-Name: mspathgens
 Prototype: G
 Help: mspathgens(M): M being a full modular symbol space, as given by
diff --git a/src/functions/modular_forms/mspathlog b/src/functions/modular_symbols/mspathlog
similarity index 97%
rename from src/functions/modular_forms/mspathlog
rename to src/functions/modular_symbols/mspathlog
index ffb1eb5..b0e2ea5 100644
--- a/src/functions/modular_forms/mspathlog
+++ b/src/functions/modular_symbols/mspathlog
@@ -1,5 +1,5 @@
 Function: mspathlog
-Section: modular_forms
+Section: modular_symbols
 C-Name: mspathlog
 Prototype: GG
 Help: mspathlog(M,p): M being a full modular symbol space, as given by
diff --git a/src/functions/modular_forms/msqexpansion b/src/functions/modular_symbols/msqexpansion
similarity index 98%
rename from src/functions/modular_forms/msqexpansion
rename to src/functions/modular_symbols/msqexpansion
index d22614a..999a55b 100644
--- a/src/functions/modular_forms/msqexpansion
+++ b/src/functions/modular_symbols/msqexpansion
@@ -1,5 +1,5 @@
 Function: msqexpansion
-Section: modular_forms
+Section: modular_symbols
 C-Name: msqexpansion
 Prototype: GGDP
 Help: msqexpansion(M,projH,{B = seriesprecision}): M being a full modular
diff --git a/src/functions/modular_forms/mssplit b/src/functions/modular_symbols/mssplit
similarity index 72%
rename from src/functions/modular_forms/mssplit
rename to src/functions/modular_symbols/mssplit
index d98e383..1a00653 100644
--- a/src/functions/modular_forms/mssplit
+++ b/src/functions/modular_symbols/mssplit
@@ -1,14 +1,16 @@
 Function: mssplit
-Section: modular_forms
+Section: modular_symbols
 C-Name: mssplit
-Prototype: GG
-Help: mssplit(M,H): M being a full modular symbol space, as given by msinit,
- and H being a subspace, split H into Hecke-simple subspaces.
+Prototype: GGD0,L,
+Help: mssplit(M,H,{dimlim}): M being a full modular symbol space, as given by
+ msinit, and H being a subspace, split H into Hecke-simple subspaces.
+ If dimlim is present and positive, restrict to dim <= dimlim.
 Doc:
  $M$ being a full modular symbol space, as given by \kbd{msinit}$(N,k,1)$
  or $\kbd{msinit}(N,k,-1)$
  and $H$ being a Hecke-stable subspace of \kbd{msnew}$(M)$, split $H$ into
- Hecke-simple subspaces.
+ Hecke-simple subspaces. If \kbd{dimlim} is present and positive, restrict to
+ subspaces of dimension $\leq \kbd{dimlim}$.
  A subspace is given by a structure allowing quick projection and restriction
  of linear operators; its first component is a matrix with integer
  coefficients whose columns form a $\Q$-basis of the subspace.
diff --git a/src/functions/modular_forms/msstar b/src/functions/modular_symbols/msstar
similarity index 95%
rename from src/functions/modular_forms/msstar
rename to src/functions/modular_symbols/msstar
index cd14628..b73c94f 100644
--- a/src/functions/modular_forms/msstar
+++ b/src/functions/modular_symbols/msstar
@@ -1,5 +1,5 @@
 Function: msstar
-Section: modular_forms
+Section: modular_symbols
 C-Name: msstar
 Prototype: GDG
 Help: msstar(M,{H}): M being a full modular symbol space,
diff --git a/src/functions/modular_symbols/mstooms b/src/functions/modular_symbols/mstooms
new file mode 100644
index 0000000..bc9c84d
--- /dev/null
+++ b/src/functions/modular_symbols/mstooms
@@ -0,0 +1,67 @@
+Function: mstooms
+Section: modular_symbols
+C-Name: mstooms
+Prototype: GG
+Help: mstooms(Mp, phi): given Mp from mspadicinit, lift the
+ (classical) eigen symbol phi to a distribution-valued overconvergent symbol
+ in the sense of Pollack and Stevens.
+ The resulting overconvergent eigensymbol can then be used in
+ mspadicmoments, then mspadicL or mspadicseries.
+Doc: given \kbd{Mp} from \kbd{mspadicinit}, lift the (classical) eigen symbol
+ \kbd{phi} to a $p$-adic distribution-valued overconvergent symbol in the
+ sense of Pollack and Stevens. More precisely, let $\phi$ belong to the space
+ $W$ of modular symbols of level $N$, $v_p(N) \leq 1$, and weight $k$ which is
+ an eigenvector for the Hecke operator $T_N(p)$ for a non-zero eigenvalue
+ $a_p$ and let $N_0 = \text{lcm}(N,p)$.
+
+ Under the action of $T_{N_0}(p)$, $\phi$ generates a subspace $W_\phi$ of
+ dimension $1$ (if $p\mid N$) or $2$ (if $p$ does not divide $N$) in the
+ space of modular symbols of level $N_0$.
+
+ Let $V_p=[p,0;0,1]$ and $C_p=[a_p,p^{k-1};-1,0]$.
+ When $p \not\mid N$ and $a_p$ is divisible by $p$, \kbd{mstooms}
+ returns the lift $\Phi$ of $(\phi,\phi|_k V_p)$ such that
+  $$T_{N_0}(p) \Phi = C_p \Phi$$
+
+ When $p \not\mid N$ and $a_p$ is not divisible by $p$, \kbd{mstooms}
+ returns the lift $\Phi$ of $\phi - \alpha^{-1} \phi|_k V_p$
+ which is an eigenvector of $T_{N_0}(p)$ for the unit eigenvalue
+ where $\alpha^2 - a_p \alpha + p^{k-1}=0$.
+
+ The resulting overconvergent eigensymbol can then be used in
+ \tet{mspadicmoments}, then \tet{mspadicL} or \tet{mspadicseries}.
+ \bprog
+ ? M = msinit(3,6, 1); p = 5;
+ ? Tp = mshecke(M, p); factor(charpoly(Tp))
+ %2 =
+ [x - 3126 2]
+
+ [   x - 6 1]
+ ? phi = matker(Tp - 6)[,1] \\ generator of p-Eigenspace, a_p = 6
+ %3 = [5, -3, -1]~
+ ? Mp = mspadicinit(M, p, 10, 0); \\ restrict to ordinary symbols, mod p^10
+ ? PHI = mstooms(Mp, phi);
+ ? mu = mspadicmoments(Mp, PHI);
+ ? mspadicL(mu)
+ %7 = 5 + 2*5^2 + 2*5^3 + ...
+ @eprog
+ A non ordinary symbol.
+ \bprog
+ ? M = msinit(4,6,1); p = 3;
+ ? Tp = mshecke(M, p); factor(charpoly(Tp))
+ %2 =
+ [x - 244 3]
+
+ [ x + 12 1]
+ ? phi = matker(Tp + 12)[,1] \\ a_p = -12 is divisible by p = 3
+ %3 = [-1/32, -1/4, -1/32, 1]~
+ ? msissymbol(M,phi)
+ %4 = 1
+ ? Mp = mspadicinit(M,3,5,0);
+ ? PHI = mstooms(Mp,phi);
+  ***   at top-level: PHI=mstooms(Mp,phi)
+  ***                     ^---------------
+  *** mstooms: incorrect type in mstooms [v_p(ap) > mspadicinit flag] (t_VEC).
+ ? Mp = mspadicinit(M,3,5,1);
+ ? PHI = mstooms(Mp,phi);
+ @eprog
diff --git a/src/functions/number_fields/bnfnarrow b/src/functions/number_fields/bnfnarrow
index c0c7a80..a9a1fdf 100644
--- a/src/functions/number_fields/bnfnarrow
+++ b/src/functions/number_fields/bnfnarrow
@@ -4,12 +4,13 @@ C-Name: buchnarrow
 Prototype: G
 Help: bnfnarrow(bnf): given a big number field as output by bnfinit, gives
  as a 3-component vector the structure of the narrow class group.
-Doc: $\var{bnf}$ being as output by
- \kbd{bnfinit}, computes the narrow class group of $\var{bnf}$. The output is
+Doc: \var{bnf} being as output by
+ \kbd{bnfinit}, computes the narrow class group of \var{bnf}. The output is
  a 3-component row vector $v$ analogous to the corresponding class group
- component \kbd{\var{bnf}.clgp} (\kbd{\var{bnf}[8][1]}): the first component
+ component \kbd{\var{bnf}.clgp}: the first component
  is the narrow class number \kbd{$v$.no}, the second component is a vector
  containing the SNF\sidx{Smith normal form} cyclic components \kbd{$v$.cyc} of
  the narrow class group, and the third is a vector giving the generators of
  the corresponding \kbd{$v$.gen} cyclic groups. Note that this function is a
- special case of \kbd{bnrinit}.
+ special case of \kbd{bnrinit}; the \var{bnf} need not contain fundamental
+ units.
diff --git a/src/functions/number_fields/bnrgaloisapply b/src/functions/number_fields/bnrgaloisapply
index 9d5b410..e67493f 100644
--- a/src/functions/number_fields/bnrgaloisapply
+++ b/src/functions/number_fields/bnrgaloisapply
@@ -3,7 +3,7 @@ Section: number_fields
 C-Name: bnrgaloisapply
 Prototype: GGG
 Help: bnrgaloisapply(bnr, mat, H): apply the automorphism given by its matrix
- mat to the cngruence subgroup H given as a HNF matrix. The matrix mat can be
+ mat to the congruence subgroup H given as a HNF matrix. The matrix mat can be
  computed with bnrgaloismatrix
 Doc: apply the automorphism given by its matrix \var{mat} to the congruence
  subgroup $H$ given as a HNF matrix.
diff --git a/src/functions/number_fields/bnrinit b/src/functions/number_fields/bnrinit
index 749d89b..2e7c9f3 100644
--- a/src/functions/number_fields/bnrinit
+++ b/src/functions/number_fields/bnrinit
@@ -9,11 +9,11 @@ Help: bnrinit(bnf,f,{flag=0}): given a bnf as output by
 Description:
  (gen,gen,?small):bnr       bnrinit0($1, $2, $3)
 Doc: $\var{bnf}$ is as
- output by \kbd{bnfinit}, $f$ is a modulus, initializes data linked to
- the ray class group structure corresponding to this module, a so-called
- \kbd{bnr} structure. One can input the associated \var{bid} with generators
- for $f$ instead of the module itself, saving some time.
- (As in \tet{idealstar}, the finite part of the conductor may be given
+ output by \kbd{bnfinit} (including fundamental units), $f$ is a modulus,
+ initializes data linked to the ray class group structure corresponding to
+ this module, a so-called \kbd{bnr} structure. One can input the associated
+ \var{bid} with generators for $f$ instead of the module itself, saving some
+ time. (As in \tet{idealstar}, the finite part of the conductor may be given
  by a factorization into prime ideals, as produced by \tet{idealfactor}.)
 
  The following member functions are available
diff --git a/src/functions/number_fields/galoissubcyclo b/src/functions/number_fields/galoissubcyclo
index 2d7caf7..811363e 100644
--- a/src/functions/number_fields/galoissubcyclo
+++ b/src/functions/number_fields/galoissubcyclo
@@ -32,7 +32,7 @@ Doc: computes the subextension
  an integer, then it is not a subgroup of $(\Z/n\Z)^*$, but of its quotient by
  $\{\pm 1\}$.
 
- If $fl=0$, compute a polynomial (in the variable \var{v}) defining the
+ If $fl=0$, compute a polynomial (in the variable \var{v}) defining
  the subfield of $\Q(\zeta_n)$ fixed by the subgroup \var{H} of $(\Z/n\Z)^*$.
 
  If $fl=1$, compute only the conductor of the abelian extension, as a module.
diff --git a/src/functions/number_fields/galoissubfields b/src/functions/number_fields/galoissubfields
index 0368767..6f1272a 100644
--- a/src/functions/number_fields/galoissubfields
+++ b/src/functions/number_fields/galoissubfields
@@ -2,8 +2,8 @@ Function: galoissubfields
 Section: number_fields
 C-Name: galoissubfields
 Prototype: GD0,L,Dn
-Help: galoissubfields(G,{flags=0},{v}):Output all the subfields of G. flags
- have the same meaning as for galoisfixedfield.
+Help: galoissubfields(G,{flag=0},{v}): Output all the subfields of G. flag
+ has the same meaning as for galoisfixedfield.
 Doc: outputs all the subfields of the Galois group \var{G}, as a vector.
  This works by applying \kbd{galoisfixedfield} to all subgroups. The meaning of
- the flag \var{fl} is the same as for \kbd{galoisfixedfield}.
+ \var{flag} is the same as for \kbd{galoisfixedfield}.
diff --git a/src/functions/number_fields/ideallistarch b/src/functions/number_fields/ideallistarch
index ade0bc5..9b097c0 100644
--- a/src/functions/number_fields/ideallistarch
+++ b/src/functions/number_fields/ideallistarch
@@ -2,7 +2,7 @@ Function: ideallistarch
 Section: number_fields
 C-Name: ideallistarch
 Prototype: GGG
-Help: ideallistarch(nf,list,arch): list is a vector of vectors of of bid's as
+Help: ideallistarch(nf,list,arch): list is a vector of vectors of bid's as
  output by ideallist. Return a vector of vectors with the same number of
  components as the original list. The leaves give information about
  moduli whose finite part is as in original list, in the same order, and
diff --git a/src/functions/number_fields/idealpow b/src/functions/number_fields/idealpow
index 1b978a0..844bde8 100644
--- a/src/functions/number_fields/idealpow
+++ b/src/functions/number_fields/idealpow
@@ -11,7 +11,7 @@ Doc: computes the $k$-th power of
  updated: i.e. raising $[I,t]$ to the $k$-th power, yields $[I^k, t^k]$.
 
  If $\fl$ is non-zero, reduce the result using \kbd{idealred}, \emph{throughout
- the (binary) powering process}; in particular, this is \emph{not} the same as
+ the (binary) powering process}; in particular, this is \emph{not} the same
  as $\kbd{idealpow}(\var{nf},x,k)$ followed by reduction.
 
 Variant:
diff --git a/src/functions/number_fields/idealprincipalunits b/src/functions/number_fields/idealprincipalunits
index f51e6fc..b054216 100644
--- a/src/functions/number_fields/idealprincipalunits
+++ b/src/functions/number_fields/idealprincipalunits
@@ -14,7 +14,7 @@ Doc: given a prime ideal in \tet{idealprimedec} format,
  ? P = idealprimedec(K,2)[1];
  ? G = idealprincipalunits(K, P, 20);
  ? G.cyc
- [512, 256, 4]   \\ Z/512 x Z/256 x Z/4
+ %4 = [512, 256, 4]   \\ Z/512 x Z/256 x Z/4
  ? G.gen
  %5 = [[-1, -2]~, 1021, [0, -1]~] \\ minimal generators of given order
  @eprog
diff --git a/src/functions/number_fields/nfbasis b/src/functions/number_fields/nfbasis
index 667d9bc..310ca1a 100644
--- a/src/functions/number_fields/nfbasis
+++ b/src/functions/number_fields/nfbasis
@@ -32,8 +32,8 @@ Doc:
 
  \item Matrix: we assume that it is a two-column matrix of a
  (partial) factorization of $D$; namely the first column contains
- \emph{primes} and the second one the valuation of $D$ at each of these
- primes.
+ distinct \emph{primes} and the second one the valuation of $D$ at each of
+ these primes.
 
  \item Integer $B$: this is replaced by the vector of primes up to $B$. Note
  that the function will use at least $O(B)$ time: a small value, about
diff --git a/src/functions/number_fields/nfcertify b/src/functions/number_fields/nfcertify
index a157826..5003297 100644
--- a/src/functions/number_fields/nfcertify
+++ b/src/functions/number_fields/nfcertify
@@ -9,10 +9,11 @@ Doc: $\var{nf}$ being as output by
  \kbd{nfinit}, checks whether the integer basis is known unconditionally.
  This is in particular useful when the argument to \kbd{nfinit} was of the
  form $[T, \kbd{listP}]$, specifying a finite list of primes when
- $p$-maximality had to be proven.
+ $p$-maximality had to be proven, or a list of coprime integers to which
+ Buchmann-Lenstra algorithm was to be applied.
 
- The function returns a vector of composite integers. If this vector is
- empty, then \kbd{nf.zk} and \kbd{nf.disc} are correct. Otherwise, the
- result is dubious. In order to obtain a certified result, one must
- completely factor each of the given integers, then \kbd{addprime} each of
- them, then check whether \kbd{nfdisc(nf.pol)} is equal to \kbd{nf.disc}.
+ The function returns a vector of coprime composite integers. If this vector
+ is empty, then \kbd{nf.zk} and \kbd{nf.disc} are correct. Otherwise, the
+ result is dubious. In order to obtain a certified result, one must completely
+ factor each of the given integers, then \kbd{addprime} each of their prime
+ factors, then check whether \kbd{nfdisc(nf.pol)} is equal to \kbd{nf.disc}.
diff --git a/src/functions/number_fields/nfeltdiveuc b/src/functions/number_fields/nfeltdiveuc
index a3a9902..32bd015 100644
--- a/src/functions/number_fields/nfeltdiveuc
+++ b/src/functions/number_fields/nfeltdiveuc
@@ -2,7 +2,7 @@ Function: nfeltdiveuc
 Section: number_fields
 C-Name: nfdiveuc
 Prototype: GGG
-Help: nfdiveuc(nf,x,y): gives algebraic integer q such that x-by is small.
+Help: nfdiveuc(nf,x,y): gives algebraic integer q such that x-qy is small.
 Doc: given two elements $x$ and $y$ in
  \var{nf}, computes an algebraic integer $q$ in the number field $\var{nf}$
  such that the components of $x-qy$ are reasonably small. In fact, this is
diff --git a/src/functions/number_fields/nfeltdivrem b/src/functions/number_fields/nfeltdivrem
index f2d5b6b..0133fe4 100644
--- a/src/functions/number_fields/nfeltdivrem
+++ b/src/functions/number_fields/nfeltdivrem
@@ -2,7 +2,7 @@ Function: nfeltdivrem
 Section: number_fields
 C-Name: nfdivrem
 Prototype: GGG
-Help: nfeltdivrem(nf,x,y): gives [q,r] such that r=x-by is small.
+Help: nfeltdivrem(nf,x,y): gives [q,r] such that r=x-qy is small.
 Doc: given two elements $x$ and $y$ in
  \var{nf}, gives a two-element row vector $[q,r]$ such that $x=qy+r$, $q$ is
  an algebraic integer in $\var{nf}$, and the components of $r$ are
diff --git a/src/functions/number_fields/nfeltmod b/src/functions/number_fields/nfeltmod
index e88c41f..ce2cfaa 100644
--- a/src/functions/number_fields/nfeltmod
+++ b/src/functions/number_fields/nfeltmod
@@ -2,7 +2,7 @@ Function: nfeltmod
 Section: number_fields
 C-Name: nfmod
 Prototype: GGG
-Help: nfeltmod(nf,x,y): gives r such that r=x-by is small with q algebraic
+Help: nfeltmod(nf,x,y): gives r such that r=x-qy is small with q algebraic
  integer.
 Doc:
  given two elements $x$ and $y$ in
diff --git a/src/functions/number_fields/nfgaloisconj b/src/functions/number_fields/nfgaloisconj
index 2bf4d66..03d8f1b 100644
--- a/src/functions/number_fields/nfgaloisconj
+++ b/src/functions/number_fields/nfgaloisconj
@@ -38,12 +38,16 @@ Doc: $\var{nf}$ being a number field as output by \kbd{nfinit}, computes the
  $K$-automorphism for any base field $K$ as follows:
  \bprog
  rnfgaloisconj(nfK, R) = \\ K-automorphisms of L = K[X] / (R)
- { my(polabs, N);
-   R *= Mod(1, nfK.pol);             \\ convert coeffs to polmod elts of K
-   polabs = rnfequation(nfK, R);
-   N = nfgaloisconj(polabs) % R;     \\ Q-automorphisms of L
-   \\ select the ones that fix K
-   select(s->subst(R, variable(R), Mod(s,R)) == 0, N);
+ {
+   my(polabs, N,al,S, ala,k, vR);
+   R *= Mod(1, nfK.pol); \\ convert coeffs to polmod elts of K
+   vR = variable(R);
+   al = Mod(variable(nfK.pol),nfK.pol);
+   [polabs,ala,k] = rnfequation(nfK, R, 1);
+   Rt = if(k==0,R,subst(R,vR,vR-al*k));
+   N = nfgaloisconj(polabs) % Rt; \\ Q-automorphisms of L
+   S = select(s->subst(Rt, vR, Mod(s,Rt)) == 0, N);
+   if (k==0, S, apply(s->subst(s,vR,vR+k*al)-k*al,S));
  }
  K  = nfinit(y^2 + 7);
  rnfgaloisconj(K, x^4 - y*x^3 - 3*x^2 + y*x + 1)  \\ K-automorphisms of L
diff --git a/src/functions/number_fields/nfhnf b/src/functions/number_fields/nfhnf
index 545e94d..425071f 100644
--- a/src/functions/number_fields/nfhnf
+++ b/src/functions/number_fields/nfhnf
@@ -7,7 +7,7 @@ Help: nfhnf(nf,x,{flag=0}): if x=[A,I], gives a pseudo-basis [B,J] of the module
  transformation matrix such that AU = [0|B]
 Doc: given a pseudo-matrix $(A,I)$, finds a
  pseudo-basis $(B,J)$ in \idx{Hermite normal form} of the module it generates.
- If $\fl$ is non-zero, also return the transfomation matrix $U$ such that
+ If $\fl$ is non-zero, also return the transformation matrix $U$ such that
  $AU = [0|B]$.
 
 Variant: Also available:
diff --git a/src/functions/number_fields/nfnewprec b/src/functions/number_fields/nfnewprec
index 1ccf2bc..62ce983 100644
--- a/src/functions/number_fields/nfnewprec
+++ b/src/functions/number_fields/nfnewprec
@@ -6,8 +6,9 @@ Help: nfnewprec(nf): transform the number field data nf into new data using
  the current (usually larger) precision.
 Doc: transforms the number field $\var{nf}$
  into the corresponding data using current (usually larger) precision. This
- function works as expected if $\var{nf}$ is in fact a $\var{bnf}$ (update
- $\var{bnf}$ to current precision) but may be quite slow (many generators of
- principal ideals have to be computed).
-Variant: See also \fun{GEN}{bnfnewprec}{GEN bnf, long prec}
- and \fun{GEN}{bnrnewprec}{GEN bnr, long prec}.
+ function works as expected if \var{nf} is in fact a \var{bnf} or a \var{bnr}
+ (update structure to current precision) but may be quite slow: many
+ generators of principal ideals have to be computed; note that in this latter
+ case, the \var{bnf} must contain fundamental units.
+Variant: See also \fun{GEN}{bnfnewprec}{GEN bnf, long prec} and
+ \fun{GEN}{bnrnewprec}{GEN bnr, long prec}.
diff --git a/src/functions/number_fields/nfsplitting b/src/functions/number_fields/nfsplitting
index 9ff82fd..69d10e9 100644
--- a/src/functions/number_fields/nfsplitting
+++ b/src/functions/number_fields/nfsplitting
@@ -3,12 +3,13 @@ Section: number_fields
 C-Name: nfsplitting
 Prototype: GDG
 Help: nfsplitting(nf,{d}): defining polynomial over Q for the splitting field of
- the number field nf; if d is given, it must be the degree of the splitting
- field
+ the number field nf; if d is given, it must be a multiple of the splitting
+ field degree
 Doc: defining polynomial over~$\Q$ for the splitting field of \var{nf};
- if $d$ is given, it must be the degree of the splitting field. Instead
- of~\kbd{nf}, it is possible to input an irreducible defining polynomial
- for~\kbd{nf}, but in general this is less efficient.
+ if $d$ is given, it must be a multiple of the splitting field degree.
+ Instead of~\kbd{nf}, it is possible to input a defining (irreducible)
+ polynomial $T$ for~\kbd{nf}, but in general this is less efficient.
+
  \bprog
  ? K = nfinit(x^3-2);
  ? nfsplitting(K)
@@ -21,8 +22,13 @@ Doc: defining polynomial over~$\Q$ for the splitting field of \var{nf};
  \bprog
  ? nfsplitting(x^17-123);
  time = 3,607 ms.
+ ? poldegree(%)
+ %2 = 272
  ? nfsplitting(x^17-123,272);
  time = 150 ms.
+ ? nfsplitting(x^17-123,273);
+  *** nfsplitting: Warning: ignoring incorrect degree bound 273
+ time = 3,611 ms.
  @eprog
  \noindent
  The complexity of the algorithm is polynomial in the degree $d$ of the
diff --git a/src/functions/number_fields/polredabs b/src/functions/number_fields/polredabs
index 9fae0be..8eb8c12 100644
--- a/src/functions/number_fields/polredabs
+++ b/src/functions/number_fields/polredabs
@@ -14,19 +14,19 @@ Doc: returns a canonical defining polynomial $P$ for the number field
  \tet{nfinit} are also allowed here, e.g. non-monic polynomials, or pairs
  \kbd{[T, listP]} specifying that a non-maximal order may be used.
 
- \misctitle{Warning 1} Using a \typ{POL} $T$ requires fully factoring the
- discriminant of $T$, which may be very hard. The format \kbd{[T, listP]}
- computes only a suborder of the maximal order and replaces this part of the
- algorithm by a polynomial time computation. In that case the polynomial $P$
- is a priori no longer canonical, and it may happen that it does not have
- minimal $T_2$ norm. The routine attempts to certify the result independently
- of this order computation (as per \tet{nfcertify}: we try to prove that the
- order is maximal); if it fails, the routine returns $0$ instead of $P$.
- In order to force an output in that case as well, you may either use
- \tet{polredbest}, or \kbd{polredabs(,16)}, or
- \bprog
-   polredabs([T, nfbasis([T, listP])])
- @eprog\noindent (In all three cases, the result is no longer canonical.)
+ \misctitle{Warning 1} Using a \typ{POL} $T$ requires computing
+ and fully factoring the discriminant $d_K$ of the maximal order which may be
+ very hard. You can use the format \kbd{[T, listP]}, where \kbd{listP}
+ encodes a list of known coprime divisors of $\disc(T)$ (see \kbd{??nfbasis}),
+ to help the routine, thereby replacing this part of the algorithm by a
+ polynomial time computation But this may only compute a suborder of the
+ maximal order, when the divisors are not squarefree or do not include all
+ primes dividing $d_K$. The routine attempts to certify the result
+ independently of this order computation as per \tet{nfcertify}: we try to
+ prove that the computed order is maximal. If the certification fails,
+ the routine then fully factors the integers returned by \kbd{nfcertify}.
+ You can use \tet{polredbest} or \kbd{polredabs(,16)} to avoid this
+ factorization step; in both cases, the result is no longer canonical.
 
  \misctitle{Warning 2} Apart from the factorization of the discriminant of
  $T$, this routine runs in polynomial time for a \emph{fixed} degree.
diff --git a/src/functions/number_fields/rnfeltabstorel b/src/functions/number_fields/rnfeltabstorel
index e1773bf..3a38259 100644
--- a/src/functions/number_fields/rnfeltabstorel
+++ b/src/functions/number_fields/rnfeltabstorel
@@ -4,10 +4,13 @@ C-Name: rnfeltabstorel
 Prototype: GG
 Help: rnfeltabstorel(rnf,x): transforms the element x from absolute to
  relative representation.
-Doc: $\var{rnf}$ being a relative
- number field extension $L/K$ as output by \kbd{rnfinit} and $x$ being an
+Doc: Let $\var{rnf}$ be a relative
+ number field extension $L/K$ as output by \kbd{rnfinit} and let $x$ be an
  element of $L$ expressed as a polynomial modulo the absolute equation
- \kbd{\var{rnf}.pol}, computes $x$ as an element of the relative extension
+ \kbd{\var{rnf}.pol}, or in terms of the absolute $\Z$-basis for $\Z_L$
+ if \var{rnf} contains one (as in \kbd{rnfinit(nf,pol,1)}, or after
+ a call to \kbd{nfinit(rnf)}).
+ Computes $x$ as an element of the relative extension
  $L/K$ as a polmod with polmod coefficients.
  \bprog
  ? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
@@ -15,11 +18,17 @@ Doc: $\var{rnf}$ being a relative
  %2 = x^4 + 1
  ? rnfeltabstorel(L, Mod(x, L.pol))
  %3 = Mod(x, x^2 + Mod(-y, y^2 + 1))
- ? rnfeltabstorel(L, Mod(2, L.pol))
- %4 = 2
+ ? rnfeltabstorel(L, 1/3)
+ %4 = 1/3
  ? rnfeltabstorel(L, Mod(x, x^2-y))
-  ***   at top-level: rnfeltabstorel(L,Mod
+ %5 = Mod(x, x^2 + Mod(-y, y^2 + 1))
+
+
+ ? rnfeltabstorel(L, [0,0,0,1]~) \\ Z_L not initialized yet
+  ***   at top-level: rnfeltabstorel(L,[0,
   ***                 ^--------------------
-  *** rnfeltabstorel: inconsistent moduli in rnfeltabstorel: x^2-y != x^4+1
+  *** rnfeltabstorel: incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).
+ ? nfinit(L); \\ initialize now
+ ? rnfeltabstorel(L, [0,0,0,1]~)
+ %6 = Mod(Mod(y, y^2 + 1)*x, x^2 + Mod(-y, y^2 + 1))
  @eprog
-
diff --git a/src/functions/number_fields/rnfeltdown b/src/functions/number_fields/rnfeltdown
index c0081e1..949dd1b 100644
--- a/src/functions/number_fields/rnfeltdown
+++ b/src/functions/number_fields/rnfeltdown
@@ -1,26 +1,39 @@
 Function: rnfeltdown
 Section: number_fields
-C-Name: rnfeltdown
-Prototype: GG
-Help: rnfeltdown(rnf,x): expresses x on the base field if possible; returns
- an error otherwise.
+C-Name: rnfeltdown0
+Prototype: GGD0,L,
+Help: rnfeltdown(rnf,x,{flag=0}): expresses x on the base field if possible;
+ returns an error otherwise.
 Doc: $\var{rnf}$ being a relative number
  field extension $L/K$ as output by \kbd{rnfinit} and $x$ being an element of
- $L$ expressed as a polynomial or polmod with polmod coefficients, computes
- $x$ as an element of $K$ as a polmod, assuming $x$ is in $K$ (otherwise a
- domain error occurs).
+ $L$ expressed as a polynomial or polmod with polmod coefficients (or as a
+ \typ{COL} on \kbd{nfinit(rnf).zk}), computes
+ $x$ as an element of $K$ as a \typ{POLMOD} if $\fl = 0$ and as a \typ{COL}
+ otherwise. If $x$ is not in $K$, a domain error occurs.
  \bprog
  ? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
  ? L.pol
  %2 = x^4 + 1
  ? rnfeltdown(L, Mod(x^2, L.pol))
  %3 = Mod(y, y^2 + 1)
+ ? rnfeltdown(L, Mod(x^2, L.pol), 1)
+ %4 = [0, 1]~
  ? rnfeltdown(L, Mod(y, x^2-y))
- %4 = Mod(y, y^2 + 1)
- ? rnfeltdown(L, Mod(y,K.pol))
  %5 = Mod(y, y^2 + 1)
+ ? rnfeltdown(L, Mod(y,K.pol))
+ %6 = Mod(y, y^2 + 1)
  ? rnfeltdown(L, Mod(x, L.pol))
   ***   at top-level: rnfeltdown(L,Mod(x,x
   ***                 ^--------------------
   *** rnfeltdown: domain error in rnfeltdown: element not in the base field
- @eprog
+ ? rnfeltdown(L, Mod(y, x^2-y), 1) \\ as a t_COL
+ %7 = [0, 1]~
+ ? rnfeltdown(L, [0,1,0,0]~) \\ not allowed without absolute nf struct
+   *** rnfeltdown: incorrect type in rnfeltdown (t_COL).
+ ? nfinit(L); \\ add absolute nf structure to L
+ ? rnfeltdown(L, [0,1,0,0]~) \\ now OK
+ %8 = Mod(y, y^2 + 1)
+ @eprog\noindent If we had started with
+ \kbd{L = rnfinit(K, x\pow2-y, 1)}, then the final would have worked directly.
+Variant: Also available is
+ \fun{GEN}{rnfeltdown}{GEN rnf, GEN x} ($\fl = 0$).
diff --git a/src/functions/number_fields/rnfelttrace b/src/functions/number_fields/rnfelttrace
index bba92de..7783cee 100644
--- a/src/functions/number_fields/rnfelttrace
+++ b/src/functions/number_fields/rnfelttrace
@@ -2,11 +2,11 @@ Function: rnfelttrace
 Section: number_fields
 C-Name: rnfelttrace
 Prototype: GG
-Help: rnfelttrace(rnf,x): returns the relative trace N_{L/K}(x), as an element
+Help: rnfelttrace(rnf,x): returns the relative trace Tr_{L/K}(x), as an element
  of K
 Doc: $\var{rnf}$ being a relative number field extension $L/K$ as output by
  \kbd{rnfinit} and $x$ being an element of $L$, returns the relative trace
- $N_{L/K}(x)$ as an element of $K$.
+ $Tr_{L/K}(x)$ as an element of $K$.
  \bprog
  ? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
  ? rnfelttrace(L, Mod(x, L.pol))
diff --git a/src/functions/number_fields/rnfeltup b/src/functions/number_fields/rnfeltup
index 3486d25..95e4a15 100644
--- a/src/functions/number_fields/rnfeltup
+++ b/src/functions/number_fields/rnfeltup
@@ -1,13 +1,15 @@
 Function: rnfeltup
 Section: number_fields
-C-Name: rnfeltup
-Prototype: GG
-Help: rnfeltup(rnf,x): expresses x (belonging to the base field) on the
- relative field.
+C-Name: rnfeltup0
+Prototype: GGD0,L,
+Help: rnfeltup(rnf,x,{flag=0}): expresses x (belonging to the base field) on
+ the relative field. As a t_POLMOD if flag = 0 and as a t_COL on the absolute
+ field integer basis if flag = 1
 Doc: $\var{rnf}$ being a relative number field extension $L/K$ as output by
  \kbd{rnfinit} and $x$ being an element of $K$, computes $x$ as an element of
- the absolute extension $L/\Q$ as a polynomial modulo the absolute equation
- \kbd{\var{rnf}.pol}.
+ the absolute extension $L/\Q$. As a \typ{POLMOD} modulo \kbd{\var{rnf}.pol}
+ if $\fl = 0$ and as a \typ{COL} on the absolute field integer basis if
+ $\fl = 1$.
  \bprog
  ? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
  ? L.pol
@@ -18,4 +20,8 @@ Doc: $\var{rnf}$ being a relative number field extension $L/K$ as output by
  %4 = Mod(x^2, x^4 + 1)
  ? rnfeltup(L, [1,2]~) \\ in terms of K.zk
  %5 = Mod(2*x^2 + 1, x^4 + 1)
+ ? rnfeltup(L, y, 1) \\ in terms of nfinit(L).zk
+ %6 = [0, 1, 0, 0]~
+ ? rnfeltup(L, [1,2]~, 1)
+ %7 = [1, 2, 0, 0]~
  @eprog
diff --git a/src/functions/number_fields/rnfidealprimedec b/src/functions/number_fields/rnfidealprimedec
new file mode 100644
index 0000000..deeee0b
--- /dev/null
+++ b/src/functions/number_fields/rnfidealprimedec
@@ -0,0 +1,30 @@
+Function: rnfidealprimedec
+Section: number_fields
+C-Name: rnfidealprimedec
+Prototype: GG
+Help: rnfidealprimedec(rnf,pr): prime ideal decomposition of the maximal
+ ideal pr of K in L/K; pr is also allowed to be a prime number p, in which
+ case we return a pair of vectors [SK,SL], where SK contains the primes of K
+ above p and SL[i] is the vector of primes of L above SK[i].
+Doc: let \var{rnf} be a relative number
+ field extension $L/K$ as output by \kbd{rnfinit}, and \kbd{pr} a maximal
+ ideal of $K$ (\kbd{prid}), this function completes the \var{rnf}
+ with a \var{nf} structure attached to $L$ (see \secref{se:rnfinit})
+ and returns the prime ideal decomposition of \kbd{pr} in $L/K$.
+ \bprog
+ ? K = nfinit(y^2+1); rnf = rnfinit(K, x^3+y+1);
+ ? P = idealprimedec(K, 2)[1];
+ ? S = rnfidealprimedec(rnf, P);
+ ? #S
+ %4 = 1
+ @eprog
+ The argument \kbd{pr} is also allowed to be a prime number $p$, in which
+ case we return a pair of vectors \kbd{[SK,SL]}, where \kbd{SK} contains
+ the primes of $K$ above $p$ and \kbd{SL}$[i]$ is the vector of primes of $L$
+ above \kbd{SK}$[i]$.
+ \bprog
+ ? [SK,SL] = rnfidealprimedec(rnf, 5);
+ ? [#SK, vector(#SL,i,#SL[i])]
+ %6 = [2, [2, 2]]
+ @eprog
+
diff --git a/src/functions/number_fields/rnfidealreltoabs b/src/functions/number_fields/rnfidealreltoabs
index 2564b16..7130100 100644
--- a/src/functions/number_fields/rnfidealreltoabs
+++ b/src/functions/number_fields/rnfidealreltoabs
@@ -1,22 +1,41 @@
 Function: rnfidealreltoabs
 Section: number_fields
-C-Name: rnfidealreltoabs
-Prototype: GG
-Help: rnfidealreltoabs(rnf,x): transforms the ideal x from relative to
- absolute representation.
-Doc: let $\var{rnf}$ be a relative
+C-Name: rnfidealreltoabs0
+Prototype: GGD0,L,
+Help: rnfidealreltoabs(rnf,x,{flag=0}): transforms the ideal x from relative to
+ absolute representation. As a vector of t_POLMODs if flag = 0 and as an ideal
+ in HNF in the absolute field if flag = 1
+Doc: Let $\var{rnf}$ be a relative
  number field extension $L/K$ as output by \kbd{rnfinit} and let $x$ be a
  relative ideal, given as a $\Z_K$-module by a pseudo matrix $[A,I]$.
- This function returns the ideal $x$ as an absolute ideal of $L/\Q$ in
- the form of a $\Z$-basis, given by a vector of polynomials (modulo
- \kbd{rnf.pol}).
-
- The reason why we do not return the customary HNF in terms of a fixed
- $\Z$-basis for $\Z_L$ is precisely that no such basis has been explicitly
- specified. On the other hand, if you already computed an (absolute) \kbd{nf}
- structure \kbd{Labs} associated to $L$, then
+ This function returns the ideal $x$ as an absolute ideal of $L/\Q$.
+ If $\fl = 0$, the result is given by a vector of \typ{POLMOD}s modulo
+ \kbd{rnf.pol} forming a $\Z$-basis; if $\fl = 1$, it is given in HNF in terms
+ of the fixed $\Z$-basis for $\Z_L$, see \secref{se:rnfinit}.
  \bprog
-   xabs = rnfidealreltoabs(L, x);
-   xLabs = mathnf(matalgtobasis(Labs, xabs));
- @eprog\noindent computes a traditional HNF \kbd{xLabs} for $x$ in terms of
- the fixed $\Z$-basis \kbd{Labs.zk}.
+ ? K = nfinit(y^2+1); rnf = rnfinit(K, x^2-y);
+ ? P = idealprimedec(K,2)[1];
+ ? P = rnfidealup(rnf, P)
+ %3 = [2, x^2 + 1, 2*x, x^3 + x]
+ ? Prel = rnfidealhnf(rnf, P)
+ %4 = [[1, 0; 0, 1], [[2, 1; 0, 1], [2, 1; 0, 1]]]
+ ? rnfidealreltoabs(rnf,Prel)
+ %5 = [2, x^2 + 1, 2*x, x^3 + x]
+ ? rnfidealreltoabs(rnf,Prel,1)
+ %6 =
+ [2 1 0 0]
+
+ [0 1 0 0]
+
+ [0 0 2 1]
+
+ [0 0 0 1]
+ @eprog
+ The reason why we do not return by default ($\fl = 0$) the customary HNF in
+ terms of a fixed $\Z$-basis for $\Z_L$ is precisely because
+ a \var{rnf} does not contain such a basis by default. Completing the
+ structure so that it contains a \var{nf} structure for $L$ is polynomial
+ time but costly when the absolute degree is large, thus it is not done by
+ default. Note that setting $\fl = 1$ will complete the \var{rnf}.
+Variant: Also available is
+ \fun{GEN}{rnfidealreltoabs}{GEN rnf, GEN x} ($\fl = 0$).
diff --git a/src/functions/number_fields/rnfidealup b/src/functions/number_fields/rnfidealup
index 6ad0f4e..754db85 100644
--- a/src/functions/number_fields/rnfidealup
+++ b/src/functions/number_fields/rnfidealup
@@ -1,21 +1,36 @@
 Function: rnfidealup
 Section: number_fields
-C-Name: rnfidealup
-Prototype: GG
-Help: rnfidealup(rnf,x): lifts the ideal x (of the base field) to the
- relative field.
+C-Name: rnfidealup0
+Prototype: GGD0,L,
+Help: rnfidealup(rnf,x,{flag=0}): lifts the ideal x (of the base field) to the
+ relative field. As a vector of t_POLMODs if flag = 0 and as an ideal in HNF
+ in the absolute field if flag = 1
 Doc: let $\var{rnf}$ be a relative number
  field extension $L/K$ as output by \kbd{rnfinit} and let $x$ be an ideal of
  $K$. This function returns the ideal $x\Z_L$ as an absolute ideal of $L/\Q$,
- in the form of a $\Z$-basis, given by a vector of polynomials (modulo
- \kbd{rnf.pol}).
-
- The reason why we do not return the customary HNF in terms of a fixed
- $\Z$-basis for $\Z_L$ is precisely that no such basis has been explicitly
- specified. On the other hand, if you already computed an (absolute) \var{nf}
- structure \kbd{Labs} associated to $L$, then
+ in the form of a $\Z$-basis. If $\fl = 0$, the result is given by a vector of
+ polynomials (modulo \kbd{rnf.pol}); if $\fl = 1$, it is given in HNF in terms
+ of the fixed $\Z$-basis for $\Z_L$, see \secref{se:rnfinit}.
  \bprog
-   xabs = rnfidealup(L, x);
-   xLabs = mathnf(matalgtobasis(Labs, xabs));
- @eprog\noindent computes a traditional HNF \kbd{xLabs} for $x$ in terms of
- the fixed $\Z$-basis \kbd{Labs.zk}.
+ ? K = nfinit(y^2+1); rnf = rnfinit(K, x^2-y);
+ ? P = idealprimedec(K,2)[1];
+ ? rnfidealup(rnf, P)
+ %3 = [2, x^2 + 1, 2*x, x^3 + x]
+ ? rnfidealup(rnf, P,1)
+ %4 =
+ [2 1 0 0]
+
+ [0 1 0 0]
+
+ [0 0 2 1]
+
+ [0 0 0 1]
+ @eprog
+ The reason why we do not return by default ($\fl = 0$) the customary HNF in
+ terms of a fixed $\Z$-basis for $\Z_L$ is precisely because
+ a \var{rnf} does not contain such a basis by default. Completing the
+ structure so that it contains a \var{nf} structure for $L$ is polynomial
+ time but costly when the absolute degree is large, thus it is not done by
+ default. Note that setting $\fl = 1$ will complete the \var{rnf}.
+Variant: Also available is
+  \fun{GEN}{rnfidealup}{GEN rnf, GEN x} ($\fl = 0$).
diff --git a/src/functions/number_fields/rnfinit b/src/functions/number_fields/rnfinit
index 31f1fda..c67b64c 100644
--- a/src/functions/number_fields/rnfinit
+++ b/src/functions/number_fields/rnfinit
@@ -1,8 +1,8 @@
 Function: rnfinit
 Section: number_fields
-C-Name: rnfinit
-Prototype: GG
-Help: rnfinit(nf,pol): pol being an irreducible polynomial
+C-Name: rnfinit0
+Prototype: GGD0,L,
+Help: rnfinit(nf,pol,{flag=0}): pol being an irreducible polynomial
  defined over the number field nf, initializes a vector of data necessary for
  working in relative number fields (rnf functions). See manual for technical
  details.
@@ -15,19 +15,23 @@ Doc: $\var{nf}$ being a number field in \kbd{nfinit}
 
  The result is a row vector, whose components are technical. In the following
  description, we let $K$ be the base field defined by $\var{nf}$ and $L/K$
- the large field associated to the \var{rnf}. Furthermore, we let
+ the extension attached to the \var{rnf}. Furthermore, we let
  $m = [K:\Q]$ the degree of the base field, $n = [L:K]$ the relative degree,
  $r_1$ and $r_2$ the number of real and complex places of $K$. Access to this
  information via \emph{member functions} is preferred since the specific
  data organization specified below will change in the future.
 
- Note that a subsequent \kbd{nfinit}$(\var{rnf})$ will explicitly add an
- \kbd{nf} structure associated to $L$ to \var{rnf} (and return it as well).
+ If $\fl = 1$, add an \var{nf} structure attached to $L$ to \var{rnf}.
  This is likely to be very expensive if the absolute degree $mn$ is large,
  but fixes an integer basis for $\Z_L$ as a $\Z$-module and allows to input
  and output elements of $L$ in absolute form: as \typ{COL} for elements,
  as \typ{MAT} in HNF for ideals, as \kbd{prid} for prime ideals. Without such
  a call, elements of $L$ are represented as \typ{POLMOD}, etc.
+ Note that a subsequent \kbd{nfinit}$(\var{rnf})$ will also explicitly
+ add such a component, and so will the following functions \kbd{rnfidealmul},
+ \kbd{rnfidealtwoelt}, \kbd{rnfidealprimedec}, \kbd{rnfidealup} (with flag 1)
+ and \kbd{rnfidealreltoabs} (with flag 1). The absolute \var{nf} structure
+ attached to $L$ can be recovered using \kbd{nfinit(rnf)}.
 
  $\var{rnf}[1]$(\kbd{rnf.pol}) contains the relative polynomial \var{pol}.
 
@@ -88,3 +92,5 @@ Doc: $\var{nf}$ being a number field in \kbd{nfinit}
  to store further information about the field as it becomes available (which
  is rarely needed, hence would be too expensive to compute during the initial
  \kbd{rnfinit} call).
+Variant: Also available is
+ \fun{GEN}{rnfinit}{GEN nf,GEN pol} ($\fl = 0$).
diff --git a/src/functions/number_theoretical/chareval b/src/functions/number_theoretical/chareval
index 0729fe4..6779685 100644
--- a/src/functions/number_theoretical/chareval
+++ b/src/functions/number_theoretical/chareval
@@ -2,7 +2,13 @@ Function: chareval
 Section: number_theoretical
 C-Name: chareval
 Prototype: GGGDG
-Help: chareval(G,chi, x, {z})):
+Help: chareval(G, chi, x, {z})): given an abelian group structure affording
+ a discrete logarithm method, e.g. G = idealstar(,N) or a bnr structure,
+ let x be an element of G and let chi be a character of G. This function
+ returns the value of chi at x, where the encoding depends on the optional
+ argument z; if z is omitted, we fix a canonical o-th root of 1, zeta_o,
+ where o is the character order and return the rational number c/o where
+ chi(x) = (zeta_o)^c
 Doc:
  Let $G$ be an abelian group structure affording a discrete logarithm
  method, e.g $G = \kbd{idealstar}(,N)$ for $(\Z/N\Z)^*$ or a \kbd{bnr}
@@ -16,12 +22,12 @@ Doc:
  multiple of the character order such that $\chi(n) = \zeta^{c(n)}$ for some
  fixed $\zeta\in K^*$ of multiplicative order $o$ and a unique morphism $c: G
  \to (\Z/o\Z,+)$. Our usual convention is to write
-    $$G = (\Z/o_1\Z) g_1 \oplus \cdots \oplus (\Z/o_d\Z) g_d$$
+ $$G = (\Z/o_1\Z) g_1 \oplus \cdots \oplus (\Z/o_d\Z) g_d$$
  for some generators $(g_i)$ of respective order $d_i$, where the group has
  exponent $o := \text{lcm}_i o_i$. Since $\zeta^o = 1$, the vector $(c_i)$ in
  $\prod (\Z/o_i\Z)$ defines a character $\chi$ on $G$ via $\chi(g_i) =
  \zeta^{c_i (o/o_i)}$ for all $i$. Classical Dirichlet characters have values
-  in $K = \C$ and we can take $\zeta = \exp(2i\pi/o)$.
+ in $K = \C$ and we can take $\zeta = \exp(2i\pi/o)$.
 
  \misctitle{Note on Dirichlet characters}
  In the special case where \var{bid} is attached to $G = (\Z/q\Z)^*$
diff --git a/src/functions/number_theoretical/ispower b/src/functions/number_theoretical/ispower
index 9eb1a2a..a376a05 100644
--- a/src/functions/number_theoretical/ispower
+++ b/src/functions/number_theoretical/ispower
@@ -11,7 +11,8 @@ Description:
  (int):small       Z_isanypower($1, NULL)
  (int, &int):small Z_isanypower($1, &$2)
 Doc: if $k$ is given, returns true (1) if $x$ is a $k$-th power, false
- (0) if not.
+ (0) if not. What it means to be a $k$-th power depends on the type of
+ $x$; see \tet{issquare} for details.
 
  If $k$ is omitted, only integers and fractions are allowed for $x$ and the
  function returns the maximal $k \geq 2$ such that $x = n^k$ is a perfect
diff --git a/src/functions/number_theoretical/issquare b/src/functions/number_theoretical/issquare
index 8cb1e58..894854d 100644
--- a/src/functions/number_theoretical/issquare
+++ b/src/functions/number_theoretical/issquare
@@ -35,6 +35,17 @@ Doc: true (1) if $x$ is a square, false (0)
  directly odd and even-power monomials) or we assume that $2$ is invertible
  and check whether squaring the truncated power series for the square root
  yields the original input.
+
+ For \typ{POLMOD} $x$, we only support \typ{POLMOD}s of \typ{INTMOD}s
+ encoding finite fields, assuming without checking that the intmod modulus
+ $p$ is prime and that the polmod modulus is irreducible modulo $p$.
+ \bprog
+ ? issquare(Mod(Mod(2,3), x^2+1), &n)
+ %1 = 1
+ ? n
+ %2 = Mod(Mod(2, 3)*x, Mod(1, 3)*x^2 + Mod(1, 3))
+ @eprog
+
 Variant: Also available is \fun{long}{issquare}{GEN x}. Deprecated
  GP-specific functions \fun{GEN}{gissquare}{GEN x} and
  \fun{GEN}{gissquareall}{GEN x, GEN *pt} return \kbd{gen\_0} and \kbd{gen\_1}
diff --git a/src/functions/number_theoretical/qfbnupow b/src/functions/number_theoretical/qfbnupow
index a2b3b15..6243132 100644
--- a/src/functions/number_theoretical/qfbnupow
+++ b/src/functions/number_theoretical/qfbnupow
@@ -10,5 +10,5 @@ Doc: $n$-th power of the primitive positive definite
  the discriminant of $x$.
 
  The current implementation is slower than the generic routine for small
- discriminant $D$, and becomes faster for $D \approx 2^45$.
+ discriminant $D$, and becomes faster for $D \approx 2^{45}$.
 
diff --git a/src/functions/number_theoretical/ramanujantau b/src/functions/number_theoretical/ramanujantau
index 98027fe..d6eebeb 100644
--- a/src/functions/number_theoretical/ramanujantau
+++ b/src/functions/number_theoretical/ramanujantau
@@ -2,8 +2,8 @@ Function: ramanujantau
 Section: number_theoretical
 C-Name: ramanujantau
 Prototype: G
-Help: tau(n): compute the value of Ramanujan's tau function at n, assuming
- the GRH. Algorithm in O(n^{1/2+eps}).
+Help: ramanujantau(n): compute the value of Ramanujan's tau function at n,
+ assuming the GRH. Algorithm in O(n^{1/2+eps}).
 Doc: compute the value of Ramanujan's tau function at an individual $n$,
  assuming the truth of the GRH (to compute quickly class numbers of imaginary
  quadratic fields using \tet{quadclassunit}).
diff --git a/src/functions/number_theoretical/znconreychar b/src/functions/number_theoretical/znconreychar
index c5cc855..8ade6a3 100644
--- a/src/functions/number_theoretical/znconreychar
+++ b/src/functions/number_theoretical/znconreychar
@@ -3,7 +3,7 @@ Section: number_theoretical
 C-Name: znconreychar
 Prototype: GG
 Help: znconreychar(bid,m): Dirichlet character associated to m in (Z/qZ)*
- in Conrey's notation, where bid is znstar(q, 2)
+ in Conrey's notation, where bid is idealstar(,q)
 Doc: Given a \var{bid} associated to $(\Z/q\Z)^*$ (as per
  \kbd{bid = idealstar(,q)}), this function returns the Dirichlet character
  associated to $m \in (\Z/q\Z)^*$ via Conrey's logarithm, which
diff --git a/src/functions/polynomials/polcoeff b/src/functions/polynomials/polcoeff
index ad9f4cf..467b228 100644
--- a/src/functions/polynomials/polcoeff
+++ b/src/functions/polynomials/polcoeff
@@ -7,8 +7,8 @@ Help: polcoeff(x,n,{v}): coefficient of degree n of x, or the n-th component
  to the main variable if v is omitted, with respect to the variable v
  otherwise.
 Description:
- (pol, 0):gen:copy       constant_term($1)
- (pol, 0,):gen:copy      constant_term($1)
+ (pol, 0):gen:copy       constant_coeff($1)
+ (pol, 0,):gen:copy      constant_coeff($1)
  (pol, small):gen:copy   RgX_coeff($1, $2)
  (pol, small,):gen:copy  RgX_coeff($1, $2)
  (gen, small, ?var):gen polcoeff0($1, $2, $3)
diff --git a/src/functions/polynomials/pollead b/src/functions/polynomials/pollead
index b7fc2a6..8857bac 100644
--- a/src/functions/polynomials/pollead
+++ b/src/functions/polynomials/pollead
@@ -6,7 +6,7 @@ Help: pollead(x,{v}): leading coefficient of polynomial or series x, or x
  itself if x is a scalar. Error otherwise. With respect to the main variable
  of x if v is omitted, with respect to the variable v otherwise.
 Description:
- (pol):gen:copy         leading_term($1)
+ (pol):gen:copy         leading_coeff($1)
  (gen):gen              pollead($1, -1)
  (gen, var):gen         pollead($1, $2)
 Doc: leading coefficient of the polynomial or power series $x$. This is
diff --git a/src/functions/polynomials/polmodular b/src/functions/polynomials/polmodular
index cf47c01..9ba433d 100644
--- a/src/functions/polynomials/polmodular
+++ b/src/functions/polynomials/polmodular
@@ -2,26 +2,37 @@ Function: polmodular
 Section: polynomials
 C-Name: polmodular
 Prototype: LD0,L,DGDnD0,L,
-Help: polmodular(L, {inv = 0}, {x = 'x}, {y = 'y}, {compute_derivs = 0}): return the
- modular polynomial of level L and invariant inv.
-Doc:
- Return the modular polynomial of level $L$ in variables $x$ and $y$
- for the modular function specified by $inv$.  If $inv$ is 0 (the
- default), use the modular f$j$ function, if $inv$ is 1 use the
- Weber-$f$ function, and if $inv$ is 5 use $\gamma_2 =
+Help: polmodular(L, {inv = 0}, {x = 'x}, {y = 'y}, {derivs = 0}):
+ return the modular polynomial of level L and invariant inv.
+Doc: Return the modular polynomial of level $L$ in variables $x$ and $y$
+ for the modular function specified by \kbd{inv}.  If \kbd{inv} is 0 (the
+ default), use the modular $j$ function, if \kbd{inv} is 1 use the
+ Weber-$f$ function, and if \kbd{inv} is 5 use $\gamma_2 =
  \sqrt[3]{j}$. If $x$ is given as \kbd{Mod(j, p)} or an element $j$ of
- a prime finite field, then return the modular polynomial of level $L$
- evaluated at $j$ modulo $p$.  If $j$ is from a finite field and
- \var{compute\_derivs} is non-zero, then return a triple where the
+ a finite field (as a \typ{FFELT}), then return the modular polynomial of
+ level $L$ evaluated at $j$.  If $j$ is from a finite field and
+ \kbd{derivs} is non-zero, then return a triple where the
  last two elements are the first and second derivatives of the modular
  polynomial evaluated at $j$.
  \bprog
  ? polmodular(3)
- %1 = x^4 + (-y^3 + 2232*y^2 - 1069956*y + 36864000)*x^3 + [...]
- ? polmodular(11, 1, , 'J)
- x^12 - J^11*x^11 + 11*J^9*x^9 - 44*J^7*x^7 + 88*J^5*x^5 - 88*J^3*x^3 + 32*J*x + J^12
- ? polmodular(11, 5, 7*ffgen(19)^0, 'j)
- j^12 + j^11 + 7*j^10 + 5*j^9 + 11*j^8 + 10*j^7 + 18*j^6 + 2*j^5 + j^4 + 18*j^3 + 13*j^2 + 11*j + 1
+ %1 = x^4 + (-y^3 + 2232*y^2 - 1069956*y + 36864000)*x^3 + ...
+ ? polmodular(7, 1, , 'J)
+ %2 = x^8 - J^7*x^7 + 7*J^4*x^4 - 8*J*x + J^8
+ ? polmodular(7, 5, 7*ffgen(19)^0, 'j)
+ %3 = j^8 + 4*j^7 + 4*j^6 + 8*j^5 + j^4 + 12*j^2 + 18*j + 18
+ ? polmodular(7, 5, Mod(7,19), 'j)
+ %4 = Mod(1, 19)*j^8 + Mod(4, 19)*j^7 + Mod(4, 19)*j^6 + ...
+
+ ? u = ffgen(5)^0; T = polmodular(3,0,,'j)*u;
+ ? polmodular(3, 0, u,'j,1)
+ %6 = [j^4 + 3*j^2 + 4*j + 1, 3*j^2 + 2*j + 4, 3*j^3 + 4*j^2 + 4*j + 2]
+ ? subst(T,x,u)
+ %7 = j^4 + 3*j^2 + 4*j + 1
+ ? subst(T',x,u)
+ %8 = 3*j^2 + 2*j + 4
+ ? subst(T'',x,u)
+ %9 = 3*j^3 + 4*j^2 + 4*j + 2
  @eprog
 Variant: Also available are
 
@@ -32,15 +43,15 @@ Variant: Also available are
  \fun{GEN}{polmodular_ZM}{long L, long inv} which returns a matrix of
  coefficients, and
 
- \fun{GEN}{Fp_polmodular_evalx}{long L, long inv, GEN J, GEN P, long
- v, int compute_derivs} which returns the modular polynomial evaluated
- at $J$ modulo $P$ in the variable $v$ (if \kbd{compute\_derivs} is
+ \fun{GEN}{Fp_polmodular_evalx}{long L, long inv, GEN J, GEN P, long v,
+ int derivs} which returns the modular polynomial evaluated
+ at $J$ modulo $P$ in the variable $v$ (if \kbd{derivs} is
  non-zero, returns a vector containing the modular polynomial and its
  first and second derivatives, all evaluated at $J$ modulo $P$).
 
 Function: _polmodular_worker
 Section: programming/internals
 C-Name: polmodular_worker
-Prototype: UUUGGGGGLGG
+Prototype: UUUGGGGLGG
 Help: used by polmodular
 Doc: used by polmodular
diff --git a/src/functions/polynomials/polresultant b/src/functions/polynomials/polresultant
index de0422b..2737dc0 100644
--- a/src/functions/polynomials/polresultant
+++ b/src/functions/polynomials/polresultant
@@ -15,10 +15,16 @@ Doc: resultant of the two
  the $u$ and $v$ such that $x*u + y*v = \text{Res}(x,y)$, use the
  \tet{polresultantext} function.
 
- If $\fl=0$ (default), uses the the algorithm best suited to the inputs,
+ If $\fl=0$ (default), uses the algorithm best suited to the inputs,
  either the \idx{subresultant algorithm} (Lazard/Ducos variant, generic case),
  a modular algorithm (inputs in $\Q[X]$) or Sylvester's matrix (inexact
  inputs).
 
  If $\fl=1$, uses the determinant of Sylvester's matrix instead; this should
  always be slower than the default.
+
+Function: _ZX_resultant_worker
+C-Name: ZX_resultant_worker
+Prototype: GGGG
+Section: programming/internals
+Help: worker for ZX_resultant
diff --git a/src/functions/polynomials/polrootsreal b/src/functions/polynomials/polrootsreal
index d5c1a90..47f50a9 100644
--- a/src/functions/polynomials/polrootsreal
+++ b/src/functions/polynomials/polrootsreal
@@ -24,7 +24,7 @@ Doc: real roots of the polynomial $T$ with rational coefficients, multiple
  The algorithm used is a modification of Uspensky's method (relying on
  Descartes's rule of sign), following Rouillier and Zimmerman ``Efficient
  isolation of a polynomial real roots''
- (\url{http://hal.inria.fr/inria-00072518/}. Barring bugs, it is guaranteed
+ (\url{http://hal.inria.fr/inria-00072518/}). Barring bugs, it is guaranteed
  to converge and to give the roots to the required accuracy.
 
  \misctitle{Remark} If the polynomial $T$ is of the
diff --git a/src/functions/polynomials/polsturm b/src/functions/polynomials/polsturm
index ead0128..46a344b 100644
--- a/src/functions/polynomials/polsturm
+++ b/src/functions/polynomials/polsturm
@@ -24,7 +24,19 @@ Doc: number of real roots of the real squarefree polynomial \var{T}. If
  %4 = 3
  ? polsturm(T, [1, Pi])  \\ Pi inexact: not recommended !
  %5 = 3
- @eprog
+ ? polsturm(T*1., [0, 4])  \\ T*1. inexact: not recommended !
+ %6 = 3
+ ? polsturm(T^2, [0, 4])  \\ not squarefree
+  ***   at top-level: polsturm(T^2,[0,4])
+  ***                 ^-------------------
+  *** polsturm: domain error in polsturm: issquarefree(pol) = 0
+ ? polsturm((T*1.)^2, [0, 4])  \\ not squarefree AND inexact
+  ***   at top-level: polsturm((T*1.)^2,[0
+  ***                 ^--------------------
+  *** polsturm: precision too low in polsturm.
+ @eprog\noindent In the last example, the input polynomial is not
+ squarefree but there is no way to ascertain it from the given
+ floating point approximation: we get a precision error in this case.
  %\syn{NO}
 
  The library syntax is \fun{long}{RgX_sturmpart}{GEN T, GEN ab} or
diff --git a/src/functions/programming/alias b/src/functions/programming/alias
index c90bdad..15a50ff 100644
--- a/src/functions/programming/alias
+++ b/src/functions/programming/alias
@@ -4,7 +4,7 @@ C-Name: alias0
 Prototype: vrr
 Help: alias(newsym,sym): defines the symbol newsym as an alias for the symbol
  sym.
-Doc: defines the symbol \var{newsym} as an alias for the the symbol \var{sym}:
+Doc: defines the symbol \var{newsym} as an alias for the symbol \var{sym}:
  \bprog
  ? alias("det", "matdet");
  ? det([1,2;3,4])
diff --git a/src/functions/programming/for b/src/functions/programming/for
index 291bfb6..985f9ce 100644
--- a/src/functions/programming/for
+++ b/src/functions/programming/for
@@ -3,6 +3,9 @@ Section: programming/control
 C-Name: forpari
 Prototype: vV=GGI
 Help: for(X=a,b,seq): the sequence is evaluated, X going from a up to b.
+ If b is set to +oo, the loop will not stop.
 Doc: evaluates \var{seq}, where
  the formal variable $X$ goes from $a$ to $b$. Nothing is done if $a>b$.
- $a$ and $b$ must be in $\R$.
+ $a$ and $b$ must be in $\R$. If $b$ is set to \kbd{+oo}, the loop will not
+ stop; it is expected that the caller will break out of the loop itself at some
+ point, using \kbd{break} or \kbd{return}.
diff --git a/src/functions/programming/forprime b/src/functions/programming/forprime
index 4164267..4ebcaa1 100644
--- a/src/functions/programming/forprime
+++ b/src/functions/programming/forprime
@@ -56,9 +56,9 @@ Doc: evaluates \var{seq},
  ? forprime(p = 4, 10, print(p))
  5
  7
- @eprog\noindent Omitting $b$ means we will run through all primes $\geq a$,
- starting an infinite loop; it is expected that the user will break out of
- the loop himself at some point, using \kbd{break} or \kbd{return}.
+ @eprog\noindent Setting $b$ to \kbd{+oo} means we will run through all primes
+ $\geq a$, starting an infinite loop; it is expected that the caller will break
+ out of the loop itself at some point, using \kbd{break} or \kbd{return}.
 
  Note that the value of $p$ cannot be modified within \var{seq}:
  \bprog
diff --git a/src/functions/programming/forstep b/src/functions/programming/forstep
index 809ebe2..a963d95 100644
--- a/src/functions/programming/forstep
+++ b/src/functions/programming/forstep
@@ -3,7 +3,8 @@ Section: programming/control
 C-Name: forstep
 Prototype: vV=GGGI
 Help: forstep(X=a,b,s,seq): the sequence is evaluated, X going from a to b
- in steps of s (can be a vector of steps).
+ in steps of s (can be a vector of steps). If b is set to +oo the loop will
+ not stop.
 Doc: evaluates \var{seq},
  where the formal variable $X$ goes from $a$ to $b$, in increments of $s$.
  Nothing is done if $s>0$ and $a>b$ or if $s<0$ and $a<b$. $s$ must be in
@@ -18,4 +19,6 @@ Doc: evaluates \var{seq},
  13
  17
  19
- @eprog
+ @eprog\noindent Setting $b$ to \kbd{+oo} will start an infinite loop; it is
+ expected that the caller will break out of the loop itself at some point,
+ using \kbd{break} or \kbd{return}.
diff --git a/src/functions/programming/parfor b/src/functions/programming/parfor
index 186ea19..de805ab 100644
--- a/src/functions/programming/parfor
+++ b/src/functions/programming/parfor
@@ -6,13 +6,13 @@ Description:
  (gen,gen,closure):void parfor($1, $2, $3, NULL, NULL)
 Help: parfor(i=a,{b},expr1,{r},{expr2}):
  evaluates the expression expr1 in parallel for all i between a and b
- (if b is omitted, the loop will not stop), resulting in as many
+ (if b is set to +oo, the loop will not stop), resulting in as many
  values; if the formal variables r and expr2 are present, evaluate
  sequentially expr2, in which r has been replaced by the different results
  obtained for expr1 and i with the corresponding arguments.
 Doc: evaluates in parallel the expression \kbd{expr1} in the formal
  argument $i$ running from $a$ to $b$.
- If $b$ is omitted, the loop runs indefinitely.
+ If $b$ is set to \kbd{+oo}, the loop runs indefinitely.
  If $r$ and \kbd{expr2} are present, the expression \kbd{expr2} in the
  formal variables $r$ and $i$ is evaluated with $r$ running through all
  the different results obtained for \kbd{expr1} and $i$ takes the
diff --git a/src/functions/programming/parforprime b/src/functions/programming/parforprime
index 461f88f..4a52ba5 100644
--- a/src/functions/programming/parforprime
+++ b/src/functions/programming/parforprime
@@ -6,7 +6,7 @@ Description:
  (gen,gen,closure):void parforprime($1, $2, $3, NULL, NULL)
 Help: parforprime(p=a,{b},expr1,{r},{expr2}):
  evaluates the expression expr1 in parallel for all primes p between a and b
- (if b is omitted, the loop will not stop), resulting in as many
+ (if b is set to +oo, the loop will not stop), resulting in as many
  values; if the formal variables r and expr2 are present, evaluate
  sequentially expr2, in which r has been replaced by the different results
  obtained for expr1 and p with the corresponding arguments.
@@ -15,7 +15,7 @@ Doc:
  Precisely, the functions evaluates in parallel the expression \kbd{expr1}
  in the formal
  argument $p$ running through the primes from $a$ to $b$.
- If $b$ is omitted, the loop runs indefinitely.
+ If $b$ is set to \kbd{+oo}, the loop runs indefinitely.
  If $r$ and \kbd{expr2} are present, the expression \kbd{expr2} in the
  formal variables $r$ and $p$ is evaluated with $r$ running through all
  the different results obtained for \kbd{expr1} and $p$ takes the
diff --git a/src/functions/sums/intnumgauss b/src/functions/sums/intnumgauss
index 8949854..5cc279d 100644
--- a/src/functions/sums/intnumgauss
+++ b/src/functions/sums/intnumgauss
@@ -31,7 +31,7 @@ Doc: numerical integration of \var{expr} on the compact interval $[a,b]$ with
  and change variables rather than increasing $n$ too much:
  \bprog
  ? f(x) = 1/(1+x^2);
- ? a = 0; b = 100;
- ? intnumgauss(x=0,1, f(x)) + intnumgauss(x=1,1/b, f(1/x)*(-1/x^2)) - atan(100)
+ ? b = 100;
+ ? intnumgauss(x=0,1, f(x)) + intnumgauss(x=1,1/b, f(1/x)*(-1/x^2)) - atan(b)
  %3 = -1.0579449157400587572 E-37
  @eprog
diff --git a/src/functions/sums/solvestep b/src/functions/sums/solvestep
index bbdb531..0ef5ff2 100644
--- a/src/functions/sums/solvestep
+++ b/src/functions/sums/solvestep
@@ -17,8 +17,9 @@ Doc: find zeros of a continuous function in the real interval $[a,b]$ by naive
  \item 2: refine the splitting until at least one zero is found
  (may loop indefinitely if there are no zeros);
 
- \item 4: do a multiplicative search (we must have $a > 0$ and $\var{step} > 1$), otherwise
- an additive search; \var{step} is the multiplicative or additive step.
+ \item 4: do a multiplicative search (we must have $a > 0$ and $\var{step} >
+ 1$), otherwise an additive search; \var{step} is the multiplicative or
+ additive step.
 
  \item 8: refine the splitting until at least one zero is very close to an
  integer.
@@ -27,7 +28,7 @@ Doc: find zeros of a continuous function in the real interval $[a,b]$ by naive
  ? solvestep(X=0,10,1,sin(X^2),1)
  %1 = 1.7724538509055160272981674833411451828
  ? solvestep(X=1,12,2,besselj(4,X),4)
- %2 = [7.5883424345038043850696300079856174174, 11.064709488501184882718322290192246095]
+ %2 = [7.588342434..., 11.064709488...]
  @eprog\noindent
 
  \synt{solvestep}{void *E,GEN (*eval)(void*,GEN),GEN a,GEN b,GEN step,long flag,long prec}.
diff --git a/src/functions/sums/sumalt b/src/functions/sums/sumalt
index 6cf4567..4f1931c 100644
--- a/src/functions/sums/sumalt
+++ b/src/functions/sums/sumalt
@@ -14,8 +14,8 @@ Doc: numerical summation of the series \var{expr}, which should be an
  $a$. Use an algorithm of Cohen, Villegas and Zagier (\emph{Experiment. Math.}
  {\bf 9} (2000), no.~1, 3--12).
 
- If $\fl=0$, assuming that that the $a_k$ are the moments of a positive
- measure on $[0,1]$, the relative error is $O(3+\sqrt8)^(-n)$ after using
+ If $\fl=0$, assuming that the $a_k$ are the moments of a positive
+ measure on $[0,1]$, the relative error is $O(3+\sqrt8)^{-n}$ after using
  $a_k$ for $k\leq n$. If \kbd{realprecision} is $p$, we thus set
  $n = \log(10)p/\log(3+\sqrt8)\approx 1.3 p$; besides the time needed to
  compute the $a_k$, $k\leq n$, the algorithm overhead is negligible: time
@@ -24,7 +24,7 @@ Doc: numerical summation of the series \var{expr}, which should be an
  If $\fl=1$, use a variant with more complicated polynomials, see
  \tet{polzagier}. If the $a_k$ are the moments of $w(x)dx$ where $w$
  (or only $xw(x^2)$) is a smooth function extending analytically to the whole
- complex plane, convergence is in $O(14.4^(-n))$. If $xw(x^2)$ extends
+ complex plane, convergence is in $O(14.4^{-n})$. If $xw(x^2)$ extends
  analytically to a smaller region, we still have exponential convergence,
  with worse constants. Usually faster when the computation of $a_k$ is
  expensive. If \kbd{realprecision} is $p$, we thus set
diff --git a/src/functions/sums/sumnum b/src/functions/sums/sumnum
index 4db5dfb..a16a48d 100644
--- a/src/functions/sums/sumnum
+++ b/src/functions/sums/sumnum
@@ -60,7 +60,7 @@ Doc: Numerical summation of $f(n)$ at high accuracy using Euler-MacLaurin,
  ? sumnum(n = 1, lngamma(1+1/n)/n, tab);
  time = 14,180 ms.
 
- ? sumnummonien(n = 1, lngamma(1+1/n)/n, tabmon); \\ fewer function evaluations!
+ ? sumnummonien(n = 1, lngamma(1+1/n)/n, tabmon); \\ fewer evaluations
  time = 717 ms.
  @eprog
 
diff --git a/src/functions/sums/sumpos b/src/functions/sums/sumpos
index 170a543..7f8490b 100644
--- a/src/functions/sums/sumpos
+++ b/src/functions/sums/sumpos
@@ -28,7 +28,7 @@ Doc: numerical summation of the series \var{expr}, which must be a series of
  rigorous use, but allowing to compute fewer series terms.
 
  To reach accuracy $10^{-p}$, both algorithms require $O(p^2)$ space;
- furthermore, assuming the terms decrease polynomially (in $O(n^-C)$), both
+ furthermore, assuming the terms decrease polynomially (in $O(n^{-C})$), both
  need to compute $O(p^2)$ terms. The \kbd{sumpos}$(,1)$ variant has a smaller
  implied constant (roughly 1.5 times smaller). Since the \kbd{sumalt}$(,1)$
  overhead is now small compared to the time needed to compute series terms,
diff --git a/src/functions/transcendental/eint1 b/src/functions/transcendental/eint1
index 55b35f6..7df7eba 100644
--- a/src/functions/transcendental/eint1
+++ b/src/functions/transcendental/eint1
@@ -12,7 +12,7 @@ Doc: exponential integral $\int_x^\infty \dfrac{e^{-t}}{t}\,dt =
  $n$-dimensional vector $[\kbd{eint1}(x),\dots,\kbd{eint1}(nx)]$. Contrary to
  other transcendental functions, and to the default case ($n$ omitted), the
  values are correct up to a bounded \emph{absolute}, rather than relative,
- error $10^-n$, where $n$ is \kbd{precision}$(x)$ if $x$ is a \typ{REAL}
+ error $10^{-n}$, where $n$ is \kbd{precision}$(x)$ if $x$ is a \typ{REAL}
  and defaults to \kbd{realprecision} otherwise. (In the most important
  application, to the computation of $L$-functions via approximate functional
  equations, those values appear as weights in long sums and small individual
diff --git a/src/functions/transcendental/gammamellininv b/src/functions/transcendental/gammamellininv
index f19e5db..ff43c15 100644
--- a/src/functions/transcendental/gammamellininv
+++ b/src/functions/transcendental/gammamellininv
@@ -1,6 +1,6 @@
 Function: gammamellininv
 Section: transcendental
-C-Name: gammamellininv_bitprec
+C-Name: gammamellininv
 Prototype: GGD0,L,b
 Help: gammamellininv(G,t,{m=0}): returns G(t), where G is as output
  by gammamellininvinit. The alternative syntax gammamellininv(A,t,m)
diff --git a/src/functions/transcendental/gammamellininvinit b/src/functions/transcendental/gammamellininvinit
index 585a3d1..a253a1a 100644
--- a/src/functions/transcendental/gammamellininvinit
+++ b/src/functions/transcendental/gammamellininvinit
@@ -1,6 +1,6 @@
 Function: gammamellininvinit
 Section: transcendental
-C-Name: gammamellininvinit_bitprec
+C-Name: gammamellininvinit
 Prototype: GD0,L,b
 Help: gammamellininvinit(A,{m=0}): initialize data for the computation by
  gammamellininv() of the m-th derivative of the inverse Mellin transform
diff --git a/src/gp/gp.c b/src/gp/gp.c
index 6557d18..e2d4ac4 100644
--- a/src/gp/gp.c
+++ b/src/gp/gp.c
@@ -275,6 +275,7 @@ init_test(void)
 {
   disable_color = 1;
   init_linewrap(76);
+  pari_errfile = stdout;
   cb_gp_output = test_output;
   cb_pari_is_interactive = test_is_interactive;
 }
diff --git a/src/gp/gp_init.h b/src/gp/gp_init.h
index 60a3886..6f8bf63 100644
--- a/src/gp/gp_init.h
+++ b/src/gp/gp_init.h
@@ -2,11 +2,11 @@
 /* See src/desc/gen_proto */
 /* Do not edit*/
 entree functions_gp[]={
-{"breakpoint",0,(void*)pari_breakpoint,14,"v","breakpoint(): interrupt the program and enter the breakloop. The program continues when the breakloop is exited."},
-{"dbg_down",0,(void*)dbg_down,14,"vD1,L,","dbg_down({n=1}): (break loop) go down n frames. Cancel a previous dbg_up."},
-{"dbg_err",0,(void*)dbg_err,14,"","dbg_err(): (break loop) return the error data of the current error, if any."},
-{"dbg_up",0,(void*)dbg_up,14,"vD1,L,","dbg_up({n=1}): (break loop) go up n frames. Allow to inspect data of the parent function."},
-{"quit",0,(void*)gp_quit,14,"vD0,L,","quit({status = 0}): quit, return to the system with exit status 'status'."},
-{"whatnow",0,(void*)whatnow0,14,"vr","whatnow(key): if key was present in GP version 1.39.15, gives the new function name."},
+{"breakpoint",0,(void*)pari_breakpoint,15,"v","breakpoint(): interrupt the program and enter the breakloop. The program continues when the breakloop is exited."},
+{"dbg_down",0,(void*)dbg_down,15,"vD1,L,","dbg_down({n=1}): (break loop) go down n frames. Cancel a previous dbg_up."},
+{"dbg_err",0,(void*)dbg_err,15,"","dbg_err(): (break loop) return the error data of the current error, if any."},
+{"dbg_up",0,(void*)dbg_up,15,"vD1,L,","dbg_up({n=1}): (break loop) go up n frames. Allow to inspect data of the parent function."},
+{"quit",0,(void*)gp_quit,15,"vD0,L,","quit({status = 0}): quit, return to the system with exit status 'status'."},
+{"whatnow",0,(void*)whatnow0,15,"vr","whatnow(key): if key was present in GP version 1.39.15, gives the new function name."},
 {NULL,0,NULL,0,NULL,NULL} /* sentinel */
 };
diff --git a/src/gp/highlvl.h b/src/gp/highlvl.h
index 8b9a5ea..867ac61 100644
--- a/src/gp/highlvl.h
+++ b/src/gp/highlvl.h
@@ -2,34 +2,34 @@
 /* See src/desc/gen_proto */
 /* Do not edit*/
 entree functions_highlevel[]={
-{"plot",0,(void*)plot,13,"vV=GGEDGDGp","plot(X=a,b,expr,{Ymin},{Ymax}): crude plot of expression expr, X goes from a to b, with Y ranging from Ymin to Ymax. If Ymin (resp. Ymax) is not given, the minimum (resp. the maximum) of the expression is used instead."},
-{"plotbox",0,(void*)rectbox,13,"vLGG","plotbox(w,x2,y2): if the cursor is at position (x1,y1), draw a box with diagonal (x1,y1) and (x2,y2) in rectwindow w (cursor does not move)."},
-{"plotclip",0,(void*)rectclip,13,"vL","plotclip(w): clip the contents of the rectwindow to the bounding box (except strings)."},
-{"plotcolor",0,(void*)rectcolor,13,"vLL","plotcolor(w,c): in rectwindow w, set default color to c. Possible values for c are given by the graphcolormap default: factory settings are 1=black, 2=blue, 3=sienna, 4=red, 5=green, 6=grey, 7=gainsborough."},
-{"plotcopy",0,(void*)rectcopy_gen,13,"vLLGGD0,L,","plotcopy(sourcew,destw,dx,dy,{flag=0}): copy the contents of rectwindow sourcew to rectwindow destw with offset (dx,dy). If flag's bit 1 is set, dx and dy express fractions of the size of the current output device, otherwise dx and dy are in pixels. dx and dy are relative positions of northwest corners if other bits of flag vanish, otherwise of: 2: southwest, 4: southeast, 6: northeast corners."},
-{"plotcursor",0,(void*)rectcursor,13,"L","plotcursor(w): current position of cursor in rectwindow w."},
-{"plotdraw",0,(void*)rectdraw_flag,13,"vGD0,L,","plotdraw(list, {flag=0}): draw vector of rectwindows list at indicated x,y positions; list is a vector w1,x1,y1,w2,x2,y2,etc. If flag!=0, x1, y1 etc. express fractions of the size of the current output device."},
-{"ploth",0,(void*)ploth,13,"V=GGEpD0,M,D0,L,\nParametric|1; Recursive|2; no_Rescale|4; no_X_axis|8; no_Y_axis|16; no_Frame|32; no_Lines|64; Points_too|128; Splines|256; no_X_ticks|512; no_Y_ticks|1024; Same_ticks|2048; Complex|4096","ploth(X=a,b,expr,{flags=0},{n=0}): plot of expression expr, X goes from a to b in high resolution. Both flags and n are optional. Binary digits of flags mean: 1=Parametric, 2=Recursive, 4=no_Rescale, 8=no_X_axis, 16=no_Y_axis, 32=no_Frame, 64=no_Lines (do no [...]
-{"plothraw",0,(void*)plothraw,13,"GGD0,L,","plothraw(listx,listy,{flag=0}): plot in high resolution points whose x (resp. y) coordinates are in listx (resp. listy). If flag is 1, join points, other non-0 flags should be combinations of bits 8,16,32,64,128,256 meaning the same as for ploth()."},
-{"plothsizes",0,(void*)plothsizes_flag,13,"D0,L,","plothsizes({flag=0}): returns array of 6 elements: terminal width and height, sizes for ticks in horizontal and vertical directions, width and height of characters. If flag=0, sizes of ticks and characters are in pixels, otherwise are fractions of the screen size."},
-{"plotinit",0,(void*)initrect_gen,13,"vLDGDGD0,L,","plotinit(w,{x},{y},{flag=0}): initialize rectwindow w to size x,y. If flag!=0, x and y express fractions of the size of the current output device. Omitting x or y means use the full size of the device."},
-{"plotkill",0,(void*)killrect,13,"vL","plotkill(w): erase the rectwindow w."},
-{"plotlines",0,(void*)rectlines,13,"vLGGD0,L,","plotlines(w,X,Y,{flag=0}): draws an open polygon in rectwindow w where X and Y contain the x (resp. y) coordinates of the vertices. If X and Y are both single values (i.e not vectors), draw the corresponding line (and move cursor). If (optional) flag is non-zero, close the polygon."},
-{"plotlinetype",0,(void*)rectlinetype,13,"vLL","plotlinetype(w,type): change the type of following lines in rectwindow w. type -2 corresponds to frames, -1 to axes, larger values may correspond to something else. w=-1 changes highlevel plotting."},
-{"plotmove",0,(void*)rectmove,13,"vLGG","plotmove(w,x,y): move cursor to position x,y in rectwindow w."},
-{"plotpoints",0,(void*)rectpoints,13,"vLGG","plotpoints(w,X,Y): draws in rectwindow w the points whose x (resp y) coordinates are in X (resp Y). If X and Y are both single values (i.e not vectors), draw the corresponding point (and move cursor)."},
-{"plotpointsize",0,(void*)rectpointsize,13,"vLG","plotpointsize(w,size): change the \"size\" of following points in rectwindow w. w=-1 changes global value."},
-{"plotpointtype",0,(void*)rectpointtype,13,"vLL","plotpointtype(w,type): change the type of following points in rectwindow w. type -1 corresponds to a dot, larger values may correspond to something else. w=-1 changes highlevel plotting."},
-{"plotrbox",0,(void*)rectrbox,13,"vLGG","plotrbox(w,dx,dy): if the cursor is at (x1,y1), draw a box with diagonal (x1,y1)-(x1+dx,y1+dy) in rectwindow w (cursor does not move)."},
-{"plotrecth",0,(void*)rectploth,13,"LV=GGEpD0,M,D0,L,\nParametric|1; Recursive|2; no_Rescale|4; no_X_axis|8; no_Y_axis|16; no_Frame|32; no_Lines|64; Points_too|128; Splines|256; no_X_ticks|512; no_Y_ticks|1024; Same_ticks|2048; Complex|4096","plotrecth(w,X=a,b,expr,{flag=0},{n=0}): writes to rectwindow w the curve output of ploth(w,X=a,b,expr,flag,n). Returns a vector for the bounding box."},
-{"plotrecthraw",0,(void*)rectplothraw,13,"LGD0,L,","plotrecthraw(w,data,{flags=0}): plot graph(s) for data in rectwindow w, where data is a vector of vectors. If plot is parametric, length of data should be even, and pairs of entries give curves to plot. If not, first entry gives x-coordinate, and the other ones y-coordinates. Admits the same optional flags as plotrecth, save that recursive plot is meaningless."},
-{"plotrline",0,(void*)rectrline,13,"vLGG","plotrline(w,dx,dy): if the cursor is at (x1,y1), draw a line from (x1,y1) to (x1+dx,y1+dy) (and move the cursor) in the rectwindow w."},
-{"plotrmove",0,(void*)rectrmove,13,"vLGG","plotrmove(w,dx,dy): move cursor to position (dx,dy) relative to the present position in the rectwindow w."},
-{"plotrpoint",0,(void*)rectrpoint,13,"vLGG","plotrpoint(w,dx,dy): draw a point (and move cursor) at position dx,dy relative to present position of the cursor in rectwindow w."},
-{"plotscale",0,(void*)rectscale,13,"vLGGGG","plotscale(w,x1,x2,y1,y2): scale the coordinates in rectwindow w so that x goes from x1 to x2 and y from y1 to y2 (y2<y1 is allowed)."},
-{"plotstring",0,(void*)rectstring3,13,"vLsD0,L,","plotstring(w,x,{flags=0}): draw in rectwindow w the string corresponding to x. Bits 1 and 2 of flag regulate horizontal alignment: left if 0, right if 2, center if 1. Bits 4 and 8 regulate vertical alignment: bottom if 0, top if 8, v-center if 4. Can insert additional gap between point and string: horizontal if bit 16 is set, vertical if bit 32 is set."},
-{"psdraw",0,(void*)postdraw_flag,13,"vGD0,L,","psdraw(list, {flag=0}): same as plotdraw, except that the output is a PostScript program in psfile (pari.ps by default), and flag!=0 scales the plot from size of the current output device to the standard PostScript plotting size."},
-{"psploth",0,(void*)postploth,13,"V=GGEpD0,L,D0,L,","psploth(X=a,b,expr,{flags=0},{n=0}): same as ploth, except that the output is a PostScript program in psfile (pari.ps by default)."},
-{"psplothraw",0,(void*)postplothraw,13,"GGD0,L,","psplothraw(listx,listy,{flag=0}): same as plothraw, except that the output is a postscript program in psfile (pari.ps by default)."},
+{"plot",0,(void*)plot,14,"vV=GGEDGDGp","plot(X=a,b,expr,{Ymin},{Ymax}): crude plot of expression expr, X goes from a to b, with Y ranging from Ymin to Ymax. If Ymin (resp. Ymax) is not given, the minimum (resp. the maximum) of the expression is used instead."},
+{"plotbox",0,(void*)rectbox,14,"vLGG","plotbox(w,x2,y2): if the cursor is at position (x1,y1), draw a box with diagonal (x1,y1) and (x2,y2) in rectwindow w (cursor does not move)."},
+{"plotclip",0,(void*)rectclip,14,"vL","plotclip(w): clip the contents of the rectwindow to the bounding box (except strings)."},
+{"plotcolor",0,(void*)rectcolor,14,"vLL","plotcolor(w,c): in rectwindow w, set default color to c. Possible values for c are given by the graphcolormap default: factory settings are 1=black, 2=blue, 3=sienna, 4=red, 5=green, 6=grey, 7=gainsborough."},
+{"plotcopy",0,(void*)rectcopy_gen,14,"vLLGGD0,L,","plotcopy(sourcew,destw,dx,dy,{flag=0}): copy the contents of rectwindow sourcew to rectwindow destw with offset (dx,dy). If flag's bit 1 is set, dx and dy express fractions of the size of the current output device, otherwise dx and dy are in pixels. dx and dy are relative positions of northwest corners if other bits of flag vanish, otherwise of: 2: southwest, 4: southeast, 6: northeast corners."},
+{"plotcursor",0,(void*)rectcursor,14,"L","plotcursor(w): current position of cursor in rectwindow w."},
+{"plotdraw",0,(void*)rectdraw_flag,14,"vGD0,L,","plotdraw(list, {flag=0}): draw vector of rectwindows list at indicated x,y positions; list is a vector w1,x1,y1,w2,x2,y2,etc. If flag!=0, x1, y1 etc. express fractions of the size of the current output device."},
+{"ploth",0,(void*)ploth,14,"V=GGEpD0,M,D0,L,\nParametric|1; Recursive|2; no_Rescale|4; no_X_axis|8; no_Y_axis|16; no_Frame|32; no_Lines|64; Points_too|128; Splines|256; no_X_ticks|512; no_Y_ticks|1024; Same_ticks|2048; Complex|4096","ploth(X=a,b,expr,{flags=0},{n=0}): plot of expression expr, X goes from a to b in high resolution. Both flags and n are optional. Binary digits of flags mean: 1=Parametric, 2=Recursive, 4=no_Rescale, 8=no_X_axis, 16=no_Y_axis, 32=no_Frame, 64=no_Lines (do no [...]
+{"plothraw",0,(void*)plothraw,14,"GGD0,L,","plothraw(listx,listy,{flag=0}): plot in high resolution points whose x (resp. y) coordinates are in listx (resp. listy). If flag is 1, join points, other non-0 flags should be combinations of bits 8,16,32,64,128,256 meaning the same as for ploth()."},
+{"plothsizes",0,(void*)plothsizes_flag,14,"D0,L,","plothsizes({flag=0}): returns array of 6 elements: terminal width and height, sizes for ticks in horizontal and vertical directions, width and height of characters. If flag=0, sizes of ticks and characters are in pixels, otherwise are fractions of the screen size."},
+{"plotinit",0,(void*)initrect_gen,14,"vLDGDGD0,L,","plotinit(w,{x},{y},{flag=0}): initialize rectwindow w to size x,y. If flag!=0, x and y express fractions of the size of the current output device. Omitting x or y means use the full size of the device."},
+{"plotkill",0,(void*)killrect,14,"vL","plotkill(w): erase the rectwindow w."},
+{"plotlines",0,(void*)rectlines,14,"vLGGD0,L,","plotlines(w,X,Y,{flag=0}): draws an open polygon in rectwindow w where X and Y contain the x (resp. y) coordinates of the vertices. If X and Y are both single values (i.e not vectors), draw the corresponding line (and move cursor). If (optional) flag is non-zero, close the polygon."},
+{"plotlinetype",0,(void*)rectlinetype,14,"vLL","plotlinetype(w,type): change the type of following lines in rectwindow w. type -2 corresponds to frames, -1 to axes, larger values may correspond to something else. w=-1 changes highlevel plotting."},
+{"plotmove",0,(void*)rectmove,14,"vLGG","plotmove(w,x,y): move cursor to position x,y in rectwindow w."},
+{"plotpoints",0,(void*)rectpoints,14,"vLGG","plotpoints(w,X,Y): draws in rectwindow w the points whose x (resp y) coordinates are in X (resp Y). If X and Y are both single values (i.e not vectors), draw the corresponding point (and move cursor)."},
+{"plotpointsize",0,(void*)rectpointsize,14,"vLG","plotpointsize(w,size): change the \"size\" of following points in rectwindow w. w=-1 changes global value."},
+{"plotpointtype",0,(void*)rectpointtype,14,"vLL","plotpointtype(w,type): change the type of following points in rectwindow w. type -1 corresponds to a dot, larger values may correspond to something else. w=-1 changes highlevel plotting."},
+{"plotrbox",0,(void*)rectrbox,14,"vLGG","plotrbox(w,dx,dy): if the cursor is at (x1,y1), draw a box with diagonal (x1,y1)-(x1+dx,y1+dy) in rectwindow w (cursor does not move)."},
+{"plotrecth",0,(void*)rectploth,14,"LV=GGEpD0,M,D0,L,\nParametric|1; Recursive|2; no_Rescale|4; no_X_axis|8; no_Y_axis|16; no_Frame|32; no_Lines|64; Points_too|128; Splines|256; no_X_ticks|512; no_Y_ticks|1024; Same_ticks|2048; Complex|4096","plotrecth(w,X=a,b,expr,{flag=0},{n=0}): writes to rectwindow w the curve output of ploth(w,X=a,b,expr,flag,n). Returns a vector for the bounding box."},
+{"plotrecthraw",0,(void*)rectplothraw,14,"LGD0,L,","plotrecthraw(w,data,{flags=0}): plot graph(s) for data in rectwindow w, where data is a vector of vectors. If plot is parametric, length of data should be even, and pairs of entries give curves to plot. If not, first entry gives x-coordinate, and the other ones y-coordinates. Admits the same optional flags as plotrecth, save that recursive plot is meaningless."},
+{"plotrline",0,(void*)rectrline,14,"vLGG","plotrline(w,dx,dy): if the cursor is at (x1,y1), draw a line from (x1,y1) to (x1+dx,y1+dy) (and move the cursor) in the rectwindow w."},
+{"plotrmove",0,(void*)rectrmove,14,"vLGG","plotrmove(w,dx,dy): move cursor to position (dx,dy) relative to the present position in the rectwindow w."},
+{"plotrpoint",0,(void*)rectrpoint,14,"vLGG","plotrpoint(w,dx,dy): draw a point (and move cursor) at position dx,dy relative to present position of the cursor in rectwindow w."},
+{"plotscale",0,(void*)rectscale,14,"vLGGGG","plotscale(w,x1,x2,y1,y2): scale the coordinates in rectwindow w so that x goes from x1 to x2 and y from y1 to y2 (y2<y1 is allowed)."},
+{"plotstring",0,(void*)rectstring3,14,"vLsD0,L,","plotstring(w,x,{flags=0}): draw in rectwindow w the string corresponding to x. Bits 1 and 2 of flag regulate horizontal alignment: left if 0, right if 2, center if 1. Bits 4 and 8 regulate vertical alignment: bottom if 0, top if 8, v-center if 4. Can insert additional gap between point and string: horizontal if bit 16 is set, vertical if bit 32 is set."},
+{"psdraw",0,(void*)postdraw_flag,14,"vGD0,L,","psdraw(list, {flag=0}): same as plotdraw, except that the output is a PostScript program in psfile (pari.ps by default), and flag!=0 scales the plot from size of the current output device to the standard PostScript plotting size."},
+{"psploth",0,(void*)postploth,14,"V=GGEpD0,L,D0,L,","psploth(X=a,b,expr,{flags=0},{n=0}): same as ploth, except that the output is a PostScript program in psfile (pari.ps by default)."},
+{"psplothraw",0,(void*)postplothraw,14,"GGD0,L,","psplothraw(listx,listy,{flag=0}): same as plothraw, except that the output is a postscript program in psfile (pari.ps by default)."},
 {NULL,0,NULL,0,NULL,NULL} /* sentinel */
 };
diff --git a/src/gp/texmacs.c b/src/gp/texmacs.c
index aa39178..e91a65d 100644
--- a/src/gp/texmacs.c
+++ b/src/gp/texmacs.c
@@ -164,7 +164,7 @@ tm_handle_command(const char *s)
 /****/
 
 int
-tm_is_interactive() { return 0; }
+tm_is_interactive(void) { return 0; }
 
 static int tm_is_waiting = 0;
 /* tell TeXmacs GP will start outputing data */
diff --git a/src/graph/plotport.c b/src/graph/plotport.c
index e3366a1..46cbf4f 100644
--- a/src/graph/plotport.c
+++ b/src/graph/plotport.c
@@ -461,7 +461,7 @@ rectticks(PARI_plot *WW, long ne,
   if (dx > 1000 || dy > 1000)
     dxy = 1000; /* avoid overflow */
   else
-    dxy = (long)sqrt(dx*dx + dy*dy);
+    dxy = usqrt(dx*dx + dy*dy);
   nticks = (long) ((dxy + 2.5)/4);
   if (!nticks) return;
 
@@ -478,7 +478,7 @@ rectticks(PARI_plot *WW, long ne,
     l_min = l2, l_max = l1;
   minstep = (l_max - l_min)/(nticks + 1);
   maxstep = 2.5*(l_max - l_min);
-  step = exp(log(10) * floor(log10(minstep)));
+  step = exp(log(10.) * floor(log10(minstep)));
   if (!(flags & TICKS_ENDSTOO)) {
     double d = 2*(l_max - l_min)/dxy1;        /* Two pixels off */
 
diff --git a/src/headers/paridecl.h b/src/headers/paridecl.h
index 2bc9caa..9ff4a07 100644
--- a/src/headers/paridecl.h
+++ b/src/headers/paridecl.h
@@ -47,6 +47,7 @@ struct bb_algebra
 {
   GEN (*red)(void *E, GEN x);
   GEN (*add)(void *E, GEN x, GEN y);
+  GEN (*sub)(void *E, GEN x, GEN y);
   GEN (*mul)(void *E, GEN x, GEN y);
   GEN (*sqr)(void *E, GEN x);
   GEN (*one)(void *E);
@@ -83,7 +84,6 @@ GEN     isprincipalgenforce(GEN bnf,GEN x);
 
 /* F2x.c */
 
-GEN     F2c_to_Flc(GEN x);
 GEN     F2c_to_ZC(GEN x);
 GEN     F2c_to_mod(GEN x);
 GEN     F2m_rowslice(GEN x, long a, long b);
@@ -93,8 +93,10 @@ GEN     F2m_to_mod(GEN z);
 void    F2v_add_inplace(GEN x, GEN y);
 ulong   F2v_dotproduct(GEN x, GEN y);
 GEN     F2v_slice(GEN x, long a, long b);
+GEN     F2v_to_Flv(GEN x);
 GEN     F2x_F2xq_eval(GEN Q, GEN x, GEN T);
 GEN     F2x_F2xqV_eval(GEN P, GEN V, GEN T);
+GEN     F2x_Frobenius(GEN T);
 GEN     F2x_1_add(GEN y);
 GEN     F2x_add(GEN x, GEN y);
 GEN     F2x_deflate(GEN x0, long d);
@@ -107,6 +109,7 @@ GEN     F2x_extgcd(GEN a, GEN b, GEN *ptu, GEN *ptv);
 GEN     F2x_gcd(GEN a, GEN b);
 GEN     F2x_halfgcd(GEN a, GEN b);
 int     F2x_issquare(GEN a);
+GEN     F2x_matFrobenius(GEN T);
 GEN     F2x_mul(GEN x, GEN y);
 GEN     F2x_rem(GEN x, GEN y);
 GEN     F2x_shift(GEN y, long d);
@@ -116,10 +119,19 @@ GEN     F2x_to_F2v(GEN x, long n);
 GEN     F2x_to_Flx(GEN x);
 GEN     F2x_to_ZX(GEN x);
 long    F2x_valrem(GEN x, GEN *Z);
+GEN     F2xC_to_FlxC(GEN v);
 GEN     F2xC_to_ZXC(GEN x);
 GEN     F2xV_to_F2m(GEN v, long n);
+GEN     F2xX_F2x_mul(GEN P, GEN U);
+GEN     F2xX_add(GEN x, GEN y);
+GEN     F2xX_deriv(GEN z);
+GEN     F2xX_renormalize(GEN /*in place*/ x, long lx);
+GEN     F2xX_to_Kronecker(GEN P, long d);
+GEN     F2xX_to_ZXX(GEN B);
+GEN     F2xY_F2xq_evalx(GEN P, GEN x, GEN T);
+GEN     F2xY_F2xqV_evalx(GEN P, GEN x, GEN T);
+long    F2xY_degreex(GEN b);
 GEN     F2xq_Artin_Schreier(GEN a, GEN T);
-GEN     FlxqXQV_autsum(GEN aut, long n, GEN S, GEN T, ulong p);
 GEN     F2xq_autpow(GEN x, long n, GEN T);
 GEN     F2xq_conjvec(GEN x, GEN T);
 GEN     F2xq_div(GEN x,GEN y,GEN T);
@@ -137,9 +149,29 @@ GEN     F2xq_sqrt(GEN a, GEN T);
 GEN     F2xq_sqrt_fast(GEN c, GEN sqx, GEN T);
 GEN     F2xq_sqrtn(GEN a, GEN n, GEN T, GEN *zeta);
 ulong   F2xq_trace(GEN x, GEN T);
+GEN     F2xqX_F2xq_mul(GEN P, GEN U, GEN T);
+GEN     F2xqX_F2xq_mul_to_monic(GEN P, GEN U, GEN T);
+GEN     F2xqX_F2xqXQ_eval(GEN Q, GEN x, GEN S, GEN T);
+GEN     F2xqX_F2xqXQV_eval(GEN P, GEN V, GEN S, GEN T);
+GEN     F2xqX_divrem(GEN x, GEN y, GEN T, GEN *pr);
+GEN     F2xqX_gcd(GEN a, GEN b, GEN T);
+GEN     F2xqX_mul(GEN x, GEN y, GEN T);
+GEN     F2xqX_normalize(GEN z, GEN T);
+GEN     F2xqX_red(GEN z, GEN T);
+GEN     F2xqX_rem(GEN x, GEN S, GEN T);
+GEN     F2xqX_sqr(GEN x, GEN T);
+GEN     F2xqXQ_mul(GEN x, GEN y, GEN S, GEN T);
+GEN     F2xqXQ_sqr(GEN x, GEN S, GEN T);
+GEN     F2xqXQ_pow(GEN x, GEN n, GEN S, GEN T);
+GEN     F2xqXQ_powers(GEN x, long l, GEN S, GEN T);
+GEN     F2xqXQV_autpow(GEN aut, long n, GEN S, GEN T);
+GEN     F2xqXQV_auttrace(GEN aut, long n, GEN S, GEN T);
 GEN     Flm_to_F2m(GEN x);
 GEN     Flv_to_F2v(GEN x);
 GEN     Flx_to_F2x(GEN x);
+GEN     FlxC_to_F2xC(GEN x);
+GEN     FlxX_to_F2xX(GEN B);
+GEN     Kronecker_to_F2xqX(GEN z, GEN T);
 GEN     Rg_to_F2xq(GEN x, GEN T);
 GEN     RgM_to_F2m(GEN x);
 GEN     RgV_to_F2v(GEN x);
@@ -149,9 +181,14 @@ GEN     ZM_to_F2m(GEN x);
 GEN     ZV_to_F2v(GEN x);
 GEN     ZX_to_F2x(GEN x);
 GEN     ZXX_to_F2xX(GEN B, long v);
+GEN     const_F2v(long m);
 GEN     gener_F2xq(GEN T, GEN *po);
 const struct bb_field *get_F2xq_field(void **E, GEN T);
+GEN     monomial_F2x(long d, long vs);
+GEN     pol1_F2xX(long v, long sv);
+GEN     polx_F2xX(long v, long sv);
 GEN     random_F2x(long d, long vs);
+GEN     random_F2xqX(long d1, long v, GEN T);
 
 /* F2xqE.c */
 
@@ -215,7 +252,7 @@ GEN     Flc_to_ZC(GEN z);
 GEN     Flm_to_FlxV(GEN x, long sv);
 GEN     Flm_to_FlxX(GEN x, long v,long w);
 GEN     Flm_to_ZM(GEN z);
-GEN     Flv_FlvV_polint(GEN xa, GEN ya, ulong p, long vs);
+GEN     Flv_Flm_polint(GEN xa, GEN ya, ulong p, long vs);
 GEN     Flv_inv(GEN x, ulong p);
 void    Flv_inv_inplace(GEN x, ulong p);
 void    Flv_inv_pre_inplace(GEN x, ulong p, ulong pi);
@@ -250,6 +287,7 @@ ulong   Flx_extresultant(GEN a, GEN b, ulong p, GEN *ptU, GEN *ptV);
 GEN     Flx_gcd(GEN a, GEN b, ulong p);
 GEN     Flx_get_red(GEN T, ulong p);
 GEN     Flx_halfgcd(GEN a, GEN b, ulong p);
+GEN     Flx_halve(GEN y, ulong p);
 GEN     Flx_inflate(GEN x0, long d);
 GEN     Flx_invBarrett(GEN T, ulong p);
 int     Flx_is_squarefree(GEN z, ulong p);
@@ -292,6 +330,7 @@ GEN     FlxX_Fl_mul(GEN x, ulong y, ulong p);
 GEN     FlxX_Flx_add(GEN y, GEN x, ulong p);
 GEN     FlxX_Flx_mul(GEN x, GEN y, ulong p);
 GEN     FlxX_add(GEN P, GEN Q, ulong p);
+GEN     FlxX_deriv(GEN z, ulong p);
 GEN     FlxX_double(GEN x, ulong p);
 GEN     FlxX_neg(GEN x, ulong p);
 GEN     FlxX_sub(GEN P, GEN Q, ulong p);
@@ -302,11 +341,14 @@ GEN     FlxX_to_Flm(GEN v, long n);
 GEN     FlxX_to_FlxC(GEN x, long N, long sv);
 GEN     FlxX_to_ZXX(GEN B);
 GEN     FlxX_triple(GEN x, ulong p);
+GEN     FlxXC_to_ZXXC(GEN B);
+GEN     FlxXM_to_ZXXM(GEN B);
 GEN     FlxXV_to_FlxM(GEN v, long n, long sv);
 GEN     FlxY_Flx_div(GEN x, GEN y, ulong p);
 GEN     FlxY_Flx_translate(GEN P, GEN c, ulong p);
 GEN     FlxY_Flxq_evalx(GEN P, GEN x, GEN T, ulong p);
 GEN     FlxY_FlxqV_evalx(GEN P, GEN x, GEN T, ulong p);
+long    FlxY_degreex(GEN b);
 ulong   FlxY_eval_powers_pre(GEN pol, GEN ypowers, GEN xpowers, ulong p, ulong pi);
 GEN     FlxY_evalx(GEN Q, ulong x, ulong p);
 GEN     FlxY_evalx_powers_pre(GEN pol, GEN ypowers, ulong p, ulong pi);
@@ -346,10 +388,11 @@ GEN     FlxqX_divrem(GEN x, GEN y, GEN T, ulong p, GEN *pr);
 GEN     FlxqX_extgcd(GEN a, GEN b, GEN T, ulong p, GEN *ptu, GEN *ptv);
 GEN     FlxqX_gcd(GEN P, GEN Q, GEN T, ulong p);
 GEN     FlxqX_get_red(GEN S, GEN T, ulong p);
+GEN     FlxqX_halfgcd(GEN x, GEN y, GEN T, ulong p);
 GEN     FlxqX_invBarrett(GEN T, GEN Q, ulong p);
 GEN     FlxqX_mul(GEN x, GEN y, GEN T, ulong p);
 GEN     FlxqX_normalize(GEN z, GEN T, ulong p);
-GEN     FlxqX_pow(GEN V, long n, GEN T, ulong p);
+GEN     FlxqX_powu(GEN V, ulong n, GEN T, ulong p);
 GEN     FlxqX_red(GEN z, GEN T, ulong p);
 GEN     FlxqX_rem(GEN x, GEN y, GEN T, ulong p);
 GEN     FlxqX_safegcd(GEN P, GEN Q, GEN T, ulong p);
@@ -360,16 +403,18 @@ GEN     FlxqXQ_invsafe(GEN x, GEN S, GEN T, ulong p);
 GEN     FlxqXQ_matrix_pow(GEN x, long n, long m, GEN S, GEN T, ulong p);
 GEN     FlxqXQ_mul(GEN x, GEN y, GEN S, GEN T, ulong p);
 GEN     FlxqXQ_pow(GEN x, GEN n, GEN S, GEN T, ulong p);
+GEN     FlxqXQ_powu(GEN x, ulong n, GEN S, GEN T, ulong p);
 GEN     FlxqXQ_powers(GEN x, long n, GEN S, GEN T, ulong p);
 GEN     FlxqXQ_sqr(GEN x, GEN S, GEN T, ulong p);
 GEN     FlxqXQV_autpow(GEN x, long n, GEN S, GEN T, ulong p);
+GEN     FlxqXQV_autsum(GEN aut, long n, GEN S, GEN T, ulong p);
 GEN     FlxqXV_prod(GEN V, GEN T, ulong p);
 GEN     Kronecker_to_FlxqX(GEN z, GEN T, ulong p);
 ulong   Rg_to_F2(GEN x);
 ulong   Rg_to_Fl(GEN x, ulong p);
 GEN     Rg_to_Flxq(GEN x, GEN T, ulong p);
 GEN     RgX_to_Flx(GEN x, ulong p);
-GEN     Z_to_Flx(GEN x, ulong p, long v);
+GEN     Z_to_Flx(GEN x, ulong p, long sv);
 GEN     ZX_to_Flx(GEN x, ulong p);
 GEN     ZXV_to_FlxV(GEN v, ulong p);
 GEN     ZXT_to_FlxT(GEN z, ulong p);
@@ -380,11 +425,12 @@ GEN     gener_Flxq(GEN T, ulong p, GEN *o);
 long    get_Flx_degree(GEN T);
 GEN     get_Flx_mod(GEN T);
 long    get_Flx_var(GEN T);
+const struct bb_field *get_Flxq_field(void **E, GEN T, ulong p);
+const struct bb_group *get_Flxq_star(void **E, GEN T, ulong p);
 long    get_FlxqX_degree(GEN T);
 GEN     get_FlxqX_mod(GEN T);
 long    get_FlxqX_var(GEN T);
-const struct bb_field *get_Flxq_field(void **E, GEN T, ulong p);
-const struct bb_group *get_Flxq_star(void **E, GEN T, ulong p);
+const struct bb_algebra *get_FlxqXQ_algebra(void **E, GEN S, GEN T, ulong p);
 GEN     monomial_Flx(ulong a, long d, long vs);
 GEN     pol1_FlxX(long v, long sv);
 GEN     polx_FlxX(long v, long sv);
@@ -473,7 +519,10 @@ GEN     random_FpXQE(GEN a4, GEN a6, GEN T, GEN p);
 int     Fp_issquare(GEN x, GEN p);
 GEN     Fp_FpX_sub(GEN x, GEN y, GEN p);
 GEN     Fp_FpXQ_log(GEN a, GEN g, GEN ord, GEN T, GEN p);
+GEN     FpV_FpM_polint(GEN xa, GEN ya, GEN p, long vs);
 GEN     FpV_inv(GEN x, GEN p);
+GEN     FpV_invVandermonde(GEN L, GEN den, GEN p);
+GEN     FpV_polint(GEN xa, GEN ya, GEN p, long v);
 GEN     FpV_roots_to_pol(GEN V, GEN p, long v);
 GEN     FpX_Fp_add(GEN x, GEN y, GEN p);
 GEN     FpX_Fp_add_shallow(GEN y,GEN x,GEN p);
@@ -482,6 +531,7 @@ GEN     FpX_Fp_mul_to_monic(GEN y,GEN x,GEN p);
 GEN     FpX_Fp_mulspec(GEN y,GEN x,GEN p,long ly);
 GEN     FpX_Fp_sub(GEN x, GEN y, GEN p);
 GEN     FpX_Fp_sub_shallow(GEN y,GEN x,GEN p);
+GEN     FpX_FpV_multieval(GEN P, GEN xa, GEN p);
 GEN     FpX_FpXQ_eval(GEN f,GEN x,GEN T,GEN p);
 GEN     FpX_FpXQV_eval(GEN f,GEN x,GEN T,GEN p);
 GEN     FpX_Frobenius(GEN T, GEN p);
@@ -549,7 +599,11 @@ GEN     FpXT_red(GEN z, GEN p);
 GEN     FpXV_prod(GEN V, GEN p);
 GEN     FpXV_red(GEN z, GEN p);
 int     Fq_issquare(GEN x, GEN T, GEN p);
+long    Fq_ispower(GEN x, GEN K, GEN T, GEN p);
 GEN     Fq_log(GEN a, GEN g, GEN ord, GEN T, GEN p);
+GEN     Fq_sqrtn(GEN a, GEN n, GEN T, GEN p, GEN *z);
+GEN     Fq_sqrt(GEN a, GEN T, GEN p);
+long    FqX_ispower(GEN f, ulong k, GEN T, GEN p, GEN *pt);
 GEN     FqV_inv(GEN x, GEN T, GEN p);
 GEN     Z_to_FpX(GEN a, GEN p, long v);
 GEN     gener_FpXQ(GEN T, GEN p, GEN *o);
@@ -557,7 +611,9 @@ GEN     gener_FpXQ_local(GEN T, GEN p, GEN L);
 long    get_FpX_degree(GEN T);
 GEN     get_FpX_mod(GEN T);
 long    get_FpX_var(GEN T);
-const struct bb_group *get_FpXQ_star(void **E, GEN T, GEN p);
+const struct bb_group * get_FpXQ_star(void **E, GEN T, GEN p);
+const struct bb_algebra * get_FpX_algebra(void **E, GEN p, long v);
+const struct bb_algebra * get_FpXQ_algebra(void **E, GEN T, GEN p);
 GEN     random_FpX(long d, long v, GEN p);
 
 /* FpX_factor.c */
@@ -576,9 +632,7 @@ long    Flx_nbroots(GEN f, ulong p);
 ulong   Flx_oneroot(GEN f, ulong p);
 ulong   Flx_oneroot_split(GEN f, ulong p);
 GEN     Flx_roots(GEN f, ulong p);
-GEN     FlxqX_Frobenius(GEN S, GEN T, ulong p);
-GEN     FlxqXQ_halfFrobenius(GEN a, GEN S, GEN T, ulong p);
-long    FlxqX_nbroots(GEN f, GEN T, ulong p);
+GEN     Flx_rootsff(GEN P, GEN T, ulong p);
 void    FlxV_to_ZXV_inplace(GEN v);
 GEN     FpX_degfact(GEN f, GEN p);
 int     FpX_is_irred(GEN f, GEN p);
@@ -592,21 +646,28 @@ GEN     FpX_oneroot(GEN f, GEN p);
 GEN     FpX_roots(GEN f, GEN p);
 GEN     FpX_rootsff(GEN P, GEN T, GEN p);
 GEN     FpX_split_part(GEN f, GEN p);
+GEN     factcantor(GEN x, GEN p);
+GEN     factormod0(GEN f, GEN p,long flag);
+GEN     rootmod0(GEN f, GEN p,long flag);
+
+/* FpXQX_factor.c */
+
+GEN     F2xqX_roots(GEN x, GEN T);
+GEN     FlxqX_Frobenius(GEN S, GEN T, ulong p);
+GEN     FlxqXQ_halfFrobenius(GEN a, GEN S, GEN T, ulong p);
+GEN     FlxqX_roots(GEN S, GEN T, ulong p);
+long    FlxqX_nbroots(GEN f, GEN T, ulong p);
 GEN     FpXQX_Frobenius(GEN S, GEN T, GEN p);
+GEN     FpXQX_factor(GEN x, GEN T, GEN p);
 long    FpXQX_nbfact(GEN u, GEN T, GEN p);
 long    FpXQX_nbroots(GEN f, GEN T, GEN p);
+GEN     FpXQX_roots(GEN f, GEN T, GEN p);
 GEN     FpXQXQ_halfFrobenius(GEN a, GEN S, GEN T, GEN p);
-GEN     FqX_deriv(GEN f, GEN T, GEN p);
-GEN     FqX_factor(GEN x, GEN T, GEN p);
 long    FqX_is_squarefree(GEN P, GEN T, GEN p);
 long    FqX_nbfact(GEN u, GEN T, GEN p);
 long    FqX_nbroots(GEN f, GEN T, GEN p);
-GEN     FqX_roots(GEN f, GEN T, GEN p);
-GEN     factcantor(GEN x, GEN p);
 GEN     factorff(GEN f, GEN p, GEN a);
-GEN     factormod0(GEN f, GEN p,long flag);
 GEN     polrootsff(GEN f, GEN p, GEN T);
-GEN     rootmod0(GEN f, GEN p,long flag);
 
 /* FpXX.c */
 
@@ -620,6 +681,7 @@ GEN     FpXQX_extgcd(GEN x, GEN y, GEN T, GEN p, GEN *ptu, GEN *ptv);
 GEN     FpXQX_fromdigits(GEN x, GEN B, GEN T, GEN p);
 GEN     FpXQX_gcd(GEN P, GEN Q, GEN T, GEN p);
 GEN     FpXQX_get_red(GEN S, GEN T, GEN p);
+GEN     FpXQX_halfgcd(GEN x, GEN y, GEN T, GEN p);
 GEN     FpXQX_invBarrett(GEN S, GEN T, GEN p);
 GEN     FpXQX_mul(GEN x, GEN y, GEN T, GEN p);
 GEN     FpXQX_powu(GEN x, ulong n, GEN T, GEN p);
@@ -636,10 +698,12 @@ GEN     FpXQXQ_powers(GEN x, long n, GEN S, GEN T, GEN p);
 GEN     FpXQXQ_sqr(GEN x, GEN S, GEN T, GEN p);
 GEN     FpXQXQV_autpow(GEN aut, long n, GEN S, GEN T, GEN p);
 GEN     FpXQXQV_autsum(GEN aut, long n, GEN S, GEN T, GEN p);
+GEN     FpXQXQV_auttrace(GEN aut, long n, GEN S, GEN T, GEN p);
 GEN     FpXQXV_prod(GEN V, GEN Tp, GEN p);
 GEN     FpXX_Fp_mul(GEN x, GEN y, GEN p);
 GEN     FpXX_FpX_mul(GEN x, GEN y, GEN p);
 GEN     FpXX_add(GEN x, GEN y, GEN p);
+GEN     FpXX_deriv(GEN P, GEN p);
 GEN     FpXX_mulu(GEN P, ulong u, GEN p);
 GEN     FpXX_neg(GEN x, GEN p);
 GEN     FpXX_red(GEN z, GEN p);
@@ -654,9 +718,11 @@ GEN     Kronecker_to_FpXQX(GEN z, GEN pol, GEN p);
 GEN     Kronecker_to_ZXX(GEN z, long N, long v);
 GEN     ZXX_mul_Kronecker(GEN x, GEN y, long n);
 GEN     ZXX_sqr_Kronecker(GEN x, long n);
+const struct bb_algebra * get_FpXQX_algebra(void **E, GEN T, GEN p, long v);
 long    get_FpXQX_degree(GEN T);
 GEN     get_FpXQX_mod(GEN T);
 long    get_FpXQX_var(GEN T);
+const struct bb_algebra * get_FpXQXQ_algebra(void **E, GEN S, GEN T, GEN p);
 GEN     random_FpXQX(long d1, long v, GEN T, GEN p);
 
 /* FpV.c */
@@ -664,11 +730,6 @@ GEN     random_FpXQX(long d1, long v, GEN T, GEN p);
 GEN     F2m_F2c_mul(GEN x, GEN y);
 GEN     F2m_mul(GEN x, GEN y);
 GEN     F2m_powu(GEN x, ulong n);
-GEN     Flc_Fl_div(GEN x, ulong y, ulong p);
-void    Flc_Fl_div_inplace(GEN x, ulong y, ulong p);
-GEN     Flc_Fl_mul(GEN x, ulong y, ulong p);
-void    Flc_Fl_mul_inplace(GEN x, ulong y, ulong p);
-void    Flc_Fl_mul_part_inplace(GEN x, ulong y, ulong p, long l);
 GEN     Flc_to_mod(GEN z, ulong pp);
 GEN     Flm_Fl_add(GEN x, ulong y, ulong p);
 GEN     Flm_Fl_mul(GEN y, ulong x, ulong p);
@@ -683,11 +744,16 @@ GEN     Flm_powu(GEN x, ulong n, ulong p);
 GEN     Flm_sub(GEN x, GEN y, ulong p);
 GEN     Flm_to_mod(GEN z, ulong pp);
 GEN     Flm_transpose(GEN x);
+GEN     Flv_Fl_div(GEN x, ulong y, ulong p);
+void    Flv_Fl_div_inplace(GEN x, ulong y, ulong p);
+GEN     Flv_Fl_mul(GEN x, ulong y, ulong p);
+void    Flv_Fl_mul_inplace(GEN x, ulong y, ulong p);
+void    Flv_Fl_mul_part_inplace(GEN x, ulong y, ulong p, long l);
 GEN     Flv_add(GEN x, GEN y, ulong p);
 void    Flv_add_inplace(GEN x, GEN y, ulong p);
+GEN     Flv_center(GEN z, ulong p, ulong ps2);
 ulong   Flv_dotproduct(GEN x, GEN y, ulong p);
 ulong   Flv_dotproduct_pre(GEN x, GEN y, ulong p, ulong pi);
-GEN     Flv_center(GEN z, ulong p, ulong ps2);
 GEN     Flv_neg(GEN v, ulong p);
 void    Flv_neg_inplace(GEN v, ulong p);
 GEN     Flv_sub(GEN x, GEN y, ulong p);
@@ -744,6 +810,7 @@ GEN     ZMV_to_FlmV(GEN z, ulong m);
 
 /* Hensel.c */
 
+GEN     Z2_sqrt(GEN x, long e);
 GEN     Zp_sqrt(GEN x, GEN p, long e);
 GEN     Zp_sqrtlift(GEN b, GEN a, GEN p, long e);
 GEN     Zp_sqrtnlift(GEN b, GEN n, GEN a, GEN p, long e);
@@ -755,12 +822,15 @@ GEN     ZpX_liftfact(GEN pol, GEN Q, GEN T, GEN p, long e, GEN pe);
 GEN     ZpX_liftroot(GEN f, GEN a, GEN p, long e);
 GEN     ZpX_liftroots(GEN f, GEN S, GEN p, long e);
 GEN     ZpX_roots(GEN f, GEN p, long e);
+GEN     ZpXQ_div(GEN a, GEN b, GEN T, GEN q, GEN p, long e);
 GEN     ZpXQ_inv(GEN a, GEN T, GEN p, long e);
 GEN     ZpXQ_invlift(GEN b, GEN a, GEN T, GEN p, long e);
 GEN     ZpXQ_log(GEN a, GEN T, GEN p, long N);
 GEN     ZpXQ_sqrt(GEN a, GEN T, GEN p, long e);
 GEN     ZpXQ_sqrtnlift(GEN b, GEN n, GEN a, GEN T, GEN p, long e);
 GEN     ZpXQM_prodFrobenius(GEN M, GEN T, GEN p, long e);
+GEN     ZpXQX_digits(GEN x, GEN B, GEN T, GEN q, GEN p, long e);
+GEN     ZpXQX_divrem(GEN x, GEN S, GEN T, GEN q, GEN p, long e, GEN *pr);
 GEN     ZpXQX_liftroot(GEN f, GEN a, GEN T, GEN p, long e);
 GEN     ZpXQX_liftroot_vald(GEN f, GEN a, long v, GEN T, GEN p, long e);
 GEN     gen_ZpX_Dixon(GEN F, GEN V, GEN q, GEN p, long N, void *E,
@@ -944,6 +1014,8 @@ GEN     RgXn_red_shallow(GEN a, long n);
 GEN     RgXn_reverse(GEN f, long e);
 GEN     RgXn_sqr(GEN f, long n);
 GEN     RgXnV_red_shallow(GEN P, long n);
+GEN     RgXn_powu(GEN x, ulong m, long n);
+GEN     RgXn_powu_i(GEN x, ulong m, long n);
 GEN     ZX_translate(GEN P, GEN c);
 GEN     ZX_unscale2n(GEN P, long n);
 GEN     ZX_unscale(GEN P, GEN h);
@@ -957,6 +1029,11 @@ GEN     gen_bkeval_powers(GEN P, long d, GEN V, void *E,
 const struct bb_algebra * get_Rg_algebra(void);
 
 /* ZG.c */
+void    ZGC_G_mul_inplace(GEN v, GEN x);
+void    ZGC_add_inplace(GEN x, GEN y);
+GEN     ZGC_add_sparse(GEN x, GEN y);
+void    ZGM_add_inplace(GEN x, GEN y);
+GEN     ZGM_add_sparse(GEN x, GEN y);
 GEN     G_ZGC_mul(GEN x, GEN v);
 GEN     G_ZG_mul(GEN x, GEN y);
 GEN     ZGC_G_mul(GEN v, GEN x);
@@ -1213,11 +1290,11 @@ GEN     bnfgwgeneric(GEN bnf, GEN Lpr, GEN Ld, GEN pl, long var);
 GEN     bnrgwsearch(GEN bnr, GEN Lpr, GEN Ld, GEN pl);
 void    checkalg(GEN x);
 void    checkhasse(GEN nf, GEN hi, GEN hf, long n);
-long    cyclicrelfrob(GEN rnf, GEN nf2, GEN auts, GEN pr);
+long    cyclicrelfrob(GEN rnf, GEN auts, GEN pr);
 GEN     hassecoprime(GEN hi, GEN hf, long n);
 GEN     hassedown(GEN nf, long n, GEN hi, GEN hf);
 GEN     hassewedderburn(GEN hi, GEN hf, long n);
-long    localhasse(GEN rnf, GEN nf2, GEN cnd, GEN pl, GEN auts, GEN b, long k);
+long    localhasse(GEN rnf, GEN cnd, GEN pl, GEN auts, GEN b, long k);
 GEN     nfgrunwaldwang(GEN nf0, GEN Lpr, GEN Ld, GEN pl, long var);
 GEN     nfgwkummer(GEN nf, GEN Lpr, GEN Ld, GEN pl, long var);
 
@@ -1434,6 +1511,8 @@ long    fetch_user_var(const char *s);
 long    fetch_var(void);
 long    fetch_var_higher(void);
 GEN     fetch_var_value(long vx, GEN t);
+char *  gp_embedded(const char *s);
+void    gp_embedded_init(long rsize, long vsize);
 GEN     gp_read_str(const char *t);
 entree* install(void *f, const char *name, const char *code);
 entree* is_entry(const char *s);
@@ -1623,6 +1702,7 @@ GEN     quadunit(GEN x);
 ulong   rootsof1_Fl(ulong n, ulong p);
 GEN     rootsof1_Fp(GEN n, GEN p);
 GEN     rootsof1u_Fp(ulong n, GEN p);
+long    sisfundamental(long x);
 GEN     sqrtint(GEN a);
 GEN     ramanujantau(GEN n);
 ulong   ugcd(ulong a,ulong b);
@@ -1656,10 +1736,12 @@ long    corediscs(long D, ulong *f);
 GEN     digits(GEN N, GEN B);
 GEN     divisors(GEN n);
 GEN     divisorsu(ulong n);
+GEN     divisorsu_fact(GEN P, GEN e);
 GEN     factor_pn_1(GEN p, ulong n);
 GEN     factor_pn_1_limit(GEN p, long n, ulong lim);
 GEN     factoru_pow(ulong n);
 GEN     fromdigits(GEN x, GEN B);
+GEN     fromdigitsu(GEN x, GEN B);
 GEN     fuse_Z_factor(GEN f, GEN B);
 GEN     gen_digits(GEN x, GEN B, long n, void *E, struct bb_ring *r,
                           GEN (*div)(void *E, GEN x, GEN y, GEN *r));
@@ -1678,6 +1760,8 @@ void    maxprime_check(ulong c);
 GEN     sumdigits(GEN n);
 GEN     sumdigits0(GEN n, GEN B);
 ulong   sumdigitsu(ulong n);
+GEN     usumdiv_fact(GEN f);
+GEN     usumdivk_fact(GEN f, ulong k);
 
 /* base1.c */
 
@@ -1713,6 +1797,8 @@ long    nf_get_prec(GEN x);
 GEN     nfcertify(GEN x);
 GEN     nfgaloismatrix(GEN nf, GEN s);
 GEN     nfgaloispermtobasis(GEN nf, GEN gal);
+void    nfinit_step1(nfbasic_t *T, GEN x, long flag);
+GEN     nfinit_step2(nfbasic_t *T, long flag, long prec);
 GEN     nfinit(GEN x, long prec);
 GEN     nfinit0(GEN x, long flag, long prec);
 GEN     nfinitall(GEN x, long flag, long prec);
@@ -1965,18 +2051,24 @@ void    nf_nfzk(GEN nf, GEN rnfeq, GEN *zknf, GEN *czknf);
 GEN     nfeltup(GEN nf, GEN x, GEN zknf, GEN czknf);
 GEN     rnfeltabstorel(GEN rnf, GEN x);
 GEN     rnfeltdown(GEN rnf, GEN x);
+GEN     rnfeltdown0(GEN rnf, GEN x, long flag);
 GEN     rnfeltreltoabs(GEN rnf, GEN x);
 GEN     rnfeltup(GEN rnf, GEN x);
+GEN     rnfeltup0(GEN rnf, GEN x, long flag);
 GEN     rnfidealabstorel(GEN rnf, GEN x);
 GEN     rnfidealdown(GEN rnf, GEN x);
 GEN     rnfidealhnf(GEN rnf, GEN x);
 GEN     rnfidealmul(GEN rnf,GEN x,GEN y);
 GEN     rnfidealnormabs(GEN rnf, GEN x);
 GEN     rnfidealnormrel(GEN rnf, GEN x);
+GEN     rnfidealprimedec(GEN rnf, GEN pr);
 GEN     rnfidealreltoabs(GEN rnf, GEN x);
+GEN     rnfidealreltoabs0(GEN rnf, GEN x, long flag);
 GEN     rnfidealtwoelement(GEN rnf,GEN x);
 GEN     rnfidealup(GEN rnf, GEN x);
+GEN     rnfidealup0(GEN rnf,GEN x, long flag);
 GEN     rnfinit(GEN nf,GEN pol);
+GEN     rnfinit0(GEN nf,GEN pol,long flag);
 
 /* bb_group.c */
 
@@ -2047,10 +2139,11 @@ GEN     ZV_sort_uniq(GEN L);
 GEN     ZV_union_shallow(GEN x, GEN y);
 GEN     binomial(GEN x, long k);
 GEN     binomialuu(ulong n, ulong k);
+int     cmp_Flx(GEN x, GEN y);
+int     cmp_RgX(GEN x, GEN y);
 int     cmp_nodata(void *data, GEN x, GEN y);
 int     cmp_prime_ideal(GEN x, GEN y);
 int     cmp_prime_over_p(GEN x, GEN y);
-int     cmp_RgX(GEN x, GEN y);
 int     cmp_universal(GEN x, GEN y);
 GEN     convol(GEN x, GEN y);
 int     gen_cmp_RgX(void *data, GEN x, GEN y);
@@ -2361,7 +2454,7 @@ GEN     ellanalyticrank(GEN e, GEN eps, long prec);
 GEN     ellanalyticrank_bitprec(GEN e, GEN eps, long bitprec);
 GEN     ellanal_globalred_all(GEN e, GEN *N, GEN *cb, GEN *tam);
 GEN     ellheegner(GEN e);
-GEN     ellL1(GEN e, long r, long prec);
+GEN     ellL1(GEN E, long r, long prec);
 GEN     ellL1_bitprec(GEN E, long r, long bitprec);
 
 /* elldata.c */
@@ -2409,6 +2502,7 @@ GEN     ellQp_u(GEN E, long prec);
 GEN     ellQp_u2(GEN E, long prec);
 GEN     ellQp_q(GEN E, long prec);
 GEN     ellQp_ab(GEN E, long prec);
+GEN     ellQp_L(GEN E, long prec);
 GEN     ellQp_root(GEN E, long prec);
 GEN     ellR_ab(GEN E, long prec);
 GEN     ellR_eta(GEN E, long prec);
@@ -2497,9 +2591,6 @@ GEN     zell(GEN e, GEN z, long prec);
 /* elltors.c */
 long    ellisdivisible(GEN E, GEN P, GEN n, GEN *Q);
 
-/* ellpadicL.c */
-GEN ellpadicL(GEN E, GEN p, long n, long r, GEN D, GEN C);
-
 /* ellisogeny.c */
 
 GEN     ellisogenyapply(GEN f, GEN P);
@@ -2523,6 +2614,7 @@ GEN     GENtoGENstr_nospace(GEN x);
 GEN     GENtoGENstr(GEN x);
 char*   GENtoTeXstr(GEN x);
 char*   GENtostr(GEN x);
+char*   GENtostr_raw(GEN x);
 char*   GENtostr_unquoted(GEN x);
 GEN     Str(GEN g);
 GEN     Strchr(GEN g);
@@ -2735,6 +2827,8 @@ GEN     FFM_mul(GEN M, GEN N, GEN ff);
 long    FFM_rank(GEN M, GEN ff);
 GEN     FFX_factor(GEN f, GEN x);
 GEN     FFX_roots(GEN f, GEN x);
+GEN     FqX_to_FFX(GEN x, GEN ff);
+GEN     Fq_to_FF(GEN x, GEN ff);
 GEN     Z_FF_div(GEN a, GEN b);
 GEN     ffgen(GEN T, long v);
 GEN     fflog(GEN x, GEN g, GEN o);
@@ -2893,9 +2987,9 @@ GEN     padic_to_Q(GEN x);
 GEN     padic_to_Q_shallow(GEN x);
 GEN     QpV_to_QV(GEN v);
 GEN     RgM_mulreal(GEN x, GEN y);
-GEN     RgX_RgM_eval_col(GEN x, GEN M, long c);
 GEN     RgX_cxeval(GEN T, GEN u, GEN ui);
 GEN     RgX_deflate_max(GEN x0, long *m);
+long    RgX_deflate_order(GEN x);
 long    RgX_degree(GEN x,long v);
 GEN     RgX_integ(GEN x);
 GEN     bitprecision0(GEN x,long n);
@@ -3047,6 +3141,7 @@ hashtable *hash_create_ulong(ulong s, long stack);
 hashtable *hash_create_str(ulong s, long stack);
 hashtable *hash_create(ulong minsize, ulong (*hash)(void*), int (*eq)(void*,void*), int use_stack);
 void hash_insert(hashtable *h, void *k, void *v);
+void hash_insert2(hashtable *h, void *k, void *v, ulong hash);
 GEN hash_keys(hashtable *h);
 GEN hash_values(hashtable *h);
 hashentry *hash_search(hashtable *h, void *k);
@@ -3242,7 +3337,7 @@ GEN     intnum(void *E, GEN (*eval) (void *, GEN), GEN a, GEN b, GEN tab, long p
 GEN     intnumgauss(void *E, GEN (*eval)(void*, GEN), GEN a, GEN b, GEN tab, long prec);
 GEN     intnumgaussinit(long n, long prec);
 GEN     intnuminit(GEN a, GEN b, long m, long prec);
-GEN     intnumromb(void *E, GEN (*eval) (void *, GEN), GEN a, GEN b, long flag, long prec);
+GEN     intnumromb(void *E, GEN (*eval)(void *, GEN), GEN a, GEN b, long flag, long prec);
 GEN     intnumromb_bitprec(void *E, GEN (*eval)(void *, GEN), GEN a, GEN b, long flag, long bit);
 GEN     sumnum(void *E, GEN (*eval)(void*, GEN), GEN a, GEN tab, long prec);
 GEN     sumnuminit(GEN fast, long prec);
@@ -3287,49 +3382,34 @@ GEN     lfun_get_w2(GEN tech);
 GEN     lfun_get_expot(GEN tech);
 long    lfun_get_der(GEN tech);
 long    lfun_get_bitprec(GEN tech);
-GEN     lfun(GEN ldata, GEN s, long prec);
-GEN     lfun_bitprec(GEN ldata, GEN s, long bitprec);
-GEN     lfun0_bitprec(GEN ldata, GEN s, long der, long bitprec);
-GEN     lfun0(GEN ldata, GEN s, long der, long prec);
-long    lfuncheckfeq(GEN data, GEN t0, long prec);
-long    lfuncheckfeq_bitprec(GEN data, GEN t0, long bitprec);
-GEN     lfunconductor(GEN data, GEN maxcond, long flag, long prec);
-GEN     lfunconductor_bitprec(GEN data, GEN maxcond, long flag, long bitprec);
+GEN     lfun(GEN ldata, GEN s, long bitprec);
+GEN     lfun0(GEN ldata, GEN s, long der, long bitprec);
+long    lfuncheckfeq(GEN data, GEN t0, long bitprec);
+GEN     lfunconductor(GEN data, GEN maxcond, long flag, long bitprec);
 GEN     lfuncost(GEN lmisc, GEN dom, long der, long bitprec);
 GEN     lfuncost0(GEN L, GEN dom, long der, long bitprec);
 GEN     lfuncreate(GEN obj);
 GEN     lfunan(GEN ldata, long L, long prec);
-GEN     lfunhardy(GEN ldata, GEN t, long prec);
-GEN     lfunhardy_bitprec(GEN ldata, GEN t, long bitprec);
-GEN     lfuninit(GEN ldata, GEN dom, long der, long prec);
-GEN     lfuninit_bitprec(GEN ldata, GEN dom, long der, long bitprec);
-GEN     lfuninit0(GEN ldata, GEN dom, long der, long prec);
-GEN     lfuninit0_bitprec(GEN ldata, GEN dom, long der, long bitprec);
+GEN     lfunhardy(GEN ldata, GEN t, long bitprec);
+GEN     lfuninit(GEN ldata, GEN dom, long der, long bitprec);
+GEN     lfuninit0(GEN ldata, GEN dom, long der, long bitprec);
 GEN     lfuninit_make(long t, GEN ldata, GEN molin, GEN domain);
 long    lfunisvgaell(GEN Vga, long flag);
-GEN     lfunlambda(GEN ldata, GEN s, long prec);
-GEN     lfunlambda_bitprec(GEN ldata, GEN s, long bitprec);
-GEN     lfunlambda0(GEN ldata, GEN s, long der, long prec);
-GEN     lfunlambda0_bitprec(GEN ldata, GEN s, long der, long bitprec);
+GEN     lfunlambda(GEN ldata, GEN s, long bitprec);
+GEN     lfunlambda0(GEN ldata, GEN s, long der, long bitprec);
 GEN     lfunmisc_to_ldata(GEN ldata);
 GEN     lfunmisc_to_ldata_shallow(GEN ldata);
-long    lfunorderzero(GEN ldata, long prec);
-long    lfunorderzero_bitprec(GEN ldata, long bitprec);
+long    lfunorderzero(GEN ldata, long bitprec);
 GEN     lfunprod_get_fact(GEN tech);
-GEN     lfunrootno(GEN data, long prec);
-GEN     lfunrootno_bitprec(GEN data, long bitprec);
-GEN     lfunrootres(GEN data, long prec);
-GEN     lfunrootres_bitprec(GEN data, long bitprec);
+GEN     lfunrootno(GEN data, long bitprec);
+GEN     lfunrootres(GEN data, long bitprec);
 GEN     lfunrtopoles(GEN r);
-GEN     lfuntheta(GEN data, GEN t, long m, long prec);
-GEN     lfuntheta_bitprec(GEN data, GEN t, long m, long bitprec);
+GEN     lfuntheta(GEN data, GEN t, long m, long bitprec);
 long    lfunthetacost0(GEN L, GEN tdom, long m, long bitprec);
 long    lfunthetacost(GEN ldata, GEN tdom, long m, long bitprec);
-GEN     lfunthetainit(GEN ldata, GEN tinf, long m, long prec);
-GEN     lfunthetainit_bitprec(GEN ldata, GEN tdom, long m, long bitprec);
+GEN     lfunthetainit(GEN ldata, GEN tdom, long m, long bitprec);
 GEN     lfunthetacheckinit(GEN data, GEN tinf, long m, long *ptbitprec, long fl);
-GEN     lfunzeros(GEN ldata, GEN lim, long divz, long prec);
-GEN     lfunzeros_bitprec(GEN ldata, GEN lim, long divz, long bitprec);
+GEN     lfunzeros(GEN ldata, GEN lim, long divz, long bitprec);
 int     sdomain_isincl(long k, GEN dom, GEN dom0);
 GEN     theta_get_an(GEN tdata);
 GEN     theta_get_K(GEN tdata);
@@ -3342,25 +3422,20 @@ GEN     theta_get_sqrtN(GEN tdata);
 /* lfunutils.c */
 
 GEN     dirzetak(GEN nf, GEN b);
-GEN     ellmoddegree(GEN e, long prec);
-GEN     ellmoddegree_bitprec(GEN e, long bitprec);
-GEN     lfunabelianrelinit(GEN bnfabs, GEN bnf, GEN polrel, GEN dom, long der, long prec);
-GEN     lfunabelianrelinit_bitprec(GEN bnfabs, GEN bnf, GEN polrel, GEN dom, long der, long bitprec);
+GEN     ellmoddegree(GEN e, long bitprec);
+GEN     lfunabelianrelinit(GEN bnfabs, GEN bnf, GEN polrel, GEN dom, long der, long bitprec);
 GEN     lfunartin(GEN N, GEN G, GEN M, long o);
-GEN     lfundiv(GEN ldata1, GEN ldata2, long prec);
-GEN     lfunellmfpeters_bitprec(GEN E, long bitprec);
-GEN     lfunetaquo(GEN ldata);
-GEN     lfunmfspec(GEN ldata, long prec);
-GEN     lfunmfspec_bitprec(GEN lmisc, long bitprec);
-GEN     lfunmfpeters(GEN ldata, long prec);
-GEN     lfunmfpeters_bitprec(GEN ldata, long bitprec);
-GEN     lfunmul(GEN ldata1, GEN ldata2, long prec);
+GEN     lfundiv(GEN ldata1, GEN ldata2, long bitprec);
+GEN     lfunellmfpeters(GEN E, long bitprec);
+GEN     lfunetaquo(GEN eta);
+GEN     lfungenus2(GEN PS);
+GEN     lfunmfspec(GEN lmisc, long bitprec);
+GEN     lfunmfpeters(GEN ldata, long bitprec);
+GEN     lfunmul(GEN ldata1, GEN ldata2, long bitprec);
 GEN     lfunqf(GEN ldata);
 GEN     lfunsymsq(GEN ldata, GEN known, long prec);
-GEN     lfunsymsqspec(GEN ldata, long prec);
-GEN     lfunsymsqspec_bitprec(GEN lmisc, long bitprec);
-GEN     lfunzetakinit(GEN pol, GEN dom, long der, long flag, long prec);
-GEN     lfunzetakinit_bitprec(GEN pol, GEN dom, long der, long flag, long bitprec);
+GEN     lfunsymsqspec(GEN lmisc, long bitprec);
+GEN     lfunzetakinit(GEN pol, GEN dom, long der, long flag, long bitprec);
 
 /* lll.c */
 
@@ -3399,15 +3474,12 @@ GEN     maptomat_shallow(GEN T);
 
 double  dbllambertW0(double a);
 double  dbllambertW_1(double a);
-double  dbllemma526(double a, double b, double c, long B);
-double  dblcoro526(double a, double c, long B);
-GEN     gammamellininv(GEN Vga, GEN s, long m, long prec);
-GEN     gammamellininv_bitprec(GEN Vga, GEN s, long m, long bitprec);
+double  dbllemma526(double a, double b, double c, double B);
+double  dblcoro526(double a, double c, double B);
+GEN     gammamellininv(GEN Vga, GEN s, long m, long bitprec);
 GEN     gammamellininvasymp(GEN Vga, long nlimmax, long m);
-GEN     gammamellininvinit(GEN Vga, long m, long prec);
-GEN     gammamellininvinit_bitprec(GEN Vga, long m, long bitprec);
-GEN     gammamellininvrt(GEN K, GEN x, long prec);
-GEN     gammamellininvrt_bitprec(GEN K, GEN s, long bitprec);
+GEN     gammamellininvinit(GEN Vga, long m, long bitprec);
+GEN     gammamellininvrt(GEN K, GEN s, long bitprec);
 
 /* members.c */
 
@@ -3731,13 +3803,13 @@ GEN     Flx_ffisom(GEN P,GEN Q,ulong l);
 GEN     Flx_roots_naive(GEN f, ulong p);
 GEN     FlxX_resultant(GEN u, GEN v, ulong p, long sx);
 GEN     Flxq_ffisom_inv(GEN S,GEN Tp, ulong p);
-GEN     FpV_polint(GEN xa, GEN ya, GEN p, long v);
 GEN     FpX_FpXY_resultant(GEN a, GEN b0, GEN p);
 GEN     FpX_factorff_irred(GEN P, GEN Q, GEN p);
 void    FpX_ffintersect(GEN P,GEN Q,long n,GEN l,GEN *SP,GEN *SQ,GEN MA,GEN MB);
 GEN     FpX_ffisom(GEN P,GEN Q,GEN l);
 GEN     FpX_translate(GEN P, GEN c, GEN p);
 GEN     FpXQ_ffisom_inv(GEN S,GEN Tp, GEN p);
+GEN     FpXQX_normalize(GEN z, GEN T, GEN p);
 GEN     FpXV_FpC_mul(GEN V, GEN W, GEN p);
 GEN     FpXY_Fq_evaly(GEN Q, GEN y, GEN T, GEN p, long vx);
 GEN     Fq_Fp_mul(GEN x, GEN y, GEN T, GEN p);
@@ -3767,7 +3839,6 @@ GEN     FqV_to_FlxV(GEN v, GEN T, GEN pp);
 GEN     FqX_Fq_add(GEN y, GEN x, GEN T, GEN p);
 GEN     FqX_Fq_mul_to_monic(GEN P, GEN U, GEN T, GEN p);
 GEN     FqX_eval(GEN x, GEN y, GEN T, GEN p);
-GEN     FqX_normalize(GEN z, GEN T, GEN p);
 GEN     FqX_translate(GEN P, GEN c, GEN T, GEN p);
 GEN     FqXQ_powers(GEN x, long l, GEN S, GEN T, GEN p);
 GEN     FqXQ_matrix_pow(GEN y, long n, long m, GEN S, GEN T, GEN p);
@@ -3783,12 +3854,12 @@ int     Rg_is_Fp(GEN x, GEN *p);
 int     Rg_is_FpXQ(GEN x, GEN *pT, GEN *pp);
 GEN     Rg_to_Fp(GEN x, GEN p);
 GEN     Rg_to_FpXQ(GEN x, GEN T, GEN p);
-GEN     RgC_to_Flc(GEN x, ulong p);
 GEN     RgC_to_FpC(GEN x, GEN p);
 int     RgM_is_FpM(GEN x, GEN *p);
 GEN     RgM_to_Flm(GEN x, ulong p);
 GEN     RgM_to_FpM(GEN x, GEN p);
 int     RgV_is_FpV(GEN x, GEN *p);
+GEN     RgV_to_Flv(GEN x, ulong p);
 GEN     RgV_to_FpV(GEN x, GEN p);
 int     RgX_is_FpX(GEN x, GEN *p);
 GEN     RgX_to_FpX(GEN x, GEN p);
@@ -3866,8 +3937,8 @@ GEN     qfauto0(GEN g, GEN flags);
 GEN     qfautoexport(GEN g, long flag);
 GEN     qfisom(GEN g, GEN h, GEN flags);
 GEN     qfisom0(GEN g, GEN h, GEN flags);
-GEN     qfisominit(GEN g, GEN flags);
-GEN     qfisominit0(GEN g, GEN flags);
+GEN     qfisominit(GEN g, GEN flags, GEN minvec);
+GEN     qfisominit0(GEN g, GEN flags, GEN minvec);
 GEN     qforbits(GEN G, GEN V);
 
 /* qfparam.c */
@@ -4047,6 +4118,7 @@ GEN     gatanh(GEN x, long prec);
 GEN     gcosh(GEN x, long prec);
 GEN     ggammah(GEN x, long prec);
 GEN     ggamma(GEN x, long prec);
+GEN     ggamma1m1(GEN x, long prec);
 GEN     glngamma(GEN x, long prec);
 GEN     gpsi(GEN x, long prec);
 GEN     gsinh(GEN x, long prec);
@@ -4099,16 +4171,20 @@ GEN     weberf1(GEN x, long prec);
 GEN     weberf2(GEN x, long prec);
 
 /* modsym.c */
-GEN     Eisenstein_symbol(GEN W, GEN c);
-GEN     Q_xpm(GEN W, GEN xpm, GEN c);
 GEN     Qevproj_apply(GEN T, GEN pro);
 GEN     Qevproj_apply_vecei(GEN T, GEN pro, long k);
 GEN     Qevproj_init(GEN M);
 GEN     RgX_act_Gl2Q(GEN g, long k);
 GEN     RgX_act_ZGl2Q(GEN z, long k);
 void    checkms(GEN W);
+void    checkmspadic(GEN W);
+GEN     ellpadicL(GEN E, GEN p, long n, GEN s, long r, GEN D);
 GEN     msfromcusp(GEN W, GEN c);
 GEN     msfromell(GEN E, long signe);
+GEN     msfromhecke(GEN W, GEN v, GEN H);
+long    msgetlevel(GEN W);
+long    msgetsign(GEN W);
+long    msgetweight(GEN W);
 GEN     msatkinlehner(GEN W, long Q, GEN);
 GEN     mscuspidal(GEN W, long flag);
 GEN     mseisenstein(GEN W);
@@ -4116,15 +4192,18 @@ GEN     mseval(GEN W, GEN s, GEN p);
 GEN     mshecke(GEN W, long p, GEN H);
 GEN     msinit(GEN N, GEN k, long sign);
 long    msissymbol(GEN W, GEN s);
-GEN     mspadicmoments(GEN W, GEN phi, long p, long n, long D);
+GEN     msomseval(GEN W, GEN phi, GEN path);
+GEN     mspadicinit(GEN W, long p, long n, long flag);
+GEN     mspadicL(GEN oms, GEN s, long r);
+GEN     mspadicmoments(GEN W, GEN phi, long D);
+GEN     mspadicseries(GEN M, long teichi);
 GEN     mspathgens(GEN W);
 GEN     mspathlog(GEN W, GEN path);
 GEN     msnew(GEN W);
 GEN     msstar(GEN W, GEN);
 GEN     msqexpansion(GEN W, GEN proV, ulong B);
-GEN     mssplit(GEN W, GEN H);
-GEN     mstooms(GEN W, GEN phi, long p, long n);
-GEN     omseval(GEN O, GEN path);
+GEN     mssplit(GEN W, GEN H, long deglim);
+GEN     mstooms(GEN W, GEN phi);
 
 /* zetamult.c */
 GEN zetamult(GEN avec, long prec);
@@ -4523,6 +4602,7 @@ INLINE GEN    Flxq_sub(GEN x,GEN y,GEN T,ulong p);
 
 INLINE GEN    FpXQX_div(GEN x, GEN y, GEN T, GEN p);
 INLINE GEN    FlxqX_div(GEN x, GEN y, GEN T, ulong p);
+INLINE GEN    F2xqX_div(GEN x, GEN y, GEN T);
 
 INLINE GEN    Fq_red(GEN x, GEN T, GEN p);
 INLINE GEN    Fq_to_FpXQ(GEN x, GEN T, GEN p);
@@ -4530,18 +4610,22 @@ INLINE GEN    gener_Fq_local(GEN T, GEN p, GEN L);
 INLINE GEN    FqX_Fp_mul(GEN P, GEN U, GEN T, GEN p);
 INLINE GEN    FqX_Fq_mul(GEN P, GEN U, GEN T, GEN p);
 INLINE GEN    FqX_add(GEN x,GEN y,GEN T,GEN p);
+INLINE GEN    FqX_deriv(GEN f, GEN T, GEN p);
 INLINE GEN    FqX_div(GEN x, GEN y, GEN T, GEN p);
 INLINE GEN    FqX_div_by_X_x(GEN x, GEN y, GEN T, GEN p, GEN *z);
 INLINE GEN    FqX_divrem(GEN x, GEN y, GEN T, GEN p, GEN *z);
 INLINE GEN    FqX_extgcd(GEN P,GEN Q,GEN T,GEN p, GEN *U, GEN *V);
+INLINE GEN    FqX_factor(GEN f, GEN T, GEN p);
 INLINE GEN    FqX_gcd(GEN P, GEN Q, GEN T, GEN p);
 INLINE GEN    FqX_get_red(GEN S, GEN T, GEN p);
 INLINE GEN    FqX_mul(GEN x, GEN y, GEN T, GEN p);
 INLINE GEN    FqX_mulu(GEN x, ulong y, GEN T, GEN p);
 INLINE GEN    FqX_neg(GEN x, GEN T, GEN p);
+INLINE GEN    FqX_normalize(GEN z, GEN T, GEN p);
 INLINE GEN    FqX_powu(GEN x, ulong n, GEN T, GEN p);
 INLINE GEN    FqX_red(GEN z, GEN T, GEN p);
 INLINE GEN    FqX_rem(GEN x, GEN y, GEN T, GEN p);
+INLINE GEN    FqX_roots(GEN f, GEN T, GEN p);
 INLINE GEN    FqX_sqr(GEN x, GEN T, GEN p);
 INLINE GEN    FqX_sub(GEN x,GEN y,GEN T,GEN p);
 
@@ -4573,6 +4657,7 @@ INLINE GEN    F2x_div(GEN x, GEN y);
 INLINE GEN    F2x_renormalize(GEN x, long lx);
 INLINE GEN    F2m_copy(GEN x);
 INLINE GEN    F2v_copy(GEN x);
+INLINE GEN    F2x_copy(GEN x);
 INLINE GEN    F2v_ei(long n, long i);
 INLINE GEN    Flm_copy(GEN x);
 INLINE GEN    Flv_copy(GEN x);
@@ -4604,6 +4689,8 @@ INLINE GEN    GENbinbase(GENbin *p);
 INLINE GEN    Q_abs(GEN x);
 INLINE GEN    Q_abs_shallow(GEN x);
 INLINE int    QV_isscalar(GEN x);
+INLINE GEN    R_abs(GEN x);
+INLINE GEN    R_abs_shallow(GEN x);
 INLINE GEN    RgC_fpnorml2(GEN x, long prec);
 INLINE GEN    RgC_gtofp(GEN x, long prec);
 INLINE GEN    RgC_gtomp(GEN x, long prec);
@@ -4667,7 +4754,7 @@ INLINE GEN    col_ei(long n, long i);
 INLINE GEN    const_col(long n, GEN x);
 INLINE GEN    const_vec(long n, GEN x);
 INLINE GEN    const_vecsmall(long n, long c);
-INLINE GEN    constant_term(GEN x);
+INLINE GEN    constant_coeff(GEN x);
 INLINE GEN    cxnorm(GEN x);
 INLINE GEN    cyclic_perm(long l, long d);
 INLINE double dbllog2r(GEN x);
@@ -4716,6 +4803,7 @@ INLINE int    is_matvec_t(long t);
 INLINE int    is_noncalc_t(long tx);
 INLINE int    is_pm1(GEN n);
 INLINE int    is_rational_t(long t);
+INLINE int    is_real_t(long t);
 INLINE int    is_recursive_t(long t);
 INLINE int    is_scalar_t(long t);
 INLINE int    is_universal_constant(GEN x);
@@ -4726,7 +4814,7 @@ INLINE int    isintzero(GEN x);
 INLINE int    ismpzero(GEN x);
 INLINE int    isonstack(GEN x);
 INLINE void   killblock(GEN x);
-INLINE GEN    leading_term(GEN x);
+INLINE GEN    leading_coeff(GEN x);
 INLINE long   lgcols(GEN x);
 INLINE long   lgpol(GEN x);
 INLINE GEN    matpascal(long n);
diff --git a/src/headers/pariinl.h b/src/headers/pariinl.h
index dc48cf9..fea9c3f 100644
--- a/src/headers/pariinl.h
+++ b/src/headers/pariinl.h
@@ -1216,10 +1216,7 @@ bin_copy(GENbin *p)
   base= p->base; dx = x - base;
   y = (GEN)memcpy((void*)new_chunk(len), (void*)GENbinbase(p), len*sizeof(long));
   y += dx;
-  if (p->canon)
-    shiftaddress_canon(y, ((ulong)y-(ulong)x));
-  else
-    shiftaddress(y, ((ulong)y-(ulong)x));
+  p->rebase(y, ((ulong)y-(ulong)x));
   pari_free(p); return y;
 }
 
@@ -1299,6 +1296,12 @@ Q_abs(GEN x) { return (typ(x) == t_INT)? absi(x): absfrac(x); }
 INLINE GEN
 Q_abs_shallow(GEN x)
 { return (typ(x) == t_INT)? absi_shallow(x): absfrac_shallow(x); }
+INLINE GEN
+R_abs_shallow(GEN x)
+{ return (typ(x) == t_FRAC)? absfrac_shallow(x): mpabs_shallow(x); }
+INLINE GEN
+R_abs(GEN x)
+{ return (typ(x) == t_FRAC)? absfrac(x): mpabs(x); }
 
 /* Force z to be of type real/complex with floating point components */
 INLINE GEN
@@ -1785,6 +1788,8 @@ is_noncalc_t(long tx) { return (tx) >= t_LIST; }
 INLINE int
 is_rational_t(long t) { return (t == t_INT || t == t_FRAC); }
 INLINE int
+is_real_t(long t) { return (t == t_INT || t == t_REAL || t == t_FRAC); }
+INLINE int
 is_recursive_t(long t) { return lontyp[t]; }
 INLINE int
 is_scalar_t(long t) { return (t < t_POL); }
@@ -1873,9 +1878,9 @@ mul_denom(GEN dx, GEN dy)
 
 /* POLYNOMIALS */
 INLINE GEN
-constant_term(GEN x) { return signe(x)? gel(x,2): gen_0; }
+constant_coeff(GEN x) { return signe(x)? gel(x,2): gen_0; }
 INLINE GEN
-leading_term(GEN x) { return lg(x) == 2? gen_0: gel(x,lg(x)-1); }
+leading_coeff(GEN x) { return lg(x) == 2? gen_0: gel(x,lg(x)-1); }
 INLINE ulong
 Flx_lead(GEN x) { return lg(x) == 2? 0: x[lg(x)-1]; }
 INLINE long
@@ -1960,6 +1965,8 @@ F2x_equal1(GEN x) { return Flx_equal1(x); }
 INLINE int
 F2x_equal(GEN V, GEN W) { return Flx_equal(V,W); }
 INLINE GEN
+F2x_copy(GEN x) { return leafcopy(x); }
+INLINE GEN
 F2v_copy(GEN x) { return leafcopy(x); }
 INLINE GEN
 Flv_copy(GEN x) { return leafcopy(x); }
@@ -2107,6 +2114,8 @@ INLINE GEN
 FpXQX_div(GEN x, GEN y, GEN T, GEN p) { return FpXQX_divrem(x, y, T, p, NULL); }
 INLINE GEN
 FlxqX_div(GEN x, GEN y, GEN T, ulong p) { return FlxqX_divrem(x, y, T, p, NULL); }
+INLINE GEN
+F2xqX_div(GEN x, GEN y, GEN T) { return F2xqX_divrem(x, y, T, NULL); }
 
 /* FqX */
 INLINE GEN
@@ -2156,6 +2165,14 @@ FqX_gcd(GEN P,GEN Q,GEN T,GEN p)
 INLINE GEN
 FqX_extgcd(GEN P,GEN Q,GEN T,GEN p, GEN *U, GEN *V)
 { return T? FpXQX_extgcd(P,Q,T,p,U,V): FpX_extgcd(P,Q,p,U,V); }
+INLINE GEN
+FqX_normalize(GEN z, GEN T, GEN p) { return T? FpXQX_normalize(z, T, p): FpX_normalize(z, p); }
+INLINE GEN
+FqX_deriv(GEN f, /*unused*/GEN T, GEN p) { (void)T; return FpXX_deriv(f, p); }
+INLINE GEN
+FqX_factor(GEN f, GEN T, GEN p) { return T?FpXQX_factor(f, T, p): FpX_factor(f, p); }
+INLINE GEN
+FqX_roots(GEN f, GEN T, GEN p) { return T?FpXQX_roots(f, T, p): FpX_roots(f, p); }
 
 /*FqXQ*/
 INLINE GEN
diff --git a/src/headers/pariold.h b/src/headers/pariold.h
index f1a0b95..d266340 100644
--- a/src/headers/pariold.h
+++ b/src/headers/pariold.h
@@ -13,6 +13,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 
 /* For compatibility with older PARI versions */
 /*functions renamed*/
+#define leading_term leading_coeff
+#define constant_term leading_coeff
+#define concat gconcat
+#define concat1 gconcat1
 #define mathell ellheightmatrix
 #define ghell ellheight
 #define mpexp1 mpexpm1
@@ -35,6 +39,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 #define vecbezout gcdext0
 #define vecbezoutres polresultantext
 #define init_primepointer init_primepointer_geq
+#define ellap0(e,p,flag) ellap(e,p)
+#define apell2(e,p) ellap(e,p)
 #define geulerphi eulerphi
 #define numbdiv numdiv
 #define gnumbdiv numdiv
@@ -48,6 +54,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 #define powell ellmul
 #define ggval gvaluation
 #define stackmalloc stack_malloc
+
+/* Following obsoleted in 2.5.* (2011) */
 #define fprintferr err_printf
 #define msgTIMER timer_printf
 #define TIMER timer_delay
@@ -97,10 +105,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 #define pariputc pari_putc
 #define pariputs pari_puts
 #define pariflush pari_flush
-#define ellap0(e,p,flag) ellap(e,p)
-#define apell2(e,p) ellap(e,p)
-#define concat gconcat
-#define concat1 gconcat1
 
 /* Following deprecated for a long time now, obsoleted in 2.3.* (2007) */
 #ifdef PARI_OLD_NAMES
diff --git a/src/headers/paripriv.h b/src/headers/paripriv.h
index 6f26f4d..b3d8f1e 100644
--- a/src/headers/paripriv.h
+++ b/src/headers/paripriv.h
@@ -140,8 +140,9 @@ void parforprime0(GEN a, GEN b, GEN code, GEN code2);
 void parforvec0(GEN a, GEN code, GEN code2, long flag);
 GEN  parvector_worker(GEN i, GEN C);
 GEN  polmodular_worker(ulong p, ulong t, ulong L, GEN hilb, GEN factu,
-       GEN vne, GEN vinfo, GEN J, long compute_derivs, GEN j_powers, GEN fdb);
+       GEN vne, GEN vinfo, long compute_derivs, GEN j_powers, GEN fdb);
 GEN  nmV_polint_center_tree_worker(GEN Va, GEN T, GEN R, GEN xa, GEN m2);
+GEN  ZX_resultant_worker(GEN P, GEN A, GEN B, GEN dB);
 
 /* multiprecision */
 GEN   addrex01(GEN x);
@@ -164,7 +165,6 @@ GEN bernfrac_using_zeta(long n);
 
 /* powers */
 GEN    rpowuu(ulong a, ulong n, long prec);
-ulong  u_pow10(int n);
 
 /* floats */
 double dabs(double s, double t);
@@ -240,11 +240,12 @@ GEN logmax_modulus_bound(GEN p);
 GEN polint_i(GEN xa, GEN ya, GEN x, long n, GEN *ptdy);
 GEN quicktrace(GEN x, GEN sym);
 GEN special_pivot(GEN x);
-GEN vandermondeinversemod(GEN L, GEN T, GEN den, GEN mod);
 GEN ZX_monic_factorpadic(GEN f, GEN p, long prec);
 
-/* Finite fields */
+/* Relative number fields */
+enum { rnf_NFABS = 1, rnf_MAPS };
 
+/* Finite fields */
 enum { t_FF_FpXQ = 0, t_FF_Flxq = 1, t_FF_F2xq = 2 };
 GEN FF_ellinit(GEN E, GEN fg);
 GEN FF_elldata(GEN E, GEN fg);
@@ -252,7 +253,8 @@ GEN FF_elldata(GEN E, GEN fg);
 /* L functions */
 enum { t_LFUN_GENERIC, t_LFUN_ZETA, t_LFUN_NF, t_LFUN_ELL, t_LFUN_KRONECKER,
        t_LFUN_CHIZ, t_LFUN_CHIGEN, t_LFUN_ETA, t_LFUN_DIV, t_LFUN_MUL,
-       t_LFUN_SYMSQ, t_LFUN_SYMSQ_ELL, t_LFUN_QF, t_LFUN_ARTIN };
+       t_LFUN_SYMSQ, t_LFUN_SYMSQ_ELL, t_LFUN_QF, t_LFUN_ARTIN,
+       t_LFUN_GENUS2 };
 enum { t_LDESC_INIT, t_LDESC_THETA, t_LDESC_PRODUCT };
 
 /* Elliptic curves */
@@ -588,6 +590,7 @@ long    val_norm(GEN x, GEN p, long *vz);
 /* base5.c */
 
 GEN     check_and_build_nfabs(GEN rnf, long prec);
+void    rnfcomplete(GEN rnf);
 
 /* buch1.c */
 
@@ -758,7 +761,6 @@ ulong   ZX_ZXY_ResBound(GEN A, GEN B, GEN dB);
 GEN     ffinit_Artin_Shreier(GEN ip, long l);
 GEN     ffinit_rand(GEN p, long n);
 void    init_modular(forprime_t *S);
-GEN     polint_triv(GEN xa, GEN ya);
 
 /* random.c */
 
@@ -814,7 +816,4 @@ GEN     polylogd0(long m, GEN x, long flag, long prec);
 GEN     trueE2(GEN tau, long prec);
 GEN     twistpartialzeta(GEN q, long f, long c, GEN va, GEN cff);
 
-/* ellpadicL.c */
-GEN ms_unit_eigenvalue(GEN ap, long k, GEN p, long n);
-
 ENDEXTERN
diff --git a/src/headers/paristio.h b/src/headers/paristio.h
index 5ff7bdf..5cf6d90 100644
--- a/src/headers/paristio.h
+++ b/src/headers/paristio.h
@@ -71,8 +71,7 @@ typedef struct GENbin {
   size_t len; /* gsizeword(x) */
   GEN x; /* binary copy of x */
   GEN base; /* base address of p->x */
-  int canon; /* 1: t_INT in canonical (native kernel) form,
-                0: t_INT according to current kernel */
+  void (*rebase)(GEN,long);
 } GENbin;
 
 struct pari_mainstack
diff --git a/src/headers/parisys.h b/src/headers/parisys.h
index a21fe4c..18373b3 100644
--- a/src/headers/parisys.h
+++ b/src/headers/parisys.h
@@ -13,22 +13,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 
 /* This files contains macros depending on system and compiler    */
 
-#ifndef LITTLE_ENDIAN_64
-#  define   LITTLE_ENDIAN_64 12345678
-#endif
-#ifndef BIG_ENDIAN_64
-#  define   BIG_ENDIAN_64    87654321
-#endif
-#ifndef LITTLE_ENDIAN
-#  define   LITTLE_ENDIAN 1234
-#endif
-#ifndef BIG_ENDIAN
-#  define   BIG_ENDIAN    4321
-#endif
-#ifndef PDP_ENDIAN
-#  define   PDP_ENDIAN    3412
-#endif
-
 #ifdef __cplusplus
 #  define ANYARG ...
 #  define BEGINEXTERN extern "C" {
diff --git a/src/headers/paritune.h b/src/headers/paritune.h
index c4c7925..6cdc83e 100644
--- a/src/headers/paritune.h
+++ b/src/headers/paritune.h
@@ -4,6 +4,7 @@
 extern long AGM_ATAN_LIMIT;
 extern long DIVRR_GMP_LIMIT;
 extern long EXPNEWTON_LIMIT;
+extern long F2x_MUL_KARATSUBA_LIMIT;
 extern long Flx_BARRETT_QUARTMULII_LIMIT;
 extern long Flx_BARRETT_HALFMULII_LIMIT;
 extern long Flx_BARRETT_KARATSUBA_LIMIT;
@@ -35,6 +36,9 @@ extern long Flx_SQR_SQRI2_LIMIT;
 extern long Flx_SQR_SQRI_LIMIT;
 extern long FlxqX_BARRETT_LIMIT;
 extern long FlxqX_DIVREM_BARRETT_LIMIT;
+extern long FlxqX_EXTGCD_LIMIT;
+extern long FlxqX_GCD_LIMIT;
+extern long FlxqX_HALFGCD_LIMIT;
 extern long FlxqX_INVBARRETT_LIMIT;
 extern long FlxqX_REM_BARRETT_LIMIT;
 extern long FpX_BARRETT_LIMIT;
@@ -46,6 +50,9 @@ extern long FpX_INVBARRETT_LIMIT;
 extern long FpX_REM_BARRETT_LIMIT;
 extern long FpXQX_BARRETT_LIMIT;
 extern long FpXQX_DIVREM_BARRETT_LIMIT;
+extern long FpXQX_EXTGCD_LIMIT;
+extern long FpXQX_GCD_LIMIT;
+extern long FpXQX_HALFGCD_LIMIT;
 extern long FpXQX_INVBARRETT_LIMIT;
 extern long FpXQX_REM_BARRETT_LIMIT;
 extern long Fp_POW_BARRETT_LIMIT;
@@ -65,6 +72,7 @@ extern long SQRI_KARATSUBA_LIMIT;
 #  define AGM_ATAN_LIMIT                 __AGM_ATAN_LIMIT
 #  define DIVRR_GMP_LIMIT                __DIVRR_GMP_LIMIT
 #  define EXPNEWTON_LIMIT                __EXPNEWTON_LIMIT
+#  define F2x_MUL_KARATSUBA_LIMIT        __F2x_MUL_KARATSUBA_LIMIT
 #  define Flx_BARRETT_QUARTMULII_LIMIT   __Flx_BARRETT_QUARTMULII_LIMIT
 #  define Flx_BARRETT_HALFMULII_LIMIT    __Flx_BARRETT_HALFMULII_LIMIT
 #  define Flx_BARRETT_KARATSUBA_LIMIT    __Flx_BARRETT_KARATSUBA_LIMIT
@@ -96,6 +104,9 @@ extern long SQRI_KARATSUBA_LIMIT;
 #  define Flx_SQR_SQRI_LIMIT             __Flx_SQR_SQRI_LIMIT
 #  define FlxqX_BARRETT_LIMIT            __FlxqX_BARRETT_LIMIT
 #  define FlxqX_DIVREM_BARRETT_LIMIT     __FlxqX_DIVREM_BARRETT_LIMIT
+#  define FlxqX_EXTGCD_LIMIT             __FlxqX_EXTGCD_LIMIT
+#  define FlxqX_GCD_LIMIT                __FlxqX_GCD_LIMIT
+#  define FlxqX_HALFGCD_LIMIT            __FlxqX_HALFGCD_LIMIT
 #  define FlxqX_INVBARRETT_LIMIT         __FlxqX_INVBARRETT_LIMIT
 #  define FlxqX_REM_BARRETT_LIMIT        __FlxqX_REM_BARRETT_LIMIT
 #  define FpX_BARRETT_LIMIT              __FpX_BARRETT_LIMIT
@@ -107,6 +118,9 @@ extern long SQRI_KARATSUBA_LIMIT;
 #  define FpX_REM_BARRETT_LIMIT          __FpX_REM_BARRETT_LIMIT
 #  define FpXQX_BARRETT_LIMIT            __FpXQX_BARRETT_LIMIT
 #  define FpXQX_DIVREM_BARRETT_LIMIT     __FpXQX_DIVREM_BARRETT_LIMIT
+#  define FpXQX_EXTGCD_LIMIT             __FpXQX_EXTGCD_LIMIT
+#  define FpXQX_GCD_LIMIT                __FpXQX_GCD_LIMIT
+#  define FpXQX_HALFGCD_LIMIT            __FpXQX_HALFGCD_LIMIT
 #  define FpXQX_INVBARRETT_LIMIT         __FpXQX_INVBARRETT_LIMIT
 #  define FpXQX_REM_BARRETT_LIMIT        __FpXQX_REM_BARRETT_LIMIT
 #  define Fp_POW_BARRETT_LIMIT           __Fp_POW_BARRETT_LIMIT
diff --git a/src/kernel/gmp/mp.c b/src/kernel/gmp/mp.c
index 901a90f..b345bd7 100644
--- a/src/kernel/gmp/mp.c
+++ b/src/kernel/gmp/mp.c
@@ -532,7 +532,7 @@ addumului(ulong a, ulong b, GEN y)
   GEN z;
   long i, lz;
   ulong hi;
-  if (!signe(y)) return utoi(a);
+  if (!b || !signe(y)) return utoi(a);
   lz = lgefint(y)+1;
   z = cgeti(lz);
   z[2]=a;
diff --git a/src/kernel/gmp/tune.h b/src/kernel/gmp/tune.h
index 09378ec..bba8cdf 100644
--- a/src/kernel/gmp/tune.h
+++ b/src/kernel/gmp/tune.h
@@ -2,6 +2,7 @@
 #define __AGM_ATAN_LIMIT                 60
 #define __DIVRR_GMP_LIMIT                4
 #define __EXPNEWTON_LIMIT                66
+#define __F2x_MUL_KARATSUBA_LIMIT        15
 #define __Flx_BARRETT_HALFMULII_LIMIT    21
 #define __Flx_BARRETT_KARATSUBA_LIMIT    1172
 #define __Flx_BARRETT_MULII2_LIMIT       16
@@ -33,10 +34,16 @@
 #define __Flx_SQR_SQRI_LIMIT             5
 #define __FlxqX_BARRETT_LIMIT            17
 #define __FlxqX_DIVREM_BARRETT_LIMIT     46
+#define __FlxqX_EXTGCD_LIMIT             44
+#define __FlxqX_GCD_LIMIT                470
+#define __FlxqX_HALFGCD_LIMIT            60
 #define __FlxqX_INVBARRETT_LIMIT         22
 #define __FlxqX_REM_BARRETT_LIMIT        48
 #define __FpXQX_BARRETT_LIMIT            12
 #define __FpXQX_DIVREM_BARRETT_LIMIT     30
+#define __FpXQX_EXTGCD_LIMIT             28
+#define __FpXQX_GCD_LIMIT                191
+#define __FpXQX_HALFGCD_LIMIT            35
 #define __FpXQX_INVBARRETT_LIMIT         40
 #define __FpXQX_REM_BARRETT_LIMIT        30
 #define __FpX_BARRETT_LIMIT              38
@@ -63,6 +70,7 @@
 #define __AGM_ATAN_LIMIT                 89
 #define __DIVRR_GMP_LIMIT                4
 #define __EXPNEWTON_LIMIT                197
+#define __F2x_MUL_KARATSUBA_LIMIT        23
 #define __Flx_BARRETT_HALFMULII_LIMIT    23
 #define __Flx_BARRETT_KARATSUBA_LIMIT    905
 #define __Flx_BARRETT_MULII2_LIMIT       647
@@ -94,10 +102,16 @@
 #define __Flx_SQR_SQRI_LIMIT             5
 #define __FlxqX_BARRETT_LIMIT            17
 #define __FlxqX_DIVREM_BARRETT_LIMIT     46
+#define __FlxqX_EXTGCD_LIMIT             44
+#define __FlxqX_GCD_LIMIT                1289
+#define __FlxqX_HALFGCD_LIMIT            89
 #define __FlxqX_INVBARRETT_LIMIT         22
 #define __FlxqX_REM_BARRETT_LIMIT        48
 #define __FpXQX_BARRETT_LIMIT            12
 #define __FpXQX_DIVREM_BARRETT_LIMIT     30
+#define __FpXQX_EXTGCD_LIMIT             28
+#define __FpXQX_GCD_LIMIT                182
+#define __FpXQX_HALFGCD_LIMIT            35
 #define __FpXQX_INVBARRETT_LIMIT         40
 #define __FpXQX_REM_BARRETT_LIMIT        30
 #define __FpX_BARRETT_LIMIT              44
diff --git a/src/kernel/none/mp.c b/src/kernel/none/mp.c
index c2f451a..7163d77 100644
--- a/src/kernel/none/mp.c
+++ b/src/kernel/none/mp.c
@@ -469,7 +469,7 @@ addumului(ulong a, ulong b, GEN Y)
   LOCAL_HIREMAINDER;
   LOCAL_OVERFLOW;
 
-  if (!signe(Y)) return utoi(a);
+  if (!b || !signe(Y)) return utoi(a);
 
   y = LIMBS(Y); z = (GEN)avma;
   ny = NLIMBS(Y);
diff --git a/src/kernel/none/tune-gen.h b/src/kernel/none/tune-gen.h
index 192af93..b65ec31 100644
--- a/src/kernel/none/tune-gen.h
+++ b/src/kernel/none/tune-gen.h
@@ -2,6 +2,7 @@
 long AGM_ATAN_LIMIT                 = __AGM_ATAN_LIMIT;
 long DIVRR_GMP_LIMIT                = __DIVRR_GMP_LIMIT;
 long EXPNEWTON_LIMIT                = __EXPNEWTON_LIMIT;
+long F2x_MUL_KARATSUBA_LIMIT        = __F2x_MUL_KARATSUBA_LIMIT;
 long Flx_BARRETT_QUARTMULII_LIMIT   = __Flx_BARRETT_QUARTMULII_LIMIT;
 long Flx_BARRETT_HALFMULII_LIMIT    = __Flx_BARRETT_HALFMULII_LIMIT;
 long Flx_BARRETT_KARATSUBA_LIMIT    = __Flx_BARRETT_KARATSUBA_LIMIT;
@@ -33,6 +34,9 @@ long Flx_SQR_SQRI2_LIMIT            = __Flx_SQR_SQRI2_LIMIT;
 long Flx_SQR_SQRI_LIMIT             = __Flx_SQR_SQRI_LIMIT;
 long FlxqX_BARRETT_LIMIT            = __FlxqX_BARRETT_LIMIT;
 long FlxqX_DIVREM_BARRETT_LIMIT     = __FlxqX_DIVREM_BARRETT_LIMIT;
+long FlxqX_EXTGCD_LIMIT             = __FlxqX_EXTGCD_LIMIT;
+long FlxqX_GCD_LIMIT                = __FlxqX_GCD_LIMIT;
+long FlxqX_HALFGCD_LIMIT            = __FlxqX_HALFGCD_LIMIT;
 long FlxqX_INVBARRETT_LIMIT         = __FlxqX_INVBARRETT_LIMIT;
 long FlxqX_REM_BARRETT_LIMIT        = __FlxqX_REM_BARRETT_LIMIT;
 long FpX_BARRETT_LIMIT              = __FpX_BARRETT_LIMIT;
@@ -44,6 +48,9 @@ long FpX_INVBARRETT_LIMIT           = __FpX_INVBARRETT_LIMIT;
 long FpX_REM_BARRETT_LIMIT          = __FpX_REM_BARRETT_LIMIT;
 long FpXQX_BARRETT_LIMIT            = __FpXQX_BARRETT_LIMIT;
 long FpXQX_DIVREM_BARRETT_LIMIT     = __FpXQX_DIVREM_BARRETT_LIMIT;
+long FpXQX_EXTGCD_LIMIT             = __FpXQX_EXTGCD_LIMIT;
+long FpXQX_GCD_LIMIT                = __FpXQX_GCD_LIMIT;
+long FpXQX_HALFGCD_LIMIT            = __FpXQX_HALFGCD_LIMIT;
 long FpXQX_INVBARRETT_LIMIT         = __FpXQX_INVBARRETT_LIMIT;
 long FpXQX_REM_BARRETT_LIMIT        = __FpXQX_REM_BARRETT_LIMIT;
 long Fp_POW_BARRETT_LIMIT           = __Fp_POW_BARRETT_LIMIT;
diff --git a/src/kernel/none/tune.h b/src/kernel/none/tune.h
index 282c5d4..51acead 100644
--- a/src/kernel/none/tune.h
+++ b/src/kernel/none/tune.h
@@ -2,6 +2,7 @@
 #define __AGM_ATAN_LIMIT                 56
 #define __DIVRR_GMP_LIMIT                -1
 #define __EXPNEWTON_LIMIT                66
+#define __F2x_MUL_KARATSUBA_LIMIT        15
 #define __Flx_BARRETT_HALFMULII_LIMIT    29
 #define __Flx_BARRETT_KARATSUBA_LIMIT    2561
 #define __Flx_BARRETT_MULII2_LIMIT       30
@@ -33,10 +34,16 @@
 #define __Flx_SQR_SQRI_LIMIT             5
 #define __FlxqX_BARRETT_LIMIT            17
 #define __FlxqX_DIVREM_BARRETT_LIMIT     46
+#define __FlxqX_EXTGCD_LIMIT             44
+#define __FlxqX_GCD_LIMIT                796
+#define __FlxqX_HALFGCD_LIMIT            191
 #define __FlxqX_INVBARRETT_LIMIT         22
 #define __FlxqX_REM_BARRETT_LIMIT        48
 #define __FpXQX_BARRETT_LIMIT            12
 #define __FpXQX_DIVREM_BARRETT_LIMIT     30
+#define __FpXQX_EXTGCD_LIMIT             34
+#define __FpXQX_GCD_LIMIT                254
+#define __FpXQX_HALFGCD_LIMIT            56
 #define __FpXQX_INVBARRETT_LIMIT         40
 #define __FpXQX_REM_BARRETT_LIMIT        30
 #define __FpX_BARRETT_LIMIT              85
@@ -63,6 +70,7 @@
 #define __AGM_ATAN_LIMIT                 159
 #define __DIVRR_GMP_LIMIT                -1
 #define __EXPNEWTON_LIMIT                66
+#define __F2x_MUL_KARATSUBA_LIMIT        23
 #define __Flx_BARRETT_HALFMULII_LIMIT    244
 #define __Flx_BARRETT_KARATSUBA_LIMIT    905
 #define __Flx_BARRETT_MULII2_LIMIT       1004
@@ -94,10 +102,16 @@
 #define __Flx_SQR_SQRI_LIMIT             1276
 #define __FlxqX_BARRETT_LIMIT            17
 #define __FlxqX_DIVREM_BARRETT_LIMIT     46
+#define __FlxqX_EXTGCD_LIMIT             44
+#define __FlxqX_GCD_LIMIT                2544
+#define __FlxqX_HALFGCD_LIMIT            427
 #define __FlxqX_INVBARRETT_LIMIT         22
 #define __FlxqX_REM_BARRETT_LIMIT        48
 #define __FpXQX_BARRETT_LIMIT            12
 #define __FpXQX_DIVREM_BARRETT_LIMIT     30
+#define __FpXQX_EXTGCD_LIMIT             28
+#define __FpXQX_GCD_LIMIT                254
+#define __FpXQX_HALFGCD_LIMIT            48
 #define __FpXQX_INVBARRETT_LIMIT         40
 #define __FpXQX_REM_BARRETT_LIMIT        30
 #define __FpX_BARRETT_LIMIT              144
diff --git a/src/language/anal.c b/src/language/anal.c
index 01ae382..644bb44 100644
--- a/src/language/anal.c
+++ b/src/language/anal.c
@@ -331,7 +331,6 @@ check_proto(const char *code)
     case 'p':
     case 'b':
     case 'r':
-    case 'x':
       arity++;
       break;
     case 'E':
@@ -438,14 +437,13 @@ type0(GEN x)
 
 #ifdef LONG_IS_64BIT
 static const long MAX_DIGITS  = 19;
-static const long MAX_XDIGITS = 15;
-static const long MAX_BDIGITS = 63;
 #else
 static const long MAX_DIGITS  = 9;
-static const long MAX_XDIGITS = 7;
-static const long MAX_BDIGITS = 31;
 #endif
 
+static const long MAX_XDIGITS = BITS_IN_LONG>>2;
+static const long MAX_BDIGITS = BITS_IN_LONG;
+
 static int
 ishex(const char **s)
 {
@@ -471,121 +469,132 @@ isbin(const char **s)
 }
 
 static ulong
-number(int *n, const char **s)
+bin_number_len(const char *s, long n)
 {
   ulong m = 0;
-  for (*n = 0; *n < MAX_DIGITS && isdigit((int)**s); (*n)++,(*s)++)
-    m = 10*m + (**s - '0');
+  long i;
+  for (i = 0; i < n; i++,s++)
+    m = 2*m + (*s - '0');
   return m;
 }
 
+static int
+pari_isbdigit(int c)
+{
+  return c=='0' || c=='1';
+}
+
 static ulong
-hexnumber(int *n, const char **s)
+hex_number_len(const char *s, long n)
 {
   ulong m = 0;
-  for(*n = 0; *n < MAX_XDIGITS; (*n)++,(*s)++)
+  long i;
+  for(i = 0; i < n; i++, s++)
   {
-    if( **s >= '0' && **s <= '9') {
-        m = 16*m + (**s - '0');
-        continue;
-    }
-    if( **s >= 'A' && **s <= 'F') {
-        m = 16*m + (**s - 'A' + 10);
-        continue;
-    }
-    if( **s >= 'a' && **s <= 'f') {
-        m = 16*m + (**s - 'a' + 10);
-        continue;
-    }
-    break;
+    ulong c;
+    if( *s >= '0' && *s <= '9')
+      c = *s - '0';
+    else if( *s >= 'A' && *s <= 'F')
+      c = *s - 'A' + 10;
+    else
+      c = *s - 'a' + 10;
+    m = 16*m + c;
   }
   return m;
 }
 
+static GEN
+strtobin_len(const char *s, long n, long B, ulong num(const char *s, long n))
+{
+  long i, l = (n+B-1)/B;
+  GEN N, Np;
+  N = cgetipos(l+2);
+  Np = int_LSW(N);
+  for (i=1; i<l; i++, Np = int_nextW(Np))
+    uel(Np, 0) = num(s+n-i*B, B);
+  uel(Np, 0) = num(s, n-(i-1)*B);
+  return int_normalize(N, 0);
+}
+
+static GEN
+binary_read(const char **ps, long B, int is(int), ulong num(const char *s, long n))
+{
+  const char *s = *ps;
+  while (is((int)**ps)) (*ps)++;
+  return strtobin_len(s, *ps-s, B, num);
+}
+
+static GEN
+bin_read(const char **ps)
+{
+  return binary_read(ps, MAX_BDIGITS, pari_isbdigit, bin_number_len);
+}
+
+static GEN
+hex_read(const char **ps)
+{
+  return binary_read(ps, MAX_XDIGITS, isxdigit, hex_number_len);
+}
+
 static ulong
-binnumber(int *n, const char **s)
+dec_number_len(const char *s, long B)
 {
   ulong m = 0;
-  for(*n = 0; *n < MAX_BDIGITS; (*n)++,(*s)++)
-  {
-    if( **s == '0' || **s == '1') {
-        m = 2*m + (**s - '0');
-    } else
-        break;
-  }
+  long n;
+  for (n = 0; n < B; n++,s++)
+    m = 10*m + (*s - '0');
   return m;
 }
 
-ulong
-u_pow10(int n)
-{
-  const ulong pw10[] = {
-    1UL
-    ,10UL
-    ,100UL
-    ,1000UL
-    ,10000UL
-    ,100000UL
-    ,1000000UL
-    ,10000000UL
-    ,100000000UL
-    ,1000000000UL
-#ifdef LONG_IS_64BIT
-    ,10000000000UL
-    ,100000000000UL
-    ,1000000000000UL
-    ,10000000000000UL
-    ,100000000000000UL
-    ,1000000000000000UL
-    ,10000000000000000UL
-    ,100000000000000000UL
-    ,1000000000000000000UL
-    ,10000000000000000000UL
-#endif
-  };
-  return pw10[n];
+static GEN
+dec_strtoi_len(const char *s, long n)
+{
+  const long B = MAX_DIGITS;
+  long i, l = (n+B-1)/B;
+  GEN V = cgetg(l+1, t_VECSMALL);
+  for (i=1; i<l; i++)
+    uel(V,i) = dec_number_len(s+n-i*B, B);
+  uel(V, i) = dec_number_len(s, n-(i-1)*B);
+  return fromdigitsu(V, powuu(10, B));
 }
 
 static GEN
-int_read_more(GEN y, const char **ps)
+dec_read_more(const char **ps)
 {
   pari_sp av = avma;
-  int i = 0, nb;
-  while (isdigit((int)**ps))
-  {
-    ulong m = number(&nb, ps);
-    if (avma != av && ++i > 4) { avma = av; i = 0; } /* HACK gerepile */
-    y = addumului(m, u_pow10(nb), y);
-  }
-  return y;
+  const char *s = *ps;
+  while (isdigit((int)**ps)) (*ps)++;
+  return gerepileuptoint(av, dec_strtoi_len(s, *ps-s));
+}
+
+static ulong
+number(int *n, const char **s)
+{
+  ulong m = 0;
+  for (*n = 0; *n < MAX_DIGITS && isdigit((int)**s); (*n)++,(*s)++)
+    m = 10*m + (**s - '0');
+  return m;
 }
 
 static GEN
-hex_read_more(GEN y, const char **ps)
+dec_read(const char **s)
 {
-  pari_sp av = avma;
-  int i = 0, nb;
-  while (isxdigit((int)**ps))
-  {
-    ulong m = hexnumber(&nb, ps);
-    if (avma != av && ++i > 4) { avma = av; i = 0; } /* HACK gerepile */
-    y = addumului(m, 1UL << (nb*4), y);
-  }
-  return y;
+  int nb;
+  ulong y  = number(&nb, s);
+  if (nb < MAX_DIGITS)
+    return utoi(y);
+  *s -= MAX_DIGITS;
+  return dec_read_more(s);
 }
 
 static GEN
-bin_read_more(GEN y, const char **ps)
+real_read_more(GEN y, const char **ps)
 {
   pari_sp av = avma;
-  int i = 0, nb;
-  while (**ps == '0' || **ps == '1')
-  {
-    ulong m = binnumber(&nb, ps);
-    if (avma != av && ++i > 4) { avma = av; i = 0; } /* HACK gerepile */
-    y = addumului(m, 1UL << nb, y);
-  }
-  return y;
+  const char *s = *ps;
+  GEN z = dec_read(ps);
+  long e = *ps-s;
+  return gerepileuptoint(av, addmulii(z, powuu(10, e), y));
 }
 
 static long
@@ -628,7 +637,7 @@ real_read(pari_sp av, const char **s, GEN y, long prec)
         }
         --*s; return y; /* member */
       }
-      y = int_read_more(y, s);
+      if (isdigit((int)**s)) y = real_read_more(y, s);
       n = old - *s;
       if (**s != 'E' && **s != 'e')
       {
@@ -654,30 +663,15 @@ real_read(pari_sp av, const char **s, GEN y, long prec)
 }
 
 static GEN
-int_read_dec(const char **s)
-{
-  int nb;
-  GEN y = utoi(number(&nb, s));
-  if (nb == MAX_DIGITS) y = int_read_more(y, s);
-  return y;
-}
-
-static GEN
 int_read(const char **s)
 {
-  int nb;
   GEN y;
-  if (isbin(s)) {
-    y = utoi(binnumber(&nb, s));
-    if (nb == MAX_BDIGITS) y = bin_read_more(y, s);
-  } else
-  if (ishex(s)) {
-    y = utoi(hexnumber(&nb, s));
-    if (nb == MAX_XDIGITS) y = hex_read_more(y, s);
-  } else
-  {
-    y = int_read_dec(s);
-  }
+  if (isbin(s))
+    y = bin_read(s);
+  else if (ishex(s))
+    y = hex_read(s);
+  else
+    y = dec_read(s);
   return y;
 }
 
@@ -688,7 +682,7 @@ GEN
 strtor(const char *s, long prec)
 {
   pari_sp av = avma;
-  GEN y = int_read_dec(&s);
+  GEN y = dec_read(&s);
   y = real_read(av, &s, y, prec);
   if (typ(y) == t_REAL) return y;
   return gerepileuptoleaf(av, itor(y, prec));
@@ -1237,22 +1231,18 @@ GEN
 ifpari(GEN g, GEN a/*closure*/, GEN b/*closure*/)
 {
   if (gequal0(g)) /* false */
-    return b?closure_evalgen(b):gnil;
+    return b? closure_evalgen(b): gnil;
   else /* true */
-    return a?closure_evalgen(a):gnil;
+    return a? closure_evalgen(a): gnil;
 }
 
 void
 ifpari_void(GEN g, GEN a/*closure*/, GEN b/*closure*/)
 {
   if (gequal0(g)) /* false */
-  {
-    if(b) closure_evalvoid(b);
-  }
+  { if (b) closure_evalvoid(b); }
   else /* true */
-  {
-    if(a) closure_evalvoid(a);
-  }
+  { if (a) closure_evalvoid(a); }
 }
 
 GEN
@@ -1293,71 +1283,17 @@ orpari(GEN a, GEN b/*closure*/)
   return gequal0(g)?gen_0:gen_1;
 }
 
-GEN gmule(GEN *x, GEN y)
-{
-  *x=gmul(*x,y);
-  return *x;
-}
-
-GEN gdive(GEN *x, GEN y)
-{
-  *x=gdiv(*x,y);
-  return *x;
-}
-
-GEN gdivente(GEN *x, GEN y)
-{
-  *x=gdivent(*x,y);
-  return *x;
-}
-
-GEN gdivrounde(GEN *x, GEN y)
-{
-  *x=gdivround(*x,y);
-  return *x;
-}
-
-GEN gmode(GEN *x, GEN y)
-{
-  *x=gmod(*x,y);
-  return *x;
-}
-
-GEN gshiftle(GEN *x, long n)
-{
-  *x=gshift(*x,n);
-  return *x;
-}
-
-GEN gshiftre(GEN *x, long n)
-{
-  *x=gshift(*x,-n);
-  return *x;
-}
-
-GEN gadde(GEN *x, GEN y)
-{
-  *x=gadd(*x,y);
-  return *x;
-}
-
-GEN gadd1e(GEN *x)
-{
-  *x=typ(*x)==t_INT?addis(*x,1):gaddgs(*x,1);
-  return *x;
-}
-
-GEN gsube(GEN *x, GEN y)
-{
-  *x=gsub(*x,y);
-  return *x;
-}
-
-GEN gsub1e(GEN *x)
-{
-  *x=typ(*x)==t_INT?subis(*x,1):gsubgs(*x,1);
-  return *x;
-}
+GEN gmule(GEN *x, GEN y) { *x = gmul(*x,y); return *x; }
+GEN gdive(GEN *x, GEN y) { *x = gdiv(*x,y); return *x; }
+GEN gdivente(GEN *x, GEN y) { *x = gdivent(*x,y); return *x; }
+GEN gdivrounde(GEN *x, GEN y) { *x = gdivround(*x,y); return *x; }
+GEN gmode(GEN *x, GEN y) { *x = gmod(*x,y); return *x; }
+GEN gshiftle(GEN *x, long n) { *x = gshift(*x,n); return *x; }
+GEN gshiftre(GEN *x, long n) { *x = gshift(*x,-n); return *x; }
+GEN gadde(GEN *x, GEN y) { *x = gadd(*x,y); return *x; }
+GEN gadd1e(GEN *x) { *x = typ(*x)==t_INT?addis(*x,1):gaddgs(*x,1); return *x; }
+GEN gsube(GEN *x, GEN y) { *x = gsub(*x,y); return *x; }
+GEN gsub1e(GEN *x) { *x = typ(*x)==t_INT?subis(*x,1):gsubgs(*x,1); return *x; }
 
 GEN gshift_right(GEN x, long n) { return gshift(x,-n); }
 
diff --git a/src/language/compile.c b/src/language/compile.c
index f0da83a..f11d054 100644
--- a/src/language/compile.c
+++ b/src/language/compile.c
@@ -716,17 +716,18 @@ matindex_type(long n)
   long fxx = tree[tree[x].x].f, fxy = tree[tree[x].y].f;
   if (y==-1)
   {
-    if (fxy!=Fnoarg) return MAT_range;
-    if (fxx==Fnoarg) compile_err("missing index",tree[n].str);
+    if (fxy!=Fnorange) return MAT_range;
+    if (fxx==Fnorange) compile_err("missing index",tree[n].str);
     return VEC_std;
   }
   else
   {
     long fyx = tree[tree[y].x].f, fyy = tree[tree[y].y].f;
-    if (fxy!=Fnoarg || fyy!=Fnoarg) return MAT_range;
-    if (fxx==Fnoarg && fyx==Fnoarg) compile_err("missing index",tree[n].str);
-    if (fxx==Fnoarg) return MAT_column;
-    if (fyx==Fnoarg) return MAT_line;
+    if (fxy!=Fnorange || fyy!=Fnorange) return MAT_range;
+    if (fxx==Fnorange && fyx==Fnorange)
+      compile_err("missing index",tree[n].str);
+    if (fxx==Fnorange) return MAT_column;
+    if (fyx==Fnorange) return MAT_line;
     return MAT_std;
   }
 }
@@ -2157,6 +2158,10 @@ compilenode(long n, int mode, long flag)
   case Fnoarg:
     compilecast(n,Gvoid,mode);
     return;
+  case Fnorange:
+    op_push(OCpushlong,LONG_MAX,n);
+    compilecast(n,Gsmall,mode);
+    return;
   default:
     pari_err_BUG("compilenode");
   }
@@ -2463,6 +2468,7 @@ optimizenode(long n)
     tree[n].flags=0;
     break;
   case Fnoarg:
+  case Fnorange:
   case Fsmall:
   case Fconst:
   case Fentry:
diff --git a/src/language/default.h b/src/language/default.h
index b773ae5..0b98a96 100644
--- a/src/language/default.h
+++ b/src/language/default.h
@@ -2,50 +2,50 @@
 /* See src/desc/gen_proto */
 /* Do not edit*/
 entree functions_default[]={
-{"TeXstyle",0,(void*)sd_TeXstyle,19,"",""},
-{"breakloop",0,(void*)sd_breakloop,19,"",""},
-{"colors",0,(void*)sd_colors,19,"",""},
-{"compatible",0,(void*)sd_compatible,19,"",""},
-{"datadir",0,(void*)sd_datadir,19,"",""},
-{"debug",0,(void*)sd_debug,19,"",""},
-{"debugfiles",0,(void*)sd_debugfiles,19,"",""},
-{"debugmem",0,(void*)sd_debugmem,19,"",""},
-{"echo",0,(void*)sd_echo,19,"",""},
-{"factor_add_primes",0,(void*)sd_factor_add_primes,19,"",""},
-{"factor_proven",0,(void*)sd_factor_proven,19,"",""},
-{"format",0,(void*)sd_format,19,"",""},
-{"graphcolormap",0,(void*)sd_graphcolormap,19,"",""},
-{"graphcolors",0,(void*)sd_graphcolors,19,"",""},
-{"help",0,(void*)sd_help,19,"",""},
-{"histfile",0,(void*)sd_histfile,19,"",""},
-{"histsize",0,(void*)sd_histsize,19,"",""},
-{"lines",0,(void*)sd_lines,19,"",""},
-{"linewrap",0,(void*)sd_linewrap,19,"",""},
-{"log",0,(void*)sd_log,19,"",""},
-{"logfile",0,(void*)sd_logfile,19,"",""},
-{"nbthreads",0,(void*)sd_nbthreads,19,"",""},
-{"new_galois_format",0,(void*)sd_new_galois_format,19,"",""},
-{"output",0,(void*)sd_output,19,"",""},
-{"parisize",0,(void*)sd_parisize,19,"",""},
-{"parisizemax",0,(void*)sd_parisizemax,19,"",""},
-{"path",0,(void*)sd_path,19,"",""},
-{"prettyprinter",0,(void*)sd_prettyprinter,19,"",""},
-{"primelimit",0,(void*)sd_primelimit,19,"",""},
-{"prompt",0,(void*)sd_prompt,19,"",""},
-{"prompt_cont",0,(void*)sd_prompt_cont,19,"",""},
-{"psfile",0,(void*)sd_psfile,19,"",""},
-{"readline",0,(void*)sd_readline,19,"",""},
-{"realbitprecision",0,(void*)sd_realbitprecision,19,"",""},
-{"realprecision",0,(void*)sd_realprecision,19,"",""},
-{"recover",0,(void*)sd_recover,19,"",""},
-{"secure",0,(void*)sd_secure,19,"",""},
-{"seriesprecision",0,(void*)sd_seriesprecision,19,"",""},
-{"simplify",0,(void*)sd_simplify,19,"",""},
-{"sopath",0,(void*)sd_sopath,19,"",""},
-{"strictargs",0,(void*)sd_strictargs,19,"",""},
-{"strictmatch",0,(void*)sd_strictmatch,19,"",""},
-{"threadsize",0,(void*)sd_threadsize,19,"",""},
-{"threadsizemax",0,(void*)sd_threadsizemax,19,"",""},
-{"timer",0,(void*)sd_timer,19,"",""},
+{"TeXstyle",0,(void*)sd_TeXstyle,20,"",""},
+{"breakloop",0,(void*)sd_breakloop,20,"",""},
+{"colors",0,(void*)sd_colors,20,"",""},
+{"compatible",0,(void*)sd_compatible,20,"",""},
+{"datadir",0,(void*)sd_datadir,20,"",""},
+{"debug",0,(void*)sd_debug,20,"",""},
+{"debugfiles",0,(void*)sd_debugfiles,20,"",""},
+{"debugmem",0,(void*)sd_debugmem,20,"",""},
+{"echo",0,(void*)sd_echo,20,"",""},
+{"factor_add_primes",0,(void*)sd_factor_add_primes,20,"",""},
+{"factor_proven",0,(void*)sd_factor_proven,20,"",""},
+{"format",0,(void*)sd_format,20,"",""},
+{"graphcolormap",0,(void*)sd_graphcolormap,20,"",""},
+{"graphcolors",0,(void*)sd_graphcolors,20,"",""},
+{"help",0,(void*)sd_help,20,"",""},
+{"histfile",0,(void*)sd_histfile,20,"",""},
+{"histsize",0,(void*)sd_histsize,20,"",""},
+{"lines",0,(void*)sd_lines,20,"",""},
+{"linewrap",0,(void*)sd_linewrap,20,"",""},
+{"log",0,(void*)sd_log,20,"",""},
+{"logfile",0,(void*)sd_logfile,20,"",""},
+{"nbthreads",0,(void*)sd_nbthreads,20,"",""},
+{"new_galois_format",0,(void*)sd_new_galois_format,20,"",""},
+{"output",0,(void*)sd_output,20,"",""},
+{"parisize",0,(void*)sd_parisize,20,"",""},
+{"parisizemax",0,(void*)sd_parisizemax,20,"",""},
+{"path",0,(void*)sd_path,20,"",""},
+{"prettyprinter",0,(void*)sd_prettyprinter,20,"",""},
+{"primelimit",0,(void*)sd_primelimit,20,"",""},
+{"prompt",0,(void*)sd_prompt,20,"",""},
+{"prompt_cont",0,(void*)sd_prompt_cont,20,"",""},
+{"psfile",0,(void*)sd_psfile,20,"",""},
+{"readline",0,(void*)sd_readline,20,"",""},
+{"realbitprecision",0,(void*)sd_realbitprecision,20,"",""},
+{"realprecision",0,(void*)sd_realprecision,20,"",""},
+{"recover",0,(void*)sd_recover,20,"",""},
+{"secure",0,(void*)sd_secure,20,"",""},
+{"seriesprecision",0,(void*)sd_seriesprecision,20,"",""},
+{"simplify",0,(void*)sd_simplify,20,"",""},
+{"sopath",0,(void*)sd_sopath,20,"",""},
+{"strictargs",0,(void*)sd_strictargs,20,"",""},
+{"strictmatch",0,(void*)sd_strictmatch,20,"",""},
+{"threadsize",0,(void*)sd_threadsize,20,"",""},
+{"threadsizemax",0,(void*)sd_threadsizemax,20,"",""},
+{"timer",0,(void*)sd_timer,20,"",""},
 {NULL,0,NULL,0,NULL,NULL} /* sentinel */
 };
diff --git a/src/language/es.c b/src/language/es.c
index 8471f58..57862a8 100644
--- a/src/language/es.c
+++ b/src/language/es.c
@@ -48,7 +48,6 @@ typedef void (*OUT_FUN)(GEN, pariout_t *, outString *);
 static void bruti_sign(GEN g, pariout_t *T, outString *S, int addsign);
 static void matbruti(GEN g, pariout_t *T, outString *S);
 static void texi_sign(GEN g, pariout_t *T, outString *S, int addsign);
-static char *GENtostr_fun(GEN x, pariout_t *T, OUT_FUN out);
 
 static void bruti(GEN g, pariout_t *T, outString *S)
 { bruti_sign(g,T,S,1); }
@@ -340,6 +339,37 @@ gp_read_str_multiline(const char *s, char *last)
   return gp_read_from_input(&IM, 1, last);
 }
 
+void
+gp_embedded_init(long rsize, long vsize)
+{
+  pari_init(rsize, 500000);
+  paristack_setsize(rsize, vsize);
+}
+
+char *
+gp_embedded(const char *s)
+{
+  char last, *res;
+  struct gp_context state;
+  gp_context_save(&state);
+  pari_CATCH(CATCH_ALL)
+  {
+    GENbin* err = copy_bin(pari_err_last());
+    gp_context_restore(&state);
+    res = pari_err2str(bin_copy(err));
+  } pari_TRY {
+    GEN z = gp_read_str_multiline(s, &last);
+    ulong n;
+    pari_add_hist(z, 0);
+    n = pari_nb_hist();
+    parivstack_reset();
+    res = (z==gnil || last==';') ? stack_strdup(""):
+          stack_sprintf("%%%lu = %Ps", n, pari_get_hist(n));
+  } pari_ENDCATCH;
+  avma = pari_mainstack->top;
+  return res;
+}
+
 GEN
 gp_readvec_stream(FILE *fi)
 {
@@ -539,7 +569,7 @@ pari_putc(char c) { out_putc(pariOut, c); }
 
 void
 out_puts(PariOUT *out, const char *s) {
-  if (*s) {  set_last_newline(s[strlen(s)-1]); out->puts(s); }
+  if (*s) { set_last_newline(s[strlen(s)-1]); out->puts(s); }
 }
 void
 pari_puts(const char *s) { out_puts(pariOut, s); }
@@ -889,6 +919,29 @@ str_putscut(outString *S, const char *str, int cut)
   }
 }
 
+/* not stack clean */
+static char *
+stack_GENtostr_fun(GEN x, pariout_t *T, OUT_FUN out)
+{
+  outString S; str_init(&S, 1);
+  out(x, T, &S); *S.cur = 0;
+  return S.string;
+}
+/* same but remove quotes "" around t_STR */
+static char *
+stack_GENtostr_fun_unquoted(GEN x, pariout_t *T, OUT_FUN f)
+{ return (typ(x)==t_STR)? GSTR(x): stack_GENtostr_fun(x, T, f); }
+
+/* stack-clean: pari-malloc'ed */
+static char *
+GENtostr_fun(GEN x, pariout_t *T, OUT_FUN out)
+{
+  pari_sp av = avma;
+  outString S; str_init(&S, 0);
+  out(x, T, &S); *S.cur = 0;
+  avma = av; return S.string;
+}
+
 /* lbuf = strlen(buf), len < 0: unset */
 static void
 outpad(outString *S, const char *buf, long lbuf, int sign, long ljust, long len, long zpad)
@@ -1370,7 +1423,7 @@ nextch:
           case 's':
           {
             char *strvalue;
-            int tofree = 0;
+            pari_sp av = avma;
 
             if (arg_vector) {
               gvalue = v_get_arg(arg_vector, &index, save_fmt);
@@ -1384,19 +1437,9 @@ nextch:
                 strvalue = va_arg(args, char *);
               }
             }
-            if (gvalue)
-            {
-              if (typ(gvalue) == t_STR)
-                strvalue = GSTR(gvalue);
-              else
-              {
-                strvalue = GENtostr_fun(gvalue, GP_DATA->fmt, bruti);
-                tofree = 1;
-              }
-            }
+            if (gvalue) strvalue = GENtostr_unquoted(gvalue);
             fmtstr(S, strvalue, ljust, len, maxwidth);
-            if (tofree) pari_free(strvalue);
-            break;
+            avma = av; break;
           }
           case 'c':
             if (arg_vector) {
@@ -1805,37 +1848,18 @@ pari_strndup(const char *s, long n)
   memcpy(t,s,n); t[n] = 0; return t;
 }
 
-/* not stack clean */
-static char *
-GENtostr_aux(GEN x, pariout_t *T, OUT_FUN out, int use_stack) {
-  outString S;
-  str_init(&S, use_stack); out(x, T, &S); *S.cur = 0;
-  return S.string;
-}
-static char *
-GENtostr_fun(GEN x, pariout_t *T, OUT_FUN out)
-{
-  pari_sp av = avma;
-  char *s = GENtostr_aux(x, T, out, 0);
-  avma = av; return s;
-}
-
 /* returns a malloc-ed string, which should be freed after usage */
 /* Returns pari_malloc()ed string */
 char *
-GENtostr(GEN x) {
-  pariout_t *T = GP_DATA->fmt;
-  return GENtostr_fun(x, T, get_fun(T->prettyp));
-}
+GENtostr(GEN x)
+{ return GENtostr_fun(x, GP_DATA->fmt, get_fun(GP_DATA->fmt->prettyp)); }
 char *
 GENtoTeXstr(GEN x) { return GENtostr_fun(x, GP_DATA->fmt, &texi); }
-
-static char *
-GENtostr1(GEN x, OUT_FUN out)
-{
-  return (typ(x) == t_STR)? pari_strdup(GSTR(x))
-                          : GENtostr_fun(x, GP_DATA->fmt, out);
-}
+char *
+GENtostr_unquoted(GEN x)
+{ return stack_GENtostr_fun_unquoted(x, GP_DATA->fmt, &bruti); }
+char *
+GENtostr_raw(GEN x) { return stack_GENtostr_fun(x,GP_DATA->fmt,&bruti); }
 
 /* see print0(). Returns pari_malloc()ed string */
 static char *
@@ -1843,28 +1867,19 @@ RgV_to_str_fun(GEN g, OUT_FUN out) {
   pari_sp av = avma;
   char *t, *t2;
   long i, tlen = 0, l = lg(g);
-  GEN Ls, Ll;
-
-  /* frequent special case */
-  if (l == 2) return GENtostr1(gel(g,1), out);
-
-  Ls = cgetg(l, t_VEC);
-  Ll = cgetg(l, t_VECSMALL);
+  GEN Ls = cgetg(l, t_VEC);
+  GEN Ll = cgetg(l, t_VECSMALL);
+  pariout_t *fmt = GP_DATA->fmt;
   for (i = 1; i < l; i++)
   {
-    char *s = GENtostr1(gel(g,i), out);
+    char *s = stack_GENtostr_fun_unquoted(gel(g,i),fmt,out);
     gel(Ls,i) = (GEN)s;
     Ll[i] = strlen(s);
     tlen += Ll[i];
   }
   t2 = t = (char*)pari_malloc(tlen + 1);
   *t = 0;
-  for (i = 1; i < l; i++)
-  {
-    strcpy(t2, (char*)Ls[i]);
-    t2 += Ll[i];
-    pari_free((void*)Ls[i]);
-  }
+  for (i = 1; i < l; i++) { strcpy(t2, (char*)Ls[i]); t2 += Ll[i]; }
   avma = av; return t;
 }
 
@@ -1903,16 +1918,6 @@ GENtoGENstr_nospace(GEN x)
   z = strtoGENstr(s); pari_free(s); return z;
 }
 
-static char *
-GENtostr_fun_unquoted(GEN x, pariout_t *T, OUT_FUN f)
-{
-  if (typ(x)==t_STR) return GSTR(x); /* text surrounded by "" otherwise */
-  return GENtostr_aux(x, T, f, 1);
-}
-char *
-GENtostr_unquoted(GEN x)
-{ return GENtostr_fun_unquoted(x, GP_DATA->fmt, &bruti); }
-
 static char
 ltoc(long n) {
   if (n <= 0 || n > 255)
@@ -3291,17 +3296,15 @@ _initout(pariout_t *T, char f, long sigd, long sp)
 
 static void
 gen_output_fun(GEN x, pariout_t *T, OUT_FUN out)
-{
-  char *s = GENtostr_fun(x, T, out);
-  pari_puts(s); pari_free(s);
-}
+{ pari_sp av = avma; pari_puts( stack_GENtostr_fun(x,T,out) ); avma = av; }
 
 void
 fputGEN_pariout(GEN x, pariout_t *T, FILE *out)
 {
-  char *s = GENtostr_fun(x, T, get_fun(T->prettyp));
-  if (*s) set_last_newline(s[strlen(s)-1]);
-  fputs(s, out); pari_free(s);
+  pari_sp av = avma;
+  char *s = stack_GENtostr_fun(x, T, get_fun(T->prettyp));
+  if (*s) { set_last_newline(s[strlen(s)-1]); fputs(s, out); }
+  avma = av;
 }
 
 void
@@ -3310,21 +3313,18 @@ gen_output(GEN x, pariout_t *T)
   if (!T) T = GP_DATA->fmt;
   gen_output_fun(x, T, get_fun(T->prettyp));
 }
-
 void
 brute(GEN g, char f, long d)
 {
   pariout_t T; _initout(&T,f,d,0);
   gen_output_fun(g, &T, &bruti);
 }
-
 void
 matbrute(GEN g, char f, long d)
 {
   pariout_t T; _initout(&T,f,d,1);
   gen_output_fun(g, &T, &matbruti);
 }
-
 void
 texe(GEN g, char f, long d)
 {
@@ -3726,9 +3726,9 @@ pari_get_homedir(const char *user)
   {
     p = getpwnam(user);
     if (p) dir = p->pw_dir;
+    /* warn, but don't kill session on startup (when expanding path) */
+    if (!dir) pari_warn(warner,"can't expand ~%s", user? user: "");
   }
-  /* warn, but don't kill session on startup (when expanding path) */
-  if (!dir) pari_warn(warner,"can't expand ~%s", user? user: "");
   return dir;
 }
 #else
@@ -4318,7 +4318,7 @@ rdGEN(FILE *f)
   p->len  = L;
   p->x    = (GEN)rd_long(f);
   p->base = (GEN)rd_long(f);
-  p->canon= 1;
+  p->rebase = &shiftaddress_canon;
   pari_fread_longs(GENbinbase(p), L,f);
   return bin_copy(p);
 }
@@ -4527,40 +4527,27 @@ readbin(const char *name, FILE *f, int *vector)
 void
 out_print0(PariOUT *out, const char *sep, GEN g, long flag)
 {
-  pari_sp av0 = avma;
+  pari_sp av = avma;
   OUT_FUN f = get_fun(flag);
   long i, l = lg(g);
-  for (i = 1; i < l; i++)
+  for (i = 1; i < l; i++, avma = av)
   {
-    pari_sp av = avma;
-    GEN x = gel(g,i);
-    char *s = GENtostr_fun_unquoted(x, GP_DATA->fmt, f);
-    out_puts(out, s); avma = av;
+    out_puts(out, stack_GENtostr_fun_unquoted(gel(g,i), GP_DATA->fmt, f));
     if (sep && i+1 < l) out_puts(out, sep);
   }
-  avma = av0;
 }
-
 static void
 str_print0(outString *S, GEN g, long flag)
 {
+  pari_sp av = avma;
   OUT_FUN f = get_fun(flag);
   long i, l = lg(g);
-  for (i = 1; i < l; i++)
-  {
-    GEN x = gel(g,i);
-    if (typ(x)==t_STR)
-      str_puts(S, GSTR(x)); /* text surrounded by "" otherwise */
-    else
-    {
-      char *s = GENtostr_fun(x, GP_DATA->fmt, f);
-      str_puts(S, s); pari_free(s);
-    }
-  }
+  for (i = 1; i < l; i++, avma = av)
+    str_puts(S, stack_GENtostr_fun_unquoted(gel(g,i), GP_DATA->fmt, f));
+  *(S->cur) = 0;
 }
 
-/*Display s, followed by the element of g */
-
+/* display s, followed by the element of g */
 char *
 pari_sprint0(const char *s, GEN g, long flag)
 {
@@ -4568,8 +4555,9 @@ pari_sprint0(const char *s, GEN g, long flag)
   str_init(&S, 0);
   str_puts(&S, s);
   str_print0(&S, g, flag);
-  *S.cur = 0; return S.string;
+  return S.string;
 }
+
 static void
 print0_file(FILE *out, GEN g, long flag)
 {
@@ -4577,18 +4565,15 @@ print0_file(FILE *out, GEN g, long flag)
   outString S;
   str_init(&S, 1);
   str_print0(&S, g, flag);
-  *S.cur = 0;
   fputs(S.string, out);
   avma = av;
 }
 
 void
 print0(GEN g, long flag) { out_print0(pariOut, NULL, g, flag); }
-
 void
 printsep(const char *s, GEN g)
 { out_print0(pariOut, s, g, f_RAW); pari_putc('\n'); pari_flush(); }
-
 void
 printsep1(const char *s, GEN g) { out_print0(pariOut, s, g, f_RAW); }
 
diff --git a/src/language/eval.c b/src/language/eval.c
index ec6983a..edc5867 100644
--- a/src/language/eval.c
+++ b/src/language/eval.c
@@ -1699,10 +1699,18 @@ parfor(GEN a, GEN b, GEN code, void *E, long call(void*, GEN, GEN))
   GEN done, stop = NULL;
   struct pari_mt pt;
   if (typ(a) != t_INT) pari_err_TYPE("parfor",a);
-  if (b && gcmp(b,a) < 0) return;
-
+  if (b)
+  {
+    if (gcmp(b,a) < 0) return;
+    if (typ(b) == t_INFINITY)
+    {
+      if (inf_get_sign(b) < 0) return;
+      b = NULL;
+    }
+    else
+      b = gfloor(b);
+  }
   mt_queue_start(&pt, worker);
-  b = b ? gfloor(b): NULL;
   a = mkvec(setloop(a));
   av2 = avma;
   while ((running = (!stop && (!b || cmpii(gel(a,1),b) <= 0))) || pending)
@@ -2358,7 +2366,7 @@ gen_relink(GEN x, hashtable *table)
       if (lg(x)==8) gen_relink(closure_get_frame(x), table);
       break;
     case t_LIST:
-      gen_relink(list_data(x), table);
+      if (list_data(x)) gen_relink(list_data(x), table);
       break;
     case t_VEC: case t_COL: case t_MAT: case t_ERROR:
       lx = lg(x);
@@ -2400,7 +2408,7 @@ gen_unlink(GEN x)
       if (lg(x)==8) gen_unlink(closure_get_frame(x));
       break;
     case t_LIST:
-      gen_unlink(list_data(x));
+      if (list_data(x)) gen_unlink(list_data(x));
       break;
     case t_VEC: case t_COL: case t_MAT: case t_ERROR:
       lx = lg(x);
diff --git a/src/language/gplib.c b/src/language/gplib.c
index 041e3b6..ad54c10 100644
--- a/src/language/gplib.c
+++ b/src/language/gplib.c
@@ -164,7 +164,7 @@ print_fun_list(char **list, long nbli)
   if (i) pari_putc('\n');
 }
 
-static const long MAX_SECTION = 14;
+static const long MAX_SECTION = 15;
 static void
 commands(long n)
 {
@@ -271,15 +271,16 @@ menu_commands(void)
   4: NUMBER THEORETICAL functions\n\
   5: Functions related to ELLIPTIC CURVES\n\
   6: Functions related to L-FUNCTIONS\n\
-  7: Functions related to MODULAR FORMS and MODULAR SYMBOLS\n\
-  8: Functions related to general NUMBER FIELDS\n\
-  9: Functions related to associative ALGEBRAS\n\
- 10: POLYNOMIALS and power series\n\
- 11: Vectors, matrices, LINEAR ALGEBRA and sets\n\
- 12: SUMS, products, integrals and similar functions\n\
- 13: GRAPHIC functions\n\
- 14: PROGRAMMING under GP\n\
- 15: The PARI community\n\
+  7: Functions related to MODULAR FORMS\n\
+  8: Functions related to MODULAR SYMBOLS\n\
+  9: Functions related to general NUMBER FIELDS\n\
+ 10: Functions related to associative ALGEBRAS\n\
+ 11: POLYNOMIALS and power series\n\
+ 12: Vectors, matrices, LINEAR ALGEBRA and sets\n\
+ 13: SUMS, products, integrals and similar functions\n\
+ 14: GRAPHIC functions\n\
+ 15: PROGRAMMING under GP\n\
+ 16: The PARI community\n\
 Also:\n\
   ? functionname (short on-line help)\n\
   ?\\             (keyboard shortcuts)\n\
@@ -360,7 +361,7 @@ reg  : regulator                                          bnf,bnr\n\
 roots: roots                                       ell,nf,bnf,bnr,    gal\n\
 sign,r1,r2 : signature                                 nf,bnf,bnr\n\
 t2   : t2 matrix                                       nf,bnf,bnr\n\
-tate : Tate's [u^2, u, q, [a,b]]                   ell\n\
+tate : Tate's [u^2, u, q, [a,b], L]                ell\n\
 tu   : torsion unit and its order                         bnf,bnr\n\
 zk   : integral basis                                  nf,bnf,bnr,rnf\n\
 zkst : structure of (Z_K/m)*         bid,                     bnr\n");
@@ -990,18 +991,21 @@ gp_load_gprc(void)
 /*                             PROMPTS                              */
 /*                                                                  */
 /********************************************************************/
-#ifndef _WIN32
 /* if prompt is coloured, tell readline to ignore the ANSI escape sequences */
 /* s must be able to store 14 chars (including final \0) */
 #ifdef READLINE
 static void
 readline_prompt_color(char *s, int c)
 {
+#ifdef _WIN32
+  (void)s; (void)c;
+#else
   *s++ = '\001'; /*RL_PROMPT_START_IGNORE*/
   term_get_color(s, c);
   s += strlen(s);
   *s++ = '\002'; /*RL_PROMPT_END_IGNORE*/
   *s = 0;
+#endif
 }
 #endif
 /* s must be able to store 14 chars (including final \0) */
@@ -1031,10 +1035,6 @@ color_prompt(const char *prompt)
   brace_color(s, c_INPUT, 1);
   return t;
 }
-#else
-static const char *
-color_prompt(const char *prompt) { return stack_strdup(prompt); }
-#endif
 
 const char *
 gp_format_prompt(const char *prompt)
diff --git a/src/language/hash.c b/src/language/hash.c
index b6b09aa..b9736ba 100644
--- a/src/language/hash.c
+++ b/src/language/hash.c
@@ -44,12 +44,14 @@ get_prime_index(ulong len)
 
 /* link hashentry e to hashtable h, setting e->hash / e->next */
 INLINE void
-hash_link(hashtable *h, hashentry *e)
+hash_link2(hashtable *h, hashentry *e, ulong hash)
 {
   ulong index;
-  e->hash = h->hash(e->key); index = e->hash % h->len;
+  e->hash = hash; index = e->hash % h->len;
   e->next = h->table[index]; h->table[index] = e;
 }
+INLINE void
+hash_link(hashtable *h, hashentry *e) { hash_link2(h,e,h->hash(e->key));}
 
 hashtable *
 hash_create(ulong minsize, ulong (*hash)(void*), int (*eq)(void*,void*),
@@ -79,7 +81,7 @@ hash_create(ulong minsize, ulong (*hash)(void*), int (*eq)(void*,void*),
 }
 
 void
-hash_insert(hashtable *h, void *k, void *v)
+hash_insert2(hashtable *h, void *k, void *v, ulong hash)
 {
   hashentry *e;
   ulong index;
@@ -110,8 +112,11 @@ hash_insert(hashtable *h, void *k, void *v)
     setlen(h, newlen);
   }
   e->key = k;
-  e->val = v; hash_link(h, e);
+  e->val = v; hash_link2(h, e, hash);
 }
+void
+hash_insert(hashtable *h, void *k, void *v)
+{ hash_insert2(h,k,v,h->hash(k)); }
 
 /* the key 'k' may correspond to different values in the hash, return
  * one satisfying the selection callback */
@@ -266,7 +271,7 @@ hashstr_dbg(hashtable *h)
 /********************************************************************/
 
 INLINE ulong
-glue(ulong h, ulong a) { return (h << 5) + (h>>2) + a; }
+glue(ulong h, ulong a) { return 404936533*h + a; }
 ulong
 hash_GEN(GEN x)
 {
diff --git a/src/language/init.c b/src/language/init.c
index be565a5..0e6e67f 100644
--- a/src/language/init.c
+++ b/src/language/init.c
@@ -242,7 +242,8 @@ gunclone_deep(GEN x)
     case t_LIST:
       v = list_data(x); lx = v? lg(v): 1;
       for (i=1;i<lx;i++) gunclone_deep(gel(v,i));
-      pari_free(v); break;
+      if (v) killblock(v);
+      break;
   }
   if (isclone(x)) gunclone(x);
   BLOCK_SIGINT_END;
@@ -1294,6 +1295,15 @@ type_dim(GEN x)
   return v;
 }
 
+static char *
+gdisplay(GEN x)
+{
+  char *s = GENtostr_raw(x);
+  if (strlen(s) < 1600) return s;
+  if (! GP_DATA->breakloop) return (char*)"(...)";
+  return stack_sprintf("\n  ***  (...) Huge %s omitted; you can access it via dbg_err()", type_name(typ(x)));
+}
+
 char *
 pari_err2str(GEN e)
 {
@@ -1312,8 +1322,8 @@ pari_err2str(GEN e)
   case e_CONSTPOL:
     return pari_sprintf("constant polynomial in %Ps.", gel(e,2));
   case e_COPRIME:
-    return pari_sprintf("elements not coprime in %Ps:\n    %Ps\n    %Ps",
-                        gel(e,2), gel(e,3), gel(e,4));
+    return pari_sprintf("elements not coprime in %Ps:\n    %s\n    %s",
+                        gel(e,2), gdisplay(gel(e,3)), gdisplay(gel(e,4)));
   case e_DIM:
     return pari_sprintf("inconsistent dimensions in %Ps.", gel(e,2));
   case e_FILE:
@@ -1325,10 +1335,11 @@ pari_err2str(GEN e)
   case e_PACKAGE:
     return pari_sprintf("package %Ps is required, please install it.", gel(e,2));
   case e_INV:
-    return pari_sprintf("impossible inverse in %Ps: %Ps.", gel(e,2), gel(e,3));
+    return pari_sprintf("impossible inverse in %Ps: %s.", gel(e,2),
+                        gdisplay(gel(e,3)));
   case e_IRREDPOL:
-    return pari_sprintf("not an irreducible polynomial in %Ps: %Ps.",
-                        gel(e,2), gel(e,3));
+    return pari_sprintf("not an irreducible polynomial in %Ps: %s.",
+                        gel(e,2), gdisplay(gel(e,3)));
   case e_MAXPRIME:
     {
       const char * msg = "not enough precomputed primes";
@@ -1341,8 +1352,8 @@ pari_err2str(GEN e)
   case e_MODULUS:
     {
       GEN x = gel(e,3), y = gel(e,4);
-      return pari_sprintf("inconsistent moduli in %Ps: %Ps != %Ps",
-                          gel(e,2), x, y);
+      return pari_sprintf("inconsistent moduli in %Ps: %s != %s",
+                          gel(e,2), gdisplay(x), gdisplay(y));
     }
   case e_NONE: return NULL;
   case e_NOTFUNC:
@@ -1399,13 +1410,13 @@ pari_err2str(GEN e)
   case e_PREC:
     return pari_sprintf("precision too low in %Ps.", gel(e,2));
   case e_PRIME:
-    return pari_sprintf("not a prime number in %Ps: %Ps.",
-                        gel(e,2), gel(e,3));
+    return pari_sprintf("not a prime number in %Ps: %s.",
+                        gel(e,2), gdisplay(gel(e,3)));
   case e_ROOTS0:
     return pari_sprintf("zero polynomial in %Ps.", gel(e,2));
   case e_SQRTN:
-    return pari_sprintf("not an n-th power residue in %Ps: %Ps.",
-                        gel(e,2), gel(e,3));
+    return pari_sprintf("not an n-th power residue in %Ps: %s.",
+                        gel(e,2), gdisplay(gel(e,3)));
   case e_STACK:
   case e_STACKTHREAD:
     {
@@ -1635,7 +1646,7 @@ list_internal_copy(GEN z, long nmax)
   GEN a;
   if (!z) return NULL;
   l = lg(z);
-  a = (GEN)pari_malloc((nmax+1) * sizeof(long));
+  a = newblock(nmax+1);
   for (i = 1; i < l; i++) gel(a,i) = gel(z,i)? gclone(gel(z,i)): gen_0;
   a[0] = z[0]; return a;
 }
@@ -1786,7 +1797,7 @@ icopy_avma_canon(GEN x, pari_sp AVMA)
   return y;
 }
 
-/* [copy_bin_canon/bin_copy_canon:] same as gcopy_av0, but copy integers in
+/* [copy_bin_canon:] same as gcopy_av0, but copy integers in
  * canonical (native kernel) form and make a full copy of t_LISTs */
 static GEN
 gcopy_av0_canon(GEN x, pari_sp *AVMA)
@@ -1825,9 +1836,10 @@ gcopy_av0_canon(GEN x, pari_sp *AVMA)
   return y;
 }
 
-/* [copy_bin/bin_copy:] size (number of words) required for gcopy_av0(x) */
+/* [copy_bin/bin_copy:] size (number of words) required for
+ * gcopy_av0_canon(x) */
 static long
-taille0(GEN x)
+taille0_canon(GEN x)
 {
   long i,n,lx, tx = typ(x);
   switch(tx)
@@ -1841,17 +1853,17 @@ taille0(GEN x)
     case t_LIST:
     {
       GEN L = list_data(x);
-      return L? 3 + taille0(L): 3;
+      return L? 3 + taille0_canon(L): 3;
     }
   }
   n = lx = lg(x);
-  for (i=lontyp[tx]; i<lx; i++) n += taille0(gel(x,i));
+  for (i=lontyp[tx]; i<lx; i++) n += taille0_canon(gel(x,i));
   return n;
 }
 
 /* [copy_bin/bin_copy:] size (number of words) required for gcopy_av0(x) */
 static long
-taille0_nolist(GEN x)
+taille0(GEN x)
 {
   long i,n,lx, tx = typ(x);
   switch(tx)
@@ -1871,7 +1883,7 @@ taille0_nolist(GEN x)
       return lg(x);
   }
   n = lx = lg(x);
-  for (i=lontyp[tx]; i<lx; i++) n += taille0_nolist(gel(x,i));
+  for (i=lontyp[tx]; i<lx; i++) n += taille0(gel(x,i));
   return n;
 }
 
@@ -1912,10 +1924,10 @@ gsizebyte(GEN x) { return gsizeword(x) * sizeof(long); }
 GENbin*
 copy_bin(GEN x)
 {
-  long t = taille0_nolist(x);
+  long t = taille0(x);
   GENbin *p = (GENbin*)pari_malloc(sizeof(GENbin) + t*sizeof(long));
   pari_sp AVMA = (pari_sp)(GENbinbase(p) + t);
-  p->canon = 0;
+  p->rebase = &shiftaddress;
   p->len = t;
   p->x   = gcopy_av0(x, &AVMA);
   p->base= (GEN)AVMA; return p;
@@ -1925,10 +1937,10 @@ copy_bin(GEN x)
 GENbin*
 copy_bin_canon(GEN x)
 {
-  long t = taille0(x);
+  long t = taille0_canon(x);
   GENbin *p = (GENbin*)pari_malloc(sizeof(GENbin) + t*sizeof(long));
   pari_sp AVMA = (pari_sp)(GENbinbase(p) + t);
-  p->canon = 1;
+  p->rebase = &shiftaddress_canon;
   p->len = t;
   p->x   = gcopy_av0_canon(x, &AVMA);
   p->base= (GEN)AVMA; return p;
diff --git a/src/language/init.h b/src/language/init.h
index 64e38e5..cb2dc25 100644
--- a/src/language/init.h
+++ b/src/language/init.h
@@ -2,12 +2,12 @@
 /* See src/desc/gen_proto */
 /* Do not edit*/
 entree functions_basic[]={
-{"!_",0,(void*)gnot,16,"G","!_"},
-{"#_",0,(void*)glength,16,"lG","#x: number of non code words in x, number of characters for a string."},
-{"%",0,(void*)pari_get_hist,16,"D0,L,","last history item."},
-{"%#",0,(void*)pari_get_histtime,16,"lD0,L,","time to compute last history item."},
-{"+_",0,NULL,16,NULL,"+_"},
-{"-_",0,(void*)gneg,16,"G","-_"},
+{"!_",0,(void*)gnot,17,"G","!_"},
+{"#_",0,(void*)glength,17,"lG","#x: number of non code words in x, number of characters for a string."},
+{"%",0,(void*)pari_get_hist,17,"D0,L,","last history item."},
+{"%#",0,(void*)pari_get_histtime,17,"lD0,L,","time to compute last history item."},
+{"+_",0,NULL,17,NULL,"+_"},
+{"-_",0,(void*)gneg,17,"G","-_"},
 {"Catalan",0,(void*)mpcatalan,3,"p","Catalan=Catalan(): Catalan's number with current precision."},
 {"Col",0,(void*)gtocol0,2,"GD0,L,","Col(x, {n}): transforms the object x into a column vector of dimension n."},
 {"Colrev",0,(void*)gtocolrev0,2,"GD0,L,","Colrev(x, {n}): transforms the object x into a column vector of dimension n in reverse order with respect to Col(x, {n}). Empty vector if x is omitted."},
@@ -17,8 +17,8 @@ entree functions_basic[]={
 {"Map",0,(void*)gtomap,2,"DG","Map({x}): converts the matrix [a_1,b_1;a_2,b_2;...;a_n,b_n] to the map a_i->b_i"},
 {"Mat",0,(void*)gtomat,2,"DG","Mat({x=[]}): transforms any GEN x into a matrix. Empty matrix if x is omitted."},
 {"Mod",0,(void*)gmodulo,2,"GG","Mod(a,b): creates 'a modulo b'."},
-{"O",0,(void*)ggrando,10,"","O(p^e): p-adic or power series zero with precision given by e"},
-{"O(_^_)",0,(void*)ggrando,18,"GD1,L,","O(p^e): p-adic or power series zero with precision given by e."},
+{"O",0,(void*)ggrando,11,"","O(p^e): p-adic or power series zero with precision given by e"},
+{"O(_^_)",0,(void*)ggrando,19,"GD1,L,","O(p^e): p-adic or power series zero with precision given by e."},
 {"Pi",0,(void*)mppi,3,"p","Pi=Pi(): the constant pi, with current precision."},
 {"Pol",0,(void*)gtopoly,2,"GDn","Pol(t,{v='x}): convert t (usually a vector or a power series) into a polynomial with variable v, starting with the leading coefficient."},
 {"Polrev",0,(void*)gtopolyrev,2,"GDn","Polrev(t,{v='x}): convert t (usually a vector or a power series) into a polynomial with variable v, starting with the constant term."},
@@ -28,185 +28,186 @@ entree functions_basic[]={
 {"Str",0,(void*)Str,2,"s*","Str({x}*): concatenates its (string) argument into a single string."},
 {"Strchr",0,(void*)Strchr,2,"G","Strchr(x): converts x to a string, translating each integer into a character."},
 {"Strexpand",0,(void*)Strexpand,2,"s*","Strexpand({x}*): concatenates its (string) argument into a single string, performing tilde expansion."},
-{"Strprintf",0,(void*)Strprintf,14,"ss*","Strprintf(fmt,{x}*): returns a string built from the remaining arguments according to the format fmt."},
+{"Strprintf",0,(void*)Strprintf,15,"ss*","Strprintf(fmt,{x}*): returns a string built from the remaining arguments according to the format fmt."},
 {"Strtex",0,(void*)Strtex,2,"s*","Strtex({x}*): translates its (string) arguments to TeX format and returns the resulting string."},
 {"Vec",0,(void*)gtovec0,2,"GD0,L,","Vec(x, {n}): transforms the object x into a vector of dimension n."},
 {"Vecrev",0,(void*)gtovecrev0,2,"GD0,L,","Vecrev(x, {n}): transforms the object x into a vector of dimension n in reverse order with respect to Vec(x, {n}). Empty vector if x is omitted."},
 {"Vecsmall",0,(void*)gtovecsmall0,2,"GD0,L,","Vecsmall(x, {n}): transforms the object x into a VECSMALL of dimension n."},
-{"[_.._]",0,(void*)vecrange,18,"GG","[a..b] = [a,a+1,...,b]"},
-{"[_|_<-_,_;_]",0,(void*)vecexpr1,18,"mGVDEDE","[a(x)|x<-b,c(x);...]"},
-{"[_|_<-_,_]",0,(void*)vecexpr0,18,"GVDEDE","[a(x)|x<-b,c(x)] = apply(a,select(c,b))"},
-{"_!",0,(void*)mpfact,16,"L","n!: factorial of n."},
-{"_!=_",0,(void*)gne,16,"GG","_!=_"},
-{"_%=_",0,(void*)gmode,16,"&G","x%=y: shortcut for x=x%y."},
-{"_%_",0,(void*)gmod,16,"GG","x%y: Euclidean remainder of x and y."},
-{"_&&_",0,(void*)andpari,16,"GE","_&&_"},
-{"_'",0,(void*)deriv,16,"GDn","x': derivative of x with respect to the main variable."},
-{"_*=_",0,(void*)gmule,16,"&G","x*=y: shortcut for x=x*y."},
-{"_*_",0,(void*)gmul,16,"GG","x*y: product of x and y."},
-{"_++",0,(void*)gadd1e,16,"&","x++"},
-{"_+=_",0,(void*)gadde,16,"&G","x+=y: shortcut for x=x+y."},
-{"_+_",0,(void*)gadd,16,"GG","x+y: sum of x and y."},
-{"_--",0,(void*)gsub1e,16,"&","x--"},
-{"_-=_",0,(void*)gsube,16,"&G","x-=y: shortcut for x=x-y."},
-{"_-_",0,(void*)gsub,16,"GG","x-y: difference of x and y."},
-{"_.a1",0,(void*)member_a1,17,"mG","_.a1"},
-{"_.a2",0,(void*)member_a2,17,"mG","_.a2"},
-{"_.a3",0,(void*)member_a3,17,"mG","_.a3"},
-{"_.a4",0,(void*)member_a4,17,"mG","_.a4"},
-{"_.a6",0,(void*)member_a6,17,"mG","_.a6"},
-{"_.area",0,(void*)member_area,17,"mG","_.area"},
-{"_.b2",0,(void*)member_b2,17,"mG","_.b2"},
-{"_.b4",0,(void*)member_b4,17,"mG","_.b4"},
-{"_.b6",0,(void*)member_b6,17,"mG","_.b6"},
-{"_.b8",0,(void*)member_b8,17,"mG","_.b8"},
-{"_.bid",0,(void*)member_bid,17,"mG","_.bid"},
-{"_.bnf",0,(void*)member_bnf,17,"mG","_.bnf"},
-{"_.c4",0,(void*)member_c4,17,"mG","_.c4"},
-{"_.c6",0,(void*)member_c6,17,"mG","_.c6"},
-{"_.clgp",0,(void*)member_clgp,17,"mG","_.clgp"},
-{"_.codiff",0,(void*)member_codiff,17,"mG","_.codiff"},
-{"_.cyc",0,(void*)member_cyc,17,"mG","_.cyc"},
-{"_.diff",0,(void*)member_diff,17,"mG","_.diff"},
-{"_.disc",0,(void*)member_disc,17,"mG","_.disc"},
-{"_.e",0,(void*)member_e,17,"mG","_.e"},
-{"_.eta",0,(void*)member_eta,17,"mG","_.eta"},
-{"_.f",0,(void*)member_f,17,"mG","_.f"},
-{"_.fu",0,(void*)member_fu,17,"G","_.fu"},
-{"_.futu",0,(void*)member_futu,17,"mG","_.futu"},
-{"_.gen",0,(void*)member_gen,17,"mG","_.gen"},
-{"_.group",0,(void*)member_group,17,"mG","_.group"},
-{"_.index",0,(void*)member_index,17,"mG","_.index"},
-{"_.j",0,(void*)member_j,17,"mG","_.j"},
-{"_.mod",0,(void*)member_mod,17,"mG","_.mod"},
-{"_.nf",0,(void*)member_nf,17,"mG","_.nf"},
-{"_.no",0,(void*)member_no,17,"mG","_.no"},
-{"_.omega",0,(void*)member_omega,17,"mG","_.omega"},
-{"_.orders",0,(void*)member_orders,17,"mG","_.orders"},
-{"_.p",0,(void*)member_p,17,"mG","_.p"},
-{"_.pol",0,(void*)member_pol,17,"mG","_.pol"},
-{"_.polabs",0,(void*)member_polabs,17,"mG","_.polabs"},
-{"_.r1",0,(void*)member_r1,17,"mG","_.r1"},
-{"_.r2",0,(void*)member_r2,17,"mG","_.r2"},
-{"_.reg",0,(void*)member_reg,17,"mG","_.reg"},
-{"_.roots",0,(void*)member_roots,17,"mG","_.roots"},
-{"_.sign",0,(void*)member_sign,17,"mG","_.sign"},
-{"_.t2",0,(void*)member_t2,17,"G","_.t2"},
-{"_.tate",0,(void*)member_tate,17,"mG","_.tate"},
-{"_.tu",0,(void*)member_tu,17,"G","_.tu"},
-{"_.tufu",0,(void*)member_tufu,17,"mG","_.tufu"},
-{"_.zk",0,(void*)member_zk,17,"mG","_.zk"},
-{"_.zkst",0,(void*)member_zkst,17,"mG","_.zkst"},
-{"_/=_",0,(void*)gdive,16,"&G","x/=y: shortcut for x=x/y."},
-{"_/_",0,(void*)gdiv,16,"GG","x/y: quotient of x and y."},
-{"_<<=_",0,(void*)gshiftle,16,"&L","x<<=y: shortcut for x=x<<y."},
-{"_<<_",0,(void*)gshift,16,"GL","x<<y"},
-{"_<=_",0,(void*)gle,16,"GG","x<=y: return 1 if x is less or equal to y, 0 otherwise."},
-{"_<_",0,(void*)glt,16,"GG","x<y: return 1 if x is strictly less than y, 0 otherwise."},
-{"_===_",0,(void*)gidentical,16,"iGG","a === b : true if a and b are identical"},
-{"_==_",0,(void*)geq,16,"GG","_==_"},
-{"_>=_",0,(void*)gge,16,"GG","x>=y: return 1 if x is greater or equal to y, 0 otherwise."},
-{"_>>=_",0,(void*)gshiftre,16,"&L","x>>=y: shortcut for x=x>>y."},
-{"_>>_",0,(void*)gshift_right,16,"GL","x>>y"},
-{"_>_",0,(void*)ggt,16,"GG","x>y: return 1 if x is strictly greater than y, 0 otherwise."},
-{"_[_.._,_.._]",0,(void*)matslice0,16,"GD0,L,D0,L,D0,L,D0,L,","x[a..b,c..d] = [x[a,c],  x[a+1,c],  ...,x[b,c];                      x[a,c+1],x[a+1,c+1],...,x[b,c+1];                        ...       ...          ...                      x[a,d],  x[a+1,d]  ,...,x[b,d]]"},
-{"_[_.._]",0,(void*)vecslice0,16,"GD0,L,L","x[a..b] = [x[a],x[a+1],...,x[b]]"},
-{"_\\/=_",0,(void*)gdivrounde,16,"&G","x\\/=y: shortcut for x=x\\/y."},
-{"_\\/_",0,(void*)gdivround,16,"GG","x\\/y: rounded Euclidean quotient of x and y."},
-{"_\\=_",0,(void*)gdivente,16,"&G","x\\=y: shortcut for x=x\\y."},
-{"_\\_",0,(void*)gdivent,16,"GG","x\\y: Euclidean quotient of x and y."},
-{"_^_",0,(void*)gpow,16,"GGp","x^y: compute x to the power y."},
-{"_^s",0,(void*)gpowgs,18,"GL","return x^n where n is a small integer"},
-{"__",0,NULL,16,NULL,"__"},
-{"_derivfun",0,(void*)derivfun0,18,"GGp","_derivfun(closure,[args]) numerical derivation of closure with respect to the first variable at (args)."},
-{"_ellsea",0,(void*)ellsea,18,"GDGD1,L,","ellsea(E,{p},{s})"},
-{"_eval_mnemonic",0,(void*)eval_mnemonic,18,"lGs","Convert a mnemonic string to a flag."},
-{"_factor_Aurifeuille",0,(void*)factor_Aurifeuille,18,"GL","_factor_Aurifeuille(a,d): return an algebraic factor of Phi_d(a), a != 0"},
-{"_factor_Aurifeuille_prime",0,(void*)factor_Aurifeuille_prime,18,"GL","_factor_Aurifeuille_prime(p,d): return an algebraic factor of Phi_d(p), p prime"},
-{"_multi_if",0,(void*)ifpari_multi,18,"GE*","internal variant of if() that allows more than 3 arguments."},
-{"_parapply_worker",0,(void*)parapply_worker,18,"GG","_parapply_worker(d,C): evaluate the closure C on d."},
-{"_pareval_worker",0,(void*)pareval_worker,18,"G","_pareval_worker(C): evaluate the closure C."},
-{"_parfor_worker",0,(void*)parfor_worker,18,"GG","_parfor_worker(i,C): evaluate the closure C on i and return [i,C(i)]"},
-{"_parvector_worker",0,(void*)parvector_worker,18,"GG","_parvector_worker(i,C): evaluate the closure C on i."},
-{"_polint_worker",0,(void*)nmV_polint_center_tree_worker,18,"GGGGG","used for parallel chinese"},
-{"_polmodular_worker",0,(void*)polmodular_worker,18,"UUUGGGGGLGG","used by polmodular"},
-{"_void_if",0,(void*)ifpari_void,18,"vGDIDI","internal variant of if() that does not return a value."},
-{"_||_",0,(void*)orpari,16,"GE","x||y: inclusive OR."},
-{"_~",0,(void*)gtrans,16,"G","x~: transpose of x."},
+{"[_.._]",0,(void*)vecrange,19,"GG","[a..b] = [a,a+1,...,b]"},
+{"[_|_<-_,_;_]",0,(void*)vecexpr1,19,"mGVDEDE","[a(x)|x<-b,c(x);...]"},
+{"[_|_<-_,_]",0,(void*)vecexpr0,19,"GVDEDE","[a(x)|x<-b,c(x)] = apply(a,select(c,b))"},
+{"_!",0,(void*)mpfact,17,"L","n!: factorial of n."},
+{"_!=_",0,(void*)gne,17,"GG","_!=_"},
+{"_%=_",0,(void*)gmode,17,"&G","x%=y: shortcut for x=x%y."},
+{"_%_",0,(void*)gmod,17,"GG","x%y: Euclidean remainder of x and y."},
+{"_&&_",0,(void*)andpari,17,"GE","_&&_"},
+{"_'",0,(void*)deriv,17,"GDn","x': derivative of x with respect to the main variable."},
+{"_*=_",0,(void*)gmule,17,"&G","x*=y: shortcut for x=x*y."},
+{"_*_",0,(void*)gmul,17,"GG","x*y: product of x and y."},
+{"_++",0,(void*)gadd1e,17,"&","x++"},
+{"_+=_",0,(void*)gadde,17,"&G","x+=y: shortcut for x=x+y."},
+{"_+_",0,(void*)gadd,17,"GG","x+y: sum of x and y."},
+{"_--",0,(void*)gsub1e,17,"&","x--"},
+{"_-=_",0,(void*)gsube,17,"&G","x-=y: shortcut for x=x-y."},
+{"_-_",0,(void*)gsub,17,"GG","x-y: difference of x and y."},
+{"_.a1",0,(void*)member_a1,18,"mG","_.a1"},
+{"_.a2",0,(void*)member_a2,18,"mG","_.a2"},
+{"_.a3",0,(void*)member_a3,18,"mG","_.a3"},
+{"_.a4",0,(void*)member_a4,18,"mG","_.a4"},
+{"_.a6",0,(void*)member_a6,18,"mG","_.a6"},
+{"_.area",0,(void*)member_area,18,"mG","_.area"},
+{"_.b2",0,(void*)member_b2,18,"mG","_.b2"},
+{"_.b4",0,(void*)member_b4,18,"mG","_.b4"},
+{"_.b6",0,(void*)member_b6,18,"mG","_.b6"},
+{"_.b8",0,(void*)member_b8,18,"mG","_.b8"},
+{"_.bid",0,(void*)member_bid,18,"mG","_.bid"},
+{"_.bnf",0,(void*)member_bnf,18,"mG","_.bnf"},
+{"_.c4",0,(void*)member_c4,18,"mG","_.c4"},
+{"_.c6",0,(void*)member_c6,18,"mG","_.c6"},
+{"_.clgp",0,(void*)member_clgp,18,"mG","_.clgp"},
+{"_.codiff",0,(void*)member_codiff,18,"mG","_.codiff"},
+{"_.cyc",0,(void*)member_cyc,18,"mG","_.cyc"},
+{"_.diff",0,(void*)member_diff,18,"mG","_.diff"},
+{"_.disc",0,(void*)member_disc,18,"mG","_.disc"},
+{"_.e",0,(void*)member_e,18,"mG","_.e"},
+{"_.eta",0,(void*)member_eta,18,"mG","_.eta"},
+{"_.f",0,(void*)member_f,18,"mG","_.f"},
+{"_.fu",0,(void*)member_fu,18,"G","_.fu"},
+{"_.futu",0,(void*)member_futu,18,"mG","_.futu"},
+{"_.gen",0,(void*)member_gen,18,"mG","_.gen"},
+{"_.group",0,(void*)member_group,18,"mG","_.group"},
+{"_.index",0,(void*)member_index,18,"mG","_.index"},
+{"_.j",0,(void*)member_j,18,"mG","_.j"},
+{"_.mod",0,(void*)member_mod,18,"mG","_.mod"},
+{"_.nf",0,(void*)member_nf,18,"mG","_.nf"},
+{"_.no",0,(void*)member_no,18,"mG","_.no"},
+{"_.omega",0,(void*)member_omega,18,"mG","_.omega"},
+{"_.orders",0,(void*)member_orders,18,"mG","_.orders"},
+{"_.p",0,(void*)member_p,18,"mG","_.p"},
+{"_.pol",0,(void*)member_pol,18,"mG","_.pol"},
+{"_.polabs",0,(void*)member_polabs,18,"mG","_.polabs"},
+{"_.r1",0,(void*)member_r1,18,"mG","_.r1"},
+{"_.r2",0,(void*)member_r2,18,"mG","_.r2"},
+{"_.reg",0,(void*)member_reg,18,"mG","_.reg"},
+{"_.roots",0,(void*)member_roots,18,"mG","_.roots"},
+{"_.sign",0,(void*)member_sign,18,"mG","_.sign"},
+{"_.t2",0,(void*)member_t2,18,"G","_.t2"},
+{"_.tate",0,(void*)member_tate,18,"mG","_.tate"},
+{"_.tu",0,(void*)member_tu,18,"G","_.tu"},
+{"_.tufu",0,(void*)member_tufu,18,"mG","_.tufu"},
+{"_.zk",0,(void*)member_zk,18,"mG","_.zk"},
+{"_.zkst",0,(void*)member_zkst,18,"mG","_.zkst"},
+{"_/=_",0,(void*)gdive,17,"&G","x/=y: shortcut for x=x/y."},
+{"_/_",0,(void*)gdiv,17,"GG","x/y: quotient of x and y."},
+{"_<<=_",0,(void*)gshiftle,17,"&L","x<<=y: shortcut for x=x<<y."},
+{"_<<_",0,(void*)gshift,17,"GL","x<<y"},
+{"_<=_",0,(void*)gle,17,"GG","x<=y: return 1 if x is less or equal to y, 0 otherwise."},
+{"_<_",0,(void*)glt,17,"GG","x<y: return 1 if x is strictly less than y, 0 otherwise."},
+{"_===_",0,(void*)gidentical,17,"iGG","a === b : true if a and b are identical"},
+{"_==_",0,(void*)geq,17,"GG","_==_"},
+{"_>=_",0,(void*)gge,17,"GG","x>=y: return 1 if x is greater or equal to y, 0 otherwise."},
+{"_>>=_",0,(void*)gshiftre,17,"&L","x>>=y: shortcut for x=x>>y."},
+{"_>>_",0,(void*)gshift_right,17,"GL","x>>y"},
+{"_>_",0,(void*)ggt,17,"GG","x>y: return 1 if x is strictly greater than y, 0 otherwise."},
+{"_ZX_resultant_worker",0,(void*)ZX_resultant_worker,19,"GGGG","worker for ZX_resultant"},
+{"_[_.._,_.._]",0,(void*)matslice0,17,"GD0,L,D0,L,D0,L,D0,L,","x[a..b,c..d] = [x[a,c],  x[a+1,c],  ...,x[b,c];                      x[a,c+1],x[a+1,c+1],...,x[b,c+1];                        ...       ...          ...                      x[a,d],  x[a+1,d]  ,...,x[b,d]]"},
+{"_[_.._]",0,(void*)vecslice0,17,"GD0,L,L","x[a..b] = [x[a],x[a+1],...,x[b]]"},
+{"_\\/=_",0,(void*)gdivrounde,17,"&G","x\\/=y: shortcut for x=x\\/y."},
+{"_\\/_",0,(void*)gdivround,17,"GG","x\\/y: rounded Euclidean quotient of x and y."},
+{"_\\=_",0,(void*)gdivente,17,"&G","x\\=y: shortcut for x=x\\y."},
+{"_\\_",0,(void*)gdivent,17,"GG","x\\y: Euclidean quotient of x and y."},
+{"_^_",0,(void*)gpow,17,"GGp","x^y: compute x to the power y."},
+{"_^s",0,(void*)gpowgs,19,"GL","return x^n where n is a small integer"},
+{"__",0,NULL,17,NULL,"__"},
+{"_derivfun",0,(void*)derivfun0,19,"GGp","_derivfun(closure,[args]) numerical derivation of closure with respect to the first variable at (args)."},
+{"_ellsea",0,(void*)ellsea,19,"GDGD1,L,","ellsea(E,{p},{s})"},
+{"_eval_mnemonic",0,(void*)eval_mnemonic,19,"lGs","Convert a mnemonic string to a flag."},
+{"_factor_Aurifeuille",0,(void*)factor_Aurifeuille,19,"GL","_factor_Aurifeuille(a,d): return an algebraic factor of Phi_d(a), a != 0"},
+{"_factor_Aurifeuille_prime",0,(void*)factor_Aurifeuille_prime,19,"GL","_factor_Aurifeuille_prime(p,d): return an algebraic factor of Phi_d(p), p prime"},
+{"_multi_if",0,(void*)ifpari_multi,19,"GE*","internal variant of if() that allows more than 3 arguments."},
+{"_parapply_worker",0,(void*)parapply_worker,19,"GG","_parapply_worker(d,C): evaluate the closure C on d."},
+{"_pareval_worker",0,(void*)pareval_worker,19,"G","_pareval_worker(C): evaluate the closure C."},
+{"_parfor_worker",0,(void*)parfor_worker,19,"GG","_parfor_worker(i,C): evaluate the closure C on i and return [i,C(i)]"},
+{"_parvector_worker",0,(void*)parvector_worker,19,"GG","_parvector_worker(i,C): evaluate the closure C on i."},
+{"_polint_worker",0,(void*)nmV_polint_center_tree_worker,19,"GGGGG","used for parallel chinese"},
+{"_polmodular_worker",0,(void*)polmodular_worker,19,"UUUGGGGLGG","used by polmodular"},
+{"_void_if",0,(void*)ifpari_void,19,"vGDIDI","internal variant of if() that does not return a value."},
+{"_||_",0,(void*)orpari,17,"GE","x||y: inclusive OR."},
+{"_~",0,(void*)gtrans,17,"G","x~: transpose of x."},
 {"abs",0,(void*)gabs,3,"Gp","abs(x): absolute value (or modulus) of x."},
 {"acos",0,(void*)gacos,3,"Gp","acos(x): arc cosine of x."},
 {"acosh",0,(void*)gacosh,3,"Gp","acosh(x): inverse hyperbolic cosine of x."},
-{"addhelp",0,(void*)addhelp,14,"vrs","addhelp(sym,str): add/change help message for the symbol sym."},
+{"addhelp",0,(void*)addhelp,15,"vrs","addhelp(sym,str): add/change help message for the symbol sym."},
 {"addprimes",0,(void*)addprimes,4,"DG","addprimes({x=[]}): add primes in the vector x to the prime table to be used in trial division. x may also be a single integer. Composite \"primes\" are NOT allowed!"},
 {"agm",0,(void*)agm,3,"GGp","agm(x,y): arithmetic-geometric mean of x and y."},
-{"alarm",0,(void*)gp_alarm,14,"D0,L,DE","alarm({s = 0},{code}): if code is omitted, trigger an \"e_ALARM\" exception after s seconds, cancelling any previously set alarm; stop a pending alarm if s = 0 or is omitted. Otherwise, evaluate code, aborting after s seconds."},
-{"algabsdim",0,(void*)algabsdim,9,"lG","algabsdim(al): dimension of the algebra al over its prime subfield."},
-{"algadd",0,(void*)algadd,9,"GGG","algadd(al,x,y): element x+y in al."},
-{"algalgtobasis",0,(void*)algalgtobasis,9,"GG","algalgtobasis(al,x): transforms the element x of the algebra al into a column vector on the integral basis of al."},
-{"algaut",0,(void*)algaut,9,"mG","algaut(al): the stored automorphism of the splitting field of the cyclic algebra al."},
-{"algb",0,(void*)algb,9,"mG","algb(al): the element b of the center of the cyclic algebra al used to define it."},
-{"algbasis",0,(void*)algbasis,9,"mG","algbasis(al): basis of the stored order of the central simple algebra al."},
-{"algbasistoalg",0,(void*)algbasistoalg,9,"GG","algbasistoalg(al,x): transforms the column vector x on the integral basis of al into an element of al in algebraic form."},
-{"algcenter",0,(void*)algcenter,9,"mG","algcenter(al): center of the algebra al."},
-{"algcentralproj",0,(void*)alg_centralproj,9,"GGD0,L,","algcentralproj(al,z,{maps=0}): projections of the algebra al on the orthogonal central idempotents z[i]."},
-{"algchar",0,(void*)algchar,9,"mG","algchar(al): characteristic of the algebra al."},
-{"algcharpoly",0,(void*)algcharpoly,9,"GGDn","algcharpoly(al,b,{v='x}): (reduced) characteristic polynomial of b in \\var{al}, with respect to the variable $v$."},
-{"algdecomposition",0,(void*)alg_decomposition,9,"G","algdecomposition(al): semisimple decomposition of the algebra al."},
-{"algdegree",0,(void*)algdegree,9,"lG","algdegree(al): degree of the central simple algebra al."},
-{"algdep",0,(void*)algdep0,11,"GLD0,L,","algdep(z,k,{flag=0}): algebraic relations up to degree n of z, using lindep([1,z,...,z^(k-1)], flag)."},
-{"algdim",0,(void*)algdim,9,"lG","algdim(al): dimension of the algebra al."},
-{"algdisc",0,(void*)algdisc,9,"G","algdisc(al): discriminant of the stored order of the algebra al."},
-{"algdivl",0,(void*)algdivl,9,"GGG","algdivl(al,x,y): element x\\y in al."},
-{"algdivr",0,(void*)algdivr,9,"GGG","algdivr(al,x,y): element x/y in al."},
-{"alggroup",0,(void*)alggroup,9,"GDG","alggroup(gal, {p=0}): constructs the group algebra of gal over Q (resp. Fp)."},
-{"alghasse",0,(void*)alghasse,9,"GG","alghasse(al,pl): the hasse invariant of the central simple algebra al at the place pl."},
-{"alghassef",0,(void*)alghassef,9,"mG","alghassef(al): the hasse invariant of the central simple algebra al at finite places."},
-{"alghassei",0,(void*)alghassei,9,"mG","alghassei(al): the hasse invariant of the central simple algebra al at infinite places."},
-{"algindex",0,(void*)algindex,9,"lGDG","algindex(al,{pl}): the index of the central simple algebra al. If pl is set, it should be a prime ideal of the center or an integer between 1 and r1+r2, and in that case return the local index at the place pl instead."},
-{"alginit",0,(void*)alginit,9,"GGDnD1,L,","alginit(B, C, {v}, {flag = 1}): initialize the central simple algebra defined by data B, C. If flag = 1, compute a maximal order."},
-{"alginv",0,(void*)alginv,9,"GG","alginv(al,x): element 1/x in al."},
-{"alginvbasis",0,(void*)alginvbasis,9,"mG","alginvbasis(al): basis of the natural order of the central simple algebra al in terms of the stored order."},
-{"algisassociative",0,(void*)algisassociative,9,"iGD0,G,","algisassociative(mt,p=0): true (1) if the multiplication table mt is suitable for algtableinit(mt,p), false (0) otherwise."},
-{"algiscommutative",0,(void*)algiscommutative,9,"iG","algiscommutative(al): test whether the algebra al is commutative."},
-{"algisdivision",0,(void*)algisdivision,9,"iGDG","algisdivision(al,{pl}): test whether the central simple algebra al is a division algebra. If pl is set, it should be a prime ideal of the center or an integer between 1 and r1+r2, and in that case test whether al is locally a division algebra at the place pl instead."},
-{"algisdivl",0,(void*)algisdivl,9,"iGGGD&","algisdivl(al,x,y,{&z}): tests whether y is left divisible by x and sets z to the left quotient x\\y."},
-{"algisinv",0,(void*)algisinv,9,"iGGD&","algisinv(al,x,{&ix}): tests whether x is invertible and sets ix to the inverse of x."},
-{"algisramified",0,(void*)algisramified,9,"iGDG","algisramified(al,{pl}): test whether the central simple algebra al is ramified, i.e. not isomorphic to a matrix ring over its center. If pl is set, it should be a prime ideal of the center or an integer between 1 and r1+r2, and in that case test whether al is locally ramified at the place pl instead."},
-{"algissemisimple",0,(void*)algissemisimple,9,"iG","algissemisimple(al): test whether the algebra al is semisimple."},
-{"algissimple",0,(void*)algissimple,9,"iGD0,L,","algissimple(al, {ss = 0}): test whether the algebra al is simple."},
-{"algissplit",0,(void*)algissplit,9,"iGDG","algissplit(al,{pl}): test whether the central simple algebra al is split, i.e. isomorphic to a matrix ring over its center. If pl is set, it should be a prime ideal of the center or an integer between 1 and r1+r2, and in that case test whether al is locally split at the place pl instead."},
-{"alglathnf",0,(void*)alglathnf,9,"GG","alglathnf(al,m): the lattice generated by the columns of m."},
-{"algleftmultable",0,(void*)algleftmultable,9,"GG","algmultable(al,x): left multiplication table of x."},
-{"algmul",0,(void*)algmul,9,"GGG","algmul(al,x,y): element x*y in al."},
-{"algmultable",0,(void*)algmultable,9,"mG","algmultable(al): multiplication table of al over its prime subfield."},
-{"algneg",0,(void*)algneg,9,"GG","algneg(al,x): element -x in al."},
-{"algnorm",0,(void*)algnorm,9,"GG","algnorm(al,x): (reduced) norm of x."},
-{"algpoleval",0,(void*)algpoleval,9,"GGG","algpoleval(al,T,b): T in K[X] evaluate T(b) in al."},
-{"algpow",0,(void*)algpow,9,"GGG","algpow(al,x,n): element x^n in al."},
-{"algprimesubalg",0,(void*)algprimesubalg,9,"G","algprimesubalg(al): prime subalgebra of the positive characteristic, semisimple algebra al."},
-{"algquotient",0,(void*)alg_quotient,9,"GGD0,L,","algquotient(al,I,{flag=0}): quotient of the algebra al by the two-sided ideal I."},
-{"algradical",0,(void*)algradical,9,"G","algradical(al): Jacobson radical of the algebra al."},
-{"algramifiedplaces",0,(void*)algramifiedplaces,9,"G","algramifiedplaces(al): vector of the places of the center of al that ramify in al. Each place is described as an integer between 1 and r1 or as a prime ideal."},
-{"algrandom",0,(void*)algrandom,9,"GG","algrandom(al,b): random element in al with coefficients in [-b,b]."},
-{"algrelmultable",0,(void*)algrelmultable,9,"mG","algrelmultable(al): multiplication table of the central simple algebra al over its center."},
-{"algsimpledec",0,(void*)algsimpledec,9,"GD0,L,","algsimpledec(al,{flag=0}): decomposition into simple algebras of the semisimple algebra al."},
-{"algsplittingdata",0,(void*)algsplittingdata,9,"mG","algsplittingdata(al): data stored in the central simple algebra al to compute a splitting of al over an extension."},
-{"algsplittingfield",0,(void*)algsplittingfield,9,"mG","algsplittingfield(al): the stored splitting field of the central simple algebra al."},
-{"algsplittingmatrix",0,(void*)algsplittingmatrix,9,"GG","algsplittingmatrix(al,x): image of x under a splitting of al."},
-{"algsqr",0,(void*)algsqr,9,"GG","algsqr(al,x): element x^2 in al."},
-{"algsub",0,(void*)algsub,9,"GGG","algsub(al,x,y): element x-y in al."},
-{"algsubalg",0,(void*)algsubalg,9,"GG","algsubalg(al,B): subalgebra of al with basis B."},
-{"algtableinit",0,(void*)algtableinit,9,"GDG","algtableinit(mt, {p=0}): initialize the associative algebra over Q (resp. Fp) defined by the multiplication table mt."},
-{"algtensor",0,(void*)algtensor,9,"GGD1,L,","algtensor(al1,al2,{maxord=1}): tensor product of al1 and al2."},
-{"algtrace",0,(void*)algtrace,9,"GG","algtrace(al,x): (reduced) trace of x."},
-{"algtype",0,(void*)algtype,9,"lG","algtype(al): type of the algebra al."},
-{"alias",0,(void*)alias0,14,"vrr","alias(newsym,sym): defines the symbol newsym as an alias for the symbol sym."},
-{"allocatemem",0,(void*)gp_allocatemem,14,"vDG","allocatemem({s=0}): allocates a new stack of s bytes. doubles the stack if s is omitted."},
-{"apply",0,(void*)apply0,14,"GG","apply(f, A): apply function f to each entry in A."},
+{"alarm",0,(void*)gp_alarm,15,"D0,L,DE","alarm({s = 0},{code}): if code is omitted, trigger an \"e_ALARM\" exception after s seconds, cancelling any previously set alarm; stop a pending alarm if s = 0 or is omitted. Otherwise, evaluate code, aborting after s seconds."},
+{"algabsdim",0,(void*)algabsdim,10,"lG","algabsdim(al): dimension of the algebra al over its prime subfield."},
+{"algadd",0,(void*)algadd,10,"GGG","algadd(al,x,y): element x+y in al."},
+{"algalgtobasis",0,(void*)algalgtobasis,10,"GG","algalgtobasis(al,x): transforms the element x of the algebra al into a column vector on the integral basis of al."},
+{"algaut",0,(void*)algaut,10,"mG","algaut(al): the stored automorphism of the splitting field of the cyclic algebra al."},
+{"algb",0,(void*)algb,10,"mG","algb(al): the element b of the center of the cyclic algebra al used to define it."},
+{"algbasis",0,(void*)algbasis,10,"mG","algbasis(al): basis of the stored order of the central simple algebra al."},
+{"algbasistoalg",0,(void*)algbasistoalg,10,"GG","algbasistoalg(al,x): transforms the column vector x on the integral basis of al into an element of al in algebraic form."},
+{"algcenter",0,(void*)algcenter,10,"mG","algcenter(al): center of the algebra al."},
+{"algcentralproj",0,(void*)alg_centralproj,10,"GGD0,L,","algcentralproj(al,z,{maps=0}): projections of the algebra al on the orthogonal central idempotents z[i]."},
+{"algchar",0,(void*)algchar,10,"mG","algchar(al): characteristic of the algebra al."},
+{"algcharpoly",0,(void*)algcharpoly,10,"GGDn","algcharpoly(al,b,{v='x}): (reduced) characteristic polynomial of b in \\var{al}, with respect to the variable $v$."},
+{"algdecomposition",0,(void*)alg_decomposition,10,"G","algdecomposition(al): semisimple decomposition of the algebra al."},
+{"algdegree",0,(void*)algdegree,10,"lG","algdegree(al): degree of the central simple algebra al."},
+{"algdep",0,(void*)algdep0,12,"GLD0,L,","algdep(z,k,{flag=0}): algebraic relations up to degree n of z, using lindep([1,z,...,z^(k-1)], flag)."},
+{"algdim",0,(void*)algdim,10,"lG","algdim(al): dimension of the algebra al."},
+{"algdisc",0,(void*)algdisc,10,"G","algdisc(al): discriminant of the stored order of the algebra al."},
+{"algdivl",0,(void*)algdivl,10,"GGG","algdivl(al,x,y): element x\\y in al."},
+{"algdivr",0,(void*)algdivr,10,"GGG","algdivr(al,x,y): element x/y in al."},
+{"alggroup",0,(void*)alggroup,10,"GDG","alggroup(gal, {p=0}): constructs the group algebra of gal over Q (resp. Fp)."},
+{"alghasse",0,(void*)alghasse,10,"GG","alghasse(al,pl): the hasse invariant of the central simple algebra al at the place pl."},
+{"alghassef",0,(void*)alghassef,10,"mG","alghassef(al): the hasse invariant of the central simple algebra al at finite places."},
+{"alghassei",0,(void*)alghassei,10,"mG","alghassei(al): the hasse invariant of the central simple algebra al at infinite places."},
+{"algindex",0,(void*)algindex,10,"lGDG","algindex(al,{pl}): the index of the central simple algebra al. If pl is set, it should be a prime ideal of the center or an integer between 1 and r1+r2, and in that case return the local index at the place pl instead."},
+{"alginit",0,(void*)alginit,10,"GGDnD1,L,","alginit(B, C, {v}, {flag = 1}): initialize the central simple algebra defined by data B, C. If flag = 1, compute a maximal order."},
+{"alginv",0,(void*)alginv,10,"GG","alginv(al,x): element 1/x in al."},
+{"alginvbasis",0,(void*)alginvbasis,10,"mG","alginvbasis(al): basis of the natural order of the central simple algebra al in terms of the stored order."},
+{"algisassociative",0,(void*)algisassociative,10,"iGD0,G,","algisassociative(mt,p=0): true (1) if the multiplication table mt is suitable for algtableinit(mt,p), false (0) otherwise."},
+{"algiscommutative",0,(void*)algiscommutative,10,"iG","algiscommutative(al): test whether the algebra al is commutative."},
+{"algisdivision",0,(void*)algisdivision,10,"iGDG","algisdivision(al,{pl}): test whether the central simple algebra al is a division algebra. If pl is set, it should be a prime ideal of the center or an integer between 1 and r1+r2, and in that case test whether al is locally a division algebra at the place pl instead."},
+{"algisdivl",0,(void*)algisdivl,10,"iGGGD&","algisdivl(al,x,y,{&z}): tests whether y is left divisible by x and sets z to the left quotient x\\y."},
+{"algisinv",0,(void*)algisinv,10,"iGGD&","algisinv(al,x,{&ix}): tests whether x is invertible and sets ix to the inverse of x."},
+{"algisramified",0,(void*)algisramified,10,"iGDG","algisramified(al,{pl}): test whether the central simple algebra al is ramified, i.e. not isomorphic to a matrix ring over its center. If pl is set, it should be a prime ideal of the center or an integer between 1 and r1+r2, and in that case test whether al is locally ramified at the place pl instead."},
+{"algissemisimple",0,(void*)algissemisimple,10,"iG","algissemisimple(al): test whether the algebra al is semisimple."},
+{"algissimple",0,(void*)algissimple,10,"iGD0,L,","algissimple(al, {ss = 0}): test whether the algebra al is simple."},
+{"algissplit",0,(void*)algissplit,10,"iGDG","algissplit(al,{pl}): test whether the central simple algebra al is split, i.e. isomorphic to a matrix ring over its center. If pl is set, it should be a prime ideal of the center or an integer between 1 and r1+r2, and in that case test whether al is locally split at the place pl instead."},
+{"alglathnf",0,(void*)alglathnf,10,"GG","alglathnf(al,m): the lattice generated by the columns of m."},
+{"algleftmultable",0,(void*)algleftmultable,10,"GG","algmultable(al,x): left multiplication table of x."},
+{"algmul",0,(void*)algmul,10,"GGG","algmul(al,x,y): element x*y in al."},
+{"algmultable",0,(void*)algmultable,10,"mG","algmultable(al): multiplication table of al over its prime subfield."},
+{"algneg",0,(void*)algneg,10,"GG","algneg(al,x): element -x in al."},
+{"algnorm",0,(void*)algnorm,10,"GG","algnorm(al,x): (reduced) norm of x."},
+{"algpoleval",0,(void*)algpoleval,10,"GGG","algpoleval(al,T,b): T in K[X] evaluate T(b) in al."},
+{"algpow",0,(void*)algpow,10,"GGG","algpow(al,x,n): element x^n in al."},
+{"algprimesubalg",0,(void*)algprimesubalg,10,"G","algprimesubalg(al): prime subalgebra of the positive characteristic, semisimple algebra al."},
+{"algquotient",0,(void*)alg_quotient,10,"GGD0,L,","algquotient(al,I,{flag=0}): quotient of the algebra al by the two-sided ideal I."},
+{"algradical",0,(void*)algradical,10,"G","algradical(al): Jacobson radical of the algebra al."},
+{"algramifiedplaces",0,(void*)algramifiedplaces,10,"G","algramifiedplaces(al): vector of the places of the center of al that ramify in al. Each place is described as an integer between 1 and r1 or as a prime ideal."},
+{"algrandom",0,(void*)algrandom,10,"GG","algrandom(al,b): random element in al with coefficients in [-b,b]."},
+{"algrelmultable",0,(void*)algrelmultable,10,"mG","algrelmultable(al): multiplication table of the central simple algebra al over its center."},
+{"algsimpledec",0,(void*)algsimpledec,10,"GD0,L,","algsimpledec(al,{flag=0}): decomposition into simple algebras of the semisimple algebra al."},
+{"algsplittingdata",0,(void*)algsplittingdata,10,"mG","algsplittingdata(al): data stored in the central simple algebra al to compute a splitting of al over an extension."},
+{"algsplittingfield",0,(void*)algsplittingfield,10,"mG","algsplittingfield(al): the stored splitting field of the central simple algebra al."},
+{"algsplittingmatrix",0,(void*)algsplittingmatrix,10,"GG","algsplittingmatrix(al,x): image of x under a splitting of al."},
+{"algsqr",0,(void*)algsqr,10,"GG","algsqr(al,x): element x^2 in al."},
+{"algsub",0,(void*)algsub,10,"GGG","algsub(al,x,y): element x-y in al."},
+{"algsubalg",0,(void*)algsubalg,10,"GG","algsubalg(al,B): subalgebra of al with basis B."},
+{"algtableinit",0,(void*)algtableinit,10,"GDG","algtableinit(mt, {p=0}): initialize the associative algebra over Q (resp. Fp) defined by the multiplication table mt."},
+{"algtensor",0,(void*)algtensor,10,"GGD1,L,","algtensor(al1,al2,{maxord=1}): tensor product of al1 and al2."},
+{"algtrace",0,(void*)algtrace,10,"GG","algtrace(al,x): (reduced) trace of x."},
+{"algtype",0,(void*)algtype,10,"lG","algtype(al): type of the algebra al."},
+{"alias",0,(void*)alias0,15,"vrr","alias(newsym,sym): defines the symbol newsym as an alias for the symbol sym."},
+{"allocatemem",0,(void*)gp_allocatemem,15,"vDG","allocatemem({s=0}): allocates a new stack of s bytes. doubles the stack if s is omitted."},
+{"apply",0,(void*)apply0,15,"GG","apply(f, A): apply function f to each entry in A."},
 {"arg",0,(void*)garg,3,"Gp","arg(x): argument of x, such that -pi<arg(x)<=pi."},
 {"asin",0,(void*)gasin,3,"Gp","asin(x): arc sine of x."},
 {"asinh",0,(void*)gasinh,3,"Gp","asinh(x): inverse hyperbolic sine of x."},
-{"asympnum",0,(void*)asympnum0,12,"GD0,L,DGp","asympnum(expr,{k=20},{alpha = 1}): asymptotic expansion of expr assuming it has rational coefficients with reasonable height; k and alpha are as in extnum."},
+{"asympnum",0,(void*)asympnum0,13,"GD0,L,DGp","asympnum(expr,{k=20},{alpha = 1}): asymptotic expansion of expr assuming it has rational coefficients with reasonable height; k and alpha are as in extnum."},
 {"atan",0,(void*)gatan,3,"Gp","atan(x): arc tangent of x."},
 {"atanh",0,(void*)gatanh,3,"Gp","atanh(x): inverse hyperbolic tangent of x."},
 {"bernfrac",0,(void*)bernfrac,3,"L","bernfrac(x): Bernoulli number B_x, as a rational number."},
@@ -223,7 +224,7 @@ entree functions_basic[]={
 {"bestappr",0,(void*)bestappr,4,"GDG","bestappr(x, {B}): returns a rational approximation to x, whose denominator is limited by B, if present. This function applies to reals, intmods, p-adics, and rationals of course. Otherwise it applies recursively to all components."},
 {"bestapprPade",0,(void*)bestapprPade,4,"GD-1,L,","bestappr(x, {B}): returns a rational function approximation to x. This function applies to series, polmods, and rational functions of course. Otherwise it applies recursively to all components."},
 {"bezout",0,(void*)gcdext0,4,"GG","bezout(x,y): deprecated alias for gcdext"},
-{"bezoutres",0,(void*)polresultantext0,10,"GGDn","bezoutres(A,B,{v}): deprecated alias for polresultantext"},
+{"bezoutres",0,(void*)polresultantext0,11,"GGDn","bezoutres(A,B,{v}): deprecated alias for polresultantext"},
 {"bigomega",0,(void*)bigomega,4,"lG","bigomega(x): number of prime divisors of x, counted with multiplicity."},
 {"binary",0,(void*)binaire,2,"G","binary(x): gives the vector formed by the binary digits of x (x integer)."},
 {"binomial",0,(void*)binomial,4,"GL","binomial(x,y): binomial coefficient x*(x-1)...*(x-y+1)/y! defined for y in Z and any x."},
@@ -234,56 +235,56 @@ entree functions_basic[]={
 {"bitprecision",0,(void*)bitprecision0,2,"GD0,L,","bitprecision(x,{n}): if n is present and positive, return x at precision n bits. If n is omitted, return real precision of object x in bits."},
 {"bittest",0,(void*)gbittest,2,"GL","bittest(x,n): gives bit number n (coefficient of 2^n) of the integer x. Negative numbers behave as if modulo big power of 2."},
 {"bitxor",0,(void*)gbitxor,2,"GG","bitxor(x,y): bitwise \"exclusive or\" of two integers x and y. Negative numbers behave as if modulo big power of 2."},
-{"bnfcertify",0,(void*)bnfcertify0,8,"lGD0,L,","bnfcertify(bnf,{flag = 0}): certify the correctness (i.e. remove the GRH) of the bnf data output by bnfinit. If flag is present, only certify that the class group is a quotient of the one computed in bnf (much simpler in general)."},
-{"bnfcompress",0,(void*)bnfcompress,8,"G","bnfcompress(bnf): converts bnf to a much smaller sbnf, containing the same information. Use bnfinit(sbnf) to recover a true bnf."},
-{"bnfdecodemodule",0,(void*)decodemodule,8,"GG","bnfdecodemodule(nf,m): given a coded module m as in bnrdisclist, gives the true module."},
-{"bnfinit",0,(void*)bnfinit0,8,"GD0,L,DGp","bnfinit(P,{flag=0},{tech=[]}): compute the necessary data for future use in ideal and unit group computations, including fundamental units if they are not too large. flag and tech are both optional. flag can be any of 0: default, 1: insist on having fundamental units. See manual for details about tech."},
-{"bnfisintnorm",0,(void*)bnfisintnorm,8,"GG","bnfisintnorm(bnf,x): compute a complete system of solutions (modulo units of positive norm) of the absolute norm equation N(a)=x, where a belongs to the maximal order of big number field bnf (if bnf is not certified, this depends on GRH)."},
-{"bnfisnorm",0,(void*)bnfisnorm,8,"GGD1,L,","bnfisnorm(bnf,x,{flag=1}): Tries to tell whether x (in Q) is the norm of some fractional y (in bnf). Returns a vector [a,b] where x=Norm(a)*b. Looks for a solution which is a S-unit, with S a certain list of primes (in bnf) containing (among others) all primes dividing x. If bnf is known to be Galois, set flag=0 (in this case, x is a norm iff b=1). If flag is non zero the program adds to S all the primes: dividing flag if flag<0, or less than  [...]
-{"bnfisprincipal",0,(void*)bnfisprincipal0,8,"GGD1,L,","bnfisprincipal(bnf,x,{flag=1}): bnf being output by bnfinit (with flag<=2), gives [v,alpha], where v is the vector of exponents on the class group generators and alpha is the generator of the resulting principal ideal. In particular x is principal if and only if v is the zero vector. flag is optional, whose binary digits mean 1: output [v,alpha] (only v if unset); 2: increase precision until alpha can be computed (do not insist if u [...]
-{"bnfissunit",0,(void*)bnfissunit,8,"GGG","bnfissunit(bnf,sfu,x): bnf being output by bnfinit (with flag<=2), sfu by bnfsunit, gives the column vector of exponents of x on the fundamental S-units and the roots of unity if x is a unit, the empty vector otherwise."},
-{"bnfisunit",0,(void*)bnfisunit,8,"GG","bnfisunit(bnf,x): bnf being output by bnfinit, gives the column vector of exponents of x on the fundamental units and the roots of unity if x is a unit, the empty vector otherwise."},
-{"bnfnarrow",0,(void*)buchnarrow,8,"G","bnfnarrow(bnf): given a big number field as output by bnfinit, gives as a 3-component vector the structure of the narrow class group."},
-{"bnfsignunit",0,(void*)signunits,8,"G","bnfsignunit(bnf): matrix of signs of the real embeddings of the system of fundamental units found by bnfinit."},
-{"bnfsunit",0,(void*)bnfsunit,8,"GGp","bnfsunit(bnf,S): compute the fundamental S-units of the number field bnf output by bnfinit, S being a list of prime ideals. res[1] contains the S-units, res[5] the S-classgroup. See manual for details."},
-{"bnrL1",0,(void*)bnrL1,8,"GDGD0,L,p","bnrL1(bnr, {H}, {flag=0}): bnr being output by bnrinit(,,1) and H being a square matrix defining a congruence subgroup of bnr (the trivial subgroup if omitted), for each character of bnr trivial on this subgroup, compute L(1, chi) (or equivalently the first non-zero term c(chi) of the expansion at s = 0). The binary digits of flag mean 1: if 0 then compute the term c(chi) and return [r(chi), c(chi)] where r(chi) is the order of L(s, chi) at s = 0, o [...]
-{"bnrchar",0,(void*)bnrchar,8,"GGDG","bnrchar(bnr,g,{v}): returns all characters chi on bnr.clgp such that chi(g[i]) = e(v[i]); if v is omitted, returns all characters that are trivial on the g[i]."},
-{"bnrclassno",0,(void*)bnrclassno0,8,"GDGDG","bnrclassno(A,{B},{C}): relative degree of the class field defined by A,B,C. [A,{B},{C}] is of type [bnr], [bnr,subgroup], [bnf,modulus], or [bnf,modulus,subgroup]. Faster than bnrinit if only the ray class number is wanted."},
-{"bnrclassnolist",0,(void*)bnrclassnolist,8,"GG","bnrclassnolist(bnf,list): if list is as output by ideallist or similar, gives list of corresponding ray class numbers."},
-{"bnrconductor",0,(void*)bnrconductor0,8,"GDGDGD0,L,","bnrconductor(A,{B},{C},{flag=0}): conductor f of the subfield of the ray class field given by A,B,C. flag is optional and can be 0: default, 1: returns [f, Cl_f, H], H subgroup of the ray class group modulo f defining the extension, 2: returns [f, bnr(f), H]."},
-{"bnrconductorofchar",0,(void*)bnrconductorofchar,8,"GG","bnrconductorofchar(bnr,chi): THIS FUNCTION IS OBSOLETE: use bnrconductor"},
-{"bnrdisc",0,(void*)bnrdisc0,8,"GDGDGD0,L,","bnrdisc(A,{B},{C},{flag=0}): absolute or relative [N,R1,discf] of the field defined by A,B,C. [A,{B},{C}] is of type [bnr], [bnr,subgroup], [bnf, modulus] or [bnf,modulus,subgroup], where bnf is as output by bnfinit, bnr by bnrinit, and subgroup is the HNF matrix of a subgroup of the corresponding ray class group (if omitted, the trivial subgroup). flag is optional whose binary digits mean 1: give relative data; 2: return 0 if modulus is not t [...]
-{"bnrdisclist",0,(void*)bnrdisclist0,8,"GGDG","bnrdisclist(bnf,bound,{arch}): gives list of discriminants of ray class fields of all conductors up to norm bound, in a long vector The ramified Archimedean places are given by arch; all possible values are taken if arch is omitted. Supports the alternative syntax bnrdisclist(bnf,list), where list is as output by ideallist or ideallistarch (with units)."},
-{"bnrgaloisapply",0,(void*)bnrgaloisapply,8,"GGG","bnrgaloisapply(bnr, mat, H): apply the automorphism given by its matrix mat to the cngruence subgroup H given as a HNF matrix. The matrix mat can be computed with bnrgaloismatrix"},
-{"bnrgaloismatrix",0,(void*)bnrgaloismatrix,8,"GG","bnrgaloismatrix(bnr,aut): return the matrix of the action of the automorphism aut of the base field bnf.nf on the generators of the ray class field bnr.gen. aut can be given as a polynomial, or a vector of automorphisms or a galois group as output by galoisinit, in which case a vector of matrices is returned (in the later case, only for the generators aut.gen)."},
-{"bnrinit",0,(void*)bnrinit0,8,"GGD0,L,","bnrinit(bnf,f,{flag=0}): given a bnf as output by bnfinit and a modulus f, initializes data linked to the ray class group structure corresponding to this module. flag is optional, and can be 0: default, 1: compute also the generators."},
-{"bnrisconductor",0,(void*)bnrisconductor0,8,"lGDGDG","bnrisconductor(A,{B},{C}): returns 1 if the modulus is the conductor of the subfield of the ray class field given by A,B,C (see bnrdisc), and 0 otherwise. Slightly faster than bnrconductor if this is the only desired result."},
-{"bnrisgalois",0,(void*)bnrisgalois,8,"lGGG","bnrisgalois(bnr, gal, H): check whether the class field associated to the subgroup H is Galois over the subfield of bnr.nf fixed by the Galois group gal, which can be given as output by galoisinit, or as a matrix or a vector of matrices as output by bnrgaloismatrix. The ray class field associated to bnr need to be Galois, which is not checked."},
-{"bnrisprincipal",0,(void*)bnrisprincipal,8,"GGD1,L,","bnrisprincipal(bnr,x,{flag=1}): bnr being output by bnrinit, gives [v,alpha], where v is the vector of exponents on the class group generators and alpha is the generator of the resulting principal ideal. In particular x is principal if and only if v is the zero vector. If (optional) flag is set to 0, output only v."},
-{"bnrrootnumber",0,(void*)bnrrootnumber,8,"GGD0,L,p","bnrrootnumber(bnr,chi,{flag=0}): returns the so-called Artin Root Number, i.e. the constant W appearing in the functional equation of the Hecke L-function associated to chi. Set flag = 1 if the character is known to be primitive."},
-{"bnrstark",0,(void*)bnrstark,8,"GDGp","bnrstark(bnr,{subgroup}): bnr being as output by bnrinit(,,1), finds a relative equation for the class field corresponding to the module in bnr and the given congruence subgroup (the trivial subgroup if omitted) using Stark's units. The ground field and the class field must be totally real."},
-{"break",0,(void*)break0,14,"D1,L,","break({n=1}): interrupt execution of current instruction sequence, and exit from the n innermost enclosing loops."},
-{"call",0,(void*)call0,14,"GG","call(f, A): A being a vector, evaluates f(A[1],...,A[#A])."},
+{"bnfcertify",0,(void*)bnfcertify0,9,"lGD0,L,","bnfcertify(bnf,{flag = 0}): certify the correctness (i.e. remove the GRH) of the bnf data output by bnfinit. If flag is present, only certify that the class group is a quotient of the one computed in bnf (much simpler in general)."},
+{"bnfcompress",0,(void*)bnfcompress,9,"G","bnfcompress(bnf): converts bnf to a much smaller sbnf, containing the same information. Use bnfinit(sbnf) to recover a true bnf."},
+{"bnfdecodemodule",0,(void*)decodemodule,9,"GG","bnfdecodemodule(nf,m): given a coded module m as in bnrdisclist, gives the true module."},
+{"bnfinit",0,(void*)bnfinit0,9,"GD0,L,DGp","bnfinit(P,{flag=0},{tech=[]}): compute the necessary data for future use in ideal and unit group computations, including fundamental units if they are not too large. flag and tech are both optional. flag can be any of 0: default, 1: insist on having fundamental units. See manual for details about tech."},
+{"bnfisintnorm",0,(void*)bnfisintnorm,9,"GG","bnfisintnorm(bnf,x): compute a complete system of solutions (modulo units of positive norm) of the absolute norm equation N(a)=x, where a belongs to the maximal order of big number field bnf (if bnf is not certified, this depends on GRH)."},
+{"bnfisnorm",0,(void*)bnfisnorm,9,"GGD1,L,","bnfisnorm(bnf,x,{flag=1}): Tries to tell whether x (in Q) is the norm of some fractional y (in bnf). Returns a vector [a,b] where x=Norm(a)*b. Looks for a solution which is a S-unit, with S a certain list of primes (in bnf) containing (among others) all primes dividing x. If bnf is known to be Galois, set flag=0 (in this case, x is a norm iff b=1). If flag is non zero the program adds to S all the primes: dividing flag if flag<0, or less than  [...]
+{"bnfisprincipal",0,(void*)bnfisprincipal0,9,"GGD1,L,","bnfisprincipal(bnf,x,{flag=1}): bnf being output by bnfinit (with flag<=2), gives [v,alpha], where v is the vector of exponents on the class group generators and alpha is the generator of the resulting principal ideal. In particular x is principal if and only if v is the zero vector. flag is optional, whose binary digits mean 1: output [v,alpha] (only v if unset); 2: increase precision until alpha can be computed (do not insist if u [...]
+{"bnfissunit",0,(void*)bnfissunit,9,"GGG","bnfissunit(bnf,sfu,x): bnf being output by bnfinit (with flag<=2), sfu by bnfsunit, gives the column vector of exponents of x on the fundamental S-units and the roots of unity if x is a unit, the empty vector otherwise."},
+{"bnfisunit",0,(void*)bnfisunit,9,"GG","bnfisunit(bnf,x): bnf being output by bnfinit, gives the column vector of exponents of x on the fundamental units and the roots of unity if x is a unit, the empty vector otherwise."},
+{"bnfnarrow",0,(void*)buchnarrow,9,"G","bnfnarrow(bnf): given a big number field as output by bnfinit, gives as a 3-component vector the structure of the narrow class group."},
+{"bnfsignunit",0,(void*)signunits,9,"G","bnfsignunit(bnf): matrix of signs of the real embeddings of the system of fundamental units found by bnfinit."},
+{"bnfsunit",0,(void*)bnfsunit,9,"GGp","bnfsunit(bnf,S): compute the fundamental S-units of the number field bnf output by bnfinit, S being a list of prime ideals. res[1] contains the S-units, res[5] the S-classgroup. See manual for details."},
+{"bnrL1",0,(void*)bnrL1,9,"GDGD0,L,p","bnrL1(bnr, {H}, {flag=0}): bnr being output by bnrinit(,,1) and H being a square matrix defining a congruence subgroup of bnr (the trivial subgroup if omitted), for each character of bnr trivial on this subgroup, compute L(1, chi) (or equivalently the first non-zero term c(chi) of the expansion at s = 0). The binary digits of flag mean 1: if 0 then compute the term c(chi) and return [r(chi), c(chi)] where r(chi) is the order of L(s, chi) at s = 0, o [...]
+{"bnrchar",0,(void*)bnrchar,9,"GGDG","bnrchar(bnr,g,{v}): returns all characters chi on bnr.clgp such that chi(g[i]) = e(v[i]); if v is omitted, returns all characters that are trivial on the g[i]."},
+{"bnrclassno",0,(void*)bnrclassno0,9,"GDGDG","bnrclassno(A,{B},{C}): relative degree of the class field defined by A,B,C. [A,{B},{C}] is of type [bnr], [bnr,subgroup], [bnf,modulus], or [bnf,modulus,subgroup]. Faster than bnrinit if only the ray class number is wanted."},
+{"bnrclassnolist",0,(void*)bnrclassnolist,9,"GG","bnrclassnolist(bnf,list): if list is as output by ideallist or similar, gives list of corresponding ray class numbers."},
+{"bnrconductor",0,(void*)bnrconductor0,9,"GDGDGD0,L,","bnrconductor(A,{B},{C},{flag=0}): conductor f of the subfield of the ray class field given by A,B,C. flag is optional and can be 0: default, 1: returns [f, Cl_f, H], H subgroup of the ray class group modulo f defining the extension, 2: returns [f, bnr(f), H]."},
+{"bnrconductorofchar",0,(void*)bnrconductorofchar,9,"GG","bnrconductorofchar(bnr,chi): THIS FUNCTION IS OBSOLETE: use bnrconductor"},
+{"bnrdisc",0,(void*)bnrdisc0,9,"GDGDGD0,L,","bnrdisc(A,{B},{C},{flag=0}): absolute or relative [N,R1,discf] of the field defined by A,B,C. [A,{B},{C}] is of type [bnr], [bnr,subgroup], [bnf, modulus] or [bnf,modulus,subgroup], where bnf is as output by bnfinit, bnr by bnrinit, and subgroup is the HNF matrix of a subgroup of the corresponding ray class group (if omitted, the trivial subgroup). flag is optional whose binary digits mean 1: give relative data; 2: return 0 if modulus is not t [...]
+{"bnrdisclist",0,(void*)bnrdisclist0,9,"GGDG","bnrdisclist(bnf,bound,{arch}): gives list of discriminants of ray class fields of all conductors up to norm bound, in a long vector The ramified Archimedean places are given by arch; all possible values are taken if arch is omitted. Supports the alternative syntax bnrdisclist(bnf,list), where list is as output by ideallist or ideallistarch (with units)."},
+{"bnrgaloisapply",0,(void*)bnrgaloisapply,9,"GGG","bnrgaloisapply(bnr, mat, H): apply the automorphism given by its matrix mat to the congruence subgroup H given as a HNF matrix. The matrix mat can be computed with bnrgaloismatrix"},
+{"bnrgaloismatrix",0,(void*)bnrgaloismatrix,9,"GG","bnrgaloismatrix(bnr,aut): return the matrix of the action of the automorphism aut of the base field bnf.nf on the generators of the ray class field bnr.gen. aut can be given as a polynomial, or a vector of automorphisms or a galois group as output by galoisinit, in which case a vector of matrices is returned (in the later case, only for the generators aut.gen)."},
+{"bnrinit",0,(void*)bnrinit0,9,"GGD0,L,","bnrinit(bnf,f,{flag=0}): given a bnf as output by bnfinit and a modulus f, initializes data linked to the ray class group structure corresponding to this module. flag is optional, and can be 0: default, 1: compute also the generators."},
+{"bnrisconductor",0,(void*)bnrisconductor0,9,"lGDGDG","bnrisconductor(A,{B},{C}): returns 1 if the modulus is the conductor of the subfield of the ray class field given by A,B,C (see bnrdisc), and 0 otherwise. Slightly faster than bnrconductor if this is the only desired result."},
+{"bnrisgalois",0,(void*)bnrisgalois,9,"lGGG","bnrisgalois(bnr, gal, H): check whether the class field associated to the subgroup H is Galois over the subfield of bnr.nf fixed by the Galois group gal, which can be given as output by galoisinit, or as a matrix or a vector of matrices as output by bnrgaloismatrix. The ray class field associated to bnr need to be Galois, which is not checked."},
+{"bnrisprincipal",0,(void*)bnrisprincipal,9,"GGD1,L,","bnrisprincipal(bnr,x,{flag=1}): bnr being output by bnrinit, gives [v,alpha], where v is the vector of exponents on the class group generators and alpha is the generator of the resulting principal ideal. In particular x is principal if and only if v is the zero vector. If (optional) flag is set to 0, output only v."},
+{"bnrrootnumber",0,(void*)bnrrootnumber,9,"GGD0,L,p","bnrrootnumber(bnr,chi,{flag=0}): returns the so-called Artin Root Number, i.e. the constant W appearing in the functional equation of the Hecke L-function associated to chi. Set flag = 1 if the character is known to be primitive."},
+{"bnrstark",0,(void*)bnrstark,9,"GDGp","bnrstark(bnr,{subgroup}): bnr being as output by bnrinit(,,1), finds a relative equation for the class field corresponding to the module in bnr and the given congruence subgroup (the trivial subgroup if omitted) using Stark's units. The ground field and the class field must be totally real."},
+{"break",0,(void*)break0,15,"D1,L,","break({n=1}): interrupt execution of current instruction sequence, and exit from the n innermost enclosing loops."},
+{"call",0,(void*)call0,15,"GG","call(f, A): A being a vector, evaluates f(A[1],...,A[#A])."},
 {"ceil",0,(void*)gceil,2,"G","ceil(x): ceiling of x = smallest integer >= x."},
 {"centerlift",0,(void*)centerlift0,2,"GDn","centerlift(x,{v}): centered lift of x. Same as lift except for intmod and padic components."},
 {"characteristic",0,(void*)characteristic,2,"mG","characteristic(x): characteristic of the base ring over which x is defined"},
 {"charconj",0,(void*)charconj0,4,"GG","charconj(cyc,chi): given a finite abelian group (by its elementary divisors cyc) and a character chi, return the conjugate character."},
 {"chardiv",0,(void*)chardiv0,4,"GGG","chardiv(cyc, a,b): given a finite abelian group (by its elementary divisors cyc) and two characters a and b, return the character a/b."},
-{"chareval",0,(void*)chareval,4,"GGGDG","chareval(G,chi, x, {z})):"},
+{"chareval",0,(void*)chareval,4,"GGGDG","chareval(G, chi, x, {z})): given an abelian group structure affording a discrete logarithm method, e.g. G = idealstar(,N) or a bnr structure, let x be an element of G and let chi be a character of G. This function returns the value of chi at x, where the encoding depends on the optional argument z; if z is omitted, we fix a canonical o-th root of 1, zeta_o, where o is the character order and return the rational number c/o where chi(x) = (zeta_o)^c"},
 {"charker",0,(void*)charker0,4,"GG","charker(cyc,chi): given a finite abelian group (by its elementary divisors cyc) and a character chi, return its kernel."},
 {"charmul",0,(void*)charmul0,4,"GGG","charmul(cyc, a,b): given a finite abelian group (by its elementary divisors cyc) and two characters a and b, return the product character ab."},
 {"charorder",0,(void*)charorder0,4,"GG","charorder(cyc,chi): given a finite abelian group (by its elementary divisors cyc) and a character chi, return the order of chi."},
-{"charpoly",0,(void*)charpoly0,11,"GDnD5,L,","charpoly(A,{v='x},{flag=5}): det(v*Id-A)=characteristic polynomial of the matrix or polmod A. flag is optional and ignored unless A is a matrix; it may be set to 0 (Le Verrier), 1 (Lagrange interpolation), 2 (Hessenberg form), 3 (Berkowitz), 4 (modular) if A is integral, or 5 (default, choose best method). Algorithms 0 (Le Verrier) and 1 (Lagrange) assume that n! is invertible, where n is the dimension of the matrix."},
+{"charpoly",0,(void*)charpoly0,12,"GDnD5,L,","charpoly(A,{v='x},{flag=5}): det(v*Id-A)=characteristic polynomial of the matrix or polmod A. flag is optional and ignored unless A is a matrix; it may be set to 0 (Le Verrier), 1 (Lagrange interpolation), 2 (Hessenberg form), 3 (Berkowitz), 4 (modular) if A is integral, or 5 (default, choose best method). Algorithms 0 (Le Verrier) and 1 (Lagrange) assume that n! is invertible, where n is the dimension of the matrix."},
 {"chinese",0,(void*)chinese,4,"GDG","chinese(x,{y}): x,y being both intmods (or polmods) computes z in the same residue classes as x and y."},
 {"cmp",0,(void*)cmp_universal,1,"iGG","cmp(x,y): compare two arbitrary objects x and y (1 if x>y, 0 if x=y, -1 if x<y). The function is used to implement sets, and has no useful mathematical meaning."},
 {"component",0,(void*)compo,2,"GL","component(x,n): the n'th component of the internal representation of x. For vectors or matrices, it is simpler to use x[]. For list objects such as nf, bnf, bnr or ell, it is much easier to use member functions starting with \".\"."},
-{"concat",0,(void*)gconcat,11,"GDG","concat(x,{y}): concatenation of x and y, which can be scalars, vectors or matrices, or lists (in this last case, both x and y have to be lists). If y is omitted, x has to be a list or row vector and its elements are concatenated."},
+{"concat",0,(void*)gconcat,12,"GDG","concat(x,{y}): concatenation of x and y, which can be scalars, vectors or matrices, or lists (in this last case, both x and y have to be lists). If y is omitted, x has to be a list or row vector and its elements are concatenated."},
 {"conj",0,(void*)gconj,2,"G","conj(x): the algebraic conjugate of x."},
 {"conjvec",0,(void*)conjvec,2,"Gp","conjvec(z): conjugate vector of the algebraic number z."},
 {"content",0,(void*)content,4,"G","content(x): gcd of all the components of x, when this makes sense."},
 {"contfrac",0,(void*)contfrac0,4,"GDGD0,L,","contfrac(x,{b},{nmax}): continued fraction expansion of x (x rational,real or rational function). b and nmax are both optional, where b is the vector of numerators of the continued fraction, and nmax is a bound for the number of terms in the continued fraction expansion."},
-{"contfraceval",0,(void*)contfraceval,12,"GGD-1,L,","contfraceval(CF,t,{lim=-1}): Given a continued fraction CF from contfracinit, evaluate the first lim terms of the continued fraction at t (all terms if lim is negative or omitted)."},
-{"contfracinit",0,(void*)contfracinit,12,"GD-1,L,","contfracinit(M,{lim = -1}): Given M representing the power series S = sum_{n>=0} M[n+1]z^n, transform it into a continued fraction suitable for evaluation."},
+{"contfraceval",0,(void*)contfraceval,13,"GGD-1,L,","contfraceval(CF,t,{lim=-1}): Given a continued fraction CF from contfracinit, evaluate the first lim terms of the continued fraction at t (all terms if lim is negative or omitted)."},
+{"contfracinit",0,(void*)contfracinit,13,"GD-1,L,","contfracinit(M,{lim = -1}): Given M representing the power series S = sum_{n>=0} M[n+1]z^n, transform it into a continued fraction suitable for evaluation."},
 {"contfracpnqn",0,(void*)contfracpnqn,4,"GD-1,L,","contfracpnqn(x, {n=-1}): [p_n,p_{n-1}; q_n,q_{n-1}] corresponding to the continued fraction x. If n >= 0 is present, returns all convergents from p_0/q_0 up to p_n/q_n."},
 {"core",0,(void*)core0,4,"GD0,L,","core(n,{flag=0}): unique squarefree integer d dividing n such that n/d is a square. If (optional) flag is non-null, output the two-component row vector [d,f], where d is the unique squarefree integer dividing n such that n/d=f^2 is a square."},
 {"coredisc",0,(void*)coredisc0,4,"GD0,L,","coredisc(n,{flag=0}): discriminant of the quadratic field Q(sqrt(n)). If (optional) flag is non-null, output a two-component row vector [d,f], where d is the discriminant of the quadratic field Q(sqrt(n)) and n=df^2. f may be a half integer."},
@@ -291,18 +292,18 @@ entree functions_basic[]={
 {"cosh",0,(void*)gcosh,3,"Gp","cosh(x): hyperbolic cosine of x."},
 {"cotan",0,(void*)gcotan,3,"Gp","cotan(x): cotangent of x."},
 {"cotanh",0,(void*)gcotanh,3,"Gp","cotanh(x): hyperbolic cotangent of x."},
-{"dbg_x",0,(void*)dbgGEN,14,"vGD-1,L,","dbg_x(A{,n}): print inner structure of A, complete if n is omitted, up to level n otherwise. Intended for debugging."},
-{"default",0,(void*)default0,14,"DrDs","default({key},{val}): returns the current value of the default key. If val is present, set opt to val first. If no argument is given, print a list of all defaults as well as their values."},
+{"dbg_x",0,(void*)dbgGEN,15,"vGD-1,L,","dbg_x(A{,n}): print inner structure of A, complete if n is omitted, up to level n otherwise. Intended for debugging."},
+{"default",0,(void*)default0,15,"DrDs","default({key},{val}): returns the current value of the default key. If val is present, set opt to val first. If no argument is given, print a list of all defaults as well as their values."},
 {"denominator",0,(void*)denom,2,"G","denominator(x): denominator of x (or lowest common denominator in case of an array)."},
-{"deriv",0,(void*)deriv,10,"GDn","deriv(x,{v}): derivative of x with respect to v, or to the main variable of x if v is omitted."},
-{"derivnum",0,(void*)derivnum0,12,"V=GEp","derivnum(X=a,expr): numerical derivation of expr with respect to X at X = a."},
-{"diffop",0,(void*)diffop0,10,"GGGD1,L,","diffop(x,v,d,{n=1}): apply the differential operator D to x, where D is defined by D(v[i])=d[i], where v is a vector of variable names. D is 0 for variables outside of v unless they appear as modulus of a POLMOD. If the optional parameter n is given, return D^n(x) instead."},
+{"deriv",0,(void*)deriv,11,"GDn","deriv(x,{v}): derivative of x with respect to v, or to the main variable of x if v is omitted."},
+{"derivnum",0,(void*)derivnum0,13,"V=GEp","derivnum(X=a,expr): numerical derivation of expr with respect to X at X = a."},
+{"diffop",0,(void*)diffop0,11,"GGGD1,L,","diffop(x,v,d,{n=1}): apply the differential operator D to x, where D is defined by D(v[i])=d[i], where v is a vector of variable names. D is 0 for variables outside of v unless they appear as modulus of a POLMOD. If the optional parameter n is given, return D^n(x) instead."},
 {"digits",0,(void*)digits,2,"GDG","digits(x,{b=10}): gives the vector formed by the digits of x in base b (x and b integers)."},
 {"dilog",0,(void*)dilog,3,"Gp","dilog(x): dilogarithm of x."},
 {"dirdiv",0,(void*)dirdiv,4,"GG","dirdiv(x,y): division of the Dirichlet series x by the Dirichlet series y."},
 {"direuler",0,(void*)direuler0,4,"V=GGEDG","direuler(p=a,b,expr,{c}): Dirichlet Euler product of expression expr from p=a to p=b, limited to b terms. Expr should be a polynomial or rational function in p and X, and X is understood to mean p^(-s). If c is present, output only the first c terms."},
 {"dirmul",0,(void*)dirmul,4,"GG","dirmul(x,y): multiplication of the Dirichlet series x by the Dirichlet series y."},
-{"dirzetak",0,(void*)dirzetak,8,"GG","dirzetak(nf,b): Dirichlet series of the Dedekind zeta function of the number field nf up to the bound b-1."},
+{"dirzetak",0,(void*)dirzetak,9,"GG","dirzetak(nf,b): Dirichlet series of the Dedekind zeta function of the number field nf up to the bound b-1."},
 {"divisors",0,(void*)divisors,4,"G","divisors(x): gives a vector formed by the divisors of x in increasing order."},
 {"divrem",0,(void*)divrem,1,"GGDn","divrem(x,y,{v}): euclidean division of x by y giving as a 2-dimensional column vector the quotient and the remainder, with respect to v (to main variable if v is omitted)"},
 {"eint1",0,(void*)veceint1,3,"GDGp","eint1(x,{n}): exponential integral E1(x). If n is present and x > 0, computes the vector of the first n values of the exponential integral E1(n.x)"},
@@ -348,14 +349,14 @@ entree functions_basic[]={
 {"elllseries",0,(void*)elllseries,5,"GGDGp","elllseries(E,s,{A=1}): L-series at s of the elliptic curve E, where A a cut-off point close to 1."},
 {"ellminimalmodel",0,(void*)ellminimalmodel,5,"GD&","ellminimalmodel(E,{&v}): return the standard minimal integral model of the rational elliptic curve E. Sets v to the corresponding change of variables."},
 {"ellminimaltwist",0,(void*)ellminimaltwist0,5,"GD0,L,","ellminimaltwist(E, {flag=0}): E being an elliptic curve defined over Q, return a discriminant D such the twist of E by D is minimal among all possible quadratic twists, i.e.  if flag=0, its minimal model has minimal discriminant, or if flag=1, it has minimal conductor."},
-{"ellmoddegree",0,(void*)ellmoddegree_bitprec,5,"Gb","ellmoddegree(e): e being an elliptic curve defined over Q output by  ellinit, compute the modular degree of e divided by the square of the  Manin constant. Return [D, err], where D is a rational number and  err is the exponent of the truncation error."},
+{"ellmoddegree",0,(void*)ellmoddegree,5,"Gb","ellmoddegree(e): e being an elliptic curve defined over Q output by  ellinit, compute the modular degree of e divided by the square of the  Manin constant. Return [D, err], where D is a rational number and  err is the exponent of the truncation error."},
 {"ellmodulareqn",0,(void*)ellmodulareqn,5,"LDnDn","ellmodulareqn(N,{x},{y}): return a vector [eqn, t] where eqn is a modular equation of level N, for N<500, N prime. This requires the package seadata to be installed.  The equation is either of canonical type (t=0) or of Atkin type (t=1)"},
 {"ellmul",0,(void*)ellmul,5,"GGG","ellmul(E,z,n): n times the point z on elliptic curve E (n in Z)."},
 {"ellneg",0,(void*)ellneg,5,"GG","ellneg(E,z): opposite of the point z on elliptic curve E."},
-{"ellnonsingularmultiple",0,(void*)ellnonsingularmultiple,5,"GG","ellnonsingularmultiple(E,P):"},
+{"ellnonsingularmultiple",0,(void*)ellnonsingularmultiple,5,"GG","ellnonsingularmultiple(E,P): given E/Q and P in E(Q), returns the pair [R,n] where n is the least positive integer such that R = [n]P has everywhere good reduction. More precisely, its image in a minimal model is everywhere non-singular."},
 {"ellorder",0,(void*)ellorder,5,"GGDG","ellorder(E,z,{o}): order of the point z on the elliptic curve E over a number field or a finite field, 0 if non-torsion. The parameter o, if present, represents a non-zero multiple of the order of z."},
 {"ellordinate",0,(void*)ellordinate,5,"GGp","ellordinate(E,x): y-coordinates corresponding to x-ordinate x on elliptic curve E."},
-{"ellpadicL",0,(void*)ellpadicL,5,"GGLD0,L,DGDG","ellpadicL(E, p, n, {r = 0}, {D}, {char}): returns the value  on a character of the derivative of order r of the L-function of  the elliptic curve E (twisted by D > 0, if present). For the moment, only  the case of the trivial character is implemented"},
+{"ellpadicL",0,(void*)ellpadicL,5,"GGLDGD0,L,DG","ellpadicL(E, p, n, {s = 0}, {r = 0}, {D = 1}): returns the value on a character of Z_p^* represented by an integer s or a vector [s1,s2] of the derivative of order r of the p-adic L-function of the elliptic curve E (twisted by D, if present)."},
 {"ellpadicfrobenius",0,(void*)ellpadicfrobenius,5,"GLL","ellpadicfrobenius(E,p,n): matrix of the Frobenius at p>2 in the standard basis of H^1_dR(E) to absolute p-adic precision p^n."},
 {"ellpadicheight",0,(void*)ellpadicheight0,5,"GGLGDG","ellpadicheight(E, p,n, P,{Q}): E elliptic curve/Q, P in E(Q), p prime, n an integer; returns the cyclotomic p-adic heights of P. Resp. the value of the associated bilinear form at (P,Q)."},
 {"ellpadicheightmatrix",0,(void*)ellpadicheightmatrix,5,"GGLG","ellpadicheightmatrix(E,p,n,v): gives the height-pairing matrix for vector of points v on elliptic curve E."},
@@ -378,15 +379,15 @@ entree functions_basic[]={
 {"ellzeta",0,(void*)ellzeta,5,"GDGp","ellzeta(w,{z='x}): computes the value at z of the Weierstrass Zeta function attached to the lattice w, as given by ellperiods(,1)."},
 {"ellztopoint",0,(void*)pointell,5,"GGp","ellztopoint(E,z): coordinates of point P on the curve E corresponding to the complex number z."},
 {"erfc",0,(void*)gerfc,3,"Gp","erfc(x): complementary error function."},
-{"errname",0,(void*)errname,14,"G","errname(E): returns the type of the error message E."},
-{"error",0,(void*)error0,14,"vs*","error({str}*): abort script with error message str."},
+{"errname",0,(void*)errname,15,"G","errname(E): returns the type of the error message E."},
+{"error",0,(void*)error0,15,"vs*","error({str}*): abort script with error message str."},
 {"eta",0,(void*)eta0,3,"GD0,L,p","eta(z,{flag=0}): if flag=0, returns prod(n=1,oo, 1-q^n), where q = exp(2 i Pi z) if z is a complex scalar (belonging to the upper half plane); q = z if z is a p-adic number or can be converted to a power series. If flag is non-zero, the function only applies to complex scalars and returns the true eta function, with the factor q^(1/24) included."},
 {"eulerphi",0,(void*)eulerphi,4,"G","eulerphi(x): Euler's totient function of x."},
-{"eval",0,(void*)geval_gp,10,"GC","eval(x): evaluation of x, replacing variables by their value."},
+{"eval",0,(void*)geval_gp,11,"GC","eval(x): evaluation of x, replacing variables by their value."},
 {"exp",0,(void*)gexp,3,"Gp","exp(x): exponential of x."},
 {"expm1",0,(void*)gexpm1,3,"Gp","expm1(x): exp(x)-1."},
-{"extern",0,(void*)gpextern,14,"s","extern(str): execute shell command str, and feeds the result to GP (as if loading from file)."},
-{"externstr",0,(void*)externstr,14,"s","externstr(str): execute shell command str, and returns the result as a vector of GP strings, one component per output line."},
+{"extern",0,(void*)gpextern,15,"s","extern(str): execute shell command str, and feeds the result to GP (as if loading from file)."},
+{"externstr",0,(void*)externstr,15,"s","externstr(str): execute shell command str, and returns the result as a vector of GP strings, one component per output line."},
 {"factor",0,(void*)gp_factor0,4,"GDG","factor(x,{lim}): factorization of x. lim is optional and can be set whenever x is of (possibly recursive) rational type. If lim is set return partial factorization, using primes < lim."},
 {"factorback",0,(void*)factorback2,4,"GDG","factorback(f,{e}): given a factorisation f, gives the factored object back. If this is a prime ideal factorisation you must supply the corresponding number field as last argument. If e is present, f has to be a vector of the same length, and we return the product of the f[i]^e[i]."},
 {"factorcantor",0,(void*)factcantor,4,"GG","factorcantor(x,p): factorization mod p of the polynomial x using Cantor-Zassenhaus."},
@@ -394,8 +395,8 @@ entree functions_basic[]={
 {"factorial",0,(void*)mpfactr,4,"Lp","factorial(x): factorial of x, the result being given as a real number."},
 {"factorint",0,(void*)factorint,4,"GD0,L,","factorint(x,{flag=0}): factor the integer x. flag is optional, whose binary digits mean 1: avoid MPQS, 2: avoid first-stage ECM (may fall back on it later), 4: avoid Pollard-Brent Rho and Shanks SQUFOF, 8: skip final ECM (huge composites will be declared prime)."},
 {"factormod",0,(void*)factormod0,4,"GGD0,L,","factormod(x,p,{flag=0}): factors the polynomial x modulo the prime p, using Berlekamp. flag is optional, and can be 0: default or 1: only the degrees of the irreducible factors are given."},
-{"factornf",0,(void*)polfnf,8,"GG","factornf(x,t): factorization of the polynomial x over the number field defined by the polynomial t."},
-{"factorpadic",0,(void*)factorpadic,10,"GGL","factorpadic(pol,p,r): p-adic factorization of the polynomial pol to precision r."},
+{"factornf",0,(void*)polfnf,9,"GG","factornf(x,t): factorization of the polynomial x over the number field defined by the polynomial t."},
+{"factorpadic",0,(void*)factorpadic,11,"GGL","factorpadic(pol,p,r): p-adic factorization of the polynomial pol to precision r."},
 {"ffgen",0,(void*)ffgen,4,"GDn","ffgen(q,{v}): return a generator X mod P(X) for the finite field with q elements. If v is given, the variable name is used to display g, else the variable 'x' is used. Alternative syntax, q = P(X) an irreducible polynomial with t_INTMOD coefficients, return the generator X mod P(X) of the finite field defined by P. If v is given, the variable name is used to display g, else the variable of the polynomial P is used."},
 {"ffinit",0,(void*)ffinit,4,"GLDn","ffinit(p,n,{v='x}): monic irreducible polynomial of degree n over F_p[v]."},
 {"fflog",0,(void*)fflog,4,"GGDG","fflog(x,g,{o}): return the discrete logarithm of the finite field element x in base g. If present, o must represents the multiplicative order of g. If no o is given, assume that g is a primitive root."},
@@ -404,94 +405,94 @@ entree functions_basic[]={
 {"ffprimroot",0,(void*)ffprimroot,4,"GD&","ffprimroot(x, {&o}): return a primitive root of the multiplicative group of the definition field of the finite field element x (not necessarily the same as the field generated by x). If present, o is set to [ord, fa], where ord is the order of the group, and fa its factorization (useful in fflog and fforder)."},
 {"fibonacci",0,(void*)fibo,4,"L","fibonacci(x): fibonacci number of index x (x C-integer)."},
 {"floor",0,(void*)gfloor,2,"G","floor(x): floor of x = largest integer <= x."},
-{"fold",0,(void*)fold0,14,"GG","fold(f, A): return f(...f(f(A[1],A[2]),A[3]),...,A[#A])"},
-{"for",0,(void*)forpari,14,"vV=GGI","for(X=a,b,seq): the sequence is evaluated, X going from a up to b."},
-{"forcomposite",0,(void*)forcomposite,14,"vV=GDGI","forcomposite(n=a,{b},seq): the sequence is evaluated, n running over the composite numbers between a and b. Omitting b runs through composites >= a"},
-{"fordiv",0,(void*)fordiv,14,"vGVI","fordiv(n,X,seq): the sequence is evaluated, X running over the divisors of n."},
-{"forell",0,(void*)forell0,14,"vVLLID0,L,","forell(E,a,b,seq,{flag=0}): execute seq for each elliptic curves E of conductor between a and b in the elldata database. If flag is non-zero, select only the first curve in each isogeny class"},
-{"forpart",0,(void*)forpart0,14,"vV=GIDGDG","forpart(X=k,seq,{a=k},{n=k}): evaluate seq where the Vecsmall X goes over the partitions of k. Optional parameter n (n=nmax or n=[nmin,nmax]) restricts the length of the partition. Optional parameter a (a=amax or a=[amin,amax]) restricts the range of the parts. Zeros are removed unless one sets amin=0 to get X of fixed length nmax (=k by default)."},
-{"forprime",0,(void*)forprime,14,"vV=GDGI","forprime(p=a,{b},seq): the sequence is evaluated, p running over the primes between a and b. Omitting b runs through primes >= a"},
-{"forqfvec",0,(void*)forqfvec0,11,"vVGDGI","forqfvec(v,q,b,expr): q being a square and symmetric integral matrix representing an positive definite quadratic form, evaluate expr for all vectors v such that q(v)<=b."},
-{"forstep",0,(void*)forstep,14,"vV=GGGI","forstep(X=a,b,s,seq): the sequence is evaluated, X going from a to b in steps of s (can be a vector of steps)."},
-{"forsubgroup",0,(void*)forsubgroup0,14,"vV=GDGI","forsubgroup(H=G,{bound},seq): execute seq for each subgroup H of the abelian group G, whose index is bounded by bound if not omitted. H is given as a left divisor of G in HNF form."},
-{"forvec",0,(void*)forvec,14,"vV=GID0,L,","forvec(X=v,seq,{flag=0}): v being a vector of two-component vectors of length n, the sequence is evaluated with X[i] going from v[i][1] to v[i][2] for i=n,..,1 if flag is zero or omitted. If flag = 1 (resp. flag = 2), restrict to increasing (resp. strictly increasing) sequences."},
+{"fold",0,(void*)fold0,15,"GG","fold(f, A): return f(...f(f(A[1],A[2]),A[3]),...,A[#A])"},
+{"for",0,(void*)forpari,15,"vV=GGI","for(X=a,b,seq): the sequence is evaluated, X going from a up to b. If b is set to +oo, the loop will not stop."},
+{"forcomposite",0,(void*)forcomposite,15,"vV=GDGI","forcomposite(n=a,{b},seq): the sequence is evaluated, n running over the composite numbers between a and b. Omitting b runs through composites >= a"},
+{"fordiv",0,(void*)fordiv,15,"vGVI","fordiv(n,X,seq): the sequence is evaluated, X running over the divisors of n."},
+{"forell",0,(void*)forell0,15,"vVLLID0,L,","forell(E,a,b,seq,{flag=0}): execute seq for each elliptic curves E of conductor between a and b in the elldata database. If flag is non-zero, select only the first curve in each isogeny class"},
+{"forpart",0,(void*)forpart0,15,"vV=GIDGDG","forpart(X=k,seq,{a=k},{n=k}): evaluate seq where the Vecsmall X goes over the partitions of k. Optional parameter n (n=nmax or n=[nmin,nmax]) restricts the length of the partition. Optional parameter a (a=amax or a=[amin,amax]) restricts the range of the parts. Zeros are removed unless one sets amin=0 to get X of fixed length nmax (=k by default)."},
+{"forprime",0,(void*)forprime,15,"vV=GDGI","forprime(p=a,{b},seq): the sequence is evaluated, p running over the primes between a and b. Omitting b runs through primes >= a"},
+{"forqfvec",0,(void*)forqfvec0,12,"vVGDGI","forqfvec(v,q,b,expr): q being a square and symmetric integral matrix representing an positive definite quadratic form, evaluate expr for all vectors v such that q(v)<=b."},
+{"forstep",0,(void*)forstep,15,"vV=GGGI","forstep(X=a,b,s,seq): the sequence is evaluated, X going from a to b in steps of s (can be a vector of steps). If b is set to +oo the loop will not stop."},
+{"forsubgroup",0,(void*)forsubgroup0,15,"vV=GDGI","forsubgroup(H=G,{bound},seq): execute seq for each subgroup H of the abelian group G, whose index is bounded by bound if not omitted. H is given as a left divisor of G in HNF form."},
+{"forvec",0,(void*)forvec,15,"vV=GID0,L,","forvec(X=v,seq,{flag=0}): v being a vector of two-component vectors of length n, the sequence is evaluated with X[i] going from v[i][1] to v[i][2] for i=n,..,1 if flag is zero or omitted. If flag = 1 (resp. flag = 2), restrict to increasing (resp. strictly increasing) sequences."},
 {"frac",0,(void*)gfrac,2,"G","frac(x): fractional part of x = x-floor(x)."},
 {"fromdigits",0,(void*)fromdigits,2,"GDG","fromdigits(x,{b=10}): gives the integer formed by the elements of x seen as the digits of a number in base b."},
-{"galoisexport",0,(void*)galoisexport,8,"GD0,L,","galoisexport(gal,{flag}): gal being a Galois group as output by galoisinit, output a string representing the underlying permutation group in GAP notation (default) or Magma notation (flag = 1)."},
-{"galoisfixedfield",0,(void*)galoisfixedfield,8,"GGD0,L,Dn","galoisfixedfield(gal,perm,{flag},{v=y}): gal being a Galois group as output by galoisinit and perm a subgroup, an element of gal.group or a vector of such elements, return [P,x] such that P is a polynomial defining the fixed field of gal[1] by the subgroup generated by perm, and x is a root of P in gal expressed as a polmod in gal.pol. If flag is 1 return only P. If flag is 2 return [P,x,F] where F is the factorization of gal.p [...]
-{"galoisgetpol",0,(void*)galoisgetpol,8,"LD0,L,D1,L,","galoisgetpol(a,{b},{s}): Query the galpol package for a polynomial with Galois group isomorphic to GAP4(a,b), totally real if s=1 (default) and totally complex if s=2.  The output is a vector [pol, den] where pol is the polynomial and den is the common denominator of the conjugates expressed as a polynomial in a root of pol. If b and s are omitted, return the number of isomorphism classes of groups of order a."},
-{"galoisidentify",0,(void*)galoisidentify,8,"G","galoisidentify(gal): gal being a Galois group as output by galoisinit, output the isomorphism class of the underlying abstract group as a two-components vector [o,i], where o is the group order, and i is the group index in the GAP4 small group library."},
-{"galoisinit",0,(void*)galoisinit,8,"GDG","galoisinit(pol,{den}): pol being a polynomial or a number field as output by nfinit defining a Galois extension of Q, compute the Galois group and all necessary information for computing fixed fields. den is optional and has the same meaning as in nfgaloisconj(,4)(see manual)."},
-{"galoisisabelian",0,(void*)galoisisabelian,8,"GD0,L,","galoisisabelian(gal,{flag=0}): gal being as output by galoisinit, return 0 if gal is not abelian, the HNF matrix of gal over gal.gen if flag=0, 1 if flag is 1, and the SNF of gal is flag=2."},
-{"galoisisnormal",0,(void*)galoisisnormal,8,"lGG","galoisisnormal(gal,subgrp): gal being as output by galoisinit, and subgrp a subgroup of gal as output by galoissubgroups, return 1 if subgrp is a normal subgroup of gal, else return 0."},
-{"galoispermtopol",0,(void*)galoispermtopol,8,"GG","galoispermtopol(gal,perm): gal being a Galois group as output by galoisinit and perm a element of gal.group, return the polynomial defining the corresponding Galois automorphism."},
-{"galoissubcyclo",0,(void*)galoissubcyclo,8,"GDGD0,L,Dn","galoissubcyclo(N,H,{fl=0},{v}):Compute a polynomial (in variable v) defining the subfield of Q(zeta_n) fixed by the subgroup H of (Z/nZ)*. N can be an integer n, znstar(n) or bnrinit(bnfinit(y),[n,[1]],1). H can be given by a generator, a set of generator given by a vector or a HNF matrix (see manual). If flag is 1, output only the conductor of the abelian extension. If flag is 2 output [pol,f] where pol is the polynomial and f th [...]
-{"galoissubfields",0,(void*)galoissubfields,8,"GD0,L,Dn","galoissubfields(G,{flags=0},{v}):Output all the subfields of G. flags have the same meaning as for galoisfixedfield."},
-{"galoissubgroups",0,(void*)galoissubgroups,8,"G","galoissubgroups(G):Output all the subgroups of G."},
+{"galoisexport",0,(void*)galoisexport,9,"GD0,L,","galoisexport(gal,{flag}): gal being a Galois group as output by galoisinit, output a string representing the underlying permutation group in GAP notation (default) or Magma notation (flag = 1)."},
+{"galoisfixedfield",0,(void*)galoisfixedfield,9,"GGD0,L,Dn","galoisfixedfield(gal,perm,{flag},{v=y}): gal being a Galois group as output by galoisinit and perm a subgroup, an element of gal.group or a vector of such elements, return [P,x] such that P is a polynomial defining the fixed field of gal[1] by the subgroup generated by perm, and x is a root of P in gal expressed as a polmod in gal.pol. If flag is 1 return only P. If flag is 2 return [P,x,F] where F is the factorization of gal.p [...]
+{"galoisgetpol",0,(void*)galoisgetpol,9,"LD0,L,D1,L,","galoisgetpol(a,{b},{s}): Query the galpol package for a polynomial with Galois group isomorphic to GAP4(a,b), totally real if s=1 (default) and totally complex if s=2.  The output is a vector [pol, den] where pol is the polynomial and den is the common denominator of the conjugates expressed as a polynomial in a root of pol. If b and s are omitted, return the number of isomorphism classes of groups of order a."},
+{"galoisidentify",0,(void*)galoisidentify,9,"G","galoisidentify(gal): gal being a Galois group as output by galoisinit, output the isomorphism class of the underlying abstract group as a two-components vector [o,i], where o is the group order, and i is the group index in the GAP4 small group library."},
+{"galoisinit",0,(void*)galoisinit,9,"GDG","galoisinit(pol,{den}): pol being a polynomial or a number field as output by nfinit defining a Galois extension of Q, compute the Galois group and all necessary information for computing fixed fields. den is optional and has the same meaning as in nfgaloisconj(,4)(see manual)."},
+{"galoisisabelian",0,(void*)galoisisabelian,9,"GD0,L,","galoisisabelian(gal,{flag=0}): gal being as output by galoisinit, return 0 if gal is not abelian, the HNF matrix of gal over gal.gen if flag=0, 1 if flag is 1, and the SNF of gal is flag=2."},
+{"galoisisnormal",0,(void*)galoisisnormal,9,"lGG","galoisisnormal(gal,subgrp): gal being as output by galoisinit, and subgrp a subgroup of gal as output by galoissubgroups, return 1 if subgrp is a normal subgroup of gal, else return 0."},
+{"galoispermtopol",0,(void*)galoispermtopol,9,"GG","galoispermtopol(gal,perm): gal being a Galois group as output by galoisinit and perm a element of gal.group, return the polynomial defining the corresponding Galois automorphism."},
+{"galoissubcyclo",0,(void*)galoissubcyclo,9,"GDGD0,L,Dn","galoissubcyclo(N,H,{fl=0},{v}):Compute a polynomial (in variable v) defining the subfield of Q(zeta_n) fixed by the subgroup H of (Z/nZ)*. N can be an integer n, znstar(n) or bnrinit(bnfinit(y),[n,[1]],1). H can be given by a generator, a set of generator given by a vector or a HNF matrix (see manual). If flag is 1, output only the conductor of the abelian extension. If flag is 2 output [pol,f] where pol is the polynomial and f th [...]
+{"galoissubfields",0,(void*)galoissubfields,9,"GD0,L,Dn","galoissubfields(G,{flag=0},{v}): Output all the subfields of G. flag has the same meaning as for galoisfixedfield."},
+{"galoissubgroups",0,(void*)galoissubgroups,9,"G","galoissubgroups(G):Output all the subgroups of G."},
 {"gamma",0,(void*)ggamma,3,"Gp","gamma(s): gamma function at s, a complex or p-adic number, or a series."},
 {"gammah",0,(void*)ggammah,3,"Gp","gammah(x): gamma of x+1/2 (x integer)."},
-{"gammamellininv",0,(void*)gammamellininv_bitprec,3,"GGD0,L,b","gammamellininv(G,t,{m=0}): returns G(t), where G is as output by gammamellininvinit. The alternative syntax gammamellininv(A,t,m) is also available."},
+{"gammamellininv",0,(void*)gammamellininv,3,"GGD0,L,b","gammamellininv(G,t,{m=0}): returns G(t), where G is as output by gammamellininvinit. The alternative syntax gammamellininv(A,t,m) is also available."},
 {"gammamellininvasymp",0,(void*)gammamellininvasymp,3,"GDPD0,L,","gammamellininvasymp(A,n,{m=0}): return the first n terms of the asymptotic expansion at infinity of the m-th derivative K^m(t) of the inverse Mellin transform of the function f(s)=Gamma_R(s+a_1)*...*Gamma_R(s+a_d), where Vga is the vector [a_1,...,a_d] and Gamma_R(s)=Pi^(-s/2)*gamma(s/2). The result is a vector [M[1]...M[n]] with M[1]=1, such that K^m(t) = \\sqrt{2^{d+1}/d}t^{a+m(2/d-1)}e^{-d pi t^{2/d}}\\sum_{n\\ge0}M[n+1 [...]
-{"gammamellininvinit",0,(void*)gammamellininvinit_bitprec,3,"GD0,L,b","gammamellininvinit(A,{m=0}): initialize data for the computation by gammamellininv() of the m-th derivative of the inverse Mellin transform of the function f(s) = Gamma_R(s+a1)*...*Gamma_R(s+ad), where A is the vector [a1,...,ad] and Gamma_R(s) = Pi^(-s/2)*gamma(s/2)."},
+{"gammamellininvinit",0,(void*)gammamellininvinit,3,"GD0,L,b","gammamellininvinit(A,{m=0}): initialize data for the computation by gammamellininv() of the m-th derivative of the inverse Mellin transform of the function f(s) = Gamma_R(s+a1)*...*Gamma_R(s+ad), where A is the vector [a1,...,ad] and Gamma_R(s) = Pi^(-s/2)*gamma(s/2)."},
 {"gcd",0,(void*)ggcd0,4,"GDG","gcd(x,{y}): greatest common divisor of x and y."},
 {"gcdext",0,(void*)gcdext0,4,"GG","gcdext(x,y): returns [u,v,d] such that d=gcd(x,y) and u*x+v*y=d."},
 {"genus2red",0,(void*)genus2red,5,"GDG","genus2red(P,{p}): let P be a polynomial with rational coefficients. Determines the reduction at p > 2 of the (proper, smooth) hyperelliptic curve C/Q: y^2 = P, of genus 2. (The special fiber X_p of the minimal regular model X of C over Z.)"},
-{"getabstime",0,(void*)getabstime,14,"l","getabstime(): time (in milliseconds) since startup."},
-{"getenv",0,(void*)gp_getenv,14,"s","getenv(s): value of the environment variable s, 0 if it is not defined."},
-{"getheap",0,(void*)getheap,14,"","getheap(): 2-component vector giving the current number of objects in the heap and the space they occupy (in long words)."},
-{"getrand",0,(void*)getrand,14,"","getrand(): current value of random number seed."},
-{"getstack",0,(void*)getstack,14,"l","getstack(): current value of stack pointer avma."},
-{"gettime",0,(void*)gettime,14,"l","gettime(): time (in milliseconds) since last call to gettime."},
-{"getwalltime",0,(void*)getwalltime,14,"","getwalltime(): time (in milliseconds) since the UNIX Epoch."},
-{"global",0,NULL,14,NULL,"global(list of variables): obsolete. Scheduled for deletion."},
+{"getabstime",0,(void*)getabstime,15,"l","getabstime(): time (in milliseconds) since startup."},
+{"getenv",0,(void*)gp_getenv,15,"s","getenv(s): value of the environment variable s, 0 if it is not defined."},
+{"getheap",0,(void*)getheap,15,"","getheap(): 2-component vector giving the current number of objects in the heap and the space they occupy (in long words)."},
+{"getrand",0,(void*)getrand,15,"","getrand(): current value of random number seed."},
+{"getstack",0,(void*)getstack,15,"l","getstack(): current value of stack pointer avma."},
+{"gettime",0,(void*)gettime,15,"l","gettime(): time (in milliseconds) since last call to gettime."},
+{"getwalltime",0,(void*)getwalltime,15,"","getwalltime(): time (in milliseconds) since the UNIX Epoch."},
+{"global",0,NULL,15,NULL,"global(list of variables): obsolete. Scheduled for deletion."},
 {"hammingweight",0,(void*)hammingweight,2,"lG","hammingweight(x): returns the Hamming weight of x."},
 {"hilbert",0,(void*)hilbert,4,"lGGDG","hilbert(x,y,{p}): Hilbert symbol at p of x,y."},
 {"hyperellcharpoly",0,(void*)hyperellcharpoly,5,"G","hyperellcharpoly(X): X being a non-singular hyperelliptic curve defined over a finite field, return the characteristic polynomial of the Frobenius automorphism.  X can be given either by a squarefree polynomial P such that X:y^2=P(x) or by a vector [P,Q] such that X:y^2+Q(x)*y=P(x) and Q^2+4P is squarefree."},
-{"hyperellpadicfrobenius",0,(void*)hyperellpadicfrobenius,5,"GUL","hyperellpadicfrobenius(Q,p,n): Q being a  rational polynomial of degree d, return the matrix of the Frobenius at p>=d in the standard basis of H^1_dR(E) to absolute p-adic precision p^n."},
+{"hyperellpadicfrobenius",0,(void*)hyperellpadicfrobenius,5,"GUL","hyperellpadicfrobenius(Q,p,n): Q being a  rational polynomial of degree d and X being the curve defined by y^2=Q(x), return the matrix of the Frobenius at p>=d in the standard basis of H^1_dR(X) to absolute p-adic precision p^n."},
 {"hyperu",0,(void*)hyperu,3,"GGGp","hyperu(a,b,x): U-confluent hypergeometric function."},
-{"idealadd",0,(void*)idealadd,8,"GGG","idealadd(nf,x,y): sum of two ideals x and y in the number field defined by nf."},
-{"idealaddtoone",0,(void*)idealaddtoone0,8,"GGDG","idealaddtoone(nf,x,{y}): if y is omitted, when the sum of the ideals in the number field K defined by nf and given in the vector x is equal to Z_K, gives a vector of elements of the corresponding ideals who sum to 1. Otherwise, x and y are ideals, and if they sum up to 1, find one element in each of them such that the sum is 1."},
-{"idealappr",0,(void*)idealappr0,8,"GGD0,L,","idealappr(nf,x,{flag=0}): x being a fractional ideal, gives an element b such that v_p(b)=v_p(x) for all prime ideals p dividing x, and v_p(b)>=0 for all other p. If (optional) flag is non-null x must be a prime ideal factorization with possibly zero exponents."},
-{"idealchinese",0,(void*)idealchinese,8,"GGDG","idealchinese(nf,x,{y}): x being a prime ideal factorization and y a vector of elements, gives an element b such that v_p(b-y_p)>=v_p(x) for all prime ideals p dividing x, and v_p(b)>=0 for all other p. If y is omitted, return a data structure which can be used in place of x in later calls."},
-{"idealcoprime",0,(void*)idealcoprime,8,"GGG","idealcoprime(nf,x,y): gives an element b in nf such that b. x is an integral ideal coprime to the integral ideal y."},
-{"idealdiv",0,(void*)idealdiv0,8,"GGGD0,L,","idealdiv(nf,x,y,{flag=0}): quotient x/y of two ideals x and y in HNF in the number field nf. If (optional) flag is non-null, the quotient is supposed to be an integral ideal (slightly faster)."},
-{"idealfactor",0,(void*)idealfactor,8,"GG","idealfactor(nf,x): factorization of the ideal x given in HNF into prime ideals in the number field nf."},
-{"idealfactorback",0,(void*)idealfactorback,8,"GGDGD0,L,","idealfactorback(nf,f,{e},{flag = 0}): given a factorisation f, gives the ideal product back. If e is present, f has to be a vector of the same length, and we return the product of the f[i]^e[i]. If flag is non-zero, perform idealred along the way."},
-{"idealfrobenius",0,(void*)idealfrobenius,8,"GGG","idealfrobenius(nf,gal,pr): Returns the Frobenius element (pr|nf/Q) associated with the unramified prime ideal pr in prid format, in the Galois group gal of the number field nf."},
-{"idealhnf",0,(void*)idealhnf0,8,"GGDG","idealhnf(nf,u,{v}): hermite normal form of the ideal u in the number field nf if v is omitted. If called as idealhnf(nf,u,v), the ideal is given as uZ_K + vZ_K in the number field K defined by nf."},
-{"idealintersect",0,(void*)idealintersect,8,"GGG","idealintersect(nf,A,B): intersection of two ideals A and B in the number field defined by nf."},
-{"idealinv",0,(void*)idealinv,8,"GG","idealinv(nf,x): inverse of the ideal x in the number field nf."},
-{"ideallist",0,(void*)ideallist0,8,"GLD4,L,","ideallist(nf,bound,{flag=4}): vector of vectors L of all idealstar of all ideals of norm<=bound. If (optional) flag is present, its binary digits are toggles meaning 1: give generators; 2: add units; 4: give only the ideals and not the bid."},
-{"ideallistarch",0,(void*)ideallistarch,8,"GGG","ideallistarch(nf,list,arch): list is a vector of vectors of of bid's as output by ideallist. Return a vector of vectors with the same number of components as the original list. The leaves give information about moduli whose finite part is as in original list, in the same order, and Archimedean part is now arch. The information contained is of the same kind as was present in the input."},
-{"ideallog",0,(void*)ideallog,8,"DGGG","ideallog({nf},x,bid): if bid is a big ideal, as given by idealstar(nf,D,...), gives the vector of exponents on the generators bid.gen (even if these generators have not been explicitly computed)."},
-{"idealmin",0,(void*)idealmin,8,"GGDG","idealmin(nf,ix,{vdir}): pseudo-minimum of the ideal ix in the direction vdir in the number field nf."},
-{"idealmul",0,(void*)idealmul0,8,"GGGD0,L,","idealmul(nf,x,y,{flag=0}): product of the two ideals x and y in the number field nf. If (optional) flag is non-nul, reduce the result."},
-{"idealnorm",0,(void*)idealnorm,8,"GG","idealnorm(nf,x): norm of the ideal x in the number field nf."},
-{"idealnumden",0,(void*)idealnumden,8,"GG","idealnumden(nf,x): returns [A,B], where A,B are coprime integer ideals such that x = A/B"},
-{"idealpow",0,(void*)idealpow0,8,"GGGD0,L,","idealpow(nf,x,k,{flag=0}): k-th power of the ideal x in HNF in the number field nf. If (optional) flag is non-null, reduce the result."},
-{"idealprimedec",0,(void*)idealprimedec_limit_f,8,"GGD0,L,","idealprimedec(nf,p,{f=0}): prime ideal decomposition of the prime number p in the number field nf as a vector of 5 component vectors [p,a,e,f,b] representing the prime ideals pZ_K+a. Z_K, e,f as usual, a as vector of components on the integral basis, b Lenstra's constant. If f is present and non-zero, restrict the result to primes of residue degree <= f."},
-{"idealprincipalunits",0,(void*)idealprincipalunits,8,"GGL","idealprincipalunits(nf,pr,k): returns the structure [no, cyc, gen] of the multiplicative group (1 + pr) / (1 + pr^k)^*."},
-{"idealramgroups",0,(void*)idealramgroups,8,"GGG","idealramgroups(nf,gal,pr): let pr be a prime ideal in prid format, and gal the Galois group of the number field nf, return a vector g such that g[1] is the decomposition group of pr, g[2] is the inertia group, g[i] is the (i-2)th ramification group of pr, all trivial subgroups being omitted."},
-{"idealred",0,(void*)idealred0,8,"GGDG","idealred(nf,I,{v=0}): LLL reduction of the ideal I in the number field nf along direction v, in HNF."},
-{"idealstar",0,(void*)idealstar0,8,"DGGD1,L,","idealstar({nf},N,{flag=1}): gives the structure of (Z_K/N)^*, where N is a modulus (an ideal in any form or a vector [f0, foo], where f0 is an ideal and foo is a {0,1}-vector with r1 components. flag is optional, and can be 0: simply gives the structure as an abelian group, i.e. a 3-component vector [h,d,g] where h is the order, d the orders of the cyclic factors and g the generators; if flag=1 (default), gives a bid structure used in ideall [...]
-{"idealtwoelt",0,(void*)idealtwoelt0,8,"GGDG","idealtwoelt(nf,x,{a}): two-element representation of an ideal x in the number field nf. If (optional) a is non-zero, first element will be equal to a."},
-{"idealval",0,(void*)gpidealval,8,"GGG","idealval(nf,x,pr): valuation at pr given in idealprimedec format of the ideal x in the number field nf."},
-{"if",0,(void*)ifpari,14,"GDEDE","if(a,{seq1},{seq2}): if a is nonzero, seq1 is evaluated, otherwise seq2. seq1 and seq2 are optional, and if seq2 is omitted, the preceding comma can be omitted also."},
-{"iferr",0,(void*)iferrpari,14,"EVEDE","iferr(seq1,E,seq2{,pred}): evaluates the expression sequence seq1. If an error occurs, set the formal parameter E set to the error data. If pred is not present or evaluates to true, catch the error and evaluate seq2. Both pred and seq2 can reference E."},
+{"idealadd",0,(void*)idealadd,9,"GGG","idealadd(nf,x,y): sum of two ideals x and y in the number field defined by nf."},
+{"idealaddtoone",0,(void*)idealaddtoone0,9,"GGDG","idealaddtoone(nf,x,{y}): if y is omitted, when the sum of the ideals in the number field K defined by nf and given in the vector x is equal to Z_K, gives a vector of elements of the corresponding ideals who sum to 1. Otherwise, x and y are ideals, and if they sum up to 1, find one element in each of them such that the sum is 1."},
+{"idealappr",0,(void*)idealappr0,9,"GGD0,L,","idealappr(nf,x,{flag=0}): x being a fractional ideal, gives an element b such that v_p(b)=v_p(x) for all prime ideals p dividing x, and v_p(b)>=0 for all other p. If (optional) flag is non-null x must be a prime ideal factorization with possibly zero exponents."},
+{"idealchinese",0,(void*)idealchinese,9,"GGDG","idealchinese(nf,x,{y}): x being a prime ideal factorization and y a vector of elements, gives an element b such that v_p(b-y_p)>=v_p(x) for all prime ideals p dividing x, and v_p(b)>=0 for all other p. If y is omitted, return a data structure which can be used in place of x in later calls."},
+{"idealcoprime",0,(void*)idealcoprime,9,"GGG","idealcoprime(nf,x,y): gives an element b in nf such that b. x is an integral ideal coprime to the integral ideal y."},
+{"idealdiv",0,(void*)idealdiv0,9,"GGGD0,L,","idealdiv(nf,x,y,{flag=0}): quotient x/y of two ideals x and y in HNF in the number field nf. If (optional) flag is non-null, the quotient is supposed to be an integral ideal (slightly faster)."},
+{"idealfactor",0,(void*)idealfactor,9,"GG","idealfactor(nf,x): factorization of the ideal x given in HNF into prime ideals in the number field nf."},
+{"idealfactorback",0,(void*)idealfactorback,9,"GGDGD0,L,","idealfactorback(nf,f,{e},{flag = 0}): given a factorisation f, gives the ideal product back. If e is present, f has to be a vector of the same length, and we return the product of the f[i]^e[i]. If flag is non-zero, perform idealred along the way."},
+{"idealfrobenius",0,(void*)idealfrobenius,9,"GGG","idealfrobenius(nf,gal,pr): Returns the Frobenius element (pr|nf/Q) associated with the unramified prime ideal pr in prid format, in the Galois group gal of the number field nf."},
+{"idealhnf",0,(void*)idealhnf0,9,"GGDG","idealhnf(nf,u,{v}): hermite normal form of the ideal u in the number field nf if v is omitted. If called as idealhnf(nf,u,v), the ideal is given as uZ_K + vZ_K in the number field K defined by nf."},
+{"idealintersect",0,(void*)idealintersect,9,"GGG","idealintersect(nf,A,B): intersection of two ideals A and B in the number field defined by nf."},
+{"idealinv",0,(void*)idealinv,9,"GG","idealinv(nf,x): inverse of the ideal x in the number field nf."},
+{"ideallist",0,(void*)ideallist0,9,"GLD4,L,","ideallist(nf,bound,{flag=4}): vector of vectors L of all idealstar of all ideals of norm<=bound. If (optional) flag is present, its binary digits are toggles meaning 1: give generators; 2: add units; 4: give only the ideals and not the bid."},
+{"ideallistarch",0,(void*)ideallistarch,9,"GGG","ideallistarch(nf,list,arch): list is a vector of vectors of bid's as output by ideallist. Return a vector of vectors with the same number of components as the original list. The leaves give information about moduli whose finite part is as in original list, in the same order, and Archimedean part is now arch. The information contained is of the same kind as was present in the input."},
+{"ideallog",0,(void*)ideallog,9,"DGGG","ideallog({nf},x,bid): if bid is a big ideal, as given by idealstar(nf,D,...), gives the vector of exponents on the generators bid.gen (even if these generators have not been explicitly computed)."},
+{"idealmin",0,(void*)idealmin,9,"GGDG","idealmin(nf,ix,{vdir}): pseudo-minimum of the ideal ix in the direction vdir in the number field nf."},
+{"idealmul",0,(void*)idealmul0,9,"GGGD0,L,","idealmul(nf,x,y,{flag=0}): product of the two ideals x and y in the number field nf. If (optional) flag is non-nul, reduce the result."},
+{"idealnorm",0,(void*)idealnorm,9,"GG","idealnorm(nf,x): norm of the ideal x in the number field nf."},
+{"idealnumden",0,(void*)idealnumden,9,"GG","idealnumden(nf,x): returns [A,B], where A,B are coprime integer ideals such that x = A/B"},
+{"idealpow",0,(void*)idealpow0,9,"GGGD0,L,","idealpow(nf,x,k,{flag=0}): k-th power of the ideal x in HNF in the number field nf. If (optional) flag is non-null, reduce the result."},
+{"idealprimedec",0,(void*)idealprimedec_limit_f,9,"GGD0,L,","idealprimedec(nf,p,{f=0}): prime ideal decomposition of the prime number p in the number field nf as a vector of 5 component vectors [p,a,e,f,b] representing the prime ideals pZ_K+a. Z_K, e,f as usual, a as vector of components on the integral basis, b Lenstra's constant. If f is present and non-zero, restrict the result to primes of residue degree <= f."},
+{"idealprincipalunits",0,(void*)idealprincipalunits,9,"GGL","idealprincipalunits(nf,pr,k): returns the structure [no, cyc, gen] of the multiplicative group (1 + pr) / (1 + pr^k)^*."},
+{"idealramgroups",0,(void*)idealramgroups,9,"GGG","idealramgroups(nf,gal,pr): let pr be a prime ideal in prid format, and gal the Galois group of the number field nf, return a vector g such that g[1] is the decomposition group of pr, g[2] is the inertia group, g[i] is the (i-2)th ramification group of pr, all trivial subgroups being omitted."},
+{"idealred",0,(void*)idealred0,9,"GGDG","idealred(nf,I,{v=0}): LLL reduction of the ideal I in the number field nf along direction v, in HNF."},
+{"idealstar",0,(void*)idealstar0,9,"DGGD1,L,","idealstar({nf},N,{flag=1}): gives the structure of (Z_K/N)^*, where N is a modulus (an ideal in any form or a vector [f0, foo], where f0 is an ideal and foo is a {0,1}-vector with r1 components. flag is optional, and can be 0: simply gives the structure as an abelian group, i.e. a 3-component vector [h,d,g] where h is the order, d the orders of the cyclic factors and g the generators; if flag=1 (default), gives a bid structure used in ideall [...]
+{"idealtwoelt",0,(void*)idealtwoelt0,9,"GGDG","idealtwoelt(nf,x,{a}): two-element representation of an ideal x in the number field nf. If (optional) a is non-zero, first element will be equal to a."},
+{"idealval",0,(void*)gpidealval,9,"GGG","idealval(nf,x,pr): valuation at pr given in idealprimedec format of the ideal x in the number field nf."},
+{"if",0,(void*)ifpari,15,"GDEDE","if(a,{seq1},{seq2}): if a is nonzero, seq1 is evaluated, otherwise seq2. seq1 and seq2 are optional, and if seq2 is omitted, the preceding comma can be omitted also."},
+{"iferr",0,(void*)iferrpari,15,"EVEDE","iferr(seq1,E,seq2{,pred}): evaluates the expression sequence seq1. If an error occurs, set the formal parameter E set to the error data. If pred is not present or evaluates to true, catch the error and evaluate seq2. Both pred and seq2 can reference E."},
 {"imag",0,(void*)gimag,2,"G","imag(x): imaginary part of x."},
 {"incgam",0,(void*)incgam0,3,"GGDGp","incgam(s,x,{g}): incomplete gamma function. g is optional and is the precomputed value of gamma(s)."},
 {"incgamc",0,(void*)incgamc,3,"GGp","incgamc(s,x): complementary incomplete gamma function."},
-{"inline",0,NULL,14,NULL,"inline(x,...,z): declares x,...,z as inline variables [EXPERIMENTAL]"},
-{"input",0,(void*)gp_input,14,"","input(): read an expression from the input file or standard input."},
-{"install",0,(void*)gpinstall,14,"vrrD\"\",r,D\"\",s,","install(name,code,{gpname},{lib}): load from dynamic library 'lib' the function 'name'. Assign to it the name 'gpname' in this GP session, with prototype 'code'. If 'lib' is omitted, all symbols known to gp (includes the whole 'libpari.so' and possibly others) are available. If 'gpname' is omitted, use 'name'."},
-{"intcirc",0,(void*)intcirc0,12,"V=GGEDGp","intcirc(X=a,R,expr,{tab}): numerical integration of expr on the circle |z-a|=R, divided by 2*I*Pi. tab is as in intnum."},
-{"intformal",0,(void*)integ,10,"GDn","intformal(x,{v}): formal integration of x with respect to v, or to the main variable of x if v is omitted."},
-{"intfuncinit",0,(void*)intfuncinit0,12,"V=GGED0,L,p","intfuncinit(t=a,b,f,{m=0}): initialize tables for integrations from a to b using a weight f(t). For integral transforms such as Fourier or Mellin transforms."},
-{"intnum",0,(void*)intnum0,12,"V=GGEDGp","intnum(X=a,b,expr,{tab}): numerical integration of expr from a to b with respect to X. Plus/minus infinity is coded as +oo/-oo. Finally tab is either omitted (let the program choose the integration step), a positive integer m (choose integration step 1/2^m), or data precomputed with intnuminit."},
-{"intnumgauss",0,(void*)intnumgauss0,12,"V=GGEDGp","intnumgauss(X=a,b,expr,{tab}): numerical integration of expr from a to b, a compact interval, with respect to X using Gauss-Legendre quadrature. tab is either omitted (and will be recomputed) or precomputed with intnumgaussinit."},
-{"intnumgaussinit",0,(void*)intnumgaussinit,12,"D0,L,p","intnumgaussinit({n}): initialize tables for n-point Gauss-Legendre integration on a compact interval."},
-{"intnuminit",0,(void*)intnuminit,12,"GGD0,L,p","intnuminit(a,b,{m=0}): initialize tables for integrations from a to b. See help for intnum for coding of a and b. Possible types: compact interval, semi-compact (one extremity at + or - infinity) or R, and very slowly, slowly or exponentially decreasing, or sine or cosine oscillating at infinities."},
-{"intnumromb",0,(void*)intnumromb0_bitprec,12,"V=GGED0,L,b","intnumromb(X=a,b,expr,{flag=0}): numerical integration of expr (smooth in ]a,b[) from a to b with respect to X. flag is optional and mean 0: default. expr can be evaluated exactly on [a,b]; 1: general function; 2: a or b can be plus or minus infinity (chosen suitably), but of same sign; 3: expr has only limits at a or b."},
+{"inline",0,NULL,15,NULL,"inline(x,...,z): declares x,...,z as inline variables [EXPERIMENTAL]"},
+{"input",0,(void*)gp_input,15,"","input(): read an expression from the input file or standard input."},
+{"install",0,(void*)gpinstall,15,"vrrD\"\",r,D\"\",s,","install(name,code,{gpname},{lib}): load from dynamic library 'lib' the function 'name'. Assign to it the name 'gpname' in this GP session, with prototype 'code'. If 'lib' is omitted, all symbols known to gp (includes the whole 'libpari.so' and possibly others) are available. If 'gpname' is omitted, use 'name'."},
+{"intcirc",0,(void*)intcirc0,13,"V=GGEDGp","intcirc(X=a,R,expr,{tab}): numerical integration of expr on the circle |z-a|=R, divided by 2*I*Pi. tab is as in intnum."},
+{"intformal",0,(void*)integ,11,"GDn","intformal(x,{v}): formal integration of x with respect to v, or to the main variable of x if v is omitted."},
+{"intfuncinit",0,(void*)intfuncinit0,13,"V=GGED0,L,p","intfuncinit(t=a,b,f,{m=0}): initialize tables for integrations from a to b using a weight f(t). For integral transforms such as Fourier or Mellin transforms."},
+{"intnum",0,(void*)intnum0,13,"V=GGEDGp","intnum(X=a,b,expr,{tab}): numerical integration of expr from a to b with respect to X. Plus/minus infinity is coded as +oo/-oo. Finally tab is either omitted (let the program choose the integration step), a positive integer m (choose integration step 1/2^m), or data precomputed with intnuminit."},
+{"intnumgauss",0,(void*)intnumgauss0,13,"V=GGEDGp","intnumgauss(X=a,b,expr,{tab}): numerical integration of expr from a to b, a compact interval, with respect to X using Gauss-Legendre quadrature. tab is either omitted (and will be recomputed) or precomputed with intnumgaussinit."},
+{"intnumgaussinit",0,(void*)intnumgaussinit,13,"D0,L,p","intnumgaussinit({n}): initialize tables for n-point Gauss-Legendre integration on a compact interval."},
+{"intnuminit",0,(void*)intnuminit,13,"GGD0,L,p","intnuminit(a,b,{m=0}): initialize tables for integrations from a to b. See help for intnum for coding of a and b. Possible types: compact interval, semi-compact (one extremity at + or - infinity) or R, and very slowly, slowly or exponentially decreasing, or sine or cosine oscillating at infinities."},
+{"intnumromb",0,(void*)intnumromb0_bitprec,13,"V=GGED0,L,b","intnumromb(X=a,b,expr,{flag=0}): numerical integration of expr (smooth in ]a,b[) from a to b with respect to X. flag is optional and mean 0: default. expr can be evaluated exactly on [a,b]; 1: general function; 2: a or b can be plus or minus infinity (chosen suitably), but of same sign; 3: expr has only limits at a or b."},
 {"isfundamental",0,(void*)isfundamental,4,"lG","isfundamental(x): true(1) if x is a fundamental discriminant (including 1), false(0) if not."},
 {"ispolygonal",0,(void*)ispolygonal,4,"lGGD&","ispolygonal(x,s,{&N}): true(1) if x is an s-gonal number, false(0) if not (s > 2). If N is given set it to n if x is the n-th s-gonal number."},
 {"ispower",0,(void*)ispower,4,"lGDGD&","ispower(x,{k},{&n}): if k > 0 is given, return true (1) if x is a k-th power, false (0) if not. If k is omitted, return the maximal k >= 2 such that x = n^k is a perfect power, or 0 if no such k exist. If n is present, and the function returns a non-zero result, set n to the k-th root of x."},
@@ -503,249 +504,260 @@ entree functions_basic[]={
 {"issquare",0,(void*)issquareall,4,"lGD&","issquare(x,{&n}): true(1) if x is a square, false(0) if not. If n is given puts the exact square root there if it was computed."},
 {"issquarefree",0,(void*)issquarefree,4,"lG","issquarefree(x): true(1) if x is squarefree, false(0) if not."},
 {"istotient",0,(void*)istotient,4,"lGD&","istotient(x,{&N}): true(1) if x = eulerphi(n) for some integer n, false(0) if not. If N is given, set N = n as well."},
-{"kill",0,(void*)kill0,14,"vr","kill(sym): restores the symbol sym to its ``undefined'' status and kill associated help messages."},
+{"kill",0,(void*)kill0,15,"vr","kill(sym): restores the symbol sym to its ``undefined'' status and kill associated help messages."},
 {"kronecker",0,(void*)kronecker,4,"lGG","kronecker(x,y): kronecker symbol (x/y)."},
 {"lambertw",0,(void*)glambertW,3,"Gp","lambertw(y): solution of the implicit equation x*exp(x)=y."},
 {"lcm",0,(void*)glcm0,4,"GDG","lcm(x,{y}): least common multiple of x and y, i.e. x*y / gcd(x,y) up to units."},
 {"length",0,(void*)glength,2,"lG","length(x): number of non code words in x, number of characters for a string."},
 {"lex",0,(void*)lexcmp,1,"iGG","lex(x,y): compare x and y lexicographically (1 if x>y, 0 if x=y, -1 if x<y)"},
-{"lfun",0,(void*)lfun0_bitprec,6,"GGD0,L,b","lfun(L,s,{D=0}): compute the L-function value L(s), or if D is set, the derivative of order D at s. L is either an Lmath, an Ldata or an Linit."},
-{"lfunabelianrelinit",0,(void*)lfunabelianrelinit_bitprec,6,"GGGGD0,L,b","lfunabelianrelinit(bnfL,bnfK,polrel,sdom,{der=0}): returns the  Linit structure associated to the Dedekind zeta function of the number field  L, given a subfield K such that L/K is abelian, where polrel defines  L over K. The priority of the variable  of bnfK must be lower than that of polrel; bnfL is the absolute polynomial  corresponding to polrel, and sdom and der are as in lfuninit."},
+{"lfun",0,(void*)lfun0,6,"GGD0,L,b","lfun(L,s,{D=0}): compute the L-function value L(s), or if D is set, the derivative of order D at s. L is either an Lmath, an Ldata or an Linit."},
+{"lfunabelianrelinit",0,(void*)lfunabelianrelinit,6,"GGGGD0,L,b","lfunabelianrelinit(bnfL,bnfK,polrel,sdom,{der=0}): returns the  Linit structure associated to the Dedekind zeta function of the number field  L, given a subfield K such that L/K is abelian, where polrel defines  L over K. The priority of the variable  of bnfK must be lower than that of polrel; bnfL is the absolute polynomial  corresponding to polrel, and sdom and der are as in lfuninit."},
 {"lfunan",0,(void*)lfunan,6,"GLp","lfunan(L,n): Compute the first n terms of the Dirichlet series  attached to the L-function given by L (Lmath, Ldata or Linit)."},
 {"lfunartin",0,(void*)lfunartin,6,"GGGL","lfunartin(nf,gal,M,n): returns the Ldata structure associated to the Artin L-function associated to the representation R of the Galois group of the extension K/Q, defined over the cyclotomic field Q(zeta_n), where nf is the nfinit structure associated to K, gal is the galoisinit structure associated to K/Q, and M is the vector of the image of the generators G.gen by R. The elements of M are matrices with polynomial entries, whose variable is unde [...]
-{"lfuncheckfeq",0,(void*)lfuncheckfeq_bitprec,6,"lGDGb","lfuncheckfeq(L,{t}): given an L-function (Lmath, Ldata or Linit), check whether the functional equation is satisfied. If the function has poles, the polar part must be specified. The program returns a bit accuracy which should be a large negative value close to the current bit accuracy. If t is given, it checks the functional equation for the theta function at t and 1/t."},
-{"lfunconductor",0,(void*)lfunconductor_bitprec,6,"GDGD0,L,b","lfunconductor(L,{ab=[1,10000]},{flag=0}): give the conductor  of the given L-function; ab = [a,b] is the interval where we expect  to find the conductor.  If flag=0 (default), give either the conductor found as an integer, or a  vector (possibly empty) of conductors found. If flag=1, same but give the  computed floating point approximations to the conductors found, without  rounding to integers.  If flag=2, give all the condu [...]
+{"lfuncheckfeq",0,(void*)lfuncheckfeq,6,"lGDGb","lfuncheckfeq(L,{t}): given an L-function (Lmath, Ldata or Linit), check whether the functional equation is satisfied. If the function has poles, the polar part must be specified. The program returns a bit accuracy which should be a large negative value close to the current bit accuracy. If t is given, it checks the functional equation for the theta function at t and 1/t."},
+{"lfunconductor",0,(void*)lfunconductor,6,"GDGD0,L,b","lfunconductor(L,{ab=[1,10000]},{flag=0}): give the conductor  of the given L-function; ab = [a,b] is the interval where we expect  to find the conductor.  If flag=0 (default), give either the conductor found as an integer, or a  vector (possibly empty) of conductors found. If flag=1, same but give the  computed floating point approximations to the conductors found, without  rounding to integers.  If flag=2, give all the conductors fo [...]
 {"lfuncost",0,(void*)lfuncost0,6,"GDGD0,L,b","lfuncost(L,{sdom},{der=0}): estimate the cost of running lfuninit(L,sdom,der) at current bit precision. Returns [t,b], to indicate that t coefficients a_n will be computed at bit accuracy b. Subsequent evaluation of lfun at s evaluates a polynomial of degree t at exp(h s). If L is already an Linit, then sdom and der are ignored."},
 {"lfuncreate",0,(void*)lfuncreate,6,"G","lfuncreate(obj): Given either an object such as a polynomial, elliptic curve, Dirichlet or Hecke character, eta quotient, etc., or an explicit 6 or 7 component vector [dir,real,Vga,k,N,eps,r], create the Ldata structure necessary for lfun computation."},
-{"lfundiv",0,(void*)lfundiv,6,"GGp","lfundiv(L1,L2): creates the Ldata structure (without  initialization) corresponding to the quotient of the Dirichlet series  given by L1 and L2."},
+{"lfundiv",0,(void*)lfundiv,6,"GGb","lfundiv(L1,L2): creates the Ldata structure (without  initialization) corresponding to the quotient of the Dirichlet series  given by L1 and L2."},
 {"lfunetaquo",0,(void*)lfunetaquo,6,"G","lfunetaquo(M): returns the Ldata structure associated to the modular form z->prod(i=1,#M[,1],eta(M[i,1]*z)^M[i,2])"},
-{"lfunhardy",0,(void*)lfunhardy_bitprec,6,"GGb","lfunhardy(L,t): Variant of the Hardy L-function corresponding to L, used for plotting on the critical line, see ??lfunhardy for the precise definition."},
-{"lfuninit",0,(void*)lfuninit0_bitprec,6,"GGD0,L,b","lfuninit(L,sdom,{der=0}): precompute data for evaluating the L-function given by 'L' (and its derivatives of order der, if set) in rectangular domain sdom = [center,w,h] centered on the real axis, |Re(s)-center| <= w, |Im(s)| <= h, where all three components of sdom are real and w,h are non-negative. The subdomain [k/2, 0, h] on the critical line can be encoded as [h] for brevity."},
-{"lfunlambda",0,(void*)lfunlambda0_bitprec,6,"GGD0,L,b","lfunlambda(L,s,{D=0}): compute the completed L function Lambda(s), or if D is set, the derivative of order D at s. L is either an Lmath, an Ldata or an Linit."},
-{"lfunmfpeters",0,(void*)lfunmfpeters_bitprec,6,"Gb","lfunmfpeters(L): L corresponding to a normalized  eigenform but NOT to the output of lfunsymsq, returns the Petersson  square of the form, computed using the symmetric square."},
-{"lfunmfspec",0,(void*)lfunmfspec_bitprec,6,"Gb","lfunmfspec(L): L corresponding to a modular form, returns  [valeven,valodd,omminus,omplus], where valeven (resp., valodd) is the vector  of even (resp., odd) periods, and omminus and omplus the corresponding  real numbers omega^- and omega^+. For the moment, only for modular forms of even weight."},
-{"lfunmul",0,(void*)lfunmul,6,"GGp","lfunmul(L1,L2): creates the Ldata structure (without  initialization) corresponding to the product of the Dirichlet series  given by L1 and L2."},
-{"lfunorderzero",0,(void*)lfunorderzero_bitprec,6,"lGb","lfunorderzero(L): computes the order of the possible zero of the L-function at the center k/2 of the critical strip."},
+{"lfungenus2",0,(void*)lfungenus2,6,"G","lfungenus2(F): returns the Ldata structure associated to the L-function associated to the genus-2 curve defined by y^2=F(x) or y^2+Q(x)*y=P(x) if F=[P,Q]. Currently, only odd conductors are supported, and the model needs to be minimal at 2."},
+{"lfunhardy",0,(void*)lfunhardy,6,"GGb","lfunhardy(L,t): Variant of the Hardy L-function corresponding to L, used for plotting on the critical line, see ??lfunhardy for the precise definition."},
+{"lfuninit",0,(void*)lfuninit0,6,"GGD0,L,b","lfuninit(L,sdom,{der=0}): precompute data for evaluating the L-function given by 'L' (and its derivatives of order der, if set) in rectangular domain sdom = [center,w,h] centered on the real axis, |Re(s)-center| <= w, |Im(s)| <= h, where all three components of sdom are real and w,h are non-negative. The subdomain [k/2, 0, h] on the critical line can be encoded as [h] for brevity."},
+{"lfunlambda",0,(void*)lfunlambda0,6,"GGD0,L,b","lfunlambda(L,s,{D=0}): compute the completed L function Lambda(s), or if D is set, the derivative of order D at s. L is either an Lmath, an Ldata or an Linit."},
+{"lfunmfpeters",0,(void*)lfunmfpeters,6,"Gb","lfunmfpeters(L): L corresponding to a normalized eigenform but NOT to the output of lfunsymsq, returns the Petersson square of the form, computed using the symmetric square."},
+{"lfunmfspec",0,(void*)lfunmfspec,6,"Gb","lfunmfspec(L): L corresponding to a modular form, returns  [valeven,valodd,omminus,omplus], where valeven (resp., valodd) is the vector  of even (resp., odd) periods, and omminus and omplus the corresponding  real numbers omega^- and omega^+. For the moment, only for modular forms of even weight."},
+{"lfunmul",0,(void*)lfunmul,6,"GGb","lfunmul(L1,L2): creates the Ldata structure (without  initialization) corresponding to the product of the Dirichlet series  given by L1 and L2."},
+{"lfunorderzero",0,(void*)lfunorderzero,6,"lGb","lfunorderzero(L): computes the order of the possible zero of the L-function at the center k/2 of the critical strip."},
 {"lfunqf",0,(void*)lfunqf,6,"G","lfunqf(Q): returns the Ldata structure associated to the theta function of the lattice associated to the definite positive quadratic form Q. This function assumes that the associated L function is self-dual, but not necessarily the lattice itself. In particular, if Q is two-dimensional, then L is always self-dual."},
-{"lfunrootres",0,(void*)lfunrootres_bitprec,6,"Gb","lfunrootres(data): given the Ldata associated to an L-function (or the output of lfunthetainit), compute the root number and the residues. In the present implementation, if the polar part is not already known completely, at most a single pole is allowed. The output is a 3-component vector [r,R,w], where r is the residue of L(s) at the unique pole (0 if no pole), R is the residue of Lambda(s), and w is the root number."},
+{"lfunrootres",0,(void*)lfunrootres,6,"Gb","lfunrootres(data): given the Ldata associated to an L-function (or the output of lfunthetainit), compute the root number and the residues. In the present implementation, if the polar part is not already known completely, at most a single pole is allowed. The output is a 3-component vector [r,R,w], where r is the residue of L(s) at the unique pole (0 if no pole), R is the residue of Lambda(s), and w is the root number."},
 {"lfunsymsq",0,(void*)lfunsymsq,6,"GDGp","lfunsymsq(L,{known=[]}): creates the Ldata corresponding to the  symmetric square of the modular form L, including the search for the  conductor and bad Euler factors. known, if present, is the vector  [conductor,[list of Euler factors]], where each Euler factor is of the form  [p, a_p] corresponding to the factor 1/(1 - a_pp^(-s)). The result can  then be used with the usual lfunxxx functions. Warning: in the present  implementation, only missin [...]
-{"lfunsymsqspec",0,(void*)lfunsymsqspec_bitprec,6,"Gb","lfunsymsqspec(L): Ldata corresponding either to a normalized  eigenform or to the output of lfunsymsq, returns [val, om2], where val  is the vector of special values of the symmetric square of the modular form  on the right of the critical strip, and om2 is a period, not canonically  normalized. For the moment, only for modular forms of even weight."},
-{"lfuntheta",0,(void*)lfuntheta_bitprec,6,"GGD0,L,b","lfuntheta(data,t,{m=0}): compute the value of the m-th derivative at t of the theta function associated to the L-function given by data. data can be either the standard L-function data, or the output of lfunthetainit."},
+{"lfunsymsqspec",0,(void*)lfunsymsqspec,6,"Gb","lfunsymsqspec(L): Ldata corresponding either to a normalized  eigenform or to the output of lfunsymsq, returns [val, om2], where val  is the vector of special values of the symmetric square of the modular form  on the right of the critical strip, and om2 is a period, not canonically  normalized. For the moment, only for modular forms of even weight."},
+{"lfuntheta",0,(void*)lfuntheta,6,"GGD0,L,b","lfuntheta(data,t,{m=0}): compute the value of the m-th derivative at t of the theta function associated to the L-function given by data. data can be either the standard L-function data, or the output of lfunthetainit."},
 {"lfunthetacost",0,(void*)lfunthetacost0,6,"lGDGD0,L,b","lfunthetacost(L,{tdom},{m=0}): estimates the cost of running lfunthetainit(L,tdom,m) at current bit precision. Returns the number of coefficients an that would be computed. Subsequent evaluation of lfuntheta computes that many values of gammamellininv. If L is already an Linit, then tdom and m are ignored."},
-{"lfunthetainit",0,(void*)lfunthetainit_bitprec,6,"GDGD0,L,b","lfunthetainit(L,{tdom},{m=0}): precompute data for evaluating  the m-th derivative of theta functions with argument in domain tdom  (by default t is real >= 1)."},
-{"lfunzeros",0,(void*)lfunzeros_bitprec,6,"GGD8,L,b","lfunzeros(L,lim,{divz=8}): lim being either an upper limit or a real interval, computes an ordered list of zeros of L(s) on the critical line up to the given upper limit or in the given interval. Use a naive algorithm which may miss some zeros. To use a finer search mesh, set divz to some integral value larger than the default (= 8)."},
+{"lfunthetainit",0,(void*)lfunthetainit,6,"GDGD0,L,b","lfunthetainit(L,{tdom},{m=0}): precompute data for evaluating  the m-th derivative of theta functions with argument in domain tdom  (by default t is real >= 1)."},
+{"lfunzeros",0,(void*)lfunzeros,6,"GGD8,L,b","lfunzeros(L,lim,{divz=8}): lim being either an upper limit or a real interval, computes an ordered list of zeros of L(s) on the critical line up to the given upper limit or in the given interval. Use a naive algorithm which may miss some zeros. To use a finer search mesh, set divz to some integral value larger than the default (= 8)."},
 {"lift",0,(void*)lift0,2,"GDn","lift(x,{v}): if v is omitted, lifts elements of Z/nZ to Z, of Qp to Q, and of K[x]/(P) to K[x]. Otherwise lift only polmods with main variable v."},
 {"liftall",0,(void*)liftall,2,"G","liftall(x): lifts every element of Z/nZ to Z, of Qp to Q, and of K[x]/(P) to K[x]."},
 {"liftint",0,(void*)liftint,2,"G","liftint(x): lifts every element of Z/nZ to Z, of Qp to Q, and of K[x]/(P) to K[x]."},
 {"liftpol",0,(void*)liftpol,2,"G","liftpol(x): lifts every polmod component of x to polynomials"},
-{"limitnum",0,(void*)limitnum0,12,"GD0,L,DGp","limitnum(expr,{k = 20},{alpha=1}): numerical limit of sequence expr using Lagrange-Zagier extrapolation; k is a multiplier so that we extrapolate from expr(k*n). Assume u(n) ~ sum a_i n^(-alpha*i). flag=2, assuming that the asymptotic expansion is in powers of 1/n^2."},
-{"lindep",0,(void*)lindep0,11,"GD0,L,","lindep(v,{flag=0}): integral linear dependencies between components of v. flag is optional, and can be 0: default, guess a suitable accuracy, or positive: accuracy to use for the computation, in decimal digits."},
-{"listcreate",0,(void*)listcreate,14,"D0,L,","listcreate(): creates an empty list."},
-{"listinsert",0,(void*)listinsert,14,"WGL","listinsert(L,x,n): insert x at index n in list L, shifting the remaining elements to the right."},
-{"listkill",0,(void*)listkill,14,"vG","listkill(L): obsolete, retained for backward compatibility."},
-{"listpop",0,(void*)listpop0,14,"vWD0,L,","listpop(list,{n}): removes n-th element from list. If n is omitted or greater than the current list length, removes last element."},
-{"listput",0,(void*)listput0,14,"WGD0,L,","listput(list,x,{n}): sets n-th element of list equal to x. If n is omitted or greater than the current list length, appends x."},
-{"listsort",0,(void*)listsort,14,"vWD0,L,","listsort(L,{flag=0}): sort the list L in place. If flag is non-zero, suppress all but one occurence of each element in list."},
+{"limitnum",0,(void*)limitnum0,13,"GD0,L,DGp","limitnum(expr,{k = 20},{alpha=1}): numerical limit of sequence expr using Lagrange-Zagier extrapolation; k is a multiplier so that we extrapolate from expr(k*n). Assume u(n) ~ sum a_i n^(-alpha*i). flag=2, assuming that the asymptotic expansion is in powers of 1/n^2."},
+{"lindep",0,(void*)lindep0,12,"GD0,L,","lindep(v,{flag=0}): integral linear dependencies between components of v. flag is optional, and can be 0: default, guess a suitable accuracy, or positive: accuracy to use for the computation, in decimal digits."},
+{"listcreate",0,(void*)listcreate,15,"D0,L,","listcreate(): creates an empty list."},
+{"listinsert",0,(void*)listinsert,15,"WGL","listinsert(L,x,n): insert x at index n in list L, shifting the remaining elements to the right."},
+{"listkill",0,(void*)listkill,15,"vG","listkill(L): obsolete, retained for backward compatibility."},
+{"listpop",0,(void*)listpop0,15,"vWD0,L,","listpop(list,{n}): removes n-th element from list. If n is omitted or greater than the current list length, removes last element."},
+{"listput",0,(void*)listput0,15,"WGD0,L,","listput(list,x,{n}): sets n-th element of list equal to x. If n is omitted or greater than the current list length, appends x."},
+{"listsort",0,(void*)listsort,15,"vWD0,L,","listsort(L,{flag=0}): sort the list L in place. If flag is non-zero, suppress all but one occurence of each element in list."},
 {"lngamma",0,(void*)glngamma,3,"Gp","lngamma(x): logarithm of the gamma function of x."},
-{"local",0,NULL,14,NULL,"local(x,...,z): declare x,...,z as (dynamically scoped) local variables."},
-{"localbitprec",0,(void*)localbitprec,14,"vL","localbitprec(p): set the real precision to p bits in the dynamic scope."},
-{"localprec",0,(void*)localprec,14,"vL","localprec(p): set the real precision to p in the dynamic scope."},
+{"local",0,NULL,15,NULL,"local(x,...,z): declare x,...,z as (dynamically scoped) local variables."},
+{"localbitprec",0,(void*)localbitprec,15,"vL","localbitprec(p): set the real precision to p bits in the dynamic scope."},
+{"localprec",0,(void*)localprec,15,"vL","localprec(p): set the real precision to p in the dynamic scope."},
 {"log",0,(void*)glog,3,"Gp","log(x): natural logarithm of x."},
 {"logint",0,(void*)logint0,4,"lGGD&","logint(x,b,&z): return the largest integer e so that b^e <= x, where the parameters b > 1 and x > 0 are both integers. If the parameter z is present, set it to b^e."},
-{"mapdelete",0,(void*)mapdelete,14,"vGG","mapdelete(M,x): removes x from the domain of the map M."},
-{"mapget",0,(void*)mapget,14,"GG","mapget(M,x): returns the image of x by the map M."},
-{"mapisdefined",0,(void*)mapisdefined,14,"iGGD&","mapisdefined(M,x,{&z}): true (1) if x has an image by the map M, false (0) otherwise. If z is present, set it to the image of x, if it exists."},
-{"mapput",0,(void*)mapput,14,"vWGG","mapput(M,x,y): associates x to y in the map M."},
-{"matadjoint",0,(void*)matadjoint0,11,"GD0,L,","matadjoint(M,{flag=0}): adjoint matrix of M using Leverrier-Faddeev's algorithm. If flag is 1, compute the characteristic polynomial independently first."},
-{"matalgtobasis",0,(void*)matalgtobasis,8,"GG","matalgtobasis(nf,x): nfalgtobasis applied to every element of the vector or matrix x."},
-{"matbasistoalg",0,(void*)matbasistoalg,8,"GG","matbasistoalg(nf,x): nfbasistoalg applied to every element of the matrix or vector x."},
-{"matcompanion",0,(void*)matcompanion,11,"G","matcompanion(x): companion matrix to polynomial x."},
-{"matconcat",0,(void*)matconcat,11,"G","matconcat(v): concatenate the entries of v and return the resulting matrix"},
-{"matdet",0,(void*)det0,11,"GD0,L,","matdet(x,{flag=0}): determinant of the matrix x using an appropriate algorithm depending on the coefficients. If (optional) flag is set to 1, use classical Gaussian elimination (usually worse than the default)."},
-{"matdetint",0,(void*)detint,11,"G","matdetint(B): some multiple of the determinant of the lattice generated by the columns of B (0 if not of maximal rank). Useful with mathnfmod."},
-{"matdiagonal",0,(void*)diagonal,11,"G","matdiagonal(x): creates the diagonal matrix whose diagonal entries are the entries of the vector x."},
-{"mateigen",0,(void*)mateigen,11,"GD0,L,p","mateigen(x,{flag=0}): complex eigenvectors of the matrix x given as columns of a matrix H. If flag=1, return [L,H], where L contains the eigenvalues and H the corresponding eigenvectors."},
-{"matfrobenius",0,(void*)matfrobenius,11,"GD0,L,Dn","matfrobenius(M,{flag},{v='x}): Return the Frobenius form of the square matrix M. If flag is 1, return only the elementary divisors as a vector of polynomials in the variable v. If flag is 2, return a two-components vector [F,B] where F is the Frobenius form and B is the basis change so that M=B^-1*F*B."},
-{"mathess",0,(void*)hess,11,"G","mathess(x): Hessenberg form of x."},
-{"mathilbert",0,(void*)mathilbert,11,"L","mathilbert(n): Hilbert matrix of order n."},
-{"mathnf",0,(void*)mathnf0,11,"GD0,L,","mathnf(M,{flag=0}): (upper triangular) Hermite normal form of M, basis for the lattice formed by the columns of M. flag is optional whose value range from 0 to 3 have a binary meaning. Bit 1: complete output, returns a 2-component vector [H,U] such that H is the HNF of M, and U is an invertible matrix such that MU=H. Bit 2: allow polynomial entries, otherwise assume that M is integral. These use a naive algorithm; larger values correspond to more i [...]
-{"mathnfmod",0,(void*)hnfmod,11,"GG","mathnfmod(x,d): (upper triangular) Hermite normal form of x, basis for the lattice formed by the columns of x, where d is a multiple of the non-zero determinant of this lattice."},
-{"mathnfmodid",0,(void*)hnfmodid,11,"GG","mathnfmodid(x,d): (upper triangular) Hermite normal form of x concatenated with matdiagonal(d)"},
-{"mathouseholder",0,(void*)mathouseholder,11,"GG","mathouseholder(Q,v): applies a sequence Q of Householder transforms to the vector or matrix v."},
-{"matid",0,(void*)matid,11,"L","matid(n): identity matrix of order n."},
-{"matimage",0,(void*)matimage0,11,"GD0,L,","matimage(x,{flag=0}): basis of the image of the matrix x. flag is optional and can be set to 0 or 1, corresponding to two different algorithms."},
-{"matimagecompl",0,(void*)imagecompl,11,"G","matimagecompl(x): vector of column indices not corresponding to the indices given by the function matimage."},
-{"matindexrank",0,(void*)indexrank,11,"G","matindexrank(x): gives two extraction vectors (rows and columns) for the matrix x such that the extracted matrix is square of maximal rank."},
-{"matintersect",0,(void*)intersect,11,"GG","matintersect(x,y): intersection of the vector spaces whose bases are the columns of x and y."},
-{"matinverseimage",0,(void*)inverseimage,11,"GG","matinverseimage(x,y): an element of the inverse image of the vector y by the matrix x if one exists, the empty vector otherwise."},
-{"matisdiagonal",0,(void*)isdiagonal,11,"iG","matisdiagonal(x): true(1) if x is a diagonal matrix, false(0) otherwise."},
-{"matker",0,(void*)matker0,11,"GD0,L,","matker(x,{flag=0}): basis of the kernel of the matrix x. flag is optional, and may be set to 0: default; non-zero: x is known to have integral entries."},
-{"matkerint",0,(void*)matkerint0,11,"GD0,L,","matkerint(x,{flag=0}): LLL-reduced Z-basis of the kernel of the matrix x with integral entries. flag is deprecated, and may be set to 0 or 1 for backward compatibility."},
-{"matmuldiagonal",0,(void*)matmuldiagonal,11,"GG","matmuldiagonal(x,d): product of matrix x by diagonal matrix whose diagonal coefficients are those of the vector d, equivalent but faster than x*matdiagonal(d)."},
-{"matmultodiagonal",0,(void*)matmultodiagonal,11,"GG","matmultodiagonal(x,y): product of matrices x and y, knowing that the result will be a diagonal matrix. Much faster than general multiplication in that case."},
-{"matpascal",0,(void*)matqpascal,11,"LDG","matpascal(n,{q}): Pascal triangle of order n if q is omitted. q-Pascal triangle otherwise."},
-{"matqr",0,(void*)matqr,11,"GD0,L,p","matqr(M,{flag=0}): returns [Q,R], the QR-decomposition of the square invertible matrix M. If flag=1, Q is given as a sequence of Householder transforms (faster and stabler)."},
-{"matrank",0,(void*)rank,11,"lG","matrank(x): rank of the matrix x."},
-{"matrix",0,(void*)matrice,11,"GGDVDVDE","matrix(m,n,{X},{Y},{expr=0}): mXn matrix of expression expr, the row variable X going from 1 to m and the column variable Y going from 1 to n. By default, fill with 0s."},
-{"matrixqz",0,(void*)matrixqz0,11,"GDG","matrixqz(A,{p=0}): if p>=0, transforms the rational or integral mxn (m>=n) matrix A into an integral matrix with gcd of maximal determinants coprime to p. If p=-1, finds a basis of the intersection with Z^n of the lattice spanned by the columns of A. If p=-2, finds a basis of the intersection with Z^n of the Q-vector space spanned by the columns of A."},
-{"matsize",0,(void*)matsize,11,"G","matsize(x): number of rows and columns of the vector/matrix x as a 2-vector."},
-{"matsnf",0,(void*)matsnf0,11,"GD0,L,","matsnf(X,{flag=0}): Smith normal form (i.e. elementary divisors) of the matrix X, expressed as a vector d. Binary digits of flag mean 1: returns [u,v,d] where d=u*X*v, otherwise only the diagonal d is returned, 2: allow polynomial entries, otherwise assume X is integral, 4: removes all information corresponding to entries equal to 1 in d."},
-{"matsolve",0,(void*)gauss,11,"GG","matsolve(M,B): solution of MX=B (M matrix, B column vector)."},
-{"matsolvemod",0,(void*)matsolvemod0,11,"GGGD0,L,","matsolvemod(M,D,B,{flag=0}): one solution of system of congruences MX=B mod D (M matrix, B and D column vectors). If (optional) flag is non-null return all solutions."},
-{"matsupplement",0,(void*)suppl,11,"G","matsupplement(x): supplement the columns of the matrix x to an invertible matrix."},
-{"mattranspose",0,(void*)gtrans,11,"G","mattranspose(x): x~ = transpose of x."},
+{"mapdelete",0,(void*)mapdelete,15,"vGG","mapdelete(M,x): removes x from the domain of the map M."},
+{"mapget",0,(void*)mapget,15,"GG","mapget(M,x): returns the image of x by the map M."},
+{"mapisdefined",0,(void*)mapisdefined,15,"iGGD&","mapisdefined(M,x,{&z}): true (1) if x has an image by the map M, false (0) otherwise. If z is present, set it to the image of x, if it exists."},
+{"mapput",0,(void*)mapput,15,"vWGG","mapput(M,x,y): associates x to y in the map M."},
+{"matadjoint",0,(void*)matadjoint0,12,"GD0,L,","matadjoint(M,{flag=0}): adjoint matrix of M using Leverrier-Faddeev's algorithm. If flag is 1, compute the characteristic polynomial independently first."},
+{"matalgtobasis",0,(void*)matalgtobasis,9,"GG","matalgtobasis(nf,x): nfalgtobasis applied to every element of the vector or matrix x."},
+{"matbasistoalg",0,(void*)matbasistoalg,9,"GG","matbasistoalg(nf,x): nfbasistoalg applied to every element of the matrix or vector x."},
+{"matcompanion",0,(void*)matcompanion,12,"G","matcompanion(x): companion matrix to polynomial x."},
+{"matconcat",0,(void*)matconcat,12,"G","matconcat(v): concatenate the entries of v and return the resulting matrix"},
+{"matdet",0,(void*)det0,12,"GD0,L,","matdet(x,{flag=0}): determinant of the matrix x using an appropriate algorithm depending on the coefficients. If (optional) flag is set to 1, use classical Gaussian elimination (usually worse than the default)."},
+{"matdetint",0,(void*)detint,12,"G","matdetint(B): some multiple of the determinant of the lattice generated by the columns of B (0 if not of maximal rank). Useful with mathnfmod."},
+{"matdiagonal",0,(void*)diagonal,12,"G","matdiagonal(x): creates the diagonal matrix whose diagonal entries are the entries of the vector x."},
+{"mateigen",0,(void*)mateigen,12,"GD0,L,p","mateigen(x,{flag=0}): complex eigenvectors of the matrix x given as columns of a matrix H. If flag=1, return [L,H], where L contains the eigenvalues and H the corresponding eigenvectors."},
+{"matfrobenius",0,(void*)matfrobenius,12,"GD0,L,Dn","matfrobenius(M,{flag},{v='x}): Return the Frobenius form of the square matrix M. If flag is 1, return only the elementary divisors as a vector of polynomials in the variable v. If flag is 2, return a two-components vector [F,B] where F is the Frobenius form and B is the basis change so that M=B^-1*F*B."},
+{"mathess",0,(void*)hess,12,"G","mathess(x): Hessenberg form of x."},
+{"mathilbert",0,(void*)mathilbert,12,"L","mathilbert(n): Hilbert matrix of order n."},
+{"mathnf",0,(void*)mathnf0,12,"GD0,L,","mathnf(M,{flag=0}): (upper triangular) Hermite normal form of M, basis for the lattice formed by the columns of M. flag is optional whose value range from 0 to 3 have a binary meaning. Bit 1: complete output, returns a 2-component vector [H,U] such that H is the HNF of M, and U is an invertible matrix such that MU=H. Bit 2: allow polynomial entries, otherwise assume that M is integral. These use a naive algorithm; larger values correspond to more i [...]
+{"mathnfmod",0,(void*)hnfmod,12,"GG","mathnfmod(x,d): (upper triangular) Hermite normal form of x, basis for the lattice formed by the columns of x, where d is a multiple of the non-zero determinant of this lattice."},
+{"mathnfmodid",0,(void*)hnfmodid,12,"GG","mathnfmodid(x,d): (upper triangular) Hermite normal form of x concatenated with matdiagonal(d)"},
+{"mathouseholder",0,(void*)mathouseholder,12,"GG","mathouseholder(Q,v): applies a sequence Q of Householder transforms to the vector or matrix v."},
+{"matid",0,(void*)matid,12,"L","matid(n): identity matrix of order n."},
+{"matimage",0,(void*)matimage0,12,"GD0,L,","matimage(x,{flag=0}): basis of the image of the matrix x. flag is optional and can be set to 0 or 1, corresponding to two different algorithms."},
+{"matimagecompl",0,(void*)imagecompl,12,"G","matimagecompl(x): vector of column indices not corresponding to the indices given by the function matimage."},
+{"matindexrank",0,(void*)indexrank,12,"G","matindexrank(x): gives two extraction vectors (rows and columns) for the matrix x such that the extracted matrix is square of maximal rank."},
+{"matintersect",0,(void*)intersect,12,"GG","matintersect(x,y): intersection of the vector spaces whose bases are the columns of x and y."},
+{"matinverseimage",0,(void*)inverseimage,12,"GG","matinverseimage(x,y): an element of the inverse image of the vector y by the matrix x if one exists, the empty vector otherwise."},
+{"matisdiagonal",0,(void*)isdiagonal,12,"iG","matisdiagonal(x): true(1) if x is a diagonal matrix, false(0) otherwise."},
+{"matker",0,(void*)matker0,12,"GD0,L,","matker(x,{flag=0}): basis of the kernel of the matrix x. flag is optional, and may be set to 0: default; non-zero: x is known to have integral entries."},
+{"matkerint",0,(void*)matkerint0,12,"GD0,L,","matkerint(x,{flag=0}): LLL-reduced Z-basis of the kernel of the matrix x with integral entries. flag is deprecated, and may be set to 0 or 1 for backward compatibility."},
+{"matmuldiagonal",0,(void*)matmuldiagonal,12,"GG","matmuldiagonal(x,d): product of matrix x by diagonal matrix whose diagonal coefficients are those of the vector d, equivalent but faster than x*matdiagonal(d)."},
+{"matmultodiagonal",0,(void*)matmultodiagonal,12,"GG","matmultodiagonal(x,y): product of matrices x and y, knowing that the result will be a diagonal matrix. Much faster than general multiplication in that case."},
+{"matpascal",0,(void*)matqpascal,12,"LDG","matpascal(n,{q}): Pascal triangle of order n if q is omitted. q-Pascal triangle otherwise."},
+{"matqr",0,(void*)matqr,12,"GD0,L,p","matqr(M,{flag=0}): returns [Q,R], the QR-decomposition of the square invertible matrix M. If flag=1, Q is given as a sequence of Householder transforms (faster and stabler)."},
+{"matrank",0,(void*)rank,12,"lG","matrank(x): rank of the matrix x."},
+{"matrix",0,(void*)matrice,12,"GGDVDVDE","matrix(m,n,{X},{Y},{expr=0}): mXn matrix of expression expr, the row variable X going from 1 to m and the column variable Y going from 1 to n. By default, fill with 0s."},
+{"matrixqz",0,(void*)matrixqz0,12,"GDG","matrixqz(A,{p=0}): if p>=0, transforms the rational or integral mxn (m>=n) matrix A into an integral matrix with gcd of maximal determinants coprime to p. If p=-1, finds a basis of the intersection with Z^n of the lattice spanned by the columns of A. If p=-2, finds a basis of the intersection with Z^n of the Q-vector space spanned by the columns of A."},
+{"matsize",0,(void*)matsize,12,"G","matsize(x): number of rows and columns of the vector/matrix x as a 2-vector."},
+{"matsnf",0,(void*)matsnf0,12,"GD0,L,","matsnf(X,{flag=0}): Smith normal form (i.e. elementary divisors) of the matrix X, expressed as a vector d. Binary digits of flag mean 1: returns [u,v,d] where d=u*X*v, otherwise only the diagonal d is returned, 2: allow polynomial entries, otherwise assume X is integral, 4: removes all information corresponding to entries equal to 1 in d."},
+{"matsolve",0,(void*)gauss,12,"GG","matsolve(M,B): solution of MX=B (M matrix, B column vector)."},
+{"matsolvemod",0,(void*)matsolvemod0,12,"GGGD0,L,","matsolvemod(M,D,B,{flag=0}): one solution of system of congruences MX=B mod D (M matrix, B and D column vectors). If (optional) flag is non-null return all solutions."},
+{"matsupplement",0,(void*)suppl,12,"G","matsupplement(x): supplement the columns of the matrix x to an invertible matrix."},
+{"mattranspose",0,(void*)gtrans,12,"G","mattranspose(x): x~ = transpose of x."},
 {"max",0,(void*)gmax,1,"GG","max(x,y): maximum of x and y"},
 {"min",0,(void*)gmin,1,"GG","min(x,y): minimum of x and y"},
-{"minpoly",0,(void*)minpoly,11,"GDn","minpoly(A,{v='x}): minimal polynomial of the matrix or polmod A."},
-{"modreverse",0,(void*)modreverse,8,"G","modreverse(z): reverse polmod of the polmod z, if it exists."},
+{"minpoly",0,(void*)minpoly,12,"GDn","minpoly(A,{v='x}): minimal polynomial of the matrix or polmod A."},
+{"modreverse",0,(void*)modreverse,9,"G","modreverse(z): reverse polmod of the polmod z, if it exists."},
 {"moebius",0,(void*)moebius,4,"lG","moebius(x): Moebius function of x."},
-{"msatkinlehner",0,(void*)msatkinlehner,7,"GLDG","msatkinlehner(M,Q,{H}): Let M be a full modular symbol space of level N, as given by msinit, let Q | N, (Q,N/Q) = 1, and let H be a subspace stable under the Atkin-Lehner involution w_Q. Return the matrix of w_Q acting on H (M if omitted)."},
-{"mscuspidal",0,(void*)mscuspidal,7,"GD0,L,","mscuspidal(M, {flag=0}): M being a full modular symbol space, as given by msinit, return its cuspidal part S. If flag = 1, return [S,E] its decomposition into Eisenstein and cuspidal parts"},
-{"mseisenstein",0,(void*)mseisenstein,7,"G","mseisenstein(M): M being a full modular symbol space, as given by msinit, return its Eisenstein subspace"},
-{"mseval",0,(void*)mseval,7,"GGDG","mseval(M,s,{p}): M being a full modular symbol space, as given by msinit, s being a modular symbol from M and p being a path between two elements in P^1(Q), return s(p)."},
-{"msfromcusp",0,(void*)msfromcusp,7,"GG","msfromcusp(M, c): returns the modular symbol associated to the cusp c, where M is a modular symbol space of level N."},
-{"msfromell",0,(void*)msfromell,7,"GD0,L,","msfromell(E, {sign=0}): return the [M, x], where M is msinit(N,2) and x is the modular symbol in M associated to the elliptic curve E/Q."},
-{"mshecke",0,(void*)mshecke,7,"GLDG","mshecke(M,p,{H}): M being a full modular symbol space, as given by msinit, p being a prime number, and H being a Hecke-stable subspace (M if omitted), return the matrix of T_p acting on H (U_p if p divides the level)."},
-{"msinit",0,(void*)msinit,7,"GGD0,L,","msinit(G, V, {sign=0}): given G a finite index subgroup of SL(2,Z) and a finite dimensional representation V of GL(2,Q), creates a space of modular symbols, the G-module Hom_G(Div^0(P^1 Q), V). This is canonically isomorphic to H^1_c(X(G), V), and allows to compute modular forms for G. If sign is present and non-zero, it must be +1 or -1 and we consider the subspace defined by Ker (Sigma - sign), where Sigma is induced by [-1,0;0,1]. Currently the o [...]
-{"msissymbol",0,(void*)msissymbol,7,"lGG","msissymbol(M,s): M being a full modular symbol space, as given by msinit, check whether s is a modular symbol associated to M"},
-{"msnew",0,(void*)msnew,7,"G","msnew(M): M being a full modular symbol space, as given by msinit, return its new cuspidal subspace"},
-{"mspathgens",0,(void*)mspathgens,7,"G","mspathgens(M): M being a full modular symbol space, as given by msinit, return a set of Z[G]-generators for Div^0(P^1 Q). The output is [g,R], where g is a minimal system of generators and R the vector of Z[G]-relations between the given generators."},
-{"mspathlog",0,(void*)mspathlog,7,"GG","mspathlog(M,p): M being a full modular symbol space, as given by msinit and p being a path between two elements in P^1(Q), return (p_i) in Z[G] such that p = \\sum p_i g_i, and the g_i are fixed Z[G]-generators for Div^0(P^1 Q), see mspathgens."},
-{"msqexpansion",0,(void*)msqexpansion,7,"GGDP","msqexpansion(M,projH,{B = seriesprecision}): M being a full modular symbol space, as given by msinit, and projH being a projector on a Hecke-simple subspace, return the Fourier coefficients [a_n, n <= B] of the corresponding normalized newform. If B omitted, use seriesprecision"},
-{"mssplit",0,(void*)mssplit,7,"GG","mssplit(M,H): M being a full modular symbol space, as given by msinit, and H being a subspace, split H into Hecke-simple subspaces."},
-{"msstar",0,(void*)msstar,7,"GDG","msstar(M,{H}): M being a full modular symbol space, as given by msinit, return the matrix of the * involution, induced by complex conjugation, acting on the (stable) subspace H (M if omitted)."},
-{"my",0,NULL,14,NULL,"my(x,...,z): declare x,...,z as lexically-scoped local variables."},
-{"newtonpoly",0,(void*)newtonpoly,8,"GG","newtonpoly(x,p): Newton polygon of polynomial x with respect to the prime p."},
-{"next",0,(void*)next0,14,"D1,L,","next({n=1}): interrupt execution of current instruction sequence, and start another iteration from the n-th innermost enclosing loops."},
+{"msatkinlehner",0,(void*)msatkinlehner,8,"GLDG","msatkinlehner(M,Q,{H}): Let M be a full modular symbol space of level N, as given by msinit, let Q | N, (Q,N/Q) = 1, and let H be a subspace stable under the Atkin-Lehner involution w_Q. Return the matrix of w_Q acting on H (M if omitted)."},
+{"mscuspidal",0,(void*)mscuspidal,8,"GD0,L,","mscuspidal(M, {flag=0}): M being a full modular symbol space, as given by msinit, return its cuspidal part S. If flag = 1, return [S,E] its decomposition into Eisenstein and cuspidal parts"},
+{"mseisenstein",0,(void*)mseisenstein,8,"G","mseisenstein(M): M being a full modular symbol space, as given by msinit, return its Eisenstein subspace"},
+{"mseval",0,(void*)mseval,8,"GGDG","mseval(M,s,{p}): M being a full modular symbol space, as given by msinit, s being a modular symbol from M and p being a path between two elements in P^1(Q), return s(p)."},
+{"msfromcusp",0,(void*)msfromcusp,8,"GG","msfromcusp(M, c): returns the modular symbol associated to the cusp c, where M is a modular symbol space of level N."},
+{"msfromell",0,(void*)msfromell,8,"GD0,L,","msfromell(E, {sign=0}): return the [M, x], where M is msinit(N,2) and x is the modular symbol in M associated to the elliptic curve E/Q."},
+{"msfromhecke",0,(void*)msfromhecke,8,"GGDG","msfromhecke(M, v, {H}): given a msinit M and a vector v of pairs [p, P] (where p is prime and P is a polynomial with integer coefficients), return a basis of all modular symbols such that P(Tp) * s = 0. If H is present, it must be a Hecke-stable subspace and we restrict to s in H."},
+{"msgetlevel",0,(void*)msgetlevel,8,"lG","msgetlevel(M): M being a full modular symbol space, as given by msinit, return its level N."},
+{"msgetsign",0,(void*)msgetsign,8,"lG","msgetsign(M): M being a full modular symbol space, as given by msinit, return its sign."},
+{"msgetweight",0,(void*)msgetweight,8,"lG","msgetweight(M): M being a full modular symbol space, as given by msinit, return its weight k."},
+{"mshecke",0,(void*)mshecke,8,"GLDG","mshecke(M,p,{H}): M being a full modular symbol space, as given by msinit, p being a prime number, and H being a Hecke-stable subspace (M if omitted), return the matrix of T_p acting on H (U_p if p divides the level)."},
+{"msinit",0,(void*)msinit,8,"GGD0,L,","msinit(G, V, {sign=0}): given G a finite index subgroup of SL(2,Z) and a finite dimensional representation V of GL(2,Q), creates a space of modular symbols, the G-module Hom_G(Div^0(P^1 Q), V). This is canonically isomorphic to H^1_c(X(G), V), and allows to compute modular forms for G. If sign is present and non-zero, it must be +1 or -1 and we consider the subspace defined by Ker (Sigma - sign), where Sigma is induced by [-1,0;0,1]. Currently the o [...]
+{"msissymbol",0,(void*)msissymbol,8,"lGG","msissymbol(M,s): M being a full modular symbol space, as given by msinit, check whether s is a modular symbol associated to M"},
+{"msnew",0,(void*)msnew,8,"G","msnew(M): M being a full modular symbol space, as given by msinit, return its new cuspidal subspace"},
+{"msomseval",0,(void*)msomseval,8,"GGG","msomseval(Mp, PHI, path): return the vectors of moments of the p-adic distribution attached to the path 'path' via the overconvergent modular symbol 'PHI'"},
+{"mspadicL",0,(void*)mspadicL,8,"GDGD0,L,","mspadicL(mu, {s = 0}, {r = 0}): given mu from mspadicmoments (p-adic distributions attached to an overconvergent symbol PHI) returns the value on a character of Z_p^* represented by s of the derivative of order r of the p-adic L-function attached to PHI."},
+{"mspadicinit",0,(void*)mspadicinit,8,"GLLD-1,L,","mspadicinit(M, p, n, {flag}): M being a full modular symbol space, as given by msinit and a prime p, initialize technical data needed to compute with overconvergent modular symbols (modulo p^n). If flag is unset, allow all symbols; if flag = 0, restrict to ordinary symbols; else initialize for symbols phi such that Tp(phi) = a_p * phi, with v_p(a_p) >= flag."},
+{"mspadicmoments",0,(void*)mspadicmoments,8,"GGD1,L,","mspadicmoments(Mp, PHI, {D = 1}): given Mp from mspadicinit, an overconvergent eigensymbol PHI, and optionally a fundamental discriminant D coprime to p, return the moments of the p-1 distributions PHI^D([0]-[oo]) | (a + pZp), 0 < a < p. To be used by mspadicL and mspadicseries"},
+{"mspadicseries",0,(void*)mspadicseries,8,"GD0,L,","mspadicseries(mu, {i=0}): given mu from mspadicmoments, returns the attached p-adic series with maximal p-adic precision, depending on the precision of M (i-th Teichmueller component, if present)."},
+{"mspathgens",0,(void*)mspathgens,8,"G","mspathgens(M): M being a full modular symbol space, as given by msinit, return a set of Z[G]-generators for Div^0(P^1 Q). The output is [g,R], where g is a minimal system of generators and R the vector of Z[G]-relations between the given generators."},
+{"mspathlog",0,(void*)mspathlog,8,"GG","mspathlog(M,p): M being a full modular symbol space, as given by msinit and p being a path between two elements in P^1(Q), return (p_i) in Z[G] such that p = \\sum p_i g_i, and the g_i are fixed Z[G]-generators for Div^0(P^1 Q), see mspathgens."},
+{"msqexpansion",0,(void*)msqexpansion,8,"GGDP","msqexpansion(M,projH,{B = seriesprecision}): M being a full modular symbol space, as given by msinit, and projH being a projector on a Hecke-simple subspace, return the Fourier coefficients [a_n, n <= B] of the corresponding normalized newform. If B omitted, use seriesprecision"},
+{"mssplit",0,(void*)mssplit,8,"GGD0,L,","mssplit(M,H,{dimlim}): M being a full modular symbol space, as given by msinit, and H being a subspace, split H into Hecke-simple subspaces. If dimlim is present and positive, restrict to dim <= dimlim."},
+{"msstar",0,(void*)msstar,8,"GDG","msstar(M,{H}): M being a full modular symbol space, as given by msinit, return the matrix of the * involution, induced by complex conjugation, acting on the (stable) subspace H (M if omitted)."},
+{"mstooms",0,(void*)mstooms,8,"GG","mstooms(Mp, phi): given Mp from mspadicinit, lift the (classical) eigen symbol phi to a distribution-valued overconvergent symbol in the sense of Pollack and Stevens. The resulting overconvergent eigensymbol can then be used in mspadicmoments, then mspadicL or mspadicseries."},
+{"my",0,NULL,15,NULL,"my(x,...,z): declare x,...,z as lexically-scoped local variables."},
+{"newtonpoly",0,(void*)newtonpoly,9,"GG","newtonpoly(x,p): Newton polygon of polynomial x with respect to the prime p."},
+{"next",0,(void*)next0,15,"D1,L,","next({n=1}): interrupt execution of current instruction sequence, and start another iteration from the n-th innermost enclosing loops."},
 {"nextprime",0,(void*)nextprime,4,"G","nextprime(x): smallest pseudoprime >= x."},
-{"nfalgtobasis",0,(void*)algtobasis,8,"GG","nfalgtobasis(nf,x): transforms the algebraic number x into a column vector on the integral basis nf.zk."},
-{"nfbasis",0,(void*)nfbasis_gp,8,"G","nfbasis(T): integral basis of the field Q[a], where a is a root of the polynomial T, using the round 4 algorithm. An argument [T,listP] is possible, where listP is a list of primes (to get an order which is maximal at certain primes only) or a prime bound."},
-{"nfbasistoalg",0,(void*)basistoalg,8,"GG","nfbasistoalg(nf,x): transforms the column vector x on the integral basis into an algebraic number."},
-{"nfcertify",0,(void*)nfcertify,8,"G","nfcertify(nf): returns a vector of composite integers used to certify nf.zk and nf.disc unconditionally (both are correct when the output is the empty vector)."},
-{"nfcompositum",0,(void*)nfcompositum,8,"GGGD0,L,","nfcompositum(nf,P,Q,{flag=0}): vector of all possible compositums of the number fields defined by the polynomials P and Q; flag is optional, whose binary digits mean 1: output for each compositum, not only the compositum polynomial pol, but a vector [R,a,b,k] where a (resp. b) is a root of P (resp. Q) expressed as a polynomial modulo R, and a small integer k such that al2+k*al1 is the chosen root of R; 2: assume that the number fields d [...]
-{"nfdetint",0,(void*)nfdetint,8,"GG","nfdetint(nf,x): multiple of the ideal determinant of the pseudo generating set x."},
-{"nfdisc",0,(void*)nfdisc,8,"G","nfdisc(T): discriminant of the number field defined by the polynomial T. An argument [T,listP] is possible, where listP is a list of primes or a prime bound."},
-{"nfeltadd",0,(void*)nfadd,8,"GGG","nfadd(nf,x,y): element x+y in nf."},
-{"nfeltdiv",0,(void*)nfdiv,8,"GGG","nfdiv(nf,x,y): element x/y in nf."},
-{"nfeltdiveuc",0,(void*)nfdiveuc,8,"GGG","nfdiveuc(nf,x,y): gives algebraic integer q such that x-by is small."},
-{"nfeltdivmodpr",0,(void*)nfdivmodpr,8,"GGGG","nfeltdivmodpr(nf,x,y,pr): element x/y modulo pr in nf, where pr is in modpr format (see nfmodprinit)."},
-{"nfeltdivrem",0,(void*)nfdivrem,8,"GGG","nfeltdivrem(nf,x,y): gives [q,r] such that r=x-by is small."},
-{"nfeltmod",0,(void*)nfmod,8,"GGG","nfeltmod(nf,x,y): gives r such that r=x-by is small with q algebraic integer."},
-{"nfeltmul",0,(void*)nfmul,8,"GGG","nfmul(nf,x,y): element x.y in nf."},
-{"nfeltmulmodpr",0,(void*)nfmulmodpr,8,"GGGG","nfeltmulmodpr(nf,x,y,pr): element x.y modulo pr in nf, where pr is in modpr format (see nfmodprinit)."},
-{"nfeltnorm",0,(void*)nfnorm,8,"GG","nfeltnorm(nf,x): norm of x."},
-{"nfeltpow",0,(void*)nfpow,8,"GGG","nfeltpow(nf,x,k): element x^k in nf."},
-{"nfeltpowmodpr",0,(void*)nfpowmodpr,8,"GGGG","nfeltpowmodpr(nf,x,k,pr): element x^k modulo pr in nf, where pr is in modpr format (see nfmodprinit)."},
-{"nfeltreduce",0,(void*)nfreduce,8,"GGG","nfeltreduce(nf,a,id): gives r such that a-r is in the ideal id and r is small."},
-{"nfeltreducemodpr",0,(void*)nfreducemodpr,8,"GGG","nfeltreducemodpr(nf,x,pr): element x modulo pr in nf, where pr is in modpr format (see nfmodprinit)."},
-{"nfelttrace",0,(void*)nftrace,8,"GG","nfelttrace(nf,x): trace of x."},
-{"nfeltval",0,(void*)gpnfvalrem,8,"GGGD&","nfeltval(nf,x,pr,{&y}): valuation of element x at the prime pr as output by idealprimedec."},
-{"nffactor",0,(void*)nffactor,8,"GG","nffactor(nf,T): factor polynomial T in number field nf."},
-{"nffactorback",0,(void*)nffactorback,8,"GGDG","nffactorback(nf,f,{e}): given a factorisation f, returns the factored object back as an nf element."},
-{"nffactormod",0,(void*)nffactormod,8,"GGG","nffactormod(nf,Q,pr): factor polynomial Q modulo prime ideal pr in number field nf."},
-{"nfgaloisapply",0,(void*)galoisapply,8,"GGG","nfgaloisapply(nf,aut,x): Apply the Galois automorphism aut to the object x (element or ideal) in the number field nf."},
-{"nfgaloisconj",0,(void*)galoisconj0,8,"GD0,L,DGp","nfgaloisconj(nf,{flag=0},{d}): list of conjugates of a root of the polynomial x=nf.pol in the same number field. flag is optional (set to 0 by default), meaning 0: use combination of flag 4 and 1, always complete; 1: use nfroots; 2 : use complex numbers, LLL on integral basis (not always complete); 4: use Allombert's algorithm, complete if the field is Galois of degree <= 35 (see manual for details). nf can be simply a polynomial."},
-{"nfgrunwaldwang",0,(void*)nfgrunwaldwang,8,"GGGGDn","nfgrunwaldwang(nf,Lpr,Ld,pl,{v='x}): a polynomial in the variable v defining a cyclic extension of nf (given in nf or bnf form) with local behaviour prescribed by Lpr, Ld and pl: the extension has local degree a multiple of Ld[i] at the prime Lpr[i], and the extension is complex at the i-th real place of nf if pl[i]=-1 (no condition if pl[i]=0). The extension has degree the LCM of the local degrees."},
-{"nfhilbert",0,(void*)nfhilbert0,8,"lGGGDG","nfhilbert(nf,a,b,{pr}): if pr is omitted, global Hilbert symbol (a,b) in nf, that is 1 if X^2-aY^2-bZ^2 has a non-trivial solution (X,Y,Z) in nf, -1 otherwise. Otherwise compute the local symbol modulo the prime ideal pr."},
-{"nfhnf",0,(void*)nfhnf0,8,"GGD0,L,","nfhnf(nf,x,{flag=0}): if x=[A,I], gives a pseudo-basis [B,J] of the module sum A_jI_j. If flag is non-zero, return [[B,J], U], where U is the transformation matrix such that AU = [0|B]"},
-{"nfhnfmod",0,(void*)nfhnfmod,8,"GGG","nfhnfmod(nf,x,detx): if x=[A,I], and detx is a multiple of the ideal determinant of x, gives a pseudo-basis of the module sum A_jI_j."},
-{"nfinit",0,(void*)nfinit0,8,"GD0,L,p","nfinit(pol,{flag=0}): pol being a nonconstant irreducible polynomial, gives the vector: [pol,[r1,r2],discf,index,[M,MC,T2,T,different] (see manual),r1+r2 first roots, integral basis, matrix of power basis in terms of integral basis, multiplication table of basis]. flag is optional and can be set to 0: default; 1: do not compute different; 2: first use polred to find a simpler polynomial; 3: outputs a two-element vector [nf,Mod(a,P)], where nf is as [...]
-{"nfisideal",0,(void*)isideal,8,"lGG","nfisideal(nf,x): true(1) if x is an ideal in the number field nf, false(0) if not."},
-{"nfisincl",0,(void*)nfisincl,8,"GG","nfisincl(x,y): tests whether the number field x is isomorphic to a subfield of y (where x and y are either polynomials or number fields as output by nfinit). Return 0 if not, and otherwise all the isomorphisms. If y is a number field, a faster algorithm is used."},
-{"nfisisom",0,(void*)nfisisom,8,"GG","nfisisom(x,y): as nfisincl but tests whether x is isomorphic to y."},
-{"nfkermodpr",0,(void*)nfkermodpr,8,"GGG","nfkermodpr(nf,x,pr): kernel of the matrix x in Z_K/pr, where pr is in modpr format (see nfmodprinit)."},
-{"nfmodprinit",0,(void*)nfmodprinit,8,"GG","nfmodprinit(nf,pr): transform the 5 element row vector pr representing a prime ideal into modpr format necessary for all operations mod pr in the number field nf (see manual for details about the format)."},
-{"nfnewprec",0,(void*)nfnewprec,8,"Gp","nfnewprec(nf): transform the number field data nf into new data using the current (usually larger) precision."},
-{"nfroots",0,(void*)nfroots,8,"DGG","nfroots({nf},x): roots of polynomial x belonging to nf (Q if omitted) without multiplicity."},
-{"nfrootsof1",0,(void*)rootsof1,8,"G","nfrootsof1(nf): number of roots of unity and primitive root of unity in the number field nf."},
-{"nfsnf",0,(void*)nfsnf0,8,"GGD0,L,","nfsnf(nf,x,{flag=0}): if x=[A,I,J], outputs D=[d_1,...d_n] Smith normal form of x. If flag is non-zero return [D,U,V], where UAV = Id."},
-{"nfsolvemodpr",0,(void*)nfsolvemodpr,8,"GGGG","nfsolvemodpr(nf,a,b,P): solution of a*x=b in Z_K/P, where a is a matrix and b a column vector, and where P is in modpr format (see nfmodprinit)."},
-{"nfsplitting",0,(void*)nfsplitting,8,"GDG","nfsplitting(nf,{d}): defining polynomial over Q for the splitting field of the number field nf; if d is given, it must be the degree of the splitting field"},
-{"nfsubfields",0,(void*)nfsubfields,8,"GD0,L,","nfsubfields(pol,{d=0}): find all subfields of degree d of number field defined by pol (all subfields if d is null or omitted). Result is a vector of subfields, each being given by [g,h], where g is an absolute equation and h expresses one of the roots of g in terms of the root x of the polynomial defining nf."},
+{"nfalgtobasis",0,(void*)algtobasis,9,"GG","nfalgtobasis(nf,x): transforms the algebraic number x into a column vector on the integral basis nf.zk."},
+{"nfbasis",0,(void*)nfbasis_gp,9,"G","nfbasis(T): integral basis of the field Q[a], where a is a root of the polynomial T, using the round 4 algorithm. An argument [T,listP] is possible, where listP is a list of primes (to get an order which is maximal at certain primes only) or a prime bound."},
+{"nfbasistoalg",0,(void*)basistoalg,9,"GG","nfbasistoalg(nf,x): transforms the column vector x on the integral basis into an algebraic number."},
+{"nfcertify",0,(void*)nfcertify,9,"G","nfcertify(nf): returns a vector of composite integers used to certify nf.zk and nf.disc unconditionally (both are correct when the output is the empty vector)."},
+{"nfcompositum",0,(void*)nfcompositum,9,"GGGD0,L,","nfcompositum(nf,P,Q,{flag=0}): vector of all possible compositums of the number fields defined by the polynomials P and Q; flag is optional, whose binary digits mean 1: output for each compositum, not only the compositum polynomial pol, but a vector [R,a,b,k] where a (resp. b) is a root of P (resp. Q) expressed as a polynomial modulo R, and a small integer k such that al2+k*al1 is the chosen root of R; 2: assume that the number fields d [...]
+{"nfdetint",0,(void*)nfdetint,9,"GG","nfdetint(nf,x): multiple of the ideal determinant of the pseudo generating set x."},
+{"nfdisc",0,(void*)nfdisc,9,"G","nfdisc(T): discriminant of the number field defined by the polynomial T. An argument [T,listP] is possible, where listP is a list of primes or a prime bound."},
+{"nfeltadd",0,(void*)nfadd,9,"GGG","nfadd(nf,x,y): element x+y in nf."},
+{"nfeltdiv",0,(void*)nfdiv,9,"GGG","nfdiv(nf,x,y): element x/y in nf."},
+{"nfeltdiveuc",0,(void*)nfdiveuc,9,"GGG","nfdiveuc(nf,x,y): gives algebraic integer q such that x-qy is small."},
+{"nfeltdivmodpr",0,(void*)nfdivmodpr,9,"GGGG","nfeltdivmodpr(nf,x,y,pr): element x/y modulo pr in nf, where pr is in modpr format (see nfmodprinit)."},
+{"nfeltdivrem",0,(void*)nfdivrem,9,"GGG","nfeltdivrem(nf,x,y): gives [q,r] such that r=x-qy is small."},
+{"nfeltmod",0,(void*)nfmod,9,"GGG","nfeltmod(nf,x,y): gives r such that r=x-qy is small with q algebraic integer."},
+{"nfeltmul",0,(void*)nfmul,9,"GGG","nfmul(nf,x,y): element x.y in nf."},
+{"nfeltmulmodpr",0,(void*)nfmulmodpr,9,"GGGG","nfeltmulmodpr(nf,x,y,pr): element x.y modulo pr in nf, where pr is in modpr format (see nfmodprinit)."},
+{"nfeltnorm",0,(void*)nfnorm,9,"GG","nfeltnorm(nf,x): norm of x."},
+{"nfeltpow",0,(void*)nfpow,9,"GGG","nfeltpow(nf,x,k): element x^k in nf."},
+{"nfeltpowmodpr",0,(void*)nfpowmodpr,9,"GGGG","nfeltpowmodpr(nf,x,k,pr): element x^k modulo pr in nf, where pr is in modpr format (see nfmodprinit)."},
+{"nfeltreduce",0,(void*)nfreduce,9,"GGG","nfeltreduce(nf,a,id): gives r such that a-r is in the ideal id and r is small."},
+{"nfeltreducemodpr",0,(void*)nfreducemodpr,9,"GGG","nfeltreducemodpr(nf,x,pr): element x modulo pr in nf, where pr is in modpr format (see nfmodprinit)."},
+{"nfelttrace",0,(void*)nftrace,9,"GG","nfelttrace(nf,x): trace of x."},
+{"nfeltval",0,(void*)gpnfvalrem,9,"GGGD&","nfeltval(nf,x,pr,{&y}): valuation of element x at the prime pr as output by idealprimedec."},
+{"nffactor",0,(void*)nffactor,9,"GG","nffactor(nf,T): factor polynomial T in number field nf."},
+{"nffactorback",0,(void*)nffactorback,9,"GGDG","nffactorback(nf,f,{e}): given a factorisation f, returns the factored object back as an nf element."},
+{"nffactormod",0,(void*)nffactormod,9,"GGG","nffactormod(nf,Q,pr): factor polynomial Q modulo prime ideal pr in number field nf."},
+{"nfgaloisapply",0,(void*)galoisapply,9,"GGG","nfgaloisapply(nf,aut,x): Apply the Galois automorphism aut to the object x (element or ideal) in the number field nf."},
+{"nfgaloisconj",0,(void*)galoisconj0,9,"GD0,L,DGp","nfgaloisconj(nf,{flag=0},{d}): list of conjugates of a root of the polynomial x=nf.pol in the same number field. flag is optional (set to 0 by default), meaning 0: use combination of flag 4 and 1, always complete; 1: use nfroots; 2 : use complex numbers, LLL on integral basis (not always complete); 4: use Allombert's algorithm, complete if the field is Galois of degree <= 35 (see manual for details). nf can be simply a polynomial."},
+{"nfgrunwaldwang",0,(void*)nfgrunwaldwang,9,"GGGGDn","nfgrunwaldwang(nf,Lpr,Ld,pl,{v='x}): a polynomial in the variable v defining a cyclic extension of nf (given in nf or bnf form) with local behaviour prescribed by Lpr, Ld and pl: the extension has local degree a multiple of Ld[i] at the prime Lpr[i], and the extension is complex at the i-th real place of nf if pl[i]=-1 (no condition if pl[i]=0). The extension has degree the LCM of the local degrees."},
+{"nfhilbert",0,(void*)nfhilbert0,9,"lGGGDG","nfhilbert(nf,a,b,{pr}): if pr is omitted, global Hilbert symbol (a,b) in nf, that is 1 if X^2-aY^2-bZ^2 has a non-trivial solution (X,Y,Z) in nf, -1 otherwise. Otherwise compute the local symbol modulo the prime ideal pr."},
+{"nfhnf",0,(void*)nfhnf0,9,"GGD0,L,","nfhnf(nf,x,{flag=0}): if x=[A,I], gives a pseudo-basis [B,J] of the module sum A_jI_j. If flag is non-zero, return [[B,J], U], where U is the transformation matrix such that AU = [0|B]"},
+{"nfhnfmod",0,(void*)nfhnfmod,9,"GGG","nfhnfmod(nf,x,detx): if x=[A,I], and detx is a multiple of the ideal determinant of x, gives a pseudo-basis of the module sum A_jI_j."},
+{"nfinit",0,(void*)nfinit0,9,"GD0,L,p","nfinit(pol,{flag=0}): pol being a nonconstant irreducible polynomial, gives the vector: [pol,[r1,r2],discf,index,[M,MC,T2,T,different] (see manual),r1+r2 first roots, integral basis, matrix of power basis in terms of integral basis, multiplication table of basis]. flag is optional and can be set to 0: default; 1: do not compute different; 2: first use polred to find a simpler polynomial; 3: outputs a two-element vector [nf,Mod(a,P)], where nf is as [...]
+{"nfisideal",0,(void*)isideal,9,"lGG","nfisideal(nf,x): true(1) if x is an ideal in the number field nf, false(0) if not."},
+{"nfisincl",0,(void*)nfisincl,9,"GG","nfisincl(x,y): tests whether the number field x is isomorphic to a subfield of y (where x and y are either polynomials or number fields as output by nfinit). Return 0 if not, and otherwise all the isomorphisms. If y is a number field, a faster algorithm is used."},
+{"nfisisom",0,(void*)nfisisom,9,"GG","nfisisom(x,y): as nfisincl but tests whether x is isomorphic to y."},
+{"nfkermodpr",0,(void*)nfkermodpr,9,"GGG","nfkermodpr(nf,x,pr): kernel of the matrix x in Z_K/pr, where pr is in modpr format (see nfmodprinit)."},
+{"nfmodprinit",0,(void*)nfmodprinit,9,"GG","nfmodprinit(nf,pr): transform the 5 element row vector pr representing a prime ideal into modpr format necessary for all operations mod pr in the number field nf (see manual for details about the format)."},
+{"nfnewprec",0,(void*)nfnewprec,9,"Gp","nfnewprec(nf): transform the number field data nf into new data using the current (usually larger) precision."},
+{"nfroots",0,(void*)nfroots,9,"DGG","nfroots({nf},x): roots of polynomial x belonging to nf (Q if omitted) without multiplicity."},
+{"nfrootsof1",0,(void*)rootsof1,9,"G","nfrootsof1(nf): number of roots of unity and primitive root of unity in the number field nf."},
+{"nfsnf",0,(void*)nfsnf0,9,"GGD0,L,","nfsnf(nf,x,{flag=0}): if x=[A,I,J], outputs D=[d_1,...d_n] Smith normal form of x. If flag is non-zero return [D,U,V], where UAV = Id."},
+{"nfsolvemodpr",0,(void*)nfsolvemodpr,9,"GGGG","nfsolvemodpr(nf,a,b,P): solution of a*x=b in Z_K/P, where a is a matrix and b a column vector, and where P is in modpr format (see nfmodprinit)."},
+{"nfsplitting",0,(void*)nfsplitting,9,"GDG","nfsplitting(nf,{d}): defining polynomial over Q for the splitting field of the number field nf; if d is given, it must be a multiple of the splitting field degree"},
+{"nfsubfields",0,(void*)nfsubfields,9,"GD0,L,","nfsubfields(pol,{d=0}): find all subfields of degree d of number field defined by pol (all subfields if d is null or omitted). Result is a vector of subfields, each being given by [g,h], where g is an absolute equation and h expresses one of the roots of g in terms of the root x of the polynomial defining nf."},
 {"norm",0,(void*)gnorm,2,"G","norm(x): norm of x."},
-{"norml2",0,(void*)gnorml2,11,"G","norml2(x): square of the L2-norm of x."},
-{"normlp",0,(void*)gnormlp,11,"GDGp","normlp(x,{p}): Lp-norm of x; sup norm if p is omitted."},
+{"norml2",0,(void*)gnorml2,12,"G","norml2(x): square of the L2-norm of x."},
+{"normlp",0,(void*)gnormlp,12,"GDGp","normlp(x,{p}): Lp-norm of x; sup norm if p is omitted."},
 {"numbpart",0,(void*)numbpart,4,"G","numbpart(n): number of partitions of n."},
 {"numdiv",0,(void*)numdiv,4,"G","numdiv(x): number of divisors of x."},
 {"numerator",0,(void*)numer,2,"G","numerator(x): numerator of x."},
 {"numtoperm",0,(void*)numtoperm,2,"LG","numtoperm(n,k): permutation number k (mod n!) of n letters (n C-integer)."},
 {"omega",0,(void*)omega,4,"lG","omega(x): number of distinct prime divisors of x."},
 {"oo",0,(void*)mkoo,2,"","oo=oo(): infinity."},
-{"padicappr",0,(void*)padicappr,10,"GG","padicappr(pol,a): p-adic roots of the polynomial pol congruent to a mod p."},
-{"padicfields",0,(void*)padicfields0,10,"GGD0,L,","padicfields(p, N, {flag=0}): returns polynomials generating all the extensions of degree N of the field of p-adic rational numbers; N is allowed to be a 2-component vector [n,d], in which case, returns the extensions of degree n and discriminant p^d. flag is optional, and can be 0: default, 1: return also the ramification index, the residual degree, the valuation of the discriminant and the number of conjugate fields, or 2: return only t [...]
+{"padicappr",0,(void*)padicappr,11,"GG","padicappr(pol,a): p-adic roots of the polynomial pol congruent to a mod p."},
+{"padicfields",0,(void*)padicfields0,11,"GGD0,L,","padicfields(p, N, {flag=0}): returns polynomials generating all the extensions of degree N of the field of p-adic rational numbers; N is allowed to be a 2-component vector [n,d], in which case, returns the extensions of degree n and discriminant p^d. flag is optional, and can be 0: default, 1: return also the ramification index, the residual degree, the valuation of the discriminant and the number of conjugate fields, or 2: return only t [...]
 {"padicprec",0,(void*)padicprec,2,"lGG","padicprec(x,p): absolute p-adic precision of object x."},
-{"parapply",0,(void*)parapply,14,"GG","parapply(f, x): parallel evaluation of f on the elements of x."},
-{"pareval",0,(void*)pareval,14,"G","pareval(x): parallel evaluation of the elements of the vector of closures x."},
-{"parfor",0,(void*)parfor0,14,"vV=GDGJDVDI","parfor(i=a,{b},expr1,{r},{expr2}): evaluates the expression expr1 in parallel for all i between a and b (if b is omitted, the loop will not stop), resulting in as many values; if the formal variables r and expr2 are present, evaluate sequentially expr2, in which r has been replaced by the different results obtained for expr1 and i with the corresponding arguments."},
-{"parforprime",0,(void*)parforprime0,14,"vV=GDGJDVDI","parforprime(p=a,{b},expr1,{r},{expr2}): evaluates the expression expr1 in parallel for all primes p between a and b (if b is omitted, the loop will not stop), resulting in as many values; if the formal variables r and expr2 are present, evaluate sequentially expr2, in which r has been replaced by the different results obtained for expr1 and p with the corresponding arguments."},
-{"parforvec",0,(void*)parforvec0,14,"vV=GJDVDID0,L,","parforvec(X=v,expr1,{j},{expr2},{flag}): evaluates the sequence expr2 (dependent on X and j) for X as generated by forvec, in random order, computed in parallel. Substitute for j the value of expr1 (dependent on X)."},
-{"parselect",0,(void*)parselect,14,"GGD0,L,","parselect(f, A, {flag = 0}): (parallel select) selects elements of A according to the selection function f which is tested in parallel. If flag is 1, return the indices of those elements (indirect selection)"},
-{"parsum",0,(void*)parsum,14,"V=GGJDG","parsum(i=a,b,expr,{x}): x plus the sum (X goes from a to b) of expression expr, evaluated in parallel (in random order)"},
+{"parapply",0,(void*)parapply,15,"GG","parapply(f, x): parallel evaluation of f on the elements of x."},
+{"pareval",0,(void*)pareval,15,"G","pareval(x): parallel evaluation of the elements of the vector of closures x."},
+{"parfor",0,(void*)parfor0,15,"vV=GDGJDVDI","parfor(i=a,{b},expr1,{r},{expr2}): evaluates the expression expr1 in parallel for all i between a and b (if b is set to +oo, the loop will not stop), resulting in as many values; if the formal variables r and expr2 are present, evaluate sequentially expr2, in which r has been replaced by the different results obtained for expr1 and i with the corresponding arguments."},
+{"parforprime",0,(void*)parforprime0,15,"vV=GDGJDVDI","parforprime(p=a,{b},expr1,{r},{expr2}): evaluates the expression expr1 in parallel for all primes p between a and b (if b is set to +oo, the loop will not stop), resulting in as many values; if the formal variables r and expr2 are present, evaluate sequentially expr2, in which r has been replaced by the different results obtained for expr1 and p with the corresponding arguments."},
+{"parforvec",0,(void*)parforvec0,15,"vV=GJDVDID0,L,","parforvec(X=v,expr1,{j},{expr2},{flag}): evaluates the sequence expr2 (dependent on X and j) for X as generated by forvec, in random order, computed in parallel. Substitute for j the value of expr1 (dependent on X)."},
+{"parselect",0,(void*)parselect,15,"GGD0,L,","parselect(f, A, {flag = 0}): (parallel select) selects elements of A according to the selection function f which is tested in parallel. If flag is 1, return the indices of those elements (indirect selection)"},
+{"parsum",0,(void*)parsum,15,"V=GGJDG","parsum(i=a,b,expr,{x}): x plus the sum (X goes from a to b) of expression expr, evaluated in parallel (in random order)"},
 {"partitions",0,(void*)partitions,4,"LDGDG","partitions(k,{a=k},{n=k})): vector of partitions of the integer k. You can restrict the length of the partitions with parameter n (n=nmax or n=[nmin,nmax]), or the range of the parts with parameter a (a=amax or a=[amin,amax]). By default remove zeros, but one can set amin=0 to get X of fixed length nmax (=k by default)."},
-{"parvector",0,(void*)parvector,14,"LVJ","parvector(N,i,expr): as vector(N,i,expr) but the evaluations of expr are done in parallel."},
+{"parvector",0,(void*)parvector,15,"LVJ","parvector(N,i,expr): as vector(N,i,expr) but the evaluations of expr are done in parallel."},
 {"permtonum",0,(void*)permtonum,2,"G","permtonum(x): ordinal (between 1 and n!) of permutation x."},
-{"polchebyshev",0,(void*)polchebyshev_eval,10,"LD1,L,DG","polchebyshev(n,{flag=1},{a='x}): Chebychev polynomial of the first (flag = 1) or second (flag = 2) kind, of degree n, evaluated at a."},
-{"polclass",0,(void*)polclass,10,"GD-1,L,Dn","polclass(D, {inv = 0}, {x = 'x}): return the Hilbert class polynomial for the discriminant D."},
-{"polcoeff",0,(void*)polcoeff0,10,"GLDn","polcoeff(x,n,{v}): coefficient of degree n of x, or the n-th component for vectors or matrices (for which it is simpler to use x[]). With respect to the main variable if v is omitted, with respect to the variable v otherwise."},
-{"polcompositum",0,(void*)polcompositum0,8,"GGD0,L,","polcompositum(P,Q,{flag=0}): vector of all possible compositums of the number fields defined by the polynomials P and Q; flag is optional, whose binary digits mean 1: output for each compositum, not only the compositum polynomial pol, but a vector [R,a,b,k] where a (resp. b) is a root of P (resp. Q) expressed as a polynomial modulo R, and a small integer k such that al2+k*al1 is the chosen root of R; 2: assume that the number fields d [...]
-{"polcyclo",0,(void*)polcyclo_eval,10,"LDG","polcyclo(n,{a = 'x}): n-th cyclotomic polynomial evaluated at a."},
-{"polcyclofactors",0,(void*)polcyclofactors,10,"G","polcyclofactors(f): returns a vector of polynomials, whose product is the product of distinct cyclotomic polynomials dividing f."},
-{"poldegree",0,(void*)gppoldegree,10,"GDn","poldegree(x,{v}): degree of the polynomial or rational function x with respect to main variable if v is omitted, with respect to v otherwise. For scalar x, return 0 if x is non-zero and -oo otherwise."},
-{"poldisc",0,(void*)poldisc0,10,"GDn","poldisc(pol,{v}): discriminant of the polynomial pol, with respect to main variable if v is omitted, with respect to v otherwise."},
-{"poldiscreduced",0,(void*)reduceddiscsmith,10,"G","poldiscreduced(f): vector of elementary divisors of Z[a]/f'(a)Z[a], where a is a root of the polynomial f."},
-{"polgalois",0,(void*)polgalois,8,"Gp","polgalois(T): Galois group of the polynomial T (see manual for group coding). Return [n, s, k, name] where n is the group order, s the signature, k the index and name is the GAP4 name of the transitive group."},
-{"polgraeffe",0,(void*)polgraeffe,10,"G","polgraeffe(f): returns the Graeffe transform g of f, such that g(x^2) = f(x)f(-x)"},
-{"polhensellift",0,(void*)polhensellift,10,"GGGL","polhensellift(A, B, p, e): lift the factorization B of A modulo p to a factorization modulo p^e using Hensel lift. The factors in B must be pairwise relatively prime modulo p."},
-{"polhermite",0,(void*)polhermite_eval,10,"LDG","polhermite(n,{a='x}): Hermite polynomial H(n,v) of degree n, evaluated at a."},
-{"polinterpolate",0,(void*)polint,10,"GDGDGD&","polinterpolate(X,{Y},{x},{&e}): polynomial interpolation at x according to data vectors X, Y (ie return P such that P(X[i]) = Y[i] for all i). If Y is omitted, return P such that P(i) = X[i]. If present, e will contain an error estimate on the returned value."},
-{"poliscyclo",0,(void*)poliscyclo,10,"lG","poliscyclo(f): returns 0 if f is not a cyclotomic polynomial, and n > 0 if f = Phi_n, the n-th cyclotomic polynomial."},
-{"poliscycloprod",0,(void*)poliscycloprod,10,"lG","poliscycloprod(f): returns 1 if f is a product of cyclotomic polynonials, and 0 otherwise."},
-{"polisirreducible",0,(void*)isirreducible,10,"lG","polisirreducible(pol): true(1) if pol is an irreducible non-constant polynomial, false(0) if pol is reducible or constant."},
-{"pollead",0,(void*)pollead,10,"GDn","pollead(x,{v}): leading coefficient of polynomial or series x, or x itself if x is a scalar. Error otherwise. With respect to the main variable of x if v is omitted, with respect to the variable v otherwise."},
-{"pollegendre",0,(void*)pollegendre_eval,10,"LDG","pollegendre(n,{a='x}): legendre polynomial of degree n evaluated at a."},
-{"polmodular",0,(void*)polmodular,10,"LD0,L,DGDnD0,L,","polmodular(L, {inv = 0}, {x = 'x}, {y = 'y}, {compute_derivs = 0}): return the modular polynomial of level L and invariant inv."},
-{"polrecip",0,(void*)polrecip,10,"G","polrecip(pol): reciprocal polynomial of pol."},
-{"polred",0,(void*)polred0,8,"GD0,L,DG","polred(T,{flag=0}): Deprecated, use polredbest. Reduction of the polynomial T (gives minimal polynomials only). The following binary digits of (optional) flag are significant 1: partial reduction, 2: gives also elements."},
-{"polredabs",0,(void*)polredabs0,8,"GD0,L,","polredabs(T,{flag=0}): a smallest generating polynomial of the number field for the T2 norm on the roots, with smallest index for the minimal T2 norm. flag is optional, whose binary digit mean 1: give the element whose characteristic polynomial is the given polynomial. 4: give all polynomials of minimal T2 norm (give only one of P(x) and P(-x))."},
-{"polredbest",0,(void*)polredbest,8,"GD0,L,","polredbest(T,{flag=0}): reduction of the polynomial T (gives minimal polynomials only). If flag=1, gives also elements."},
-{"polredord",0,(void*)polredord,8,"G","polredord(x): reduction of the polynomial x, staying in the same order."},
-{"polresultant",0,(void*)polresultant0,10,"GGDnD0,L,","polresultant(x,y,{v},{flag=0}): resultant of the polynomials x and y, with respect to the main variables of x and y if v is omitted, with respect to the variable v otherwise. flag is optional, and can be 0: default, uses either the subresultant algorithm, a modular algorithm or Sylvester's matrix, depending on the inputs; 1 uses Sylvester's matrix (should always be slower than the default)."},
-{"polresultantext",0,(void*)polresultantext0,10,"GGDn","polresultantext(A,B,{v}): return [U,V,R] such that R=polresultant(A,B,v) and U*A+V*B = R, where A and B are polynomials."},
-{"polroots",0,(void*)roots,10,"Gp","polroots(x): complex roots of the polynomial x using Schonhage's method, as modified by Gourdon."},
+{"polchebyshev",0,(void*)polchebyshev_eval,11,"LD1,L,DG","polchebyshev(n,{flag=1},{a='x}): Chebychev polynomial of the first (flag = 1) or second (flag = 2) kind, of degree n, evaluated at a."},
+{"polclass",0,(void*)polclass,11,"GD-1,L,Dn","polclass(D, {inv = 0}, {x = 'x}): return the Hilbert class polynomial for the discriminant D."},
+{"polcoeff",0,(void*)polcoeff0,11,"GLDn","polcoeff(x,n,{v}): coefficient of degree n of x, or the n-th component for vectors or matrices (for which it is simpler to use x[]). With respect to the main variable if v is omitted, with respect to the variable v otherwise."},
+{"polcompositum",0,(void*)polcompositum0,9,"GGD0,L,","polcompositum(P,Q,{flag=0}): vector of all possible compositums of the number fields defined by the polynomials P and Q; flag is optional, whose binary digits mean 1: output for each compositum, not only the compositum polynomial pol, but a vector [R,a,b,k] where a (resp. b) is a root of P (resp. Q) expressed as a polynomial modulo R, and a small integer k such that al2+k*al1 is the chosen root of R; 2: assume that the number fields d [...]
+{"polcyclo",0,(void*)polcyclo_eval,11,"LDG","polcyclo(n,{a = 'x}): n-th cyclotomic polynomial evaluated at a."},
+{"polcyclofactors",0,(void*)polcyclofactors,11,"G","polcyclofactors(f): returns a vector of polynomials, whose product is the product of distinct cyclotomic polynomials dividing f."},
+{"poldegree",0,(void*)gppoldegree,11,"GDn","poldegree(x,{v}): degree of the polynomial or rational function x with respect to main variable if v is omitted, with respect to v otherwise. For scalar x, return 0 if x is non-zero and -oo otherwise."},
+{"poldisc",0,(void*)poldisc0,11,"GDn","poldisc(pol,{v}): discriminant of the polynomial pol, with respect to main variable if v is omitted, with respect to v otherwise."},
+{"poldiscreduced",0,(void*)reduceddiscsmith,11,"G","poldiscreduced(f): vector of elementary divisors of Z[a]/f'(a)Z[a], where a is a root of the polynomial f."},
+{"polgalois",0,(void*)polgalois,9,"Gp","polgalois(T): Galois group of the polynomial T (see manual for group coding). Return [n, s, k, name] where n is the group order, s the signature, k the index and name is the GAP4 name of the transitive group."},
+{"polgraeffe",0,(void*)polgraeffe,11,"G","polgraeffe(f): returns the Graeffe transform g of f, such that g(x^2) = f(x)f(-x)"},
+{"polhensellift",0,(void*)polhensellift,11,"GGGL","polhensellift(A, B, p, e): lift the factorization B of A modulo p to a factorization modulo p^e using Hensel lift. The factors in B must be pairwise relatively prime modulo p."},
+{"polhermite",0,(void*)polhermite_eval,11,"LDG","polhermite(n,{a='x}): Hermite polynomial H(n,v) of degree n, evaluated at a."},
+{"polinterpolate",0,(void*)polint,11,"GDGDGD&","polinterpolate(X,{Y},{x},{&e}): polynomial interpolation at x according to data vectors X, Y (ie return P such that P(X[i]) = Y[i] for all i). If Y is omitted, return P such that P(i) = X[i]. If present, e will contain an error estimate on the returned value."},
+{"poliscyclo",0,(void*)poliscyclo,11,"lG","poliscyclo(f): returns 0 if f is not a cyclotomic polynomial, and n > 0 if f = Phi_n, the n-th cyclotomic polynomial."},
+{"poliscycloprod",0,(void*)poliscycloprod,11,"lG","poliscycloprod(f): returns 1 if f is a product of cyclotomic polynonials, and 0 otherwise."},
+{"polisirreducible",0,(void*)isirreducible,11,"lG","polisirreducible(pol): true(1) if pol is an irreducible non-constant polynomial, false(0) if pol is reducible or constant."},
+{"pollead",0,(void*)pollead,11,"GDn","pollead(x,{v}): leading coefficient of polynomial or series x, or x itself if x is a scalar. Error otherwise. With respect to the main variable of x if v is omitted, with respect to the variable v otherwise."},
+{"pollegendre",0,(void*)pollegendre_eval,11,"LDG","pollegendre(n,{a='x}): legendre polynomial of degree n evaluated at a."},
+{"polmodular",0,(void*)polmodular,11,"LD0,L,DGDnD0,L,","polmodular(L, {inv = 0}, {x = 'x}, {y = 'y}, {derivs = 0}): return the modular polynomial of level L and invariant inv."},
+{"polrecip",0,(void*)polrecip,11,"G","polrecip(pol): reciprocal polynomial of pol."},
+{"polred",0,(void*)polred0,9,"GD0,L,DG","polred(T,{flag=0}): Deprecated, use polredbest. Reduction of the polynomial T (gives minimal polynomials only). The following binary digits of (optional) flag are significant 1: partial reduction, 2: gives also elements."},
+{"polredabs",0,(void*)polredabs0,9,"GD0,L,","polredabs(T,{flag=0}): a smallest generating polynomial of the number field for the T2 norm on the roots, with smallest index for the minimal T2 norm. flag is optional, whose binary digit mean 1: give the element whose characteristic polynomial is the given polynomial. 4: give all polynomials of minimal T2 norm (give only one of P(x) and P(-x))."},
+{"polredbest",0,(void*)polredbest,9,"GD0,L,","polredbest(T,{flag=0}): reduction of the polynomial T (gives minimal polynomials only). If flag=1, gives also elements."},
+{"polredord",0,(void*)polredord,9,"G","polredord(x): reduction of the polynomial x, staying in the same order."},
+{"polresultant",0,(void*)polresultant0,11,"GGDnD0,L,","polresultant(x,y,{v},{flag=0}): resultant of the polynomials x and y, with respect to the main variables of x and y if v is omitted, with respect to the variable v otherwise. flag is optional, and can be 0: default, uses either the subresultant algorithm, a modular algorithm or Sylvester's matrix, depending on the inputs; 1 uses Sylvester's matrix (should always be slower than the default)."},
+{"polresultantext",0,(void*)polresultantext0,11,"GGDn","polresultantext(A,B,{v}): return [U,V,R] such that R=polresultant(A,B,v) and U*A+V*B = R, where A and B are polynomials."},
+{"polroots",0,(void*)roots,11,"Gp","polroots(x): complex roots of the polynomial x using Schonhage's method, as modified by Gourdon."},
 {"polrootsff",0,(void*)polrootsff,4,"GDGDG","polrootsff(x,{p},{a}): returns the roots of the polynomial x in the finite field F_p[X]/a(X)F_p[X]. a or p can be omitted if x has t_FFELT coefficients."},
-{"polrootsmod",0,(void*)rootmod0,10,"GGD0,L,","polrootsmod(pol,p,{flag=0}): roots mod the prime p of the polynomial pol. flag is optional, and can be 0: default, or 1: use a naive search, useful for small p."},
-{"polrootspadic",0,(void*)rootpadic,10,"GGL","polrootspadic(x,p,r): p-adic roots of the polynomial x to precision r."},
-{"polrootsreal",0,(void*)realroots,10,"GDGp","polrootsreal(T, {ab}): real roots of the polynomial T with rational coefficients, using Uspensky's method. In interval ab = [a,b] if present."},
-{"polsturm",0,(void*)sturmpart,10,"lGDGDG","polsturm(T,{ab}): number of real roots of the squarefree polynomial T (in the interval ab = [a,b] if present)."},
-{"polsubcyclo",0,(void*)polsubcyclo,10,"LLDn","polsubcyclo(n,d,{v='x}): finds an equation (in variable v) for the d-th degree subfields of Q(zeta_n). Output is a polynomial, or a vector of polynomials if there are several such fields or none."},
-{"polsylvestermatrix",0,(void*)sylvestermatrix,10,"GG","polsylvestermatrix(x,y): forms the sylvester matrix associated to the two polynomials x and y. Warning: the polynomial coefficients are in columns, not in rows."},
-{"polsym",0,(void*)polsym,10,"GL","polsym(x,n): column vector of symmetric powers of the roots of x up to n."},
-{"poltchebi",0,(void*)polchebyshev1,10,"LDn","poltchebi(n,{v='x}): deprecated alias for polchebyshev"},
-{"poltschirnhaus",0,(void*)tschirnhaus,8,"G","poltschirnhaus(x): random Tschirnhausen transformation of the polynomial x."},
+{"polrootsmod",0,(void*)rootmod0,11,"GGD0,L,","polrootsmod(pol,p,{flag=0}): roots mod the prime p of the polynomial pol. flag is optional, and can be 0: default, or 1: use a naive search, useful for small p."},
+{"polrootspadic",0,(void*)rootpadic,11,"GGL","polrootspadic(x,p,r): p-adic roots of the polynomial x to precision r."},
+{"polrootsreal",0,(void*)realroots,11,"GDGp","polrootsreal(T, {ab}): real roots of the polynomial T with rational coefficients, using Uspensky's method. In interval ab = [a,b] if present."},
+{"polsturm",0,(void*)sturmpart,11,"lGDGDG","polsturm(T,{ab}): number of real roots of the squarefree polynomial T (in the interval ab = [a,b] if present)."},
+{"polsubcyclo",0,(void*)polsubcyclo,11,"LLDn","polsubcyclo(n,d,{v='x}): finds an equation (in variable v) for the d-th degree subfields of Q(zeta_n). Output is a polynomial, or a vector of polynomials if there are several such fields or none."},
+{"polsylvestermatrix",0,(void*)sylvestermatrix,11,"GG","polsylvestermatrix(x,y): forms the sylvester matrix associated to the two polynomials x and y. Warning: the polynomial coefficients are in columns, not in rows."},
+{"polsym",0,(void*)polsym,11,"GL","polsym(x,n): column vector of symmetric powers of the roots of x up to n."},
+{"poltchebi",0,(void*)polchebyshev1,11,"LDn","poltchebi(n,{v='x}): deprecated alias for polchebyshev"},
+{"poltschirnhaus",0,(void*)tschirnhaus,9,"G","poltschirnhaus(x): random Tschirnhausen transformation of the polynomial x."},
 {"polylog",0,(void*)polylog0,3,"LGD0,L,p","polylog(m,x,{flag=0}): m-th polylogarithm of x. flag is optional, and can be 0: default, 1: D_m~-modified m-th polylog of x, 2: D_m-modified m-th polylog of x, 3: P_m-modified m-th polylog of x."},
-{"polzagier",0,(void*)polzag,10,"LL","polzagier(n,m): Zagier's polynomials of index n,m."},
+{"polzagier",0,(void*)polzag,11,"LL","polzagier(n,m): Zagier's polynomials of index n,m."},
 {"powers",0,(void*)gpowers0,1,"GLDG","powers(x,n,{x0}): return the vector [1,x,...,x^n] if x0 is omitted, and [x0, x0*x, ..., x0*x^n] otherwise."},
 {"precision",0,(void*)precision0,2,"GD0,L,","precision(x,{n}): if n is present, return x at precision n. If n is omitted, return real precision of object x."},
 {"precprime",0,(void*)precprime,4,"G","precprime(x): largest pseudoprime <= x, 0 if x<=1."},
 {"prime",0,(void*)prime,4,"L","prime(n): returns the n-th prime (n C-integer)."},
 {"primepi",0,(void*)primepi,4,"G","primepi(x): the prime counting function pi(x) = #{p <= x, p prime}."},
 {"primes",0,(void*)primes0,4,"G","primes(n): returns the vector of the first n primes (integer), or the primes in interval n = [a,b]."},
-{"print",0,(void*)print,14,"vs*","print({str}*): outputs its string arguments (in raw format) ending with a newline."},
-{"print1",0,(void*)print1,14,"vs*","print1({str}*): outputs its string arguments (in raw format) without ending with newline."},
-{"printf",0,(void*)printf0,14,"vss*","printf(fmt,{x}*): prints its arguments according to the format fmt."},
-{"printsep",0,(void*)printsep,14,"vss*","printsep(sep,{str}*): outputs its string arguments (in raw format), separated by 'sep', ending with a newline."},
-{"printsep1",0,(void*)printsep1,14,"vss*","printsep(sep,{str}*): outputs its string arguments (in raw format), separated by 'sep', without ending with a newline."},
-{"printtex",0,(void*)printtex,14,"vs*","printtex({str}*): outputs its string arguments in TeX format."},
-{"prod",0,(void*)produit,12,"V=GGEDG","prod(X=a,b,expr,{x=1}): x times the product (X runs from a to b) of expression."},
-{"prodeuler",0,(void*)prodeuler0,12,"V=GGEp","prodeuler(X=a,b,expr): Euler product (X runs over the primes between a and b) of real or complex expression."},
-{"prodinf",0,(void*)prodinf0,12,"V=GED0,L,p","prodinf(X=a,expr,{flag=0}): infinite product (X goes from a to infinity) of real or complex expression. flag can be 0 (default) or 1, in which case compute the product of the 1+expr instead."},
+{"print",0,(void*)print,15,"vs*","print({str}*): outputs its string arguments (in raw format) ending with a newline."},
+{"print1",0,(void*)print1,15,"vs*","print1({str}*): outputs its string arguments (in raw format) without ending with newline."},
+{"printf",0,(void*)printf0,15,"vss*","printf(fmt,{x}*): prints its arguments according to the format fmt."},
+{"printsep",0,(void*)printsep,15,"vss*","printsep(sep,{str}*): outputs its string arguments (in raw format), separated by 'sep', ending with a newline."},
+{"printsep1",0,(void*)printsep1,15,"vss*","printsep(sep,{str}*): outputs its string arguments (in raw format), separated by 'sep', without ending with a newline."},
+{"printtex",0,(void*)printtex,15,"vs*","printtex({str}*): outputs its string arguments in TeX format."},
+{"prod",0,(void*)produit,13,"V=GGEDG","prod(X=a,b,expr,{x=1}): x times the product (X runs from a to b) of expression."},
+{"prodeuler",0,(void*)prodeuler0,13,"V=GGEp","prodeuler(X=a,b,expr): Euler product (X runs over the primes between a and b) of real or complex expression."},
+{"prodinf",0,(void*)prodinf0,13,"V=GED0,L,p","prodinf(X=a,expr,{flag=0}): infinite product (X goes from a to infinity) of real or complex expression. flag can be 0 (default) or 1, in which case compute the product of the 1+expr instead."},
 {"psi",0,(void*)gpsi,3,"Gp","psi(x): psi-function at x."},
-{"qfauto",0,(void*)qfauto0,11,"GDG","qfauto(G,{fl}): automorphism group of the positive definite quadratic form G."},
-{"qfautoexport",0,(void*)qfautoexport,11,"GD0,L,","qfautoexport(qfa,{flag}): qfa being an automorphism group as output by qfauto, output a string representing the underlying matrix group in GAP notation (default) or Magma notation (flag = 1)."},
+{"qfauto",0,(void*)qfauto0,12,"GDG","qfauto(G,{fl}): automorphism group of the positive definite quadratic form G."},
+{"qfautoexport",0,(void*)qfautoexport,12,"GD0,L,","qfautoexport(qfa,{flag}): qfa being an automorphism group as output by qfauto, output a string representing the underlying matrix group in GAP notation (default) or Magma notation (flag = 1)."},
 {"qfbclassno",0,(void*)qfbclassno0,4,"GD0,L,","qfbclassno(D,{flag=0}): class number of discriminant D using Shanks's method by default. If (optional) flag is set to 1, use Euler products."},
 {"qfbcompraw",0,(void*)qfbcompraw,4,"GG","qfbcompraw(x,y): Gaussian composition without reduction of the binary quadratic forms x and y."},
 {"qfbhclassno",0,(void*)hclassno,4,"G","qfbhclassno(x): Hurwitz-Kronecker class number of x>0."},
-{"qfbil",0,(void*)qfbil,11,"GGDG","qfbil(x,y,{q}): evaluate the bilinear form q (symmetric matrix) at (x,y); if q omitted, use the standard Euclidean scalar product."},
+{"qfbil",0,(void*)qfbil,12,"GGDG","qfbil(x,y,{q}): evaluate the bilinear form q (symmetric matrix) at (x,y); if q omitted, use the standard Euclidean scalar product."},
 {"qfbnucomp",0,(void*)nucomp,4,"GGG","qfbnucomp(x,y,L): composite of primitive positive definite quadratic forms x and y using nucomp and nudupl, where L=[|D/4|^(1/4)] is precomputed."},
 {"qfbnupow",0,(void*)nupow,4,"GGDG","qfbnupow(x,n,{L}): n-th power of primitive positive definite quadratic form x using nucomp and nudupl."},
 {"qfbpowraw",0,(void*)qfbpowraw,4,"GL","qfbpowraw(x,n): n-th power without reduction of the binary quadratic form x."},
@@ -753,20 +765,20 @@ entree functions_basic[]={
 {"qfbred",0,(void*)qfbred0,4,"GD0,L,DGDGDG","qfbred(x,{flag=0},{d},{isd},{sd}): reduction of the binary quadratic form x. All other args. are optional. The arguments d, isd and sd, if present, supply the values of the discriminant, floor(sqrt(d)) and sqrt(d) respectively. If d<0, its value is not used and all references to Shanks's distance hereafter are meaningless. flag can be any of 0: default, uses Shanks's distance function d; 1: use d, do a single reduction step; 2: do not use d; 3 [...]
 {"qfbredsl2",0,(void*)qfbredsl2,4,"GDG","qfbredsl2(x,{data}): reduction of the binary quadratic form x, return [y,g] where y is reduced and g in Sl(2,Z) is such that g.x = y; data, if present, must be equal to [D, sqrtint(D)], where D > 0 is the discriminant of x."},
 {"qfbsolve",0,(void*)qfbsolve,4,"GG","qfbsolve(Q,p): Return [x,y] so that Q(x,y)=p where Q is a binary quadratic form and p a prime number, or 0 if there is no solution."},
-{"qfgaussred",0,(void*)qfgaussred,11,"G","qfgaussred(q): square reduction of the (symmetric) matrix q (returns a square matrix whose i-th diagonal term is the coefficient of the i-th square in which the coefficient of the i-th variable is 1)."},
-{"qfisom",0,(void*)qfisom0,11,"GGDG","qfisom(G,H,{fl}): find an isomorphism between the integral positive definite quadratic forms G and H if it exists. G can also be given by a qfisominit structure which is preferable if several forms need to be compared to G."},
-{"qfisominit",0,(void*)qfisominit0,11,"GDG","qfisominit(G,{fl}): G being a square and symmetric matrix representing an integral positive definite quadratic form, this function return a structure allowing to compute isomorphisms between G and other quadratic form faster."},
-{"qfjacobi",0,(void*)jacobi,11,"Gp","qfjacobi(A): eigenvalues and orthogonal matrix of eigenvectors of the real symmetric matrix A."},
-{"qflll",0,(void*)qflll0,11,"GD0,L,","qflll(x,{flag=0}): LLL reduction of the vectors forming the matrix x (gives the unimodular transformation matrix T such that x*T is LLL-reduced). flag is optional, and can be 0: default, 1: assumes x is integral, 2: assumes x is integral, returns a partially reduced basis, 4: assumes x is integral, returns [K,T] where K is the integer kernel of x and T the LLL reduced image, 5: same as 4 but x may have polynomial coefficients, 8: same as 0 but x may  [...]
-{"qflllgram",0,(void*)qflllgram0,11,"GD0,L,","qflllgram(G,{flag=0}): LLL reduction of the lattice whose gram matrix is G (gives the unimodular transformation matrix). flag is optional and can be 0: default,1: assumes x is integral, 4: assumes x is integral, returns [K,T],  where K is the integer kernel of x and T the LLL reduced image, 5: same as 4 but x may have polynomial coefficients, 8: same as 0 but x may have polynomial coefficients."},
-{"qfminim",0,(void*)qfminim0,11,"GDGDGD0,L,p","qfminim(x,{b},{m},{flag=0}): x being a square and symmetric matrix representing a positive definite quadratic form, this function deals with the vectors of x whose norm is less than or equal to b, enumerated using the Fincke-Pohst algorithm, storing at most m vectors (no limit if m is omitted). The function searches for the minimal non-zero vectors if b is omitted. The precise behavior depends on flag. 0: returns at most 2m vectors (unless m [...]
-{"qfnorm",0,(void*)qfnorm,11,"GDG","qfnorm(x,{q}): evaluate the binary quadratic form q (symmetric matrix) at x; if q omitted, use the standard Euclidean form."},
-{"qforbits",0,(void*)qforbits,11,"GG","qforbits(G,V): return the orbits of V under the action of the group of linear transformation generated by the set G, which must stabilize V."},
-{"qfparam",0,(void*)qfparam,11,"GGD0,L,","qfparam(G, sol, {flag = 0}): coefficients of binary quadratic forms that parametrize the solutions of the ternary quadratic form G, using the particular solution sol."},
-{"qfperfection",0,(void*)perf,11,"G","qfperfection(G): rank of matrix of xx~ for x minimal vectors of a gram matrix G."},
-{"qfrep",0,(void*)qfrep0,11,"GGD0,L,","qfrep(q,B,{flag=0}): vector of (half) the number of vectors of norms from 1 to B for the integral and definite quadratic form q. If flag is 1, count vectors of even norm from 1 to 2B."},
-{"qfsign",0,(void*)qfsign,11,"G","qfsign(x): signature of the symmetric matrix x."},
-{"qfsolve",0,(void*)qfsolve,11,"G","qfsolve(G): solve over Q the quadratic equation X^t G X = 0, where G is a symmetric matrix."},
+{"qfgaussred",0,(void*)qfgaussred,12,"G","qfgaussred(q): square reduction of the (symmetric) matrix q (returns a square matrix whose i-th diagonal term is the coefficient of the i-th square in which the coefficient of the i-th variable is 1)."},
+{"qfisom",0,(void*)qfisom0,12,"GGDG","qfisom(G,H,{fl}): find an isomorphism between the integral positive definite quadratic forms G and H if it exists. G can also be given by a qfisominit structure which is preferable if several forms need to be compared to G."},
+{"qfisominit",0,(void*)qfisominit0,12,"GDGDG","qfisominit(G,{fl},{m}): G being a square and symmetric matrix representing an integral positive definite quadratic form, this function returns a structure allowing to compute isomorphisms between G and other quadratic form faster."},
+{"qfjacobi",0,(void*)jacobi,12,"Gp","qfjacobi(A): eigenvalues and orthogonal matrix of eigenvectors of the real symmetric matrix A."},
+{"qflll",0,(void*)qflll0,12,"GD0,L,","qflll(x,{flag=0}): LLL reduction of the vectors forming the matrix x (gives the unimodular transformation matrix T such that x*T is LLL-reduced). flag is optional, and can be 0: default, 1: assumes x is integral, 2: assumes x is integral, returns a partially reduced basis, 4: assumes x is integral, returns [K,T] where K is the integer kernel of x and T the LLL reduced image, 5: same as 4 but x may have polynomial coefficients, 8: same as 0 but x may  [...]
+{"qflllgram",0,(void*)qflllgram0,12,"GD0,L,","qflllgram(G,{flag=0}): LLL reduction of the lattice whose gram matrix is G (gives the unimodular transformation matrix). flag is optional and can be 0: default,1: assumes x is integral, 4: assumes x is integral, returns [K,T],  where K is the integer kernel of x and T the LLL reduced image, 5: same as 4 but x may have polynomial coefficients, 8: same as 0 but x may have polynomial coefficients."},
+{"qfminim",0,(void*)qfminim0,12,"GDGDGD0,L,p","qfminim(x,{b},{m},{flag=0}): x being a square and symmetric matrix representing a positive definite quadratic form, this function deals with the vectors of x whose norm is less than or equal to b, enumerated using the Fincke-Pohst algorithm, storing at most m vectors (no limit if m is omitted). The function searches for the minimal non-zero vectors if b is omitted. The precise behavior depends on flag. 0: returns at most 2m vectors (unless m [...]
+{"qfnorm",0,(void*)qfnorm,12,"GDG","qfnorm(x,{q}): evaluate the binary quadratic form q (symmetric matrix) at x; if q omitted, use the standard Euclidean form."},
+{"qforbits",0,(void*)qforbits,12,"GG","qforbits(G,V): return the orbits of V under the action of the group of linear transformation generated by the set G, which must stabilize V."},
+{"qfparam",0,(void*)qfparam,12,"GGD0,L,","qfparam(G, sol, {flag = 0}): coefficients of binary quadratic forms that parametrize the solutions of the ternary quadratic form G, using the particular solution sol."},
+{"qfperfection",0,(void*)perf,12,"G","qfperfection(G): rank of matrix of xx~ for x minimal vectors of a gram matrix G."},
+{"qfrep",0,(void*)qfrep0,12,"GGD0,L,","qfrep(q,B,{flag=0}): vector of (half) the number of vectors of norms from 1 to B for the integral and definite quadratic form q. If flag is 1, count vectors of even norm from 1 to 2B."},
+{"qfsign",0,(void*)qfsign,12,"G","qfsign(x): signature of the symmetric matrix x."},
+{"qfsolve",0,(void*)qfsolve,12,"G","qfsolve(G): solve over Q the quadratic equation X^t G X = 0, where G is a symmetric matrix."},
 {"quadclassunit",0,(void*)quadclassunit0,4,"GD0,L,DGp","quadclassunit(D,{flag=0},{tech=[]}): compute the structure of the class group and the regulator of the quadratic field of discriminant D. See manual for the optional technical parameters."},
 {"quaddisc",0,(void*)quaddisc,4,"G","quaddisc(x): discriminant of the quadratic field Q(sqrt(x))."},
 {"quadgen",0,(void*)quadgen,4,"G","quadgen(D): standard generator of quadratic order of discriminant D."},
@@ -775,67 +787,68 @@ entree functions_basic[]={
 {"quadray",0,(void*)quadray,4,"GGp","quadray(D,f): relative equation for the ray class field of conductor f for the quadratic field of discriminant D (which can also be a bnf)."},
 {"quadregulator",0,(void*)quadregulator,4,"Gp","quadregulator(x): regulator of the real quadratic field of discriminant x."},
 {"quadunit",0,(void*)quadunit,4,"G","quadunit(D): fundamental unit of the quadratic field of discriminant D where D must be positive."},
-{"ramanujantau",0,(void*)ramanujantau,4,"G","tau(n): compute the value of Ramanujan's tau function at n, assuming the GRH. Algorithm in O(n^{1/2+eps})."},
+{"ramanujantau",0,(void*)ramanujantau,4,"G","ramanujantau(n): compute the value of Ramanujan's tau function at n, assuming the GRH. Algorithm in O(n^{1/2+eps})."},
 {"random",0,(void*)genrand,2,"DG","random({N=2^31}): random object, depending on the type of N. Integer between 0 and N-1 (t_INT), int mod N (t_INTMOD), element in a finite field (t_FFELT), point on an elliptic curve (ellinit mod p or over a finite field)."},
 {"randomprime",0,(void*)randomprime,4,"DG","randomprime({N = 2^31}): returns a strong pseudo prime in [2, N-1]."},
-{"read",0,(void*)gp_read_file,14,"D\"\",s,","read({filename}): read from the input file filename. If filename is omitted, reread last input file, be it from read() or \\r."},
-{"readstr",0,(void*)readstr,14,"D\"\",s,","readstr({filename}): returns the vector of GP strings containing the lines in filename."},
-{"readvec",0,(void*)gp_readvec_file,14,"D\"\",s,","readvec({filename}): create a vector whose components are the evaluation of all the expressions found in the input file filename."},
+{"read",0,(void*)gp_read_file,15,"D\"\",s,","read({filename}): read from the input file filename. If filename is omitted, reread last input file, be it from read() or \\r."},
+{"readstr",0,(void*)readstr,15,"D\"\",s,","readstr({filename}): returns the vector of GP strings containing the lines in filename."},
+{"readvec",0,(void*)gp_readvec_file,15,"D\"\",s,","readvec({filename}): create a vector whose components are the evaluation of all the expressions found in the input file filename."},
 {"real",0,(void*)greal,2,"G","real(x): real part of x."},
 {"removeprimes",0,(void*)removeprimes,4,"DG","removeprimes({x=[]}): remove primes in the vector x from the prime table. x can also be a single integer. List the current extra primes if x is omitted."},
-{"return",0,(void*)return0,14,"DG","return({x=0}): return from current subroutine with result x."},
-{"rnfalgtobasis",0,(void*)rnfalgtobasis,8,"GG","rnfalgtobasis(rnf,x): relative version of nfalgtobasis, where rnf is a relative numberfield."},
-{"rnfbasis",0,(void*)rnfbasis,8,"GG","rnfbasis(bnf,M): given a projective Z_K-module M as output by rnfpseudobasis or rnfsteinitz, gives either a basis of M if it is free, or an n+1-element generating set."},
-{"rnfbasistoalg",0,(void*)rnfbasistoalg,8,"GG","rnfbasistoalg(rnf,x): relative version of nfbasistoalg, where rnf is a relative numberfield."},
-{"rnfcharpoly",0,(void*)rnfcharpoly,8,"GGGDn","rnfcharpoly(nf,T,a,{var='x}): characteristic polynomial of a over nf, where a belongs to the algebra defined by T over nf. Returns a polynomial in variable var (x by default)."},
-{"rnfconductor",0,(void*)rnfconductor,8,"GG","rnfconductor(bnf,pol): conductor of the Abelian extension of bnf defined by pol. The result is [conductor,bnr,subgroup], where conductor is the conductor itself, bnr the associated bnr structure, and subgroup the HNF defining the norm group (Artin or Takagi group) on the given generators bnr.gen"},
-{"rnfdedekind",0,(void*)rnfdedekind,8,"GGDGD0,L,","rnfdedekind(nf,pol,{pr},{flag=0}): relative Dedekind criterion over the number field K, represented by nf, applied to the order O_K[X]/(P), modulo the prime ideal pr (at all primes if pr omitted, in which case flag is automatically set to 1). P is assumed to be monic, irreducible, in O_K[X]. Returns [max,basis,v], where basis is a pseudo-basis of the enlarged order, max is 1 iff this order is pr-maximal, and v is the valuation at pr of t [...]
-{"rnfdet",0,(void*)rnfdet,8,"GG","rnfdet(nf,M): given a pseudo-matrix M, compute its determinant."},
-{"rnfdisc",0,(void*)rnfdiscf,8,"GG","rnfdisc(nf,pol): given a pol with coefficients in nf, gives a 2-component vector [D,d], where D is the relative ideal discriminant, and d is the relative discriminant in nf^*/nf*^2."},
-{"rnfeltabstorel",0,(void*)rnfeltabstorel,8,"GG","rnfeltabstorel(rnf,x): transforms the element x from absolute to relative representation."},
-{"rnfeltdown",0,(void*)rnfeltdown,8,"GG","rnfeltdown(rnf,x): expresses x on the base field if possible; returns an error otherwise."},
-{"rnfeltnorm",0,(void*)rnfeltnorm,8,"GG","rnfeltnorm(rnf,x): returns the relative norm N_{L/K}(x), as an element of K"},
-{"rnfeltreltoabs",0,(void*)rnfeltreltoabs,8,"GG","rnfeltreltoabs(rnf,x): transforms the element x from relative to absolute representation."},
-{"rnfelttrace",0,(void*)rnfelttrace,8,"GG","rnfelttrace(rnf,x): returns the relative trace N_{L/K}(x), as an element of K"},
-{"rnfeltup",0,(void*)rnfeltup,8,"GG","rnfeltup(rnf,x): expresses x (belonging to the base field) on the relative field."},
-{"rnfequation",0,(void*)rnfequation0,8,"GGD0,L,","rnfequation(nf,pol,{flag=0}): given a pol with coefficients in nf, gives an absolute equation z of the number field defined by pol. flag is optional, and can be 0: default, or non-zero, gives [z,al,k], where z defines the absolute equation L/Q as in the default behavior, al expresses as an element of L a root of the polynomial defining the base field nf, and k is a small integer such that t = b + k al is a root of z, for b a root of pol."},
-{"rnfhnfbasis",0,(void*)rnfhnfbasis,8,"GG","rnfhnfbasis(bnf,x): given an order x as output by rnfpseudobasis, gives either a true HNF basis of the order if it exists, zero otherwise."},
-{"rnfidealabstorel",0,(void*)rnfidealabstorel,8,"GG","rnfidealabstorel(rnf,x): transforms the ideal x from absolute to relative representation."},
-{"rnfidealdown",0,(void*)rnfidealdown,8,"GG","rnfidealdown(rnf,x): finds the intersection of the ideal x with the base field."},
-{"rnfidealhnf",0,(void*)rnfidealhnf,8,"GG","rnfidealhnf(rnf,x): relative version of idealhnf, where rnf is a relative numberfield."},
-{"rnfidealmul",0,(void*)rnfidealmul,8,"GGG","rnfidealmul(rnf,x,y): relative version of idealmul, where rnf is a relative numberfield."},
-{"rnfidealnormabs",0,(void*)rnfidealnormabs,8,"GG","rnfidealnormabs(rnf,x): absolute norm of the ideal x."},
-{"rnfidealnormrel",0,(void*)rnfidealnormrel,8,"GG","rnfidealnormrel(rnf,x): relative norm of the ideal x."},
-{"rnfidealreltoabs",0,(void*)rnfidealreltoabs,8,"GG","rnfidealreltoabs(rnf,x): transforms the ideal x from relative to absolute representation."},
-{"rnfidealtwoelt",0,(void*)rnfidealtwoelement,8,"GG","rnfidealtwoelt(rnf,x): relative version of idealtwoelt, where rnf is a relative numberfield."},
-{"rnfidealup",0,(void*)rnfidealup,8,"GG","rnfidealup(rnf,x): lifts the ideal x (of the base field) to the relative field."},
-{"rnfinit",0,(void*)rnfinit,8,"GG","rnfinit(nf,pol): pol being an irreducible polynomial defined over the number field nf, initializes a vector of data necessary for working in relative number fields (rnf functions). See manual for technical details."},
-{"rnfisabelian",0,(void*)rnfisabelian,8,"lGG","rnfisabelian(nf,T): T being a relative polynomial with coefficients in nf, return 1 if it defines an abelian extension, and 0 otherwise."},
-{"rnfisfree",0,(void*)rnfisfree,8,"lGG","rnfisfree(bnf,x): given an order x as output by rnfpseudobasis or rnfsteinitz, outputs true (1) or false (0) according to whether the order is free or not."},
-{"rnfisnorm",0,(void*)rnfisnorm,8,"GGD0,L,","rnfisnorm(T,a,{flag=0}): T is as output by rnfisnorminit applied to L/K. Tries to tell whether a is a norm from L/K. Returns a vector [x,q] where a=Norm(x)*q. Looks for a solution which is a S-integer, with S a list of places in K containing the ramified primes, generators of the class group of ext, as well as those primes dividing a. If L/K is Galois, omit flag, otherwise it is used to add more places to S: all the places above the primes p < [...]
-{"rnfisnorminit",0,(void*)rnfisnorminit,8,"GGD2,L,","rnfisnorminit(pol,polrel,{flag=2}): let K be defined by a root of pol, L/K the extension defined by polrel. Compute technical data needed by rnfisnorm to solve norm equations Nx = a, for x in L, and a in K. If flag=0, do not care whether L/K is Galois or not; if flag = 1, assume L/K is Galois; if flag = 2, determine whether L/K is Galois."},
-{"rnfkummer",0,(void*)rnfkummer,8,"GDGD0,L,p","rnfkummer(bnr,{subgp},{d=0}): bnr being as output by bnrinit, finds a relative equation for the class field corresponding to the module in bnr and the given congruence subgroup (the ray class field if subgp is omitted). d can be zero (default), or positive, and in this case the output is the list of all relative equations of degree d for the given bnr, with the same conductor as (bnr, subgp)."},
-{"rnflllgram",0,(void*)rnflllgram,8,"GGGp","rnflllgram(nf,pol,order): given a pol with coefficients in nf and an order as output by rnfpseudobasis or similar, gives [[neworder],U], where neworder is a reduced order and U is the unimodular transformation matrix."},
-{"rnfnormgroup",0,(void*)rnfnormgroup,8,"GG","rnfnormgroup(bnr,pol): norm group (or Artin or Takagi group) corresponding to the Abelian extension of bnr.bnf defined by pol, where the module corresponding to bnr is assumed to be a multiple of the conductor. The result is the HNF defining the norm group on the generators in bnr.gen."},
-{"rnfpolred",0,(void*)rnfpolred,8,"GGp","rnfpolred(nf,pol): given a pol with coefficients in nf, finds a list of relative polynomials defining some subfields, hopefully simpler."},
-{"rnfpolredabs",0,(void*)rnfpolredabs,8,"GGD0,L,","rnfpolredabs(nf,pol,{flag=0}): given a pol with coefficients in nf, finds a relative simpler polynomial defining the same field. Binary digits of flag mean: 1: return also the element whose characteristic polynomial is the given polynomial, 2: return an absolute polynomial, 16: partial reduction."},
-{"rnfpolredbest",0,(void*)rnfpolredbest,8,"GGD0,L,","rnfpolredbest(nf,pol,{flag=0}): given a pol with coefficients in nf, finds a relative polynomial P defining the same field, hopefully simpler than pol; flag can be 0: default, 1: return [P,a], where a is a root of pol 2: return an absolute polynomial Pabs, 3: return [Pabs, a,b], where a is a root of nf.pol and b is a root of pol."},
-{"rnfpseudobasis",0,(void*)rnfpseudobasis,8,"GG","rnfpseudobasis(nf,pol): given a pol with coefficients in nf, gives a 4-component vector [A,I,D,d] where [A,I] is a pseudo basis of the maximal order in HNF on the power basis, D is the relative ideal discriminant, and d is the relative discriminant in nf^*/nf*^2."},
-{"rnfsteinitz",0,(void*)rnfsteinitz,8,"GG","rnfsteinitz(nf,x): given an order x as output by rnfpseudobasis, gives [A,I,D,d] where (A,I) is a pseudo basis where all the ideals except perhaps the last are trivial."},
+{"return",0,(void*)return0,15,"DG","return({x=0}): return from current subroutine with result x."},
+{"rnfalgtobasis",0,(void*)rnfalgtobasis,9,"GG","rnfalgtobasis(rnf,x): relative version of nfalgtobasis, where rnf is a relative numberfield."},
+{"rnfbasis",0,(void*)rnfbasis,9,"GG","rnfbasis(bnf,M): given a projective Z_K-module M as output by rnfpseudobasis or rnfsteinitz, gives either a basis of M if it is free, or an n+1-element generating set."},
+{"rnfbasistoalg",0,(void*)rnfbasistoalg,9,"GG","rnfbasistoalg(rnf,x): relative version of nfbasistoalg, where rnf is a relative numberfield."},
+{"rnfcharpoly",0,(void*)rnfcharpoly,9,"GGGDn","rnfcharpoly(nf,T,a,{var='x}): characteristic polynomial of a over nf, where a belongs to the algebra defined by T over nf. Returns a polynomial in variable var (x by default)."},
+{"rnfconductor",0,(void*)rnfconductor,9,"GG","rnfconductor(bnf,pol): conductor of the Abelian extension of bnf defined by pol. The result is [conductor,bnr,subgroup], where conductor is the conductor itself, bnr the associated bnr structure, and subgroup the HNF defining the norm group (Artin or Takagi group) on the given generators bnr.gen"},
+{"rnfdedekind",0,(void*)rnfdedekind,9,"GGDGD0,L,","rnfdedekind(nf,pol,{pr},{flag=0}): relative Dedekind criterion over the number field K, represented by nf, applied to the order O_K[X]/(P), modulo the prime ideal pr (at all primes if pr omitted, in which case flag is automatically set to 1). P is assumed to be monic, irreducible, in O_K[X]. Returns [max,basis,v], where basis is a pseudo-basis of the enlarged order, max is 1 iff this order is pr-maximal, and v is the valuation at pr of t [...]
+{"rnfdet",0,(void*)rnfdet,9,"GG","rnfdet(nf,M): given a pseudo-matrix M, compute its determinant."},
+{"rnfdisc",0,(void*)rnfdiscf,9,"GG","rnfdisc(nf,pol): given a pol with coefficients in nf, gives a 2-component vector [D,d], where D is the relative ideal discriminant, and d is the relative discriminant in nf^*/nf*^2."},
+{"rnfeltabstorel",0,(void*)rnfeltabstorel,9,"GG","rnfeltabstorel(rnf,x): transforms the element x from absolute to relative representation."},
+{"rnfeltdown",0,(void*)rnfeltdown0,9,"GGD0,L,","rnfeltdown(rnf,x,{flag=0}): expresses x on the base field if possible; returns an error otherwise."},
+{"rnfeltnorm",0,(void*)rnfeltnorm,9,"GG","rnfeltnorm(rnf,x): returns the relative norm N_{L/K}(x), as an element of K"},
+{"rnfeltreltoabs",0,(void*)rnfeltreltoabs,9,"GG","rnfeltreltoabs(rnf,x): transforms the element x from relative to absolute representation."},
+{"rnfelttrace",0,(void*)rnfelttrace,9,"GG","rnfelttrace(rnf,x): returns the relative trace Tr_{L/K}(x), as an element of K"},
+{"rnfeltup",0,(void*)rnfeltup0,9,"GGD0,L,","rnfeltup(rnf,x,{flag=0}): expresses x (belonging to the base field) on the relative field. As a t_POLMOD if flag = 0 and as a t_COL on the absolute field integer basis if flag = 1"},
+{"rnfequation",0,(void*)rnfequation0,9,"GGD0,L,","rnfequation(nf,pol,{flag=0}): given a pol with coefficients in nf, gives an absolute equation z of the number field defined by pol. flag is optional, and can be 0: default, or non-zero, gives [z,al,k], where z defines the absolute equation L/Q as in the default behavior, al expresses as an element of L a root of the polynomial defining the base field nf, and k is a small integer such that t = b + k al is a root of z, for b a root of pol."},
+{"rnfhnfbasis",0,(void*)rnfhnfbasis,9,"GG","rnfhnfbasis(bnf,x): given an order x as output by rnfpseudobasis, gives either a true HNF basis of the order if it exists, zero otherwise."},
+{"rnfidealabstorel",0,(void*)rnfidealabstorel,9,"GG","rnfidealabstorel(rnf,x): transforms the ideal x from absolute to relative representation."},
+{"rnfidealdown",0,(void*)rnfidealdown,9,"GG","rnfidealdown(rnf,x): finds the intersection of the ideal x with the base field."},
+{"rnfidealhnf",0,(void*)rnfidealhnf,9,"GG","rnfidealhnf(rnf,x): relative version of idealhnf, where rnf is a relative numberfield."},
+{"rnfidealmul",0,(void*)rnfidealmul,9,"GGG","rnfidealmul(rnf,x,y): relative version of idealmul, where rnf is a relative numberfield."},
+{"rnfidealnormabs",0,(void*)rnfidealnormabs,9,"GG","rnfidealnormabs(rnf,x): absolute norm of the ideal x."},
+{"rnfidealnormrel",0,(void*)rnfidealnormrel,9,"GG","rnfidealnormrel(rnf,x): relative norm of the ideal x."},
+{"rnfidealprimedec",0,(void*)rnfidealprimedec,9,"GG","rnfidealprimedec(rnf,pr): prime ideal decomposition of the maximal ideal pr of K in L/K; pr is also allowed to be a prime number p, in which case we return a pair of vectors [SK,SL], where SK contains the primes of K above p and SL[i] is the vector of primes of L above SK[i]."},
+{"rnfidealreltoabs",0,(void*)rnfidealreltoabs0,9,"GGD0,L,","rnfidealreltoabs(rnf,x,{flag=0}): transforms the ideal x from relative to absolute representation. As a vector of t_POLMODs if flag = 0 and as an ideal in HNF in the absolute field if flag = 1"},
+{"rnfidealtwoelt",0,(void*)rnfidealtwoelement,9,"GG","rnfidealtwoelt(rnf,x): relative version of idealtwoelt, where rnf is a relative numberfield."},
+{"rnfidealup",0,(void*)rnfidealup0,9,"GGD0,L,","rnfidealup(rnf,x,{flag=0}): lifts the ideal x (of the base field) to the relative field. As a vector of t_POLMODs if flag = 0 and as an ideal in HNF in the absolute field if flag = 1"},
+{"rnfinit",0,(void*)rnfinit0,9,"GGD0,L,","rnfinit(nf,pol,{flag=0}): pol being an irreducible polynomial defined over the number field nf, initializes a vector of data necessary for working in relative number fields (rnf functions). See manual for technical details."},
+{"rnfisabelian",0,(void*)rnfisabelian,9,"lGG","rnfisabelian(nf,T): T being a relative polynomial with coefficients in nf, return 1 if it defines an abelian extension, and 0 otherwise."},
+{"rnfisfree",0,(void*)rnfisfree,9,"lGG","rnfisfree(bnf,x): given an order x as output by rnfpseudobasis or rnfsteinitz, outputs true (1) or false (0) according to whether the order is free or not."},
+{"rnfisnorm",0,(void*)rnfisnorm,9,"GGD0,L,","rnfisnorm(T,a,{flag=0}): T is as output by rnfisnorminit applied to L/K. Tries to tell whether a is a norm from L/K. Returns a vector [x,q] where a=Norm(x)*q. Looks for a solution which is a S-integer, with S a list of places in K containing the ramified primes, generators of the class group of ext, as well as those primes dividing a. If L/K is Galois, omit flag, otherwise it is used to add more places to S: all the places above the primes p < [...]
+{"rnfisnorminit",0,(void*)rnfisnorminit,9,"GGD2,L,","rnfisnorminit(pol,polrel,{flag=2}): let K be defined by a root of pol, L/K the extension defined by polrel. Compute technical data needed by rnfisnorm to solve norm equations Nx = a, for x in L, and a in K. If flag=0, do not care whether L/K is Galois or not; if flag = 1, assume L/K is Galois; if flag = 2, determine whether L/K is Galois."},
+{"rnfkummer",0,(void*)rnfkummer,9,"GDGD0,L,p","rnfkummer(bnr,{subgp},{d=0}): bnr being as output by bnrinit, finds a relative equation for the class field corresponding to the module in bnr and the given congruence subgroup (the ray class field if subgp is omitted). d can be zero (default), or positive, and in this case the output is the list of all relative equations of degree d for the given bnr, with the same conductor as (bnr, subgp)."},
+{"rnflllgram",0,(void*)rnflllgram,9,"GGGp","rnflllgram(nf,pol,order): given a pol with coefficients in nf and an order as output by rnfpseudobasis or similar, gives [[neworder],U], where neworder is a reduced order and U is the unimodular transformation matrix."},
+{"rnfnormgroup",0,(void*)rnfnormgroup,9,"GG","rnfnormgroup(bnr,pol): norm group (or Artin or Takagi group) corresponding to the Abelian extension of bnr.bnf defined by pol, where the module corresponding to bnr is assumed to be a multiple of the conductor. The result is the HNF defining the norm group on the generators in bnr.gen."},
+{"rnfpolred",0,(void*)rnfpolred,9,"GGp","rnfpolred(nf,pol): given a pol with coefficients in nf, finds a list of relative polynomials defining some subfields, hopefully simpler."},
+{"rnfpolredabs",0,(void*)rnfpolredabs,9,"GGD0,L,","rnfpolredabs(nf,pol,{flag=0}): given a pol with coefficients in nf, finds a relative simpler polynomial defining the same field. Binary digits of flag mean: 1: return also the element whose characteristic polynomial is the given polynomial, 2: return an absolute polynomial, 16: partial reduction."},
+{"rnfpolredbest",0,(void*)rnfpolredbest,9,"GGD0,L,","rnfpolredbest(nf,pol,{flag=0}): given a pol with coefficients in nf, finds a relative polynomial P defining the same field, hopefully simpler than pol; flag can be 0: default, 1: return [P,a], where a is a root of pol 2: return an absolute polynomial Pabs, 3: return [Pabs, a,b], where a is a root of nf.pol and b is a root of pol."},
+{"rnfpseudobasis",0,(void*)rnfpseudobasis,9,"GG","rnfpseudobasis(nf,pol): given a pol with coefficients in nf, gives a 4-component vector [A,I,D,d] where [A,I] is a pseudo basis of the maximal order in HNF on the power basis, D is the relative ideal discriminant, and d is the relative discriminant in nf^*/nf*^2."},
+{"rnfsteinitz",0,(void*)rnfsteinitz,9,"GG","rnfsteinitz(nf,x): given an order x as output by rnfpseudobasis, gives [A,I,D,d] where (A,I) is a pseudo basis where all the ideals except perhaps the last are trivial."},
 {"round",0,(void*)round0,2,"GD&","round(x,{&e}): take the nearest integer to all the coefficients of x. If e is present, do not take into account loss of integer part precision, and set e = error estimate in bits."},
-{"select",0,(void*)select0,14,"GGD0,L,","select(f, A, {flag = 0}): selects elements of A according to the selection function f. If flag is 1, return the indices of those elements (indirect selection)"},
-{"self",0,(void*)pari_self,14,"m","self(): return the calling function or closure. Useful for defining anonymous recursive functions."},
-{"seralgdep",0,(void*)seralgdep,11,"GLL","seralgdep(s,p,r): find a linear relation between powers (1,s, ..., s^p) of the series s, with polynomial coefficients of degree <= r."},
-{"serconvol",0,(void*)convol,10,"GG","serconvol(x,y): convolution (or Hadamard product) of two power series."},
-{"serlaplace",0,(void*)laplace,10,"G","serlaplace(x): replaces the power series sum of a_n*x^n/n! by sum of a_n*x^n. For the reverse operation, use serconvol(x,exp(X))."},
-{"serreverse",0,(void*)serreverse,10,"G","serreverse(s): reversion of the power series s."},
-{"setbinop",0,(void*)setbinop,11,"GGDG","setbinop(f,X,{Y}): the set {f(x,y), x in X, y in Y}. If Y is omitted, assume that X = Y and that f is symmetric."},
-{"setintersect",0,(void*)setintersect,11,"GG","setintersect(x,y): intersection of the sets x and y."},
-{"setisset",0,(void*)setisset,11,"lG","setisset(x): true(1) if x is a set (row vector with strictly increasing entries), false(0) if not."},
-{"setminus",0,(void*)setminus,11,"GG","setminus(x,y): set of elements of x not belonging to y."},
-{"setrand",0,(void*)setrand,14,"vG","setrand(n): reset the seed of the random number generator to n."},
-{"setsearch",0,(void*)setsearch,11,"lGGD0,L,","setsearch(S,x,{flag=0}): determines whether x belongs to the set (or sorted list) S. If flag is 0 or omitted, returns 0 if it does not, otherwise returns the index j such that x==S[j]. If flag is non-zero, return 0 if x belongs to S, otherwise the index j where it should be inserted."},
-{"setunion",0,(void*)setunion,11,"GG","setunion(x,y): union of the sets x and y."},
+{"select",0,(void*)select0,15,"GGD0,L,","select(f, A, {flag = 0}): selects elements of A according to the selection function f. If flag is 1, return the indices of those elements (indirect selection)"},
+{"self",0,(void*)pari_self,15,"m","self(): return the calling function or closure. Useful for defining anonymous recursive functions."},
+{"seralgdep",0,(void*)seralgdep,12,"GLL","seralgdep(s,p,r): find a linear relation between powers (1,s, ..., s^p) of the series s, with polynomial coefficients of degree <= r."},
+{"serconvol",0,(void*)convol,11,"GG","serconvol(x,y): convolution (or Hadamard product) of two power series."},
+{"serlaplace",0,(void*)laplace,11,"G","serlaplace(x): replaces the power series sum of a_n*x^n/n! by sum of a_n*x^n. For the reverse operation, use serconvol(x,exp(X))."},
+{"serreverse",0,(void*)serreverse,11,"G","serreverse(s): reversion of the power series s."},
+{"setbinop",0,(void*)setbinop,12,"GGDG","setbinop(f,X,{Y}): the set {f(x,y), x in X, y in Y}. If Y is omitted, assume that X = Y and that f is symmetric."},
+{"setintersect",0,(void*)setintersect,12,"GG","setintersect(x,y): intersection of the sets x and y."},
+{"setisset",0,(void*)setisset,12,"lG","setisset(x): true(1) if x is a set (row vector with strictly increasing entries), false(0) if not."},
+{"setminus",0,(void*)setminus,12,"GG","setminus(x,y): set of elements of x not belonging to y."},
+{"setrand",0,(void*)setrand,15,"vG","setrand(n): reset the seed of the random number generator to n."},
+{"setsearch",0,(void*)setsearch,12,"lGGD0,L,","setsearch(S,x,{flag=0}): determines whether x belongs to the set (or sorted list) S. If flag is 0 or omitted, returns 0 if it does not, otherwise returns the index j such that x==S[j]. If flag is non-zero, return 0 if x belongs to S, otherwise the index j where it should be inserted."},
+{"setunion",0,(void*)setunion,12,"GG","setunion(x,y): union of the sets x and y."},
 {"shift",0,(void*)gshift,1,"GL","shift(x,n): shift x left n bits if n>=0, right -n bits if n<0."},
 {"shiftmul",0,(void*)gmul2n,1,"GL","shiftmul(x,n): multiply x by 2^n (n>=0 or n<0)"},
 {"sigma",0,(void*)sumdivk,4,"GD1,L,","sigma(x,{k=1}): sum of the k-th powers of the divisors of x. k is optional and if omitted is assumed to be equal to 1."},
@@ -846,73 +859,73 @@ entree functions_basic[]={
 {"sinh",0,(void*)gsinh,3,"Gp","sinh(x): hyperbolic sine of x."},
 {"sizebyte",0,(void*)gsizebyte,2,"lG","sizebyte(x): number of bytes occupied by the complete tree of the object x."},
 {"sizedigit",0,(void*)sizedigit,2,"lG","sizedigit(x): rough upper bound for the number of decimal digits of (the components of) $x$. DEPRECATED."},
-{"solve",0,(void*)zbrent0,12,"V=GGEp","solve(X=a,b,expr): real root of expression expr (X between a and b), where expr(a)*expr(b)<=0."},
-{"solvestep",0,(void*)solvestep0,12,"V=GGGED0,L,p","solvestep(X=a,b,step,expr,{flag=0}): find zeros of a function in the real interval [a,b] by naive interval splitting."},
+{"solve",0,(void*)zbrent0,13,"V=GGEp","solve(X=a,b,expr): real root of expression expr (X between a and b), where expr(a)*expr(b)<=0."},
+{"solvestep",0,(void*)solvestep0,13,"V=GGGED0,L,p","solvestep(X=a,b,step,expr,{flag=0}): find zeros of a function in the real interval [a,b] by naive interval splitting."},
 {"sqr",0,(void*)gsqr,3,"G","sqr(x): square of x. NOT identical to x*x."},
 {"sqrt",0,(void*)gsqrt,3,"Gp","sqrt(x): square root of x."},
 {"sqrtint",0,(void*)sqrtint,4,"G","sqrtint(x): integer square root of x, where x is a non-negative integer."},
 {"sqrtn",0,(void*)gsqrtn,3,"GGD&p","sqrtn(x,n,{&z}): nth-root of x, n must be integer. If present, z is set to a suitable root of unity to recover all solutions. If it was not possible, z is set to zero."},
 {"sqrtnint",0,(void*)sqrtnint,4,"GL","sqrtnint(x,n): integer n-th root of x, where x is non-negative integer."},
 {"stirling",0,(void*)stirling,4,"LLD1,L,","stirling(n,k,{flag=1}): If flag=1 (default) return the Stirling number of the first kind s(n,k), if flag=2, return the Stirling number of the second kind S(n,k)."},
-{"subgrouplist",0,(void*)subgrouplist0,8,"GDGD0,L,","subgrouplist(bnr,{bound},{flag=0}): bnr being as output by bnrinit or a list of cyclic components of a finite Abelian group G, outputs the list of subgroups of G (of index bounded by bound, if not omitted), given as HNF left divisors of the SNF matrix corresponding to G. If flag=0 (default) and bnr is as output by bnrinit, gives only the subgroups for which the modulus is the conductor."},
-{"subst",0,(void*)gsubst,10,"GnG","subst(x,y,z): in expression x, replace the variable y by the expression z."},
-{"substpol",0,(void*)gsubstpol,10,"GGG","substpol(x,y,z): in expression x, replace the polynomial y by the expression z, using remainder decomposition of x."},
-{"substvec",0,(void*)gsubstvec,10,"GGG","substvec(x,v,w): in expression x, make a best effort to replace the variables v1,...,vn by the expression w1,...,wn."},
-{"sum",0,(void*)somme,12,"V=GGEDG","sum(X=a,b,expr,{x=0}): x plus the sum (X goes from a to b) of expression expr."},
-{"sumalt",0,(void*)sumalt0,12,"V=GED0,L,p","sumalt(X=a,expr,{flag=0}): Cohen-Villegas-Zagier's acceleration of alternating series expr, X starting at a. flag is optional, and can be 0: default, or 1: uses a slightly different method using Zagier's polynomials."},
+{"subgrouplist",0,(void*)subgrouplist0,9,"GDGD0,L,","subgrouplist(bnr,{bound},{flag=0}): bnr being as output by bnrinit or a list of cyclic components of a finite Abelian group G, outputs the list of subgroups of G (of index bounded by bound, if not omitted), given as HNF left divisors of the SNF matrix corresponding to G. If flag=0 (default) and bnr is as output by bnrinit, gives only the subgroups for which the modulus is the conductor."},
+{"subst",0,(void*)gsubst,11,"GnG","subst(x,y,z): in expression x, replace the variable y by the expression z."},
+{"substpol",0,(void*)gsubstpol,11,"GGG","substpol(x,y,z): in expression x, replace the polynomial y by the expression z, using remainder decomposition of x."},
+{"substvec",0,(void*)gsubstvec,11,"GGG","substvec(x,v,w): in expression x, make a best effort to replace the variables v1,...,vn by the expression w1,...,wn."},
+{"sum",0,(void*)somme,13,"V=GGEDG","sum(X=a,b,expr,{x=0}): x plus the sum (X goes from a to b) of expression expr."},
+{"sumalt",0,(void*)sumalt0,13,"V=GED0,L,p","sumalt(X=a,expr,{flag=0}): Cohen-Villegas-Zagier's acceleration of alternating series expr, X starting at a. flag is optional, and can be 0: default, or 1: uses a slightly different method using Zagier's polynomials."},
 {"sumdedekind",0,(void*)sumdedekind,4,"GG","sumdedekind(h,k): Dedekind sum associated to h,k"},
 {"sumdigits",0,(void*)sumdigits0,4,"GDG","sumdigits(n,{B=10}): sum of digits in the integer n, when written in base B."},
-{"sumdiv",0,(void*)sumdivexpr,12,"GVE","sumdiv(n,X,expr): sum of expression expr, X running over the divisors of n."},
-{"sumdivmult",0,(void*)sumdivmultexpr,12,"GVE","sumdivmult(n,d,expr): sum of multiplicative function expr, d running over the divisors of n."},
-{"sumformal",0,(void*)sumformal,10,"GDn","sumformal(f,{v}): formal sum of f with respect to v, or to the main variable of f if v is omitted."},
-{"suminf",0,(void*)suminf0,12,"V=GEp","suminf(X=a,expr): infinite sum (X goes from a to infinity) of real or complex expression expr."},
-{"sumnum",0,(void*)sumnum0,12,"V=GEDGp","sumnum(n=a,f,{tab}): numerical summation of f(n) from n = a to +infinity using Euler-MacLaurin summation. Assume that f corresponds to a series with positive terms and is a C^oo function; a must be an integer, and tab, if given, is the output of sumnuminit."},
-{"sumnuminit",0,(void*)sumnuminit,12,"DGp","sumnuminit({asymp}): initialize tables for Euler-MacLaurin delta summation of a series with positive terms."},
-{"sumnummonien",0,(void*)sumnummonien0,12,"V=GEDGp","sumnummonien(n=a,f,{tab}): numerical summation from n = a to +infinity using Monien summation."},
-{"sumnummonieninit",0,(void*)sumnummonieninit,12,"DGDGDGp","sumnummonieninit({asymp},{w},{n0 = 1}): initialize tables for Monien summation of a series with positive terms."},
-{"sumpos",0,(void*)sumpos0,12,"V=GED0,L,p","sumpos(X=a,expr,{flag=0}): sum of positive (or negative) series expr, the formal variable X starting at a. flag is optional, and can be 0: default, or 1: uses a slightly different method using Zagier's polynomials."},
-{"system",0,(void*)gpsystem,14,"vs","system(str): str being a string, execute the system command str."},
+{"sumdiv",0,(void*)sumdivexpr,13,"GVE","sumdiv(n,X,expr): sum of expression expr, X running over the divisors of n."},
+{"sumdivmult",0,(void*)sumdivmultexpr,13,"GVE","sumdivmult(n,d,expr): sum of multiplicative function expr, d running over the divisors of n."},
+{"sumformal",0,(void*)sumformal,11,"GDn","sumformal(f,{v}): formal sum of f with respect to v, or to the main variable of f if v is omitted."},
+{"suminf",0,(void*)suminf0,13,"V=GEp","suminf(X=a,expr): infinite sum (X goes from a to infinity) of real or complex expression expr."},
+{"sumnum",0,(void*)sumnum0,13,"V=GEDGp","sumnum(n=a,f,{tab}): numerical summation of f(n) from n = a to +infinity using Euler-MacLaurin summation. Assume that f corresponds to a series with positive terms and is a C^oo function; a must be an integer, and tab, if given, is the output of sumnuminit."},
+{"sumnuminit",0,(void*)sumnuminit,13,"DGp","sumnuminit({asymp}): initialize tables for Euler-MacLaurin delta summation of a series with positive terms."},
+{"sumnummonien",0,(void*)sumnummonien0,13,"V=GEDGp","sumnummonien(n=a,f,{tab}): numerical summation from n = a to +infinity using Monien summation."},
+{"sumnummonieninit",0,(void*)sumnummonieninit,13,"DGDGDGp","sumnummonieninit({asymp},{w},{n0 = 1}): initialize tables for Monien summation of a series with positive terms."},
+{"sumpos",0,(void*)sumpos0,13,"V=GED0,L,p","sumpos(X=a,expr,{flag=0}): sum of positive (or negative) series expr, the formal variable X starting at a. flag is optional, and can be 0: default, or 1: uses a slightly different method using Zagier's polynomials."},
+{"system",0,(void*)gpsystem,15,"vs","system(str): str being a string, execute the system command str."},
 {"tan",0,(void*)gtan,3,"Gp","tan(x): tangent of x."},
 {"tanh",0,(void*)gtanh,3,"Gp","tanh(x): hyperbolic tangent of x."},
-{"taylor",0,(void*)tayl,10,"GnDP","taylor(x,t,{d=seriesprecision}): taylor expansion of x with respect to t, adding O(t^d) to all components of x."},
+{"taylor",0,(void*)tayl,11,"GnDP","taylor(x,t,{d=seriesprecision}): taylor expansion of x with respect to t, adding O(t^d) to all components of x."},
 {"teichmuller",0,(void*)teichmuller,3,"GDG","teichmuller(x,{tab}): teichmuller character of p-adic number x. If x = [p,n], return the lifts of all teichmuller(i + O(p^n)) for i = 1, ..., p-1. Such a vector can be fed back to teichmuller, as the optional argument tab, to speed up later computations."},
 {"theta",0,(void*)theta,3,"GGp","theta(q,z): Jacobi sine theta-function."},
 {"thetanullk",0,(void*)thetanullk,3,"GLp","thetanullk(q,k): k-th derivative at z=0 of theta(q,z)."},
-{"thue",0,(void*)thue,10,"GGDG","thue(tnf,a,{sol}): solve the equation P(x,y)=a, where tnf was created with thueinit(P), and sol, if present, contains the solutions of Norm(x)=a modulo units in the number field defined by P. If tnf was computed without assuming GRH (flag 1 in thueinit), the result is unconditional. If tnf is a polynomial, compute thue(thueinit(P,0), a)."},
-{"thueinit",0,(void*)thueinit,10,"GD0,L,p","thueinit(P,{flag=0}): initialize the tnf corresponding to P, that will be used to solve Thue equations P(x,y) = some-integer. If flag is non-zero, certify the result unconditionaly. Otherwise, assume GRH (much faster of course)."},
-{"trace",0,(void*)gtrace,11,"G","trace(x): trace of x."},
-{"trap",0,(void*)trap0,14,"DrDEDE","trap({e}, {rec}, seq): try to execute seq, trapping runtime error e (all of them if e omitted); sequence rec is executed if the error occurs and is the result of the command. THIS FUNCTION IS OBSOLETE: use \"IFERR\""},
+{"thue",0,(void*)thue,11,"GGDG","thue(tnf,a,{sol}): solve the equation P(x,y)=a, where tnf was created with thueinit(P), and sol, if present, contains the solutions of Norm(x)=a modulo units in the number field defined by P. If tnf was computed without assuming GRH (flag 1 in thueinit), the result is unconditional. If tnf is a polynomial, compute thue(thueinit(P,0), a)."},
+{"thueinit",0,(void*)thueinit,11,"GD0,L,p","thueinit(P,{flag=0}): initialize the tnf corresponding to P, that will be used to solve Thue equations P(x,y) = some-integer. If flag is non-zero, certify the result unconditionaly. Otherwise, assume GRH (much faster of course)."},
+{"trace",0,(void*)gtrace,12,"G","trace(x): trace of x."},
+{"trap",0,(void*)trap0,15,"DrDEDE","trap({e}, {rec}, seq): try to execute seq, trapping runtime error e (all of them if e omitted); sequence rec is executed if the error occurs and is the result of the command. THIS FUNCTION IS OBSOLETE: use \"IFERR\""},
 {"truncate",0,(void*)trunc0,2,"GD&","truncate(x,{&e}): truncation of x; when x is a power series,take away the O(X^). If e is present, do not take into account loss of integer part precision, and set e = error estimate in bits."},
-{"type",0,(void*)type0,14,"G","type(x): return the type of the GEN x."},
-{"uninline",0,NULL,14,NULL,"uninline(): forget all inline variables [EXPERIMENTAL]"},
-{"until",0,(void*)untilpari,14,"vEI","until(a,seq): evaluate the expression sequence seq until a is nonzero."},
+{"type",0,(void*)type0,15,"G","type(x): return the type of the GEN x."},
+{"uninline",0,NULL,15,NULL,"uninline(): forget all inline variables [EXPERIMENTAL]"},
+{"until",0,(void*)untilpari,15,"vEI","until(a,seq): evaluate the expression sequence seq until a is nonzero."},
 {"valuation",0,(void*)gpvaluation,2,"GG","valuation(x,p): valuation of x with respect to p."},
 {"varhigher",0,(void*)varhigher,2,"sDn","varhigher(name,{v}): return a variable 'name' whose priority is higher than the priority of v (of all existing variables if v is omitted)."},
 {"variable",0,(void*)gpolvar,2,"DG","variable({x}): main variable of object x. Gives p for p-adic x, 0 if no variable can be associated to x. Returns the list of user variables if x is omitted."},
 {"variables",0,(void*)variables_vec,2,"DG","variables({x}): all variables occuring in object x, sorted by decreasing priority. Returns the list of user variables if x is omitted."},
 {"varlower",0,(void*)varlower,2,"sDn","varlower(name,{v}): return a variable 'name' whose priority is lower than the priority of v (of all existing variables if v is omitted."},
-{"vecextract",0,(void*)extract0,11,"GGDG","vecextract(x,y,{z}): extraction of the components of the matrix or vector x according to y and z. If z is omitted, y represents columns, otherwise y corresponds to rows and z to columns. y and z can be vectors (of indices), strings (indicating ranges as in \"1..10\") or masks (integers whose binary representation indicates the indices to extract, from left to right 1, 2, 4, 8, etc.)."},
+{"vecextract",0,(void*)extract0,12,"GGDG","vecextract(x,y,{z}): extraction of the components of the matrix or vector x according to y and z. If z is omitted, y represents columns, otherwise y corresponds to rows and z to columns. y and z can be vectors (of indices), strings (indicating ranges as in \"1..10\") or masks (integers whose binary representation indicates the indices to extract, from left to right 1, 2, 4, 8, etc.)."},
 {"vecmax",0,(void*)vecmax0,1,"GD&","vecmax(x,{&v}): largest entry in the vector/matrix x. If v is present, set it to the index of a largest entry (indirect max)."},
 {"vecmin",0,(void*)vecmin0,1,"GD&","vecmin(x,{&v}): smallest entry in the vector/matrix x. If v is present, set it to the index of a smallest entry (indirect min)."},
-{"vecsearch",0,(void*)vecsearch,11,"lGGDG","vecsearch(v,x,{cmpf}): determines whether x belongs to the sorted vector v. If the comparison function cmpf is explicitly given, assume that v was sorted according to vecsort(, cmpf)."},
-{"vecsort",0,(void*)vecsort0,11,"GDGD0,L,","vecsort(x,{cmpf},{flag=0}): sorts the vector of vectors (or matrix) x in ascending order, according to the comparison function cmpf, if not omitted. (If cmpf is an integer, sort according to the value of the k-th component of each entry.) Binary digits of flag (if present) mean: 1: indirect sorting, return the permutation instead of the permuted vector, 2: sort using lexicographic order, 4: use descending instead of ascending order, 8: remove d [...]
-{"vecsum",0,(void*)vecsum,11,"G","vecsum(v): return the sum of the components of the vector v"},
-{"vector",0,(void*)vecteur,11,"GDVDE","vector(n,{X},{expr=0}): row vector with n components of expression expr (X ranges from 1 to n). By default, fill with 0s."},
-{"vectorsmall",0,(void*)vecteursmall,11,"GDVDE","vectorsmall(n,{X},{expr=0}): VECSMALL with n components of expression expr (X ranges from 1 to n) which must be small integers. By default, fill with 0s."},
-{"vectorv",0,(void*)vvecteur,11,"GDVDE","vectorv(n,{X},{expr=0}): column vector with n components of expression expr (X ranges from 1 to n). By default, fill with 0s."},
-{"version",0,(void*)pari_version,14,"","version(): returns the PARI version as [major,minor,patch] or [major,minor,patch,VCSversion]."},
-{"warning",0,(void*)warning0,14,"vs*","warning({str}*): display warning message str"},
+{"vecsearch",0,(void*)vecsearch,12,"lGGDG","vecsearch(v,x,{cmpf}): determines whether x belongs to the sorted vector v. If the comparison function cmpf is explicitly given, assume that v was sorted according to vecsort(, cmpf)."},
+{"vecsort",0,(void*)vecsort0,12,"GDGD0,L,","vecsort(x,{cmpf},{flag=0}): sorts the vector of vectors (or matrix) x in ascending order, according to the comparison function cmpf, if not omitted. (If cmpf is an integer, sort according to the value of the k-th component of each entry.) Binary digits of flag (if present) mean: 1: indirect sorting, return the permutation instead of the permuted vector, 4: use descending instead of ascending order, 8: remove duplicate entries."},
+{"vecsum",0,(void*)vecsum,12,"G","vecsum(v): return the sum of the components of the vector v"},
+{"vector",0,(void*)vecteur,12,"GDVDE","vector(n,{X},{expr=0}): row vector with n components of expression expr (X ranges from 1 to n). By default, fill with 0s."},
+{"vectorsmall",0,(void*)vecteursmall,12,"GDVDE","vectorsmall(n,{X},{expr=0}): VECSMALL with n components of expression expr (X ranges from 1 to n) which must be small integers. By default, fill with 0s."},
+{"vectorv",0,(void*)vvecteur,12,"GDVDE","vectorv(n,{X},{expr=0}): column vector with n components of expression expr (X ranges from 1 to n). By default, fill with 0s."},
+{"version",0,(void*)pari_version,15,"","version(): returns the PARI version as [major,minor,patch] or [major,minor,patch,VCSversion]."},
+{"warning",0,(void*)warning0,15,"vs*","warning({str}*): display warning message str"},
 {"weber",0,(void*)weber0,3,"GD0,L,p","weber(x,{flag=0}): One of Weber's f function of x. flag is optional, and can be 0: default, function f(x)=exp(-i*Pi/24)*eta((x+1)/2)/eta(x), 1: function f1(x)=eta(x/2)/eta(x) 2: function f2(x)=sqrt(2)*eta(2*x)/eta(x). Note that j = (f^24-16)^3/f^24 = (f1^24+16)^3/f1^24 = (f2^24+16)^3/f2^24."},
-{"while",0,(void*)whilepari,14,"vEI","while(a,seq): while a is nonzero evaluate the expression sequence seq. Otherwise 0."},
-{"write",0,(void*)write0,14,"vss*","write(filename,{str}*): appends the remaining arguments (same output as print) to filename."},
-{"write1",0,(void*)write1,14,"vss*","write1(filename,{str}*): appends the remaining arguments (same output as print1) to filename."},
-{"writebin",0,(void*)gpwritebin,14,"vsDG","writebin(filename,{x}): write x as a binary object to file filename. If x is omitted, write all session variables."},
-{"writetex",0,(void*)writetex,14,"vss*","writetex(filename,{str}*): appends the remaining arguments (same format as print) to filename, in TeX format."},
+{"while",0,(void*)whilepari,15,"vEI","while(a,seq): while a is nonzero evaluate the expression sequence seq. Otherwise 0."},
+{"write",0,(void*)write0,15,"vss*","write(filename,{str}*): appends the remaining arguments (same output as print) to filename."},
+{"write1",0,(void*)write1,15,"vss*","write1(filename,{str}*): appends the remaining arguments (same output as print1) to filename."},
+{"writebin",0,(void*)gpwritebin,15,"vsDG","writebin(filename,{x}): write x as a binary object to file filename. If x is omitted, write all session variables."},
+{"writetex",0,(void*)writetex,15,"vss*","writetex(filename,{str}*): appends the remaining arguments (same format as print) to filename, in TeX format."},
 {"zeta",0,(void*)gzeta,3,"Gp","zeta(s): Riemann zeta function at s with s a complex or a p-adic number."},
 {"zetamult",0,(void*)zetamult,3,"Gp","zetamult(s): multiple zeta value at integral s = [s1,...,sd]."},
 {"zncharinduce",0,(void*)zncharinduce,4,"GGG","zncharinduce(G, chi, N): Let G be idealstar(,q), let chi be a Dirichlet character mod q and let N be a multiple of q. Return the character modulo N induced by chi."},
 {"zncharisodd",0,(void*)zncharisodd,4,"lGG","zncharisodd(G, chi): Let G be idealstar(,N), let chi be a Dirichlet character mod N, return 1 if and only if chi(-1) = -1 and 0 otherwise."},
-{"znconreychar",0,(void*)znconreychar,4,"GG","znconreychar(bid,m): Dirichlet character associated to m in (Z/qZ)* in Conrey's notation, where bid is znstar(q, 2)"},
+{"znconreychar",0,(void*)znconreychar,4,"GG","znconreychar(bid,m): Dirichlet character associated to m in (Z/qZ)* in Conrey's notation, where bid is idealstar(,q)"},
 {"znconreyconductor",0,(void*)znconreyconductor,4,"GGD&","znconreyconductor(bid,chi, {&chi0}): Let bid be idealstar(,q) and chi be a Dirichlet character on (Z/qZ)* given by its Conrey logarithm. Return the conductor of chi, and set chi0 to (the Conrey logarithm of) the associated primitive character. If chi0 != chi, return the conductor and its factorization."},
 {"znconreyexp",0,(void*)znconreyexp,4,"GG","znconreyexp(bid, chi): Conrey exponential attached to bid = idealstar(,q). Returns the element m in (Z/qZ)^* attached to the character chi on bid: znconreylog(bid, m) = chi."},
 {"znconreylog",0,(void*)znconreylog,4,"GG","znconreylog(bid,m): Conrey logarithm associated to m in (Z/qZ)*, where bid is idealstar(,q)"},
diff --git a/src/language/intnum.c b/src/language/intnum.c
index 414698e..948f7d4 100644
--- a/src/language/intnum.c
+++ b/src/language/intnum.c
@@ -282,18 +282,10 @@ static const long LGTAB = 8;
 #define TABwm(v) gel(v,7)
 
 static int
-isinR(GEN z)
-{
-  long tz = typ(z);
-  return (tz == t_INT || tz == t_REAL || tz == t_FRAC);
-}
-
+isinR(GEN z) { return is_real_t(typ(z)); }
 static int
 isinC(GEN z)
-{
-  return (typ(z) == t_COMPLEX)? isinR(gel(z,1)) && isinR(gel(z,2)):
-                                isinR(z);
-}
+{ return (typ(z) == t_COMPLEX)? isinR(gel(z,1)) && isinR(gel(z,2)): isinR(z); }
 
 static int
 checktabsimp(GEN tab)
diff --git a/src/language/parse.c b/src/language/parse.c
index cebd5ab..0b0052f 100644
--- a/src/language/parse.c
+++ b/src/language/parse.c
@@ -1,19 +1,20 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
-
-/* Bison implementation for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+/* A Bison parser, made by GNU Bison 2.4.3.  */
 
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+   2009, 2010 Free Software Foundation, Inc.
+   
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
-
+   
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
+   
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
@@ -26,7 +27,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -44,7 +45,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "2.4.3"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -58,17 +59,23 @@
 /* Pull parsers.  */
 #define YYPULL 1
 
+/* Using locations.  */
+#define YYLSP_NEEDED 1
 
 /* Substitute the variable and function names.  */
 #define yyparse         pari_parse
 #define yylex           pari_lex
 #define yyerror         pari_error
+#define yylval          pari_lval
+#define yychar          pari_char
 #define yydebug         pari_debug
 #define yynerrs         pari_nerrs
-
+#define yylloc          pari_lloc
 
 /* Copy the first part of user declarations.  */
-#line 1 "../src/language/parse.y" /* yacc.c:339  */
+
+/* Line 189 of yacc.c  */
+#line 1 "../src/language/parse.y"
 
 /* Copyright (C) 2006  The PARI group.
 
@@ -91,16 +98,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
          (Current).end    = (Rhs)[N].end)
 #include "parsec.h"
 #define NOARG(x) newnode(Fnoarg,-1,-1,&(x))
+#define NORANGE(x) newnode(Fnorange,-1,-1,&(x))
 
-#line 96 "../src/language/parse.c" /* yacc.c:339  */
 
-# ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
-#  else
-#   define YY_NULLPTR 0
-#  endif
-# endif
+/* Line 189 of yacc.c  */
+#line 106 "../src/language/parse.c"
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -110,84 +117,81 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 # define YYERROR_VERBOSE 1
 #endif
 
-/* In a future release of Bison, this section will be replaced
-   by #include "parse.h".  */
-#ifndef YY_PARI_SRC_LANGUAGE_PARSE_H_INCLUDED
-# define YY_PARI_SRC_LANGUAGE_PARSE_H_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int pari_debug;
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
 #endif
 
-/* Token type.  */
+
+/* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
-  enum yytokentype
-  {
-    KPARROW = 258,
-    KARROW = 259,
-    KDOTDOT = 260,
-    KPE = 261,
-    KSE = 262,
-    KME = 263,
-    KDE = 264,
-    KDRE = 265,
-    KEUCE = 266,
-    KMODE = 267,
-    KAND = 268,
-    KOR = 269,
-    KID = 270,
-    KEQ = 271,
-    KNE = 272,
-    KGE = 273,
-    KLE = 274,
-    KSRE = 275,
-    KSLE = 276,
-    KSR = 277,
-    KSL = 278,
-    KDR = 279,
-    KPP = 280,
-    KSS = 281,
-    KINTEGER = 282,
-    KREAL = 283,
-    KENTRY = 284,
-    KSTRING = 285,
-    SEQ = 286,
-    DEFFUNC = 287,
-    INT = 288,
-    LVAL = 289,
-    SIGN = 290
-  };
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     KPARROW = 258,
+     KARROW = 259,
+     KDOTDOT = 260,
+     KPE = 261,
+     KSE = 262,
+     KME = 263,
+     KDE = 264,
+     KDRE = 265,
+     KEUCE = 266,
+     KMODE = 267,
+     KAND = 268,
+     KOR = 269,
+     KID = 270,
+     KEQ = 271,
+     KNE = 272,
+     KGE = 273,
+     KLE = 274,
+     KSRE = 275,
+     KSLE = 276,
+     KSR = 277,
+     KSL = 278,
+     KDR = 279,
+     KPP = 280,
+     KSS = 281,
+     KINTEGER = 282,
+     KREAL = 283,
+     KENTRY = 284,
+     KSTRING = 285,
+     DEFFUNC = 286,
+     SEQ = 287,
+     LVAL = 288,
+     INT = 289,
+     SIGN = 290
+   };
 #endif
 
-/* Value type.  */
 
-/* Location type.  */
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE YYLTYPE;
-struct YYLTYPE
+typedef struct YYLTYPE
 {
   int first_line;
   int first_column;
   int last_line;
   int last_column;
-};
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
 # define YYLTYPE_IS_DECLARED 1
 # define YYLTYPE_IS_TRIVIAL 1
 #endif
 
 
-
-int pari_parse (char **lex);
-
-#endif /* !YY_PARI_SRC_LANGUAGE_PARSE_H_INCLUDED  */
-
 /* Copy the second part of user declarations.  */
 
-#line 191 "../src/language/parse.c" /* yacc.c:358  */
+
+/* Line 264 of yacc.c  */
+#line 195 "../src/language/parse.c"
 
 #ifdef short
 # undef short
@@ -201,8 +205,11 @@ typedef unsigned char yytype_uint8;
 
 #ifdef YYTYPE_INT8
 typedef YYTYPE_INT8 yytype_int8;
-#else
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
 #endif
 
 #ifdef YYTYPE_UINT16
@@ -222,7 +229,8 @@ typedef short int yytype_int16;
 #  define YYSIZE_T __SIZE_TYPE__
 # elif defined size_t
 #  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
@@ -236,68 +244,39 @@ typedef short int yytype_int16;
 # if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(Msgid) Msgid
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE
-# if (defined __GNUC__                                               \
-      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
-     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
-#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
-# else
-#  define YY_ATTRIBUTE(Spec) /* empty */
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE_PURE
-# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
-#endif
-
-#ifndef YY_ATTRIBUTE_UNUSED
-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
-#endif
-
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
-# else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+#  define YY_(msgid) msgid
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(E) ((void) (E))
+# define YYUSE(e) ((void) (e))
 #else
-# define YYUSE(E) /* empty */
+# define YYUSE(e) /* empty */
 #endif
 
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
-/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
-    _Pragma ("GCC diagnostic push") \
-    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
-    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
-    _Pragma ("GCC diagnostic pop")
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
 #else
-# define YY_INITIAL_VALUE(Value) Value
-#endif
-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+    int yyi;
 #endif
-#ifndef YY_INITIAL_VALUE
-# define YY_INITIAL_VALUE(Value) /* Nothing. */
+{
+  return yyi;
+}
 #endif
 
-
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */
@@ -315,11 +294,11 @@ typedef short int yytype_int16;
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
 #     endif
 #    endif
 #   endif
@@ -327,8 +306,8 @@ typedef short int yytype_int16;
 # endif
 
 # ifdef YYSTACK_ALLOC
-   /* Pacify GCC's 'empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
 #  ifndef YYSTACK_ALLOC_MAXIMUM
     /* The OS might guarantee only one guard page at the bottom of the stack,
        and a page size can be as small as 4096 bytes.  So we cannot safely
@@ -342,23 +321,25 @@ typedef short int yytype_int16;
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
+#  if (defined __cplusplus && ! defined _STDLIB_H \
        && ! ((defined YYMALLOC || defined malloc) \
-             && (defined YYFREE || defined free)))
+	     && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef EXIT_SUCCESS
-#    define EXIT_SUCCESS 0
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
@@ -368,8 +349,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 
 #if (! defined yyoverflow \
      && (! defined __cplusplus \
-         || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
-             && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
@@ -388,46 +369,42 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
       + 2 * YYSTACK_GAP_MAXIMUM)
 
-# define YYCOPY_NEEDED 1
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
    elements in the stack, and YYPTR gives the new location of the
    stack.  Advance YYPTR to a properly aligned location for the next
    stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
-    do                                                                  \
-      {                                                                 \
-        YYSIZE_T yynewbytes;                                            \
-        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
-        Stack = &yyptr->Stack_alloc;                                    \
-        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-        yyptr += yynewbytes / sizeof (*yyptr);                          \
-      }                                                                 \
-    while (0)
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)				\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
+	Stack = &yyptr->Stack_alloc;					\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
 
 #endif
 
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from SRC to DST.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(Dst, Src, Count) \
-      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
-#  else
-#   define YYCOPY(Dst, Src, Count)              \
-      do                                        \
-        {                                       \
-          YYSIZE_T yyi;                         \
-          for (yyi = 0; yyi < (Count); yyi++)   \
-            (Dst)[yyi] = (Src)[yyi];            \
-        }                                       \
-      while (0)
-#  endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  47
 /* YYLAST -- Last index in YYTABLE.  */
@@ -439,19 +416,17 @@ union yyalloc
 #define YYNNTS  21
 /* YYNRULES -- Number of rules.  */
 #define YYNRULES  109
-/* YYNSTATES -- Number of states.  */
+/* YYNRULES -- Number of states.  */
 #define YYNSTATES  192
 
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   290
 
-#define YYTRANSLATE(YYX)                                                \
+#define YYTRANSLATE(YYX)						\
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -487,24 +462,85 @@ static const yytype_uint8 yytranslate[] =
 };
 
 #if YYDEBUG
-  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint16 yyprhs[] =
+{
+       0,     0,     3,     5,     6,     8,    11,    15,    16,    18,
+      22,    25,    31,    35,    37,    40,    42,    45,    48,    51,
+      55,    59,    61,    63,    65,    69,    71,    74,    76,    81,
+      83,    85,    87,    89,    91,    95,    99,   102,   105,   109,
+     113,   117,   121,   125,   129,   133,   137,   141,   144,   147,
+     151,   155,   159,   163,   167,   171,   175,   179,   183,   187,
+     191,   195,   199,   203,   207,   211,   215,   219,   223,   226,
+     229,   233,   236,   239,   242,   245,   247,   251,   255,   257,
+     260,   264,   266,   270,   274,   278,   281,   287,   291,   295,
+     299,   303,   308,   310,   314,   318,   324,   330,   332,   337,
+     340,   341,   346,   348,   352,   357,   361,   368,   374,   378
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      62,     0,    -1,    63,    -1,    -1,    68,    -1,    63,    35,
+      -1,    63,    35,    68,    -1,    -1,    68,    -1,    68,     5,
+      68,    -1,    48,    68,    -1,    52,    64,    36,    64,    57,
+      -1,    52,    64,    57,    -1,    58,    -1,    66,    58,    -1,
+      43,    -1,    43,    27,    -1,    43,    66,    -1,    43,    49,
+      -1,    43,    49,    27,    -1,    43,    49,    66,    -1,    27,
+      -1,    28,    -1,    54,    -1,    27,    54,    29,    -1,    30,
+      -1,    53,    29,    -1,    67,    -1,    68,    55,    78,    59,
+      -1,    79,    -1,    69,    -1,    72,    -1,    75,    -1,    81,
+      -1,    72,    37,    68,    -1,    69,    37,    68,    -1,    69,
+      25,    -1,    69,    26,    -1,    69,     8,    68,    -1,    69,
+       9,    68,    -1,    69,    10,    68,    -1,    69,    11,    68,
+      -1,    69,    12,    68,    -1,    69,    21,    68,    -1,    69,
+      20,    68,    -1,    69,     6,    68,    -1,    69,     7,    68,
+      -1,    50,    68,    -1,    49,    68,    -1,    68,    14,    68,
+      -1,    68,    13,    68,    -1,    68,    38,    68,    -1,    68,
+      15,    68,    -1,    68,    16,    68,    -1,    68,    17,    68,
+      -1,    68,    18,    68,    -1,    68,    39,    68,    -1,    68,
+      19,    68,    -1,    68,    40,    68,    -1,    68,    42,    68,
+      -1,    68,    41,    68,    -1,    68,    23,    68,    -1,    68,
+      22,    68,    -1,    68,    43,    68,    -1,    68,    24,    68,
+      -1,    68,    44,    68,    -1,    68,    45,    68,    -1,    68,
+      46,    68,    -1,    41,    68,    -1,    42,    68,    -1,    68,
+      48,    68,    -1,    68,    51,    -1,    68,    53,    -1,    68,
+      50,    -1,    68,    65,    -1,    80,    -1,    68,    56,    29,
+      -1,    55,    68,    59,    -1,    29,    -1,    69,    65,    -1,
+      69,    56,    29,    -1,    68,    -1,    70,    36,    68,    -1,
+      70,    35,    70,    -1,    71,    35,    70,    -1,    52,    57,
+      -1,    52,    68,     5,    68,    57,    -1,    52,    35,    57,
+      -1,    52,    70,    57,    -1,    52,    71,    57,    -1,    52,
+       1,    57,    -1,    69,    40,    42,    68,    -1,    73,    -1,
+      73,    36,    68,    -1,    73,    35,    74,    -1,    73,    36,
+      68,    35,    74,    -1,    52,    68,    60,    74,    57,    -1,
+      63,    -1,    69,    52,     5,    57,    -1,    38,    69,    -1,
+      -1,    76,     1,    77,    68,    -1,    76,    -1,    78,    36,
+      76,    -1,    29,    55,    78,    59,    -1,    68,    54,    29,
+      -1,    29,    55,    78,    59,    37,    63,    -1,    68,    54,
+      29,    37,    63,    -1,    69,     4,    63,    -1,    55,    78,
+       3,    63,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
-       0,    85,    85,    88,    89,    90,    91,    94,    95,    96,
-      97,   100,   101,   104,   105,   108,   109,   110,   111,   112,
-     113,   116,   117,   118,   119,   121,   122,   123,   124,   125,
-     126,   127,   128,   129,   130,   131,   132,   133,   134,   135,
-     136,   137,   138,   139,   140,   141,   142,   143,   144,   145,
-     146,   147,   148,   149,   150,   151,   152,   153,   154,   155,
-     156,   157,   158,   159,   160,   161,   162,   163,   164,   165,
-     166,   167,   168,   169,   170,   171,   172,   173,   176,   177,
-     178,   181,   182,   185,   186,   189,   190,   191,   192,   193,
-     194,   197,   200,   201,   202,   203,   206,   209,   210,   211,
-     212,   212,   216,   217,   220,   223,   226,   228,   230,   231
+       0,    86,    86,    89,    90,    91,    92,    95,    96,    97,
+      98,   101,   102,   105,   106,   109,   110,   111,   112,   113,
+     114,   117,   118,   119,   120,   122,   123,   124,   125,   126,
+     127,   128,   129,   130,   131,   132,   133,   134,   135,   136,
+     137,   138,   139,   140,   141,   142,   143,   144,   145,   146,
+     147,   148,   149,   150,   151,   152,   153,   154,   155,   156,
+     157,   158,   159,   160,   161,   162,   163,   164,   165,   166,
+     167,   168,   169,   170,   171,   172,   173,   174,   177,   178,
+     179,   182,   183,   186,   187,   190,   191,   192,   193,   194,
+     195,   198,   201,   202,   203,   204,   207,   210,   211,   212,
+     213,   213,   217,   218,   221,   224,   227,   229,   231,   232
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || 1
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
@@ -514,19 +550,19 @@ static const char *const yytname[] =
   "\"&&\"", "\"||\"", "\"===\"", "\"==\"", "\"!=\"", "\">=\"", "\"<=\"",
   "\">>=\"", "\"<<=\"", "\">>\"", "\"<<\"", "\"\\\\/\"", "\"++\"",
   "\"--\"", "\"integer\"", "\"real number\"", "\"variable name\"",
-  "\"character string\"", "SEQ", "DEFFUNC", "INT", "LVAL", "';'", "','",
+  "\"character string\"", "DEFFUNC", "SEQ", "LVAL", "INT", "';'", "','",
   "'='", "'&'", "'>'", "'<'", "'+'", "'-'", "'%'", "'\\\\'", "'/'", "'*'",
   "SIGN", "'^'", "'#'", "'!'", "'~'", "'['", "'\\''", "'.'", "'('", "':'",
   "']'", "'`'", "')'", "'|'", "$accept", "sequence", "seq", "range",
   "matrix_index", "backticks", "history", "expr", "lvalue", "matrixelts",
   "matrixlines", "matrix", "in", "inseq", "compr", "arg", "$@1", "listarg",
-  "funcid", "memberid", "definition", YY_NULLPTR
+  "funcid", "memberid", "definition", 0
 };
 #endif
 
 # ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
-   (internal) symbol number NUM (which must be that of a token).  */
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
 static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
@@ -539,45 +575,41 @@ static const yytype_uint16 yytoknum[] =
 };
 # endif
 
-#define YYPACT_NINF -165
-
-#define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-165)))
-
-#define YYTABLE_NINF -104
-
-#define yytable_value_is_error(Yytable_value) \
-  0
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    61,    62,    63,    63,    63,    63,    64,    64,    64,
+      64,    65,    65,    66,    66,    67,    67,    67,    67,    67,
+      67,    68,    68,    68,    68,    68,    68,    68,    68,    68,
+      68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
+      68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
+      68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
+      68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
+      68,    68,    68,    68,    68,    68,    68,    68,    69,    69,
+      69,    70,    70,    71,    71,    72,    72,    72,    72,    72,
+      72,    73,    74,    74,    74,    74,    75,    76,    76,    76,
+      77,    76,    78,    78,    79,    80,    81,    81,    81,    81
+};
 
-  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-     STATE-NUM.  */
-static const yytype_int16 yypact[] =
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
 {
-     616,   -33,  -165,   -28,  -165,   616,   616,   -17,   616,   616,
-      84,     1,  -165,   582,    31,     3,  -165,   461,   141,    46,
-    -165,  -165,  -165,  -165,    60,   582,   150,   150,  -165,    12,
-    -165,    38,   190,    54,    42,    44,  -165,   172,    36,    47,
-    -165,    61,     3,   325,   227,     6,    33,  -165,   616,   616,
-     616,   616,   616,   616,   616,   616,   616,   616,   616,   616,
-     616,   616,   616,   616,   616,   616,   616,   616,   616,  -165,
-    -165,   599,  -165,    73,   582,    74,  -165,   616,   616,   616,
-     616,   616,   616,   616,   616,   616,   616,  -165,  -165,   616,
-      86,  -165,   616,  -165,   -22,  -165,    38,  -165,  -165,  -165,
-     616,    61,   616,   616,  -165,   616,  -165,  -165,   -36,  -165,
-     282,  -165,   616,   582,   461,   503,   503,   538,   538,   538,
-     538,   538,   150,   150,   150,   503,   538,   538,   552,   552,
-     150,   150,   150,   150,   150,   616,    50,   252,    79,   -19,
-    -165,     3,   461,   461,   461,   461,   461,   461,   461,   461,
-     461,   461,  -165,   461,    80,   372,   -27,   -12,    63,   461,
-      82,   461,    82,    64,   616,     3,    32,   461,   599,  -165,
-     616,   616,  -165,   616,  -165,    87,    61,   616,  -165,  -165,
-     461,    65,   461,     3,     3,   616,  -165,   417,  -165,   461,
-      61,  -165
+       0,     2,     1,     0,     1,     2,     3,     0,     1,     3,
+       2,     5,     3,     1,     2,     1,     2,     2,     2,     3,
+       3,     1,     1,     1,     3,     1,     2,     1,     4,     1,
+       1,     1,     1,     1,     3,     3,     2,     2,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     2,     2,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     2,     2,
+       3,     2,     2,     2,     2,     1,     3,     3,     1,     2,
+       3,     1,     3,     3,     3,     2,     5,     3,     3,     3,
+       3,     4,     1,     3,     3,     5,     5,     1,     4,     2,
+       0,     4,     1,     3,     4,     3,     6,     5,     3,     4
 };
 
-  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
-     Performed when YYTABLE does not specify something else to do.  Zero
-     means the default is an error.  */
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
        3,    21,    22,    78,    25,     0,     0,    15,     0,     0,
@@ -602,15 +634,7 @@ static const yytype_uint8 yydefact[] =
        0,    95
 };
 
-  /* YYPGOTO[NTERM-NUM].  */
-static const yytype_int16 yypgoto[] =
-{
-    -165,  -165,    11,   -44,   -16,    99,  -165,    -5,    -7,   -83,
-    -165,  -165,  -165,  -164,  -165,    18,  -165,   -10,  -165,  -165,
-    -165
-};
-
-  /* YYDEFGOTO[NTERM-NUM].  */
+/* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
       -1,    14,    42,   136,    76,    31,    16,    17,    18,    38,
@@ -618,9 +642,46 @@ static const yytype_int16 yydefgoto[] =
       23
 };
 
-  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
-     positive, shift that token.  If negative, reduce the rule whose
-     number is the opposite.  If YYTABLE_NINF, syntax error.  */
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -165
+static const yytype_int16 yypact[] =
+{
+     616,   -33,  -165,   -28,  -165,   616,   616,   -17,   616,   616,
+      84,     1,  -165,   582,    31,     3,  -165,   461,   141,    46,
+    -165,  -165,  -165,  -165,    60,   582,   150,   150,  -165,    12,
+    -165,    38,   190,    54,    42,    44,  -165,   172,    36,    47,
+    -165,    61,     3,   325,   227,     6,    33,  -165,   616,   616,
+     616,   616,   616,   616,   616,   616,   616,   616,   616,   616,
+     616,   616,   616,   616,   616,   616,   616,   616,   616,  -165,
+    -165,   599,  -165,    73,   582,    74,  -165,   616,   616,   616,
+     616,   616,   616,   616,   616,   616,   616,  -165,  -165,   616,
+      86,  -165,   616,  -165,   -22,  -165,    38,  -165,  -165,  -165,
+     616,    61,   616,   616,  -165,   616,  -165,  -165,   -36,  -165,
+     282,  -165,   616,   582,   461,   503,   503,   538,   538,   538,
+     538,   538,   150,   150,   150,   503,   538,   538,   552,   552,
+     150,   150,   150,   150,   150,   616,    50,   252,    79,   -19,
+    -165,     3,   461,   461,   461,   461,   461,   461,   461,   461,
+     461,   461,  -165,   461,    80,   372,   -27,   -12,    63,   461,
+      82,   461,    82,    64,   616,     3,    32,   461,   599,  -165,
+     616,   616,  -165,   616,  -165,    87,    61,   616,  -165,  -165,
+     461,    65,   461,     3,     3,   616,  -165,   417,  -165,   461,
+      61,  -165
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+    -165,  -165,    11,   -44,   -16,    99,  -165,    -5,    -7,   -83,
+    -165,  -165,  -165,  -164,  -165,    18,  -165,   -10,  -165,  -165,
+    -165
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -104
 static const yytype_int16 yytable[] =
 {
       26,    27,    91,    32,    33,    37,    44,   111,    43,  -102,
@@ -765,8 +826,8 @@ static const yytype_int16 yycheck[] =
       54,    55
 };
 
-  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-     symbol of state STATE-NUM.  */
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
        0,    27,    28,    29,    30,    41,    42,    43,    49,    50,
@@ -791,114 +852,80 @@ static const yytype_uint8 yystos[] =
       35,    74
 };
 
-  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    61,    62,    63,    63,    63,    63,    64,    64,    64,
-      64,    65,    65,    66,    66,    67,    67,    67,    67,    67,
-      67,    68,    68,    68,    68,    68,    68,    68,    68,    68,
-      68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
-      68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
-      68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
-      68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
-      68,    68,    68,    68,    68,    68,    68,    68,    69,    69,
-      69,    70,    70,    71,    71,    72,    72,    72,    72,    72,
-      72,    73,    74,    74,    74,    74,    75,    76,    76,    76,
-      77,    76,    78,    78,    79,    80,    81,    81,    81,    81
-};
-
-  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     1,     0,     1,     2,     3,     0,     1,     3,
-       2,     5,     3,     1,     2,     1,     2,     2,     2,     3,
-       3,     1,     1,     1,     3,     1,     2,     1,     4,     1,
-       1,     1,     1,     1,     3,     3,     2,     2,     3,     3,
-       3,     3,     3,     3,     3,     3,     3,     2,     2,     3,
-       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     3,     3,     3,     2,     2,
-       3,     2,     2,     2,     2,     1,     3,     3,     1,     2,
-       3,     1,     3,     3,     3,     2,     5,     3,     3,     3,
-       3,     4,     1,     3,     3,     5,     5,     1,     4,     2,
-       0,     4,     1,     3,     4,     3,     6,     5,     3,     4
-};
-
-
-#define yyerrok         (yyerrstatus = 0)
-#define yyclearin       (yychar = YYEMPTY)
-#define YYEMPTY         (-2)
-#define YYEOF           0
-
-#define YYACCEPT        goto yyacceptlab
-#define YYABORT         goto yyabortlab
-#define YYERROR         goto yyerrorlab
-
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
+
+#define YYFAIL		goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
       yyerror (&yylloc, lex, YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
+      YYERROR;							\
+    }								\
+while (YYID (0))
 
-/* Error token number */
-#define YYTERROR        1
-#define YYERRCODE       256
+
+#define YYTERROR	1
+#define YYERRCODE	256
 
 
 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
    If N is 0, then set CURRENT to the empty location which ends
    the previous symbol: RHS[0] (always defined).  */
 
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
 #ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)                                \
-    do                                                                  \
-      if (N)                                                            \
-        {                                                               \
-          (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
-          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
-          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
-          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
-        }                                                               \
-      else                                                              \
-        {                                                               \
-          (Current).first_line   = (Current).last_line   =              \
-            YYRHSLOC (Rhs, 0).last_line;                                \
-          (Current).first_column = (Current).last_column =              \
-            YYRHSLOC (Rhs, 0).last_column;                              \
-        }                                                               \
-    while (0)
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
 #endif
 
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)                        \
-do {                                            \
-  if (yydebug)                                  \
-    YYFPRINTF Args;                             \
-} while (0)
-
 
 /* YY_LOCATION_PRINT -- Print the location on the stream.
    This macro was not mandated originally: define only if we know
@@ -906,74 +933,84 @@ do {                                            \
 
 #ifndef YY_LOCATION_PRINT
 # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
 
-/* Print *YYLOCP on YYO.  Private, do not rely on its existence. */
 
-YY_ATTRIBUTE_UNUSED
-static unsigned
-yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
-{
-  unsigned res = 0;
-  int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
-  if (0 <= yylocp->first_line)
-    {
-      res += YYFPRINTF (yyo, "%d", yylocp->first_line);
-      if (0 <= yylocp->first_column)
-        res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
-    }
-  if (0 <= yylocp->last_line)
-    {
-      if (yylocp->first_line < yylocp->last_line)
-        {
-          res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
-          if (0 <= end_col)
-            res += YYFPRINTF (yyo, ".%d", end_col);
-        }
-      else if (0 <= end_col && yylocp->first_column < end_col)
-        res += YYFPRINTF (yyo, "-%d", end_col);
-    }
-  return res;
- }
+/* YYLEX -- calling `yylex' with the right arguments.  */
 
-#  define YY_LOCATION_PRINT(File, Loc)          \
-  yy_location_print_ (File, &(Loc))
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, lex)
+#endif
 
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
 # endif
-#endif
 
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (YYID (0))
 
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
-do {                                                                      \
-  if (yydebug)                                                            \
-    {                                                                     \
-      YYFPRINTF (stderr, "%s ", Title);                                   \
-      yy_symbol_print (stderr,                                            \
-                  Type, Value, Location, lex); \
-      YYFPRINTF (stderr, "\n");                                           \
-    }                                                                     \
-} while (0)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value, Location, lex); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
 
 
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
 
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, char **lex)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, lex)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+    char **lex;
+#endif
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
-  YYUSE (yylocationp);
-  YYUSE (lex);
   if (!yyvaluep)
     return;
+  YYUSE (yylocationp);
+  YYUSE (lex);
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
 # endif
-  YYUSE (yytype);
+  switch (yytype)
+    {
+      default:
+	break;
+    }
 }
 
 
@@ -981,11 +1018,24 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue
 | Print this symbol on YYOUTPUT.  |
 `--------------------------------*/
 
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, char **lex)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, lex)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+    char **lex;
+#endif
 {
-  YYFPRINTF (yyoutput, "%s %s (",
-             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
 
   YY_LOCATION_PRINT (yyoutput, *yylocationp);
   YYFPRINTF (yyoutput, ": ");
@@ -998,8 +1048,16 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYL
 | TOP (included).                                                   |
 `------------------------------------------------------------------*/
 
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static void
 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
+#endif
 {
   YYFPRINTF (stderr, "Stack now");
   for (; yybottom <= yytop; yybottom++)
@@ -1010,42 +1068,51 @@ yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
   YYFPRINTF (stderr, "\n");
 }
 
-# define YY_STACK_PRINT(Bottom, Top)                            \
-do {                                                            \
-  if (yydebug)                                                  \
-    yy_stack_print ((Bottom), (Top));                           \
-} while (0)
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (YYID (0))
 
 
 /*------------------------------------------------.
 | Report that the YYRULE is going to be reduced.  |
 `------------------------------------------------*/
 
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, char **lex)
+#else
 static void
-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, char **lex)
+yy_reduce_print (yyvsp, yylsp, yyrule, lex)
+    YYSTYPE *yyvsp;
+    YYLTYPE *yylsp;
+    int yyrule;
+    char **lex;
+#endif
 {
-  unsigned long int yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
   int yyi;
+  unsigned long int yylno = yyrline[yyrule];
   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
-             yyrule - 1, yylno);
+	     yyrule - 1, yylno);
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr,
-                       yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
-                       , &(yylsp[(yyi + 1) - (yynrhs)])                       , lex);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       , &(yylsp[(yyi + 1) - (yynrhs)])		       , lex);
       YYFPRINTF (stderr, "\n");
     }
 }
 
-# define YY_REDUCE_PRINT(Rule)          \
-do {                                    \
-  if (yydebug)                          \
-    yy_reduce_print (yyssp, yyvsp, yylsp, Rule, lex); \
-} while (0)
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, yylsp, Rule, lex); \
+} while (YYID (0))
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
    multiple parsers can coexist.  */
@@ -1059,7 +1126,7 @@ int yydebug;
 
 
 /* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef YYINITDEPTH
+#ifndef	YYINITDEPTH
 # define YYINITDEPTH 200
 #endif
 
@@ -1074,6 +1141,7 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
+

 
 #if YYERROR_VERBOSE
 
@@ -1082,8 +1150,15 @@ int yydebug;
 #   define yystrlen strlen
 #  else
 /* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static YYSIZE_T
 yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
 {
   YYSIZE_T yylen;
   for (yylen = 0; yystr[yylen]; yylen++)
@@ -1099,8 +1174,16 @@ yystrlen (const char *yystr)
 #  else
 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
    YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static char *
 yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
 {
   char *yyd = yydest;
   const char *yys = yysrc;
@@ -1130,27 +1213,27 @@ yytnamerr (char *yyres, const char *yystr)
       char const *yyp = yystr;
 
       for (;;)
-        switch (*++yyp)
-          {
-          case '\'':
-          case ',':
-            goto do_not_strip_quotes;
-
-          case '\\':
-            if (*++yyp != '\\')
-              goto do_not_strip_quotes;
-            /* Fall through.  */
-          default:
-            if (yyres)
-              yyres[yyn] = *yyp;
-            yyn++;
-            break;
-
-          case '"':
-            if (yyres)
-              yyres[yyn] = '\0';
-            return yyn;
-          }
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
     do_not_strip_quotes: ;
     }
 
@@ -1161,301 +1244,366 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
-   about the unexpected token YYTOKEN for the state stack whose top is
-   YYSSP.
-
-   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
-   not large enough to hold the message.  In that case, also set
-   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
-   required number of bytes is too large to store.  */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
-                yytype_int16 *yyssp, int yytoken)
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
 {
-  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = YY_NULLPTR;
-  /* Arguments of yyformat. */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-  /* Number of reported tokens (one for the "unexpected", one per
-     "expected"). */
-  int yycount = 0;
-
-  /* There are many possibilities here to consider:
-     - If this state is a consistent state with a default action, then
-       the only way this function was invoked is if the default action
-       is an error action.  In that case, don't check for expected
-       tokens because there are none.
-     - The only way there can be no lookahead present (in yychar) is if
-       this state is a consistent state with a default action.  Thus,
-       detecting the absence of a lookahead is sufficient to determine
-       that there is no unexpected or expected token to report.  In that
-       case, just report a simple "syntax error".
-     - Don't assume there isn't a lookahead just because this state is a
-       consistent state with a default action.  There might have been a
-       previous inconsistent state, consistent state with a non-default
-       action, or user semantic action that manipulated yychar.
-     - Of course, the expected token list depends on states to have
-       correct lookahead information, and it depends on the parser not
-       to perform extra reductions after fetching a lookahead from the
-       scanner and before detecting a syntax error.  Thus, state merging
-       (from LALR or IELR) and default reductions corrupt the expected
-       token list.  However, the list is correct for canonical LR with
-       one exception: it will still contain any token that will not be
-       accepted due to an error action in a later state.
-  */
-  if (yytoken != YYEMPTY)
-    {
-      int yyn = yypact[*yyssp];
-      yyarg[yycount++] = yytname[yytoken];
-      if (!yypact_value_is_default (yyn))
-        {
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for
-             this state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytname[yyx];
-                {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                    return 2;
-                  yysize = yysize1;
-                }
-              }
-        }
-    }
+  int yyn = yypact[yystate];
 
-  switch (yycount)
-    {
-# define YYCASE_(N, S)                      \
-      case N:                               \
-        yyformat = S;                       \
-      break
-      YYCASE_(0, YY_("syntax error"));
-      YYCASE_(1, YY_("syntax error, unexpected %s"));
-      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
-      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
-      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
-      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
-    }
-
-  {
-    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-      return 2;
-    yysize = yysize1;
-  }
-
-  if (*yymsg_alloc < yysize)
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
     {
-      *yymsg_alloc = 2 * yysize;
-      if (! (yysize <= *yymsg_alloc
-             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
-        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
     }
-
-  /* Avoid sprintf, as that infringes on the user's name space.
-     Don't have undefined behavior even if the translation
-     produced a string with the wrong number of "%s"s.  */
-  {
-    char *yyp = *yymsg;
-    int yyi = 0;
-    while ((*yyp = *yyformat) != '\0')
-      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-        {
-          yyp += yytnamerr (yyp, yyarg[yyi++]);
-          yyformat += 2;
-        }
-      else
-        {
-          yyp++;
-          yyformat++;
-        }
-  }
-  return 0;
 }
 #endif /* YYERROR_VERBOSE */
+

 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
 `-----------------------------------------------*/
 
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static void
 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, char **lex)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, lex)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+    char **lex;
+#endif
 {
   YYUSE (yyvaluep);
   YYUSE (yylocationp);
   YYUSE (lex);
+
   if (!yymsg)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   switch (yytype)
     {
-          case 63: /* seq  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1321 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 64: /* range  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1327 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 65: /* matrix_index  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1333 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 66: /* backticks  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1339 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 67: /* history  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1345 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 68: /* expr  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1351 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 69: /* lvalue  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1357 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 70: /* matrixelts  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1363 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 71: /* matrixlines  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1369 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 72: /* matrix  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1375 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 73: /* in  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1381 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 74: /* inseq  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1387 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 75: /* compr  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1393 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 76: /* arg  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1399 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 78: /* listarg  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1405 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 79: /* funcid  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1411 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 80: /* memberid  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1417 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
-    case 81: /* definition  */
-#line 82 "../src/language/parse.y" /* yacc.c:1257  */
-      { pari_discarded++; }
-#line 1423 "../src/language/parse.c" /* yacc.c:1257  */
-        break;
-
+      case 63: /* "seq" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1394 "../src/language/parse.c"
+	break;
+      case 64: /* "range" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1403 "../src/language/parse.c"
+	break;
+      case 65: /* "matrix_index" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1412 "../src/language/parse.c"
+	break;
+      case 66: /* "backticks" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1421 "../src/language/parse.c"
+	break;
+      case 67: /* "history" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1430 "../src/language/parse.c"
+	break;
+      case 68: /* "expr" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1439 "../src/language/parse.c"
+	break;
+      case 69: /* "lvalue" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1448 "../src/language/parse.c"
+	break;
+      case 70: /* "matrixelts" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1457 "../src/language/parse.c"
+	break;
+      case 71: /* "matrixlines" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1466 "../src/language/parse.c"
+	break;
+      case 72: /* "matrix" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1475 "../src/language/parse.c"
+	break;
+      case 73: /* "in" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1484 "../src/language/parse.c"
+	break;
+      case 74: /* "inseq" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1493 "../src/language/parse.c"
+	break;
+      case 75: /* "compr" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1502 "../src/language/parse.c"
+	break;
+      case 76: /* "arg" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1511 "../src/language/parse.c"
+	break;
+      case 78: /* "listarg" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1520 "../src/language/parse.c"
+	break;
+      case 79: /* "funcid" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1529 "../src/language/parse.c"
+	break;
+      case 80: /* "memberid" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1538 "../src/language/parse.c"
+	break;
+      case 81: /* "definition" */
+
+/* Line 1009 of yacc.c  */
+#line 83 "../src/language/parse.y"
+	{ pari_discarded++; };
+
+/* Line 1009 of yacc.c  */
+#line 1547 "../src/language/parse.c"
+	break;
 
       default:
-        break;
+	break;
     }
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
 }
 
+/* Prevent warnings from -Wmissing-prototypes.  */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (char **lex);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
 
 
 
-/*----------.
-| yyparse.  |
-`----------*/
 
+
+/*-------------------------.
+| yyparse or yypush_parse.  |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 int
 yyparse (char **lex)
+#else
+int
+yyparse (lex)
+    char **lex;
+#endif
+#endif
 {
 /* The lookahead symbol.  */
 int yychar;
 
-
 /* The semantic value of the lookahead symbol.  */
-/* Default value used for initialization, for pacifying older GCCs
-   or non-GCC compilers.  */
-YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
-YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
+YYSTYPE yylval;
 
 /* Location data for the lookahead symbol.  */
-static YYLTYPE yyloc_default
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-  = { 1, 1, 1, 1 }
-# endif
-;
-YYLTYPE yylloc = yyloc_default;
+YYLTYPE yylloc;
 
     /* Number of syntax errors so far.  */
     int yynerrs;
@@ -1465,11 +1613,11 @@ YYLTYPE yylloc = yyloc_default;
     int yyerrstatus;
 
     /* The stacks and their tools:
-       'yyss': related to states.
-       'yyvs': related to semantic values.
-       'yyls': related to locations.
+       `yyss': related to states.
+       `yyvs': related to semantic values.
+       `yyls': related to locations.
 
-       Refer to the stacks through separate pointers, to allow yyoverflow
+       Refer to the stacks thru separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
 
     /* The state stack.  */
@@ -1495,7 +1643,7 @@ YYLTYPE yylloc = yyloc_default;
   int yyn;
   int yyresult;
   /* Lookahead token as an internal (translated) token number.  */
-  int yytoken = 0;
+  int yytoken;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
@@ -1514,9 +1662,10 @@ YYLTYPE yylloc = yyloc_default;
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yyssp = yyss = yyssa;
-  yyvsp = yyvs = yyvsa;
-  yylsp = yyls = yylsa;
+  yytoken = 0;
+  yyss = yyssa;
+  yyvs = yyvsa;
+  yyls = yylsa;
   yystacksize = YYINITDEPTH;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1526,12 +1675,30 @@ YYLTYPE yylloc = yyloc_default;
   yynerrs = 0;
   yychar = YYEMPTY; /* Cause a token to be read.  */
 
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+  yyssp = yyss;
+  yyvsp = yyvs;
+  yylsp = yyls;
+
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+  /* Initialize the default location before parsing starts.  */
+  yylloc.first_line   = yylloc.last_line   = 1;
+  yylloc.first_column = yylloc.last_column = 1;
+#endif
+
 /* User initialization code.  */
-#line 29 "../src/language/parse.y" /* yacc.c:1429  */
+
+/* Line 1251 of yacc.c  */
+#line 30 "../src/language/parse.y"
 { yylloc.start=yylloc.end=*lex; }
 
-#line 1534 "../src/language/parse.c" /* yacc.c:1429  */
+/* Line 1251 of yacc.c  */
+#line 1700 "../src/language/parse.c"
   yylsp[0] = yylloc;
+
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -1552,26 +1719,26 @@ YYLTYPE yylloc = yyloc_default;
 
 #ifdef yyoverflow
       {
-        /* Give user a chance to reallocate the stack.  Use copies of
-           these so that the &'s don't force the real ones into
-           memory.  */
-        YYSTYPE *yyvs1 = yyvs;
-        yytype_int16 *yyss1 = yyss;
-        YYLTYPE *yyls1 = yyls;
-
-        /* Each stack pointer address is followed by the size of the
-           data in use in that stack, in bytes.  This used to be a
-           conditional around just the two extra args, but that might
-           be undefined if yyoverflow is a macro.  */
-        yyoverflow (YY_("memory exhausted"),
-                    &yyss1, yysize * sizeof (*yyssp),
-                    &yyvs1, yysize * sizeof (*yyvsp),
-                    &yyls1, yysize * sizeof (*yylsp),
-                    &yystacksize);
-
-        yyls = yyls1;
-        yyss = yyss1;
-        yyvs = yyvs1;
+	/* Give user a chance to reallocate the stack.  Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	yytype_int16 *yyss1 = yyss;
+	YYLTYPE *yyls1 = yyls;
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yyls1, yysize * sizeof (*yylsp),
+		    &yystacksize);
+
+	yyls = yyls1;
+	yyss = yyss1;
+	yyvs = yyvs1;
       }
 #else /* no yyoverflow */
 # ifndef YYSTACK_RELOCATE
@@ -1579,23 +1746,23 @@ YYLTYPE yylloc = yyloc_default;
 # else
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
-        goto yyexhaustedlab;
+	goto yyexhaustedlab;
       yystacksize *= 2;
       if (YYMAXDEPTH < yystacksize)
-        yystacksize = YYMAXDEPTH;
+	yystacksize = YYMAXDEPTH;
 
       {
-        yytype_int16 *yyss1 = yyss;
-        union yyalloc *yyptr =
-          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-        if (! yyptr)
-          goto yyexhaustedlab;
-        YYSTACK_RELOCATE (yyss_alloc, yyss);
-        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-        YYSTACK_RELOCATE (yyls_alloc, yyls);
+	yytype_int16 *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss_alloc, yyss);
+	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+	YYSTACK_RELOCATE (yyls_alloc, yyls);
 #  undef YYSTACK_RELOCATE
-        if (yyss1 != yyssa)
-          YYSTACK_FREE (yyss1);
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
       }
 # endif
 #endif /* no yyoverflow */
@@ -1605,10 +1772,10 @@ YYLTYPE yylloc = yyloc_default;
       yylsp = yyls + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
+		  (unsigned long int) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
-        YYABORT;
+	YYABORT;
     }
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1628,7 +1795,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yypact_value_is_default (yyn))
+  if (yyn == YYPACT_NINF)
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -1637,7 +1804,7 @@ yybackup:
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = yylex (&yylval, &yylloc, lex);
+      yychar = YYLEX;
     }
 
   if (yychar <= YYEOF)
@@ -1659,8 +1826,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yytable_value_is_error (yyn))
-        goto yyerrlab;
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -1677,9 +1844,7 @@ yybackup:
   yychar = YYEMPTY;
 
   yystate = yyn;
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
   *++yylsp = yylloc;
   goto yynewstate;
 
@@ -1702,7 +1867,7 @@ yyreduce:
   yylen = yyr2[yyn];
 
   /* If YYLEN is nonzero, implement the default value of the action:
-     '$$ = $1'.
+     `$$ = $1'.
 
      Otherwise, the following line sets YYVAL to garbage.
      This behavior is undocumented and Bison
@@ -1717,669 +1882,768 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 85 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 1723 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 86 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 3:
-#line 88 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=NOARG((yyloc));}
-#line 1729 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 89 "../src/language/parse.y"
+    {(yyval.val)=NOARG((yyloc));;}
     break;
 
   case 4:
-#line 89 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 1735 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 90 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 5:
-#line 90 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[-1].val); (yyloc)=(yylsp[-1]);}
-#line 1741 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 91 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (2)].val); (yyloc)=(yylsp[(1) - (2)]);;}
     break;
 
   case 6:
-#line 91 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fseq,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1747 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 92 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fseq,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 7:
-#line 94 "../src/language/parse.y" /* yacc.c:1646  */
-    { (yyval.val)=newnode(Frange,NOARG((yyloc)),NOARG((yyloc)),&(yyloc)); }
-#line 1753 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 95 "../src/language/parse.y"
+    { (yyval.val)=newnode(Frange,NORANGE((yyloc)),NORANGE((yyloc)),&(yyloc)); ;}
     break;
 
   case 8:
-#line 95 "../src/language/parse.y" /* yacc.c:1646  */
-    { (yyval.val)=newnode(Frange,(yyvsp[0].val),NOARG((yyloc)),&(yyloc)); }
-#line 1759 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 96 "../src/language/parse.y"
+    { (yyval.val)=newnode(Frange,(yyvsp[(1) - (1)].val),NORANGE((yyloc)),&(yyloc)); ;}
     break;
 
   case 9:
-#line 96 "../src/language/parse.y" /* yacc.c:1646  */
-    { (yyval.val)=newnode(Frange,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc)); }
-#line 1765 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 97 "../src/language/parse.y"
+    { (yyval.val)=newnode(Frange,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc)); ;}
     break;
 
   case 10:
-#line 97 "../src/language/parse.y" /* yacc.c:1646  */
-    { (yyval.val)=newnode(Frange,NOARG((yyloc)),(yyvsp[0].val),&(yyloc)); }
-#line 1771 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 98 "../src/language/parse.y"
+    { (yyval.val)=newnode(Frange,NORANGE((yyloc)),(yyvsp[(2) - (2)].val),&(yyloc)); ;}
     break;
 
   case 11:
-#line 100 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fmatrix,(yyvsp[-3].val),(yyvsp[-1].val),&(yyloc));}
-#line 1777 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 101 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fmatrix,(yyvsp[(2) - (5)].val),(yyvsp[(4) - (5)].val),&(yyloc));;}
     break;
 
   case 12:
-#line 101 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fmatrix,(yyvsp[-1].val),-1,&(yyloc));}
-#line 1783 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 102 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fmatrix,(yyvsp[(2) - (3)].val),-1,&(yyloc));;}
     break;
 
   case 13:
-#line 104 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=1;}
-#line 1789 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 105 "../src/language/parse.y"
+    {(yyval.val)=1;;}
     break;
 
   case 14:
-#line 105 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[-1].val)+1;}
-#line 1795 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 106 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (2)].val)+1;;}
     break;
 
   case 15:
-#line 108 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPhist,-1,-1,&(yyloc));}
-#line 1801 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 109 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPhist,-1,-1,&(yyloc));;}
     break;
 
   case 16:
-#line 109 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPhist,newintnode(&(yylsp[0])),-1,&(yyloc));}
-#line 1807 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 110 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPhist,newintnode(&(yylsp[(2) - (2)])),-1,&(yyloc));;}
     break;
 
   case 17:
-#line 110 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPhist,newnode(Fsmall,-(yyvsp[0].val),-1,&(yyloc)),-1,&(yyloc));}
-#line 1813 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 111 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPhist,newnode(Fsmall,-(yyvsp[(2) - (2)].val),-1,&(yyloc)),-1,&(yyloc));;}
     break;
 
   case 18:
-#line 111 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPhisttime,-1,-1,&(yyloc));}
-#line 1819 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 112 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPhisttime,-1,-1,&(yyloc));;}
     break;
 
   case 19:
-#line 112 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPhisttime,newintnode(&(yylsp[0])),-1,&(yyloc));}
-#line 1825 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 113 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPhisttime,newintnode(&(yylsp[(3) - (3)])),-1,&(yyloc));;}
     break;
 
   case 20:
-#line 113 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPhisttime,newnode(Fsmall,-(yyvsp[0].val),-1,&(yyloc)),-1,&(yyloc));}
-#line 1831 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 114 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPhisttime,newnode(Fsmall,-(yyvsp[(3) - (3)].val),-1,&(yyloc)),-1,&(yyloc));;}
     break;
 
   case 21:
-#line 116 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newintnode(&(yylsp[0]));}
-#line 1837 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 117 "../src/language/parse.y"
+    {(yyval.val)=newintnode(&(yylsp[(1) - (1)]));;}
     break;
 
   case 22:
-#line 117 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newconst(CSTreal,&(yyloc));}
-#line 1843 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 118 "../src/language/parse.y"
+    {(yyval.val)=newconst(CSTreal,&(yyloc));;}
     break;
 
   case 23:
-#line 118 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newconst(CSTreal,&(yyloc));}
-#line 1849 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 119 "../src/language/parse.y"
+    {(yyval.val)=newconst(CSTreal,&(yyloc));;}
     break;
 
   case 24:
-#line 119 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Ffunction,newconst(CSTmember,&(yylsp[0])),
-                                                newintnode(&(yylsp[-2])),&(yyloc));}
-#line 1856 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 120 "../src/language/parse.y"
+    {(yyval.val)=newnode(Ffunction,newconst(CSTmember,&(yylsp[(3) - (3)])),
+                                                newintnode(&(yylsp[(1) - (3)])),&(yyloc));;}
     break;
 
   case 25:
-#line 121 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newconst(CSTstr,&(yyloc));}
-#line 1862 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 122 "../src/language/parse.y"
+    {(yyval.val)=newconst(CSTstr,&(yyloc));;}
     break;
 
   case 26:
-#line 122 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newconst(CSTquote,&(yyloc));}
-#line 1868 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 123 "../src/language/parse.y"
+    {(yyval.val)=newconst(CSTquote,&(yyloc));;}
     break;
 
   case 27:
-#line 123 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 1874 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 124 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 28:
-#line 124 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fcall,(yyvsp[-3].val),(yyvsp[-1].val),&(yyloc));}
-#line 1880 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 125 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fcall,(yyvsp[(1) - (4)].val),(yyvsp[(3) - (4)].val),&(yyloc));;}
     break;
 
   case 29:
-#line 125 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 1886 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 126 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 30:
-#line 126 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 1892 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 127 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 31:
-#line 127 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 1898 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 128 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 32:
-#line 128 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 1904 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 129 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 33:
-#line 129 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 1910 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 130 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 34:
-#line 130 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fassign,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1916 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 131 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fassign,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 35:
-#line 131 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fassign,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1922 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 132 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fassign,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 36:
-#line 132 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPpp,(yyvsp[-1].val),-1,&(yyloc));}
-#line 1928 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 133 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPpp,(yyvsp[(1) - (2)].val),-1,&(yyloc));;}
     break;
 
   case 37:
-#line 133 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPss,(yyvsp[-1].val),-1,&(yyloc));}
-#line 1934 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 134 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPss,(yyvsp[(1) - (2)].val),-1,&(yyloc));;}
     break;
 
   case 38:
-#line 134 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPme,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1940 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 135 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPme,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 39:
-#line 135 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPde,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1946 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 136 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPde,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 40:
-#line 136 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPdre,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1952 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 137 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPdre,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 41:
-#line 137 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPeuce,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1958 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 138 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPeuce,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 42:
-#line 138 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPmode,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1964 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 139 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPmode,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 43:
-#line 139 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPsle,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1970 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 140 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPsle,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 44:
-#line 140 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPsre,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1976 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 141 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPsre,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 45:
-#line 141 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPpe,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1982 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 142 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPpe,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 46:
-#line 142 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPse,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 1988 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 143 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPse,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 47:
-#line 143 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPnb,(yyvsp[0].val),-1,&(yyloc));}
-#line 1994 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 144 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPnb,(yyvsp[(2) - (2)].val),-1,&(yyloc));;}
     break;
 
   case 48:
-#line 144 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPlength,(yyvsp[0].val),-1,&(yyloc));}
-#line 2000 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 145 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPlength,(yyvsp[(2) - (2)].val),-1,&(yyloc));;}
     break;
 
   case 49:
-#line 145 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPor,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2006 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 146 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPor,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 50:
-#line 146 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPand,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2012 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 147 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPand,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 51:
-#line 147 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPand,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2018 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 148 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPand,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 52:
-#line 148 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPid,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2024 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 149 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPid,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 53:
-#line 149 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPeq,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2030 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 150 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPeq,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 54:
-#line 150 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPne,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2036 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 151 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPne,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 55:
-#line 151 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPge,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2042 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 152 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPge,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 56:
-#line 152 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPg,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2048 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 153 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPg,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 57:
-#line 153 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPle,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2054 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 154 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPle,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 58:
-#line 154 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPl,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2060 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 155 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPl,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 59:
-#line 155 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPs,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2066 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 156 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPs,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 60:
-#line 156 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPp,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2072 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 157 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPp,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 61:
-#line 157 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPsl,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2078 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 158 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPsl,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 62:
-#line 158 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPsr,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2084 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 159 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPsr,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 63:
-#line 159 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPmod,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2090 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 160 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPmod,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 64:
-#line 160 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPdr,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2096 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 161 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPdr,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 65:
-#line 161 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPeuc,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2102 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 162 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPeuc,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 66:
-#line 162 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPd,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2108 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 163 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPd,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 67:
-#line 163 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPm,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2114 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 164 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPm,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 68:
-#line 164 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 2120 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 165 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(2) - (2)].val);;}
     break;
 
   case 69:
-#line 165 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPn,(yyvsp[0].val),-1,&(yyloc));}
-#line 2126 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 166 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPn,(yyvsp[(2) - (2)].val),-1,&(yyloc));;}
     break;
 
   case 70:
-#line 166 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPpow,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2132 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 167 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPpow,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 71:
-#line 167 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPtrans,(yyvsp[-1].val),-1,&(yyloc));}
-#line 2138 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 168 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPtrans,(yyvsp[(1) - (2)].val),-1,&(yyloc));;}
     break;
 
   case 72:
-#line 168 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPderiv,(yyvsp[-1].val),-1,&(yyloc));}
-#line 2144 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 169 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPderiv,(yyvsp[(1) - (2)].val),-1,&(yyloc));;}
     break;
 
   case 73:
-#line 169 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPfact,(yyvsp[-1].val),-1,&(yyloc));}
-#line 2150 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 170 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPfact,(yyvsp[(1) - (2)].val),-1,&(yyloc));;}
     break;
 
   case 74:
-#line 170 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fmatcoeff,(yyvsp[-1].val),(yyvsp[0].val),&(yyloc));}
-#line 2156 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 171 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fmatcoeff,(yyvsp[(1) - (2)].val),(yyvsp[(2) - (2)].val),&(yyloc));;}
     break;
 
   case 75:
-#line 171 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 2162 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 172 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 76:
-#line 172 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Ftag,(yyvsp[-2].val),0,&(yyloc));}
-#line 2168 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 173 "../src/language/parse.y"
+    {(yyval.val)=newnode(Ftag,(yyvsp[(1) - (3)].val),0,&(yyloc));;}
     break;
 
   case 77:
-#line 173 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[-1].val);}
-#line 2174 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 174 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(2) - (3)].val);;}
     break;
 
   case 78:
-#line 176 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fentry,newconst(CSTentry,&(yylsp[0])),-1,&(yyloc));}
-#line 2180 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 177 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fentry,newconst(CSTentry,&(yylsp[(1) - (1)])),-1,&(yyloc));;}
     break;
 
   case 79:
-#line 177 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fmatcoeff,(yyvsp[-1].val),(yyvsp[0].val),&(yyloc));}
-#line 2186 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 178 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fmatcoeff,(yyvsp[(1) - (2)].val),(yyvsp[(2) - (2)].val),&(yyloc));;}
     break;
 
   case 80:
-#line 178 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Ftag,(yyvsp[-2].val),newconst(CSTentry,&(yylsp[-1])),&(yyloc));}
-#line 2192 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 179 "../src/language/parse.y"
+    {(yyval.val)=newnode(Ftag,(yyvsp[(1) - (3)].val),newconst(CSTentry,&(yylsp[(2) - (3)])),&(yyloc));;}
     break;
 
   case 81:
-#line 181 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 2198 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 182 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 82:
-#line 182 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fmatrixelts,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2204 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 183 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fmatrixelts,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 83:
-#line 185 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fmatrixlines,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2210 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 186 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fmatrixlines,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 84:
-#line 186 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fmatrixlines,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2216 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 187 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fmatrixlines,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 85:
-#line 189 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fvec,-1,-1,&(yyloc));}
-#line 2222 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 190 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fvec,-1,-1,&(yyloc));;}
     break;
 
   case 86:
-#line 190 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPrange,(yyvsp[-3].val),(yyvsp[-1].val),&(yyloc));}
-#line 2228 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 191 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPrange,(yyvsp[(2) - (5)].val),(yyvsp[(4) - (5)].val),&(yyloc));;}
     break;
 
   case 87:
-#line 191 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fmat,-1,-1,&(yyloc));}
-#line 2234 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 192 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fmat,-1,-1,&(yyloc));;}
     break;
 
   case 88:
-#line 192 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fvec,(yyvsp[-1].val),-1,&(yyloc));}
-#line 2240 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 193 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fvec,(yyvsp[(2) - (3)].val),-1,&(yyloc));;}
     break;
 
   case 89:
-#line 193 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fmat,(yyvsp[-1].val),-1,&(yyloc));}
-#line 2246 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 194 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fmat,(yyvsp[(2) - (3)].val),-1,&(yyloc));;}
     break;
 
   case 90:
-#line 194 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=-1; YYABORT;}
-#line 2252 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 195 "../src/language/parse.y"
+    {(yyval.val)=-1; YYABORT;;}
     break;
 
   case 91:
-#line 197 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Flistarg,(yyvsp[0].val),(yyvsp[-3].val),&(yyloc));}
-#line 2258 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 198 "../src/language/parse.y"
+    {(yyval.val)=newnode(Flistarg,(yyvsp[(4) - (4)].val),(yyvsp[(1) - (4)].val),&(yyloc));;}
     break;
 
   case 92:
-#line 200 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPcompr,(yyvsp[0].val),-2,&(yyloc));}
-#line 2264 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 201 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPcompr,(yyvsp[(1) - (1)].val),-2,&(yyloc));;}
     break;
 
   case 93:
-#line 201 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall3(OPcompr,(yyvsp[-2].val),-2,(yyvsp[0].val),&(yyloc));}
-#line 2270 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 202 "../src/language/parse.y"
+    {(yyval.val)=newopcall3(OPcompr,(yyvsp[(1) - (3)].val),-2,(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 94:
-#line 202 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall(OPcomprc,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2276 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 203 "../src/language/parse.y"
+    {(yyval.val)=newopcall(OPcomprc,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 95:
-#line 203 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newopcall3(OPcomprc,(yyvsp[-4].val),(yyvsp[0].val),(yyvsp[-2].val),&(yyloc));}
-#line 2282 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 204 "../src/language/parse.y"
+    {(yyval.val)=newopcall3(OPcomprc,(yyvsp[(1) - (5)].val),(yyvsp[(5) - (5)].val),(yyvsp[(3) - (5)].val),&(yyloc));;}
     break;
 
   case 96:
-#line 206 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=addcurrexpr((yyvsp[-1].val),(yyvsp[-3].val),&(yyloc));}
-#line 2288 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 207 "../src/language/parse.y"
+    {(yyval.val)=addcurrexpr((yyvsp[(4) - (5)].val),(yyvsp[(2) - (5)].val),&(yyloc));;}
     break;
 
   case 97:
-#line 209 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 2294 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 210 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 98:
-#line 210 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Fvararg,(yyvsp[-3].val),-1,&(yyloc));}
-#line 2300 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 211 "../src/language/parse.y"
+    {(yyval.val)=newnode(Fvararg,(yyvsp[(1) - (4)].val),-1,&(yyloc));;}
     break;
 
   case 99:
-#line 211 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Frefarg,(yyvsp[0].val),-1,&(yyloc));}
-#line 2306 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 212 "../src/language/parse.y"
+    {(yyval.val)=newnode(Frefarg,(yyvsp[(2) - (2)].val),-1,&(yyloc));;}
     break;
 
   case 100:
-#line 212 "../src/language/parse.y" /* yacc.c:1646  */
-    {if (!pari_once) { yyerrok; } pari_once=1;}
-#line 2312 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 213 "../src/language/parse.y"
+    {if (!pari_once) { yyerrok; } pari_once=1;;}
     break;
 
   case 101:
-#line 213 "../src/language/parse.y" /* yacc.c:1646  */
-    {pari_once=0; (yyval.val)=newopcall(OPcat,(yyvsp[-3].val),(yyvsp[0].val),&(yyloc));}
-#line 2318 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 214 "../src/language/parse.y"
+    {pari_once=0; (yyval.val)=newopcall(OPcat,(yyvsp[(1) - (4)].val),(yyvsp[(4) - (4)].val),&(yyloc));;}
     break;
 
   case 102:
-#line 216 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=(yyvsp[0].val);}
-#line 2324 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 217 "../src/language/parse.y"
+    {(yyval.val)=(yyvsp[(1) - (1)].val);;}
     break;
 
   case 103:
-#line 217 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Flistarg,(yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2330 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 218 "../src/language/parse.y"
+    {(yyval.val)=newnode(Flistarg,(yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 104:
-#line 220 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Ffunction,newconst(CSTentry,&(yylsp[-3])),(yyvsp[-1].val),&(yyloc));}
-#line 2336 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 221 "../src/language/parse.y"
+    {(yyval.val)=newnode(Ffunction,newconst(CSTentry,&(yylsp[(1) - (4)])),(yyvsp[(3) - (4)].val),&(yyloc));;}
     break;
 
   case 105:
-#line 223 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Ffunction,newconst(CSTmember,&(yylsp[0])),(yyvsp[-2].val),&(yyloc));}
-#line 2342 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 224 "../src/language/parse.y"
+    {(yyval.val)=newnode(Ffunction,newconst(CSTmember,&(yylsp[(3) - (3)])),(yyvsp[(1) - (3)].val),&(yyloc));;}
     break;
 
   case 106:
-#line 227 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newfunc(CSTentry,&(yylsp[-5]),(yyvsp[-3].val),(yyvsp[0].val),&(yyloc));}
-#line 2348 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 228 "../src/language/parse.y"
+    {(yyval.val)=newfunc(CSTentry,&(yylsp[(1) - (6)]),(yyvsp[(3) - (6)].val),(yyvsp[(6) - (6)].val),&(yyloc));;}
     break;
 
   case 107:
-#line 229 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newfunc(CSTmember,&(yylsp[-2]),(yyvsp[-4].val),(yyvsp[0].val),&(yyloc));}
-#line 2354 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 230 "../src/language/parse.y"
+    {(yyval.val)=newfunc(CSTmember,&(yylsp[(3) - (5)]),(yyvsp[(1) - (5)].val),(yyvsp[(5) - (5)].val),&(yyloc));;}
     break;
 
   case 108:
-#line 230 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Flambda, (yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2360 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 231 "../src/language/parse.y"
+    {(yyval.val)=newnode(Flambda, (yyvsp[(1) - (3)].val),(yyvsp[(3) - (3)].val),&(yyloc));;}
     break;
 
   case 109:
-#line 231 "../src/language/parse.y" /* yacc.c:1646  */
-    {(yyval.val)=newnode(Flambda, (yyvsp[-2].val),(yyvsp[0].val),&(yyloc));}
-#line 2366 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 232 "../src/language/parse.y"
+    {(yyval.val)=newnode(Flambda, (yyvsp[(2) - (4)].val),(yyvsp[(4) - (4)].val),&(yyloc));;}
     break;
 
 
-#line 2370 "../src/language/parse.c" /* yacc.c:1646  */
+
+/* Line 1464 of yacc.c  */
+#line 2645 "../src/language/parse.c"
       default: break;
     }
-  /* User semantic actions sometimes alter yychar, and that requires
-     that yytoken be updated with the new translation.  We take the
-     approach of translating immediately before every use of yytoken.
-     One alternative is translating here after every semantic action,
-     but that translation would be missed if the semantic action invokes
-     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
-     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
-     incorrect destructor might then be invoked immediately.  In the
-     case of YYERROR or YYBACKUP, subsequent parser actions might lead
-     to an incorrect destructor call or verbose syntax error message
-     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -2389,7 +2653,7 @@ yyreduce:
   *++yyvsp = yyval;
   *++yylsp = yyloc;
 
-  /* Now 'shift' the result of the reduction.  Determine what state
+  /* Now `shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
 
@@ -2404,14 +2668,10 @@ yyreduce:
   goto yynewstate;
 
 
-/*--------------------------------------.
-| yyerrlab -- here on detecting error.  |
-`--------------------------------------*/
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
 yyerrlab:
-  /* Make sure we have latest lookahead translation.  See comments at
-     user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -2419,36 +2679,37 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (&yylloc, lex, YY_("syntax error"));
 #else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
-                                        yyssp, yytoken)
       {
-        char const *yymsgp = YY_("syntax error");
-        int yysyntax_error_status;
-        yysyntax_error_status = YYSYNTAX_ERROR;
-        if (yysyntax_error_status == 0)
-          yymsgp = yymsg;
-        else if (yysyntax_error_status == 1)
-          {
-            if (yymsg != yymsgbuf)
-              YYSTACK_FREE (yymsg);
-            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
-            if (!yymsg)
-              {
-                yymsg = yymsgbuf;
-                yymsg_alloc = sizeof yymsgbuf;
-                yysyntax_error_status = 2;
-              }
-            else
-              {
-                yysyntax_error_status = YYSYNTAX_ERROR;
-                yymsgp = yymsg;
-              }
-          }
-        yyerror (&yylloc, lex, yymsgp);
-        if (yysyntax_error_status == 2)
-          goto yyexhaustedlab;
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (&yylloc, lex, yymsg);
+	  }
+	else
+	  {
+	    yyerror (&yylloc, lex, YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
       }
-# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -2457,20 +2718,20 @@ yyerrlab:
   if (yyerrstatus == 3)
     {
       /* If just tried and failed to reuse lookahead token after an
-         error, discard it.  */
+	 error, discard it.  */
 
       if (yychar <= YYEOF)
-        {
-          /* Return failure if at end of input.  */
-          if (yychar == YYEOF)
-            YYABORT;
-        }
+	{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+	}
       else
-        {
-          yydestruct ("Error: discarding",
-                      yytoken, &yylval, &yylloc, lex);
-          yychar = YYEMPTY;
-        }
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval, &yylloc, lex);
+	  yychar = YYEMPTY;
+	}
     }
 
   /* Else will try to reuse lookahead token after shifting the error
@@ -2490,7 +2751,7 @@ yyerrorlab:
      goto yyerrorlab;
 
   yyerror_range[1] = yylsp[1-yylen];
-  /* Do not reclaim the symbols of the rule whose action triggered
+  /* Do not reclaim the symbols of the rule which action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
   yylen = 0;
@@ -2503,37 +2764,35 @@ yyerrorlab:
 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
 `-------------------------------------------------------------*/
 yyerrlab1:
-  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
 
   for (;;)
     {
       yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
-        {
-          yyn += YYTERROR;
-          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-            {
-              yyn = yytable[yyn];
-              if (0 < yyn)
-                break;
-            }
-        }
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
 
       /* Pop the current state because it cannot handle the error token.  */
       if (yyssp == yyss)
-        YYABORT;
+	YYABORT;
 
       yyerror_range[1] = *yylsp;
       yydestruct ("Error: popping",
-                  yystos[yystate], yyvsp, yylsp, lex);
+		  yystos[yystate], yyvsp, yylsp, lex);
       YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
     }
 
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   yyerror_range[2] = yylloc;
   /* Using YYLLOC is tempting, but would change the location of
@@ -2562,7 +2821,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined yyoverflow || YYERROR_VERBOSE
+#if !defined(yyoverflow) || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -2574,21 +2833,16 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-    {
-      /* Make sure we have latest lookahead translation.  See comments at
-         user semantic actions for why this is necessary.  */
-      yytoken = YYTRANSLATE (yychar);
-      yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval, &yylloc, lex);
-    }
-  /* Do not reclaim the symbols of the rule whose action triggered
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval, &yylloc, lex);
+  /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
   YY_STACK_PRINT (yyss, yyssp);
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-                  yystos[*yyssp], yyvsp, yylsp, lex);
+		  yystos[*yyssp], yyvsp, yylsp, lex);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
@@ -2599,7 +2853,13 @@ yyreturn:
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
 #endif
-  return yyresult;
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
 }
-#line 234 "../src/language/parse.y" /* yacc.c:1906  */
+
+
+
+/* Line 1684 of yacc.c  */
+#line 235 "../src/language/parse.y"
+
 
diff --git a/src/language/parse.h b/src/language/parse.h
index b76c034..94b38d2 100644
--- a/src/language/parse.h
+++ b/src/language/parse.h
@@ -1,19 +1,20 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
-
-/* Bison interface for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+/* A Bison parser, made by GNU Bison 2.4.3.  */
 
+/* Skeleton interface for Bison's Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+   2009, 2010 Free Software Foundation, Inc.
+   
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
-
+   
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
+   
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
@@ -26,79 +27,75 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-#ifndef YY_PARI_SRC_LANGUAGE_PARSE_H_INCLUDED
-# define YY_PARI_SRC_LANGUAGE_PARSE_H_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int pari_debug;
-#endif
 
-/* Token type.  */
+/* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
-  enum yytokentype
-  {
-    KPARROW = 258,
-    KARROW = 259,
-    KDOTDOT = 260,
-    KPE = 261,
-    KSE = 262,
-    KME = 263,
-    KDE = 264,
-    KDRE = 265,
-    KEUCE = 266,
-    KMODE = 267,
-    KAND = 268,
-    KOR = 269,
-    KID = 270,
-    KEQ = 271,
-    KNE = 272,
-    KGE = 273,
-    KLE = 274,
-    KSRE = 275,
-    KSLE = 276,
-    KSR = 277,
-    KSL = 278,
-    KDR = 279,
-    KPP = 280,
-    KSS = 281,
-    KINTEGER = 282,
-    KREAL = 283,
-    KENTRY = 284,
-    KSTRING = 285,
-    SEQ = 286,
-    DEFFUNC = 287,
-    INT = 288,
-    LVAL = 289,
-    SIGN = 290
-  };
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     KPARROW = 258,
+     KARROW = 259,
+     KDOTDOT = 260,
+     KPE = 261,
+     KSE = 262,
+     KME = 263,
+     KDE = 264,
+     KDRE = 265,
+     KEUCE = 266,
+     KMODE = 267,
+     KAND = 268,
+     KOR = 269,
+     KID = 270,
+     KEQ = 271,
+     KNE = 272,
+     KGE = 273,
+     KLE = 274,
+     KSRE = 275,
+     KSLE = 276,
+     KSR = 277,
+     KSL = 278,
+     KDR = 279,
+     KPP = 280,
+     KSS = 281,
+     KINTEGER = 282,
+     KREAL = 283,
+     KENTRY = 284,
+     KSTRING = 285,
+     DEFFUNC = 286,
+     SEQ = 287,
+     LVAL = 288,
+     INT = 289,
+     SIGN = 290
+   };
 #endif
 
-/* Value type.  */
 
-/* Location type.  */
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE YYLTYPE;
-struct YYLTYPE
+typedef struct YYLTYPE
 {
   int first_line;
   int first_column;
   int last_line;
   int last_column;
-};
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
 # define YYLTYPE_IS_DECLARED 1
 # define YYLTYPE_IS_TRIVIAL 1
 #endif
 
 
 
-int pari_parse (char **lex);
-
-#endif /* !YY_PARI_SRC_LANGUAGE_PARSE_H_INCLUDED  */
diff --git a/src/language/parse.y b/src/language/parse.y
index cbd3748..f2bec24 100644
--- a/src/language/parse.y
+++ b/src/language/parse.y
@@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
          (Current).end    = (Rhs)[N].end)
 #include "parsec.h"
 #define NOARG(x) newnode(Fnoarg,-1,-1,&(x))
+#define NORANGE(x) newnode(Fnorange,-1,-1,&(x))
 %}
 %error-verbose
 %name-prefix "pari_"
@@ -91,10 +92,10 @@ seq: /**/ %prec SEQ  {$$=NOARG(@$);}
    | seq ';' expr    {$$=newnode(Fseq,$1,$3,&@$);}
 ;
 
-range: /* */          { $$=newnode(Frange,NOARG(@$),NOARG(@$),&@$); }
-     | expr           { $$=newnode(Frange,$1,NOARG(@$),&@$); }
+range: /* */          { $$=newnode(Frange,NORANGE(@$),NORANGE(@$),&@$); }
+     | expr           { $$=newnode(Frange,$1,NORANGE(@$),&@$); }
      | expr ".." expr { $$=newnode(Frange,$1,$3,&@$); }
-     | '^' expr       { $$=newnode(Frange,NOARG(@$),$2,&@$); }
+     | '^' expr       { $$=newnode(Frange,NORANGE(@$),$2,&@$); }
 ;
 
 matrix_index: '[' range ',' range ']' {$$=newnode(Fmatrix,$2,$4,&@$);}
diff --git a/src/language/sumiter.c b/src/language/sumiter.c
index 8a5db13..c12dc95 100644
--- a/src/language/sumiter.c
+++ b/src/language/sumiter.c
@@ -57,7 +57,7 @@ forparii(GEN a, GEN b, GEN code)
   pari_sp av, av0 = avma;
   GEN aa;
   if (gcmp(b,a) < 0) return;
-  b = gfloor(b);
+  if (typ(b) != t_INFINITY) b = gfloor(b);
   aa = a = setloop(a);
   av=avma;
   push_lex(a,code);
@@ -145,7 +145,7 @@ forstep(GEN a, GEN b, GEN s, GEN code)
   GEN v = NULL;
   int (*cmp)(GEN,GEN);
 
-  b = gcopy(b); av=avma;
+  b = gcopy(b); s = gcopy(s); av=avma;
   push_lex(a,code);
   if (is_vec_t(typ(s)))
   {
@@ -208,10 +208,12 @@ sieve_init(forprime_t *T, ulong a, ulong b)
   T->pos = T->maxpos = 0;
 }
 
+enum {PRST_none, PRST_diffptr, PRST_sieve, PRST_unextprime, PRST_nextprime};
+
 static void
 u_forprime_set_prime_table(forprime_t *T, ulong a)
 {
-  T->strategy = 1;
+  T->strategy = PRST_diffptr;
   if (a < 3)
   {
     T->p = 0;
@@ -243,7 +245,7 @@ u_forprime_arith_init(forprime_t *T, ulong a, ulong b, ulong c, ulong q)
   ulong maxp, maxp2;
   if (a > b || b < 2)
   {
-    T->strategy = 1; /* paranoia */
+    T->strategy = PRST_diffptr; /* paranoia */
     T->p = 0; /* empty */
     T->b = 0; /* empty */
     T->d = diffptr;
@@ -257,7 +259,7 @@ u_forprime_arith_init(forprime_t *T, ulong a, ulong b, ulong c, ulong q)
   }
   T->q = q;
   T->c = c;
-  T->strategy = 0; /* unknown */
+  T->strategy = PRST_none; /* unknown */
   T->sieve = NULL; /* unused for now */
   if (!odd(b) && b > 2) b--;
   T->b = b;
@@ -278,7 +280,7 @@ u_forprime_arith_init(forprime_t *T, ulong a, ulong b, ulong c, ulong q)
   /* FIXME: should sieve as well if q != 1, adapt sieve code */
   if (q != 1 || (maxp2 && maxp2 <= a)
              || T->b - maxuu(a,maxp) < maxp / expu(b))
-  { if (!T->strategy) T->strategy = 3; }
+  { if (T->strategy==PRST_none) T->strategy = PRST_unextprime; }
   else
   { /* worth sieving */
 #ifdef LONG_IS_64BIT
@@ -290,7 +292,7 @@ u_forprime_arith_init(forprime_t *T, ulong a, ulong b, ulong c, ulong q)
     if (b > UPRIME_MAX) b = UPRIME_MAX;
     sieveb = b;
     if (maxp2 && maxp2 < b) sieveb = maxp2;
-    if (!T->strategy) T->strategy = 2;
+    if (T->strategy==PRST_none) T->strategy = PRST_sieve;
     sieve_init(T, maxuu(maxp+2, a), sieveb);
   }
   return 1;
@@ -311,27 +313,34 @@ forprime_init(forprime_t *T, GEN a, GEN b)
   long lb;
   a = gceil(a); if (typ(a) != t_INT) pari_err_TYPE("forprime_init",a);
   if (signe(a) <= 0) a = gen_1;
-  if (b)
+  if (b && typ(b) != t_INFINITY)
   {
     b = gfloor(b);
     if (typ(b) != t_INT) pari_err_TYPE("forprime_init",b);
     if (signe(b) < 0 || cmpii(a,b) > 0)
     {
-      T->strategy = 4; /* paranoia */
+      T->strategy = PRST_nextprime; /* paranoia */
       T->bb = gen_0;
       T->pp = gen_0;
       return 0;
     }
     lb = lgefint(b);
   }
-  else
+  else if (!b || inf_get_sign(b) > 0)
     lb = lgefint(a) + 4;
+  else /* b == -oo */
+  {
+    T->strategy = PRST_nextprime; /* paranoia */
+    T->bb = gen_0;
+    T->pp = gen_0;
+    return 0;
+  }
   T->bb = b;
   T->pp = cgeti(lb);
   /* a, b are positive integers, a <= b */
   if (lgefint(a) == 3) /* lb == 3 implies b != NULL */
     return u_forprime_init(T, uel(a,2), lb == 3? uel(b,2): ULONG_MAX);
-  T->strategy = 4;
+  T->strategy = PRST_nextprime;
   affii(subiu(a,1), T->pp);
   return 1;
 }
@@ -382,13 +391,13 @@ shift_cache(forprime_t *T)
 ulong
 u_forprime_next(forprime_t *T)
 {
-  if (T->strategy == 1)
+  if (T->strategy == PRST_diffptr)
   {
     for(;;)
     {
       if (!*(T->d))
       {
-        T->strategy = T->sieve? 2: 3;
+        T->strategy = T->sieve? PRST_sieve: PRST_unextprime;
         if (T->q != 1) { arith_set(T); if (!T->p) return 0; }
         /* T->p possibly not a prime if q != 1 */
         break;
@@ -401,7 +410,7 @@ u_forprime_next(forprime_t *T)
       }
     }
   }
-  if (T->strategy == 2)
+  if (T->strategy == PRST_sieve)
   {
     ulong n;
     if (T->cache[0]) return shift_cache(T);
@@ -451,7 +460,7 @@ NEXT_CHUNK:
     if (T->maxpos && T->end >= T->sieveb) /* done with sieves ? */
     {
       if (T->sieveb == T->b && T->b != ULONG_MAX) return 0;
-      T->strategy = 3;
+      T->strategy = PRST_unextprime;
     }
     else
     { /* initialize next chunk */
@@ -469,7 +478,7 @@ NEXT_CHUNK:
       goto NEXT_CHUNK;
     }
   }
-  if (T->strategy == 3)
+  if (T->strategy == PRST_unextprime)
   {
     if (T->q == 1)
       T->p = unextprime(T->p + 1);
@@ -481,7 +490,7 @@ NEXT_CHUNK:
       } while (!uisprime(T->p));
     }
     if (!T->p) /* overflow ulong, switch to GEN */
-      T->strategy = 4;
+      T->strategy = PRST_nextprime;
     else
     {
       if (T->p > T->b) return 0;
@@ -496,12 +505,12 @@ forprime_next(forprime_t *T)
 {
   pari_sp av;
   GEN p;
-  if (T->strategy <= 3)
+  if (T->strategy != PRST_nextprime)
   {
     ulong q = u_forprime_next(T);
     if (q) { affui(q, T->pp); return T->pp; }
     /* failure */
-    if (T->strategy <= 3) return NULL; /* we're done */
+    if (T->strategy != PRST_nextprime) return NULL; /* we're done */
     /* overflow ulong, switch to GEN */
     affui(ULONG_MAX, T->pp); /* initialize */
   }
@@ -1770,7 +1779,7 @@ limit_init(struct limit *L, void *E, GEN (*f)(void*,GEN,long),
   L->prec = nbits2prec((long)ceil(1.25*bitprec) + 32);
   L->prec0 = prec;
   L->u = get_u(E, f, N, muli, L->prec);
-  if (alpha && gcmp1(alpha)) alpha = NULL;
+  if (alpha && gequal1(alpha)) alpha = NULL;
   L->na = na  = cgetg(N+1, t_VEC);
   for (n = 1; n <= N; n++)
   {
@@ -1861,7 +1870,7 @@ asympnum(void *E, GEN (*f)(void *, GEN, long), long muli, GEN alpha, long prec)
     a = gdiv(p,q);
     s = gsub(s, a);
     /* |s|q^2 > eps */
-    if (!gcmp0(s) && gexpo(s) + 2*expi(q) > -17) break;
+    if (!gequal0(s) && gexpo(s) + 2*expi(q) > -17) break;
     vectrunc_append(vres, a);
     for (n = 1; n <= L.N; n++) gel(u,n) = gmul(gsub(gel(u,n), a), gel(L.na,n));
   }
diff --git a/src/language/tree.h b/src/language/tree.h
index 6b40936..af7b9d8 100644
--- a/src/language/tree.h
+++ b/src/language/tree.h
@@ -18,7 +18,7 @@ typedef enum {Fseq,
               Fassign,
               Fmatcoeff,
               Fmatrixelts,Fmatrixlines,
-              Fmat,Fvec,Fnoarg,
+              Fmat,Fvec,Fnoarg,Fnorange,
               Flistarg,
               Frefarg, Fvararg,
               Fconst,Fsmall,
diff --git a/src/modules/algebras.c b/src/modules/algebras.c
index 761489f..871280c 100644
--- a/src/modules/algebras.c
+++ b/src/modules/algebras.c
@@ -288,14 +288,7 @@ backtrackfacto(GEN y0, long n, GEN red, GEN pl, GEN nf, GEN data, int (*test)(GE
     while (1) {
       i=n;
       while (i>0) {
-        if (v[i]==b) {
-          v[i] = -b;
-          i--;
-        }
-        else {
-          v[i]++;
-          break;
-        }
+        if (v[i]==b) { v[i] = -b; i--; } else { v[i]++; break; }
       }
       if (i==0) break;
 
@@ -312,12 +305,12 @@ backtrackfacto(GEN y0, long n, GEN red, GEN pl, GEN nf, GEN data, int (*test)(GE
 
       y2 = idealdivexact(nf,y1,idealadd(nf,y1,I));
       *fa = idealfactor(nf, y2);
-      if (data==gen_0 || test(data,y1,*fa)) return y1;
+      if (!data || test(data,y1,*fa)) return y1;
     }
   }
 }
 
-/* if data == gen_0, the test is skipped */
+/* if data == NULL, the test is skipped */
 /* in the test, the factorization does not contain the known factors */
 static GEN
 factoredextchinesetest(GEN nf, GEN x, GEN y, GEN pl, GEN* fa, GEN data, int (*test)(GEN,GEN,GEN))
@@ -354,7 +347,7 @@ factoredextchinesetest(GEN nf, GEN x, GEN y, GEN pl, GEN* fa, GEN data, int (*te
 
 static GEN
 factoredextchinese(GEN nf, GEN x, GEN y, GEN pl, GEN* fa)
-{ return factoredextchinesetest(nf,x,y,pl,fa,gen_0,NULL); }
+{ return factoredextchinesetest(nf,x,y,pl,fa,NULL,NULL); }
 
 /** OPERATIONS ON ASSOCIATIVE ALGEBRAS algebras.c **/
 
@@ -1502,7 +1495,7 @@ _tablemul_ej_Fl(GEN mt, GEN x, long j, ulong p)
     ulong c = x[i];
     if (c) {
       GEN My = gel(gel(mt,i),j);
-      GEN t = Flc_Fl_mul(My,c, p);
+      GEN t = Flv_Fl_mul(My,c, p);
       res = res? Flv_add(res,t, p): t;
     }
   }
@@ -1768,7 +1761,7 @@ algZmultable(GEN al, GEN x) {
     case al_TRIVIAL:
       x0 = gel(x,1);
       if(typ(x0)==t_POLMOD) x0 = gel(x0,2);
-      if(typ(x0)==t_POL) x0 = constant_term(x0);
+      if(typ(x0)==t_POL) x0 = constant_coeff(x0);
       res = mkmatcopy(mkcol(x0));
       break;
     case al_ALGEBRAIC: res = algmtK2Z(al,algalgmultable(al,x)); break;
@@ -2877,23 +2870,15 @@ cyclicrelfrob0(GEN nf, GEN aut, GEN pr, GEN q, long f, long g)
 }
 
 static GEN
-rnfprimedec(GEN rnf, GEN nf2, GEN pr)
-{
-  GEN pr2;
-  pr2 = idealhnf(nf2,gtomat(matalgtobasis(nf2,rnfidealup(rnf, pr))));
-  return idealfactor(nf2, pr2);
-}
+rnfprimedec(GEN rnf, GEN pr)
+{ return idealfactor(obj_check(rnf,rnf_NFABS), rnfidealup0(rnf, pr, 1)); }
 
 long
-cyclicrelfrob(GEN rnf, GEN nf2, GEN auts, GEN pr)
+cyclicrelfrob(GEN rnf, GEN auts, GEN pr)
 {
   pari_sp av = avma;
-  long n,f,g,frob;
-  GEN nf, fa, ppr, autabs;
-  n = rnf_get_degree(rnf);
-  nf = rnf_get_nf(rnf);
-
-  fa = rnfprimedec(rnf, nf2, pr);
+  long f,g,frob, n = rnf_get_degree(rnf);
+  GEN fa = rnfprimedec(rnf, pr);
 
   if (cmpis(gcoeff(fa,1,2), 1) > 0)
     pari_err_DOMAIN("cyclicrelfrob","e(PR/pr)",">",gen_1,pr);
@@ -2902,16 +2887,17 @@ cyclicrelfrob(GEN rnf, GEN nf2, GEN auts, GEN pr)
 
   if (f <= 2) frob = g%n;
   else {
-    ppr = gcoeff(fa,1,1);
-    autabs = rnfeltreltoabs(rnf,gel(auts,g));
+    GEN nf2, PR = gcoeff(fa,1,1);
+    GEN autabs = rnfeltreltoabs(rnf,gel(auts,g));
+    nf2 = obj_check(rnf,rnf_NFABS);
     autabs = nfadd(nf2, autabs, gmul(rnf_get_k(rnf), rnf_get_alpha(rnf)));
-    frob = cyclicrelfrob0(nf2, autabs, ppr, idealnorm(nf,pr), f, g);
+    frob = cyclicrelfrob0(nf2, autabs, PR, pr_norm(pr), f, g);
   }
   avma = av; return frob;
 }
 
 long
-localhasse(GEN rnf, GEN nf2, GEN cnd, GEN pl, GEN auts, GEN b, long k)
+localhasse(GEN rnf, GEN cnd, GEN pl, GEN auts, GEN b, long k)
 {
   pari_sp av = avma;
   long v, m, h, lfa, frob, n, i;
@@ -2936,7 +2922,7 @@ localhasse(GEN rnf, GEN nf2, GEN cnd, GEN pl, GEN auts, GEN b, long k)
   for (i=1; i<=lfa; i++) {
     q = gcoeff(fa,i,1);
     if (cmp_prime_ideal(pr,q)) {
-      frob = cyclicrelfrob(rnf, nf2, auts, q);
+      frob = cyclicrelfrob(rnf, auts, q);
       frob = Fl_mul(frob,umodiu(gcoeff(fa,i,2),n),n);
       h = Fl_add(h,frob,n);
     }
@@ -3055,7 +3041,7 @@ dividesmod(long d, long h, long n) { return !(h%cgcd(d,n)); }
 
 /* ramified prime with nontrivial Hasse invariant */
 static GEN
-localcomplete(GEN rnf, GEN nf2, GEN pl, GEN cnd, GEN auts, long j, long n, long h, long* v)
+localcomplete(GEN rnf, GEN pl, GEN cnd, GEN auts, long j, long n, long h, long* v)
 {
   GEN nf, gens, hgens, pr, modpr, T, p, Np, sol, U, D, b, gene, randg, pu;
   long ngens, i, d, np, k, d1, d2, hg, dnf, vcnd, curgcd;
@@ -3074,7 +3060,7 @@ localcomplete(GEN rnf, GEN nf2, GEN pl, GEN cnd, GEN auts, long j, long n, long
 
   if (!uisprime(n)) {
     gene =  pr_get_gen(pr);
-    hg = localhasse(rnf, nf2, cnd, pl, auts, gene, j);
+    hg = localhasse(rnf, cnd, pl, auts, gene, j);
     nextgen(gene, hg, &gens, &hgens, &ngens, &curgcd);
   }
 
@@ -3083,7 +3069,7 @@ localcomplete(GEN rnf, GEN nf2, GEN pl, GEN cnd, GEN auts, long j, long n, long
     pu = abgrp_get_gen(pu);
     for (i=1; i<lg(pu) && !dividesmod(curgcd,h,n); i++) {
       gene = gel(pu,i);
-      hg = localhasse(rnf, nf2, cnd, pl, auts, gene, j);
+      hg = localhasse(rnf, cnd, pl, auts, gene, j);
       nextgen(gene, hg, &gens, &hgens, &ngens, &curgcd);
     }
   }
@@ -3097,7 +3083,7 @@ localcomplete(GEN rnf, GEN nf2, GEN pl, GEN cnd, GEN auts, long j, long n, long
 
       if (!gequal0(randg) && !gequal1(randg)) {
         gene = Fq_to_nf(randg, modpr);
-        hg = localhasse(rnf, nf2, cnd, pl, auts, gene, j);
+        hg = localhasse(rnf, cnd, pl, auts, gene, j);
         nextgen(gene, hg, &gens, &hgens, &ngens, &curgcd);
       }
     }
@@ -3127,20 +3113,21 @@ localcomplete(GEN rnf, GEN nf2, GEN pl, GEN cnd, GEN auts, long j, long n, long
 static int
 testsplits(GEN data, GEN b, GEN fa)
 {
-  GEN rnf, nf2, fapr, pr, forbid, nf;
-  long i, g, n;
+  GEN rnf, fapr, forbid, P, E;
+  long i, n;
+  if (gequal0(b)) return 0;
+  P = gel(fa,1);
+  E = gel(fa,2);
   rnf = gel(data,1);
-  nf2 = gel(data,2);
-  forbid = gel(data,3);
+  forbid = gel(data,2);
   n = rnf_get_degree(rnf);
-  nf = rnf_get_nf(rnf);
-  if (gequal0(b)) return 0;
   for (i=1; i<lgcols(fa); i++) {
-    pr = gcoeff(fa,i,1);
-    if (idealval(nf,forbid,pr)) return 0;
-    fapr = rnfprimedec(rnf,nf2,pr);
+    GEN pr = gel(P,i);
+    long g;
+    if (tablesearch(forbid, pr, &cmp_prime_ideal)) return 0;
+    fapr = rnfprimedec(rnf,pr);
     g = nbrows(fapr);
-    if ((itos(gcoeff(fa,i,2))*g)%n) return 0;
+    if ((itos(gel(E,i))*g)%n) return 0;
   }
   return 1;
 }
@@ -3173,11 +3160,12 @@ pr_primes(GEN v)
   return ZV_sort_uniq(w);
 }
 
+/* rnf complete */
 static GEN
 alg_complete0(GEN rnf, GEN aut, GEN hf, GEN hi, long maxord)
 {
   pari_sp av = avma;
-  GEN nf, pl, pl2, cnd, prcnd, cnds, y, Lpr, auts, nf2, b, fa, data, hfe;
+  GEN nf, pl, pl2, cnd, prcnd, cnds, y, Lpr, auts, b, fa, data, hfe;
   GEN forbid, al;
   long D, n, d, i, j;
   nf = rnf_get_nf(rnf);
@@ -3190,48 +3178,37 @@ alg_complete0(GEN rnf, GEN aut, GEN hf, GEN hi, long maxord)
   hfe = gel(hf,2);
 
   auts = allauts(rnf,aut);
-  nf2 = check_and_build_nfabs(rnf, nf_get_prec(rnf_get_nf(rnf)));
 
   pl = gcopy(hi); /* conditions on the final b */
   pl2 = gcopy(hi); /* conditions for computing local Hasse invariants */
   for (i=1; i<lg(pl); i++) {
-    if (hi[i]) {
-      pl[i] = -1;
-      pl2[i] = 1;
-    }
-    else if (!rnfrealdec(rnf,i)) {
-      pl[i] = 1;
-      pl2[i] = 1;
-    }
+    if (hi[i]) { pl[i] = -1; pl2[i] = 1; }
+    else if (!rnfrealdec(rnf,i)) { pl[i] = 1; pl2[i] = 1; }
   }
 
   cnds = computecnd(rnf,Lpr);
   prcnd = gel(cnds,1);
   cnd = gel(cnds,2);
   y = cgetg(lgcols(prcnd),t_VEC);
-  forbid = gen_1;
+  forbid = vectrunc_init(lg(Lpr));
   for (i=j=1; i<lg(Lpr); i++)
   {
-    GEN pr = gcoeff(prcnd,i,1);
+    GEN pr = gcoeff(prcnd,i,1), yi;
     long v, e = itos( gcoeff(prcnd,i,2) );
     if (!e) {
-      long frob, f1, f2;
-      gel(y,i) = gen_0;
-      frob = cyclicrelfrob(rnf,nf2,auts,pr);
-      f1 = cgcd(frob,n);
-      f2 = frob/f1;
-      v = ((hfe[i] / f1) * Fl_inv(f2,n)) % n;
-      forbid = idealmul(nf,forbid,pr);
-    }
-    else {
-      gel(y,i) = localcomplete(rnf, nf2, pl2, cnd, auts, j, n, hfe[i], &v);
-      j++;
+      long frob = cyclicrelfrob(rnf,auts,pr), f1 = cgcd(frob,n);
+      vectrunc_append(forbid, pr);
+      yi = gen_0;
+      v = ((hfe[i]/f1) * Fl_inv(frob/f1,n)) % n;
     }
+    else
+      yi = localcomplete(rnf, pl2, cnd, auts, j++, n, hfe[i], &v);
+    gel(y,i) = yi;
     gcoeff(prcnd,i,2) = stoi(e + v);
   }
   for (; i<lgcols(prcnd); i++) gel(y,i) = gen_1;
-
-  data = mkvec3(rnf,nf2,forbid);
+  gen_sort_inplace(forbid, (void*)&cmp_prime_ideal, &cmp_nodata, NULL);
+  data = mkvec2(rnf,forbid);
   b = factoredextchinesetest(nf,prcnd,y,pl,&fa,data,testsplits);
 
   al = cgetg(12, t_VEC);
@@ -3260,6 +3237,7 @@ GEN
 alg_complete(GEN rnf, GEN aut, GEN hf, GEN hi, long maxord)
 {
   long n = rnf_get_degree(rnf);
+  rnfcomplete(rnf);
   return alg_complete0(rnf,aut,hasseconvert(hf,n),hasseconvert(hi,n), maxord);
 }
 
@@ -3508,8 +3486,9 @@ genefrob(GEN nf, GEN gal, GEN r)
 }
 
 static GEN
-rnfcycaut(GEN rnf, GEN nf2)
+rnfcycaut(GEN rnf)
 {
+  GEN nf2 = obj_check(rnf, rnf_NFABS);
   GEN L, alpha, pol, salpha, s, sj, polabs, k, X, pol0, nf;
   long i, d, j;
   d = rnf_get_degree(rnf);
@@ -3542,7 +3521,7 @@ GEN
 alg_hasse(GEN nf, long n, GEN hf, GEN hi, long var, long maxord)
 {
   pari_sp av = avma;
-  GEN primary, al = gen_0, al2, rnf, hil, hfl, Ld, pl, pol, nf2, Lpr, aut;
+  GEN primary, al = gen_0, al2, rnf, hil, hfl, Ld, pl, pol, Lpr, aut;
   long i, lk, j;
   primary = hassecoprime(hf, hi, n);
   for (i=1; i<lg(primary); i++) {
@@ -3559,10 +3538,8 @@ alg_hasse(GEN nf, long n, GEN hf, GEN hi, long var, long maxord)
       for (j=1; j<lg(pl); j++) pl[j] = pl[j] ? -1 : 0;
 
       pol = nfgrunwaldwang(nf,Lpr,Ld,pl,var);
-      rnf = rnfinit(nf,pol);
-      nf2 = check_and_build_nfabs(rnf, nf_get_prec(nf));
-
-      aut = rnfcycaut(rnf,nf2);
+      rnf = rnfinit0(nf,pol,1);
+      aut = rnfcycaut(rnf);
       al2 = alg_complete0(rnf,aut,hfl,hil,maxord);
     }
     else al2 = alg_matrix(nf, lk, var, cgetg(1,t_VEC), maxord);
@@ -3692,7 +3669,7 @@ static void
 algcomputehasse(GEN al)
 {
   long r1, k, n, m, m1, m2, m3, i, m23, m123;
-  GEN rnf, nf, b, fab, disc2, cnd, fad, auts, nf2, pr, pl, perm;
+  GEN rnf, nf, b, fab, disc2, cnd, fad, auts, pr, pl, perm;
   GEN hi, PH, H, L;
 
   rnf = alg_get_splittingfield(al);
@@ -3701,7 +3678,7 @@ algcomputehasse(GEN al)
   b = alg_get_b(al);
   r1 = nf_get_r1(nf);
   auts = alg_get_auts(al);
-  nf2 = alg_get_abssplitting(al);
+  (void)alg_get_abssplitting(al);
 
   /* real places where rnf/nf ramifies */
   pl = cgetg(r1+1, t_VECSMALL);
@@ -3742,7 +3719,7 @@ algcomputehasse(GEN al)
     long frob, e, j = perm[k];
     pr = gcoeff(fab,j,1);
     e = itos(gcoeff(fab,j,2));
-    frob = cyclicrelfrob(rnf, nf2, auts, pr);
+    frob = cyclicrelfrob(rnf, auts, pr);
     gel(PH,k) = pr;
     H[k] = Fl_mul(frob, e, n);
   }
@@ -3761,7 +3738,7 @@ algcomputehasse(GEN al)
     gcoeff(cnd,k+m2,2) = gel(L,j);
   }
   gel(cnd,2) = gdiventgs(gel(cnd,2), eulerphiu(n));
-  for (k=1; k<=m23; k++) H[k+m1] = localhasse(rnf, nf2, cnd, pl, auts, b, k);
+  for (k=1; k<=m23; k++) H[k+m1] = localhasse(rnf, cnd, pl, auts, b, k);
   gel(al,4) = hi;
   gel(al,5) = mkvec2(PH,H);
   checkhasse(nf,alg_get_hasse_f(al),alg_get_hasse_i(al),n);
@@ -3853,7 +3830,7 @@ ismaximalsubfield(GEN al, GEN x, GEN d, long v, GEN *pt_minpol)
 {
   GEN cp = algbasischarpoly(al, x, v), lead;
   if (!ispower(cp, d, pt_minpol)) return 0;
-  lead = leading_term(*pt_minpol);
+  lead = leading_coeff(*pt_minpol);
   if(isintm1(lead)) *pt_minpol = gneg(*pt_minpol);
   return ZX_is_irred(*pt_minpol);
 }
diff --git a/src/modules/genus2red.c b/src/modules/genus2red.c
index 823fe39..0cf33aa 100644
--- a/src/modules/genus2red.c
+++ b/src/modules/genus2red.c
@@ -107,13 +107,13 @@ gmul(gmul(gmul(gmul(gmulsg(1568, a0), a2), gsqr(a3)), a4), a6)), -10));
 /**   A REDUCTION ALGORITHM "A LA TATE" FOR CURVES OF GENUS 2      **/
 /**                                                                **/
 /********************************************************************/
-/* Based on genus2reduction-0.3, http://www.math.u-bordeaux1.fr/~liu/G2R/
- * by Qing Liu <liu at math.u-bordeaux1.fr>
- * and Henri Cohen <cohen at math.u-bordeaux1.fr>
+/* Based on genus2reduction-0.3, http://www.math.u-bordeaux.fr/~liu/G2R/
+ * by Qing Liu <liu at math.u-bordeaux.fr>
+ * and Henri Cohen <cohen at math.u-bordeaux.fr>
 
  * Qing Liu: Modeles minimaux des courbes de genre deux
  * J. fuer die Reine und Angew. Math., 453 (1994), 137-164.
- * http://www.math.u-bordeaux1.fr/~liu/articles/modregE.ps */
+ * http://www.math.u-bordeaux.fr/~liu/articles/modregE.ps */
 
 /* some auxiliary polynomials, gp2c-generated */
 
diff --git a/src/modules/krasner.c b/src/modules/krasner.c
index e094054..ad8cc62 100644
--- a/src/modules/krasner.c
+++ b/src/modules/krasner.c
@@ -374,7 +374,7 @@ Quick_FqX_roots(KRASNER_t *data, GEN pol)
     ind = ZXY_z_eval(pol, data->q[2], data->p[2]);
     if (gel(data->roottable, ind)) return gel(data->roottable, ind);
   }
-  rts = FqX_roots(pol, data->uplr, data->p);
+  rts = FpXQX_roots(pol, data->uplr, data->p);
 
   if (ind) gel(data->roottable, ind) = gclone(rts);
   return rts;
diff --git a/src/modules/kummer.c b/src/modules/kummer.c
index a8c2b6a..1d4f1df 100644
--- a/src/modules/kummer.c
+++ b/src/modules/kummer.c
@@ -529,18 +529,18 @@ fix_kernel(GEN K, GEN M, GEN vecMsup, long lW, long ell)
     if (j != --idx) swap(gel(K, j), gel(K, idx));
     Kidx[idx] = i;
     if (coeff(K,i,idx) != 1)
-      Flc_Fl_div_inplace(gel(K,idx), coeff(K,i,idx), ell);
+      Flv_Fl_div_inplace(gel(K,idx), coeff(K,i,idx), ell);
     Ki = gel(K,idx);
     if (coeff(K,i,dK) != 1)
     {
       ulong t = Fl_sub(coeff(K,i,dK), 1, ell);
-      Flv_sub_inplace(gel(K,dK), Flc_Fl_mul(Ki, t, ell), ell);
+      Flv_sub_inplace(gel(K,dK), Flv_Fl_mul(Ki, t, ell), ell);
     }
     for (j = dK; --j > 0; )
     {
       if (j == idx) continue;
       if (coeff(K,i,j))
-        Flv_sub_inplace(gel(K,j), Flc_Fl_mul(Ki, coeff(K,i,j), ell), ell);
+        Flv_sub_inplace(gel(K,j), Flv_Fl_mul(Ki, coeff(K,i,j), ell), ell);
     }
   }
   /* ffree = first vector that is not "free" for the scalar products */
@@ -559,7 +559,7 @@ fix_kernel(GEN K, GEN M, GEN vecMsup, long lW, long ell)
       if (dotprod)
       {
         if (j != --ffree) swap(gel(K, j), gel(K, ffree));
-        if (dotprod != 1) Flc_Fl_div_inplace(gel(K, ffree), dotprod, ell);
+        if (dotprod != 1) Flv_Fl_div_inplace(gel(K, ffree), dotprod, ell);
         break;
       }
     }
@@ -579,13 +579,13 @@ fix_kernel(GEN K, GEN M, GEN vecMsup, long lW, long ell)
     if (dotprod != 1)
     {
       ulong t = Fl_sub(dotprod,1,ell);
-      Flv_sub_inplace(gel(K,dK), Flc_Fl_mul(Ki,t,ell), ell);
+      Flv_sub_inplace(gel(K,dK), Flv_Fl_mul(Ki,t,ell), ell);
     }
     for (j = dK; --j > 0; )
     {
       if (j == ffree) continue;
       dotprod = Flv_dotproduct(Msup, gel(K,j), ell);
-      if (dotprod) Flv_sub_inplace(gel(K,j), Flc_Fl_mul(Ki,dotprod,ell), ell);
+      if (dotprod) Flv_sub_inplace(gel(K,j), Flv_Fl_mul(Ki,dotprod,ell), ell);
     }
   }
   if (ell == 2)
@@ -850,7 +850,7 @@ FOUND:  X = Flm_Flc_mul(K, y, ell);
                 if (lg(K2) != 2) pari_err_BUG("linear algebra");
                 K2 = gel(K2,1);
                 if (K2[1] != K2[2])
-                  Flc_Fl_mul_inplace(colgrp, Fl_div(K2[2],K2[1],ell), ell);
+                  Flv_Fl_mul_inplace(colgrp, Fl_div(K2[2],K2[1],ell), ell);
               }
             }
             Flv_fill(gel(matgrp,rk), colgrp);
diff --git a/src/modules/mpqs.c b/src/modules/mpqs.c
index 622a7f4..6439840 100644
--- a/src/modules/mpqs.c
+++ b/src/modules/mpqs.c
@@ -2031,7 +2031,7 @@ mpqs_eval_cand(mpqs_handle_t *h, long number_of_cand,
       }
       p = FB[pi].fbe_p;
 #ifdef MPQS_DEBUG_CANDIDATE_EVALUATION
-      err_printf("MPQS DEBUG: Qx=%Ps p=%ld\n", Qx, (long)p);
+      err_printf("MPQS DEBUG: Qx=%Ps p=%ld\n", Qx, p);
 #endif
       /* otherwise p might still divide the current adjusted Qx. Try it... */
       /* NOTE: break out of loop when remaining Qx is 1 ?  Or rather, suppress
diff --git a/src/modules/stark.c b/src/modules/stark.c
index 177b5db..bca42c5 100644
--- a/src/modules/stark.c
+++ b/src/modules/stark.c
@@ -407,7 +407,7 @@ CplxModulus(GEN data, long *newprec)
     pr = nbits2extraprec( gexpo(pol) );
     if (pr < 0) pr = 0;
     dprec = maxss(dprec, pr) + EXTRA_PREC;
-    if (!gequal0(leading_term(pol)))
+    if (!gequal0(leading_coeff(pol)))
     {
       cpl = RgX_fpnorml2(pol, DEFAULTPREC);
       if (!gequal0(cpl)) break;
@@ -2861,7 +2861,7 @@ GEN
 qfbforms(GEN D)
 {
   ulong d = itou(D), dover3 = d/3, t, b2, a, b, c, h;
-  GEN L = cgetg((long)(sqrt(d) * log2(d)), t_VEC);
+  GEN L = cgetg((long)(sqrt((double)d) * log2(d)), t_VEC);
   b2 = b = (d&1); h = 0;
   if (!b) /* b = 0 treated separately to avoid special cases */
   {
diff --git a/src/modules/subfield.c b/src/modules/subfield.c
index 4beec1e..3241f84 100644
--- a/src/modules/subfield.c
+++ b/src/modules/subfield.c
@@ -308,7 +308,7 @@ polsimplify(GEN x)
 {
   long i,lx = lg(x);
   for (i=2; i<lx; i++)
-    if (typ(gel(x,i)) == t_POL) gel(x,i) = constant_term(gel(x,i));
+    if (typ(gel(x,i)) == t_POL) gel(x,i) = constant_coeff(gel(x,i));
   return x;
 }
 
@@ -447,7 +447,7 @@ get_bezout(GEN pol, GEN fk, GEN p)
     B = FpX_div(pol, A, p);
     d = FpX_extgcd(A,B,p, &u, &v);
     if (degpol(d) > 0) pari_err_COPRIME("get_bezout",A,B);
-    d = constant_term(d);
+    d = constant_coeff(d);
     if (!gequal1(d)) v = FpX_Fp_mul(v, Fp_inv(d, p), p);
     gel(U,i) = FpX_mul(B,v, p);
   }
@@ -507,7 +507,7 @@ init_primedata(primedata *S)
   for (l=1,j=1; j<lff; j++)
   { /* compute roots and fix ordering (Frobenius cycles) */
     GEN F = gel(S->ff, j), deg1 = FpX_factorff_irred(F, T,p);
-    GEN H = gel(deg1,1), a = Fq_neg(constant_term(H), T,p);
+    GEN H = gel(deg1,1), a = Fq_neg(constant_coeff(H), T,p);
     GEN Q = FqX_div(F, H, T,p);
     GEN q = Fq_inv(FqX_eval(Q, a, T,p), T,p);
     gel(S->interp,j) = FqX_Fq_mul(Q, q, T,p); /* = 1 at a, 0 at other roots */
@@ -543,7 +543,7 @@ choose_prime(primedata *S, GEN pol, GEN dpol)
     for (j=2; j<=r; j++) { n[j] = degpol(gel(ff,j)); lcm = clcm(lcm, n[j]); }
     if (lcm <= oldlcm) continue; /* false when oldlcm = 0 */
 
-    if (DEBUGLEVEL) err_printf("p = %ld,\tlcm = %ld,\torbits: %Ps\n",p,lcm,n);
+    if (DEBUGLEVEL) err_printf("p = %lu,\tlcm = %ld,\torbits: %Ps\n",p,lcm,n);
     pp = p;
     oldn = n;
     oldff = ff;
@@ -731,7 +731,7 @@ subfield(GEN A, blockdata *B)
      * if g o h = 0 (pol), we'll have h(Ai[j]) = delta[i] for all j */
     /* fk[k] belongs to block number whichdelta[k] */
     for (j=1; j<=d; j++) whichdelta[Ai[j]] = i;
-    if (typ(p1) == t_POL) p1 = constant_term(p1);
+    if (typ(p1) == t_POL) p1 = constant_coeff(p1);
     d_1_term = addii(d_1_term, p1);
   }
   d_1_term = centermod(d_1_term, pe); /* Tr(g) */
diff --git a/src/mt/mpi.c b/src/mt/mpi.c
index 6ea5209..620b125 100644
--- a/src/mt/mpi.c
+++ b/src/mt/mpi.c
@@ -35,7 +35,9 @@ static struct mt_mstate *pari_mt;
 static void
 send_long(long a, long dest)
 {
+  BLOCK_SIGINT_START
   MPI_Send(&a, 1, MPI_LONG, dest, 0, MPI_COMM_WORLD);
+  BLOCK_SIGINT_END
 }
 
 static void
@@ -52,7 +54,11 @@ send_GEN(GEN elt, int dest)
   GEN reloc = copybin_unlink(elt);
   GENbin *buf = copy_bin(mkvec2(elt,reloc));
   size = sizeof(GENbin) + buf->len*sizeof(ulong);
-  MPI_Send(buf, size, MPI_CHAR, dest, 0, MPI_COMM_WORLD);
+  {
+    BLOCK_SIGINT_START
+    MPI_Send(buf, size, MPI_CHAR, dest, 0, MPI_COMM_WORLD);
+    BLOCK_SIGINT_END
+  }
   pari_free(buf); avma = av;
 }
 
@@ -74,7 +80,9 @@ static long
 recvfrom_long(int src)
 {
   long a;
+  BLOCK_SIGINT_START
   MPI_Recv(&a, 1, MPI_LONG, src, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+  BLOCK_SIGINT_END
   return a;
 }
 
@@ -89,11 +97,13 @@ recvstatus_buf(int source, MPI_Status *status)
 {
   int size;
   GENbin *buf;
+  BLOCK_SIGINT_START
 
   MPI_Get_count(status, MPI_CHAR, &size);
   buf = (GENbin *)pari_malloc(size);
   MPI_Recv(buf, size, MPI_CHAR, source, 0/* tag */,
           MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+  BLOCK_SIGINT_END
   return buf;
 }
 
@@ -117,7 +127,9 @@ static GEN
 recvfrom_GEN(int src)
 {
   MPI_Status status;
+  BLOCK_SIGINT_START
   MPI_Probe(src, 0, MPI_COMM_WORLD, &status);
+  BLOCK_SIGINT_END
   return recvstatus_GEN(src, &status);
 }
 
@@ -125,8 +137,10 @@ static GEN
 recvany_GEN(int *source)
 {
   MPI_Status status;
+  BLOCK_SIGINT_START
   MPI_Probe(MPI_ANY_SOURCE, 0 /* tag */, MPI_COMM_WORLD, &status);
   *source = status.MPI_SOURCE;
+  BLOCK_SIGINT_END
   return recvstatus_GEN(*source, &status);
 }
 
@@ -134,8 +148,10 @@ static void
 recvany_void(int *source)
 {
   MPI_Status status;
+  BLOCK_SIGINT_START
   MPI_Probe(MPI_ANY_SOURCE, 0 /* tag */, MPI_COMM_WORLD, &status);
   *source = status.MPI_SOURCE;
+  BLOCK_SIGINT_END
   recvstatus_void(*source, &status);
 }
 
diff --git a/src/test/32/algebras b/src/test/32/algebras
index 72ff5c8..dc668cd 100644
--- a/src/test/32/algebras
+++ b/src/test/32/algebras
@@ -4,194 +4,195 @@ contains nfabs: 1
 x^3], [1, 1, 1, 1]], [1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1], 1, [y
 , [1, 0], 1, 1, [Mat(1), Mat(1), Mat(1), Mat(1), 1, Mat(1), [1, 0], []], [0.
 E-57], [1], Mat(1), Mat(1)], [x^4 + x^3 + x^2 + x + 1, 0, -1, y, x^4 + x^3 +
- x^2 + x + 1], [0]], [x^2, -x^3 - x^2 - x - 1, x^3], Mod(3, y), Vecsmall([0]
-), [[[3, [3]~, 1, 1, 1], [5, [5]~, 1, 1, 1]], Vecsmall([3, 1])], 0, [1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
-, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 1], [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 
-0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, -1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
-0, 0, -1, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, -1, 0, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0], [0, 0, -1, 1, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0
-, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 
-0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0,
- 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 1, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -
-1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 1, 0, -1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1], [
-0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, -1, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, -1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3; 1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -
-3, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3; 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, -3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 0,
- 0; 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, -1, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 1, 0, 
-0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
- 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -3; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 3, -3; 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, -1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0,
- 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0,
- 0, 3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, -1, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, -3, 
-3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, -3, 0, 0, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0,
- 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- -3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0; 0, 0, 0, -1, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0; 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, -1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, -1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0,
- 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -3
-, 0, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -3; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 3, -3; 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 1, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 
--3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- -3, 0, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 3; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, -1
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 3, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 
-0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 3, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 3; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0
-, -3, 3, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 
-0, 0; 0, 0, 0, 0, 3, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 3, -3,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -3
-, 0, 0, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0; 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, -3, 0, 3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0; 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0; 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, -1, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0], [0, 0, 0, 0, -3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -3, 0
-, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, -3, 3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0, 0, 0, 0; 
-0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 3, 
--3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3; 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3; 0, 0, -1, 
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, -1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 3, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 3, 
-0, -3, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -3, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, -3, 3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, -3, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 1
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 0, [16, -4, -4
-, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
+ x^2 + x + 1], [0, [[1; 0; 0; 0], Mat(1), 1, Vecsmall([1])]]], [x^2, -x^3 - 
+x^2 - x - 1, x^3], Mod(3, y), Vecsmall([0]), [[[3, [3]~, 1, 1, 1], [5, [5]~,
+ 1, 1, 1]], Vecsmall([3, 1])], 0, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
+, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 
+0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
+, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
+0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0;
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
+, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [[1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
+0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
+0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
+, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, -
+1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 0, 0; 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, -1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0; 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, -1
+, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+; 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -
+1, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0; 0, 
+0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 0, -1, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1; 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, -1, 0, 0], [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0; 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 
+1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
+0, 0; 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0;
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0; 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 1, 0, 0, -1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1; 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1], [0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 0; 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0,
+ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0
+, 0; 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, -1, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0; 
+0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+1, -1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0; 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -1, 0, 0, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0], [0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0; 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0
+, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
+0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
+, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, -3, 0, 3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0; 0, 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0; 0, 0, 0, -1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0; 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0,
+ -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
+, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 
+0, 0, 0; 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
+0, 0, -1, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0,
+ 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
+ -1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3;
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3; 0, 0
+, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0; 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, -1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1
+, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
+, 0, 0, -1, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 
+0; 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, -3, 3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0; 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 0, -3, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1
+, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
+, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 
+0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
+0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0,
+ 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, -1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0
+], [0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0; 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0; 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 3; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
+0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
+0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
+, 0, 0, 0, -3, 0, 3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 3, 0, 
+0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, -3, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0,
+ 3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, -3, 0, 0; 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1
+, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, -1, 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0; 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
+0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
+ 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0,
+ 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0
+, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3; 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 3, 0, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -
+3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3; 0, 0, -1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1,
+ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, -1, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
+, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 
+0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 
+0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3,
+ 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0; 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -3, 0, 0, 3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0
+; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 1, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 
+-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0,
+ 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
+ 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0
+, 0, 0, 0, 0], [0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
+0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0
+, 0, 0; 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0; 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0; 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3; 1, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0, 0, 0, 0, 0; 0
+, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 3, 0, -3, 0, 0, 
+0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
+0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3,
+ 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 3, 0, 0, 0, 0; 0, 0, 0, 0,
+ 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -3, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3; 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 
+0, 0; 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, -1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
+ 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, -3, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
+ 0, 0, 0, -3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -3, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 0, 0, 0; 0, 0, 0
+, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 
+0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
+0, 0, -3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -3; 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, -3; 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, -1, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 3, 0, 0, -3, 
+0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 3, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
+0, 0, 0, 0, 0, 3, -3, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+-3, 3, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0; 0, 0, 0,
+ 0, 0, 0, 0, 0, 3, 0, -3, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -3, 0
+, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0; 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0, 0, -3, 0, 3, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 
+0, 0, 3; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0; 0, -1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 0]], 0, [16, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0]]
 Suite: all
 Suite: get
 degree: 1
@@ -251,14 +252,14 @@ cyclo construction: [[x^2 + x + 1, [[1], 1], [Mat(3), -3], 1, [], [], [[1, x
 707529361835], [1, 0; 1, -1], [2, -1; -1, -1], [3, 2; 0, 1], [1, -1; -1, -2]
 , [3, [2, -1; 1, 1]], []], [-0.50000000000000000000000000000000000000 + 0.86
 602540378443864676372317075293618347*I], [1, x], [1, 0; 0, 1], [1, 0, 0, -1;
- 0, 1, 1, -1]]]], [-x - 1], Mod(-175624635, y), Vecsmall([1]), [[[5, [5]~, 1
-, 1, 1], [11708309, [11708309]~, 1, 1, 1], [3, [3]~, 1, 1, 1]], Vecsmall([1,
- 1, 1])], 0, [1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 2/3; 0, 0, 0, 1/3], [1, 0, 0,
- 0; 0, 1, 0, 0; 0, 0, 1, -2; 0, 0, 0, 3], [[1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1,
- 0; 0, 0, 0, 1], [0, -1, 0, 0; 1, -1, 0, 0; 0, 0, 1, 1; 0, 0, -3, -2], [0, 0
-, -175624635, -117083090; 0, 0, 0, -58541545; 1, -2, 0, 0; 0, 3, 0, 0], [0, 
-0, -58541545, -58541545; 0, 0, 58541545, 0; 0, -1, 0, 0; 1, 1, 0, 0]], 0, [4
-, -2, 0, 0]]
+ 0, 1, 1, -1]], [[1; 0], Mat(1), 1, Vecsmall([1])]]], [-x - 1], Mod(-1756246
+35, y), Vecsmall([1]), [[[5, [5]~, 1, 1, 1], [11708309, [11708309]~, 1, 1, 1
+], [3, [3]~, 1, 1, 1]], Vecsmall([1, 1, 1])], 0, [1, 0, 0, 0; 0, 1, 0, 0; 0,
+ 0, 1, 2/3; 0, 0, 0, 1/3], [1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, -2; 0, 0, 0, 3]
+, [[1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1], [0, -1, 0, 0; 1, -1, 0,
+ 0; 0, 0, 1, 1; 0, 0, -3, -2], [0, 0, -175624635, -117083090; 0, 0, 0, -5854
+1545; 1, -2, 0, 0; 0, 3, 0, 0], [0, 0, -58541545, -58541545; 0, 0, 58541545,
+ 0; 0, -1, 0, 0; 1, 1, 0, 0]], 0, [4, -2, 0, 0]]
 cyclo ramified at infinity: 1
 cyclo unramified at infinity: 1
 cyclo 5: 1
@@ -303,14 +304,14 @@ test: [[J^2 + 8, [[1], 1], [Mat(8), -2], Mat(2), [], [], [[1, J], [1, Mat(1/
 887242096980786*I]), [1, 1.4142135623730950488016887242096980786; 1, -1.4142
 135623730950488016887242096980786], [1, 1; 1, -1], [2, 0; 0, -4], [4, 0; 0, 
 2], [2, 0; 0, -1], [2, [0, -2; 1, 0]], []], [0.E-77 + 2.82842712474619009760
-33774484193961571*I], [1, 1/2*J], [1, 0; 0, 2], [1, 0, 0, -2; 0, 1, 1, 0]]]]
-, [-J], Mod(-39, y), Vecsmall([1]), [[[13, [13]~, 1, 1, 1], [2, [2]~, 1, 1, 
-1], [3, [3]~, 1, 1, 1]], Vecsmall([1, 0, 0])], 0, [1, 0, 1/2, 1/2; 0, 1, 0, 
-1/4; 0, 0, 1/2, 1/6; 0, 0, 0, 1/12], [1, 0, -1, -4; 0, 1, 0, -3; 0, 0, 2, -4
-; 0, 0, 0, 12], [[1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1], [0, -2, 2
-, 0; 1, 0, 2, 1; 0, 0, 2, 1; 0, 0, -6, -2], [0, -2, -10, -4; 0, -1, 0, -2; 1
-, -2, 1, 0; 0, 6, 0, 2], [0, -1, -3, -2; 0, 0, 2, 0; 0, -1, 1, 0; 1, 2, -1, 
-1]], 0, [4, 0, 2, 2]]
+33774484193961571*I], [1, 1/2*J], [1, 0; 0, 2], [1, 0, 0, -2; 0, 1, 1, 0]], 
+[[1; 0], Mat(1), 1, Vecsmall([1])]]], [-J], Mod(-39, y), Vecsmall([1]), [[[1
+3, [13]~, 1, 1, 1], [2, [2]~, 1, 1, 1], [3, [3]~, 1, 1, 1]], Vecsmall([1, 0,
+ 0])], 0, [1, 0, 1/2, 1/2; 0, 1, 0, 1/4; 0, 0, 1/2, 1/6; 0, 0, 0, 1/12], [1,
+ 0, -1, -4; 0, 1, 0, -3; 0, 0, 2, -4; 0, 0, 0, 12], [[1, 0, 0, 0; 0, 1, 0, 0
+; 0, 0, 1, 0; 0, 0, 0, 1], [0, -2, 2, 0; 1, 0, 2, 1; 0, 0, 2, 1; 0, 0, -6, -
+2], [0, -2, -10, -4; 0, -1, 0, -2; 1, -2, 1, 0; 0, 6, 0, 2], [0, -1, -3, -2;
+ 0, 0, 2, 0; 0, -1, 1, 0; 1, 2, -1, 1]], 0, [4, 0, 2, 2]]
 degree 6 algebra over Q: 1
 trivial finite conditions: [Vecsmall([1, 1]), [[[3, [3, 0]~, 1, 2, 1], [5, [
 1, 2]~, 2, 1, [1, 2; 2, -1]]], Vecsmall([0, 0])]]
@@ -332,50 +333,50 @@ construct algebra: [[x^3 - 21*x + 7, [[1], 1], [Mat(49), 1], Mat(27), [], []
 54388638, 0.33512560373788642573341538698076855680, 4.4058132074145147574166
 139170446703070], [1, 1/3*x + 1/3, 1/9*x^2 - 1/9*x - 11/9], [1, -1, 10; 0, 3
 , 3; 0, 0, 9], [1, 0, 0, 0, 1, -1, 0, -1, 2; 0, 1, 0, 1, 1, 1, 0, 1, -1; 0, 
-0, 1, 0, 1, 0, 1, 0, 0]]]], [-1/3*x^2 - 2/3*x + 14/3, 1/3*x^2 - 1/3*x - 14/3
-], Mod(-6, y), Vecsmall([0]), [[[2, [2]~, 1, 1, 1], [3, [3]~, 1, 1, 1], [7, 
-[7]~, 1, 1, 1]], Vecsmall([1, 2, 0])], 0, [1, 0, 0, 0, 0, 4/7, 0, 4/7, 5/7; 
-0, 1, 0, 0, 0, 4/7, 0, 2/7, 5/7; 0, 0, 1, 0, 0, 5/7, 0, 0, 1/7; 0, 0, 0, 1, 
-0, 5/7, 0, 1/7, 5/7; 0, 0, 0, 0, 1, 5/7, 0, 4/7, 5/7; 0, 0, 0, 0, 0, 1/7, 0,
- 0, 1/7; 0, 0, 0, 0, 0, 0, 1, 2/7, 5/7; 0, 0, 0, 0, 0, 0, 0, 1/7, 5/7; 0, 0,
- 0, 0, 0, 0, 0, 0, 1/7], [1, 0, 0, 0, 0, -4, 0, -4, 19; 0, 1, 0, 0, 0, -4, 0
-, -2, 9; 0, 0, 1, 0, 0, -5, 0, 0, 4; 0, 0, 0, 1, 0, -5, 0, -1, 5; 0, 0, 0, 0
-, 1, -5, 0, -4, 20; 0, 0, 0, 0, 0, 7, 0, 0, -7; 0, 0, 0, 0, 0, 0, 1, -2, 5; 
-0, 0, 0, 0, 0, 0, 0, 7, -35; 0, 0, 0, 0, 0, 0, 0, 0, 7], [[1, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1], [
-0, 1, -1, 4, 4, 5, 19, 8, 17; 1, 1, 1, 4, 4, 7, 9, 6, 12; 0, 1, 0, 5, 5, 7, 
-4, 5, 10; 0, 0, 0, 6, 5, 7, 5, 5, 10; 0, 0, 0, 4, 4, 5, 20, 8, 17; 0, 0, 0, 
--7, -7, -9, -7, -7, -14; 0, 0, 0, 0, 0, 0, 5, 1, 2; 0, 0, 0, 0, 0, 0, -35, -
-9, -21; 0, 0, 0, 0, 0, 0, 7, 2, 5], [0, -1, 2, 0, -4, -2, -15, -9, -22; 0, 1
-, -1, 0, -4, -3, -7, -5, -11; 1, 0, 0, 0, -5, -3, -4, -4, -8; 0, 0, 0, 0, -4
-, -3, -4, -4, -8; 0, 0, 0, 1, -4, -2, -16, -9, -22; 0, 0, 0, 0, 7, 5, 7, 7, 
-14; 0, 0, 0, 0, 0, 0, -2, -1, -3; 0, 0, 0, 0, 0, 0, 28, 12, 35; 0, 0, 0, 0, 
-0, 0, -7, -3, -9], [0, 0, -4, 0, -4, -3, -6, -4, -5; 0, 0, -4, 0, -2, -3, 0,
- -2, -5; 0, 0, -5, 0, 0, -3, 0, 0, -1; 1, 0, -5, 0, -1, -3, 0, 0, 0; 0, 1, -
-5, 0, -4, -3, 0, -2, 0; 0, 0, 7, 0, 0, 4, 0, 0, 0; 0, 0, 0, 1, -2, 0, 0, -1,
- 0; 0, 0, 0, 0, 7, 0, 0, 4, 0; 0, 0, 0, 0, 0, 1, 0, 0, 1], [0, -4, 0, -15, -
-15, -21, 0, -11, -19; 0, -4, 0, -7, -7, -11, 0, -7, -15; 0, -5, 0, -4, -4, -
-8, -6, -6, -13; 0, -4, -1, -4, -4, -8, 0, -4, -8; 1, -4, 1, -16, -16, -21, 0
-, -12, -22; 0, 7, 0, 7, 7, 13, 0, 7, 14; 0, 0, 0, -2, -3, -3, 0, -2, -3; 0, 
-0, 0, 28, 28, 35, 0, 20, 35; 0, 0, 0, -7, -7, -9, 0, -5, -9], [0, -3, -2, -9
-, -12, -15, -5, -12, -23; 0, -1, -3, -3, -6, -8, 1, -6, -14; 0, -3, -3, 0, -
-3, -6, -4, -4, -9; 0, -3, -4, 1, -3, -6, 0, -3, -6; 0, -2, -3, -9, -12, -15,
- 0, -11, -21; 1, 5, 5, 1, 5, 11, 1, 6, 12; 0, 0, 0, -1, -3, -2, 2, -2, -3; 0
-, 0, 0, 21, 21, 23, 0, 19, 36; 0, 0, 0, -5, -4, -5, -1, -4, -8], [0, -4, 19,
- -6, 0, 7, 0, -2, -1; 0, -2, 9, 0, -6, 1, 0, -4, -1; 0, 0, 4, 0, 0, 2, 0, 0,
- 4; 0, -1, 5, 0, 0, 3, -6, -2, 0; 0, -4, 20, 0, 0, 12, 0, -2, 0; 0, 0, -7, 0
-, 0, -5, 0, 0, -7; 1, -2, 5, 0, 0, 3, 0, 0, 0; 0, 7, -35, 0, 0, -21, 0, 2, 0
-; 0, 0, 7, 0, 0, 5, 0, 0, 1], [0, -1, 4, -10, -8, -9, 8, -4, -4; 0, -1, 2, -
-2, -4, -3, 6, -2, -2; 0, -2, 1, 0, 0, -1, 2, 0, 1; 0, -2, 0, 0, -1, -2, 4, 0
-, 2; 0, -1, 5, -8, -8, -7, 10, -4, -4; 0, 3, -1, 2, 2, 4, -8, 0, -3; 0, 0, 1
-, -1, -2, -1, 2, -1, -1; 1, -2, -9, 16, 17, 13, -10, 10, 12; 0, 1, 2, -4, -4
-, -3, 2, -2, -2], [0, 5, 8, -17, -10, -7, 20, -2, 3; 0, 2, 3, 1, -4, 2, 20, 
-2, 9; 0, 0, 0, 5, 4, 5, 16, 7, 17; 0, -1, -1, 2, 0, 0, 15, 4, 13; 0, 6, 9, -
-9, -9, 0, 30, 1, 10; 0, 0, 0, 0, 0, 0, -28, -7, -21; 0, 1, 2, -1, -3, 0, 4, 
--1, 0; 0, -14, -21, 21, 21, 0, -21, 7, 0; 1, 5, 5, -5, -4, 2, 4, 0, 3]], 0, 
-[9, 3, 3, 0, 0, 9, 0, 6, 9]]
+0, 1, 0, 1, 0, 1, 0, 0]], [[1; 0; 0], Mat(1), 1, Vecsmall([1])]]], [-1/3*x^2
+ - 2/3*x + 14/3, 1/3*x^2 - 1/3*x - 14/3], Mod(-6, y), Vecsmall([0]), [[[2, [
+2]~, 1, 1, 1], [3, [3]~, 1, 1, 1], [7, [7]~, 1, 1, 1]], Vecsmall([1, 2, 0])]
+, 0, [1, 0, 0, 0, 0, 4/7, 0, 4/7, 5/7; 0, 1, 0, 0, 0, 4/7, 0, 2/7, 5/7; 0, 0
+, 1, 0, 0, 5/7, 0, 0, 1/7; 0, 0, 0, 1, 0, 5/7, 0, 1/7, 5/7; 0, 0, 0, 0, 1, 5
+/7, 0, 4/7, 5/7; 0, 0, 0, 0, 0, 1/7, 0, 0, 1/7; 0, 0, 0, 0, 0, 0, 1, 2/7, 5/
+7; 0, 0, 0, 0, 0, 0, 0, 1/7, 5/7; 0, 0, 0, 0, 0, 0, 0, 0, 1/7], [1, 0, 0, 0,
+ 0, -4, 0, -4, 19; 0, 1, 0, 0, 0, -4, 0, -2, 9; 0, 0, 1, 0, 0, -5, 0, 0, 4; 
+0, 0, 0, 1, 0, -5, 0, -1, 5; 0, 0, 0, 0, 1, -5, 0, -4, 20; 0, 0, 0, 0, 0, 7,
+ 0, 0, -7; 0, 0, 0, 0, 0, 0, 1, -2, 5; 0, 0, 0, 0, 0, 0, 0, 7, -35; 0, 0, 0,
+ 0, 0, 0, 0, 0, 7], [[1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0; 
+0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0
+, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0,
+ 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 1, -1, 4, 4, 5, 19, 8, 17; 1, 1, 1
+, 4, 4, 7, 9, 6, 12; 0, 1, 0, 5, 5, 7, 4, 5, 10; 0, 0, 0, 6, 5, 7, 5, 5, 10;
+ 0, 0, 0, 4, 4, 5, 20, 8, 17; 0, 0, 0, -7, -7, -9, -7, -7, -14; 0, 0, 0, 0, 
+0, 0, 5, 1, 2; 0, 0, 0, 0, 0, 0, -35, -9, -21; 0, 0, 0, 0, 0, 0, 7, 2, 5], [
+0, -1, 2, 0, -4, -2, -15, -9, -22; 0, 1, -1, 0, -4, -3, -7, -5, -11; 1, 0, 0
+, 0, -5, -3, -4, -4, -8; 0, 0, 0, 0, -4, -3, -4, -4, -8; 0, 0, 0, 1, -4, -2,
+ -16, -9, -22; 0, 0, 0, 0, 7, 5, 7, 7, 14; 0, 0, 0, 0, 0, 0, -2, -1, -3; 0, 
+0, 0, 0, 0, 0, 28, 12, 35; 0, 0, 0, 0, 0, 0, -7, -3, -9], [0, 0, -4, 0, -4, 
+-3, -6, -4, -5; 0, 0, -4, 0, -2, -3, 0, -2, -5; 0, 0, -5, 0, 0, -3, 0, 0, -1
+; 1, 0, -5, 0, -1, -3, 0, 0, 0; 0, 1, -5, 0, -4, -3, 0, -2, 0; 0, 0, 7, 0, 0
+, 4, 0, 0, 0; 0, 0, 0, 1, -2, 0, 0, -1, 0; 0, 0, 0, 0, 7, 0, 0, 4, 0; 0, 0, 
+0, 0, 0, 1, 0, 0, 1], [0, -4, 0, -15, -15, -21, 0, -11, -19; 0, -4, 0, -7, -
+7, -11, 0, -7, -15; 0, -5, 0, -4, -4, -8, -6, -6, -13; 0, -4, -1, -4, -4, -8
+, 0, -4, -8; 1, -4, 1, -16, -16, -21, 0, -12, -22; 0, 7, 0, 7, 7, 13, 0, 7, 
+14; 0, 0, 0, -2, -3, -3, 0, -2, -3; 0, 0, 0, 28, 28, 35, 0, 20, 35; 0, 0, 0,
+ -7, -7, -9, 0, -5, -9], [0, -3, -2, -9, -12, -15, -5, -12, -23; 0, -1, -3, 
+-3, -6, -8, 1, -6, -14; 0, -3, -3, 0, -3, -6, -4, -4, -9; 0, -3, -4, 1, -3, 
+-6, 0, -3, -6; 0, -2, -3, -9, -12, -15, 0, -11, -21; 1, 5, 5, 1, 5, 11, 1, 6
+, 12; 0, 0, 0, -1, -3, -2, 2, -2, -3; 0, 0, 0, 21, 21, 23, 0, 19, 36; 0, 0, 
+0, -5, -4, -5, -1, -4, -8], [0, -4, 19, -6, 0, 7, 0, -2, -1; 0, -2, 9, 0, -6
+, 1, 0, -4, -1; 0, 0, 4, 0, 0, 2, 0, 0, 4; 0, -1, 5, 0, 0, 3, -6, -2, 0; 0, 
+-4, 20, 0, 0, 12, 0, -2, 0; 0, 0, -7, 0, 0, -5, 0, 0, -7; 1, -2, 5, 0, 0, 3,
+ 0, 0, 0; 0, 7, -35, 0, 0, -21, 0, 2, 0; 0, 0, 7, 0, 0, 5, 0, 0, 1], [0, -1,
+ 4, -10, -8, -9, 8, -4, -4; 0, -1, 2, -2, -4, -3, 6, -2, -2; 0, -2, 1, 0, 0,
+ -1, 2, 0, 1; 0, -2, 0, 0, -1, -2, 4, 0, 2; 0, -1, 5, -8, -8, -7, 10, -4, -4
+; 0, 3, -1, 2, 2, 4, -8, 0, -3; 0, 0, 1, -1, -2, -1, 2, -1, -1; 1, -2, -9, 1
+6, 17, 13, -10, 10, 12; 0, 1, 2, -4, -4, -3, 2, -2, -2], [0, 5, 8, -17, -10,
+ -7, 20, -2, 3; 0, 2, 3, 1, -4, 2, 20, 2, 9; 0, 0, 0, 5, 4, 5, 16, 7, 17; 0,
+ -1, -1, 2, 0, 0, 15, 4, 13; 0, 6, 9, -9, -9, 0, 30, 1, 10; 0, 0, 0, 0, 0, 0
+, -28, -7, -21; 0, 1, 2, -1, -3, 0, 4, -1, 0; 0, -14, -21, 21, 21, 0, -21, 7
+, 0; 1, 5, 5, -5, -4, 2, 4, 0, 3]], 0, [9, 3, 3, 0, 0, 9, 0, 6, 9]]
 norm(u): 1
 norm(t): 1
 trace(u): 1
@@ -1305,1175 +1306,135 @@ al2 contains nfabs: 1
 , 0, 0]], [x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191, -1406/29213
 3*x^5 + 4870/292133*x^4 - 7674/292133*x^3 - 64939/292133*x^2 - 119188/292133
 *x + 52103/292133, 0, y^3 - y + 1, x^2 + (-2*y^2 + 2*y)*x + (6*y^2 - 5*y + 5
-)], [0]], [[1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1], [0, 0, 1, 0; 1,
- 0, 0, 1; 0, 0, 0, 0; 0, 0, -1, 0], [0, 0, 0, 0; 0, 0, 0, 0; 1, 0, 0, 0; 0, 
-1, 0, 0], [0, 0, 0, 0; 0, 0, 0, 0; 0, 0, 1, 0; 1, 0, 0, 1]], [[0, 1, -1, -1,
- -2, 2, 0, 0, -2, 2, 0, 0]~, [1, 0; 0, 0; 0, 0; 0, 0; 0, 0; 0, 0; 0, 1; 0, 0
-; 0, 0; 0, 0; 0, 0; 0, 0], [Mod(1, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 +
- 36*x + 191), Mod(-1964/292133*x^5 + 4725/292133*x^4 - 14044/292133*x^3 - 95
-698/292133*x^2 - 164828/292133*x - 456632/292133, x^6 - 4*x^5 + 15*x^4 + 14*
-x^3 + 120*x^2 + 36*x + 191), Mod(-1406/292133*x^5 + 4870/292133*x^4 - 7674/2
-92133*x^3 - 64939/292133*x^2 - 119188/292133*x + 52103/292133, x^6 - 4*x^5 +
- 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-516/6719059*x^5 + 59549/67190
-59*x^4 - 144104/6719059*x^3 + 56369/6719059*x^2 + 2656099/6719059*x + 556383
-1/6719059, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-54291
-/6719059*x^5 + 210489/6719059*x^4 - 786258/6719059*x^3 - 905381/6719059*x^2 
-- 6840464/6719059*x - 4510816/6719059, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x
-^2 + 36*x + 191), Mod(-48132/6719059*x^5 + 241931/6719059*x^4 - 785055/67190
-59*x^3 - 523468/6719059*x^2 - 1628025/6719059*x + 4121552/6719059, x^6 - 4*x
-^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(0, x^6 - 4*x^5 + 15*x^4 + 
-14*x^3 + 120*x^2 + 36*x + 191), Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x
-^2 + 36*x + 191), Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 19
-1), Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(0, x^6
- - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(0, x^6 - 4*x^5 + 15*
-x^4 + 14*x^3 + 120*x^2 + 36*x + 191); Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 +
- 120*x^2 + 36*x + 191), Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*
-x + 191), Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(
--499864/154538357*x^5 - 232506/154538357*x^4 + 2075504/154538357*x^3 - 39252
-216/154538357*x^2 - 107292314/154538357*x - 129681996/154538357, x^6 - 4*x^5
- + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(1153778/154538357*x^5 - 4109
-402/154538357*x^4 + 13244560/154538357*x^3 + 24564582/154538357*x^2 + 151883
-496/154538357*x - 10149974/154538357, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^
-2 + 36*x + 191), Mod(171940/154538357*x^5 - 3019052/154538357*x^4 + 13537158
-/154538357*x^3 - 30710744/154538357*x^2 - 25903390/154538357*x - 175396598/1
-54538357, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(1, x^6 
-- 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-1964/292133*x^5 + 47
-25/292133*x^4 - 14044/292133*x^3 - 95698/292133*x^2 - 164828/292133*x - 4566
-32/292133, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-1406/
-292133*x^5 + 4870/292133*x^4 - 7674/292133*x^3 - 64939/292133*x^2 - 119188/2
-92133*x + 52103/292133, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191
-), Mod(-516/6719059*x^5 + 59549/6719059*x^4 - 144104/6719059*x^3 + 56369/671
-9059*x^2 + 2656099/6719059*x + 5563831/6719059, x^6 - 4*x^5 + 15*x^4 + 14*x^
-3 + 120*x^2 + 36*x + 191), Mod(-54291/6719059*x^5 + 210489/6719059*x^4 - 786
-258/6719059*x^3 - 905381/6719059*x^2 - 6840464/6719059*x - 4510816/6719059, 
-x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-48132/6719059*x^
-5 + 241931/6719059*x^4 - 785055/6719059*x^3 - 523468/6719059*x^2 - 1628025/6
-719059*x + 4121552/6719059, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x +
- 191)]], 0, 0, 0, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [[1, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 
-0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -
-1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 1, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, -1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, -1, 0], [0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 1, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
- 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
- [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 1, 
-0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1; 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0], [0, 0, 0, 0, 0, 0,
+)], [0, [[1, 0, 0; 0, 1, 0; 0, 0, 1; 0, 0, 0; 0, 0, 0; 0, 0, 0], [1, 0, 0; 0
+, 1, 0; 0, 0, 1], 1, Vecsmall([1, 2, 3])]]], [[1, 0, 0, 0; 0, 1, 0, 0; 0, 0,
+ 1, 0; 0, 0, 0, 1], [0, 0, 1, 0; 1, 0, 0, 1; 0, 0, 0, 0; 0, 0, -1, 0], [0, 0
+, 0, 0; 0, 0, 0, 0; 1, 0, 0, 0; 0, 1, 0, 0], [0, 0, 0, 0; 0, 0, 0, 0; 0, 0, 
+1, 0; 1, 0, 0, 1]], [[0, 1, -1, -1, -2, 2, 0, 0, -2, 2, 0, 0]~, [1, 0; 0, 0;
+ 0, 0; 0, 0; 0, 0; 0, 0; 0, 1; 0, 0; 0, 0; 0, 0; 0, 0; 0, 0], [Mod(1, x^6 - 
+4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-1964/292133*x^5 + 4725
+/292133*x^4 - 14044/292133*x^3 - 95698/292133*x^2 - 164828/292133*x - 456632
+/292133, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-1406/29
+2133*x^5 + 4870/292133*x^4 - 7674/292133*x^3 - 64939/292133*x^2 - 119188/292
+133*x + 52103/292133, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191),
+ Mod(-516/6719059*x^5 + 59549/6719059*x^4 - 144104/6719059*x^3 + 56369/67190
+59*x^2 + 2656099/6719059*x + 5563831/6719059, x^6 - 4*x^5 + 15*x^4 + 14*x^3 
++ 120*x^2 + 36*x + 191), Mod(-54291/6719059*x^5 + 210489/6719059*x^4 - 78625
+8/6719059*x^3 - 905381/6719059*x^2 - 6840464/6719059*x - 4510816/6719059, x^
+6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-48132/6719059*x^5 
++ 241931/6719059*x^4 - 785055/6719059*x^3 - 523468/6719059*x^2 - 1628025/671
+9059*x + 4121552/6719059, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 1
+91), Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(0, x^
+6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(0, x^6 - 4*x^5 + 15
+*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 
++ 120*x^2 + 36*x + 191), Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36
+*x + 191), Mod(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191); Mod
+(0, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(0, x^6 - 4*x^
+5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(0, x^6 - 4*x^5 + 15*x^4 + 1
+4*x^3 + 120*x^2 + 36*x + 191), Mod(-499864/154538357*x^5 - 232506/154538357*
+x^4 + 2075504/154538357*x^3 - 39252216/154538357*x^2 - 107292314/154538357*x
+ - 129681996/154538357, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191
+), Mod(1153778/154538357*x^5 - 4109402/154538357*x^4 + 13244560/154538357*x^
+3 + 24564582/154538357*x^2 + 151883496/154538357*x - 10149974/154538357, x^6
+ - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(171940/154538357*x^5
+ - 3019052/154538357*x^4 + 13537158/154538357*x^3 - 30710744/154538357*x^2 -
+ 25903390/154538357*x - 175396598/154538357, x^6 - 4*x^5 + 15*x^4 + 14*x^3 +
+ 120*x^2 + 36*x + 191), Mod(1, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*
+x + 191), Mod(-1964/292133*x^5 + 4725/292133*x^4 - 14044/292133*x^3 - 95698/
+292133*x^2 - 164828/292133*x - 456632/292133, x^6 - 4*x^5 + 15*x^4 + 14*x^3 
++ 120*x^2 + 36*x + 191), Mod(-1406/292133*x^5 + 4870/292133*x^4 - 7674/29213
+3*x^3 - 64939/292133*x^2 - 119188/292133*x + 52103/292133, x^6 - 4*x^5 + 15*
+x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-516/6719059*x^5 + 59549/6719059*x
+^4 - 144104/6719059*x^3 + 56369/6719059*x^2 + 2656099/6719059*x + 5563831/67
+19059, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191), Mod(-54291/671
+9059*x^5 + 210489/6719059*x^4 - 786258/6719059*x^3 - 905381/6719059*x^2 - 68
+40464/6719059*x - 4510816/6719059, x^6 - 4*x^5 + 15*x^4 + 14*x^3 + 120*x^2 +
+ 36*x + 191), Mod(-48132/6719059*x^5 + 241931/6719059*x^4 - 785055/6719059*x
+^3 - 523468/6719059*x^2 - 1628025/6719059*x + 4121552/6719059, x^6 - 4*x^5 +
+ 15*x^4 + 14*x^3 + 120*x^2 + 36*x + 191)]], 0, 0, 0, [1, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
+0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
+; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 
+0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1
+, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 1], [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
+0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0
+, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, -1, 0
+, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, -1,
+ 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
  0, 0, -1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, -1, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1; 1, -1, 0, 0, 0, 0, 0
-, 0, 0, 1, -1, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 1, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, -1, 1, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, -1, 1; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1
-; 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 0, 1, -1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, -1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 1, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 
+, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1; 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 1, -1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0], [0, -1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 0, 0; 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 
+0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 
+0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
+; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1; 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 
 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 1, 0, 0
 , 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, -1,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0
-, 0, 0, -1; 1, -1, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0
-, 0, -1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, -1, 1; 0, 
-0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1; 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]], 0, [1
-2, -4, 0, 0, 0, 0, 0, 0, 0, 6, -2, 0]]
+ 0, 0, 0, 0, 0, 0, 0, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -
+1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
+0, -1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 
+-1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0
+, 0, 0, 0, -1; 1, -1, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0; 0, -1, 0, 0, 0, 0, 0, 0
+, 0, 0, -1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0; 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0], [0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
+0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, -1, 1;
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1; 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0; 0, 0, 0, 0
+, 0, 0, 0, 0, -1, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0], [0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
+0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0
+, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 
+0, 0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
+ -1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 1, 0, 0, 0,
+ 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
+0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0
+, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 1, 0, 0, 
+0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
+0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
+, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1
+, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 
+0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1; 1, -1, 0, 0, 0, 0, 0, 0, 0, 1
+, -1, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 
+0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0; 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, -1,
+ 1, 0, 0, 0, 0, 0, 0, 0, -1, 1; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1; 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0]], 0, [12, -4, 0, 0, 0, 0, 0, 0, 0, 6, -2, 0]]
 csa al3
 al3 contains nfabs: 1
-[[x^3 + (3*y^2 - 4)*x^2 + (-5*y^2 - 2*y + 4)*x + (2*y^2 + 3*y - 1), [[175, 8
-8*x^8 - 401*x^7 + 384*x^6 + 1285*x^5 - 2326*x^4 + 1534*x^3 - 1207*x^2 - 275*
-x + 1004, -161*x^8 + 762*x^7 - 793*x^6 - 2355*x^5 + 4657*x^4 - 2938*x^3 + 24
-39*x^2 + 80*x - 2218], 1/175], [[351425, 326042, 160047; 0, 1, 0; 0, 0, 1], 
-[44, -37, -41]~], 1, [], [], [[1, x, x^2], [1, 1, 1]], [1, 0, 0; 0, 1, 0; 0,
- 0, 1], 1, [y^3 - y + 1, [1, 1], -23, 1, [[1, 0.7548776662466927600495088963
-5852869189, -1.3247179572447460259609088544780973407; 1, -0.8774388331233463
-8002475444817926434595 + 0.74486176661974423659317042860439236724*I, 0.66235
-897862237301298045442723904867037 + 0.56227951206230124389918214490937306150
-*I], [1, 0.75487766624669276004950889635852869189, -1.3247179572447460259609
-088544780973407; 1, -0.13257706650360214343158401957487197871, 1.22463849068
-46742568796365721484217319; 1, -1.6223005997430906166179248767836567132, 0.1
-0007946656007176908127228232967560887], [1, 1, -1; 1, 0, 1; 1, -2, 0], [3, -
-1, 0; -1, 1, -3; 0, -3, 2], [23, 16, 10; 0, 1, 0; 0, 0, 1], [7, -2, -3; -2, 
--6, -9; -3, -9, -2], [23, [-10, -1, 8; -7, -3, 1; 1, 7, -10]], [23]], [-1.32
-47179572447460259609088544780973407, 0.6623589786223730129804544272390486703
-7 + 0.56227951206230124389918214490937306150*I], [1, y^2 - 1, y], [1, 0, 1; 
-0, 0, 1; 0, 1, 0], [1, 0, 0, 0, 0, -1, 0, -1, 1; 0, 1, 0, 1, -1, 0, 0, 0, 1;
- 0, 0, 1, 0, -1, 0, 1, 0, 0]], [x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x
-^4 - 41*x^3 + 21*x^2 + 13*x - 17, -23/25*x^8 + 762/175*x^7 - 793/175*x^6 - 4
-71/35*x^5 + 4657/175*x^4 - 2938/175*x^3 + 2439/175*x^2 + 16/35*x - 2218/175,
- 0, y^3 - y + 1, x^3 + (3*y^2 - 4)*x^2 + (-5*y^2 - 2*y + 4)*x + (2*y^2 + 3*y
- - 1)], [0]], [[1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1,
- 0; 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 1, 0, 0, 0, 0, 0; 1, 0, 0, 0, 1, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, -1
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, -1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 1, 0; 1, 0, 0, 0, 0, 0, 0, 0, 1; 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, -1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, -1, 0, 0], [0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0; 1, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 1, 0; 1, 0, 0, 0, 0, 0, 0, 0, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 1, 0, 0, 0, 0, 0; 1, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0
-], [0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0; 1, 0, 0,
- 0, 0, 0, 0, 0, 1]], [[0, -1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0
-, 0, 0, 1, 0, 1, 0, 0, 0, 0]~, [1, 0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0;
- 0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 1, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 
-0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 1; 0, 0, 0; 0, 0, 0; 0, 0, 0
-; 0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0; 0, 0, 0], [Mod(1, x^9 - 6*x^8 + 11*x^7
- + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(88/175*x^8 - 
-401/175*x^7 + 384/175*x^6 + 257/35*x^5 - 2326/175*x^4 + 1534/175*x^3 - 1207/
-175*x^2 - 11/7*x + 1004/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 
-- 41*x^3 + 21*x^2 + 13*x - 17), Mod(-23/25*x^8 + 762/175*x^7 - 793/175*x^6 -
- 471/35*x^5 + 4657/175*x^4 - 2938/175*x^3 + 2439/175*x^2 + 16/35*x - 2218/17
-5, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x -
- 17), Mod(-239/175*x^8 + 1128/175*x^7 - 1187/175*x^6 - 681/35*x^5 + 6793/175
-*x^4 - 4672/175*x^3 + 4096/175*x^2 - 38/35*x - 3027/175, x^9 - 6*x^8 + 11*x^
-7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-14/25*x^8 +
- 481/175*x^7 - 564/175*x^6 - 54/7*x^5 + 3091/175*x^4 - 2264/175*x^3 + 1812/1
-75*x^2 - 52/35*x - 1384/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 
-- 41*x^3 + 21*x^2 + 13*x - 17), Mod(173/175*x^8 - 816/175*x^7 + 869/175*x^6 
-+ 488/35*x^5 - 4931/175*x^4 + 3499/175*x^3 - 2927/175*x^2 + 48/35*x + 297/25
-, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 
-17), Mod(-8/7*x^8 + 27/5*x^7 - 198/35*x^6 - 576/35*x^5 + 229/7*x^4 - 761/35*
-x^3 + 671/35*x^2 - 11/35*x - 542/35, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 +
- 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-4/175*x^8 + 33/175*x^7 - 11/25*
-x^6 - 6/35*x^5 + 353/175*x^4 - 51/25*x^3 + 106/175*x^2 - 2/5*x - 202/175, x^
-9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17),
- Mod(88/175*x^8 - 401/175*x^7 + 384/175*x^6 + 257/35*x^5 - 2326/175*x^4 + 15
-34/175*x^3 - 1207/175*x^2 - 4/7*x + 1004/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 -
- 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7
- + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^
-8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, 
-x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17
-), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 +
- 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 
-+ 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4
- - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^
-5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x
-^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11
-*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 
-6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod
-(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x 
-- 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x
-^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*
-x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56
-*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 4
-7*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 +
- 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 
-+ 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^
-9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17);
- Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 1
-3*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 
-21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 -
- 41*x^3 + 21*x^2 + 13*x - 17), Mod(-346/175*x^8 + 1627/175*x^7 - 1678/175*x^
-6 - 1007/35*x^5 + 9837/175*x^4 - 6428/175*x^3 + 5309/175*x^2 + 33/35*x - 481
-8/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13
-*x - 17), Mod(-349/175*x^8 + 1628/175*x^7 - 236/25*x^6 - 202/7*x^5 + 9738/17
-5*x^4 - 921/25*x^3 + 5381/175*x^2 + 9/5*x - 4622/175, x^9 - 6*x^8 + 11*x^7 +
- 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(596/175*x^8 - 4
-01/25*x^7 + 2918/175*x^6 + 1726/35*x^5 - 17057/175*x^4 + 11208/175*x^3 - 927
-9/175*x^2 - 11/7*x + 8178/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^
-4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-26/25*x^8 + 849/175*x^7 - 871/175*x^6
- - 521/35*x^5 + 5064/175*x^4 - 3441/175*x^3 + 2913/175*x^2 - 18/35*x - 2361/
-175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x
- - 17), Mod(-279/175*x^8 + 1313/175*x^7 - 196/25*x^6 - 160/7*x^5 + 7918/175*
-x^4 - 771/25*x^3 + 4576/175*x^2 + 2/5*x - 3607/175, x^9 - 6*x^8 + 11*x^7 + 8
-*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(404/175*x^8 - 192
-3/175*x^7 + 2057/175*x^6 + 1158/35*x^5 - 11803/175*x^4 + 7967/175*x^3 - 6641
-/175*x^2 + 36/35*x + 5447/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^
-4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(1, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x
-^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(88/175*x^8 - 401/175*x^7 + 3
-84/175*x^6 + 257/35*x^5 - 2326/175*x^4 + 1534/175*x^3 - 1207/175*x^2 - 11/7*
-x + 1004/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x
-^2 + 13*x - 17), Mod(-23/25*x^8 + 762/175*x^7 - 793/175*x^6 - 471/35*x^5 + 4
-657/175*x^4 - 2938/175*x^3 + 2439/175*x^2 + 16/35*x - 2218/175, x^9 - 6*x^8 
-+ 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-239/
-175*x^8 + 1128/175*x^7 - 1187/175*x^6 - 681/35*x^5 + 6793/175*x^4 - 4672/175
-*x^3 + 4096/175*x^2 - 38/35*x - 3027/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*
-x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-14/25*x^8 + 481/175*x^7 - 
-564/175*x^6 - 54/7*x^5 + 3091/175*x^4 - 2264/175*x^3 + 1812/175*x^2 - 52/35*
-x - 1384/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x
-^2 + 13*x - 17), Mod(173/175*x^8 - 816/175*x^7 + 869/175*x^6 + 488/35*x^5 - 
-4931/175*x^4 + 3499/175*x^3 - 2927/175*x^2 + 48/35*x + 297/25, x^9 - 6*x^8 +
- 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-8/7*x
-^8 + 27/5*x^7 - 198/35*x^6 - 576/35*x^5 + 229/7*x^4 - 761/35*x^3 + 671/35*x^
-2 - 11/35*x - 542/35, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^
-3 + 21*x^2 + 13*x - 17), Mod(-4/175*x^8 + 33/175*x^7 - 11/25*x^6 - 6/35*x^5 
-+ 353/175*x^4 - 51/25*x^3 + 106/175*x^2 - 2/5*x - 202/175, x^9 - 6*x^8 + 11*
-x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(88/175*x^8
- - 401/175*x^7 + 384/175*x^6 + 257/35*x^5 - 2326/175*x^4 + 1534/175*x^3 - 12
-07/175*x^2 - 4/7*x + 1004/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^
-4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x
-^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*
-x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 1
-1*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 -
- 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mo
-d(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x
- - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*
-x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41
-*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 5
-6*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 
-47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17); Mod(0, x^9 - 6*x^8 + 11*x^7 
-+ 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8
- + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x
-^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17)
-, Mod(-26/25*x^8 + 849/175*x^7 - 871/175*x^6 - 521/35*x^5 + 5064/175*x^4 - 3
-441/175*x^3 + 2913/175*x^2 - 18/35*x - 2361/175, x^9 - 6*x^8 + 11*x^7 + 8*x^
-6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-279/175*x^8 + 1313/
-175*x^7 - 196/25*x^6 - 160/7*x^5 + 7918/175*x^4 - 771/25*x^3 + 4576/175*x^2 
-+ 2/5*x - 3607/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 
-+ 21*x^2 + 13*x - 17), Mod(404/175*x^8 - 1923/175*x^7 + 2057/175*x^6 + 1158/
-35*x^5 - 11803/175*x^4 + 7967/175*x^3 - 6641/175*x^2 + 36/35*x + 5447/175, x
-^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17)
-, Mod(-3/7*x^8 + 67/35*x^7 - 61/35*x^6 - 218/35*x^5 + 368/35*x^4 - 247/35*x^
-3 + 223/35*x^2 + 4/35*x - 174/35, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56
-*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-36/25*x^8 + 1194/175*x^7 - 1266/17
-5*x^6 - 144/7*x^5 + 7279/175*x^4 - 4971/175*x^3 + 4188/175*x^2 + 13/35*x - 3
-336/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 
-13*x - 17), Mod(37/25*x^8 - 1243/175*x^7 + 1357/175*x^6 + 741/35*x^5 - 7748/
-175*x^4 + 5202/175*x^3 - 4251/175*x^2 + 36/35*x + 3602/175, x^9 - 6*x^8 + 11
-*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 
-6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod
-(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x 
-- 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x
-^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*
-x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56
-*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 4
-7*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 + 11*x^7 +
- 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^9 - 6*x^8 
-+ 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(0, x^
-9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17),
- Mod(1, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 1
-3*x - 17), Mod(88/175*x^8 - 401/175*x^7 + 384/175*x^6 + 257/35*x^5 - 2326/17
-5*x^4 + 1534/175*x^3 - 1207/175*x^2 - 11/7*x + 1004/175, x^9 - 6*x^8 + 11*x^
-7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-23/25*x^8 +
- 762/175*x^7 - 793/175*x^6 - 471/35*x^5 + 4657/175*x^4 - 2938/175*x^3 + 2439
-/175*x^2 + 16/35*x - 2218/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^
-4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-239/175*x^8 + 1128/175*x^7 - 1187/175
-*x^6 - 681/35*x^5 + 6793/175*x^4 - 4672/175*x^3 + 4096/175*x^2 - 38/35*x - 3
-027/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 
-13*x - 17), Mod(-14/25*x^8 + 481/175*x^7 - 564/175*x^6 - 54/7*x^5 + 3091/175
-*x^4 - 2264/175*x^3 + 1812/175*x^2 - 52/35*x - 1384/175, x^9 - 6*x^8 + 11*x^
-7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(173/175*x^8 
-- 816/175*x^7 + 869/175*x^6 + 488/35*x^5 - 4931/175*x^4 + 3499/175*x^3 - 292
-7/175*x^2 + 48/35*x + 297/25, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4
- - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-8/7*x^8 + 27/5*x^7 - 198/35*x^6 - 576/
-35*x^5 + 229/7*x^4 - 761/35*x^3 + 671/35*x^2 - 11/35*x - 542/35, x^9 - 6*x^8
- + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17), Mod(-4/1
-75*x^8 + 33/175*x^7 - 11/25*x^6 - 6/35*x^5 + 353/175*x^4 - 51/25*x^3 + 106/1
-75*x^2 - 2/5*x - 202/175, x^9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 4
-1*x^3 + 21*x^2 + 13*x - 17), Mod(88/175*x^8 - 401/175*x^7 + 384/175*x^6 + 25
-7/35*x^5 - 2326/175*x^4 + 1534/175*x^3 - 1207/175*x^2 - 4/7*x + 1004/175, x^
-9 - 6*x^8 + 11*x^7 + 8*x^6 - 47*x^5 + 56*x^4 - 41*x^3 + 21*x^2 + 13*x - 17)]
-], 0, 0, 0, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
-0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [[1, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, -1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 1, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0], [0, -1, 1, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
-0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -1, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0
-, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
-, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 
-0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, -1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0; 0, 0, -1, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1; 1, -1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0;
- 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- -1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -1, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1; 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1; 1, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1
-, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, -1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0,
- 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 
-0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0
-, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
--1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-1, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, -1, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -1; 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-1, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, -1, 1; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 1; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
-, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, -1, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, -1, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 
--1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -
-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 1, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0
-, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 1, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0; 0, 1, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0; 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, -1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 1, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0; 0, 0, -1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1; 1, -1, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0; 0, -1, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0],
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
- 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 1, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0; 0, -1, 1, 0, 0, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1; 0, 0, 1, 0, 0, 0, 0, 
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1; 1, 0, 0, 0, 0, 0
-, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]], 0, [27, -
-9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, -3,
- 0]]
 trivial algebra over a quadratic field
 [[x, [[1, -x], 1], [[1, 0; 0, 1], 1], 1, [], [], [[1], [1]], Mat(1), 1, [y^2
  + 1, [0, 1], -4, 1, [Mat([1, 0.E-57 + 1.00000000000000000000000000000000000
@@ -2486,8 +1447,9 @@ trivial algebra over a quadratic field
  1.0000000000000000000000000000000000000], [1, -1; 1, 1], [2, 0; 0, -2], [2,
  0; 0, 2], [1, 0; 0, -1], [1, [0, -1; 1, 0]], []], [0.E-77 + 1.0000000000000
 000000000000000000000000*I], [1, -x], [1, 0; 0, -1], [1, 0, 0, -1; 0, 1, 1, 
-0]]]], [Mod(y, y^2 + 1)], Mod(1, y^2 + 1), Vecsmall([]), [[], Vecsmall([])],
- 0, [1, 0; 0, 1], [1, 0; 0, 1], [[1, 0; 0, 1], [0, -1; 1, 0]], 0, [2, 0]]
+0]], [[1, 0; 0, 1], [1, 0; 0, 1], 1, Vecsmall([1, 2])]]], [Mod(y, y^2 + 1)],
+ Mod(1, y^2 + 1), Vecsmall([]), [[], Vecsmall([])], 0, [1, 0; 0, 1], [1, 0; 
+0, 1], [[1, 0; 0, 1], [0, -1; 1, 0]], 0, [2, 0]]
 [y]~
 [-2*y + 1]~
 [3, 1]~
@@ -2518,9 +1480,9 @@ trivial algebra over Q
 [[x, [[1], 1], [Mat(1), 1], 1, [], [], [[1], [1]], Mat(1), 1, [y, [1, 0], 1,
  1, [Mat(1), Mat(1), Mat(1), Mat(1), 1, Mat(1), [1, 0], []], [0.E-57], [1], 
 Mat(1), Mat(1)], [x, 0, -1, y, x], [[x, [1, 0], 1, 1, [Mat(1), Mat(1), Mat(1
-), Mat(1), 1, Mat(1), [1, 0], []], [0.E-77], [1], Mat(1), Mat(1)]]], [0], Mo
-d(1, y), Vecsmall([0]), [[], Vecsmall([])], 0, Mat(1), Mat(1), [Mat(1)], 0, 
-[1]]
+), Mat(1), 1, Mat(1), [1, 0], []], [0.E-77], [1], Mat(1), Mat(1)], [Mat(1), 
+Mat(1), 1, Vecsmall([1])]]], [0], Mod(1, y), Vecsmall([0]), [[], Vecsmall([]
+)], 0, Mat(1), Mat(1), [Mat(1)], 0, [1]]
 [-2]~
 [1/3]~
 [-3]~
@@ -3392,4 +2354,4 @@ alggroup
 1
 1
 1
-Total time spent: 6771
+Total time spent: 8312
diff --git a/src/test/32/bnr b/src/test/32/bnr
index 89883d5..1004e46 100644
--- a/src/test/32/bnr
+++ b/src/test/32/bnr
@@ -57,4 +57,9 @@
 1
 [4, [2, 2], [[3, 1; 0, 1], [114, 1; 0, 1]]]
 [[1, 0, 0; 0, 1, 0; 0, 0, 1], [0]]
-Total time spent: 30
+[2, 2, 5]
+[1, 2, [1, 0; 0, 1]]
+0
+0
+[2, 2, 5]
+Total time spent: 32
diff --git a/src/test/32/charpoly b/src/test/32/charpoly
index b298187..58fb9ea 100644
--- a/src/test/32/charpoly
+++ b/src/test/32/charpoly
@@ -64,6 +64,7 @@ Mod(1, 18446744073709551629)*x^4 + Mod(18446744073709551600, 184467440737095
   *** charpoly: incorrect priority in charpoly: variable x = x
 x^4 - 4*x^3 + 6*x^2 - 4*x + 2
 x^2
+x - 1
 []
 [[], [;]]
 
diff --git a/src/test/32/chinese b/src/test/32/chinese
index 52f64b7..39345c2 100644
--- a/src/test/32/chinese
+++ b/src/test/32/chinese
@@ -6,7 +6,7 @@ Mod(2, 3)*x^2 + Mod(1, 6)*x + Mod(1, 6)
   ***                 ^----------
   *** chinese: incorrect type in association (t_INT).
 Mod(0, 1)
-  ***   at top-level: ...Mod(0,1);m2=Mod(1,x^2+1);chinese(m1,m2)
-  ***                                             ^--------------
-  *** chinese: inconsistent chinese t_INTMOD , t_POLMOD.
-Total time spent: 4
+Mod(x + 1, x^2)
+Mod(x + 1, 2*x^2)
+Mod(x + 1, x^2)
+Total time spent: 0
diff --git a/src/test/32/compat b/src/test/32/compat
index 80ddf12..1c687a4 100644
--- a/src/test/32/compat
+++ b/src/test/32/compat
@@ -1498,11 +1498,11 @@ A function with that name existed in GP-1.39.15. Please update your script.
 
 New syntax: ideallistarchgen(nf,list,arch) ===> ideallistarch(nf,list,arch)
 
-ideallistarch(nf,list,arch): list is a vector of vectors of of bid's as output 
-by ideallist. Return a vector of vectors with the same number of components as 
-the original list. The leaves give information about moduli whose finite part 
-is as in original list, in the same order, and Archimedean part is now arch. 
-The information contained is of the same kind as was present in the input.
+ideallistarch(nf,list,arch): list is a vector of vectors of bid's as output by 
+ideallist. Return a vector of vectors with the same number of components as the 
+original list. The leaves give information about moduli whose finite part is as 
+in original list, in the same order, and Archimedean part is now arch. The 
+information contained is of the same kind as was present in the input.
 
 
   ***   at top-level: ideallistunit()
@@ -1525,11 +1525,11 @@ A function with that name existed in GP-1.39.15. Please update your script.
 
 New syntax: ideallistunitarch ===> ideallistarch(nf,list,arch)
 
-ideallistarch(nf,list,arch): list is a vector of vectors of of bid's as output 
-by ideallist. Return a vector of vectors with the same number of components as 
-the original list. The leaves give information about moduli whose finite part 
-is as in original list, in the same order, and Archimedean part is now arch. 
-The information contained is of the same kind as was present in the input.
+ideallistarch(nf,list,arch): list is a vector of vectors of bid's as output by 
+ideallist. Return a vector of vectors with the same number of components as the 
+original list. The leaves give information about moduli whose finite part is as 
+in original list, in the same order, and Archimedean part is now arch. The 
+information contained is of the same kind as was present in the input.
 
 
   ***   at top-level: ideallistunitarchgen
@@ -1539,11 +1539,11 @@ A function with that name existed in GP-1.39.15. Please update your script.
 
 New syntax: ideallistunitarchgen ===> ideallistarch(nf,list,arch)
 
-ideallistarch(nf,list,arch): list is a vector of vectors of of bid's as output 
-by ideallist. Return a vector of vectors with the same number of components as 
-the original list. The leaves give information about moduli whose finite part 
-is as in original list, in the same order, and Archimedean part is now arch. 
-The information contained is of the same kind as was present in the input.
+ideallistarch(nf,list,arch): list is a vector of vectors of bid's as output by 
+ideallist. Return a vector of vectors with the same number of components as the 
+original list. The leaves give information about moduli whose finite part is as 
+in original list, in the same order, and Archimedean part is now arch. The 
+information contained is of the same kind as was present in the input.
 
 
   ***   at top-level: ideallistunitgen()
@@ -1729,9 +1729,8 @@ vecsort(x,{cmpf},{flag=0}): sorts the vector of vectors (or matrix) x in
 ascending order, according to the comparison function cmpf, if not omitted. (If 
 cmpf is an integer, sort according to the value of the k-th component of each 
 entry.) Binary digits of flag (if present) mean: 1: indirect sorting, return 
-the permutation instead of the permuted vector, 2: sort using lexicographic 
-order, 4: use descending instead of ascending order, 8: remove duplicate 
-entries.
+the permutation instead of the permuted vector, 4: use descending instead of 
+ascending order, 8: remove duplicate entries.
 
 
   ***   at top-level: initalg()
@@ -2279,9 +2278,8 @@ vecsort(x,{cmpf},{flag=0}): sorts the vector of vectors (or matrix) x in
 ascending order, according to the comparison function cmpf, if not omitted. (If 
 cmpf is an integer, sort according to the value of the k-th component of each 
 entry.) Binary digits of flag (if present) mean: 1: indirect sorting, return 
-the permutation instead of the permuted vector, 2: sort using lexicographic 
-order, 4: use descending instead of ascending order, 8: remove duplicate 
-entries.
+the permutation instead of the permuted vector, 4: use descending instead of 
+ascending order, 8: remove duplicate entries.
 
 
   ***   at top-level: lindep2()
@@ -2720,7 +2718,7 @@ A function with that name existed in GP-1.39.15. Please update your script.
 
 New syntax: nfdiveuc(nf,a,b) ===> nfeltdiveuc(nf,a,b)
 
-nfdiveuc(nf,x,y): gives algebraic integer q such that x-by is small.
+nfdiveuc(nf,x,y): gives algebraic integer q such that x-qy is small.
 
 
   ***   at top-level: nfdivres()
@@ -2730,7 +2728,7 @@ A function with that name existed in GP-1.39.15. Please update your script.
 
 New syntax: nfdivres(nf,a,b) ===> nfeltdivrem(nf,a,b)
 
-nfeltdivrem(nf,x,y): gives [q,r] such that r=x-by is small.
+nfeltdivrem(nf,x,y): gives [q,r] such that r=x-qy is small.
 
 
   ***   at top-level: nfhermite()
@@ -2763,7 +2761,7 @@ A function with that name existed in GP-1.39.15. Please update your script.
 
 New syntax: nfmod(nf,a,b) ===> nfeltmod(nf,a,b)
 
-nfeltmod(nf,x,y): gives r such that r=x-by is small with q algebraic integer.
+nfeltmod(nf,x,y): gives r such that r=x-qy is small with q algebraic integer.
 
 
   ***   at top-level: nfmul()
@@ -3816,9 +3814,8 @@ vecsort(x,{cmpf},{flag=0}): sorts the vector of vectors (or matrix) x in
 ascending order, according to the comparison function cmpf, if not omitted. (If 
 cmpf is an integer, sort according to the value of the k-th component of each 
 entry.) Binary digits of flag (if present) mean: 1: indirect sorting, return 
-the permutation instead of the permuted vector, 2: sort using lexicographic 
-order, 4: use descending instead of ascending order, 8: remove duplicate 
-entries.
+the permutation instead of the permuted vector, 4: use descending instead of 
+ascending order, 8: remove duplicate entries.
 
 
   ***   at top-level: sqred()
@@ -4067,9 +4064,8 @@ vecsort(x,{cmpf},{flag=0}): sorts the vector of vectors (or matrix) x in
 ascending order, according to the comparison function cmpf, if not omitted. (If 
 cmpf is an integer, sort according to the value of the k-th component of each 
 entry.) Binary digits of flag (if present) mean: 1: indirect sorting, return 
-the permutation instead of the permuted vector, 2: sort using lexicographic 
-order, 4: use descending instead of ascending order, 8: remove duplicate 
-entries.
+the permutation instead of the permuted vector, 4: use descending instead of 
+ascending order, 8: remove duplicate entries.
 
 
   ***   at top-level: veclexsort()
@@ -4083,9 +4079,8 @@ vecsort(x,{cmpf},{flag=0}): sorts the vector of vectors (or matrix) x in
 ascending order, according to the comparison function cmpf, if not omitted. (If 
 cmpf is an integer, sort according to the value of the k-th component of each 
 entry.) Binary digits of flag (if present) mean: 1: indirect sorting, return 
-the permutation instead of the permuted vector, 2: sort using lexicographic 
-order, 4: use descending instead of ascending order, 8: remove duplicate 
-entries.
+the permutation instead of the permuted vector, 4: use descending instead of 
+ascending order, 8: remove duplicate entries.
 
 
   ***   at top-level: vvector()
@@ -4575,4 +4570,4 @@ New syntax: texprint(x) ===> printtex(x)
 printtex({str}*): outputs its string arguments in TeX format.
 
 
-Total time spent: 12
+Total time spent: 11
diff --git a/src/test/32/digits b/src/test/32/digits
index 5beaa7a..57d92f3 100644
--- a/src/test/32/digits
+++ b/src/test/32/digits
@@ -34,7 +34,12 @@
   *** binary: incorrect type in binary (t_COMPLEX).
 [16, 21, 21, 21, 19, 27, 43, 45, 45, 39]
 [1, 0, 3]
+[232830, 2764705149]
 4
 74565
+90144042671290236482932261665
+74565
+219
+13221424875890015231
 219
-Total time spent: 64
+Total time spent: 68
diff --git a/src/test/32/div b/src/test/32/div
index cc46869..b2f994e 100644
--- a/src/test/32/div
+++ b/src/test/32/div
@@ -14,7 +14,7 @@
 0.96774193548387096774193548387096774194
 0
 3
-0
+1
 [0, 3]~
 * [1, 4]
 6
@@ -140,7 +140,7 @@ error("forbidden division t_INT \\ t_INTMOD.")
 0.77500000000000000000000000000000000000
 0
 3.1000000000000000000000000000000000000
-0
+1
 [0, 3.1000000000000000000000000000000000000]~
 * [3, 3]
 1.0000000000000000000000000000000000000
@@ -798,7 +798,7 @@ error("forbidden division t_SER \\ t_INT.")
 6774194]
 [0, 0]
 [2, 3]
-[0, 0]
+[1, 1]
 * [2, 4]
 [4, 6]
 [4, 6]
@@ -853,7 +853,7 @@ Mat(1)
 Mat(0.64516129032258064516129032258064516129)
 Mat(0)
 Mat(2)
-Mat(0)
+Mat(1)
 * [3, 4]
 Mat(4)
 Mat(4)
diff --git a/src/test/32/ell b/src/test/32/ell
index f714cc9..ffb885f 100644
--- a/src/test/32/ell
+++ b/src/test/32/ell
@@ -162,23 +162,27 @@ all([1]), [Vecsmall([128, -1])], [0, 0, 0, 0, 0, 0, 0, [[2, 3]~]]]
 [3, [3], [[0, 2]]]
 1
 [4, [4], [[Mod(3, 5), Mod(3, 5)]]]
-[1 + 2*3 + 3^2 + 2*3^3 + 3^4 + 3^5 + 2*3^6 + 3^7 + O(3^8), 1 + 3 + 3^3 + 3^4
- + 2*3^5 + 2*3^6 + 2*3^7 + O(3^8), 3 + 2*3^3 + O(3^6), [1 + 2*3 + 3^2 + 2*3^
-3 + 3^4 + 3^6 + 2*3^7 + O(3^8), 1 + 3 + 2*3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^6 + 
-3^7 + O(3^8)]]
-[3^-1 + 2 + 2*3^2 + 2*3^5 + 2*3^6 + O(3^8)]~
-[3^2 + 2*3^3 + 3^4 + 2*3^5 + 3^6 + 3^7 + 2*3^8 + 3^9 + O(3^10), 3 + 3^2 + 3^
-4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + O(3^9), 3 + 2*3^3 + O(3^6), [3^-2 + 2*3^-1
- + 1 + 2*3 + 3^2 + 3^4 + 2*3^5 + O(3^6), 3^-2 + 3^-1 + 2 + 3 + 2*3^2 + 2*3^3
- + 3^4 + 3^5 + O(3^6)]]
+[1 + 2*3 + 3^2 + 2*3^3 + 3^4 + 3^5 + 2*3^6 + 3^7 + 3^8 + 3^9 + O(3^10), 1 + 
+3 + 3^3 + 3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^9 + O(3^10), 3 + 2*3^3 + 2*3^7 +
+ O(3^8), [1 + 2*3 + 3^2 + 2*3^3 + 3^4 + 3^6 + 2*3^8 + O(3^10), 1 + 3 + 2*3^2
+ + 3^3 + 2*3^4 + 2*3^5 + 3^6 + 3^8 + 2*3^9 + O(3^10)], 2*3^2 + 3^4 + 3^5 + 3
+^6 + O(3^7)]
+[3^-1 + 2 + 2*3^2 + 2*3^5 + 2*3^6 + 2*3^7 + 3^8 + O(3^10)]~
+[3^2 + 2*3^3 + 3^4 + 2*3^5 + 3^6 + 3^7 + 2*3^8 + 3^9 + 3^10 + 3^11 + O(3^12)
+, 3 + 3^2 + 3^4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^10 + O(3^11), 3 + 2*3^3 
++ 2*3^7 + O(3^8), [3^-2 + 2*3^-1 + 1 + 2*3 + 3^2 + 3^4 + 2*3^6 + O(3^8), 3^-
+2 + 3^-1 + 2 + 3 + 2*3^2 + 2*3^3 + 3^4 + 3^6 + 2*3^7 + O(3^8)], 2*3^2 + 3^4 
++ 3^5 + 3^6 + O(3^7)]
 error("incorrect type in obj_check (t_VEC).")
 [2 + 2^6 + 2^10 + O(2^11), Mod(x, x^2 + (2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^7 + 2
 ^8 + 2^9 + O(2^11))), 2^3 + 2^4 + O(2^8), [2^-3 + 2^2 + 2^4 + 2^7 + 2^10 + O
-(2^11), 2^-3 + 2^2 + 2^5 + 2^6 + 2^10 + O(2^13)]]
+(2^11), 2^-3 + 2^2 + 2^5 + 2^6 + 2^10 + O(2^13)], 1]
 x^-2 + 31/15*x^2 + 2501/756*x^4 + 961/675*x^6 + 77531/41580*x^8 + O(x^9)
 [5.0000000000000000000000000000000000000, 4.99999999999999999999999999999999
 99998]
 [0]
+[-1.2137559863387746413172077159498331998, -0.757861263970860955134912630669
+68406624*I]
 [-1, -2*w]
 [-1, 1/2*I]
 [[-1, 1/2*I], [0.59200051084078635056480901325155142952, -6.5791855625999796
@@ -229,7 +233,7 @@ x^-1 - 34.663332023692872920394589364735574123*x^3 + 129.9910084007043654401
 x^-1 - 34.663332023692872920394589364735574123*x^3 + 129.9910084007043654401
 0385343881155485*x^5 - 514.94853727918793173210571636955592878*x^7 + O(x^8)
 2.0876703200272312306836757817491311900
-0
+-0.75852497993155073361697100017220952422*I
 1.8018229730105461594800210664505892466 - 4.22108966565276293974646245627813
 69159*I
 [2, 3]
@@ -240,7 +244,7 @@ x^-1 - 34.663332023692872920394589364735574123*x^3 + 129.9910084007043654401
 x^-1 - 34.663332023692872920394589364735574123*x^3 + 129.9910084007043654401
 0385343881155485*x^5 - 514.94853727918793173210571636955592878*x^7 + O(x^8)
 2.0876703200272312306836757817491311900
-0
+-0.75852497993155073361697100017220952422*I
 1.8018229730105461594800210664505892466 - 4.22108966565276293974646245627813
 69159*I
 [3, 1]
@@ -259,7 +263,7 @@ x - 8.6658330059232182300986473411838935307*x^5 + 21.66516806678406090668397
 x - 8.6658330059232182300986473411838935307*x^5 + 21.66516806678406090668397
 5573135259142*x^7 - 26.820236316624371444380506060914371291*x^9 + O(x^10)
 0.30631122697380979289268115078987850649
-0.E-38
+0.28630802922181366479814671169863862828*I
 0.53021646242894349905972369056429285872 + 0.3781418838145237834855647058271
 9409288*I
 [3, 3]
@@ -270,7 +274,7 @@ x - 8.6658330059232182300986473411838935307*x^5 + 21.66516806678406090668397
 x - 8.6658330059232182300986473411838935307*x^5 + 21.66516806678406090668397
 5573135259142*x^7 - 26.820236316624371444380506060914371291*x^9 + O(x^10)
 0.30631122697380979289268115078987850649
-0.E-38
+0.28630802922181366479814671169863862828*I
 0.53021646242894349905972369056429285872 + 0.3781418838145237834855647058271
 9409288*I
 [4, 1]
@@ -285,14 +289,16 @@ x - 8.6658330059232182300986473411838935307*x^5 + 21.66516806678406090668397
 0
 0
 -1.1831536122930622250712755356827420688
--1.2506870224867757820652851907990498543
+-1.2506870224867757820652851907990498543 + 1.5707963267948966192313216916397
+514421*I
 -0.42886850134944751864186009377385060418 + 0.619519575104929600932212172490
 11490053*I
 [4, 3]
 0
 0
 -1.1831536122930622250712755356827420688
--1.2506870224867757820652851907990498543
+-1.2506870224867757820652851907990498543 + 1.5707963267948966192313216916397
+514421*I
 -0.42886850134944751864186009377385060418 + 0.619519575104929600932212172490
 11490053*I
 [2.5135797437238231405782694715779164652, 1.25678987186191157028913473578895
@@ -324,7 +330,7 @@ x - 8.6658330059232182300986473411838935307*x^5 + 21.66516806678406090668397
 391807553710802962*I]
 3 + 11^2 + 2*11^3 + 3*11^4 + O(11^5)
 Mod((2 + 3 + O(3^4))*x + (2*3 + 3^2 + O(3^4)), x^2 + (1 + 3 + 2*3^4 + 3^8 + 
-2*3^9 + O(3^10)))
+O(3^9)))
 Mod((1 + 3 + 3^3 + 3^4 + 2*3^6 + 2*3^8 + 2*3^9 + O(3^10))*x + (1 + 3 + 3^2 +
  3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 3^9 + O(3^10)), x^2 + (3 + 3^3 + 2*3^4 + 3^5 
 + 2*3^6 + 3^7 + 2*3^8 + 3^9 + 2*3^10 + 3^11 + 2*3^12 + O(3^13)))
@@ -349,30 +355,56 @@ small([1]), [Vecsmall([128, -1])], [0, 0, 0, 0, 0, 0, 0, [[2, 3]~, [1/2, 0,
 
 0
 20 0 0 -16 0 -4 14 8 0 0 0 26 0 2 0 -28 
+11124672632 0 0 0 0 0 9623756642 1757839784 0 10364773916 0 -11268052540 -89
+20565254 10819287710 0 0 0 8122434446 
 1728
 0 0 -22 0 -14 0 -22 0 0 26 0 18 0 -14 2 0 
+0 -11632185758 0 11654847458 0 6266694946 12139026234 0 -765697030 0 -993589
+2958 0 11860023378 -8888351742 0 -12108381446 0 -12120201878 
 -3375
 16 0 -10 0 -22 24 0 -20 0 0 4 0 8 -18 -26 0 
+3823447300 13247194 -10908503128 0 1880681120 0 0 12050551284 10977324518 0 
+0 0 -948699894 0 0 9979357082 11495943932 0 
 8000
 0 -18 6 22 0 0 0 2 0 0 18 0 0 22 0 0 
+-10793410270 0 0 30 0 0 0 2640064994 8901937002 0 0 0 0 8077589434 0 5325840
+630 -5129549082 0 
 54000
 20 0 0 16 0 4 -14 -8 0 0 0 26 0 2 0 -28 
+-11124672632 0 0 0 0 0 -9623756642 1757839784 0 10364773916 0 -11268052540 8
+920565254 -10819287710 0 0 0 8122434446 
 -32768
 0 0 3 0 0 0 23 16 0 0 21 25 -15 0 0 -20 
+7894594559 0 0 9919498893 0 0 -7887871151 0 0 0 0 0 491192422 -8259190543 0 
+0 0 12121352347 
 287496
 0 0 22 0 -14 0 22 0 0 -26 0 -18 0 14 2 0 
+0 -11632185758 0 11654847458 0 -6266694946 -12139026234 0 -765697030 0 99358
+92958 0 11860023378 8888351742 0 -12108381446 0 12120201878 
 -884736
 0 7 23 -9 11 0 18 -24 0 0 0 0 17 0 -22 -25 
+0 -8412576737 0 0 0 0 8538343901 12113814432 -11651750401 12092421657 0 0 0 
+0 0 -11058211849 0 -1330007630 
 -12288000
 20 0 0 -23 0 19 14 25 0 0 0 7 0 23 0 -11 
+-9788647777 0 0 0 0 0 11231998687 11288673199 0 304785419 0 -11268052540 268
+1012851 10819287710 0 0 0 -11884260649 
 16581375
 16 0 10 0 22 24 0 -20 0 0 -4 0 8 -18 -26 0 
+-3823447300 13247194 -10908503128 0 1880681120 0 0 12050551284 10977324518 0
+ 0 0 948699894 0 0 9979357082 11495943932 0 
 -884736000
 11 0 0 -13 0 0 0 0 -25 -2 0 -6 0 -27 -10 0 
+-12128231367 0 -9395300833 -435256334 0 0 0 -11932204400 -10588952138 0 0 0 
+0 0 0 -7319300662 0 0 
 -147197952000
 -21 -16 0 0 -23 1 5 7 20 -25 0 11 0 13 0 -27 
+0 11781526319 1637387588 0 12146798315 0 -8198706882 0 3977562293 8890885111
+ -9549303299 -11553067388 9924967665 3852111021 0 5199002617 772472488 0 
 -262537412640768000
 0 19 0 0 0 -21 0 0 4 -23 8 0 0 0 -25 -12 
+0 0 6564371741 0 0 2618909413 0 2136229176 0 0 0 4357107277 1635802689 30896
+18289 0 -5064045658 0 0 
 4294985035
 [0, 1, [5, 0, 0, 0], 1]
 1
@@ -479,4 +511,4 @@ t + 1/3*t^3 - 1/2*t^4 + 14/15*t^5 + O(t^6)
   *** ellformalw: domain error in ellformalw: precision <= 0
 242.47010035195076100129810400142304776
 0
-Total time spent: 432
+Total time spent: 364
diff --git a/src/test/32/ellanal b/src/test/32/ellanal
index 122db6c..e8cdb19 100644
--- a/src/test/32/ellanal
+++ b/src/test/32/ellanal
@@ -26,6 +26,6 @@
 [4, -56]
 [8, -56]
 [1, -56]
-[2, -57]
-[72, -62]
-Total time spent: 1604
+[2, -56]
+[72, -63]
+Total time spent: 1944
diff --git a/src/test/32/ellpadic b/src/test/32/ellpadic
index 0b1a6e0..841ec0f 100644
--- a/src/test/32/ellpadic
+++ b/src/test/32/ellpadic
@@ -1,4 +1,3 @@
-  ***   Warning: new stack size = 40000000 (38.147 Mbytes).
 [2^-2 + 2^-1 + 1 + 2 + O(2^2), 1 + 2 + 2^2 + 2^3 + O(2^4)]
 [3 + 2*3^2 + 3^4 + O(3^5), 2*3^4 + 3^5 + O(3^8)]
 [3*5 + 5^2 + 2*5^3 + 3*5^4 + O(5^5), 5^2 + 4*5^4 + O(5^6)]
@@ -6,8 +5,6 @@
   ***   at top-level: ellpadicheight(E,19,
   ***                 ^--------------------
   *** ellpadicheight: domain error in ellpadicheight: precision <= 0
-[2^-1 + 2 + 2^2 + O(2^5), 2^-1 + 2^2 + 2^3 + O(2^5)]
-[2^-1 + 1 + 2^2 + 2^4 + O(2^5), 1 + 2^2 + 2^4 + O(2^6)]
 [2*3^2 + 2*3^3 + 3^4 + 3^5 + 3^6 + O(3^7), 2*3^2 + 3^4 + 2*3^5 + 3^6 + O(3^7
 )]
   ***   at top-level: ellpadiclog(E,3,5,P)
@@ -69,12 +66,4 @@ O(5^7)
 
 [2*3 + 3^3 + 3^4 + O(3^5)                       3^4 + O(3^5)]
 
-[2*3^-1 + 1 + 3 + 3^2 + O(3^3), 3^-1 + 1 + 3 + 3^2 + O(3^3)]
-[1 + 2*3 + 2*3^3 + O(3^4), O(3^4)]~
-[1 + O(3^4), O(3^4)]~
-4 + 3*5 + 4*5^2 + 2*5^3 + O(5^4)
-1 + O(5^4)
-[1 + O(3^4), O(3^4)]~
-[1 + O(3^4), O(3^5)]~
-[O(3^3), O(3^3)]
-Total time spent: 2124
+Total time spent: 76
diff --git a/src/test/32/ellweilpairing b/src/test/32/ellweilpairing
index e3da8f9..019aed9 100644
--- a/src/test/32/ellweilpairing
+++ b/src/test/32/ellweilpairing
@@ -26,14 +26,31 @@
 [144, 0, [30, 6]]
 [1, 0, [128]]
 [1, 0, [192]]
-[1, 1, [114]]
-[1, 1, [18, 6]]
+[1, 112, [114]]
+[1, 126, [18, 6]]
 [156, 1, [12, 12]]
 [1, 1, [180]]
 [1, 1, [192]]
 [1, 3, [6]]
+[1, 2, [3, 3]]
 t^5 + t^3 + t^2
 t^5 + t^4 + 1
+t^4 + t^2 + 1
+t^5 + t
+2*t^5 + t^4 + t^3 + t
+t^3 + 2*t^2 + 2
+2*t^5 + 2*t^4 + 2*t^3 + 2*t^2
+2*t^5 + 2*t^2 + 1
+3*t^5 + 3*t^4 + 2*t^3 + t^2 + 2*t + 3
+2*t^4 + t^3 + 3*t
+2*t^5 + t^4 + t^3 + 2*t^2
+3*t^5 + 4*t^4 + 4*t^3 + 3*t^2 + 4
+t
+2*t^4 + 2*t^2 + 2*t + 1
+4*t^3 + t + 1
+[36893488147419103362, 36893488147419103362]
+9688432087730133707
+9688432087730133707
 [0, 0, 0, 2, 0]:[2, 2]
 [0, 0, 1, 2, 2]:[2, 2]
 [0, 0, 2, 2, 2]:[2, 2]
@@ -293,5 +310,4 @@ t^5 + t^4 + 1
 [4, 4, 3, 3, 1]:[2, 2]
 [4, 4, 4, 1, 3]:[2, 2]
 [4, 4, 4, 4, 1]:[4, 2]
-[36893488147419103364, 36893488147419103364]
-Total time spent: 108
+Total time spent: 84
diff --git a/src/test/32/equal b/src/test/32/equal
index aad3204..0bf1f53 100644
--- a/src/test/32/equal
+++ b/src/test/32/equal
@@ -64,4 +64,5 @@
 [0, 0]
 [0, 1]
 1
+1
 Total time spent: 4
diff --git a/src/test/32/err b/src/test/32/err
index a4487c5..0d85e36 100644
--- a/src/test/32/err
+++ b/src/test/32/err
@@ -487,7 +487,7 @@
   *** hilbert: inconsistent moduli in hilbert: 5 != 3
   ***   at top-level: hilbert(Mod(1,3),2,0
   ***                 ^--------------------
-  *** hilbert: inconsistent moduli in hilbert: 3 != oo
+  *** hilbert: inconsistent moduli in hilbert: 3 != "oo"
   ***   at top-level: znorder(0)
   ***                 ^----------
   *** znorder: incorrect type in znorder [t_INTMOD expected] (t_INT).
@@ -556,7 +556,7 @@
   *** mathnfmod: domain error in ZM_hnfmod: nb lines > nb columns
   ***   at top-level: polsturm(x^2*1.)
   ***                 ^----------------
-  *** polsturm: domain error in polsturm: issquarefree(pol) = 0
+  *** polsturm: precision too low in polsturm.
   ***   at top-level: removeprimes(2)
   ***                 ^---------------
   *** removeprimes: domain error in removeprime: prime not in primetable
@@ -601,4 +601,10 @@ INFINITY
   ***                 ^------------
   ***   not a function in function call
 1
-Total time spent: 12
+  ***   at top-level: znlog(Mod(1,n),Mod(1
+  ***                 ^--------------------
+  *** znlog: inconsistent moduli in Rg_to_Fp: (...) != (...)
+  ***   at top-level: Mod(0,n)^(-1)
+  ***                         ^-----
+  *** _^_: impossible inverse in Fp_inv: (...).
+Total time spent: 8
diff --git a/src/test/32/factorff b/src/test/32/factorff
new file mode 100644
index 0000000..2f5270c
--- /dev/null
+++ b/src/test/32/factorff
@@ -0,0 +1,97 @@
+[t, t^2 + 1, -t^2 - t + 1]~
+[t, t^2 + 1, -t^2 - t + 1]~
+[Mod(Mod(1, 2), Mod(1, 2)*y^2 + Mod(1, 2)*y + Mod(1, 2))]~
+
+[x + 1 6]
+
+[x + t 6]
+
+[]~
+[]~
+
+[                x + 1 1]
+
+[                x + 2 1]
+
+[                x + 3 1]
+
+[                x + 4 1]
+
+[      x + (t^3 + 4*t) 1]
+
+[  x + (t^3 + 4*t + 1) 1]
+
+[  x + (t^3 + 4*t + 2) 1]
+
+[  x + (t^3 + 4*t + 3) 1]
+
+[  x + (t^3 + 4*t + 4) 1]
+
+[    x + (2*t^3 + 3*t) 1]
+
+[x + (2*t^3 + 3*t + 1) 1]
+
+[x + (2*t^3 + 3*t + 2) 1]
+
+[x + (2*t^3 + 3*t + 3) 1]
+
+[x + (2*t^3 + 3*t + 4) 1]
+
+[    x + (3*t^3 + 2*t) 1]
+
+[x + (3*t^3 + 2*t + 1) 1]
+
+[x + (3*t^3 + 2*t + 2) 1]
+
+[x + (3*t^3 + 2*t + 3) 1]
+
+[x + (3*t^3 + 2*t + 4) 1]
+
+[      x + (4*t^3 + t) 1]
+
+[  x + (4*t^3 + t + 1) 1]
+
+[  x + (4*t^3 + t + 2) 1]
+
+[  x + (4*t^3 + t + 3) 1]
+
+[  x + (4*t^3 + t + 4) 1]
+
+
+[0 1]
+
+[;]
+
+[Mod(Mod(1, 5), Mod(1, 5)*t^4 + Mod(1, 5)*t^3 + Mod(2, 5)*t^2 + Mod(1, 5)*t 
++ Mod(3, 5))*x^4 + Mod(Mod(0, 5), Mod(1, 5)*t^4 + Mod(1, 5)*t^3 + Mod(2, 5)*
+t^2 + Mod(1, 5)*t + Mod(3, 5))*x^3 + Mod(Mod(0, 5), Mod(1, 5)*t^4 + Mod(1, 5
+)*t^3 + Mod(2, 5)*t^2 + Mod(1, 5)*t + Mod(3, 5))*x^2 + Mod(Mod(0, 5), Mod(1,
+ 5)*t^4 + Mod(1, 5)*t^3 + Mod(2, 5)*t^2 + Mod(1, 5)*t + Mod(3, 5))*x + Mod(M
+od(4, 5)*t, Mod(1, 5)*t^4 + Mod(1, 5)*t^3 + Mod(2, 5)*t^2 + Mod(1, 5)*t + Mo
+d(3, 5)) 1]
+
+[1, a, a + 1, a^2]~
+
+[                                    x + 79228162514264337593543950396 1]
+
+[                                  x + 79228162514264337593543950396*a 1]
+
+[x + (79228162514264337593543950396*a + 79228162514264337593543950396) 1]
+
+[                                x + 79228162514264337593543950396*a^2 1]
+
+[                                    x^2 + (2*a + 1)*x + (a^2 + a + 1) 1]
+
+[                                              x^4 + x^3 + x^2 + x + 1 1]
+
+3
+3
+107
+37
+4096
+3584
+5832
+200
+1000
+200
+Total time spent: 4620
diff --git a/src/test/32/factormod b/src/test/32/factormod
index 863dac5..0215b70 100644
--- a/src/test/32/factormod
+++ b/src/test/32/factormod
@@ -176,19 +176,19 @@ x + 9233, 1; x + 9244, 1; x + 9247, 1; x + 9261, 1; x + 9269, 1; x + 9270, 1
 1; x + 12226, 1; x + 12229, 1; x + 12239, 1; x + 12265, 1; x + 12268, 1; x +
  12269, 1; x + 12281, 1; x + 12282, 1]
 
-[ y + 697093550 1]
+[1 1 1]
 
-[y + 1551133506 1]
+[1 1 1]
 
-[y + 2227781066 1]
 
+[1 3 27]
 
-[x 1]
+[1 1  1]
 
-[x^3 + x^2 + 1 1]
 
-[x^27 + x^25 + x^24 + x^23 + x^22 + x^17 + x^16 + x^15 + x^13 + x^12 + x^9 +
- x^8 + x^4 + x + 1 1]
+[1 2 4 5 15 15 52 131 373 400]
+
+[4 1 1 1  1  1  1   1   1   1]
 
 [Mod(1, 41), Mod(3, 41), Mod(9, 41), Mod(14, 41), Mod(27, 41), Mod(32, 41), 
 Mod(38, 41), Mod(40, 41)]~
@@ -251,4 +251,4 @@ Mod(38, 41), Mod(40, 41)]~
 
 [Mod(1, 100000000000000000039)*x + Mod(1, 100000000000000000039) 2]
 
-Total time spent: 68
+Total time spent: 64
diff --git a/src/test/32/ff b/src/test/32/ff
index 26ed2ac..01d551c 100644
--- a/src/test/32/ff
+++ b/src/test/32/ff
@@ -17,12 +17,12 @@ a^2 + a, a^16 + a^12 + a^9 + a^8 + a^6 + a^4 + a^3 + a^2 + a + 1, a^12 + a^9
 16 + a^12 + a^9 + a^6 + a^4 + a^3 + a^2 + 1, a^16 + a^12 + a^9 + a^6 + a^4 +
  a^3 + a, a^16 + a^12 + a^9 + a^6 + a^3 + a^2 + a + 1, a^16 + a^12 + a^9 + a
 ^8 + a^6 + a^4 + a^3 + a^2 + a]~, [x^3 + (a^17 + a^16 + a^10 + a^7 + a^3), 1
-; x^3 + (a^17 + a^16 + a^10 + a^7 + a^3 + a), 1], [], a/x, 1, a^19 + a^17 + 
-a^16 + a^14 + a^13 + a^12 + a^8 + a^6 + a^3 + a^2 + 1, 1048575, a, [x + (a^1
-8 + a^16 + a^13 + a^9 + a^8 + a^7 + a^6 + a^4 + a^2 + a), 1; x + (a^18 + a^1
-6 + a^13 + a^9 + a^8 + a^7 + a^6 + a^4 + a^2 + a + 1), 1], [a^18 + a^16 + a^
-13 + a^9 + a^8 + a^7 + a^6 + a^4 + a^2 + a, a^18 + a^16 + a^13 + a^9 + a^8 +
- a^7 + a^6 + a^4 + a^2 + a + 1]~]
+; x^3 + (a^17 + a^16 + a^10 + a^7 + a^3 + a), 1], [], a/x, 1, a^18 + a^17 + 
+a^16 + a^15 + a^12 + a^8 + a^2, 1048575, a, [x + (a^18 + a^16 + a^13 + a^9 +
+ a^8 + a^7 + a^6 + a^4 + a^2 + a), 1; x + (a^18 + a^16 + a^13 + a^9 + a^8 + 
+a^7 + a^6 + a^4 + a^2 + a + 1), 1], [a^18 + a^16 + a^13 + a^9 + a^8 + a^7 + 
+a^6 + a^4 + a^2 + a, a^18 + a^16 + a^13 + a^9 + a^8 + a^7 + a^6 + a^4 + a^2 
++ a + 1]~]
 ? test(7,7)
 [a^2 + 3*a + 1, a^6 + 2*a^4 + 5*a^3 + 2*a^2 + 5*a + 1, 3*a + 3, a + 3, 5*a^6
  + 3*a^4 + 4*a^3 + 3*a^2 + 4*a, 2*a + 2, 2*a + 2, 4*a + 4, 6*a^6 + 6*a^5 + 5
@@ -35,9 +35,10 @@ od(1, 7), Mod(1, 7)*x^7 + Mod(1, 7)*x^6 + Mod(2, 7)*x^5 + Mod(5, 7)*x + Mod(
 *a^2 + 6, 6*a^6 + a^5 + 2*a^4 + 2*a^2]~, [x^2 + (a^6 + 6*a^5 + 4*a^4 + 5*a^3
  + 4)*x + 4, 1; x^2 + (2*a^6 + 5*a^5 + a^4 + 3*a^3 + 1)*x + 2, 1; x^2 + (4*a
 ^6 + 3*a^5 + 2*a^4 + 6*a^3 + 2)*x + 1, 1], a^6 + 4*a^5 + 4*a^4 + 6*a^2 + a +
- 4, a/x, (x + a)/(x + 6*a), 3*a^6 + 3*a^4 + 4*a^3 + 5*a^2 + 3*a + 4, 274514,
- a, [x + (2*a^6 + 6*a^5 + 5*a^2 + 2*a + 1), 1; x + (5*a^6 + a^5 + 2*a^2 + 5*
-a), 1], [2*a^6 + 6*a^5 + 5*a^2 + 2*a, 5*a^6 + a^5 + 2*a^2 + 5*a + 6]~]
+ 4, a/x, (x + a)/(x + 6*a), 5*a^6 + 6*a^5 + 4*a^4 + 2*a^3 + 6*a^2 + 3*a + 5,
+ 274514, a, [x + (2*a^6 + 6*a^5 + 5*a^2 + 2*a + 1), 1; x + (5*a^6 + a^5 + 2*
+a^2 + 5*a), 1], [2*a^6 + 6*a^5 + 5*a^2 + 2*a, 5*a^6 + a^5 + 2*a^2 + 5*a + 6]
+~]
 ? test(precprime(2^32),3)
 [a^2 + 3*a + 1, 3435973833*a^2 + 3435973833, 2863311528*a + 2863311528, a + 
 3435973833, 3579139409*a^2 + 2863311528, 3579139410*a + 3579139410, 1024*a +
@@ -52,11 +53,11 @@ a, a^2 + a + 4294967288, 4294967290*a^2 + 4294967289*a + 2]~, [x + (34444702
 021233148), 1; x^2 + (954915748*a^2 + 2667389600*a + 2273734143)*x + (816322
 992*a^2 + 830924795*a + 1995175223), 1; x^2 + (3950520268*a^2 + 2678380601*a
  + 4042507205)*x + (1642837480*a^2 + 2548350348*a + 1670376662), 1], 3618892
-287*a^2 + 1482857269*a + 1021597254, a/x, (x + a)/(x + 4294967290*a), 193102
-0128*a^2 + 2510126022*a + 210458928, 36893488070109691946, a, [x + (13656704
-90*a^2 + 3373566631*a + 4083593885), 1; x + (2929296801*a^2 + 921400660*a + 
-211373407), 1], [1365670490*a^2 + 3373566631*a + 4083593884, 2929296801*a^2 
-+ 921400660*a + 211373406]~]
+287*a^2 + 1482857269*a + 1021597254, a/x, (x + a)/(x + 4294967290*a), 349038
+3416*a^2 + 1759576229*a + 3092551593, 36893488070109691946, a, [x + (1365670
+490*a^2 + 3373566631*a + 4083593885), 1; x + (2929296801*a^2 + 921400660*a +
+ 211373407), 1], [1365670490*a^2 + 3373566631*a + 4083593884, 2929296801*a^2
+ + 921400660*a + 211373406]~]
 ? test(nextprime(2^32),3)
 [a^2 + 3*a + 1, a^2 + 4294967310, 1431655771*a + 1431655771, a + 3435973849,
  3579139425*a^2 + 1431655772, 715827886*a + 715827886, 1024*a + 1024, 114504
@@ -70,11 +71,13 @@ Mod(4294967310, 4294967311), Mod(1, 4294967311)*x^3 + Mod(1, 4294967311)*x^2
 94967309, 4294967310*a^2 + 4294967310*a + 1]~, [x^2 + (2086193155*a^2 + 1225
 81001)*x + 2086193154, 1; x^2 + (2208774157*a^2 + 4172386308)*x + 2208774156
 , 1; x^2 + (4294967310*a^2 + 2)*x + 1, 1], 1484088443*a^2 + 1141114953*a + 4
-283364322, a/x, (x + a)/(x + 4294967310*a), 3579574627*a^2 + 2804395212*a + 
-4147536492, 6148914735617846011, a, [x + (268392743*a^2 + 2459390605*a + 130
-4316255), 1; x + (4026574568*a^2 + 1835576706*a + 2990651057), 1], [26839274
-3*a^2 + 2459390605*a + 1304316254, 4026574568*a^2 + 1835576706*a + 299065105
-6]~]
+283364322, a/x, (x + a)/(x + 4294967310*a), 1892124804*a^2 + 446887574*a + 1
+010425087, 6148914735617846011, a, [x + (268392743*a^2 + 2459390605*a + 1304
+316255), 1; x + (4026574568*a^2 + 1835576706*a + 2990651057), 1], [268392743
+*a^2 + 2459390605*a + 1304316254, 4026574568*a^2 + 1835576706*a + 2990651056
+]~]
+? ftest(p,n,r)=my(a=ffgen(ffinit(p,n),'a)^r);if(sqrtn(a,r)^r!=a,error([p,n,r]));
+? ftest(2,1005,7);
 ? ffgen(ffinit(2^32-5,101),'a)^10000
 2904925334*a^100 + 700105542*a^99 + 1727200511*a^98 + 1173808205*a^97 + 9542
 0994*a^96 + 3202419959*a^95 + 2481924190*a^94 + 3126863204*a^93 + 2955970830
@@ -160,28 +163,10 @@ a^9 + 9319609099157088592*a^8 + 3845681432811214920*a^7 + 380965757660125686
 29908274
 291902314
 2885628658
-? do(f,p,T)=centerlift(lift(polrootsff(f,p,T)));
-? do(x^3+x^2+x-1,3,t^3+t^2+t-1)
-[t, t^2 + 1, -t^2 - t + 1]~
-? t=ffgen(3^3,'t);do((x^3+x^2+x-1)*t^0,t.p,t.mod)
-[t, t^2 + 1, -t^2 - t + 1]~
-? polrootsff(x^4+1,2,y^2+y+1)
-[Mod(Mod(1, 2), Mod(1, 2)*y^2 + Mod(1, 2)*y + Mod(1, 2))]~
 ? t=ffgen(2^64)^((2^64-1)\5);1/t
 x^58 + x^57 + x^56 + x^52 + x^51 + x^49 + x^46 + x^45 + x^42 + x^39 + x^36 +
  x^35 + x^32 + x^30 + x^29 + x^25 + x^23 + x^22 + x^21 + x^20 + x^19 + x^12 
 + x^8 + x^7 + x^6 + x^2
-? t=ffgen(('t^2+'t+1)*Mod(1,2));
-? factorff(x^12+t*x^10+x^6+(t+1)*x^2+1)
-
-[x + 1 6]
-
-[x + t 6]
-
-? polrootsff(x^2-x-ffgen((v^2+1)*Mod(1,3)))
-[]~
-? polrootsff(2*x+1,2,y)
-[]~
 ? sqrt(Mod(-1,4296540161))
 Mod(1086811600, 4296540161)
 ? sqrt(Mod(-1,18446744073944432641))
@@ -195,8 +180,6 @@ Mod(6687681666819568403, 18446744073944432641)
 41036151112220792, x - 2888582621843189425, x - 2370518075556110396, x - 248
 527397336721375, x - 3, x - 2, x - 1, x^2 + 2, x^2 + 3, x^2 + 8, x^2 + 10, x
 ^2 - 10, x^2 - 8, x^2 - 3, x^2 - 2]~
-? #polrootsff(x^107+2*x^3+1,3,ffinit(3,107,'a))
-107
 ? ffgen(x^2+x+Mod(1,3))
   ***   at top-level: ffgen(x^2+x+Mod(1,3)
   ***                 ^--------------------
@@ -204,73 +187,6 @@ Mod(6687681666819568403, 18446744073944432641)
 ? conjvec(Mod(x,x^2+Mod(1,3)))
 [Mod(Mod(1, 3)*x, Mod(1, 3)*x^2 + Mod(1, 3)), Mod(Mod(2, 3)*x, Mod(1, 3)*x^2
  + Mod(1, 3))]~
-? t=ffgen(5^4,'t);
-? factor((x^24-1)*t^0)
-
-[                x + 1 1]
-
-[                x + 2 1]
-
-[                x + 3 1]
-
-[                x + 4 1]
-
-[      x + (t^3 + 4*t) 1]
-
-[  x + (t^3 + 4*t + 1) 1]
-
-[  x + (t^3 + 4*t + 2) 1]
-
-[  x + (t^3 + 4*t + 3) 1]
-
-[  x + (t^3 + 4*t + 4) 1]
-
-[    x + (2*t^3 + 3*t) 1]
-
-[x + (2*t^3 + 3*t + 1) 1]
-
-[x + (2*t^3 + 3*t + 2) 1]
-
-[x + (2*t^3 + 3*t + 3) 1]
-
-[x + (2*t^3 + 3*t + 4) 1]
-
-[    x + (3*t^3 + 2*t) 1]
-
-[x + (3*t^3 + 2*t + 1) 1]
-
-[x + (3*t^3 + 2*t + 2) 1]
-
-[x + (3*t^3 + 2*t + 3) 1]
-
-[x + (3*t^3 + 2*t + 4) 1]
-
-[      x + (4*t^3 + t) 1]
-
-[  x + (4*t^3 + t + 1) 1]
-
-[  x + (4*t^3 + t + 2) 1]
-
-[  x + (4*t^3 + t + 3) 1]
-
-[  x + (4*t^3 + t + 4) 1]
-
-? factorff(Pol(0),t.p,t.mod)
-
-[0 1]
-
-? factorff(Pol(1),t.p,t.mod)
-[;]
-? factorff(x^4-t,t.p,t.mod)
-
-[Mod(Mod(1, 5), Mod(1, 5)*t^4 + Mod(1, 5)*t^3 + Mod(2, 5)*t^2 + Mod(1, 5)*t 
-+ Mod(3, 5))*x^4 + Mod(Mod(0, 5), Mod(1, 5)*t^4 + Mod(1, 5)*t^3 + Mod(2, 5)*
-t^2 + Mod(1, 5)*t + Mod(3, 5))*x^3 + Mod(Mod(0, 5), Mod(1, 5)*t^4 + Mod(1, 5
-)*t^3 + Mod(2, 5)*t^2 + Mod(1, 5)*t + Mod(3, 5))*x^2 + Mod(Mod(0, 5), Mod(1,
- 5)*t^4 + Mod(1, 5)*t^3 + Mod(2, 5)*t^2 + Mod(1, 5)*t + Mod(3, 5))*x + Mod(M
-od(4, 5)*t, Mod(1, 5)*t^4 + Mod(1, 5)*t^3 + Mod(2, 5)*t^2 + Mod(1, 5)*t + Mo
-d(3, 5)) 1]
-
 ? test(q)=my(t=ffgen(q,'t),m=[t,t^2,1+t^3;1+t,1+t^2,1+t^3]);print(matker(m));print(matimage(m));print(matrank(m));my(M=[t,2*t^0,3*t^0;t,t^2,1+t^3;1+t,1+t^2,1+t^3]);print(matdet(M));print(M^(-1)*M);my(v=[t^0,t^1,t^2]~);print(M*v);
 ? test(2^5)
 [t^4 + t^3; t^4 + t^3; 1]
@@ -306,4 +222,4 @@ t^4 + t^2
 ? test(nextprime(2^63)^5)
 1
 ? print("Total time spent: ",gettime);
-Total time spent: 1480
+Total time spent: 896
diff --git a/src/test/32/gamma b/src/test/32/gamma
index 6166f3b..d81cae7 100644
--- a/src/test/32/gamma
+++ b/src/test/32/gamma
@@ -10,6 +10,10 @@
 5150063470794*x^2 - 0.90747907608088628901656016735627511493*x^3 + 0.9817280
 8683440018733638029402185085036*x^4 - 0.981995068903145202104701413791374675
 51*x^5 + O(x^6)
+1 + 0.42278433509846713939348790991759756896*x + 0.4118403304264396947888835
+6141823227689*x^2 + 0.081576919247086266378835484144359593009*x^3 + 0.074249
+010753513898319820126665575735431*x^4 - 0.0002669820687450147683211197695238
+2515602*x^5 + O(x^6)
 0.50000000000000000000000000000000000000*x^-1 + 0.46139216754923356969674395
 495879878448 + 0.93661624898783663224281375818851553069*x + 0.72048875166669
 501900756857612523634633*x^2 + 1.1032890464233243060581361321045221793*x^3 +
@@ -26,10 +30,13 @@
 2301259461*x^2 - 0.40068563438653142846657938717048333025*x^3 + 0.2705808084
 2778454787900092413529197569*x^4 - 0.20738555102867398526627309729140683361*
 x^5 + O(x^6)
-  *** lngamma: Warning: normalizing a series with 0 leading term.
   ***   at top-level: lngamma(-2+x)
   ***                 ^-------------
   *** lngamma: domain error in intformal: residue(series, pole) != 0
+0.42278433509846713939348790991759756896*x + 0.32246703342411321823620758332
+301259461*x^2 - 0.067352301053198095133246053837149996921*x^3 + 0.0205808084
+27784547879000924135291975694*x^4 - 0.00738555102867398526627309729140683361
+08*x^5 + O(x^6)
 0.E-38
 0.E-38
 (0.59465032062247697727187848272191072247 + 0.576674047468581174134050794750
@@ -44,20 +51,28 @@ x^5 + O(x^6)
 0251892*x - 1.2020569031595942853997381615114499908*x^2 + 1.0823232337111381
 915160036965411679028*x^3 - 1.0369277551433699263313654864570341681*x^4 + 1.
 0173430619844491397145179297909205279*x^5 + O(x^6)
-  *** psi: Warning: normalizing a series with 0 leading term.
--1.0000000000000000000000000000000000000*x^-1 + 0.92278433509846713939348790
-991759756896 + 2.8949340668482264364724151666460251892*x - 0.077056903159594
-285399738161511449990765*x^2 + 2.1448232337111381915160036965411679028*x^3 +
- O(x^4)
+-x^-1 + 0.92278433509846713939348790991759756896 + 2.89493406684822643647241
+51666460251892*x - 0.077056903159594285399738161511449990762*x^2 + 2.1448232
+337111381915160036965411679028*x^3 + O(x^4)
 -3.5449077018110320545963349666822903656 - 0.1293535897955400553154795370758
 8123112*x - 15.838884621997332891305490359174586834*x^2 - 0.0882351409230713
 74511750322744686276244*x^3 - 63.934119924167817737375290277713885431*x^4 - 
 0.042848354492868684268292005312709223076*x^5 + O(x^6)
 1 - 0.57721566490153286060651209008240243104*a*x + O(x^2)
--1.0000000000000000000000000000000000000*x^-1 - 0.57721566490153286060651209
-008240243104 + 1.6449340668482264364724151666460251892*x - 1.202056903159594
-2853997381615114499908*x^2 + 1.0823232337111381915160036965411679028*x^3 - 1
-.0369277551433699263313654864570341681*x^4 + O(x^5)
+-0.57721566490153286060651209008240243104*a*x + O(x^2)
+  ***   at top-level: gamma(O(x))
+  ***                 ^-----------
+  *** gamma: domain error in gamma: argument = 0
+  ***   at top-level: lngamma(O(x))
+  ***                 ^-------------
+  *** lngamma: domain error in lngamma: argument = 0
+  ***   at top-level: psi(O(x))
+  ***                 ^---------
+  *** psi: domain error in psi: argument = 0
+-x^-1 - 0.57721566490153286060651209008240243104 + 1.64493406684822643647241
+51666460251892*x - 1.2020569031595942853997381615114499908*x^2 + 1.082323233
+7111381915160036965411679028*x^3 - 1.0369277551433699263313654864570341681*x
+^4 + 1.0173430619844491397145179297909205279*x^5 + O(x^6)
 x^-1 - 0.57721566490153286060651209008240243104 + 0.989055995327972555395395
 65150063470794*x - 0.90747907608088628901656016735627511493*x^2 + 0.98172808
 683440018733638029402185085036*x^3 - 0.9819950689031452021047014137913746755
@@ -65,6 +80,8 @@ x^-1 - 0.57721566490153286060651209008240243104 + 0.989055995327972555395395
 4.0238726007709377354370243392300398572 E2564
 277.25887222397812376689284858327062723
 0.70315664064524318722569033366791109947
+-x^-1 + O(x^0)
+x^-1 + O(x^0)
 170141183460469231740910675752738881536
 1001.0000000000000000000000000000000000
 8.4592930575197658134779513864578051837 E92
@@ -93,4 +110,4 @@ x^-1 - 0.57721566490153286060651209008240243104 + 0.989055995327972555395395
 0.99999999999999999999999999999942278433509846713939348790991858662495316863
 6615471796845732492343995375856774526593328777198552545340369146294559716293
 3800
-Total time spent: 24
+Total time spent: 16
diff --git a/src/test/32/gcdext b/src/test/32/gcdext
index d64db0d..43de2d9 100644
--- a/src/test/32/gcdext
+++ b/src/test/32/gcdext
@@ -38,6 +38,9 @@
 [0, 1, (10*T^3 + 3*T + 5)*z^6 + (11*T^3 + 15*T^2 + 10*T + 13)*z^4 + (14*T^3 
 + 13*T^2 + 15)*z^2 + (9 + 13*T + 14*T^2 + 11*T^3 + O(T^20))]
 Mod(1, 7)*x
+x + a
+[(a^4 + 2*a^3 + a^2 + a + 1)*x^2 + (a^4 + 2*a^3 + a^2 + a + 2)*x + 1, (2*a^4
+ + a^3 + 2*a^2 + 2*a + 2)*x + (2*a^4 + a^3 + 2*a^2 + 2*a + 1), 1]
 1 + I
 1
 1
diff --git a/src/test/32/help b/src/test/32/help
index 93e2e26..c15307e 100644
--- a/src/test/32/help
+++ b/src/test/32/help
@@ -37,15 +37,16 @@ Help topics: for a list of relevant subtopics, type ?n for n in
   4: NUMBER THEORETICAL functions
   5: Functions related to ELLIPTIC CURVES
   6: Functions related to L-FUNCTIONS
-  7: Functions related to MODULAR FORMS and MODULAR SYMBOLS
-  8: Functions related to general NUMBER FIELDS
-  9: Functions related to associative ALGEBRAS
- 10: POLYNOMIALS and power series
- 11: Vectors, matrices, LINEAR ALGEBRA and sets
- 12: SUMS, products, integrals and similar functions
- 13: GRAPHIC functions
- 14: PROGRAMMING under GP
- 15: The PARI community
+  7: Functions related to MODULAR FORMS
+  8: Functions related to MODULAR SYMBOLS
+  9: Functions related to general NUMBER FIELDS
+ 10: Functions related to associative ALGEBRAS
+ 11: POLYNOMIALS and power series
+ 12: Vectors, matrices, LINEAR ALGEBRA and sets
+ 13: SUMS, products, integrals and similar functions
+ 14: GRAPHIC functions
+ 15: PROGRAMMING under GP
+ 16: The PARI community
 Also:
   ? functionname (short on-line help)
   ?\             (keyboard shortcuts)
@@ -83,7 +84,7 @@ reg  : regulator                                          bnf,bnr
 roots: roots                                       ell,nf,bnf,bnr,    gal
 sign,r1,r2 : signature                                 nf,bnf,bnr
 t2   : t2 matrix                                       nf,bnf,bnr
-tate : Tate's [u^2, u, q, [a,b]]                   ell
+tate : Tate's [u^2, u, q, [a,b], L]                ell
 tu   : torsion unit and its order                         bnf,bnr
 zk   : integral basis                                  nf,bnf,bnr,rnf
 zkst : structure of (Z_K/m)*         bid,                     bnr
@@ -158,4 +159,4 @@ f =
 g =
   ()->0
 
-Total time spent: 4
+Total time spent: 0
diff --git a/src/test/32/hyperell b/src/test/32/hyperell
index 0d2064a..29cca5e 100644
--- a/src/test/32/hyperell
+++ b/src/test/32/hyperell
@@ -103,10 +103,11 @@ x^2 - 2*x - 2
 x^2 - 2
 x^2 - 4
 x^2 - 2
+x^2 - 686
   ***   at top-level: hyperellcharpoly((25
   ***                 ^--------------------
   *** hyperellcharpoly: domain error in hyperellpadicfrobenius: H is singular at 5
   ***   at top-level: hyperellcharpoly((25
   ***                 ^--------------------
   *** hyperellcharpoly: domain error in hyperellpadicfrobenius: H is singular at 5
-Total time spent: 3180
+Total time spent: 3592
diff --git a/src/test/32/incgam b/src/test/32/incgam
index 65c610b..fb0122f 100644
--- a/src/test/32/incgam
+++ b/src/test/32/incgam
@@ -1,61 +1,6 @@
-      1/2,          -100: 5.0 e-18
-   10 - I,    19 + 236*I: 3.4 e-18
-   10 - I,          -100: 3.8 e-18
-1 + 128*I,       -1/10*I: 1.9 e-17
-1 + 128*I, 1/10 - 1/10*I: 6.5 e-18
-       60,    19 + 236*I: 2.3 e-18
-       60,          1/10: 1.5 e-18
-       60,         -1/10: 1.6 e-18
-       60,        1/10*I: 2.9 e-18
-       60,       -1/10*I: 2.9 e-18
-       60, 1/10 - 1/10*I: 2.9 e-18
-       60,           100: 2.3 e-18
-       60,  100 + 1001*I: 2.0 e-17
-30 + 60*I,    19 + 236*I: 2.0 e-17
-30 + 60*I,  100 + 1001*I: 1.8 e-17
-      1/2,          -100: 1.0 e-37
-   10 - I,    19 + 236*I: 6.3 e-37
-   10 - I,          -100: 5.8 e-37
-1 + 128*I,       -1/10*I: 8.6 e-37
-1 + 128*I, 1/10 - 1/10*I: 2.1 e-37
-       60,           100: 1.5 e-37
-       60,  100 + 1001*I: 6.8 e-37
-30 + 60*I,    19 + 236*I: 8.1 e-37
-30 + 60*I,  100 + 1001*I: 2.4 e-36
-        0,          -100: 8.4 e-95
-1 + 128*I,       -1/10*I: 6.2 e-95
-1 + 128*I, 1/10 - 1/10*I: 1.6 e-94
-       60,           100: 2.4 e-95
-       60,  100 + 1001*I: 5.7 e-95
-30 + 60*I,  100 + 1001*I: 3.1 e-94
-1: -37
-2: -37
-3: -38
-4: -39
-5: -37
-6: -37
-7: oo
-8: -37
-9: oo
-10: -34
-11: oo
-12: -41
-13: -40
-1: -75
-2: -75
-3: -77
-4: -77
-5: -76
-6: -75
-7: -76
-8: -75
-9: -76
-10: -72
-11: -77
-12: -79
-13: -79
-6.4517096605632180286130396475962100207 E-43429453
-1.0805427490386563567297010582115145985 E-14
+6.4517096605632180286130396475945591199 E-43429453
+1.0805427490386563567297010582115146397 E-14
+8.3049286655793859421463034969090657184 E-24
 -0.0096304981549875294045330406967324266080 + 0.0104448408245333075664155335
 90425336553*I
 3.6835977616820321802351926205081189877 E-46
@@ -89,4 +34,4 @@
   ***   at top-level: eint1(0)
   ***                 ^--------
   *** eint1: domain error in eint1: x = 0
-Total time spent: 118
+Total time spent: 400
diff --git a/src/test/32/ispower b/src/test/32/ispower
index b416529..0935892 100644
--- a/src/test/32/ispower
+++ b/src/test/32/ispower
@@ -1150,6 +1150,12 @@ Mod(583, 875)
 Mod(0, 2)
 0
 0
+1
+Mod(Mod(1, 2)*y^2 + Mod(1, 2)*y + Mod(1, 2), Mod(1, 2)*y^3 + Mod(1, 2)*y^2 +
+ Mod(1, 2))
+0
+Mod(Mod(3, 5)*y^2 + Mod(1, 5), Mod(1, 5)*y^3 + Mod(1, 5)*y^2 + Mod(1, 5))
+Mod(2, 5)
 0
 1
 0
@@ -1203,4 +1209,14 @@ x + 2
 1
 5
 51
-Total time spent: 3032
+[0, 1, 1, 1, 1, 1]
+[0, 1, 1, 1, 1, 1]
+[0, 1, 1, 1, 1, 1]
+[0, 1, 1, 1, 1, 1]
+  ***   at top-level: ispower(Mod(x,x^2+1)
+  ***                 ^--------------------
+  *** ispower: sorry, ispower for general t_POLMOD is not yet implemented.
+  ***   at top-level: ispower(Mod(x,x^2+1)
+  ***                 ^--------------------
+  *** ispower: sorry, ispower for general t_POLMOD is not yet implemented.
+Total time spent: 2604
diff --git a/src/test/32/iterator b/src/test/32/iterator
index a8e3bd4..07738a6 100644
--- a/src/test/32/iterator
+++ b/src/test/32/iterator
@@ -8,12 +8,29 @@
 -18446744073709551616
 -18446744073709551615
 -18446744073709551614
+2
+3
+4
+5
+6
+7
+8
+9
+10
 4294967279
 4294967291
 4294967311
 18446744073709551557
 18446744073709551629
 18446744073709551653
+2
+3
+5
+7
+2
+3
+5
+7
 0.50000000000000000000000000000000000000
 1.5000000000000000000000000000000000000
 2.5000000000000000000000000000000000000
@@ -23,6 +40,7 @@
 12
 5 3 1 
 1 2 5 6 9 10 
+210
   ***   at top-level: forprime(p=2,10,p=4)
   ***                                   ^--
   ***   prime index read-only: was changed to 4.
diff --git a/src/test/32/lfun b/src/test/32/lfun
index dd347c4..2ba427e 100644
--- a/src/test/32/lfun
+++ b/src/test/32/lfun
@@ -1,5 +1,5 @@
   ***   Warning: new stack size = 32000000 (30.518 Mbytes).
-[647, 196]
+[688, 196]
 371
 1:-0.33333333333333333333333333333333333333
 2:0
@@ -12,15 +12,16 @@
 9:-179843066266647.30303030303030303030303
 10:0
 1:0.33063066328223158676532076242927218282
-2:0.65737655586117037348678949547515310667
+2:0.65737655586117037348678949547515310666
 3:0.83891994700224752688923802043332022788
-4:0.92491465281539828015714800144878813270
-5:0.96452286982609889100272493876597162372
-6:0.98297145977262401505413785166918148218
-7:0.99172249343786354566494479026158994579
-8:0.99593957135944435652980046461493771766
-9:0.99799568488420794431041938185291613554
-10:0.99900642043725868624437550798777108366
+4:0.92491465281539828015714800144878813258
+5:0.96452286982609889100272493876597162333
+6:0.98297145977262401505413785166918148201
+7:0.99172249343786354566494479026158994548
+8:0.99593957135944435652980046461493771761
+9:0.99799568488420794431041938185291613541
+10:0.99900642043725868624437550798777108358
+[441, 365]
 0.65054897266021897189117007748600082014 + 0.3797872612825021141546006883142
 4264229*I
 1.0197948617829165568371172783583479161 + 0.01753787982678033377468853770967
@@ -28,6 +29,11 @@
 -1.0000000000000000000000000000000000000*x^-2 + 0.07281584548367672486058637
 5874901319140 + O(x)
 1.1179816853477385178979715038469170225
+1.0000000000000000000000000000000000000*x^-2 + 1.154431329803065721213024180
+1648048621*x^-1 + O(x^0)
+0.61685027506808491367715568749225944596*x^-2 + 1.01511996319472488016374193
+63106928091*x^-1 + O(x^0)
+1.0000000000000000000000000000000000000*x^-1 + O(x^0)
 246.96037648704266640450758953126840719
 1.00000000000000000000000000000000000000000000000000000*x^-1 + O(x^0)
 4.59057737496905265921181053582421504989219703475223909 - 3.1894012475791441
@@ -49,6 +55,8 @@
 89847743543530991534013594552*x^13 - 1.0000000000000065439687498919193731717
 8549879786061140*x^14 - 0.99999999999999969875751286332132050502895615410010
 3971*x^15 + O(x^16)
+[14.1347251417346937904572519835624702707842571156992432]
+[14.1347251417346937904572519835624702707842571156992432]
 [14.1347251417346937904572519835624702707842571156992432, 21.022039638771554
 9926284795938969027773343405249027818, 25.0108575801456887632137909925628218
 186595496725579967]
@@ -80,13 +88,16 @@
 [[1, 25/48, 5/12, 25/48, 1], [1620/691, 1, 9/14, 9/14, 1, 1620/691], 0.00741
 542092989613058900642774590022872478364665364735552, 0.005083512108393286860
 49429013743874732263404552491812001]
+[[1, 4/7, 2/3, 64/45, 6144/1225, 430080/15893], 0.00424084298467049849793665
+766287427417384922300805979914]
+0.0813494568253817285691508190219681325308278179080356549
 2.99829512187626747049837118353413149411569186966170254 - 0.0193445925339772
 841452384712897772364256641021849529530*I
 2.99829512187626747049837118353413149411569186966170254 - 0.0193445925339772
 841452384712897772364256641021849529530*I
 2.99829512187626747049837118353413149411569186966170254 - 0.0193445925339772
 841452384712897772364256641021849529530*I
-971
+974
 0.177455993247329238699202652214156646711252940222106816
 [0.201954787411261026528684690029341772176043691915844168, 0]
 0.97906557276284488612288786018111182197046845456987142630213045542848319630
@@ -136,11 +147,13 @@
 -188
 1.97848884347766873530779261857994032392637450942515837 + 0.0609239674747025
 097814469640574145327771779577841455860*I
--191
+-190
 x^3 - x - 1
-Curve y^2=x^6 + 58*x^5 + 1401*x^4 + 18038*x^3 + 130546*x^2 + 503516*x + 8085
-61
--63
+Curve y^2+(x^3+x^2+1)*y = x^2+x
+-62
+Curve y^2+(x^2+x)*y = x^6+3*x^5+6*x^4+7*x^3+6*x^2+3*x+1
+  *** lfungenus2: Warning: unknown valuation of conductor at 2.
+-61
 Curve y^2=x^5 + x
 -125
 [0, 0, -1]
@@ -151,15 +164,17 @@ Curve y^2=x^5 + 1
 1.0314071041733177562983179141216861078
 Elliptic curves over number fields
 -124
-1.3894051168795718563026565631765059399
+1.3894051168795718563026565631765059398
 -125
-1.7561367497808959311966399691482152393
+1.7561367497808959311966399691482152395
 -124
-2.7749792286446646504296418681816946543
+2.7749792286446646504296418681816946545
 -124
-4.4552267729872870508917049939747968506
+4.4552267729872870508917049939747968543
+-126
+8.2306621809152393859013012963081422203
 -126
-8.2306621809152393859013012963081422201
+1.6750185734169267044822713906540188705
 check all formats
 -191
 -191
@@ -198,18 +213,16 @@ check all formats
 -0.500000000000000000000000000000000000000000000000000000
 1.00000000000000000000000000000000000000000000000000000*x^-1 + O(x^0)
 -184
-1.64493406684822643647241516664602518921894990120679844*x^-1 - 3.96073485153
-165635508952127603670030164316292161954347 + O(x)
+1.64493406684822643647241516664602518921894990120679844*x^-1 + O(x^0)
 1.97730435029729611819708544148512557208215146666013421
 -186
 -0.822467033424113218236207583323012594609474950603399219
-1.20205690315959428539973816151144999076498629234049888*x^-1 - 2.03850450785
-979240066883653755585364209903359729371080 + O(x)
-  *** lfuninit: Warning: #an = 598 < 931, results may be imprecise.
+1.20205690315959428539973816151144999076498629234049888*x^-1 + O(x^0)
+  *** lfuninit: Warning: #an = 598 < 1012, results may be imprecise.
 1.01542133944024439298806668944681826497337332941038810
-[[146, 204], [146, 204], [146, 204]]
+[[147, 203], [147, 203], [147, 203]]
 -188
-[[11, 193], [7, 193]]
+[[11, 193], [6, 193]]
 1
   ***   at top-level: lfuntheta(1,0)
   ***                 ^--------------
@@ -230,5 +243,6 @@ check all formats
 28614069.00000000000
 1
 [6, 184]
-[[12, 126], [12, 126], [5, 125]]
-Total time spent: 9281
+[[12, 125], [11, 125], [5, 124]]
+1.000000000000000019
+Total time spent: 6236
diff --git a/src/test/32/lfuntype b/src/test/32/lfuntype
index 6b3dfc5..c4d27b7 100644
--- a/src/test/32/lfuntype
+++ b/src/test/32/lfuntype
@@ -64,234 +64,245 @@
 6 (lfunhardy): -4.0882933850254632425733862599048558633
 6 (lfuntheta): 1.1375713725509771962438425200438560299
 6 (lfunan): [1, 1, 0, 1, 0, 0, 2, 1, 2, 0]
-7 (lfun(2+2*I)): 1.0101495968934043412732800200854418054 + 0.004609503326023
-2147701632196287121437829*I
-7 (lfun): 1.0252001241345418724140560939356526952
-7 (lfuncreate): 1.0252001241345418724140560939356526952
-7 (lfunderiv): 0.29024384665957598438544288826949641263
-7 (lfunlambda): 49.048985289902361654934745411419681479
-7 (lfunderivlambda): 122.70316145654544382956158595378438704
+7 (lfun(2+2*I)): 0.88705172216113322480409469919534965612 - 0.09990678085842
+8073943765393502858953797*I
+7 (lfun): 1.2199870868057000148286320542635728879
+7 (lfuncreate): 1.2199870868057000148286320542635728879
+7 (lfunderiv): 0.76279628494731231763615969761776115936
+7 (lfunlambda): 5.5505341159944627753280928032151833524
+7 (lfunderivlambda): 16.424727310701215600165088962170900302
 7 (lfuncheckfeq): -124
-7 (lfunhardy): -416.09983196508983799680981895045379214
-7 (lfuntheta): 3.4408766070486585094477767051533947061
-7 (lfunan): [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-8 (lfun(2+2*I)): 0.94991647591129072043581963833883739774 + 0.03585105823427
-7443293287918437084238484*I
-8 (lfun): 1.1100010060250153929372222560595385375
-8 (lfuncreate): 1.1100010060250153929372222560595385375
-8 (lfunderiv): 0.66985260944239582916060974832249875293
-8 (lfunlambda): 0.41169121016707136240079852448689476625
-8 (lfunderivlambda): 1.0217697192872996687480118838767986988
+7 (lfunhardy): -33.351091907649273629818419728456878713
+7 (lfuntheta): 0.36149966339864669981432842318357647671
+7 (lfunan): [1, 0, 1, 1, 0, 0, 0, 0, 1, 0]
+8 (lfun(2+2*I)): 1.0101495968934043412732800200854418054 + 0.004609503326023
+2147701632196287121437829*I
+8 (lfun): 1.0252001241345418724140560939356526952
+8 (lfuncreate): 1.0252001241345418724140560939356526952
+8 (lfunderiv): 0.29024384665957598438544288826949641263
+8 (lfunlambda): 49.048985289902361654934745411419681479
+8 (lfunderivlambda): 122.70316145654544382956158595378438704
 8 (lfuncheckfeq): -124
-8 (lfunhardy): -3.6466012956392990113851960814374302626
-8 (lfuntheta): 0.015798831739815398531916606977185172990
-8 (lfunan): [1, 0, 0, 0, 1, 0, 1, 1, 0, 0]
-9 (lfun(2+2*I)): 0.96046911396271941245734106936390276916 - 0.19913331853054
-320497393259062063479030*I
-9 (lfun): 1.4401597158776080801495064365138846123
-9 (lfuncreate): 1.4401597158776080801495064365138846123
-9 (lfunderiv): 1.2079049332895341520216765453021425233
-9 (lfunlambda): 15.139485785201416763757736219721592777
-9 (lfunderivlambda): 33.440587260542738156400195687111808794
+8 (lfunhardy): -416.09983196508983799680981895045379214
+8 (lfuntheta): 3.4408766070486585094477767051533947061
+8 (lfunan): [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+9 (lfun(2+2*I)): 0.94991647591129072043581963833883739774 + 0.03585105823427
+7443293287918437084238484*I
+9 (lfun): 1.1100010060250153929372222560595385375
+9 (lfuncreate): 1.1100010060250153929372222560595385375
+9 (lfunderiv): 0.66985260944239582916060974832249875293
+9 (lfunlambda): 0.41169121016707136240079852448689476625
+9 (lfunderivlambda): 1.0217697192872996687480118838767986988
 9 (lfuncheckfeq): -124
-9 (lfunhardy): -4.0882933850254632425733862599048558633
-9 (lfuntheta): 1.1375713725509771962438425200438560299
-9 (lfunan): [1, 1, 0, 1, 0, 0, 2, 1, 2, 0]
-10 (lfun(2+2*I)): 1.0101495968934043412732800200854418054 + 0.00460950332602
-32147701632196287121437829*I
-10 (lfun): 1.0252001241345418724140560939356526952
-10 (lfuncreate): 1.0252001241345418724140560939356526952
-10 (lfunderiv): 0.29024384665957598438544288826949641263
-10 (lfunlambda): 49.048985289902361654934745411419681479
-10 (lfunderivlambda): 122.70316145654544382956158595378438704
+9 (lfunhardy): -3.6466012956392990113851960814374302626
+9 (lfuntheta): 0.015798831739815398531916606977185172990
+9 (lfunan): [1, 0, 0, 0, 1, 0, 1, 1, 0, 0]
+10 (lfun(2+2*I)): 0.96046911396271941245734106936390276916 - 0.1991333185305
+4320497393259062063479030*I
+10 (lfun): 1.4401597158776080801495064365138846123
+10 (lfuncreate): 1.4401597158776080801495064365138846123
+10 (lfunderiv): 1.2079049332895341520216765453021425233
+10 (lfunlambda): 15.139485785201416763757736219721592777
+10 (lfunderivlambda): 33.440587260542738156400195687111808794
 10 (lfuncheckfeq): -124
-10 (lfunhardy): -416.09983196508983799680981895045379214
-10 (lfuntheta): 3.4408766070486585094477767051533947061
-10 (lfunan): [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-11 (lfun(2+2*I)): 1.1253218963557071550693052856154296376 - 0.19811927124022
+10 (lfunhardy): -4.0882933850254632425733862599048558633
+10 (lfuntheta): 1.1375713725509771962438425200438560299
+10 (lfunan): [1, 1, 0, 1, 0, 0, 2, 1, 2, 0]
+11 (lfun(2+2*I)): 1.0101495968934043412732800200854418054 + 0.00460950332602
+32147701632196287121437829*I
+11 (lfun): 1.0252001241345418724140560939356526952
+11 (lfuncreate): 1.0252001241345418724140560939356526952
+11 (lfunderiv): 0.29024384665957598438544288826949641263
+11 (lfunlambda): 49.048985289902361654934745411419681479
+11 (lfunderivlambda): 122.70316145654544382956158595378438704
+11 (lfuncheckfeq): -124
+11 (lfunhardy): -416.09983196508983799680981895045379214
+11 (lfuntheta): 3.4408766070486585094477767051533947061
+11 (lfunan): [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+12 (lfun(2+2*I)): 1.1253218963557071550693052856154296376 - 0.19811927124022
 079554887193782410084230*I
-11 (lfun): 1.1264614928374354582658928874128263889
-11 (lfuncreate): 1.1264614928374354582658928874128263889
-11 (lfunderiv): -0.10664330325574414917137228626962922306
-11 (lfunlambda): 6.0955851027836191952110423376698748409
-11 (lfunderivlambda): 3.7433308797907653080501083741412594803
-11 (lfuncheckfeq): -126
-11 (lfunhardy): 7.7257057464347992184653892456526767355
-11 (lfuntheta): 1.0563976349426781093403848049102677979
-11 (lfunan): [1, 1, -1, 1, -1, -1, -1, 1, 1, -1]
-12 (lfun(2+2*I)): 1.0366273282049135932270814089727935794 + 0.08598041394827
+12 (lfun): 1.1264614928374354582658928874128263889
+12 (lfuncreate): 1.1264614928374354582658928874128263889
+12 (lfunderiv): -0.10664330325574414917137228626962922306
+12 (lfunlambda): 6.0955851027836191952110423376698748409
+12 (lfunderivlambda): 3.7433308797907653080501083741412594803
+12 (lfuncheckfeq): -126
+12 (lfunhardy): 7.7257057464347992184653892456526767355
+12 (lfuntheta): 1.0563976349426781093403848049102677979
+12 (lfunan): [1, 1, -1, 1, -1, -1, -1, 1, 1, -1]
+13 (lfun(2+2*I)): 1.0366273282049135932270814089727935794 + 0.08598041394827
 8313963891368691632639062*I
-12 (lfun): 0.91596559417721901505460351493238411078
-12 (lfuncreate): 0.91596559417721901505460351493238411078
-12 (lfunderiv): -0.074415212435678234968463235419624378152
-12 (lfunlambda): 0.58312180806163756027676891293678983773
-12 (lfunderivlambda): 0.11461361270605074146108788204186899939
-12 (lfuncheckfeq): -127
-12 (lfunhardy): 1.1188781062286078283093507637195622642
-12 (lfuntheta): 0.086427836524391208443231605210323282841
-12 (lfunan): [1, 0, -1, 0, 1, 0, -1, 0, 1, 0]
-13 (lfun(2+2*I)): 1.1233314114077833561582504428550435835 - 0.20572393424008
+13 (lfun): 0.91596559417721901505460351493238411078
+13 (lfuncreate): 0.91596559417721901505460351493238411078
+13 (lfunderiv): -0.074415212435678234968463235419624378152
+13 (lfunlambda): 0.58312180806163756027676891293678983773
+13 (lfunderivlambda): 0.11461361270605074146108788204186899939
+13 (lfuncheckfeq): -127
+13 (lfunhardy): 1.1188781062286078283093507637195622642
+13 (lfuntheta): 0.086427836524391208443231605210323282841
+13 (lfunan): [1, 0, -1, 0, 1, 0, -1, 0, 1, 0]
+14 (lfun(2+2*I)): 1.1233314114077833561582504428550435835 - 0.20572393424008
 957916898605857624221327*I
-13 (lfun): 1.1266824413000205751592654900629088681
-13 (lfuncreate): 1.1266824413000205751592654900629088681
-13 (lfunderiv): -0.073966539477079629182643885150638146555
-13 (lfunlambda): 307.34947482475061378201159711485734531
-13 (lfunderivlambda): 2028.4436121153168471302904406930171615
-13 (lfuncheckfeq): -126
-13 (lfunhardy): -32.018714245905908906772024097979947352
-13 (lfuntheta): 0.64488044392253325202054921399500268289
-13 (lfunan): [1, 1, -1, 1, -1, -1, -1, 1, 1, -1]
-14 (lfun(2+2*I)): 1.1899347435430418620272738925933102302 + 0.13284931798399
+14 (lfun): 1.1266824413000205751592654900629088681
+14 (lfuncreate): 1.1266824413000205751592654900629088681
+14 (lfunderiv): -0.073966539477079629182643885150638146555
+14 (lfunlambda): 307.34947482475061378201159711485734531
+14 (lfunderivlambda): 2028.4436121153168471302904406930171615
+14 (lfuncheckfeq): -126
+14 (lfunhardy): -32.018714245905908906772024097979947352
+14 (lfuntheta): 0.64488044392253325202054921399500268289
+14 (lfunan): [1, 1, -1, 1, -1, -1, -1, 1, 1, -1]
+15 (lfun(2+2*I)): 1.1899347435430418620272738925933102302 + 0.13284931798399
 008158139344550778717503*I
-14 (lfun): 0.95871612271688315539193642933117852641 + 0.14556587678508959046
+15 (lfun): 0.95871612271688315539193642933117852641 + 0.14556587678508959046
 170451181198645372*I
-14 (lfuncreate): 0.95871612271688315539193642933117852641 + 0.14556587678508
+15 (lfuncreate): 0.95871612271688315539193642933117852641 + 0.14556587678508
 959046170451181198645372*I
-14 (lfunderiv): -0.059141321804795456439850793792381255731 + 0.0061186575828
+15 (lfunderiv): -0.059141321804795456439850793792381255731 + 0.0061186575828
 237615678208745373111870021*I
-14 (lfunlambda): 0.76292204976144041869087066615444364971 + 0.11583764417926
+15 (lfunlambda): 0.76292204976144041869087066615444364971 + 0.11583764417926
 391071741847670955038937*I
-14 (lfunderivlambda): 0.19928889238023943688189401030203636553 + 0.014134398
+15 (lfunderivlambda): 0.19928889238023943688189401030203636553 + 0.014134398
 189618376193588831806358170666*I
-14 (lfuncheckfeq): -127
-14 (lfunhardy): 1.5591777703301761172588208954327252551
-14 (lfuntheta): 0.14490184193508174938690941658301401010 + 0.000154027540511
+15 (lfuncheckfeq): -127
+15 (lfunhardy): 1.5591777703301761172588208954327252551
+15 (lfuntheta): 0.14490184193508174938690941658301401010 + 0.000154027540511
 12997934085459682226059462*I
-14 (lfunan): [1, I, -I, -1, 0, 1, I, -I, -1, 0]
-15 (lfun(2+2*I)): 0.81260447883761526408104144169608149511 + 0.5144166513337
+15 (lfunan): [1, I, -I, -1, 0, 1, I, -I, -1, 0]
+16 (lfun(2+2*I)): 0.81260447883761526408104144169608149511 + 0.5144166513337
 4637809100837010866265633*I
-15 (lfun): 0.54604803621501351833412666043344433859
-15 (lfuncreate): 0.54604803621501351833412666043344433859
-15 (lfunderiv): -0.095957311923813606000713880504095971510
-15 (lfunlambda): 0.30429428345183609897245459495726899126
-15 (lfunderivlambda): 0.095266257729556417098633725894681176014
-15 (lfuncheckfeq): -127
-15 (lfunhardy): 0.97613504532230008589418374710889823825
-15 (lfuntheta): 0.043171973528082749943827357182478083529
-15 (lfunan): [1, -2, -1, 2, 1, 2, -2, 0, -2, -2]
-16 (lfun(2+2*I)): 1.0544108896702584763970017458267826847 - 0.04379652183085
+16 (lfun): 0.54604803621501351833412666043344433859
+16 (lfuncreate): 0.54604803621501351833412666043344433859
+16 (lfunderiv): -0.095957311923813606000713880504095971510
+16 (lfunlambda): 0.30429428345183609897245459495726899126
+16 (lfunderivlambda): 0.095266257729556417098633725894681176014
+16 (lfuncheckfeq): -127
+16 (lfunhardy): 0.97613504532230008589418374710889823825
+16 (lfuntheta): 0.043171973528082749943827357182478083529
+16 (lfunan): [1, -2, -1, 2, 1, 2, -2, 0, -2, -2]
+17 (lfun(2+2*I)): 1.0544108896702584763970017458267826847 - 0.04379652183085
 4397224379011005489686310*I
-16 (lfun): 0.85415099058271070490531884226581179146
-16 (lfuncreate): 0.85415099058271070490531884226581179146
-16 (lfunderiv): -0.56368025436957145796165019177868545250
-16 (lfunlambda): 21.462810165028656830342316601064230458
-16 (lfunderivlambda): 84.686002725623067381430447870497647113
-16 (lfuncheckfeq): -123
-16 (lfunhardy): 7.7431197030007111287831790642229368607
-16 (lfuntheta): 0.84521747322794073828148208807828496968
-16 (lfunan): [1, 0, 0, 0, -3, 0, 3, 0, -3, 0]
-17 (lfun(2+2*I)): 0.98312302696660097223527176346483215206 - 0.1427950673893
+17 (lfun): 0.85415099058271070490531884226581179146
+17 (lfuncreate): 0.85415099058271070490531884226581179146
+17 (lfunderiv): -0.56368025436957145796165019177868545250
+17 (lfunlambda): 21.462810165028656830342316601064230458
+17 (lfunderivlambda): 84.686002725623067381430447870497647113
+17 (lfuncheckfeq): -123
+17 (lfunhardy): 7.7431197030007111287831790642229368607
+17 (lfuntheta): 0.84521747322794073828148208807828496968
+17 (lfunan): [1, 0, 0, 0, -3, 0, 3, 0, -3, 0]
+18 (lfun(2+2*I)): 0.98312302696660097223527176346483215206 - 0.1427950673893
 8341065723807966678967160*I
-17 (lfun): 0.82757526074455562700765359269996549955
-17 (lfuncreate): 0.82757526074455562700765359269996549955
-17 (lfunderiv): -0.87512118124347393325952081941890290952
-17 (lfunlambda): 378.67068685244416028912739442353179344
-17 (lfunderivlambda): 4720.9665435827617633763166279999891270
-17 (lfuncheckfeq): -127
-17 (lfunhardy): -15.149647103802510158707354941231055482
-17 (lfuntheta): -7.6688743804622365519219315981408517165
-17 (lfunan): [1, 0, 0, 0, 1, 0, -5, 0, -3, 0]
-18 (lfun(2+2*I)): 0.98627253010480952593175189385314157899 + 0.3801943625589
-2826912755460379882393981*I
-18 (lfun): 0.66147518792106974272752063397962688979
-18 (lfuncreate): 0.66147518792106974272752063397962688979
-18 (lfunderiv): -0.14384139549317635426356865639499369619
-18 (lfunlambda): 0.50266086742650446274974513333867258927
-18 (lfunderivlambda): 0.19442331022115954163350803417532382469
+18 (lfun): 0.82757526074455562700765359269996549955
+18 (lfuncreate): 0.82757526074455562700765359269996549955
+18 (lfunderiv): -0.87512118124347393325952081941890290952
+18 (lfunlambda): 378.67068685244416028912739442353179344
+18 (lfunderivlambda): 4720.9665435827617633763166279999891270
 18 (lfuncheckfeq): -127
-18 (lfunhardy): 1.4076935244557198875463930525207828840
-18 (lfuntheta): 0.074804214825265387726031644781601219253
-18 (lfunan): [1, -1, -1, -1, 1, 1, 0, 3, 1, -1]
-19 (lfun(2+2*I)): 1.5440136714872304773986991780907589211 - 0.30661960725519
+18 (lfunhardy): -15.149647103802510158707354941231055482
+18 (lfuntheta): -7.6688743804622365519219315981408517165
+18 (lfunan): [1, 0, 0, 0, 1, 0, -5, 0, -3, 0]
+19 (lfun(2+2*I)): 0.98627253010480952593175189385314157899 + 0.3801943625589
+2826912755460379882393981*I
+19 (lfun): 0.66147518792106974272752063397962688979
+19 (lfuncreate): 0.66147518792106974272752063397962688979
+19 (lfunderiv): -0.14384139549317635426356865639499369619
+19 (lfunlambda): 0.50266086742650446274974513333867258927
+19 (lfunderivlambda): 0.19442331022115954163350803417532382469
+19 (lfuncheckfeq): -127
+19 (lfunhardy): 1.4076935244557198875463930525207828840
+19 (lfuntheta): 0.074804214825265387726031644781601219253
+19 (lfunan): [1, -1, -1, -1, 1, 1, 0, 3, 1, -1]
+20 (lfun(2+2*I)): 1.5440136714872304773986991780907589211 - 0.30661960725519
 029288002589339018937061*I
-19 (lfun): 1.0575992445909578493475116523231674725
-19 (lfuncreate): 1.0575992445909578493475116523231674725
-19 (lfunderiv): -0.40874788643585924772279469406166841139
-19 (lfunlambda): 2.0636065064337882642106195341697561190
-19 (lfunderivlambda): 1.5118482678149543000643643698970410347
-19 (lfuncheckfeq): -125
-19 (lfunhardy): 2.5141116494240547692059934356337208455
-19 (lfuntheta): 0.23289067751256198570325301650715050859
-19 (lfunan): [1, 2, -2, 0, -4, -4, -3, 0, 10, -8]
-20 (lfun(2+2*I)): 0.94255444322004905127830492051658000648 + 0.3126778218091
+20 (lfun): 1.0575992445909578493475116523231674725
+20 (lfuncreate): 1.0575992445909578493475116523231674725
+20 (lfunderiv): -0.40874788643585924772279469406166841139
+20 (lfunlambda): 2.0636065064337882642106195341697561190
+20 (lfunderivlambda): 1.5118482678149543000643643698970410347
+20 (lfuncheckfeq): -125
+20 (lfunhardy): 2.5141116494240547692059934356337208455
+20 (lfuntheta): 0.23289067751256198570325301650715050859
+20 (lfunan): [1, 2, -2, 0, -4, -4, -3, 0, 10, -8]
+21 (lfun(2+2*I)): 0.94255444322004905127830492051658000648 + 0.3126778218091
 7321626495545838012354813*I
-20 (lfun): 0.71564612886082497549611412954606651956
-20 (lfuncreate): 0.71564612886082497549611412954606651956
-20 (lfunderiv): -0.10407894584023904016468453592994890959
-20 (lfunlambda): 0.21753033853570730528434199705036653995
-20 (lfunderivlambda): 0.089237881186363955097754401634415704592
-20 (lfuncheckfeq): -127
-20 (lfunhardy): 0.91836381109207465259393909159615943678
-20 (lfuntheta): 0.037630673702661307416849865951733658142
-20 (lfunan): [1, -1, -1, 1, 0, 1, 0, -1, 1, 0]
-21 (lfun(2+2*I)): 0.98315688287807993848728217136059188364 + 0.3531949622611
-9600256485776532890264370*I
-21 (lfun): 0.67479969464784155829709087304704402380
-21 (lfuncreate): 0.67479969464784155829709087304704402380
-21 (lfunderiv): -0.14445905207331063984929465902657559948
-21 (lfunlambda): 0.78627229350688518181479057787879442122
-21 (lfunderivlambda): 0.43960077502814326043064320757682369479
+21 (lfun): 0.71564612886082497549611412954606651956
+21 (lfuncreate): 0.71564612886082497549611412954606651956
+21 (lfunderiv): -0.10407894584023904016468453592994890959
+21 (lfunlambda): 0.21753033853570730528434199705036653995
+21 (lfunderivlambda): 0.089237881186363955097754401634415704592
 21 (lfuncheckfeq): -127
-21 (lfunhardy): 3.7906123947888162118912745573290423840
-21 (lfuntheta): 0.13420087505683188828132600694374189569
-21 (lfunan): [1, -1, -1, 0, 0, 1, 0, 1, 0, 0]
-22 (lfun(2+2*I)): 0.96298216848967988043139203558640711798 - 0.2342009590489
+21 (lfunhardy): 0.91836381109207465259393909159615943678
+21 (lfuntheta): 0.037630673702661307416849865951733658142
+21 (lfunan): [1, -1, -1, 1, 0, 1, 0, -1, 1, 0]
+22 (lfun(2+2*I)): 0.98315688287807993848728217136059188364 + 0.3531949622611
+9600256485776532890264370*I
+22 (lfun): 0.67479969464784155829709087304704402380
+22 (lfuncreate): 0.67479969464784155829709087304704402380
+22 (lfunderiv): -0.14445905207331063984929465902657559948
+22 (lfunlambda): 0.78627229350688518181479057787879442122
+22 (lfunderivlambda): 0.43960077502814326043064320757682369479
+22 (lfuncheckfeq): -127
+22 (lfunhardy): 3.7906123947888162118912745573290423840
+22 (lfuntheta): 0.13420087505683188828132600694374189569
+22 (lfunan): [1, -1, -1, 0, 0, 1, 0, 1, 0, 0]
+23 (lfun(2+2*I)): 0.96298216848967988043139203558640711798 - 0.2342009590489
 5188293534871602747646966*I
-22 (lfun): 1.4318824514464387465676045965741854843
-22 (lfuncreate): 1.4318824514464387465676045965741854843
-22 (lfunderiv): 1.1422304123026129533330985802463952101
-22 (lfunlambda): 1.1759743869874435481612945489432475212
-22 (lfunderivlambda): 2.4084264843810884136659888848787984212
-22 (lfuncheckfeq): -124
-22 (lfunhardy): -7.5183989759241169055381813793310826092
-22 (lfuntheta): 0.082926332933319155259202716459188391609
-22 (lfunan): [1, 1, 0, 1, 1, 0, 0, 1, 0, 1]
-23 (lfun(2+2*I)): 1.0554498431937466016399059838514723665 - 0.02784638539565
+23 (lfun): 1.4318824514464387465676045965741854843
+23 (lfuncreate): 1.4318824514464387465676045965741854843
+23 (lfunderiv): 1.1422304123026129533330985802463952101
+23 (lfunlambda): 1.1759743869874435481612945489432475212
+23 (lfunderivlambda): 2.4084264843810884136659888848787984212
+23 (lfuncheckfeq): -124
+23 (lfunhardy): -7.5183989759241169055381813793310826092
+23 (lfuntheta): 0.082926332933319155259202716459188391609
+23 (lfunan): [1, 1, 0, 1, 1, 0, 0, 1, 0, 1]
+24 (lfun(2+2*I)): 1.0554498431937466016399059838514723665 - 0.02784638539565
 8970273799631703681748409*I
-23 (lfun): 0.93316836286939013447125902611036854752
-23 (lfuncreate): 0.93316836286939013447125902611036854752
-23 (lfunderiv): -0.20133842629482530350224118884420836660
-23 (lfunlambda): 22.150738128072135257046224387043103356
-23 (lfunderivlambda): 67.856243754653225347348872059210166995
-23 (lfuncheckfeq): -125
-23 (lfunhardy): 34.264753605661655413113407773581100347
-23 (lfuntheta): 1.4615812546350410806241912565112410208
-23 (lfunan): [1, 0, 0, 0, -1, 0, -1, 0, 0, 0]
-24 (lfun(2+2*I)): 0.31472576404209958223490432211550805736 - 0.2316796487505
-2068322446450582306984884*I
-24 (lfun): -0.50000000000000000000000000000000000000
-24 (lfuncreate): -0.50000000000000000000000000000000000000
-24 (lfunderiv): -2.0063564559085848512101000267299604382
-24 (lfunlambda): -1.0000000000000000000000000000000000000*x^-1 + O(x^0)
-24 (lfunderivlambda): -2.0000000000000000000000000000000000000*x^-3 + O(x^0)
+24 (lfun): 0.93316836286939013447125902611036854752
+24 (lfuncreate): 0.93316836286939013447125902611036854752
+24 (lfunderiv): -0.20133842629482530350224118884420836660
+24 (lfunlambda): 22.150738128072135257046224387043103356
+24 (lfunderivlambda): 67.856243754653225347348872059210166995
 24 (lfuncheckfeq): -125
+24 (lfunhardy): 34.264753605661655413113407773581100347
+24 (lfuntheta): 1.4615812546350410806241912565112410208
+24 (lfunan): [1, 0, 0, 0, -1, 0, -1, 0, 0, 0]
+25 (lfun(2+2*I)): 0.31472576404209958223490432211550805736 - 0.2316796487505
+2068322446450582306984884*I
+25 (lfun): -0.50000000000000000000000000000000000000
+25 (lfuncreate): -0.50000000000000000000000000000000000000
+25 (lfunderiv): -2.0063564559085848512101000267299604382
+25 (lfunlambda): -1.0000000000000000000000000000000000000*x^-1 + O(x^0)
+25 (lfunderivlambda): -2.0000000000000000000000000000000000000*x^-3 + O(x^0)
+25 (lfuncheckfeq): -125
   *** lfunhardy: Warning: lfuninit: insufficient initialization.
-24 (lfunhardy): -0.56003058147354490789526675361134629435
-24 (lfuntheta): 1.7436711781044978198393639306933465212 E-6
-24 (lfunan): [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
-25 (lfun(2+2*I)): 4.5022051938493762630318608209969624314 - 4.32986359287055
+25 (lfunhardy): -0.56003058147354490789526675361134629435
+25 (lfuntheta): 1.7436711781044978198393639306933465212 E-6
+25 (lfunan): [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
+26 (lfun(2+2*I)): 4.5022051938493762630318608209969624314 - 4.32986359287055
 56420242996824232187809*I
-25 (lfun): 9.8696044010893586188344909998761511353*x^-1 + O(x^0)
-25 (lfuncreate): 9.8696044010893586188344909998761511353*x^-1 + O(x^0)
-25 (lfunderiv): 19.739208802178717237668981999752302271*x^-3 + O(x^0)
-25 (lfunlambda): 2.0000000000000000000000000000000000000*x^-1 + O(x^0)
-25 (lfunderivlambda): 4.0000000000000000000000000000000000000*x^-3 + O(x^0)
-25 (lfuncheckfeq): -127
-25 (lfunhardy): -2.5469113466196770062933385045593301523
-25 (lfuntheta): 0.030046893520745694160538411115727227082
-25 (lfunan): [8, 24, 32, 24, 48, 96, 64, 24, 104, 144]
-26 (lfun(2+2*I)): 1.1880469326252707442140202415265756569 + 0.01694679050176
-8770099808695642642617468*I
-26 (lfun): 0.93105766066370458950111047246090696916
-26 (lfuncreate): 0.93105766066370458950111047246090696916
-26 (lfunderiv): -0.19875301303842881461288412642672936246
-26 (lfunlambda): 2.2168928091162464996705548722606546078
-26 (lfunderivlambda): 1.8835751442729164002985938822801004139
+26 (lfun): 9.8696044010893586188344909998761511354*x^-1 + O(x^0)
+26 (lfuncreate): 9.8696044010893586188344909998761511354*x^-1 + O(x^0)
+26 (lfunderiv): 19.739208802178717237668981999752302271*x^-3 + O(x^0)
+26 (lfunlambda): 2.0000000000000000000000000000000000000*x^-1 + O(x^0)
+26 (lfunderivlambda): 4.0000000000000000000000000000000000000*x^-3 + O(x^0)
 26 (lfuncheckfeq): -127
-26 (lfunhardy): 7.1739599307895241834661105153799234554
-26 (lfuntheta): 0.33740734290941194013785615355015968564
-26 (lfunan): [1, 0.61803398874989484820458683436563811772 + 0.E-38*I, -1.618
+26 (lfunhardy): -2.5469113466196770062933385045593301523
+26 (lfuntheta): 0.030046893520745694160538411115727227082
+26 (lfunan): [8, 24, 32, 24, 48, 96, 64, 24, 104, 144]
+27 (lfun(2+2*I)): 1.1880469326252707442140202415265756569 + 0.01694679050176
+8770099808695642642617468*I
+27 (lfun): 0.93105766066370458950111047246090696916
+27 (lfuncreate): 0.93105766066370458950111047246090696916
+27 (lfunderiv): -0.19875301303842881461288412642672936246
+27 (lfunlambda): 2.2168928091162464996705548722606546078
+27 (lfunderivlambda): 1.8835751442729164002985938822801004139
+27 (lfuncheckfeq): -127
+27 (lfunhardy): 7.1739599307895241834661105153799234554
+27 (lfuntheta): 0.33740734290941194013785615355015968564
+27 (lfunan): [1, 0.61803398874989484820458683436563811772 + 0.E-38*I, -1.618
 0339887498948482045868343656381177 + 0.E-38*I, -0.61803398874989484820458683
 436563811772 + 0.E-38*I, 0, -1, 0.61803398874989484820458683436563811772 + 0
 .E-38*I, -1, 1.6180339887498948482045868343656381177 + 0.E-38*I, 0]
-Total time spent: 2160
+Total time spent: 1952
diff --git a/src/test/32/lift b/src/test/32/lift
index e69dce8..c85f0f0 100644
--- a/src/test/32/lift
+++ b/src/test/32/lift
@@ -6,6 +6,7 @@ x
 8/3
 x
 x + 2
+1 + 2*x + 3*x^2 + O(x^4)
 (a)->lift(a,'x)
 1
 Mod(2, 3)
@@ -14,6 +15,7 @@ x
 2*3^-1 + 2 + O(3)
 x
 Mod(1, 3)*x + Mod(2, 3)
+Mod(1, 5) + Mod(2, 5)*x + Mod(3, 5)*x^2 + O(x^4)
 (a)->lift(a,'y)
 1
 Mod(2, 3)
@@ -22,6 +24,7 @@ x
 2*3^-1 + 2 + O(3)
 Mod(x, x^2)
 Mod(1, 3)*x + Mod(2, 3)
+Mod(1, 5) + Mod(2, 5)*x + Mod(3, 5)*x^2 + O(x^4)
 (a)->lift(a,'z)
 1
 Mod(2, 3)
@@ -30,6 +33,7 @@ x
 2*3^-1 + 2 + O(3)
 Mod(x, x^2)
 Mod(1, 3)*x + Mod(2, 3)
+Mod(1, 5) + Mod(2, 5)*x + Mod(3, 5)*x^2 + O(x^4)
 centerlift
 1
 -1
@@ -38,6 +42,7 @@ x
 -1/3
 x
 x - 1
+1 + 2*x - 2*x^2 + O(x^4)
 liftall
 1
 2
@@ -46,6 +51,7 @@ x
 8/3
 x
 x + 2
+1 + 2*x + 3*x^2 + O(x^4)
 liftint
 1
 2
@@ -54,6 +60,7 @@ x
 8/3
 Mod(x, x^2)
 x + 2
+1 + 2*x + 3*x^2 + O(x^4)
 liftpol
 1
 Mod(2, 3)
@@ -62,4 +69,5 @@ x
 2*3^-1 + 2 + O(3)
 x
 Mod(1, 3)*x + Mod(2, 3)
-Total time spent: 4
+Mod(1, 5) + Mod(2, 5)*x + Mod(3, 5)*x^2 + O(x^4)
+Total time spent: 0
diff --git a/src/test/32/list b/src/test/32/list
index 94a4a6c..133c9ee 100644
--- a/src/test/32/list
+++ b/src/test/32/list
@@ -19,7 +19,7 @@ List([])
 List([1, y + 1])
 List([y, x])
 List([y, y*x])
-108
+127
 Mod(0, 1)
 Mod(1, 3)
 Mod(22, 30)
@@ -29,4 +29,4 @@ List([0, 1])
 List([2, 2, 3])
 3
 List([3, 2, 3])
-Total time spent: 20
+Total time spent: 24
diff --git a/src/test/32/map b/src/test/32/map
index 63157be..228908e 100644
--- a/src/test/32/map
+++ b/src/test/32/map
@@ -12,6 +12,9 @@ Map([1, 4; 3, 16; 5, 36])
 Map([1, -2; 3, -4; 5, -6])
 [1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]
 [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]
+Map([;])
+0
+Map(Mat([2, 3]))
   ***   at top-level: mapget(M,7)
   ***                 ^-----------
   *** mapget: non-existent component in mapget: index not in map
@@ -24,4 +27,7 @@ Map([1, -2; 3, -4; 5, -6])
   ***   at top-level: Vec(M,-1)
   ***                 ^---------
   *** Vec: incorrect type in gtovec (t_LIST).
+  ***   at top-level: Map([1,2;2,3;1,3;1,4
+  ***                 ^--------------------
+  *** Map: domain error in Map: x is not one-to-one
 Total time spent: 20
diff --git a/src/test/32/member b/src/test/32/member
index 373efe0..0b272a6 100644
--- a/src/test/32/member
+++ b/src/test/32/member
@@ -256,9 +256,9 @@ ELLQp
 .j: 6128487/10351
 .p: 11
 .roots: [9 + O(11^2)]~
-.tate: [6 + 8*11 + 5*11^2 + O(11^4), Mod(x, x^2 + (5 + 2*11 + 5*11^2 + 10*11
-^3 + O(11^4))), 3*11 + 7*11^2 + O(11^4), [6 + 3*11 + O(11^4), 6 + 11 + 9*11^
-2 + 11^3 + O(11^4)]]
+.tate: [6 + 8*11 + 5*11^2 + 8*11^4 + O(11^5), Mod(x, x^2 + (5 + 2*11 + 5*11^
+2 + 10*11^3 + 2*11^4 + O(11^5))), 3*11 + 7*11^2 + O(11^5), [6 + 3*11 + O(11^
+5), 6 + 11 + 9*11^2 + 11^3 + 2*11^4 + O(11^5)], 1]
 FFELT
 .f: 3
 .mod: x^3 + x^2 + 1
@@ -324,4 +324,4 @@ ll([])], Mat([1/2, -1/2])]], [[], [], []]], Mat([0, 1])]
 
 [  0   0 1/6]
 
-Total time spent: 26
+Total time spent: 24
diff --git a/src/test/32/modsym b/src/test/32/modsym
index 123fdd0..413e7d3 100644
--- a/src/test/32/modsym
+++ b/src/test/32/modsym
@@ -1,4 +1,9 @@
-  ***   Warning: new stack size = 100000000 (95.367 Mbytes).
+  ***   Warning: new stack size = 30000000 (28.610 Mbytes).
+-1
+1
+0
+11
+2
 
 [-2]
 
@@ -23,6 +28,20 @@
 1/2
 [1/4, -1/2, -1/2]
 -1/2
+[[1/6, -1/12, 0, -1/6, -1/3, 1/6, 1/4, 1/12, 0, 1/6, 1/12, -1/12, -1/12]~, [
+0, 1/4, 1/2, 0, 0, 0, -1/4, -1/4, -1/2, 0, 1/4, 1/4, -1/4]~]
+[[0, 1/2, -1/2, 1/11, -1/2, 0, 3/11, -1/22, 0, 0, -3/22, -1/2, 0, -1/2, 0, -
+2/11, -2/11, 0, -3/22, -1/22, -1/2, 3/11, 1/11]~, [0, 1/2, 3/2, -1, -1/2, -1
+, 0, -1/2, -1, 1, -1/2, 1/2, 1, 1/2, -2, 0, 0, 1, 1/2, 1/2, 1/2, 0, 1]~]
+[[1/2, -1/2, -1/2, -1/2, 1/2, 1/4, 1/2, 0, -1/4, -1/2, 0, -1/4, 1/4]~, [0, 1
+/2, 0, 0, -1/2, 1/8, 0, 1/2, -3/8, -1/2, 0, 3/8, -1/8]~]
+[[1, -1, 0, -1/2, 0, -1/2, 1/2, 1, -1/2, -1, 1/2, 0, 0, -1/2, 0, 1/2, -1/2, 
+1/2, 1/2, -1/2, 1/2, -1/2, -1/2, 1, -1]~, [0, 0, 2/5, 1/10, 0, -1/2, 1/10, 0
+, 1/2, 0, -1/2, 0, -2/5, -1/10, 0, 1/2, -1/2, -1/2, -1/10, 1/2, -1/10, 1/2, 
+-1/2, 0, -2/5]~]
+[[1/3, -1/2, 1/6, 0, -1/2, 1/6, 0]~, [0, 1/2, -1/6, -1/3, -1/2, 1/6, 1/3]~]
+[[1/4, -1/2, -1/2]~, [0, 1/2, -1/2]~]
+227
 [[[-2, 2; 7, -1; 8, 4; 1, -1; -4, 1; -6, 0; -2, -1; 4, -1; 2, 1; -1, 1; -11,
  -1; -9, -3; -8, -4; -5, 2; -8, 2; 2, 1; -4, 1; 8, 1; -1, 1; 1, -1], [1, 2; 
 7, 2], 12, Vecsmall([1, 2])], [[0, 0; 0, 0; 0, 0; -2, 3; 2, -3; 0, 0; -2, 3;
@@ -52,6 +71,15 @@
 32, 1224, 480, -120, -120; -753, 248, -536, -192, 224, 318, -20, -136, -156,
  72; 324, 752, 640, 624, 32, -264, 160, 176, -576, -576], 912, Vecsmall([1, 
 2, 3, 4, 5, 6, 7, 8, 10, 11])]]
+0
+3
+4
+[[[480; -333; -869; 5082; 20933; 19965], Mat(1), 480, Vecsmall([1])], [[1868
+80, -809440, 2610920; -45395, 179585, -543430; -931532, 3896816, -12312388; 
+-5482620, 23280510, -74291580; -12944096, 55235048, -176685289; -10864953, 4
+6410639, -148395852], [-311578267, 693784960, -96693630; -175661395, 4373882
+00, -56555050; -32022627, 85940960, -10612280], 351095745000, Vecsmall([1, 2
+, 3])]]
 [154, 24]
 x^2 - 9*x + 8
 x^4 - 54*x^3 + 333*x^2 + 10692*x + 39204
@@ -64,11 +92,10 @@ x^4 - 113*x^3 - 1872*x^2 - 6208*x + 8192
 [0, Mat([[1, 0; 0, 1], 1])]
 [Mat([[1, 1; 2, 3], -1]), 0]
 [0, 0]
-[64*x^6 - 272*x^4 + 136*x^2 - 8, 384*x^5 + 960*x^4 + 192*x^3 - 672*x^2 - 432
-*x - 72]
+[8*x^6 - 34*x^4 + 17*x^2 - 1, 48*x^5 + 120*x^4 + 24*x^3 - 84*x^2 - 54*x - 9]
 0
-64*x^6 - 272*x^4 + 136*x^2 - 8
-384*x^5 + 960*x^4 + 192*x^3 - 672*x^2 - 432*x - 72
+8*x^6 - 34*x^4 + 17*x^2 - 1
+48*x^5 + 120*x^4 + 24*x^3 - 84*x^2 - 54*x - 9
 [[[1, 1; -5, 0; 0, -5], [0, -1; 5, 1], 5, Vecsmall([1, 2])], [[1; 0; 0], Mat
 (1), 1, Vecsmall([1])]]
 1
@@ -76,6 +103,13 @@ x^4 - 113*x^3 - 1872*x^2 - 6208*x + 8192
 [-1, 0, 0]~
 [1, 0, 0]~
 [-1, 0, 0]~
+
+[ 1  1]
+
+[-5  0]
+
+[ 0 -5]
+
 [Mod(1, x^2 + x - 1), Mod(x, x^2 + x - 1), Mod(-2*x - 1, x^2 + x - 1), Mod(-
 x - 1, x^2 + x - 1), Mod(2*x, x^2 + x - 1), Mod(x - 2, x^2 + x - 1), Mod(2*x
  + 2, x^2 + x - 1), Mod(-2*x - 1, x^2 + x - 1), Mod(2, x^2 + x - 1), Mod(-2*
@@ -112,45 +146,45 @@ x^2 + x - 1)]
 
 1
 
-[ 1 -1/3    0  4  -2   1]
+[ 1  -2    0  4  -2   1]
 
-[ 0    0    0 12  -6   3]
+[ 0   0    0  2  -1 1/2]
 
-[ 6   -3    0 78 -36  16]
+[ 6 -18    0 78 -36  16]
 
-[ 3  1/3 -1/2 18  -7 5/2]
+[ 3   2 -1/2 18  -7 5/2]
 
-[12    2   -2 60 -23   8]
+[12  12   -2 60 -23   8]
 
-[12    3   -2 48 -18   6]
+[12  18   -2 48 -18   6]
 
 1
 
-[  3    0 -1/3   24  -10   4]
+[  3   0 -1/3   24  -10    4]
 
-[  0    0    0  -18    6  -2]
+[  0   0    0   -3    1 -1/3]
 
-[ 24    0   -3  288 -120  48]
+[ 24   0   -3  288 -120   48]
 
-[ -2 -1/2  1/3  -32   13  -5]
+[ -2  -3  1/3  -32   13   -5]
 
-[-12   -2    2 -180   73 -28]
+[-12 -12    2 -180   73  -28]
 
-[-18   -2    3 -252  102 -39]
+[-18 -12    3 -252  102  -39]
 
 1
 
-[ 1 0 0   10  -4   5/3]
+[ 1 0   0   10  -4   5/3]
 
-[-6 0 1  -60  24    -9]
+[-1 0 1/6  -10   4  -3/2]
 
-[ 6 1 0  150 -60    24]
+[ 6 6   0  150 -60    24]
 
-[ 0 0 0  -24  10 -25/6]
+[ 0 0   0  -24  10 -25/6]
 
-[ 0 0 0 -120  49   -20]
+[ 0 0   0 -120  49   -20]
 
-[ 0 0 0 -150  60   -24]
+[ 0 0   0 -150  60   -24]
 
 1
   ***   at top-level: msatkinlehner(W,4)
@@ -176,6 +210,7 @@ x^2 + x - 1)]
 [[Mat([[1, 0; 0, 1], 1]), 0, 0, 0, 0], [0, Mat([[1, 0; 0, 1], 1]), 0, 0, 0],
  [0, 0, Mat([[1, 0; 0, 1], 1]), 0, 0], [0, 0, 0, Mat([[1, 0; 0, 1], 1]), 0],
  [0, 0, 0, 0, Mat([[1, 0; 0, 1], 1])]]
+[84, 10]
 1
 1
 1
@@ -213,4 +248,61 @@ x^2 + x - 1)]
 
 [-1]
 
-Total time spent: 2129
+x^8 - 28*x^7 - 292*x^6 + 16496*x^5 - 115568*x^4 - 1800704*x^3 + 33061376*x^2
+ - 192352256*x + 396169216
+[[[[0, 33, 693, 54, 648, 486, 0], [0, 33, 693, 54, 648, 486, 0]]], 2 + 2*3 +
+ 3^2 + 3^3 + 2*3^4 + 3^5 + O(3^6), Vecsmall([3, 6, 6, 1])]
+O(3^6) + (2 + 3 + 3^3 + O(3^4))*x + (2*3 + O(3^2))*x^2 + O(3^2)*x^3 + O(x^4)
+O(3^6) + O(3^4)*x + O(3^2)*x^2 + O(3^2)*x^3 + O(x^4)
+[[[[1243, 273, 2254, 1029, 0], [1234, 833, 294, 0, 0], [1243, 1295, 196, 137
+2, 0], [1243, 1295, 196, 1372, 0], [1234, 833, 294, 0, 0], [1243, 273, 2254,
+ 1029, 0]]], 1 + 2*7 + 4*7^2 + 2*7^3 + O(7^4), Vecsmall([7, 4, 4, 1])]
+(6 + 3*7 + 5*7^2 + 3*7^3 + O(7^4)) + (6*7^2 + O(7^3))*x + (7 + O(7^2))*x^2 +
+ O(7)*x^3 + O(x^4)
+6 + 3*7 + 5*7^2 + 3*7^3 + O(7^4)
+[[[[6558, 5094, 2304, 5832, 2268, 0, 5103, 0], [6558, 5094, 2304, 5832, 2268
+, 0, 5103, 0]], [[3, 3024, 5508, 4374, 2916, 0, 0, 0], [3, 3024, 5508, 4374,
+ 2916, 0, 0, 0]]], [0, 1/36; 1/36, 0], Vecsmall([3, 8, 7, 1])]
+[(2*3^-1 + 1 + 3 + 3^2 + 3^3 + 3^4 + O(3^5)) + (2 + 3^3 + O(3^4))*x + (1 + 2
+*3 + O(3^2))*x^2 + (2*3^-1 + 1 + O(3))*x^3 + (2*3^-1 + O(3^0))*x^4 + O(x^5),
+ (3^-1 + 1 + 3 + 3^2 + 3^3 + 3^4 + O(3^5)) + (1 + 2*3 + 2*3^2 + 3^3 + O(3^4)
+)*x + (3^-2 + 3^-1 + O(3^2))*x^2 + (2*3^-2 + 2 + O(3))*x^3 + (3^-2 + 2*3^-1 
++ O(3^0))*x^4 + O(x^5)]
+[O(3^5) + O(3^4)*x + O(3^2)*x^2 + O(3)*x^3 + O(x^4), O(3^5) + O(3^4)*x + O(3
+^2)*x^2 + O(3)*x^3 + O(x^4)]
+[[[[6558, 2205, 5895, 972, 1296, 5832, 5103, 0], [6558, 2205, 5895, 972, 129
+6, 5832, 5103, 0]], [[3, 729, 459, 3645, 2673, 2187, 4374, 0], [3, 729, 459,
+ 3645, 2673, 2187, 4374, 0]]], [0, 1/18; 1/18, 0], Vecsmall([3, 8, 7, 1])]
+[[[[0, 1953, 729, 3888, 729, 3645, 0, 0], [0, 1953, 729, 3888, 729, 3645, 0,
+ 0]], [[0, 3312, 1863, 5994, 729, 1458, 0, 0], [0, 3312, 1863, 5994, 729, 14
+58, 0, 0]]], [0, 1/18; 1/18, 1/18], Vecsmall([3, 8, 7, 1])]
+[[[[6546, 684, 5499, 4617, 2106, 5832, 5832, 0], [6546, 684, 5499, 4617, 210
+6, 5832, 5832, 0]], [[6, 5427, 2673, 2187, 1458, 0, 0, 0], [6, 5427, 2673, 2
+187, 1458, 0, 0, 0]]], [0, 1/126; 1/126, 1/126], Vecsmall([3, 8, 7, 1])]
+(2 + 3 + 3^2 + O(3^3)) + (1 + O(3))*x + (1 + O(3))*x^2 + O(x^3)
+(2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)) + (1 + 3 + 2*3^2 + 3^3 + O(3^5)
+)*x + (1 + 2*3 + O(3^3))*x^2 + (3 + O(3^2))*x^3 + O(3)*x^4 + O(x^5)
+O(3^7) + O(3^5)*x + O(3^3)*x^2 + O(3^2)*x^3 + O(3)*x^4 + O(x^5)
+(2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)) + (1 + 3 + 2*3^2 + 3^3 + O(3^5)
+)*x + (1 + 2*3 + O(3^3))*x^2 + (3 + O(3^2))*x^3 + O(3)*x^4 + O(x^5)
+O(11^9) + O(11^8)*x + O(11^7)*x^2 + O(11^6)*x^3 + O(11^5)*x^4 + O(11^4)*x^5 
++ O(11^3)*x^6 + O(11^2)*x^7 + O(11)*x^8 + O(x^9)
+O(3^5) + O(3^3)*x + (1 + 2*3 + O(3^2))*x^2 + (1 + O(3))*x^3 + O(x^4)
+O(11^7) + (10 + 3*11 + 6*11^2 + 9*11^3 + 8*11^4 + 5*11^5 + O(11^6))*x + (6 +
+ 3*11 + 2*11^2 + 6*11^3 + 6*11^4 + O(11^5))*x^2 + (2 + 2*11 + 11^2 + 10*11^3
+ + O(11^4))*x^3 + (5 + 8*11^2 + O(11^3))*x^4 + (4 + 10*11 + O(11^2))*x^5 + (
+1 + O(11))*x^6 + O(x^7)
+(2 + 2*3 + 2*3^2 + 3^4 + O(3^6)) + (1 + 2*3 + 3^2 + 3^3 + O(3^4))*x + (1 + 3
+ + O(3^2))*x^2 + (2 + O(3^2))*x^3 + O(x^4)
+[(2*3^-1 + 1 + 3 + 3^2 + 3^3 + 3^4 + O(3^5)) + (2 + 3^3 + O(3^4))*x + (1 + 2
+*3 + O(3^2))*x^2 + (2*3^-1 + 1 + O(3))*x^3 + (2*3^-1 + O(3^0))*x^4 + O(x^5),
+ (3^-1 + 1 + 3 + 3^2 + 3^3 + 3^4 + O(3^5)) + (1 + 2*3 + 2*3^2 + 3^3 + O(3^4)
+)*x + (3^-2 + 3^-1 + O(3^2))*x^2 + (2*3^-2 + 2 + O(3))*x^3 + (3^-2 + 2*3^-1 
++ O(3^0))*x^4 + O(x^5)]
+[O(5^19), 4 + 3*5 + 3*5^2 + 4*5^3 + 3*5^4 + 4*5^5 + 4*5^6 + 3*5^7 + 5^8 + 2*
+5^10 + 3*5^13 + 3*5^14 + 3*5^16 + 5^18 + O(5^19), O(5^19), 2 + 2*5^2 + 3*5^3
+ + 3*5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + 5^9 + 4*5^10 + 4*5^11 + 4*5^12 + 3*
+5^13 + 3*5^14 + 4*5^15 + 3*5^16 + 4*5^17 + 2*5^18 + O(5^19), O(5^19), 4 + 5 
++ 4*5^4 + 4*5^5 + 3*5^8 + 5^11 + 3*5^12 + 5^13 + 3*5^14 + 5^15 + 5^16 + 3*5^
+17 + 4*5^18 + O(5^19)]
+Total time spent: 2772
diff --git a/src/test/32/mspadic b/src/test/32/mspadic
new file mode 100644
index 0000000..ae3e9ef
--- /dev/null
+++ b/src/test/32/mspadic
@@ -0,0 +1,309 @@
+  ***   Warning: new stack size = 60000000 (57.220 Mbytes).
+[2^-1 + 1 + 2^2 + 2^4 + O(2^5), 1 + 2^2 + O(2^4)]~
+[2*3^-1 + 1 + 3 + 3^2 + 3^3 + O(3^4), 3^-1 + 1 + 3 + 3^2 + 3^3 + O(3^4)]~
+[1 + O(3^5), O(3^5)]~
+4 + 3*5 + 4*5^2 + 2*5^3 + O(5^4)
+1 + O(5^4)
+[1 + O(3^5), O(3^5)]~
+[O(2^3), O(2^2)]~
+2^4 + 2^5 + O(2^6)
+[O(3^10), O(3^10)]~
+[2 + 3 + 3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + O(3^9), 2*3 + 2*3^2 + 2*3^3 + 3^5 +
+ 2*3^8 + O(3^9)]~
+[2*5 + 5^2 + 5^4 + O(5^5), 3*5 + 3*5^2 + 2*5^4 + O(5^5)]~
+[[[[2031, 1484, 1568, 0, 0], [2031, 1960, 1029, 343, 0], [2006, 1792, 1764, 
+686, 0], [2006, 1792, 1764, 686, 0], [2031, 1960, 1029, 343, 0], [2031, 1484
+, 1568, 0, 0]]], 1 + 5*7 + 7^3 + O(7^4), Vecsmall([7, 4, 4, 1])]
+[[[[2017, 441, 2009, 0, 0], [2017, 2177, 1421, 1372, 0], [2009, 1715, 2058, 
+0, 0], [2009, 1715, 2058, 0, 0], [2017, 2177, 1421, 1372, 0], [2017, 441, 20
+09, 0, 0]]], 4 + 7 + 2*7^3 + O(7^4), Vecsmall([7, 4, 4, 1])]
+[[[[2184, 720, 117, 1458, 81, 0, 729], [2184, 720, 117, 1458, 81, 0, 729]], 
+[[3, 837, 1134, 0, 729, 0, 0], [3, 837, 1134, 0, 729, 0, 0]]], [0, 1/36; 1/3
+6, 0], Vecsmall([3, 7, 6, 1])]
+[[[[3, 1617, 980, 0, 0], [0, 861, 1764, 686, 0], [2398, 1526, 490, 1029, 0],
+ [2398, 1526, 490, 1029, 0], [0, 861, 1764, 686, 0], [3, 1617, 980, 0, 0]]],
+ 1/6, Vecsmall([7, 4, 4, 1])]
+[[[[28, 63, 0, 0, 0], [28, 63, 0, 0, 0]]], 2 + 2*3 + 3^2 + 3^3 + O(3^4), Vec
+small([3, 4, 4, 29])]
+[[[[63, 27, 0, 0, 0], [63, 27, 0, 0, 0]]], 2 + 3 + 3^2 + 3^3 + O(3^4), Vecsm
+all([3, 4, 4, 5])]
+[[[[1850, 2500, 1250, 0, 0], [2500, 125, 0, 0, 0], [625, 3000, 0, 0, 0], [12
+75, 625, 1875, 0, 0]]], 3*5^-1 + 5 + O(5^3), Vecsmall([5, 5, 4, -3])]
+0:
+2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + 3^7 + O(3^10)
+3 + 2*3^4 + 2*3^5 + 2*3^6 + O(3^8)
+3^4 + 2*3^7 + O(3^8)
+3^3 + 2*3^5 + O(3^7)
+-2:
+2 + 2*3 + 2*3^2 + 2*3^4 + 3^6 + 3^7 + 3^8 + 3^9 + O(3^10)
+3 + 2*3^3 + 3^4 + 3^5 + 2*3^7 + O(3^8)
+3^3 + 2*3^4 + 2*3^6 + 2*3^7 + O(3^8)
+3^3 + 2*3^5 + 2*3^6 + O(3^7)
+[0, 1]:
+O(3^10)
+O(3^8)
+O(3^8)
+O(3^7)
+[1, 0]:
+2 + 2*3 + 3^3 + 3^4 + 3^6 + 3^8 + O(3^10)
+3 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 3^7 + O(3^8)
+3^3 + 3^5 + 3^6 + 2*3^7 + O(3^8)
+3^3 + 2*3^5 + 3^6 + O(3^7)
+[2, 0]:
+2 + 3^3 + 3^4 + 3^6 + 3^8 + 3^9 + O(3^10)
+3 + 2*3^3 + 3^4 + 3^5 + 3^7 + O(3^8)
+2*3^3 + 2*3^4 + 2*3^6 + O(3^8)
+3^3 + O(3^7)
+0:
+[2^-1 + 2 + 2^2 + 2^5 + 2^6 + O(2^9), 2^-1 + 2^2 + 2^3 + 2^6 + 2^7 + O(2^8)]
+~
+[1 + 2^4 + 2^5 + 2^6 + 2^7 + O(2^8), 1 + 2^2 + 2^3 + 2^5 + O(2^7)]~
+[2^2 + 2^4 + 2^5 + O(2^7), 2^2 + 2^3 + 2^4 + 2^5 + O(2^6)]~
+[2^4 + O(2^5), O(2^4)]~
+-2:
+[2^-1 + 2^2 + 2^3 + 2^5 + 2^7 + O(2^9), 2^-1 + 2 + 2^3 + 2^5 + 2^6 + O(2^8)]
+~
+[1 + 2^3 + 2^5 + O(2^8), 1 + 2^2 + 2^4 + 2^5 + 2^6 + O(2^7)]~
+[2^2 + 2^4 + O(2^7), 2^2 + 2^3 + 2^4 + 2^5 + O(2^6)]~
+[2^4 + O(2^5), O(2^4)]~
+[0, 1]:
+[O(2^9), O(2^8)]~
+[O(2^8), O(2^7)]~
+[O(2^7), O(2^6)]~
+[O(2^5), O(2^4)]~
+[1, 0]:
+[2^-1 + 1 + 2^7 + 2^8 + O(2^9), 2^-1 + 1 + 2 + 2^2 + 2^3 + 2^4 + 2^7 + O(2^8
+)]~
+[1 + 2^2 + 2^3 + 2^7 + O(2^8), 1 + 2^3 + 2^4 + 2^5 + O(2^7)]~
+[2^2 + 2^5 + O(2^7), 2^2 + 2^3 + 2^4 + 2^5 + O(2^6)]~
+[2^4 + O(2^5), O(2^4)]~
+[2, 0]:
+[2^-1 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + O(2^9), 2^-1 + 2 + 2^2 + 2^3 + 2^4 + O
+(2^8)]~
+[1 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + O(2^8), 1 + 2^2 + 2^5 + 2^6 + O(2^7)]~
+[2^2 + 2^4 + 2^6 + O(2^7), 2^2 + 2^3 + 2^4 + 2^5 + O(2^6)]~
+[2^4 + O(2^5), O(2^4)]~
+0:
+5 + 7 + 5*7^2 + 4*7^3 + 7^4 + 2*7^5 + 4*7^6 + 4*7^7 + 2*7^8 + 2*7^9 + O(7^10
+)
+5*7 + 2*7^2 + 6*7^3 + 2*7^4 + 2*7^5 + O(7^9)
+3*7^2 + 6*7^3 + 3*7^4 + 3*7^5 + 7^7 + 2*7^8 + O(7^9)
+6*7^3 + 7^4 + 3*7^5 + 6*7^7 + O(7^9)
+-2:
+3 + 3*7 + 5*7^2 + 4*7^3 + 2*7^4 + 7^5 + 5*7^6 + 4*7^7 + 5*7^8 + 2*7^9 + O(7^
+10)
+7 + 4*7^2 + 3*7^3 + 6*7^4 + 4*7^5 + 7^6 + 2*7^7 + 7^8 + O(7^9)
+2*7^2 + 2*7^3 + 5*7^4 + 4*7^5 + 6*7^6 + 6*7^7 + 7^8 + O(7^9)
+6*7^3 + 6*7^4 + 6*7^5 + 7^6 + 6*7^7 + 4*7^8 + O(7^9)
+[0, 1]:
+O(7^10)
+O(7^9)
+O(7^9)
+O(7^9)
+[1, 0]:
+5 + 6*7 + 5*7^2 + 4*7^3 + 6*7^4 + 5*7^5 + 7^6 + 5*7^7 + 2*7^8 + 3*7^9 + O(7^
+10)
+5*7 + 5*7^2 + 7^3 + 7^4 + 7^5 + 5*7^6 + 5*7^8 + O(7^9)
+3*7^2 + 5*7^3 + 3*7^4 + 7^5 + 2*7^6 + 7^7 + 5*7^8 + O(7^9)
+6*7^3 + 4*7^4 + 6*7^5 + 6*7^6 + 3*7^7 + 3*7^8 + O(7^9)
+[2, 0]:
+5 + 4*7 + 2*7^2 + 3*7^3 + 3*7^4 + 4*7^5 + 6*7^6 + 6*7^7 + 5*7^8 + O(7^10)
+5*7 + 7^2 + 3*7^3 + 4*7^4 + 6*7^5 + 5*7^6 + 4*7^7 + 6*7^8 + O(7^9)
+3*7^2 + 4*7^3 + 6*7^4 + 2*7^5 + 5*7^6 + O(7^9)
+6*7^3 + 3*7^5 + 4*7^7 + 4*7^8 + O(7^9)
+0:
+1 + O(3^10)
+2*3 + 2*3^5 + 2*3^6 + O(3^8)
+2*3^3 + 3^4 + 2*3^5 + O(3^8)
+2*3^3 + 2*3^5 + 2*3^6 + O(3^7)
+-2:
+1 + 2*3 + 2*3^2 + 3^4 + 3^5 + 2*3^6 + 3^7 + 2*3^8 + 2*3^9 + O(3^10)
+2*3 + 3^4 + 3^5 + 2*3^6 + 3^7 + O(3^8)
+3^3 + 3^4 + 2*3^5 + 3^6 + 3^7 + O(3^8)
+2*3^3 + 3^5 + O(3^7)
+[0, 1]:
+O(3^10)
+O(3^8)
+O(3^8)
+O(3^7)
+[1, 0]:
+1 + 2*3 + 3^2 + 3^3 + 3^4 + 2*3^5 + 3^6 + 3^7 + 2*3^8 + 3^9 + O(3^10)
+2*3 + 2*3^4 + 2*3^6 + 2*3^7 + O(3^8)
+3^3 + O(3^8)
+2*3^3 + 3^5 + O(3^7)
+[2, 0]:
+1 + 3 + 3^3 + 3^5 + 2*3^6 + 2*3^7 + 3^8 + O(3^10)
+2*3 + 2*3^3 + 2*3^5 + 3^6 + O(3^8)
+2*3^4 + 3^6 + 2*3^7 + O(3^8)
+2*3^3 + 2*3^5 + 3^6 + O(3^7)
+0:
+O(11^10)
+4*11 + 3*11^2 + 10*11^3 + 7*11^4 + 5*11^5 + 10*11^6 + 2*11^7 + 9*11^8 + 6*11
+^9 + O(11^10)
+5*11^3 + 7*11^4 + 10*11^5 + 6*11^6 + 2*11^7 + 5*11^8 + 2*11^9 + O(11^10)
+5*11^3 + 3*11^4 + 11^5 + 2*11^6 + 8*11^8 + 5*11^9 + O(11^10)
+-2:
+6 + 5*11 + 5*11^2 + 2*11^3 + 9*11^4 + 11^5 + 9*11^6 + 7*11^7 + 3*11^8 + 8*11
+^9 + O(11^10)
+2*11 + 11^2 + 8*11^3 + 4*11^4 + 4*11^5 + 10*11^6 + 10*11^7 + 11^8 + 8*11^9 +
+ O(11^10)
+11^2 + 11^4 + 8*11^5 + 7*11^6 + 5*11^7 + 2*11^8 + 6*11^9 + O(11^10)
+7*11^4 + 7*11^5 + 2*11^6 + 9*11^7 + 5*11^8 + 9*11^9 + O(11^10)
+[0, 1]:
+O(11^10)
+O(11^10)
+O(11^10)
+O(11^10)
+[1, 0]:
+4*11 + 3*11^2 + 6*11^3 + 8*11^4 + 3*11^5 + 6*11^6 + 11^7 + 4*11^8 + 4*11^9 +
+ O(11^10)
+4*11 + 3*11^2 + 11^3 + 6*11^4 + 3*11^5 + 11^6 + 11^7 + 10*11^8 + 8*11^9 + O(
+11^10)
+10*11^3 + 10*11^4 + 9*11^5 + 5*11^6 + 2*11^7 + 3*11^8 + 9*11^9 + O(11^10)
+5*11^3 + 3*11^4 + 8*11^5 + 2*11^6 + 9*11^7 + 2*11^8 + 6*11^9 + O(11^10)
+[2, 0]:
+8*11 + 6*11^2 + 6*11^4 + 2*11^5 + 7*11^7 + 6*11^8 + 9*11^9 + O(11^10)
+4*11 + 3*11^2 + 8*11^3 + 7*11^4 + 9*11^5 + 3*11^6 + 2*11^7 + 8*11^8 + 4*11^9
+ + O(11^10)
+4*11^3 + 3*11^4 + 5*11^5 + 4*11^6 + 7*11^7 + 6*11^8 + 8*11^9 + O(11^10)
+5*11^3 + 3*11^4 + 4*11^5 + 11^6 + 10*11^7 + 4*11^8 + 5*11^9 + O(11^10)
+0:
+[O(2^10), O(2^9)]~
+[O(2^8), O(2^7)]~
+[2^5 + 2^6 + O(2^7), 2^5 + O(2^6)]~
+[O(2^5), O(2^4)]~
+-2:
+[2^6 + 2^7 + 2^9 + O(2^10), 2^6 + 2^7 + 2^8 + O(2^9)]~
+[2^6 + 2^7 + O(2^8), 2^6 + O(2^7)]~
+[2^5 + 2^6 + O(2^7), 2^5 + O(2^6)]~
+[O(2^5), O(2^4)]~
+[0, 1]:
+[O(2^10), O(2^9)]~
+[O(2^8), O(2^7)]~
+[O(2^7), O(2^6)]~
+[O(2^5), O(2^4)]~
+[1, 0]:
+[2^4 + 2^6 + 2^7 + O(2^10), 2^4 + 2^7 + O(2^9)]~
+[O(2^8), O(2^7)]~
+[2^5 + O(2^7), 2^5 + O(2^6)]~
+[O(2^5), O(2^4)]~
+[2, 0]:
+[2^6 + 2^7 + O(2^10), 2^6 + 2^7 + 2^8 + O(2^9)]~
+[2^6 + O(2^8), 2^6 + O(2^7)]~
+[2^5 + 2^6 + O(2^7), 2^5 + O(2^6)]~
+[O(2^5), O(2^4)]~
+[[[[2, 51, 0, 54, 0], [79, 30, 0, 27, 0]]], 1 + 2*3 + O(3^4), Vecsmall([3, 4
+, 4, 5])]
+[[[[174, 425, 475, 0, 0], [172, 400, 300, 0, 0], [172, 400, 300, 0, 0], [174
+, 425, 475, 0, 0]]], 3 + 3*5 + 5^2 + O(5^4), Vecsmall([5, 4, 4, -3])]
+[[[[5094, 783, 324, 4131, 729, 4374, 0, 0, 0], [5094, 783, 324, 4131, 729, 4
+374, 0, 0, 0]]], 2 + 2*3 + 3^2 + 3^3 + 3^4 + 2*3^5 + 3^6 + 3^7 + O(3^8), Vec
+small([3, 8, 8, 1])]
+  ***   at top-level: Wp=mspadicinit(msinit(2
+  ***                    ^--------------------
+  *** mspadicinit: sorry, mspadicinit when p^2 | N is not yet implemented.
+  ***   at top-level: oms=mspadicmoments(Wp,ph
+  ***                     ^--------------------
+  *** mspadicmoments: incorrect type in mstooms [v_p(ap) > mspadicinit flag] (t_VEC).
+[3^-1 + 1 + 2*3 + 3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + O(3^7), 2*3^-1 + 2 +
+ 2*3 + 2*3^2 + 3^3 + 2*3^4 + 3^5 + O(3^7)]~
+[1 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + O(3^9), O(3^9),
+ O(3^9), O(3^9), 2 + 2*3 + O(3^9)]
+[O(3^10), 1 + O(3^10), O(3^10), 1 + O(3^10), O(3^10)]
+[5 + 2*5^2 + 2*5^3 + 2*5^4 + 5^6 + 5^8 + 5^9 + 2*5^10 + 5^11 + O(5^13), O(5^
+13), 3 + 4*5 + 4*5^2 + 3*5^5 + 4*5^6 + 5^8 + 3*5^9 + 4*5^11 + 5^12 + O(5^13)
+, O(5^13), 4*5 + 4*5^3 + 5^5 + 5^6 + 2*5^7 + 3*5^8 + 4*5^10 + 5^11 + 3*5^12 
++ O(5^13)]
+[O(5^13), 4 + 3*5 + 3*5^2 + 4*5^3 + 3*5^4 + 4*5^5 + 4*5^6 + 3*5^7 + 5^8 + 2*
+5^10 + O(5^13), O(5^13), 2 + 2*5^2 + 3*5^3 + 3*5^4 + 5^5 + 3*5^6 + 3*5^7 + 2
+*5^8 + 5^9 + 4*5^10 + 4*5^11 + 4*5^12 + O(5^13), O(5^13)]
+[1 + 3*5 + 5^2 + 4*5^3 + 5^6 + 3*5^7 + 5^8 + 2*5^9 + 5^10 + 2*5^11 + O(5^13)
+, O(5^13), 4 + 3*5^2 + 3*5^3 + 5^5 + 2*5^6 + 2*5^7 + 5^8 + 4*5^9 + 3*5^10 + 
+5^12 + O(5^13), O(5^13), 1 + 2*5 + 5^2 + 5^3 + 5^5 + 4*5^6 + 3*5^8 + 5^9 + 2
+*5^11 + 2*5^12 + O(5^13)]
+[4 + 7 + 5*7^2 + 5*7^3 + 2*7^4 + 2*7^5 + 3*7^6 + 7^7 + 4*7^8 + 3*7^9 + 4*7^1
+0 + 3*7^12 + 2*7^13 + 7^14 + O(7^15), O(7^15), 4 + 2*7 + 7^2 + 4*7^4 + 5*7^5
+ + 5*7^6 + 6*7^7 + 2*7^8 + 6*7^9 + 7^10 + 6*7^11 + 7^12 + 2*7^13 + 3*7^14 + 
+O(7^15), O(7^15), 1 + 6*7 + 7^2 + 2*7^3 + 3*7^4 + 5*7^6 + 4*7^7 + 3*7^8 + 2*
+7^9 + 6*7^10 + 4*7^11 + 7^12 + 6*7^13 + 5*7^14 + O(7^15), O(7^15), 4 + 3*7 +
+ 5*7^2 + 6*7^3 + 7^4 + 3*7^5 + 2*7^6 + 4*7^7 + 6*7^9 + 4*7^11 + 5*7^12 + 3*7
+^13 + 2*7^14 + O(7^15)]
+[O(7^15), 2 + 3*7 + 4*7^2 + 3*7^3 + 2*7^4 + 4*7^7 + 4*7^8 + 3*7^9 + 7^10 + 7
+^11 + 2*7^12 + 4*7^13 + 2*7^14 + O(7^15), O(7^15), 5 + 6*7 + 6*7^2 + 2*7^3 +
+ 3*7^5 + 5*7^6 + 3*7^7 + 2*7^8 + 5*7^9 + 7^10 + 3*7^11 + 4*7^12 + 2*7^13 + 7
+^14 + O(7^15), O(7^15), 1 + 7 + 5*7^2 + 2*7^3 + 3*7^4 + 5*7^5 + 5*7^7 + 6*7^
+8 + 7^9 + 3*7^10 + 2*7^11 + 3*7^12 + 7^14 + O(7^15), O(7^15)]
+[1 + 3 + 3^3 + 3^4 + 2*3^5 + 3^6 + 3^9 + O(3^11), O(3^11), 1 + 3^2 + 2*3^4 +
+ 3^7 + 2*3^8 + 2*3^9 + 2*3^10 + O(3^11)]
+[1 + 7 + 3*7^2 + 7^3 + 3*7^4 + 5*7^5 + 5*7^6 + 6*7^8 + 7^9 + 5*7^10 + O(7^11
+), O(7^11), 4 + 2*7 + 6*7^2 + 3*7^3 + 3*7^4 + 4*7^5 + 7^6 + 7^7 + 7^9 + 3*7^
+10 + O(7^11)]
+[O(7^11), 1 + 2*7 + 3*7^2 + 4*7^3 + 7^5 + 7^6 + 4*7^9 + 4*7^10 + O(7^11), O(
+7^11)]
+[7 + 3*7^2 + 7^3 + 3*7^4 + 6*7^5 + 5*7^7 + 2*7^8 + 6*7^9 + 5*7^10 + O(7^11),
+ O(7^11), 5*7 + 6*7^3 + 6*7^4 + 7^5 + 5*7^6 + 7^7 + 3*7^8 + 6*7^9 + 5*7^10 +
+ O(7^11)]
+[3 + 5*7 + 2*7^2 + 5*7^3 + 6*7^4 + 4*7^5 + 6*7^6 + 2*7^7 + 2*7^8 + 6*7^9 + 5
+*7^10 + 2*7^11 + 5*7^12 + O(7^13), O(7^13), O(7^13), O(7^13), 2 + 7 + 5*7^2 
++ 5*7^3 + 3*7^4 + 3*7^5 + 7^6 + 3*7^7 + 6*7^8 + 4*7^9 + 3*7^11 + 2*7^12 + O(
+7^13)]
+[O(7^13), 5 + 6*7 + 3*7^2 + 7^4 + 6*7^5 + 7^6 + 7^7 + 7^9 + 2*7^10 + 7^11 + 
+O(7^13), O(7^13), 3 + 4*7 + 7^2 + 3*7^3 + 6*7^4 + 6*7^5 + 3*7^6 + 4*7^7 + 4*
+7^10 + 4*7^11 + O(7^13), O(7^13)]
+[6*7^2 + 4*7^3 + 2*7^4 + 6*7^5 + 4*7^6 + 2*7^9 + O(7^10), O(7^10), O(7^10), 
+O(7^10), 2*7^2 + 2*7^3 + 6*7^4 + 7^5 + 2*7^6 + 3*7^7 + 3*7^8 + 6*7^9 + O(7^1
+0)]
+[O(7^10), 5*7 + 6*7^2 + 5*7^3 + 3*7^4 + 6*7^5 + 6*7^6 + 6*7^7 + 6*7^8 + 6*7^
+9 + O(7^10), O(7^10), 6*7 + 6*7^2 + 2*7^3 + 5*7^4 + 6*7^5 + 6*7^6 + 6*7^7 + 
+6*7^8 + 6*7^9 + O(7^10), O(7^10)]
+[[3^-1 + 1 + 2*3 + 3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3
+^9 + 2*3^10 + 2*3^11 + O(3^12), 2*3^-1 + 2 + 2*3 + 2*3^2 + 3^3 + 2*3^4 + 3^5
+ + O(3^12)]~, [O(3^12), O(3^12)]~, [3^-2 + 2*3^-1 + 1 + O(3^12), 3^-2 + 3^-1
+ + 1 + 2*3 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 
++ 2*3^11 + O(3^12)]~, [O(3^12), O(3^12)]~, [3^-1 + 2 + 2*3 + 2*3^2 + 2*3^3 +
+ 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + O(3^12), 
+2*3^-1 + 1 + 3^3 + O(3^12)]~]
+[[3*5^-1 + 2*5 + 4*5^2 + 4*5^3 + 4*5^4 + 4*5^5 + 4*5^6 + 4*5^7 + 4*5^8 + 4*5
+^9 + 4*5^10 + O(5^11), 3*5^-1 + 3 + 3*5 + 3*5^2 + O(5^13)]~, [O(5^11), O(5^1
+3)]~, [3*5^-1 + 1 + O(5^11), 3*5^-1 + 4 + 2*5 + 4*5^2 + 4*5^3 + 4*5^4 + 4*5^
+5 + 4*5^6 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11 + 4*5^12 + O(5^13)]~]
+[[2 + 3^2 + 3^4 + 2*3^5 + O(3^13), 2 + 3^4 + 3^6 + 2*3^8 + 3^9 + 2*3^10 + 2*
+3^11 + 2*3^12 + 2*3^13 + O(3^14)]~, [O(3^13), O(3^14)]~, [O(3^13), O(3^14)]~
+, [O(3^13), O(3^14)]~, [1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*
+3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + O(3^13), 1 + 2*3 + 3^4 + O(
+3^14)]~]
+[[1 + 2^2 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + 2^10 + 2^11 + 2^12 + 2^13 + 2^14 +
+ 2^15 + 2^16 + 2^17 + O(2^18), 2 + 2^3 + 2^7 + 2^9 + 2^10 + O(2^18)]~, [O(2^
+18), O(2^18)]~, [2^-1 + 2 + 2^3 + 2^5 + 2^6 + 2^9 + 2^10 + 2^13 + 2^14 + 2^1
+7 + O(2^18), 2^-1 + 1 + 2^2 + 2^3 + 2^5 + 2^6 + 2^7 + 2^9 + 2^12 + 2^13 + 2^
+16 + 2^17 + O(2^18)]~, [O(2^18), O(2^18)]~, [2^-1 + 2^2 + 2^3 + 2^4 + 2^6 + 
+2^7 + 2^8 + 2^10 + 2^11 + 2^12 + 2^14 + 2^15 + 2^16 + O(2^18), 2^-1 + 1 + 2 
++ 2^3 + 2^4 + 2^6 + 2^10 + 2^14 + O(2^18)]~, [O(2^18), O(2^18)]~, [1 + O(2^1
+8), 2 + 2^6 + 2^7 + 2^8 + 2^9 + 2^10 + 2^11 + 2^12 + 2^13 + 2^14 + 2^15 + 2^
+16 + 2^17 + O(2^18)]~]
+[[2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^8 + 2^11 + 2^14 + O(2^18), 2^4 + 2^7 + 2^9 +
+ 2^10 + 2^13 + 2^14 + 2^16 + 2^17 + O(2^18)]~, [O(2^18), O(2^18)]~, [1 + 2^2
+ + 2^3 + 2^7 + 2^11 + 2^13 + 2^15 + 2^17 + O(2^18), 1 + 2^5 + 2^8 + 2^11 + 2
+^12 + 2^13 + O(2^18)]~, [O(2^18), O(2^18)]~, [1 + 2^3 + 2^5 + 2^6 + 2^7 + 2^
+10 + 2^12 + 2^14 + 2^16 + O(2^18), 1 + 2^2 + 2^3 + 2^5 + 2^6 + 2^8 + 2^9 + 2
+^11 + O(2^18)]~, [O(2^18), O(2^18)]~, [2 + 2^2 + 2^4 + 2^7 + O(2^18), 2^4 + 
+2^6 + 2^7 + 2^8 + 2^10 + 2^12 + 2^14 + 2^15 + 2^16 + 2^17 + O(2^18)]~]
+[2^6 + 2^7 + 2^8 + 2^9 + O(2^10), O(2^10), 2^6 + 2^7 + 2^9 + O(2^10), O(2^10
+), 2^6 + 2^7 + 2^8 + 2^9 + O(2^10), O(2^10), 2^6 + 2^7 + 2^9 + O(2^10)]
+[[2*7^-1 + 5 + 7 + 4*7^2 + O(7^17), 5*7^-1 + 5 + 6*7^2 + 5*7^3 + 4*7^4 + 2*7
+^5 + 2*7^7 + 2*7^9 + 6*7^10 + 6*7^11 + 6*7^12 + 6*7^13 + 6*7^14 + 6*7^15 + 6
+*7^16 + O(7^17)]~, [O(7^17), O(7^17)]~, [5*7^-2 + 5*7^-1 + 2 + 4*7 + 6*7^2 +
+ 6*7^3 + 6*7^4 + 6*7^5 + 6*7^6 + 6*7^7 + 6*7^8 + 6*7^9 + 6*7^10 + 6*7^11 + 6
+*7^12 + 6*7^13 + 6*7^14 + 6*7^15 + 6*7^16 + O(7^17), 4*7^-2 + 1 + 6*7 + 2*7^
+2 + 6*7^3 + 6*7^4 + 6*7^5 + 2*7^6 + O(7^17)]~, [O(7^17), O(7^17)]~, [6*7^-2 
++ 5*7^-1 + 6*7 + 2*7^2 + 7^3 + 4*7^4 + 5*7^5 + 2*7^6 + 7^7 + 4*7^8 + 5*7^9 +
+ 2*7^10 + 7^11 + 4*7^12 + 5*7^13 + 2*7^14 + 7^15 + 4*7^16 + O(7^17), 2*7^-2 
++ 7^-1 + 2 + 2*7 + 4*7^2 + 3*7^3 + 4*7^5 + 5*7^6 + 2*7^7 + 7^8 + 4*7^9 + 5*7
+^10 + 2*7^11 + 7^12 + 4*7^13 + 5*7^14 + 2*7^15 + 7^16 + O(7^17)]~, [O(7^17),
+ O(7^17)]~, [6*7^-2 + 6*7^-1 + 4 + 6*7 + 6*7^2 + 6*7^3 + 6*7^4 + 6*7^5 + 6*7
+^6 + 6*7^7 + 6*7^8 + 6*7^9 + 6*7^10 + 6*7^11 + 6*7^12 + 6*7^13 + 6*7^14 + 6*
+7^15 + 6*7^16 + O(7^17), 2*7^-2 + 6*7^-1 + 6*7 + 7^2 + 2*7^3 + 2*7^4 + 2*7^5
+ + O(7^17)]~, [O(7^17), O(7^17)]~, [4*7^-1 + 2 + O(7^17), 3*7^-1 + 5 + 2*7 +
+ 4*7^2 + 7^3 + 4*7^7 + 6*7^8 + 6*7^9 + 6*7^10 + 6*7^11 + 6*7^12 + 6*7^13 + 6
+*7^14 + 6*7^15 + 6*7^16 + O(7^17)]~]
+Total time spent: 6468
diff --git a/src/test/32/nf b/src/test/32/nf
index 3844f02..04f605d 100644
--- a/src/test/32/nf
+++ b/src/test/32/nf
@@ -1,6 +1,10 @@
 [85997496, [42998748, 2], [[408188227, 99620635; 0, 1], [2, 1; 0, 1]]]
 12.340047278667903334059769086970462209
 4.1894250945222025884896456921310573069
+  *** bnfinit: Warning: non-monic polynomial in bnfinit, using polredbest.
+[1, [], []]
+  *** bnfinit: Warning: non-monic polynomial in bnfinit, using polredbest.
+[1, [], []]
 20915648110955829231381594293324156411897455346679838307589120000
 571459344155975480004612560667633185714077696
 [54898, [54898], [[7, 0; 0, 1]]]
@@ -443,4 +447,8 @@ d(-62626/622201*y - 860751/622201, y^2 - 5), x^10 + 5*x^9 + 15*x^8 + 30*x^7
   ***                 ^--------------------
   *** nfcompositum: incorrect priority in nffactor: variable y >= x
 [x^3 - 3*x^2 + 3*x + 1, x^6 + 3*x^5 + 6*x^4 + 11*x^3 + 12*x^2 - 3*x + 1]
-Total time spent: 1271
+  ***   at top-level: nfcompositum(bnfinit
+  ***                 ^--------------------
+  *** nfcompositum: incorrect priority in polcompositum: variable x == x
+[x^3 - 3*x^2 + 3*x + 1, x^6 + 3*x^5 + 6*x^4 + 11*x^3 + 12*x^2 - 3*x + 1]
+Total time spent: 2004
diff --git a/src/test/32/nfhilbert b/src/test/32/nfhilbert
index 84ac7e8..fc2458b 100644
--- a/src/test/32/nfhilbert
+++ b/src/test/32/nfhilbert
@@ -69,18 +69,18 @@ p = 0:
 1: 1
 2: 1
 3: 1
-4: error("inconsistent moduli in hilbert: 2 != oo")
-5: error("inconsistent moduli in hilbert: 4 != oo")
-6: error("inconsistent moduli in hilbert: 8 != oo")
-7: error("inconsistent moduli in hilbert: 3 != oo")
-8: error("inconsistent moduli in hilbert: 5 != oo")
+4: error("inconsistent moduli in hilbert: 2 != \"oo\"")
+5: error("inconsistent moduli in hilbert: 4 != \"oo\"")
+6: error("inconsistent moduli in hilbert: 8 != \"oo\"")
+7: error("inconsistent moduli in hilbert: 3 != \"oo\"")
+8: error("inconsistent moduli in hilbert: 5 != \"oo\"")
 9: error("inconsistent moduli in hilbert: 0 != 2")
 10: error("inconsistent moduli in hilbert: 0 != 2")
 11: error("inconsistent moduli in hilbert: 0 != 5")
 p = 2:
 1: 1
 2: -1
-3: error("inconsistent moduli in hilbert: 2 != oo")
+3: error("inconsistent moduli in hilbert: 2 != \"oo\"")
 4: error("precision too low in hilbert.")
 5: error("precision too low in hilbert.")
 6: 1
@@ -92,7 +92,7 @@ p = 2:
 p = 5:
 1: 1
 2: 1
-3: error("inconsistent moduli in hilbert: 5 != oo")
+3: error("inconsistent moduli in hilbert: 5 != \"oo\"")
 4: error("inconsistent moduli in hilbert: 2 != 5")
 5: error("inconsistent moduli in hilbert: 4 != 5")
 6: error("inconsistent moduli in hilbert: 8 != 5")
@@ -104,4 +104,4 @@ p = 5:
 -1
 -1
 1
-Total time spent: 1084
+Total time spent: 1052
diff --git a/src/test/32/nfields b/src/test/32/nfields
index 43e92f6..4768aee 100644
--- a/src/test/32/nfields
+++ b/src/test/32/nfields
@@ -202,7 +202,7 @@ x + 318920215718580450], 1/83718587879473471], [[49744, 0, 0; 0, 49744, 0; 0
 38840187320655696/83718587879473471*x^5 + 5180390720553188700/83718587879473
 471*x^4 - 8374015687535120430/83718587879473471*x^3 + 8907744727915040221/83
 718587879473471*x^2 + 4155976664123434381/83718587879473471*x + 318920215718
-580450/83718587879473471, -1, y^3 - y - 1, x^5 - x - 2], [0]]
+580450/83718587879473471, -1, y^3 - y - 1, x^5 - x - 2], [0, 0]]
 ? bnfcertify(bnf)
 1
 ? dobnf(x^4+24*x^2+585*x+1791,,[0.1,0.1])
diff --git a/src/test/32/nfsplitting b/src/test/32/nfsplitting
index 3040b0a..c0e3d5d 100644
--- a/src/test/32/nfsplitting
+++ b/src/test/32/nfsplitting
@@ -45,4 +45,8 @@ x^32 - 10356*x^24 + 127847862*x^16 - 11069073684*x^8 + 565036352721
 x^10 - 30*x^8 + 325*x^6 - 1500*x^4 + 2500*x^2 + 2000
 x^22 + x^21 + x^20 + x^19 + x^18 + x^17 + x^16 + x^15 + x^14 + x^13 + x^12 +
  x^11 + x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
-Total time spent: 372
+x^42 + 48020*x^28 + 96001584*x^14 + 52706752
+x^42 + 48020*x^28 + 96001584*x^14 + 52706752
+  *** nfsplitting: Warning: ignoring incorrect degree bound 43.
+x^42 + 48020*x^28 + 96001584*x^14 + 52706752
+Total time spent: 332
diff --git a/src/test/32/padic b/src/test/32/padic
index 4a35740..faf7f34 100644
--- a/src/test/32/padic
+++ b/src/test/32/padic
@@ -104,4 +104,6 @@ O(x)
 101 + 50*101^2 + 84*101^3 + 41*101^4 + 89*101^5 + 4*101^6 + 34*101^7 + 10*10
 1^8 + 77*101^9 + O(101^10)
 []~
-Total time spent: 0
+[]~
+[]~
+Total time spent: 8
diff --git a/src/test/32/parallel b/src/test/32/parallel
index 53b9373..712e8f2 100644
--- a/src/test/32/parallel
+++ b/src/test/32/parallel
@@ -21,6 +21,7 @@ Vecsmall([188, 722, 752])
 7432339208719
 [75, 85070591730234615858594180193637120807]
 4037913
+4037913
 122000794103870768
 36
 65
diff --git a/src/test/32/polred b/src/test/32/polred
index 14f6af7..656272f 100644
--- a/src/test/32/polred
+++ b/src/test/32/polred
@@ -69,4 +69,5 @@ x^16 - 4*x^15 - 334*x^14 + 264*x^13 + 32231*x^12 + 57392*x^11 - 1031422*x^10
  - 3628868*x^9 + 7185297*x^8 + 42417784*x^7 + 11283472*x^6 - 137773504*x^5 -
  127243504*x^4 + 69059728*x^3 + 56307944*x^2 - 6264432*x + 6436
   ***   Warning: new stack size = 25165824 (24.000 Mbytes).
-Total time spent: 5340
+x^5 + 5*x - 1
+Total time spent: 4393
diff --git a/src/test/32/qfisom b/src/test/32/qfisom
index 411fa2e..eed1da3 100644
--- a/src/test/32/qfisom
+++ b/src/test/32/qfisom
@@ -3,6 +3,8 @@
 78382080
 78382080
 78382080
+78382080
+78382080
 339738624
 339738624
 339738624
@@ -24,4 +26,4 @@ OK
 [12, 4]
 [12, 4]
 [12, 4]
-Total time spent: 920
+Total time spent: 972
diff --git a/src/test/32/ramanujantau b/src/test/32/ramanujantau
index aa6fce1..d7a224e 100644
--- a/src/test/32/ramanujantau
+++ b/src/test/32/ramanujantau
@@ -1,3 +1,7 @@
 1
 -804352952075176386846143824455748
-Total time spent: 708
+0
+0
+0
+-6048
+Total time spent: 644
diff --git a/src/test/32/ranges b/src/test/32/ranges
index 85597ec..5f9adcb 100644
--- a/src/test/32/ranges
+++ b/src/test/32/ranges
@@ -21,6 +21,11 @@
 [1, 2, 3, 4]
 [3, 4, 5]
 [1, 2, 4, 5]
+[]
+[]
+[]
+[]
+[]
 Vecsmall([2, 3])
 Vecsmall([1, 2, 3, 4])
 Vecsmall([3, 4, 5])
diff --git a/src/test/32/rfrac b/src/test/32/rfrac
index 066de55..4afa106 100644
--- a/src/test/32/rfrac
+++ b/src/test/32/rfrac
@@ -2,7 +2,8 @@ y^2/x
 (32*b^4 + 128*b^3 + 80*b^2 + 16*b + 1)/(32*b^3 + 40*b^2 + 12*b + 1)
 (x^408 - x^306 - x^102 + 1)/(x^510 + 1)
 (-x^994 + x^497)/(x^1491 + 1)
+((1 + O(3^5))*x + (1 + O(3^5)))/((1 + O(3^5))*x + (2 + O(3^5)))
 [1, 0]
 0
 0.E-38/x
-Total time spent: 3004
+Total time spent: 2232
diff --git a/src/test/32/rnf b/src/test/32/rnf
index 6629421..2157b7e 100644
--- a/src/test/32/rnf
+++ b/src/test/32/rnf
@@ -65,9 +65,9 @@ at(1), Mat(1), Mat(1), 1, Mat(1), [1, 0], []], [0.E-57], [1], Mat(1), Mat(1)
 [x, -1]
   *** rnfisnorm: Warning: useless flag in rnfisnorm: the extension is Galois.
 [1, 2]
-[(-1451837462/360375*x^3 + 4372012019/360375*x^2 + 34789922587/360375*x - 75
-933670573/360375)*t + (-200284867/93*x^3 + 604108834/93*x^2 + 4792007039/93*
-x - 10464784139/93), 30/31*x^3 - 45/31*x^2 - 600/31*x + 447/31]
+[(23744929442/360375*x^3 + 109626697/120125*x^2 - 640450701997/360375*x - 20
+8304418339/120125)*t + (-1027687659/31*x^3 - 42693506/93*x^2 + 27718910683/3
+1*x + 81139328311/93), 30/31*x^3 - 45/31*x^2 - 600/31*x + 447/31]
 Mod(x^5 + x^2 + 2, x^6 + x^5 + x^4 + x^3 + x^2 + x + 1)
 Mod(z^2, z^3 + z^2 - 2*z - 1)
 [[1, 0, 0; 0, 1, 0; 0, 0, 1], [1, 1, 1]]
@@ -206,7 +206,7 @@ Mod(-y, y^3 - 21)
 10:
 [Mod(y^2 + 1/2*y, y^3 - 21), Mod(1, y^3 - 21)]~
 Mod(x + Mod(1/2*y, y^3 - 21), x^2 + Mod(-y, y^3 - 21))
-Mod(x + Mod(1/2*y, y^3 - 21), x^2 - y)
+Mod(x + Mod(1/2*y, y^3 - 21), x^2 + Mod(-y, y^3 - 21))
 Mod(1/2*x^2 + x, x^6 - 21)
 error("inconsistent moduli in nf_to_scalar_or_basis: x^2 - y != y^3 - 21")
 error("domain error in rnfeltdown: element not in the base field")
@@ -243,39 +243,39 @@ error("inconsistent moduli in rnfeltabstorel: y^2 + 1 != x^6 - 21")
 error("inconsistent dimensions in rnfalgtobasis.")
 error("inconsistent operation 'RgV_RgC_mul' t_VEC (2 elts) , t_COL (1 elts).
 ")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 error("incorrect type in rnfeltreltoabs (t_COL).")
 error("incorrect type in nf_to_scalar_or_basis (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltdown (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 15:
 [1, 2]~
 Mod(2*x + Mod(-2*y^2 + 1, y^3 - 21), x^2 + Mod(-y, y^3 - 21))
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 error("incorrect type in rnfeltreltoabs (t_COL).")
 error("incorrect type in nf_to_scalar_or_basis (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltdown (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 16:
 [1, Mod(y, y^3 - 21)]~
 Mod(Mod(y, y^3 - 21)*x + Mod(-20, y^3 - 21), x^2 + Mod(-y, y^3 - 21))
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 error("incorrect type in rnfeltreltoabs (t_COL).")
 error("incorrect type in nf_to_scalar_or_basis (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltdown (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 17:
 error("incorrect type in rnfalgtobasis (t_COMPLEX).")
 error("incorrect type in nf_to_scalar_or_alg (t_COMPLEX).")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 error("incorrect type in rnfeltreltoabs (t_COL).")
 error("incorrect type in nf_to_scalar_or_basis (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltdown (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 18:
 error("incorrect type in rnfalgtobasis (t_POL).")
 error("incorrect type in rnfbasistoalg (t_POL).")
@@ -426,31 +426,31 @@ error("domain error in rnfeltdown: element not in the base field")
 error("inconsistent dimensions in rnfalgtobasis.")
 error("inconsistent operation 'RgV_RgC_mul' t_VEC (2 elts) , t_COL (1 elts).
 ")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 error("incorrect type in rnfeltreltoabs (t_COL).")
 1
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
+1
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 12:
 [1, 2]~
 Mod(2*x + 1, x^2 + 1)
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 error("incorrect type in rnfeltreltoabs (t_COL).")
 error("incorrect type in nf_to_scalar_or_basis (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltdown (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 13:
 error("inconsistent dimensions in rnfalgtobasis.")
 error("inconsistent operation 'RgV_RgC_mul' t_VEC (2 elts) , t_COL (1 elts).
 ")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 error("incorrect type in rnfeltreltoabs (t_COL).")
 Mod(y, x^2 - 2*x + 2)
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
-error("incorrect type in rnfeltabstorel (t_COL).")
+error("incorrect type in rnfeltdown (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
+error("incorrect type in rnfeltabstorel, apply nfinit(rnf) (t_COL).")
 1:
 x^2 - 4*x + 4
 2:
@@ -481,12 +481,17 @@ Mod(1, x^2 - 2)
 0
 [[1, -66328; 0, 1], [[280970, 12259, 35869; 0, 1, 0; 0, 0, 1], [1, 1/2, 1/2;
  0, 1/2, 0; 0, 0, 1/2]]]
+1
 [280970, x^2 + 12259, x^4 + 35869, -x^4 + x - 66328, -1/2*x^4 + 1/2*x^3 - 33
 164*x^2 + 1/2*x - 66349/2, 1/2*x^5 - 66329/2*x^4 - 21/2*x^2 + 1/2*x - 33164]
 1
+[[3, [0, 1, 0, 0, 0, 0]~, 6, 1]]
+[[[7, [0, 1, 0]~, 3, 1]], [[7, [0, 1, 0, 0, 0, 0]~, 6, 1]]]
 [18416, x^2 + 6979, x^4 + 3879, -9208*x^4 + 9208*x, -6979/2*x^4 + 1/2*x^3 + 
 6979/2*x - 21/2, 1/2*x^5 - 3879/2*x^4 - 21/2*x^2 + 3879/2*x]
 1
+1
+1
 
 [280970 12259 35869]
 
@@ -496,6 +501,7 @@ Mod(1, x^2 - 2)
 
 [280970, x^2 + 12259, x^4 + 35869, -140485*x^4 + 140485*x, -12259/2*x^4 + 1/
 2*x^3 + 12259/2*x - 21/2, 1/2*x^5 - 35869/2*x^4 - 21/2*x^2 + 35869/2*x]
+1
 1:
 [[1, 0; 0, 1], [2, 1]]
 [2, 2*x^2, 2*x^4, -x^4 + x, x^3 - 21, x^5 - 21*x^2]
@@ -686,14 +692,14 @@ error("inconsistent variables in nf_to_scalar_or_basis, x != y.")
 441
 [21, Mod(Mod(y, y^3 - 21), x^2 + Mod(-y, y^3 - 21))]
 20:
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealabstorel (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
+[[;], []]
+[]
+[[;], []]
+[;]
 []
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
+[;]
+0
+[0, 0]
 21:
 [[;], []]
 []
@@ -732,25 +738,28 @@ error("inconsistent dimensions in rnfidealabstorel.")
 error("inconsistent dimensions in rnfidealabstorel.")
 error("inconsistent dimensions in rnfidealabstorel.")
 25:
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealabstorel (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
+error("inconsistent dimensions in rnfidealabstorel.")
+error("inconsistent dimensions in rnfidealabstorel.")
+error("inconsistent dimensions in rnfidealabstorel.")
+error("incorrect type in idealhnf [wrong dimension] (t_MAT).")
 [18416, x^2 + 6979, x^4 + 3879, -9208*x^4 + 9208*x, -6979/2*x^4 + 1/2*x^3 + 
 6979/2*x - 21/2, 1/2*x^5 - 3879/2*x^4 - 21/2*x^2 + 3879/2*x]
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
+error("inconsistent dimensions in rnfidealabstorel.")
+error("inconsistent dimensions in rnfidealabstorel.")
+error("inconsistent dimensions in rnfidealabstorel.")
 26:
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealabstorel (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("inconsistent operation 'RgV_RgC_mul' t_VEC (3 elts) , t_COL (6 elts).
-")
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
-error("incorrect type in rnfidealhnf (t_MAT).")
+[[1, -66328; 0, 1], [[280970, 12259, 35869; 0, 1, 0; 0, 0, 1], [1, 1/2, 1/2;
+ 0, 1/2, 0; 0, 0, 1/2]]]
+[280970, x^2 + 12259, x^4 + 35869, -x^4 + x - 66328, -1/2*x^4 + 1/2*x^3 - 33
+164*x^2 + 1/2*x - 66349/2, 1/2*x^5 - 66329/2*x^4 - 21/2*x^2 + 1/2*x - 33164]
+[[1, -66328; 0, 1], [[280970, 12259, 35869; 0, 1, 0; 0, 0, 1], [1, 1/2, 1/2;
+ 0, 1/2, 0; 0, 0, 1/2]]]
+[280970, 12259, 35869; 0, 1, 0; 0, 0, 1]
+error("incorrect type in nf_to_scalar_or_basis (t_COL).")
+[561940, 12259, 316839; 0, 1, 0; 0, 0, 1]
+561940
+[280970, Mod(x + Mod(-140485*y + 110026, y^3 - 21), x^2 + Mod(-y, y^3 - 21))
+]
 27:
 [[1, -66328; 0, 1], [[280970, 12259, 35869; 0, 1, 0; 0, 0, 1], [1, 1/2, 1/2;
  0, 1/2, 0; 0, 0, 1/2]]]
@@ -814,4 +823,4 @@ error("inconsistent operation 'RgV_RgC_mul' t_VEC (3 elts) , t_COL (2 elts).
   ***                 ^--------------------
   *** rnfidealtwoelt: incorrect type in idealtyp [non-square t_MAT] (t_MAT).
 0
-Total time spent: 636
+Total time spent: 824
diff --git a/src/test/32/rnfkummer b/src/test/32/rnfkummer
index bd371fe..467ea6d 100644
--- a/src/test/32/rnfkummer
+++ b/src/test/32/rnfkummer
@@ -120,8 +120,8 @@ x^2 + (8*y - 109)
 x^2 + (485/684*y^7 + 65/76*y^6 - 3010/57*y^5 - 1220/19*y^4 + 11125/12*y^3 + 
 4555/4*y^2 - 23555/9*y - 3360)
 18
-x^3 + (-29*y^3 + 156*y^2 + 403*y - 4767)*x + (-430655/6*y^3 + 1953316/3*y^2 
-- 10148915/6*y - 7987262/3)
+x^3 + (29*y^3 - 156*y^2 - 403*y + 4767)*x + (-582335/6*y^3 + 840637/3*y^2 + 
+22819345/6*y - 72890309/3)
 19
 [x^3 - 3*x - 1]
 20
@@ -132,4 +132,4 @@ x^5 - 10*x^3 + 5*x^2 + 10*x + 1
 x^2 + (3158/5*y^3 + 1123*y^2 - 185813/5*y - 66076)
 x^2 + (-200*y^2 + 380*y - 265)
 x^2 + (-429*y^2 - 312*y - 624)
-Total time spent: 7972
+Total time spent: 6732
diff --git a/src/test/32/rootsreal b/src/test/32/rootsreal
index 2179f55..d58aff9 100644
--- a/src/test/32/rootsreal
+++ b/src/test/32/rootsreal
@@ -53,6 +53,9 @@
 3
 2
 3
+[]~
+[]~
+[0.E-38]~
 [1.2599210498948731647672106072782283506]~
 [-1.2599210498948731647672106072782283506]~
 2
@@ -61,5 +64,23 @@
   ***   at top-level: polsturm((x^4-2)^2)
   ***                 ^-------------------
   *** polsturm: domain error in polsturm: issquarefree(pol) = 0
+[-2.0000000000000000000000000000000000000]~
+1
+1
+1
+1
+1
+1
+1
+1
+1
+[0.59441447601624956642908249516963028371]~
+[-1.1451026912004224304268100262663119669, 0.4760236029181340344691576771197
+9045497, 3.6690790882822883959576523491465215119]~
+[0.E-38, 0.E-38, 1.0000000000000000000000000000000000000]~
+[0.E-38, 0.E-38, 1.0000000000000000000000000000000000000, 2.0000000000000000
+000000000000000000000, 2.0000000000000000000000000000000000000, 2.0000000000
+000000000000000000000000000, 3.0000000000000000000000000000000000000, 3.0000
+000000000000000000000000000000000]~
 19
-Total time spent: 89
+Total time spent: 92
diff --git a/src/test/32/ser b/src/test/32/ser
index 8738d44..f1c610b 100644
--- a/src/test/32/ser
+++ b/src/test/32/ser
@@ -90,4 +90,6 @@ Mod(0, 2)*x^-1 + O(x^0)
 1
 1
 0
-Total time spent: 2
+1 + O(x^200)
+1
+Total time spent: 36
diff --git a/src/test/32/sqrtn b/src/test/32/sqrtn
index 48b9d59..27d9916 100644
--- a/src/test/32/sqrtn
+++ b/src/test/32/sqrtn
@@ -1,3 +1,4 @@
+0.E-38
 0.E-12
 0.E-12 + 0.E-12*I
 0.79370052598409973737585281963615413020
diff --git a/src/test/32/trans b/src/test/32/trans
index 483a614..df8604f 100644
--- a/src/test/32/trans
+++ b/src/test/32/trans
@@ -305,7 +305,7 @@
 1500909352126758407037897070495877541155382167014686679926985084543258893429
 2523223786390424776086340213091005298521362801566765133992860125583585795444
 9639568300115324366185686646564753267835392477541687524855810599859189805331
-4864484749494393924622766968581269240091451867
+4864484749494393924622766968581269240091451873
 ? log(2)
 0.69314718055994530941723212145817656807550013436025525412068000949339362196
 9694715605863326996418687542001481020570685733685520235758130557032670751635
@@ -435,4 +435,4 @@ x^17 - 1
 763732423 E-8*I
 ? if(getheap()!=HEAP,getheap())
 ? print("Total time spent: ",gettime);
-Total time spent: 17
+Total time spent: 12
diff --git a/src/test/in/algebras b/src/test/in/algebras
index ac3e2f2..f212733 100644
--- a/src/test/in/algebras
+++ b/src/test/in/algebras
@@ -1533,8 +1533,6 @@ print(al2b);
 print("csa al3");
 al3 = alginit(nf, matrixringmt(3), 'x);
 print("al3 contains nfabs: ", algsplittingfield(al3)[12][1] != 0);
-al3b = al3; al3b[1][12][1] = 0; \\ depends on 32/64bit
-print(al3b);
 
 \\limit cases
 print("trivial algebra over a quadratic field");
diff --git a/src/test/in/bnr b/src/test/in/bnr
index 62ba8be..ab45afb 100644
--- a/src/test/in/bnr
+++ b/src/test/in/bnr
@@ -67,3 +67,12 @@ bnr=bnrinit(bnfinit(x^2-97),1,1); bnrrootnumber(bnr,[])
 
 bnfnarrow(bnfinit(x^2-460))
 bnrconductor(bnfinit(K),4,Mat(3))
+
+\\#1804
+K=bnfinit(y^2-5);
+bnr = bnrinit(K,[1,[1,1]]);
+bnrdisc(bnr)
+bnrdisc(bnr,,,1)
+bnrdisc(bnr,,,2)
+bnrdisc(K,[1,[1,0]],,2)
+bnrdisc(K,[1,[0,0]],,2)
diff --git a/src/test/in/charpoly b/src/test/in/charpoly
index 846b020..600d4a7 100644
--- a/src/test/in/charpoly
+++ b/src/test/in/charpoly
@@ -28,6 +28,7 @@ matadjoint([Mod(1,2)*x,0,0;0,0,0;0,0,0])
 charpoly(x*matid(3))
 minpoly(Mod(x+1,x^4+1))
 minpoly(Mod(x,x^2))
+minpoly(Mod(1,x^2+x+1))
 
 a=[1,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0;0,1,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0;0,0,1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0;-1,-1,-1,4,0,0,0,0,-1,0,0,0,0,0,0,0,0;0,0,0,0,1,0,0,-1,0,0,0,0,0,0,0,0,0;0,0,0,0,0,1,0,-1,0,0,0,0,0,0,0,0,0;0,0,0,0,0,0,1,-1,0,0,0,0,0,0,0,0,0;0,0,0,0,-1,-1,-1,4,-1,0,0,0,0,0,0,0,0;0,0,0,-1,0,0,0,-1,4,-1,-1,0,0,0,0,0,0;0,0,0,0,0,0,0,0,-1,1,0,0,0,0,0,0,0;0,0,0,0,0,0,0,0,-1,0,4,-1,-1,-1,0,0,0;0,0,0,0,0,0,0,0,0,0,-1,1,0,0,0,0,0;0,0,0,0,0,0,0,0,0,0,-1,0,1,0,0,0,0;0,0,0,0,0,0,0,0,0,0,-1 [...]
 mateigen(a);
diff --git a/src/test/in/chinese b/src/test/in/chinese
index 1159cba..4b86fb6 100644
--- a/src/test/in/chinese
+++ b/src/test/in/chinese
@@ -4,5 +4,7 @@ chinese(Mod(1,2)*x+Mod(1,2), Mod(2,3)*x^2+Mod(1,3)*x+Mod(1,3))
 chinese([Mod(1,2),Mod(1,3)], [Mod(1,4),Mod(1,2)])
 chinese(1)
 chinese([])
-m1=Mod(0,1);m2=Mod(1,x^2+1);chinese(m1,m2)
+chinese(Mod(1+x,x^2),Mod(0,1))
+chinese(Mod(1+x,x^2),Mod(1,2))
+chinese(Mod(0,1),Mod(1+x,x^2))
 
diff --git a/src/test/in/digits b/src/test/in/digits
index 88fea86..05c15c0 100644
--- a/src/test/in/digits
+++ b/src/test/in/digits
@@ -20,7 +20,12 @@ binary([0,1])
 binary(I)
 vector(10, i, sumdigits(123456789, i+1))
 digits(2^128+3, 2^64)
+digits(999999999999999,4294967295)
 sumdigits(2^128+3, 2^64)
 
 0x12345
+0x1234567890ABCDEF987654321
+0x0000000000000000012345
 0b11011011
+0b1011011101111011111011111101111111011111111011111111101111111111
+0b000000000000000000000000000000000000000000000000000000000000000011011011
diff --git a/src/test/in/ell b/src/test/in/ell
index 0332563..dd8a295 100644
--- a/src/test/in/ell
+++ b/src/test/in/ell
@@ -152,6 +152,8 @@ e = ellinit([1,1,0,-1740,22184]);
 z=-3.0059315873096303229151114945365166621 + 0.E-36*I/2;
 ellztopoint(e,z)
 
+\\#1800
+ellztopoint(ellinit([-1,0]), I)
 
 \\#1186
 ellmul(ellinit([3,0]), [1,2], -quadgen(-4))
@@ -240,7 +242,9 @@ for (i=1,#J,
   my(e = ellinit(ellfromj(J[i])));
   my(v = ellan(e,200));
   print("\n", e.j);
-  forprime(p = 127, 200, print1(v[p]," "))
+  forprime(p = 127, 200, print1(v[p]," "));
+  print();
+  forprime(p = 2^65, 2^65+1000, print1(ellap(e,p)," "));
 );
 }
 
diff --git a/src/test/in/ellff b/src/test/in/ellff
index b2086eb..1859be4 100644
--- a/src/test/in/ellff
+++ b/src/test/in/ellff
@@ -143,3 +143,18 @@ check(q)=
 check(2^4)
 check(3^4)
 check((2^64+13)^4)
+
+checkext(p)=
+{
+  b=ffgen(p,'a);
+  E=ellinit([1,0,0,0,1],p);
+  a=ffgen(p^6,'b);
+  F=ellinit(E,a);
+  P=random(F);
+  if (!ellisoncurve(F,P),error(p));
+  if(!ellisoncurve(F,ellmul(F,P,2)),error(p));
+}
+checkext(5)
+checkext(3)
+checkext(2)
+
diff --git a/src/test/in/ellpadic b/src/test/in/ellpadic
index 2a1aab2..a7c85da 100644
--- a/src/test/in/ellpadic
+++ b/src/test/in/ellpadic
@@ -1,5 +1,3 @@
-default(parisize,"40M");
-
 e=ellinit([1,-1,1,-1,-14]);
 E=ellinit([0,0,0,-e.c4/48,-e.c6/864]);
 P=[1,-1/4;0,1];
@@ -14,13 +12,10 @@ E=ellinit([1,-1,1,0,0]);P=[0,0];
 ellpadicheight(E,2,4, P)
 ellpadicheight(E,3,4, P)
 ellpadicheight(E,5,4, P)
+
 E=ellinit([0,-1,1,-10,-20]);P=[5,5];
 ellpadicheight(E,19,6, P)
 ellpadicheight(E,19,0, P)
-ellpadicL(E,2,5)
-
-E=ellinit([0,1,1,-9,-15]);
-ellpadicL(E,2,5)
 
 E=ellinit([0,0,1,-4,2]);P=[-2,1];
 ellpadicheight(E,3,5, P)
@@ -52,30 +47,3 @@ E=ellinit([1, -1, 1, 0, 0]);
 ellpadicfrobenius(E,5,7)
 E=ellinit([0,0,1,-4,2]);
 ellpadicfrobenius(E,3,5)
-
-e=ellinit([1,-1,1,-1,-14]);p=3;\\supersingular
-L=ellpadicL(e,p,4)
-F=[0,-p;1,ellap(e,p)];\\Frobeniusmatrixinthebasis(omega,F(omega)
-Lf=(1-p^{-1}*F)^-2*L~
-Lf/bestappr(ellL1(e,0)/e.omega[1])
-
-p=5;\\ordinary
-L=ellpadicL(e,p,4)
-al=polrootspadic(x^2-ellap(e,p)*x+p,p,7)[2];
-(1-al^(-1))^(-2)*L/bestappr(ellL1(e,0)/e.omega[1])
-
-e=ellinit([-4831,-129242]);p=3;\\supersingular
-L=ellpadicL(e,p,4);
-F=[0,-p;1,ellap(e,p)];
-Lf=(1-p^{-1}*F)^-2*L~;
-Lf/bestappr(ellL1(e,0)/e.omega[1])
-
-e=ellinit([1,-1,1,-3,3]);p=3;
-L=ellpadicL(e,p,4);
-F=[0,-p;1,ellap(e,p)];
-Lf=(1-p^{-1}*F)^-2*L~;
-Lf/bestappr(ellL1(e,0)/e.omega[1])
-
-e=ellinit([0,0,1,-4,2]);p=3;n=3;
-ellpadicL(e,p,n)
-
diff --git a/src/test/in/ellweilpairing b/src/test/in/ellweilpairing
index 52eed98..383b1cb 100644
--- a/src/test/in/ellweilpairing
+++ b/src/test/in/ellweilpairing
@@ -41,6 +41,7 @@ check([0,0,1,0,0],[126,78],[89,78],2,157);
 check([0,0,1,0,0],[150,89],[150,89],2,179);
 check([0,0,1,0,0],[22,95],[22,95],2,191);
 check([0,0,0,1,3],[4,1],[4,6],6,7);
+check([0,0,0,0,2],[3,1],[3,1], 3,7);
 
 t=ffgen(Mod(1,2)*(t^6+t^5+t^3+t^2+1));
 E=ellinit([0,0,1,0,0],t);
@@ -48,6 +49,51 @@ P=[t^2+t+1,t+1];
 Q=[t^5+t^3+t^2,t^5+t^4+t^3+t^2+t+1];
 ellweilpairing(E,P,Q,3)
 elltatepairing(E,P,Q,3)
+elltatepairing(E,P,P,3)
+elltatepairing(E,Q,Q,3)
+
+t=ffgen(ffinit(3,6),'t);
+E=ellinit([0,0,0,1,0],t);
+P=[2*t^5+2*t^4+t^2+2*t+2,2*t^5+t^4+t^3+2*t^2+1];
+Q=[t^4+t^3+t^2+t+2,t^5+2*t^4+2*t^2+t];
+ellweilpairing(E,P,Q,28)
+elltatepairing(E,P,Q,28)
+elltatepairing(E,P,P,28)
+elltatepairing(E,Q,Q,28)
+
+t=ffgen(ffinit(5,6),'t);
+E=ellinit([0,0,1,0,0],t);
+P=[4*t^5+4*t^4+3*t^3+2*t^2+2*t,4*t^5+4*t^4+2*t^3+2*t^2+4];
+Q=[t^5+2*t^4+4*t^3+2*t^2+4*t+1,2*t^5+t^4+3*t+1];
+ellweilpairing(E,P,Q,126)
+elltatepairing(E,P,Q,126)
+elltatepairing(E,P,P,126)
+elltatepairing(E,Q,Q,126)
+
+t=ffgen(2^4,'t);
+E=ellinit([1,0,0,0,t^3+t^2+t+1]);
+Q=[t^3+t^2,t+1];
+elltatepairing(E,Q,Q,5)^3
+
+t=ffgen(3^6,'t);
+E=ellinit([0,2*t^5+2*t^3+t^2+t+1,0,0,t^3+2*t^2+t]);
+Q=[2*t^5+2*t^4+t^3+2*t^2+2*t+1,2*t^5+t^2];
+elltatepairing(E,Q,Q,8)^91
+
+t=ffgen(5^4,'t);
+E=ellinit([0,0,0,4*t^3+4*t^2+4*t+1,3*t^3+2]);
+Q=[3*t^3+2*t^2+1,3*t^2+4*t];
+elltatepairing(E,Q,Q,48)^13
+
+p=nextprime(2^65);
+t=ffgen(p^2,'t);
+E=ellinit([t^2,0]);
+[N]=ellgroup(E)
+d=(p^2-1)/N;
+P=[14078684373865444404*t+24675141949190748313,34082614562121616748*t+9184592839883218620];
+Q=[3606608601291892434*t+22502667145150289531,23709671617839429105*t+22495649567796533868];
+ellweilpairing(E,P,Q,N)
+elltatepairing(E,P,Q,N)^d
 
 test(p) =
 {
@@ -59,4 +105,3 @@ test(p) =
 }
 test(3);
 test(5);
-p=nextprime(2^65);a=ffgen(p^2,'a);ellgroup(ellinit([a^0,0]))
diff --git a/src/test/in/equal b/src/test/in/equal
index ddf674d..3f1e757 100644
--- a/src/test/in/equal
+++ b/src/test/in/equal
@@ -55,3 +55,5 @@ for (i=1,#v, print([v[i]==1,v[i]==-1]))
 
 A=Ser(vector(40000,i,i==1));
 A==A
+
+Mod(Mod(y,y^2+1),x^2-2) == Mod(y,y^2+1)
diff --git a/src/test/in/err b/src/test/in/err
index 640045e..e622ae3 100644
--- a/src/test/in/err
+++ b/src/test/in/err
@@ -257,3 +257,6 @@ trap (e_INV, INFINITY, log(0))
 a=1;
 notafunc('a)
 a
+n=1<<10000;
+znlog(Mod(1,n),Mod(1,n+1))
+Mod(0,n)^(-1)
diff --git a/src/test/in/factorff b/src/test/in/factorff
new file mode 100644
index 0000000..de66a3e
--- /dev/null
+++ b/src/test/in/factorff
@@ -0,0 +1,55 @@
+do(f,p,T)=centerlift(lift(polrootsff(f,p,T)));
+do(x^3+x^2+x-1,3,t^3+t^2+t-1)
+t = ffgen(3^3,'t); do((x^3+x^2+x-1)*t^0, t.p, t.mod)
+polrootsff(x^4+1,2,y^2+y+1)
+t = ffgen(('t^2+'t+1)*Mod(1,2));
+factorff(x^12 + t*x^10 + x^6 + (t+1)*x^2 + 1)
+
+\\ #1241
+polrootsff(x^2 - x - ffgen((v^2+1) * Mod(1,3)))
+\\ #1350
+polrootsff(2*x+1,2,y)
+
+t = ffgen(5^4,'t);
+factor((x^24-1)*t^0)
+factorff(Pol(0),t.p,t.mod)
+factorff(Pol(1),t.p,t.mod)
+factorff(x^4-t,t.p,t.mod)
+
+p = nextprime(2^96); a = ffgen(p^3,'a);
+P=(x-1)*(x-a)*(x-a^2)*(x-a-1)*subst(ffinit(p,2),x,x+a)*ffinit(p,4);
+polrootsff(P)
+factorff(P)
+
+check(P)=my(V=polrootsff(P));for(i=1,#V,if(subst(P,x,V[i])!=0,error(P)));#V;
+a=ffgen([3,2],'a);check((x^2+a*x)^3*(x+1))
+a=ffgen([2,2],'a);check((x^2+a*x)^2*(x+1))
+a=ffgen([3,107],'a);check(x^107+2*x^3+a^0)
+a=ffgen([3,37],'a);check(subst(x^37+x^3+x^2+2*x+2,x,x+a))
+{
+  my(s);
+  a=ffgen([2,2],'a);
+  forvec(v=vector(6,i,[0,3]),
+    P = x^7+Polrev([(x\2)*a+x|x<-v]);
+    s += check(P));
+  s
+}
+{
+  my(s);
+  a=ffgen([2,3],'a);
+  forvec(v=vector(4,i,[0,7]),
+    P = x^6+Polrev([(x\4)*a^2+(x\2)*a+x|x<-v])*x+1;
+    s += check(P));
+  s
+}
+{
+  my(s);
+  a=ffgen([3,2],'a);
+  forvec(v=vector(4,i,[0,8]),
+    P = x^6+Polrev([(x\3)*a+x|x<-v])*x+1;
+    s += check(P));
+  s
+}
+a=ffprimroot(ffgen([2,10],'a));check(factorback(vector(200,i,x-a^i)))
+a=ffprimroot(ffgen([3,7],'a)); check(factorback(vector(1000,i,x-a^i)))
+a=ffprimroot(ffgen([nextprime(2^100),2],'a));check(factorback(vector(200,i,x-a^i)))
diff --git a/src/test/in/factormod b/src/test/in/factormod
index 2558c54..e2ec3dd 100644
--- a/src/test/in/factormod
+++ b/src/test/in/factormod
@@ -1,7 +1,17 @@
 print(lift(factorcantor(x^1024+1,12289)))
-setrand(4); lift(factormod(y^3-3*y-1,2238004061))
+check(P,p)=
+{
+  my(F=factormod(P,p));
+  my(G=factorcantor(P,p));
+  if(F!=G || factorback(F)!=P,error(P));
+  F[,1]=apply(poldegree,F[,1]);
+  F~;
+}
+setrand(4); check(y^3-3*y-1,2238004061)
 \\#1451
-lift(factormod(x^31+x^30+x^29+x^28+x^26+x^24+x^23+x^21+x^16+x^15+x^14+x^11+x^10+x^9+x^8+x^7+x^3+x^2+x,2))
+check(x^31+x^30+x^29+x^28+x^26+x^24+x^23+x^21+x^16+x^15+x^14+x^11+x^10+x^9+x^8+x^7+x^3+x^2+x,2)
+localbitprec(1000);check(Polrev(binary(round(Pi*2^1000))),2)
+
 polrootsmod(x^16-1,41,1)
 polrootsmod(x^5+x^2-4*x+2,5,1)
 polrootsmod(Pol(0),2)
diff --git a/src/test/in/ff b/src/test/in/ff
index 8ed968c..0612d9a 100644
--- a/src/test/in/ff
+++ b/src/test/in/ff
@@ -26,7 +26,7 @@ factor(x^6-a*x^3+1),
 jell(ellinit([a,1])),
 a/x,
 (x+a)/(x-a),
-b=ffprimroot(a),
+if(1,setrand(1);b=ffprimroot(a)),
 fforder(a),
 b^fflog(a,b),
 factorff(x^2+x+a),
@@ -40,37 +40,26 @@ test(7, 7)
 test(precprime(2^32), 3)
 test(nextprime(2^32), 3)
 
+ftest(p,n,r)=
+{
+  my(a=ffgen(ffinit(p,n),'a)^r);
+  if(sqrtn(a,r)^r!=a,error([p,n,r]));
+}
+
+ftest(2,1005,7);
 ffgen(ffinit(2^32-5,101),'a)^10000
 ffgen(ffinit(2^64-59,101),'a)^10000
 
 for(i=1,10,print(ffnbirred(11,i)));
 for(i=1,10,print(ffnbirred(11,i,1)));
 
-do(f,p,T)=centerlift(lift(polrootsff(f,p,T)));
-do(x^3+x^2+x-1,3,t^3+t^2+t-1)
-t = ffgen(3^3,'t); do((x^3+x^2+x-1)*t^0, t.p, t.mod)
-polrootsff(x^4+1,2,y^2+y+1)
-
 t = ffgen(2^64)^((2^64-1)\5);1/t
 
-t = ffgen(('t^2+'t+1)*Mod(1,2));
-factorff(x^12 + t*x^10 + x^6 + (t+1)*x^2 + 1)
-
-\\ #1241
-polrootsff(x^2 - x - ffgen((v^2+1) * Mod(1,3)))
-\\ #1350
-polrootsff(2*x+1,2,y)
 sqrt(Mod(-1,4296540161))
 sqrt(Mod(-1,18446744073944432641))
 centerlift(factorcantor(prod(i=-10,10,(x^2-i)),2^64+13)[,1])
-#polrootsff(x^107+2*x^3+1,3,ffinit(3,107,'a))
 ffgen(x^2+x+Mod(1,3))
 conjvec(Mod(x, x^2+Mod(1,3)))
-t = ffgen(5^4,'t);
-factor((x^24-1)*t^0)
-factorff(Pol(0),t.p,t.mod)
-factorff(Pol(1),t.p,t.mod)
-factorff(x^4-t,t.p,t.mod)
 
 test(q)=
 {
diff --git a/src/test/in/gamma b/src/test/in/gamma
index 07ca5e5..de210ea 100644
--- a/src/test/in/gamma
+++ b/src/test/in/gamma
@@ -2,10 +2,12 @@ default(realprecision,38);
 default(seriesprecision,6);
 gamma(2+I+x)
 gamma(1+x)
+gamma(2+x)
 gamma(-2+x)
 lngamma(2+I+x)
 lngamma(1+x)
 lngamma(-2+x)
+lngamma(2+x)
 lngamma(1)
 lngamma(1.)
 psi(2+I+x)
@@ -13,12 +15,18 @@ psi(1+x)
 psi(-2+x)
 gamma(-1/2+x)
 gamma(1+a*x+O(x^2))
+lngamma(1+a*x+O(x^2))
+gamma(O(x))
+lngamma(O(x))
+psi(O(x))
 
 psi(x)
 gamma(x)
 gamma(1000)
 psi(2^400)
 psi(-1.5)
+psi(x+O(x^2))
+gamma(x+O(x^2))
 
 binomial(2^64+1,2)
 binomial(1001.,1000)
diff --git a/src/test/in/gcdext b/src/test/in/gcdext
index 6c6d0a5..90eb2c6 100644
--- a/src/test/in/gcdext
+++ b/src/test/in/gcdext
@@ -12,6 +12,9 @@ AA=truncate(lift(lift(FF)));
 BB=truncate(lift(lift(GG)));
 gcdext(AA,BB)
 gcd(x*Mod(1,7),x*Mod(1,7))
+a=ffgen([3,5],'a);
+gcd((x^2+a*x+1)*(x+a),(x^3+a*x^2+a*x)*(x+a))
+gcdext(x^2+a*x+1,x^3+a*x^2+a*x)
 
 gcd(2*I, 1+I)
 gcd(I*1., I+1.)
diff --git a/src/test/in/hyperell b/src/test/in/hyperell
index 20cd9b6..db84a35 100644
--- a/src/test/in/hyperell
+++ b/src/test/in/hyperell
@@ -1,5 +1,6 @@
 checkfeq(P,q)=
 {
+  for(i=0,poldegree(P),if (type(polcoeff(P,i))!="t_INT",error(dbg_x(P))));
   my(M=minpoly(Mod(x+q/x,P)));
   if(poldegree(M)!=poldegree(P)/2,error([P,q,M]));
   M;
@@ -31,6 +32,16 @@ checkfeq(P,q)=
     print(checkfeq(H,p^3)));
 }
 
+{
+  my(a,P,Q,E);
+  a=ffgen([5,5],'a);
+  setrand(3);
+  for (i=1, 10,
+    P=random(a*x^3); H=hyperellcharpoly(P);
+    E=ellinit(ellfromeqn('y^2-P));
+    if(ellap(E)!=-polcoeff(H,1),error(H)));
+}
+
 g=ffgen(ffinit(79,2),'g);
 P=hyperellcharpoly(x^5+g*x^3+2*x+5);checkfeq(P,79^2)
 P=hyperellcharpoly(g*(x^5+g*x^3+2*x+5));checkfeq(P,79^2)
@@ -50,6 +61,7 @@ P=hyperellcharpoly([x^6+x+1,x^3]*Mod(1,2));checkfeq(P,2)
 P=hyperellcharpoly([x^2+x+1,x^3]*Mod(1,2));checkfeq(P,2)
 P=hyperellcharpoly([x^3+x+1,x^3]*Mod(1,2));checkfeq(P,2)
 P=hyperellcharpoly([x^4+x+1,x^3]*Mod(1,2));checkfeq(P,2)
+g=ffgen(ffinit(7,3),'g);P=hyperellcharpoly(x^5+g);checkfeq(P,7^3)
 
 hyperellcharpoly((256*a^5+5)*Mod(1,5))
 hyperellcharpoly((256*a^5+5)*ffgen(5^2))
diff --git a/src/test/in/incgam b/src/test/in/incgam
index 0bde7e1..995723e 100644
--- a/src/test/in/incgam
+++ b/src/test/in/incgam
@@ -1,5 +1,5 @@
-Vs=[0,1/2,10-I,1+128*I,60,30+60*I];
-Vx=[19+236*I,1/10,-1/10,I/10,-I/10,1/10-I/10,100,-100,100+1001*I];
+Vs=[0,10^-10,10^-100,200,-21/2,1/2,10-I,1+128*I,60,30+60*I];
+Vx=[19+236*I,1/10,-1/10,I/10,-I/10,1/10-I/10,50,100,-100,100+1001*I];
 
 test(fun, p) =
 {
@@ -9,8 +9,8 @@ test(fun, p) =
       my (v,w, s = Vs[i], x = Vx[j]);
       localprec(p);      v = fun(s, x);
       localprec(p + 38); w = fun(s, x);
-\\      e = abs((v-w)/w);
-      e = if (abs(w) < 1, abs(v-w), abs((v-w)/w));
+      e = abs((v-w)/w);
+\\      e = if (abs(w) < 1, abs(v-w), abs((v-w)/w));
       if (e > P, printf("%9s, %13s: %.1e\n", s,x,e));
     )
   );
@@ -18,28 +18,20 @@ test(fun, p) =
 
 test(incgam, 19)
 test(incgam, 38)
+test(incgam, 77)
 test(incgam, 96)
+test(incgam, 115)
 
-mylog(x)=if(x==0, "oo", round(log(abs(x))/log(10)));
+Vs=[1/10+1/5*I,-1/10,-1/10+2/5*I,2/5*I,-2/5*I,-1,-20,-200001/10000];
+Vx=[11/10,13/10,1/10000];
 
-Vs=[1/10+1/5*I,-1/10,-1/10,-1/10+2/5*I,-1/10+2/5*I,2/5*I,2/5*I,-2/5*I,-2/5*I,-1,-1,-20,-200001/10000];
-Vx=[13/10,1/10000,13/10,13/10,1/10000,11/10,1/10000,11/10,1/10000,1/10000,11/10,11/10,11/10];
-
-localprec(100); VR = vector(#Vs,j,incgam(Vs[j]*1.,Vx[j]*1.));
-test(fun, prec)=
-{
-  localprec(prec);
-  for(j=1,#Vs,
-    res = fun(Vs[j]*1.,Vx[j]*1.) - VR[j];
-    print(j, ": ", mylog(res))
-  );
-}
 test(incgam, 38)
 test(incgam, 76)
 
 default(realprecision, 38);
 incgam(1/2,10^8)
 incgam(-3,20)
+incgam(1/5,50)
 
 eint1(-0.3-95*I)
 eint1(100)
diff --git a/src/test/in/ispower b/src/test/in/ispower
index 1b2a5bc..d65e54b 100644
--- a/src/test/in/ispower
+++ b/src/test/in/ispower
@@ -72,6 +72,11 @@ issquare(Mod(1,2))
 issquare(Mod(0,2),&s);s
 issquare(Mod(2,3))
 issquare(Mod(13,121))
+issquare(Mod(Mod(1,2)*y,y^3+y^2+1))
+if (issquare(Mod(Mod(1,2)*y,y^3+y^2+1),&b),b)
+issquare(Mod(Mod(1,5)*y+2,y^3+y^2+1))
+if (issquare(Mod(Mod(1,5)*y,y^3+y^2+1),&b),b)
+if (issquare(Mod(Mod(4,5),y^3+y^2+1),&b),b)
 
 default(realprecision,38);
 if(issquare(Pol(0),&z),z)
@@ -130,3 +135,15 @@ issquare(Mod(3,22))
 ispower(-167^10)
 \\#1782
 isprimepower(30011^(17*3))
+
+do(f,k) = ispower(f,k,&z) && z^k == f;
+test(t) =
+{ my(T = x^3+x^2+t);
+  [do(T,3), do(T^6,3), do(T^9,3), do(T^18,3), do(T^18,9), do(T^18,18)];
+}
+test(Mod(1,2))
+test(ffgen(2^3,'t))
+test(ffgen(3^3,'t))
+test(Mod(Mod(1,2),y^3+y^2+1))
+ispower(Mod(x,x^2+1), 2, &y)
+ispower(Mod(x,x^2+1), 2)
diff --git a/src/test/in/iterator b/src/test/in/iterator
index c9a76c6..4c76169 100644
--- a/src/test/in/iterator
+++ b/src/test/in/iterator
@@ -2,15 +2,19 @@ default(realprecision,38);
 N = 1<<64;
 for(a=N-2, N+2, print(a))
 for(a=-N-2, -N+2, print(a))
+for(n=2,oo,if(n>10,break);print(n))
 
 forprime(p=2^32-50,2^32+30,print(p))
 forprime(p=2^64-70,2^64+50,print(p))
+forprime(n=2,,if(n>10,break);print(n)) /*backward compat */
+forprime(n=2,oo,if(n>10,break);print(n))
 
 for(a=0.5,3,print(a))
 for(a=1,10, print(a+=2))
 
 forstep(a=5,1,-2,print1(a," "))
 forstep(a=1,10,[1,3],print1(a," "))
+my(s=1,a=0);forstep(i=1,20,s,s++;a+=i);a
 
 forprime(p=2,10,p=4)
 
diff --git a/src/test/in/lfun b/src/test/in/lfun
index c565fe8..eb586f1 100644
--- a/src/test/in/lfun
+++ b/src/test/in/lfun
@@ -11,6 +11,7 @@ L117=lfuncreate([n->dirdiv(dirzetak(nfinit('x^4-'x^3-'x^2+'x+1),n),zetaan(n)),0,
 for(i=1,10,print(i,":",lfun(L117,i)))
 e121=ellinit([1,1,1,-30,-76]);  \\ 121a1
 L121=lfuninit(e121,[100],2);
+lfuncost(L121)
 lfun(L121,1+100*I)
 lfun(L121,1+x+O(x^3))
 
@@ -18,9 +19,13 @@ lfun(1,1+x+O(x^4),1)
 
 lfun(polcyclo(12),2)
 
+lfun(lfunmul(1,1),1)
+lfun(lfunmul(x^2+1,x^2+1),1)
+lfun(lfundiv(x^2+1,-4),1)
+
 \\ check for loss in accuracy in lfunthetaspec
 pol=x^5-5*x^3-x^2+3*x+1;
-nf24217=dirzetak(nfinit(pol),32000);
+nf24217=dirzetak(nfinit(pol),32254);
 L2=lfuncreate([n->nf24217[1..n],0,[0,0,0,0,0],1,24217,1,0]);
 lfunhardy(L2,5)
 
@@ -33,6 +38,8 @@ lfun(lzeta,1/2+200*I)
 lfun(lzeta,.5+200*I)
 lfun(lzeta,0,1)
 lfun(lzeta,x)
+lfunzeros(lzeta,14.14)
+lfunzeros(lzeta,[14,14.5])
 lfunzeros(lzeta,30)
 lzeta[6]=0; lfun(lzeta,2)
 /* odd Dirichlet char */
@@ -45,6 +52,9 @@ lfunzeros(L5077,20)
 /* Ramanujan */
 ltau=lfuncreate([n->Vec(eta('x+O('x^n))^24),0,[0,1],12,1,1]);
 lfunmfspec(ltau)
+lfunsymsqspec(ltau)
+
+lfunmfpeters(ellinit([0, 1, 0, 4, 4]))
 
 /* other functions */
 t = 4+I/5;
@@ -111,11 +121,14 @@ L=lfuncreate([[(p,d)->my(id=idealprimedec(K,p));simplify(lift(prod(i=1,#id,1-Mod
 algdep(exp(lfun(L,0,1)),3)
 
 /* GENUS 2 curve */
-P=x^6+58*x^5+1401*x^4+18038*x^3+130546*x^2+503516*x+808561;
-print("Curve y^2=",P);
-hcfp(eq,p) = polrecip(hyperellcharpoly(eq*Mod(1,p)));
-L=lfuncreate([[(p,d)->hcfp(P,p),[2, 1+3*x+5*x^2+6*x^3+4*x^4], [13, 1+5*x+13*x^2] ], 0, [0,0,1,1], 2, 169, 1]);
-default("realprecision",19)
+print("Curve y^2+(x^3+x^2+1)*y = x^2+x");
+L=lfungenus2([x^2+x,x^3+x^2+1]);
+default("realprecision",19);
+lfuncheckfeq(L)
+
+print("Curve y^2+(x^2+x)*y = x^6+3*x^5+6*x^4+7*x^3+6*x^2+3*x+1");
+L=lfungenus2([x^6+3*x^5+6*x^4+7*x^3+6*x^2+3*x+1,x^2+x]);
+L[5]*=4;
 lfuncheckfeq(L)
 
 print("Curve y^2=",x^5+x);
@@ -184,6 +197,11 @@ E5=ellinit([a,1-a,1,-1,0],K2);
 L5=lfuncreate([[g(K2,E5),[2,1-x^2],[5,(1+x)*(1+5*x^2)]],0,[0,0,1,1],2,19^2*20,1]);
 lfuncheckfeq(L5)
 lfunlambda(L5,1)
+K3=bnfinit(a^2-a-9);
+E6=ellinit([0,2,1,-19-8*a,28+11*a],K3);
+L6=lfuncreate([g(K3,E6),0,[0,0,1,1],2,37^2,1]);
+lfuncheckfeq(L6)
+lfunlambda(L6,1)
 
 print("check all formats");
 default("realprecision",54)
@@ -294,9 +312,7 @@ lfunconductor(lnf725,,1)
  * remark: should be able to search in a big range
  * with few coefficients, would be faster
  */
-lim=100000;
-nf24217=dirzetak(nfinit(x^5-5*x^3-x^2+3*x+1),lim);
-nf24217z=dirdiv(nf24217,vector(lim,k,1));
+nf24217z=dirdiv(nf24217,vector(#nf24217,k,1));
 lnf24217=lfuncreate([n->nf24217z[1..n],0,[0,0,0,0],1,24217,1]);
 lfunconductor(lnf24217,10^5,1)
 
@@ -313,3 +329,5 @@ localbitprec(20); #lfunzeros('x^2-2,6)
 lfuncost(1, [100], 5)
 L = lfuninit(polcyclo(5), [1/2,1/2,50]);
 lfuncost(L)
+
+lfun(1,2000)
diff --git a/src/test/in/lfuntype b/src/test/in/lfuntype
index 5c11add..ce5dd50 100644
--- a/src/test/in/lfuntype
+++ b/src/test/in/lfuntype
@@ -6,29 +6,35 @@ VALL={
 lfuncreate([n->vector(n,i,kronecker(i,857)),0,[0],1,857,1]),
 lfunthetainit(zet),
 lfuninit(zet,[1,1,2],2),
+\\5
 lfuninit(x^3-x-1,[1,1,2],2),
 lfuninit(x^4-2,[1,1,2],2),
+lfuninit(x^6+108,[1,1,2],2),
 lfuninit(polsubcyclo(11,5),[1,1,2],2),
 x^3-x-1,
+\\10
 x^4-2,
 polsubcyclo(11,5),
 17,
 -4,
 857,
+\\15
 [idealstar(,5),2],
 ellinit([0,-1,1,-10,-20]),  \\ 11a1
 ellinit([1,1]),
-ellinit([0,0,0,-7,3]),
+ellinit([-7,3]),
 lfunetaquo([1,1;3,1;5,1;15,1]),
+\\20
 lfunsymsq(ellinit([0,-1,1,-10,-20])),  \\ 11a1
 lfunmul(-4,-3),
 lfundiv(x^3-x-1,1),
 bnfinit(x^4+2*x^2+5),
 [bnrinit(bnfinit(x^3+x^2+2*x+1),4),[1]],
+\\25
 Z(2),
 lfunqf(matid(4)),
    if(1,my(N=nfinit(x^10-2*x^8-9*x^6+57*x^4-69*x^2+47),G=galoisinit(N));
-L=lfunartin(N,G,[['a,0;0,'a^-1],[0,1;1,0]],5))
+L=lfunartin(N,G,[['a,0;0,'a^4],[0,1;1,0]],5))
 ];
 }
 
diff --git a/src/test/in/lift b/src/test/in/lift
index 4db29b2..090bcf2 100644
--- a/src/test/in/lift
+++ b/src/test/in/lift
@@ -1,6 +1,6 @@
 v=[Mod(y,y^2+1), Mod(1,z), Mod(2,3), 1+O(3)];
 T=Pol(v,'x);
-Z=[1, Mod(5,3), "x", 3+O(3^3), -1/3+O(3), Mod(x,x^2), x*Mod(1,3) + Mod(2,3)];
+Z=[1, Mod(5,3), "x", 3+O(3^3), -1/3+O(3), Mod(x,x^2), x*Mod(1,3) + Mod(2,3), (1+2*x+3*x^2+O(x^4))*Mod(1,5)];
 F=[lift, a->lift(a,'x), a->lift(a,'y), a->lift(a,'z), centerlift,liftall,liftint,liftpol];
 {
   for(i=1,#F,
diff --git a/src/test/in/map b/src/test/in/map
index 6e17458..73b5085 100644
--- a/src/test/in/map
+++ b/src/test/in/map
@@ -54,8 +54,16 @@ MV=[M0,M1,M2,M3,M4];
 [a==b|a<-MV;b<-MV]
 [a===b|a<-MV;b<-MV]
 
+M=Map();
+mapput(M,2,3);
+mapdelete(M,2);
+M
+mapisdefined(M,2)
+mapput(M,2,3);M
+
 M=Map([1,2;3,4;5,6]);
 mapget(M,7)
 mapdelete(M,7)
 Vec(M,1)
 Vec(M,-1)
+Map([1,2;2,3;1,3;1,4])
diff --git a/src/test/in/modsym b/src/test/in/modsym
index b7fc20a..dc73a42 100644
--- a/src/test/in/modsym
+++ b/src/test/in/modsym
@@ -1,27 +1,47 @@
-allocatemem(100*10^6)
+allocatemem(30*10^6)
 N = 11;
 W2 = msinit(N,2,-1);
 W1 = msinit(N,2,1);
 W = msinit(N,2);
+msgetsign(W2)
+msgetsign(W1)
+msgetsign(W)
+msgetlevel(W)
+msgetweight(W)
 mshecke(W2, 2)
 mshecke(W1, 2)
 mshecke(W, 2)
 mshecke(W1, 11)
 
-E=ellinit([1,2]);
-[W,xpm]= msfromell(E);
+E = ellinit([1,2]);
+[W,xpm] = msfromell(E);
 mseval(W,xpm[1],[1/2,1/3])
-E=ellinit([0,-1,1,-10,-20]);
-[W,xpm]= msfromell(E,1);
+E = ellinit([0,-1,1,-10,-20]);
+[W,xpm] = msfromell(E,1);
 mseval(W,xpm,[1/2,1/3])
 E=ellinit([1,-1,1,-1,-14]);
-[W,xpm]= msfromell(E,1);
+[W,xpm] = msfromell(E,1);
 mseval(W,xpm)
 mseval(W,xpm,[0,1/3])
 
-N = 227;
+check_twist(e) = msfromell(ellinit(e))[2];
+check_twist([0,1]) \\36a1
+check_twist([0,-1,1,-7,10]) \\121b1
+check_twist([1,-1,0,0,-5]) \\45a1
+check_twist([0,0,1,-3,-5]) \\99d1
+check_twist([0,0,1,0,-7])  \\27a1
+check_twist([1,-1,1,-1,-14])\\17a1
+
+N = 227
 W = msinit(N,2,1);
-mssplit(W, msnew(W))
+Wnew = msnew(W);
+mssplit(W, Wnew)
+#mssplit(W, Wnew, 1)
+#mssplit(W, Wnew, 2)
+#mssplit(W, Wnew, 3)
+
+W = msinit(11,6,1);
+mssplit(W,msnew(W))
 
 N = 1000;
 W = msinit(N,2,1);
@@ -59,14 +79,15 @@ S == mscuspidal(W)
 msfromcusp(W,1)
 msfromcusp(W,oo)
 msfromcusp(W,1/2)
+msfromhecke(W, [[2,-2],[3,-1]])
 
 W = msinit(23,2, 1);
 V = mssplit(W, msnew(W));
 msqexpansion(W, V[1], 30)
 msqexpansion(W, V[1])
 
-M=msinit(603,2,1);L=msnew(M);V=mssplit(M,L);
-Set([v|v<-vector(#V,i,msqexpansion(M,V[i])),type(v[1])=="t_INT"])
+M=msinit(603,2,1);L=msnew(M);V=mssplit(M,L,1);
+Set([v|v<-vector(#V,i,msqexpansion(M,V[i]))])
 
 W = msinit(6,4);
 m=msatkinlehner(W,1)
@@ -98,10 +119,8 @@ W=msinit(17,2);
 G=mspathgens(W)[1];
 vector(#G,i,mspathlog(W,G[i]))
 
-/* slow
 W=msinit(96,6,1);
-matsize(msnew(W)[1])
-*/
+matsize(msnew(W)[1]) \\ used to be too slow
 
 check(N,k)=
 {
@@ -123,3 +142,55 @@ M=msinit(14,2,1);
 S=mscuspidal(M);
 mshecke(M,2)
 mshecke(M,2,S)
+
+M = msinit(23,4);
+S = msfromhecke(M, [[5, x^4-14*x^3-244*x^2+4832*x-19904]]);
+charpoly(mshecke(M,5,S))
+
+ellpadicmoments(e,p,n, D=1) =
+{
+  e = ellinit(e);
+  my(Wp, [M,xpm]=msfromell(e,sign(D)));
+  Wp = mspadicinit(M, p, n);
+  mspadicmoments(Wp, xpm, D)
+};
+msseries(e,p,n,i=0,D=1)={
+  my(M = ellpadicmoments(e,p,n,D));
+  mspadicseries(M,i)
+};
+
+/* good ordinary */
+M=ellpadicmoments([0,1,1,0,0],3,4) \\ 43a1
+mspadicseries(M)
+mspadicseries(M,1)
+M=ellpadicmoments([0,1,1,-9,-15],7,2) \\ 19a1
+mspadicseries(M)
+mspadicL(M,0)
+
+/* supersingular */
+M=ellpadicmoments([1,-1,1,-1,-14],3,5) \\ 17a1
+mspadicseries(M)
+mspadicseries(M,1)
+ellpadicmoments([1,-1,0,4,-3],3,5) \\ 73a1
+ellpadicmoments([1,-1,1,0,0],3,5) \\ 53a1 ,a_3=-3 rank 1
+ellpadicmoments([1,-1,1,-3,3],3,5) \\ 26b1 ,a_3=-3 rank 0
+
+E11a1=[0,-1,1,-10,-20];
+E15a1=[1,1,1,-10,-10];
+E17a1=[1,-1,1,-1,-14];
+E43a1=[0,1,1,0,0];
+E389a1=[0,1,1,-2,0];
+msseries(E11a1,3,1)
+msseries(E11a1,3,5)
+msseries(E11a1,3,5,1) \\ 1-teich component -> 0
+msseries(E11a1,3,5,2) \\ 2-teich component
+msseries(E15a1,11,7,7) \\ 2 real connected comp.
+msseries(E389a1,3,3) \\ 2 real connected comp.
+msseries(E11a1,11,7) \\ split -> trivial zero
+msseries(E43a1,3,4,0,-19) \\ twist
+msseries(E17a1,3,5) \\ supersingular
+
+M=msinit(3,6,-1); xpm=[1]~;
+Wp = mspadicinit(M,5,10);
+oms = mspadicmoments(Wp, xpm, 1);
+vector(6,j,mspadicL(oms,j-1))
diff --git a/src/test/in/mspadic b/src/test/in/mspadic
new file mode 100644
index 0000000..e5ab9a5
--- /dev/null
+++ b/src/test/in/mspadic
@@ -0,0 +1,167 @@
+default(parisize, "60M");
+
+{
+elldata= Map([
+  \\ rank 0
+  "11a1",[0,-1,1,-10,-20];
+  "14a1",[1,0,1,4,-6];
+  "15a1",[1,1,1,-10,-10];
+  "17a1",[1,-1,1,-1,-14];
+  "19a1",[0,1,1,-9,-15];
+  "26b1",[1,-1,1,-3,3];
+  "33a1",[1,1,0,-11,0];
+  "43a1",[0,1,1,0,0];
+  \\ rank 1
+  "37a1",[0,0,1,-1,0];
+  "53a1",[1,-1,1,0,0];
+  \\ rank 2
+  "389a1",[0,1,1,-2,0]
+]);
+}
+myellinit(s)= ellinit(if(type(s)=="t_STR",mapget(elldata,s),s));
+
+\\ a2 = 0
+e=myellinit("19a1");
+ellpadicL(e, 2, 5)
+
+\\ a3 = 0
+e=myellinit("17a1");p=3;
+L=ellpadicL(e,p,4)
+F=[0,-p;1,ellap(e,p)];
+(1-p^{-1}*F)^-2*L / bestappr(ellL1(e)/e.omega[1])
+
+\\ a5 = -2
+p=5;
+L=ellpadicL(e,p,4)
+al=polrootspadic(x^2-ellap(e,p)*x+p,p,7)[2];
+(1-al^(-1))^(-2)*L / bestappr(ellL1(e)/e.omega[1])
+
+\\ a3 = -3 != 0
+e=myellinit("26b1");p=3;
+L=ellpadicL(e,p,4);
+F=[0,-p;1,ellap(e,p)];
+(1-p^{-1}*F)^-2*L / bestappr(ellL1(e)/e.omega[1])
+
+\\ huge memory 1001a1
+e=ellinit([0,-1,1,-15881,778423]);p=2;n=3;
+ellpadicL(e,p,n)
+
+E=myellinit("53a1");P=[0,0];
+ellpadicL(E,2,10,,2)
+ellpadicL(E,3,10)
+ellpadicL(E,3,10,,1)
+ellpadicL(E,5,5,,2)
+
+testord(s, p, n, D = 1) =
+{
+  my(e = myellinit(s));
+  my([M,xp] = msfromell(e,1));
+  Wp = mspadicinit(M, p, n, 0);
+  mspadicmoments(Wp, xp, D);
+}
+testss(s, p, n) =
+{
+  my(e = myellinit(s));
+  my([M,xp] = msfromell(e,1));
+  Wp = mspadicinit(M, p, n);
+  mspadicmoments(Wp,xp);
+}
+
+testord("11a1", 7, 4)
+testord("17a1", 7, 4)
+testss("17a1", 3, 4)
+testord("14a1", 7, 4)
+testord("43a1", 3, 4, 29)
+
+e=myellinit("11a1");
+[M,phi]=msfromell(e,1);
+Wp = mspadicinit(M, 3, 4, 0);
+mspadicmoments(Wp, phi, 5)
+Wp = mspadicinit(M, 5, 4, 0);
+mspadicmoments(Wp, phi, -3)
+
+vchar = [0,-2,[0,1],[1,0],[2,0]];
+test(M,phi,p)=
+{ my(Wp, mu, ap);
+  ap = mshecke(M,p,phi)[1,1];
+  Wp = mspadicinit(M,p,10, valuation(ap,p));
+  mu=mspadicmoments(Wp,phi);
+  for (i=1,#vchar,
+    print(vchar[i],":");
+    for(r=0,3, print(mspadicL(mu,vchar[i],r)));
+  );
+}
+test(M,phi,3);
+test(M,phi,2);
+test(M,phi,7);
+
+e=myellinit("33a1");
+[M,phi]=msfromell(e,1);
+test(M,phi,3)
+test(M,phi,11)
+
+e=myellinit("389a1");
+[M,phi]=msfromell(e,1);
+test(M,phi,2)
+
+[M,phi]=msfromell(e,-1);
+Wp = mspadicinit(M, 3, 4, 0);
+mspadicmoments(Wp, phi, 5)
+Wp = mspadicinit(M, 5, 4, 0);
+mspadicmoments(Wp, phi, -3)
+
+\\====
+
+W = msinit(50,4,1);
+phi = mssplit(W, msnew(W), 1)[1];
+Wp = mspadicinit(W, 3, 6, 0);
+mspadicmoments(Wp, phi)
+
+Wp=mspadicinit(msinit(25,2,1),5,4, 1); \\ must fail p^2 | N
+
+M=msinit(4,6,1);
+phi=[1,8,1,-32]~; \\ v_p(ap) = 1
+Wp=mspadicinit(M,3,5, 2);
+oms=mspadicmoments(Wp, phi); \\ must fail
+Wp=mspadicinit(M,3,5, 1);
+oms=mspadicmoments(Wp, phi); \\ now succeeds
+mspadicL(oms)
+
+msnewsymb(N,k,s=1) = {
+ my(xpm,M); M=msinit(N,k,s);
+ xpm = mssplit(M,msnew(M),1)[1]; [M,xpm];
+};
+
+testmspadicL(N,k,p,signe=1,D=1) = {
+  my([M,xpm]=msnewsymb(N,k,signe));
+  my(ap = mshecke(M,p,xpm)[1,1]);
+  my(Wp,oms);
+  Wp = mspadicinit(M,p,10, if(ap,valuation(ap,p), k-1));
+  oms = mspadicmoments(Wp, xpm, D);
+  vector(k-1,j, mspadicL(oms,j-1));
+}
+\\ ordinary
+testmspadicL(3,6,3)
+testmspadicL(3,6,3,-1)
+testmspadicL(3,6,5)
+testmspadicL(3,6,5,-1)
+testmspadicL(3,6,5,-1, -3)
+testmspadicL(3,8,7)
+testmspadicL(3,8,7,-1)
+testmspadicL(5,4,3)
+testmspadicL(5,4,7)
+testmspadicL(5,4,7,-1)
+testmspadicL(5,4,7,1, 5)
+testmspadicL(11,6,7)
+testmspadicL(11,6,7,-1)
+testmspadicL(14,6,7)
+testmspadicL(14,6,7,-1)
+
+\\supersingular
+testmspadicL(4,6,3)  \\ ap=12
+testmspadicL(9,4,5)  \\ ap=0
+testmspadicL(17,6,3) \\ ap=-18
+testmspadicL(3,8,2) \\
+testmspadicL(5,8,2)
+testmspadicL(10,8,2)
+testmspadicL(3,10,7) \\ ap=9128, valuation 1
diff --git a/src/test/in/nf b/src/test/in/nf
index ad1d16d..63a15b4 100644
--- a/src/test/in/nf
+++ b/src/test/in/nf
@@ -2,6 +2,8 @@ default(realprecision,38);
 setrand(1429412696);bnfinit(x^2+29051222508*x-12).clgp
 setrand(1); bnfinit(x^8 + 12*x^6 + 30*x^4 + 24*x^2 + 4).reg
 setrand(1); bnfinit(x^4 - 3*x^2 + 49).reg
+bnfinit(x-1/2).clgp
+bnfinit(x^2-1/2).clgp
 
 nfinit(factor(polzagier(9,5))[2,1],2).disc
 nfinit(Pol([1,0,42,112,728,3248,14224,3392,289478,-804944,2966908,-11015200,17342836,-108601584,381107816,-1679988352,6252186465,-14812800240,28868620970,-27997506768,-33428758132,98285772160,-51592356424,-39975211584,55983352320,-24670808064,5337884160,-733917184,87744512])).disc
@@ -112,3 +114,6 @@ nfcompositum(nfinit(x^2+1),x^3-2,x^3-1)
 nfcompositum(nfinit(x-1),y^3-2,y^3-1)
 nfcompositum(nfinit(y-1),x^3-2,x^3-1)
 
+\\#1796
+nfcompositum(bnfinit(x),x^3-2,x^3-1)
+nfcompositum(bnfinit(y),x^3-2,x^3-1)
diff --git a/src/test/in/nfields b/src/test/in/nfields
index 06428ab..9e1ea5a 100644
--- a/src/test/in/nfields
+++ b/src/test/in/nfields
@@ -1,4 +1,4 @@
-HEAP=[166, if(precision(1.)==38,70246,71858)];
+HEAP=[166, if(precision(1.)==38,70249,71861)];
 default(realprecision,154); Pi; default(realprecision,38);
 dobnf(T,flag=0,tech=[])= setrand(1); my(K = bnfinit(T,flag,tech)); [K.cyc,K.fu];
 \e
diff --git a/src/test/in/nfsplitting b/src/test/in/nfsplitting
index 5e3dd48..55173ff 100644
--- a/src/test/in/nfsplitting
+++ b/src/test/in/nfsplitting
@@ -8,3 +8,6 @@ nfsplitting(x^8+3,32)
 nfsplitting(nfinit(x^8+3))
 nfsplitting(x^5+5/4*x+1)
 nfsplitting(polcyclo(23))
+nfsplitting(x^7-2)
+nfsplitting(x^7-2,42)
+nfsplitting(x^7-2,43)
diff --git a/src/test/in/padic b/src/test/in/padic
index 98d5d2c..d71f2fa 100644
--- a/src/test/in/padic
+++ b/src/test/in/padic
@@ -57,3 +57,8 @@ liftall( padicappr(phi, Mod(-2+O(p^prec),  v[1])) )
 
 T = teichmuller([17,10]);
 for(i=1,16,if (teichmuller(i+O(17^10),T) != teichmuller(i+O(17^10)), error(i)))
+
+\\#1793
+padicappr(x^3+1,-2+O(2^5))
+padicappr(x^3+1,Mod(-2+O(2^5),y^3+3))
+
diff --git a/src/test/in/parallel b/src/test/in/parallel
index 82503b5..5fd847b 100644
--- a/src/test/in/parallel
+++ b/src/test/in/parallel
@@ -35,7 +35,8 @@ uninline();
 
 my(N=1);until(type(A)=="t_ERROR",A=alarm(1,parfor(i=1,10,for(i=1,N,isprime(i))));N*=2);
 
-my(s);parfor(x=1,10,x!,f,s+=f);s
+my(s,L=List());parfor(x=1,10,x!,f,s+=f);s
+my(s,L=List());parfor(x=1,oo,if(x<=10,x!),f,s+=f;if(x>=10,break));s
 my(s);parforprime(p=2,20,p!,f,s+=f);s
 my(s);parforvec(v=[[1,3],[1,3]],factorback(v),f,s+=f);s
 my(s);parforvec(v=[[1,4],[1,4]],factorback(v),f,s+=f,1);s
diff --git a/src/test/in/polred b/src/test/in/polred
index 6b4e89a..d146144 100644
--- a/src/test/in/polred
+++ b/src/test/in/polred
@@ -57,3 +57,4 @@ polredabs(x^16-4*x^15-334*x^14+264*x^13+32231*x^12+57392*x^11-1031422*x^10-36288
 default(parisize, 3<<23);
 f=x^40+10*x^39+75*x^38+410*x^37+1888*x^36+7364*x^35+25310*x^34+77140*x^33+211669*x^32+524946*x^31+1183823*x^30+2430610*x^29+4548530*x^28+7743916*x^27+11954920*x^26+16627228*x^25+20626386*x^24+22445616*x^23+20835590*x^22+15611648*x^21+8209812*x^20+1290846*x^19-2562740*x^18-2525172*x^17-76374*x^16+2095346*x^15+2320830*x^14+1050748*x^13-71120*x^12-238080*x^11+31952*x^10+106808*x^9+12549*x^8-18470*x^7-485*x^6+3202*x^5-232*x^4-430*x^3+150*x^2-20*x+1;
 polredbest(f);
+polredabs(x^5 - 331137220*x^4 + 37922047405356360*x^3 - 1127174691845938128093840*x^2 + 52208293424667465123438066822480*x - 16507431553557006099641796204889368224)
diff --git a/src/test/in/qfisom b/src/test/in/qfisom
index d21c69e..8adbcd5 100644
--- a/src/test/in/qfisom
+++ b/src/test/in/qfisom
@@ -1,3 +1,4 @@
+maxdiag(M)=vecmax(vector(#M,i,M[i,i]));
 in(M,fl)=if(fl,qfisominit(M,fl),qfisominit(M));
 checkauto(M,f,fl)=
 {
@@ -13,6 +14,8 @@ checkisom(M,N,f,fl)=
 }
 qfauto(Mat(1))
 M=[4,-2,-1,1,1,-2,-2,-2,-1,-1,-1,-1;-2,4,-1,-2,-2,2,2,0,-1,-1,-1,-1;-1,-1,4,-1,-1,1,1,2,0,0,2,2;1,-2,-1,4,1,-1,-1,0,2,2,-1,-1;1,-2,-1,1,4,-1,-1,-1,1,1,0,0;-2,2,1,-1,-1,4,1,0,-1,-1,-1,-1;-2,2,1,-1,-1,1,4,2,1,1,0,0;-2,0,2,0,-1,0,2,4,2,2,2,2;-1,-1,0,2,1,-1,1,2,4,2,1,0;-1,-1,0,2,1,-1,1,2,2,4,0,1;-1,-1,2,-1,0,-1,0,2,1,0,4,2;-1,-1,2,-1,0,-1,0,2,0,1,2,4];
+qfauto(qfisominit(M,,qfminim(M,maxdiag(M))))[1]
+qfauto(qfisominit(M,,qfminim(M,maxdiag(M))[3]))[1]
 checkauto(M,0)
 checkauto(M,0,[1,1])
 checkauto(M,1)
diff --git a/src/test/in/ramanujantau b/src/test/in/ramanujantau
index 0cbcdb6..281c7a2 100644
--- a/src/test/in/ramanujantau
+++ b/src/test/in/ramanujantau
@@ -1,3 +1,7 @@
 tauvec(N) = Vec(q*eta(q + O(q^N))^24);
 N = 10^3; vector(N, n, ramanujantau(n)) == tauvec(N)
 ramanujantau(10^6+3)
+ramanujantau(-1)
+ramanujantau(factor(-1))
+ramanujantau(factor(0))
+ramanujantau(factor(6))
diff --git a/src/test/in/ranges b/src/test/in/ranges
index 7f2233e..c98dbdd 100644
--- a/src/test/in/ranges
+++ b/src/test/in/ranges
@@ -11,6 +11,11 @@ V[2..3]
 V[1..-2]
 V[-3..-1]
 V[^3]
+V[6..5]
+V[6..-1]
+V[1..0]
+V[0..-1]
+V[-1..-2]
 V=Vecsmall(V);
 V[2..3]
 V[1..-2]
diff --git a/src/test/in/rfrac b/src/test/in/rfrac
index 2d81ce0..33b2b04 100644
--- a/src/test/in/rfrac
+++ b/src/test/in/rfrac
@@ -36,6 +36,8 @@ x1-x2 \\ simplified ?
 n=102;(1-x^n)*(1-x^(3*n))/(1+x^(5*n))
 n=497;x^n*(1-x^n)/(1+(x^3)^n)
 
+(1+x)/(2+x)*(1+O(3^5))
+
 M = [ 1, 1, 1; 'a, 'b, 'c; 'a^2, 'b^2, 'c^2 ];
 [A, B, C] = M^-1 * [ 'u, 'v, 'w ]~;
 X = A^2 + B^2 + C^2; Y = A*B + A*C + B*C; Z = 'u^2 - 2*Y;
diff --git a/src/test/in/rnf b/src/test/in/rnf
index 2159bb2..167bac5 100644
--- a/src/test/in/rnf
+++ b/src/test/in/rnf
@@ -86,6 +86,7 @@ K=bnfinit(y^3-21);
 bnfisnorm(K,2)
 bnfisnorm(K,6)
 L=rnfinit(K,x^2-y);
+
 v = [2,1/2,x+y,Mod(1,K.pol),Mod(1/2,K.pol),Mod(y,K.pol),Mod(1,L.polabs),Mod(1/2,L.polabs),Mod(x,L.polabs),Mod(x+y/2,L.pol),y,z,Mod(y+1/2,y^2+1),[1]~,[1,2]~,[1,y]~,[1,I]~, y+I,x^2];
 f=[rnfalgtobasis,rnfbasistoalg,rnfeltabstorel,rnfeltreltoabs,rnfeltup,rnfeltdown,rnfelttrace,rnfeltnorm];
 
@@ -113,18 +114,28 @@ rel = Mod(Mod(1,y)+0*y,x^2-2);
 a = rnfeltreltoabs(rnf,rel)
 variable(lift(a))
 
-Labs = nfinit(L.polabs);
+Labs = nfinit(L);
 idL = idealhnf(Labs, x^3+x^2+10);
 idK = idealhnf(K, y^2+10*y+5);
 id = rnfidealabstorel(L,Labs.zk*idL)
-rnfidealnormabs(L,id) == idealnorm(Labs, idL);
+rnfidealnormabs(L,id) == idealnorm(Labs, idL)
 m = rnfidealreltoabs(L, id)
 mathnf(matalgtobasis(Labs,m)) == idL
 
+P3 = idealprimedec(K,3);
+\\ pr[5] depends on 32/64-bit arch
+strip5(pr)=pr[1..4];
+apply(strip5, rnfidealprimedec(L, P3[1]))
+my(v=rnfidealprimedec(L,7)); [apply(strip5, v[1]), apply(strip5, v[2][1])]
+
 m = rnfidealup(L, idK)
+mabs = rnfidealup(L, idK, 1);
+mathnf( Mat(apply(x->nfalgtobasis(Labs,x), m)) ) == mabs
 rnfidealdown(L, m) == idK
+rnfidealdown(L, mabs) == idK
 m = rnfidealdown(L, Labs.zk*idL)
-rnfidealup(L, m)
+M=rnfidealup(L, m)
+mathnf(matalgtobasis(Labs,M)) == rnfidealup(L, m, 1)
 \\
 V=concat(v, [[;], [], 0, [[;],[]], idealprimedec(K,2)[1], idK, idL, Labs.zk*idL, id]);
 f=[rnfidealhnf,rnfidealreltoabs,rnfidealabstorel,rnfidealdown,rnfidealup,rnfidealnormrel,rnfidealnormabs,rnfidealtwoelt];
diff --git a/src/test/in/rootsreal b/src/test/in/rootsreal
index 8e44491..1befe53 100644
--- a/src/test/in/rootsreal
+++ b/src/test/in/rootsreal
@@ -36,6 +36,10 @@ polsturm(U)
 polsturm(U,[-oo,1])
 polsturm(U,[-1,+oo])
 
+polrootsreal(x,[1,2])
+polrootsreal(x,[-2,-1])
+polrootsreal(x,[-1,1])
+
 polrootsreal(x^3-2)
 polrootsreal(x^3+2)
 \\#1605
@@ -44,5 +48,29 @@ polrootsreal(4*x)
 polsturm(-4*x)
 polsturm((x^4-2)^2)
 
+\\#1807
+T=x^3+x^2-x+2;
+polrootsreal(T)
+polsturm(T)
+polsturm(T,[-3,-1])
+polsturm(T,[-2,-1])
+polsturm(T,[-oo,-2])
+polsturm(T,[-2,oo])
+T=4*x^3-2*x^2-x-1;
+polsturm(T,[0,oo])
+polsturm(T,[0,1])
+polsturm(T,[0,2])
+polsturm(T,[1,3])
+
+\\#1808
+polrootsreal(3*x^3-4*x^2+3*x-1)
+
+\\#1809
+polrootsreal(x^3-3*x^2-3*x+2)
+
+\\#1810
+polrootsreal(x^3-x^2)
+polrootsreal((x^3-x^2)*(x-2)^3*(x-3)^2)
+
 default(realprecision,19);
 #polroots((x+1)^2 * (x-1)^7 * (x^2-x+1)^5 * 1.0)
diff --git a/src/test/in/ser b/src/test/in/ser
index 87ad9da..24bb778 100644
--- a/src/test/in/ser
+++ b/src/test/in/ser
@@ -60,3 +60,6 @@ subst(1+x+O(x^2),x,y^2)
 O(1)==O(x)
 O(1)==x
 O(x)==1
+
+exp(x+O(x^200))*exp(-x+O(x^200))
+exp(x+O(x^200))^2==exp(2*x+O(x^200))
diff --git a/src/test/in/sqrtn b/src/test/in/sqrtn
index ac9d316..b440713 100644
--- a/src/test/in/sqrtn
+++ b/src/test/in/sqrtn
@@ -1,4 +1,5 @@
 default(realprecision,38);
+sqrt(0)
 sqrtn(0.,3)
 sqrtn(0.*I,3)
 sqrtn(1/2,3)
diff --git a/src/test/in/trans b/src/test/in/trans
index bd8fc5c..c28de16 100644
--- a/src/test/in/trans
+++ b/src/test/in/trans
@@ -1,4 +1,4 @@
-HEAP=[183, if(precision(1.)==38, 5762, 8928)];
+HEAP=[183, if(precision(1.)==38, 5765, 8934)];
 \\ A tres grande precision
 \p 2000
 \e
diff --git a/src/test/tune.c b/src/test/tune.c
index d682c5f..ca5a91c 100644
--- a/src/test/tune.c
+++ b/src/test/tune.c
@@ -99,6 +99,14 @@ rand_FpX(long n)
 }
 /* Flx, degree n */
 static GEN
+rand_F2x(long n)
+{
+  GEN x;
+  do x = random_F2x(BITS_IN_LONG*n, 0); while (lgpol(x) < n);
+  return x;
+}
+/* Flx, degree n */
+static GEN
 rand_Flx(long n, ulong l)
 {
   GEN x;
@@ -155,22 +163,23 @@ rand_NFpXQX(long n, GEN T)
   return gerepileupto(av, x);
 }
 
-#define t_Fqx     100
-#define t_Fhx     101
-#define t_Flx     102
-#define t_Fl1x    103
-#define t_Fl2x    104
-#define t_NFqx    110
-#define t_NFhx    111
-#define t_NFlx    112
-#define t_NFl1x   113
-#define t_NFl2x   114
-#define t_FpX     200
-#define t_NFpX    210
-#define t_FlxqX   300
-#define t_NFlxqX  310
-#define t_FpXQX   400
-#define t_NFpXQX  410
+#define t_F2x     100
+#define t_Fqx     200
+#define t_Fhx     201
+#define t_Flx     202
+#define t_Fl1x    203
+#define t_Fl2x    204
+#define t_NFqx    210
+#define t_NFhx    211
+#define t_NFlx    212
+#define t_NFl1x   213
+#define t_NFl2x   214
+#define t_FpX     300
+#define t_NFpX    310
+#define t_FlxqX   400
+#define t_NFlxqX  410
+#define t_FpXQX   500
+#define t_NFpXQX  510
 
 static GEN
 rand_g(speed_param *s)
@@ -179,6 +188,7 @@ rand_g(speed_param *s)
   switch (s->type) {
     case t_INT:  return rand_INT(n);
     case t_REAL: return rand_REAL(n);
+    case t_F2x:  return rand_F2x(n);
     case t_Fqx:  return rand_Flx(n,DFLT_qmod);
     case t_Fhx:  return rand_Flx(n,DFLT_hmod);
     case t_Flx:  return rand_Flx(n,DFLT_mod);
@@ -202,7 +212,10 @@ rand_g(speed_param *s)
 static void
 dft_Flxq(speed_param *s)
 {
-  s->T = rand_NFlx(10, s->l);
+  do
+  {
+    s->T = rand_NFlx(10, s->l);
+  } while (!Flx_is_irred(s->T, s->l));
   s->T[1] = evalvarn(1);
   s->T = Flx_get_red(s->T, s->l);
 }
@@ -305,6 +318,9 @@ static double speed_divrr(speed_param *s)
 static double speed_invmod(speed_param *s)
 { GEN T; TIME_FUN(invmod(s->x, s->y, &T)); }
 
+static double speed_F2x_mul(speed_param *s)
+{ TIME_FUN(F2x_mul(s->x, s->y)); }
+
 static double speed_Flx_sqr(speed_param *s)
 { TIME_FUN(Flx_sqr(s->x, s->l)); }
 
@@ -390,6 +406,15 @@ static double speed_FlxqXQ_red(speed_param *s) {
   TIME_FUN(FlxqX_rem(x, q, s->T, s->l));
 }
 
+static double speed_FlxqX_halfgcd(speed_param *s)
+{ TIME_FUN(FlxqX_halfgcd(s->x, s->y, s->T, s->l)); }
+
+static double speed_FlxqX_extgcd(speed_param *s)
+{ GEN u,v; TIME_FUN(FlxqX_extgcd(s->x, s->y, s->T, s->l, &u, &v)); }
+
+static double speed_FlxqX_gcd(speed_param *s)
+{ TIME_FUN(FlxqX_gcd(s->x, s->y, s->T, s->l)); }
+
 static double speed_FpXQX_inv(speed_param *s)
 { TIME_FUN(FpXQX_invBarrett(s->x, s->T, s->p)); }
 
@@ -411,6 +436,15 @@ static double speed_FpXQXQ_red(speed_param *s) {
   TIME_FUN(FpXQX_rem(x, q, s->T, s->p));
 }
 
+static double speed_FpXQX_halfgcd(speed_param *s)
+{ TIME_FUN(FpXQX_halfgcd(s->x, s->y, s->T, s->p)); }
+
+static double speed_FpXQX_extgcd(speed_param *s)
+{ GEN u,v; TIME_FUN(FpXQX_extgcd(s->x, s->y, s->T, s->p, &u, &v)); }
+
+static double speed_FpXQX_gcd(speed_param *s)
+{ TIME_FUN(FpXQX_gcd(s->x, s->y, s->T, s->p)); }
+
 /* small coeffs: earlier thresholds for more complicated rings */
 static double speed_RgX_sqr(speed_param *s)
 { TIME_FUN(RgX_sqr(s->x)); }
@@ -442,6 +476,7 @@ static tune_param param[] = {
 {0,   var(LOGAGMCX_LIMIT),         t_REAL,3,0, speed_logcx,0.05},
 {0,   var(AGM_ATAN_LIMIT),         t_REAL,20,0, speed_atan,0.05},
 {GMP, var(INVMOD_GMP_LIMIT),       t_INT, 3,0, speed_invmod},
+{0,   var(F2x_MUL_KARATSUBA_LIMIT),t_F2x,3,0, speed_F2x_mul},
 {0,   var(Flx_MUL_KARATSUBA_LIMIT),t_Flx,5,0, speed_Flx_mul,0,0,&Fmod_MUL_MULII_LIMIT},
 {0,   var(Flx_SQR_KARATSUBA_LIMIT),t_Flx,5,0, speed_Flx_sqr,0,0,&Fmod_SQR_SQRI_LIMIT},
 {0,   var(Flx_MUL_QUARTMULII_LIMIT),t_Fqx,3,0, speed_Flx_mul},
@@ -490,6 +525,9 @@ static tune_param param[] = {
 {0,  var(FlxqX_BARRETT_LIMIT),   t_NFlxqX,10,0, speed_FlxqXQ_red,0.05},
 {0,  var(FlxqX_DIVREM_BARRETT_LIMIT), t_NFlxqX,10,0, speed_FlxqX_divrem,0.05},
 {0,  var(FlxqX_REM_BARRETT_LIMIT), t_NFlxqX,10,0, speed_FlxqX_rem,0.05},
+{0,  var(FlxqX_HALFGCD_LIMIT),    t_FlxqX,10,0, speed_FlxqX_halfgcd,0.05},
+{0,  var(FlxqX_GCD_LIMIT),        t_FlxqX,10,0, speed_FlxqX_gcd,0.05},
+{0,  var(FlxqX_EXTGCD_LIMIT),     t_FlxqX,10,0, speed_FlxqX_extgcd,0.05},
 {0,  var(FpX_INVBARRETT_LIMIT),   t_NFpX,10,0, speed_FpX_inv,0.05},
 {0,  var(FpX_DIVREM_BARRETT_LIMIT),t_NFpX,10,0, speed_FpX_divrem,0.05},
 {0,  var(FpX_REM_BARRETT_LIMIT),  t_NFpX,10,0, speed_FpX_rem,0.05},
@@ -501,6 +539,9 @@ static tune_param param[] = {
 {0,  var(FpXQX_BARRETT_LIMIT),   t_NFpXQX,10,0, speed_FpXQXQ_red,0.05},
 {0,  var(FpXQX_DIVREM_BARRETT_LIMIT), t_NFpXQX,10,0, speed_FpXQX_divrem,0.05},
 {0,  var(FpXQX_REM_BARRETT_LIMIT), t_NFpXQX,10,0, speed_FpXQX_rem,0.05},
+{0,  var(FpXQX_HALFGCD_LIMIT),    t_FpXQX,10,0, speed_FpXQX_halfgcd,0.05},
+{0,  var(FpXQX_GCD_LIMIT),        t_FpXQX,10,0, speed_FpXQX_gcd,0.05},
+{0,  var(FpXQX_EXTGCD_LIMIT),     t_FpXQX,10,0, speed_FpXQX_extgcd,0.05},
 {0,  var(RgX_MUL_LIMIT),           t_FpX, 4,0, speed_RgX_mul},
 {0,  var(RgX_SQR_LIMIT),           t_FpX, 4,0, speed_RgX_sqr},
 };

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pari-sage.git



More information about the debian-science-commits mailing list