pari_header=\
\\ gcd in ZZ[i].\
{\
 ggcd(x,y)=if(x==0,return(y));\
  while(y!=0, t=x;x=y;y=t-y*round(t/y);); return(x);\
}\
\
\\ Compute the factorization of a ZZ-prime in ZZ[i].\
{\
 sqp(p)=if(p%4!=1 || !isprime(p),return());\
  i=2; while(i<=p-1 && (Mod(i,p)^((p-1)/2))!=Mod(-1,p),i++);\
  r=lift(Mod(i,p)^((p-1)/4));\
  s=ggcd(p,r+I); return(s);\
}\
\
\\ Add the effect of one more prime into the table.\
{\
 expand(table,p,this,power)=tlen=matsize(table)[2];\
  this2=this^2; if(power%2==0,\
   if(tlen==0, thistab=[p^(power/2)], thistab=p^(power/2)*table);\
   acc=this2,\
   thistab=[];acc=this;\
  );\
  en=floor((power+1)/2); for(k=1,en,\
   if(tlen==0, thistab=concat(thistab,p^(en-k)*acc),\
    if(real(table[1])*imag(table[1])==0, \
     thistab=concat(thistab,[p^(en-k)*table[1]*acc]), \
     thistab=concat(thistab, p^(en-k)*table[1]*[acc,conj(acc)]);\
    );\
    if(tlen>=2, tt=vecextract(table,Str("2.."tlen));\
     thistab=concat(thistab, p^(en-k)*acc*tt);\
     thistab=concat(thistab, p^(en-k)*conj(acc)*tt);\
    );\
    if(matsize(thistab)[2]>=$compute_max, \
     return(vecextract(thistab,"1..$compute_max"));\
    );\
   );\
   acc=acc*this2;\
  );\
  return(thistab);\
}\
\
\\ Sort the decomposition table, and output it in table format.\
{\
 trim(table)=len=matsize(table)[2];\
  re=abs(real(table));im=abs(imag(table));\
  for(j=1,len, if(re[j]>im[j], x3=re[j]; re[j]=im[j]; im[j]=x3));\
  so=vecsort(re,,1); re=vecextract(re,so); im=vecextract(im,so);\
  return(concat(Mat(re~),Mat(im~)));\
}\
\
\\ Main routine, compute the table of decompositions.\
{\
 twosquare(fac)=n=matsize(fac)[1];mult=1;out=[];mswitch=0;\
  for(j=1,n,l=Mat(fac)[j,]; pr=l[1]; pow=l[2];\
   if(pr==2, if(pow%2==1, mswitch=1); mult=mult*2^(floor(pow/2)) );\
   if(pr%4==3, if(pow%2==1, return(0), mult=mult*pr^(pow/2)));\
   if(pr%4==1, this=sqp(pr); out=expand(out,pr,this,pow));\
  );\
  if(matsize(out)[2]==0, out=[1]);\
  if(mswitch!=0, out=out+I*out);\
  out=trim(out); return(mult*out);\
}\
\
\\ Compute the number of decompositions from the factorization table.\
{\
 total(fac)=n=matsize(fac)[1];delta=1;\
  for(j=1,n, l=Mat(fac)[j,]; pr=l[1]; pow=l[2];\
   if(pr%4==3 && pow%2==1, return(0));\
   if(pr%4==1, delta=(pow+1)*delta);\
  );\
  return(ceil(delta/2));\
}\

pari_src1=!nosubst p=abs(round($input));print(p)\
f=factor(p);print(f)\
print(total(f))

pari_src2=!nosubst sq=twosquare(f); print(vecextract(sq,"$first..$last",3))

