code 34501;
integer procedure ZERPOL(N, A, EM, RE, IM, D);
  value N; integer N; array A, EM, RE, IM, D;
begin integer I, TOTIT, IT, FAIL, START, UP, MAX, GIEX, ITMAX;
   real X, Y, NEWF, OLDF, MAXRAD, AE, TOL, H1, H2, LN2;
   array F[0 : 5], TRIES[1 : 10];

  boolean procedure FUNCTION;
  begin integer K, M1, M2;
    real P, Q, QSQRT, F01, F02, F03, F11, F12, F13,
           F21, F22, F23, STOP;
    IT:= IT + 1;
    P:= 2 * X; Q:= -(X * X + Y * Y); QSQRT:= SQRT(-Q);
    F01:= F11:= F21:= D[0]; F02:= F12:= F22:= 0;
    M1:= N - 4; M2:= N - 2;
    STOP:= ABS(F01) * 0.8;
    for K:= 1 step 1 until M1 do 
    begin F03:= F02; F02:= F01; F01:= D[K] + P * F02 + Q * F03;
      F13:= F12; F12:= F11; F11:= F01 + P * F12 + Q * F13;
      F23:= F22; F22:= F21; F21:= F11 + P * F22 + Q * F23;
      STOP:= QSQRT * STOP + ABS(F01)
    end;
    if M1 < 0 then M1:= 0;
    for K:= M1 + 1 step 1 until M2 do 
    begin F03:= F02; F02:= F01; F01:= D[K] + P * F02 + Q * F03;
      F13:= F12; F12:= F11; F11:= F01 + P * F12 + Q * F13;
      STOP:= QSQRT * STOP + ABS(F01)
    end;
    if N = 3 then F21:= 0;
    F03:= F02; F02:= F01; F01:= D[N - 1] + P * F02 + Q * F03;
    F[0]:= D[N] + X * F01 + Q * F02;
    F[1]:= Y * F01;
    F[2]:= F01 - 2 * F12 * Y * Y;
    F[3]:= 2 * Y * (- X * F12 + F11);
    F[4]:= 2 * (- X * F12 + F11) - 8 * Y * Y * (- X * F22 + F21);
    F[5]:= Y * (6 * F12 - 8 * Y * Y * F22);
    STOP:= QSQRT * (QSQRT * STOP + ABS(F01)) + ABS(F[0]);
    NEWF:= F02:= COMABS(F[0], F[1]);
    FUNCTION:= F02 < (2 * ABS(X * F01) - 8 * (ABS(F[0]) + ABS(F01)
       * QSQRT) + 10 * STOP) * TOL * (1 + TOL) ** (4 * N + 3)
  boolean procedure CONTROL;
  if IT > ITMAX then 
  begin TOTIT:= TOTIT + IT; FAIL:= 3; goto EXIT end 
  else if IT = 0 then 
  begin integer I, H; real H1, SIDE;
    MAXRAD:= 0; MAX:= (GIEX - LN(ABS(D[0])) / LN2) / N;
    for I:= 1 step 1 until N do 
    begin H1:= if D[I] = 0 then 0
      else EXP(LN(ABS(D[I] / D[0])) / I);
      if H1 > MAXRAD then MAXRAD:= H1
    end;
    for I:= 1 step 1 until N - 1 do 
    if D[I] ^= 0 then 
    begin H:= (GIEX - LN(ABS(D[I])) / LN2) / (N - I);
      if H < MAX then MAX:= H
    end;
    MAX:= MAX * LN2 / LN(N);
    SIDE:= - D[1] / D[0];
    SIDE:= if ABS(SIDE) < TOL then 0 else SIGN(SIDE);
    if SIDE = 0 then 
    begin TRIES[7]:= TRIES[2]:= MAXRAD; TRIES[9]:= -MAXRAD;
      TRIES[6]:= TRIES[4]:= TRIES[3]:= MAXRAD / SQRT(2);
      TRIES[5]:= -TRIES[3]; TRIES[10]:= TRIES[8]:= TRIES[1]:= 0
    end else 
    begin TRIES[8]:= TRIES[4]:= MAXRAD/ SQRT(2);
       TRIES[1]:= SIDE * MAXRAD; TRIES[3]:= TRIES[4] * SIDE;
       TRIES[6]:= MAXRAD; TRIES[7]:= -TRIES[3];
       TRIES[9]:= -TRIES[1]; TRIES[2]:= TRIES[5]:= TRIES[10]:= 0
    end;
    if COMABS(X, Y) > 2 * MAXRAD then X:= Y:= 0;
    CONTROL:= false 
  end else 
  begin if IT > 1 & NEWF >= OLDF then 
    begin UP:= UP+ 1;
      if UP = 5 & START < 5 then 
      begin START:= START + 1; UP:= 0; X:= TRIES[2 * START - 1];
        Y:= TRIES[2 * START]; CONTROL:= false 
      end else CONTROL:= true 
    end else CONTROL:= true 
  procedure DEFLATION;
  if X = 0 & Y = 0 then N:= N - 1 else 
  begin integer I, SPLIT; real H1, H2;
    array B[0 : N - 1];
    if Y = 0 then 
    begin N:= N - 1; B[N]:= -D[N + 1] / X;
      for I:= 1 step 1 until N do 
      B[N - I]:= (B[N - I + 1] - D[N - I + 1]) / X;
      for I:= 1 step 1 until N do 
      D[I]:= D[I] + D[I - 1] * X
    end else 
    begin H1:= - 2 * X; H2:= X * X + Y * Y;
      N:= N - 2;
      B[N]:= D[N + 2] / H2; B[N - 1]:= (D[N + 1] - H1 * B[N]) / H2;
      for I:= 2 step 1 until N do 
      B[N - I]:=  (D[N - I + 2] - H1 * B[N - I + 1] - B[N - I + 2])/H2;
      D[1]:= D[1] - H1 * D[0];
      for I:= 2 step 1 until N do 
      D[I]:= D[I] - H1 * D[I-1] - H2 * D[I-2]
    end;
    SPLIT:= N;
    H2:= ABS(D[N] - B[N]) / (ABS(D[N]) + ABS(B[N]));
    for I:= N - 1 step -1 until 0 do 
    begin H1:= ABS(D[I]) + ABS(B[I]);
      if H1 > TOL then 
      begin H1:= ABS(D[I] - B[I]) / H1;
        if H1 < H2 then begin H2:= H1; SPLIT:= I end 
      end 
    end;
    for I := SPLIT + 1 step 1 until N do D[I]:= B[I];
    D[SPLIT]:= (D[SPLIT] + B[SPLIT]) / 2
  end OF DEFLATION;

  procedure LAGUERRE;
  begin integer M;
    real S1RE, S1IM, S2RE, S2IM, DX, DY, H1, H2, H3, H4, H5, H6;
    if ABS(F[0]) > ABS(F[1]) then 
    begin H1:= F[0]; H6:= F[1] / H1; H2:= F[2] + H6 * F[3];
      H3:= F[3] - H6 * F[2]; H4:= F[4] + H6 * F[5];
      H5:= F[5] - H6 * F[4]; H6:= H6 * F[1] + H1
    end else 
    begin H1:= F[1]; H6:= F[0] / H1; H2:= H6 * F[2] + F[3];
      H3:= H6 * F[3] - F[2]; H4:= H6 * F[4] + F[5];
      H5:= H6 * F[5] - F[4]; H6:= H6 * F[0] + F[1]
    S1RE:= H2 / H6; S1IM:= H3 / H6;
    H2:= S1RE * S1RE - S1IM * S1IM; H3:= 2 * S1RE * S1IM;
    S2RE:= H2 - H4 / H6; S2IM:= H3 - H5 / H6;
    H1:= S2RE * S2RE + S2IM * S2IM;
    H1:= if H1 ^= 0 then (S2RE * H2 + S2IM * H3) / H1 else 1;
    M:= if H1 >= N - 1 then (if N > 1 then N - 1 else 1)
        else if H1 > 1 then H1 else 1;
    H1:= (N - M) / M;
    COMSQRT(H1 * (N * S2RE - H2), H1 * (N * S2IM - H3), H2, H3);
    if S1RE * H2 + S1IM * H3 < 0 then 
    begin H2:= - H2; H3:= - H3 end;
    H2:= S1RE + H2; H3:= S1IM + H3;
    H1:= H2 * H2 + H3 * H3;
    if H1 = 0 then begin DX:= -N; DY:= N end else 
    begin DX:= - N * H2 / H1; DY:= N * H3 / H1 end;
    H1:= ABS(X) * TOL + AE; H2:= ABS(Y) * TOL+ AE;
    if ABS(DX) < H1 & ABS(DY) < H2 then 
    begin DX:= if DX = 0 then H1 else SIGN(DX) * H1;
      DY:= if DY = 0 then H2 else SIGN(DY) * H2
    end;
    X:= X + DX; Y:= Y + DY;
    if COMABS(X, Y) > 2 * MAXRAD then 
    begin H1:= if ABS(X) > ABS(Y) then ABS(X) else ABS(Y);
      H2:= LN(H1) / LN2 + 1 - MAX;
      if H2 > 0 then 
      begin H2:= 2 ** H2; X:= X / H2; Y:= Y / H2 end 
    end 
  end OF LAGUERRE;

  TOTIT:= IT:= FAIL:= UP:= START:= 0; LN2:= LN(2);
  NEWF:= GIANT; AE:= DWARF; GIEX:= LN(NEWF) / LN2 - 40;
  TOL:= EM[0]; ITMAX:= EM[1];
  for I:= 0 step 1 until N do D[I]:= A[N-I];
  if N <= 0 then 
  begin FAIL:= 1; goto EXIT end 
  else if D[0] = 0 then 
  begin FAIL:= 2; goto EXIT end;
  for I:= 1 while D[N] = 0 & N > 0 do 
  begin RE[N]:= IM[N]:= 0; N:= N - 1 end;
  for I:= 1 while N > 2 do 
  begin if CONTROL then LAGUERRE;
    OLDF:= NEWF;
    if FUNCTION then 
    begin if Y ^= 0 & ABS(Y) < .1 then 
      begin real H; H:= Y; Y:= 0;
         if ^ FUNCTION then Y:= H
      end;
      RE[N]:= X; IM[N]:= Y;
      if Y ^= 0 then begin RE[N - 1]:= X; IM[N - 1]:= -Y end;
      DEFLATION; TOTIT:= TOTIT + IT; UP:= START:= IT:= 0
    end 
  end;
  if N = 1 then begin RE[1]:= - D[1] / D[0]; IM[1]:= 0 end 
  else 
  begin real H1, H2;
    H1:= - 0.5 * D[1] / D[0]; H2:= H1 * H1 - D[2] / D[0];
    if H2 >= 0 then 
    begin RE[2]:= if H1 < 0 then H1 - SQRT(H2)
            else H1 + SQRT(H2);
      RE[1]:= D[2] / (D[0] * RE[2]);
      IM[2]:= IM[1]:= 0
    end else 
    begin RE[2]:= RE[1]:= H1;
      IM[2]:= SQRT(-H2); IM[1]:= -IM[2]
    end 
  end; N:= 0;
EXIT:  EM[2]:= FAIL; EM[3]:= START; EM[4]:= TOTIT;
  for I:= (N-1) "DIV" 2 step -1 until 0 do 
  begin TOL := D[I]; D[I]:= D[N-I]; D[N-I]:= TOL
  end;
  ZERPOL:= N
end OF ZERPOL;
        eop