math/fgoldi.[ch]: Implement the extra operations needed for Ed448.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 1 May 2017 00:38:30 +0000 (01:38 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 14 May 2017 13:58:43 +0000 (14:58 +0100)
math/fgoldi.c
math/fgoldi.h
math/t/fgoldi

index afc4332..9061a74 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "config.h"
 
+#include "ct.h"
 #include "fgoldi.h"
 
 /*----- Basic setup -------------------------------------------------------*
@@ -399,8 +400,72 @@ void fgoldi_sub(fgoldi *z, const fgoldi *x, const fgoldi *y)
   for (i = 0; i < NPIECE; i++) z->P[i] = x->P[i] - y->P[i];
 }
 
+/* --- @fgoldi_neg@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result (may alias @x@)
+ *             @const fgoldi *x@ = an operand
+ *
+ * Returns:    ---
+ *
+ * Use:                Set @z = -x@.
+ */
+
+void fgoldi_neg(fgoldi *z, const fgoldi *x)
+{
+  unsigned i;
+  for (i = 0; i < NPIECE; i++) z->P[i] = -x->P[i];
+}
+
 /*----- Constant-time utilities -------------------------------------------*/
 
+/* --- @fgoldi_pick2@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result (may alias @x@ or @y@)
+ *             @const fgoldi *x, *y@ = two operands
+ *             @uint32 m@ = a mask
+ *
+ * Returns:    ---
+ *
+ * Use:                If @m@ is zero, set @z = y@; if @m@ is all-bits-set, then set
+ *             @z = x@.  If @m@ has some other value, then scramble @z@ in
+ *             an unhelpful way.
+ */
+
+void fgoldi_pick2(fgoldi *z, const fgoldi *x, const fgoldi *y, uint32 m)
+{
+  mask32 mm = FIX_MASK32(m);
+  unsigned i;
+  for (i = 0; i < NPIECE; i++) z->P[i] = PICK2(x->P[i], y->P[i], mm);
+}
+
+/* --- @fgoldi_pickn@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result
+ *             @const fgoldi *v@ = a table of entries
+ *             @size_t n@ = the number of entries in @v@
+ *             @size_t i@ = an index
+ *
+ * Returns:    ---
+ *
+ * Use:                If @0 <= i < n < 32@ then set @z = v[i]@.  If @n >= 32@ then
+ *             do something unhelpful; otherwise, if @i >= n@ then set @z@
+ *             to zero.
+ */
+
+void fgoldi_pickn(fgoldi *z, const fgoldi *v, size_t n, size_t i)
+{
+  uint32 b = (uint32)1 << (31 - i);
+  mask32 m;
+  unsigned j;
+
+  for (j = 0; j < NPIECE; j++) z->P[j] = 0;
+  while (n--) {
+    m = SIGN(b);
+    for (j = 0; j < NPIECE; j++) CONDPICK(z->P[j], v->P[j], m);
+    v++; b <<= 1;
+  }
+}
+
 /* --- @fgoldi_condswap@ --- *
  *
  * Arguments:  @fgoldi *x, *y@ = two operands
@@ -421,6 +486,36 @@ void fgoldi_condswap(fgoldi *x, fgoldi *y, uint32 m)
   for (i = 0; i < NPIECE; i++) CONDSWAP(x->P[i], y->P[i], mm);
 }
 
+/* --- @fgoldi_condneg@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result (may alias @x@)
+ *             @const fgoldi *x@ = an operand
+ *             @uint32 m@ = a mask
+ *
+ * Returns:    ---
+ *
+ * Use:                If @m@ is zero, set @z = x@; if @m@ is all-bits-set, then set
+ *             @z = -x@.  If @m@ has some other value then scramble @z@ in
+ *             an unhelpful way.
+ */
+
+void fgoldi_condneg(fgoldi *z, const fgoldi *x, uint32 m)
+{
+#ifdef NEG_TWOC
+  mask32 m_xor = FIX_MASK32(m);
+  piece m_add = m&1;
+# define CONDNEG(x) (((x) ^ m_xor) + m_add)
+#else
+  int s = PICK2(-1, +1, m);
+# define CONDNEG(x) (s*(x))
+#endif
+
+  unsigned i;
+  for (i = 0; i < NPIECE; i++) z->P[i] = CONDNEG(x->P[i]);
+
+#undef CONDNEG
+}
+
 /*----- Multiplication ----------------------------------------------------*/
 
 #if FGOLDI_IMPL == 28
@@ -785,6 +880,88 @@ void fgoldi_inv(fgoldi *z, const fgoldi *x)
 #undef SQRN
 }
 
+/* --- @fgoldi_quosqrt@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result (may alias @x@ or @y@)
+ *             @const fgoldi *x, *y@ = two operands
+ *
+ * Returns:    Zero if successful, @-1@ if %$x/y$% is not a square.
+ *
+ * Use:                Stores in @z@ the one of the square roots %$\pm\sqrt{x/y}$%.
+ *             If %$x = y = 0% then the result is zero; if %$y = 0$% but %$x
+ *             \ne 0$% then the operation fails.  If you wanted a specific
+ *             square root then you'll have to pick it yourself.
+ */
+
+int fgoldi_quosqrt(fgoldi *z, const fgoldi *x, const fgoldi *y)
+{
+  fgoldi t, u, v;
+  octet xb[56], b0[56];
+  int32 rc = -1;
+  mask32 m;
+  unsigned i;
+
+#define SQRN(z, x, n) do {                                             \
+  fgoldi_sqr((z), (x));                                                        \
+  for (i = 1; i < (n); i++) fgoldi_sqr((z), (z));                      \
+} while (0)
+
+  /* This is, fortunately, significantly easier than the equivalent problem
+   * in GF(2^255 - 19), since p == 3 (mod 4).
+   *
+   * If x/y is square, then so is v = y^2 x/y = x y, and therefore u has
+   * order r = (p - 1)/2.  Let w = v^{(p-3)/4}.  Then w^2 = v^{(p-3)/2} =
+   * u^{r-1} = 1/v = 1/x y.  Clearly, then, (x w)^2 = x^2/x y = x/y, so x w
+   * is one of the square roots we seek.
+   *
+   * The addition chain, then, is a prefix of the previous one.
+   */
+  fgoldi_mul(&v, x, y);
+
+  fgoldi_sqr(&u, &v);                  /*    1 | 2 */
+  fgoldi_mul(&t, &u, &v);              /*    2 | 3 */
+  SQRN(&u, &t, 2);                     /*    4 | 12 */
+  fgoldi_mul(&t, &u, &t);              /*    5 | 15 */
+  SQRN(&u, &t, 4);                     /*    9 | 240 */
+  fgoldi_mul(&u, &u, &t);              /*   10 | 255 = 2^8 - 1 */
+  SQRN(&u, &u, 4);                     /*   14 | 2^12 - 16 */
+  fgoldi_mul(&t, &u, &t);              /*   15 | 2^12 - 1 */
+  SQRN(&u, &t, 12);                    /*   27 | 2^24 - 2^12 */
+  fgoldi_mul(&u, &u, &t);              /*   28 | 2^24 - 1 */
+  SQRN(&u, &u, 12);                    /*   40 | 2^36 - 2^12 */
+  fgoldi_mul(&t, &u, &t);              /*   41 | 2^36 - 1 */
+  fgoldi_sqr(&t, &t);                  /*   42 | 2^37 - 2 */
+  fgoldi_mul(&t, &t, &v);              /*   43 | 2^37 - 1 */
+  SQRN(&u, &t, 37);                    /*   80 | 2^74 - 2^37 */
+  fgoldi_mul(&u, &u, &t);              /*   81 | 2^74 - 1 */
+  SQRN(&u, &u, 37);                    /*  118 | 2^111 - 2^37 */
+  fgoldi_mul(&t, &u, &t);              /*  119 | 2^111 - 1 */
+  SQRN(&u, &t, 111);                   /*  230 | 2^222 - 2^111 */
+  fgoldi_mul(&t, &u, &t);              /*  231 | 2^222 - 1 */
+  fgoldi_sqr(&u, &t);                  /*  232 | 2^223 - 2 */
+  fgoldi_mul(&u, &u, &v);              /*  233 | 2^223 - 1 */
+  SQRN(&u, &u, 223);                   /*  456 | 2^446 - 2^223 */
+  fgoldi_mul(&t, &u, &t);              /*  457 | 2^446 - 2^222 - 1 */
+
+#undef SQRN
+
+  /* Now we must decide whether the answer was right.  We should have z^2 =
+   * x/y, so y z^2 = x.
+   *
+   * The easiest way to compare is to encode.  This isn't as wasteful as it
+   * sounds: the hard part is normalizing the representations, which we have
+   * to do anyway.
+   */
+  fgoldi_mul(z, x, &t);
+  fgoldi_sqr(&t, z);
+  fgoldi_mul(&t, &t, y);
+  fgoldi_store(xb, x);
+  fgoldi_store(b0, &t);
+  m = -ct_memeq(xb, b0, 56);
+  rc = PICK2(0, rc, m);
+  return (rc);
+}
+
 /*----- Test rig ----------------------------------------------------------*/
 
 #ifdef TEST_RIG
@@ -857,6 +1034,7 @@ static const test_type
 
 TEST_UNOP(sqr)
 TEST_UNOP(inv)
+TEST_UNOP(neg)
 
 #define TEST_BINOP(op)                                                 \
   static int vrf_##op(dstr dv[])                                       \
@@ -904,6 +1082,79 @@ static int vrf_mulc(dstr dv[])
   return (ok);
 }
 
+static int vrf_condneg(dstr dv[])
+{
+  fgoldi *x = (fgoldi *)dv[0].buf;
+  uint32 m = *(uint32 *)dv[1].buf;
+  fgoldi z;
+  int ok = 1;
+
+  fgoldi_condneg(&z, x, m);
+  if (!eq(&z, &dv[2])) {
+    ok = 0;
+    fprintf(stderr, "failed!\n");
+    fdump(stderr, "x", x->P);
+    fprintf(stderr, "m = 0x%08lx\n", (unsigned long)m);
+    fdump(stderr, "calc z", z.P);
+    fgoldi_load(&z, (const octet *)dv[1].buf);
+    fdump(stderr, "want z", z.P);
+  }
+
+  return (ok);
+}
+
+static int vrf_pick2(dstr dv[])
+{
+  fgoldi *x = (fgoldi *)dv[0].buf, *y = (fgoldi *)dv[1].buf;
+  uint32 m = *(uint32 *)dv[2].buf;
+  fgoldi z;
+  int ok = 1;
+
+  fgoldi_pick2(&z, x, y, m);
+  if (!eq(&z, &dv[3])) {
+    ok = 0;
+    fprintf(stderr, "failed!\n");
+    fdump(stderr, "x", x->P);
+    fdump(stderr, "y", y->P);
+    fprintf(stderr, "m = 0x%08lx\n", (unsigned long)m);
+    fdump(stderr, "calc z", z.P);
+    fgoldi_load(&z, (const octet *)dv[3].buf);
+    fdump(stderr, "want z", z.P);
+  }
+
+  return (ok);
+}
+
+static int vrf_pickn(dstr dv[])
+{
+  dstr d = DSTR_INIT;
+  fgoldi v[32], z;
+  size_t i = *(uint32 *)dv[1].buf, j, n;
+  const char *p;
+  char *q;
+  int ok = 1;
+
+  for (q = dv[0].buf, n = 0; (p = str_qword(&q, 0)) != 0; n++)
+    { cvt_fgoldi(p, &d); v[n] = *(fgoldi *)d.buf; }
+
+  fgoldi_pickn(&z, v, n, i);
+  if (!eq(&z, &dv[2])) {
+    ok = 0;
+    fprintf(stderr, "failed!\n");
+    for (j = 0; j < n; j++) {
+      fprintf(stderr, "v[%2u]", (unsigned)j);
+      fdump(stderr, "", v[j].P);
+    }
+    fprintf(stderr, "i = %u\n", (unsigned)i);
+    fdump(stderr, "calc z", z.P);
+    fgoldi_load(&z, (const octet *)dv[2].buf);
+    fdump(stderr, "want z", z.P);
+  }
+
+  dstr_destroy(&d);
+  return (ok);
+}
+
 static int vrf_condswap(dstr dv[])
 {
   fgoldi *x = (fgoldi *)dv[0].buf, *y = (fgoldi *)dv[1].buf;
@@ -929,6 +1180,35 @@ static int vrf_condswap(dstr dv[])
   return (ok);
 }
 
+static int vrf_quosqrt(dstr dv[])
+{
+  fgoldi *x = (fgoldi *)dv[0].buf, *y = (fgoldi *)dv[1].buf;
+  fgoldi z, zz;
+  int rc;
+  int ok = 1;
+
+  if (dv[2].len) { fixdstr(&dv[2]); fixdstr(&dv[3]); }
+  rc = fgoldi_quosqrt(&z, x, y);
+  if (!dv[2].len ? !rc : (rc || (!eq(&z, &dv[2]) && !eq(&z, &dv[3])))) {
+    ok = 0;
+    fprintf(stderr, "failed!\n");
+    fdump(stderr, "x", x->P);
+    fdump(stderr, "y", y->P);
+    if (rc) fprintf(stderr, "calc: FAIL\n");
+    else fdump(stderr, "calc", z.P);
+    if (!dv[2].len)
+      fprintf(stderr, "exp: FAIL\n");
+    else {
+      fgoldi_load(&zz, (const octet *)dv[2].buf);
+      fdump(stderr, "z", zz.P);
+      fgoldi_load(&zz, (const octet *)dv[3].buf);
+      fdump(stderr, "z'", zz.P);
+    }
+  }
+
+  return (ok);
+}
+
 static int vrf_sub_mulc_add_sub_mul(dstr dv[])
 {
   fgoldi *u = (fgoldi *)dv[0].buf, *v = (fgoldi *)dv[1].buf,
@@ -966,13 +1246,22 @@ static int vrf_sub_mulc_add_sub_mul(dstr dv[])
 static test_chunk tests[] = {
   { "add", vrf_add, { &type_fgoldi, &type_fgoldi, &type_fgoldi_ref } },
   { "sub", vrf_sub, { &type_fgoldi, &type_fgoldi, &type_fgoldi_ref } },
+  { "neg", vrf_neg, { &type_fgoldi, &type_fgoldi_ref } },
+  { "condneg", vrf_condneg,
+    { &type_fgoldi, &type_uint32, &type_fgoldi_ref } },
   { "mul", vrf_mul, { &type_fgoldi, &type_fgoldi, &type_fgoldi_ref } },
   { "mulconst", vrf_mulc, { &type_fgoldi, &type_long, &type_fgoldi_ref } },
+  { "pick2", vrf_pick2,
+    { &type_fgoldi, &type_fgoldi, &type_uint32, &type_fgoldi_ref } },
+  { "pickn", vrf_pickn,
+    { &type_string, &type_uint32, &type_fgoldi_ref } },
   { "condswap", vrf_condswap,
     { &type_fgoldi, &type_fgoldi, &type_uint32,
       &type_fgoldi_ref, &type_fgoldi_ref } },
   { "sqr", vrf_sqr, { &type_fgoldi, &type_fgoldi_ref } },
   { "inv", vrf_inv, { &type_fgoldi, &type_fgoldi_ref } },
+  { "quosqrt", vrf_quosqrt,
+    { &type_fgoldi, &type_fgoldi, &type_hex, &type_hex } },
   { "sub-mulc-add-sub-mul", vrf_sub_mulc_add_sub_mul,
     { &type_fgoldi, &type_fgoldi, &type_long, &type_fgoldi,
       &type_fgoldi, &type_fgoldi, &type_fgoldi_ref } },
index 4f6c043..6e35107 100644 (file)
@@ -134,6 +134,52 @@ extern void fgoldi_add(fgoldi */*z*/,
 extern void fgoldi_sub(fgoldi */*z*/,
                       const fgoldi */*x*/, const fgoldi */*y*/);
 
+/* --- @fgoldi_neg@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result (may alias @x@)
+ *             @const fgoldi *x@ = an operand
+ *
+ * Returns:    ---
+ *
+ * Use:                Set @z = -x@.
+ */
+
+extern void fgoldi_neg(fgoldi */*z*/, const fgoldi */*x*/);
+
+/* --- @fgoldi_pick2@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result (may alias @x@ or @y@)
+ *             @const fgoldi *x, *y@ = two operands
+ *             @uint32 m@ = a mask
+ *
+ * Returns:    ---
+ *
+ * Use:                If @m@ is zero, set @z = y@; if @m@ is all-bits-set, then set
+ *             @z = x@.  If @m@ has some other value, then scramble @z@ in
+ *             an unhelpful way.
+ */
+
+extern void fgoldi_pick2(fgoldi */*z*/,
+                        const fgoldi */*x*/, const fgoldi */*y*/,
+                        uint32 /*m*/);
+
+/* --- @fgoldi_pickn@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result
+ *             @const fgoldi *v@ = a table of entries
+ *             @size_t n@ = the number of entries in @v@
+ *             @size_t i@ = an index
+ *
+ * Returns:    ---
+ *
+ * Use:                If @0 <= i < n < 32@ then set @z = v[i]@.  If @n >= 32@ then
+ *             do something unhelpful; otherwise, if @i >= n@ then set @z@
+ *             to zero.
+ */
+
+extern void fgoldi_pickn(fgoldi */*z*/,
+                        const fgoldi */*v*/, size_t /*n*/, size_t /*i*/);
+
 /* --- @fgoldi_condswap@ --- *
  *
  * Arguments:  @fgoldi *x, *y@ = two operands
@@ -148,6 +194,21 @@ extern void fgoldi_sub(fgoldi */*z*/,
 
 extern void fgoldi_condswap(fgoldi */*x*/, fgoldi */*y*/, uint32 /*m*/);
 
+/* --- @fgoldi_condneg@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result (may alias @x@)
+ *             @const fgoldi *x@ = an operand
+ *             @uint32 m@ = a mask
+ *
+ * Returns:    ---
+ *
+ * Use:                If @m@ is zero, set @z = x@; if @m@ is all-bits-set, then set
+ *             @z = -x@.  If @m@ has some other value then scramble @z@ in
+ *             an unhelpful way.
+ */
+
+extern void fgoldi_condneg(fgoldi */*z*/, const fgoldi */*x*/, uint32 /*m*/);
+
 /* --- @fgoldi_mulconst@ --- *
  *
  * Arguments:  @fgoldi *z@ = where to put the result (may alias @x@)
@@ -200,6 +261,22 @@ extern void fgoldi_sqr(fgoldi */*z*/, const fgoldi */*x*/);
 
 extern void fgoldi_inv(fgoldi */*z*/, const fgoldi */*x*/);
 
+/* --- @fgoldi_quosqrt@ --- *
+ *
+ * Arguments:  @fgoldi *z@ = where to put the result (may alias @x@ or @y@)
+ *             @const fgoldi *x, *y@ = two operands
+ *
+ * Returns:    Zero if successful, @-1@ if %$x/y$% is not a square.
+ *
+ * Use:                Stores in @z@ the one of the square roots %$\pm\sqrt{x/y}$%.
+ *             If %$x = y = 0% then the result is zero; if %$y = 0$% but %$x
+ *             \ne 0$% then the operation fails.  If you wanted a specific
+ *             square root then you'll have to pick it yourself.
+ */
+
+extern int fgoldi_quosqrt(fgoldi */*z*/,
+                         const fgoldi */*x*/, const fgoldi */*y*/);
+
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus
index 1f635c7..d959699 100644 (file)
@@ -137,6 +137,541 @@ sub {
     81a3d26fcb1461ce12ca47a5a640ca496ca3a6c2234ad151bae95b9c8d0580c4a281bcd78fd72a7ed142013b98eed06d3cda9556ad8946af;
 }
 
+neg {
+  d9896c114cda5ec75cc8c83b3c40dc902488ba8120386566d5d0e2565cd95239af0b13e7c5cbb10a4945287a2c08377e77e757b17fcb92ab
+    267693eeb325a138a33737c4c3bf236fdb77457edfc79a992a2f1da9a226adc650f4ec183a344ef5b6bad785d3f7c8818818a84e80346d54;
+  949b01988f46422a30731b9f068a8f0c306d1c473e21f2e6d863d8113bfa2a14f509b62075523b79b8235700da7232229f28432bc68fda06
+    6b64fe6770b9bdd5cf8ce460f97570f3cf92e3b8c1de0d19279c27eec305d5eb0af649df8aadc48647dca8ff258dcddd60d7bcd4397025f9;
+  8bc90df2665b8fa08bd56786c48bac6d979bfbeb4075e8e6977384e76a67d29e361f44cf37d0731a8e7f4372ebcc7e1dcb6c6c3d11ff8dfb
+    7436f20d99a4705f742a98793b74539268640414bf8a1719688c7b1894982d61c9e0bb30c82f8ce57180bc8d143381e2349393c2ee007204;
+  9024073bf10dbc8920b3bc44885bf0824cb802059db0516eba89bb1999318809772e5ab763f1f247642e91af8abb26b89c7afb2bc8396201
+    6fdbf8c40ef24376df4c43bb77a40f7db347fdfa624fae91457644e665ce77f688d1a5489c0e0db89bd16e507544d947638504d437c69dfe;
+  b8c5af6a467e916b164b32c92d3d39992bab6a1d0224cc524e33fb18375e6e2d1b11ddaf6bbfb65232fd4746e7a8bc3414c281e45149de1c
+    473a5095b9816e94e9b4cd36d2c2c666d45495e2fddb33adb1cc04e7c7a191d2e4ee2250944049adcd02b8b9185743cbeb3d7e1baeb621e3;
+  c6410909ea127f2e65866bba1a06597092f91acf99183d2e93cde9c0d4a0cd93fc257c4e26f5353bfda8475bede2e97b4b2d2015c2d4d4ba
+    39bef6f615ed80d19a799445e5f9a68f6d06e53066e7c2d16c32163f2a5f326c03da83b1d90acac40257b8a4121d1684b4d2dfea3d2b2b45;
+  7701cc2280295f4672194b1ed8ab9a15c0326921d3bcf7021df3bf04c95300d5142e0871eaa8af63aa392df32a7a58062f297b49409fdff5
+    88fe33dd7fd6a0b98de6b4e1275465ea3fcd96de2c4308fde20c40fb35acff2aebd1f78e1557509c55c6d20cd585a7f9d0d684b6bf60200a;
+  036a68a27955c5a1b6f5a3e5e9fff0e2b10f6793c56f33e30b77ad044d518dc4bfe970c066af5ece389010de893fe68ab112eaae8655168c
+    fc95975d86aa3a5e490a5c1a16000f1d4ef0986c3a90cc1cf48852fbb1ae723b40168f3f9950a131c76fef2176c019754eed155179aae973;
+  efc6d5d9e176498e572908e2df6dc9e3e42115b86fc83986ce46437bb051ad44f738e5be55e749a9deed3e82756780ecc84b4360a084552c
+    10392a261e89b671a8d6f71d2092361c1bdeea479037c67931b9bc844eae52bb08c71a41aa18b6562112c17d8a987f1337b4bc9f5f7baad3;
+  e7ffd0c07e713cacd8818c62af15b301d32e6ed32869d05177d1259b8e5b5ac23f78a521ce5fd41e9cf5531414aeb698e8672c8dcf296d48
+    18002f3f818ec353277e739d50ea4cfe2cd1912cd7962fae882eda6470a4a53dc0875ade31a02be1630aacebeb5149671798d37230d692b7;
+  fa61a67bb3c9dc4200c3c3b411bdf278b0fd88d4a555e8e3e216d6c2bcc859ce91b3bf6a4dc89e84bcfef5e1f300f70ea4ce7260cd731718
+    059e59844c3623bdff3c3c4bee420d874f02772b5aaa171c1de9293d4237a6316e4c4095b237617b43010a1e0cff08f15b318d9f328ce8e7;
+  024f59ff23bf83c2ccaeaead5e72dc5c97babbcf3f8af77b51ac7f66889bc1365f7b679c9cb9525883ebf4e0bfb754667330b253df8e7f12
+    fdb0a600dc407c3d33515152a18d23a368454430c0750884ae53809976643ec9a08498636346ada77c140b1f4048ab998ccf4dac207180ed;
+  dbfb52b68131b340dcce6558ae4aa0c6c86ffe3773346d926015f0408a297ea7ce06499d52da453787b415ca03eb55ac5aeb55d0f34b0e64
+    2404ad497ece4cbf23319aa751b55f39379001c88ccb926d9fea0fbf74d6815831f9b662ad25bac8784bea35fc14aa53a514aa2f0cb4f19b;
+  f8d76b01b9535f2124a793c9d089e37d8ba8e1de70555b26dc7fa1818bce8ab0b5d8351697d2b87efe312f22a1cb6607cb03b5a75167161c
+    072894fe46aca0dedb586c362f761c8274571e218faaa4d923805e7e7331754f4a27cae9682d478101ced0dd5e3499f834fc4a58ae98e9e3;
+  118e8ba034869d617a4abd5d8be3cf89b0fb27f4f59aeefcb4b9d7f4c82d45a9f9f28a95d6461def92ba4f9c1c03f35020d8e9365afa845d
+    ee71745fcb79629e85b542a2741c30764f04d80b0a6511034b46280b36d2ba56060d756a29b9e2106d45b063e3fc0cafdf2716c9a5057ba2;
+  1d6d927d1d83ce210b5b507d5904d057c94a904a3e47725bcad8b97855027ae074dde4a4f6b7c858b4e80122dc633b380dbc18d6c835cd88
+    e2926d82e27c31def4a4af82a6fb2fa836b56fb5c1b88da435274687a9fd851f8b221b5b094837a74b17fedd239cc4c7f243e72937ca3277;
+  c2fe9dc69d09f11da27fab3a411330eb14184fedd50e848641caa58dd679218915e4b27860a64363ab6320dd01e9f92479dfe15b7961cb48
+    3d01623962f60ee25d8054c5beeccf14ebe7b0122af17b79be355a722886de76ea1b4d879f59bc9c549cdf22fe1606db86201ea4869e34b7;
+  38d96118fba44851468a78979e93f4266c8c8a74acfce812bae9e27534fe386a49987008dc468bd349eb8b8b51bb6bdc5a39f783e8f502e0
+    c7269ee7045bb7aeb9758768616c0bd99373758b530317ed45161d8aca01c795b6678ff723b9742cb6147474ae449423a5c6087c170afd1f;
+  50d37cca9bd507dfd5a9d7f0020a2c62adaceb7e8e684cd649ddfdbaba964e3b625b7687a9cb732e1f62afccf4a5cc7e6b5372029d5b6401
+    af2c8335642af8202a56280ffdf5d39d525314817197b329b62202454469b1c49da4897856348cd1e09d50330b5a338194ac8dfd62a49bfe;
+  607ebda1658ac485ca10ddbd5ae8644520680b5cc88841ef2504b61be1d41129c7ab98994dde7c5fe2510c3f474ee1671b95fd0ff060a4aa
+    9f81425e9a753b7a35ef2242a5179bbadf97f4a33777be10dafb49e41d2beed638546766b22183a01daef3c0b8b11e98e46a02f00f9f5b55;
+}
+
+condneg {
+  7dfa038f1acab8951c3a21c91e13a79697f9a2f3093a3bac6c2c3f522fc54da8b437f8e062bddcaf7eeeef0b2676360bcb2673105d02a0c8
+    0xffffffff
+    8205fc70e535476ae3c5de36e1ec586968065d0cf6c5c45393d3c0adcf3ab2574bc8071f9d422350811110f4d989c9f434d98cefa2fd5f37;
+  197b6ee90f9f42e3107619b8aa2c078ce46d6dff7b2e79c92ebe9907abcfa758d266b9f90859f73982d201dd636e80e093a2c519649f3779
+    0x00000000
+    197b6ee90f9f42e3107619b8aa2c078ce46d6dff7b2e79c92ebe9907abcfa758d266b9f90859f73982d201dd636e80e093a2c519649f3779;
+  a5e54cbd5a218159a5ba7835b00e639a014e516a551dfc1174074f968856a446e997f453f0f0416f11fbcdd3792d4c6a65ccd3ec38d33dbe
+    0x00000000
+    a5e54cbd5a218159a5ba7835b00e639a014e516a551dfc1174074f968856a446e997f453f0f0416f11fbcdd3792d4c6a65ccd3ec38d33dbe;
+  25d7150e99dd1648661388751c86948a3c76b3f104e4c767af863d658e1f4e4b0d1a4d4f7f66dcbd46c0d302e6e2a2964c1694faaae7513a
+    0x00000000
+    25d7150e99dd1648661388751c86948a3c76b3f104e4c767af863d658e1f4e4b0d1a4d4f7f66dcbd46c0d302e6e2a2964c1694faaae7513a;
+  fd58dde069ed4e9422011f16b79c407333e2b9683e92009f2288c20c72f2b44d5715cbc13d7e60ffd4fecba31430235829aa6cddb5e418a4
+    0x00000000
+    fd58dde069ed4e9422011f16b79c407333e2b9683e92009f2288c20c72f2b44d5715cbc13d7e60ffd4fecba31430235829aa6cddb5e418a4;
+  36cc9dbcfbea98cd1956c8bcfb38c237456ee1987fc474bb504538210f155da6e1102d2511278f3890654ed6134df4461242173aebe070a4
+    0x00000000
+    36cc9dbcfbea98cd1956c8bcfb38c237456ee1987fc474bb504538210f155da6e1102d2511278f3890654ed6134df4461242173aebe070a4;
+  19ffe362cba138117e21df0dd008bcb285127e5f7790fc108be5bec8f14878c355b47770a1138ddd8029390e88aa0d3087ef5d6452f656ad
+    0xffffffff
+    e6001c9d345ec7ee81de20f22ff7434d7aed81a0886f03ef741a41370db7873caa4b888f5eec72227fd6c6f17755f2cf7810a29bad09a952;
+  8814ecf8c0cc3323b5260f1617788ad2059fca72c0671d0aa26ee9500e5a11d57c9365886a6c9d93aceb8e613a25926c79f8a9b3a29177a0
+    0x00000000
+    8814ecf8c0cc3323b5260f1617788ad2059fca72c0671d0aa26ee9500e5a11d57c9365886a6c9d93aceb8e613a25926c79f8a9b3a29177a0;
+  6d9c88f9558b04bae55eb44d0bc8f0dbadf888a80e8b52f84dae150b070e2e0ab92a5229c7e453bfecfb51dbe164f3b3777f1dceef0808ee
+    0x00000000
+    6d9c88f9558b04bae55eb44d0bc8f0dbadf888a80e8b52f84dae150b070e2e0ab92a5229c7e453bfecfb51dbe164f3b3777f1dceef0808ee;
+  f3cee5e619e94efc433d88126c3148ae98d546011a69c347682010aafa688cd7271bcbfd9d5f7bb9ae88da3897ff5b8e685d129d68caa2d4
+    0xffffffff
+    0c311a19e616b103bcc277ed93ceb751672ab9fee5963cb897dfef5504977328d8e4340262a08446517725c76800a47197a2ed6297355d2b;
+  0c547e2eee557a3e7c845fa8bdb92869c3f5590ef9b1e1a7e5751fafef9126845249706748ba670c3b59003122d1a046e547436e0ba7d7a1
+    0xffffffff
+    f3ab81d111aa85c1837ba0574246d7963c0aa6f1064e1e581a8ae0500f6ed97badb68f98b74598f3c4a6ffcedd2e5fb91ab8bc91f458285e;
+  f9e339c89305a8a8a1a2abddc0126e0fff89eeffecbe9b852f55f78db40861ca33ac676df746a81686d158dee8b9ae5a347f46764558a293
+    0xffffffff
+    061cc6376cfa57575e5d54223fed91f0007611001341647ad0aa08724af79e35cc53989208b957e9792ea721174651a5cb80b989baa75d6c;
+  d26b1098dfb25f4c7433509b2907b4525951f6106523b248e77c680d12d2f4a6e4a384b7487f061e02eec80ac8cbf04139519cce03fa11cb
+    0x00000000
+    d26b1098dfb25f4c7433509b2907b4525951f6106523b248e77c680d12d2f4a6e4a384b7487f061e02eec80ac8cbf04139519cce03fa11cb;
+  41e3ffb83686f06084d1e22f3a625f2563f02cca14b2eaa024359b671e491f52372f945590e67031bca91fa033cf8a1d51bd39dc45339336
+    0x00000000
+    41e3ffb83686f06084d1e22f3a625f2563f02cca14b2eaa024359b671e491f52372f945590e67031bca91fa033cf8a1d51bd39dc45339336;
+  4a1354afe9dac02b4b8e5ec74c2fe12ef7df09a568bcb7504aac77a3faa480228ea9d3d87d7652448deb7f34fb1ff85c9b5bb6b3e8bd521b
+    0xffffffff
+    b5ecab5016253fd4b471a138b3d01ed10820f65a974348afb553885c045b7fdd71562c278289adbb721480cb04e007a364a4494c1742ade4;
+  19b757ffe399587fbba2f444c529497f9006f43987ff52eb9003da41da827f519d82bfdcb9a30cf2d7bc742c69d1ef6c28d0fbc77d85f4d9
+    0xffffffff
+    e648a8001c66a780445d0bbb3ad6b6806ff90bc67800ad146ffc25be247d80ae627d4023465cf30d28438bd3962e1093d72f0438827a0b26;
+  06e66f7f99e3e1154fdbdd7110fa1ce13c3395154106c677422196864d23d3d688e29c1113a4e695d5a633a5fc766a173c4abc5a5fccd617
+    0xffffffff
+    f9199080661c1eeab024228eef05e31ec3cc6aeabef93988bdde6979b1dc2c29771d63eeec5b196a2a59cc5a038995e8c3b543a5a03329e8;
+  f192679b0f3cc35ea26650ce64dacbee9ac76f3aa1fc7038ccbe279b0e0ac8a5b539a7e84fb879ff377ea8247697e5e916e6f31d1bb3ddb5
+    0x00000000
+    f192679b0f3cc35ea26650ce64dacbee9ac76f3aa1fc7038ccbe279b0e0ac8a5b539a7e84fb879ff377ea8247697e5e916e6f31d1bb3ddb5;
+  4a9b13b1ddb93d1000b6175e695048c7583f3ed00aa24f0f24bef8fbefbbcb70bf092710d904e000796cc1dada03bf0cf23dc71aee9fbe08
+    0xffffffff
+    b564ec4e2246c2efff49e8a196afb738a7c0c12ff55db0f0db4107040f44348f40f6d8ef26fb1fff86933e2525fc40f30dc238e5116041f7;
+  afcf052c2711fa86d84902e8e36ba390e8cc05024edc48f36542a1d606f725a1f2734a65d52aa6cd3df5ed76492f748ecc67ba6e7a0dd6e3
+    0x00000000
+    afcf052c2711fa86d84902e8e36ba390e8cc05024edc48f36542a1d606f725a1f2734a65d52aa6cd3df5ed76492f748ecc67ba6e7a0dd6e3;
+}
+
+pick2 {
+  7a55c27ebd6c3ffcad279ed64e2601ae7da07db4eb8b5d10e50b3f91bebc856069a0dcc55d3863a3bf1901e4efcb33408184713bacbf4bb9
+    ae8b385f8f198e299cec30c2532acbc94311cad7871116f5f40d3d840efec110dc7e85f7539ceeae2189afffb7374f8a58f2310fd9abc102
+    0xffffffff
+    7a55c27ebd6c3ffcad279ed64e2601ae7da07db4eb8b5d10e50b3f91bebc856069a0dcc55d3863a3bf1901e4efcb33408184713bacbf4bb9;
+  6182ed9478343417a7a144ebb6744ba9b71c592a076cd39e253377e3cdb158f565a8f2b5aa018da89f1f1278fc7a5e3caf998aa850f863fb
+    035575425027376fbb24c8d4efcbfb19bbf57ac87a6b24113f1f1e0a63a5a4dffe11b348bb0433b78b05f8ad49bd4fa8e463883df3f8185f
+    0x00000000
+    035575425027376fbb24c8d4efcbfb19bbf57ac87a6b24113f1f1e0a63a5a4dffe11b348bb0433b78b05f8ad49bd4fa8e463883df3f8185f;
+  2f332b50c57c29b114fbbf0fb902230eb33ed85987b53e4b6ff24a7e57243728db92642e6500cc17ddf69348e09f1f00eb29ecdd601c808e
+    0bbacc95ae142ce1ea25b2d52e22d89b10877972f6b2c2ef0ef815e0c6cfa203b6a175d37b9bbdd92c132c13a24d77249eecd664589f704e
+    0xffffffff
+    2f332b50c57c29b114fbbf0fb902230eb33ed85987b53e4b6ff24a7e57243728db92642e6500cc17ddf69348e09f1f00eb29ecdd601c808e;
+  1d63593f536dc9027c3ac672cdb1b323f647ac11e0e3d5797884c330a897718a5b120c58dd1fa50272f065cc650be36d747df128d7a3afd1
+    29282ede408ea3755c43949b96b8494c3083b65a0fcc0e9737e35c573db0109b1aaca9024154e56db389e874be900b6ce66618e976c34ada
+    0xffffffff
+    1d63593f536dc9027c3ac672cdb1b323f647ac11e0e3d5797884c330a897718a5b120c58dd1fa50272f065cc650be36d747df128d7a3afd1;
+  ca76f29f750d228a9fa5e9795152ddbdf59a245d34efce86d1781e16d1ef4b996fcab77b83704d59ef2b2945e52c506f97bfada6aa97edfb
+    9d533ea73ffb765fbf53ba2808d48fa17a9d9381697fd4b9f70e5452e504ea1b881d7ced5dafad838587304c0990beeab5ec70c69e384a31
+    0x00000000
+    9d533ea73ffb765fbf53ba2808d48fa17a9d9381697fd4b9f70e5452e504ea1b881d7ced5dafad838587304c0990beeab5ec70c69e384a31;
+  a9c03a383e3b424e7f04db6d8c3c2a37efec54d0158d7ab03848cc6ed70f083138c48003995724b49978587e8ede7f6cb1de8fef59654fb2
+    60e193f96c3140b7e0322d34a5088c50f31af480701d6b0ee665474b6d70bc2eacd5798d46dedf38adfd25205808ee5a022801bda3c91568
+    0x00000000
+    60e193f96c3140b7e0322d34a5088c50f31af480701d6b0ee665474b6d70bc2eacd5798d46dedf38adfd25205808ee5a022801bda3c91568;
+  f790450391bc9d9616d768d1c2d065e1c70a780e0ede7bbcbce3c6f395a1f40a526d8f7e5a41b412cf3856a7a8cae34217db68874676cfe0
+    d065d763532f4fab55c4dc4cafe493836855f3018a2e6cba6969b3c9fe95e091ee52eef098f901d286a482dcf4710d88b5d95abb95131acb
+    0xffffffff
+    f790450391bc9d9616d768d1c2d065e1c70a780e0ede7bbcbce3c6f395a1f40a526d8f7e5a41b412cf3856a7a8cae34217db68874676cfe0;
+  95d0462a02c45400d97615d14968e90a32a0d3b8a19046f96777cc6def800c7e938d0b65669515d1de2c9d0d5de740589861493f87257f0e
+    967eb0d765904def8c6fc9d0bb710d838897429cccf444cd243892bcfac20eb704b82cc33e89599d7cbd02d9f44a24afb05b8f6da76de800
+    0x00000000
+    967eb0d765904def8c6fc9d0bb710d838897429cccf444cd243892bcfac20eb704b82cc33e89599d7cbd02d9f44a24afb05b8f6da76de800;
+  004b205b5877056695259d930cc8de77af754369b49e5040016f3d84a18e9022f8203a6fd7df4d576d4ce7f7a91a6342596dc0b8d5ef102f
+    640b649372ebcffb4f87f2bf4430a9e70028b75e6d3e838686ac4737dd48a1cff113b8f83082cd37b2550605cf087a4d8e0d5df6247bce0b
+    0xffffffff
+    004b205b5877056695259d930cc8de77af754369b49e5040016f3d84a18e9022f8203a6fd7df4d576d4ce7f7a91a6342596dc0b8d5ef102f;
+  e47a20b61c777f8cea3d3560163b30f00912aa3e0371273fc6126a1bc6d4657d4e1546193169a174424479685ded08f84db407371854ff2a
+    1d8c7ecebe575309ad46aa947afa16bdbb7013681273fae0d4f1c3c4cbefe7711d33080665cc904553ad5389ae8632657563404348a6cfed
+    0xffffffff
+    e47a20b61c777f8cea3d3560163b30f00912aa3e0371273fc6126a1bc6d4657d4e1546193169a174424479685ded08f84db407371854ff2a;
+  02aadd15ef52a17127be8544587ab64a497a2408e34821505a8d8b2a7f4ae43beb027aff78379668bc80bf54507107de4725773e0d39d8a1
+    4af336b21ee8d83886c8159f3dd61a79affd12ac1b105989d2b6aec3e62616f2753b8f7c4b19717f9643b06025fe46a41ed6f665b2fec236
+    0xffffffff
+    02aadd15ef52a17127be8544587ab64a497a2408e34821505a8d8b2a7f4ae43beb027aff78379668bc80bf54507107de4725773e0d39d8a1;
+  316fa09d97d9f6de3e932dc58d08431b6bc2e5efefbacd1f7b53df5a0400b4e82de675893704298557c7c5f0614333d636c4133c75d7165b
+    2032908acfe8ea2ff0f9863734ffcf7203218d58660795978486a151b0c38019146dba917a393012de90eac47ba1264e53d1ea2291e9adfe
+    0xffffffff
+    316fa09d97d9f6de3e932dc58d08431b6bc2e5efefbacd1f7b53df5a0400b4e82de675893704298557c7c5f0614333d636c4133c75d7165b;
+  470221fe5cb385fac6cbdae93ecb144c6b6d79196feed7d3dca54376f97d222a5ae435f87a164f11b87b1526ae5aebfb0527e3adfa16f18d
+    1481f5b202094c6328d07778e261e5509802792d603aa64b5f20a2c10d9e4dc8d0ca7e4868564823ec547746a6938dfc521afd719eeecbeb
+    0x00000000
+    1481f5b202094c6328d07778e261e5509802792d603aa64b5f20a2c10d9e4dc8d0ca7e4868564823ec547746a6938dfc521afd719eeecbeb;
+  febd75b83d9aecaba9b1ee2d5b299874ba62a338fab52e6c85a0fdd172591e5f09764ad473c6e5b0aebc74e553aea0d9cd201834cca122ce
+    fc1750a2d1438a1779e26207c0da139847d21533285857549555d2f445b76cef302c56e29e724c9a8af3ecaf2064d5626fec066f58eda2e5
+    0xffffffff
+    febd75b83d9aecaba9b1ee2d5b299874ba62a338fab52e6c85a0fdd172591e5f09764ad473c6e5b0aebc74e553aea0d9cd201834cca122ce;
+  39fd301ac8fe36dd77bfbdc5566fb2c6eab8c983bae9d248a679ced3153c17419bd951e0feb0508881cb8464adc3da30753cf005bf98a83e
+    0b164941ab9f2670c523549f1f86c06446f5f84a037e58e44f9b689332f807ebbecc7460187e40f31b92944a13f9f9886b31cf8d325e6c57
+    0xffffffff
+    39fd301ac8fe36dd77bfbdc5566fb2c6eab8c983bae9d248a679ced3153c17419bd951e0feb0508881cb8464adc3da30753cf005bf98a83e;
+  df87ee832636112c76789f71cf8f9b1153b78cc1640dec69f93b7c6598604725464eee088cdb78731f9f119b13e64dbe776dd498ffb90b1e
+    092ff08a968b0ca27f3b7029c044ec12c091bf6c5cba203b109577967200dc403a8763c87bc64f0eb85923aceabe98466680ddf0e1d35d20
+    0x00000000
+    092ff08a968b0ca27f3b7029c044ec12c091bf6c5cba203b109577967200dc403a8763c87bc64f0eb85923aceabe98466680ddf0e1d35d20;
+  b266f3cced76432399eccc2093f9041acce722ff0f2214a539ef61e96306af2fa1c103305fc9b23a9f4d8aa20cc44086dcd15d02140a93dd
+    2e446cf54eb539fbe9981ec3c2665ca435824813ef49d856a8f1d2019bc10f51854432cea7f0d31370b6612734e3e480963f3f68bbb916bd
+    0x00000000
+    2e446cf54eb539fbe9981ec3c2665ca435824813ef49d856a8f1d2019bc10f51854432cea7f0d31370b6612734e3e480963f3f68bbb916bd;
+  ba30728ef7df7f7e89fd6cb3f5693700e3c21844a3612bd60f319b95d95ed86d20c785f742e07c2d1c0bd0f4c6a14b875a9663ded379cbde
+    a53d479c598379813a085d982b84494bcbf81a5cb40e2757d05ea1770b47afba2abcaa1a4b699b019db0c85f4c37408c8c740f205051b7cc
+    0xffffffff
+    ba30728ef7df7f7e89fd6cb3f5693700e3c21844a3612bd60f319b95d95ed86d20c785f742e07c2d1c0bd0f4c6a14b875a9663ded379cbde;
+  1c824caec1b5b45655d31d449de4b66c635ac916336becfc67c1c74192d9a960ba04915db34546a4f3f6aee95a15a9035043d60b4e6eceed
+    1b5f89674c8970aa0e7e37b0d5d78648a22e74943d0498c0a80ab8f7eec14523d6a9c375e340051f8915473ecafe5eb99451b7ab5a7b86bc
+    0x00000000
+    1b5f89674c8970aa0e7e37b0d5d78648a22e74943d0498c0a80ab8f7eec14523d6a9c375e340051f8915473ecafe5eb99451b7ab5a7b86bc;
+  2bc7f4385c02d100b9e1f3951eaac1f4d4da0efc673f99964d7c79f07f198aca2f58ddbd18cae49db1c609cf346fb1ec6d82040be3a8d21f
+    cb7eb21d871b3128c2a82731fb5cb11661f5633be69dde24392ad7b8397d2914da06df867e297e37371f2e2219037ea9790d7dc43d93c1df
+    0x00000000
+    cb7eb21d871b3128c2a82731fb5cb11661f5633be69dde24392ad7b8397d2914da06df867e297e37371f2e2219037ea9790d7dc43d93c1df;
+}
+
+pickn {
+  "c111d1169e6d48f8307bb8000db91bec0b7c0359a138b765ee875467e67eabf50fd8202ee6395858d9dca1c6930b43bbb4fc8286a0d03b2d
+   a2ae5318d8970c6b23555f7a78fb2e1f939359fb50c1af1c1f45b3206b7dfe2a1a0bbc59ae80f3a1bad53d563227a1194a98aec5395a745a"
+    0
+    c111d1169e6d48f8307bb8000db91bec0b7c0359a138b765ee875467e67eabf50fd8202ee6395858d9dca1c6930b43bbb4fc8286a0d03b2d;
+  "56652f690dda35003fd5a1bbfe3764c54ffae6d22e01c2502d980a644c5a24a506c8ad3b75172f8011398341cb4ba2be1b1e223717f295db
+   6607761fb135db6d10f305aed2e03cadc7b72576f592151aebe49d81ee3337d538cd8b7de47a8aa51fbc25b39ffee729c436e4e28ac9c172
+   89b3d0755fc7ba0a7be79c06ef733cbf936c59e9109fc6cc5fd2203c1b6461a23a4f4bb6049c08dd2d25323f2d095e9618f3a1ea06978eaa
+   c5a71a5570bbb041abca85711385157e3c45696ab4a21d82081db9f17004f0137fbf0a410052ae90575a6a654695957912081b3bad77ea7c
+   5bab97e0accc3eb2cec060dc453dc134155efa7f328f602083d7171e3e55ba55d3700c53d1be75cae24c043ba2d9a37bd735443fdd14073f
+   471f03e2a16a1d58a2db4622106d68523858d1a630e563f5eb2196ed8072e2389e0d2cfadf7ab7f22f14789d5f707408b75e9462cd9b13a4
+   6b155c607498cd03aff93a8091391b1f7ad1c902e801f2a5761e8822ebde0312cc6ddf799006fe27d8dc1c9411f5bf844c40b02634e520d1
+   6a98599067cdf9366e8b779c58981571040e72dbe821cad95e9d313a2ce960e4b52b8ab7278bdc7402c248035999ffc0d4cf1d7df1eda96d
+   7fa1311eb8205d30d4cf98aa1634abaf2aded1d6e00e1f06d48a47280da3a5f5f7c2eef4fd4998b9fa7a92c71ee0457321378c76304fabf1
+   05c9f88763636d1a2df050796aad0e775d6a198c205511d92ebfaf54537730f70f04f36673dccba4bf028d124e83c346e701d063fa8b1f40
+   69c05dc94a3f889551e427f57a9b9e2f9983c703cd7cfb71382718bfbe72b6c47d2daf3037d718e93a934a82de6ec459eaa74219fe59ea11
+   2c510a74adef807a7a53025f5e7c68cfd155ace0ee620d1724146d9e3741586439dda0549b6a298164099a972cf3b368b9f3d0b5f611d89d
+   c6feb2190597901c146dcb4d234d8c93f38713fcd77e3d4ffdde2784a9a7306866b15d4d752c11235ad6c543b2f1159383838d340cada73d
+   0ae29f7144712727e6126848a324f1f580b93badc4c92f694ddd907fbc960e3de0b6d73264d72f3f96c9ad27c381f84292dcb3f9bc850eb4
+   bc8c21c071c96eacb758899a1ba76379d27761553e783140e7fdfef0de5d01b4262df4ea4a8bc335331989bdc57856329c68421d7de19e70
+   7cf0275d5ff8ac9db3d141c7bbec0cfdf016086a6d4cfbfaa2fdd0573378b8c0f8552bd770eb691f10c9b77648edaa8701faaec45d9275e4
+   0be835baf0615b52b1c581985c6326d691e4e5fe27a689af8f90e9b8a2e4f2758eafc3a699f509e5efbf2059e9d2ddfda686f76f7db54e6f"
+    9
+    05c9f88763636d1a2df050796aad0e775d6a198c205511d92ebfaf54537730f70f04f36673dccba4bf028d124e83c346e701d063fa8b1f40;
+  "1761d78c67a47efd41c727b28ee3e28b3e0a483169762c59b8c5639ab463d36b9aee572003ee6066785e6ae511179d99e14d83813032f702
+   94ed128ce89d6b103bb05130fe9495fa753b8967083d2e67a6f64a31d479ad35c69e55bec5fc1803210ef803cd9d29ad29c94f96032c3fa3
+   ef4c5022433ddce62346608cc53f3e0c1ca77f60267ae835e5088d779207dcb748543afe12301beae94ffb7df48e41454d96b23f7faaa2b9
+   c33287e4827795dbe221be26a4d9de426178e31e01a4b35c01825c4b964d7ccc8a8416b0c0c3f4224d189fa414649cb16ff181c3ef234954
+   699852c0172b295a3aa4927c1a575e3e86ace71cebfd96174a9b98f8f9b9e8a766b9d614eb5728f28a7c52b70a2529e78ba4a3157b80ffd6"
+    1
+    94ed128ce89d6b103bb05130fe9495fa753b8967083d2e67a6f64a31d479ad35c69e55bec5fc1803210ef803cd9d29ad29c94f96032c3fa3;
+  "c82c6cc7016ba8a520f3bb1123e6f8d815f4f6d00d717e8c9627b450755f6719cca857fac950b8cb7f10a396b0302b4f3446807ad2c77cc2
+   403a265b82d695d93c3b095026b2accb1f2391dc7d2536380ef38e1bcc49c31b10924f08b47eda2bb5de1d5211eecf787b741c633cc4be52
+   41bd729e42d602fcb416b2cfd243565d12c75fc2577fc5d0ebf2ffad631e6134907c35632dfe459f9ceff9d5a1b5d978f4785c87d0a42cf0
+   9ec71e5bdb0ce3415f71de3021b47331cb99959628457befc8b936e8b1dafc0f42fab0fe79f64a00d5b4b5241cd6a24469fa5fcec2fff9e0
+   d67552c6ecd44fb81662b842110ea7aaf2c409bff06079cbd68937c1bd5f5dbb7408e5cdbca88e8bdad5d68d5acd30309afb654e2c2ce41f
+   710601d0f2c0b48a9388eec3fc9da68ede14aa5782ab6bec47d4e107ba61159e31d70f4b0759f818bd6711771d4ae5aaf3187761c4adc5dd
+   c9b3d60b7c5c6a36a696e8ff3d3a8b48191cf67d9f5bd030573a4d2f03fca8dc0dbbef01a21a49e4e186c12384469f644d9b1882cdad6d69
+   fcb04d71a80e210b4ad1aa0bc2f351b7e6d05cfbd99f2508517a8abebf7cca24f369691255a1b10dad01eb19e6e08b66800be75fa9c9e42b
+   f128eac996e72401ed0719d6c5ef1a4ba47c9a92173d7152f35c8c668310e3a2fa10809ad2310f16738480a8ab1067ea3083820a888e64e7
+   5ef91a7c27f6ec4114a9d91f9c7dc98df38e0840257736d8c406698069e7e0a130ce30d4a7db28abb132a7b659e4d9893223c514a383de17
+   3c5fe8a4da4837e1d0a588559c00b982621f715c7c0a762000db530d3185cea9e846fa6b55b64da6bea3dfc36bc9dd4965fcbfc22f423369
+   ab33aaba975b5468fb8580964ce85fc558d5c7e46831e430a1179552398dab3483f6e80607b7e9b0bdc7a3193841320200f991a5825eb544
+   cdcf2bee6ec33f553696d36a43dfaecc576bf0dc10cb985665cdf5fc0c22397841c34df9d1b0d79f4b745dba4575bfe1c0cb17eee8d58930
+   ac4f846c26c749c96d757abdb8c165b6bbe2a8ee20bf09c81ff921468bc451f878815c85ce98132c355f8a1cc6a9b7334bceea3e51f5bfa7
+   366bec09b5e7d11fc33586af6659de01af4e4c2c82b2940327ed3d4a2bdf89d65d938720ed141dedb41bc57aa219fa2a8f250fdf1a87506f
+   4fa25a1891b93c5b29b859810317fabecf9b0e54125c2ec642f13685acefc438a8ff524ce7d60f11d68b8f8fcdc4905996e4d088cba13021
+   31b8c72f219142f8c8ef3c0c6ff7251ce37827f12ace60821cb7f412f23635767d2bea11b83a43a78b39252685246b2d39463c35075be03a
+   17594d562b7a553025dd0aa59b33f00288804b8d380c31515873d68343bf0aba715eac1ea86fe1682eb1b3b45237d7080346c072a29afff5
+   4b3ae7807c00dae2edbfb98c7124cf08be06951505c6606145a7d021d124179096982bb0ba65a66924ea31b088a036bfd9d500de9543de5e
+   9ca4d39595f39f53d630484bdaf84532713a22f3c74676e64e4f7035a749af123249d67597287f076a0b6a0fc85ef962a2dca1039e227c87
+   b76d8972d596a2e115a6645e940d873945e51dbb6e3a1f99e4bef76434053186709b3534aea8fa1fac04e54b21cfd8a3afe4e636c6072594
+   7b2d6702d70acf03e4339f5e1733083f8fe42580392f0cf00d822ed8dd21f7768c2e311a1742027561bdefffe8e0f77b0336e622bd808772
+   eb7bd19cdd6f25d0feff6764cb92fa71b402942cf7ea5cbdacd8a8d77493e57b84581100b2cc36a80a8e196d0ba9338b2d036a24b498d252
+   e7635ca51bcb6621c6820a2b20c53bca39433a1fd703c210612f73ad4dce07801ad712f3d1d67ae035a81bf9b787019ee641730426f7f72f
+   6903e3b6923f362d86de6668d1c6967184210d7179fe8d208df776c5ad34c81e0b9fa1ee8be7790fe5a14ea2be238b671a1ba0ebedbdb40e
+   93cfdcde11d3995683c0d4b579e377e252763ffa79d432ab50ede5fc36fc7a1938c420626753a597469236f2e0ca542431df03fbafcd35ba
+   1d121bf8ca1e6d0326e942c304e3394bbb64e3c2680c7dafa9f3d8eb22147b6222e94e0c45395aecdcd7570e9ca434cd4c156239ba7a3ea3
+   db63495a79fc9e5882de7de5f75986c634a2e46d6ba62622304473e5dc0c52d0cfb27f4160bf5e07825f8b917ecc39a6ef9dced3af4a94b5
+   282ec969fc5f1b916e73087168b413dc5e1173c476b82182217f4bfde3dc380ab3ac7640f895db7bd010387b71a93c67d3c3c7bc3b910c59
+   3b03aeeb54e41843e8cd13078a3fc7a7f3be9667a7fb18bdb47841e836ef1c4e298e4b6ed82f7be14c1fbf301921e1542c0e7c69cc71f8af"
+    0
+    c82c6cc7016ba8a520f3bb1123e6f8d815f4f6d00d717e8c9627b450755f6719cca857fac950b8cb7f10a396b0302b4f3446807ad2c77cc2;
+  "47920f234374435b73520ba1fa993be624dafc3eef106ac6bf2192acbb20335e19084ca6d12349d07b3f645ecf29192c7dbbeb2e71610882
+   a636b649653ca52b58ac4c9f3df1c683a5d9950bf1ca4de46d283625ffa003cd2b4f561253793497a686c4e1ea98d9983f10ce7ecbb0c33a
+   7c9839bf1bd919bc6096aaee1719b729850cd84c726436d5a9989a48ee6ac5a6320086d1ab0f597a5e93e2b730ed09e8ecd3479ece8bf065
+   1a189e009eb30b119828633f8fb0a196a99f05f96ae77ce97235b7973f75cbeb585ca003d364598a0b743663ff1d154c1bb3d364183608b4
+   7b4a757245f542e2d1b0a8cdd5e4a55da3c199aa52de92d721078297cafff9011b55948b9adfe3311b552d2c19c440faa1982e96e039d65c
+   c731a531b71b1a55084172793319af4c996fa3c439a34347b9b086fee7e65936bb149192bd13371da64fb29935d9dc61c944deab0c5b7848
+   0114312cb9ab5c1dc8c0b60618d32cb803ac596830c64df424aa237232fd689f1cc5bd55852ae63d1a7257f18415c9eea782a15a92538ae0
+   36df269f88be577ca8f481f13c15591d7253a85bc2ad9fa35f48383dfca23a8d6a90105d9ea6fa537d2cd7fa7949cf0313de6817c0a20884
+   74902032e94280f6e8eaee2031700dbd4f6f054f0958052fe10d6eba00e453f287020c458b5628af386d587b2ff421818e1771f067be24b2
+   9243c0b32bcd5fd0abb3f0ce622fa6aecc6761069a81afa690f37fce556eb8d0058916579f985c7ad31a7701b39deee196b3967b7d48e911
+   d3c385930879cd57f1ac584da5550e31bf274433cabc24168d2a3aba3fc8e5aae9efdd6f5c73dfed0c64a5b4c33b0ffeea27c78b5b425a06
+   63924723d76999ce0b01e78e4a10d60b296cf2fc96cb19eed9590b6c363d39b888eae5b3164db86f5b9add3d617c174d46b78bb5510d7405
+   af0985ff58b80b4433eb3f5eefddc5a5aaac777ef907f4d5ecbb11aac1a71e975402878c62e99da178c8956140a8d424f86896d1f31b8274
+   89bf4b5f5107390506e4c0b446da902b98bfc41c2ac09726fb5a2ce09e690917a78e8e7468910fd80dc623ee8ca1241664a82bd474b72c6b
+   4a6080e6e1451c375df90a724ff8d4a066bc49a45e3124c65c54d9430a62b7c1804d57a4f8347f30cdc23dbb9d7bab9a64a0b10989c9bc60
+   6a2f3fb086cdd63c015c5ed6675e3a12dd61b579842ce305994e44c7b1669f5a6fca3c5f7654ba967d86037297e0b41ccfb6b99f462b2e7d
+   7286b6e41f25a3c46733037bf2a5a366ab5b243d28362dbcaad7119f578f8db790704a087c9ad15cd345a92bc49b8782b40615d409a5a746
+   983fc505bbdb899e11b5dd1e9798850c649424b0d2ced8e22d647e1d515664ebb0c36ad29acff5a7658d061e55b8151d0bb7ecee14a977ab
+   9ccfc931e25cbe1007a4033175764b273ac16d0baf27e4640d458d06e4cd5739fa98556f76add81a299329087becde66b0d6336e202004ee
+   d2bdc3f41276bb70c085fe95820be3dd92966dc7eaa884cb9bb8164fedf34f38132f778467bb3bde9055939ef72c9f7d8cd3f7b123d2ce32
+   5fd81a497f6c7fd7d42125a6d8ebbbb203077286e1c7afc9b708bc803e79518cada09ac733d616bccc231d7ad1069a83f5344cfd9f1d7717
+   adf72350d2b2e3fee58a0253e23899192101df06efda29d5e47339803e24be20fe559bcd19954711ae44c017de491d3d4a0e6a00efc5f33a
+   23b45c33b81bc6d34e05316378745efaab97c809541487d353438fdc6d062dfa7f9febe97001a758a1c27fb113b33c5f52b101518d8868d0"
+    22
+    23b45c33b81bc6d34e05316378745efaab97c809541487d353438fdc6d062dfa7f9febe97001a758a1c27fb113b33c5f52b101518d8868d0;
+  "cc23c9f8a157bcc9ab7f0aab31324516e5b349e478b01dae9e71d35b27aa1dbebf7de83b996ac18d002c90c5089a749cd1f617f06153d578
+   80dd767012d4b3fb8303d95fdfcc793cb3e18666c7d1e897c2a6d319cfb827c2e6f5566e58b5d15fb0db5cbabbb5764bd17139241279f157
+   441708fdb2f5fee3292aa0f7b0dc2c533c3c15fc1c9a319c9ed46f126f0ac1f8eee9e0c9f716c849876d2767fd5dd8631e630402060c31d0
+   065ac50aa12a2d2bedce03e9d3af2695cc951f86327e1a72ac48fca9d24d6f01b7322bc7f66f1b1506d50b372a38db511252d57960708690
+   496becacfee8d16896d44715f12f6ad8d4d01415412e05dc14ad09c49efdf2afda17d8c2a701bbf7385b121fdf035af5dc71db5df20a7ac9
+   752d045e149d1a15e882d7ef9b81e7592af0c882f16f68dcd746329abc98dc8bdbbfeb18e64aefcc4d52993d614c528502334960913120bc
+   6eaea0a9a2bdf4ebd45937eb38937bfc5a166839a38eaae6d726177826eeef6733a366624ef7f1c29deedc4c08a06064d349904ea4b68278
+   2f5ae15affe9c1db93d8b7531d03cbbc931bfd0e6ab25cb30835ebda13af12a8af25c20fe7cfe295c6dee00e11a29b050ee282c216d30e9f
+   c2a05a4b6263a927bb7f4cc0cd2669df289be262eb6b1a94602fd2b4fc6c02fe5c06ebc7cbba6c0374e42341b0525ad962bc4cd02eb97ad5
+   08c31e5e6bdf80a289dc8b7dfb62234061b3a068996aafaa7fe8d0623acaec089fc51ebd6b07ba1796663e41e6edbff0318e4137cfabb5b0
+   ea940acb717d6e9238f942de94a3fdf430ebcc47481c29d72d688395722ffa4bdd4e4a6eaafbfcc2f7d73c10be7cf46b01dba1747281193a
+   15adb7665d1180c00b90dcb9bbd43e2cb452e05bbd863b73ba12983fa7490d878fd598063c497727e6786a0ced54dab63984e10e0bf03f51
+   b93ce97764fb51e090a624e26c08c632b519327d812444d7e3d5e144acb99d5a0f3f3c38d1005e8920c8906f72ea0ff9b086ac5d632e9e33
+   3b9550aba22b08807d06b0267ab13954b85d07ad3112e6242f44642947d3f2f0cee777c6a84cd42adc30f355218b63e3ca9bc2db824e9b67
+   5cf635672d5b1d4ff706e52c9712dec5db11edf73d0e3450947b22475036b4f801646e6434261cb8dd4197f967a0576a7f2470edc47c64f8
+   ea684a2d34ceecdf41457431fe0f6d3613fbf7b23bbf096ca1fcf1e5cc18a575c6e569a8723850641993f7cd7a90e73491af16ab8f32064e
+   0a316437e201049ed82f760e8fc1fe24c5000bbb45f0af479e1ff3a46b7a93e4486e80a0e8be342492c3f3de3bd9df497746af4aab713c10
+   28100df25f0f447261a6cc7669a360ea718db598771b7b68a03a1f35cd376fe093ab4d0521210d99abe8d83e7af39f4101113d0873ca37a6
+   acef13338e2ad16fab3b25b2cd69771d9871b87613de64bd97b45256c52a91e3e7551ddf0bcf32071387e49f666208a6f05d3688f1ce8d23
+   78c4866ca4f94f8b65481cb64edef246c10a67744383581b1e71d202b7b830e0c3d8113574b008ad59fd4a2a4f369756eb82495c409d8b4b
+   fb8b6a84fbc3724e2a1ec057f8b0c90f38ecb058357914ecc20ef1921f609c24776a0399e95640e8763c52a4b6546f6e61ae264fac6b0fa6
+   f307e5052df7b843a92ee073e9c68339213f8269a92c1c009c39d384c2739823ef099f047e0c3d98b4aa0df85f75497ff48215fb5067d39b
+   f0f5414c477ade9ce17880e5825803b3d493b002aa9b221f642b311ff1ca6cbaaeb772459857faae9996371a9c415dbd8c11cd23f26f83e7
+   7f1190954fe5395727adb14f65e30d20abc11605afa06ea31a737082457c56f1fb0af7508ce8293cefaa2854505c4e5c6c286ece26e08206
+   1d13d997a0acfac41dad8fa4f27a109f270f9751a2b3ab05d1fe5f9652f93955283c625092472b33754de4aedb96cfd45322aef6ff11f516
+   38c37a41716b96c811ba9fb01f85e85ea2a6e341bbb106f63eaed6eec4fcb801054aee5d23a61d72591bf50d1e8db6df6102efd5cbb88eb5"
+    4
+    496becacfee8d16896d44715f12f6ad8d4d01415412e05dc14ad09c49efdf2afda17d8c2a701bbf7385b121fdf035af5dc71db5df20a7ac9;
+  "2b884bc1d8f4dc7f1113a02319a7d7f90697c9191c937d9ca8950d70c8b5303febe37051bbea2d552aeab38904061c7bef3b16727ab28536
+   93ac6aac6d9be22469c5348bf4892c7a327560860bb8cdcc3df04b4d9b6f02ac5e71fe45f2af8139a1b79468e9d7e130e94aaa5269a326d9
+   b57a9885f05b77d976f5a5f2b0f2d4d5e1cd53563271d2f2f2c662605994bd38ec2084a48af8d996398bd17704366cfb88b3dd237dc630c5
+   d8a073dab102aa0087269231c73768138e25b29509bdb8a41c6ac185fcdda0fe95508f770008891502451452a33b28cb1f970b99e99660ad
+   90322d8b23bc34e0096ba95ed7b684b57b191c9a3a261907f9d51f487d80e73c5eda6ac4e28a46cd0f036957f887fa2d64925ebf1cf3fb92
+   7fd678ae15bf660a33b90dbf617a113613d9db51066fe9a64b5ef08ba56ff89859633084d08030f83d708dadf86d85a3ade8b9c886cdf09c
+   398577d3575b41ffe6a33a3087ebcfe65f1b6ba19f7cab354a1447f098a589a249db68f1b404c179c7871a2f62cc47fddb224a733601fe58
+   73c1de266a33ce6ed869eeaaaea93628fa858f72ba45cce1650bce71d0fa2a84fa109864403455fceae8d6f668a556c50298a72cf32c4005
+   d33a2391754ef5cade904482354cfad4446e4edee17bb1b6afe62be457f85fe3a1d19123366b904638c2168e476b9f68bb97bec49881f449
+   8075e0656a3032c6e2a069395f491c2e41a3339b016cc2502b41167aaea6ac87c143fb5326ea29692e5406d0304068df913a7fbe1825fe6d
+   cbfa40aa4c00bf11a0a41e7c2b70563d4eb94673443eb114602c9262b5c629ef96eada6b9973d3b74159acc26c077e62c8b0a860b1e20509
+   81f8d188a6892f0d6bd3bc72e5fba7218070edc08ef12b78bfa4cc7610cc33ea0260d12872bbcbbb7d7a3faa657ea4f116bae7774fc3a8bf
+   1f6e9318eff1512c6f4efaf3730d44d9a7dad90712187ab5ac5415e7129faf9f1ef6ea12c3cc299274b448169bb2a29bc5e23197adc64cb5
+   7a97a826d12a9b0a9c8db01fae68bb9824a1f81e1146e67e12b7681672a4e7d697130a26847d15f85aa352f6940401dbd9ee3333cdc10de5
+   6d7c1914c7f71702a14a3b55536d41c26696c31eca45ed234722c53cc620550a6dcc8c369af7ed68792d9b9b205dd4d76c91990fa3ef69ea
+   f1abc1def89612938b1105fc276615c996221149d2823b1081e820d715bc3465da753302b30174a10efdbedf4e089c767303370b054968eb
+   199ec5ba6d5c13b1a9e3f08366e984d3d6058bcfe225e316536debba6327e603371474fd20b40e8ab912aa5efcdc9f65edb885ba2e6acd67
+   7d3b2e72ccda092a549152a7375e9dfa0e8e43a8a4a8cf275bc6cfddf98fdfa1789283860a69cd67b083b67a74bb14bbb8955b793d2917b7
+   9e32e392d0602a659e08915acace1ec1d0536f34db1aa43aac27a8a670119d830ed5908e66ecf98aa245f6d81884a9ea081f557fe95fbb7a"
+    18
+    9e32e392d0602a659e08915acace1ec1d0536f34db1aa43aac27a8a670119d830ed5908e66ecf98aa245f6d81884a9ea081f557fe95fbb7a;
+  "784ef2f9b927026c7999df317e1ffa02168b44e06b4a8665b91693423025eccc797a3edb30ad6da7a81b5a47fee475d4c26a8c7c8338bf87
+   af0b5e0b9925df9f4c440f29d5a8acd2fdb0279ae897fb011a72d1f0e8e8dec941e05ebc5b607965ddd8862a4b19eee50f0c030dc69db7a7
+   407668731d72fa7bc377feaadd59d0c9a8fdc628741e09c13984654dd1c6e8db573956e7a1ee74e215d12934088c519ed61c5f905bdbe47c
+   566f26ed397dea8cc9f8afafb6f8bb4a87ec8904a4655c76a262e0abadf6f4a4e2e2e1b56956e611564f43249ed1d32699a92b1bd845aa2a
+   8ea05614172b945e59d42e07b1dd7824492d004a0da66c5005cc918881fa601346dce3ad934e422b4fab17e70f2f30110dd5e0f2fbc0a451
+   587edb0b7eb27cb3d20873bf36f48841d86e961e23bfb79252884b191e8bce521cd41aab69036cc14d6ddcbee7491cbd5f5fa44904d4bbdc
+   8f8b3c45f7ca308bd2e3871e66c5bfd78d24541cb85aee2c0b3ab7e9c52cf7316c65896f1cda006ce8584d4df4f5672e7762c8e3b2cdef64"
+    3
+    566f26ed397dea8cc9f8afafb6f8bb4a87ec8904a4655c76a262e0abadf6f4a4e2e2e1b56956e611564f43249ed1d32699a92b1bd845aa2a;
+  "d222fd0f672396160c990e63b69beb9b50101a29e23f4594b8cf9606142df7bce1744bd9bd23af50addfca783abc00433b2f2f1e8714b657
+   d77579f75fe3d2e25ce0582b481237309f704b9c26b2c92f1c074e7c82731c3f8ebfdde4be8016eac2cac15b5aef25895876bfa0a006abef
+   215ab5a32a9d319dc87c080edba717cda588acda5453c32f25c8ac10b78dbb2351dced4873d35993343256cb391b53e586868e7df85e1b9c
+   c0576813fe879523d227daad9c1f9ee46d3166e6ab2b0e2d7dcf87e3608e8c3df6a42931e86f046b5ab09a2491f90a085ca3c2a8a99c50b8
+   c9902d3f732c823d8c7b7bed3a894468b41742a81c22106a4b97d63dcf9f67e67b5d501462f14f76ea4738b255cc1d7a8b589dd948a9e245
+   4f3332f6938d3dc5433070ad1446eb0ccb63891bb87f73e36b439fe1b985861417d44280141984b919f19a4bb4b2a78d0500de6f5272274b
+   085027b48c4e73d81cb44fbf4d2b75af8436252e3b69bff47266ccb44262fbc69597f707fa213130b883346bf2de2c72dc07d0bab90ef2b7
+   dad3a8e492f601ab4e87718dd285d63fe8448e32f074cc22052071d63ed8b3abbc03e44bbf9293e752691540ac5f6e7474e3f9b857e924d7"
+    5
+    4f3332f6938d3dc5433070ad1446eb0ccb63891bb87f73e36b439fe1b985861417d44280141984b919f19a4bb4b2a78d0500de6f5272274b;
+  "c6adf901eeaac94ad01f1ed91cc0665a31664343d7504e64c125fa201d13c081e3fb96029c7148b7853c543c6a533262cc2a4165f55a36bf
+   a797f6a408ff400e2b9af731312dfc8ad9b5e9f60784964998e157ddd0a012432eaedbecfba3103d3b3fde71896e98016d61aa9450b494d0
+   2075ed1d7c05da216efa077e9e9df4d665edd4edd403590d5661239ad8f218bf97f0fad2baca3a5769b871bb75d6ca81818c24486a6a7d20
+   9ac8883902c5aadeea582978096b02dbc0201448ac32ddae068f614b34265649f85d104d60c4f8b26c8f32d6234af5198e6c35a699cad7f5
+   53bf780d121adb03ecfdb5b490c57f0a9c3c33f8da35414ae727affb3df746d7b5e815ade075a611aa936e2a3d2cf0744431d09d2ee34cd2"
+    1
+    a797f6a408ff400e2b9af731312dfc8ad9b5e9f60784964998e157ddd0a012432eaedbecfba3103d3b3fde71896e98016d61aa9450b494d0;
+  "01fef7d69aab6551318c12940098bfd2567895a7a6ee0bcfe3f36ba265b906ec9d4d17184082a08318b387549776ae2ccb6909206c7035da
+   dca0461d8ceb43475764ae67a21f2fa83be4325b65e484fd5474defb1371753cc2bdde641abbfa8d628e2bed81b2fdac3970148d84b5905f
+   5cde9f0cee376cf67e17dc1012dc79cf50b848c8b4bcd02d5097cda42a7b69d997e1acbb63ddb3c50dc1145982a53b63df1f33d3f8f1f03c
+   19dc49166d3dc7c3c12ae671cf3357a00cfe3d573096052199464ed2b9295348b5adaf20efd8af863b64016992dc6b2069b839c65b1f77b5
+   b4233f54659521a9abc2d695ec203e51934f8bbb692f421acca3294ae3b3e6ee8f34629755e2a66404bb8e661fe66c9be3e9ce424d6d8d0e
+   0431d4fda1d0e67384a8a2aa187cfb832eb472f2f9504249d6174d805a6da162554e61ba82105edd16e650baa6f6a11e3bab88dc391747d0
+   9e48544c13a70c3c0615c3a600a70477bf2d367cc3bee5ed04e48d95128e379e83bf1b7ae81ec5b2d9d5724172fac5e3a9731659724c17b9
+   742d047c946e15212675b11d93578a0692b2ab9263a37e7984c7f448ffc3f62ef0dc4f9521abbd3cc132f716cc3c8241a8fa25651dd4f4ff
+   ebca8c7c6df38989bd3c118c481eb606d8687d76cbffa8370d729a6b66d6f50cab181769e5970c169ac3a940ad97c4b87b5c146c4b680131
+   9cd27898e35a850144a5011293e2b6914b760a2a772bfe080b91a4516a7a81329e8bb013fb6ddafb668c3af388e73c71ef7e9f92d34d68f1
+   1853758aa063418c68600bc5be6ae38ba281795e5d2440646661a10812b8292b0ada841048b8fe63f63663974a6668a8809d0c16dd68c709
+   5876b4cc9c0b72c4c7289c1d04431cab19931fac1eca2f4bccd827ef15b90d3c6902515d36e21677901acb2decf69febba5d1b91b4b564a0
+   be72b4281b1cfe9f5449d8e534e7a5b7fca05291d5b5502ecc53d1910525392afb0dd5731682053369ffa0b96c80328c515a858b9c9e7df9
+   ff447e23b4e9337754b3a4a103ceea5dae583ec0d8e95c0e2022a701802b5133dbc5711e686d9ef1f8b9a7d740b35a7a1add878f57c39084
+   791ddd6a98b7ad13945a721f64363d80370bd1bbcd6b607f81b4027369a7286892dd418ac3fa508d9c359bb0af7a28fe61faa777e35532da
+   639c6b7ae2ba3581e67599a31ede062466f29d3dc920bb1c26fd0d86e57a9ea4f028a3f1aea41293fc7cffea7c0eb0fee8d46eefb5f015cb
+   b933133a80f707e0a4d4afecfe5af5978103f68759cc0a3772567e92522aaac9cf3919361f2d1f699562834a1cb1af413b6c5ee8bdfb094c
+   63922aaa6687ed42a587db1cab982a6becb9f7a8112610c93fc4ebbd67d80ad803d67f2f1691be669ddcfa90d254ce6db1c986b297c6f099
+   f373144afee1b800b8e873b5fc1fe711855bb1a1a7986f7903c652eba8d06c14800c5fa2a415783195a34091865dbb4d9e802aebf8e12c48
+   df26c33ee19c9ee2812443b8b847b1c490cf6a021d33d1bfd7e55f15a5ded473c24eecaee21e53b6059d35bd29c25a7640efef8f3b74c53a
+   3acc27c90c853f579a2166bad94698fd105d78abc7177b5157ce7cbd9cdb9af483aad43a41f5838f3962ab54a34f60a299b0693da1ce8d8f
+   9fedf20b7dd1ec189f3c5777a90e49f62592a6bd761fcda02739740a1e965793a3350a96e76fc9295d0a3c07763f8b303b3def61b5c79d91"
+    10
+    1853758aa063418c68600bc5be6ae38ba281795e5d2440646661a10812b8292b0ada841048b8fe63f63663974a6668a8809d0c16dd68c709;
+  "b0dd459972f26130e56b213ee143fac607fb05d903d704c5341ea4d9e1400e7f153fb61c08d96a7cb7d9504f29e82d62b121bf8f093e2a70
+   4e3b3cca8e30e19a1e42ba712bf2cc7bf652a60fcdf20ce1ab0d644db6ba3859980ea1bb7686d36aa0336f5ff68767f764b451ca99bb4662
+   2fca99e06eb792e7ab282ae71cff46caebfb2cb3ffcfc24a286ea93aea330b30000352e468f012082f6da3afed8d250139a993f6cb9b01b4
+   7ccc0dc8b4c8a40be0590bb3bd04ba1a83b739064b9a908c171116b9aa542d6a3c5020860d82ae5616df8f9d6888f4a1893f84548242a30d
+   4f2558c7afbe00affffb7a6e6d3197b3c06070a6abd1fcf9fe96c95e907384db741e2d96a9f8c2b4d321271cbedd0acc28107516b9c35e3b
+   144339eafb5f4410ce53e42d265ad23cc1f50e2285bc83a6e5b1283fe13c2f8ed717e0c7701665c15287f3a4403fc965300993d58e2d352e
+   fa6591a0da6e941904c14419d7967183efc74121d2f4707bec26d3ad7945aa8a2fd915f88bbe5d0c4cf88d1a3b3c2cc34e2366d4bdaa8f0e
+   bfa04bbde306fe6f183ebc475063e663ecd17d0a5d8e7ac9f0d0c086d1a492d3699fc60884ebb40092998675070be71a37af44381b263edb
+   008c47bec8df4c8b58b2bec8b0caf1b1196a9743264ff97505f0f54957b677cbe65b55c3b618369bd359643f8cc197d3eee6da3f0752c65f
+   bf303c7d3cc0fdfd856e55e224933e3dec2925f9dbb585901f677cc20b9e82a9322165e9860cefea0b496cbc7045d419051ba60502301f79
+   77fa87fb306649e879e4401c563435387497b8e0d0529e2c1089071cdc25c1b994654322604fbeecd6f1f4b09b6c4b38c7c8dcf927df3375
+   6e293762f58649f8db7f95f796f05afd0128bdba1a1450758873ce107bfd73d9b02446e12f389a70472c11fe890138e5910ee36a5207ea1b
+   d4acc12993ab8fc63772089ce1e6099c6d1c10f6a9f37dc10cb484ece0fed7e3913728308cde4cb1dd45ca116e2cff539139ec26ac0cac1b
+   a5ec3a36809e887e328a170a26fc0260701c0eaabe85344a77c7b92bfcec2b6d51e95d9c049e01ab2d9eb92d504645a3810aa9cb4ecb541e
+   a3f3009f5a30ff617b13c88ffe56c8f3931166cecbb14191e87f5fcc885f26ac202ed15141a0f44faf89ba0667bae3bb898f11c87d94bf19
+   368d8d71b1b8842b18ac8e238de930e1d41856c2ddf233532fbad0a8230cd735490ff220eb296c65f6453b551507bda195129f1237e36bce
+   044bc78718d29575ae879945a68385fb47a258751899efd20a129b60afb82d78e19865828ef514b5221482a87f87431a6da768a29a8a1b3b
+   d266acf94a0b7dc47a22aaa7de74d57845403cb2b19bf49a1cea2709707290578f495721bd502c3f01aec5e39f8db00fee463842235e7322
+   1f20eda3f21264d35ca121761286dc86565af4129e5935e3022beb901e1c33f036be8080b0db811c35d1fa2c89d4bd1e3b83f7702f7e0b81
+   ac9de8b30fb75c96ae660a66694efe1bafcb17d3a86763dd772e835cf156003363a513e40bc336ee370aa4c6fc16858c7b8cc81cabc2a26d
+   0d755b67af16b13b5b1480b715ec45e7f358bc13def20ac584a0828dfed32ee645c07ceff44b9984f47ee8167763db849cd09d632decaa9d
+   6318f97723d10a076df680ec053ef5edaa80aea43380188deb6f01867d44e7b3a2d6b6afb1b9ce20effdbfae3747a4383ae9bf922156176d
+   ec3d903f8b9e7d7cb5b9ac03e594d126cafdc2006a6d9d6340ae97709d3b5f204fb5800d71f22d3846e7538e7bf8bbfd8dfd56a6872b171b
+   a0a8f7ee813c54a12d25f8bec0fd1e1c17dc53d507b679fb9c642d16b52396ff38a047070dbe6c525aa8155dde5410176ee61fbe73f1d119"
+    6
+    fa6591a0da6e941904c14419d7967183efc74121d2f4707bec26d3ad7945aa8a2fd915f88bbe5d0c4cf88d1a3b3c2cc34e2366d4bdaa8f0e;
+  "ccab4f0c141d4be56445e44b9ca31713a70f04068c1d6f8773133a3fa12b5780bf77e7cf2198d0bfc47718626699dd5fcc739c3e1b5e56d2
+   12967eea5ed26c7440dfb69af543073caf91f8524b5a012e36637ae289070c638e0fe6055da8e03cc04dca88748cd3c8e8996b5ed01a7a60
+   491cea5146604369331d9e03a8aa24e57cf67cab73feb2eabf575f25d8ef8c9e197c16302cb579399e35688da7a4d9697a8b783bff4ef105
+   6caef4b5076ec61992bca432a1fcd2b49c9f7bc667ef66564ead294772a877aa3872b85cf2796468d8cae91857e3fa3720534fc58c12411d
+   eb68efcd55e40f78de8cc4d6d98a04782acc6487c44c88297a62b18fcf10b8e621bed29ac2168c10c025012f20e478496b9c29120a50c72b
+   9b92a017cb7ab4a7b6d8149d91a2c2b492f7b468368c2c78ad4fc9afbc20b337b7a8b56cfcf9f78a4825776a52f659863fcef3b99a95e5d7
+   b00b881d7c2ceb22741b836a9842b238ef7f57709b651772b20954ebd0fbcf352aa02c566c4be7801df8f9858880dd941f34fafd42e93b16
+   4f8acae1f7fd9b9e16d1e254f686ba3355c70d66a297fd44520b7ee868a534b57c0a8431431197147a2767faf6acd8fabb0cd92f10fe0b2d
+   48f351f7f4d0cc779b6086e851ec32cbff01d5be770c971ee7043a750e0b8c27f2fd0dac950b97f2498510e1e478febe5bee4fefae2bc63b
+   588cb86fb2a2006c9bd6c59fa0c2ee6328de8637480ee66f7034338aac29bc30b8096a4d5775cf15aac5f3fc6a0bcc4cc3db5caac0fa0f7b
+   06f7de48f58b098e9d671eceabf64042c4786787b8d4d09ef39919268a7d61308dd1a8f1788b95557ed51f6541156524e3db8a84429823e2
+   96e1b238e36ffe5be8475c3465d4fcfae0823b30c29dfa22604c1865c64964e6676324e602fabebaf31e79e2babaa406e2a6cfd1379537ce
+   f41dd5a29af40dac44fccb3b6158f5b7d262898cf7d3bb55605d38f564eac8e1a78263fa3fe6a8083d6dfe2b715edc1e20525c73935b0028
+   417b125deae3ca19098d8db58aaf30da9e4ce695205bc0121dac49e6006cc1c739a8a35cc59b7222b89f89a9d3a0f4e5ece07a1b0eb05a55
+   ed9b7a983e2fd96a0a51bbc431e3e678e2cce9a6c1e163b2e74896930bec4fe1099ed4bbc4f99bfe131b9d15476b7b8e382d19eafc31a665
+   47445ec916b8e648f789819db1b43cccc39cc0ffabeaeb6ee01dc27ff34772c3d3ac29279abbe245bd4f76105dc39671b8b2e72744fc0bd8
+   766f9594940f6af58f357a2f70abd52df591122af84c0e52c8f263a087883739731717367c194f5c1d7fb4eae7718caab7be60fc4d983a92
+   a936541ad44e13dcffffbafe4502688982aa10149286213786b5b241ca2b6a469a0bacca56fb4663b96c4427f4a4858de682600495678c61"
+    1
+    12967eea5ed26c7440dfb69af543073caf91f8524b5a012e36637ae289070c638e0fe6055da8e03cc04dca88748cd3c8e8996b5ed01a7a60;
+  "8cdcc79df50ede419c9312072720bd05817b40758c4428a4558685c35f51bcb513cf69457f3e376401a57cdc50cf6bc32a227328a584e324
+   a7fcb9ca52fef752909da2ab425b7f265aafd34a532098f4ddf44b1358efe735cb556db2db513a3e628080064057490cdd9e531f93287576"
+    1
+    a7fcb9ca52fef752909da2ab425b7f265aafd34a532098f4ddf44b1358efe735cb556db2db513a3e628080064057490cdd9e531f93287576;
+  "320c54a4573375dc00877072cbe456458878e2afec6ca4ef9bdbcc626a2a864c8580ca29e2f08be0df0f79f19d90f12e23a779b446622723
+   4f8905963f7449ac324babf3ad410821f28218336b0eea4bdcddd53df65f6ba4b5ce214bfe16b514bfd6b8643ee5728108061300fdc15aaf
+   d35cdf2ab2b43c692449b60b6f9bf51e5a8f62dda8d01498a029adec0e028a3d656a9ff89268e0b4d50ffb6b0b7b8d3bead33d1a6f6343c0
+   7a6e2dac050b25d374c41f997ca2ef066a39499cfa42092ac6bffc1d45032426020f76017c6f1d88b6b9f6fb6a39b1ab4e5c10042f52ae1d
+   09cbd7f71674cef676dcb610f32abcdc69278a4015ea047baf02756af19dd92b232ec24ec245089fcc02d6ecc9f9f0c954b4ba12403b1577
+   3f3c0e9f659db7385864ec08b0070418223ed5abf92c93153d21619ba7b92e2d0c2225ff8c41cc28f59f4cc09bbad24668c3b240e288e7bc
+   7deeb1a4868ada13ad6a571d901346d9211b7279b34724ff9d54a595bf11e26dc02abbfca03a6f644163f38de1159004e7e6b0e9e95bd44b"
+    0
+    320c54a4573375dc00877072cbe456458878e2afec6ca4ef9bdbcc626a2a864c8580ca29e2f08be0df0f79f19d90f12e23a779b446622723;
+  "7b40e118dce4b0002313fe1b1a6c1bd204000d70f785b862afdf3c526da930433e23f3945c704e52790dacaf884966eb144e667c652a45f4
+   cf26ed192ba166343068e3d42102235c4ac9c237c631f7582ee32e7ec56fa9c8ae1f8f9d81f5678a7669b7cd377095c885da64fc802eb19a
+   865c12256db1fbb617cc3f05b1f612d67a2acdfe39dc94edf56a70fba908a1fe30083d3c59124847e8ad4640b6c9821731e6b3f8a72a8d82
+   b23e5271565249015b6cf890ee2268c9757ca61008c51ee4551a9cc5b49c8ff9797dda658abe963861965e88e79f4940e1a01ac0b542a28b
+   616be12145fcff9f23947494e5afaf0d689b1438426498f6b755f743804bc3663c1f9c6a08a545ecd4267e1254862e8107c83263378d0534
+   081653b1ad2b7dc50983f09c5f86e7b0cc2892d875d3becfbe2f2606d2e96d0ffca3820c02fdc2eac29cea70b1c09e911d4cc9dfbac64371
+   261854d5b0ee5fb1d158a7f10ef7573e6ad855c950f1bca6edf9a6ed6e421c14c4daad7268017e5d8aee68ee81582083824182d5bc7b8757
+   77780f8e27261f0dc2e9deeb90a7df2a3cb78fe73499dbb08b502019f15fac269394f8d5244451b4c249d370613f30c2639c6c9d8d0ce20e
+   209c9d58a10a1b8dc7ac099de5d7aea7df722fc42aa80ec53becc9d1c51c3496e88a740a2bdca964dc9fe30205ef1d1237de66bde6578bed
+   cf810e1d256d39bda5e99b1828bea7020487de3b8e9f02a6a28296d7a50e8b6fd3ff7e5f8986beb80df3271c8f59d24fe1556f2378b07159
+   8448134451144751373f2ec4843c736fb732298f25f80236731ea996e8e077d7c2b28256b5eed60b26f70835829d260010b50bdf14b75b33
+   c126cfb52ca7878f68e16956fc50efff007cd3390c129b95e05f62d85fd070d52b2913033e0970473f4c9d5f8626c06663af36f7a9ca1ef7
+   a0f342e4284d7f78485aa503833e96e6552de7da3fc5faeb396659eca24ad3a77d1f29c4da10af9689d239edbaf035d78b21a9230aed368d
+   91313abd6a16eed80c3ca1682e7ccb53242609898021e5cffc565a9e02ab331d1d646aa35737055e9ca1fb6d5105ef6848de0ff554d8bbf2
+   32c84317a8dd5480c855d9f1b0b17b31621a84b4b740f62b48c84539fac7afe3ce774cc181cc331470a8edd3623d4b238e7ea952c18c1480
+   48adf9043dfbe3fc7dacc54542a07b5b357f95b4fb8c3402732c567ed229e96b8528cbcf0ef3f3b32e6bdc7cae369ccc2585cb6273b2069f
+   708b127a4abf9ed2eac6db4d3ec4a61a1ee3b333df694f1ccf1a82839ddd4a7df7888a8da3100d1ced09288bd7465d0c75b39570c8e9f666
+   b0f76dc2a85d96f93b13b0d5a3af482bc85a476fffa2eea56369155bd35a8ce58c5cb828cc0defb630865e6c5a4e4b64abf340a279c61ae2
+   2e1bb979c25dd7d8bcda1db000e1f36e63660bad24e6a8a1300cf249fda8b7faa35a5f0f1012200a21e74c9787b9091d76da1137b6b16ce9
+   0e3288e0d0c0ab49ad55b6420f5c6277f7ec5cff69498d231dcfe435694396653fe167be1942bb4926378684478a7dc96a8c983030632646
+   ec2f0426767bf10018c0486ae303fc4c1680b0d7e8d9086b129d3edeafdd4828019963c3a4a77366e99f01dd363b0189fc08d534688349ba
+   2f6dd77cd75961e8e01d7cd6ff0a575b44305772d42c20c73013c007224918f991c135355fa170652af9b20ec8a6e3716a69d01df943e2b0
+   ec0056f155947157b5507657b8bd81c9081efb470169fde59e7491fe6cb970dad8fb5599c9c296337525038b0d2912b5a8169c1cd3b0ef17
+   079140c4624d0bbe887054863a1c6db1c71d33a7cf3e81dc08db118dfcdd3f6e9bd13b2d68cc4f957ad212fb246fecf8b042e7424f211602
+   ebb41f7bb07e945c49177e3a2096db7bcc299d63239b3496ea09a9e619fb173daa10fd3892aa21c9ea44d506e02919e2a762ac283cae06a4
+   6e6125322201fa911178a8aa1ef86c60f78591d9a41e99c04640ba3cd9e31c040ef9716a13c15cecd120e101e151ed1d7b5c820c3783fe23
+   b58a44654698fad8c09df2c47dc65103b636fcb7d003c913ee0ac5fbfc41c30cb513de83e770608cfe968bee9049454603839c3f7dfd38a7
+   ac5e4adefdbeca79f82c626a49037f0f20aa27d4e79ce692dbd56d7a32ee7e56f567558ae35c59e0077b9920aab0e9e288ab4135ab4a8bb8
+   2b0f72e08cf751955e070e2c9175f5fbea10a0e863a9a4320bc1f542bb94ba2df539888b52963a8642ee2e89ca0695e47f245988a9cc5017
+   e71381ad841759e1192238340581579b8240a0b8d864df5ebaa59d1c3e404d80e55cd71f450dc3abd72f51826c9f95c53b9860c7b11fe81f"
+    20
+    ec2f0426767bf10018c0486ae303fc4c1680b0d7e8d9086b129d3edeafdd4828019963c3a4a77366e99f01dd363b0189fc08d534688349ba;
+  "3ee6bc766b8a4f70d9dffc141a8720bca8fa0555325559cae8e894286c62b6181a86da701f870d8438503aae2c6816fc990a4aaaa3c34ac8
+   57ddb56c6ea3640ce87ae490cb3de3c5dfcc73ca56f0c8166344bd8147aa774f4ed4f99f3843d87adffe51585d9bbf5a5aeead0249fd943b"
+    1
+    57ddb56c6ea3640ce87ae490cb3de3c5dfcc73ca56f0c8166344bd8147aa774f4ed4f99f3843d87adffe51585d9bbf5a5aeead0249fd943b;
+  "64923b0839c1ddae94113bc77a095aea7beae2fc781044305bf7560f75f191015a0780cae4fe386e02164667ee49ce2255d70205f8b95061
+   03d4b35714f7e1d1550ff9c7c2bce527ba685d5acc11fe028cdf7d01b2f7a88ed7f91e61aa9fe3bcd56d03a1c6dcee4b22b8388e6192f0a0
+   101abbc5fd41c7d15af6060ab65a9f26f22708231fe4fa210d3d47612e0980b102b5b065c124303e65736cdd354dc7f635daaa16837f6f58
+   b1e6dee61bb752d0f861d6cde0ff5c000bb79ebccad5eac7248219f0ce2892fb4d36b6cdd626fc1c4ccd3c2eb4446aeb809b851f54ab637d
+   fd01f0857716beed6146e69b98b77c050e464bdfe39388dd4069e21f934f78871f4667b91aa15bb5a4431b6515e228971da72653312dba4f
+   ba23aaae35cb4698b99a71310ac4d91319d544b2a6d484c968b6e60b07ac0dc4b27ead47c706d6bb337707bc0d7d2b215293ba2f3d54823c
+   4b00fbaa072a3932d1340bc8aa4d64a0dd2e94c238eec0c01c714f01be4efe68771d641db26fe3cff052039120f1a4577f0ee49789b04760
+   7a16353d4e3f5a611d356087822fbe7a5b8cd4759fb73e498262150c625436c7c92b7b85fd7d37019b6b5829625373e134b15b6fe9e1a3c5
+   cc26a1679c0159dbbe9c2183abe2ea5365870ece6f3f5415913e8cc673c7aef3d493d385883670f394a7958eab3c27cf5edbc238319a38f4
+   63e4267cb67861d332a6ef69e7de91e55545d7ae6c57058edc8d07b572c0adb24fc618328496f7a6ea7d33b17085578f3e09d48718e81cd1
+   7c381d103db934fcf0ac2b6ceffd3ea770f8d41903bfbe40898cc42dd2925632b051313485f37fbc205ce02ffa4932fc66b6a6a3e8f92894
+   74a8bbbc822c5a802dc22bdc2572349fe9e4b67467fe1af5b5d15a14b96b9228e6207b0ce334595a391c9271ce87149839ea54d9c57afb6f
+   0e0b81a7f9ed3386a95095efc79ab14374b3b24d9fb041ea1744dd2653693ded0aba625c0b0abd8dd43354acb25d09ad5753358c0b3fbc01
+   9a1dc5b5c8062e2db0353af54de4b7031e004c4c2dc44f485e3fbafba1d36f13eceae3e798ed6feaceef7f62621bb044f67e3652a6be2438
+   e8ae38041d9ffb082cf6e09e6a1155faa5cb882dd4bd59bdfa77eea06a89c128398770929a77c9df8007a1aae42e7da264fcd0ff91d6983f
+   90a1d0add21d33bb51ed34e78df11bd63f09b8435b896a6f92eb90d1a89ab725e5c95a3061cdb76afdd23c97dbc250c5a04049d136f64ecc
+   480ed123adf437beaf8a52906cbc4e659c3bcb2a0a38abf7674fe791df579cfefa0fef81426b03627151880f627a8443b366c2981f3781aa
+   afcd937d109e4f48295d96d85f1aa5b2dbd3a57b180b276a834c16a548c508072e5c4975e4505c2b77d65d5f44acd9fda3fd9ffba43bf790
+   0fb7f24d28cd68cd36012603e46f13fc3bc7e160e5d279654dc0b3bc7a6e1a6504ff68c3bb6a4dd3c62d4914470bb18c240322b823a59d4a
+   2fc7f189408d131cc71581de4fd30dc4141f4d64e519955364f7d0e1edf648e056e246e849f6165134ceeb09e7428a85f1dc2b7fcb4759b6
+   f34d225d73c898e00c139993934ea4fe75f63dbc78e9f73d598274a35dd30828522ab0fd0ff45cc755e975e3ce29ec1eb952c2e14a184c25
+   eae46e62ad9da564239446ae36b08e5abe97d5420a5d874c3b9df3e7e0fe20ac7da239b55a40e68220fed770896b8d912af3e7e91faa9112"
+    4
+    fd01f0857716beed6146e69b98b77c050e464bdfe39388dd4069e21f934f78871f4667b91aa15bb5a4431b6515e228971da72653312dba4f;
+  "df12a2d80adee0cf7e51b3f5746ee311a26041da37ef591fb9db82994b05c045afafd016c01572a54f3f866479c19c10cef6dd91cee1a758
+   537f656d9d2a02f94b5e62a77be3edafa937c2fe64052a9a50191422f565e3afb7dd35cbcc42982a341ce7297a64cbfb39ec39c2dcf02707
+   9c455d5d0c800754a4c62cbb20ab7bd15390de954547bed2d50b2299476ff6106995b9a4193435cdd65642f9b97d645bc1ddb64a0fa76cec
+   db602c286da5b68027b6341e09f2d04b7d4de0e5e69f7f98aaf5e3356f7674cd7aca07e07feb8a592ed38253910d80458a4b92b62439da8e
+   0b78e6ef87be5081ad0f17a25e02f11ddc9d2e1a50c8034c41893bfeee3dc1c5500145a0f7b4785aa387b6976749be5d50cf2b3f747a7198
+   6aac5037ce56e36a3125fd648e2fa38d028496501b91958c6c7b4c4a4af715d054e41c5fcf3a1050f627718deab0a5afe04f0bfa486026bb
+   5931140c034302b23f67a8c59d47812c34f07a0e89c0c2a0cde21ff3b2582999e21a9a125e4c475cf6139a315dae9b280572e9c3a3cb9b6a
+   0a532903d8d46e6833ac623e2d36e6b439c750309e40a4f04ac27eef685eb0286498dbefbceefe0d17af160eac02583ccbd4ce76c3c3e291
+   25e62741157a21bd593b7019af188f87f5c1327bc71e4a4b04e75ec4a471cba67c9c8525d9431db65f4cd29fe446c11ec22d8eb3d8763f96
+   49b319aaaa39a8c567159a361e6b6cd5606083678f65ad887bef643a22337119d11c14d808347b135c1cb2c873b06ae9300504d17c2562ed
+   c43066b69c7b78eda663a407d5335727df3c16d190876edf1fb2f7f1b923b12e71016a4f72ba08c6c0dbf3b56c145afe75d133413dd2c051
+   adde9ff89c361413c9685d5bd8a25539bb6e834c2730b0462864bb77cdc09dfa34db23c6192eeb8fadead450d5ca86695ecdd579bb0e70cd
+   c7a14d2415432bf7f9543023689e5ffc335d766eb52103827f3c5db76bdf392dbdf3ee42b08749f702c3e5e8d5d16628e5c6f0392e67c472
+   560a7b9032c0eb25d8470b64a009c576456226200a85f63f3f9735f4814897b2e687d0b20cb62915b10c225610c87bd9aa3303c1da8a7705
+   8fdaa407861a1b16f36571029d492ac6beeab627ac76992bff07aad688d3fb6d67afc7afe2ead365cfb8093bd7a46285b4112c55d5071735
+   86774ed864ada8fe180264fb80c1e41dd80b2ad3f08859c8f295a9527eefd858f9de22c186dbdb05b028538e1198e099a15fe56af5183764
+   8ab5e7a159f44e3d4bcba598cf2207ce0a1a490386ca2fa2e1ab767d676b92a8e96e464fcdf92a1b41c31d534ed8ae2525e65831945e7388
+   dddb00e27a12adfbb3f7bd005668f3b1253985ad7969567d7d3f994010a438ec9f72fe6443dae930c4a85087acaf53dd63db5799088d395b
+   3a91d9141f0cb0d8f4f60fcf70c7c46c22db720af58710c9e106a26e3d5cee95c695a205791a92c99536c1c7071eaaeca5db3d897613a3a3
+   98b8fb64470162840c6a4c50431ef9323578752c66422f95daf2a8bc7601f5974e99ef5f0b2addabf0c028059145956c6486ed9bae560089
+   20750ce31325c8036558effec24b9551ff28c66d66ae4d484798ece5f52dd62482901cfc5ff31977c15c5ebcd959d2ce76e90f6b2b98776a
+   48f579e7362d27765968081d549578cae8f88a6c092ce45678fee4a68fbaef82775f441538c85e66b7fa96c825c2e7859dff814b9cff628c
+   c82123558c6bb18ddf96c2dd4a317f0e75d6927ef14d409bd9e46fb3b43ab8ea7b74f50b6d13d64ffe92698a076bd6c89eb8e2846e6fdd32
+   a4320c4d9d647d32c46225f741641681ea81de604f2f8cacf4a8721a948baa86fc4433fcb8cd818d44fefd58d68066a2b44ebc8b71ab2ca5"
+    3
+    db602c286da5b68027b6341e09f2d04b7d4de0e5e69f7f98aaf5e3356f7674cd7aca07e07feb8a592ed38253910d80458a4b92b62439da8e;
+  "2b32c10edef7a71e025cf8cda4b901a5d70aa7a6c8d234c3564d6be3732bceb317f3902d908483c04862cc0e4626742fb221cbf3ebfd5b63
+   4e9cfe329c1bf51d8a102ed97bcbb7f8fe72b535393955d138881fa1796a68ff70bc38361b5926a313389756da797b40cb0ac3c1d164e895
+   53b03cd17c9baf7a59879393046d178bfda4a73b9e6bd500717eef1463d5f55ac802924b7dd323932b3382023c2e32cf4a8f01e13d8b0e25
+   11c19f0aa645361c3e024de76d9db38ed381d55e5a08a8cd32f1117f37b1e3afca1fe42c52fe2762c45cabd451cc73dc2fa3096b0fa565ac
+   91dde9eebb775f4dc6291be5ea32877d4dbc91404edaa2145423c7b83007c65161f7139dbd009c67629a49d4718ed47318d07324f357c319
+   bf9f23cd67c9614689e77c066f3185b8614924d379bef722c05d8a4758527c05262895351bba2726b55714f65bf2493956dbbb5ca33b5249
+   4a14e23723cc4154f7ce0e45af8db9de5c6d4a1d910c6e2f7b403fa8f069dfd0c844fab6ea81b736924b754864cb6ca8e76a4c626532fad5
+   ceb9c350542515c3112b8ea2f08a78d5e564614529a482a5d541b7c38d6e3318fde02b3d740021b453f1120b558e089478e39646ea5cdf5a
+   35850876387b426d8d7be7d1b77162c39309c83f0e2363ae1580fae2342a6847c9c79590148887a94672f5b6707d6711207b62aabd08ffda
+   b680b68b6c61e7c23daba813e1a0283ad83e20f5a9500a22c22077cd12e0164562d8ed9cffdf2f267ff95197d40a7ad26eaef750d9310ad8"
+    9
+    b680b68b6c61e7c23daba813e1a0283ad83e20f5a9500a22c22077cd12e0164562d8ed9cffdf2f267ff95197d40a7ad26eaef750d9310ad8;
+}
+
 condswap {
   db0be3ccfda1e2f8492bffb5d3344f1856ff1896b6a067d2fa064423ac5b05b669db1c9b51899c44a7f470be4173856d9aa3d1cd10cb8c9b
     3005560f89232a97cebf6808e7493dd0f17e572556b53723b57faee51d8a0a45c7fb51aeb916f59c74ea6041494483b2fdce72189d1bd031
@@ -448,6 +983,78 @@ inv {
     9de1360b4718fc762e6ffab46827c5e4672a77d797aa608b31c132d1ad8138e7a64ba1f4278a07a6088f8cec9a01ea9bc1427c55241433c5;
 }
 
+quosqrt {
+  100abc40abe680b1d68dff51c5fdeff4dbdf3f57ee5730f93e2fd4ce2b0170c513699af25c399df66312923103fc6ca6ac0a70019ba667c3
+    1b56e39c8b69559d258a2b6d3741c63bdb397f7337c8948e27ca9edc533cffebd3d065ce09ac3f809900528960673cc565363c22070efa56
+    "" "";
+  239454b921927e75aab58e729b5023c6631e99dac090b8ff731c59e1f17e8444b17669eddb4dca4c7625453b3039fbbc33a67d63ae0bbbb4
+    7f6be86111136b43f87d17f2b150e07d63ce8b76566931539093d8f4d63171076f468dceee0ae254fb4699d6b9a17737622b2769616ea22a
+    29bd0d1ff7823b25c9abc822a64d70651d4570436c60c17d163334e0b1e7dacd00e4100d5e11afaecd7a9c695453b327851f322f12d5833f
+    d642f2e0087dc4da365437dd59b28f9ae2ba8fbc939f3e82e9cccb1f4d182532ff1beff2a1ee505132856396abac4cd87ae0cdd0ed2a7cc0;
+  449eef9eed43b44c96da3562082d6533c4fe380263ee99adef4d6b9bbec8a5451a0aaafe13b31625be0d978e15b69285d773fa5d32050aa5
+    786ffc54916ebfd732f8c41bf176e0d9ab00378a1f323e7bdd06ccdb5b7bd691998465972d9a9270c63b2d36f32dcafed3d759fea17049d5
+    658ca99561d3fa22ee444585198de88164bc394196cff32589e3bba41bae4eb0426515aacce53f9f6e65367a06862e61dba2ef214e113a53
+    9a73566a9e2c05dd11bbba7ae672177e9b43c6be69300cda761c445be351b14fbd9aea55331ac060919ac985f979d19e245d10deb1eec5ac;
+  a00bb50d51f804d768ebe27b6eaa73909638c7873ee3e29c2286bdb08c41e9b83b006501e1b19bb7a5ca02619e3a48d1897e2df89aa77d12
+    9726ef3cd5a227ae1b19b4b8e935b5894f147b8917a26e796748827dea21cad2f31114fbe65d72105af5f092d781ffa883e556070ba7dc89
+    "" "";
+  f1910f1ebbe859e8cc70ab7b4c7878c83e9136a1d65446b89c89e48e2d56069cd17b2fae6e9ed534570c69c3d7da5480246e25d562ab1e79
+    da061395a5c61f3931f6ffd82ce2cfde3566c1c1aa08bdf4ab3fb78af01ed9707fd3106c1895a5e232cad0703cafdbcf9e702602d7bf74f8
+    "" "";
+  ef24c61d4dce505ed20a1326c295af061102ec611279a5b5370c606e02af725fa9ee12dfe43f08de228ce080e3ed9f5119f325bee206b24a
+    8c19db90355ae4b7a2068e11a469aa89ed6026cdfd7956e5499d3d32f31af08b133c4232c8a423f6892581035de4b489bccafa5a9a99a17c
+    23f8c54fa352bb2ac8eec7d0d011127265c48971ab81510d9fa70760d1c16f6121642d9165532dfb8f3b6d59b4d76c764c374a03f5785847
+    dc073ab05cad44d53711382f2feeed8d9a3b768e547eaef26058f89f2d3e909ede9bd26e9aacd20470c492a64b289389b3c8b5fc0a87a7b8;
+  d0e656fc86a3ee7df5e49994762c296ed4c42b6519f72379132c89cb40559ade3c4df282cb78188d0603bfd853035d961c7af054ec104ef3
+    d2606596b3129852263146178eab3f1ddeed9830165891ba60446fe3c5fa6dc0fa14b1b4dd136b63beb8e0d4670ae68a41489a3fa8f5f644
+    171a22e9185b78ee81e4812c46610e53d0be70dc7517c6c55646731acff302ec1a95f36600864891a448c2d7419277d6de828b4b2a197f1a
+    e8e5dd16e7a487117e1b7ed3b99ef1ac2f418f238ae8393aa9b98ce52f0cfd13e56a0c99ff79b76e5bb73d28be6d8829217d74b4d5e680e5;
+  aa9f4fd1cd6feeefd624e86f9e6751fea77c3cc5a5916bb52c20b0dfefadf87f609a10e7b818b8797b784f0cc0b047019705369fd8de946d
+    aa088ec4d424a3af2c1d151a863453598dfad13d9b2e6f57b94305f174ed21344ba94fa0c6765607bb55fbdc50bb188109a8232c616f38dc
+    4dd7a6455110fcbc1f784278f28ae42e87da315dc9c88ad34ba8bf13208ab19a24524aabfb6716bf003c9152162bdb4f46bb39a3c1407824
+    b22859baaeef0343e087bd870d751bd17825cea23637752cb45740ecde754e65dbadb5540498e940ffc36eade9d424b0b944c65c3ebf87db;
+  f4cc007c66ef922475c5bae6858a814102081e18af24a841e302bd6a75c2a120c5ac184ba368f275b7dbcddbdbf311aba0ff992ab561de59
+    83a2284878419a68270ca5fbbb8a3457f4a07fd59008fb5ce29775738e3df014f17b166a2e636695c3dda22f35b81836daf86a21ee0246d8
+    "" "";
+  0555309931da55258d2e6da8cc793e1d78fa1922a05538e1611231ff69056de819a6beba569b6f5d49326eb6b70677979083c231cb17e78a
+    d5ce37e5d8e058951bfa6803bece0e3c7aecdaaa9a10b6c01a7e0d0026140c149b17e1e314d4f6940376e88c9653778fde547df2f378551c
+    "" "";
+  07e8c468fcd665489f5a7dfe78417f568eebd0688f57736b7781e19986eebeb8613bb2b99d86dc4b7868b5fd24903124c513946b0265c894
+    dd952ccfcb51790b6dbc92e2331c2b870c991ed195050a6b31bf9d149d20a2393aeea8aea2a09bb226a70868cebaa50f972f2e2b40dac5f2
+    bd5929643f7fdcb2ea2d805109559ca9f3793d8f5d2aba837e286d7cdf95bec28540d1b267b9308efcdd2db734dbb14613884d29e26d0876
+    42a6d69bc080234d15d27faef6aa63560c86c270a2d5457c81d792831f6a413d7abf2e4d9846cf710322d248cb244eb9ec77b2d61d92f789;
+  7598705d29e83f8417cb5a474405b8e399186c3862512b882982e0a7f4805381d5873ae9cb2675d381c40ae05ecda9305477a085d42c877c
+    4352a058af51f0e17428d8df65a33e994cc7981e232420f1429c83fa43f295266d46ff5b2edf72de4c736b92f9ae5af86a9e49cf038118d5
+    "" "";
+  d2f39c7279dc2f48241a5405f368b4678ae576c89a09bf38300dc8a1b814d1639d89381374e3ddc67ec9517250844c9bdd91ba1d1256e344
+    3ed16dc77ed6004dc9547ab5f1b0955ad4d2a055cb0c928e0d33fce40a25ab8501efe829aff4e7a236140b03757988b406178b3e2aa4bd0f
+    "" "";
+  3940a5776e676b759b2ab804f1b693a3f0f3fd63da5bc0c91beb667d59834dbd23bbe01c9e308a24d52f143e8ca0215334cfb4d98823bc3c
+    e3bc2075bcf73a1b75cb45d355ee2706e4757cf26caab0dd50291e7b5b1e7ce54a033049c3a975429fda3e23fde7fe2989004072c3efcc26
+    "" "";
+  7f7ff2a3709b15fbd132ddc0449f3979c84314e03a85077b42926e5d82abd6abee2eff387fababf834ee5d037bc97c212f7f4eb48b4d2a0c
+    96690b4239613235334c326d3b039c905d7869fb208ecbb0fdc66f9bb6e8628118a3cbb9276f7f0d404eee5b6dcef28aa89533cf03950ad4
+    "" "";
+  6ff98f80efb05e4ea76de993f1e7f37f733a6c5f6197b21ab54ebc097a8d2c23bb563f143fe2c05cf92b80e8b731e1552f85e5facfa0a06d
+    aee1a3767feece38a2a10983d6407f698c4e52832010d47d183dc2a6370ffae821228ce0957653e4c6f761db61cd24e0ad88e62bb5a85c4b
+    f46208f05a7299e8f40dd8d14ec4391b39576d5e2c262190e77098897fd29229a6f658b4e63dd5f014763eeb6d1aa0cc54f649aba4b7cd02
+    0b9df70fa58d66170bf2272eb13bc6e4c6a892a1d3d9de6f188f67767f2d6dd65909a74b19c22a0feb89c11492e55f33ab09b6545b4832fd;
+  eba0f9a06f06afe5735574b112735e92e835461b2cd246b4fd32eb775a87c88254bf208e98b79cd95eecd2a0e1745e30d0ee96b3e9e6ed65
+    d48f41458ca8db481e6ca199cde1c7817779787e38f3d70f9b36f4d1c78f8fa9a15f91c4347d19b15bb853cbaf9d917ad88407aa302f1984
+    f43b72258ac14cdc4bf54571c2abee8921e98d01674160fc799a2b0f831a492ac17886684b4fda37cfb62284ce9fc2dd6de0a933b49e8247
+    0bc48dda753eb323b40aba8e3d541176de1672fe98be9f038665d4f07be5b6d53e877997b4b025c83049dd7b31603d22921f56cc4b617db8;
+  425d1f0c8179fdba18dd955de429100fa31195954756e9a3107e893fdbc3cc256e33c11e25c854ef5d5689641cdcdcf2afc92f7d26d03da8
+    8f869392da799c2b62d148289c5c918b0ce81bdc740323f382dfa365a95e78b7d037ebb106e167f5354b51d230763037d3b8e0d52c16a07c
+    "" "";
+  3a99c7d5bad60caef7d655995be6eb4af9bc8e9878533d45764acec722b77d99aa4cd17f444c36d8c0a4028b197faea904053f2f279e75ba
+    a8cdbcd7aea486f317c0349a2d7965bbafc553092a06b2d01714d1d2773dfe64d045670201ca319a9a00378b85c0c8496256d3ce227a44e2
+    31604ec92e3ac8eca3b3ede34dabc4b5cb64ca26401b828f0e0336493ff47b5dd992cc48ec220787c4675fce022caf943d2f7f152818ab42
+    ce9fb136d1c537135c4c121cb2543b4a349b35d9bfe47d70f1fcc9b6bf0b84a2266d33b713ddf8783b98a031fdd3506bc2d080ead7e754bd;
+  2f1bec35e993f3359fccad84f3fcf6f5e5268d40214922d43c402282e6b79cf5125b614e7c9dec90821a66ce9d3a671afb7367774d8dad48
+    cb31d1ea1e4eb4bb1fc5ea102cc54f7be2f8cb48646d5c51939877842063655f25993052da3586ae04540650dc0b31fd87d55e2880f9d13a
+    "" "";
+}
+
 sub-mulc-add-sub-mul {
   07ebfe324f64b54e938951a1e437bab4d35c2bbf5f210c5d78ca2b4eb7ef9c3dab61724be4fa7c2e43086b58db7e961f62a44b029f9901d5
     d44920bba642b8162d1c3e956e060bbe6f15484298c2ec55575ee378556b0e8826f627bebda963b7d4d9f1c768a49cd408957105d3c6008a -41997