diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for `ghc-internal`
 
+## 9.1401.0 -- yyyy-mm-dd
+
+* Introduce `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively.
+
 ## 9.1001.0 -- 2024-05-01
 
 * Package created containing implementation moved from `base`.
diff --git a/aclocal.m4 b/aclocal.m4
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -293,3 +293,48 @@
     #include <unistd.h>
   ])
 ])
+
+
+dnl--------------------------------------------------------------------
+dnl * Check whether this machine has gmp/gmp3 installed
+dnl--------------------------------------------------------------------
+
+AC_DEFUN([LOOK_FOR_GMP_LIB],[
+    if test "$HaveFrameworkGMP" = "NO"
+    then
+        AC_CHECK_LIB([gmp],  [__gmpz_powm],
+                     [HaveLibGmp=YES; GMP_LIBS=gmp])
+        if test "$HaveLibGmp" = "NO"
+        then
+            AC_CHECK_LIB([gmp3], [__gmpz_powm],
+                         [HaveLibGmp=YES; GMP_LIBS=gmp3])
+        fi
+        if test "$HaveLibGmp" = "YES"
+        then
+            AC_CHECK_LIB([$GMP_LIBS], [__gmpz_powm_sec],
+                         [HaveSecurePowm=1])
+        fi
+    fi
+])
+
+dnl--------------------------------------------------------------------
+dnl * Mac OS X only: check for GMP.framework
+dnl--------------------------------------------------------------------
+
+AC_DEFUN([LOOK_FOR_GMP_FRAMEWORK],[
+    if test "$HaveLibGmp" = "NO"
+    then
+        case $target_os in
+        darwin*)
+            AC_MSG_CHECKING([for GMP.framework])
+            save_libs="$LIBS"
+            LIBS="-framework GMP"
+            AC_TRY_LINK_FUNC(__gmpz_powm_sec,
+                             [HaveFrameworkGMP=YES; GMP_FRAMEWORK=GMP])
+            LIBS="$save_libs"
+            AC_MSG_RESULT([$HaveFrameworkGMP])
+            ;;
+        esac
+    fi
+])
+
diff --git a/cbits/HeapPrim.cmm b/cbits/HeapPrim.cmm
new file mode 100644
--- /dev/null
+++ b/cbits/HeapPrim.cmm
@@ -0,0 +1,13 @@
+#include "Cmm.h"
+
+aToWordzh (P_ clos)
+{
+    return (clos);
+}
+
+reallyUnsafePtrEqualityUpToTag (W_ clos1, W_  clos2)
+{
+    clos1 = UNTAG(clos1);
+    clos2 = UNTAG(clos2);
+    return (clos1 == clos2);
+}
diff --git a/cbits/RtsIface.c b/cbits/RtsIface.c
--- a/cbits/RtsIface.c
+++ b/cbits/RtsIface.c
@@ -14,40 +14,26 @@
 #define CLOSURE(module, symbol) \
     extern StgClosure ghczminternal_##module##_##symbol;
 
-#define PRIMCLOSURE(module, symbol) \
-    extern StgClosure ghczmprim_##module##_##symbol;
-
 #define UNDEF_CLOSURE(module, symbol)
 
 #define INFO_TBL(module, symbol) \
     extern const StgInfoTable ghczminternal_##module##_##symbol;
 
-#define PRIM_INFO_TBL(module, symbol) \
-    extern const StgInfoTable ghczmprim_##module##_##symbol;
-
 #include "RtsIfaceSymbols.h"
 
 #undef CLOSURE
-#undef PRIMCLOSURE
 #undef UNDEF_CLOSURE
 #undef INFO_TBL
-#undef PRIM_INFO_TBL
 
 // HsIface definition
 #define CLOSURE(module, symbol) \
     .symbol = &ghczminternal_##module##_##symbol,
 
-#define PRIMCLOSURE(module, symbol) \
-    .symbol = &ghczmprim_##module##_##symbol,
-
 #define UNDEF_CLOSURE(module, symbol) \
     .symbol = NULL,
 
 #define INFO_TBL(module, symbol) \
     .symbol = &ghczminternal_##module##_##symbol,
-
-#define PRIM_INFO_TBL(module, symbol) \
-    .symbol = &ghczmprim_##module##_##symbol,
 
 static HsIface the_ghc_hs_iface = {
 #include "RtsIfaceSymbols.h"
diff --git a/cbits/Stack.cmm b/cbits/Stack.cmm
new file mode 100644
--- /dev/null
+++ b/cbits/Stack.cmm
@@ -0,0 +1,182 @@
+// Uncomment to enable assertions during development
+// #define DEBUG 1
+
+#include "Cmm.h"
+
+// StgStack_marking was not available in the Stage0 compiler at the time of
+// writing. Because, it has been added to derivedConstants when Stack.cmm was
+// developed.
+#if defined(StgStack_marking)
+
+// Returns the next stackframe's StgStack* and offset in it. And, an indicator
+// if this frame is the last one (`hasNext` bit.)
+// (StgStack*, StgWord, StgWord) advanceStackFrameLocationzh(StgStack* stack, StgWord offsetWords)
+advanceStackFrameLocationzh (P_ stack, W_ offsetWords) {
+  W_ frameSize;
+  (frameSize) = ccall stackFrameSize(stack, offsetWords);
+
+  P_ nextClosurePtr;
+  nextClosurePtr = (StgStack_sp(stack) + WDS(offsetWords) + WDS(frameSize));
+
+  P_ stackArrayPtr;
+  stackArrayPtr = stack + SIZEOF_StgHeader + OFFSET_StgStack_stack;
+
+  P_ stackBottom;
+  W_ stackSize, stackSizeInBytes;
+  stackSize = TO_W_(StgStack_stack_size(stack));
+  stackSizeInBytes = WDS(stackSize);
+  stackBottom = stackSizeInBytes + stackArrayPtr;
+
+  P_ newStack;
+  W_ newOffsetWords, hasNext;
+  if(nextClosurePtr < stackBottom) (likely: True) {
+    newStack = stack;
+    newOffsetWords = offsetWords + frameSize;
+    hasNext = 1;
+  } else {
+    P_ underflowFrameStack;
+    (underflowFrameStack) = ccall getUnderflowFrameStack(stack, offsetWords);
+    if (underflowFrameStack == NULL) (likely: True) {
+      newStack = NULL;
+      newOffsetWords = NULL;
+      hasNext = NULL;
+    } else {
+      newStack = underflowFrameStack;
+      newOffsetWords = NULL;
+      hasNext = 1;
+    }
+  }
+
+  return (newStack, newOffsetWords, hasNext);
+}
+
+// (StgWord, StgWord) getSmallBitmapzh(StgStack* stack, StgWord offsetWords)
+getSmallBitmapzh(P_ stack, W_ offsetWords) {
+  P_ c;
+  c = StgStack_sp(stack) + WDS(offsetWords);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  W_ bitmap, size;
+  (bitmap) = ccall getBitmapWord(c);
+  (size) = ccall getBitmapSize(c);
+
+  return (bitmap, size);
+}
+
+
+// (StgWord, StgWord) getRetFunSmallBitmapzh(StgStack* stack, StgWord offsetWords)
+getRetFunSmallBitmapzh(P_ stack, W_ offsetWords) {
+  P_ c;
+  c = StgStack_sp(stack) + WDS(offsetWords);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  W_ bitmap, size, specialType;
+  (bitmap) = ccall getRetFunBitmapWord(c);
+  (size) = ccall getRetFunBitmapSize(c);
+
+  return (bitmap, size);
+}
+
+// (StgWord*, StgWord) getLargeBitmapzh(StgStack* stack, StgWord offsetWords)
+getLargeBitmapzh(P_ stack, W_ offsetWords) {
+  P_ c, words;
+  W_ size;
+  c = StgStack_sp(stack) + WDS(offsetWords);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  (words) = ccall getLargeBitmap(MyCapability(), c);
+  (size) = ccall getLargeBitmapSize(c);
+
+  return (words, size);
+}
+
+// (StgWord*, StgWord) getBCOLargeBitmapzh(StgStack* stack, StgWord offsetWords)
+getBCOLargeBitmapzh(P_ stack, W_ offsetWords) {
+  P_ c, words;
+  W_ size;
+  c = StgStack_sp(stack) + WDS(offsetWords);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  (words) = ccall getBCOLargeBitmap(MyCapability(), c);
+  (size) = ccall getBCOLargeBitmapSize(c);
+
+  return (words, size);
+}
+
+// (StgWord*, StgWord) getRetFunLargeBitmapzh(StgStack* stack, StgWord offsetWords)
+getRetFunLargeBitmapzh(P_ stack, W_ offsetWords) {
+  P_ c, words;
+  W_ size;
+  c = StgStack_sp(stack) + WDS(offsetWords);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  (words) = ccall getRetFunLargeBitmap(MyCapability(), c);
+  (size) = ccall getRetFunSize(c);
+
+  return (words, size);
+}
+
+// (StgWord) getWordzh(StgStack* stack, StgWord offsetWords)
+getWordzh(P_ stack, W_ offsetWords) {
+  P_ wordAddr;
+  wordAddr = (StgStack_sp(stack) + WDS(offsetWords));
+  return (W_[wordAddr]);
+}
+
+// (StgStack*) getUnderflowFrameNextChunkzh(StgStack* stack, StgWord offsetWords)
+getUnderflowFrameNextChunkzh(P_ stack, W_ offsetWords) {
+  P_ closurePtr;
+  closurePtr = (StgStack_sp(stack) + WDS(offsetWords));
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(closurePtr));
+
+  P_ next_chunk;
+  (next_chunk) = ccall getUnderflowFrameNextChunk(closurePtr);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(next_chunk));
+  return (next_chunk);
+}
+
+// (StgWord) getRetFunTypezh(StgStack* stack, StgWord offsetWords)
+isArgGenBigRetFunTypezh(P_ stack, W_ offsetWords) {
+  P_ c;
+  c = StgStack_sp(stack) + WDS(offsetWords);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  W_ type;
+  (type) = ccall isArgGenBigRetFunType(c);
+  return (type);
+}
+
+// (StgInfoTable*, StgInfoTable*) getInfoTableAddrszh(StgStack* stack, StgWord offsetWords)
+getInfoTableAddrszh(P_ stack, W_ offsetWords) {
+  P_ p, info_struct, info_ptr_ipe_key;
+  p = StgStack_sp(stack) + WDS(offsetWords);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(p));
+  info_struct = %GET_STD_INFO(UNTAG(p));
+  info_ptr_ipe_key = %INFO_PTR(UNTAG(p));
+  return (info_struct, info_ptr_ipe_key);
+}
+
+// (StgInfoTable*) getStackInfoTableAddrzh(StgStack* stack)
+getStackInfoTableAddrzh(P_ stack) {
+  P_ info;
+  info = %GET_STD_INFO(UNTAG(stack));
+  return (info);
+}
+
+// (StgClosure*) getStackClosurezh(StgStack* stack, StgWord offsetWords)
+getStackClosurezh(P_ stack, W_ offsetWords) {
+  P_ ptr;
+  ptr = StgStack_sp(stack) + WDS(offsetWords);
+
+  P_ closure;
+  (closure) = ccall getStackClosure(ptr);
+  return (closure);
+}
+
+// (bits32) getStackFieldszh(StgStack* stack)
+getStackFieldszh(P_ stack){
+  bits32 size;
+  size = StgStack_stack_size(stack);
+  return (size);
+}
+#endif
diff --git a/cbits/StackCloningDecoding.cmm b/cbits/StackCloningDecoding.cmm
--- a/cbits/StackCloningDecoding.cmm
+++ b/cbits/StackCloningDecoding.cmm
@@ -17,10 +17,3 @@
 
     return ();
 }
-
-stg_decodeStackzh (gcptr stgStack) {
-    gcptr stackEntries;
-    ("ptr" stackEntries) = ccall decodeClonedStack(MyCapability() "ptr", stgStack "ptr");
-
-    return (stackEntries);
-}
diff --git a/cbits/Stack_c.c b/cbits/Stack_c.c
new file mode 100644
--- /dev/null
+++ b/cbits/Stack_c.c
@@ -0,0 +1,151 @@
+#include "MachDeps.h"
+#include "Rts.h"
+#include "RtsAPI.h"
+#include "rts/Messages.h"
+#include "rts/Types.h"
+#include "rts/storage/ClosureTypes.h"
+#include "rts/storage/Closures.h"
+#include "rts/storage/FunTypes.h"
+#include "rts/storage/InfoTables.h"
+
+StgWord stackFrameSize(StgStack *stack, StgWord offset) {
+  StgClosure *c = (StgClosure *)(stack->sp + offset);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+  return stack_frame_sizeW(c);
+}
+
+StgStack *getUnderflowFrameStack(StgStack *stack, StgWord offset) {
+  StgClosure *frame = (StgClosure *)(stack->sp + offset);
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(frame));
+  const StgRetInfoTable *info = get_ret_itbl((StgClosure *)frame);
+
+  if (info->i.type == UNDERFLOW_FRAME) {
+    return ((StgUnderflowFrame *)frame)->next_chunk;
+  } else {
+    return NULL;
+  }
+}
+
+// Only exists to make the get_itbl macro available in Haskell code (via FFI).
+const StgInfoTable *getItbl(StgClosure *closure) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(closure));
+  return get_itbl(closure);
+}
+
+StgWord getBitmapSize(StgClosure *c) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  const StgInfoTable *info = get_itbl(c);
+  StgWord bitmap = info->layout.bitmap;
+  return BITMAP_SIZE(bitmap);
+}
+
+StgWord getRetFunBitmapSize(StgRetFun *ret_fun) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(ret_fun));
+
+  const StgFunInfoTable *fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
+  switch (fun_info->f.fun_type) {
+  case ARG_GEN:
+    return BITMAP_SIZE(fun_info->f.b.bitmap);
+  case ARG_GEN_BIG:
+    return GET_FUN_LARGE_BITMAP(fun_info)->size;
+  default:
+    return BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]);
+  }
+}
+
+StgWord getBitmapWord(StgClosure *c) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  const StgInfoTable *info = get_itbl(c);
+  StgWord bitmap = info->layout.bitmap;
+  StgWord bitmapWord = BITMAP_BITS(bitmap);
+  return bitmapWord;
+}
+
+StgWord getRetFunBitmapWord(StgRetFun *ret_fun) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(ret_fun));
+
+  const StgFunInfoTable *fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
+  fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
+  switch (fun_info->f.fun_type) {
+  case ARG_GEN:
+    return BITMAP_BITS(fun_info->f.b.bitmap);
+  case ARG_GEN_BIG:
+    // Cannot do more than warn and exit.
+    errorBelch("Unexpected ARG_GEN_BIG StgRetFun closure %p", ret_fun);
+    stg_exit(EXIT_INTERNAL_ERROR);
+  default:
+    return BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]);
+  }
+}
+
+StgWord getLargeBitmapSize(StgClosure *c) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  const StgInfoTable *info = get_itbl(c);
+  StgLargeBitmap *bitmap = GET_LARGE_BITMAP(info);
+  return bitmap->size;
+}
+
+StgWord getRetFunSize(StgRetFun *ret_fun) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(ret_fun));
+
+  const StgFunInfoTable *fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
+  fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
+  switch (fun_info->f.fun_type) {
+  case ARG_GEN:
+    return BITMAP_SIZE(fun_info->f.b.bitmap);
+  case ARG_GEN_BIG:
+    return GET_FUN_LARGE_BITMAP(fun_info)->size;
+  default:
+    return BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]);
+  }
+}
+
+StgWord getBCOLargeBitmapSize(StgClosure *c) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  StgBCO *bco = (StgBCO *)*c->payload;
+
+  return BCO_BITMAP_SIZE(bco);
+}
+
+StgWord *getLargeBitmap(Capability *cap, StgClosure *c) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+  const StgInfoTable *info = get_itbl(c);
+  StgLargeBitmap *bitmap = GET_LARGE_BITMAP(info);
+
+  return bitmap->bitmap;
+}
+
+StgWord *getRetFunLargeBitmap(Capability *cap, StgRetFun *ret_fun) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(ret_fun));
+
+  const StgFunInfoTable *fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
+  StgLargeBitmap *bitmap = GET_FUN_LARGE_BITMAP(fun_info);
+
+  return bitmap->bitmap;
+}
+
+StgWord *getBCOLargeBitmap(Capability *cap, StgClosure *c) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(c));
+
+  StgBCO *bco = (StgBCO *)*c->payload;
+  StgLargeBitmap *bitmap = BCO_BITMAP(bco);
+
+  return bitmap->bitmap;
+}
+
+StgStack *getUnderflowFrameNextChunk(StgUnderflowFrame *frame) {
+  return frame->next_chunk;
+}
+
+StgWord isArgGenBigRetFunType(StgRetFun *ret_fun) {
+  ASSERT(LOOKS_LIKE_CLOSURE_PTR(ret_fun));
+
+  const StgFunInfoTable *fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
+  return fun_info->f.fun_type == ARG_GEN_BIG;
+}
+
+StgClosure *getStackClosure(StgClosure **c) { return *c; }
diff --git a/cbits/debug.c b/cbits/debug.c
new file mode 100644
--- /dev/null
+++ b/cbits/debug.c
@@ -0,0 +1,10 @@
+
+#include <stdio.h>
+
+void debugLn(char *s) {
+    printf("%s\n", s);
+}
+
+void debugErrLn(char *s) {
+    fprintf(stderr, "%s\n", s);
+}
diff --git a/cbits/gmp_wrappers.c b/cbits/gmp_wrappers.c
new file mode 100644
--- /dev/null
+++ b/cbits/gmp_wrappers.c
@@ -0,0 +1,896 @@
+/*
+ * `ghc-bignum` GMP FFI wrappers
+ *
+ * Copyright (c) 2014, Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * BSD3 licensed, see ../LICENSE file for details
+ *
+ */
+
+#define _ISOC99_SOURCE
+
+#include "HsFFI.h"
+#include "MachDeps.h"
+#include "HsIntegerGmp.h"
+#include "ghc-gmp.h"
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <stdio.h>
+
+
+
+// GMP 4.x compatibility
+#if !defined(__GNU_MP_VERSION)
+# error __GNU_MP_VERSION not defined
+#elif __GNU_MP_VERSION < 4
+# error need GMP 4.0 or later
+#elif __GNU_MP_VERSION < 5
+typedef unsigned long int mp_bitcnt_t;
+#endif
+
+#if (GMP_NUMB_BITS) != (GMP_LIMB_BITS)
+# error GMP_NUMB_BITS != GMP_LIMB_BITS not supported
+#endif
+
+#if (WORD_SIZE_IN_BITS) != (GMP_LIMB_BITS)
+# error WORD_SIZE_IN_BITS != GMP_LIMB_BITS not supported
+#endif
+
+// sanity check
+#if (SIZEOF_HSWORD*8) != WORD_SIZE_IN_BITS
+# error (SIZEOF_HSWORD*8) != WORD_SIZE_IN_BITS
+#endif
+
+// Turn a (const) {xp,xn} pair into static initializer
+#define CONST_MPZ_INIT(xp,xn) \
+  {{ ._mp_alloc = 0, ._mp_size  = (xn), ._mp_d = (mp_limb_t*)(xp) }}
+
+// Test if {sp,sn} represents a zero value
+static inline int
+mp_limb_zero_p(const mp_limb_t sp[], mp_size_t sn)
+{
+  return !sn || ((sn == 1 || sn == -1) && !sp[0]);
+}
+
+static inline mp_size_t
+mp_size_abs(const mp_size_t x)
+{
+  return x>=0 ? x : -x;
+}
+
+static inline mp_size_t
+mp_size_min(const mp_size_t x, const mp_size_t y)
+{
+  return x<y ? x : y;
+}
+
+static inline mp_size_t
+mp_size_minabs(const mp_size_t x, const mp_size_t y)
+{
+  return mp_size_min(mp_size_abs(x), mp_size_abs(y));
+}
+
+/* Perform arithmetic right shift on MPNs (multi-precision naturals)
+ *
+ * pre-conditions:
+ *  - 0 < count < sn*GMP_NUMB_BITS
+ *  - rn = sn - floor(count / GMP_NUMB_BITS)
+ *  - sn > 0
+ *
+ * write {sp,sn} right-shifted by count bits into {rp,rn}
+ *
+ * return value: most-significant limb stored in {rp,rn} result
+ */
+mp_limb_t
+integer_gmp_mpn_rshift (mp_limb_t rp[], const mp_limb_t sp[], mp_size_t sn,
+                        mp_bitcnt_t count)
+{
+  const mp_size_t    limb_shift = count / GMP_NUMB_BITS;
+  const unsigned int bit_shift  = count % GMP_NUMB_BITS;
+  const mp_size_t    rn         = sn - limb_shift;
+
+  if (bit_shift)
+    mpn_rshift(rp, &sp[limb_shift], rn, bit_shift);
+  else
+    memcpy(rp, &sp[limb_shift], rn*sizeof(mp_limb_t));
+
+  return rp[rn-1];
+}
+
+/* Twos-complement version of 'integer_gmp_mpn_rshift' for performing
+ * arithmetic right shifts on "negative" MPNs.
+ *
+ * pre-conditions:
+ *  - 0 < count < sn*GMP_NUMB_BITS
+ *  - rn = sn - floor((count - 1) / GMP_NUMB_BITS)
+ *  - sn > 0
+ *
+ * This variant is needed to operate on MPNs interpreted as negative
+ * numbers, which require "rounding" towards minus infinity iff a
+ * non-zero bit is shifted out.
+ */
+mp_limb_t
+integer_gmp_mpn_rshift_2c (mp_limb_t rp[], const mp_limb_t sp[],
+                           const mp_size_t sn, const mp_bitcnt_t count)
+{
+  const mp_size_t    limb_shift = count / GMP_NUMB_BITS;
+  const unsigned int bit_shift  = count % GMP_NUMB_BITS;
+  mp_size_t    rn         = sn - limb_shift;
+
+  // whether non-zero bits were shifted out
+  bool nz_shift_out = false;
+
+  if (bit_shift) {
+    if (mpn_rshift(rp, &sp[limb_shift], rn, bit_shift))
+      nz_shift_out = true;
+  } else {
+    // rp was allocated (rn + 1) limbs, to prevent carry
+    // on mpn_add_1 when all the bits of {rp, rn} are 1.
+    memset(&rp[rn], 0, sizeof(mp_limb_t));
+    memcpy(rp, &sp[limb_shift], rn*sizeof(mp_limb_t));
+    rn++;
+  }
+
+  if (!nz_shift_out)
+    for (unsigned i = 0; i < limb_shift; i++)
+      if (sp[i]) {
+        nz_shift_out = true;
+        break;
+      }
+
+  // round if non-zero bits were shifted out
+  if (nz_shift_out)
+    if (mpn_add_1(rp, rp, rn, 1))
+      abort(); /* should never happen */
+
+  return rp[rn-1];
+}
+
+/* Perform left-shift operation on MPN
+ *
+ * pre-conditions:
+ *  - 0 < count
+ *  - rn = sn + ceil(count / GMP_NUMB_BITS)
+ *  - sn > 0
+ *
+ * return value: most-significant limb stored in {rp,rn} result
+ */
+mp_limb_t
+integer_gmp_mpn_lshift (mp_limb_t rp[], const mp_limb_t sp[],
+                        const mp_size_t sn, const mp_bitcnt_t count)
+{
+  const mp_size_t    limb_shift = count / GMP_NUMB_BITS;
+  const unsigned int bit_shift  = count % GMP_NUMB_BITS;
+  const mp_size_t    rn0        = sn + limb_shift;
+
+  memset(rp, 0, limb_shift*sizeof(mp_limb_t));
+  if (bit_shift) {
+    const mp_limb_t msl = mpn_lshift(&rp[limb_shift], sp, sn, bit_shift);
+    rp[rn0] = msl;
+    return msl;
+  } else {
+    memcpy(&rp[limb_shift], sp, sn*sizeof(mp_limb_t));
+    return rp[rn0-1];
+  }
+}
+
+/* Convert bignum to a `double`, truncating if necessary
+ * (i.e. rounding towards zero).
+ *
+ * sign of mp_size_t argument controls sign of converted double
+ */
+HsDouble
+integer_gmp_mpn_get_d (const mp_limb_t sp[], const mp_size_t sn,
+                       const HsInt exponent)
+{
+  if (mp_limb_zero_p(sp, sn))
+    return 0.0;
+
+  const mpz_t mpz = CONST_MPZ_INIT(sp, sn);
+
+  if (!exponent)
+    return mpz_get_d(mpz);
+
+  long e = 0;
+  double d = mpz_get_d_2exp (&e, mpz);
+
+  // TODO: over/underflow handling?
+  return ldexp(d, e+exponent);
+}
+
+mp_limb_t
+integer_gmp_gcd_word(const mp_limb_t x, const mp_limb_t y)
+{
+  if (!x) return y;
+  if (!y) return x;
+
+  return mpn_gcd_1(&x, 1, y);
+}
+
+mp_limb_t
+integer_gmp_mpn_gcd_1(const mp_limb_t x[], const mp_size_t xn,
+                      const mp_limb_t y)
+{
+  assert (xn > 0);
+  assert (xn == 1 || y != 0);
+
+  if (xn == 1)
+    return integer_gmp_gcd_word(x[0], y);
+
+  return mpn_gcd_1(x, xn, y);
+}
+
+
+mp_size_t
+integer_gmp_mpn_gcd(mp_limb_t r[],
+                    const mp_limb_t x0[], const mp_size_t xn,
+                    const mp_limb_t y0[], const mp_size_t yn)
+{
+  assert (xn >= yn);
+  assert (yn > 0);
+  assert (xn == yn || yn > 1 || y0[0] != 0);
+  /* post-condition: rn <= xn */
+
+  if (yn == 1) {
+    if (y0[0]) {
+      r[0] = integer_gmp_mpn_gcd_1(x0, xn, y0[0]);
+      return 1;
+    } else { /* {y0,yn} == 0 */
+      assert (xn==yn); /* NB: redundant assertion */
+      memcpy(r, x0, xn*sizeof(mp_limb_t));
+      return xn;
+    }
+  } else {
+    // mpn_gcd() seems to require non-trivial normalization of its
+    // input arguments (which does not seem to be documented anywhere,
+    // see source of mpz_gcd() for more details), so we resort to just
+    // use mpz_gcd() which does the tiresome normalization for us at
+    // the cost of a few additional temporary buffer allocations in
+    // C-land.
+
+    const mpz_t op1 = CONST_MPZ_INIT(x0, xn);
+    const mpz_t op2 = CONST_MPZ_INIT(y0, yn);
+
+    mpz_t rop;
+    mpz_init (rop);
+
+    mpz_gcd(rop, op1, op2);
+
+    const mp_size_t rn = rop[0]._mp_size;
+    assert(rn > 0);
+    assert(rn <= xn);
+
+    /* the allocation/memcpy of the result can be neglectable since
+       mpz_gcd() already has to allocate other temporary buffers
+       anyway */
+    memcpy(r, rop[0]._mp_d, rn*sizeof(mp_limb_t));
+
+    mpz_clear(rop);
+
+    return rn;
+  }
+}
+
+/* wraps mpz_gcdext()
+ *
+ * Set g={g0,gn} to the greatest common divisor of x={x0,xn} and
+ * y={y0,yn}, and in addition set s={s0,sn} and t={t0,tn} to
+ * coefficients satisfying x*s + y*t = g.
+ *
+ * g0 must have space for exactly gn=min(xn,yn) limbs.
+ * s0 must have space for at least yn limbs.
+ * t0 must have space for at least xn limbs.
+ *
+ * Actual sizes are returned by pointers.
+ *
+ */
+void
+integer_gmp_gcdext(mp_limb_t s0[], int32_t * ssn,
+                   mp_limb_t t0[], int32_t * stn,
+                   mp_limb_t g0[], int32_t * gn,
+                   const mp_limb_t x0[], const mp_size_t xn,
+                   const mp_limb_t y0[], const mp_size_t yn)
+{
+  const mpz_t x = CONST_MPZ_INIT(x0, mp_limb_zero_p(x0,xn) ? 0 : xn);
+  const mpz_t y = CONST_MPZ_INIT(y0, mp_limb_zero_p(y0,yn) ? 0 : yn);
+
+  mpz_t g, s, t;
+  mpz_init (g);
+  mpz_init (s);
+  mpz_init (t);
+
+  mpz_gcdext (g, s, t, x, y);
+
+  // g must be positive (0 <= gn).
+  // According to the docs for mpz_gcdext(), we have:
+  //       g < min(|y|/2|s|, |x|/2|t|)
+  // -->   g < min(|y|, |x|)
+  // -->   gn <= min(yn, xn)
+  // <->   gn <= gn0
+  const mp_size_t gn0 = mp_size_minabs(xn, yn);
+  *gn = g[0]._mp_size;
+  assert(0 <= *gn && *gn <= gn0);
+  memcpy(g0, g[0]._mp_d, *gn * sizeof(mp_limb_t));
+  mpz_clear (g);
+
+  // According to the docs for mpz_gcdext(), we have:
+  //       |s| < |y| / 2g
+  // -->   |s| < |y|         (note g > 0)
+  // -->   sn <= yn
+  *ssn = s[0]._mp_size;
+  const mp_size_t sn  = mp_size_abs(*ssn);
+  assert(sn <= mp_size_abs(yn));
+  memcpy(s0, s[0]._mp_d, sn*sizeof(mp_limb_t));
+  mpz_clear (s);
+
+  // According to the docs for mpz_gcdext(), we have:
+  //       |t| < |x| / 2g
+  // -->   |t| < |x|         (note g > 0)
+  // -->   st <= xn
+  *stn = t[0]._mp_size;
+  const mp_size_t tn  = mp_size_abs(*stn);
+  assert(tn <= mp_size_abs(xn));
+  memcpy(t0, t[0]._mp_d, tn*sizeof(mp_limb_t));
+  mpz_clear (t);
+}
+
+/* Truncating (i.e. rounded towards zero) integer division-quotient of MPN */
+void
+integer_gmp_mpn_tdiv_q (mp_limb_t q[],
+                        const mp_limb_t n[], const mp_size_t nn,
+                        const mp_limb_t d[], const mp_size_t dn)
+{
+  /* qn = 1+nn-dn; rn = dn */
+  assert(nn>=dn);
+
+  if (dn > 128) {
+    // Use temporary heap allocated throw-away buffer for MPNs larger
+    // than 1KiB for 64bit-sized limbs (larger than 512bytes for
+    // 32bit-sized limbs)
+    mp_limb_t *const r = malloc(dn*sizeof(mp_limb_t));
+    mpn_tdiv_qr(q, r, 0, n, nn, d, dn);
+    free (r);
+  } else { // allocate smaller arrays on the stack
+    mp_limb_t r[dn];
+    mpn_tdiv_qr(q, r, 0, n, nn, d, dn);
+  }
+}
+
+/* Truncating (i.e. rounded towards zero) integer division-remainder of MPNs */
+void
+integer_gmp_mpn_tdiv_r (mp_limb_t r[],
+                        const mp_limb_t n[], const mp_size_t nn,
+                        const mp_limb_t d[], const mp_size_t dn)
+{
+  /* qn = 1+nn-dn; rn = dn */
+  assert(nn>=dn);
+  const mp_size_t qn = 1+nn-dn;
+
+  if (qn > 128) {
+    // Use temporary heap allocated throw-away buffer for MPNs larger
+    // than 1KiB for 64bit-sized limbs (larger than 512bytes for
+    // 32bit-sized limbs)
+    mp_limb_t *const q = malloc(qn*sizeof(mp_limb_t));
+    mpn_tdiv_qr(q, r, 0, n, nn, d, dn);
+    free (q);
+  } else { // allocate smaller arrays on the stack
+    mp_limb_t q[qn];
+    mpn_tdiv_qr(q, r, 0, n, nn, d, dn);
+  }
+}
+
+
+/* Wraps GMP's 'mpz_sizeinbase()' function */
+HsWord
+integer_gmp_mpn_sizeinbase(const mp_limb_t s[], const mp_size_t sn,
+                           const HsInt base)
+{
+  assert (2 <= base && base <= 256);
+
+  if (mp_limb_zero_p(s,sn)) return 1;
+
+  const mpz_t zs = CONST_MPZ_INIT(s, sn);
+
+  return mpz_sizeinbase(zs, base);
+}
+
+/* Single-limb version of 'integer_gmp_mpn_sizeinbase()' */
+HsWord
+integer_gmp_mpn_sizeinbase1(const mp_limb_t s, const HsInt base)
+{
+  return s ? integer_gmp_mpn_sizeinbase(&s, 1, base) : 1;
+}
+
+/* Wrapper around GMP's 'mpz_export()' function */
+HsWord
+integer_gmp_mpn_export(const mp_limb_t s[], const mp_size_t sn,
+                       void *destptr, HsInt destofs, HsInt msbf)
+{
+  /* TODO: implement w/o GMP, c.f. 'integer_gmp_mpn_import()' */
+  assert (msbf == 0 || msbf == 1);
+
+  if (mp_limb_zero_p(s,sn)) return 0;
+
+  const mpz_t zs = CONST_MPZ_INIT(s, sn);
+
+  size_t written = 0;
+
+  // mpz_export (void *rop, size_t *countp, int order, size_t size, int endian,
+  //             size_t nails, const mpz_t op)
+  (void) mpz_export(((char *)destptr)+destofs, &written, !msbf ? -1 : 1,
+                    /* size */ 1, /* endian */ 0, /* nails */ 0, zs);
+
+  return written;
+}
+
+/* Single-limb version of 'integer_gmp_mpn_export()' */
+HsWord
+integer_gmp_mpn_export1(const mp_limb_t s,
+                        void *destptr, const HsInt destofs, const HsInt msbf)
+{
+  /* TODO: implement w/o GMP */
+  return integer_gmp_mpn_export(&s, 1, destptr, destofs, msbf);
+}
+
+/* Import single limb from memory location
+ *
+ * We can't use GMP's 'mpz_import()'
+ */
+HsWord
+integer_gmp_mpn_import1(const uint8_t *srcptr, const HsWord srcofs,
+                        const HsWord srclen, const HsInt msbf)
+{
+  assert (msbf == 0 || msbf == 1);
+  assert (srclen <= SIZEOF_HSWORD);
+
+  srcptr += srcofs;
+
+  HsWord result = 0;
+
+  if (msbf)
+    for (unsigned i = 0; i < srclen; ++i)
+      result |= (HsWord)srcptr[i] << ((srclen-i-1)*8);
+  else // lsbf
+    for (unsigned i = 0; i < srclen; ++i)
+      result |= (HsWord)srcptr[i] << (i*8);
+
+  return result;
+}
+
+/* import into mp_limb_t[] from memory location */
+void
+integer_gmp_mpn_import(mp_limb_t * restrict r, const uint8_t * restrict srcptr,
+                       const HsWord srcofs, const HsWord srclen,
+                       const HsInt msbf)
+{
+  assert (msbf == 0 || msbf == 1);
+
+  srcptr += srcofs;
+
+  const unsigned  limb_cnt_rem = srclen % SIZEOF_HSWORD;
+  const mp_size_t limb_cnt     = srclen / SIZEOF_HSWORD;
+
+  if (msbf) {
+    if (limb_cnt_rem) { // partial limb
+      r[limb_cnt] = integer_gmp_mpn_import1(srcptr, 0, limb_cnt_rem, 1);
+      srcptr += limb_cnt_rem;
+    }
+
+    for (unsigned ri = 0; ri < limb_cnt; ++ri) {
+      r[limb_cnt-ri-1] = integer_gmp_mpn_import1(srcptr, 0, SIZEOF_HSWORD, 1);
+      srcptr += SIZEOF_HSWORD;
+    }
+  } else { // lsbf
+    for (unsigned ri = 0; ri < limb_cnt; ++ri) {
+      r[ri] = integer_gmp_mpn_import1(srcptr, 0, SIZEOF_HSWORD, 0);
+      srcptr += SIZEOF_HSWORD;
+    }
+
+    if (limb_cnt_rem) // partial limb
+      r[limb_cnt] = integer_gmp_mpn_import1(srcptr, 0, limb_cnt_rem, 0);
+  }
+}
+
+/* Scan for first non-zero byte starting at srcptr[srcofs], ending at
+ * srcptr[srcofs+srclen-1];
+ *
+ * If no non-zero byte found, returns srcofs+srclen; otherwise returns
+ * index of srcptr where first non-zero byte was found.
+ */
+HsWord
+integer_gmp_scan_nzbyte(const uint8_t *srcptr,
+                        const HsWord srcofs, const HsWord srclen)
+{
+  // TODO: consider implementing this function in Haskell-land
+  srcptr += srcofs;
+
+  for (unsigned i = 0; i < srclen; ++i)
+    if (srcptr[i])
+      return srcofs+i;
+
+  return srcofs+srclen;
+}
+
+/* Reverse scan for non-zero byte
+ * starting at srcptr[srcofs+srclen-1], ending at srcptr[srcofs].
+ *
+ * Returns new length srclen1 such that srcptr[srcofs+i] == 0 for
+ * srclen1 <= i < srclen.
+ */
+HsWord
+integer_gmp_rscan_nzbyte(const uint8_t *srcptr,
+                         const HsWord srcofs, const HsWord srclen)
+{
+  // TODO: consider implementing this function in Haskell-land
+  srcptr += srcofs;
+
+  for (unsigned i = srclen; i > 0; --i)
+    if (srcptr[i-1])
+      return i;
+
+  return 0;
+}
+
+/* wrapper around mpz_probab_prime_p */
+HsInt
+integer_gmp_test_prime(const mp_limb_t s[], const mp_size_t sn, const HsInt rep)
+{
+  if (mp_limb_zero_p(s,sn)) return 0;
+
+  const mpz_t sz = CONST_MPZ_INIT(s, sn);
+
+  // int mpz_probab_prime_p (const mpz_t n, int reps)
+  return mpz_probab_prime_p(sz, rep);
+}
+
+/* wrapper around mpz_probab_prime_p */
+HsInt
+integer_gmp_test_prime1(const mp_limb_t limb, const HsInt rep)
+{
+  if (!limb) return 0;
+
+  return integer_gmp_test_prime(&limb, 1, rep);
+}
+
+/* wrapper around mpz_nextprime()
+ *
+ * Stores next prime (relative to {sp,sn}) in {rp,sn}.
+ * Return value is most significant limb of {rp,sn+1}.
+ */
+mp_limb_t
+integer_gmp_next_prime(mp_limb_t rp[], const mp_limb_t sp[],
+                       const mp_size_t sn)
+{
+  assert (sn>=0);
+
+  if (!sn) return 2;
+  if (sn == 1 && sp[0] < 2) {
+    rp[0] = 2;
+    return 0;
+  }
+
+  const mpz_t op = CONST_MPZ_INIT(sp, sn);
+
+  mpz_t rop;
+  mpz_init (rop);
+  mpz_nextprime (rop, op);
+
+  const mp_size_t rn = rop[0]._mp_size;
+
+  // copy result into {rp,sn} buffer
+  assert (rn == sn || rn == sn+1);
+  memcpy(rp, rop[0]._mp_d, sn*sizeof(mp_limb_t));
+  const mp_limb_t result = rn>sn ? rop[0]._mp_d[sn] : 0;
+
+  mpz_clear (rop);
+
+  return result;
+}
+
+/* wrapper around mpz_nextprime()
+ *
+ * returns next prime modulo 2^GMP_LIMB_BITS
+ */
+mp_limb_t
+integer_gmp_next_prime1(const mp_limb_t limb)
+{
+  if (limb < 2) return 2;
+
+  const mpz_t op = CONST_MPZ_INIT(&limb, 1);
+
+  mpz_t rop;
+  mpz_init (rop);
+  mpz_nextprime (rop, op);
+  assert (rop[0]._mp_size > 0);
+  const mp_limb_t result = rop[0]._mp_d[0];
+  mpz_clear (rop);
+
+  return result;
+}
+
+/* wrapper around mpz_powm()
+ *
+ * Store '(B^E) mod M' in {rp,rn}
+ *
+ * rp must have allocated mn limbs; This function's return value is
+ * the actual number rn (0 < rn <= mn) of limbs written to the rp limb-array.
+ *
+ * bn and en are allowed to be negative to denote negative numbers
+ */
+mp_size_t
+integer_gmp_powm(mp_limb_t rp[], // result
+                 const mp_limb_t bp[], const mp_size_t bn, // base
+                 const mp_limb_t ep[], const mp_size_t en, // exponent
+                 const mp_limb_t mp[], const mp_size_t mn) // mod
+{
+  assert(!mp_limb_zero_p(mp,mn));
+
+  if ((mn == 1 || mn == -1) && mp[0] == 1) {
+    return 0;
+  }
+
+  if (mp_limb_zero_p(ep,en)) {
+    rp[0] = 1;
+    return 1;
+  }
+
+  const mpz_t b = CONST_MPZ_INIT(bp, mp_limb_zero_p(bp,bn) ? 0 : bn);
+  const mpz_t e = CONST_MPZ_INIT(ep, en);
+  const mpz_t m = CONST_MPZ_INIT(mp, mn);
+
+  mpz_t r;
+  mpz_init (r);
+
+  mpz_powm(r, b, e, m);
+
+  const mp_size_t rn = r[0]._mp_size;
+
+  if (rn) {
+    assert(0 < rn && rn <= mn);
+    memcpy(rp, r[0]._mp_d, rn*sizeof(mp_limb_t));
+  }
+
+  mpz_clear (r);
+
+  return rn;
+}
+
+/* version of integer_gmp_powm() for single-limb moduli */
+mp_limb_t
+integer_gmp_powm1(const mp_limb_t bp[], const mp_size_t bn, // base
+                  const mp_limb_t ep[], const mp_size_t en, // exponent
+                  const mp_limb_t m0) // mod
+{
+  assert(m0);
+
+  if (m0==1) return 0;
+  if (mp_limb_zero_p(ep,en)) return 1;
+
+  const mpz_t b = CONST_MPZ_INIT(bp, mp_limb_zero_p(bp,bn) ? 0 : bn);
+  const mpz_t e = CONST_MPZ_INIT(ep, en);
+  const mpz_t m = CONST_MPZ_INIT(&m0, !!m0);
+
+  mpz_t r;
+  mpz_init (r);
+  mpz_powm(r, b, e, m);
+
+  assert(r[0]._mp_size == 0 || r[0]._mp_size == 1);
+  const mp_limb_t result = r[0]._mp_size ? r[0]._mp_d[0] : 0;
+
+  mpz_clear (r);
+
+  return result;
+}
+
+/* version of integer_gmp_powm() for single-limb arguments */
+mp_limb_t
+integer_gmp_powm_word(const mp_limb_t b0, // base
+                      const mp_limb_t e0, // exponent
+                      const mp_limb_t m0) // mod
+{
+  return integer_gmp_powm1(&b0, !!b0, &e0, !!e0, m0);
+}
+
+/* version of integer_gmp_powm() based on mpz_powm_sec
+ *
+ * With GMP 5.0 or later execution time depends on size of arguments
+ * and size of result.
+ *
+ * 'M' must be odd and 'E' non-negative.
+ */
+mp_size_t
+integer_gmp_powm_sec(mp_limb_t rp[], // result
+                     const mp_limb_t bp[], const mp_size_t bn, // base
+                     const mp_limb_t ep[], const mp_size_t en, // exponent
+                     const mp_limb_t mp[], const mp_size_t mn) // mod
+{
+  assert(!mp_limb_zero_p(mp,mn));
+  assert(mp[0] & 1);
+
+  if ((mn == 1 || mn == -1) && mp[0] == 1) {
+    return 0;
+  }
+
+  if (mp_limb_zero_p(ep,en)) {
+    rp[0] = 1;
+    return 1;
+  }
+
+  assert(en > 0);
+
+  const mpz_t b = CONST_MPZ_INIT(bp, mp_limb_zero_p(bp,bn) ? 0 : bn);
+  const mpz_t e = CONST_MPZ_INIT(ep, en);
+  const mpz_t m = CONST_MPZ_INIT(mp, mn);
+
+  mpz_t r;
+  mpz_init (r);
+
+#if HAVE_SECURE_POWM == 0
+  mpz_powm(r, b, e, m);
+#else
+  mpz_powm_sec(r, b, e, m);
+#endif
+
+  const mp_size_t rn = r[0]._mp_size;
+
+  if (rn) {
+    assert(0 < rn && rn <= mn);
+    memcpy(rp, r[0]._mp_d, rn*sizeof(mp_limb_t));
+  }
+
+  mpz_clear (r);
+
+  return rn;
+}
+
+
+/* wrapper around mpz_invert()
+ *
+ * Store '(1/X) mod abs(M)' in {rp,rn}
+ *
+ * rp must have allocated mn limbs; This function's return value is
+ * the actual number rn (0 < rn <= mn) of limbs written to the rp limb-array.
+ *
+ * Returns 0 if inverse does not exist.
+ */
+mp_size_t
+integer_gmp_invert(mp_limb_t rp[], // result
+                   const mp_limb_t xp[], const mp_size_t xn, // base
+                   const mp_limb_t mp[], const mp_size_t mn) // mod
+{
+  if (mp_limb_zero_p(xp,xn)
+      || mp_limb_zero_p(mp,mn)
+      || ((mn == 1 || mn == -1) && mp[0] == 1)) {
+    return 0;
+  }
+
+  const mpz_t x = CONST_MPZ_INIT(xp, xn);
+  const mpz_t m = CONST_MPZ_INIT(mp, mn);
+
+  mpz_t r;
+  mpz_init (r);
+
+  const int inv_exists = mpz_invert(r, x, m);
+
+  const mp_size_t rn = inv_exists ? r[0]._mp_size : 0;
+
+  if (rn) {
+    assert(0 < rn && rn <= mn);
+    memcpy(rp, r[0]._mp_d, rn*sizeof(mp_limb_t));
+  }
+
+  mpz_clear (r);
+
+  return rn;
+}
+
+
+/* Version of integer_gmp_invert() operating on single limbs */
+mp_limb_t
+integer_gmp_invert_word(const mp_limb_t x0, const mp_limb_t m0)
+{
+  if (!x0 || m0<=1) return 0;
+  if (x0 == 1) return 1;
+
+  const mpz_t x = CONST_MPZ_INIT(&x0, 1);
+  const mpz_t m = CONST_MPZ_INIT(&m0, 1);
+
+  mpz_t r;
+  mpz_init (r);
+
+  const int inv_exists = mpz_invert(r, x, m);
+  const mp_size_t rn = inv_exists ? r[0]._mp_size : 0;
+
+  assert (rn == 0 || rn == 1);
+  const mp_limb_t r0 = rn ? r[0]._mp_d[0] : 0;
+
+  mpz_clear (r);
+
+  return r0;
+}
+
+
+/* Wrappers for GMP 4.x compat
+ *
+ * In GMP 5.0 the following operations were added:
+ *
+ *  mpn_sqr, mpn_and_n, mpn_ior_n, mpn_xor_n, mpn_nand_n, mpn_nior_n,
+ *  mpn_xnor_n, mpn_andn_n, mpn_iorn_n, mpn_com, mpn_neg, mpn_copyi,
+ *  mpn_copyd, mpn_zero
+ *
+ * We use some of those, but for GMP 4.x compatibility we need to
+ * emulate those (while incurring some overhead).
+ */
+#if __GNU_MP_VERSION < 5
+
+#define MPN_LOGIC_OP_WRAPPER(MPN_WRAPPER, MPZ_OP) \
+void                                                               \
+MPN_WRAPPER(mp_limb_t *rp, const mp_limb_t *s1p,                   \
+            const mp_limb_t *s2p, mp_size_t n)                     \
+{                                                                  \
+  assert(n > 0);                                                   \
+                                                                   \
+  const mpz_t s1 = CONST_MPZ_INIT(s1p, n);                         \
+  const mpz_t s2 = CONST_MPZ_INIT(s2p, n);                         \
+                                                                   \
+  mpz_t r;                                                         \
+  mpz_init (r);                                                    \
+  MPZ_OP (r, s1, s2);                                              \
+                                                                   \
+  const mp_size_t rn = r[0]._mp_size;                              \
+  memset (rp, 0, n*sizeof(mp_limb_t));                             \
+  memcpy (rp, r[0]._mp_d, mp_size_minabs(rn,n)*sizeof(mp_limb_t)); \
+                                                                   \
+  mpz_clear (r);                                                   \
+}
+
+static void
+__mpz_andn(mpz_t r, const mpz_t s1, const mpz_t s2)
+{
+  mpz_t s2c;
+  mpz_init (s2c);
+  mpz_com (s2c, s2);
+  mpz_and (r, s1, s2c);
+  mpz_clear (s2c);
+}
+
+MPN_LOGIC_OP_WRAPPER(integer_gmp_mpn_and_n,  mpz_and)
+MPN_LOGIC_OP_WRAPPER(integer_gmp_mpn_andn_n, __mpz_andn)
+MPN_LOGIC_OP_WRAPPER(integer_gmp_mpn_ior_n,  mpz_ior)
+MPN_LOGIC_OP_WRAPPER(integer_gmp_mpn_xor_n,  mpz_xor)
+
+#else /* __GNU_MP_VERSION >= 5 */
+void
+integer_gmp_mpn_and_n(mp_limb_t *rp, const mp_limb_t *s1p,
+                      const mp_limb_t *s2p, mp_size_t n)
+{
+  mpn_and_n(rp, s1p, s2p, n);
+}
+
+void
+integer_gmp_mpn_andn_n(mp_limb_t *rp, const mp_limb_t *s1p,
+                      const mp_limb_t *s2p, mp_size_t n)
+{
+  mpn_andn_n(rp, s1p, s2p, n);
+}
+
+void
+integer_gmp_mpn_ior_n(mp_limb_t *rp, const mp_limb_t *s1p,
+                      const mp_limb_t *s2p, mp_size_t n)
+{
+  mpn_ior_n(rp, s1p, s2p, n);
+}
+
+void
+integer_gmp_mpn_xor_n(mp_limb_t *rp, const mp_limb_t *s1p,
+                      const mp_limb_t *s2p, mp_size_t n)
+{
+  mpn_xor_n(rp, s1p, s2p, n);
+}
+#endif
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -652,6 +652,18 @@
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
 EXTRA_LIBS
+GhcGmpVerPl
+GhcGmpVerMi
+GhcGmpVerMj
+UseIntreeGmp
+HaveSecurePowm
+HaveFrameworkGMP
+HaveLibGmp
+GMP_INSTALL_INCLUDES
+GMP_FRAMEWORK
+GMP_LIB_DIRS
+GMP_LIBS
+GMP_INCLUDE_DIRS
 ICONV_LIB_DIRS
 ICONV_INCLUDE_DIRS
 EGREP
@@ -709,6 +721,11 @@
 enable_largefile
 with_iconv_includes
 with_iconv_libraries
+with_gmp
+with_gmp_includes
+with_gmp_libraries
+with_gmp_framework_preferred
+with_intree_gmp
 with_libcharset
 '
       ac_precious_vars='build_alias
@@ -1345,6 +1362,12 @@
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   --with-iconv-includes   directory containing iconv.h
   --with-iconv-libraries  directory containing iconv library
+  --with-gmp              Enable GMP backend
+  --with-gmp-includes     directory containing gmp.h
+  --with-gmp-libraries    directory containing gmp library
+  --with-gmp-framework-preferred
+                          on OSX, prefer the GMP framework to the gmp lib
+  --with-intree-gmp       force using the in-tree GMP
   --with-libcharset       Use libcharset [default=only if available]
 
 Some influential environment variables:
@@ -5046,6 +5069,488 @@
 
 
 
+
+# Check whether --with-gmp was given.
+if test ${with_gmp+y}
+then :
+  withval=$with_gmp; GMP_ENABLED=YES
+else $as_nop
+  GMP_ENABLED=NO
+fi
+
+
+
+# Check whether --with-gmp-includes was given.
+if test ${with_gmp_includes+y}
+then :
+  withval=$with_gmp_includes; GMP_INCLUDE_DIRS=$withval; CPPFLAGS="-I$withval"
+else $as_nop
+  GMP_INCLUDE_DIRS=
+fi
+
+
+
+# Check whether --with-gmp-libraries was given.
+if test ${with_gmp_libraries+y}
+then :
+  withval=$with_gmp_libraries; GMP_LIB_DIRS=$withval; LDFLAGS="-L$withval"
+else $as_nop
+  GMP_LIB_DIRS=
+fi
+
+
+
+# Check whether --with-gmp-framework-preferred was given.
+if test ${with_gmp_framework_preferred+y}
+then :
+  withval=$with_gmp_framework_preferred; GMP_PREFER_FRAMEWORK=YES
+else $as_nop
+  GMP_PREFER_FRAMEWORK=NO
+fi
+
+
+
+# Check whether --with-intree-gmp was given.
+if test ${with_intree_gmp+y}
+then :
+  withval=$with_intree_gmp; GMP_FORCE_INTREE=YES
+else $as_nop
+  GMP_FORCE_INTREE=NO
+fi
+
+
+if test "$GMP_ENABLED" = "YES"
+then
+
+
+   HaveLibGmp=NO
+   GMP_LIBS=
+   HaveFrameworkGMP=NO
+   GMP_FRAMEWORK=
+   HaveSecurePowm=0
+
+   if test "$GMP_FORCE_INTREE" != "YES"
+   then
+       if test "$GMP_PREFER_FRAMEWORK" = "YES"
+       then
+
+    if test "$HaveLibGmp" = "NO"
+    then
+        case $target_os in
+        darwin*)
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GMP.framework" >&5
+printf %s "checking for GMP.framework... " >&6; }
+            save_libs="$LIBS"
+            LIBS="-framework GMP"
+            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char __gmpz_powm_sec ();
+int
+main (void)
+{
+return __gmpz_powm_sec ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  HaveFrameworkGMP=YES; GMP_FRAMEWORK=GMP
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+            LIBS="$save_libs"
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $HaveFrameworkGMP" >&5
+printf "%s\n" "$HaveFrameworkGMP" >&6; }
+            ;;
+        esac
+    fi
+
+
+    if test "$HaveFrameworkGMP" = "NO"
+    then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __gmpz_powm in -lgmp" >&5
+printf %s "checking for __gmpz_powm in -lgmp... " >&6; }
+if test ${ac_cv_lib_gmp___gmpz_powm+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgmp  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char __gmpz_powm ();
+int
+main (void)
+{
+return __gmpz_powm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_lib_gmp___gmpz_powm=yes
+else $as_nop
+  ac_cv_lib_gmp___gmpz_powm=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp___gmpz_powm" >&5
+printf "%s\n" "$ac_cv_lib_gmp___gmpz_powm" >&6; }
+if test "x$ac_cv_lib_gmp___gmpz_powm" = xyes
+then :
+  HaveLibGmp=YES; GMP_LIBS=gmp
+fi
+
+        if test "$HaveLibGmp" = "NO"
+        then
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __gmpz_powm in -lgmp3" >&5
+printf %s "checking for __gmpz_powm in -lgmp3... " >&6; }
+if test ${ac_cv_lib_gmp3___gmpz_powm+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgmp3  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char __gmpz_powm ();
+int
+main (void)
+{
+return __gmpz_powm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_lib_gmp3___gmpz_powm=yes
+else $as_nop
+  ac_cv_lib_gmp3___gmpz_powm=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp3___gmpz_powm" >&5
+printf "%s\n" "$ac_cv_lib_gmp3___gmpz_powm" >&6; }
+if test "x$ac_cv_lib_gmp3___gmpz_powm" = xyes
+then :
+  HaveLibGmp=YES; GMP_LIBS=gmp3
+fi
+
+        fi
+        if test "$HaveLibGmp" = "YES"
+        then
+            as_ac_Lib=`printf "%s\n" "ac_cv_lib_$GMP_LIBS""___gmpz_powm_sec" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __gmpz_powm_sec in -l$GMP_LIBS" >&5
+printf %s "checking for __gmpz_powm_sec in -l$GMP_LIBS... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$GMP_LIBS  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char __gmpz_powm_sec ();
+int
+main (void)
+{
+return __gmpz_powm_sec ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  eval "$as_ac_Lib=yes"
+else $as_nop
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
+  HaveSecurePowm=1
+fi
+
+        fi
+    fi
+
+       else
+
+    if test "$HaveFrameworkGMP" = "NO"
+    then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __gmpz_powm in -lgmp" >&5
+printf %s "checking for __gmpz_powm in -lgmp... " >&6; }
+if test ${ac_cv_lib_gmp___gmpz_powm+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgmp  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char __gmpz_powm ();
+int
+main (void)
+{
+return __gmpz_powm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_lib_gmp___gmpz_powm=yes
+else $as_nop
+  ac_cv_lib_gmp___gmpz_powm=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp___gmpz_powm" >&5
+printf "%s\n" "$ac_cv_lib_gmp___gmpz_powm" >&6; }
+if test "x$ac_cv_lib_gmp___gmpz_powm" = xyes
+then :
+  HaveLibGmp=YES; GMP_LIBS=gmp
+fi
+
+        if test "$HaveLibGmp" = "NO"
+        then
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __gmpz_powm in -lgmp3" >&5
+printf %s "checking for __gmpz_powm in -lgmp3... " >&6; }
+if test ${ac_cv_lib_gmp3___gmpz_powm+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgmp3  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char __gmpz_powm ();
+int
+main (void)
+{
+return __gmpz_powm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_lib_gmp3___gmpz_powm=yes
+else $as_nop
+  ac_cv_lib_gmp3___gmpz_powm=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp3___gmpz_powm" >&5
+printf "%s\n" "$ac_cv_lib_gmp3___gmpz_powm" >&6; }
+if test "x$ac_cv_lib_gmp3___gmpz_powm" = xyes
+then :
+  HaveLibGmp=YES; GMP_LIBS=gmp3
+fi
+
+        fi
+        if test "$HaveLibGmp" = "YES"
+        then
+            as_ac_Lib=`printf "%s\n" "ac_cv_lib_$GMP_LIBS""___gmpz_powm_sec" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __gmpz_powm_sec in -l$GMP_LIBS" >&5
+printf %s "checking for __gmpz_powm_sec in -l$GMP_LIBS... " >&6; }
+if eval test \${$as_ac_Lib+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$GMP_LIBS  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char __gmpz_powm_sec ();
+int
+main (void)
+{
+return __gmpz_powm_sec ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  eval "$as_ac_Lib=yes"
+else $as_nop
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"
+then :
+  HaveSecurePowm=1
+fi
+
+        fi
+    fi
+
+
+    if test "$HaveLibGmp" = "NO"
+    then
+        case $target_os in
+        darwin*)
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GMP.framework" >&5
+printf %s "checking for GMP.framework... " >&6; }
+            save_libs="$LIBS"
+            LIBS="-framework GMP"
+            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char __gmpz_powm_sec ();
+int
+main (void)
+{
+return __gmpz_powm_sec ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  HaveFrameworkGMP=YES; GMP_FRAMEWORK=GMP
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+            LIBS="$save_libs"
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $HaveFrameworkGMP" >&5
+printf "%s\n" "$HaveFrameworkGMP" >&6; }
+            ;;
+        esac
+    fi
+
+       fi
+   fi
+
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use in-tree GMP" >&5
+printf %s "checking whether to use in-tree GMP... " >&6; }
+   if test "$HaveFrameworkGMP" = "YES" || test "$HaveLibGmp" = "YES"
+   then
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       UseIntreeGmp=0
+       ac_fn_c_check_header_compile "$LINENO" "gmp.h" "ac_cv_header_gmp_h" "$ac_includes_default"
+if test "x$ac_cv_header_gmp_h" = xyes
+then :
+
+else $as_nop
+  as_fn_error $? "Cannot find gmp.h" "$LINENO" 5
+fi
+
+
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking GMP version" >&5
+printf %s "checking GMP version... " >&6; }
+       if ac_fn_c_compute_int "$LINENO" "__GNU_MP_VERSION" "GhcGmpVerMj"        "#include <gmp.h>"
+then :
+
+else $as_nop
+  as_fn_error $? "Unable to get value of __GNU_MP_VERSION" "$LINENO" 5
+fi
+
+       if ac_fn_c_compute_int "$LINENO" "__GNU_MP_VERSION_MINOR" "GhcGmpVerMi"        "#include <gmp.h>"
+then :
+
+else $as_nop
+  as_fn_error $? "Unable to get value of __GNU_MP_VERSION_MINOR" "$LINENO" 5
+fi
+
+       if ac_fn_c_compute_int "$LINENO" "__GNU_MP_VERSION_PATCHLEVEL" "GhcGmpVerPl"        "#include <gmp.h>"
+then :
+
+else $as_nop
+  as_fn_error $? "Unable to get value of __GNU_MP_VERSION_PATCHLEVEL" "$LINENO" 5
+fi
+
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl" >&5
+printf "%s\n" "$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl" >&6; }
+
+   else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       UseIntreeGmp=1
+       HaveSecurePowm=1
+
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking GMP version" >&5
+printf %s "checking GMP version... " >&6; }
+       GhcGmpVerMj=6
+       GhcGmpVerMi=1
+       GhcGmpVerPl=2
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl" >&5
+printf "%s\n" "$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl" >&6; }
+   fi
+
+   GMP_INSTALL_INCLUDES="HsIntegerGmp.h ghc-gmp.h"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 # Compute offsets/sizes used by jsbits/base.js
 if test "$host" = "javascript-ghcjs"
 then
@@ -32800,7 +33305,7 @@
 
 
 
-ac_config_files="$ac_config_files ghc-internal.buildinfo"
+ac_config_files="$ac_config_files ghc-internal.buildinfo include/HsIntegerGmp.h"
 
 
 cat >confcache <<\_ACEOF
@@ -33490,6 +33995,7 @@
     "include/HsBaseConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS include/HsBaseConfig.h" ;;
     "include/EventConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS include/EventConfig.h" ;;
     "ghc-internal.buildinfo") CONFIG_FILES="$CONFIG_FILES ghc-internal.buildinfo" ;;
+    "include/HsIntegerGmp.h") CONFIG_FILES="$CONFIG_FILES include/HsIntegerGmp.h" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -132,7 +132,110 @@
 AC_SUBST(ICONV_INCLUDE_DIRS)
 AC_SUBST(ICONV_LIB_DIRS)
 
+dnl--------------------------------------------------------------------
+dnl * Deal with arguments telling us gmp is somewhere odd
+dnl--------------------------------------------------------------------
 
+AC_ARG_WITH([gmp],
+  [AS_HELP_STRING([--with-gmp],
+    [Enable GMP backend])],
+    [GMP_ENABLED=YES],
+    [GMP_ENABLED=NO])
+
+AC_ARG_WITH([gmp-includes],
+  [AS_HELP_STRING([--with-gmp-includes],
+    [directory containing gmp.h])],
+    [GMP_INCLUDE_DIRS=$withval; CPPFLAGS="-I$withval"],
+    [GMP_INCLUDE_DIRS=])
+
+AC_ARG_WITH([gmp-libraries],
+  [AS_HELP_STRING([--with-gmp-libraries],
+    [directory containing gmp library])],
+    [GMP_LIB_DIRS=$withval; LDFLAGS="-L$withval"],
+    [GMP_LIB_DIRS=])
+
+AC_ARG_WITH([gmp-framework-preferred],
+  [AS_HELP_STRING([--with-gmp-framework-preferred],
+    [on OSX, prefer the GMP framework to the gmp lib])],
+    [GMP_PREFER_FRAMEWORK=YES],
+    [GMP_PREFER_FRAMEWORK=NO])
+
+AC_ARG_WITH([intree-gmp],
+  [AS_HELP_STRING([--with-intree-gmp],
+    [force using the in-tree GMP])],
+    [GMP_FORCE_INTREE=YES],
+    [GMP_FORCE_INTREE=NO])
+
+if test "$GMP_ENABLED" = "YES"
+then
+
+dnl--------------------------------------------------------------------
+dnl * Detect gmp
+dnl--------------------------------------------------------------------
+
+   HaveLibGmp=NO
+   GMP_LIBS=
+   HaveFrameworkGMP=NO
+   GMP_FRAMEWORK=
+   HaveSecurePowm=0
+
+   if test "$GMP_FORCE_INTREE" != "YES"
+   then
+       if test "$GMP_PREFER_FRAMEWORK" = "YES"
+       then
+           LOOK_FOR_GMP_FRAMEWORK
+           LOOK_FOR_GMP_LIB
+       else
+           LOOK_FOR_GMP_LIB
+           LOOK_FOR_GMP_FRAMEWORK
+       fi
+   fi
+
+   AC_MSG_CHECKING([whether to use in-tree GMP])
+   if test "$HaveFrameworkGMP" = "YES" || test "$HaveLibGmp" = "YES"
+   then
+       AC_MSG_RESULT([no])
+       UseIntreeGmp=0
+       AC_CHECK_HEADER([gmp.h], , [AC_MSG_ERROR([Cannot find gmp.h])])
+
+       AC_MSG_CHECKING([GMP version])
+       AC_COMPUTE_INT(GhcGmpVerMj, __GNU_MP_VERSION, [#include <gmp.h>],
+           AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION]))
+       AC_COMPUTE_INT(GhcGmpVerMi, __GNU_MP_VERSION_MINOR, [#include <gmp.h>],
+           AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_MINOR]))
+       AC_COMPUTE_INT(GhcGmpVerPl, __GNU_MP_VERSION_PATCHLEVEL, [#include <gmp.h>],
+           AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_PATCHLEVEL]))
+       AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
+
+   else
+       AC_MSG_RESULT([yes])
+       UseIntreeGmp=1
+       HaveSecurePowm=1
+
+       AC_MSG_CHECKING([GMP version])
+       GhcGmpVerMj=6
+       GhcGmpVerMi=1
+       GhcGmpVerPl=2
+       AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
+   fi
+
+   GMP_INSTALL_INCLUDES="HsIntegerGmp.h ghc-gmp.h"
+fi
+
+
+AC_SUBST(GMP_INCLUDE_DIRS)
+AC_SUBST(GMP_LIBS)
+AC_SUBST(GMP_LIB_DIRS)
+AC_SUBST(GMP_FRAMEWORK)
+AC_SUBST(GMP_INSTALL_INCLUDES)
+AC_SUBST(HaveLibGmp)
+AC_SUBST(HaveFrameworkGMP)
+AC_SUBST(HaveSecurePowm)
+AC_SUBST(UseIntreeGmp)
+AC_SUBST(GhcGmpVerMj)
+AC_SUBST(GhcGmpVerMi)
+AC_SUBST(GhcGmpVerPl)
+
 # Compute offsets/sizes used by jsbits/base.js
 if test "$host" = "javascript-ghcjs"
 then
@@ -305,6 +408,6 @@
 AC_CHECK_SIZEOF([struct MD5Context], [], [#include "include/md5.h"])
 
 AC_SUBST(EXTRA_LIBS)
-AC_CONFIG_FILES([ghc-internal.buildinfo])
+AC_CONFIG_FILES([ghc-internal.buildinfo include/HsIntegerGmp.h])
 
 AC_OUTPUT
diff --git a/ghc-internal.buildinfo.in b/ghc-internal.buildinfo.in
--- a/ghc-internal.buildinfo.in
+++ b/ghc-internal.buildinfo.in
@@ -1,4 +1,5 @@
-extra-lib-dirs: @ICONV_LIB_DIRS@
-extra-libraries: @EXTRA_LIBS@
-include-dirs: @ICONV_INCLUDE_DIRS@
-install-includes: HsBaseConfig.h EventConfig.h
+extra-lib-dirs: @ICONV_LIB_DIRS@ @GMP_LIB_DIRS@
+extra-libraries: @EXTRA_LIBS@ @GMP_LIBS@
+include-dirs: @ICONV_INCLUDE_DIRS@ @GMP_INCLUDE_DIRS@
+frameworks: @GMP_FRAMEWORK@
+install-includes: HsBaseConfig.h EventConfig.h @GMP_INSTALL_INCLUDES@
diff --git a/ghc-internal.cabal b/ghc-internal.cabal
--- a/ghc-internal.cabal
+++ b/ghc-internal.cabal
@@ -4,7 +4,7 @@
 name:           ghc-internal
 -- The project is ghc's version plus ghc-internal's version suffix.
 -- For example, for ghc=9.10.1, ghc-internal's version will be 9.1001.0.
-version:        9.1204.0
+version:        9.1401.0
 license:        BSD-3-Clause
 license-file:   LICENSE
 maintainer:     The GHC Developers <ghc-devs@haskell.org>
@@ -31,6 +31,7 @@
     aclocal.m4
     ghc-internal.buildinfo.in
     CHANGELOG.md
+    cbits/gmp_wrappers.c
     configure
     configure.ac
     include/CTypes.h
@@ -40,6 +41,8 @@
     include/md5.h
     include/fs.h
     include/winio_structs.h
+    include/WordSize.h
+    include/HsIntegerGmp.h.in
     include/RtsIfaceSymbols.h
     install-sh
 
@@ -48,6 +51,32 @@
     location: https://gitlab.haskell.org/ghc/ghc.git
     subdir:   libraries/base
 
+Flag bignum-native
+    Description: Enable native Haskell bignum backend
+    Manual: True
+    Default: False
+
+Flag bignum-ffi
+    Description: Enable FFI bignum backend
+    Manual: True
+    Default: False
+
+Flag bignum-gmp
+    Description: Enable GMP bignum backend
+    Manual: True
+    Default: False
+
+Flag bignum-check
+    Description: Validate results of the enabled backend against native backend.
+    Manual: True
+    Default: False
+
+Flag need-atomic
+    Description: Enable linking with "atomic" library (for 64-bit atomic ops on armel, #20549)
+    Manual: True
+    Default: False
+
+
 Library
     default-language: Haskell2010
     default-extensions:
@@ -91,11 +120,10 @@
         Unsafe
 
     build-depends:
-        rts == 1.0.*,
-        ghc-prim >= 0.11 && < 0.14,
-        ghc-bignum >= 1.0 && < 2.0
+        rts == 1.0.*
 
     exposed-modules:
+        GHC.Internal.AllocationLimitHandler
         GHC.Internal.ClosureTypes
         GHC.Internal.Control.Arrow
         GHC.Internal.Control.Category
@@ -130,6 +158,7 @@
         GHC.Internal.Data.List.NonEmpty
         GHC.Internal.Data.Maybe
         GHC.Internal.Data.Monoid
+        GHC.Internal.Data.NonEmpty
         GHC.Internal.Data.OldList
         GHC.Internal.Data.Ord
         GHC.Internal.Data.Proxy
@@ -203,6 +232,12 @@
         GHC.Internal.GHCi
         GHC.Internal.GHCi.Helpers
         GHC.Internal.Generics
+        GHC.Internal.Heap.Closures
+        GHC.Internal.Heap.Constants
+        GHC.Internal.Heap.InfoTable
+        GHC.Internal.Heap.InfoTable.Types
+        GHC.Internal.Heap.InfoTableProf
+        GHC.Internal.Heap.ProfInfo.Types
         GHC.Internal.InfoProv
         GHC.Internal.InfoProv.Types
         GHC.Internal.IO
@@ -255,14 +290,18 @@
         GHC.Internal.RTS.Flags
         GHC.Internal.RTS.Flags.Test
         GHC.Internal.ST
-        GHC.Internal.Stack.CloneStack
         GHC.Internal.StaticPtr
         GHC.Internal.STRef
         GHC.Internal.Show
         GHC.Internal.Stable
         GHC.Internal.StableName
         GHC.Internal.Stack
+        GHC.Internal.Stack.Annotation
         GHC.Internal.Stack.CCS
+        GHC.Internal.Stack.CloneStack
+        GHC.Internal.Stack.Constants
+        GHC.Internal.Stack.ConstantsProf
+        GHC.Internal.Stack.Decode
         GHC.Internal.Stack.Types
         GHC.Internal.Stats
         GHC.Internal.Storable
@@ -299,15 +338,25 @@
         GHC.Internal.Type.Reflection
         GHC.Internal.Type.Reflection.Unsafe
         GHC.Internal.Unsafe.Coerce
-        -- TODO: remove
-        GHC.Internal.IOPort
 
-    reexported-modules:
-          GHC.Num.Integer
-        , GHC.Num.Natural
-        , GHC.Num.BigNat
-        , GHC.Tuple
+        GHC.Internal.CString
+        GHC.Internal.Classes
+        GHC.Internal.Debug
+        GHC.Internal.Magic
+        GHC.Internal.Magic.Dict
+        GHC.Internal.Prim
+        GHC.Internal.Prim.Ext
+        GHC.Internal.Prim.Panic
+        GHC.Internal.Prim.Exception
+        GHC.Internal.Prim.PtrEq
+        GHC.Internal.PrimopWrappers
+        GHC.Internal.Tuple
+        GHC.Internal.Types
 
+    autogen-modules:
+        GHC.Internal.Prim
+        GHC.Internal.PrimopWrappers
+
     other-modules:
         GHC.Internal.Data.Typeable.Internal
         GHC.Internal.IO.Handle.Lock.Common
@@ -324,7 +373,6 @@
         GHC.Internal.Event.IntVar
         GHC.Internal.Event.PSQ
         GHC.Internal.Event.Unique
-        -- GHC.Internal.IOPort -- TODO: hide again after debug
         GHC.Internal.Unicode.Bits
         GHC.Internal.Unicode.Char.DerivedCoreProperties
         GHC.Internal.Unicode.Char.UnicodeData.GeneralCategory
@@ -334,6 +382,55 @@
         GHC.Internal.Unicode.Version
         GHC.Internal.System.Environment.ExecutablePath
 
+
+    ----------------------------------------
+    -- Bignum configuration
+    ----------------------------------------
+    -- check that at least one backend is enabled
+    if !flag(bignum-native) && !flag(bignum-gmp) && !flag(bignum-ffi)
+      buildable: False
+
+    -- check that at most one flag is set
+    if flag(bignum-native) && (flag(bignum-gmp) || flag(bignum-ffi))
+      buildable: False
+    if flag(bignum-gmp) && flag(bignum-ffi)
+      buildable: False
+
+    if flag(bignum-gmp)
+        cpp-options: -DBIGNUM_GMP
+        other-modules:
+           GHC.Internal.Bignum.Backend.GMP
+        c-sources:
+           cbits/gmp_wrappers.c
+
+    if flag(bignum-ffi)
+        cpp-options: -DBIGNUM_FFI
+        other-modules:
+           GHC.Internal.Bignum.Backend.FFI
+
+    if flag(bignum-native)
+        cpp-options: -DBIGNUM_NATIVE
+
+    if flag(bignum-check)
+        cpp-options: -DBIGNUM_CHECK
+        other-modules:
+           GHC.Internal.Bignum.Backend.Check
+
+    exposed-modules:
+      GHC.Internal.Bignum.Primitives
+      GHC.Internal.Bignum.WordArray
+      GHC.Internal.Bignum.BigNat
+      GHC.Internal.Bignum.Backend
+      GHC.Internal.Bignum.Backend.Selected
+      GHC.Internal.Bignum.Backend.Native
+      GHC.Internal.Bignum.Natural
+      GHC.Internal.Bignum.Integer
+
+    -- some other properties related to bignum are set via the
+    -- ghc-internal.buildinfo file generated by this package's configure script
+    ----------------------------------------
+
+
     if !arch(javascript)
       c-sources:
           cbits/DarwinUtils.c
@@ -346,10 +443,14 @@
           cbits/sysconf.c
           cbits/fs.c
           cbits/strerror.c
+          cbits/debug.c
+          cbits/Stack_c.c
           cbits/RtsIface.c
 
       cmm-sources:
           cbits/StackCloningDecoding.cmm
+          cbits/Stack.cmm
+          cbits/HeapPrim.cmm
 
     if arch(javascript)
       js-sources:
@@ -367,10 +468,16 @@
         HsBase.h
         consUtils.h
 
+    if flag(need-atomic)
+        -- for 64-bit atomic ops on armel (#20549)
+        extra-libraries: atomic
+
     -- OS Specific
     if os(windows)
         -- Windows requires some extra libraries for linking because the RTS
-        -- is no longer re-exporting them.
+        -- is no longer re-exporting them (see #11223)
+        -- ucrt: standard C library. The RTS will automatically include this,
+        --       but is added for completeness.
         -- mingwex: provides GNU POSIX extensions that aren't provided by ucrt.
         -- mingw32: Unfortunately required because of a resource leak between
         --          mingwex and mingw32. the __math_err symbol is defined in
@@ -382,9 +489,11 @@
         -- ntdll: provides access to functions to inspect window handles
         -- kernel32: provides GetConsoleCP
         -- advapi32: provides advanced kernel functions
+        -- user32: provides access to apis to modify user components (UI etc)
+        --         on Windows. Required because of mingw32.
         extra-libraries:
             wsock32, user32, shell32, mingw32, kernel32, advapi32,
-            mingwex, ws2_32, shlwapi, ole32, rpcrt4, ntdll
+            mingwex, ws2_32, shlwapi, ole32, rpcrt4, ntdll, ucrt
         -- Minimum supported Windows version.
         -- These numbers can be found at:
         --  https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx
@@ -427,9 +536,10 @@
             GHC.Internal.Event.Thread
             GHC.Internal.Event.TimerManager
 
-
-        if arch(javascript)
-          other-modules:
+    if os(linux)
+        -- we need libm, but for musl and other's we might need libc, as libm
+        -- is just an empty shell.
+        extra-libraries: c, m
 
     -- The Ports framework always passes this flag when building software that
     -- uses iconv to make iconv from Ports compatible with iconv from the base system
diff --git a/include/HsIntegerGmp.h.in b/include/HsIntegerGmp.h.in
new file mode 100644
--- /dev/null
+++ b/include/HsIntegerGmp.h.in
@@ -0,0 +1,14 @@
+#pragma once
+
+/* Whether GMP is embedded into ghc-internal */
+#define GHC_GMP_INTREE     @UseIntreeGmp@
+
+/* The following values denote the GMP version used during GHC build-time */
+#define GHC_GMP_VERSION_MJ @GhcGmpVerMj@
+#define GHC_GMP_VERSION_MI @GhcGmpVerMi@
+#define GHC_GMP_VERSION_PL @GhcGmpVerPl@
+#define GHC_GMP_VERSION \
+    (@GhcGmpVerMj@ * 10000 + @GhcGmpVerMi@ * 100 + @GhcGmpVerPl@)
+
+/* Whether GMP supports mpz_powm_sec */
+#define HAVE_SECURE_POWM @HaveSecurePowm@
diff --git a/include/RtsIfaceSymbols.h b/include/RtsIfaceSymbols.h
--- a/include/RtsIfaceSymbols.h
+++ b/include/RtsIfaceSymbols.h
@@ -7,14 +7,13 @@
 #endif
 CLOSURE(GHCziInternalziTopHandler, runIO_closure)
 CLOSURE(GHCziInternalziTopHandler, runNonIO_closure)
-PRIMCLOSURE(GHCziTuple, Z0T_closure)
-PRIMCLOSURE(GHCziTypes, True_closure)
-PRIMCLOSURE(GHCziTypes, False_closure)
+CLOSURE(GHCziInternalziTuple, Z0T_closure)
+CLOSURE(GHCziInternalziTypes, True_closure)
+CLOSURE(GHCziInternalziTypes, False_closure)
 CLOSURE(GHCziInternalziPack, unpackCString_closure)
 CLOSURE(GHCziInternalziWeakziFinalizze, runFinalizzerBatch_closure)
 CLOSURE(GHCziInternalziIOziException, stackOverflow_closure)
 CLOSURE(GHCziInternalziIOziException, heapOverflow_closure)
-CLOSURE(GHCziInternalziIOPort, doubleReadException_closure)
 CLOSURE(GHCziInternalziIOziException, allocationLimitExceeded_closure)
 CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnMVar_closure)
 CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnSTM_closure)
@@ -36,12 +35,13 @@
 CLOSURE(GHCziInternalziConcziSignal, runHandlersPtr_closure)
 CLOSURE(GHCziInternalziTopHandler, flushStdHandles_closure)
 CLOSURE(GHCziInternalziTopHandler, runMainIO_closure)
-PRIM_INFO_TBL(GHCziTypes, Czh_con_info)
-PRIM_INFO_TBL(GHCziTypes, Izh_con_info)
-PRIM_INFO_TBL(GHCziTypes, Fzh_con_info)
-PRIM_INFO_TBL(GHCziTypes, Dzh_con_info)
-PRIM_INFO_TBL(GHCziTypes, Wzh_con_info)
-PRIMCLOSURE(GHCziPrimziPanic, absentSumFieldError_closure)
+INFO_TBL(GHCziInternalziTypes, Czh_con_info)
+INFO_TBL(GHCziInternalziTypes, Izh_con_info)
+INFO_TBL(GHCziInternalziTypes, Fzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Dzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Wzh_con_info)
+CLOSURE(GHCziInternalziPrimziPanic, absentSumFieldError_closure)
+CLOSURE(GHCziInternalziAllocationLimitHandler, runAllocationLimitHandler_closure)
 INFO_TBL(GHCziInternalziPtr, Ptr_con_info)
 INFO_TBL(GHCziInternalziPtr, FunPtr_con_info)
 INFO_TBL(GHCziInternalziInt, I8zh_con_info)
@@ -57,8 +57,8 @@
 CLOSURE(GHCziInternalziExceptionziType, divZZeroException_closure)
 CLOSURE(GHCziInternalziExceptionziType, underflowException_closure)
 CLOSURE(GHCziInternalziExceptionziType, overflowException_closure)
-PRIM_INFO_TBL(GHCziCString, unpackCStringzh_info)
-PRIM_INFO_TBL(GHCziCString, unpackCStringUtf8zh_info)
+INFO_TBL(GHCziInternalziCString, unpackCStringzh_info)
+INFO_TBL(GHCziInternalziCString, unpackCStringUtf8zh_info)
 #if defined(wasm32_HOST_ARCH) && defined(__PIC__)
 CLOSURE(GHCziInternalziWasmziPrimziImports, raiseJSException_closure)
 INFO_TBL(GHCziInternalziWasmziPrimziTypes, JSVal_con_info)
diff --git a/include/WordSize.h b/include/WordSize.h
new file mode 100644
--- /dev/null
+++ b/include/WordSize.h
@@ -0,0 +1,32 @@
+#include "MachDeps.h"
+
+#if WORD_SIZE_IN_BITS == 64
+
+# define WORD_SIZE_IN_BYTES    8
+# define WORD_SIZE_BYTES_SHIFT 3
+# define WORD_SIZE_BYTES_MASK  0b111
+# define WORD_SIZE_BITS_SHIFT  6
+# define WORD_SIZE_BITS_MASK   0b111111
+# define WORD_MAXBOUND         0xffffffffffffffff
+# define INT_MINBOUND         -0x8000000000000000
+# define INT_MAXBOUND          0x7fffffffffffffff
+# define ABS_INT_MINBOUND      0x8000000000000000
+# define SQRT_INT_MAXBOUND     0xb504f333
+
+#elif WORD_SIZE_IN_BITS == 32
+
+# define WORD_SIZE_IN_BYTES    4
+# define WORD_SIZE_BYTES_SHIFT 2
+# define WORD_SIZE_BYTES_MASK  0b11
+# define WORD_SIZE_BITS_SHIFT  5
+# define WORD_SIZE_BITS_MASK   0b11111
+# define WORD_MAXBOUND         0xffffffff
+# define INT_MINBOUND         -0x80000000
+# define INT_MAXBOUND          0x7fffffff
+# define ABS_INT_MINBOUND      0x80000000
+# define SQRT_INT_MAXBOUND     0xb504
+
+#else
+# error unsupported WORD_SIZE_IN_BITS config
+#endif
+
diff --git a/jsbits/base.js b/jsbits/base.js
--- a/jsbits/base.js
+++ b/jsbits/base.js
@@ -44,30 +44,45 @@
 }
 
 function h$close(fd,c) {
-  if (c) {
-    //asynchronous
-    var fdo = h$base_fds[fd];
-    if(fdo) {
+  var fdo = h$base_fds[fd];
+
+  // File descriptor was closed already?
+  // It may happen only if its reference count reached <1 and actual closing is processed at underlying fd
+  if (!fdo) {
+    h$setErrno('EINVAL');
+
+    if (c) {
+      TRACE_IO("base_close: file descriptor not found, already closed?")
+      c(-1);
+      return;
+    }
+
+    TRACE_IO("base_close sync: file descriptor not found, already closed?")
+    return (-1);
+  }
+
+  fdo.refs--;
+
+  if (fdo.refs < 1) {
+    // Process closing at underlying fd
+
+    if (c) {
+      TRACE_IO("base_close: closing underlying fd")
+      if (fdo.close) {
+        fdo.close(fd, fdo, c);
+      } else {
+        TRACE_IO("base_close: no actual underlying fd close, dummy implementation")
         delete h$base_fds[fd];
-        if(--fdo.refs < 1) {
-          TRACE_IO("base_close: closing underlying fd")
-          if(fdo.close) {
-            fdo.close(fd, fdo, c);
-          } else {
-            c(0);
-          }
-        } else {
-          TRACE_IO("base_close: remaining references, not closing underlying fd")
-          c(0);
-        }
-    } else {
-        TRACE_IO("base_close: file descriptor not found, already closed?")
-        h$errno = CONST_EINVAL;
-        c(-1);
+        c(0);
+      }
+      return;
     }
-  } else {
-    //synchronous
+
+    TRACE_IO("base_close sync: closing underlying fd")
     try {
+      // See: https://nodejs.org/api/fs.html#fsclosesyncfd
+      // Calling fs.closeSync() on any file descriptor (fd) that is currently in use through any other fs operation may lead to undefined behavior.
+      delete h$base_fds[fd];
       h$fs.closeSync(fd);
       return 0;
     } catch(err) {
@@ -75,6 +90,16 @@
       return (-1);
     }
   }
+
+  // Dummy process closing due of remaining references
+  if (c) {
+    TRACE_IO("base_close: remaining references, not closing underlying fd")
+    c(0);
+    return;
+  }
+
+  TRACE_IO("base_close sync: remaining references, not closing underlying fd")
+  return 0;
 }
 
 function h$base_dup(fd, c) {
@@ -122,7 +147,7 @@
 }
 
 function h$base_fstat(fd, stat, stat_off, c) {
-    TRACE_IO("base_stat")
+    TRACE_IO("base_fstat")
 #ifndef GHCJS_BROWSER
     if(h$isNode()) {
         h$fs.fstat(fd, function(err, fs) {
@@ -384,11 +409,13 @@
 }
 
 function h$rename(old_path, old_path_off, new_path, new_path_off) {
-  TRACE_IO("rename")
+  var old_path_str = h$decodeUtf8z(old_path, old_path_off);
+  var new_path_str = h$decodeUtf8z(new_path, new_path_off);
+  TRACE_IO("rename sync: " + old_path_str + " -> " + new_path_str)
 #ifndef GHCJS_BROWSER
   if (h$isNode()) {
     try {
-      h$fs.renameSync(h$decodeUtf8z(old_path, old_path_off), h$decodeUtf8z(new_path, new_path_off));
+      h$fs.renameSync(old_path_str, new_path_str);
       return 0;
     } catch(e) {
       h$setErrno(e);
@@ -473,11 +500,13 @@
 
 function h$openat(dirfd, file, file_off, how, mode, c) {
   var path = h$calculate_at(dirfd, file, file_off);
+  TRACE_IO("openat" + (!!c ? ": " : " sync: ") + path)
   return h$base_open(path, how, mode, c);
 }
 
 function h$open(file, file_off, how, mode, c) {
   var path = h$decodeUtf8z(file, file_off);
+  TRACE_IO("open" + (!!c ? ": " : " sync: ") + path)
   return h$base_open(path, how, mode, c);
 }
 
@@ -485,7 +514,7 @@
 #ifndef GHCJS_BROWSER
     if(h$isNode()) {
         var flags, off;
-        TRACE_IO("open: " + fp)
+        TRACE_IO("base_open" + (!!c ? ": " : " sync: ") + fp)
         var acc  = how & h$base_o_accmode;
         // passing a number lets node.js use it directly as the flags (undocumented)
         if(acc === h$base_o_rdonly) {
@@ -539,7 +568,7 @@
                                        , pos:   p
                                        , refs:  1
                                        };
-                      TRACE_IO("open: " + fp + " -> " + fd)
+                      TRACE_IO("base_open sync: " + fp + " -> " + fd)
                   }
             if(off === -1) {
               var fs = h$fs.statSync(fp);
@@ -944,8 +973,8 @@
     h$base_closeFile = function(fd, fdo, c) {
         TRACE_IO("base_closeFile: " + fd + " (" + fdo.fd + ")")
         var real_fd = typeof fdo.fd === 'number' ? fdo.fd : fd;
+        delete h$base_fds[fd];
         h$fs.close(real_fd, function(err) {
-            delete h$base_fds[fd];
             h$handleErrnoC(err, -1, 0, c);
         });
     }
@@ -1216,9 +1245,21 @@
 
 // It is required by Google Closure Compiler to be at least defined if
 // somewhere it is used
-var h$stg_cloneMyStackzh, h$stg_decodeStackzh
+var h$stg_cloneMyStackzh,
+    h$advanceStackFrameLocationzh, h$getStackFieldszh, h$getStackClosurezh,
+    h$getWordzh, h$getStackInfoTableAddrzh, h$getRetFunSmallBitmapzh, h$getRetFunLargeBitmapzh,
+    h$isArgGenBigRetFunTypezh,
+    h$getUnderflowFrameNextChunkzh,
+    h$getInfoTableAddrszh,
+    h$getLargeBitmapzh, h$getSmallBitmapzh, h$getBCOLargeBitmapzh
 h$stg_cloneMyStackzh
-  = h$stg_decodeStackzh
+  = h$advanceStackFrameLocationzh
+  = h$getStackFieldszh = h$getStackClosurezh
+  = h$getWordzh, h$getStackInfoTableAddrzh = h$getRetFunSmallBitmapzh = h$getRetFunLargeBitmapzh
+  = h$isArgGenBigRetFunTypezh
+  = h$getUnderflowFrameNextChunkzh
+  = h$getInfoTableAddrszh
+  = h$getLargeBitmapzh = h$getSmallBitmapzh = h$getBCOLargeBitmapzh
   = function () {
     throw new Error('Stack Cloning Decoding: Not Implemented Yet')
   }
diff --git a/jsbits/errno.js b/jsbits/errno.js
--- a/jsbits/errno.js
+++ b/jsbits/errno.js
@@ -52,6 +52,7 @@
       if(es.indexOf('EBADF') !== -1)        return CONST_EBADF;
       if(es.indexOf('ENOSPC') !== -1)       return CONST_ENOSPC;
       if(es.indexOf('EACCES') !== -1)       return CONST_EACCES;
+      if(es.indexOf('EXDEV') !== -1)        return CONST_EXDEV;
       if(es.indexOf('Bad argument') !== -1) return CONST_ENOENT; // fixme?
       throw ("setErrno not yet implemented for: " + e);
 
@@ -72,6 +73,7 @@
                    , CONST_EPIPE:   "Broken pipe"
                    , CONST_EAGAIN:  "Resource temporarily unavailable"
                    , CONST_ESPIPE:  "Illegal seek"
+                   , CONST_EXDEV:   "Cross-device link" // See https://en.cppreference.com/w/cpp/error/errno_macros
                    }
 
 function h$handleErrno(r_err, f) {
diff --git a/src/GHC/Internal/AllocationLimitHandler.hs b/src/GHC/Internal/AllocationLimitHandler.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/AllocationLimitHandler.hs
@@ -0,0 +1,117 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# OPTIONS_HADDOCK not-home #-}
+module GHC.Internal.AllocationLimitHandler
+  ( runAllocationLimitHandler
+  , setGlobalAllocationLimitHandler
+  , AllocationLimitKillBehaviour(..)
+  , getAllocationCounterFor
+  , setAllocationCounterFor
+  , enableAllocationLimitFor
+  , disableAllocationLimitFor
+  )
+  where
+import GHC.Internal.Base
+import GHC.Internal.Conc.Sync (ThreadId(..))
+import GHC.Internal.Data.IORef (IORef, readIORef, writeIORef, newIORef)
+import GHC.Internal.Foreign.C.Types
+import GHC.Internal.IO (unsafePerformIO)
+import GHC.Internal.Int (Int64(..))
+
+
+{-# NOINLINE allocationLimitHandler #-}
+allocationLimitHandler :: IORef (ThreadId -> IO ())
+allocationLimitHandler = unsafePerformIO (newIORef defaultHandler)
+
+defaultHandler :: ThreadId -> IO ()
+defaultHandler _ = pure ()
+
+foreign import ccall "setAllocLimitKill" setAllocLimitKill :: CBool -> CBool -> IO ()
+
+runAllocationLimitHandler :: ThreadId# -> IO ()
+runAllocationLimitHandler tid = do
+  hook <- getAllocationLimitHandler
+  hook $ ThreadId tid
+
+getAllocationLimitHandler :: IO (ThreadId -> IO ())
+getAllocationLimitHandler = readIORef allocationLimitHandler
+
+data AllocationLimitKillBehaviour =
+  KillOnAllocationLimit
+  -- ^ Throw a @AllocationLimitExceeded@ async exception to the thread when the
+  -- allocation limit is exceeded.
+  | DontKillOnAllocationLimit
+  -- ^ Do not throw an exception when the allocation limit is exceeded.
+
+-- | Define the behaviour for handling allocation limits.
+-- The default behaviour is to throw an @AllocationLimitExceeded@ async exception to the thread.
+-- This can be overriden using @AllocationLimitKillBehaviour@.
+--
+-- We can set a user-specified handler, which can be run in addition to
+-- or in place of the exception.
+-- This allows for instance logging on the allocation limit being exceeded,
+-- or dynamically determining whether to terminate the thread.
+-- The handler is not guaranteed to run before the thread is terminated or restarted.
+--
+-- Note: that if you don't terminate the thread, then the allocation limit gets
+-- removed.
+-- If you wish to keep the allocation limit you will have to reset it using
+-- @setAllocationCounter@ and @enableAllocationLimit@.
+setGlobalAllocationLimitHandler :: AllocationLimitKillBehaviour -> Maybe (ThreadId -> IO ()) -> IO ()
+setGlobalAllocationLimitHandler killBehaviour mHandler = do
+  shouldRunHandler <- case mHandler of
+    Just hook -> do
+      writeIORef allocationLimitHandler hook
+      pure 1
+    Nothing -> do
+      writeIORef allocationLimitHandler defaultHandler
+      pure 0
+  let shouldKill =
+        case killBehaviour of
+          KillOnAllocationLimit -> 1
+          DontKillOnAllocationLimit -> 0
+  setAllocLimitKill shouldKill shouldRunHandler
+
+-- | Retrieves the allocation counter for the another thread.
+foreign import prim "stg_getOtherThreadAllocationCounterzh" getOtherThreadAllocationCounter#
+  :: ThreadId#
+  -> State# RealWorld
+  -> (# State# RealWorld, Int64# #)
+
+-- | Get the allocation counter for a different thread.
+--
+-- Note: this doesn't take the current nursery chunk into account.
+-- If the thread is running then it may underestimate allocations by the size of a nursery thread.
+getAllocationCounterFor :: ThreadId -> IO Int64
+getAllocationCounterFor (ThreadId t#) = IO $ \s ->
+  case getOtherThreadAllocationCounter# t# s of (# s', i# #)  -> (# s', I64# i# #)
+
+-- | Set the allocation counter for a different thread.
+-- This can be combined with 'enableAllocationLimitFor' to enable allocation limits for another thread.
+-- You may wish to do this during a user-specified allocation limit handler.
+--
+-- Note: this doesn't take the current nursery chunk into account.
+-- If the thread is running then it may overestimate allocations by the size of a nursery thread,
+-- and trigger the limit sooner than expected.
+setAllocationCounterFor :: Int64 -> ThreadId -> IO ()
+setAllocationCounterFor (I64# i#) (ThreadId t#) = IO $ \s ->
+  case setOtherThreadAllocationCounter# i# t# s of s' -> (# s', () #)
+
+
+-- | Enable allocation limit processing the thread @t@.
+enableAllocationLimitFor :: ThreadId -> IO ()
+enableAllocationLimitFor (ThreadId t) = do
+  rts_enableThreadAllocationLimit t
+
+-- | Disable allocation limit processing the thread @t@.
+disableAllocationLimitFor :: ThreadId -> IO ()
+disableAllocationLimitFor (ThreadId t) = do
+  rts_disableThreadAllocationLimit t
+
+foreign import ccall unsafe "rts_enableThreadAllocationLimit"
+  rts_enableThreadAllocationLimit :: ThreadId# -> IO ()
+
+foreign import ccall unsafe "rts_disableThreadAllocationLimit"
+  rts_disableThreadAllocationLimit :: ThreadId# -> IO ()
diff --git a/src/GHC/Internal/ArrayArray.hs b/src/GHC/Internal/ArrayArray.hs
--- a/src/GHC/Internal/ArrayArray.hs
+++ b/src/GHC/Internal/ArrayArray.hs
@@ -48,9 +48,9 @@
   )
   where
 
-import GHC.Prim
-import GHC.Prim.PtrEq ( unsafePtrEquality# )
-import GHC.Types ( Type, UnliftedType, isTrue# )
+import GHC.Internal.Prim
+import GHC.Internal.Prim.PtrEq ( unsafePtrEquality# )
+import GHC.Internal.Types ( Type, UnliftedType, isTrue# )
 import GHC.Internal.Unsafe.Coerce ( unsafeCoerce, unsafeCoerceUnlifted )
 default ()
 
diff --git a/src/GHC/Internal/Base.hs b/src/GHC/Internal/Base.hs
--- a/src/GHC/Internal/Base.hs
+++ b/src/GHC/Internal/Base.hs
@@ -11,13 +11,13 @@
 So the rough structure is as follows, in (linearised) dependency order
 
 
-GHC.Prim        Has no implementation.  It defines built-in things, and
-                by importing it you bring them into scope.
-                The source file is GHC.Prim.hi-boot, which is just
-                copied to make GHC.Prim.hi
+GHC.Internal.Prim        Has no implementation.  It defines built-in things, and
+                         by importing it you bring them into scope.
+                         The source file is GHC.Internal.Prim.hi-boot, which is just
+                         copied to make GHC.Internal.Prim.hi
 
 GHC.Internal.Base        Classes: Eq, Ord, Functor, Monad
-                Types:   List, (), Int, Bool, Ordering, Char, String
+                Types:   List, (), Int, Bool, Ordering, Char, String, NonEmpty
 
 GHC.Internal.Data.Tuple      Types: tuples, plus instances for GHC.Internal.Base classes
 
@@ -29,6 +29,13 @@
 
 GHC.Internal.List        List functions
 
+GHC.Internal.Data.NonEmpty   Orphan instances for GHC.Internal.Base.NonEmpty of
+                             GHC.Internal.Base classes (other than Eq and Ord)
+                             plus function map
+
+GHC.Internal.Data.List.NonEmpty   Re-export GHC.Internal.Data.NonEmpty plus
+                                  functions zip and zipWith
+
 GHC.Internal.Num         Class: Num, plus instances for Int
                 Type:  Integer, plus instances for all classes so far (Eq, Ord, Num, Show)
 
@@ -99,20 +106,20 @@
 module GHC.Internal.Base
         (
         module GHC.Internal.Base,
-        module GHC.Classes,
-        module GHC.CString,
-        module GHC.Magic,
-        module GHC.Magic.Dict,
-        module GHC.Types,
-        module GHC.Prim,         -- Re-export GHC.Prim, GHC.Prim.Ext,
-        module GHC.Prim.Ext,     -- GHC.Prim.PtrEq and [boot] GHC.Internal.Err
-        module GHC.Prim.PtrEq,   -- to avoid lots of people having to
-        module GHC.Internal.Err, -- import these modules explicitly
+        module GHC.Internal.Classes,
+        module GHC.Internal.CString,
+        module GHC.Internal.Magic,
+        module GHC.Internal.Magic.Dict,
+        module GHC.Internal.Types,
+        module GHC.Internal.Prim,         -- Re-export GHC.Internal.Prim, GHC.Internal.Prim.Ext,
+        module GHC.Internal.Prim.Ext,     -- GHC.Internal.Prim.PtrEq and [boot] GHC.Internal.Err
+        module GHC.Internal.Prim.PtrEq,   -- to avoid lots of people having to
+        module GHC.Internal.Err,          -- import these modules explicitly
         module GHC.Internal.Maybe
   )
         where
 
-import GHC.Types hiding (
+import GHC.Internal.Types hiding (
   Unit#,
   Solo#,
   Tuple0#,
@@ -243,7 +250,7 @@
   Sum62#,
   Sum63#,
   )
-import GHC.Classes hiding (
+import GHC.Internal.Classes hiding (
   CUnit,
   CSolo,
   CTuple0,
@@ -312,21 +319,21 @@
   CTuple63,
   CTuple64,
   )
-import GHC.CString
-import GHC.Magic
-import GHC.Magic.Dict
-import GHC.Prim hiding (dataToTagSmall#, dataToTagLarge#, whereFrom#)
+import GHC.Internal.CString
+import GHC.Internal.Magic
+import GHC.Internal.Magic.Dict
+import GHC.Internal.Prim hiding (dataToTagSmall#, dataToTagLarge#, whereFrom#)
   -- Hide dataToTag# ops because they are expected to break for
   -- GHC-internal reasons in the near future, and shouldn't
   -- be exposed from base (not even GHC.Exts)
 
-import GHC.Prim.Ext
-import GHC.Prim.PtrEq
+import GHC.Internal.Prim.Ext
+import GHC.Internal.Prim.PtrEq
 import GHC.Internal.Err
 import GHC.Internal.Maybe
 import {-# SOURCE #-} GHC.Internal.IO (mkUserError, mplusIO)
 
-import GHC.Tuple (Solo (MkSolo))
+import GHC.Internal.Tuple (Solo (MkSolo))
 
 -- See Note [Semigroup stimes cycle]
 import {-# SOURCE #-} GHC.Internal.Num (Num (..))
@@ -371,11 +378,11 @@
 
 W1:
   Common awkward dependencies:
-   * TypeRep metadata introduces references to GHC.Types in EVERY module.
-   * A String literal introduces a reference to GHC.CString, for either
+   * TypeRep metadata introduces references to GHC.Internal.Types in EVERY module.
+   * A String literal introduces a reference to GHC.Internal.CString, for either
      unpackCString# or unpackCStringUtf8# depending on its contents.
-   * Tuple-notation introduces references to GHC.Tuple.
-   * Constraint tuples introduce references to GHC.Classes.
+   * Tuple-notation introduces references to GHC.Internal.Tuple.
+   * Constraint tuples introduce references to GHC.Internal.Classes.
    * Short lists like [3,8,2] produce references to GHC.Internal.Base.build
 
   A module can transitively depend on all of these by importing any of
@@ -387,7 +394,7 @@
    * Most modules in ghc-internal import GHC.Internal.Base.
    * Most modules in compiler/ import GHC.Prelude, which imports Prelude.
    * Most hs-boot files that would otherwise have no imports can get
-     away with just importing GHC.Types.
+     away with just importing GHC.Internal.Types.
 
   Unfortunately, the requirement to transitively import these modules
   when they are implicitly used is obscure and causes only /intermittent/
@@ -401,7 +408,8 @@
   missing record fields, and missing class instance methods all
   introduce references to GHC.Internal.Control.Exception.Base.
 
-  These constructs are therefore not allowed in ghc-prim or ghc-bignum.
+  These constructs are therefore not allowed in packages below ghc-internal.
+  This was the case when ghc-prim and ghc-bignum were separate of ghc-internal.
   But since they generally have bad code smell and are avoided by
   developers anyway, this restriction has not been very burdensome.
 
@@ -442,7 +450,7 @@
 
 W5:
   If no explicit "default" declaration is present, the assumed
-  "default (Integer, Double)" creates a dependency on GHC.Num.Integer
+  "default (Integer, Double)" creates a dependency on GHC.Internal.Bignum.Integer
   for the Integer type if defaulting is ever attempted during
   type-checking.  (This doesn't apply to hs-boot files, which can't
   be given "default" declarations anyway.)
@@ -754,10 +762,6 @@
 -}
 
 -- | @since base-4.9.0.0
-instance Semigroup (NonEmpty a) where
-        (a :| as) <> ~(b :| bs) = a :| (as ++ b : bs)
-
--- | @since base-4.9.0.0
 instance Semigroup b => Semigroup (a -> b) where
         f <> g = \x -> f x <> g x
         stimes n f e = stimes n (f e)
@@ -972,7 +976,7 @@
     -- | 'fmap' is used to apply a function of type @(a -> b)@ to a value of type @f a@,
     -- where f is a functor, to produce a value of type @f b@.
     -- Note that for any type constructor with more than one parameter (e.g., 'Either'),
-    -- only the last type parameter can be modified with `fmap` (e.g., `b` in `Either a b`).
+    -- only the last type parameter can be modified with `fmap` (e.g., `b` in @Either a b@).
     --
     -- Some type constructors with two parameters or more have a @'Data.Bifunctor'@ instance that allows
     -- both the last and the penultimate parameters to be mapped over.
@@ -1707,25 +1711,6 @@
            , Ord -- ^ @since base-4.9.0.0
            )
 
--- | @since base-4.9.0.0
-instance Functor NonEmpty where
-  fmap f ~(a :| as) = f a :| fmap f as
-  b <$ ~(_ :| as)   = b   :| (b <$ as)
-
--- | @since base-4.9.0.0
-instance Applicative NonEmpty where
-  pure a = a :| []
-  (<*>) = ap
-  liftA2 = liftM2
-
--- | @since base-4.9.0.0
-instance Monad NonEmpty where
-  ~(a :| as) >>= f = b :| (bs ++ bs')
-    where b :| bs = f a
-          bs' = as >>= toList . f
-          toList ~(c :| cs) = c : cs
-
-
 ----------------------------------------------
 -- The list type
 
@@ -2107,6 +2092,9 @@
 
 -- Assertion function.  This simply ignores its boolean argument.
 -- The compiler may rewrite it to @('assertError' line)@.
+-- The Haddock below is attached to `assert`, since that is
+-- what occurs in source programs.
+-- See Note [Overview of assertions] in GHC.Tc.Gen.Head
 
 -- | If the first argument evaluates to 'True', then the result is the
 -- second argument.  Otherwise an 'Control.Exception.AssertionFailed' exception
@@ -2115,14 +2103,9 @@
 --
 -- Assertions can normally be turned on or off with a compiler flag
 -- (for GHC, assertions are normally on unless optimisation is turned on
--- with @-O@ or the @-fignore-asserts@
--- option is given).  When assertions are turned off, the first
--- argument to 'assert' is ignored, and the second argument is
--- returned as the result.
-
---      SLPJ: in 5.04 etc 'assert' is in GHC.Prim,
---      but from Template Haskell onwards it's simply
---      defined here in Base.hs
+-- with @-O@ or the @-fignore-asserts@ option is given). When assertions
+-- are turned off, the first argument to 'assert' is ignored, and the second
+-- argument is returned as the result.
 assert :: Bool -> a -> a
 assert _pred r = r
 
diff --git a/src/GHC/Internal/Bignum/Backend.hs b/src/GHC/Internal/Bignum/Backend.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Backend.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+-- | Selected backend
+module GHC.Internal.Bignum.Backend
+   ( module Backend
+   )
+where
+
+#if defined(BIGNUM_CHECK)
+import GHC.Internal.Bignum.Backend.Check    as Backend
+#else
+import GHC.Internal.Bignum.Backend.Selected as Backend
+#endif
+
diff --git a/src/GHC/Internal/Bignum/Backend/Check.hs b/src/GHC/Internal/Bignum/Backend/Check.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Backend/Check.hs
@@ -0,0 +1,508 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+{-# LANGUAGE NegativeLiterals #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# OPTIONS_GHC -Wno-name-shadowing #-}
+
+-- | Check Native implementation against another backend
+module GHC.Internal.Bignum.Backend.Check where
+
+import GHC.Internal.CString
+import GHC.Internal.Prim
+import GHC.Internal.Types
+import GHC.Internal.Bignum.WordArray
+import GHC.Internal.Bignum.Primitives
+import {-# SOURCE #-} GHC.Internal.Bignum.Integer
+import {-# SOURCE #-} GHC.Internal.Bignum.Natural
+import qualified GHC.Internal.Bignum.Backend.Native   as Native
+import qualified GHC.Internal.Bignum.Backend.Selected as Other
+
+#if defined(BIGNUM_NATIVE)
+#error You can't validate Native backend against itself. Choose another backend (e.g. gmp, ffi)
+#endif
+
+default ()
+
+-- | ghc-bignum backend name
+backendName :: [Char]
+backendName = unpackAppendCString# "check-"# Other.backendName
+  -- we don't have (++) at our disposal, so we directly use
+  -- `unpackAppendCString#`
+
+bignat_compare
+   :: WordArray#
+   -> WordArray#
+   -> Int#
+bignat_compare a b =
+   let
+      gr = Other.bignat_compare a b
+      nr = Native.bignat_compare a b
+   in case gr ==# nr of
+         0# -> unexpectedValue_Int# (# #)
+         _  -> gr
+
+mwaCompare
+   :: MutableWordArray# s
+   -> MutableWordArray# s
+   -> State# s
+   -> (# State# s, Bool# #)
+mwaCompare mwa mwb s =
+   case mwaSize# mwa s of
+      (# s, szA #) -> case mwaSize# mwb s of
+         (# s, szB #) -> case szA ==# szB of
+            0# -> (# s, 0# #)
+            _  -> let
+                     go i s
+                        | isTrue# (i <# 0#) = (# s, 1# #)
+                        | True =
+                           case readWordArray# mwa i s of
+                              (# s, a #) -> case readWordArray# mwb i s of
+                                 (# s, b #) -> case a `eqWord#` b of
+                                    0# -> (# s, 0# #)
+                                    _  -> go (i -# 1#) s
+                  in go (szA -# 1#) s
+
+mwaCompareOp
+   :: MutableWordArray# s
+   -> (MutableWordArray# s -> State# s -> State# s)
+   -> (MutableWordArray# s -> State# s -> State# s)
+   -> State# s
+   -> State# s
+mwaCompareOp mwa f g s =
+   case mwaSize# mwa s of { (# s, sz #) ->
+   case newWordArray# sz s of { (# s, mwb #) ->
+   case f mwa s of { s ->
+   case g mwb s of { s ->
+   case mwaTrimZeroes# mwa s of { s ->
+   case mwaTrimZeroes# mwb s of { s ->
+   case mwaCompare mwa mwb s of
+      (# s, 0# #) -> case unexpectedValue of
+                        !_ -> s
+                        -- see Note [ghc-bignum exceptions] in
+                        -- GHC.Num.Primitives
+      (# s, _  #) -> s
+   }}}}}}
+
+mwaCompareOp2
+   :: MutableWordArray# s
+   -> MutableWordArray# s
+   -> (MutableWordArray# s -> MutableWordArray# s -> State# s -> State# s)
+   -> (MutableWordArray# s -> MutableWordArray# s -> State# s -> State# s)
+   -> State# s
+   -> State# s
+mwaCompareOp2 mwa mwb f g s =
+   case mwaSize# mwa s of { (# s, szA #) ->
+   case mwaSize# mwb s of { (# s, szB #) ->
+   case newWordArray# szA s of { (# s, mwa' #) ->
+   case newWordArray# szB s of { (# s, mwb' #) ->
+   case f mwa  mwb  s of { s ->
+   case g mwa' mwb' s of { s ->
+   case mwaTrimZeroes# mwa s of { s ->
+   case mwaTrimZeroes# mwb s of { s ->
+   case mwaTrimZeroes# mwa' s of { s ->
+   case mwaTrimZeroes# mwb' s of { s ->
+   case mwaCompare mwa mwa' s of { (# s, ba #) ->
+   case mwaCompare mwb mwb' s of { (# s, bb #) ->
+   case ba &&# bb of
+      0# -> case unexpectedValue of
+               !_ -> s
+               -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
+      _  -> s
+   }}}}}}}}}}}}
+
+mwaCompareOpBool
+   :: MutableWordArray# s
+   -> (MutableWordArray# s -> State# s -> (#State# s, Bool# #))
+   -> (MutableWordArray# s -> State# s -> (#State# s, Bool# #))
+   -> State# s
+   -> (# State# s, Bool# #)
+mwaCompareOpBool mwa f g s =
+   case mwaSize# mwa s of { (# s, sz #) ->
+   case newWordArray# sz s of { (# s, mwb #) ->
+   case f mwa s of { (# s, ra #) ->
+   case g mwb s of { (# s, rb #) ->
+   case ra ==# rb of
+      0# -> case unexpectedValue of
+               !_ -> (# s, ra #)
+               -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
+      _  -> case ra of -- don't compare MWAs if underflow signaled!
+         0# -> (# s, ra #) -- underflow
+         _  -> case mwaTrimZeroes# mwa s of { s ->
+               case mwaTrimZeroes# mwb s of { s ->
+               case mwaCompare mwa mwb s of
+                  (# s, 0# #) -> case unexpectedValue of
+                                    !_ -> (# s, ra #)
+                                    -- see Note [ghc-bignum exceptions] in
+                                    -- GHC.Num.Primitives
+                  _  -> (# s, ra #)
+   }}}}}}
+
+mwaCompareOpWord
+   :: MutableWordArray# s
+   -> (MutableWordArray# s -> State# s -> (#State# s, Word# #))
+   -> (MutableWordArray# s -> State# s -> (#State# s, Word# #))
+   -> State# s
+   -> (# State# s, Word# #)
+mwaCompareOpWord mwa f g s =
+   case mwaSize# mwa s of { (# s, sz #) ->
+   case newWordArray# sz s of { (# s, mwb #) ->
+   case f mwa s of { (# s, ra #) ->
+   case g mwb s of { (# s, rb #) ->
+   case mwaTrimZeroes# mwa s of { s ->
+   case mwaTrimZeroes# mwb s of { s ->
+   case mwaCompare mwa mwb s of
+      (# s, b #) -> case b &&# (ra `eqWord#` rb) of
+         0# -> case unexpectedValue of
+                  !_ -> (# s, ra #)
+                  -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
+         _  -> (# s, ra #)
+   }}}}}}
+
+bignat_add
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_add mwa wa wb
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_add m wa wb)
+      (\m -> Native.bignat_add m wa wb)
+
+bignat_add_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_add_word mwa wa b
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_add_word m wa b)
+      (\m -> Native.bignat_add_word m wa b)
+
+bignat_mul_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_mul_word mwa wa b
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_mul_word m wa b)
+      (\m -> Native.bignat_mul_word m wa b)
+
+bignat_sub
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> (# State# RealWorld, Bool# #)
+bignat_sub mwa wa wb
+   = mwaCompareOpBool mwa
+      (\m -> Other.bignat_sub m wa wb)
+      (\m -> Native.bignat_sub m wa wb)
+
+bignat_sub_word
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> (# State# RealWorld, Bool# #)
+bignat_sub_word mwa wa b
+   = mwaCompareOpBool mwa
+      (\m -> Other.bignat_sub_word m wa b)
+      (\m -> Native.bignat_sub_word m wa b)
+
+bignat_mul
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_mul mwa wa wb
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_mul m wa wb)
+      (\m -> Native.bignat_mul m wa wb)
+
+bignat_popcount :: WordArray# -> Word#
+bignat_popcount wa =
+   let
+      gr = Other.bignat_popcount wa
+      nr = Native.bignat_popcount wa
+   in case gr `eqWord#` nr of
+         0# -> 1## `quotWord#` 0##
+         _  -> gr
+
+bignat_shiftl
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_shiftl mwa wa n
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_shiftl m wa n)
+      (\m -> Native.bignat_shiftl m wa n)
+
+bignat_shiftr
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_shiftr mwa wa n
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_shiftr m wa n)
+      (\m -> Native.bignat_shiftr m wa n)
+
+bignat_shiftr_neg
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_shiftr_neg mwa wa n
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_shiftr_neg m wa n)
+      (\m -> Native.bignat_shiftr_neg m wa n)
+
+bignat_or
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_or mwa wa wb
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_or m wa wb)
+      (\m -> Native.bignat_or m wa wb)
+
+bignat_xor
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_xor mwa wa wb
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_xor m wa wb)
+      (\m -> Native.bignat_xor m wa wb)
+
+bignat_and
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_and mwa wa wb
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_and m wa wb)
+      (\m -> Native.bignat_and m wa wb)
+
+bignat_and_not
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_and_not mwa wa wb
+   = mwaCompareOp mwa
+      (\m -> Other.bignat_and_not m wa wb)
+      (\m -> Native.bignat_and_not m wa wb)
+
+bignat_quotrem
+   :: MutableWordArray# RealWorld
+   -> MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quotrem mwq mwr wa wb
+   = mwaCompareOp2 mwq mwr
+      (\m1 m2 -> Other.bignat_quotrem m1 m2 wa wb)
+      (\m1 m2 -> Native.bignat_quotrem m1 m2 wa wb)
+
+bignat_quot
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quot mwq wa wb
+   = mwaCompareOp mwq
+      (\m -> Other.bignat_quot m wa wb)
+      (\m -> Native.bignat_quot m wa wb)
+
+bignat_rem
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_rem mwr wa wb
+   = mwaCompareOp mwr
+      (\m -> Other.bignat_rem m wa wb)
+      (\m -> Native.bignat_rem m wa wb)
+
+bignat_quotrem_word
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> (# State# RealWorld, Word# #)
+bignat_quotrem_word mwq wa b
+   = mwaCompareOpWord mwq
+      (\m -> Other.bignat_quotrem_word m wa b)
+      (\m -> Native.bignat_quotrem_word m wa b)
+
+bignat_quot_word
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quot_word mwq wa b
+   = mwaCompareOp mwq
+      (\m -> Other.bignat_quot_word m wa b)
+      (\m -> Native.bignat_quot_word m wa b)
+
+bignat_rem_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+bignat_rem_word wa b =
+   let
+      gr = Other.bignat_rem_word wa b
+      nr = Native.bignat_rem_word wa b
+   in case gr `eqWord#` nr of
+       1# -> gr
+       _  -> unexpectedValue_Word# (# #)
+
+bignat_gcd
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_gcd mwr wa wb
+   = mwaCompareOp mwr
+      (\m -> Other.bignat_gcd m wa wb)
+      (\m -> Native.bignat_gcd m wa wb)
+
+bignat_gcd_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+bignat_gcd_word wa b =
+   let
+      gr = Other.bignat_gcd_word wa b
+      nr = Native.bignat_gcd_word wa b
+   in case gr `eqWord#` nr of
+       1# -> gr
+       _  -> unexpectedValue_Word# (# #)
+
+bignat_gcd_word_word
+   :: Word#
+   -> Word#
+   -> Word#
+bignat_gcd_word_word a b =
+   let
+      gr = Other.bignat_gcd_word_word a b
+      nr = Native.bignat_gcd_word_word a b
+   in case gr `eqWord#` nr of
+       1# -> gr
+       _  -> unexpectedValue_Word# (# #)
+
+bignat_encode_double :: WordArray# -> Int# -> Double#
+bignat_encode_double a e =
+   let
+      gr = Other.bignat_encode_double a e
+      nr = Native.bignat_encode_double a e
+   in case gr ==## nr of
+       1# -> gr
+       _  -> case unexpectedValue of
+               !_ -> 0.0##
+               -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
+
+bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
+bignat_powmod_word b e m =
+   let
+      gr = Other.bignat_powmod_word b e m
+      nr = Native.bignat_powmod_word b e m
+   in case gr `eqWord#` nr of
+       1# -> gr
+       _  -> unexpectedValue_Word# (# #)
+
+bignat_powmod
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_powmod r b e m
+   = mwaCompareOp r
+      (\r' -> Other.bignat_powmod r' b e m)
+      (\r' -> Native.bignat_powmod r' b e m)
+
+bignat_powmod_words
+   :: Word#
+   -> Word#
+   -> Word#
+   -> Word#
+bignat_powmod_words b e m =
+   let
+      gr = Other.bignat_powmod_words b e m
+      nr = Native.bignat_powmod_words b e m
+   in case gr `eqWord#` nr of
+       1# -> gr
+       _  -> unexpectedValue_Word# (# #)
+
+integer_gcde
+   :: Integer
+   -> Integer
+   -> (# Integer, Integer, Integer #)
+integer_gcde a b =
+   let
+      !(# g0,x0,y0 #) = Other.integer_gcde a b
+      !(# g1,x1,y1 #) = Native.integer_gcde a b
+   in if isTrue# (integerEq# x0 x1
+                  &&# integerEq# y0 y1
+                  &&# integerEq# g0 g1)
+         then (# g0, x0, y0 #)
+         else case unexpectedValue of
+            !_ -> (# integerZero, integerZero, integerZero #)
+
+integer_recip_mod
+   :: Integer
+   -> Natural
+   -> (# Natural | () #)
+integer_recip_mod x m =
+   let
+      !r0 = Other.integer_recip_mod x m
+      !r1 = Native.integer_recip_mod x m
+   in case (# r0, r1 #) of
+         (# (# | () #), (# | () #) #) -> r0
+         (# (# y0 | #), (# y1 | #) #)
+            | isTrue# (naturalEq# y0 y1) -> r0
+         _ -> case unexpectedValue of
+            !_ -> (# | () #)
+
+integer_powmod
+   :: Integer
+   -> Natural
+   -> Natural
+   -> Natural
+integer_powmod b e m =
+   let
+      !r0 = Other.integer_powmod b e m
+      !r1 = Native.integer_powmod b e m
+   in if isTrue# (naturalEq# r0 r1)
+         then r0
+         else case unexpectedValue of
+               !_ -> naturalZero
diff --git a/src/GHC/Internal/Bignum/Backend/FFI.hs b/src/GHC/Internal/Bignum/Backend/FFI.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Backend/FFI.hs
@@ -0,0 +1,641 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+{-# LANGUAGE NegativeLiterals #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+-- | External BigNat backend that directly call FFI operations.
+--
+-- This backend can be useful for specific compilers such as GHCJS or Asterius
+-- that replace bignat foreign calls with calls to the native platform bignat
+-- library (e.g. JavaScript's BigInt). You can also link an extra object
+-- providing the implementation.
+module GHC.Internal.Bignum.Backend.FFI where
+
+import GHC.Internal.Prim
+import GHC.Internal.Types
+import GHC.Internal.Bignum.WordArray
+import GHC.Internal.Bignum.Primitives
+import qualified GHC.Internal.Bignum.Backend.Native as Native
+import {-# SOURCE #-} GHC.Internal.Bignum.Natural
+import {-# SOURCE #-} GHC.Internal.Bignum.Integer
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+-- (This module uses the empty tuple () and string literals.)
+import GHC.Internal.Tuple ()
+import GHC.Internal.CString ()
+
+default ()
+
+-- | ghc-bignum backend name
+backendName :: [Char]
+backendName = "ffi"
+
+-- | Compare two non-zero BigNat of the same length
+--
+-- Return:
+--     < 0 ==> LT
+--    == 0 ==> EQ
+--     > 0 ==> GT
+bignat_compare
+   :: WordArray#
+   -> WordArray#
+   -> Int#
+bignat_compare = ghc_bignat_compare
+
+foreign import ccall unsafe ghc_bignat_compare
+   :: WordArray#
+   -> WordArray#
+   -> Int#
+
+-- | Add two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: max (size a, size b) + 1
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
+bignat_add
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_add mwa wa wb s
+   = ioVoid (ghc_bignat_add mwa wa wb) s
+
+foreign import ccall unsafe ghc_bignat_add
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | Add a non-zero BigNat and a non-zero Word#
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a + 1
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
+bignat_add_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_add_word mwa wa b s =
+   ioVoid (ghc_bignat_add_word mwa wa b) s
+
+foreign import ccall unsafe ghc_bignat_add_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> IO ()
+
+-- | Multiply a non-zero BigNat and a non-zero Word#
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a + 1
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
+bignat_mul_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_mul_word mwa wa b s =
+   ioVoid (ghc_bignat_mul_word mwa wa b) s
+
+foreign import ccall unsafe ghc_bignat_mul_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> IO ()
+
+-- | Sub two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+--
+-- Return False# to indicate underflow.
+bignat_sub
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> (# State# RealWorld, Bool# #)
+bignat_sub mwa wa wb s = ioBool (ghc_bignat_sub mwa wa wb) s
+
+foreign import ccall unsafe ghc_bignat_sub
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> IO Bool
+
+-- | Sub a non-zero word from a non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+--
+-- Return False# to indicate underflow.
+bignat_sub_word
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> (# State# RealWorld, Bool# #)
+bignat_sub_word mwa wa b s = ioBool (ghc_bignat_sub_word mwa wa b) s
+
+foreign import ccall unsafe ghc_bignat_sub_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> IO Bool
+
+-- | Multiply two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a+size b
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
+bignat_mul
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_mul mwa wa wb s = ioVoid (ghc_bignat_mul mwa wa wb) s
+
+foreign import ccall unsafe ghc_bignat_mul
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | PopCount of a non-zero BigNat
+bignat_popcount :: WordArray# -> Word#
+bignat_popcount = ghc_bignat_popcount
+
+foreign import ccall unsafe ghc_bignat_popcount
+   :: WordArray#
+   -> Word#
+
+-- | Left-shift a non-zero BigNat by a non-zero amount of bits
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a + required new limbs
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
+bignat_shiftl
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_shiftl mwa wa n s = ioVoid (ghc_bignat_shiftl mwa wa n) s
+
+foreign import ccall unsafe ghc_bignat_shiftl
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> IO ()
+
+-- | Right-shift a non-zero BigNat by a non-zero amount of bits
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: required limbs
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
+bignat_shiftr
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_shiftr mwa wa n s = ioVoid (ghc_bignat_shiftr mwa wa n) s
+
+foreign import ccall unsafe ghc_bignat_shiftr
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> IO ()
+
+-- | Right-shift a non-zero BigNat by a non-zero amount of bits by first
+-- converting it into its two's complement representation and then again after
+-- the arithmetic shift.
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: required limbs
+--
+-- The potential 0 most-significant Words (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
+bignat_shiftr_neg
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_shiftr_neg mwa wa n s = ioVoid (ghc_bignat_shiftr_neg mwa wa n) s
+
+foreign import ccall unsafe ghc_bignat_shiftr_neg
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> IO ()
+
+
+-- | OR two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: max (size a, size b)
+bignat_or
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_or #-}
+bignat_or mwa wa wb s = ioVoid (ghc_bignat_or mwa wa wb) s
+
+foreign import ccall unsafe ghc_bignat_or
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | XOR two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: max (size a, size b)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_xor
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_xor #-}
+bignat_xor mwa wa wb s = ioVoid (ghc_bignat_xor mwa wa wb) s
+
+foreign import ccall unsafe ghc_bignat_xor
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | AND two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: min (size a, size b)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_and
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_and #-}
+bignat_and mwa wa wb s = ioVoid (ghc_bignat_and mwa wa wb) s
+
+foreign import ccall unsafe ghc_bignat_and
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | ANDNOT two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_and_not
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_and_not #-}
+bignat_and_not mwa wa wb s = ioVoid (ghc_bignat_and_not mwa wa wb) s
+
+foreign import ccall unsafe ghc_bignat_and_not
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | QuotRem of two non-zero BigNat
+--
+-- Result quotient and remainder are to be stored in the MutableWordArray#.
+-- The first one (quotient) has size: size(A)-size(B)+1
+-- The second one (remainder) has size: size(b)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_quotrem
+   :: MutableWordArray# RealWorld -- ^ Quotient
+   -> MutableWordArray# RealWorld -- ^ Remainder
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quotrem mwq mwr wa wb s =
+   ioVoid (ghc_bignat_quotrem mwq mwr wa wb) s
+
+foreign import ccall unsafe ghc_bignat_quotrem
+   :: MutableWordArray# RealWorld
+   -> MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | Quotient of two non-zero BigNat
+--
+-- Result quotient is to be stored in the MutableWordArray#.
+-- The latter has size: size(A)-size(B)+1
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_quot
+   :: MutableWordArray# RealWorld -- ^ Quotient
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quot mwq wa wb s =
+   ioVoid (ghc_bignat_quot mwq wa wb) s
+
+foreign import ccall unsafe ghc_bignat_quot
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | Remainder of two non-zero BigNat
+--
+-- Result remainder is to be stored in the MutableWordArray#.
+-- The latter has size: size(B)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_rem
+   :: MutableWordArray# RealWorld -- ^ Quotient
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_rem mwr wa wb s =
+   ioVoid (ghc_bignat_rem mwr wa wb) s
+
+foreign import ccall unsafe ghc_bignat_rem
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | QuotRem of a non-zero BigNat and a non-zero Word
+--
+-- Result quotient is to be stored in the MutableWordArray#.
+-- The latter has size: size(A)
+--
+-- The remainder is returned.
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_quotrem_word
+   :: MutableWordArray# RealWorld -- ^ Quotient
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> (# State# RealWorld, Word# #)
+bignat_quotrem_word mwq wa b s =
+   ioWord# (ghc_bignat_quotrem_word mwq wa b) s
+
+foreign import ccall unsafe ghc_bignat_quotrem_word
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> IO Word
+
+-- | Quot of a non-zero BigNat and a non-zero Word
+--
+-- Result quotient is to be stored in the MutableWordArray#.
+-- The latter has size: size(A)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_quot_word
+   :: MutableWordArray# RealWorld -- ^ Quotient
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quot_word mwq wa b s =
+   ioVoid (ghc_bignat_quot_word mwq wa b) s
+
+foreign import ccall unsafe ghc_bignat_quot_word
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> IO ()
+
+-- | Remainder of a non-zero BigNat and a non-zero Word
+--
+-- The remainder is returned.
+bignat_rem_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+bignat_rem_word = ghc_bignat_rem_word
+
+foreign import ccall unsafe ghc_bignat_rem_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+
+
+-- | Greatest common divisor (GCD) of two non-zero and non-one BigNat
+--
+-- Result GCD is to be stored in the MutableWordArray#.
+-- The latter has size: size(B)
+-- The first WordArray# is greater than the second WordArray#.
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_gcd
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_gcd mwr wa wb s =
+   ioVoid (ghc_bignat_gcd mwr wa wb) s
+
+foreign import ccall unsafe ghc_bignat_gcd
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | Greatest common divisor (GCD) of a non-zero/non-one BigNat and a
+-- non-zero/non-one Word#
+--
+-- Result GCD is returned
+bignat_gcd_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+bignat_gcd_word = ghc_bignat_gcd_word
+
+foreign import ccall unsafe ghc_bignat_gcd_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+
+-- | Greatest common divisor (GCD) of two Word#
+--
+-- Result GCD is returned
+bignat_gcd_word_word
+   :: Word#
+   -> Word#
+   -> Word#
+bignat_gcd_word_word = ghc_bignat_gcd_word_word
+
+foreign import ccall unsafe ghc_bignat_gcd_word_word
+   :: Word#
+   -> Word#
+   -> Word#
+
+-- | Encode (# BigNat mantissa, Int# exponent #) into a Double#
+bignat_encode_double :: WordArray# -> Int# -> Double#
+bignat_encode_double = ghc_bignat_encode_double
+
+foreign import ccall unsafe ghc_bignat_encode_double
+   :: WordArray#
+   -> Int#
+   -> Double#
+
+-- | \"@'bignat_powmod_word' /b/ /e/ /m/@\" computes base @/b/@ raised to
+-- exponent @/e/@ modulo @/m/@.
+--
+-- b > 1
+-- e > 0
+-- m > 1
+bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
+bignat_powmod_word = ghc_bignat_powmod_word
+
+foreign import ccall unsafe ghc_bignat_powmod_word
+   :: WordArray# -> WordArray# -> Word# -> Word#
+
+-- | \"@'bignat_powmod' r /b/ /e/ /m/@\" computes base @/b/@ raised to
+-- exponent @/e/@ modulo @/m/@.
+--
+-- b > 1
+-- e > 0
+-- m > 1
+--
+-- Result is to be stored in the MutableWordArray# (which size is equal to the
+-- one of m).
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+bignat_powmod
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_powmod r b e m s =
+   ioVoid (ghc_bignat_powmod r b e m) s
+
+foreign import ccall unsafe ghc_bignat_powmod
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> WordArray#
+   -> IO ()
+
+-- | \"@'bignat_powmod' /b/ /e/ /m/@\" computes base @/b/@ raised to
+-- exponent @/e/@ modulo @/m/@.
+--
+-- b > 1
+-- e > 0
+-- m > 1
+bignat_powmod_words
+   :: Word#
+   -> Word#
+   -> Word#
+   -> Word#
+bignat_powmod_words = ghc_bignat_powmod_words
+
+foreign import ccall unsafe ghc_bignat_powmod_words
+   :: Word# -> Word# -> Word# -> Word#
+
+
+-- | Return extended GCD of two non-zero integers.
+--
+-- I.e. integer_gcde a b returns (g,x,y) so that ax + by = g
+--
+-- Input: a and b are non zero.
+-- Output: g must be > 0
+--
+integer_gcde
+   :: Integer
+   -> Integer
+   -> (# Integer, Integer, Integer #)
+integer_gcde = Native.integer_gcde
+   -- for now we use Native's implementation. If some FFI backend user needs a
+   -- specific implementation, we'll need to determine a prototype to pass and
+   -- return BigNat signs and sizes via FFI.
+
+
+-- | Computes the modular inverse of two non-zero integers.
+--
+-- I.e. y = integer_recip_mod x m
+--        = x^(-1) `mod` m
+--
+-- with 0 < y < abs m
+integer_recip_mod
+   :: Integer
+   -> Natural
+   -> (# Natural | () #)
+integer_recip_mod = Native.integer_recip_mod
+   -- for now we use Native's implementation. If some FFI backend user needs a
+   -- specific implementation, we'll need to determine a prototype to pass and
+   -- return BigNat signs and sizes via FFI.
+
+-- | Computes the modular exponentiation.
+--
+-- I.e. y = integer_powmod b e m
+--        = b^e `mod` m
+--
+-- with 0 <= y < abs m
+integer_powmod
+   :: Integer
+   -> Natural
+   -> Natural
+   -> Natural
+integer_powmod = Native.integer_powmod
+   -- for now we use Native's implementation. If some FFI backend user needs a
+   -- specific implementation, we'll need to determine a prototype to pass and
+   -- return BigNat signs and sizes via FFI.
diff --git a/src/GHC/Internal/Bignum/Backend/GMP.hs b/src/GHC/Internal/Bignum/Backend/GMP.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Backend/GMP.hs
@@ -0,0 +1,642 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+{-# LANGUAGE NegativeLiterals #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE LambdaCase #-}
+
+{-# OPTIONS_GHC -Wno-name-shadowing #-}
+
+-- | Backend based on the GNU GMP library.
+--
+-- This has been adapted from the legacy `integer-gmp` package written by
+-- Herbert Valerio Riedel.
+module GHC.Internal.Bignum.Backend.GMP where
+
+#include "MachDeps.h"
+#include "WordSize.h"
+
+import GHC.Internal.Bignum.WordArray
+import GHC.Internal.Bignum.Primitives
+import GHC.Internal.Prim
+import GHC.Internal.Types
+import GHC.Internal.Magic (runRW#)
+import {-# SOURCE #-} GHC.Internal.Bignum.Integer
+import {-# SOURCE #-} GHC.Internal.Bignum.BigNat
+import {-# SOURCE #-} GHC.Internal.Bignum.Natural
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+-- (This module uses the empty tuple () and string literals.)
+import GHC.Internal.Tuple ()
+import GHC.Internal.CString ()
+
+default ()
+
+-- | ghc-bignum backend name
+backendName :: [Char]
+backendName = "gmp"
+
+----------------------------------------------------------------------------
+-- type definitions
+
+-- NB: all code assumes GMP_LIMB_BITS == WORD_SIZE_IN_BITS
+-- The C99 code in cbits/gmp_wrappers.c will fail to compile if this doesn't hold
+
+-- | Type representing a GMP Limb
+type GmpLimb = Word -- actually, 'CULong'
+type GmpLimb# = Word#
+
+-- | Count of 'GmpLimb's, must be positive (unless specified otherwise).
+type GmpSize = Int  -- actually, a 'CLong'
+type GmpSize# = Int#
+
+narrowGmpSize# :: Int# -> Int#
+#if SIZEOF_LONG == SIZEOF_HSWORD
+narrowGmpSize# x = x
+#elif (SIZEOF_LONG == 4) && (SIZEOF_HSWORD == 8)
+-- On IL32P64 (i.e. Win64), we have to be careful with CLong not being
+-- 64bit.  This is mostly an issue on values returned from C functions
+-- due to sign-extension.
+narrowGmpSize# = narrow32Int#
+#endif
+
+narrowCInt# :: Int# -> Int#
+narrowCInt# = narrow32Int#
+
+bignat_compare :: WordArray# -> WordArray# -> Int#
+bignat_compare x y = narrowCInt# (c_mpn_cmp x y (wordArraySize# x))
+
+bignat_add
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_add #-}
+bignat_add mwa wa wb s
+   -- weird GMP requirement: the biggest comes first
+   | isTrue# (wordArraySize# wb ># wordArraySize# wa)
+   = case ioWord# (c_mpn_add mwa wb (wordArraySize# wb) wa (wordArraySize# wa)) s of
+      (# s', c #) -> mwaWriteMostSignificant mwa c s'
+
+   | True
+   = case ioWord# (c_mpn_add mwa wa (wordArraySize# wa) wb (wordArraySize# wb)) s of
+      (# s', c #) -> mwaWriteMostSignificant mwa c s'
+
+bignat_add_word
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_add_word #-}
+bignat_add_word mwa wa b s = do
+   case ioWord# (c_mpn_add_1 mwa wa (wordArraySize# wa) b) s of
+      (# s', c #) -> mwaWriteMostSignificant mwa c s'
+
+bignat_sub
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> (# State# RealWorld, Bool# #)
+{-# INLINE bignat_sub #-}
+bignat_sub mwa wa wb s =
+   case ioWord# (c_mpn_sub mwa wa (wordArraySize# wa) wb (wordArraySize# wb)) s of
+      (# s', 1## #) -> (# s', 0# #) -- underflow
+      (# s', _   #) -> (# s', 1# #) -- no underflow
+
+bignat_sub_word
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> (# State# RealWorld, Bool# #)
+{-# INLINE bignat_sub_word #-}
+bignat_sub_word mwa wa b s =
+   case ioWord# (c_mpn_sub_1 mwa wa (wordArraySize# wa) b) s of
+      (# s', 1## #) -> (# s', 0# #) -- underflow
+      (# s', _   #) -> (# s', 1# #) -- no underflow
+
+bignat_mul
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_mul #-}
+bignat_mul mwa wa wb s = do
+   case ioWord# (c_mpn_mul mwa wa (wordArraySize# wa) wb (wordArraySize# wb)) s of
+      (# s', _msl #) -> s' -- we don't care about the most-significant
+                           -- limb. The caller shrink the mwa if
+                           -- necessary anyway.
+
+bignat_mul_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_mul_word #-}
+bignat_mul_word mwa wa b s =
+   case ioWord# (c_mpn_mul_1 mwa wa (wordArraySize# wa) b) s of
+      (# s', c #) -> mwaWriteMostSignificant mwa c s'
+
+bignat_popcount :: WordArray# -> Word#
+{-# INLINE bignat_popcount #-}
+bignat_popcount wa = c_mpn_popcount wa (wordArraySize# wa)
+
+
+bignat_shiftl
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_shiftl #-}
+bignat_shiftl mwa wa n s =
+   case ioWord# (c_mpn_lshift mwa wa (wordArraySize# wa) n) s of
+      (# s', _msl #) -> s' -- we don't care about the most-significant
+                           -- limb. The caller shrink the mwa if
+                           -- necessary anyway.
+
+bignat_shiftr
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_shiftr #-}
+bignat_shiftr mwa wa n s =
+   case ioWord# (c_mpn_rshift mwa wa (wordArraySize# wa) n) s of
+      (# s', _msl #) -> s' -- we don't care about the most-significant
+                           -- limb. The caller shrink the mwa if
+                           -- necessary anyway.
+
+bignat_or
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_or #-}
+bignat_or mwa wa wb s1
+   | isTrue# (szA >=# szB) = go wa szA wb szB s1
+   | True                  = go wb szB wa szA s1
+   where
+      !szA = wordArraySize# wa
+      !szB = wordArraySize# wb
+      -- nx >= ny
+      go wx nx wy ny s = case ioVoid (c_mpn_ior_n mwa wx wy ny) s of
+         s' -> mwaArrayCopy# mwa ny wx ny (nx -# ny) s'
+
+bignat_xor
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_xor #-}
+bignat_xor mwa wa wb s1
+   | isTrue# (szA >=# szB) = go wa szA wb szB s1
+   | True                  = go wb szB wa szA s1
+   where
+      !szA = wordArraySize# wa
+      !szB = wordArraySize# wb
+      -- nx >= ny
+      go wx nx wy ny s = case ioVoid (c_mpn_xor_n mwa wx wy ny) s of
+         s' -> mwaArrayCopy# mwa ny wx ny (nx -# ny) s'
+
+bignat_and
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_and #-}
+bignat_and mwa wa wb s = ioVoid (c_mpn_and_n mwa wa wb sz) s
+   where
+      !szA = wordArraySize# wa
+      !szB = wordArraySize# wb
+      !sz  = minI# szA szB
+
+bignat_and_not
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+{-# INLINE bignat_and_not #-}
+bignat_and_not mwa wa wb s =
+   case ioVoid (c_mpn_andn_n mwa wa wb n) s of
+      s' -> mwaArrayCopy# mwa szB wa szB (szA -# szB) s'
+   where
+      !szA = wordArraySize# wa
+      !szB = wordArraySize# wb
+      !n   = minI# szA szB
+
+bignat_quotrem
+   :: MutableWordArray# RealWorld
+   -> MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quotrem mwq mwr wa wb s =
+   ioVoid (c_mpn_tdiv_qr mwq mwr 0# wa szA wb szB) s
+   where
+      szA = wordArraySize# wa
+      szB = wordArraySize# wb
+
+bignat_quot
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quot mwq wa wb s =
+   ioVoid (c_mpn_tdiv_q mwq wa szA wb szB) s
+   where
+      szA = wordArraySize# wa
+      szB = wordArraySize# wb
+
+bignat_rem
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_rem mwr wa wb s =
+   ioVoid (c_mpn_tdiv_r mwr wa szA wb szB) s
+   where
+      szA = wordArraySize# wa
+      szB = wordArraySize# wb
+
+bignat_quotrem_word
+   :: MutableWordArray# RealWorld -- ^ Quotient
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> (# State# RealWorld, Word# #)
+bignat_quotrem_word mwq wa b s =
+   ioWord# (c_mpn_divrem_1 mwq 0# wa szA b) s
+   where
+      szA = wordArraySize# wa
+
+bignat_quot_word
+   :: MutableWordArray# RealWorld -- ^ Quotient
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quot_word mwq wa b s =
+   case bignat_quotrem_word mwq wa b s of
+      (# s', _ #) -> s'
+
+bignat_rem_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+bignat_rem_word wa b =
+   c_mpn_mod_1 wa (wordArraySize# wa) b
+
+
+bignat_gcd
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_gcd mwr wa wb s =
+   -- wa > wb
+   case ioInt# (c_mpn_gcd# mwr wa (wordArraySize# wa) wb (wordArraySize# wb)) s of
+      (# s', sz #) -> mwaSetSize# mwr (narrowGmpSize# sz) s'
+
+bignat_gcd_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+bignat_gcd_word wa b = c_mpn_gcd_1# wa (wordArraySize# wa) b
+
+bignat_gcd_word_word
+   :: Word#
+   -> Word#
+   -> Word#
+bignat_gcd_word_word = integer_gmp_gcd_word
+
+
+bignat_encode_double :: WordArray# -> Int# -> Double#
+bignat_encode_double wa e = c_mpn_get_d wa (wordArraySize# wa) e
+
+bignat_shiftr_neg
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_shiftr_neg mwa wa n s =
+   ioVoid (c_mpn_rshift_2c mwa wa (wordArraySize# wa) n) s
+
+bignat_powmod_word
+   :: WordArray#
+   -> WordArray#
+   -> Word#
+   -> Word#
+bignat_powmod_word b e m =
+   integer_gmp_powm1# b (wordArraySize# b) e (wordArraySize# e) m
+
+bignat_powmod_words
+   :: Word#
+   -> Word#
+   -> Word#
+   -> Word#
+bignat_powmod_words = integer_gmp_powm_word
+
+bignat_powmod
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_powmod r b e m s = sbignat_powmod r (wordArraySize# b) b e m s
+
+integer_powmod
+   :: Integer
+   -> Natural
+   -> Natural
+   -> Natural
+integer_powmod b e m = naturalFromBigNat# (withNewWordArray# szm io)
+   where
+      !be = naturalToBigNat# e
+      !bm = naturalToBigNat# m
+      !(# sb, bb #) = integerToBigNatSign# b
+      !szb = bigNatSize# bb
+      !szm = bigNatSize# bm
+      !ssb = case sb of -- signed size of b
+               0# -> szb
+               _  -> negateInt# szb
+
+      io r s = sbignat_powmod r ssb bb be bm s
+
+
+sbignat_powmod
+   :: MutableWordArray# RealWorld
+   -> Int#
+   -> WordArray#
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+sbignat_powmod r b_signed_size b e m s =
+   case ioInt# (integer_gmp_powm# r b b_signed_size e (wordArraySize# e) m (wordArraySize# m)) s of
+      (# s', n #) -> mwaSetSize# r (narrowGmpSize# n) s'
+
+integer_gcde
+   :: Integer
+   -> Integer
+   -> (# Integer, Integer, Integer #)
+integer_gcde a b = case runRW# io of (# _, a #) -> a
+   where
+      !(# sa, ba #) = integerToBigNatSign# a
+      !(# sb, bb #) = integerToBigNatSign# b
+      !sza          = bigNatSize# ba
+      !szb          = bigNatSize# bb
+      -- signed sizes of a and b
+      !ssa          = case sa of
+                           0# -> sza
+                           _  -> negateInt# sza
+      !ssb          = case sb of
+                        0# -> szb
+                        _  -> negateInt# szb
+
+      -- gcd(a,b) < min(a,b)
+      !g_init_sz = minI# sza szb
+
+      -- According to https://gmplib.org/manual/Number-Theoretic-Functions.html#index-mpz_005fgcdext
+      -- a*x + b*y = g
+      -- abs(x) < abs(b) / (2 g) < abs(b)
+      -- abs(y) < abs(a) / (2 g) < abs(a)
+      !x_init_sz = szb
+      !y_init_sz = sza
+
+      io s =
+         -- allocate output arrays
+         case newWordArray# g_init_sz s     of { (# s, mbg #) ->
+         case newWordArray# x_init_sz s     of { (# s, mbx #) ->
+         case newWordArray# y_init_sz s     of { (# s, mby #) ->
+         -- allocate space to return sizes (3x4 = 12)
+         case newPinnedByteArray# 12# s     of { (# s, mszs #) ->
+         case unsafeFreezeByteArray# mszs s of { (# s, szs #) ->
+         let !ssx_ptr = byteArrayContents# szs in
+         let !ssy_ptr = ssx_ptr `plusAddr#` 4# in
+         let !sg_ptr  = ssy_ptr `plusAddr#` 4# in
+         -- call GMP
+         case ioVoid (integer_gmp_gcdext# mbx ssx_ptr mby ssy_ptr mbg sg_ptr ba ssa bb ssb) s of { s ->
+         -- read sizes
+         case readInt32OffAddr# ssx_ptr 0# s of { (# s, ssx #) ->
+         case readInt32OffAddr# ssy_ptr 0# s of { (# s, ssy #) ->
+         case readInt32OffAddr# sg_ptr  0# s of { (# s, sg #) ->
+         case touch# szs s of { s ->
+         -- shrink x, y and g to their actual sizes and freeze them
+         let !sx = absI# (int32ToInt# ssx) in
+         let !sy = absI# (int32ToInt# ssy) in
+         case mwaSetSize# mbx sx s of { s ->
+         case mwaSetSize# mby sy s of { s ->
+         case mwaSetSize# mbg (int32ToInt# sg) s of { s ->
+
+         -- return x, y and g as Integer
+         case unsafeFreezeByteArray# mbx s of { (# s, bx #) ->
+         case unsafeFreezeByteArray# mby s of { (# s, by #) ->
+         case unsafeFreezeByteArray# mbg s of { (# s, bg #) ->
+
+         (# s, (# integerFromBigNat# bg
+               ,  integerFromBigNatSign# (int32ToInt# ssx <# 0#) bx
+               ,  integerFromBigNatSign# (int32ToInt# ssy <# 0#) by #) #)
+         }}}}}}}}}}}}}}}}
+
+
+
+integer_recip_mod
+   :: Integer
+   -> Natural
+   -> (# Natural | () #)
+integer_recip_mod x m =
+   let
+      !(#  sign_x, bx #) = integerToBigNatSign# x
+      !bm = naturalToBigNat# m
+      !br = sbignat_recip_mod sign_x bx bm
+   in if isTrue# (bigNatIsZero# br)
+         then (# | () #)
+         else (# naturalFromBigNat# br | #)
+
+
+-- | Return 0 for invalid inputs
+sbignat_recip_mod :: Int# -> BigNat# -> BigNat# -> BigNat#
+sbignat_recip_mod sign_x x m = withNewWordArray# szm io
+  where
+    io r s = case ioInt# (integer_gmp_invert# r x ssx m szm) s of
+               (# s, rn #) -> mwaSetSize# r (narrowGmpSize# rn) s
+    !szx  = bigNatSize# x
+    !szm  = bigNatSize# m
+    !ssx = case sign_x of -- signed size of x
+            0# -> szx
+            _  -> negateInt# szx
+
+----------------------------------------------------------------------
+-- FFI ccall imports
+
+foreign import ccall unsafe "integer_gmp_gcd_word"
+  integer_gmp_gcd_word :: GmpLimb# -> GmpLimb# -> GmpLimb#
+
+foreign import ccall unsafe "integer_gmp_mpn_gcd_1"
+  c_mpn_gcd_1# :: ByteArray# -> GmpSize# -> GmpLimb# -> GmpLimb#
+
+foreign import ccall unsafe "integer_gmp_mpn_gcd"
+  c_mpn_gcd# :: MutableByteArray# s -> ByteArray# -> GmpSize#
+                -> ByteArray# -> GmpSize# -> IO GmpSize
+
+foreign import ccall unsafe "integer_gmp_gcdext" integer_gmp_gcdext#
+  :: MutableByteArray# s -> Addr#
+  -> MutableByteArray# s -> Addr#
+  -> MutableByteArray# s -> Addr#
+  -> ByteArray# -> GmpSize#
+  -> ByteArray# -> GmpSize#
+  -> IO ()
+
+foreign import ccall unsafe "integer_gmp_invert"
+  integer_gmp_invert# :: MutableByteArray# RealWorld
+                         -> ByteArray# -> GmpSize#
+                         -> ByteArray# -> GmpSize# -> IO GmpSize
+
+-- mp_limb_t mpn_add_1 (mp_limb_t *rp, const mp_limb_t *s1p, mp_size_t n,
+--                      mp_limb_t s2limb)
+foreign import ccall unsafe "gmp.h __gmpn_add_1"
+  c_mpn_add_1 :: MutableByteArray# s -> ByteArray# -> GmpSize# -> GmpLimb#
+                 -> IO GmpLimb
+
+-- mp_limb_t mpn_sub_1 (mp_limb_t *rp, const mp_limb_t *s1p, mp_size_t n,
+--                      mp_limb_t s2limb)
+foreign import ccall unsafe "gmp.h __gmpn_sub_1"
+  c_mpn_sub_1 :: MutableByteArray# s -> ByteArray# -> GmpSize# -> GmpLimb#
+                 -> IO GmpLimb
+
+-- mp_limb_t mpn_mul_1 (mp_limb_t *rp, const mp_limb_t *s1p, mp_size_t n,
+--                      mp_limb_t s2limb)
+foreign import ccall unsafe "gmp.h __gmpn_mul_1"
+  c_mpn_mul_1 :: MutableByteArray# s -> ByteArray# -> GmpSize# -> GmpLimb#
+                 -> IO GmpLimb
+
+-- mp_limb_t mpn_add (mp_limb_t *rp, const mp_limb_t *s1p, mp_size_t s1n,
+--                    const mp_limb_t *s2p, mp_size_t s2n)
+foreign import ccall unsafe "gmp.h __gmpn_add"
+  c_mpn_add :: MutableByteArray# s -> ByteArray# -> GmpSize#
+               -> ByteArray# -> GmpSize# -> IO GmpLimb
+
+-- mp_limb_t mpn_sub (mp_limb_t *rp, const mp_limb_t *s1p, mp_size_t s1n,
+--                    const mp_limb_t *s2p, mp_size_t s2n)
+foreign import ccall unsafe "gmp.h __gmpn_sub"
+  c_mpn_sub :: MutableByteArray# s -> ByteArray# -> GmpSize# -> ByteArray#
+               -> GmpSize# -> IO GmpLimb
+
+-- mp_limb_t mpn_mul (mp_limb_t *rp, const mp_limb_t *s1p, mp_size_t s1n,
+--                    const mp_limb_t *s2p, mp_size_t s2n)
+foreign import ccall unsafe "gmp.h __gmpn_mul"
+  c_mpn_mul :: MutableByteArray# s -> ByteArray# -> GmpSize# -> ByteArray#
+               -> GmpSize# -> IO GmpLimb
+
+-- int mpn_cmp (const mp_limb_t *s1p, const mp_limb_t *s2p, mp_size_t n)
+foreign import ccall unsafe "gmp.h __gmpn_cmp"
+  c_mpn_cmp :: ByteArray# -> ByteArray# -> GmpSize# -> Int#
+
+-- void mpn_tdiv_qr (mp_limb_t *qp, mp_limb_t *rp, mp_size_t qxn,
+--                   const mp_limb_t *np, mp_size_t nn,
+--                   const mp_limb_t *dp, mp_size_t dn)
+foreign import ccall unsafe "gmp.h __gmpn_tdiv_qr"
+  c_mpn_tdiv_qr :: MutableByteArray# s -> MutableByteArray# s -> GmpSize#
+                   -> ByteArray# -> GmpSize# -> ByteArray# -> GmpSize# -> IO ()
+
+foreign import ccall unsafe "integer_gmp_mpn_tdiv_q"
+  c_mpn_tdiv_q :: MutableByteArray# s -> ByteArray# -> GmpSize# -> ByteArray#
+                  -> GmpSize# -> IO ()
+
+foreign import ccall unsafe "integer_gmp_mpn_tdiv_r"
+  c_mpn_tdiv_r :: MutableByteArray# s -> ByteArray# -> GmpSize# -> ByteArray#
+                  -> GmpSize# -> IO ()
+
+-- mp_limb_t mpn_divrem_1 (mp_limb_t *r1p, mp_size_t qxn, mp_limb_t *s2p,
+--                         mp_size_t s2n, mp_limb_t s3limb)
+foreign import ccall unsafe "gmp.h __gmpn_divrem_1"
+  c_mpn_divrem_1 :: MutableByteArray# s -> GmpSize# -> ByteArray# -> GmpSize#
+                    -> GmpLimb# -> IO GmpLimb
+
+-- mp_limb_t mpn_mod_1 (const mp_limb_t *s1p, mp_size_t s1n, mp_limb_t s2limb)
+foreign import ccall unsafe "gmp.h __gmpn_mod_1"
+  c_mpn_mod_1 :: ByteArray# -> GmpSize# -> GmpLimb# -> GmpLimb#
+
+-- mp_limb_t integer_gmp_mpn_rshift (mp_limb_t rp[], const mp_limb_t sp[],
+--                                   mp_size_t sn, mp_bitcnt_t count)
+foreign import ccall unsafe "integer_gmp_mpn_rshift"
+  c_mpn_rshift :: MutableByteArray# s -> ByteArray# -> GmpSize# -> Word#
+                  -> IO GmpLimb
+
+-- mp_limb_t integer_gmp_mpn_rshift (mp_limb_t rp[], const mp_limb_t sp[],
+--                                   mp_size_t sn, mp_bitcnt_t count)
+foreign import ccall unsafe "integer_gmp_mpn_rshift_2c"
+  c_mpn_rshift_2c :: MutableByteArray# s -> ByteArray# -> GmpSize# -> Word#
+                     -> IO GmpLimb
+
+-- mp_limb_t integer_gmp_mpn_lshift (mp_limb_t rp[], const mp_limb_t sp[],
+--                                   mp_size_t sn, mp_bitcnt_t count)
+foreign import ccall unsafe "integer_gmp_mpn_lshift"
+  c_mpn_lshift :: MutableByteArray# s -> ByteArray# -> GmpSize# -> Word#
+                  -> IO GmpLimb
+
+-- void mpn_and_n (mp_limb_t *rp, const mp_limb_t *s1p, const mp_limb_t *s2p,
+--                 mp_size_t n)
+foreign import ccall unsafe "integer_gmp_mpn_and_n"
+  c_mpn_and_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> GmpSize#
+                 -> IO ()
+
+-- void mpn_andn_n (mp_limb_t *rp, const mp_limb_t *s1p, const mp_limb_t *s2p,
+--                  mp_size_t n)
+foreign import ccall unsafe "integer_gmp_mpn_andn_n"
+  c_mpn_andn_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> GmpSize#
+                  -> IO ()
+
+-- void mpn_ior_n (mp_limb_t *rp, const mp_limb_t *s1p, const mp_limb_t *s2p,
+--                 mp_size_t n)
+foreign import ccall unsafe "integer_gmp_mpn_ior_n"
+  c_mpn_ior_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> GmpSize#
+                 -> IO ()
+
+-- void mpn_xor_n (mp_limb_t *rp, const mp_limb_t *s1p, const mp_limb_t *s2p,
+--                 mp_size_t n)
+foreign import ccall unsafe "integer_gmp_mpn_xor_n"
+  c_mpn_xor_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> GmpSize#
+                 -> IO ()
+
+-- mp_bitcnt_t mpn_popcount (const mp_limb_t *s1p, mp_size_t n)
+foreign import ccall unsafe "gmp.h __gmpn_popcount"
+  c_mpn_popcount :: ByteArray# -> GmpSize# -> Word#
+
+-- double integer_gmp_mpn_get_d (const mp_limb_t sp[], const mp_size_t sn)
+foreign import ccall unsafe "integer_gmp_mpn_get_d"
+  c_mpn_get_d :: ByteArray# -> GmpSize# -> Int# -> Double#
+
+foreign import ccall unsafe "integer_gmp_powm"
+  integer_gmp_powm# :: MutableByteArray# RealWorld
+                       -> ByteArray# -> GmpSize# -> ByteArray# -> GmpSize#
+                       -> ByteArray# -> GmpSize# -> IO GmpSize
+
+foreign import ccall unsafe "integer_gmp_powm_word"
+  integer_gmp_powm_word :: GmpLimb# -> GmpLimb# -> GmpLimb# -> GmpLimb#
+
+foreign import ccall unsafe "integer_gmp_powm1"
+  integer_gmp_powm1# :: ByteArray# -> GmpSize# -> ByteArray# -> GmpSize#
+                        -> GmpLimb# -> GmpLimb#
diff --git a/src/GHC/Internal/Bignum/Backend/Native.hs b/src/GHC/Internal/Bignum/Backend/Native.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Backend/Native.hs
@@ -0,0 +1,786 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE NegativeLiterals #-}
+{-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE BinaryLiterals #-}
+{-# OPTIONS_GHC -Wno-name-shadowing #-}
+
+module GHC.Internal.Bignum.Backend.Native where
+
+#include "MachDeps.h"
+#include "WordSize.h"
+
+#if defined(BIGNUM_NATIVE) || defined(BIGNUM_CHECK) || defined(BIGNUM_FFI)
+import {-# SOURCE #-} GHC.Internal.Bignum.BigNat
+import {-# SOURCE #-} GHC.Internal.Bignum.Natural
+import {-# SOURCE #-} GHC.Internal.Bignum.Integer
+#else
+import GHC.Internal.Bignum.BigNat
+import GHC.Internal.Bignum.Natural
+import GHC.Internal.Bignum.Integer
+#endif
+import GHC.Internal.Bignum.WordArray
+import GHC.Internal.Bignum.Primitives
+import GHC.Internal.Prim
+import GHC.Internal.Types
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+-- (This module uses the empty tuple () and string literals.)
+import GHC.Internal.Tuple ()
+import GHC.Internal.CString ()
+
+default ()
+
+-- | ghc-bignum backend name
+backendName :: [Char]
+backendName = "native"
+
+
+count_words_bits :: Word# -> (# Word#, Word# #)
+count_words_bits n = (# nw, nb #)
+   where
+      nw = n `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#
+      nb = n `and#` WORD_SIZE_BITS_MASK##
+
+count_words_bits_int :: Word# -> (# Int#, Int# #)
+count_words_bits_int n = case count_words_bits n of
+   (# nw, nb #) -> (# word2Int# nw, word2Int# nb #)
+
+bignat_compare :: WordArray# -> WordArray# -> Int#
+bignat_compare wa wb = go (sz -# 1#)
+   where
+      sz = wordArraySize# wa
+      go i
+         | isTrue# (i <# 0#) = 0#
+         | a <- indexWordArray# wa i
+         , b <- indexWordArray# wb i
+         = if | isTrue# (a `eqWord#` b) -> go (i -# 1#)
+              | isTrue# (a `gtWord#` b) -> 1#
+              | True                    -> -1#
+
+bignat_add
+   :: MutableWordArray# s -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# s
+   -> State# s
+bignat_add mwa wa wb = addABc 0# 0##
+   where
+      !szA     = wordArraySize# wa
+      !szB     = wordArraySize# wb
+      !szMin   = minI# szA szB
+
+      -- we have four cases:
+      -- 1) we have a digit in A and in B + a potential carry
+      --    => perform triple addition
+      --    => result in (carry,word)
+      -- 2) we have a digit only in A or B and a carry
+      --    => perform double addition from a single array
+      --    => result in (carry,word)
+      -- 3) we have a digit only in A or B and no carry
+      --    => perform array copy and shrink the array
+      -- 4) We only have a potential carry
+      --    => write the carry or shrink the array
+
+      addABc i carry s
+         | isTrue# (i <# szMin) =
+            let
+               !(# carry', r #) = plusWord3#
+                                    (indexWordArray# wa i)
+                                    (indexWordArray# wb i)
+                                    carry
+            in case mwaWrite# mwa i r s of
+               s' -> addABc (i +# 1#) carry' s'
+
+         | isTrue# ((i ==# szA) &&# (i ==# szB))
+         = mwaWriteOrShrink mwa carry i s
+
+         | isTrue# (i ==# szA)
+         = addAoBc wb i carry s
+
+         | True
+         = addAoBc wa i carry s
+
+      addAoBc wab i carry s
+         | isTrue# (i ==# wordArraySize# wab)
+         = mwaWriteOrShrink mwa carry i s
+
+         | 0## <- carry
+         = -- copy the remaining words and remove the word allocated for the
+           -- potential carry
+           case mwaArrayCopy# mwa i wab i (wordArraySize# wab -# i) s of
+            s' -> mwaShrink# mwa 1# s'
+
+         | True
+         = let !(# carry', r #) = plusWord2# (indexWordArray# wab i) carry
+           in case mwaWrite# mwa i r s of
+               s' -> addAoBc wab (i +# 1#) carry' s'
+
+bignat_add_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_add_word mwa wa b s = mwaInitArrayPlusWord mwa wa b s
+
+bignat_sub_word
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> (# State# RealWorld, Bool# #)
+bignat_sub_word mwa wa b = go b 0#
+   where
+      !sz = wordArraySize# wa
+      go carry i s
+         | isTrue# (i >=# sz)
+         = (# s, carry `eqWord#` 0## #)
+
+         | 0## <- carry
+         = case mwaArrayCopy# mwa i wa i (sz -# i) s of
+            s' -> (# s', 1# #) -- no underflow
+
+         | True
+         = case subWordC# (indexWordArray# wa i) carry of
+            (# 0##, 0# #)
+               | isTrue# (i ==# sz) -> case mwaShrink# mwa 1# s of
+                                          s' -> (# s', 1# #) -- no underflow
+
+            (# l  , c  #) -> case mwaWrite# mwa i l s of
+                              s1 -> go (int2Word# c) (i +# 1#) s1
+
+bignat_mul_word
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> Word#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_mul_word mwa wa b = go 0# 0##
+   where
+      !szA = wordArraySize# wa
+      go i carry s
+         | isTrue# (i ==# szA) = mwaWriteOrShrink mwa carry i s
+         | True =
+            let
+               ai               = indexWordArray# wa i
+               !(# carry', r #) = plusWord12# carry (timesWord2# ai b)
+            in case mwaWrite# mwa i r s of
+                  s' -> go (i +# 1#) carry' s'
+
+
+bignat_mul
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_mul mwa wa wb s1 =
+   -- initialize the resulting WordArray
+   case mwaFill# mwa 0## 0## (int2Word# sz) s1 of
+      s' -> mulEachB ctzB s' -- loop on b Words
+   where
+      !szA = wordArraySize# wa
+      !szB = wordArraySize# wb
+      !sz  = szA +# szB
+
+      !ctzA = word2Int# (bigNatCtzWord# wa)
+      !ctzB = word2Int# (bigNatCtzWord# wb)
+
+      -- multiply a single bj Word# to the whole wa WordArray
+      mul mwa wa bj j i carry s
+         | isTrue# (i ==# wordArraySize# wa)
+         -- write the carry
+         = mwaAddInplaceWord# mwa (i +# j) carry s
+
+         | True = let
+                     ai           = indexWordArray# wa i
+                     !(# c',r' #) = timesWord2# ai bj
+                     !(# c'',r #) = plusWord2# r' carry
+                     carry'       = plusWord# c' c''
+                  in case mwaAddInplaceWord# mwa (i +# j) r s of
+                        s' -> mul mwa wa bj j (i +# 1#) carry' s'
+
+      -- for each bj in wb, call `mul bj wa`
+      mulEachB i s
+         | isTrue# (i ==# szB) = s
+         | True = case indexWordArray# wb i of
+            -- detect bj == 0## and skip the loop
+            0## -> mulEachB (i +# 1#) s
+            bi  -> case mul mwa wa bi i ctzA 0## s of
+                     s' -> mulEachB (i +# 1#) s'
+
+bignat_sub
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> (# State# RealWorld, Bool# #)
+bignat_sub mwa wa wb s =
+   -- initialize the resulting WordArray
+   -- Note: we could avoid the copy by subtracting the first non-zero
+   -- less-significant word of b...
+   case mwaArrayCopy# mwa 0# wa 0# (wordArraySize# wa) s of
+      s' -> mwaSubInplaceArray mwa 0# wb s'
+
+bignat_popcount :: WordArray# -> Word#
+bignat_popcount wa = go 0# 0##
+   where
+      !sz = wordArraySize# wa
+      go i c
+         | isTrue# (i ==# sz) = c
+         | True               = go (i +# 1#) (c `plusWord#` popCnt# (indexWordArray# wa i))
+
+bignat_shiftl
+   :: MutableWordArray# s
+   -> WordArray#
+   -> Word#
+   -> State# s
+   -> State# s
+bignat_shiftl mwa wa n s1 =
+   -- set the lower words to 0
+   case mwaFill# mwa 0## 0## (int2Word# nw) s1 of
+      s2 -> if
+            | 0# <- nb -> mwaArrayCopy# mwa nw wa 0# szA s2
+            | True     -> mwaBitShift 0# 0## s2
+   where
+      !szA          = wordArraySize# wa
+      !(# nw, nb #) = count_words_bits_int n
+      !sh           = WORD_SIZE_IN_BITS# -# nb
+
+      -- Bit granularity (c is the carry from the previous shift)
+      mwaBitShift i c s
+         -- write the carry
+         | isTrue# (i ==# szA)
+         = mwaWriteOrShrink mwa c (i +# nw) s
+
+         | True =
+            let
+               !ai = indexWordArray# wa i
+               !v  = c `or#` (ai `uncheckedShiftL#` nb)
+               !c' = ai `uncheckedShiftRL#` sh
+            in case mwaWrite# mwa (i +# nw) v s of
+                  s' -> mwaBitShift (i +# 1#) c' s'
+
+
+bignat_shiftr
+   :: MutableWordArray# s
+   -> WordArray#
+   -> Word#
+   -> State# s
+   -> State# s
+bignat_shiftr mwa wa n s1
+   | isTrue# (nb ==# 0#) = mwaArrayCopy# mwa 0# wa nw sz s1
+   | True                = mwaBitShift (sz -# 1#) 0## s1
+   where
+      !szA          = wordArraySize# wa
+      !(# nw, nb #) = count_words_bits_int n
+      !sz           = szA -# nw
+      !sh           = WORD_SIZE_IN_BITS# -# nb
+
+      -- Bit granularity (c is the carry from the previous shift)
+      mwaBitShift i c s
+         | isTrue# (i <# 0#) = s
+         | True =
+            let
+               !ai = indexWordArray# wa (i +# nw)
+               !v  = c `or#` (ai `uncheckedShiftRL#` nb)
+               !c' = ai `uncheckedShiftL#` sh
+            in case mwaWrite# mwa i v s of
+                  s' -> mwaBitShift (i -# 1#) c' s'
+
+bignat_shiftr_neg
+   :: MutableWordArray# s
+   -> WordArray#
+   -> Word#
+   -> State# s
+   -> State# s
+bignat_shiftr_neg mwa wa n s1
+   -- initialize higher limb of mwa
+   = case mwaSize# mwa s1 of
+      (# s2, sz_mwa #) -> case mwaWrite# mwa (sz_mwa -# 1#) 0## s2 of
+        s3 -> case bignat_shiftr mwa wa n s3 of
+           s4 -> if nz_shifted_out
+                    -- round if non-zero bits were shifted out
+                    then mwaAddInplaceWord# mwa 0# 1## s4
+                    else s4
+   where
+      !(# nw, nb #) = count_words_bits_int n
+
+      -- non-zero bits are shifted out?
+      nz_shifted_out
+         -- test nb bits
+         | isTrue# (
+            (nb /=# 0#)
+            &&# (indexWordArray# wa nw `uncheckedShiftL#`
+                  (WORD_SIZE_IN_BITS# -# nb) `neWord#` 0##))
+         = True
+         -- test nw words
+         | True
+         = let
+            go j
+               | isTrue# (j ==# nw)                           = False
+               | isTrue# (indexWordArray# wa j `neWord#` 0##) = True
+               | True                                         = go (j +# 1#)
+           in go 0#
+
+
+bignat_or
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_or mwa wa wb s1
+   | isTrue# (szA >=# szB) = go wa szA wb szB s1
+   | True                  = go wb szB wa szA s1
+   where
+      !szA = wordArraySize# wa
+      !szB = wordArraySize# wb
+      -- nx >= ny
+      go wx nx wy ny s =
+         case mwaInitArrayBinOp mwa wx wy or# s of
+            s' -> mwaArrayCopy# mwa ny wx ny (nx -# ny) s'
+
+bignat_xor
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_xor mwa wa wb s1
+   | isTrue# (szA >=# szB) = go wa szA wb szB s1
+   | True                  = go wb szB wa szA s1
+   where
+      !szA = wordArraySize# wa
+      !szB = wordArraySize# wb
+      -- nx >= ny
+      go wx nx wy ny s =
+         case mwaInitArrayBinOp mwa wx wy xor# s of
+            s' -> mwaArrayCopy# mwa ny wx ny (nx -# ny) s'
+
+bignat_and
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_and mwa wa wb s = mwaInitArrayBinOp mwa wa wb and# s
+
+bignat_and_not
+   :: MutableWordArray# RealWorld -- ^ Result
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_and_not mwa wa wb s =
+   case mwaInitArrayBinOp mwa wa wb (\x y -> x `and#` not# y) s of
+      s' -> mwaArrayCopy# mwa szB wa szB (szA -# szB) s'
+   where
+      !szA = wordArraySize# wa
+      !szB = wordArraySize# wb
+
+bignat_quotrem
+   :: MutableWordArray# s
+   -> MutableWordArray# s
+   -> WordArray#
+   -> WordArray#
+   -> State# s
+   -> State# s
+bignat_quotrem mwq mwr uwa uwb s0 =
+   -- Normalization consists in left-shifting bits in B and A so that the
+   -- most-significant bit of the most-significant word of B is 1. It makes
+   -- quotient prediction much more efficient as we only use the two most
+   -- significant words of A and the most significant word of B to make the
+   -- prediction.
+
+   -- we will left-shift A and B of "clzb" bits for normalization
+   let !clzb  = clz# (indexWordArray# uwb (wordArraySize# uwb -# 1#))
+
+   -- we use a single array initially containing A (normalized) and
+   -- returning the remainder (normalized): mnwa (for "mutable normalized
+   -- wordarray A")
+   --
+   -- We allocate it here with an additionnal Word compared to A because
+   -- normalizing can left shift at most (N-1) bits (on N-bit arch).
+   in case newWordArray# (wordArraySize# uwa +# 1#) s0 of { (# s1, mnwa #) ->
+
+   -- normalized A in mnwa
+   let normalizeA s = case mwaWrite# mnwa (wordArraySize# uwa) 0## s of -- init potential carry
+                         s -> case bignat_shiftl mnwa uwa clzb s of     -- left shift
+                            s -> mwaTrimZeroes# mnwa s                  -- remove null carry if any
+   in case normalizeA s1 of { s2 ->
+
+   -- normalize B. We don't do it in a MutableWordArray because it will remain
+   -- constant during the whole computation.
+   let !nwb = bigNatShiftL# uwb clzb in
+
+   -- perform quotrem on normalized inputs
+   case bignat_quotrem_normalized mwq mnwa nwb s2 of { s3 ->
+
+   -- denormalize the remainder now stored in mnwa. We just have to right shift
+   -- of "clzb" bits. We copy the result into "mwr" array.
+   let denormalizeR s = case mwaTrimZeroes# mnwa s of
+                         s -> case unsafeFreezeByteArray# mnwa s of
+                            (# s, wr #) -> case mwaSetSize# mwr (wordArraySize# wr) s of
+                               s -> case bignat_shiftr mwr wr clzb s of
+                                 s -> mwaTrimZeroes# mwr s
+   in denormalizeR s3
+   }}}
+
+
+
+bignat_quot
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_quot mwq wa wb s =
+   -- allocate a temporary array for the remainder and call quotrem
+   case newWordArray# (wordArraySize# wb) s of
+      (# s, mwr #) -> bignat_quotrem mwq mwr wa wb s
+
+bignat_rem
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_rem mwr wa wb s =
+   -- allocate a temporary array for the quotient and call quotrem
+   -- (we could avoid allocating it as it is not used to compute the result but
+   -- it would require non trivial modification of bignat_quotrem)
+   case newWordArray# szQ s of
+      (# s, mwq #) -> bignat_quotrem mwq mwr wa wb s
+   where
+   szA = wordArraySize# wa
+   szB = wordArraySize# wb
+   szQ = 1# +# szA -# szB
+
+-- | Perform quotRem on normalized inputs:
+--    * highest bit of B is set
+--    * A is trimmed
+--    * A >= B
+--    * B > 1
+bignat_quotrem_normalized
+   :: MutableWordArray# s
+   -> MutableWordArray# s
+   -> WordArray#
+   -> State# s
+   -> State# s
+bignat_quotrem_normalized mwq mwa b s0 =
+
+   -- n is the size of B
+   let !n = wordArraySize# b
+
+   -- m+n is the size of A (m >= 0)
+   in case mwaSize# mwa s0 of { (# s1, szA #) ->
+   let !m = szA -# n in
+
+   -- Definitions:
+   --    MSW(x) is the most-significant word of x
+   --    MSB(x) the most-significant bit of x
+
+   -- We first compute MSW(Q).  Thanks to the normalization of B, MSW(Q) can
+   -- only be 0 or 1 so we only have to perform a prefix comparison to compute
+   -- MSW(Q).
+   --
+   --    Proof MSW(Q) < 2:
+   --       * MSB(MSW(B)) = 1 thanks to normalization.
+   --       * MSW(B) * MSW(Q) <= MSW(A) by definition
+   --       * suppose MSW(Q) >= 2:
+   --          MSW(B) * MSW(Q) >= MSW(B) << 1    { MSW(Q) >= 2              }
+   --                          >  MAX_WORD_VALUE { MSB(MSW(B)) = 1          }
+   --                          >  MSW(A)         { MSW(A) <= MAX_WORD_VALUE }
+   --          contradiction.
+   --
+   -- If A >= (B << m words)
+   --    then Qm = 1
+   --         A := A - (B << m words)
+   --    else Qm = 0
+   --         A unchanged
+   let computeQm s = case mwaTrimCompare m mwa b s of
+         (# s, LT #) -> (# s, 0## #)
+         (# s, _  #) -> (# s, 1## #)
+
+       updateQj j qj qjb s = case mwaWrite# mwq j qj s of -- write Qj
+               s | 0## <- qj -> s
+                 | True      -> case mwaSubInplaceArray mwa j qjb s of -- subtract (qjB << j words)
+                                 (# s, _ #) -> s
+
+       -- update the highest word of Q
+       updateQm s = case computeQm s of
+         (# s, qm #) -> updateQj m qm b s
+
+       -- the size of Q is szA+szB+1 BEFORE normalization. Normalization may add
+       -- an additional higher word to A.
+       --   * If A has an additional limb:
+       --      * MSW(A) < MSW(B). Because MSB(MSW(A)) can't be set (it would
+       --        mean that we shifted a whole word, which we didn't)
+       --      * hence MSW(Q) = 0 but we don't have to write it (and we mustn't)
+       --        because of the size of Q
+       --   * If A has no additional limb:
+       --      * We have to check if MSW(A) >= MSW(B) and to adjust A and MSW(Q)
+       --        accordingly
+       --
+       -- We detect if A has an additional limb by comparing the size of Q with m
+       updateQmMaybe s = case mwaSize# mwq s of
+         (# s, szQ #) | isTrue# (m <# szQ) -> updateQm s
+                      | True               -> s
+
+   in case updateQmMaybe s1 of { s2 ->
+
+
+   -- main loop: for j from (m-1) downto 0
+   --    We estimate a one Word quotient qj:
+   --       e1e0 <- a(n+j)a(n+j-1) `div` b(n-1)
+   --       qj | e1 == 0   = e0
+   --          | otherwise = maxBound
+   --    We loop until we find the real quotient:
+   --       while (A < ((qj*B) << j words)) qj--
+   --    We update A and Qj:
+   --       Qj := qj
+   --       A  := A - (qj*B << j words)
+
+   let bmsw = wordArrayLast# b -- most significant word of B
+
+       estimateQj j s =
+         case mwaRead# mwa (n +# j) s of
+           (# s, a1 #) -> case mwaRead# mwa (n +# j -# 1#) s of
+             (# s, a0 #) -> case quotRemWord3# (# a1, a0 #) bmsw of
+               (# (# 0##, qj #), _ #) -> (# s,              qj #)
+               (# (#   _,  _ #), _ #) -> (# s, WORD_MAXBOUND## #)
+
+       -- we perform the qj*B multiplication once and then we subtract B from
+       -- qj*B as much as needed until (qj'*B << j words) <= A
+       findRealQj j qj s = findRealQj' j qj (bigNatMulWord# b qj) s
+
+       findRealQj' j qj qjB s = case mwaTrimCompare j mwa qjB s of
+         (# s, LT #) -> findRealQj' j (qj `minusWord#` 1##) (bigNatSubUnsafe qjB b) s
+                                                            -- TODO: we could do the sub inplace to
+                                                            -- reduce allocations
+         (# s, _  #) -> (# s, qj, qjB #)
+
+       loop j s = case estimateQj j s of
+         (# s, qj #) -> case findRealQj j qj s of
+            (# s, qj, qjB #) -> case updateQj j qj qjB s of
+               s | 0# <- j -> s
+                 | True    -> loop (j -# 1#) s
+
+
+   in if | 0# <- m -> s2
+         | True    -> loop (m -# 1#) s2
+   }}
+
+bignat_quotrem_word
+   :: MutableWordArray# s -- ^ Quotient
+   -> WordArray#
+   -> Word#
+   -> State# s
+   -> (# State# s, Word# #)
+bignat_quotrem_word mwq wa b s = go (sz -# 1#) 0## s
+   where
+      sz = wordArraySize# wa
+      go i r s
+         | isTrue# (i <# 0#) = (# s, r #)
+         | True =
+            let
+               ai          = indexWordArray# wa i
+               !(# q,r' #) = quotRemWord2# r ai b
+            in case mwaWrite# mwq i q s of
+                  s' -> go (i -# 1#) r' s'
+
+bignat_quot_word
+   :: MutableWordArray# s -- ^ Quotient
+   -> WordArray#
+   -> Word#
+   -> State# s
+   -> State# s
+bignat_quot_word mwq wa b s = go (sz -# 1#) 0## s
+   where
+      sz = wordArraySize# wa
+      go i r s
+         | isTrue# (i <# 0#) = s
+         | True =
+            let
+               ai          = indexWordArray# wa i
+               !(# q,r' #) = quotRemWord2# r ai b
+            in case mwaWrite# mwq i q s of
+                  s' -> go (i -# 1#) r' s'
+
+bignat_rem_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+bignat_rem_word wa b = go (sz -# 1#) 0##
+   where
+      sz = wordArraySize# wa
+      go i r
+         | isTrue# (i <# 0#) = r
+         | True =
+            let
+               ai          = indexWordArray# wa i
+               !(# _,r' #) = quotRemWord2# r ai b
+            in go (i -# 1#) r'
+
+
+bignat_gcd
+   :: MutableWordArray# s
+   -> WordArray#
+   -> WordArray#
+   -> State# s
+   -> State# s
+bignat_gcd mwr = go
+   where
+      go wmax wmin s
+         | isTrue# (wordArraySize# wmin ==# 0#)
+         = mwaInitCopyShrink# mwr wmax s
+
+         | True
+         = let
+             wmax' = wmin
+             !wmin' = bigNatRem wmax wmin
+           in go wmax' wmin' s
+
+bignat_gcd_word
+   :: WordArray#
+   -> Word#
+   -> Word#
+bignat_gcd_word a b = bignat_gcd_word_word b (bigNatRemWord# a b)
+
+-- | This operation doesn't really belongs here, but GMP's one is much faster
+-- than this simple implementation (basic Euclid algorithm).
+--
+-- Ideally we should make an implementation as fast as GMP's one and put it into
+-- GHC.Internal.Bignum.Primitives.
+bignat_gcd_word_word
+   :: Word#
+   -> Word#
+   -> Word#
+bignat_gcd_word_word a 0## = a
+bignat_gcd_word_word a b   = bignat_gcd_word_word b (a `remWord#` b)
+
+bignat_encode_double :: WordArray# -> Int# -> Double#
+bignat_encode_double wa e0 = go 0.0## e0 0#
+   where
+      sz = wordArraySize# wa
+      go acc e i
+         | isTrue# (i >=# sz) = acc
+         | True
+         = go (acc +## wordEncodeDouble# (indexWordArray# wa i) e)
+              (e +# WORD_SIZE_IN_BITS#) -- FIXME: we assume that e doesn't overflow...
+              (i +# 1#)
+
+bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
+bignat_powmod_word b0 e0 m = go (naturalFromBigNat# b0) (naturalFromBigNat# e0) (naturalFromWord# 1##)
+   where
+      go !b e !r
+        | isTrue# (e `naturalTestBit#` 0##)
+        = go b' e' ((r `naturalMul` b) `naturalRem` m')
+
+        | naturalIsZero e
+        = naturalToWord# r
+
+        | True
+        = go b' e' r
+        where
+          b' = (b `naturalMul` b) `naturalRem` m'
+          m' = naturalFromWord# m
+          e' = e `naturalShiftR#` 1## -- slightly faster than "e `div` 2"
+
+bignat_powmod
+   :: MutableWordArray# RealWorld
+   -> WordArray#
+   -> WordArray#
+   -> WordArray#
+   -> State# RealWorld
+   -> State# RealWorld
+bignat_powmod r b0 e0 m s = mwaInitCopyShrink# r r' s
+   where
+      !r' = go (naturalFromBigNat# b0)
+               (naturalFromBigNat# e0)
+               (naturalFromWord# 1##)
+
+      go !b e !r
+        | isTrue# (e `naturalTestBit#` 0##)
+        = go b' e' ((r `naturalMul` b) `naturalRem` m')
+
+        | naturalIsZero e
+        = naturalToBigNat# r
+
+        | True
+        = go b' e' r
+        where
+          b' = (b `naturalMul` b) `naturalRem` m'
+          m' = naturalFromBigNat# m
+          e' = e `naturalShiftR#` 1## -- slightly faster than "e `div` 2"
+
+bignat_powmod_words
+   :: Word#
+   -> Word#
+   -> Word#
+   -> Word#
+bignat_powmod_words b e m =
+   bignat_powmod_word (wordArrayFromWord# b)
+                      (wordArrayFromWord# e)
+                      m
+
+
+integer_gcde
+   :: Integer
+   -> Integer
+   -> (# Integer, Integer, Integer #)
+integer_gcde a b = f (# a,integerOne,integerZero #) (# b,integerZero,integerOne #)
+  where
+    -- returned "g" must be positive
+    fix (# g, x, y #)
+       | integerIsNegative g = (# integerNegate g, integerNegate x, integerNegate y #)
+       | True                = (# g,x,y #)
+
+    f old@(# old_g, old_s, old_t #) new@(# g, s, t #)
+      | integerIsZero g = fix old
+      | True            = case integerQuotRem# old_g g of
+                              !(# q, r #) -> f new (# r , old_s `integerSub` (q `integerMul` s)
+                                                        , old_t `integerSub` (q `integerMul` t) #)
+
+integer_recip_mod
+   :: Integer
+   -> Natural
+   -> (# Natural | () #)
+integer_recip_mod x m =
+   let m' = integerFromNatural m
+   in case integer_gcde x m' of
+      (# g, a, _b #)
+         -- gcd(x,m) = ax+mb = 1
+         -- ==> ax - 1 = -mb
+         -- ==> ax     = 1 [m]
+         | g `integerEq` integerOne -> (# integerToNatural (a `integerMod` m') | #)
+                                       -- a `mod` m > 0 because m > 0
+         | True                     -> (# | () #)
+
+integer_powmod
+   :: Integer
+   -> Natural
+   -> Natural
+   -> Natural
+integer_powmod b0 e0 m = go b0 e0 integerOne
+   where
+      !m' = integerFromNatural m
+
+      go !b e !r
+        | isTrue# (e `naturalTestBit#` 0##)
+        = go b' e' ((r `integerMul` b) `integerMod` m')
+
+        | naturalIsZero e
+        = integerToNatural r -- r >= 0 by integerMod above
+
+        | True
+        = go b' e' r
+        where
+          b' = (b `integerMul` b) `integerRem` m'
+          e' = e `naturalShiftR#` 1##
diff --git a/src/GHC/Internal/Bignum/Backend/Selected.hs b/src/GHC/Internal/Bignum/Backend/Selected.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Backend/Selected.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+-- | Selected backend
+--
+-- We need this module in addition to GHC.Internal.Bignum.Backend to avoid module loops with
+-- Check backend.
+module GHC.Internal.Bignum.Backend.Selected
+   ( module Backend
+   )
+where
+
+#if defined(BIGNUM_NATIVE)
+import GHC.Internal.Bignum.Backend.Native as Backend
+
+#elif defined(BIGNUM_FFI)
+import GHC.Internal.Bignum.Backend.FFI as Backend
+
+#elif defined(BIGNUM_GMP)
+import GHC.Internal.Bignum.Backend.GMP as Backend
+
+#else
+#error Undefined BigNum backend. Use a flag to select it (e.g. gmp, native, ffi)`
+#endif
diff --git a/src/GHC/Internal/Bignum/BigNat.hs b/src/GHC/Internal/Bignum/BigNat.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/BigNat.hs
@@ -0,0 +1,1647 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE BinaryLiterals #-}
+{-# OPTIONS_GHC -Wno-name-shadowing #-}
+
+-- | Multi-precision natural
+module GHC.Internal.Bignum.BigNat where
+
+#include "MachDeps.h"
+#include "WordSize.h"
+
+import GHC.Internal.Prim
+import GHC.Internal.Types
+import GHC.Internal.Classes
+import GHC.Internal.Magic
+import GHC.Internal.Bignum.Primitives
+import GHC.Internal.Bignum.WordArray
+import GHC.Internal.Bignum.Backend
+
+default ()
+
+-- | A BigNat
+--
+-- Represented as an array of limbs (Word#) stored in little-endian order (Word#
+-- themselves use machine order).
+--
+-- Invariant (canonical representation): higher Word# is non-zero.
+--
+-- As a consequence, zero is represented with a WordArray# whose size is 0.
+type BigNat# = WordArray#
+   -- we use a type-alias instead of an unlifted newtype to make Integer/Natural
+   -- types easier to wire in the compiler
+
+-- | A lifted BigNat
+--
+-- Represented as an array of limbs (Word#) stored in little-endian order (Word#
+-- themselves use machine order).
+--
+-- Invariant (canonical representation): higher Word# is non-zero.
+--
+-- As a consequence, zero is represented with a WordArray# whose size is 0.
+data BigNat = BN# { unBigNat :: BigNat# }
+
+-- Note [Why (# #)?]
+-- ~~~~~~~~~~~~~~~~~
+--
+-- We can't have top-level BigNat# for now because they are unlifted ByteArray#
+-- (see #17521). So we use functions that take an empty argument (# #) that
+-- will be discarded at compile time.
+
+
+-- | Check that the BigNat is valid
+bigNatCheck# :: BigNat# -> Bool#
+bigNatCheck# bn
+   | 0#  <- bigNatSize# bn                         = 1#
+   -- check that size is a multiple of Word size
+   | r <- remInt# (sizeofByteArray# bn) WORD_SIZE_IN_BYTES#
+   , isTrue# (r /=# 0#)                            = 0#
+   -- check that most-significant limb isn't zero
+   | 0## <- bigNatIndex# bn (bigNatSize# bn -# 1#) = 0#
+   | True                                          = 1#
+
+-- | Check that the BigNat is valid
+bigNatCheck :: BigNat# -> Bool
+bigNatCheck bn = isTrue# (bigNatCheck# bn)
+
+-- | Number of words in the BigNat
+bigNatSize :: BigNat# -> Word
+bigNatSize bn = W# (int2Word# (bigNatSize# bn))
+
+-- | Number of words in the BigNat
+bigNatSize# :: BigNat# -> Int#
+bigNatSize# ba = wordArraySize# ba
+
+{-# NOINLINE bigNatZero #-}
+bigNatZero :: BigNat
+bigNatZero = BN# (withNewWordArray# 0# (\_ s -> s))
+
+{-# NOINLINE bigNatOne #-}
+bigNatOne :: BigNat
+bigNatOne = BN# (bigNatFromWord# 1##)
+
+-- | BigNat Zero
+bigNatZero# :: (# #) -> BigNat# -- cf Note [Why (# #)?]
+bigNatZero# _ = case bigNatZero of
+   BN# w -> w
+
+-- | BigNat one
+bigNatOne# :: (# #) -> BigNat# -- cf Note [Why (# #)?]
+bigNatOne# _ = case bigNatOne of
+   BN# w -> w
+
+raiseDivZero_BigNat :: (# #) -> BigNat#
+raiseDivZero_BigNat _ = case raiseDivZero of
+   !_ -> bigNatZero# (# #)
+   -- see Note [ghc-bignum exceptions] in GHC.Internal.Bignum.Primitives
+
+-- | Indicate if a bigNat is zero
+bigNatIsZero :: BigNat# -> Bool
+bigNatIsZero bn = isTrue# (bigNatIsZero# bn)
+
+-- | Indicate if a bigNat is zero
+bigNatIsZero# :: BigNat# -> Bool#
+bigNatIsZero# ba = wordArraySize# ba ==# 0#
+
+-- | Indicate if a bigNat is one
+bigNatIsOne :: BigNat# -> Bool
+bigNatIsOne bn = isTrue# (bigNatIsOne# bn)
+
+-- | Indicate if a bigNat is one
+bigNatIsOne# :: BigNat# -> Bool#
+bigNatIsOne# ba =
+   wordArraySize# ba ==# 1#
+   &&# indexWordArray# ba 0# `eqWord#` 1##
+
+-- | Indicate if a bigNat is two
+bigNatIsTwo :: BigNat# -> Bool
+bigNatIsTwo bn = isTrue# (bigNatIsTwo# bn)
+
+-- | Indicate if a bigNat is two
+bigNatIsTwo# :: BigNat# -> Bool#
+bigNatIsTwo# ba =
+   wordArraySize# ba ==# 1#
+   &&# indexWordArray# ba 0# `eqWord#` 2##
+
+-- | Indicate if the value is a power of two and which one
+bigNatIsPowerOf2# :: BigNat# -> (# (# #) | Word# #)
+bigNatIsPowerOf2# a
+   | bigNatIsZero a                      = (# (# #) | #)
+   | True =
+    let
+      msw  = bigNatIndex# a imax
+      sz   = bigNatSize# a
+      imax = sz -# 1#
+      checkAllZeroes i
+         | isTrue# (i <# 0#) = 1#
+         | True = case bigNatIndex# a i of
+                     0## -> checkAllZeroes (i -# 1#)
+                     _   -> 0#
+    in case wordIsPowerOf2# msw of
+               (# (# #) | #) -> (# (# #) | #)
+               (# | c  #) -> case checkAllZeroes (imax -# 1#) of
+                  0# -> (# (# #) | #)
+                  _  -> (# | c `plusWord#`
+                              (int2Word# imax `uncheckedShiftL#` WORD_SIZE_BITS_SHIFT#) #)
+
+-- | Return the Word# at the given index
+bigNatIndex# :: BigNat# -> Int# -> Word#
+bigNatIndex# x i = indexWordArray# x i
+
+-- | Return the Word# at the given index
+bigNatIndex :: BigNat# -> Int# -> Word
+bigNatIndex bn i = W# (bigNatIndex# bn i)
+
+-------------------------------------------------
+-- Conversion
+-------------------------------------------------
+
+-- | Create a BigNat from a Word
+bigNatFromWord :: Word -> BigNat#
+bigNatFromWord (W# w) = bigNatFromWord# w
+
+-- | Create a BigNat from a Word
+bigNatFromWord# :: Word# -> BigNat#
+bigNatFromWord# 0## = bigNatZero# (# #)
+bigNatFromWord# w   = wordArrayFromWord# w
+
+-- | Convert a list of non-zero Words (most-significant first) into a BigNat
+bigNatFromWordList :: [Word] -> BigNat#
+bigNatFromWordList (W# 0##:xs) = bigNatFromWordList xs
+bigNatFromWordList xs          = bigNatFromWordListUnsafe xs
+
+-- | Convert a list of non-zero Words (most-significant first) into a BigNat
+bigNatFromWordList# :: [Word] -> WordArray#
+{-# NOINLINE bigNatFromWordList# #-}
+bigNatFromWordList# xs = bigNatFromWordList xs
+
+-- | Return the absolute value of the Int# in a BigNat
+bigNatFromAbsInt# :: Int# -> BigNat#
+bigNatFromAbsInt# i = bigNatFromWord# (wordFromAbsInt# i)
+
+-- | Convert a list of non-zero Words (most-significant first) into a BigNat.
+-- Don't remove most-significant zero words
+bigNatFromWordListUnsafe :: [Word] -> BigNat#
+bigNatFromWordListUnsafe [] = bigNatZero# (# #)
+bigNatFromWordListUnsafe xs =
+   let
+      length i []     = i
+      length i (_:ys) = length (i +# 1#) ys
+      !lxs = length 0# xs
+      writeWordList _mwa _i []        s = s
+      writeWordList mwa   i (W# w:ws) s =
+         case mwaWrite# mwa i w s of
+            s1 -> writeWordList mwa (i -# 1#) ws s1
+   in withNewWordArray# lxs \mwa ->
+            writeWordList mwa (lxs -# 1#) xs
+
+-- | Convert a BigNat into a list of non-zero Words (most-significant first)
+bigNatToWordList :: BigNat# -> [Word]
+bigNatToWordList bn = go (bigNatSize# bn)
+   where
+      go 0# = []
+      go n  = bigNatIndex bn (n -# 1#) : go (n -# 1#)
+
+
+-- | Convert two Word# (most-significant first) into a BigNat
+bigNatFromWord2# :: Word# -> Word# -> BigNat#
+bigNatFromWord2# 0## 0## = bigNatZero# (# #)
+bigNatFromWord2# 0## l   = bigNatFromWord# l
+bigNatFromWord2# h   l   = wordArrayFromWord2# h l
+
+-- | Convert a BigNat into a Word#
+bigNatToWord# :: BigNat# -> Word#
+bigNatToWord# a
+   | bigNatIsZero a = 0##
+   | True           = bigNatIndex# a 0#
+
+-- | Convert a BigNat into a Word# if it fits
+bigNatToWordMaybe# :: BigNat# -> (# (# #) | Word# #)
+bigNatToWordMaybe# a
+   | bigNatIsZero a                = (#       | 0## #)
+   | isTrue# (bigNatSize# a ># 1#) = (# (# #) |     #)
+   | True                          = (#       | bigNatIndex# a 0# #)
+
+-- | Convert a BigNat into a Word
+bigNatToWord :: BigNat# -> Word
+bigNatToWord bn = W# (bigNatToWord# bn)
+
+-- | Convert a BigNat into a Int#
+bigNatToInt# :: BigNat# -> Int#
+bigNatToInt# a
+   | bigNatIsZero a = 0#
+   | True           = indexIntArray# a 0#
+
+-- | Convert a BigNat into a Int
+bigNatToInt :: BigNat# -> Int
+bigNatToInt bn = I# (bigNatToInt# bn)
+
+#if WORD_SIZE_IN_BITS == 32
+
+-- | Convert a Word64# into a BigNat on 32-bit architectures
+bigNatFromWord64# :: Word64# -> BigNat#
+bigNatFromWord64# w64 = bigNatFromWord2# wh# wl#
+  where
+    wh# = word64ToWord# (uncheckedShiftRL64# w64 32#)
+    wl# = word64ToWord# w64
+
+-- | Convert a BigNat into a Word64# on 32-bit architectures
+bigNatToWord64# :: BigNat# -> Word64#
+bigNatToWord64# b
+  | bigNatIsZero b = wordToWord64# 0##
+  | wl <- wordToWord64# (bigNatToWord# b)
+  = if isTrue# (bigNatSize# b ># 1#)
+      then
+         let wh = wordToWord64# (bigNatIndex# b 1#)
+         in uncheckedShiftL64# wh 32# `or64#` wl
+      else wl
+
+#else
+
+-- | Convert a Word64# into a BigNat on 64-bit architectures
+bigNatFromWord64# :: Word64# -> BigNat#
+bigNatFromWord64# w64 = bigNatFromWord# (word64ToWord# w64)
+
+-- | Convert a BigNat into a Word64# on 64-bit architectures
+bigNatToWord64# :: BigNat# -> Word64#
+bigNatToWord64# b = wordToWord64# (bigNatToWord# b)
+
+#endif
+
+-- | Encode (# BigNat mantissa, Int# exponent #) into a Double#
+bigNatEncodeDouble# :: BigNat# -> Int# -> Double#
+bigNatEncodeDouble# a e
+   | bigNatIsZero a
+   = word2Double# 0## -- FIXME: isn't it NaN on 0# exponent?
+
+   | True
+   = inline bignat_encode_double a e
+
+-------------------------------------------------
+-- Predicates
+-------------------------------------------------
+
+-- | Test if a BigNat is greater than a Word
+bigNatGtWord# :: BigNat# -> Word# -> Bool#
+bigNatGtWord# bn w =
+   notB# (bigNatIsZero# bn)
+   &&# (   bigNatSize# bn ># 1#
+       ||# bigNatIndex# bn 0# `gtWord#` w
+       )
+
+-- | Test if a BigNat is equal to a Word
+bigNatEqWord# :: BigNat# -> Word# -> Bool#
+bigNatEqWord# bn w
+   | 0## <- w
+   = bigNatIsZero# bn
+
+   | isTrue# (bigNatSize# bn ==# 1#)
+   = bigNatIndex# bn 0# `eqWord#` w
+
+   | True
+   = 0#
+
+-- | Test if a BigNat is greater than a Word
+bigNatGtWord :: BigNat# -> Word -> Bool
+bigNatGtWord bn (W# w) = isTrue# (bigNatGtWord# bn w)
+
+-- | Test if a BigNat is lower than or equal to a Word
+bigNatLeWord# :: BigNat# -> Word# -> Bool#
+bigNatLeWord# bn w = notB# (bigNatGtWord# bn w)
+
+-- | Test if a BigNat is lower than or equal to a Word
+bigNatLeWord :: BigNat# -> Word -> Bool
+bigNatLeWord bn (W# w) = isTrue# (bigNatLeWord# bn w)
+
+-- | Equality test for BigNat
+bigNatEq# :: BigNat# -> BigNat# -> Bool#
+{-# NOINLINE bigNatEq# #-}
+bigNatEq# wa wb
+   | isTrue# (wordArraySize# wa /=# wordArraySize# wb) = 0#
+   | isTrue# (wordArraySize# wa ==# 0#)                = 1#
+   | True = inline bignat_compare wa wb ==# 0#
+
+-- | Equality test for BigNat
+bigNatEq :: BigNat# -> BigNat# -> Bool
+bigNatEq a b = isTrue# (bigNatEq# a b)
+
+-- | Inequality test for BigNat
+bigNatNe# :: BigNat# -> BigNat# -> Bool#
+bigNatNe# a b = notB# (bigNatEq# a b)
+
+-- | Equality test for BigNat
+bigNatNe :: BigNat# -> BigNat# -> Bool
+bigNatNe a b = isTrue# (bigNatNe# a b)
+
+-- | Compare a BigNat and a Word#
+bigNatCompareWord# :: BigNat# -> Word# -> Ordering
+{-# NOINLINE bigNatCompareWord# #-}
+bigNatCompareWord# a b
+   | bigNatIsZero a                   = cmpW# 0## b
+   | isTrue# (wordArraySize# a ># 1#) = GT
+   | True
+   = cmpW# (indexWordArray# a 0#) b
+
+-- | Compare a BigNat and a Word
+bigNatCompareWord :: BigNat# -> Word -> Ordering
+bigNatCompareWord a (W# b) = bigNatCompareWord# a b
+
+-- | Compare two BigNat
+bigNatCompare :: BigNat# -> BigNat# -> Ordering
+{-# NOINLINE bigNatCompare #-}
+bigNatCompare a b =
+   let
+      szA = wordArraySize# a
+      szB = wordArraySize# b
+   in if
+   | isTrue# (szA ># szB) -> GT
+   | isTrue# (szA <# szB) -> LT
+   | isTrue# (szA ==# 0#) -> EQ
+   | True                 -> compareInt# (inline bignat_compare a b) 0#
+
+
+-- | Predicate: a < b
+bigNatLt# :: BigNat# -> BigNat# -> Bool#
+bigNatLt# a b
+  | LT <- bigNatCompare a b = 1#
+  | True                    = 0#
+
+-- | Predicate: a < b
+bigNatLt :: BigNat# -> BigNat# -> Bool
+bigNatLt a b = isTrue# (bigNatLt# a b)
+
+-- | Predicate: a <= b
+bigNatLe# :: BigNat# -> BigNat# -> Bool#
+bigNatLe# a b
+  | GT <- bigNatCompare a b = 0#
+  | True                    = 1#
+
+-- | Predicate: a <= b
+bigNatLe :: BigNat# -> BigNat# -> Bool
+bigNatLe a b = isTrue# (bigNatLe# a b)
+
+-- | Predicate: a > b
+bigNatGt# :: BigNat# -> BigNat# -> Bool#
+bigNatGt# a b
+  | GT <- bigNatCompare a b = 1#
+  | True                    = 0#
+
+-- | Predicate: a > b
+bigNatGt :: BigNat# -> BigNat# -> Bool
+bigNatGt a b = isTrue# (bigNatGt# a b)
+
+-- | Predicate: a >= b
+bigNatGe# :: BigNat# -> BigNat# -> Bool#
+bigNatGe# a b
+  | LT <- bigNatCompare a b = 0#
+  | True                    = 1#
+
+-- | Predicate: a >= b
+bigNatGe :: BigNat# -> BigNat# -> Bool
+bigNatGe a b = isTrue# (bigNatGe# a b)
+
+-------------------------------------------------
+-- Addition
+-------------------------------------------------
+
+-- | Add a bigNat and a Word#
+bigNatAddWord# :: BigNat# -> Word# -> BigNat#
+bigNatAddWord# a b
+   | 0## <- b
+   = a
+
+   | bigNatIsZero a
+   = bigNatFromWord# b
+
+   | True
+   = withNewWordArrayTrimmed# (wordArraySize# a +# 1#) \mwa s ->
+         inline bignat_add_word mwa a b s
+
+-- | Add a bigNat and a Word
+bigNatAddWord :: BigNat# -> Word -> BigNat#
+bigNatAddWord a (W# b) = bigNatAddWord# a b
+
+-- | Add two bigNats
+bigNatAdd :: BigNat# -> BigNat# -> BigNat#
+bigNatAdd a b
+   | bigNatIsZero a = b
+   | bigNatIsZero b = a
+   | True =
+   let
+      !szA     = wordArraySize# a
+      !szB     = wordArraySize# b
+      !szMax   = maxI# szA szB
+      !sz      = szMax +# 1# -- for the potential carry
+   in withNewWordArrayTrimmed# sz \mwa s ->
+         inline bignat_add mwa a b s
+
+-------------------------------------------------
+-- Multiplication
+-------------------------------------------------
+
+-- | Multiply a BigNat by a Word#
+bigNatMulWord# :: BigNat# -> Word# -> BigNat#
+bigNatMulWord# a w
+   | 0## <- w       = bigNatZero# (# #)
+   | 1## <- w       = a
+   | bigNatIsZero a = bigNatZero# (# #)
+   | bigNatIsOne  a = bigNatFromWord# w
+   | isTrue# (bigNatSize# a ==# 1#)
+   = case timesWord2# (bigNatIndex# a 0#) w of
+      (# h, l #) -> bigNatFromWord2# h l
+   | True = withNewWordArrayTrimmed# (bigNatSize# a +# 1#) \mwa s ->
+               inline bignat_mul_word mwa a w s
+
+-- | Multiply a BigNAt by a Word
+bigNatMulWord :: BigNat# -> Word -> BigNat#
+bigNatMulWord a (W# w) = bigNatMulWord# a w
+
+-- | Square a BigNat
+bigNatSqr :: BigNat# -> BigNat#
+bigNatSqr a = bigNatMul a a
+   -- This can be replaced by a backend primitive in the future (e.g. to use
+   -- GMP's mpn_sqr)
+
+-- | Multiplication (classical algorithm)
+bigNatMul :: BigNat# -> BigNat# -> BigNat#
+bigNatMul a b
+   | bigNatSize b > bigNatSize a = bigNatMul b a -- optimize loops
+   | bigNatIsZero a = a
+   | bigNatIsZero b = b
+   | bigNatIsOne  a = b
+   | bigNatIsOne  b = a
+   | True =
+      let
+         !szA = wordArraySize# a
+         !szB = wordArraySize# b
+         !sz  = szA +# szB
+      in withNewWordArrayTrimmed# sz \mwa s->
+            inline bignat_mul mwa a b s
+
+
+-------------------------------------------------
+-- Subtraction
+-------------------------------------------------
+
+-- | Subtract a Word# from a BigNat
+--
+-- The BigNat must be bigger than the Word#.
+bigNatSubWordUnsafe# :: BigNat# -> Word# -> BigNat#
+bigNatSubWordUnsafe# x y
+   | 0## <- y = x
+   | True     = withNewWordArrayTrimmed# sz \mwa -> go mwa y 0#
+   where
+      !sz = wordArraySize# x
+
+      go mwa carry i s
+         | isTrue# (i >=# sz)
+         = s
+
+         | 0## <- carry
+         = mwaArrayCopy# mwa i x i (sz -# i) s
+
+         | True
+         = case subWordC# (indexWordArray# x i) carry of
+            (# l, c #) -> case mwaWrite# mwa i l s of
+                              s1 -> go mwa (int2Word# c) (i +# 1#) s1
+
+-- | Subtract a Word# from a BigNat
+--
+-- The BigNat must be bigger than the Word#.
+bigNatSubWordUnsafe :: BigNat# -> Word -> BigNat#
+bigNatSubWordUnsafe x (W# y) = bigNatSubWordUnsafe# x y
+
+-- | Subtract a Word# from a BigNat
+bigNatSubWord# :: BigNat# -> Word# -> (# (# #) | BigNat# #)
+bigNatSubWord# a b
+   | 0## <- b          = (# | a #)
+   | bigNatIsZero a    = (# (# #) | #)
+   | True
+   = withNewWordArrayTrimmedMaybe# (bigNatSize# a) \mwa s ->
+            inline bignat_sub_word mwa a b s
+
+
+-- | Subtract two BigNat (don't check if a >= b)
+bigNatSubUnsafe :: BigNat# -> BigNat# -> BigNat#
+bigNatSubUnsafe a b
+   | bigNatIsZero b = a
+   | True =
+      let szA = wordArraySize# a
+      in withNewWordArrayTrimmed# szA \mwa s->
+            case inline bignat_sub mwa a b s of
+               (# s', 1# #) -> s'
+               (# s', _  #) -> case raiseUnderflow of
+                                 !_ -> s'
+                                 -- see Note [ghc-bignum exceptions] in
+                                 -- GHC.Internal.Bignum.Primitives
+
+-- | Subtract two BigNat
+bigNatSub :: BigNat# -> BigNat# -> (# (# #) | BigNat# #)
+bigNatSub a b
+   | bigNatIsZero b = (# | a #)
+   | isTrue# (bigNatSize# a <# bigNatSize# b)
+   = (# (# #) | #)
+
+   | True
+   = withNewWordArrayTrimmedMaybe# (bigNatSize# a) \mwa s ->
+            inline bignat_sub mwa a b s
+
+
+-------------------------------------------------
+-- Division
+-------------------------------------------------
+
+-- | Divide a BigNat by a Word, return the quotient
+--
+-- Require:
+--    b /= 0
+bigNatQuotWord# :: BigNat# -> Word# -> BigNat#
+bigNatQuotWord# a b
+   | 1## <- b = a
+   | 0## <- b = raiseDivZero_BigNat (# #)
+   | True =
+   let
+      sz = wordArraySize# a
+   in withNewWordArrayTrimmed# sz \mwq s ->
+         inline bignat_quot_word mwq a b s
+
+-- | Divide a BigNat by a Word, return the quotient
+--
+-- Require:
+--    b /= 0
+bigNatQuotWord :: BigNat# -> Word -> BigNat#
+bigNatQuotWord a (W# b) = bigNatQuotWord# a b
+
+-- | Divide a BigNat by a Word, return the remainder
+--
+-- Require:
+--    b /= 0
+bigNatRemWord# :: BigNat# -> Word# -> Word#
+bigNatRemWord# a b
+   | 0## <- b       = raiseDivZero_Word# (# #)
+   | 1## <- b       = 0##
+   | bigNatIsZero a = 0##
+   | True           = inline bignat_rem_word a b
+
+-- | Divide a BigNat by a Word, return the remainder
+--
+-- Require:
+--    b /= 0
+bigNatRemWord :: BigNat# -> Word -> Word
+bigNatRemWord a (W# b) = W# (bigNatRemWord# a b)
+
+-- | QuotRem a BigNat by a Word
+--
+-- Require:
+--    b /= 0
+bigNatQuotRemWord# :: BigNat# -> Word# -> (# BigNat#, Word# #)
+bigNatQuotRemWord# a b
+   | 0## <- b = case raiseDivZero of
+                  !_ -> (# bigNatZero# (# #), 0## #)
+                  -- see Note [ghc-bignum exceptions] in GHC.Internal.Bignum.Primitives
+   | 1## <- b = (# a, 0## #)
+   | isTrue# (bigNatSize# a ==# 1#)
+   , a0 <- indexWordArray# a 0#
+   = case compareWord# a0 b of
+      LT -> (# bigNatZero# (# #), a0  #)
+      EQ -> (# bigNatOne#  (# #), 0## #)
+      GT -> case quotRemWord# a0 b of
+               (# q, r #) -> (# bigNatFromWord# q, r #)
+   | True =
+   let
+      sz = wordArraySize# a
+      io s =
+         case newWordArray# sz s of { (# s1, mwq #) ->
+         case inline bignat_quotrem_word mwq a b s1 of { (# s2, r #)  ->
+         case mwaTrimZeroes# mwq s2 of { s3 ->
+         case unsafeFreezeByteArray# mwq s3 of { (# s4, wq #) ->
+         (# s4, (# wq, r #) #)
+         }}}}
+   in case runRW# io of
+         (# _, (# wq,r #) #) -> (# wq, r #)
+
+
+-- | BigNat division returning (quotient,remainder)
+bigNatQuotRem# :: BigNat# -> BigNat# -> (# BigNat#, BigNat# #)
+bigNatQuotRem# a b
+   | bigNatIsZero b          = case raiseDivZero of
+                                 !_ -> (# bigNatZero# (# #), bigNatZero# (# #) #)
+                                 -- see Note [ghc-bignum exceptions] in GHC.Internal.Bignum.Primitives
+   | bigNatIsZero a          = (# bigNatZero# (# #), bigNatZero# (# #) #)
+   | bigNatIsOne b           = (# a                , bigNatZero# (# #) #)
+   | LT <- cmp               = (# bigNatZero# (# #), a #)
+   | EQ <- cmp               = (# bigNatOne#  (# #), bigNatZero# (# #) #)
+   | isTrue# (szB ==# 1#)    = case bigNatQuotRemWord# a (bigNatIndex# b 0#) of
+                                 (# q, r #) -> (# q, bigNatFromWord# r #)
+
+   | True = withNewWordArray2Trimmed# szQ szR \mwq mwr s ->
+                     inline bignat_quotrem mwq mwr a b s
+   where
+   cmp = bigNatCompare a b
+   szA = wordArraySize# a
+   szB = wordArraySize# b
+   szQ = 1# +# szA -# szB
+   szR = szB
+
+
+-- | BigNat division returning quotient
+bigNatQuot :: BigNat# -> BigNat# -> BigNat#
+bigNatQuot a b
+   | bigNatIsZero b          = raiseDivZero_BigNat (# #)
+   | bigNatIsZero a          = bigNatZero# (# #)
+   | bigNatIsOne b           = a
+   | LT <- cmp               = bigNatZero# (# #)
+   | EQ <- cmp               = bigNatOne# (# #)
+   | isTrue# (szB ==# 1#)    = bigNatQuotWord# a (bigNatIndex# b 0#)
+   | True                    = withNewWordArrayTrimmed# szQ \mwq s ->
+                                 inline bignat_quot mwq a b s
+   where
+   cmp = bigNatCompare a b
+   szA = wordArraySize# a
+   szB = wordArraySize# b
+   szQ = 1# +# szA -# szB
+
+-- | BigNat division returning remainder
+bigNatRem :: BigNat# -> BigNat# -> BigNat#
+bigNatRem a b
+   | bigNatIsZero b          = raiseDivZero_BigNat (# #)
+   | bigNatIsZero a          = bigNatZero# (# #)
+   | bigNatIsOne b           = bigNatZero# (# #)
+   | LT <- cmp               = a
+   | EQ <- cmp               = bigNatZero# (# #)
+   | isTrue# (szB ==# 1#)    = case bigNatRemWord# a (bigNatIndex# b 0#) of
+                                 r -> bigNatFromWord# r
+   | True                    = withNewWordArrayTrimmed# szR \mwr s ->
+                                 inline bignat_rem mwr a b s
+   where
+   cmp = bigNatCompare a b
+   szB = wordArraySize# b
+   szR = szB
+
+-------------------------------------------------
+-- GCD / LCM
+-------------------------------------------------
+
+-- Word#/Int# GCDs shouldn't be here in BigNat. However GMP provides a very fast
+-- implementation so we keep this here at least until we get a native Haskell
+-- implementation as fast as GMP's one. Note that these functions are used in
+-- `base` (e.g. in GHC.Real)
+
+-- | Greatest common divisor between two Word#
+gcdWord# :: Word# -> Word# -> Word#
+gcdWord# = bignat_gcd_word_word
+
+-- | Greatest common divisor between two Word
+gcdWord :: Word -> Word -> Word
+gcdWord (W# x) (W# y) = W# (gcdWord# x y)
+
+-- | Greatest common divisor between two Int#
+--
+-- __Warning__: result may become negative if (at least) one argument
+-- is 'minBound'
+gcdInt# :: Int# -> Int# -> Int#
+gcdInt# x y = word2Int# (gcdWord# (wordFromAbsInt# x) (wordFromAbsInt# y))
+
+-- | Greatest common divisor between two Int
+--
+-- __Warning__: result may become negative if (at least) one argument
+-- is 'minBound'
+gcdInt :: Int -> Int -> Int
+gcdInt (I# x) (I# y) = I# (gcdInt# x y)
+
+-- | Greatest common divisor
+bigNatGcd :: BigNat# -> BigNat# -> BigNat#
+bigNatGcd a b
+   | bigNatIsZero a = b
+   | bigNatIsZero b = a
+   | bigNatIsOne a  = a
+   | bigNatIsOne b  = b
+   | True
+   = case (# bigNatSize# a, bigNatSize# b #) of
+      (# 1#, 1# #) -> bigNatFromWord# (gcdWord# (bigNatIndex# a 0#)
+                                                (bigNatIndex# b 0#))
+      (# 1#, _  #) -> bigNatFromWord# (bigNatGcdWord# b (bigNatIndex# a 0#))
+      (# _ , 1# #) -> bigNatFromWord# (bigNatGcdWord# a (bigNatIndex# b 0#))
+      _            ->
+         let
+            go wx wy = -- wx > wy
+               withNewWordArrayTrimmed# (wordArraySize# wy) \mwr s ->
+                  bignat_gcd mwr wx wy s
+         in case bigNatCompare a b of
+               EQ -> a
+               LT -> go b a
+               GT -> go a b
+
+-- | Greatest common divisor
+bigNatGcdWord# :: BigNat# -> Word# -> Word#
+bigNatGcdWord# a b
+   | bigNatIsZero a = 0##
+   | 0## <- b       = 0##
+   | bigNatIsOne a  = 1##
+   | 1## <- b       = 1##
+   | True           = case bigNatCompareWord# a b of
+      EQ -> b
+      _  -> bignat_gcd_word a b
+
+-- | Least common multiple
+bigNatLcm :: BigNat# -> BigNat# -> BigNat#
+bigNatLcm a b
+   | bigNatIsZero a = bigNatZero# (# #)
+   | bigNatIsZero b = bigNatZero# (# #)
+   | bigNatIsOne  a = b
+   | bigNatIsOne  b = a
+   | True
+   = case (# bigNatSize# a, bigNatSize# b #) of
+      (# 1#, 1# #) -> bigNatLcmWordWord# (bigNatIndex# a 0#) (bigNatIndex# b 0#)
+      (# 1#, _  #) -> bigNatLcmWord# b (bigNatIndex# a 0#)
+      (# _ , 1# #) -> bigNatLcmWord# a (bigNatIndex# b 0#)
+      _            -> (a `bigNatQuot` (a `bigNatGcd` b)) `bigNatMul` b
+                       -- TODO: use extended GCD to get a's factor directly
+
+-- | Least common multiple with a Word#
+bigNatLcmWord# :: BigNat# -> Word# -> BigNat#
+bigNatLcmWord# a b
+   | bigNatIsZero a      = bigNatZero# (# #)
+   | 0## <- b            = bigNatZero# (# #)
+   | bigNatIsOne  a      = bigNatFromWord# b
+   | 1## <- b            = a
+   | 1# <- bigNatSize# a = bigNatLcmWordWord# (bigNatIndex# a 0#) b
+   | True
+   = (a `bigNatQuotWord#` (a `bigNatGcdWord#` b)) `bigNatMulWord#` b
+      -- TODO: use extended GCD to get a's factor directly
+
+-- | Least common multiple between two Word#
+bigNatLcmWordWord# :: Word# -> Word# -> BigNat#
+bigNatLcmWordWord# a b
+   | 0## <- a = bigNatZero# (# #)
+   | 0## <- b = bigNatZero# (# #)
+   | 1## <- a = bigNatFromWord# b
+   | 1## <- b = bigNatFromWord# a
+   | True     = case (a `quotWord#` (a `gcdWord#` b)) `timesWord2#` b of
+                     -- TODO: use extended GCD to get a's factor directly
+      (# h, l #) -> bigNatFromWord2# h l
+
+
+-------------------------------------------------
+-- Bitwise operations
+-------------------------------------------------
+
+-- | Bitwise OR
+bigNatOr :: BigNat# -> BigNat# -> BigNat#
+bigNatOr a b
+   | bigNatIsZero a = b
+   | bigNatIsZero b = a
+   | True           = withNewWordArray# sz \mwa s ->
+                        inline bignat_or mwa a b s
+   where
+      !szA = wordArraySize# a
+      !szB = wordArraySize# b
+      !sz  = maxI# szA szB
+
+-- | Bitwise OR with Word#
+bigNatOrWord# :: BigNat# -> Word# -> BigNat#
+bigNatOrWord# a b
+   | bigNatIsZero a = bigNatFromWord# b
+   | 0## <- b       = a
+   | True           =
+      let sz = wordArraySize# a
+      in withNewWordArray# sz \mwa s ->
+            case mwaArrayCopy# mwa 1# a 1# (sz -# 1#) s of
+               s' -> mwaWrite# mwa 0# (indexWordArray# a 0# `or#` b) s'
+
+-- | Bitwise AND
+bigNatAnd :: BigNat# -> BigNat# -> BigNat#
+bigNatAnd a b
+   | bigNatIsZero a = a
+   | bigNatIsZero b = b
+   | True           = withNewWordArrayTrimmed# sz \mwa s ->
+                        inline bignat_and mwa a b s
+   where
+      !szA = wordArraySize# a
+      !szB = wordArraySize# b
+      !sz  = minI# szA szB
+
+-- | Bitwise ANDNOT
+bigNatAndNot :: BigNat# -> BigNat# -> BigNat#
+bigNatAndNot a b
+   | bigNatIsZero a = a
+   | bigNatIsZero b = a
+   | True           = withNewWordArrayTrimmed# szA \mwa s ->
+                        inline bignat_and_not mwa a b s
+   where
+      !szA = wordArraySize# a
+
+-- | Bitwise AND with Word#
+bigNatAndWord# :: BigNat# -> Word# -> BigNat#
+bigNatAndWord# a b
+   | bigNatIsZero a = a
+   | True           = bigNatFromWord# (indexWordArray# a 0# `and#` b)
+
+-- | Bitwise ANDNOT with Word#
+bigNatAndNotWord# :: BigNat# -> Word# -> BigNat#
+bigNatAndNotWord# a b
+   | bigNatIsZero a     = a
+   | szA <- bigNatSize# a
+   = withNewWordArray# szA \mwa s ->
+      -- duplicate higher limbs
+      case mwaArrayCopy# mwa 1# a 1# (szA -# 1#) s of
+         s' -> writeWordArray# mwa 0#
+               (indexWordArray# a 0# `and#` not# b) s'
+
+-- | Bitwise AND with Int#
+bigNatAndInt# :: BigNat# -> Int# -> BigNat#
+bigNatAndInt# a b
+   | bigNatIsZero a     = a
+   | isTrue# (b >=# 0#) = bigNatAndWord# a (int2Word# b)
+   | szA <- bigNatSize# a
+   = withNewWordArray# szA \mwa s ->
+      -- duplicate higher limbs (because of sign-extension of b)
+      case mwaArrayCopy# mwa 1# a 1# (szA -# 1#) s of
+         s' -> writeWordArray# mwa 0#
+               (indexWordArray# a 0# `and#` int2Word# b) s'
+
+
+-- | Bitwise XOR
+bigNatXor :: BigNat# -> BigNat# -> BigNat#
+bigNatXor a b
+   | bigNatIsZero a = b
+   | bigNatIsZero b = a
+   | True           = withNewWordArrayTrimmed# sz \mwa s ->
+                        inline bignat_xor mwa a b s
+   where
+      !szA = wordArraySize# a
+      !szB = wordArraySize# b
+      !sz  = maxI# szA szB
+
+-- | Bitwise XOR with Word#
+bigNatXorWord# :: BigNat# -> Word# -> BigNat#
+bigNatXorWord# a b
+   | bigNatIsZero a = bigNatFromWord# b
+   | 0## <- b       = a
+   | True           =
+      let
+         sz = wordArraySize# a
+      in withNewWordArray# sz \mwa s ->
+            case mwaArrayCopy# mwa 1# a 1# (sz -# 1#) s of
+               s' -> mwaWrite# mwa 0# (indexWordArray# a 0# `xor#` b) s'
+
+-- | PopCount for BigNat
+bigNatPopCount :: BigNat# -> Word
+bigNatPopCount a = W# (bigNatPopCount# a)
+
+-- | PopCount for BigNat
+bigNatPopCount# :: BigNat# -> Word#
+bigNatPopCount# a
+   | bigNatIsZero a = 0##
+   | True           = inline bignat_popcount a
+
+-- | Bit shift right
+bigNatShiftR# :: BigNat# -> Word# -> BigNat#
+bigNatShiftR# a n
+   | 0## <- n
+   = a
+
+   | isTrue# (wordArraySize# a ==# 0#)
+   = a
+
+   | nw <- word2Int# (n `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+   , isTrue# (nw >=# wordArraySize# a)
+   = bigNatZero# (# #)
+
+   | True
+   = let
+      !szA = wordArraySize# a
+      !nw  = word2Int# (n `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+      !sz  = szA -# nw
+     in withNewWordArrayTrimmed# sz \mwa s ->
+         inline bignat_shiftr mwa a n s
+
+-- | Bit shift right (two's complement)
+bigNatShiftRNeg# :: BigNat# -> Word# -> BigNat#
+bigNatShiftRNeg# a n
+   | 0## <- n
+   = a
+
+   | isTrue# (wordArraySize# a ==# 0#)
+   = a
+
+   | nw <- word2Int# (n `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+   , isTrue# (nw >=# wordArraySize# a)
+   = bigNatZero# (# #)
+
+   | True
+   = let
+      !szA = wordArraySize# a
+      !nw  = (word2Int# n -# 1#) `uncheckedIShiftRL#` WORD_SIZE_BITS_SHIFT#
+      !sz  = szA -# nw
+     in withNewWordArrayTrimmed# sz \mwa s ->
+         inline bignat_shiftr_neg mwa a n s
+
+
+-- | Bit shift right
+bigNatShiftR :: BigNat# -> Word -> BigNat#
+bigNatShiftR a (W# n) = bigNatShiftR# a n
+
+-- | Bit shift left
+bigNatShiftL :: BigNat# -> Word -> BigNat#
+bigNatShiftL a (W# n) = bigNatShiftL# a n
+
+-- | Bit shift left
+bigNatShiftL# :: BigNat# -> Word# -> BigNat#
+bigNatShiftL# a n
+   | 0## <- n
+   = a
+
+   | isTrue# (wordArraySize# a ==# 0#)
+   = a
+
+   | True
+   = let
+      !szA = wordArraySize# a
+      !nw  = word2Int# (n `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+      !nb  = word2Int# (n `and#` WORD_SIZE_BITS_MASK##)
+      !sz   = szA +# nw +# (nb /=# 0#)
+
+     in withNewWordArrayTrimmed# sz \mwa s ->
+         inline bignat_shiftl mwa a n s
+
+
+-- | BigNat bit test
+bigNatTestBit# :: BigNat# -> Word# -> Bool#
+bigNatTestBit# a n =
+   let
+      !sz = wordArraySize# a
+      !nw = word2Int# (n `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+      !nb = n `and#` WORD_SIZE_BITS_MASK##
+   in if
+      | isTrue# (nw >=# sz) -> 0#
+      | True                -> testBitW# (indexWordArray# a nw) nb
+
+-- | BigNat bit test
+bigNatTestBit :: BigNat# -> Word -> Bool
+bigNatTestBit a (W# n) = isTrue# (bigNatTestBit# a n)
+
+
+-- | Return a BigNat whose bit `i` is the only one set.
+--
+-- Specialized version of `bigNatShiftL (bigNatFromWord# 1##)`
+--
+bigNatBit# :: Word# -> BigNat#
+bigNatBit# i
+   | 0## <- i = bigNatOne# (# #)
+   | True =
+   let
+      !nw = word2Int# (i `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+      !nb = word2Int# (i `and#` WORD_SIZE_BITS_MASK##)
+      !sz = nw +# 1#
+      !v  = 1## `uncheckedShiftL#` nb
+   in withNewWordArray# sz \mwa s ->
+         -- clear the array
+         case mwaFill# mwa 0## 0## (int2Word# sz) s of
+            -- set the bit in the most-significant word
+            s2 -> mwaWrite# mwa (sz -# 1#) v s2
+
+-- | Return a BigNat whose bit `i` is the only one set.
+--
+-- Specialized version of `bigNatShiftL (bigNatFromWord# 1##)`
+--
+bigNatBit :: Word -> BigNat#
+bigNatBit (W# i) = bigNatBit# i
+
+-- | BigNat clear bit
+bigNatClearBit# :: BigNat# -> Word# -> BigNat#
+bigNatClearBit# a n
+   -- check the range validity and the current bit value
+   | isTrue# (bigNatTestBit# a n ==# 0#) = a
+   | True
+   = let
+      !sz = wordArraySize# a
+      !nw = word2Int# (n `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+      !nb = word2Int# (n `and#` WORD_SIZE_BITS_MASK##)
+      !nv = bigNatIndex# a nw `xor#` bitW# nb
+   in if
+      | isTrue# (sz ==# 1#)
+      -> bigNatFromWord# nv
+
+      -- special case, operating on most-significant Word
+      | 0## <- nv
+      , isTrue# (nw +# 1# ==# sz)
+      -> case sz -# (waClzAt a (sz -# 2#) +# 1#) of
+            0#  -> bigNatZero# (# #)
+            nsz -> withNewWordArray# nsz \mwa s ->
+                     mwaArrayCopy# mwa 0# a 0# nsz s
+
+      | True ->
+         withNewWordArray# sz \mwa s ->
+            case mwaArrayCopy# mwa 0# a 0# sz s of
+               s' -> writeWordArray# mwa nw nv s'
+
+-- | BigNat set bit
+bigNatSetBit# :: BigNat# -> Word# -> BigNat#
+{-# NOINLINE bigNatSetBit# #-}
+bigNatSetBit# a n
+   -- check the current bit value
+   | isTrue# (bigNatTestBit# a n) = a
+   | True
+   = let
+      !sz = wordArraySize# a
+      !nw = word2Int# (n `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+      !nb = word2Int# (n `and#` WORD_SIZE_BITS_MASK##)
+      d   = nw +# 1# -# sz
+   in if
+      -- result BigNat will have more limbs
+      | isTrue# (d ># 0#)
+      -> withNewWordArray# (nw +# 1#) \mwa s ->
+            case mwaArrayCopy# mwa 0# a 0# sz s of
+               s' -> case mwaFill# mwa 0## (int2Word# sz) (int2Word# (d -# 1#)) s' of
+                  s'' -> writeWordArray# mwa nw (bitW# nb) s''
+
+      | nv <- bigNatIndex# a nw `or#` bitW# nb
+      -> withNewWordArray# sz \mwa s ->
+            case mwaArrayCopy# mwa 0# a 0# sz s of
+               s' -> writeWordArray# mwa nw nv s'
+
+-- | Reverse the given bit
+bigNatComplementBit# :: BigNat# -> Word# -> BigNat#
+bigNatComplementBit# a n =
+   let
+      !sz = wordArraySize# a
+      !nw = word2Int# (n `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+      !nb = word2Int# (n `and#` WORD_SIZE_BITS_MASK##)
+      d   = nw +# 1# -# sz
+   in if
+      -- result BigNat will have more limbs
+      | isTrue# (d ># 0#)
+      -> withNewWordArray# (nw +# 1#) \mwa s ->
+            case mwaArrayCopy# mwa 0# a 0# sz s of
+               s' -> case mwaFill# mwa 0## (int2Word# sz) (int2Word# (d -# 1#)) s' of
+                  s'' -> writeWordArray# mwa nw (bitW# nb) s''
+
+      | nv <- bigNatIndex# a nw `xor#` bitW# nb
+      -> withNewWordArrayTrimmed# sz \mwa s ->
+            case mwaArrayCopy# mwa 0# a 0# sz s of
+               s' -> writeWordArray# mwa nw nv s'
+
+-------------------------------------------------
+-- Log operations
+-------------------------------------------------
+
+-- | Base 2 logarithm
+bigNatLog2# :: BigNat# -> Word#
+bigNatLog2# a
+   | bigNatIsZero a = 0##
+   | True           =
+      let i = int2Word# (bigNatSize# a) `minusWord#` 1##
+      in wordLog2# (bigNatIndex# a (word2Int# i))
+         `plusWord#` (i `uncheckedShiftL#` WORD_SIZE_BITS_SHIFT#)
+
+-- | Base 2 logarithm
+bigNatLog2 :: BigNat# -> Word
+bigNatLog2 a = W# (bigNatLog2# a)
+
+-- | Logarithm for an arbitrary base
+bigNatLogBase# :: BigNat# -> BigNat# -> Word#
+bigNatLogBase# base a
+   | bigNatIsZero base || bigNatIsOne base
+   = unexpectedValue_Word# (# #)
+
+   | 1# <- bigNatSize# base
+   , 2## <- bigNatIndex# base 0#
+   = bigNatLog2# a
+
+   -- TODO: optimize log base power of 2 (256, etc.)
+
+   | True
+   = case go base of (# _, e' #) -> e'
+   where
+      go pw = if a `bigNatLt` pw
+         then (# a, 0## #)
+         else case go (bigNatSqr pw) of
+          (# q, e #) -> if q `bigNatLt` pw
+            then (# q, 2## `timesWord#` e #)
+            else (# q `bigNatQuot` pw
+                 , (2## `timesWord#` e) `plusWord#` 1## #)
+
+-- | Logarithm for an arbitrary base
+bigNatLogBase :: BigNat# -> BigNat# -> Word
+bigNatLogBase base a = W# (bigNatLogBase# base a)
+
+-- | Logarithm for an arbitrary base
+bigNatLogBaseWord# :: Word# -> BigNat# -> Word#
+bigNatLogBaseWord# base a
+   | 0## <- base = unexpectedValue_Word# (# #)
+   | 1## <- base = unexpectedValue_Word# (# #)
+   | 2## <- base = bigNatLog2# a
+   -- TODO: optimize log base power of 2 (256, etc.)
+   | True = bigNatLogBase# (bigNatFromWord# base) a
+
+-- | Logarithm for an arbitrary base
+bigNatLogBaseWord :: Word -> BigNat# -> Word
+bigNatLogBaseWord (W# base) a = W# (bigNatLogBaseWord# base a)
+
+-------------------------------------------------
+-- Various
+-------------------------------------------------
+
+-- | Compute the number of digits of the BigNat in the given base.
+--
+-- `base` must be > 1
+bigNatSizeInBase# :: Word# -> BigNat# -> Word#
+bigNatSizeInBase# base a
+   | isTrue# (base `leWord#` 1##)
+   = unexpectedValue_Word# (# #)
+
+   | bigNatIsZero a
+   = 0##
+
+   | True
+   = bigNatLogBaseWord# base a `plusWord#` 1##
+
+-- | Compute the number of digits of the BigNat in the given base.
+--
+-- `base` must be > 1
+bigNatSizeInBase :: Word -> BigNat# -> Word
+bigNatSizeInBase (W# w) a = W# (bigNatSizeInBase# w a)
+
+-------------------------------------------------
+-- PowMod
+-------------------------------------------------
+
+-- Word# powMod shouldn't be here in BigNat. However GMP provides a very fast
+-- implementation so we keep this here at least until we get a native Haskell
+-- implementation as fast as GMP's one.
+
+powModWord# :: Word# -> Word# -> Word# -> Word#
+powModWord# = bignat_powmod_words
+
+
+-- | \"@'bigNatPowModWord#' /b/ /e/ /m/@\" computes base @/b/@ raised to
+-- exponent @/e/@ modulo @/m/@.
+bigNatPowModWord# :: BigNat# -> BigNat# -> Word# -> Word#
+bigNatPowModWord# !_ !_ 0## = raiseDivZero_Word# (# #)
+bigNatPowModWord# _  _  1## = 0##
+bigNatPowModWord# b  e  m
+   | bigNatIsZero e         = 1##
+   | bigNatIsZero b         = 0##
+   | bigNatIsOne  b         = 1##
+   | True                   = bignat_powmod_word b e m
+
+-- | \"@'bigNatPowMod' /b/ /e/ /m/@\" computes base @/b/@ raised to
+-- exponent @/e/@ modulo @/m/@.
+bigNatPowMod :: BigNat# -> BigNat# -> BigNat# -> BigNat#
+bigNatPowMod !b !e !m
+   | (# | m' #) <- bigNatToWordMaybe# m
+   = bigNatFromWord# (bigNatPowModWord# b e m')
+   | bigNatIsZero m = raiseDivZero_BigNat (# #)
+   | bigNatIsOne  m = bigNatFromWord# 0##
+   | bigNatIsZero e = bigNatFromWord# 1##
+   | bigNatIsZero b = bigNatFromWord# 0##
+   | bigNatIsOne  b = bigNatFromWord# 1##
+   | True           = withNewWordArrayTrimmed# (bigNatSize# m) \mwa s ->
+                         inline bignat_powmod mwa b e m s
+
+-- | Return count of trailing zero bits
+--
+-- Return 0 for zero BigNat
+bigNatCtz# :: BigNat# -> Word#
+bigNatCtz# a
+   | bigNatIsZero a = 0##
+   | True           = go 0# 0##
+      where
+         go i c = case indexWordArray# a i of
+            0## -> go (i +# 1#) (c `plusWord#` WORD_SIZE_IN_BITS##)
+            w   -> ctz# w `plusWord#` c
+
+-- | Return count of trailing zero bits
+--
+-- Return 0 for zero BigNat
+bigNatCtz :: BigNat# -> Word
+bigNatCtz a = W# (bigNatCtz# a)
+
+
+-- | Return count of trailing zero words
+--
+-- Return 0 for zero BigNat
+bigNatCtzWord# :: BigNat# -> Word#
+bigNatCtzWord# a
+   | bigNatIsZero a = 0##
+   | True           = go 0# 0##
+      where
+         go i c = case indexWordArray# a i of
+            0## -> go (i +# 1#) (c `plusWord#` 1##)
+            _   -> c
+
+-- | Return count of trailing zero words
+--
+-- Return 0 for zero BigNat
+bigNatCtzWord :: BigNat# -> Word
+bigNatCtzWord a = W# (bigNatCtzWord# a)
+
+-------------------------------------------------
+-- Export to memory
+-------------------------------------------------
+
+-- | Write a BigNat in base-256 little-endian representation and return the
+-- number of bytes written.
+--
+-- Use \"@'bigNatSizeInBase' 256# /i/@\" to compute the exact number of bytes
+-- written in advance. In case of @/i/ == 0@, the function will write and report
+-- zero bytes written.
+bigNatToAddrLE# :: BigNat# -> Addr# -> State# s -> (# State# s, Word# #)
+{-# NOINLINE bigNatToAddrLE# #-}
+bigNatToAddrLE# a addr s0
+   | isTrue# (sz ==# 0#) = (# s0, 0## #)
+   | True = case writeMSB s0 of
+      (# s1, k #) -> case go 0# s1 of
+         s2 -> (# s2, k `plusWord#` (int2Word# li `uncheckedShiftL#` WORD_SIZE_BYTES_SHIFT#) #)
+   where
+     !sz = wordArraySize# a
+     !li = sz -# 1#
+
+     writeMSB = wordToAddrLE# (indexWordArray# a li)
+                  (addr `plusAddr#` (li `uncheckedIShiftL#` WORD_SIZE_BYTES_SHIFT#))
+
+     go i s
+      | isTrue# (i <# li)
+      , off <- i `uncheckedIShiftL#` WORD_SIZE_BYTES_SHIFT#
+      , w <- indexWordArray# a i
+      = case wordWriteAddrLE# w (addr `plusAddr#` off) s of
+         s -> go (i +# 1#) s
+
+      | True
+      = s
+
+-- | Write a BigNat in base-256 big-endian representation and return the
+-- number of bytes written.
+--
+-- Use \"@'bigNatSizeInBase' 256# /i/@\" to compute the exact number of bytes
+-- written in advance. In case of @/i/ == 0@, the function will write and report
+-- zero bytes written.
+bigNatToAddrBE# :: BigNat# -> Addr# -> State# s -> (# State# s, Word# #)
+{-# NOINLINE bigNatToAddrBE# #-}
+bigNatToAddrBE# a addr s0
+   | isTrue# (sz ==# 0#) = (# s0, 0## #)
+   | msw <- indexWordArray# a (sz -# 1#)
+   = case wordToAddrBE# msw addr s0 of
+      (# s1, k #) -> case go (sz -# 1#) (addr `plusAddr#` word2Int# k) s1 of
+         s2 -> (# s2, k `plusWord#` (int2Word# (sz -# 1#) `uncheckedShiftL#` WORD_SIZE_BYTES_SHIFT#) #)
+   where
+     sz   = wordArraySize# a
+
+     go i adr s
+      | 0# <- i
+      = s
+
+      | w <- indexWordArray# a (i -# 1#)
+      = case wordWriteAddrBE# w adr s of
+         s' -> go (i -# 1#)
+                  (adr `plusAddr#` WORD_SIZE_IN_BYTES# ) s'
+
+
+-- | Write a BigNat in base-256 representation and return the
+-- number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Use \"@'bigNatSizeInBase' 256# /i/@\" to compute the exact number of bytes
+-- written in advance. In case of @/i/ == 0@, the function will write and report
+-- zero bytes written.
+bigNatToAddr# :: BigNat# -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
+bigNatToAddr# a addr 0# s = bigNatToAddrLE# a addr s
+bigNatToAddr# a addr _  s = bigNatToAddrBE# a addr s
+
+-- | Write a BigNat in base-256 representation and return the
+-- number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Use \"@'bigNatSizeInBase' 256# /i/@\" to compute the exact number of bytes
+-- written in advance. In case of @/i/ == 0@, the function will write and report
+-- zero bytes written.
+bigNatToAddr :: BigNat# -> Addr# -> Bool# -> IO Word
+bigNatToAddr a addr e = IO \s -> case bigNatToAddr# a addr e s of
+   (# s', w #) -> (# s', W# w #)
+
+
+
+-------------------------------------------------
+-- Import from memory
+-------------------------------------------------
+
+-- | Read a BigNat in base-256 little-endian representation from an Addr#.
+--
+-- The size is given in bytes.
+--
+-- Higher limbs equal to 0 are automatically trimmed.
+bigNatFromAddrLE# :: Word# -> Addr# -> State# s -> (# State# s, BigNat# #)
+{-# NOINLINE bigNatFromAddrLE# #-}
+bigNatFromAddrLE# 0## _    s = (# s, bigNatZero# (# #) #)
+bigNatFromAddrLE# sz  addr s =
+   let
+      !nw = sz `uncheckedShiftRL#` WORD_SIZE_BYTES_SHIFT#
+      !nb = sz `and#` WORD_SIZE_BYTES_MASK##
+
+      readMSB mwa s
+         | 0## <- nb
+         = s
+
+         | off <- word2Int# (nw `uncheckedShiftL#` WORD_SIZE_BYTES_SHIFT#)
+         = case wordFromAddrLE# nb (addr `plusAddr#` off) s of
+            (# s, w #) -> mwaWrite# mwa (word2Int# nw) w s
+
+      go mwa i s
+         | isTrue# (i ==# word2Int# nw)
+         = s
+
+         | off <- i `uncheckedIShiftL#` WORD_SIZE_BYTES_SHIFT#
+         = case wordFromAddrLE# WORD_SIZE_IN_BYTES## (addr `plusAddr#` off) s of
+            (# s, w #) -> case mwaWrite# mwa i w s of
+               s -> go mwa (i +# 1#) s
+
+   in case newWordArray# (word2Int# nw +# (word2Int# nb /=# 0#)) s of
+         (# s, mwa #) -> case readMSB mwa s of
+            s -> case go mwa 0# s of
+               s -> case mwaTrimZeroes# mwa s of
+                  s -> unsafeFreezeByteArray# mwa s
+
+-- | Read a BigNat in base-256 big-endian representation from an Addr#.
+--
+-- The size is given in bytes.
+--
+-- Null higher limbs are automatically trimmed.
+bigNatFromAddrBE# :: Word# -> Addr# -> State# s -> (# State# s, BigNat# #)
+{-# NOINLINE bigNatFromAddrBE# #-}
+bigNatFromAddrBE# 0## _    s = (# s, bigNatZero# (# #) #)
+bigNatFromAddrBE# sz  addr s =
+   let
+      !nw = word2Int# (sz `uncheckedShiftRL#` WORD_SIZE_BYTES_SHIFT#)
+      !nb = sz `and#` WORD_SIZE_BYTES_MASK##
+
+      goMSB mwa s
+         | 0## <- nb
+         = s
+
+         | True
+         = case wordFromAddrBE# nb addr s of
+            (# s, w #) -> mwaWrite# mwa nw w s
+
+      go mwa i s
+         | isTrue# (i ==# nw)
+         = s
+
+         | k <- nw -# 1# -# i
+         , off <- (k `uncheckedIShiftL#` WORD_SIZE_BYTES_SHIFT#) +# word2Int# nb
+         = case wordFromAddrBE# WORD_SIZE_IN_BYTES## (addr `plusAddr#` off) s of
+            (# s, w #) -> case mwaWrite# mwa i w s of
+               s -> go mwa (i +# 1#) s
+
+   in case newWordArray# (nw +# (word2Int# nb /=# 0#)) s of
+         (# s, mwa #) -> case goMSB mwa s of
+            s -> case go mwa 0# s of
+               s -> case mwaTrimZeroes# mwa s of
+                  s -> unsafeFreezeByteArray# mwa s
+
+-- | Read a BigNat in base-256 representation from an Addr#.
+--
+-- The size is given in bytes.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Null higher limbs are automatically trimmed.
+bigNatFromAddr# :: Word# -> Addr# -> Bool# -> State# s -> (# State# s, BigNat# #)
+bigNatFromAddr# sz addr 0# s = bigNatFromAddrLE# sz addr s
+bigNatFromAddr# sz addr _  s = bigNatFromAddrBE# sz addr s
+
+-------------------------------------------------
+-- Export to ByteArray
+-------------------------------------------------
+
+-- | Write a BigNat in base-256 little-endian representation and return the
+-- number of bytes written.
+--
+-- Use \"@'bigNatSizeInBase' 256# /i/@\" to compute the exact number of bytes
+-- written in advance. In case of @/i/ == 0@, the function will write and report
+-- zero bytes written.
+bigNatToMutableByteArrayLE# :: BigNat# -> MutableByteArray# s -> Word# -> State# s -> (# State# s, Word# #)
+{-# NOINLINE bigNatToMutableByteArrayLE# #-}
+bigNatToMutableByteArrayLE# a mba moff s0
+   | isTrue# (sz ==# 0#) = (# s0, 0## #)
+   | True = case writeMSB s0 of
+      (# s1, k #) -> case go 0# s1 of
+         s2 -> (# s2, k `plusWord#` (int2Word# li `uncheckedShiftL#` WORD_SIZE_BYTES_SHIFT#) #)
+   where
+     !sz = wordArraySize# a
+     !li = sz -# 1#
+
+     writeMSB = wordToMutableByteArrayLE# (indexWordArray# a li)
+                  mba (moff `plusWord#` int2Word# (li `uncheckedIShiftL#` WORD_SIZE_BYTES_SHIFT#))
+
+     go i s
+      | isTrue# (i <# li)
+      , off <- int2Word# i `uncheckedShiftL#` WORD_SIZE_BYTES_SHIFT#
+      , w <- indexWordArray# a i
+      = case wordWriteMutableByteArrayLE# w mba (moff `plusWord#` off) s of
+         s -> go (i +# 1#) s
+
+      | True
+      = s
+
+-- | Write a BigNat in base-256 big-endian representation and return the
+-- number of bytes written.
+--
+-- Use \"@'bigNatSizeInBase' 256# /i/@\" to compute the exact number of bytes
+-- written in advance. In case of @/i/ == 0@, the function will write and report
+-- zero bytes written.
+bigNatToMutableByteArrayBE# :: BigNat# -> MutableByteArray# s -> Word# -> State# s -> (# State# s, Word# #)
+{-# NOINLINE bigNatToMutableByteArrayBE# #-}
+bigNatToMutableByteArrayBE# a mba moff s0
+   | isTrue# (sz ==# 0#) = (# s0, 0## #)
+   | msw <- indexWordArray# a (sz -# 1#)
+   = case wordToMutableByteArrayBE# msw mba moff s0 of
+      (# s1, k #) -> case go (sz -# 1#) k s1 of
+         s2 -> (# s2, k `plusWord#` (int2Word# (sz -# 1#) `uncheckedShiftL#` WORD_SIZE_BYTES_SHIFT#) #)
+   where
+     sz   = wordArraySize# a
+
+     go i c s
+      | 0# <- i
+      = s
+
+      | w <- indexWordArray# a (i -# 1#)
+      = case wordWriteMutableByteArrayBE# w mba (moff `plusWord#` c) s of
+         s' -> go (i -# 1#)
+                  (c `plusWord#` WORD_SIZE_IN_BYTES## ) s'
+
+
+-- | Write a BigNat in base-256 representation and return the
+-- number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Use \"@'bigNatSizeInBase' 256# /i/@\" to compute the exact number of bytes
+-- written in advance. In case of @/i/ == 0@, the function will write and report
+-- zero bytes written.
+bigNatToMutableByteArray# :: BigNat# -> MutableByteArray# s -> Word# -> Bool# -> State# s -> (# State# s, Word# #)
+bigNatToMutableByteArray# a mba off 0# s = bigNatToMutableByteArrayLE# a mba off s
+bigNatToMutableByteArray# a mba off _  s = bigNatToMutableByteArrayBE# a mba off s
+
+-------------------------------------------------
+-- Import from ByteArray
+-------------------------------------------------
+
+-- | Read a BigNat in base-256 little-endian representation from a ByteArray#.
+--
+-- The size is given in bytes.
+--
+-- Null higher limbs are automatically trimmed.
+bigNatFromByteArrayLE# :: Word# -> ByteArray# -> Word# -> State# s -> (# State# s, BigNat# #)
+{-# NOINLINE bigNatFromByteArrayLE# #-}
+bigNatFromByteArrayLE# 0## _  _    s = (# s, bigNatZero# (# #) #)
+bigNatFromByteArrayLE# sz  ba moff s =
+   let
+      !nw = sz `uncheckedShiftRL#` WORD_SIZE_BYTES_SHIFT#
+      !nb = sz `and#` WORD_SIZE_BYTES_MASK##
+
+      readMSB mwa s
+         | 0## <- nb
+         = s
+
+         | off <- nw `uncheckedShiftL#` WORD_SIZE_BYTES_SHIFT#
+         = case wordFromByteArrayLE# nb ba (moff `plusWord#` off) of
+               w -> mwaWrite# mwa (word2Int# nw) w s
+
+      go mwa i s
+         | isTrue# (i `eqWord#` nw)
+         = s
+
+         | off <- i `uncheckedShiftL#` WORD_SIZE_BYTES_SHIFT#
+         = case wordFromByteArrayLE# WORD_SIZE_IN_BYTES## ba (moff `plusWord#` off) of
+               w -> case mwaWrite# mwa (word2Int# i) w s of
+                  s -> go mwa (i `plusWord#` 1##) s
+
+   in case newWordArray# (word2Int# nw +# (word2Int# nb /=# 0#)) s of
+         (# s, mwa #) -> case readMSB mwa s of
+            s -> case go mwa 0## s of
+               s -> case mwaTrimZeroes# mwa s of
+                  s -> unsafeFreezeByteArray# mwa s
+
+-- | Read a BigNat in base-256 big-endian representation from a ByteArray#.
+--
+-- The size is given in bytes.
+--
+-- Null higher limbs are automatically trimmed.
+bigNatFromByteArrayBE# :: Word# -> ByteArray# -> Word# -> State# s -> (# State# s, BigNat# #)
+{-# NOINLINE bigNatFromByteArrayBE# #-}
+bigNatFromByteArrayBE# 0## _  _    s = (# s, bigNatZero# (# #) #)
+bigNatFromByteArrayBE# sz  ba moff s =
+   let
+      !nw = sz `uncheckedShiftRL#` WORD_SIZE_BYTES_SHIFT#
+      !nb = sz `and#` WORD_SIZE_BYTES_MASK##
+
+      goMSB mwa s
+         | 0## <- nb
+         = s
+
+         | True
+         = case wordFromByteArrayBE# nb ba moff of
+            w -> mwaWrite# mwa (word2Int# nw) w s
+
+      go mwa i s
+         | isTrue# (i `eqWord#` nw)
+         = s
+
+         | k <- nw `minusWord#` 1## `minusWord#` i
+         , off <- (k `uncheckedShiftL#` WORD_SIZE_BYTES_SHIFT#) `plusWord#` nb
+         = case wordFromByteArrayBE# WORD_SIZE_IN_BYTES## ba (moff `plusWord#` off) of
+            w -> case mwaWrite# mwa (word2Int# i) w s of
+               s -> go mwa (i `plusWord#` 1##) s
+
+   in case newWordArray# (word2Int# nw +# (word2Int# nb /=# 0#)) s of
+         (# s, mwa #) -> case goMSB mwa s of
+            s -> case go mwa 0## s of
+               s -> case mwaTrimZeroes# mwa s of
+                  s -> unsafeFreezeByteArray# mwa s
+
+-- | Read a BigNat in base-256 representation from a ByteArray#.
+--
+-- The size is given in bytes.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Null higher limbs are automatically trimmed.
+bigNatFromByteArray# :: Word# -> ByteArray# -> Word# -> Bool# -> State# s -> (# State# s, BigNat# #)
+bigNatFromByteArray# sz ba off 0# s = bigNatFromByteArrayLE# sz ba off s
+bigNatFromByteArray# sz ba off _  s = bigNatFromByteArrayBE# sz ba off s
+
+
+
+
+-- | Create a BigNat# from a WordArray# containing /n/ limbs in
+-- least-significant-first order.
+--
+-- If possible 'WordArray#', will be used directly (i.e. shared
+-- /without/ cloning the 'WordArray#' into a newly allocated one)
+bigNatFromWordArray# :: WordArray# -> Word# -> BigNat#
+{-# NOINLINE bigNatFromWordArray# #-}
+bigNatFromWordArray# wa n0
+   | isTrue# (n `eqWord#` 0##)
+   = bigNatZero# (# #)
+
+   | isTrue# (r `eqWord#` 0##) -- i.e. wa is multiple of limb-size
+   , isTrue# (q `eqWord#` n)
+   = wa
+
+   | True = withNewWordArray# (word2Int# n) \mwa s ->
+               mwaArrayCopy# mwa 0# wa 0# (word2Int# n) s
+   where
+      !(# q, r #) = quotRemWord# (int2Word# (sizeofByteArray# wa))
+                                 WORD_SIZE_IN_BYTES##
+      -- find real size in Words by removing trailing null limbs
+      !n = real_size n0
+      real_size 0## = 0##
+      real_size i
+           | 0## <- bigNatIndex# wa (word2Int# (i `minusWord#` 1##))
+           = real_size (i `minusWord#` 1##)
+      real_size i = i
+
+
+-- | Create a BigNat from a WordArray# containing /n/ limbs in
+-- least-significant-first order.
+--
+-- If possible 'WordArray#', will be used directly (i.e. shared
+-- /without/ cloning the 'WordArray#' into a newly allocated one)
+bigNatFromWordArray :: WordArray# -> Word# -> BigNat
+bigNatFromWordArray wa n = BN# (bigNatFromWordArray# wa n)
+
+-------------------------------------------------
+-- Instances
+-------------------------------------------------
+
+instance Eq BigNat where
+   BN# a == BN# b = bigNatEq a b
+   BN# a /= BN# b = bigNatNe a b
+
+instance Ord BigNat where
+   (BN# a) `compare` (BN# b) = bigNatCompare a b
+   BN# a <  BN# b = bigNatLt a b
+   BN# a <= BN# b = bigNatLe a b
+   BN# a >  BN# b = bigNatGt a b
+   BN# a >= BN# b = bigNatGe a b
diff --git a/src/GHC/Internal/Bignum/BigNat.hs-boot b/src/GHC/Internal/Bignum/BigNat.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/BigNat.hs-boot
@@ -0,0 +1,23 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+
+module GHC.Internal.Bignum.BigNat where
+
+import GHC.Internal.Bignum.WordArray
+import GHC.Internal.Bignum.Primitives
+import GHC.Internal.Prim
+
+type BigNat# = WordArray#
+data BigNat = BN# { unBigNat :: BigNat# }
+
+bigNatIsZero# :: BigNat# -> Bool#
+bigNatSize# :: BigNat# -> Int#
+bigNatSubUnsafe :: BigNat# -> BigNat# -> BigNat#
+bigNatMulWord# :: BigNat# -> Word# -> BigNat#
+bigNatRem :: BigNat# -> BigNat# -> BigNat#
+bigNatRemWord# :: BigNat# -> Word# -> Word#
+bigNatShiftR# :: BigNat# -> Word# -> BigNat#
+bigNatShiftL# :: BigNat# -> Word# -> BigNat#
+bigNatCtz# :: BigNat# -> Word#
+bigNatCtzWord# :: BigNat# -> Word#
diff --git a/src/GHC/Internal/Bignum/Integer.hs b/src/GHC/Internal/Bignum/Integer.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Integer.hs
@@ -0,0 +1,1668 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE NegativeLiterals #-}
+{-# LANGUAGE BinaryLiterals #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE LambdaCase #-}
+
+-- |
+-- Module      :  GHC.Internal.Bignum.Integer
+-- Copyright   :  (c) Sylvain Henry 2019,
+--                (c) Herbert Valerio Riedel 2014
+-- License     :  BSD3
+--
+-- Maintainer  :  sylvain@haskus.fr
+-- Stability   :  provisional
+-- Portability :  non-portable (GHC Extensions)
+--
+-- The 'Integer' type.
+
+module GHC.Internal.Bignum.Integer
+    ( Integer(..)
+    , integerCheck
+    , integerCheck#
+
+      -- * Useful constants
+    , integerZero
+    , integerOne
+
+      -- * Conversion with...
+      -- ** 'Int'
+    , integerFromInt#
+    , integerFromInt
+    , integerToInt#
+    , integerToInt
+      -- ** 'BigNat'
+    , integerFromBigNat#
+    , integerFromBigNatNeg#
+    , integerFromBigNatSign#
+    , integerToBigNatSign#
+    , integerToBigNatClamp#
+      -- ** 'Word'
+    , integerFromWord#
+    , integerFromWord
+    , integerFromWordNeg#
+    , integerFromWordSign#
+    , integerToWord#
+    , integerToWord
+      -- ** 'Natural'
+    , integerFromNatural
+    , integerToNaturalClamp
+    , integerToNatural
+    , integerToNaturalThrow
+      -- ** 'Int64'/'Word64'
+    , integerFromInt64#
+    , integerFromWord64#
+    , integerToInt64#
+    , integerToWord64#
+      -- ** Floating-point
+    , integerDecodeDouble#
+    , integerEncodeDouble#
+    , integerEncodeDouble
+    , integerEncodeFloat#
+      -- ** 'Addr#'
+    , integerToAddr#
+    , integerToAddr
+    , integerFromAddr#
+    , integerFromAddr
+      -- ** Limbs
+    , integerFromWordList
+    , integerToMutableByteArray#
+    , integerToMutableByteArray
+    , integerFromByteArray#
+    , integerFromByteArray
+
+      -- * Predicates
+    , integerIsNegative#
+    , integerIsNegative
+    , integerIsZero
+    , integerIsOne
+
+      -- * Comparison
+    , integerNe
+    , integerEq
+    , integerLe
+    , integerLt
+    , integerGt
+    , integerGe
+    , integerEq#
+    , integerNe#
+    , integerGt#
+    , integerLe#
+    , integerLt#
+    , integerGe#
+    , integerCompare
+
+      -- * Arithmetic
+    , integerSub
+    , integerAdd
+    , integerMul
+    , integerNegate
+    , integerAbs
+    , integerSignum
+    , integerSignum#
+    , integerQuotRem#
+    , integerQuotRem
+    , integerQuot
+    , integerRem
+    , integerDivMod#
+    , integerDivMod
+    , integerDiv
+    , integerMod
+    , integerGcd
+    , integerLcm
+    , integerSqr
+    , integerLog2#
+    , integerLog2
+    , integerLogBaseWord#
+    , integerLogBaseWord
+    , integerLogBase#
+    , integerLogBase
+    , integerIsPowerOf2#
+    , integerGcde#
+    , integerGcde
+    , integerRecipMod#
+    , integerPowMod#
+
+      -- * Bit operations
+    , integerPopCount#
+    , integerBit#
+    , integerBit
+    , integerTestBit#
+    , integerTestBit
+    , integerShiftR#
+    , integerShiftR
+    , integerShiftL#
+    , integerShiftL
+    , integerOr
+    , integerXor
+    , integerAnd
+    , integerComplement
+
+      -- * Miscellaneous
+    , integerSizeInBase#
+    ) where
+
+#include "MachDeps.h"
+#include "WordSize.h"
+
+import GHC.Internal.Prim
+import GHC.Internal.Types
+import GHC.Internal.Classes
+import GHC.Internal.Magic
+import GHC.Internal.Bignum.Primitives
+import GHC.Internal.Bignum.BigNat
+import GHC.Internal.Bignum.Natural
+import qualified GHC.Internal.Bignum.Backend as Backend
+
+default ()
+
+-- | Arbitrary precision integers. In contrast with fixed-size integral types
+-- such as 'Int', the 'Integer' type represents the entire infinite range of
+-- integers.
+--
+-- Integers are stored in a kind of sign-magnitude form, hence do not expect
+-- two's complement form when using bit operations.
+--
+-- If the value is small (i.e., fits into an 'Int'), the 'IS' constructor is
+-- used. Otherwise 'IP' and 'IN' constructors are used to store a 'BigNat'
+-- representing the positive or the negative value magnitude, respectively.
+--
+-- Invariant: 'IP' and 'IN' are used iff the value does not fit in 'IS'.
+data Integer
+   = IS !Int#    -- ^ iff value in @[minBound::'Int', maxBound::'Int']@ range
+   | IP !BigNat# -- ^ iff value in @]maxBound::'Int', +inf[@ range
+   | IN !BigNat# -- ^ iff value in @]-inf, minBound::'Int'[@ range
+
+
+-- | Check Integer invariants
+integerCheck# :: Integer -> Bool#
+integerCheck# (IS  _) = 1#
+integerCheck# (IP bn) = bigNatCheck# bn &&# (bn `bigNatGtWord#` INT_MAXBOUND##)
+integerCheck# (IN bn) = bigNatCheck# bn &&# (bn `bigNatGtWord#` ABS_INT_MINBOUND##)
+
+-- | Check Integer invariants
+integerCheck :: Integer -> Bool
+integerCheck i = isTrue# (integerCheck# i)
+
+-- | Integer Zero
+integerZero :: Integer
+integerZero = IS 0#
+
+-- | Integer One
+integerOne :: Integer
+integerOne = IS 1#
+
+---------------------------------------------------------------------
+-- Conversions
+---------------------------------------------------------------------
+
+-- | Create a positive Integer from a BigNat
+integerFromBigNat# :: BigNat# -> Integer
+integerFromBigNat# !bn
+   | bigNatIsZero bn
+   = integerZero
+
+   | isTrue# (bn `bigNatLeWord#` INT_MAXBOUND##)
+   = IS (word2Int# (bigNatIndex# bn 0#))
+
+   | True
+   = IP bn
+
+-- | Create a negative Integer from a BigNat
+integerFromBigNatNeg# :: BigNat# -> Integer
+integerFromBigNatNeg# !bn
+   | bigNatIsZero bn
+   = integerZero
+
+   | 1# <- bigNatSize# bn
+   , i <- negateInt# (word2Int# (bigNatIndex# bn 0#))
+   , isTrue# (i <=# 0#)
+   = IS i
+
+   | True
+   = IN bn
+
+-- | Create an Integer from a sign-bit and a BigNat
+integerFromBigNatSign# :: Int# -> BigNat# -> Integer
+integerFromBigNatSign# !sign !bn
+   | 0# <- sign
+   = integerFromBigNat# bn
+
+   | True
+   = integerFromBigNatNeg# bn
+
+-- | Convert an Integer into a sign-bit and a BigNat
+integerToBigNatSign# :: Integer -> (# Int#, BigNat# #)
+integerToBigNatSign# = \case
+   IS x
+      | isTrue# (x >=# 0#)
+      -> (# 0#, bigNatFromWord# (int2Word# x) #)
+      | True
+      -> (# 1#, bigNatFromWord# (int2Word# (negateInt# x)) #)
+   IP x -> (# 0#, x #)
+   IN x -> (# 1#, x #)
+
+-- | Convert an Integer into a BigNat.
+--
+-- Return 0 for negative Integers.
+integerToBigNatClamp# :: Integer -> BigNat#
+integerToBigNatClamp# (IP x) = x
+integerToBigNatClamp# (IS x)
+   | isTrue# (x >=# 0#)     = bigNatFromWord# (int2Word# x)
+integerToBigNatClamp# _     = bigNatZero# (# #)
+
+-- | Create an Integer from an Int#
+integerFromInt# :: Int# -> Integer
+integerFromInt# i = IS i
+
+-- | Create an Integer from an Int
+integerFromInt :: Int -> Integer
+integerFromInt (I# i) = IS i
+
+-- | Truncates 'Integer' to least-significant 'Int#'
+integerToInt# :: Integer -> Int#
+{-# NOINLINE integerToInt# #-}
+integerToInt# (IS i) = i
+integerToInt# (IP b) = word2Int# (bigNatToWord# b)
+integerToInt# (IN b) = negateInt# (word2Int# (bigNatToWord# b))
+
+-- | Truncates 'Integer' to least-significant 'Int#'
+integerToInt :: Integer -> Int
+integerToInt i = I# (integerToInt# i)
+
+-- | Convert a Word# into an Integer
+integerFromWord# :: Word# -> Integer
+{-# NOINLINE integerFromWord# #-}
+integerFromWord# w
+   | i <- word2Int# w
+   , isTrue# (i >=# 0#)
+   = IS i
+
+   | True
+   = IP (bigNatFromWord# w)
+
+-- | Convert a Word into an Integer
+integerFromWord :: Word -> Integer
+integerFromWord (W# w) = integerFromWord# w
+
+-- | Create a negative Integer with the given Word magnitude
+integerFromWordNeg# :: Word# -> Integer
+integerFromWordNeg# w
+  | isTrue# (w `leWord#` ABS_INT_MINBOUND##)
+  = IS (negateInt# (word2Int# w))
+
+  | True
+  = IN (bigNatFromWord# w)
+
+-- | Create an Integer from a sign and a Word magnitude
+integerFromWordSign# :: Int# -> Word# -> Integer
+integerFromWordSign# 0# w = integerFromWord# w
+integerFromWordSign# _  w = integerFromWordNeg# w
+
+-- | Truncate an Integer into a Word
+integerToWord# :: Integer -> Word#
+{-# NOINLINE integerToWord# #-}
+integerToWord# (IS i)  = int2Word# i
+integerToWord# (IP bn) = bigNatToWord# bn
+integerToWord# (IN bn) = int2Word# (negateInt# (word2Int# (bigNatToWord# bn)))
+
+-- | Truncate an Integer into a Word
+integerToWord :: Integer -> Word
+integerToWord !i = W# (integerToWord# i)
+
+-- | Convert a Natural into an Integer
+integerFromNatural :: Natural -> Integer
+{-# NOINLINE integerFromNatural #-}
+integerFromNatural (NS x) = integerFromWord# x
+integerFromNatural (NB x) = IP x
+
+-- | Convert a list of Word into an Integer
+integerFromWordList :: Bool -> [Word] -> Integer
+integerFromWordList True  ws = integerFromBigNatNeg# (bigNatFromWordList ws)
+integerFromWordList False ws = integerFromBigNat#    (bigNatFromWordList ws)
+
+-- | Convert an Integer into a Natural
+--
+-- Return 0 for negative Integers.
+integerToNaturalClamp :: Integer -> Natural
+{-# NOINLINE integerToNaturalClamp #-}
+integerToNaturalClamp (IS x)
+   | isTrue# (x <# 0#) = naturalZero
+   | True              = naturalFromWord# (int2Word# x)
+integerToNaturalClamp (IP x) = naturalFromBigNat# x
+integerToNaturalClamp (IN _) = naturalZero
+
+-- | Convert an Integer into a Natural
+--
+-- Return absolute value
+integerToNatural :: Integer -> Natural
+{-# NOINLINE integerToNatural #-}
+integerToNatural (IS x) = naturalFromWord# (wordFromAbsInt# x)
+integerToNatural (IP x) = naturalFromBigNat# x
+integerToNatural (IN x) = naturalFromBigNat# x
+
+-- | Convert an Integer into a Natural
+--
+-- Throw an Underflow exception if input is negative.
+integerToNaturalThrow :: Integer -> Natural
+{-# NOINLINE integerToNaturalThrow #-}
+integerToNaturalThrow (IS x)
+  | isTrue# (x <# 0#) = raiseUnderflow
+  | True              = naturalFromWord# (int2Word# x)
+integerToNaturalThrow (IP x) = naturalFromBigNat# x
+integerToNaturalThrow (IN _) = raiseUnderflow
+
+---------------------------------------------------------------------
+-- Predicates
+---------------------------------------------------------------------
+
+{- Note [Bangs in Integer functions]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In this module some functions have banged arguments.  E.g.
+    integerNe !x !y = isTrue# (integerNe# x y)
+This will ensure that both argument are evaluated first, and then pattern
+matching takes place just a multi-way jump.
+
+In some cases (e.g. integerMul, integerSub) this actually makes the function
+strict when it would otherwise not be; but in other cases (e.g integerNe) the
+function is strict in both arguments anyway.  In the latter case it's a bit moot
+whether to have the bangs or not; so this Note just documents that there is no
+Deep Reason why they have to be there.  See Note Note [Case-to-let for
+strictly-used binders] in GHC.Core.Opt.Simplify.Iteration for discussion about
+evals on strictly-used binders.
+
+I have not pointed to this Note from every such use.  There are a lot of them!
+-}
+
+-- | Negative predicate
+integerIsNegative# :: Integer -> Bool#
+integerIsNegative# (IS i#) = i# <# 0#
+integerIsNegative# (IP _)  = 0#
+integerIsNegative# (IN _)  = 1#
+
+-- | Negative predicate
+integerIsNegative :: Integer -> Bool
+integerIsNegative !i = isTrue# (integerIsNegative# i)
+   -- Note [Bangs in Integer functions]
+
+-- | Zero predicate
+integerIsZero :: Integer -> Bool
+integerIsZero (IS 0#) = True
+integerIsZero _       = False
+
+-- | One predicate
+integerIsOne :: Integer -> Bool
+integerIsOne (IS 1#) = True
+integerIsOne _       = False
+
+-- | Not-equal predicate.
+integerNe :: Integer -> Integer -> Bool
+integerNe !x !y = isTrue# (integerNe# x y)
+   -- Note [Bangs in Integer functions]
+
+-- | Equal predicate.
+integerEq :: Integer -> Integer -> Bool
+integerEq !x !y = isTrue# (integerEq# x y)
+   -- See Note [Bangs in Integer functions]
+
+-- | Lower-or-equal predicate.
+integerLe :: Integer -> Integer -> Bool
+integerLe !x !y = isTrue# (integerLe# x y)
+   -- See Note [Bangs in Integer functions]
+
+-- | Lower predicate.
+integerLt :: Integer -> Integer -> Bool
+integerLt !x !y = isTrue# (integerLt# x y)
+   -- See Note [Bangs in Integer functions]
+
+-- | Greater predicate.
+integerGt :: Integer -> Integer -> Bool
+integerGt !x !y = isTrue# (integerGt# x y)
+   -- See Note [Bangs in Integer functions]
+
+-- | Greater-or-equal predicate.
+integerGe :: Integer -> Integer -> Bool
+integerGe !x !y = isTrue# (integerGe# x y)
+   -- See Note [Bangs in Integer functions]
+
+-- | Equal predicate.
+integerEq# :: Integer -> Integer -> Bool#
+integerEq# (IS x) (IS y) = x ==# y
+integerEq# (IN x) (IN y) = bigNatEq# x y
+integerEq# (IP x) (IP y) = bigNatEq# x y
+integerEq# _       _     = 0#
+
+-- | Not-equal predicate.
+integerNe# :: Integer -> Integer -> Bool#
+integerNe# (IS x) (IS y) = x /=# y
+integerNe# (IN x) (IN y) = bigNatNe# x y
+integerNe# (IP x) (IP y) = bigNatNe# x y
+integerNe# _       _     = 1#
+
+-- | Greater predicate.
+integerGt# :: Integer -> Integer -> Bool#
+integerGt# (IS x) (IS y)                  = x ># y
+integerGt# x y | GT <- integerCompare x y = 1#
+integerGt# _ _                            = 0#
+
+-- | Lower-or-equal predicate.
+integerLe# :: Integer -> Integer -> Bool#
+integerLe# (IS x) (IS y)                  = x <=# y
+integerLe# x y | GT <- integerCompare x y = 0#
+integerLe# _ _                            = 1#
+
+-- | Lower predicate.
+integerLt# :: Integer -> Integer -> Bool#
+integerLt# (IS x) (IS y)                  = x <# y
+integerLt# x y | LT <- integerCompare x y = 1#
+integerLt# _ _                            = 0#
+
+-- | Greater-or-equal predicate.
+integerGe# :: Integer -> Integer -> Bool#
+integerGe# (IS x) (IS y)                  = x >=# y
+integerGe# x y | LT <- integerCompare x y = 0#
+integerGe# _ _                            = 1#
+
+instance Eq Integer where
+   (==) = integerEq
+   (/=) = integerNe
+
+-- | Compare two Integer
+integerCompare :: Integer -> Integer -> Ordering
+{-# INLINEABLE integerCompare #-}
+integerCompare (IS x) (IS y) = compareInt# x y
+integerCompare (IP x) (IP y) = bigNatCompare x y
+integerCompare (IN x) (IN y) = bigNatCompare y x
+integerCompare (IS _) (IP _) = LT
+integerCompare (IS _) (IN _) = GT
+integerCompare (IP _) (IS _) = GT
+integerCompare (IN _) (IS _) = LT
+integerCompare (IP _) (IN _) = GT
+integerCompare (IN _) (IP _) = LT
+
+instance Ord Integer where
+   compare = integerCompare
+   (<)     = integerLt
+   (<=)    = integerLe
+   (>)     = integerGt
+   (>=)    = integerGe
+
+---------------------------------------------------------------------
+-- Operations
+---------------------------------------------------------------------
+
+-- | Subtract one 'Integer' from another.
+integerSub :: Integer -> Integer -> Integer
+{-# NOINLINE integerSub #-}
+integerSub !x      (IS 0#) = x     -- Note [Bangs in Integer functions]
+integerSub (IS x#) (IS y#)
+  = case subIntC# x# y# of
+    (# z#, 0# #) -> IS z#
+    (# 0#, _  #) -> IN (bigNatFromWord2# 1## 0##)
+    (# z#, _  #)
+      | isTrue# (z# ># 0#)
+      -> IN (bigNatFromWord# ( (int2Word# (negateInt# z#))))
+      | True
+      -> IP (bigNatFromWord# ( (int2Word# z#)))
+integerSub (IS x#) (IP y)
+  | isTrue# (x# >=# 0#)
+  = integerFromBigNatNeg# (bigNatSubWordUnsafe# y (int2Word# x#))
+  | True
+  = IN (bigNatAddWord# y (int2Word# (negateInt# x#)))
+integerSub (IS x#) (IN y)
+  | isTrue# (x# >=# 0#)
+  = IP (bigNatAddWord# y (int2Word# x#))
+  | True
+  = integerFromBigNat# (bigNatSubWordUnsafe# y (int2Word# (negateInt# x#)))
+integerSub (IP x) (IP y)
+  = case bigNatCompare x y of
+    LT -> integerFromBigNatNeg# (bigNatSubUnsafe y x)
+    EQ -> IS 0#
+    GT -> integerFromBigNat# (bigNatSubUnsafe x y)
+integerSub (IP x) (IN y) = IP (bigNatAdd x y)
+integerSub (IN x) (IP y) = IN (bigNatAdd x y)
+integerSub (IN x) (IN y)
+  = case bigNatCompare x y of
+    LT -> integerFromBigNat# (bigNatSubUnsafe y x)
+    EQ -> IS 0#
+    GT -> integerFromBigNatNeg# (bigNatSubUnsafe x y)
+integerSub (IP x) (IS y#)
+  | isTrue# (y# >=# 0#)
+  = integerFromBigNat# (bigNatSubWordUnsafe# x (int2Word# y#))
+  | True
+  = IP (bigNatAddWord# x (int2Word# (negateInt# y#)))
+integerSub (IN x) (IS y#)
+  | isTrue# (y# >=# 0#)
+  = IN (bigNatAddWord# x (int2Word# y#))
+  | True
+  = integerFromBigNatNeg# (bigNatSubWordUnsafe# x (int2Word# (negateInt# y#)))
+
+-- | Add two 'Integer's
+integerAdd :: Integer -> Integer -> Integer
+{-# NOINLINE integerAdd #-}
+integerAdd !x      (IS 0#) = x
+integerAdd (IS 0#) y       = y
+integerAdd (IS x#) (IS y#)
+  = case addIntC# x# y# of
+    (# z#, 0# #) -> IS z#
+    (# 0#, _  #) -> IN (bigNatFromWord2# 1## 0##) -- 2*minBound::Int
+    (# z#, _  #)
+      | isTrue# (z# ># 0#) -> IN (bigNatFromWord# ( (int2Word# (negateInt# z#))))
+      | True               -> IP (bigNatFromWord# ( (int2Word# z#)))
+integerAdd y@(IS _) x = integerAdd x y
+integerAdd (IP x) (IP y) = IP (bigNatAdd x y)
+integerAdd (IN x) (IN y) = IN (bigNatAdd x y)
+integerAdd (IP x) (IS y#) -- edge-case: @(maxBound+1) + minBound == 0@
+  | isTrue# (y# >=# 0#) = IP (bigNatAddWord# x (int2Word# y#))
+  | True                = integerFromBigNat# (bigNatSubWordUnsafe# x (int2Word#
+                                                              (negateInt# y#)))
+integerAdd (IN x) (IS y#) -- edge-case: @(minBound-1) + maxBound == -2@
+  | isTrue# (y# >=# 0#) = integerFromBigNatNeg# (bigNatSubWordUnsafe# x (int2Word# y#))
+  | True                = IN (bigNatAddWord# x (int2Word# (negateInt# y#)))
+integerAdd y@(IN _) x@(IP _) = integerAdd x y
+integerAdd (IP x) (IN y)
+    = case bigNatCompare x y of
+      LT -> integerFromBigNatNeg# (bigNatSubUnsafe y x)
+      EQ -> IS 0#
+      GT -> integerFromBigNat# (bigNatSubUnsafe x y)
+
+-- | Multiply two 'Integer's
+integerMul :: Integer -> Integer -> Integer
+{-# NOINLINE integerMul #-}
+integerMul !_       (IS 0#)  = IS 0#  -- Note [Bangs in Integer functions]
+integerMul (IS 0#)  _        = IS 0#
+integerMul x        (IS 1#)  = x
+integerMul (IS 1#)  y        = y
+integerMul x        (IS -1#) = integerNegate x
+integerMul (IS -1#) y        = integerNegate y
+integerMul (IS x)   (IS y)   = case timesInt2# x y of
+   (# 0#, _h, l #) -> IS l
+   (# _ ,  h, l #)
+      | isTrue# (h >=# 0#)
+      -> IP (bigNatFromWord2# (int2Word# h) (int2Word# l))
+      | True
+      -> let
+          -- two's complement of a two-word negative Int:
+          --   l' = complement l + 1
+          --   h' = complement h + carry
+          !(# l',c #) = addWordC# (not# (int2Word# l)) 1##
+          !h'         = int2Word# c `plusWord#` not# (int2Word# h)
+         in IN (bigNatFromWord2# h' l')
+integerMul x@(IS _) y    = integerMul y x
+integerMul (IP x) (IP y) = IP (bigNatMul x y)
+integerMul (IP x) (IN y) = IN (bigNatMul x y)
+integerMul (IP x) (IS y)
+  | isTrue# (y >=# 0#)   = IP (bigNatMulWord# x (int2Word# y))
+  | True                 = IN (bigNatMulWord# x (int2Word# (negateInt# y)))
+integerMul (IN x) (IN y) = IP (bigNatMul x y)
+integerMul (IN x) (IP y) = IN (bigNatMul x y)
+integerMul (IN x) (IS y)
+  | isTrue# (y >=# 0#)   = IN (bigNatMulWord# x (int2Word# y))
+  | True                 = IP (bigNatMulWord# x (int2Word# (negateInt# y)))
+
+-- | Negate 'Integer'.
+--
+-- One edge-case issue to take into account is that Int's range is not
+-- symmetric around 0.  I.e. @minBound+maxBound = -1@
+--
+-- IP is used iff n > maxBound::Int
+-- IN is used iff n < minBound::Int
+integerNegate :: Integer -> Integer
+{-# NOINLINE integerNegate #-}
+integerNegate (IN b)             = IP b
+integerNegate (IS INT_MINBOUND#) = IP (bigNatFromWord# ABS_INT_MINBOUND##)
+integerNegate (IS i)             = IS (negateInt# i)
+integerNegate (IP b)
+  | isTrue# (bigNatEqWord# b ABS_INT_MINBOUND##) = IS INT_MINBOUND#
+  | True                                         = IN b
+
+{-# RULES
+"integerNegate/integerNegate" forall x. integerNegate (integerNegate x) = x
+#-}
+
+-- | Compute absolute value of an 'Integer'
+integerAbs :: Integer -> Integer
+{-# NOINLINE integerAbs #-}
+integerAbs   (IN i)     = IP i
+integerAbs n@(IP _)     = n
+integerAbs n@(IS i)
+   | isTrue# (i >=# 0#) = n
+   | INT_MINBOUND# <- i = IP (bigNatFromWord# ABS_INT_MINBOUND##)
+   | True               = IS (negateInt# i)
+
+
+-- | Return @-1@, @0@, and @1@ depending on whether argument is
+-- negative, zero, or positive, respectively
+integerSignum :: Integer -> Integer
+integerSignum !j = IS (integerSignum# j)
+     -- Note [Bangs in Integer functions]
+
+-- | Return @-1#@, @0#@, and @1#@ depending on whether argument is
+-- negative, zero, or positive, respectively
+integerSignum# :: Integer -> Int#
+integerSignum# (IN _)  = -1#
+integerSignum# (IS i#) = sgnI# i#
+integerSignum# (IP _ ) =  1#
+
+-- | Count number of set bits. For negative arguments returns
+-- the negated population count of the absolute value.
+integerPopCount# :: Integer -> Int#
+{-# NOINLINE integerPopCount# #-}
+integerPopCount# (IS i)
+   | isTrue# (i >=# 0#)  = word2Int# (popCntI# i)
+   | True                = negateInt# (word2Int# (popCntI# (negateInt# i)))
+integerPopCount# (IP bn) = word2Int# (bigNatPopCount# bn)
+integerPopCount# (IN bn) = negateInt# (word2Int# (bigNatPopCount# bn))
+
+-- | Positive 'Integer' for which only /n/-th bit is set
+integerBit# :: Word# -> Integer
+{-# NOINLINE integerBit# #-}
+integerBit# i
+  | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
+  = IS (uncheckedIShiftL# 1# (word2Int# i))
+
+  | True = IP (bigNatBit# i)
+
+-- | 'Integer' for which only /n/-th bit is set
+integerBit :: Word -> Integer
+integerBit (W# i) = integerBit# i
+
+-- | Test if /n/-th bit is set.
+--
+-- Fake 2's complement for negative values (might be slow)
+integerTestBit# :: Integer -> Word# -> Bool#
+{-# NOINLINE integerTestBit# #-}
+integerTestBit# (IS x) i
+   | isTrue# (i `ltWord#` WORD_SIZE_IN_BITS##)
+   = testBitI# x i
+   | True
+   = x <# 0#
+integerTestBit# (IP x) i = bigNatTestBit# x i
+integerTestBit# (IN x) i
+   | isTrue# (iw >=# n)
+   = 1#
+   -- if all the limbs j with j < iw are null, then we have to consider the
+   -- carry of the 2's complement conversion. Otherwise we just have to return
+   -- the inverse of the bit test
+   | allZ iw = testBitW# (xi `minusWord#` 1##) ib ==# 0#
+   | True    = testBitW# xi ib ==# 0#
+   where
+      !xi  = bigNatIndex# x iw
+      !n   = bigNatSize# x
+      !iw  = word2Int# (i `uncheckedShiftRL#` WORD_SIZE_BITS_SHIFT#)
+      !ib  = i `and#` WORD_SIZE_BITS_MASK##
+
+      allZ 0# = True
+      allZ j | isTrue# (bigNatIndex# x (j -# 1#) `eqWord#` 0##) = allZ (j -# 1#)
+             | True                 = False
+
+-- | Test if /n/-th bit is set. For negative Integers it tests the n-th bit of
+-- the negated argument.
+--
+-- Fake 2's complement for negative values (might be slow)
+integerTestBit :: Integer -> Word -> Bool
+integerTestBit !i (W# n) = isTrue# (integerTestBit# i n)
+
+-- | Shift-right operation
+--
+-- Fake 2's complement for negative values (might be slow)
+integerShiftR# :: Integer -> Word# -> Integer
+{-# NOINLINE integerShiftR# #-}
+integerShiftR# !x      0## = x   -- Note [Bangs in Integer functions]
+integerShiftR# (IS i)  n   = IS (iShiftRA# i (word2Int# n))
+  where
+    iShiftRA# a b
+      | isTrue# (b >=# WORD_SIZE_IN_BITS#) = (a <# 0#) *# (-1#)
+      | True                               = a `uncheckedIShiftRA#` b
+integerShiftR# (IP bn) n   = integerFromBigNat# (bigNatShiftR# bn n)
+integerShiftR# (IN bn) n   =
+   case integerFromBigNatNeg# (bigNatShiftRNeg# bn n) of
+      IS 0# -> IS -1#
+      r     -> r
+
+-- | Shift-right operation
+--
+-- Fake 2's complement for negative values (might be slow)
+integerShiftR :: Integer -> Word -> Integer
+integerShiftR !x (W# w) = integerShiftR# x w
+   -- Note [Bangs in Integer functions]
+
+-- | Shift-left operation
+integerShiftL# :: Integer -> Word# -> Integer
+{-# NOINLINE integerShiftL# #-}
+integerShiftL# !x      0## = x  -- Note [Bangs in Integer functions]
+integerShiftL# (IS 0#) _   = IS 0#
+integerShiftL# (IS 1#) n   = integerBit# n
+integerShiftL# (IS i)  n
+  | isTrue# (i >=# 0#) = integerFromBigNat#    (bigNatShiftL# (bigNatFromWord# (int2Word# i)) n)
+  | True               = integerFromBigNatNeg# (bigNatShiftL# (bigNatFromWord# (int2Word# (negateInt# i))) n)
+integerShiftL# (IP bn) n   = IP (bigNatShiftL# bn n)
+integerShiftL# (IN bn) n   = IN (bigNatShiftL# bn n)
+
+-- | Shift-left operation
+--
+-- Remember that bits are stored in sign-magnitude form, hence the behavior of
+-- negative Integers is different from negative Int's behavior.
+integerShiftL :: Integer -> Word -> Integer
+integerShiftL !x (W# w) = integerShiftL# x w
+    -- Note [Bangs in Integer functions]
+
+-- | Bitwise OR operation
+--
+-- Fake 2's complement for negative values (might be slow)
+integerOr :: Integer -> Integer -> Integer
+{-# NOINLINE integerOr #-}
+integerOr a b = case a of
+   IS  0# -> b
+   IS -1# -> IS -1#
+   IS  x  -> case b of
+               IS  0# -> a
+               IS -1# -> IS -1#
+               IS  y  -> IS (orI# x y)
+               IP  y
+                  | isTrue# (x >=# 0#) -> IP (bigNatOrWord# y (int2Word# x))
+                  | True               -> integerFromBigNatNeg#
+                                             (bigNatAddWord#
+                                                (bigNatAndNot -- use De Morgan's laws
+                                                   (bigNatFromWord#
+                                                      (int2Word# (negateInt# x) `minusWord#` 1##))
+                                                   y)
+                                                1##)
+               IN y
+                  | isTrue# (x >=# 0#) -> integerFromBigNatNeg#
+                                             (bigNatAddWord#
+                                                (bigNatAndNotWord# -- use De Morgan's laws
+                                                   (bigNatSubWordUnsafe# y 1##)
+                                                   (int2Word# x))
+                                                1##)
+                  | True               -> integerFromBigNatNeg#
+                                             (bigNatAddWord#
+                                                (bigNatAndWord#  -- use De Morgan's laws
+                                                   (bigNatSubWordUnsafe# y 1##)
+                                                   (int2Word# (negateInt# x) `minusWord#` 1##))
+                                                1##)
+   IP  x  -> case b of
+               IS _ -> integerOr b a
+               IP y -> IP (bigNatOr x y)
+               IN y -> integerFromBigNatNeg#
+                        (bigNatAddWord#
+                           (bigNatAndNot -- use De Morgan's laws
+                              (bigNatSubWordUnsafe# y 1##)
+                              x)
+                           1##)
+   IN  x  -> case b of
+               IS _ -> integerOr b a
+               IN y -> integerFromBigNatNeg#
+                        (bigNatAddWord#
+                           (bigNatAnd  -- use De Morgan's laws
+                              (bigNatSubWordUnsafe# x 1##)
+                              (bigNatSubWordUnsafe# y 1##))
+                           1##)
+               IP y -> integerFromBigNatNeg#
+                        (bigNatAddWord#
+                           (bigNatAndNot -- use De Morgan's laws
+                              (bigNatSubWordUnsafe# x 1##)
+                              y)
+                           1##)
+
+
+-- | Bitwise XOR operation
+--
+-- Fake 2's complement for negative values (might be slow)
+integerXor :: Integer -> Integer -> Integer
+{-# NOINLINE integerXor #-}
+integerXor a b = case a of
+   IS  0# -> b
+   IS -1# -> integerComplement b
+   IS x   -> case b of
+               IS  0# -> a
+               IS -1# -> integerComplement a
+               IS y   -> IS (xorI# x y)
+               IP y
+                  | isTrue# (x >=# 0#) -> integerFromBigNat# (bigNatXorWord# y (int2Word# x))
+                  | True               -> integerFromBigNatNeg#
+                                             (bigNatAddWord#
+                                                (bigNatXorWord#
+                                                   y
+                                                   (int2Word# (negateInt# x) `minusWord#` 1##))
+                                                1##)
+               IN y
+                  | isTrue# (x >=# 0#) -> integerFromBigNatNeg#
+                                             (bigNatAddWord#
+                                                (bigNatXorWord#
+                                                   (bigNatSubWordUnsafe# y 1##)
+                                                   (int2Word# x))
+                                                1##)
+                  | True               -> integerFromBigNat#
+                                             (bigNatXorWord# -- xor (not x) (not y) = xor x y
+                                                (bigNatSubWordUnsafe# y 1##)
+                                                (int2Word# (negateInt# x) `minusWord#` 1##))
+   IP x   -> case b of
+               IS _ -> integerXor b a
+               IP y -> integerFromBigNat# (bigNatXor x y)
+               IN y -> integerFromBigNatNeg#
+                        (bigNatAddWord#
+                           (bigNatXor
+                              x
+                              (bigNatSubWordUnsafe# y 1##))
+                           1##)
+   IN x   -> case b of
+               IS _ -> integerXor b a
+               IN y -> integerFromBigNat#
+                        (bigNatXor -- xor (not x) (not y) = xor x y
+                           (bigNatSubWordUnsafe# x 1##)
+                           (bigNatSubWordUnsafe# y 1##))
+               IP y -> integerFromBigNatNeg#
+                        (bigNatAddWord#
+                           (bigNatXor
+                              y
+                              (bigNatSubWordUnsafe# x 1##))
+                           1##)
+
+
+
+-- | Bitwise AND operation
+--
+-- Fake 2's complement for negative values (might be slow)
+integerAnd :: Integer -> Integer -> Integer
+{-# NOINLINE integerAnd #-}
+integerAnd a b = case a of
+   IS 0#  -> IS 0#
+   IS -1# -> b
+   IS x   -> case b of
+               IS  0# -> IS 0#
+               IS -1# -> a
+               IS y   -> IS (andI# x y)
+               IP y   -> integerFromBigNat# (bigNatAndInt# y x)
+               IN y
+                  | isTrue# (x >=# 0#) -> integerFromWord# (int2Word# x `andNot#` (indexWordArray# y 0# `minusWord#` 1##))
+                  | True               -> integerFromBigNatNeg#
+                                             (bigNatAddWord#
+                                                (bigNatOrWord#  -- use De Morgan's laws
+                                                   (bigNatSubWordUnsafe# y 1##)
+                                                   (wordFromAbsInt# x `minusWord#` 1##))
+                                                1##)
+   IP x   -> case b of
+               IS _ -> integerAnd b a
+               IP y -> integerFromBigNat# (bigNatAnd x y)
+               IN y -> integerFromBigNat# (bigNatAndNot x (bigNatSubWordUnsafe# y 1##))
+   IN x   -> case b of
+               IS _ -> integerAnd b a
+               IN y -> integerFromBigNatNeg#
+                        (bigNatAddWord#
+                           (bigNatOr  -- use De Morgan's laws
+                              (bigNatSubWordUnsafe# x 1##)
+                              (bigNatSubWordUnsafe# y 1##))
+                           1##)
+               IP y -> integerFromBigNat# (bigNatAndNot y (bigNatSubWordUnsafe# x 1##))
+
+
+
+-- | Binary complement of the
+integerComplement :: Integer -> Integer
+{-# NOINLINE integerComplement #-}
+integerComplement (IS x) = IS (notI# x)
+integerComplement (IP x) = IN (bigNatAddWord# x 1##)
+integerComplement (IN x) = IP (bigNatSubWordUnsafe# x 1##)
+
+
+-- | Simultaneous 'integerQuot' and 'integerRem'.
+--
+-- Divisor must be non-zero otherwise the GHC runtime will terminate
+-- with a division-by-zero fault.
+integerQuotRem# :: Integer -> Integer -> (# Integer, Integer #)
+{-# NOINLINE integerQuotRem# #-}
+integerQuotRem# !n      (IS 1#) = (# n, IS 0# #) -- Note [Bangs in Integer functions]
+integerQuotRem# !n     (IS -1#) = let !q = integerNegate n in (# q, (IS 0#) #)
+integerQuotRem# !_      (IS 0#) = case raiseDivZero of
+                                    !_ -> (# IS 0#, IS 0# #)
+                                    -- see Note [ghc-bignum exceptions] in GHC.Internal.Bignum.Primitives
+integerQuotRem# (IS 0#) _       = (# IS 0#, IS 0# #)
+integerQuotRem# (IS n#) (IS d#) = case quotRemInt# n# d# of
+    (# q#, r# #) -> (# IS q#, IS r# #)
+integerQuotRem# (IP n)  (IP d)  = case bigNatQuotRem# n d of
+    (# q, r #) -> (# integerFromBigNat# q, integerFromBigNat# r #)
+integerQuotRem# (IP n)  (IN d)  = case bigNatQuotRem# n d of
+    (# q, r #) -> (# integerFromBigNatNeg# q, integerFromBigNat# r #)
+integerQuotRem# (IN n)  (IN d)  = case bigNatQuotRem# n d of
+    (# q, r #) -> (# integerFromBigNat# q, integerFromBigNatNeg# r #)
+integerQuotRem# (IN n)  (IP d)  = case bigNatQuotRem# n d of
+    (# q, r #) -> (# integerFromBigNatNeg# q, integerFromBigNatNeg# r #)
+integerQuotRem# (IP n)  (IS d#)
+  | isTrue# (d# >=# 0#) = case bigNatQuotRemWord# n (int2Word# d#) of
+      (# q, r# #) -> (# integerFromBigNat# q, integerFromWord# r# #)
+  | True                = case bigNatQuotRemWord# n (int2Word# (negateInt# d#)) of
+      (# q, r# #) -> (# integerFromBigNatNeg# q, integerFromWord# r# #)
+integerQuotRem# (IN n)  (IS d#)
+  | isTrue# (d# >=# 0#) = case bigNatQuotRemWord# n (int2Word# d#) of
+      (# q, r# #) -> (# integerFromBigNatNeg# q, integerFromWordNeg# r# #)
+  | True                = case bigNatQuotRemWord# n (int2Word# (negateInt# d#)) of
+      (# q, r# #) -> (# integerFromBigNat# q, integerFromWordNeg# r# #)
+integerQuotRem# n@(IS _) (IN _) = (# IS 0#, n #) -- since @n < d@
+integerQuotRem# n@(IS n#) (IP d) -- need to account for (IS minBound)
+    | isTrue# (n# ># 0#)                                    = (# IS 0#, n #)
+    | isTrue# (bigNatGtWord# d (int2Word# (negateInt# n#))) = (# IS 0#, n #)
+    | True {- abs(n) == d -}                                = (# IS -1#, IS 0# #)
+
+-- | Simultaneous 'integerQuot' and 'integerRem'.
+--
+-- Divisor must be non-zero otherwise the GHC runtime will terminate
+-- with a division-by-zero fault.
+integerQuotRem :: Integer -> Integer -> (Integer, Integer)
+integerQuotRem !x !y = case integerQuotRem# x y of
+  -- Note [Bangs in Integer functions]
+  (# q, r #) -> (q, r)
+
+
+integerQuot :: Integer -> Integer -> Integer
+{-# NOINLINE integerQuot #-}
+integerQuot !n      (IS 1#)  = n  -- Note [Bangs in Integer functions]
+integerQuot !n      (IS -1#) = integerNegate n
+integerQuot !_      (IS 0#)  = raiseDivZero
+integerQuot (IS 0#) _        = IS 0#
+integerQuot (IS n#) (IS d#)  = IS (quotInt# n# d#)
+integerQuot (IP n)  (IS d#)
+  | isTrue# (d# >=# 0#) = integerFromBigNat#    (bigNatQuotWord# n (int2Word# d#))
+  | True                = integerFromBigNatNeg# (bigNatQuotWord# n
+                                              (int2Word# (negateInt# d#)))
+integerQuot (IN n)   (IS d#)
+  | isTrue# (d# >=# 0#) = integerFromBigNatNeg# (bigNatQuotWord# n (int2Word# d#))
+  | True                = integerFromBigNat#    (bigNatQuotWord# n
+                                              (int2Word# (negateInt# d#)))
+integerQuot (IP n) (IP d) = integerFromBigNat#    (bigNatQuot n d)
+integerQuot (IP n) (IN d) = integerFromBigNatNeg# (bigNatQuot n d)
+integerQuot (IN n) (IP d) = integerFromBigNatNeg# (bigNatQuot n d)
+integerQuot (IN n) (IN d) = integerFromBigNat#    (bigNatQuot n d)
+integerQuot n d = case integerQuotRem# n d of (# q, _ #) -> q
+
+integerRem :: Integer -> Integer -> Integer
+{-# NOINLINE integerRem #-}
+integerRem !_       (IS 1#) = IS 0#   -- Note [Bangs in Integer functions]
+integerRem _       (IS -1#) = IS 0#
+integerRem _        (IS 0#) = IS (remInt# 0# 0#)
+integerRem (IS 0#) _        = IS 0#
+integerRem (IS n#) (IS d#) = IS (remInt# n# d#)
+integerRem (IP n)  (IS d#)
+    = integerFromWord#    (bigNatRemWord# n (int2Word# (absI# d#)))
+integerRem (IN n)  (IS d#)
+    = integerFromWordNeg# (bigNatRemWord# n (int2Word# (absI# d#)))
+integerRem (IP n)  (IP d)  = integerFromBigNat#    (bigNatRem n d)
+integerRem (IP n)  (IN d)  = integerFromBigNat#    (bigNatRem n d)
+integerRem (IN n)  (IP d)  = integerFromBigNatNeg# (bigNatRem n d)
+integerRem (IN n)  (IN d)  = integerFromBigNatNeg# (bigNatRem n d)
+integerRem n d = case integerQuotRem# n d of (# _, r #) -> r
+
+
+-- | Simultaneous 'integerDiv' and 'integerMod'.
+--
+-- Divisor must be non-zero otherwise the GHC runtime will terminate
+-- with a division-by-zero fault.
+integerDivMod# :: Integer -> Integer -> (# Integer, Integer #)
+{-# NOINLINE integerDivMod# #-}
+integerDivMod# !n !d    -- Note [Bangs in Integer functions]
+  | isTrue# (integerSignum# r ==# negateInt# (integerSignum# d))
+     = let !q' = integerSub q (IS 1#)
+           !r' = integerAdd r d
+       in (# q', r' #)
+  | True = qr
+  where
+    !qr@(# q, r #) = integerQuotRem# n d
+
+-- | Simultaneous 'integerDiv' and 'integerMod'.
+--
+-- Divisor must be non-zero otherwise the GHC runtime will terminate
+-- with a division-by-zero fault.
+integerDivMod :: Integer -> Integer -> (Integer, Integer)
+integerDivMod !n !d = case integerDivMod# n d of
+   -- Note [Bangs in Integer functions]
+   (# q,r #) -> (q,r)
+
+
+integerDiv :: Integer -> Integer -> Integer
+{-# NOINLINE integerDiv #-}
+integerDiv !n !d  -- Note [Bangs in Integer functions]
+   -- same-sign ops can be handled by more efficient 'integerQuot'
+   | isTrue# (integerIsNegative# n ==# integerIsNegative# d) = integerQuot n d
+   | True = case integerDivMod# n d of (# q, _ #) -> q
+
+
+integerMod :: Integer -> Integer -> Integer
+{-# NOINLINE integerMod #-}
+integerMod !n !d  -- Note [Bangs in Integer functions]
+   -- same-sign ops can be handled by more efficient 'integerRem'
+   | isTrue# (integerIsNegative# n ==# integerIsNegative# d) = integerRem n d
+   | True = case integerDivMod# n d of (# _, r #) -> r
+
+-- | Compute greatest common divisor.
+integerGcd :: Integer -> Integer -> Integer
+{-# NOINLINE integerGcd #-}
+integerGcd (IS 0#)  !b       = integerAbs b
+integerGcd a        (IS 0#)  = integerAbs a
+integerGcd (IS 1#)  _        = IS 1#
+integerGcd (IS -1#) _        = IS 1#
+integerGcd _        (IS 1#)  = IS 1#
+integerGcd _        (IS -1#) = IS 1#
+integerGcd (IS a)   (IS b)   = integerFromWord# (gcdWord#
+                                 (int2Word# (absI# a))
+                                 (int2Word# (absI# b)))
+integerGcd a@(IS _) b        = integerGcd b a
+integerGcd (IN a)   b        = integerGcd (IP a) b
+integerGcd (IP a)   (IP b)   = integerFromBigNat# (bigNatGcd a b)
+integerGcd (IP a)   (IN b)   = integerFromBigNat# (bigNatGcd a b)
+integerGcd (IP a)   (IS b)   = integerFromWord# (bigNatGcdWord# a (int2Word# (absI# b)))
+
+-- | Compute least common multiple.
+integerLcm :: Integer -> Integer -> Integer
+{-# NOINLINE integerLcm #-}
+integerLcm (IS 0#) !_  = IS 0#
+integerLcm (IS 1#)  b  = integerAbs b
+integerLcm (IS -1#) b  = integerAbs b
+integerLcm _ (IS 0#)   = IS 0#
+integerLcm a (IS 1#)   = integerAbs a
+integerLcm a (IS -1#)  = integerAbs a
+integerLcm a b         = (aa `integerQuot` (aa `integerGcd` ab)) `integerMul` ab
+  where                   -- TODO: use extended GCD to get a's factor directly
+    aa = integerAbs a
+    ab = integerAbs b
+
+-- | Square a Integer
+integerSqr :: Integer -> Integer
+integerSqr !a = integerMul a a
+
+
+-- | Base 2 logarithm (floor)
+--
+-- For numbers <= 0, return 0
+integerLog2# :: Integer -> Word#
+integerLog2# (IS i)
+   | isTrue# (i <=# 0#) = 0##
+   | True               = wordLog2# (int2Word# i)
+integerLog2# (IN _)     = 0##
+integerLog2# (IP b)     = bigNatLog2# b
+
+-- | Base 2 logarithm (floor)
+--
+-- For numbers <= 0, return 0
+integerLog2 :: Integer -> Word
+integerLog2 !i = W# (integerLog2# i)
+
+-- | Logarithm (floor) for an arbitrary base
+--
+-- For numbers <= 0, return 0
+integerLogBaseWord# :: Word# -> Integer -> Word#
+integerLogBaseWord# base !i
+   | integerIsNegative i = 0##
+   | True                = naturalLogBaseWord# base (integerToNatural i)
+
+-- | Logarithm (floor) for an arbitrary base
+--
+-- For numbers <= 0, return 0
+integerLogBaseWord :: Word -> Integer -> Word
+integerLogBaseWord (W# base) !i = W# (integerLogBaseWord# base i)
+
+-- | Logarithm (floor) for an arbitrary base
+--
+-- For numbers <= 0, return 0
+integerLogBase# :: Integer -> Integer -> Word#
+integerLogBase# !base !i
+   | integerIsNegative i = 0##
+   | True                = naturalLogBase# (integerToNatural base)
+                                           (integerToNatural i)
+
+-- | Logarithm (floor) for an arbitrary base
+--
+-- For numbers <= 0, return 0
+integerLogBase :: Integer -> Integer -> Word
+integerLogBase !base !i = W# (integerLogBase# base i)
+
+-- | Indicate if the value is a power of two and which one
+integerIsPowerOf2# :: Integer -> (# (# #) | Word# #)
+integerIsPowerOf2# (IS i)
+   | isTrue# (i <=# 0#) = (# (# #) | #)
+   | True               = wordIsPowerOf2# (int2Word# i)
+integerIsPowerOf2# (IN _) = (# (# #) | #)
+integerIsPowerOf2# (IP w) = bigNatIsPowerOf2# w
+
+-- | Convert an Int64# into an Integer
+integerFromInt64# :: Int64# -> Integer
+{-# NOINLINE integerFromInt64# #-}
+integerFromInt64# i
+  | isTrue# ((i `leInt64#` intToInt64#  INT_MAXBOUND#)
+      &&# (i `geInt64#` intToInt64# INT_MINBOUND#))
+  = IS (int64ToInt# i)
+
+  | isTrue# (i `geInt64#` intToInt64# 0#)
+  = IP (bigNatFromWord64# (int64ToWord64# i))
+
+  | True
+  = IN (bigNatFromWord64# (int64ToWord64# (negateInt64# i)))
+
+-- | Convert a Word64# into an Integer
+integerFromWord64# :: Word64# -> Integer
+{-# NOINLINE integerFromWord64# #-}
+integerFromWord64# !w
+  | isTrue# (w `leWord64#` wordToWord64# INT_MAXBOUND##)
+  = IS (int64ToInt# (word64ToInt64# w))
+  | True
+  = IP (bigNatFromWord64# w)
+
+-- | Convert an Integer into an Int64#
+integerToInt64# :: Integer -> Int64#
+{-# NOINLINE integerToInt64# #-}
+integerToInt64# (IS i) = intToInt64# i
+integerToInt64# (IP b) = word64ToInt64# (bigNatToWord64# b)
+integerToInt64# (IN b) = negateInt64# (word64ToInt64# (bigNatToWord64# b))
+
+-- | Convert an Integer into a Word64#
+integerToWord64# :: Integer -> Word64#
+{-# NOINLINE integerToWord64# #-}
+integerToWord64# (IS i) = int64ToWord64# (intToInt64# i)
+integerToWord64# (IP b) = bigNatToWord64# b
+integerToWord64# (IN b) = int64ToWord64# (negateInt64# (word64ToInt64# (bigNatToWord64# b)))
+
+----------------------------------------------------------------------------
+-- Conversions to/from floating point
+----------------------------------------------------------------------------
+
+-- | Decode a Double# into (# Integer mantissa, Int# exponent #)
+integerDecodeDouble# :: Double# -> (# Integer, Int# #)
+{-# INLINE integerDecodeDouble# #-} -- decodeDouble_Int64# is constant-folded
+                                    -- in GHC.Core.Opt.ConstantFold
+integerDecodeDouble# !x = case decodeDouble_Int64# x of
+                            (# m, e #) -> (# integerFromInt64# m, e #)
+
+-- | Encode (# Integer mantissa, Int# exponent #) into a Double#
+integerEncodeDouble# :: Integer -> Int# -> Double#
+{-# NOINLINE integerEncodeDouble# #-}
+integerEncodeDouble# (IS i) 0# = int2Double# i
+integerEncodeDouble# (IS i) e  = intEncodeDouble# i e
+integerEncodeDouble# (IP b) e  = bigNatEncodeDouble# b e
+integerEncodeDouble# (IN b) e  = negateDouble# (bigNatEncodeDouble# b e)
+
+-- | Encode (Integer mantissa, Int exponent) into a Double
+integerEncodeDouble :: Integer -> Int -> Double
+integerEncodeDouble !m (I# e)  = D# (integerEncodeDouble# m e)
+
+-- | Encode (# Integer mantissa, Int# exponent #) into a Float#
+--
+-- TODO: Not sure if it's worth to write 'Float' optimized versions here
+integerEncodeFloat# :: Integer -> Int# -> Float#
+{-# NOINLINE integerEncodeFloat# #-}
+integerEncodeFloat# !m e  = double2Float# (integerEncodeDouble# m e)
+
+-- | Compute the number of digits of the Integer (without the sign) in the given base.
+--
+-- `base` must be > 1
+integerSizeInBase# :: Word# -> Integer -> Word#
+integerSizeInBase# base (IS i) = wordSizeInBase# base (int2Word# (absI# i))
+integerSizeInBase# base (IP n) = bigNatSizeInBase# base n
+integerSizeInBase# base (IN n) = bigNatSizeInBase# base n
+
+-- | Write an 'Integer' (without sign) to @/addr/@ in base-256 representation
+-- and return the number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: write most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+integerToAddr# :: Integer -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
+integerToAddr# (IS i) = wordToAddr# (int2Word# (absI# i))
+integerToAddr# (IP n) = bigNatToAddr# n
+integerToAddr# (IN n) = bigNatToAddr# n
+
+-- | Write an 'Integer' (without sign) to @/addr/@ in base-256 representation
+-- and return the number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: write most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+integerToAddr :: Integer -> Addr# -> Bool# -> IO Word
+integerToAddr a addr e = IO \s -> case integerToAddr# a addr e s of
+   (# s', w #) -> (# s', W# w #)
+
+-- | Read an 'Integer' (without sign) in base-256 representation from an Addr#.
+--
+-- The size is given in bytes.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Null higher limbs are automatically trimed.
+integerFromAddr# :: Word# -> Addr# -> Bool# -> State# s -> (# State# s, Integer #)
+integerFromAddr# sz addr e s =
+   case bigNatFromAddr# sz addr e s of
+      (# s', n #) -> (# s', integerFromBigNat# n #)
+
+-- | Read an 'Integer' (without sign) in base-256 representation from an Addr#.
+--
+-- The size is given in bytes.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Null higher limbs are automatically trimed.
+integerFromAddr :: Word# -> Addr# -> Bool# -> IO Integer
+integerFromAddr sz addr e = IO (integerFromAddr# sz addr e)
+
+
+
+-- | Write an 'Integer' (without sign) in base-256 representation and return the
+-- number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+integerToMutableByteArray# :: Integer -> MutableByteArray# s -> Word# -> Bool# -> State# s -> (# State# s, Word# #)
+integerToMutableByteArray# (IS i) = wordToMutableByteArray# (int2Word# (absI# i))
+integerToMutableByteArray# (IP a) = bigNatToMutableByteArray# a
+integerToMutableByteArray# (IN a) = bigNatToMutableByteArray# a
+
+-- | Write an 'Integer' (without sign) in base-256 representation and return the
+-- number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+integerToMutableByteArray :: Integer -> MutableByteArray# RealWorld -> Word# -> Bool# -> IO Word
+integerToMutableByteArray i mba w e = IO \s -> case integerToMutableByteArray# i mba w e s of
+   (# s', r #) -> (# s', W# r #)
+
+-- | Read an 'Integer' (without sign) in base-256 representation from a ByteArray#.
+--
+-- The size is given in bytes.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Null higher limbs are automatically trimed.
+integerFromByteArray# :: Word# -> ByteArray# -> Word# -> Bool# -> State# s -> (# State# s, Integer #)
+integerFromByteArray# sz ba off e s = case bigNatFromByteArray# sz ba off e s of
+   (# s', a #) -> (# s', integerFromBigNat# a #)
+
+-- | Read an 'Integer' (without sign) in base-256 representation from a ByteArray#.
+--
+-- The size is given in bytes.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Null higher limbs are automatically trimed.
+integerFromByteArray :: Word# -> ByteArray# -> Word# -> Bool# -> Integer
+integerFromByteArray sz ba off e = case runRW# (integerFromByteArray# sz ba off e) of
+   (# _, i #) -> i
+
+
+-- | Get the extended GCD of two integers.
+--
+-- `integerGcde# a b` returns (# g,x,y #) where
+--    * ax + by = g = |gcd a b|
+integerGcde#
+   :: Integer
+   -> Integer
+   -> (# Integer, Integer, Integer #)
+integerGcde# a b
+   | integerIsZero a && integerIsZero b    =     (# integerZero, integerZero, integerZero #)
+   | integerIsZero a                       = fix (# b          , integerZero, integerOne #)
+   | integerIsZero b                       = fix (# a          , integerOne,  integerZero #)
+   | integerAbs a `integerEq` integerAbs b = fix (# b          , integerZero, integerOne #)
+   | True                                  = Backend.integer_gcde a b
+   where
+      -- returned "g" must be positive
+      fix (# g, x, y #)
+         | integerIsNegative g = (# integerNegate g, integerNegate x, integerNegate y #)
+         | True                = (# g,x,y #)
+
+-- | Get the extended GCD of two integers.
+--
+-- `integerGcde a b` returns (g,x,y) where
+--    * ax + by = g = |gcd a b|
+integerGcde
+   :: Integer
+   -> Integer
+   -> ( Integer, Integer, Integer)
+integerGcde a b = case integerGcde# a b of
+   (# g,x,y #) -> (g,x,y)
+
+
+-- | Computes the modular inverse.
+--
+-- @integerRecipMod# x m@ behaves as follows:
+--
+--   * If m > 1 and gcd x m = 1, it returns an integer y with 0 < y < m such
+--     that x*y is congruent to 1 modulo m.
+--
+--   * If m > 1 and gcd x m > 1, it fails.
+--
+--   * If m = 1, it returns @0@ for all x.  The computation effectively takes
+--     place in the zero ring, which has a single element 0 with 0+0 = 0*0 = 0:
+--     the element 0 is the multiplicative identity element and is its own
+--     multiplicative inverse.
+--
+--   * If m = 0, it fails.
+--
+-- NB. Successful evaluation returns a value of the form @(# n | #)@; failure is
+-- indicated by returning @(# | () #)@.
+integerRecipMod#
+   :: Integer
+   -> Natural
+   -> (# Natural | () #)
+integerRecipMod# x m
+   | naturalIsZero m = (# | () #)
+   | naturalIsOne  m = (# naturalZero | #)
+   | integerIsZero x = (# | () #)
+   | True            = Backend.integer_recip_mod x m
+
+
+-- | Computes the modular exponentiation.
+--
+-- @integerPowMod# b e m@ behaves as follows:
+--
+--   * If m > 1 and e >= 0, it returns an integer y with 0 <= y < m
+--     and y congruent to b^e modulo m.
+--
+--   * If m > 1 and e < 0, it uses `integerRecipMod#` to try to find a modular
+--     multiplicative inverse b' (which only exists if gcd b m = 1) and then
+--     caculates (b')^(-e) modulo m (note that -e > 0); if the inverse does not
+--     exist then it fails.
+--
+--   * If m = 1, it returns @0@ for all b and e.
+--
+--   * If m = 0, it fails.
+--
+-- NB. Successful evaluation returns a value of the form @(# n | #)@; failure is
+-- indicated by returning @(# | () #)@.
+
+integerPowMod# :: Integer -> Integer -> Natural -> (# Natural | () #)
+integerPowMod# !b !e !m
+   | naturalIsZero m  = (# | () #)
+   | naturalIsOne  m  = (# naturalZero | #)
+   | integerIsZero e  = (# naturalOne  | #)
+   | integerIsZero b
+     && integerGt e 0 = (# naturalZero | #)
+   | integerIsOne  b  = (# naturalOne  | #)
+     -- when the exponent is negative, try to find the modular multiplicative
+     -- inverse and use it instead
+   | integerIsNegative e = case integerRecipMod# b m of
+      (#    | () #) -> (# | () #)
+      (# b' |    #) -> integerPowMod#
+                        (integerFromNatural b')
+                        (integerNegate e)
+                        m
+
+     -- e > 0 by cases above
+   | True = (# Backend.integer_powmod b (integerToNatural e) m | #)
+
+
+{-
+Note [Optimising conversions between numeric types]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Converting between numeric types is very common in Haskell codes.  Suppose that
+we have N inter-convertible numeric types (Word, Word8, Word32, Int, etc.).
+
+- We don't want to have to use one conversion function per pair of types as that
+would require N^2 functions: wordToWord8, wordToInt, word8ToWord32...
+
+- The following kind of class would allow us to have a single conversion
+function but at the price of N^2 instances and of the use of
+MultiParamTypeClasses extension.
+
+    class Convert a b where
+      convert :: a -> b
+
+So what we do instead is that we use the Integer type (signed, unbounded) as a
+passthrough type to perform every conversion. Hence we only need to define two
+functions per numeric type:
+
+  class Integral a where
+    toInteger :: a -> Integer
+
+  class Num a where
+    fromInteger :: Integer -> a
+
+These classes have a single parameter and can be derived automatically (e.g. for
+newtypes). So we don't even have to define 2*N instances. For example, all the
+instances for the types in Foreign.C.Types (CChar, CShort, CInt, CUInt, etc.)
+are automatically derived from the instances for Word, Int, Word8, Word16, etc.
+
+Finally we can define a generic conversion function:
+
+  -- in the Prelude
+  fromIntegral :: (Integral a, Num b) => a -> b
+  fromIntegral = fromInteger . toInteger
+
+Efficient conversions
+~~~~~~~~~~~~~~~~~~~~~
+
+An issue with this approach is that performance might be terrible. E.g.
+converting an Int into a Word, which is a no-op at the machine level, becomes
+costly when performed via `fromIntegral` or any similar function because an
+intermediate Integer has to be allocated in the heap to perform the conversion.
+
+A solution is to bless one particular `fromIntegral`-like function and to use
+rewrite rules to replace it with a more efficient function when both types are
+known. This is what was done in the past, see next section. We use another
+approach nowadays:
+
+Notice that the set of primitive operations to convert from and to Integer and
+Natural is pretty small:
+
+  - Natural <-> Word#/BigNat#
+  - Integer <-> Int#/Word#/Natural/BigNat# (+ Int64#/Word64# on 32-bit arch)
+
+For example, we have the following primitives:
+  - integerToWord#   :: Integer -> Word#
+  - integerFromWord# :: Word# -> Integer
+  - integerToInt#    :: Integer -> Int#
+  - ...
+
+Compared to optimising `fromIntegral :: (Integral a, Num b) => a -> b` where `a`
+and `b` are arbitrary, we only have to write rewrite rules for the concrete
+types that can be converted from and to Natural/Integer. All the other ones
+necessarily pass through these concrete types!
+
+For example we have the following rules:
+    integerToWord# (integerFromWord# x) ===> x
+    integerToInt# (integerFromWord# x)  ===> word2Int# x
+
+But we don't need rules to handle conversion from/to e.g. Word32# because there
+is no Word32#-to-Integer primitive: Word32# must be converted into something
+else first (e.g. Word#) for which we have rules.
+
+We rely on inlining of fromInteger/toInteger and on other transformations (e.g.
+float-in) to make these rules likely to fire. It seems to work well in practice.
+
+Example 1: converting an Int into a Word
+
+  fromIntegral @Int @Word x
+
+  ===> {inline fromIntegral}
+  fromInteger @Word (toInteger @Int x)
+
+  ===> {inline fromInteger and toInteger}
+  W# (integerToWord# (case x of { I# x# -> IS x# }))
+
+  ===> {float-in}
+  case x of { I# x# -> W# (integerToWord# (IS x#)) }
+
+  ===> {rewrite rule for "integerToWord# . IS"}
+  case x of { I# x# -> W# (int2Word# x#) }
+
+
+Example 2: converting an Int8 into a Word32
+
+  fromIntegral @Int8 @Word32 x
+
+  ===> {inline fromIntegral}
+  fromInteger @Word32 (toInteger @Int8 x)
+
+  ===> {inline fromInteger and toInteger}
+  W32# (wordToWord32# (integerToWord# (case x of { I8# x# -> IS (int8ToInt# x#) })))
+
+  ===> {float-in}
+  case x of { I8# x# -> W32# (wordToWord32# (integerToWord# (IS (int8ToInt# x#)))) }
+
+  ===> {rewrite rule for "integerToWord# . IS"}
+  case x of { I8# x# -> W32# (wordToWord32# (int2Word# (int8ToInt# x#))) }
+
+  Notice that in the resulting expression the value passes through types Int#
+  and Word# with native machine word size: it is first sign-extended from Int8#
+  to Int#, then cast into Word#, and finally truncated into Word32#. These are
+  all very cheap operations that are performed in registers without allocating
+  anything in the heap.
+
+
+
+Historical fromIntegral optimisations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the past, `fromIntegral` function in the Prelude was special because many
+rewrite rules were mentioning it explicitly. For example to replace a call to
+`fromIntegral :: Int -> Word`, which allocates an intermediate Integer, with a
+call to `intToWord`, which is a no-op when compiled into machine code. Nowadays
+`fromIntegral` isn't a special function anymore and we just INLINE it (see above).
+
+- first `fromIntegral` was specialized (SPECIALIZE pragma). However it would
+need N^2 pragmas to cover every case and it wouldn't cover user defined numeric
+types which don't belong to base.
+
+- `-fwarn-identities` enables a warning to detect useless conversions via
+fromIntegral (since 0656c72a8f):
+
+  > fromIntegral (1 :: Int) :: Int
+
+  <interactive>:3:21: warning: [-Widentities]
+      Call of fromIntegral :: Int -> Int
+        can probably be omitted
+
+
+- many rules were added (e.g. in e0c787c10f) to perform float-in transformations
+explicitly (to allow more fromIntegral rules to fire) and to replace some
+fromIntegral calls with faster operations:
+
+    "fromIntegral/Int8->Int8" fromIntegral = id :: Int8 -> Int8
+    "fromIntegral/a->Int8"    fromIntegral = \x -> case fromIntegral x of I# x# -> I8# (intToInt8# x#)
+    "fromIntegral/Int8->a"    fromIntegral = \(I8# x#) -> fromIntegral (I# x#)
+
+It worked but there were still some issues with this approach:
+
+1. These rules only work for `fromIntegral`. If we wanted to define our own
+   similar function (e.g. using other type-classes), we would also have to redefine
+   all the rules to get similar performance.
+
+2. `fromIntegral` had to be marked `NOINLINE [1]`:
+    - NOINLINE to allow rules to match
+    - [1] to allow inlining in later phases to avoid incurring a function call
+      overhead for such a trivial operation
+
+   Users of the function had to be careful because a simple helper without an
+   INLINE pragma like:
+
+      toInt :: Integral a => a -> Int
+      toInt = fromIntegral
+
+   had the following unfolding:
+
+      toInt = integerToInt . toInteger
+
+   which doesn't mention `fromIntegral` anymore. Hence `fromIntegral` rules
+   wouldn't fire for codes using `toInt` while they would if they had used
+   `fromIntegral` directly!
+   For this reason, a bunch of rules for bignum primitives as we have now were
+   already present to handle these cases.
+
+3. These rewrite rules were tedious to write and error-prone (cf #19345).
+
+For these reasons, it is simpler to not consider fromIntegral special at all and
+to only rely on rewrite rules for bignum functions.
+
+-}
+
+-- See Note [Optimising conversions between numeric types]
+{-# RULES
+"Word# -> Natural -> Integer"
+  forall x. integerFromNatural (NS x) = integerFromWord# x
+
+"BigNat# -> Natural -> Integer"
+  forall x. integerFromNatural (NB x) = IP x
+
+"Int# -> Integer -> Int#"
+  forall x. integerToInt# (IS x) = x
+
+"Word# -> Integer -> Word#"
+  forall x. integerToWord# (integerFromWord# x) = x
+
+"Natural -> Integer -> Natural (wrap)"
+  forall x. integerToNatural (integerFromNatural x) = x
+
+"Natural -> Integer -> Natural (throw)"
+  forall x. integerToNaturalThrow (integerFromNatural x) = x
+
+"Natural -> Integer -> Natural (clamp)"
+  forall x. integerToNaturalClamp (integerFromNatural x) = x
+
+"Natural -> Integer -> Word#"
+  forall x. integerToWord# (integerFromNatural x) = naturalToWord# x
+
+"Int# -> Integer -> Word#"
+  forall x. integerToWord# (IS x) = int2Word# x
+
+"Word# -> Integer -> Int#"
+  forall x. integerToInt# (integerFromWord# x) = word2Int# x
+
+"Word# -> Integer -> Natural (wrap)"
+  forall x. integerToNatural (integerFromWord# x) = NS x
+
+"Word# -> Integer -> Natural (throw)"
+  forall x. integerToNaturalThrow (integerFromWord# x) = NS x
+
+"Word# -> Integer -> Natural (clamp)"
+  forall x. integerToNaturalClamp (integerFromWord# x) = NS x
+
+#-}
+
+{-# RULES
+
+"Int64# -> Integer -> Int64#"
+  forall x. integerToInt64# (integerFromInt64# x) = x
+
+"Word64# -> Integer -> Word64#"
+  forall x. integerToWord64# (integerFromWord64# x) = x
+
+"Int64# -> Integer -> Word64#"
+  forall x. integerToWord64# (integerFromInt64# x) = int64ToWord64# x
+
+"Word64# -> Integer -> Int64#"
+  forall x. integerToInt64# (integerFromWord64# x) = word64ToInt64# x
+
+"Word# -> Integer -> Word64#"
+  forall x. integerToWord64# (integerFromWord# x) = wordToWord64# x
+
+"Word64# -> Integer -> Word#"
+  forall x. integerToWord# (integerFromWord64# x) = word64ToWord# x
+
+"Int# -> Integer -> Int64#"
+  forall x. integerToInt64# (IS x) = intToInt64# x
+
+"Int64# -> Integer -> Int#"
+  forall x. integerToInt# (integerFromInt64# x) = int64ToInt# x
+
+"Int# -> Integer -> Word64#"
+  forall x. integerToWord64# (IS x) = int64ToWord64# (intToInt64# x)
+
+"Int64# -> Integer -> Word#"
+  forall x. integerToWord# (integerFromInt64# x) = int2Word# (int64ToInt# x)
+
+"Word# -> Integer -> Int64#"
+  forall x. integerToInt64# (integerFromWord# x) = word64ToInt64# (wordToWord64# x)
+
+"Word64# -> Integer -> Int#"
+  forall x. integerToInt# (integerFromWord64# x) = word2Int# (word64ToWord# x)
+
+#-}
diff --git a/src/GHC/Internal/Bignum/Integer.hs-boot b/src/GHC/Internal/Bignum/Integer.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Integer.hs-boot
@@ -0,0 +1,37 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE MagicHash #-}
+
+module GHC.Internal.Bignum.Integer where
+
+import GHC.Internal.Types
+import GHC.Internal.Prim
+import {-# SOURCE #-} GHC.Internal.Bignum.BigNat
+import {-# SOURCE #-} GHC.Internal.Bignum.Natural
+
+data Integer
+
+integerZero :: Integer
+integerOne :: Integer
+
+integerEq# :: Integer -> Integer -> Int#
+integerEq :: Integer -> Integer -> Bool
+integerGt :: Integer -> Integer -> Bool
+integerIsZero :: Integer -> Bool
+integerIsOne :: Integer -> Bool
+integerIsNegative :: Integer -> Bool
+
+integerSub :: Integer -> Integer -> Integer
+integerMul :: Integer -> Integer -> Integer
+integerMod :: Integer -> Integer -> Integer
+integerRem :: Integer -> Integer -> Integer
+integerNegate :: Integer -> Integer
+integerAbs :: Integer -> Integer
+integerDivMod# :: Integer -> Integer -> (# Integer, Integer #)
+integerQuotRem# :: Integer -> Integer -> (# Integer, Integer #)
+
+integerToBigNatSign# :: Integer -> (# Int#, BigNat# #)
+integerFromBigNatSign# :: Int# -> BigNat# -> Integer
+integerFromBigNat# :: BigNat# -> Integer
+integerToNatural :: Integer -> Natural
+integerFromNatural :: Natural -> Integer
diff --git a/src/GHC/Internal/Bignum/Natural.hs b/src/GHC/Internal/Bignum/Natural.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Natural.hs
@@ -0,0 +1,722 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE BlockArguments #-}
+
+#include "MachDeps.h"
+#include "WordSize.h"
+
+module GHC.Internal.Bignum.Natural
+    ( Natural(..)
+    , naturalCheck#
+    , naturalCheck
+
+      -- * Useful constants
+    , naturalZero
+    , naturalOne
+
+      -- * Predicates
+    , naturalIsZero
+    , naturalIsOne
+    , naturalIsPowerOf2#
+
+      -- * Conversion with...
+      -- ** 'BigNat'
+    , naturalFromBigNat#
+    , naturalToBigNat#
+      -- ** 'Word'
+    , naturalFromWord#
+    , naturalFromWord2#
+    , naturalFromWord
+    , naturalToWord#
+    , naturalToWord
+    , naturalToWordClamp#
+    , naturalToWordClamp
+    , naturalToWordMaybe#
+      -- ** Limbs
+    , naturalFromWordList
+    , naturalToMutableByteArray#
+    , naturalFromByteArray#
+      -- ** Floating point
+    , naturalEncodeDouble#
+    , naturalEncodeFloat#
+      -- ** 'Addr#'
+    , naturalToAddr#
+    , naturalToAddr
+    , naturalFromAddr#
+    , naturalFromAddr
+
+      -- * Comparison
+    , naturalEq#
+    , naturalEq
+    , naturalNe#
+    , naturalNe
+    , naturalGe#
+    , naturalGe
+    , naturalLe#
+    , naturalLe
+    , naturalGt#
+    , naturalGt
+    , naturalLt#
+    , naturalLt
+    , naturalCompare
+
+      -- * Bit operations
+    , naturalPopCount#
+    , naturalPopCount
+    , naturalShiftR#
+    , naturalShiftR
+    , naturalShiftL#
+    , naturalShiftL
+    , naturalAnd
+    , naturalAndNot
+    , naturalOr
+    , naturalXor
+    , naturalTestBit#
+    , naturalTestBit
+    , naturalBit#
+    , naturalBit
+    , naturalSetBit#
+    , naturalSetBit
+    , naturalClearBit#
+    , naturalClearBit
+    , naturalComplementBit#
+    , naturalComplementBit
+
+      -- * Arithmetic
+    , naturalAdd
+    , naturalSub
+    , naturalSubThrow
+    , naturalSubUnsafe
+    , naturalMul
+    , naturalSqr
+    , naturalSignum
+    , naturalNegate
+    , naturalQuotRem#
+    , naturalQuotRem
+    , naturalQuot
+    , naturalRem
+    , naturalGcd
+    , naturalLcm
+    , naturalLog2#
+    , naturalLog2
+    , naturalLogBaseWord#
+    , naturalLogBaseWord
+    , naturalLogBase#
+    , naturalLogBase
+    , naturalPowMod
+
+      -- * Miscellaneous
+    , naturalSizeInBase#
+    ) where
+
+import GHC.Internal.Prim
+import GHC.Internal.Types
+import GHC.Internal.Classes
+
+import GHC.Internal.Bignum.BigNat
+import GHC.Internal.Bignum.Primitives
+
+default ()
+
+-- | Natural number
+--
+-- Invariant: numbers <= WORD_MAXBOUND use the `NS` constructor
+data Natural
+   = NS !Word#
+   | NB !BigNat#
+
+instance Eq Natural where
+   (==) = naturalEq
+   (/=) = naturalNe
+
+instance Ord Natural where
+   compare = naturalCompare
+   (>)     = naturalGt
+   (>=)    = naturalGe
+   (<)     = naturalLt
+   (<=)    = naturalLe
+
+
+-- | Check Natural invariants
+naturalCheck# :: Natural -> Bool#
+naturalCheck# (NS _)  = 1#
+naturalCheck# (NB bn) = bigNatCheck# bn &&# bigNatSize# bn ># 1#
+
+-- | Check Natural invariants
+naturalCheck :: Natural -> Bool
+naturalCheck !n = isTrue# (naturalCheck# n)
+
+-- | Zero Natural
+naturalZero :: Natural
+naturalZero = NS 0##
+
+-- | One Natural
+naturalOne :: Natural
+naturalOne = NS 1##
+
+-- | Test Zero Natural
+naturalIsZero :: Natural -> Bool
+naturalIsZero (NS 0##) = True
+naturalIsZero _        = False
+
+-- | Test One Natural
+naturalIsOne :: Natural -> Bool
+naturalIsOne (NS 1##) = True
+naturalIsOne _        = False
+
+-- | Indicate if the value is a power of two and which one
+naturalIsPowerOf2# :: Natural -> (# (# #) | Word# #)
+naturalIsPowerOf2# (NS w) = wordIsPowerOf2# w
+naturalIsPowerOf2# (NB w) = bigNatIsPowerOf2# w
+
+-- | Create a Natural from a BigNat# (respect the invariants)
+naturalFromBigNat# :: BigNat# -> Natural
+{-# NOINLINE naturalFromBigNat# #-}
+naturalFromBigNat# x = case bigNatSize# x of
+   0# -> naturalZero
+   1# -> NS (bigNatIndex# x 0#)
+   _  -> NB x
+
+-- | Convert a Natural into a BigNat#
+naturalToBigNat# :: Natural -> BigNat#
+{-# NOINLINE naturalToBigNat# #-}
+naturalToBigNat# (NS w)  = bigNatFromWord# w
+naturalToBigNat# (NB bn) = bn
+
+-- | Create a Natural from a Word#
+naturalFromWord# :: Word# -> Natural
+naturalFromWord# x = NS x
+
+-- | Convert two Word# (most-significant first) into a Natural
+naturalFromWord2# :: Word# -> Word# -> Natural
+naturalFromWord2# 0## 0## = naturalZero
+naturalFromWord2# 0## l   = NS l
+naturalFromWord2# h   l   = NB (bigNatFromWord2# h l)
+
+-- | Create a Natural from a Word
+naturalFromWord :: Word -> Natural
+naturalFromWord (W# x) = NS x
+
+-- | Create a Natural from a list of Word
+naturalFromWordList :: [Word] -> Natural
+naturalFromWordList xs = naturalFromBigNat# (bigNatFromWordList xs)
+
+-- | Convert the lower bits of a Natural into a Word#
+naturalToWord# :: Natural -> Word#
+{-# NOINLINE naturalToWord# #-}
+naturalToWord# (NS x) = x
+naturalToWord# (NB b) = bigNatIndex# b 0#
+
+-- | Convert the lower bits of a Natural into a Word
+naturalToWord :: Natural -> Word
+naturalToWord !n = W# (naturalToWord# n)
+
+-- | Convert a Natural into a Word# clamping to (maxBound :: Word#).
+naturalToWordClamp# :: Natural -> Word#
+naturalToWordClamp# (NS x) = x
+naturalToWordClamp# (NB _) = WORD_MAXBOUND##
+
+-- | Convert a Natural into a Word# clamping to (maxBound :: Word).
+naturalToWordClamp :: Natural -> Word
+naturalToWordClamp !n = W# (naturalToWordClamp# n)
+
+-- | Try downcasting 'Natural' to 'Word' value.
+-- Returns '(##)' if value doesn't fit in 'Word'.
+naturalToWordMaybe# :: Natural -> (# (# #) | Word# #)
+naturalToWordMaybe# (NS w) = (#       | w #)
+naturalToWordMaybe# _      = (# (# #) |   #)
+
+-- | Encode (# Natural mantissa, Int# exponent #) into a Double#
+naturalEncodeDouble# :: Natural -> Int# -> Double#
+naturalEncodeDouble# (NS w) 0# = word2Double# w
+naturalEncodeDouble# (NS w) e  = wordEncodeDouble# w e
+naturalEncodeDouble# (NB b) e  = bigNatEncodeDouble# b e
+
+-- | Encode (# Natural mantissa, Int# exponent #) into a Float#
+--
+-- TODO: Not sure if it's worth to write 'Float' optimized versions here
+naturalEncodeFloat# :: Natural -> Int# -> Float#
+naturalEncodeFloat# !m e  = double2Float# (naturalEncodeDouble# m e)
+
+-- | Equality test for Natural
+naturalEq# :: Natural -> Natural -> Bool#
+naturalEq# (NS x) (NS y) = x `eqWord#` y
+naturalEq# (NB x) (NB y) = bigNatEq# x y
+naturalEq# _      _      = 0#
+
+-- | Equality test for Natural
+naturalEq :: Natural -> Natural -> Bool
+naturalEq !x !y = isTrue# (naturalEq# x y)
+
+-- | Inequality test for Natural
+naturalNe# :: Natural -> Natural -> Bool#
+naturalNe# (NS x) (NS y) = x `neWord#` y
+naturalNe# (NB x) (NB y) = bigNatNe# x y
+naturalNe# _      _      = 1#
+
+-- | Inequality test for Natural
+naturalNe :: Natural -> Natural -> Bool
+naturalNe !x !y = isTrue# (naturalNe# x y)
+
+-- | Greater or equal test for Natural
+naturalGe# :: Natural -> Natural -> Bool#
+naturalGe# (NS x) (NS y) = x `geWord#` y
+naturalGe# (NS _) (NB _) = 0#
+naturalGe# (NB _) (NS _) = 1#
+naturalGe# (NB x) (NB y) = bigNatGe# x y
+
+-- | Greater or equal test for Natural
+naturalGe :: Natural -> Natural -> Bool
+naturalGe !x !y = isTrue# (naturalGe# x y)
+
+-- | Lower or equal test for Natural
+naturalLe# :: Natural -> Natural -> Bool#
+naturalLe# (NS x) (NS y) = x `leWord#` y
+naturalLe# (NS _) (NB _) = 1#
+naturalLe# (NB _) (NS _) = 0#
+naturalLe# (NB x) (NB y) = bigNatLe# x y
+
+-- | Lower or equal test for Natural
+naturalLe :: Natural -> Natural -> Bool
+naturalLe !x !y = isTrue# (naturalLe# x y)
+
+
+-- | Greater test for Natural
+naturalGt# :: Natural -> Natural -> Bool#
+naturalGt# (NS x) (NS y) = x `gtWord#` y
+naturalGt# (NS _) (NB _) = 0#
+naturalGt# (NB _) (NS _) = 1#
+naturalGt# (NB x) (NB y) = bigNatGt# x y
+
+-- | Greater test for Natural
+naturalGt :: Natural -> Natural -> Bool
+naturalGt !x !y = isTrue# (naturalGt# x y)
+
+-- | Lower test for Natural
+naturalLt# :: Natural -> Natural -> Bool#
+naturalLt# (NS x) (NS y) = x `ltWord#` y
+naturalLt# (NS _) (NB _) = 1#
+naturalLt# (NB _) (NS _) = 0#
+naturalLt# (NB x) (NB y) = bigNatLt# x y
+
+-- | Lower test for Natural
+naturalLt :: Natural -> Natural -> Bool
+naturalLt !x !y = isTrue# (naturalLt# x y)
+
+-- | Compare two Natural
+naturalCompare :: Natural -> Natural -> Ordering
+naturalCompare (NS x) (NS y) = cmpW# x y
+naturalCompare (NB x) (NB y) = bigNatCompare x y
+naturalCompare (NS _) (NB _) = LT
+naturalCompare (NB _) (NS _) = GT
+
+-- | PopCount for Natural
+naturalPopCount# :: Natural -> Word#
+{-# NOINLINE naturalPopCount# #-}
+naturalPopCount# (NS x) = popCnt# x
+naturalPopCount# (NB x) = bigNatPopCount# x
+
+-- | PopCount for Natural
+naturalPopCount :: Natural -> Word
+naturalPopCount (NS x) = W# (popCnt# x)
+naturalPopCount (NB x) = bigNatPopCount x
+
+-- | Right shift for Natural
+naturalShiftR# :: Natural -> Word# -> Natural
+{-# NOINLINE naturalShiftR# #-}
+naturalShiftR# (NS x) n = NS (x `shiftRW#` n)
+naturalShiftR# (NB x) n = naturalFromBigNat# (x `bigNatShiftR#` n)
+
+-- | Right shift for Natural
+naturalShiftR :: Natural -> Word -> Natural
+naturalShiftR x (W# n) = naturalShiftR# x n
+
+-- | Left shift
+naturalShiftL# :: Natural -> Word# -> Natural
+{-# NOINLINE naturalShiftL# #-}
+naturalShiftL# v@(NS x) n
+   | 0## <- x                     = v
+   | isTrue# (clz# x `geWord#` n) = NS (x `uncheckedShiftL#` word2Int# n)
+   | True                         = NB (bigNatFromWord# x `bigNatShiftL#` n)
+naturalShiftL# (NB x) n = NB (x `bigNatShiftL#` n)
+
+-- | Left shift
+naturalShiftL :: Natural -> Word -> Natural
+naturalShiftL !x (W# n) = naturalShiftL# x n
+
+-- | Add two naturals
+naturalAdd :: Natural -> Natural -> Natural
+{-# NOINLINE naturalAdd #-}
+naturalAdd (NS x) (NB y) = NB (bigNatAddWord# y x)
+naturalAdd (NB x) (NS y) = NB (bigNatAddWord# x y)
+naturalAdd (NB x) (NB y) = NB (bigNatAdd x y)
+naturalAdd (NS x) (NS y) =
+   case addWordC# x y of
+      (# l,0# #) -> NS l
+      (# l,c  #) -> NB (bigNatFromWord2# (int2Word# c) l)
+
+-- | Sub two naturals
+naturalSub :: Natural -> Natural -> (# (# #) | Natural #)
+{-# NOINLINE naturalSub #-}
+naturalSub (NS _) (NB _) = (# (# #) | #)
+naturalSub (NB x) (NS y) = (# | naturalFromBigNat# (bigNatSubWordUnsafe# x y) #)
+naturalSub (NS x) (NS y) =
+   case subWordC# x y of
+      (# l,0# #) -> (#       | NS l #)
+      (# _,_  #) -> (# (# #) |      #)
+naturalSub (NB x) (NB y) =
+   case bigNatSub x y of
+      (# (# #) |    #) -> (# (# #) | #)
+      (#       | z  #) -> (#       | naturalFromBigNat# z #)
+
+-- | Sub two naturals
+--
+-- Throw an Underflow exception if x < y
+naturalSubThrow :: Natural -> Natural -> Natural
+{-# NOINLINE naturalSubThrow #-}
+naturalSubThrow (NS _) (NB _) = raiseUnderflow
+naturalSubThrow (NB x) (NS y) = naturalFromBigNat# (bigNatSubWordUnsafe# x y)
+naturalSubThrow (NS x) (NS y) =
+   case subWordC# x y of
+      (# l,0# #) -> NS l
+      (# _,_  #) -> raiseUnderflow
+naturalSubThrow (NB x) (NB y) =
+   case bigNatSub x y of
+      (# (# #) |   #) -> raiseUnderflow
+      (#       | z #) -> naturalFromBigNat# z
+
+-- | Sub two naturals
+--
+-- Unsafe: don't check that x >= y
+-- Undefined results if it happens
+naturalSubUnsafe :: Natural -> Natural -> Natural
+{-# NOINLINE naturalSubUnsafe #-}
+naturalSubUnsafe (NS x) (NS y) = NS (minusWord# x y)
+naturalSubUnsafe (NS _) (NB _) = naturalZero
+naturalSubUnsafe (NB x) (NS y) = naturalFromBigNat# (bigNatSubWordUnsafe# x y)
+naturalSubUnsafe (NB x) (NB y) =
+   case bigNatSub x y of
+      (# (# #) |   #) -> naturalZero
+      (#       | z #) -> naturalFromBigNat# z
+
+-- | Multiplication
+naturalMul :: Natural -> Natural -> Natural
+{-# NOINLINE naturalMul #-}
+naturalMul a b = case a of
+   NS 0## -> NS 0##
+   NS 1## -> b
+   NS x   -> case b of
+               NS 0## -> NS 0##
+               NS 1## -> a
+               NS y   -> case timesWord2# x y of
+                           (# h,l #) -> naturalFromWord2# h l
+               NB y   -> NB (bigNatMulWord# y x)
+   NB x   -> case b of
+               NS 0## -> NS 0##
+               NS 1## -> a
+               NS y   -> NB (bigNatMulWord# x y)
+               NB y   -> NB (bigNatMul x y)
+
+-- | Square a Natural
+naturalSqr :: Natural -> Natural
+naturalSqr !a = naturalMul a a
+
+-- | Signum for Natural
+naturalSignum :: Natural -> Natural
+naturalSignum (NS 0##) = NS 0##
+naturalSignum _        = NS 1##
+
+-- | Negate for Natural
+naturalNegate :: Natural -> Natural
+naturalNegate (NS 0##) = NS 0##
+naturalNegate _        = raiseUnderflow
+
+-- | Return division quotient and remainder
+--
+-- Division by zero is handled by BigNat
+naturalQuotRem# :: Natural -> Natural -> (# Natural, Natural #)
+{-# NOINLINE naturalQuotRem# #-}
+naturalQuotRem# (NS n) (NS d) = case quotRemWord# n d of
+                                 (# q, r #) -> (# NS q, NS r #)
+naturalQuotRem# (NB n) (NS d) = case bigNatQuotRemWord# n d of
+                                 (# q, r #) -> (# naturalFromBigNat# q, NS r #)
+naturalQuotRem# (NS n) (NB d) = case bigNatQuotRem# (bigNatFromWord# n) d of
+                                 (# q, r #) -> (# naturalFromBigNat# q, naturalFromBigNat# r #)
+naturalQuotRem# (NB n) (NB d) = case bigNatQuotRem# n d of
+                                 (# q, r #) -> (# naturalFromBigNat# q, naturalFromBigNat# r #)
+
+-- | Return division quotient and remainder
+naturalQuotRem :: Natural -> Natural -> (Natural, Natural)
+naturalQuotRem !n !d = case naturalQuotRem# n d of
+   (# q, r #) -> (q,r)
+
+-- | Return division quotient
+naturalQuot :: Natural -> Natural -> Natural
+{-# NOINLINE naturalQuot #-}
+naturalQuot (NS n) (NS d) = case quotWord# n d of
+                             q -> NS q
+naturalQuot (NB n) (NS d) = case bigNatQuotWord# n d of
+                             q -> naturalFromBigNat# q
+naturalQuot (NS n) (NB d) = case bigNatQuot (bigNatFromWord# n) d of
+                             q -> naturalFromBigNat# q
+naturalQuot (NB n) (NB d) = case bigNatQuot n d of
+                             q -> naturalFromBigNat# q
+
+-- | Return division remainder
+naturalRem :: Natural -> Natural -> Natural
+{-# NOINLINE naturalRem #-}
+naturalRem (NS n) (NS d) = case remWord# n d of
+                             r -> NS r
+naturalRem (NB n) (NS d) = case bigNatRemWord# n d of
+                             r -> NS r
+naturalRem (NS n) (NB d) = case bigNatRem (bigNatFromWord# n) d of
+                             r -> naturalFromBigNat# r
+naturalRem (NB n) (NB d) = case bigNatRem n d of
+                             r -> naturalFromBigNat# r
+
+naturalAnd :: Natural -> Natural -> Natural
+{-# NOINLINE naturalAnd #-}
+naturalAnd (NS n) (NS m) = NS (n `and#` m)
+naturalAnd (NS n) (NB m) = NS (n `and#` bigNatToWord# m)
+naturalAnd (NB n) (NS m) = NS (bigNatToWord# n `and#` m)
+naturalAnd (NB n) (NB m) = naturalFromBigNat# (bigNatAnd n m)
+
+naturalAndNot :: Natural -> Natural -> Natural
+{-# NOINLINE naturalAndNot #-}
+naturalAndNot (NS n) (NS m) = NS (n `and#` not# m)
+naturalAndNot (NS n) (NB m) = NS (n `and#` not# (bigNatToWord# m))
+naturalAndNot (NB n) (NS m) = NB (bigNatAndNotWord# n m)
+naturalAndNot (NB n) (NB m) = naturalFromBigNat# (bigNatAndNot n m)
+
+naturalOr :: Natural -> Natural -> Natural
+{-# NOINLINE naturalOr #-}
+naturalOr (NS n) (NS m) = NS (n `or#` m)
+naturalOr (NS n) (NB m) = NB (bigNatOrWord# m n)
+naturalOr (NB n) (NS m) = NB (bigNatOrWord# n m)
+naturalOr (NB n) (NB m) = NB (bigNatOr n m)
+
+naturalXor :: Natural -> Natural -> Natural
+{-# NOINLINE naturalXor #-}
+naturalXor (NS n) (NS m) = NS (n `xor#` m)
+naturalXor (NS n) (NB m) = NB (bigNatXorWord# m n)
+naturalXor (NB n) (NS m) = NB (bigNatXorWord# n m)
+naturalXor (NB n) (NB m) = naturalFromBigNat# (bigNatXor n m)
+
+naturalTestBit# :: Natural -> Word# -> Bool#
+{-# NOINLINE naturalTestBit# #-}
+naturalTestBit# (NS w) i  = (i `ltWord#` WORD_SIZE_IN_BITS##) &&#
+                            ((w `and#` (1## `uncheckedShiftL#` word2Int# i)) `neWord#` 0##)
+naturalTestBit# (NB bn) i = bigNatTestBit# bn i
+
+naturalTestBit :: Natural -> Word -> Bool
+naturalTestBit !n (W# i) = isTrue# (naturalTestBit# n i)
+
+naturalBit# :: Word# -> Natural
+{-# NOINLINE naturalBit# #-}
+naturalBit# i
+  | isTrue# (i `ltWord#` WORD_SIZE_IN_BITS##) = NS (1## `uncheckedShiftL#` word2Int# i)
+  | True                                      = NB (bigNatBit# i)
+
+naturalBit :: Word -> Natural
+naturalBit (W# i) = naturalBit# i
+
+-- | @since 1.3
+naturalSetBit# :: Natural -> Word# -> Natural
+naturalSetBit# (NS n) i
+  | isTrue# (i `ltWord#` WORD_SIZE_IN_BITS##) = NS (n `or#` (1## `uncheckedShiftL#` word2Int# i))
+  | True                                      = NB (bigNatSetBit# (bigNatFromWord# n) i)
+naturalSetBit# (NB n) i                       = NB (bigNatSetBit# n i)
+
+-- | @since 1.3
+naturalSetBit :: Natural -> Word -> Natural
+naturalSetBit !n (W# i) = naturalSetBit# n i
+
+-- | @since 1.3
+naturalClearBit# :: Natural -> Word# -> Natural
+naturalClearBit# x@(NS n) i
+  | isTrue# (i `ltWord#` WORD_SIZE_IN_BITS##) = NS (n `and#` not# (1## `uncheckedShiftL#` word2Int# i))
+  | True                                      = x
+naturalClearBit# (NB n) i                     = naturalFromBigNat# (bigNatClearBit# n i)
+
+-- | @since 1.3
+naturalClearBit :: Natural -> Word -> Natural
+naturalClearBit !n (W# i) = naturalClearBit# n i
+
+-- | @since 1.3
+naturalComplementBit# :: Natural -> Word# -> Natural
+naturalComplementBit# (NS n) i
+  | isTrue# (i `ltWord#` WORD_SIZE_IN_BITS##) = NS (n `xor#` (1## `uncheckedShiftL#` word2Int# i))
+  | True                                      = NB (bigNatSetBit# (bigNatFromWord# n) i)
+naturalComplementBit# (NB n) i                = naturalFromBigNat# (bigNatComplementBit# n i)
+
+-- | @since 1.3
+naturalComplementBit :: Natural -> Word -> Natural
+naturalComplementBit !n (W# i) = naturalComplementBit# n i
+
+-- | Compute greatest common divisor.
+naturalGcd :: Natural -> Natural -> Natural
+{-# NOINLINE naturalGcd #-}
+naturalGcd (NS 0##) !y       = y
+naturalGcd x        (NS 0##) = x
+naturalGcd (NS 1##) _        = NS 1##
+naturalGcd _        (NS 1##) = NS 1##
+naturalGcd (NB x)   (NB y)   = naturalFromBigNat# (bigNatGcd x y)
+naturalGcd (NB x)   (NS y)   = NS (bigNatGcdWord# x y)
+naturalGcd (NS x)   (NB y)   = NS (bigNatGcdWord# y x)
+naturalGcd (NS x)   (NS y)   = NS (gcdWord# x y)
+
+-- | Compute least common multiple.
+naturalLcm :: Natural -> Natural -> Natural
+{-# NOINLINE naturalLcm #-}
+naturalLcm (NS 0##) !_       = NS 0##
+naturalLcm _        (NS 0##) = NS 0##
+naturalLcm (NS 1##) y        = y
+naturalLcm x        (NS 1##) = x
+naturalLcm (NS a  ) (NS b  ) = naturalFromBigNat# (bigNatLcmWordWord# a b)
+naturalLcm (NB a  ) (NS b  ) = naturalFromBigNat# (bigNatLcmWord# a b)
+naturalLcm (NS a  ) (NB b  ) = naturalFromBigNat# (bigNatLcmWord# b a)
+naturalLcm (NB a  ) (NB b  ) = naturalFromBigNat# (bigNatLcm a b)
+
+-- | Base 2 logarithm
+naturalLog2# :: Natural -> Word#
+{-# NOINLINE naturalLog2# #-}
+naturalLog2# (NS w) = wordLog2# w
+naturalLog2# (NB b) = bigNatLog2# b
+
+-- | Base 2 logarithm
+naturalLog2 :: Natural -> Word
+naturalLog2 !n = W# (naturalLog2# n)
+
+-- | Logarithm for an arbitrary base
+naturalLogBaseWord# :: Word# -> Natural -> Word#
+{-# NOINLINE naturalLogBaseWord# #-}
+naturalLogBaseWord# base (NS a) = wordLogBase# base a
+naturalLogBaseWord# base (NB a) = bigNatLogBaseWord# base a
+
+-- | Logarithm for an arbitrary base
+naturalLogBaseWord :: Word -> Natural -> Word
+naturalLogBaseWord (W# base) !a = W# (naturalLogBaseWord# base a)
+
+-- | Logarithm for an arbitrary base
+naturalLogBase# :: Natural -> Natural -> Word#
+{-# NOINLINE naturalLogBase# #-}
+naturalLogBase# (NS base) !a     = naturalLogBaseWord# base a
+naturalLogBase# (NB _   ) (NS _) = 0##
+naturalLogBase# (NB base) (NB a) = bigNatLogBase# base a
+
+-- | Logarithm for an arbitrary base
+naturalLogBase :: Natural -> Natural -> Word
+naturalLogBase !base !a = W# (naturalLogBase# base a)
+
+-- | \"@'naturalPowMod' /b/ /e/ /m/@\" computes base @/b/@ raised to
+-- exponent @/e/@ modulo @/m/@.
+naturalPowMod :: Natural -> Natural -> Natural -> Natural
+{-# NOINLINE naturalPowMod #-}
+naturalPowMod !_         !_       (NS 0##) = raiseDivZero
+naturalPowMod _          _        (NS 1##) = NS 0##
+naturalPowMod _          (NS 0##) _        = NS 1##
+naturalPowMod (NS 0##)   _        _        = NS 0##
+naturalPowMod (NS 1##)   _        _        = NS 1##
+naturalPowMod (NS b)    (NS e)   (NS m)    = NS (powModWord# b e m)
+naturalPowMod b         e        (NS m)    = NS (bigNatPowModWord#
+                                                   (naturalToBigNat# b)
+                                                   (naturalToBigNat# e)
+                                                    m)
+naturalPowMod b         e        (NB m)    = naturalFromBigNat#
+                                                (bigNatPowMod (naturalToBigNat# b)
+                                                              (naturalToBigNat# e)
+                                                              m)
+
+-- | Compute the number of digits of the Natural in the given base.
+--
+-- `base` must be > 1
+naturalSizeInBase# :: Word# -> Natural -> Word#
+{-# NOINLINE naturalSizeInBase# #-}
+naturalSizeInBase# base (NS w) = wordSizeInBase# base w
+naturalSizeInBase# base (NB n) = bigNatSizeInBase# base n
+
+-- | Write a 'Natural' to @/addr/@ in base-256 representation and return the
+-- number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: write most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+naturalToAddr# :: Natural -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
+naturalToAddr# (NS i) = wordToAddr# i
+naturalToAddr# (NB n) = bigNatToAddr# n
+
+-- | Write a 'Natural' to @/addr/@ in base-256 representation and return the
+-- number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: write most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+naturalToAddr :: Natural -> Addr# -> Bool# -> IO Word
+naturalToAddr a addr e = IO \s -> case naturalToAddr# a addr e s of
+   (# s', w #) -> (# s', W# w #)
+
+
+-- | Read a Natural in base-256 representation from an Addr#.
+--
+-- The size is given in bytes.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Null higher limbs are automatically trimed.
+naturalFromAddr# :: Word# -> Addr# -> Bool# -> State# s -> (# State# s, Natural #)
+naturalFromAddr# sz addr e s =
+   case bigNatFromAddr# sz addr e s of
+      (# s', n #) -> (# s', naturalFromBigNat# n #)
+
+-- | Read a Natural in base-256 representation from an Addr#.
+--
+-- The size is given in bytes.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Null higher limbs are automatically trimed.
+naturalFromAddr :: Word# -> Addr# -> Bool# -> IO Natural
+naturalFromAddr sz addr e = IO (naturalFromAddr# sz addr e)
+
+
+-- | Write a Natural in base-256 representation and return the
+-- number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+naturalToMutableByteArray# :: Natural -> MutableByteArray# s -> Word# -> Bool# -> State# s -> (# State# s, Word# #)
+naturalToMutableByteArray# (NS w) = wordToMutableByteArray# w
+naturalToMutableByteArray# (NB a) = bigNatToMutableByteArray# a
+
+-- | Read a Natural in base-256 representation from a ByteArray#.
+--
+-- The size is given in bytes.
+--
+-- The endianness is selected with the Bool# parameter: most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- Null higher limbs are automatically trimed.
+naturalFromByteArray# :: Word# -> ByteArray# -> Word# -> Bool# -> State# s -> (# State# s, Natural #)
+naturalFromByteArray# sz ba off e s = case bigNatFromByteArray# sz ba off e s of
+   (# s', a #) -> (# s', naturalFromBigNat# a #)
+
+
+
+-- See Note [Optimising conversions between numeric types]
+-- in GHC.Internal.Bignum.Integer
+{-# RULES
+"Word# -> Natural -> Word#"
+  forall x. naturalToWord# (NS x) = x
+
+"BigNat# -> Natural -> BigNat#"
+  forall x. naturalToBigNat# (naturalFromBigNat# x) = x
+#-}
diff --git a/src/GHC/Internal/Bignum/Natural.hs-boot b/src/GHC/Internal/Bignum/Natural.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Natural.hs-boot
@@ -0,0 +1,27 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE MagicHash #-}
+
+module GHC.Internal.Bignum.Natural where
+
+import {-# SOURCE #-} GHC.Internal.Bignum.BigNat
+import GHC.Internal.Bignum.Primitives
+import GHC.Internal.Prim
+import GHC.Internal.Types
+
+data Natural
+   = NS !Word#
+   | NB !BigNat#
+
+naturalToWord# :: Natural -> Word#
+naturalFromWord# :: Word# -> Natural
+naturalFromBigNat# :: BigNat# -> Natural
+naturalToBigNat# :: Natural -> BigNat#
+
+naturalZero :: Natural
+naturalMul :: Natural -> Natural -> Natural
+naturalRem :: Natural -> Natural -> Natural
+naturalShiftR# :: Natural -> Word# -> Natural
+
+naturalIsZero :: Natural -> Bool
+naturalTestBit# :: Natural -> Word# -> Bool#
+naturalEq# :: Natural -> Natural -> Bool#
diff --git a/src/GHC/Internal/Bignum/Primitives.hs b/src/GHC/Internal/Bignum/Primitives.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/Primitives.hs
@@ -0,0 +1,633 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+{-# LANGUAGE NegativeLiterals #-}
+{-# LANGUAGE ExplicitForAll #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE BinaryLiterals #-}
+{-# OPTIONS_GHC -fexpose-all-unfoldings #-}
+
+module GHC.Internal.Bignum.Primitives
+   (
+   -- * Bool#
+   Bool#
+   , (&&#)
+   , (||#)
+   , notB#
+   -- * Int#
+   , testBitI#
+   , minI#
+   , maxI#
+   , sgnI#
+   , absI#
+   , cmpI#
+   , intEncodeDouble#
+   , popCntI#
+   -- * Word#
+   , andNot#
+   , cmpW#
+   , bitW#
+   , maxW#
+   , minW#
+   , testBitW#
+   , shiftRW#
+   , plusWord3#
+   , plusWord12#
+   , quotRemWord3#
+   , wordFromAbsInt#
+   , wordLog2#
+   , wordLogBase#
+   , wordSizeInBase#
+   , wordIsPowerOf2#
+   , wordEncodeDouble#
+   , wordReverseBits#
+   , wordReverseBits32#
+   , wordReverseBytes#
+   -- ** Addr import/export
+   , wordFromAddr#
+   , wordFromAddrLE#
+   , wordFromAddrBE#
+   , wordToAddr#
+   , wordToAddrLE#
+   , wordToAddrBE#
+   , wordWriteAddrLE#
+   , wordWriteAddrBE#
+   -- ** ByteArray import/export
+   , wordFromByteArray#
+   , wordFromByteArrayLE#
+   , wordFromByteArrayBE#
+   , wordToMutableByteArray#
+   , wordToMutableByteArrayLE#
+   , wordToMutableByteArrayBE#
+   , wordWriteMutableByteArrayLE#
+   , wordWriteMutableByteArrayBE#
+   -- * Exception
+   , raiseUnderflow
+   , raiseUnderflow_Word#
+   , raiseDivZero
+   , raiseDivZero_Word#
+   , unexpectedValue
+   , unexpectedValue_Int#
+   , unexpectedValue_Word#
+   -- * IO
+   , ioWord#
+   , ioInt#
+   , ioVoid
+   , ioBool
+   )
+where
+
+#include "MachDeps.h"
+#include "WordSize.h"
+
+-- Required for WORDS_BIGENDIAN
+#include <ghcautoconf.h>
+
+import GHC.Internal.Prim.Exception
+
+import GHC.Internal.Prim
+import GHC.Internal.Types
+
+default ()
+
+----------------------------------
+-- Bool#
+----------------------------------
+
+type Bool# = Int#
+
+(&&#) :: Bool# -> Bool# -> Bool#
+(&&#) = andI#
+
+(||#) :: Bool# -> Bool# -> Bool#
+(||#) = orI#
+
+notB# :: Bool# -> Bool#
+notB# x = x `xorI#` 1#
+
+infixr 3  &&#
+infixr 2  ||#
+
+
+----------------------------------
+-- Int#
+----------------------------------
+
+-- | Branchless `abs`
+absI# :: Int# -> Int#
+absI# i# = (i# `xorI#` nsign) -# nsign
+  where
+    -- nsign = negateInt# (i# <# 0#)
+    nsign = uncheckedIShiftRA# i# (WORD_SIZE_IN_BITS# -# 1#)
+
+-- | Branchless `signum`
+sgnI# :: Int# -> Int#
+sgnI# x# = (x# ># 0#) -# (x# <# 0#)
+
+-- | Population count
+popCntI# :: Int# -> Word#
+popCntI# i = popCnt# (int2Word# i)
+
+-- | Branchless comparison
+cmpI# :: Int# -> Int# -> Int#
+cmpI# x# y# = (x# ># y#) -# (x# <# y#)
+
+testBitI# :: Int# -> Word# -> Bool#
+testBitI# x i = ((uncheckedIShiftL# 1# (word2Int# i)) `andI#` x) /=# 0#
+
+minI# :: Int# -> Int# -> Int#
+minI# x y | isTrue# (x <=# y) = x
+          | True              = y
+
+maxI# :: Int# -> Int# -> Int#
+maxI# x y | isTrue# (x >=# y) = x
+          | True              = y
+
+-- | Encode (# Int# mantissa, Int# exponent #) into a Double#.
+--
+-- (provided by GHC's RTS)
+foreign import ccall unsafe "__int_encodeDouble"
+   intEncodeDouble# :: Int# -> Int# -> Double#
+
+----------------------------------
+-- Word#
+----------------------------------
+
+andNot# :: Word# -> Word# -> Word#
+andNot# x y = x `and#` (not# y)
+
+cmpW# :: Word# -> Word# -> Ordering
+{-# INLINE cmpW# #-}
+cmpW# x# y#
+  | isTrue# (x# `ltWord#` y#) = LT
+  | isTrue# (x# `eqWord#` y#) = EQ
+  | True                      = GT
+
+-- | Return the absolute value of the Int# in a Word#
+wordFromAbsInt# :: Int# -> Word#
+wordFromAbsInt# i
+   | isTrue# (i >=# 0#) = int2Word# i
+   | True               = int2Word# (negateInt# i)
+
+minW# :: Word# -> Word# -> Word#
+minW# x# y# | isTrue# (x# `leWord#` y#) = x#
+            | True                      = y#
+
+maxW# :: Word# -> Word# -> Word#
+maxW# x# y# | isTrue# (x# `gtWord#` y#) = x#
+            | True                      = y#
+
+bitW# :: Int# -> Word#
+bitW# k = 1## `uncheckedShiftL#` k
+
+testBitW# :: Word# -> Word# -> Bool#
+testBitW# w k = w `and#` (1## `uncheckedShiftL#` word2Int# k) `neWord#` 0##
+
+-- | Safe right shift for Word#
+shiftRW# :: Word# -> Word# -> Word#
+shiftRW# a b
+   | isTrue# (b `geWord#` WORD_SIZE_IN_BITS##) = 0##
+   | True                                      = a `uncheckedShiftRL#` (word2Int# b)
+
+-- | (h,l) <- a + (hb,lb)
+plusWord12# :: Word# -> (# Word#,Word# #) -> (# Word#,Word# #)
+{-# INLINABLE plusWord12# #-}
+plusWord12# a0 (# b1,b0 #) = (# m1, m0 #)
+   where
+      !(# t, m0 #) = plusWord2# a0 b0
+      !m1          = plusWord# t b1
+
+-- | Add 3 values together
+plusWord3# :: Word# -> Word# -> Word# -> (# Word#, Word# #)
+{-# INLINABLE plusWord3# #-}
+plusWord3# a b c = (# r1, r0 #)
+   where
+      !(# t1, t0 #) = plusWord2# a b
+      !(# t2, r0 #) = plusWord2# t0 c
+      !r1           = plusWord# t1 t2
+
+
+-- | 2-by-1 large division
+--
+-- Requires:
+--    b0 /= 0
+--    a1 >= b0 (not required, but if not q1=0)
+quotRemWord3# :: (# Word#,Word# #) -> Word# -> (# (# Word#,Word# #),Word# #)
+quotRemWord3# (# a1,a0 #) b0 = (# (# q1, q0 #), r0 #)
+   where
+      !(# q1, r' #) = quotRemWord# a1 b0
+      !(# q0, r0 #) = quotRemWord2# r' a0 b0
+
+
+
+-- | Encode (# Word# mantissa, Int# exponent #) into a Double#.
+--
+-- (provided by GHC's RTS)
+foreign import ccall unsafe "__word_encodeDouble"
+   wordEncodeDouble# :: Word# -> Int# -> Double#
+
+-- | Compute base-2 log of 'Word#'
+--
+-- This is internally implemented as count-leading-zeros machine instruction.
+wordLog2# :: Word# -> Word#
+wordLog2# w   = (WORD_SIZE_IN_BITS## `minusWord#` 1##) `minusWord#` (clz# w)
+
+-- | Logarithm for an arbitrary base
+wordLogBase# :: Word# -> Word# -> Word#
+wordLogBase# base a
+   | isTrue# (base `leWord#` 1##)
+   = unexpectedValue_Word# (# #)
+
+   | 2## <- base
+   = wordLog2# a
+
+   | True
+   = case go base of (# _, e' #) -> e'
+   where
+      goSqr pw = case timesWord2# pw pw of
+         (# 0##, l #) -> go l
+         (# _  , _ #) -> (# a, 0## #)
+      go pw = if isTrue# (a `ltWord#` pw)
+         then (# a, 0## #)
+         else case goSqr pw of
+            (# q, e #) -> if isTrue# (q `ltWord#` pw)
+               then (# q, 2## `timesWord#` e #)
+               else (# q `quotWord#` pw
+                    , 2## `timesWord#` e `plusWord#` 1## #)
+
+wordSizeInBase# :: Word# -> Word# -> Word#
+wordSizeInBase# _    0## = 0##
+wordSizeInBase# base w   = 1## `plusWord#` wordLogBase# base w
+
+-- | Indicate if the value is a power of two and which one
+wordIsPowerOf2# :: Word# -> (# (# #) | Word# #)
+wordIsPowerOf2# w
+   | isTrue# (popCnt# w `neWord#` 1##) = (# (# #) | #)
+   | True                              = (# | ctz# w #)
+
+-- | Reverse bytes in a Word#
+wordReverseBytes# :: Word# -> Word#
+wordReverseBytes# x0 = r
+   where
+#if WORD_SIZE_IN_BITS == 64
+      x1 = ((x0 `and#` 0x00FF00FF00FF00FF##) `uncheckedShiftL#`  8#) `or#` ((x0 `and#` 0xFF00FF00FF00FF00##) `uncheckedShiftRL#`  8#)
+      x2 = ((x1 `and#` 0x0000FFFF0000FFFF##) `uncheckedShiftL#` 16#) `or#` ((x1 `and#` 0xFFFF0000FFFF0000##) `uncheckedShiftRL#` 16#)
+      r  = ((x2 `and#` 0x00000000FFFFFFFF##) `uncheckedShiftL#` 32#) `or#` ((x2 `and#` 0xFFFFFFFF00000000##) `uncheckedShiftRL#` 32#)
+#else
+      x1 = ((x0 `and#` 0x00FF00FF##) `uncheckedShiftL#`  8#) `or#` ((x0 `and#` 0xFF00FF00##) `uncheckedShiftRL#`  8#)
+      r  = ((x1 `and#` 0x0000FFFF##) `uncheckedShiftL#` 16#) `or#` ((x1 `and#` 0xFFFF0000##) `uncheckedShiftRL#` 16#)
+#endif
+
+
+-- | Reverse bits in a Word#
+wordReverseBits# :: Word# -> Word#
+wordReverseBits# x0 = r
+   where
+#if WORD_SIZE_IN_BITS == 64
+      x1 = ((x0 `and#` 0x5555555555555555##) `uncheckedShiftL#`  1#) `or#` ((x0 `and#` 0xAAAAAAAAAAAAAAAA##) `uncheckedShiftRL#`  1#)
+      x2 = ((x1 `and#` 0x3333333333333333##) `uncheckedShiftL#`  2#) `or#` ((x1 `and#` 0xCCCCCCCCCCCCCCCC##) `uncheckedShiftRL#`  2#)
+      x3 = ((x2 `and#` 0x0F0F0F0F0F0F0F0F##) `uncheckedShiftL#`  4#) `or#` ((x2 `and#` 0xF0F0F0F0F0F0F0F0##) `uncheckedShiftRL#`  4#)
+      x4 = ((x3 `and#` 0x00FF00FF00FF00FF##) `uncheckedShiftL#`  8#) `or#` ((x3 `and#` 0xFF00FF00FF00FF00##) `uncheckedShiftRL#`  8#)
+      x5 = ((x4 `and#` 0x0000FFFF0000FFFF##) `uncheckedShiftL#` 16#) `or#` ((x4 `and#` 0xFFFF0000FFFF0000##) `uncheckedShiftRL#` 16#)
+      r  = ((x5 `and#` 0x00000000FFFFFFFF##) `uncheckedShiftL#` 32#) `or#` ((x5 `and#` 0xFFFFFFFF00000000##) `uncheckedShiftRL#` 32#)
+#else
+      x1 = ((x0 `and#` 0x55555555##) `uncheckedShiftL#`  1#) `or#` ((x0 `and#` 0xAAAAAAAA##) `uncheckedShiftRL#`  1#)
+      x2 = ((x1 `and#` 0x33333333##) `uncheckedShiftL#`  2#) `or#` ((x1 `and#` 0xCCCCCCCC##) `uncheckedShiftRL#`  2#)
+      x3 = ((x2 `and#` 0x0F0F0F0F##) `uncheckedShiftL#`  4#) `or#` ((x2 `and#` 0xF0F0F0F0##) `uncheckedShiftRL#`  4#)
+      x4 = ((x3 `and#` 0x00FF00FF##) `uncheckedShiftL#`  8#) `or#` ((x3 `and#` 0xFF00FF00##) `uncheckedShiftRL#`  8#)
+      r  = ((x4 `and#` 0x0000FFFF##) `uncheckedShiftL#` 16#) `or#` ((x4 `and#` 0xFFFF0000##) `uncheckedShiftRL#` 16#)
+#endif
+
+-- | Reverse bits in the Word32 subwords composing a Word#
+wordReverseBits32# :: Word# -> Word#
+#if WORD_SIZE_IN_BITS == 64
+wordReverseBits32# x0 = r
+   where
+      x1 = ((x0 `and#` 0x5555555555555555##) `uncheckedShiftL#`  1#) `or#` ((x0 `and#` 0xAAAAAAAAAAAAAAAA##) `uncheckedShiftRL#`  1#)
+      x2 = ((x1 `and#` 0x3333333333333333##) `uncheckedShiftL#`  2#) `or#` ((x1 `and#` 0xCCCCCCCCCCCCCCCC##) `uncheckedShiftRL#`  2#)
+      x3 = ((x2 `and#` 0x0F0F0F0F0F0F0F0F##) `uncheckedShiftL#`  4#) `or#` ((x2 `and#` 0xF0F0F0F0F0F0F0F0##) `uncheckedShiftRL#`  4#)
+      x4 = ((x3 `and#` 0x00FF00FF00FF00FF##) `uncheckedShiftL#`  8#) `or#` ((x3 `and#` 0xFF00FF00FF00FF00##) `uncheckedShiftRL#`  8#)
+      r  = ((x4 `and#` 0x0000FFFF0000FFFF##) `uncheckedShiftL#` 16#) `or#` ((x4 `and#` 0xFFFF0000FFFF0000##) `uncheckedShiftRL#` 16#)
+#else
+wordReverseBits32# x0 = wordReverseBits# x0
+#endif
+
+
+-- | Write a Word to @/addr/@ in base-256 little-endian representation and
+-- return the number of bytes written.
+wordToAddrLE# :: Word# -> Addr# -> State# s -> (# State# s, Word# #)
+wordToAddrLE# x addr = go x 0#
+   where
+      go w c s
+         | 0## <- w
+         = (# s, int2Word# c #)
+
+         | True
+         = case writeWord8OffAddr# addr c (wordToWord8# w) s of
+            s' -> go (w `uncheckedShiftRL#` 8#) (c +# 1#) s'
+
+-- | Write a Word to @/addr/@ in base-256 big-endian representation and
+-- return the number of bytes written.
+wordToAddrBE# :: Word# -> Addr# -> State# s -> (# State# s, Word# #)
+wordToAddrBE# w addr = go 0# (WORD_SIZE_IN_BITS# -# clz)
+   where
+     !clz = word2Int# (clz# w `and#` (not# 0b0111##)) -- keep complete bytes
+
+     go c sh s
+      | 0# <- sh
+      = (# s, int2Word# c #)
+
+      | True
+      , w' <- wordToWord8# (w `uncheckedShiftRL#` (sh -# 8#))
+      = case writeWord8OffAddr# addr c w' s of
+         s' -> go (c +# 1#) (sh -# 8#) s'
+
+-- | Write a Word to @/addr/@ in base-256 representation and
+-- return the number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: write most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+wordToAddr# :: Word# -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
+wordToAddr# a addr 0# s = wordToAddrLE# a addr s
+wordToAddr# a addr _  s = wordToAddrBE# a addr s
+
+
+-- | Read a Word from @/addr/@ in base-256 little-endian representation.
+--
+-- @'n' is the number of bytes to read.
+wordFromAddrLE# :: Word# -> Addr# -> State# s -> (# State# s, Word# #)
+wordFromAddrLE# n addr s
+   -- Optimize when we read a full word
+   | WORD_SIZE_IN_BYTES## <- n
+   = case readWordOffAddr# addr 0# s of
+#if defined(WORDS_BIGENDIAN)
+      (# s', w #) -> (# s', wordReverseBytes# w #)
+#else
+      (# s', w #) -> (# s', w #)
+#endif
+
+wordFromAddrLE# n addr s0 = go 0## 0# s0
+   where
+      go w c s
+         | isTrue# (c ==# word2Int# n)
+         = (# s, w #)
+
+         | True
+         = case readWord8OffAddr# addr c s of
+            (# s', b #) -> go (w `or#` (word8ToWord# b `uncheckedShiftL#` (c `uncheckedIShiftL#` 3#)))
+                              (c +# 1#)
+                              s'
+
+-- | Read a Word from @/addr/@ in base-256 big-endian representation.
+--
+-- @'n' is the number of bytes to read.
+wordFromAddrBE# :: Word# -> Addr# -> State# s -> (# State# s, Word# #)
+wordFromAddrBE# n addr s
+   -- Optimize when we read a full word
+   | WORD_SIZE_IN_BYTES## <- n
+   = case readWordOffAddr# addr 0# s of
+#if defined(WORDS_BIGENDIAN)
+      (# s', w #) -> (# s', w #)
+#else
+      (# s', w #) -> (# s', wordReverseBytes# w #)
+#endif
+
+wordFromAddrBE# n addr s0 = go 0## 0# s0
+   where
+      go w c s
+         | isTrue# (c ==# word2Int# n)
+         = (# s, w #)
+
+         | True
+         = case readWord8OffAddr# addr c s of
+            (# s', b #) -> go ((w `uncheckedShiftL#` 8#) `or#` word8ToWord# b)
+                              (c +# 1#)
+                              s'
+
+-- | Read a Word from @/addr/@ in base-256 representation.
+--
+-- @'n' is the number of bytes to read.
+--
+-- The endianness is selected with the Bool# parameter: write most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+wordFromAddr# :: Word# -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
+wordFromAddr# a addr 0# s = wordFromAddrLE# a addr s
+wordFromAddr# a addr _  s = wordFromAddrBE# a addr s
+
+
+
+-- | Write a full word with little-endian encoding
+wordWriteAddrLE# :: Word# -> Addr# -> State# s -> State# s
+wordWriteAddrLE# w addr = writeWordOffAddr# addr 0#
+#if defined(WORDS_BIGENDIAN)
+   (wordReverseBytes# w)
+#else
+   w
+#endif
+
+-- | Write a full word with little-endian encoding
+wordWriteAddrBE# :: Word# -> Addr# -> State# s -> State# s
+wordWriteAddrBE# w addr = writeWordOffAddr# addr 0#
+#if defined(WORDS_BIGENDIAN)
+   w
+#else
+   (wordReverseBytes# w)
+#endif
+
+-- | Write a Word to @/MutableByteArray/@ in base-256 little-endian
+-- representation and return the number of bytes written.
+--
+-- The offset is in bytes.
+wordToMutableByteArrayLE# :: Word# -> MutableByteArray# s -> Word# -> State# s -> (# State# s, Word# #)
+wordToMutableByteArrayLE# x mba off = go x 0#
+   where
+      go w c s
+         | 0## <- w
+         = (# s, int2Word# c #)
+
+         | True
+         = case writeWord8Array# mba (word2Int# off +# c) (wordToWord8# w) s of
+            s' -> go (w `uncheckedShiftRL#` 8#) (c +# 1#) s'
+
+-- | Write a Word to @/MutableByteArray/@ in base-256 big-endian representation and
+-- return the number of bytes written.
+--
+-- The offset is in bytes.
+wordToMutableByteArrayBE# :: Word# -> MutableByteArray# s -> Word# -> State# s -> (# State# s, Word# #)
+wordToMutableByteArrayBE# w mba off = go 0# (WORD_SIZE_IN_BITS# -# clz)
+   where
+     !clz = word2Int# (clz# w `and#` (not# 0b0111##)) -- keep complete bytes
+
+     go c sh s
+      | 0# <- sh
+      = (# s, int2Word# c #)
+
+      | True
+      , w' <- wordToWord8# (w `uncheckedShiftRL#` (sh -# 8#))
+      = case writeWord8Array# mba (word2Int# off +# c) w' s of
+         s' -> go (c +# 1#) (sh -# 8#) s'
+
+-- | Write a Word to @/MutableByteArray/@ in base-256 representation and
+-- return the number of bytes written.
+--
+-- The endianness is selected with the Bool# parameter: write most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+--
+-- The offset is in bytes.
+wordToMutableByteArray# :: Word# -> MutableByteArray# s -> Word# -> Bool# -> State# s -> (# State# s, Word# #)
+wordToMutableByteArray# a mba off 0# s = wordToMutableByteArrayLE# a mba off s
+wordToMutableByteArray# a mba off _  s = wordToMutableByteArrayBE# a mba off s
+
+-- | Write a full word with little-endian encoding
+wordWriteMutableByteArrayLE# :: Word# -> MutableByteArray# s -> Word# -> State# s -> State# s
+wordWriteMutableByteArrayLE# w mba off = writeWord8ArrayAsWord# mba (word2Int# off)
+#if defined(WORDS_BIGENDIAN)
+   (wordReverseBytes# w)
+#else
+   w
+#endif
+
+-- | Write a full word with little-endian encoding
+wordWriteMutableByteArrayBE# :: Word# -> MutableByteArray# s -> Word# -> State# s -> State# s
+wordWriteMutableByteArrayBE# w mba off = writeWord8ArrayAsWord# mba (word2Int# off)
+#if defined(WORDS_BIGENDIAN)
+   w
+#else
+   (wordReverseBytes# w)
+#endif
+
+-- | Read a Word from @/ByteArray/@ in base-256 little-endian representation.
+--
+-- @'n' is the number of bytes to read.
+wordFromByteArrayLE# :: Word# -> ByteArray# -> Word# -> Word#
+wordFromByteArrayLE# n ba off =
+   case n of
+      -- Optimize when we read a full word
+      WORD_SIZE_IN_BYTES## -> case indexWord8ArrayAsWord# ba (word2Int# off) of
+#if defined(WORDS_BIGENDIAN)
+         w -> wordReverseBytes# w
+#else
+         w -> w
+#endif
+
+      _ -> let
+            go w c
+               | isTrue# (c ==# word2Int# n)
+               = w
+
+               | True
+               = case indexWord8Array# ba (word2Int# off +# c) of
+                  b -> go (w `or#` (word8ToWord# b `uncheckedShiftL#` (c `uncheckedIShiftL#` 3#)))
+                          (c +# 1#)
+           in go 0## 0#
+
+-- | Read a Word from @/ByteArray/@ in base-256 big-endian representation.
+--
+-- @'n' is the number of bytes to read.
+wordFromByteArrayBE# :: Word# -> ByteArray# -> Word# -> Word#
+wordFromByteArrayBE# n ba off
+   -- Optimize when we read a full word
+   | WORD_SIZE_IN_BYTES## <- n
+   = case indexWord8ArrayAsWord# ba (word2Int# off) of
+#if defined(WORDS_BIGENDIAN)
+      w -> w
+#else
+      w -> wordReverseBytes# w
+#endif
+
+wordFromByteArrayBE# n ba off = go 0## 0#
+   where
+      go w c
+         | isTrue# (c ==# word2Int# n)
+         = w
+
+         | True
+         = case indexWord8Array# ba (word2Int# off +# c) of
+            b -> go ((w `uncheckedShiftL#` 8#) `or#` word8ToWord# b) (c +# 1#)
+
+-- | Read a Word from @/ByteArray/@ in base-256 representation.
+--
+-- @'n' is the number of bytes to read.
+--
+-- The endianness is selected with the Bool# parameter: write most significant
+-- byte first (big-endian) if @1#@ or least significant byte first
+-- (little-endian) if @0#@.
+wordFromByteArray# :: Word# -> ByteArray# -> Word# -> Bool# -> Word#
+wordFromByteArray# a ba off 0# = wordFromByteArrayLE# a ba off
+wordFromByteArray# a ba off _  = wordFromByteArrayBE# a ba off
+
+----------------------------------
+-- IO
+----------------------------------
+
+ioVoid :: IO a -> State# RealWorld -> State# RealWorld
+ioVoid (IO io) s = case io s of
+                  (# s', _ #) -> s'
+
+ioWord# :: IO Word -> State# RealWorld -> (# State# RealWorld, Word# #)
+ioWord# (IO io) s = case io s of
+   (# s', W# w #) -> (# s', w #)
+
+ioInt# :: IO Int -> State# RealWorld -> (# State# RealWorld, Int# #)
+ioInt# (IO io) s = case io s of
+   (# s', I# i #) -> (# s', i #)
+
+ioBool :: IO Bool -> State# RealWorld -> (# State# RealWorld, Bool# #)
+ioBool (IO io) s = case io s of
+   (# s', False #) -> (# s', 0# #)
+   (# s', True #) -> (# s', 1# #)
+
+
+----------------------------------
+-- Exception
+----------------------------------
+
+-- Note [ghc-bignum exceptions]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- `ghc-bignum` package couldn't depend on `ghc-internal` package (it would create a cyclic
+-- dependency). Hence it couldn't import "Control.Exception" and throw exceptions
+-- the usual way. Instead it uses some wired-in functions from `ghc-internal` which
+-- themselves call wired-in functions from the RTS: raiseOverflow,
+-- raiseUnderflow, raiseDivZero.
+--
+-- We have to be careful when we want to throw an exception instead of returning
+-- an unlifted value (e.g. Word#, unboxed tuple, etc.). We have to ensure the
+-- evaluation of the exception throwing function before returning a dummy value,
+-- otherwise it will be removed by the simplifier as dead-code.
+--
+--    foo :: ... -> Word#
+--    foo = ... case raiseDivZero of
+--                !_ -> 0## -- the bang-pattern is necessary!
+--                          -- 0## is a dummy value (unreachable code)
+--
+-- Since ghc-bignum has been merged into ghc-internal, it may be possible to
+-- replace these exception primops with hs-boot files.
+
+unexpectedValue_Int# :: (# #) -> Int#
+unexpectedValue_Int# _ = case unexpectedValue of
+   !_ -> 0# -- see Note [ghc-bignum exceptions]
+
+unexpectedValue_Word# :: (# #) -> Word#
+unexpectedValue_Word# _ = case unexpectedValue of
+   !_ -> 0## -- see Note [ghc-bignum exceptions]
+
+raiseDivZero_Word# :: (# #) -> Word#
+raiseDivZero_Word# _ = case raiseDivZero of
+   !_ -> 0## -- see Note [ghc-bignum exceptions]
+
+raiseUnderflow_Word# :: (# #) -> Word#
+raiseUnderflow_Word# _ = case raiseUnderflow of
+   !_ -> 0## -- see Note [ghc-bignum exceptions]
+
+
+unexpectedValue :: a
+unexpectedValue = raiseOverflow
diff --git a/src/GHC/Internal/Bignum/WordArray.hs b/src/GHC/Internal/Bignum/WordArray.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Bignum/WordArray.hs
@@ -0,0 +1,434 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE KindSignatures #-}
+{-# OPTIONS_GHC -Wno-name-shadowing #-}
+
+module GHC.Internal.Bignum.WordArray where
+
+import GHC.Internal.Prim
+import GHC.Internal.Magic
+import GHC.Internal.Types
+import GHC.Internal.Bignum.Primitives
+
+#include "MachDeps.h"
+#include "WordSize.h"
+
+default ()
+
+-- | Unlifted array of Word
+type WordArray#        = ByteArray#
+type MutableWordArray# = MutableByteArray#
+
+data WordArray          = WordArray WordArray#
+data MutableWordArray s = MutableWordArray (MutableWordArray# s)
+
+-- | Convert limb count into byte count
+wordsToBytes# :: Int# -> Int#
+wordsToBytes# i = i `uncheckedIShiftL#` WORD_SIZE_BYTES_SHIFT#
+
+-- | Convert byte count into limb count
+bytesToWords# :: Int# -> Int#
+bytesToWords# i = i `uncheckedIShiftRL#` WORD_SIZE_BYTES_SHIFT#
+
+
+-- | Create a new WordArray# of the given size (*in Word#*) and apply the
+-- action to it before returning it frozen
+withNewWordArray#
+   :: Int#  -- ^ Size in Word
+   -> (MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld)
+   -> WordArray#
+withNewWordArray# sz act = case runRW# io of (# _, a #) -> a
+   where
+      io s =
+         case newWordArray# sz s of { (# s, mwa #) ->
+         case act mwa s          of { s ->
+         unsafeFreezeByteArray# mwa s
+         }}
+
+-- | Create two new WordArray# of the given sizes (*in Word#*) and apply the
+-- action to them before returning them frozen
+withNewWordArray2#
+   :: Int# -- ^ Size in Word
+   -> Int# -- ^ Ditto
+   -> (MutableWordArray# RealWorld
+      -> MutableWordArray# RealWorld
+      -> State# RealWorld
+      -> State# RealWorld)
+   -> (# WordArray#, WordArray# #)
+withNewWordArray2# sz1 sz2 act = case runRW# io of (# _, a #) -> a
+   where
+      io s =
+         case newWordArray# sz1 s of { (# s, mwa1 #) ->
+         case newWordArray# sz2 s of { (# s, mwa2 #) ->
+         case act mwa1 mwa2 s     of { s ->
+         case unsafeFreezeByteArray# mwa1 s of { (# s, wa1 #) ->
+         case unsafeFreezeByteArray# mwa2 s of { (# s, wa2 #) ->
+            (# s, (# wa1, wa2 #) #)
+         }}}}}
+
+-- | Create a new WordArray#
+newWordArray# :: Int# -> State# s -> (# State# s, MutableWordArray# s #)
+newWordArray# sz s = newByteArray# (wordsToBytes# sz) s
+
+-- | Create a new WordArray# of the given size (*in Word#*), apply the action to
+-- it, trim its most significant zeroes, then return it frozen
+withNewWordArrayTrimmed#
+   :: Int#  -- ^ Size in Word
+   -> (MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld)
+   -> WordArray#
+withNewWordArrayTrimmed# sz act = withNewWordArray# sz \mwa s ->
+   case act mwa s of
+      s' -> mwaTrimZeroes# mwa s'
+
+-- | Create two new WordArray# of the given sizes (*in Word#*), apply the action
+-- to them, trim their most significant zeroes, then return them frozen
+withNewWordArray2Trimmed#
+   :: Int#  -- ^ Size in Word
+   -> Int#  -- ^ Ditto
+   -> (MutableWordArray# RealWorld
+      -> MutableWordArray# RealWorld
+      -> State# RealWorld
+      -> State# RealWorld)
+   -> (# WordArray#, WordArray# #)
+withNewWordArray2Trimmed# sz1 sz2 act = withNewWordArray2# sz1 sz2 \mwa1 mwa2 s ->
+   case act mwa1 mwa2 s of
+      s' -> case mwaTrimZeroes# mwa1 s' of
+         s'' -> mwaTrimZeroes# mwa2 s''
+
+-- | Create a new WordArray# of the given size (*in Word#*), apply the action to
+-- it. If the action returns true#, trim its most significant zeroes, then
+-- return it frozen. Otherwise, return ().
+withNewWordArrayTrimmedMaybe#
+   :: Int#  -- ^ Size in Word
+   -> (MutableWordArray# RealWorld -> State# RealWorld -> (# State# RealWorld, Bool# #))
+   -> (# (# #) | WordArray# #)
+withNewWordArrayTrimmedMaybe# sz act = case runRW# io of (# _, a #) -> a
+   where
+      io s =
+         case newWordArray# sz s of
+            (# s, mwa #) -> case act mwa s of
+               (# s, 0# #) -> (# s, (# (# #) | #) #)
+               (# s, _  #) -> case mwaTrimZeroes# mwa s of
+                  s -> case unsafeFreezeByteArray# mwa s of
+                     (# s, ba #) -> (# s, (# | ba #) #)
+
+-- | Create a WordArray# from two Word#
+--
+-- `wordArrayFromWord2# h l
+--    where h is the most significant word
+--          l is the least significant word
+wordArrayFromWord2# :: Word# -> Word# -> WordArray#
+wordArrayFromWord2# h l   =
+   withNewWordArray# 2# \mwa s ->
+      case mwaWrite# mwa 0# l s of
+         s -> mwaWrite# mwa 1# h s
+
+-- | Create a WordArray# from one Word#
+wordArrayFromWord# :: Word# -> WordArray#
+wordArrayFromWord# w   =
+   withNewWordArray# 1# \mwa s ->
+      mwaWrite# mwa 0# w s
+
+-- | Word array size
+wordArraySize# :: WordArray# -> Int#
+wordArraySize# ba = bytesToWords# (sizeofByteArray# ba)
+
+
+-- | Equality test for WordArray#
+
+-- | Get size in Words
+mwaSize# :: MutableWordArray# s-> State# s -> (# State# s, Int# #)
+mwaSize# mba s = case getSizeofMutableByteArray# mba s of
+   (# s2, sz #) -> (# s2, bytesToWords# sz #)
+
+-- | Get the last Word (must be non empty!)
+wordArrayLast# :: WordArray# -> Word#
+wordArrayLast# a = indexWordArray# a (wordArraySize# a -# 1#)
+
+-- | Copy Words from a WordArray
+--
+-- Don't do anything if the number of words to copy is <= 0
+mwaArrayCopy# :: MutableByteArray# s -> Int# -> WordArray# -> Int# -> Int# -> State# s -> State# s
+mwaArrayCopy# dst dstIdx src srcIdx n s
+   | isTrue# (n <=# 0#) = s
+   | True = copyByteArray#
+               src (wordsToBytes# srcIdx)
+               dst (wordsToBytes# dstIdx)
+               (wordsToBytes# n) s
+
+-- | Shrink last words of a WordArray
+mwaShrink# :: MutableByteArray# s -> Int# -> State# s -> State# s
+mwaShrink# _mwa 0# s = s
+mwaShrink# mwa  i  s =
+   case mwaSize# mwa s of
+      (# s, n #) -> shrinkMutableByteArray# mwa (wordsToBytes# (n -# i)) s
+
+-- | Set size
+mwaSetSize# :: MutableByteArray# s -> Int# -> State# s -> State# s
+mwaSetSize# mwa n s = shrinkMutableByteArray# mwa (wordsToBytes# n) s
+
+-- | Copy the WordArray into the MWA and shrink the size of MWA to the one of
+-- the WordArray
+mwaInitCopyShrink# :: MutableByteArray# s -> WordArray# -> State# s -> State# s
+mwaInitCopyShrink# mwa wa s =
+   case mwaArrayCopy# mwa 0# wa 0# (wordArraySize# wa) s of
+      s -> mwaSetSize# mwa (wordArraySize# wa) s
+
+-- | Trim ending zeroes
+mwaTrimZeroes# :: MutableByteArray# s -> State# s -> State# s
+mwaTrimZeroes# mwa s1 =
+   case mwaClz mwa s1 of
+      (# s2, 0# #) -> s2
+      (# s2, c  #) -> mwaShrink# mwa c s2
+
+-- | Count leading zero Words
+mwaClz :: MutableWordArray# s -> State# s -> (# State# s, Int# #)
+mwaClz mwa s1 = case mwaSize# mwa s1 of
+   (# s2,sz #)  -> mwaClzAt mwa (sz -# 1#) s2
+
+-- | Count leading zero Words starting at given position
+mwaClzAt :: MutableWordArray# s -> Int# -> State# s -> (# State# s, Int# #)
+mwaClzAt mwa = go 0#
+   where
+      go c i s
+         | isTrue# (i <# 0#) = (# s, c #)
+         | True = case readWordArray# mwa i s of
+            (# s', 0## #) -> go (c +# 1#) (i -# 1#) s'
+            (# s', _   #) -> (# s', c #)
+
+-- | Count leading zero Words starting at given position
+waClzAt :: WordArray# -> Int# -> Int#
+waClzAt wa = go 0#
+   where
+      go c i
+         | isTrue# (i <# 0#)
+         = c
+
+         | 0## <- indexWordArray# wa i
+         = go (c +# 1#) (i -# 1#)
+
+         | True
+         = c
+
+-- | Compare the most signiciant limbs of a and b. The comparison stops (i.e.
+-- returns EQ) when there isn't enough lims in a or b to perform another
+-- comparison.
+wordArrayCompareMSWords :: WordArray# -> WordArray# -> Ordering
+wordArrayCompareMSWords wa wb
+   | 0# <- szA
+   , 0# <- szB
+   = EQ
+
+   | 0# <- szA
+   = LT
+
+   | 0# <- szB
+   = GT
+
+   | True
+   = go (szA -# 1#) (szB -# 1#)
+   where
+      szA  = wordArraySize# wa
+      szB  = wordArraySize# wb
+
+      go i j
+         | isTrue# (i <# 0#) = EQ
+         | isTrue# (j <# 0#) = EQ
+         | True =
+            let
+               a = indexWordArray# wa i
+               b = indexWordArray# wb j
+            in if | isTrue# (a `gtWord#` b) -> GT
+                  | isTrue# (b `gtWord#` a) -> LT
+                  | True                    -> go (i -# 1#) (j -# 1#)
+
+
+-- | Compute MutableWordArray <- WordArray + Word
+--
+-- The MutableWordArray may not be initialized and will be erased anyway.
+--
+-- Input: Size(MutableWordArray) = Size(WordArray) + 1
+-- Output: Size(MutableWordArray) = Size(WordArray) [+ 1]
+mwaInitArrayPlusWord :: MutableWordArray# s -> WordArray# -> Word# -> State# s -> State#s
+mwaInitArrayPlusWord mwa wa = go 0#
+   where
+      sz = wordArraySize# wa
+      go i carry s
+         | isTrue# (i ># sz)  = s
+         | isTrue# (i ==# sz) = mwaWriteOrShrink mwa carry i s
+         | 0## <- carry       = -- copy higher remaining words and shrink the mwa
+                                case mwaArrayCopy# mwa i wa i (sz -# i) s of
+                                    s2 -> mwaShrink# mwa 1# s2
+         | True               = let !(# l,c #) = addWordC# (indexWordArray# wa i) carry
+                                in case mwaWrite# mwa i l s of
+                                    s2 -> go (i +# 1#) (int2Word# c) s2
+
+-- | Write the most-significant Word:
+--    * if it is 0: shrink the array of 1 Word
+--    * otherwise: write it
+mwaWriteOrShrink :: MutableWordArray# s -> Word# -> Int# -> State# s -> State# s
+mwaWriteOrShrink mwa 0## _i s = mwaShrink# mwa 1# s
+mwaWriteOrShrink mwa  w   i s = mwaWrite# mwa i w s
+
+-- | Compute the index of the most-significant Word and write it.
+mwaWriteMostSignificant :: MutableWordArray# s -> Word# -> State# s -> State# s
+mwaWriteMostSignificant mwa w s =
+   case mwaSize# mwa s of
+      (# s', sz #) -> mwaWriteOrShrink mwa w (sz -# 1#) s'
+
+-- | MutableWordArray <- zipWith op wa1 wa2
+--
+-- Required output: Size(MutableWordArray) = min Size(wa1) Size(wa2)
+mwaInitArrayBinOp :: MutableWordArray# s -> WordArray# -> WordArray# -> (Word# -> Word# -> Word#) -> State# s -> State#s
+mwaInitArrayBinOp mwa wa wb op s = go 0# s
+   where
+      !sz = minI# (wordArraySize# wa) (wordArraySize# wb)
+      go i s'
+         | isTrue# (i ==# sz) = s'
+         | True =
+            case indexWordArray# wa i `op` indexWordArray# wb i of
+               v -> case mwaWrite# mwa i v s' of
+                  s'' -> go (i +# 1#) s''
+
+-- | Write an element of the MutableWordArray
+mwaWrite# :: MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
+mwaWrite# = writeWordArray#
+
+-- | Fill some part of a MutableWordArray with the given Word#
+mwaFill# :: MutableWordArray# s -> Word# -> Word# -> Word# -> State# s -> State# s
+mwaFill# _   _ _   0## s = s
+mwaFill# mwa v off n   s = case mwaWrite# mwa (word2Int# off) v s of
+   s' -> mwaFill# mwa v (off `plusWord#` 1##) (n `minusWord#` 1##) s'
+
+-- | Add Word# inplace (a the specified offset) in the mwa with carry propagation.
+mwaAddInplaceWord# :: MutableWordArray# d -> Int# -> Word# -> State# d -> State# d
+mwaAddInplaceWord#   _ _ 0## s = s
+mwaAddInplaceWord# mwa i y   s = case readWordArray# mwa i s of
+   (# s1, x #) -> let !(# h,l #) = plusWord2# x y
+                  in case mwaWrite# mwa i l s1 of
+                        s2 -> mwaAddInplaceWord# mwa (i +# 1#) h s2
+
+-- | Sub Word# inplace (at the specified offset) in the mwa with carry
+-- propagation.
+--
+-- Return False# on underflow
+mwaSubInplaceWord#
+   :: MutableWordArray# d
+   -> Int#
+   -> Word#
+   -> State# d
+   -> (# State# d, Bool# #)
+mwaSubInplaceWord# mwa ii iw s1 = case mwaSize# mwa s1 of
+   (# is, sz #) ->
+      let
+         go _ 0## s = (# s, 1# #) -- no underflow
+         go i y   s
+            | isTrue# (i >=# sz) = (# s, 0# #) -- underflow
+            | True = case readWordArray# mwa i s of
+               (# s1, x #) -> let !(# l,h #) = subWordC# x y
+                  in case mwaWrite# mwa i l s1 of
+                     s2 -> go (i +# 1#) (int2Word# h) s2
+      in go ii iw is
+
+
+-- | Trim `a` of `k` less significant limbs and then compare the result with `b`
+--
+-- "mwa" doesn't need to be trimmed
+mwaTrimCompare :: Int# -> MutableWordArray# s -> WordArray# -> State# s -> (# State# s, Ordering #)
+mwaTrimCompare k mwa wb s1
+   | (# s, szA #) <- mwaSize# mwa s1
+   , szB <- wordArraySize# wb
+   =
+     let
+      go i s
+         | isTrue# (i <# 0#) = (# s, EQ #)
+         | True = case readWordArray# mwa (i +# k) s of
+            (# s2, ai #) ->
+               let bi = if isTrue# (i >=# szB)
+                           then 0##
+                           else indexWordArray# wb i
+               in if | isTrue# (ai `gtWord#` bi) -> (# s2, GT #)
+                     | isTrue# (bi `gtWord#` ai) -> (# s2, LT #)
+                     | True                      -> go (i -# 1#) s2
+
+      szTrimA = szA -# k
+
+     in if | isTrue# (szTrimA <# szB) -> (# s, LT #)
+           | True                     -> go (szA -# k -# 1#) s
+
+
+-- | Sub array inplace (at the specified offset) in the mwa with carry propagation.
+--
+-- We don't trim the resulting array!
+--
+-- Return False# on underflow.
+mwaSubInplaceArray :: MutableWordArray# d -> Int# -> WordArray# -> State# d -> (# State# d, Bool# #)
+mwaSubInplaceArray mwa off wb = go (wordArraySize# wb -# 1#)
+   where
+      go i s
+         | isTrue# (i <# 0#) = (# s, 1# #) -- no underflow
+         | True
+         = case mwaSubInplaceWord# mwa (off +# i) (indexWordArray# wb i) s of
+            (# s2, 1# #) -> go (i -# 1#) s2
+            (# s2, _  #) -> (# s2, 0# #) -- underflow
+
+-- | Add array inplace (a the specified offset) in the mwa with carry propagation.
+--
+-- Upper bound of the result mutable aray is not checked against overflow.
+mwaAddInplaceArray :: MutableWordArray# d -> Int# -> WordArray# -> State# d -> State# d
+mwaAddInplaceArray mwa off wb = go 0# 0##
+   where
+      !maxi = wordArraySize# wb
+      go i c s
+         | isTrue# (i ==# maxi) = mwaAddInplaceWord# mwa (i +# off) c s
+         | True
+         = case readWordArray# mwa (i +# off) s of
+            (# s, v #) -> case plusWord3# v (indexWordArray# wb i) c of
+               (# c', v' #) -> case writeWordArray# mwa (i +# off) v' s of
+                  s -> go (i +# 1#) c' s
+
+-- | Sub array inplace (at the specified offset) in the mwa with carry propagation.
+--
+-- We don't trim the resulting array!
+--
+-- Return False# on underflow.
+mwaSubInplaceMutableArray :: MutableWordArray# d -> Int# -> MutableWordArray# d -> State# d -> (# State# d, Bool# #)
+mwaSubInplaceMutableArray mwa off mwb s0 =
+   case mwaSize# mwb s0 of
+      (# s1, szB #) -> go (szB -# 1#) s1
+   where
+      go i s
+         | isTrue# (i <# 0#) = (# s, 1# #) -- no underflow
+         | True
+         = case readWordArray# mwb i s of
+            (# s1, bi #) -> case mwaSubInplaceWord# mwa (off +# i) bi s1 of
+               (# s2, 1# #) -> go (i -# 1#) s2
+               (# s2, _  #) -> (# s2, 0# #) -- underflow
+
+-- | Sub an array inplace and then trim zeroes
+--
+-- Don't check overflow. The caller must ensure that a>=b
+mwaSubInplaceArrayTrim :: MutableWordArray# d -> Int# -> WordArray# -> State# d -> State# d
+mwaSubInplaceArrayTrim mwa off wb s =
+   case mwaSubInplaceArray mwa off wb s of
+      (# s', _ #) -> mwaTrimZeroes# mwa s'
+
+
+-- | Read an indexed Word in the MutableWordArray. If the index is out-of-bound,
+-- return zero.
+mwaReadOrZero :: MutableWordArray# s -> Int# -> State# s  -> (# State# s, Word# #)
+mwaReadOrZero mwa i s = case mwaSize# mwa s of
+   (# s2, sz #)
+      | isTrue# (i >=# sz) -> (# s2, 0## #)
+      | isTrue# (i <# 0#)  -> (# s2, 0## #)
+      | True               -> readWordArray# mwa i s2
+
+mwaRead# :: MutableWordArray# s -> Int# -> State# s -> (# State# s, Word# #)
+mwaRead# = readWordArray#
diff --git a/src/GHC/Internal/ByteOrder.hs-boot b/src/GHC/Internal/ByteOrder.hs-boot
--- a/src/GHC/Internal/ByteOrder.hs-boot
+++ b/src/GHC/Internal/ByteOrder.hs-boot
@@ -20,7 +20,7 @@
 module GHC.Internal.ByteOrder where
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 
 data ByteOrder
     = BigEndian
diff --git a/src/GHC/Internal/CString.hs b/src/GHC/Internal/CString.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/CString.hs
@@ -0,0 +1,344 @@
+{-# LANGUAGE MagicHash, NoImplicitPrelude, BangPatterns, UnliftedFFITypes #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  GHC.Internal.CString
+-- Copyright   :  (c) The University of Glasgow 2011
+-- License     :  see libraries/ghc-internal/LICENSE
+--
+-- Maintainer  :  ghc-devs@haskell.org
+-- Stability   :  internal
+-- Portability :  non-portable (GHC Extensions)
+--
+-- GHC C strings definitions (previously in GHC.Internal.Base).
+-- Use GHC.Exts from the base package instead of importing this
+-- module directly.
+--
+-----------------------------------------------------------------------------
+
+module GHC.Internal.CString (
+        -- * Ascii variants
+        unpackCString#, unpackAppendCString#, unpackFoldrCString#,
+        cstringLength#,
+
+        -- * Utf variants
+        unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#,
+
+        -- * Other
+        unpackNBytes#,
+    ) where
+
+import GHC.Internal.Types hiding (One)
+import GHC.Internal.Prim
+
+{-
+Note [String literals in GHC]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+String literals get quite a bit of special handling in GHC.  This Note
+summarises the moving parts.
+
+* Desugaring: see GHC.HsToCore.Match.Literal.dsLit, which in
+  turn calls GHC.Core.Make.mkStringExprFS.
+
+  The desugarer desugars the Haskell literal "foo" into Core
+     GHC.Internal.CString.unpackCString# "foo"#
+  where "foo"# is primitive string literal (of type Addr#).
+
+  When the string cannot be encoded as a C string, we use UTF8:
+     GHC.Internal.CString.unpackCStringUtf8# "foo"#
+
+* The library module ghc-internal:GHC.Internal.CString has a bunch of functions that
+  work over primitive strings, including GHC.Internal.CString.unpackCString#
+
+* GHC.Core.Op.ConstantFold has some RULES that optimise certain string
+  operations on literal strings. For example:
+
+    + Constant folding the desugared form of ("foo" ++ "bar")
+      into ("foobar")
+    + Comparing strings
+    + and more
+
+* GHC.Internal.Base has a number of regular rules for String literals.
+
+  + a rule "eqString": (==) @String = eqString
+    where GHC.Internal.Base.eqString :: String -> String -> Bool
+
+    ConstantFold has a RULE for eqString on literals:
+     eqString (Lit "foo"#) (Lit "bar"#) --> False
+
+    This allows compile time evaluation of things like "foo" == "bar"
+
+  + A bunch of rules to promote fusion:
+
+    "unpack"       [~1] forall a   . unpackCString# a             = build (unpackFoldrCString# a)
+    "unpack-list"  [1]  forall a   . unpackFoldrCString# a (:) [] = unpackCString# a
+    "unpack-append"     forall a n . unpackFoldrCString# a (:) n  = unpackAppendCString# a n
+
+    And UTF8 variants of these rules.
+
+* We allow primitive (unlifted) literal strings to be top-level
+  bindings, breaking out usual rule.  See GHC.Core
+  Note [Core top-level string literals]
+
+* TODO: There is work on a special code-gen path for top-level boxed strings
+     str :: [Char]
+     str = unpackCString# "foo"#
+  so that they can all share a common code pointer
+
+  There is a WIP MR on gitlab for this: !3012
+
+-}
+
+-----------------------------------------------------------------------------
+-- Unpacking C strings
+-----------------------------------------------------------------------------
+
+-- This code is needed for virtually all programs, since it's used for
+-- unpacking the strings of error messages.
+
+{- Note [Inlining unpackCString#]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+There's really no point in ever inlining things like unpackCString# as the loop
+doesn't specialise in an interesting way and we can't deforest the list
+constructors (we'd want to use unpackFoldrCString# for this). Moreover, it's
+pretty small, so there's a danger that it'll be inlined at every literal, which
+is a waste.
+
+Moreover, inlining early may interfere with a variety of rules that are supposed
+to match unpackCString#,
+
+ * BuiltInRules in GHC.Core.Opt.ConstantFold; e.g.
+       eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2)
+          = s1 == s2
+
+ * unpacking rules; e.g. in GHC.Internal.Base,
+       unpackCString# a
+          = build (unpackFoldrCString# a)
+
+ * stream fusion rules; e.g. in the `text` library,
+       unstream (S.map safe (S.streamList (GHC.unpackCString# a)))
+          = unpackCString# a
+
+Moreover, we want to make it CONLIKE, so that:
+
+* the rules in GHC.Core.Opt.ConstantFold will fire when the string is let-bound.
+  E.g. the eqString rule in GHC.Core.Opt.ConstantFold
+   eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2) = s1==s2
+
+* exprIsConApp_maybe will see the string when we have
+     let x = unpackCString# "foo"#
+     ...(case x of algs)...
+
+All of this goes for unpackCStringUtf8# too.
+-}
+
+{-
+Note [Inlining of unpackFoldrCString]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Usually the unpack-list rule turns unpackFoldrCString# into unpackCString#
+It also has a BuiltInRule in PrelRules.hs:
+     unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n)
+       =  unpackFoldrCString# "foobaz" c n
+
+We use NOINLINE [0] on the grounds that, unlike
+unpackCString#, there *is* some point in inlining
+unpackFoldrCString#, because we get better code for the
+higher-order function call.
+
+This can cause a code size increase but it was minimal
+when looking at nofib.
+
+This is especially important for elem which then results in an
+allocation free loop.
+
+Note [unpackCString# iterating over addr]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+When unpacking unpackCString# and friends repeatedly return a cons cell
+containing:
+* The current character we just unpacked.
+* A thunk to unpack the rest of the string.
+
+In order to minimize the size of the thunk we do not index of
+the start of the string, offsetting into it, but instead increment
+the addr and always use offset 0#.
+
+This works since these two expressions will read from the same address.
+* `indexCharOffAddr# a i`
+* `indexCharOffAddr (a `plusAddr#` i) 0#`
+
+This way we avoid the need for the thunks to close over both the start of
+the string and the current offset, saving a word for each character unpacked.
+
+This has the additional advantage the we can guarantee that only the
+increment will happen in the loop.
+-}
+
+unpackCString# :: Addr# -> [Char]
+{-# NOINLINE CONLIKE unpackCString# #-}
+unpackCString# addr
+    | isTrue# (ch `eqChar#` '\0'#) = []
+    | True                         = C# ch : unpackCString# (addr `plusAddr#` 1#)
+      where
+        -- See Note [unpackCString# iterating over addr]
+        !ch = indexCharOffAddr# addr 0#
+
+
+unpackAppendCString# :: Addr# -> [Char] -> [Char]
+{-# NOINLINE unpackAppendCString# #-}
+     -- See the NOINLINE note on unpackCString#
+unpackAppendCString# addr rest
+    | isTrue# (ch `eqChar#` '\0'#) = rest
+    | True                         = C# ch : unpackAppendCString# (addr `plusAddr#` 1#) rest
+      where
+        -- See Note [unpackCString# iterating over addr]
+        !ch = indexCharOffAddr# addr 0#
+
+-- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString#.
+-- See Note [String literals in GHC] for more details.
+-- See [Inlining of unpackFoldrCString]
+{-# NOINLINE[0] unpackFoldrCString# #-}
+unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a
+unpackFoldrCString# str f z_init = go str z_init
+  where
+    go addr z
+      | isTrue# (ch `eqChar#` '\0'#) = z
+      | True                         = C# ch `f` go (addr `plusAddr#` 1#) z
+      where
+        -- See Note [unpackCString# iterating over addr]
+        !ch = indexCharOffAddr# addr 0#
+
+-- There's really no point in inlining this for the same reasons as
+-- unpackCString. See Note [Inlining unpackCString#] above for details.
+unpackCStringUtf8# :: Addr# -> [Char]
+{-# NOINLINE CONLIKE unpackCStringUtf8# #-}
+unpackCStringUtf8# addr
+    | isTrue# (ch `eqChar#` '\0'#  ) = []
+    | True =
+        let !byte_count = getByteCount ch
+            !utf_ch = unpackUtf8Char# byte_count ch addr
+            !addr' = addr `plusBytes` byte_count
+        in  C# utf_ch : unpackCStringUtf8# addr'
+      where
+        -- See Note [unpackCString# iterating over addr]
+        !ch = indexCharOffAddr# addr 0#
+
+unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char]
+{-# NOINLINE unpackAppendCStringUtf8# #-}
+     -- See the NOINLINE note on unpackCString#
+unpackAppendCStringUtf8# addr rest
+    | isTrue# (ch `eqChar#` '\0'#) = rest
+    | True =
+        let !byte_count = getByteCount ch
+            !utf_ch = unpackUtf8Char# byte_count ch addr
+            !addr' = (addr `plusBytes` byte_count)
+        in  C# utf_ch : unpackAppendCStringUtf8# addr' rest
+      where
+        -- See Note [unpackCString# iterating over addr]
+        !ch = indexCharOffAddr# addr 0#
+
+-- See Note [Inlining of unpackFoldrCString]
+{-# NOINLINE[0] unpackFoldrCStringUtf8# #-}
+unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a
+unpackFoldrCStringUtf8# addr_init f z_init
+  = go addr_init z_init
+  where
+    go addr z
+      | isTrue# (ch `eqChar#` '\0'#) = z
+      | True =
+          let !byte_count = getByteCount ch
+              !utf_ch = unpackUtf8Char# byte_count ch addr
+              !addr' = (addr `plusBytes` byte_count)
+          in C# utf_ch `f` go addr' z
+      where
+        -- See Note [unpackCString# iterating over addr]
+        !ch = indexCharOffAddr# addr 0#
+
+-- There's really no point in inlining this for the same reasons as
+-- unpackCString. See Note [Inlining unpackCString#] above for details.
+unpackNBytes# :: Addr# -> Int# -> [Char]
+{-# NOINLINE unpackNBytes# #-}
+unpackNBytes# _addr 0#   = []
+unpackNBytes#  addr len# = unpack [] (len# -# 1#)
+    where
+     unpack :: [Char] -> Int# -> [Char]
+     unpack acc i#
+      | isTrue# (i# <# 0#)  = acc
+      | True                =
+         case indexCharOffAddr# addr i# of
+            ch -> unpack (C# ch : acc) (i# -# 1#)
+
+-- The return type is not correct here. We really want CSize,
+-- but that type is defined in base. However, CSize should always
+-- match the size of a machine word (I hope), so this is probably
+-- alright on all platforms that GHC supports.
+foreign import ccall unsafe "strlen" c_strlen :: Addr# -> Int#
+
+-- | Compute the length of a NUL-terminated string. This address
+-- must refer to immutable memory. GHC includes a built-in rule for
+-- constant folding when the argument is a statically-known literal.
+-- That is, a core-to-core pass reduces the expression
+-- @cstringLength# "hello"#@ to the constant @5#@.
+cstringLength# :: Addr# -> Int#
+{-# INLINE[0] cstringLength# #-}
+cstringLength# = c_strlen
+
+
+------------------------------
+--- UTF-8 decoding utilities
+------------------------------
+--
+-- This is one of several UTF-8 implementations provided by GHC; see Note
+-- [GHC's many UTF-8 implementations] in "GHC.Encoding.UTF8" for an
+-- overview.
+--
+-- These functions make explicit the logic that was originally
+-- part of unpackCStringUtf8. Since we want the same support for ascii
+-- and non-ascii a variety of functions needs the same logic. Instead
+-- of C&P'in the decoding logic all over we have it here once, and then
+-- force GHC to inline it.
+--
+-- All the overhead of the Bytes argument and calls goes away once all is
+-- said and done. And what remains is readable code in Haskell land and
+-- performant code in the resulting binary.
+
+data Bytes = One | Two | Three | Four
+
+{-# INLINE getByteCount #-}
+getByteCount :: Char# -> Bytes
+getByteCount ch
+    | isTrue# (ch `leChar#` '\x7F'#) = One
+    | isTrue# (ch `leChar#` '\xDF'#) = Two
+    | isTrue# (ch `leChar#` '\xEF'#) = Three
+    | True                           = Four
+
+{-# INLINE plusBytes #-}
+plusBytes :: Addr# -> Bytes -> Addr#
+plusBytes addr bytes =
+  case bytes of
+    One   -> addr `plusAddr#` 1#
+    Two   -> addr `plusAddr#` 2#
+    Three -> addr `plusAddr#` 3#
+    Four  -> addr `plusAddr#` 4#
+
+-- | Take the current address, read unicode char of the given size.
+-- We obviously want the number of bytes, but we have to read one
+-- byte to determine the number of bytes for the current codepoint
+-- so we might as well reuse it and avoid a read.
+--
+-- Side Note: We don't dare to decode all 4 possibilities at once.
+-- Reading past the end of the addr might trigger an exception.
+-- For this reason we really have to check the width first and only
+-- decode after.
+{-# INLINE unpackUtf8Char# #-}
+unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char#
+unpackUtf8Char# bytes ch addr =
+  case bytes of
+    One -> ch
+    Two ->   (chr# (((ord# ch                                           -# 0xC0#) `uncheckedIShiftL#`  6#) +#
+                     (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#)))
+    Three -> (chr# (((ord# ch                                           -# 0xE0#) `uncheckedIShiftL#` 12#) +#
+                    ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#`  6#) +#
+                     (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#)))
+    Four ->  (chr# (((ord# ch                                           -# 0xF0#) `uncheckedIShiftL#` 18#) +#
+                    ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +#
+                    ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#`  6#) +#
+                     (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#)))
diff --git a/src/GHC/Internal/Char.hs b/src/GHC/Internal/Char.hs
--- a/src/GHC/Internal/Char.hs
+++ b/src/GHC/Internal/Char.hs
@@ -6,7 +6,7 @@
       chr
 
       -- * Monomorphic equality operators
-      -- | See GHC.Classes#matching_overloaded_methods_in_rules
+      -- | See GHC.Internal.Classes#matching_overloaded_methods_in_rules
     , eqChar, neChar
     ) where
 
diff --git a/src/GHC/Internal/Classes.hs b/src/GHC/Internal/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Classes.hs
@@ -0,0 +1,1608 @@
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE NoImplicitPrelude, MagicHash, StandaloneDeriving, BangPatterns,
+             KindSignatures, DataKinds, ConstraintKinds,
+              MultiParamTypeClasses, FunctionalDependencies #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+  -- ip :: IP x a => a  is strictly speaking ambiguous, but IP is magic
+{-# LANGUAGE UndecidableSuperClasses #-}
+  -- Because of the type-variable superclasses for tuples
+
+{-# OPTIONS_GHC -Wno-unused-imports #-}
+-- -Wno-unused-imports needed for the GHC.Internal.Tuple import below. Sigh.
+
+{-# OPTIONS_GHC -Wno-unused-top-binds #-}
+-- -Wno-unused-top-binds is there (I hope) to stop Haddock complaining
+-- about the constraint tuples being defined but not used
+
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE UndecidableSuperClasses #-}
+{-# LANGUAGE ConstraintKinds #-}
+
+{-# OPTIONS_HADDOCK not-home #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  GHC.Internal.Classes
+-- Copyright   :  (c) The University of Glasgow, 1992-2002
+-- License     :  see libraries/base/LICENSE
+--
+-- Maintainer  :  ghc-devs@haskell.org
+-- Stability   :  internal
+-- Portability :  non-portable (GHC extensions)
+--
+-- Basic classes.
+-- Do not import this module directly.  It is an GHC internal only
+-- module.  Some of its contents are instead available from @Prelude@
+-- and @GHC.Int@.
+--
+-----------------------------------------------------------------------------
+
+module GHC.Internal.Classes(
+    -- * Implicit parameters
+    IP(..),
+
+    -- * Equality and ordering
+    -- | Do not import these classes from this module. Import them
+    -- from @Prelude@ instead.
+    Eq(..),
+    Ord(..),
+    -- ** Monomorphic equality operators
+    -- $matching_overloaded_methods_in_rules
+    eqInt, neInt,
+    eqWord, neWord,
+    eqChar, neChar,
+    eqFloat, eqDouble,
+    -- ** Monomorphic comparison operators
+    gtInt, geInt, leInt, ltInt, compareInt, compareInt#,
+    gtWord, geWord, leWord, ltWord, compareWord, compareWord#,
+
+    -- * Functions over Bool
+    -- | Do not import these functions from this module. Import them
+    -- from @Prelude@ instead.
+    (&&), (||), not,
+
+    -- * Integer arithmetic
+    divInt#, divInt8#, divInt16#, divInt32#,
+    modInt#, modInt8#, modInt16#, modInt32#,
+    divModInt#, divModInt8#, divModInt16#, divModInt32#,
+
+    -- * Constraint tuples
+    CUnit,
+    CSolo,
+    CTuple0,
+    CTuple1,
+    CTuple2,
+    CTuple3,
+    CTuple4,
+    CTuple5,
+    CTuple6,
+    CTuple7,
+    CTuple8,
+    CTuple9,
+    CTuple10,
+    CTuple11,
+    CTuple12,
+    CTuple13,
+    CTuple14,
+    CTuple15,
+    CTuple16,
+    CTuple17,
+    CTuple18,
+    CTuple19,
+    CTuple20,
+    CTuple21,
+    CTuple22,
+    CTuple23,
+    CTuple24,
+    CTuple25,
+    CTuple26,
+    CTuple27,
+    CTuple28,
+    CTuple29,
+    CTuple30,
+    CTuple31,
+    CTuple32,
+    CTuple33,
+    CTuple34,
+    CTuple35,
+    CTuple36,
+    CTuple37,
+    CTuple38,
+    CTuple39,
+    CTuple40,
+    CTuple41,
+    CTuple42,
+    CTuple43,
+    CTuple44,
+    CTuple45,
+    CTuple46,
+    CTuple47,
+    CTuple48,
+    CTuple49,
+    CTuple50,
+    CTuple51,
+    CTuple52,
+    CTuple53,
+    CTuple54,
+    CTuple55,
+    CTuple56,
+    CTuple57,
+    CTuple58,
+    CTuple59,
+    CTuple60,
+    CTuple61,
+    CTuple62,
+    CTuple63,
+    CTuple64,
+ ) where
+
+-- GHC.Magic is used in some derived instances
+import GHC.Internal.Magic ()
+import GHC.Internal.Prim
+import GHC.Internal.Tuple
+import GHC.Internal.CString (unpackCString#)
+import GHC.Internal.Types
+
+infix  4  ==, /=, <, <=, >=, >
+infixr 3  &&
+infixr 2  ||
+
+default ()              -- Double isn't available yet
+
+-- | The syntax @?x :: a@ is desugared into @IP "x" a@
+-- IP is declared very early, so that libraries can take
+-- advantage of the implicit-call-stack feature
+class IP (x :: Symbol) a | x -> a where
+  ip :: a
+
+{- $matching_overloaded_methods_in_rules
+
+Matching on class methods (e.g. @(==)@) in rewrite rules tends to be a bit
+fragile. For instance, consider this motivating example from the @bytestring@
+library,
+
+@
+break :: (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
+breakByte :: Word8 -> ByteString -> (ByteString, ByteString)
+\{\-\# RULES "break -> breakByte" forall a. break (== x) = breakByte x \#\-\}
+@
+
+Here we have two functions, with @breakByte@ providing an optimized
+implementation of @break@ where the predicate is merely testing for equality
+with a known @Word8@. As written, however, this rule will be quite fragile as
+the @(==)@ class operation rule may rewrite the predicate before our @break@
+rule has a chance to fire.
+
+For this reason, most of the primitive types in @base@ have 'Eq' and 'Ord'
+instances defined in terms of helper functions with inlinings delayed to phase
+1. For instance, @Word8@\'s @Eq@ instance looks like,
+
+@
+instance Eq Word8 where
+    (==) = eqWord8
+    (/=) = neWord8
+
+eqWord8, neWord8 :: Word8 -> Word8 -> Bool
+eqWord8 (W8# x) (W8# y) = ...
+neWord8 (W8# x) (W8# y) = ...
+\{\-\# INLINE [1] eqWord8 \#\-\}
+\{\-\# INLINE [1] neWord8 \#\-\}
+@
+
+This allows us to save our @break@ rule above by rewriting it to instead match
+against @eqWord8@,
+
+@
+\{\-\# RULES "break -> breakByte" forall a. break (`eqWord8` x) = breakByte x \#\-\}
+@
+
+Currently this is only done for @('==')@, @('/=')@, @('<')@, @('<=')@, @('>')@,
+and @('>=')@ for the types in "GHC.Word" and "GHC.Int".
+-}
+
+-- | The 'Eq' class defines equality ('==') and inequality ('/=').
+-- All the basic datatypes exported by the "Prelude" are instances of 'Eq',
+-- and 'Eq' may be derived for any datatype whose constituents are also
+-- instances of 'Eq'.
+--
+-- The Haskell Report defines no laws for 'Eq'. However, instances are
+-- encouraged to follow these properties:
+--
+-- [__Reflexivity__]: @x == x@ = 'True'
+-- [__Symmetry__]: @x == y@ = @y == x@
+-- [__Transitivity__]: if @x == y && y == z@ = 'True', then @x == z@ = 'True'
+-- [__Extensionality__]: if @x == y@ = 'True' and @f@ is a function
+-- whose return type is an instance of 'Eq', then @f x == f y@ = 'True'
+-- [__Negation__]: @x /= y@ = @not (x == y)@
+class  Eq a  where
+    (==), (/=)           :: a -> a -> Bool
+
+    {-# INLINE (/=) #-}
+    {-# INLINE (==) #-}
+    x /= y               = not (x == y)
+    x == y               = not (x /= y)
+    {-# MINIMAL (==) | (/=) #-}
+
+deriving instance Eq ()
+deriving instance Eq a => Eq (Solo a)
+deriving instance (Eq  a, Eq  b) => Eq  (a, b)
+deriving instance (Eq  a, Eq  b, Eq  c) => Eq  (a, b, c)
+deriving instance (Eq  a, Eq  b, Eq  c, Eq  d) => Eq  (a, b, c, d)
+deriving instance (Eq  a, Eq  b, Eq  c, Eq  d, Eq  e) => Eq  (a, b, c, d, e)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f)
+               => Eq (a, b, c, d, e, f)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g)
+               => Eq (a, b, c, d, e, f, g)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
+                   Eq h)
+               => Eq (a, b, c, d, e, f, g, h)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
+                   Eq h, Eq i)
+               => Eq (a, b, c, d, e, f, g, h, i)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
+                   Eq h, Eq i, Eq j)
+               => Eq (a, b, c, d, e, f, g, h, i, j)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
+                   Eq h, Eq i, Eq j, Eq k)
+               => Eq (a, b, c, d, e, f, g, h, i, j, k)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
+                   Eq h, Eq i, Eq j, Eq k, Eq l)
+               => Eq (a, b, c, d, e, f, g, h, i, j, k, l)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
+                   Eq h, Eq i, Eq j, Eq k, Eq l, Eq m)
+               => Eq (a, b, c, d, e, f, g, h, i, j, k, l, m)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
+                   Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n)
+               => Eq (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
+deriving instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g,
+                   Eq h, Eq i, Eq j, Eq k, Eq l, Eq m, Eq n, Eq o)
+               => Eq (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+
+instance (Eq a) => Eq [a] where
+    {-# SPECIALISE instance Eq [[Char]] #-}
+    {-# SPECIALISE instance Eq [Char] #-}
+    {-# SPECIALISE instance Eq [Int] #-}
+    []     == []     = True
+    (x:xs) == (y:ys) = x == y && xs == ys
+    _xs    == _ys    = False
+
+deriving instance Eq Module
+
+instance Eq TrName where
+    TrNameS a == TrNameS b = isTrue# (a `eqAddr#` b)
+    a == b = toString a == toString b
+      where
+        toString (TrNameS s) = unpackCString# s
+        toString (TrNameD s) = s
+
+deriving instance Eq Bool
+deriving instance Eq Ordering
+
+instance Eq Word where
+    (==) = eqWord
+    (/=) = neWord
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+{-# INLINE [1] eqWord #-}
+{-# INLINE [1] neWord #-}
+eqWord, neWord :: Word -> Word -> Bool
+(W# x) `eqWord` (W# y) = isTrue# (x `eqWord#` y)
+(W# x) `neWord` (W# y) = isTrue# (x `neWord#` y)
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+instance Eq Char where
+    (==) = eqChar
+    (/=) = neChar
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+{-# INLINE [1] eqChar #-}
+{-# INLINE [1] neChar #-}
+eqChar, neChar :: Char -> Char -> Bool
+(C# x) `eqChar` (C# y) = isTrue# (x `eqChar#` y)
+(C# x) `neChar` (C# y) = isTrue# (x `neChar#` y)
+
+-- | Note that due to the presence of @NaN@, `Float`'s 'Eq' instance does not
+-- satisfy reflexivity.
+--
+-- >>> 0/0 == (0/0 :: Float)
+-- False
+--
+-- Also note that `Float`'s 'Eq' instance does not satisfy extensionality:
+--
+-- >>> 0 == (-0 :: Float)
+-- True
+-- >>> recip 0 == recip (-0 :: Float)
+-- False
+instance Eq Float where
+    (==) = eqFloat
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+{-# INLINE [1] eqFloat #-}
+eqFloat :: Float -> Float -> Bool
+(F# x) `eqFloat` (F# y) = isTrue# (x `eqFloat#` y)
+
+-- | Note that due to the presence of @NaN@, `Double`'s 'Eq' instance does not
+-- satisfy reflexivity.
+--
+-- >>> 0/0 == (0/0 :: Double)
+-- False
+--
+-- Also note that `Double`'s 'Eq' instance does not satisfy substitutivity:
+--
+-- >>> 0 == (-0 :: Double)
+-- True
+-- >>> recip 0 == recip (-0 :: Double)
+-- False
+instance Eq Double where
+    (==) = eqDouble
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+{-# INLINE [1] eqDouble #-}
+eqDouble :: Double -> Double -> Bool
+(D# x) `eqDouble` (D# y) = isTrue# (x ==## y)
+
+instance Eq Int where
+    (==) = eqInt
+    (/=) = neInt
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+{-# INLINE [1] eqInt #-}
+{-# INLINE [1] neInt #-}
+eqInt, neInt :: Int -> Int -> Bool
+(I# x) `eqInt` (I# y) = isTrue# (x ==# y)
+(I# x) `neInt` (I# y) = isTrue# (x /=# y)
+
+instance Eq TyCon where
+  (==) (TyCon hi1 lo1 _ _ _ _) (TyCon hi2 lo2 _ _ _ _)
+       = isTrue# (hi1 `eqWord64#` hi2) && isTrue# (lo1 `eqWord64#` lo2)
+instance Ord TyCon where
+  compare (TyCon hi1 lo1 _ _ _ _) (TyCon hi2 lo2 _ _ _ _)
+    | isTrue# (hi1 `gtWord64#` hi2) = GT
+    | isTrue# (hi1 `ltWord64#` hi2) = LT
+    | isTrue# (lo1 `gtWord64#` lo2) = GT
+    | isTrue# (lo1 `ltWord64#` lo2) = LT
+    | True                = EQ
+
+
+-- | The 'Ord' class is used for totally ordered datatypes.
+--
+-- Instances of 'Ord' can be derived for any user-defined datatype whose
+-- constituent types are in 'Ord'. The declared order of the constructors in
+-- the data declaration determines the ordering in derived 'Ord' instances. The
+-- 'Ordering' datatype allows a single comparison to determine the precise
+-- ordering of two objects.
+--
+-- 'Ord', as defined by the Haskell report, implements a total order and has the
+-- following properties:
+--
+-- [__Comparability__]: @x <= y || y <= x@ = 'True'
+-- [__Transitivity__]: if @x <= y && y <= z@ = 'True', then @x <= z@ = 'True'
+-- [__Reflexivity__]: @x <= x@ = 'True'
+-- [__Antisymmetry__]: if @x <= y && y <= x@ = 'True', then @x == y@ = 'True'
+--
+-- The following operator interactions are expected to hold:
+--
+-- 1. @x >= y@ = @y <= x@
+-- 2. @x < y@ = @x <= y && x /= y@
+-- 3. @x > y@ = @y < x@
+-- 4. @x < y@ = @compare x y == LT@
+-- 5. @x > y@ = @compare x y == GT@
+-- 6. @x == y@ = @compare x y == EQ@
+-- 7. @min x y == if x <= y then x else y@ = 'True'
+-- 8. @max x y == if x >= y then x else y@ = 'True'
+--
+-- Note that (7.) and (8.) do /not/ require 'min' and 'max' to return either of
+-- their arguments. The result is merely required to /equal/ one of the
+-- arguments in terms of '(==)'. Users who expect a stronger guarantee are advised
+-- to write their own min and/or max functions.
+--
+-- The nuance of the above distinction is not always fully internalized by
+-- developers, and in the past (tracing back to the Haskell 1.4 Report) the
+-- specification for 'Ord' asserted the stronger property that @(min x y, max x
+-- y) = (x, y)@ or @(y, x)@, or in other words, that 'min' and 'max' /will/
+-- return one of their arguments, using argument order as the tie-breaker if
+-- the arguments are equal by comparison. A few list and
+-- 'Data.Foldable.Foldable' functions have behavior that is best understood
+-- with this assumption in mind: all variations of @minimumBy@ and @maximumBy@
+-- (which can't use 'min' and 'max' in their implementations) are written such
+-- that @minimumBy 'compare'@ and @maximumBy 'compare'@ are respectively
+-- equivalent to @minimum@ and @maximum@ (which do use 'min' and 'max') only if
+-- 'min' and 'max' adhere to this tie-breaking convention. Otherwise, if there
+-- are multiple least or largest elements in a container, @minimum@ and
+-- @maximum@ may not return the /same/ one that @minimumBy 'compare'@ and
+-- @maximumBy 'compare'@ do (though they should return something that is
+-- /equal/). (This is relevant for types with non-extensional equality, like
+-- 'Data.Semigroup.Arg', but also in cases where the precise reference held
+-- matters for memory-management reasons.) Unless there is a reason to deviate,
+-- it is less confusing for implementors of 'Ord' to respect this same
+-- convention (as the default definitions of 'min' and 'max' do).
+--
+-- Minimal complete definition: either 'compare' or '<='.
+-- Using 'compare' can be more efficient for complex types.
+--
+class  (Eq a) => Ord a  where
+    compare              :: a -> a -> Ordering
+    (<), (<=), (>), (>=) :: a -> a -> Bool
+    max, min             :: a -> a -> a
+
+    compare x y = if x == y then EQ
+                  -- NB: must be '<=' not '<' to validate the
+                  -- above claim about the minimal things that
+                  -- can be defined for an instance of Ord:
+                  else if x <= y then LT
+                  else GT
+
+    x <= y = case compare x y of { GT -> False; _ -> True }
+    x >= y = y <= x
+    x > y = not (x <= y)
+    x < y = not (y <= x)
+
+
+        -- These two default methods use '<=' rather than 'compare'
+        -- because the latter is often more expensive
+    max x y = if x <= y then y else x
+    min x y = if x <= y then x else y
+    {-# MINIMAL compare | (<=) #-}
+
+deriving instance Ord ()
+deriving instance Ord a => Ord (Solo a)
+deriving instance (Ord a, Ord b) => Ord (a, b)
+deriving instance (Ord a, Ord b, Ord c) => Ord (a, b, c)
+deriving instance (Ord a, Ord b, Ord c, Ord d) => Ord (a, b, c, d)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e) => Ord (a, b, c, d, e)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f)
+               => Ord (a, b, c, d, e, f)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g)
+               => Ord (a, b, c, d, e, f, g)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
+                   Ord h)
+               => Ord (a, b, c, d, e, f, g, h)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
+                   Ord h, Ord i)
+               => Ord (a, b, c, d, e, f, g, h, i)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
+                   Ord h, Ord i, Ord j)
+               => Ord (a, b, c, d, e, f, g, h, i, j)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
+                   Ord h, Ord i, Ord j, Ord k)
+               => Ord (a, b, c, d, e, f, g, h, i, j, k)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
+                   Ord h, Ord i, Ord j, Ord k, Ord l)
+               => Ord (a, b, c, d, e, f, g, h, i, j, k, l)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
+                   Ord h, Ord i, Ord j, Ord k, Ord l, Ord m)
+               => Ord (a, b, c, d, e, f, g, h, i, j, k, l, m)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
+                   Ord h, Ord i, Ord j, Ord k, Ord l, Ord m, Ord n)
+               => Ord (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
+deriving instance (Ord a, Ord b, Ord c, Ord d, Ord e, Ord f, Ord g,
+                   Ord h, Ord i, Ord j, Ord k, Ord l, Ord m, Ord n, Ord o)
+               => Ord (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+
+instance (Ord a) => Ord [a] where
+    {-# SPECIALISE instance Ord [[Char]] #-}
+    {-# SPECIALISE instance Ord [Char] #-}
+    {-# SPECIALISE instance Ord [Int] #-}
+    compare []     []     = EQ
+    compare []     (_:_)  = LT
+    compare (_:_)  []     = GT
+    compare (x:xs) (y:ys) = case compare x y of
+                                EQ    -> compare xs ys
+                                other -> other
+
+deriving instance Ord Bool
+deriving instance Ord Ordering
+
+-- We don't use deriving for Ord Char, because for Ord the derived
+-- instance defines only compare, which takes two primops.  Then
+-- '>' uses compare, and therefore takes two primops instead of one.
+instance Ord Char where
+    (C# c1) >  (C# c2) = isTrue# (c1 `gtChar#` c2)
+    (C# c1) >= (C# c2) = isTrue# (c1 `geChar#` c2)
+    (C# c1) <= (C# c2) = isTrue# (c1 `leChar#` c2)
+    (C# c1) <  (C# c2) = isTrue# (c1 `ltChar#` c2)
+
+-- | See @instance@ 'Ord' 'Double' for discussion of deviations from IEEE 754 standard.
+instance Ord Float where
+    (F# x) `compare` (F# y)
+        = if      isTrue# (x `ltFloat#` y) then LT
+          else if isTrue# (x `eqFloat#` y) then EQ
+          else                                  GT
+
+    (F# x) <  (F# y) = isTrue# (x `ltFloat#` y)
+    (F# x) <= (F# y) = isTrue# (x `leFloat#` y)
+    (F# x) >= (F# y) = isTrue# (x `geFloat#` y)
+    (F# x) >  (F# y) = isTrue# (x `gtFloat#` y)
+
+-- | IEEE 754 'Double'-precision type includes not only numbers, but also
+-- positive and negative infinities and a special element called @NaN@
+-- (which can be quiet or signal).
+--
+-- IEEE 754-2008, section 5.11 requires that if at least one of arguments of
+-- '<=', '<', '>', '>=' is @NaN@ then the result of the comparison is 'False',
+-- and @instance@ 'Ord' 'Double' complies with this requirement. This violates
+-- the reflexivity: both @NaN@ '<=' @NaN@ and @NaN@ '>=' @NaN@ are 'False'.
+--
+-- IEEE 754-2008, section 5.10 defines @totalOrder@ predicate. Unfortunately,
+-- 'compare' on 'Double's violates the IEEE standard and does not define a total order.
+-- More specifically, both 'compare' @NaN@ @x@ and 'compare' @x@ @NaN@ always return 'GT'.
+--
+-- Thus, users must be extremely cautious when using @instance@ 'Ord' 'Double'.
+-- For instance, one should avoid ordered containers with keys represented by 'Double',
+-- because data loss and corruption may happen. An IEEE-compliant 'compare' is available
+-- in @fp-ieee@ package as @TotallyOrdered@ newtype.
+--
+-- Moving further, the behaviour of 'min' and 'max' with regards to @NaN@ is
+-- also non-compliant. IEEE 754-2008, section 5.3.1 defines that quiet @NaN@
+-- should be treated as a missing data by @minNum@ and @maxNum@ functions,
+-- for example, @minNum(NaN, 1) = minNum(1, NaN) = 1@. Some languages such as Java
+-- deviate from the standard implementing @minNum(NaN, 1) = minNum(1, NaN) = NaN@.
+-- However, 'min' / 'max' in @base@ are even worse: 'min' @NaN@ 1 is 1, but 'min' 1 @NaN@
+-- is @NaN@.
+--
+-- IEEE 754-2008 compliant 'min' / 'max' can be found in @ieee754@ package under
+-- @minNum@ / @maxNum@ names. Implementations compliant with
+-- @minimumNumber@ / @maximumNumber@ from a newer
+-- [IEEE 754-2019](https://grouper.ieee.org/groups/msc/ANSI_IEEE-Std-754-2019/background/),
+-- section 9.6 are available from @fp-ieee@ package.
+--
+instance Ord Double where
+    (D# x) `compare` (D# y)
+        = if      isTrue# (x <##  y) then LT
+          else if isTrue# (x ==## y) then EQ
+          else                            GT
+
+    (D# x) <  (D# y) = isTrue# (x <##  y)
+    (D# x) <= (D# y) = isTrue# (x <=## y)
+    (D# x) >= (D# y) = isTrue# (x >=## y)
+    (D# x) >  (D# y) = isTrue# (x >##  y)
+
+instance Ord Int where
+    compare = compareInt
+    (<)     = ltInt
+    (<=)    = leInt
+    (>=)    = geInt
+    (>)     = gtInt
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+{-# INLINE [1] gtInt #-}
+{-# INLINE [1] geInt #-}
+{-# INLINE [1] ltInt #-}
+{-# INLINE [1] leInt #-}
+gtInt, geInt, ltInt, leInt :: Int -> Int -> Bool
+(I# x) `gtInt` (I# y) = isTrue# (x >#  y)
+(I# x) `geInt` (I# y) = isTrue# (x >=# y)
+(I# x) `ltInt` (I# y) = isTrue# (x <#  y)
+(I# x) `leInt` (I# y) = isTrue# (x <=# y)
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+{-# INLINE [1] compareInt #-}
+compareInt :: Int -> Int -> Ordering
+(I# x#) `compareInt` (I# y#) = compareInt# x# y#
+
+compareInt# :: Int# -> Int# -> Ordering
+compareInt# x# y#
+    | isTrue# (x# <#  y#) = LT
+    | isTrue# (x# ==# y#) = EQ
+    | True                = GT
+
+instance Ord Word where
+    compare = compareWord
+    (<)     = ltWord
+    (<=)    = leWord
+    (>=)    = geWord
+    (>)     = gtWord
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+{-# INLINE [1] gtWord #-}
+{-# INLINE [1] geWord #-}
+{-# INLINE [1] ltWord #-}
+{-# INLINE [1] leWord #-}
+gtWord, geWord, ltWord, leWord :: Word -> Word -> Bool
+(W# x) `gtWord` (W# y) = isTrue# (x `gtWord#` y)
+(W# x) `geWord` (W# y) = isTrue# (x `geWord#` y)
+(W# x) `ltWord` (W# y) = isTrue# (x `ltWord#` y)
+(W# x) `leWord` (W# y) = isTrue# (x `leWord#` y)
+
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
+{-# INLINE [1] compareWord #-}
+compareWord :: Word -> Word -> Ordering
+(W# x#) `compareWord` (W# y#) = compareWord# x# y#
+
+compareWord# :: Word# -> Word# -> Ordering
+compareWord# x# y#
+    | isTrue# (x# `ltWord#` y#) = LT
+    | isTrue# (x# `eqWord#` y#) = EQ
+    | True                      = GT
+
+-- OK, so they're technically not part of a class...:
+
+-- Boolean functions
+
+-- | Boolean \"and\", lazy in the second argument
+(&&)                    :: Bool -> Bool -> Bool
+True  && x              =  x
+False && _              =  False
+
+-- | Boolean \"or\", lazy in the second argument
+(||)                    :: Bool -> Bool -> Bool
+True  || _              =  True
+False || x              =  x
+
+-- | Boolean \"not\"
+not                     :: Bool -> Bool
+not True                =  False
+not False               =  True
+
+
+------------------------------------------------------------------------
+-- These don't really belong here, but we don't have a better place to
+-- put them
+
+-- These functions have built-in rules.
+{-# INLINE [0] divInt# #-}
+divInt# :: Int# -> Int# -> Int#
+x# `divInt#` y# = ((x# +# bias#) `quotInt#` y#) -# hard#
+   where
+      -- See Note [divInt# implementation]
+      !yn#   = y# <# 0#
+      !c0#   = (x# <# 0#) `andI#` (notI# yn#)
+      !c1#   = (x# ># 0#) `andI#` yn#
+      !bias# = c0# -# c1#
+      !hard# = c0# `orI#` c1#
+
+{-# INLINE [0] divInt8# #-}
+divInt8# :: Int8# -> Int8# -> Int8#
+x# `divInt8#` y# = ((x# `plusInt8#` bias#) `quotInt8#` y#) `subInt8#` hard#
+   where
+      zero# = intToInt8# 0#
+      x `andInt8#` y = word8ToInt8# (int8ToWord8# x `andWord8#` int8ToWord8# y)
+      x `orInt8#` y = word8ToInt8# (int8ToWord8# x `orWord8#` int8ToWord8# y)
+      notInt8# x = word8ToInt8# (notWord8# (int8ToWord8# x))
+      -- See Note [divInt# implementation]
+      !yn#   = intToInt8# (y# `ltInt8#` zero#)
+      !c0#   = intToInt8# (x# `ltInt8#` zero#) `andInt8#` (notInt8# yn#)
+      !c1#   = intToInt8# (x# `gtInt8#` zero#) `andInt8#` yn#
+      !bias# = c0# `subInt8#` c1#
+      !hard# = c0# `orInt8#` c1#
+
+{-# INLINE [0] divInt16# #-}
+divInt16# :: Int16# -> Int16# -> Int16#
+x# `divInt16#` y# = ((x# `plusInt16#` bias#) `quotInt16#` y#) `subInt16#` hard#
+   where
+      zero# = intToInt16# 0#
+      x `andInt16#` y = word16ToInt16# (int16ToWord16# x `andWord16#` int16ToWord16# y)
+      x `orInt16#` y = word16ToInt16# (int16ToWord16# x `orWord16#` int16ToWord16# y)
+      notInt16# x = word16ToInt16# (notWord16# (int16ToWord16# x))
+      -- See Note [divInt# implementation]
+      !yn#   = intToInt16# (y# `ltInt16#` zero#)
+      !c0#   = intToInt16# (x# `ltInt16#` zero#) `andInt16#` (notInt16# yn#)
+      !c1#   = intToInt16# (x# `gtInt16#` zero#) `andInt16#` yn#
+      !bias# = c0# `subInt16#` c1#
+      !hard# = c0# `orInt16#` c1#
+
+{-# INLINE [0] divInt32# #-}
+divInt32# :: Int32# -> Int32# -> Int32#
+x# `divInt32#` y# = ((x# `plusInt32#` bias#) `quotInt32#` y#) `subInt32#` hard#
+   where
+      zero# = intToInt32# 0#
+      x `andInt32#` y = word32ToInt32# (int32ToWord32# x `andWord32#` int32ToWord32# y)
+      x `orInt32#` y = word32ToInt32# (int32ToWord32# x `orWord32#` int32ToWord32# y)
+      notInt32# x = word32ToInt32# (notWord32# (int32ToWord32# x))
+      -- See Note [divInt# implementation]
+      !yn#   = intToInt32# (y# `ltInt32#` zero#)
+      !c0#   = intToInt32# (x# `ltInt32#` zero#) `andInt32#` (notInt32# yn#)
+      !c1#   = intToInt32# (x# `gtInt32#` zero#) `andInt32#` yn#
+      !bias# = c0# `subInt32#` c1#
+      !hard# = c0# `orInt32#` c1#
+
+-- Note [divInt# implementation]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- divInt# (truncated toward zero) is implemented with quotInt# (truncated
+-- toward negative infinity). They differ when inputs x and y have different signs:
+--  - x `rem` y has the sign of x and (x `quot` y)*y + (x `rem` y) == x
+--  - x `mod` y has the sign of y and (x `div`  y)*y + (x `mod` y) == x
+--
+-- So we bias the input and the result of quotInt as follows:
+--
+--         if isTrue# (x# ># 0#) && isTrue# (y# <# 0#) then ((x# -# 1#) `quotInt#` y#) -# 1#
+--    else if isTrue# (x# <# 0#) && isTrue# (y# ># 0#) then ((x# +# 1#) `quotInt#` y#) -# 1#
+--    else x# `quotInt#` y#
+--
+-- However this leads to assembly code with lots of branches (#19636) while we
+-- would like simpler code that we could inline (#18067). So we use some
+-- branchless code instead as derived below:
+--
+--         if isTrue# (x# ># 0#) && isTrue# (y# <# 0#) then ((x# -# 1#) `quotInt#` y#) -# 1#
+--    else if isTrue# (x# <# 0#) && isTrue# (y# ># 0#) then ((x# +# 1#) `quotInt#` y#) -# 1#
+--    else x# `quotInt#` y#
+--
+--  ===> { Give names to constants and always use them }
+--
+--    ((x# +# bias#) `quotInt#` y#) -# hard#
+--      where
+--        (bias#,hard#)
+--          | isTrue# (x# ># 0#) && isTrue# (y# <# 0#) = (-1#, 1#)
+--          | isTrue# (x# <# 0#) && isTrue# (y# ># 0#) = ( 1#, 1#)
+--          | otherwise                                = ( 0#, 0#)
+--
+--  ===> { Compute bias# and hard# independently using Bool# (0#,1#) }
+--
+--    ((x# +# bias#) `quotInt#` y#) -# hard#
+--      where
+--        c0#   = (x# <# 0#) &&# (y# ># 0#)
+--        c1#   = (x# ># 0#) &&# (y# <# 0#)
+--        bias# = c0# -# c1#  -- both cases are mutually exclusive so we can subtract them
+--        hard# = c0# ||# c1# -- (we could add them too here but OR is slightly better)
+--
+--  ===> { Use yn# variable for "y# <# 0#" }
+--
+--    ((x# +# bias#) `quotInt#` y#) -# hard#
+--      where
+--        -- y# ==# 0# throws an exception so we don't need to consider it
+--        yn#   = y# <# 0#
+--        c0#   = (x# <# 0#) &&# (notI# yn#)
+--        c1#   = (x# ># 0#) &&# yn#
+--        bias# = c0# -# c1#
+--        hard# = c0# ||# c1#
+--
+--
+-- Note that we need to be careful NOT to overflow if we do any additional
+-- arithmetic on the arguments...  the following previous version of this code
+-- had problems with overflow:
+--    | (x# ># 0#) && (y# <# 0#) = ((x# -# y#) -# 1#) `quotInt#` y#
+--    | (x# <# 0#) && (y# ># 0#) = ((x# -# y#) +# 1#) `quotInt#` y#
+
+{-# INLINE [0] modInt# #-}
+modInt# :: Int# -> Int# -> Int#
+x# `modInt#` y# = r# +# k#
+  where
+    -- See Note [modInt# implementation]
+    !yn# = y# <# 0#
+    !c0# = (x# <# 0#) `andI#` (notI# yn#)
+    !c1# = (x# ># 0#) `andI#` yn#
+    !s#  = 0# -# ((c0# `orI#` c1#) `andI#` (r# /=# 0#))
+    !k#  = s# `andI#` y#
+    !r#  = x# `remInt#` y#
+
+{-# INLINE [0] modInt8# #-}
+modInt8# :: Int8# -> Int8# -> Int8#
+x# `modInt8#` y# = r# `plusInt8#` k#
+  where
+    zero# = intToInt8# 0#
+    x `andInt8#` y = word8ToInt8# (int8ToWord8# x `andWord8#` int8ToWord8# y)
+    x `orInt8#` y = word8ToInt8# (int8ToWord8# x `orWord8#` int8ToWord8# y)
+    notInt8# x = word8ToInt8# (notWord8# (int8ToWord8# x))
+    -- See Note [modInt# implementation]
+    !yn# = intToInt8# (y# `ltInt8#` zero#)
+    !c0# = intToInt8# (x# `ltInt8#` zero#) `andInt8#` (notInt8# yn#)
+    !c1# = intToInt8# (x# `gtInt8#` zero#) `andInt8#` yn#
+    !s#  = zero# `subInt8#` ((c0# `orInt8#` c1#) `andInt8#` (intToInt8# (r# `neInt8#` zero#)))
+    !k#  = s# `andInt8#` y#
+    !r#  = x# `remInt8#` y#
+
+{-# INLINE [0] modInt16# #-}
+modInt16# :: Int16# -> Int16# -> Int16#
+x# `modInt16#` y# = r# `plusInt16#` k#
+  where
+    zero# = intToInt16# 0#
+    x `andInt16#` y = word16ToInt16# (int16ToWord16# x `andWord16#` int16ToWord16# y)
+    x `orInt16#` y = word16ToInt16# (int16ToWord16# x `orWord16#` int16ToWord16# y)
+    notInt16# x = word16ToInt16# (notWord16# (int16ToWord16# x))
+    -- See Note [modInt# implementation]
+    !yn# = intToInt16# (y# `ltInt16#` zero#)
+    !c0# = intToInt16# (x# `ltInt16#` zero#) `andInt16#` (notInt16# yn#)
+    !c1# = intToInt16# (x# `gtInt16#` zero#) `andInt16#` yn#
+    !s#  = zero# `subInt16#` ((c0# `orInt16#` c1#) `andInt16#` (intToInt16# (r# `neInt16#` zero#)))
+    !k#  = s# `andInt16#` y#
+    !r#  = x# `remInt16#` y#
+
+{-# INLINE [0] modInt32# #-}
+modInt32# :: Int32# -> Int32# -> Int32#
+x# `modInt32#` y# = r# `plusInt32#` k#
+  where
+    zero# = intToInt32# 0#
+    x `andInt32#` y = word32ToInt32# (int32ToWord32# x `andWord32#` int32ToWord32# y)
+    x `orInt32#` y = word32ToInt32# (int32ToWord32# x `orWord32#` int32ToWord32# y)
+    notInt32# x = word32ToInt32# (notWord32# (int32ToWord32# x))
+    -- See Note [modInt# implementation]
+    !yn# = intToInt32# (y# `ltInt32#` zero#)
+    !c0# = intToInt32# (x# `ltInt32#` zero#) `andInt32#` (notInt32# yn#)
+    !c1# = intToInt32# (x# `gtInt32#` zero#) `andInt32#` yn#
+    !s#  = zero# `subInt32#` ((c0# `orInt32#` c1#) `andInt32#` (intToInt32# (r# `neInt32#` zero#)))
+    !k#  = s# `andInt32#` y#
+    !r#  = x# `remInt32#` y#
+
+-- Note [modInt# implementation]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- Similarly to divInt# (see Note [divInt# implementation]), we can derive the
+-- branchless implementation of modInt# as follows:
+--
+--    = if isTrue# (x# ># 0#) && isTrue# (y# <# 0#) ||
+--         isTrue# (x# <# 0#) && isTrue# (y# ># 0#)
+--      then if isTrue# (r# /=# 0#) then r# +# y# else 0#
+--      else r#
+--    where
+--     r# = x# `remInt#` y#
+--
+--  ===> { Introduce constant k# }
+--
+--    r# +# k#
+--      where
+--        k# = if isTrue# (x# ># 0#) && isTrue# (y# <# 0#) ||
+--                isTrue# (x# <# 0#) && isTrue# (y# ># 0#)
+--             then if isTrue# (r# /=# 0#) then y# else 0#
+--             else 0#
+--        r# = x# `remInt#` y#
+--
+--  ===> { Compute using Bool# }
+--
+--    r# +# k#
+--      where
+--        yn# = y# <# 0# -- we don't need to consider y# ==# 0#
+--        c0# = (x# <# 0#) &&# (notI# yn#)
+--        c1# = (x# ># 0#) &&# yn#
+--        k#  = if isTrue# ((c0# ||# c1#) &&# (r# /=# 0#))
+--                then y#
+--                else 0#
+--        r#  = x# `remInt#` y#
+--
+--  ===> { Select y# or 0# in branchless way }
+--
+--    r# +# k#
+--      where
+--        yn# = y# <# 0#
+--        c0# = (x# <# 0#) &&# (notI# yn#)
+--        c1# = (x# ># 0#) &&# yn#
+--        -- s# is either equal to:
+--        --    0#  (00..00b)
+--        --    -1# (11..11b)
+--        -- So we can AND s# with y#
+--        s#  = 0# -# ((c0# ||# c1#) &&# (r# /=# 0#))
+--        k#  = s# &&# y#
+--        r#  = x# `remInt#` y#
+
+{-# INLINE [0] divModInt# #-}
+divModInt# :: Int# -> Int# -> (# Int#, Int# #)
+x# `divModInt#` y# = case (x# +# bias#) `quotRemInt#` y# of
+  (# q#, r# #) -> (# q# -# hard#, r# +# k# #)
+  where
+    -- See Note [divModInt# implementation]
+    !yn#   = y# <# 0#
+    !c0#   = (x# <# 0#) `andI#` (notI# yn#)
+    !c1#   = (x# ># 0#) `andI#` yn#
+    !bias# = c0# -# c1#
+    !hard# = c0# `orI#` c1#
+    !s#    = 0# -# hard#
+    !k#    = (s# `andI#` y#) -# bias#
+
+{-# INLINE [0] divModInt8# #-}
+divModInt8# :: Int8# -> Int8# -> (# Int8#, Int8# #)
+x# `divModInt8#` y# = case (x# `plusInt8#` bias#) `quotRemInt8#` y# of
+  (# q#, r# #) -> (# q# `subInt8#` hard#, r# `plusInt8#` k# #)
+  where
+    zero# = intToInt8# 0#
+    x `andInt8#` y = word8ToInt8# (int8ToWord8# x `andWord8#` int8ToWord8# y)
+    x `orInt8#` y = word8ToInt8# (int8ToWord8# x `orWord8#` int8ToWord8# y)
+    notInt8# x = word8ToInt8# (notWord8# (int8ToWord8# x))
+    -- See Note [divModInt# implementation]
+    !yn#   = intToInt8# (y# `ltInt8#` zero#)
+    !c0#   = intToInt8# (x# `ltInt8#` zero#) `andInt8#` (notInt8# yn#)
+    !c1#   = intToInt8# (x# `gtInt8#` zero#) `andInt8#` yn#
+    !bias# = c0# `subInt8#` c1#
+    !hard# = c0# `orInt8#` c1#
+    !s#    = zero# `subInt8#` hard#
+    !k#    = (s# `andInt8#` y#) `subInt8#` bias#
+
+{-# INLINE [0] divModInt16# #-}
+divModInt16# :: Int16# -> Int16# -> (# Int16#, Int16# #)
+x# `divModInt16#` y# = case (x# `plusInt16#` bias#) `quotRemInt16#` y# of
+  (# q#, r# #) -> (# q# `subInt16#` hard#, r# `plusInt16#` k# #)
+  where
+    zero# = intToInt16# 0#
+    x `andInt16#` y = word16ToInt16# (int16ToWord16# x `andWord16#` int16ToWord16# y)
+    x `orInt16#` y = word16ToInt16# (int16ToWord16# x `orWord16#` int16ToWord16# y)
+    notInt16# x = word16ToInt16# (notWord16# (int16ToWord16# x))
+    -- See Note [divModInt# implementation]
+    !yn#   = intToInt16# (y# `ltInt16#` zero#)
+    !c0#   = intToInt16# (x# `ltInt16#` zero#) `andInt16#` (notInt16# yn#)
+    !c1#   = intToInt16# (x# `gtInt16#` zero#) `andInt16#` yn#
+    !bias# = c0# `subInt16#` c1#
+    !hard# = c0# `orInt16#` c1#
+    !s#    = zero# `subInt16#` hard#
+    !k#    = (s# `andInt16#` y#) `subInt16#` bias#
+
+{-# INLINE [0] divModInt32# #-}
+divModInt32# :: Int32# -> Int32# -> (# Int32#, Int32# #)
+x# `divModInt32#` y# = case (x# `plusInt32#` bias#) `quotRemInt32#` y# of
+  (# q#, r# #) -> (# q# `subInt32#` hard#, r# `plusInt32#` k# #)
+  where
+    zero# = intToInt32# 0#
+    x `andInt32#` y = word32ToInt32# (int32ToWord32# x `andWord32#` int32ToWord32# y)
+    x `orInt32#` y = word32ToInt32# (int32ToWord32# x `orWord32#` int32ToWord32# y)
+    notInt32# x = word32ToInt32# (notWord32# (int32ToWord32# x))
+    -- See Note [divModInt# implementation]
+    !yn#   = intToInt32# (y# `ltInt32#` zero#)
+    !c0#   = intToInt32# (x# `ltInt32#` zero#) `andInt32#` (notInt32# yn#)
+    !c1#   = intToInt32# (x# `gtInt32#` zero#) `andInt32#` yn#
+    !bias# = c0# `subInt32#` c1#
+    !hard# = c0# `orInt32#` c1#
+    !s#    = zero# `subInt32#` hard#
+    !k#    = (s# `andInt32#` y#) `subInt32#` bias#
+
+-- Note [divModInt# implementation]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- divModInt# is written by deriving the following code similarly to divInt# and
+-- modInt# (see Note [divInt# implementation] and Note [modInt#
+-- implementation]).
+--
+--    x# `divModInt#` y#
+--     | isTrue# (x# ># 0#) && isTrue# (y# <# 0#) =
+--                                        case (x# -# 1#) `quotRemInt#` y# of
+--                                          (# q, r #) -> (# q -# 1#, r +# y# +# 1# #)
+--     | isTrue# (x# <# 0#) && isTrue# (y# ># 0#) =
+--                                        case (x# +# 1#) `quotRemInt#` y# of
+--                                          (# q, r #) -> (# q -# 1#, r +# y# -# 1# #)
+--     | otherwise                                =
+--                                        x# `quotRemInt#` y#
+--
+--  ===> { Introduce constants }
+--
+--    case (x# +# bias#) `quotRemInt#` y# of
+--      (# q#, r# #) -> (# q# -# hard#, r# +# k# #)
+--      where
+--       (bias#,hard#,k#)
+--        | isTrue# (x# ># 0#) && isTrue# (y# <# 0#) = (-1#, 1#, y#+1#)
+--        | isTrue# (x# <# 0#) && isTrue# (y# ># 0#) = ( 1#, 1#, y#-1#)
+--        | otherwise                                = ( 0#, 0#, 0#-0#)
+--
+--  ===> { Compute using Bool# }
+--
+--    case (x# +# bias#) `quotRemInt#` y# of
+--      (# q#, r# #) -> (# q# -# hard#, r# +# k# #)
+--      where
+--        yn#   = y# <# 0#
+--        c0#   = (x# <# 0#) `andI#` (notI# yn#)
+--        c1#   = (x# ># 0#) `andI#` yn#
+--        bias# = c0# -# c1#
+--        hard# = c0# `orI#` c1#
+--        s#    = 0# -# hard#
+--        k#    = (s# `andI#` y#) -# bias#
+--
+
+{- *************************************************************
+*                                                              *
+*               Constraint tuples                              *
+*                                                              *
+************************************************************* -}
+
+type CTuple0 = (() :: Constraint)
+type CTuple1 = CSolo
+
+class CUnit
+class a => CSolo a
+class (c1, c2) => CTuple2 c1 c2
+class (c1, c2, c3) => CTuple3 c1 c2 c3
+class (c1, c2, c3, c4) => CTuple4 c1 c2 c3 c4
+class (c1, c2, c3, c4, c5) => CTuple5 c1 c2 c3 c4 c5
+class (c1, c2, c3, c4, c5, c6) => CTuple6 c1 c2 c3 c4 c5 c6
+class (c1, c2, c3, c4, c5, c6, c7) => CTuple7 c1 c2 c3 c4 c5 c6 c7
+class (c1, c2, c3, c4, c5, c6, c7, c8) => CTuple8 c1 c2 c3 c4 c5 c6 c7 c8
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9)
+   => CTuple9 c1 c2 c3 c4 c5 c6 c7 c8 c9
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
+   => CTuple10 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11)
+   => CTuple11 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)
+   => CTuple12 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+   => CTuple13 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14)
+   => CTuple14 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15)
+   => CTuple15 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16)
+   => CTuple16 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17)
+   => CTuple17 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17,c18)
+   => CTuple18 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19)
+   => CTuple19 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20)
+   => CTuple20 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21)
+   => CTuple21 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22)
+   => CTuple22 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23)
+   => CTuple23 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24)
+   => CTuple24 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25)
+   => CTuple25 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26)
+   => CTuple26 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27)
+   => CTuple27 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28)
+   => CTuple28 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29)
+   => CTuple29 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30)
+   => CTuple30 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31)
+   => CTuple31 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32)
+   => CTuple32 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33)
+   => CTuple33 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34)
+   => CTuple34 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35)
+   => CTuple35 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36)
+   => CTuple36 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37)
+   => CTuple37 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38)
+   => CTuple38 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39)
+   => CTuple39 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40)
+   => CTuple40 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41)
+   => CTuple41 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42)
+   => CTuple42 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43)
+   => CTuple43 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44)
+   => CTuple44 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45)
+   => CTuple45 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46)
+   => CTuple46 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47)
+   => CTuple47 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48)
+   => CTuple48 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49)
+   => CTuple49 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50)
+   => CTuple50 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51)
+   => CTuple51 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52)
+   => CTuple52 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53)
+   => CTuple53 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54)
+   => CTuple54 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55)
+   => CTuple55 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56)
+   => CTuple56 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57)
+   => CTuple57 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58)
+   => CTuple58 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59)
+   => CTuple59 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60)
+   => CTuple60 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60, c61)
+   => CTuple61 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60 c61
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60, c61, c62)
+   => CTuple62 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60 c61 c62
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60, c61, c62, c63)
+   => CTuple63 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60 c61 c62 c63
+class (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60, c61, c62, c63, c64)
+   => CTuple64 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60 c61 c62 c63 c64
+
+instance CUnit
+instance a => CSolo a
+instance (c1, c2) => CTuple2 c1 c2
+instance (c1, c2, c3) => CTuple3 c1 c2 c3
+instance (c1, c2, c3, c4) => CTuple4 c1 c2 c3 c4
+instance (c1, c2, c3, c4, c5) => CTuple5 c1 c2 c3 c4 c5
+instance (c1, c2, c3, c4, c5, c6) => CTuple6 c1 c2 c3 c4 c5 c6
+instance (c1, c2, c3, c4, c5, c6, c7) => CTuple7 c1 c2 c3 c4 c5 c6 c7
+instance (c1, c2, c3, c4, c5, c6, c7, c8) => CTuple8 c1 c2 c3 c4 c5 c6 c7 c8
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9)
+   => CTuple9 c1 c2 c3 c4 c5 c6 c7 c8 c9
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
+   => CTuple10 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11)
+   => CTuple11 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)
+   => CTuple12 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+   => CTuple13 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14)
+   => CTuple14 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15)
+   => CTuple15 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16)
+   => CTuple16 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17)
+   => CTuple17 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17,c18)
+   => CTuple18 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19)
+   => CTuple19 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20)
+   => CTuple20 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21)
+   => CTuple21 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22)
+   => CTuple22 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23)
+   => CTuple23 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24)
+   => CTuple24 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25)
+   => CTuple25 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26)
+   => CTuple26 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27)
+   => CTuple27 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28)
+   => CTuple28 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29)
+   => CTuple29 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30)
+   => CTuple30 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31)
+   => CTuple31 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32)
+   => CTuple32 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33)
+   => CTuple33 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34)
+   => CTuple34 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35)
+   => CTuple35 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36)
+   => CTuple36 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37)
+   => CTuple37 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38)
+   => CTuple38 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39)
+   => CTuple39 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40)
+   => CTuple40 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41)
+   => CTuple41 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42)
+   => CTuple42 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43)
+   => CTuple43 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44)
+   => CTuple44 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45)
+   => CTuple45 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46)
+   => CTuple46 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47)
+   => CTuple47 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48)
+   => CTuple48 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49)
+   => CTuple49 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50)
+   => CTuple50 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51)
+   => CTuple51 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52)
+   => CTuple52 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53)
+   => CTuple53 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54)
+   => CTuple54 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55)
+   => CTuple55 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56)
+   => CTuple56 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57)
+   => CTuple57 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58)
+   => CTuple58 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59)
+   => CTuple59 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60)
+   => CTuple60 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60, c61)
+   => CTuple61 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60 c61
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60, c61, c62)
+   => CTuple62 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60 c61 c62
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60, c61, c62, c63)
+   => CTuple63 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60 c61 c62 c63
+instance (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16,
+       c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
+       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42, c43, c44,
+       c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58,
+       c59, c60, c61, c62, c63, c64)
+   => CTuple64 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18
+       c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36
+       c37 c38 c39 c40 c41 c42 c43 c44 c45 c46 c47 c48 c49 c50 c51 c52 c53 c54
+       c55 c56 c57 c58 c59 c60 c61 c62 c63 c64
diff --git a/src/GHC/Internal/ClosureTypes.hs b/src/GHC/Internal/ClosureTypes.hs
--- a/src/GHC/Internal/ClosureTypes.hs
+++ b/src/GHC/Internal/ClosureTypes.hs
@@ -83,5 +83,6 @@
     | SMALL_MUT_ARR_PTRS_FROZEN_CLEAN
     | COMPACT_NFDATA
     | CONTINUATION
+    | ANN_FRAME
     | N_CLOSURE_TYPES
     deriving (Enum, Eq, Ord, Show, Generic)
diff --git a/src/GHC/Internal/Conc/IO.hs b/src/GHC/Internal/Conc/IO.hs
--- a/src/GHC/Internal/Conc/IO.hs
+++ b/src/GHC/Internal/Conc/IO.hs
@@ -176,14 +176,22 @@
       let killAction = Sync.killThread t
       return (waitAction, killAction)
 
--- | Close a file descriptor in a concurrency-safe way (GHC only).  If
--- you are using 'threadWaitRead' or 'threadWaitWrite' to perform
--- blocking I\/O, you /must/ use this function to close file
--- descriptors, or blocked threads may not be woken.
+-- | Close a file descriptor in a concurrency-safe way as far as the runtime
+-- system is concerned (GHC only).  If you are using 'threadWaitRead' or
+-- 'threadWaitWrite' to perform blocking I\/O, you /must/ use this function
+-- to close file descriptors, or blocked threads may not be woken.
 --
 -- Any threads that are blocked on the file descriptor via
 -- 'threadWaitRead' or 'threadWaitWrite' will be unblocked by having
 -- IO exceptions thrown.
+--
+-- Note that on systems that reuse file descriptors (such as Linux),
+-- using this function on a file descriptor while other threads can still
+-- potentially use it is always prone to race conditions without further
+-- synchronization.
+--
+-- It is recommended to only call @'closeFdWith'@ once no other threads can
+-- use the given file descriptor anymore.
 closeFdWith :: (Fd -> IO ()) -- ^ Low-level action that performs the real close.
             -> Fd            -- ^ File descriptor to close.
             -> IO ()
diff --git a/src/GHC/Internal/Conc/Signal.hs b/src/GHC/Internal/Conc/Signal.hs
--- a/src/GHC/Internal/Conc/Signal.hs
+++ b/src/GHC/Internal/Conc/Signal.hs
@@ -19,7 +19,7 @@
 import GHC.Internal.Foreign.Marshal.Alloc (finalizerFree)
 import GHC.Internal.Arr (inRange)
 import GHC.Internal.Base
-import GHC.Internal.Conc.Sync (forkIO)
+import GHC.Internal.Conc.Sync (myThreadId, labelThread, forkIO)
 import GHC.Internal.IO (mask_, unsafePerformIO)
 import GHC.Internal.IOArray (IOArray, boundsIOArray, newIOArray,
                     unsafeReadIOArray, unsafeWriteIOArray)
@@ -69,7 +69,10 @@
       else do handler <- unsafeReadIOArray arr int
               case handler of
                 Nothing -> return ()
-                Just (f,_)  -> do _ <- forkIO (f p_info)
+                Just (f,_)  -> do _ <- forkIO $ do
+                                    tid <- myThreadId
+                                    labelThread tid "signal handler"
+                                    f p_info
                                   return ()
 
 -- It is our responsibility to free the memory buffer, so we create a
diff --git a/src/GHC/Internal/Conc/Sync.hs b/src/GHC/Internal/Conc/Sync.hs
--- a/src/GHC/Internal/Conc/Sync.hs
+++ b/src/GHC/Internal/Conc/Sync.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE MagicHash #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE RankNTypes #-}
@@ -394,13 +393,14 @@
 getNumProcessors = fmap fromIntegral c_getNumberOfProcessors
 
 foreign import ccall unsafe "getNumberOfProcessors"
-  c_getNumberOfProcessors :: IO CUInt
+  c_getNumberOfProcessors :: IO Word32
 
 -- | Returns the number of sparks currently in the local spark pool
 numSparks :: IO Int
 numSparks = IO $ \s -> case numSparks# s of (# s', n #) -> (# s', I# n #)
 
-foreign import ccall "&enabled_capabilities" enabled_capabilities :: Ptr CInt
+foreign import ccall "&enabled_capabilities"
+  enabled_capabilities :: Ptr Word32
 
 childHandler :: SomeException -> IO ()
 childHandler err = catch (real_handler err) childHandler
@@ -514,7 +514,7 @@
     IO $ \s -> case labelThread# t str s of s1 -> (# s1, () #)
 
 --      Nota Bene: 'pseq' used to be 'seq'
---                 but 'seq' is now defined in GHC.Prim
+--                 but 'seq' is now defined in GHC.Internal.Prim
 --
 -- "pseq" is defined a bit weirdly (see below)
 --
diff --git a/src/GHC/Internal/ConsoleHandler.hsc b/src/GHC/Internal/ConsoleHandler.hsc
--- a/src/GHC/Internal/ConsoleHandler.hsc
+++ b/src/GHC/Internal/ConsoleHandler.hsc
@@ -23,7 +23,7 @@
         where
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 #else /* whole file */
         ( Handler(..)
         , installHandler
diff --git a/src/GHC/Internal/Control/Arrow.hs b/src/GHC/Internal/Control/Arrow.hs
--- a/src/GHC/Internal/Control/Arrow.hs
+++ b/src/GHC/Internal/Control/Arrow.hs
@@ -131,10 +131,10 @@
     --   The default definition may be overridden with a more efficient
     --   version if desired.
     --
-    -- >   b ╭─────╮ b'
+    -- >   b ╭─────╮ c
     -- > >───┼─ f ─┼───>
     -- > >───┼─ g ─┼───>
-    -- >   c ╰─────╯ c'
+    -- >   b'╰─────╯ c'
     (***) :: a b c -> a b' c' -> a (b,b') (c,c')
     f *** g = first f >>> arr swap >>> first g >>> arr swap
       where swap ~(x,y) = (y,x)
diff --git a/src/GHC/Internal/Control/Exception/Base.hs b/src/GHC/Internal/Control/Exception/Base.hs
--- a/src/GHC/Internal/Control/Exception/Base.hs
+++ b/src/GHC/Internal/Control/Exception/Base.hs
@@ -421,7 +421,7 @@
 
 -----
 
--- See Note [Compiler error functions] in ghc-prim:GHC.Prim.Panic
+-- See Note [Compiler error functions] in ghc-internal:GHC.Internal.Prim.Panic
 recSelError, recConError, typeError,
   nonExhaustiveGuardsError, patError, noMethodBindingError
         :: Addr# -> a   -- All take a UTF8-encoded C string
diff --git a/src/GHC/Internal/Control/Monad/Fail.hs b/src/GHC/Internal/Control/Monad/Fail.hs
--- a/src/GHC/Internal/Control/Monad/Fail.hs
+++ b/src/GHC/Internal/Control/Monad/Fail.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE InstanceSigs #-}
 {-# LANGUAGE Trustworthy #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 
@@ -13,7 +14,10 @@
 --
 module GHC.Internal.Control.Monad.Fail ( MonadFail(fail) ) where
 
-import GHC.Internal.Base (String, Monad(), Maybe(Nothing), IO(), failIO)
+import GHC.Internal.Base (String, Monad(), Maybe(Nothing), IO(), (.))
+import {-# SOURCE #-} GHC.Internal.IO (throwIO)
+import {-# SOURCE #-} GHC.Internal.IO.Exception (userError)
+import GHC.Internal.Stack.Types (HasCallStack)
 
 -- | When a value is bound in @do@-notation, the pattern on the left
 -- hand side of @<-@ might not match. In this case, this class
@@ -42,18 +46,21 @@
 --
 -- @since base-4.9.0.0
 class Monad m => MonadFail m where
-    fail :: String -> m a
+    fail :: HasCallStack => String -> m a
 
 
 -- | @since base-4.9.0.0
 instance MonadFail Maybe where
+    fail :: HasCallStack => String -> Maybe a
     fail _ = Nothing
 
 -- | @since base-4.9.0.0
 instance MonadFail [] where
     {-# INLINE fail #-}
+    fail :: HasCallStack => String -> [a]
     fail _ = []
 
 -- | @since base-4.9.0.0
 instance MonadFail IO where
-    fail = failIO
+    fail :: HasCallStack => String -> IO a
+    fail = throwIO . userError
diff --git a/src/GHC/Internal/Control/Monad/Fix.hs b/src/GHC/Internal/Control/Monad/Fix.hs
--- a/src/GHC/Internal/Control/Monad/Fix.hs
+++ b/src/GHC/Internal/Control/Monad/Fix.hs
@@ -32,9 +32,10 @@
 import GHC.Internal.Data.Maybe
 import GHC.Internal.Data.Monoid ( Monoid, Dual(..), Sum(..), Product(..)
                    , First(..), Last(..), Alt(..), Ap(..) )
+import GHC.Internal.Data.NonEmpty ( NonEmpty(..) )
 import GHC.Internal.Data.Ord ( Down(..) )
 import GHC.Internal.Data.Tuple ( Solo(..), snd )
-import GHC.Internal.Base ( Monad, NonEmpty(..), errorWithoutStackTrace, (.) )
+import GHC.Internal.Base ( Monad, errorWithoutStackTrace, (.) )
 import GHC.Internal.Generics
 import GHC.Internal.List ( head, drop )
 import GHC.Internal.Control.Monad.ST.Imp
diff --git a/src/GHC/Internal/Control/Monad/Zip.hs b/src/GHC/Internal/Control/Monad/Zip.hs
--- a/src/GHC/Internal/Control/Monad/Zip.hs
+++ b/src/GHC/Internal/Control/Monad/Zip.hs
@@ -22,9 +22,9 @@
 import GHC.Internal.Data.Functor.Identity
 import qualified GHC.Internal.Data.Functor
 import GHC.Internal.Data.Monoid
+import GHC.Internal.Data.NonEmpty ( NonEmpty(..) )
 import GHC.Internal.Data.Ord ( Down(..) )
 import GHC.Internal.Data.Proxy
-import GHC.Internal.Base (NonEmpty(..))
 --import qualified Data.List.NonEmpty as NE
 import GHC.Internal.Generics
 import qualified GHC.Internal.Data.List.NonEmpty as NE
diff --git a/src/GHC/Internal/Data/Coerce.hs b/src/GHC/Internal/Data/Coerce.hs
--- a/src/GHC/Internal/Data/Coerce.hs
+++ b/src/GHC/Internal/Data/Coerce.hs
@@ -24,5 +24,5 @@
           -- @since base-4.7.0.0
           coerce, Coercible
         ) where
-import GHC.Prim (coerce)
-import GHC.Types (Coercible)
+import GHC.Internal.Prim (coerce)
+import GHC.Internal.Types (Coercible)
diff --git a/src/GHC/Internal/Data/Data.hs b/src/GHC/Internal/Data/Data.hs
--- a/src/GHC/Internal/Data/Data.hs
+++ b/src/GHC/Internal/Data/Data.hs
@@ -115,16 +115,17 @@
 import GHC.Internal.Data.Eq
 import GHC.Internal.Data.Maybe
 import GHC.Internal.Data.Monoid
+import GHC.Internal.Data.NonEmpty ( NonEmpty(..) )
 import GHC.Internal.Data.Ord
 import GHC.Internal.Data.List (findIndex)
 import GHC.Internal.Data.Typeable
 import GHC.Internal.Data.Version( Version(..) )
-import GHC.Internal.Base hiding (Any, IntRep, FloatRep)
+import GHC.Internal.Base hiding (Any, IntRep, FloatRep, NonEmpty(..))
 import GHC.Internal.List
 import GHC.Internal.Num
 import GHC.Internal.Read
 import GHC.Internal.Show
-import GHC.Tuple (Solo (..))
+import GHC.Internal.Tuple (Solo (..))
 import GHC.Internal.Text.Read( reads )
 
 -- Imports for the instances
diff --git a/src/GHC/Internal/Data/Foldable.hs b/src/GHC/Internal/Data/Foldable.hs
--- a/src/GHC/Internal/Data/Foldable.hs
+++ b/src/GHC/Internal/Data/Foldable.hs
@@ -66,7 +66,7 @@
                   foldl1Elems, foldr1Elems)
 import GHC.Internal.Base hiding ( foldr )
 import GHC.Internal.Generics
-import GHC.Tuple (Solo (..))
+import GHC.Internal.Tuple (Solo (..))
 import GHC.Internal.Num  ( Num(..) )
 
 -- $setup
@@ -709,7 +709,7 @@
 
 -- | @since base-4.9.0.0
 instance Foldable NonEmpty where
-  foldr f z ~(a :| as) = f a (List.foldr f z as)
+  foldr f z (a :| as) = f a (List.foldr f z as)
   foldl f z (a :| as) = List.foldl f (f z a) as
   foldl1 f (a :| as) = List.foldl f a as
 
@@ -729,9 +729,9 @@
   -- The default definition also works great for null and foldl'.
   -- As usual for cons lists, foldr' is basically hopeless.
 
-  foldMap f ~(a :| as) = f a `mappend` foldMap f as
-  fold ~(m :| ms) = m `mappend` fold ms
-  toList ~(a :| as) = a : as
+  foldMap f (a :| as) = f a `mappend` foldMap f as
+  fold (m :| ms) = m `mappend` fold ms
+  toList (a :| as) = a : as
 
 -- | @since base-4.7.0.0
 instance Foldable (Either a) where
@@ -1529,4 +1529,3 @@
 `ByteString` preallocate the required storage, and then combine all the list
 elements in a single pass.
 -}
-
diff --git a/src/GHC/Internal/Data/Functor/Identity.hs b/src/GHC/Internal/Data/Functor/Identity.hs
--- a/src/GHC/Internal/Data/Functor/Identity.hs
+++ b/src/GHC/Internal/Data/Functor/Identity.hs
@@ -49,7 +49,7 @@
 import GHC.Internal.Read (Read(..), lex, readParen)
 import GHC.Internal.Real (Fractional, Integral, Real, RealFrac)
 import GHC.Internal.Show (Show(..), showParen, showString)
-import GHC.Types (Bool(..))
+import GHC.Internal.Types (Bool(..))
 
 -- | Identity functor and monad. (a non-strict monad)
 --
diff --git a/src/GHC/Internal/Data/List/NonEmpty.hs b/src/GHC/Internal/Data/List/NonEmpty.hs
--- a/src/GHC/Internal/Data/List/NonEmpty.hs
+++ b/src/GHC/Internal/Data/List/NonEmpty.hs
@@ -4,18 +4,19 @@
   ( NonEmpty(..)
   , zip
   , zipWith
+  , map
   ) where
 
-import GHC.Internal.Base
+import GHC.Internal.Data.NonEmpty (NonEmpty (..), map)
 import qualified GHC.Internal.Data.List as List
 
 -- | The 'zip' function takes two streams and returns a stream of
 -- corresponding pairs.
 zip :: NonEmpty a -> NonEmpty b -> NonEmpty (a,b)
-zip ~(x :| xs) ~(y :| ys) = (x, y) :| List.zip xs ys
+zip (x :| xs) (y :| ys) = (x, y) :| List.zip xs ys
 
 -- | The 'zipWith' function generalizes 'zip'. Rather than tupling
 -- the elements, the elements are combined using the function
 -- passed as the first argument.
 zipWith :: (a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
-zipWith f ~(x :| xs) ~(y :| ys) = f x y :| List.zipWith f xs ys
+zipWith f (x :| xs) (y :| ys) = f x y :| List.zipWith f xs ys
diff --git a/src/GHC/Internal/Data/Maybe.hs b/src/GHC/Internal/Data/Maybe.hs
--- a/src/GHC/Internal/Data/Maybe.hs
+++ b/src/GHC/Internal/Data/Maybe.hs
@@ -79,8 +79,8 @@
 maybe n _ Nothing  = n
 maybe _ f (Just x) = f x
 
--- | The 'isJust' function returns 'True' iff its argument is of the
--- form @Just _@.
+-- | 'isJust' @x@ returns 'True' when @x@ is of the form @Just _@ and 'False'
+-- otherwise.
 --
 -- ==== __Examples__
 --
@@ -104,7 +104,7 @@
 isJust Nothing = False
 isJust _       = True
 
--- | The 'isNothing' function returns 'True' iff its argument is 'Nothing'.
+-- | 'isNothing' @x@ returns 'True' when @x@ is 'Nothing' and 'False' otherwise.
 --
 -- ==== __Examples__
 --
diff --git a/src/GHC/Internal/Data/NonEmpty.hs b/src/GHC/Internal/Data/NonEmpty.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Data/NonEmpty.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE Trustworthy #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
+
+module GHC.Internal.Data.NonEmpty
+  ( NonEmpty (..)
+  , map
+  ) where
+
+import GHC.Internal.Base
+         ( Applicative (..), Functor (..), Monad (..), NonEmpty (..)
+         , Semigroup (..), (++), (.), ap, liftM2
+         )
+
+-- The following were moved here from module Data.List.NonEmpty of the base
+-- package: map.
+
+-- | Map a function over a 'NonEmpty' stream.
+map :: (a -> b) -> NonEmpty a -> NonEmpty b
+map f (a :| as) = f a :| fmap f as
+
+-- The following orphan instances were moved here from module GHC.Internal.Base:
+-- Semigroup, Functor, Applicative and Monad.
+
+-- | @since base-4.9.0.0
+instance Semigroup (NonEmpty a) where
+  (a :| as) <> bs = a :| (as ++ toList bs)
+   where
+    toList (c :| cs) = c : cs
+
+-- | @since base-4.9.0.0
+instance Functor NonEmpty where
+  fmap = map
+  b <$ (_ :| as) = b :| (b <$ as)
+
+-- | @since base-4.9.0.0
+instance Applicative NonEmpty where
+  pure a = a :| []
+  (<*>) = ap
+  liftA2 = liftM2
+
+-- | @since base-4.9.0.0
+instance Monad NonEmpty where
+  (a :| as) >>= f =
+    case f a of
+      b :| bs -> b :| (bs ++ bs')
+    where
+     bs' = as >>= toList . f
+     toList (c :| cs) = c : cs
diff --git a/src/GHC/Internal/Data/OldList.hs b/src/GHC/Internal/Data/OldList.hs
--- a/src/GHC/Internal/Data/OldList.hs
+++ b/src/GHC/Internal/Data/OldList.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE CPP, NoImplicitPrelude, ScopedTypeVariables,
+{-# LANGUAGE NoImplicitPrelude, ScopedTypeVariables,
              MagicHash, BangPatterns #-}
 
 -----------------------------------------------------------------------------
@@ -370,9 +370,6 @@
 -- >>> findIndices (\l -> length l > 3) ["a", "bcde", "fgh", "ijklmnop"]
 -- [1,3]
 findIndices      :: (a -> Bool) -> [a] -> [Int]
-#if defined(USE_REPORT_PRELUDE)
-findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
-#else
 -- Efficient definition, adapted from Data.Sequence
 -- (Note that making this INLINABLE instead of INLINE allows
 -- 'findIndex' to fuse, fixing #15426.)
@@ -381,7 +378,6 @@
   let go x r k | p x       = I# k `c` r (k +# 1#)
                | otherwise = r (k +# 1#)
   in foldr go (\_ -> n) ls 0#
-#endif  /* USE_REPORT_PRELUDE */
 
 -- | \(\mathcal{O}(\min(m,n))\). The 'isPrefixOf' function takes two lists and
 -- returns 'True' iff the first list is a prefix of the second.
@@ -540,10 +536,6 @@
 -- >>> nubBy (>) [1, 2, 3, 2, 1, 5, 4, 5, 3, 2]
 -- [1,2,3,5,5]
 nubBy                   :: (a -> a -> Bool) -> [a] -> [a]
-#if defined(USE_REPORT_PRELUDE)
-nubBy eq []             =  []
-nubBy eq (x:xs)         =  x : nubBy eq (filter (\ y -> not (eq x y)) xs)
-#else
 -- stolen from HBC
 nubBy eq l              = nubBy' l []
   where
@@ -562,7 +554,6 @@
 elem_by :: (a -> a -> Bool) -> a -> [a] -> Bool
 elem_by _  _ []         =  False
 elem_by eq y (x:xs)     =  x `eq` y || elem_by eq y xs
-#endif
 
 
 -- | \(\mathcal{O}(n)\). 'delete' @x@ removes the first occurrence of @x@ from
@@ -1627,10 +1618,6 @@
 -- [(1,"Hello"),(2,"world"),(4,"!")]
 sortBy :: (a -> a -> Ordering) -> [a] -> [a]
 
-#if defined(USE_REPORT_PRELUDE)
-sort = sortBy compare
-sortBy cmp = foldr (insertBy cmp) []
-#else
 
 {-
 GHC's mergesort replaced by a better implementation, 24/12/2009.
@@ -1840,8 +1827,6 @@
         _  -> rqpart cmp x ys (y:rle) rgt r
 -}
 
-#endif /* USE_REPORT_PRELUDE */
-
 -- | Sort a list by comparing the results of a key function applied to each
 -- element.  @'sortOn' f@ is equivalent to @'sortBy' ('comparing' f)@, but has the
 -- performance advantage of only evaluating @f@ once for each element in the
@@ -2027,14 +2012,10 @@
 -- >>> unlines . lines $ "foo\nbar"
 -- "foo\nbar\n"
 unlines                 :: [String] -> String
-#if defined(USE_REPORT_PRELUDE)
-unlines                 =  concatMap (++ "\n")
-#else
 -- HBC version (stolen)
 -- here's a more efficient version
 unlines [] = []
 unlines (l:ls) = l ++ '\n' : unlines ls
-#endif
 
 -- | 'words' breaks a string up into a list of words, which were delimited
 -- by white space (as defined by 'isSpace'). This function trims any white spaces
@@ -2085,10 +2066,6 @@
 -- >>> unwords ["foo", "bar", "", "baz"]
 -- "foo bar  baz"
 unwords                 :: [String] -> String
-#if defined(USE_REPORT_PRELUDE)
-unwords []              =  ""
-unwords ws              =  foldr1 (\w s -> w ++ ' ':s) ws
-#else
 -- Here's a lazier version that can get the last element of a
 -- _|_-terminated list.
 {-# NOINLINE [1] unwords #-}
@@ -2118,7 +2095,6 @@
 {-# INLINE [0] unwordsFB #-}
 unwordsFB               :: String -> String -> String
 unwordsFB w r           = ' ' : w ++ r
-#endif
 
 {- A "SnocBuilder" is a version of Chris Okasaki's banker's queue that supports
 toListSB instead of uncons. In single-threaded use, its performance
diff --git a/src/GHC/Internal/Data/Traversable.hs b/src/GHC/Internal/Data/Traversable.hs
--- a/src/GHC/Internal/Data/Traversable.hs
+++ b/src/GHC/Internal/Data/Traversable.hs
@@ -54,7 +54,7 @@
                   ($), (.), id, flip )
 import GHC.Internal.Generics
 import qualified GHC.Internal.List as List ( foldr )
-import GHC.Tuple (Solo (..))
+import GHC.Internal.Tuple (Solo (..))
 
 -- $setup
 -- >>> import Prelude
@@ -245,7 +245,7 @@
 
 -- | @since base-4.9.0.0
 instance Traversable NonEmpty where
-  traverse f ~(a :| as) = liftA2 (:|) (f a) (traverse f as)
+  traverse f (a :| as) = liftA2 (:|) (f a) (traverse f as)
 
 -- | @since base-4.7.0.0
 instance Traversable (Either a) where
@@ -486,4 +486,3 @@
 {-# INLINE foldMapDefault #-}
 -- See Note [Function coercion] in Data.Functor.Utils.
 foldMapDefault = coerce (traverse @t @(Const m) @a @())
-
diff --git a/src/GHC/Internal/Data/Tuple.hs b/src/GHC/Internal/Data/Tuple.hs
--- a/src/GHC/Internal/Data/Tuple.hs
+++ b/src/GHC/Internal/Data/Tuple.hs
@@ -25,7 +25,7 @@
   , swap
   ) where
 
-import GHC.Tuple (Solo (..), getSolo)
+import GHC.Internal.Tuple (Solo (..), getSolo)
 
 default ()              -- Double isn't available yet
 
diff --git a/src/GHC/Internal/Data/Type/Ord.hs b/src/GHC/Internal/Data/Type/Ord.hs
--- a/src/GHC/Internal/Data/Type/Ord.hs
+++ b/src/GHC/Internal/Data/Type/Ord.hs
@@ -38,7 +38,7 @@
 import GHC.Internal.TypeError
 import GHC.Internal.TypeLits.Internal
 import GHC.Internal.TypeNats.Internal
-import GHC.Types (type (~), Char)
+import GHC.Internal.Types (type (~), Char)
 import GHC.Internal.Data.Bool
 import GHC.Internal.Data.Eq
 import GHC.Internal.Data.Ord
diff --git a/src/GHC/Internal/Data/Typeable/Internal.hs b/src/GHC/Internal/Data/Typeable/Internal.hs
--- a/src/GHC/Internal/Data/Typeable/Internal.hs
+++ b/src/GHC/Internal/Data/Typeable/Internal.hs
@@ -58,8 +58,8 @@
 
     -- * TypeRep
     TypeRep,
-    pattern TypeRep,
-    pattern App, pattern Con, pattern Con', pattern Fun,
+    data TypeRep,
+    data App, data Con, data Con', data Fun,
     typeRep,
     typeOf,
     typeRepTyCon,
@@ -948,7 +948,7 @@
 -- somehow. We need to construct this by hand because otherwise
 -- we end up with horrible and somewhat mysterious loops trying to calculate
 -- typeRep @TYPE. For the moment, we use the fact that we can get the proper
--- name of the ghc-prim package from the TyCon of LiftedRep (which we can
+-- name of the ghc-internal package from the TyCon of LiftedRep (which we can
 -- produce a TypeRep for without difficulty), and then just substitute in the
 -- appropriate module and constructor names.
 --
@@ -962,26 +962,26 @@
 -- #14480.
 
 tyConRuntimeRep :: TyCon
-tyConRuntimeRep = mkTyCon ghcPrimPackage "GHC.Types" "RuntimeRep" 0
+tyConRuntimeRep = mkTyCon ghcPrimPackage "GHC.Internal.Types" "RuntimeRep" 0
   (KindRepTYPE (BoxedRep Lifted))
 
 tyConTYPE :: TyCon
-tyConTYPE = mkTyCon ghcPrimPackage "GHC.Prim" "TYPE" 0
+tyConTYPE = mkTyCon ghcPrimPackage "GHC.Internal.Prim" "TYPE" 0
     (KindRepFun
       (KindRepTyConApp tyConRuntimeRep [])
       (KindRepTYPE (BoxedRep Lifted))
     )
 
 tyConLevity :: TyCon
-tyConLevity = mkTyCon ghcPrimPackage "GHC.Types" "Levity" 0
+tyConLevity = mkTyCon ghcPrimPackage "GHC.Internal.Types" "Levity" 0
   (KindRepTYPE (BoxedRep Lifted))
 
 tyCon'Lifted :: TyCon
-tyCon'Lifted = mkTyCon ghcPrimPackage "GHC.Types" "'Lifted" 0
+tyCon'Lifted = mkTyCon ghcPrimPackage "GHC.Internal.Types" "'Lifted" 0
   (KindRepTyConApp tyConLevity [])
 
 tyCon'BoxedRep :: TyCon
-tyCon'BoxedRep = mkTyCon ghcPrimPackage "GHC.Types" "'BoxedRep" 0
+tyCon'BoxedRep = mkTyCon ghcPrimPackage "GHC.Internal.Types" "'BoxedRep" 0
   (KindRepFun (KindRepTyConApp tyConLevity []) (KindRepTyConApp tyConRuntimeRep []))
 
 ghcPrimPackage :: String
@@ -995,8 +995,8 @@
 
 isTupleTyCon :: TyCon -> Maybe (Bool, Int)
 isTupleTyCon tc
-  | tyConPackage tc == "ghc-prim"
-  , tyConModule  tc == "GHC.Tuple" || tyConModule tc == "GHC.Types"
+  | tyConPackage tc == "ghc-internal"
+  , tyConModule  tc == "GHC.Internal.Tuple" || tyConModule tc == "GHC.Internal.Types"
   = case tyConName tc of
       "Unit" -> Just (True, 0)
       "Unit#" -> Just (False, 0)
@@ -1138,7 +1138,7 @@
 
 mkTypeLitTyCon :: String -> TyCon -> TyCon
 mkTypeLitTyCon name kind_tycon
-  = mkTyCon "base" "GHC.TypeLits" name 0 kind
+  = mkTyCon "base" "GHC.Internal.TypeLits" name 0 kind
   where kind = KindRepTyConApp kind_tycon []
 
 -- | Used to make `'Typeable' instance for things of kind Nat
diff --git a/src/GHC/Internal/Data/Version.hs-boot b/src/GHC/Internal/Data/Version.hs-boot
--- a/src/GHC/Internal/Data/Version.hs-boot
+++ b/src/GHC/Internal/Data/Version.hs-boot
@@ -5,7 +5,7 @@
   , makeVersion
   ) where
 
-import GHC.Types
+import GHC.Internal.Types
 
 
 -- The generated module GHC.Internal.Unicode.Version depends on
diff --git a/src/GHC/Internal/Debug.hs b/src/GHC/Internal/Debug.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Debug.hs
@@ -0,0 +1,53 @@
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE MagicHash, NoImplicitPrelude, UnboxedTuples, UnliftedFFITypes #-}
+
+-- | Users should not import this module.  It is GHC internal only.
+
+module GHC.Internal.Debug ( debugLn, debugErrLn ) where
+
+import GHC.Internal.Prim
+import GHC.Internal.Types
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+-- (This module uses the empty tuple.)
+import GHC.Internal.Tuple ()
+
+debugLn :: [Char] -> IO ()
+debugLn xs = IO (\s0 ->
+                 case mkMBA s0 xs of
+                 (# s1, mba #) ->
+                     case c_debugLn mba of
+                     IO f -> f s1)
+
+debugErrLn :: [Char] -> IO ()
+debugErrLn xs = IO (\s0 ->
+                    case mkMBA s0 xs of
+                    (# s1, mba #) ->
+                        case c_debugErrLn mba of
+                        IO f -> f s1)
+
+foreign import ccall unsafe "debugLn"
+    c_debugLn :: MutableByteArray# RealWorld -> IO ()
+
+foreign import ccall unsafe "debugErrLn"
+    c_debugErrLn :: MutableByteArray# RealWorld -> IO ()
+
+mkMBA :: State# RealWorld -> [Char] ->
+         (# State# RealWorld, MutableByteArray# RealWorld #)
+mkMBA s0 xs = -- Start with 1 so that we have space to put in a \0 at
+              -- the end
+              case len 1# xs of
+              l ->
+                  case newByteArray# l s0 of
+                  (# s1, mba #) ->
+                      case write mba 0# xs s1 of
+                      s2 -> (# s2, mba #)
+    where len l [] = l
+          len l (_ : xs') = len (l +# 1#) xs'
+
+          write mba offset [] s = writeCharArray# mba offset '\0'# s
+          write mba offset (C# x : xs') s
+              = case writeCharArray# mba offset x s of
+                s' ->
+                    write mba (offset +# 1#) xs' s'
+
diff --git a/src/GHC/Internal/Encoding/UTF8.hs b/src/GHC/Internal/Encoding/UTF8.hs
--- a/src/GHC/Internal/Encoding/UTF8.hs
+++ b/src/GHC/Internal/Encoding/UTF8.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE BangPatterns, MagicHash, UnboxedTuples, NoImplicitPrelude #-}
 {-# OPTIONS_GHC -O2 -fno-warn-name-shadowing #-}
 
@@ -42,7 +41,7 @@
     , utf8EncodedLength
     ) where
 
-import GHC.Types
+import GHC.Internal.Types
 import GHC.Internal.Base
 import GHC.Internal.IO
 import GHC.Internal.ST
@@ -66,7 +65,7 @@
 b. the copy of the `ghc-boot` definition now exported by `base:GHC.Encoding.UTF8`.
    This can be used at `Addr#`, `Ptr`, `ByteArray#`, and `ForeignPtr`.
 
-c. the decoder used by `unpackCStringUtf8#` in `ghc-prim:GHC.CString`; this is
+c. the decoder used by `unpackCStringUtf8#` in `ghc-internal:GHC.Internal.CString`; this is
    specialised at `Addr#`.
 
 d. the codec used by the IO subsystem in `base:GHC.IO.Encoding.UTF8`; this is
@@ -82,7 +81,7 @@
 codepoints). Consequently, it's quite unclear that further consolidation
 would be worthwhile.
 
-The most obvious opportunity is to move (b) into `ghc-prim` and use it to
+The most obvious opportunity is to move (b) into `ghc-internal` and use it to
 implement (c) (namely `unpackCStringUtf8#` and friends). However, it's not
 clear that this would be worthwhile as several of the types supported by (b)
 are defined in `base`.
@@ -149,11 +148,7 @@
 -- | Decode a single character at the given 'Addr#'.
 utf8DecodeCharAddr# :: Addr# -> Int# -> (# Char#, Int# #)
 utf8DecodeCharAddr# a# off# =
-#if !MIN_VERSION_ghc_prim(0,10,0)
-    utf8DecodeChar# (\i# -> indexWord8OffAddr# a# (i# +# off#))
-#else
     utf8DecodeChar# (\i# -> word8ToWord# (indexWord8OffAddr# a# (i# +# off#)))
-#endif
 
 -- | Decode a single codepoint starting at the given 'Ptr'.
 utf8DecodeCharPtr :: Ptr Word8 -> (Char, Int)
@@ -165,11 +160,7 @@
 -- 'ByteArray#'.
 utf8DecodeCharByteArray# :: ByteArray# -> Int# -> (# Char#, Int# #)
 utf8DecodeCharByteArray# ba# off# =
-#if !MIN_VERSION_ghc_prim(0,10,0)
-    utf8DecodeChar# (\i# -> indexWord8Array# ba# (i# +# off#))
-#else
     utf8DecodeChar# (\i# -> word8ToWord# (indexWord8Array# ba# (i# +# off#)))
-#endif
 
 {-# INLINE utf8Decode# #-}
 utf8Decode# :: (IO ()) -> (Int# -> (# Char#, Int# #)) -> Int# -> IO [Char]
@@ -216,29 +207,16 @@
          | isTrue# (off1 >=# sz1)                          = LT
          | isTrue# (off2 >=# sz2)                          = GT
          | otherwise =
-#if !MIN_VERSION_ghc_prim(0,10,0)
-               let !b1_1 = indexWord8Array# a1 off1
-                   !b2_1 = indexWord8Array# a2 off2
-#else
                let !b1_1 = word8ToWord# (indexWord8Array# a1 off1)
                    !b2_1 = word8ToWord# (indexWord8Array# a2 off2)
-#endif
                in case b1_1 of
                   0xC0## -> case b2_1 of
                      0xC0## -> go (off1 +# 1#) (off2 +# 1#)
-#if !MIN_VERSION_ghc_prim(0,10,0)
-                     _      -> case indexWord8Array# a1 (off1 +# 1#) of
-#else
                      _      -> case word8ToWord# (indexWord8Array# a1 (off1 +# 1#)) of
-#endif
                         0x80## -> LT
                         _      -> go (off1 +# 1#) (off2 +# 1#)
                   _      -> case b2_1 of
-#if !MIN_VERSION_ghc_prim(0,10,0)
-                     0xC0## -> case indexWord8Array# a2 (off2 +# 1#) of
-#else
                      0xC0## -> case word8ToWord# (indexWord8Array# a2 (off2 +# 1#)) of
-#endif
                         0x80## -> GT
                         _      -> go (off1 +# 1#) (off2 +# 1#)
                      _   | isTrue# (b1_1 `gtWord#` b2_1) -> GT
@@ -284,23 +262,14 @@
   where
     {-# INLINE write #-}
     write (I# off#) (W# c#) = ST $ \s ->
-#if !MIN_VERSION_ghc_prim(0,10,0)
-      case write# off# (narrowWord8# c#) s of
-#else
       case write# off# (wordToWord8# c#) s of
-#endif
         s -> (# s, () #)
 
 utf8EncodePtr :: Ptr Word8 -> String -> IO ()
 utf8EncodePtr (Ptr a#) str = go a# str
   where go !_   []   = return ()
         go a# (c:cs) = do
-#if !MIN_VERSION_ghc_prim(0,10,0)
-          -- writeWord8OffAddr# was taking a Word#
-          I# off# <- stToIO $ utf8EncodeChar (\i w -> writeWord8OffAddr# a# i (extendWord8# w)) c
-#else
           I# off# <- stToIO $ utf8EncodeChar (writeWord8OffAddr# a#) c
-#endif
           go (a# `plusAddr#` off#) cs
 
 utf8EncodeByteArray# :: String -> ByteArray#
@@ -314,12 +283,7 @@
   where
     go _ _ [] = return ()
     go mba# i# (c:cs) = do
-#if !MIN_VERSION_ghc_prim(0,10,0)
-      -- writeWord8Array# was taking a Word#
-      I# off# <- utf8EncodeChar (\j# w -> writeWord8Array# mba# (i# +# j#) (extendWord8# w)) c
-#else
       I# off# <- utf8EncodeChar (\j# -> writeWord8Array# mba# (i# +# j#)) c
-#endif
       go mba# (i# +# off#) cs
 
 utf8EncodedLength :: String -> Int
diff --git a/src/GHC/Internal/Enum.hs b/src/GHC/Internal/Enum.hs
--- a/src/GHC/Internal/Enum.hs
+++ b/src/GHC/Internal/Enum.hs
@@ -39,10 +39,10 @@
 
 import GHC.Internal.Base hiding ( many )
 import GHC.Internal.Char
-import GHC.Num.Integer
+import GHC.Internal.Bignum.Integer
 import GHC.Internal.Num
 import GHC.Internal.Show
-import GHC.Tuple (Solo (..))
+import GHC.Internal.Tuple (Solo (..))
 default ()              -- Double isn't available yet
 
 -- | The 'Bounded' class is used to name the upper and lower limits of a
@@ -1098,7 +1098,7 @@
 enumIntToWord :: Int -> Word
 enumIntToWord (I# i) = W# (int2Word# i)
 
--- Instances from GHC.Types
+-- Instances from GHC.Internal.Types
 
 -- | @since base-4.16.0.0
 deriving instance Bounded Levity
diff --git a/src/GHC/Internal/Enum.hs-boot b/src/GHC/Internal/Enum.hs-boot
--- a/src/GHC/Internal/Enum.hs-boot
+++ b/src/GHC/Internal/Enum.hs-boot
@@ -6,6 +6,6 @@
 module GHC.Internal.Enum (Enum) where
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 
 class Enum a
diff --git a/src/GHC/Internal/Err.hs b/src/GHC/Internal/Err.hs
--- a/src/GHC/Internal/Err.hs
+++ b/src/GHC/Internal/Err.hs
@@ -1,7 +1,6 @@
 {-# LANGUAGE Trustworthy #-}
 {-# LANGUAGE NoImplicitPrelude, MagicHash, ImplicitParams #-}
 {-# LANGUAGE RankNTypes, PolyKinds, DataKinds #-}
-{-# LANGUAGE BangPatterns #-}
 {-# OPTIONS_HADDOCK not-home #-}
 
 -----------------------------------------------------------------------------
@@ -24,10 +23,9 @@
 -----------------------------------------------------------------------------
 
 module GHC.Internal.Err( absentErr, error, errorWithoutStackTrace, undefined ) where
-import GHC.Types (Char, RuntimeRep)
+import GHC.Internal.Types (Char, RuntimeRep)
 import GHC.Internal.Stack.Types
-import GHC.Prim
-import GHC.Magic ( noinline )
+import GHC.Internal.Prim
 import {-# SOURCE #-} GHC.Internal.Exception
   ( errorCallWithCallStackException
   , errorCallException )
@@ -35,10 +33,7 @@
 -- | 'error' stops execution and displays an error message.
 error :: forall (r :: RuntimeRep). forall (a :: TYPE r).
          HasCallStack => [Char] -> a
-error s =
-  -- See Note [Capturing the backtrace in throw] and Note [Hiding precise exception signature in throw]
-  let !se = noinline (errorCallWithCallStackException s ?callStack)
-  in raise# se
+error s = raise# (errorCallWithCallStackException s ?callStack)
           -- Bleh, we should be using 'GHC.Internal.Stack.callStack' instead of
           -- '?callStack' here, but 'GHC.Internal.Stack.callStack' depends on
           -- 'GHC.Internal.Stack.popCallStack', which is partial and depends on
@@ -78,10 +73,7 @@
 -- nor wanted (see #19886). We’d like to use withFrozenCallStack, but that
 -- is not available in this module yet, and making it so is hard. So let’s just
 -- use raise# directly.
-undefined =
-    -- See Note [Capturing the backtrace in throw] and Note [Hiding precise exception signature in throw]
-    let !se = noinline (errorCallWithCallStackException "Prelude.undefined" ?callStack)
-    in raise# se
+undefined = raise# (errorCallWithCallStackException "Prelude.undefined" ?callStack)
 
 -- | Used for compiler-generated error message;
 -- encoding saves bytes of string junk.
diff --git a/src/GHC/Internal/Event.hs b/src/GHC/Internal/Event.hs
--- a/src/GHC/Internal/Event.hs
+++ b/src/GHC/Internal/Event.hs
@@ -1,6 +1,5 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE CPP #-}
-{-# LANGUAGE Safe #-}
 
 -- ----------------------------------------------------------------------------
 -- | This module provides scalable event notification for file
@@ -13,6 +12,10 @@
 module GHC.Internal.Event
 #if defined(javascript_HOST_ARCH)
     ( ) where
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+import GHC.Internal.Types ()
+
 #else
     ( -- * Types
       EventManager
diff --git a/src/GHC/Internal/Event/Arr.hs b/src/GHC/Internal/Event/Arr.hs
--- a/src/GHC/Internal/Event/Arr.hs
+++ b/src/GHC/Internal/Event/Arr.hs
@@ -10,9 +10,9 @@
     ) where
 
 import GHC.Internal.Base (($))
-import GHC.Prim (MutableArray#, RealWorld, newArray#, readArray#,
-                 sizeofMutableArray#, writeArray#)
-import GHC.Types (IO(..), Int(..))
+import GHC.Internal.Prim (MutableArray#, RealWorld, newArray#, readArray#,
+                          sizeofMutableArray#, writeArray#)
+import GHC.Internal.Types (IO(..), Int(..))
 
 data Arr a = Arr (MutableArray# RealWorld a)
 
diff --git a/src/GHC/Internal/Event/IntTable.hs b/src/GHC/Internal/Event/IntTable.hs
--- a/src/GHC/Internal/Event/IntTable.hs
+++ b/src/GHC/Internal/Event/IntTable.hs
@@ -18,12 +18,12 @@
 import GHC.Internal.Data.IORef (IORef, newIORef, readIORef, writeIORef)
 import GHC.Internal.Data.Maybe (Maybe(..), isJust)
 import GHC.Internal.Base (Monad(..), (=<<), ($), ($!), const, liftM, otherwise, when)
-import GHC.Classes (Eq(..), Ord(..))
+import GHC.Internal.Classes (Eq(..), Ord(..))
 import GHC.Internal.Event.Arr (Arr)
 import GHC.Internal.Event.IntVar
 import GHC.Internal.Num (Num(..))
-import GHC.Prim (seq)
-import GHC.Types (Bool(..), IO(..), Int(..))
+import GHC.Internal.Prim (seq)
+import GHC.Internal.Types (Bool(..), IO(..), Int(..))
 import qualified GHC.Internal.Event.Arr as Arr
 
 -- A very simple chained integer-keyed mutable hash table. We use
diff --git a/src/GHC/Internal/Event/Internal.hs b/src/GHC/Internal/Event/Internal.hs
--- a/src/GHC/Internal/Event/Internal.hs
+++ b/src/GHC/Internal/Event/Internal.hs
@@ -41,6 +41,14 @@
 
     -- | Register, modify, or unregister interest in the given events
     -- on the given file descriptor.
+    --
+    -- Returns 'True' if the modification succeeded.
+    -- Returns 'False' if this backend does not support
+    -- event notifications on this type of file.
+    --
+    -- If this function throws, the IO manager assumes that the registration
+    -- of the file descriptor failed, so the backend must not throw if the
+    -- registration was successful.
     , _beModifyFd :: a
                   -> Fd       -- file descriptor
                   -> Event    -- old events to watch for ('mempty' for new)
@@ -49,6 +57,14 @@
 
     -- | Register interest in new events on a given file descriptor, set
     -- to be deactivated after the first event.
+    --
+    -- Returns 'True' if the modification succeeded.
+    -- Returns 'False' if this backend does not support
+    -- event notifications on this type of file.
+    --
+    -- If this function throws, the IO manager assumes that the registration
+    -- of the file descriptor failed, so the backend must not throw if the
+    -- registration was successful.
     , _beModifyFdOnce :: a
                          -> Fd    -- file descriptor
                          -> Event -- new events to watch
diff --git a/src/GHC/Internal/Event/Internal/Types.hs b/src/GHC/Internal/Event/Internal/Types.hs
--- a/src/GHC/Internal/Event/Internal/Types.hs
+++ b/src/GHC/Internal/Event/Internal/Types.hs
@@ -61,6 +61,11 @@
 {-# INLINE evtWrite #-}
 
 -- | Another thread closed the file descriptor.
+--
+-- This event is only meant to be used by @'closeFdWith'@ to signal other
+-- threads currently waiting on the same file descriptor that it was closed.
+-- It is not meant to be waited on directly and intentionally not exposed
+-- in the external interface (only @'evtRead'@ and @'evtWrite'@ are).
 evtClose :: Event
 evtClose = Event 4
 {-# INLINE evtClose #-}
diff --git a/src/GHC/Internal/Event/Manager.hs b/src/GHC/Internal/Event/Manager.hs
--- a/src/GHC/Internal/Event/Manager.hs
+++ b/src/GHC/Internal/Event/Manager.hs
@@ -312,6 +312,11 @@
 -- platform's @select@ or @epoll@ system call, which tend to vary in
 -- what sort of fds are permitted. For instance, waiting on regular files
 -- is not allowed on many platforms.
+--
+-- This function rethrows exceptions originating from the underlying backend,
+-- for instance due to concurrently closing a file descriptor while it is
+-- just being registered. In that case, it assumes that the registration was
+-- not successful. See #21969.
 registerFd_ :: EventManager -> IOCallback -> Fd -> Event -> Lifetime
             -> IO (FdKey, Bool)
 registerFd_ mgr@(EventManager{..}) cb fd evs lt = do
@@ -327,13 +332,20 @@
 
         el' :: EventLifetime
         el' = prevEvs `mappend` el
+
+        -- Used for restoring the old state if registering the FD
+        -- in the backend failed, due to either
+        -- 1. that file type not being supported, or
+        -- 2. the backend throwing an exception
+        undoRegistration = IT.reset fd' oldFdd tbl
     case I.elLifetime el' of
       -- All registrations want one-shot semantics and this is supported
       OneShot | haveOneShot -> do
         ok <- I.modifyFdOnce emBackend fd (I.elEvent el')
+          `onException` undoRegistration
         if ok
           then return (False, True)
-          else IT.reset fd' oldFdd tbl >> return (False, False)
+          else undoRegistration >> return (False, False)
 
       -- We don't want or don't support one-shot semantics
       _ -> do
@@ -342,10 +354,11 @@
               then let newEvs = I.elEvent el'
                        oldEvs = I.elEvent prevEvs
                    in I.modifyFd emBackend fd oldEvs newEvs
+                        `onException` undoRegistration
               else return True
         if ok
           then return (modify, True)
-          else IT.reset fd' oldFdd tbl >> return (False, False)
+          else undoRegistration >> return (False, False)
   -- this simulates behavior of old IO manager:
   -- i.e. just call the callback if the registration fails.
   when (not ok) (cb reg evs)
diff --git a/src/GHC/Internal/Event/Thread.hs b/src/GHC/Internal/Event/Thread.hs
--- a/src/GHC/Internal/Event/Thread.hs
+++ b/src/GHC/Internal/Event/Thread.hs
@@ -7,6 +7,10 @@
 module GHC.Internal.Event.Thread
 #if defined(javascript_HOST_ARCH)
     ( ) where
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+import GHC.Internal.Types ()
+
 #else
     ( getSystemEventManager
     , getSystemTimerManager
@@ -112,6 +116,13 @@
 -- Any threads that are blocked on the file descriptor via
 -- 'threadWaitRead' or 'threadWaitWrite' will be unblocked by having
 -- IO exceptions thrown.
+--
+-- Closing file descriptors on one thread while they are still being
+-- used by other threads is always prone to race conditions (since e.g.
+-- on Linux file descriptors can be immediately reused after closing).
+--
+-- It is recommended to only call @'closeFdWith'@ when the file descriptor
+-- can no longer be used by other threads.
 closeFdWith :: (Fd -> IO ())        -- ^ Action that performs the close.
             -> Fd                   -- ^ File descriptor to close.
             -> IO ()
@@ -154,6 +165,10 @@
             close fd `finally` sequence_ (zipWith3 finish mgrs tables cbApps)
             pure (pure ())
 
+-- | Wait for an event on a file descriptor.
+--
+-- The given @'Event'@ may only be (a combination of) @'evtRead'@ or
+-- @'evtWrite'@, but not @'evtClose'@. See @'evtClose'@ for more details.
 threadWait :: Event -> Fd -> IO ()
 threadWait evt fd = mask_ $ do
   m <- newEmptyMVar
diff --git a/src/GHC/Internal/Event/TimerManager.hs b/src/GHC/Internal/Event/TimerManager.hs
--- a/src/GHC/Internal/Event/TimerManager.hs
+++ b/src/GHC/Internal/Event/TimerManager.hs
@@ -1,8 +1,11 @@
 {-# LANGUAGE CPP #-}
 #if defined(javascript_HOST_ARCH)
 
-{-# LANGUAGE Safe #-}
 module GHC.Internal.Event.TimerManager () where
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+import GHC.Internal.Types ()
+
 
 #else
 
diff --git a/src/GHC/Internal/Event/Windows.hsc b/src/GHC/Internal/Event/Windows.hsc
--- a/src/GHC/Internal/Event/Windows.hsc
+++ b/src/GHC/Internal/Event/Windows.hsc
@@ -109,7 +109,6 @@
 import GHC.Internal.Conc.Bound
 import GHC.Internal.Conc.Sync
 import GHC.Internal.IO
-import GHC.Internal.IOPort
 import GHC.Internal.Num
 import GHC.Internal.Real
 import GHC.Internal.Bits
@@ -170,7 +169,7 @@
 --    fact that something else has finished the remainder of their queue or must
 --    have a guarantee to never block.  In this implementation we strive to
 --    never block.   This is achieved by not having the worker threads call out
---    to any user code, and to have the IOPort synchronization primitive never
+--    to any user code, and to have the MVar synchronization primitive never
 --    block.   This means if the port is full the message is lost, however we
 --    have an invariant that the port can never be full and have a waiting
 --    receiver.  As such, dropping the message does not change anything as there
@@ -541,11 +540,9 @@
                  -> CompletionCallback (IOResult a)
                  -> IO (IOResult a)
 withOverlappedEx mgr fname h async offset startCB completionCB = do
-    signal <- newEmptyIOPort :: IO (IOPort (IOResult a))
-    let signalReturn a = failIfFalse_ (dbgMsg "signalReturn") $
-                            writeIOPort signal (IOSuccess a)
-        signalThrow ex = failIfFalse_ (dbgMsg "signalThrow") $
-                            writeIOPort signal (IOFailed ex)
+    signal <- newEmptyMVar :: IO (MVar (IOResult a))
+    let signalReturn a = putMVar signal (IOSuccess a)
+        signalThrow ex = putMVar signal (IOFailed ex)
     mask_ $ do
       let completionCB' e b = do
             result <- completionCB e b
@@ -689,7 +686,7 @@
                              registerAlertableWait delay
                         return $ IOFailed Nothing
         let runner = do debugIO $ (dbgMsg ":: waiting ") ++ " | "  ++ show lpol
-                        res <- readIOPort signal `catch` cancel
+                        res <- readMVar signal `catch` cancel
                         debugIO $ dbgMsg ":: signaled "
                         case res of
                           IOFailed err -> FFI.throwWinErr fname (maybe 0 fromIntegral err)
@@ -722,7 +719,7 @@
                                     let err' = fromIntegral err
                                     debugIO $ dbgMsg $ ":: done callback: " ++ show err' ++ " - " ++ show numBytes
                                     completionCB err' (fromIntegral numBytes)
-              else readIOPort signal
+              else readMVar signal
           CbError err  -> do
             reqs3 <- removeRequest
             debugIO $ "-1.. " ++ show reqs3 ++ " requests queued."
@@ -742,10 +739,10 @@
                     -- Uses an inline definition of threadDelay to prevent an import
                     -- cycle.
                     let usecs = 250 -- 0.25ms
-                    m <- newEmptyIOPort
+                    m <- newEmptyMVar
                     reg <- registerTimeout mgr usecs $
-                                writeIOPort m () >> return ()
-                    readIOPort m `onException` unregisterTimeout mgr reg
+                                putMVar m () >> return ()
+                    readMVar m `onException` unregisterTimeout mgr reg
                 | otherwise = sleepBlock 1 -- 1 ms
             waitForCompletion :: HANDLE -> Ptr FFI.OVERLAPPED -> IO (CbResult Int)
             waitForCompletion fhndl lpol = do
diff --git a/src/GHC/Internal/Event/Windows/ConsoleEvent.hsc b/src/GHC/Internal/Event/Windows/ConsoleEvent.hsc
--- a/src/GHC/Internal/Event/Windows/ConsoleEvent.hsc
+++ b/src/GHC/Internal/Event/Windows/ConsoleEvent.hsc
@@ -53,7 +53,10 @@
 start_console_handler r =
   case toWin32ConsoleEvent r of
     Just x  -> withMVar win32ConsoleHandler $ \handler -> do
-                 _ <- forkIO (handler x)
+                 _ <- forkIO $ do
+                     tid <- myThreadId
+                     labelThread tid "console event handler"
+                     handler x
                  return ()
     Nothing -> return ()
 
diff --git a/src/GHC/Internal/Event/Windows/Thread.hs b/src/GHC/Internal/Event/Windows/Thread.hs
--- a/src/GHC/Internal/Event/Windows/Thread.hs
+++ b/src/GHC/Internal/Event/Windows/Thread.hs
@@ -11,7 +11,7 @@
 import GHC.Internal.Base
 import GHC.Internal.Event.Windows
 import GHC.Internal.IO
-import GHC.Internal.IOPort
+import GHC.Internal.MVar
 
 ensureIOManagerIsRunning :: IO ()
 ensureIOManagerIsRunning = wakeupIOManager
@@ -23,10 +23,10 @@
 -- 2147483647 μs, less than 36 minutes.
 threadDelay :: Int -> IO ()
 threadDelay usecs = mask_ $ do
-    m <- newEmptyIOPort
+    m <- newEmptyMVar
     mgr <- getSystemManager
-    reg <- registerTimeout mgr usecs $ writeIOPort m () >> return ()
-    readIOPort m `onException` unregisterTimeout mgr reg
+    reg <- registerTimeout mgr usecs $ putMVar m () >> return ()
+    readMVar m `onException` unregisterTimeout mgr reg
 
 -- | Be careful not to exceed @maxBound :: Int@, which on 32-bit machines is only
 -- 2147483647 μs, less than 36 minutes.
diff --git a/src/GHC/Internal/Exception.hs b/src/GHC/Internal/Exception.hs
--- a/src/GHC/Internal/Exception.hs
+++ b/src/GHC/Internal/Exception.hs
@@ -59,7 +59,7 @@
     , toExceptionWithBacktrace
 
       -- * Reexports
-      -- Re-export CallStack and SrcLoc from GHC.Types
+      -- Re-export CallStack and SrcLoc from GHC.Internal.Types
     , CallStack, fromCallSiteList, getCallStack, prettyCallStack
     , prettyCallStackLines
     , SrcLoc(..), prettySrcLoc
diff --git a/src/GHC/Internal/Exception.hs-boot b/src/GHC/Internal/Exception.hs-boot
--- a/src/GHC/Internal/Exception.hs-boot
+++ b/src/GHC/Internal/Exception.hs-boot
@@ -31,7 +31,7 @@
   ) where
 
 import {-# SOURCE #-} GHC.Internal.Exception.Type
-import GHC.Types ( Char )
+import GHC.Internal.Types ( Char )
 import GHC.Internal.Stack.Types ( CallStack )
 
 errorCallException :: [Char] -> SomeException
diff --git a/src/GHC/Internal/Exception/Backtrace.hs b/src/GHC/Internal/Exception/Backtrace.hs
--- a/src/GHC/Internal/Exception/Backtrace.hs
+++ b/src/GHC/Internal/Exception/Backtrace.hs
@@ -3,20 +3,7 @@
 {-# LANGUAGE NamedFieldPuns #-}
 {-# LANGUAGE RankNTypes #-}
 
-module GHC.Internal.Exception.Backtrace
-    ( -- * Backtrace mechanisms
-      BacktraceMechanism(..)
-    , getBacktraceMechanismState
-    , setBacktraceMechanismState
-      -- * Collecting backtraces
-    , Backtraces(..)
-    , displayBacktraces
-    , collectBacktraces
-    , CollectExceptionAnnotationMechanism
-    , getCollectExceptionAnnotationMechanism
-    , setCollectExceptionAnnotation
-    , collectExceptionAnnotation
-    ) where
+module GHC.Internal.Exception.Backtrace where
 
 import GHC.Internal.Base
 import GHC.Internal.Data.OldList
@@ -24,11 +11,12 @@
 import GHC.Internal.IO.Unsafe (unsafePerformIO)
 import GHC.Internal.Exception.Context
 import GHC.Internal.Ptr
-import GHC.Internal.Data.Maybe (fromMaybe)
+import GHC.Internal.Data.Maybe (fromMaybe, mapMaybe)
 import GHC.Internal.Stack.Types as GHC.Stack (CallStack, HasCallStack)
 import qualified GHC.Internal.Stack as HCS
 import qualified GHC.Internal.ExecutionStack.Internal as ExecStack
 import qualified GHC.Internal.Stack.CloneStack as CloneStack
+import qualified GHC.Internal.Stack.Decode as CloneStack
 import qualified GHC.Internal.Stack.CCS as CCS
 
 -- | How to collect a backtrace when an exception is thrown.
@@ -156,7 +144,7 @@
     displayExec = unlines . map (indent 2 . flip ExecStack.showLocation "") . fromMaybe [] . ExecStack.stackFrames
     -- The unsafePerformIO here is safe as 'StackSnapshot' makes sure neither the stack frames nor
     -- references closures can be garbage collected.
-    displayIpe  = unlines . map (indent 2 . CloneStack.prettyStackEntry) . unsafePerformIO . CloneStack.decode
+    displayIpe  = unlines . mapMaybe (fmap (indent 2) . CloneStack.prettyStackFrameWithIpe) . unsafePerformIO . CloneStack.decodeStackWithIpe
     displayHsc  = unlines . map (indent 2 . prettyCallSite) . HCS.getCallStack
       where prettyCallSite (f, loc) = f ++ ", called at " ++ HCS.prettySrcLoc loc
 
diff --git a/src/GHC/Internal/Exception/Context.hs-boot b/src/GHC/Internal/Exception/Context.hs-boot
--- a/src/GHC/Internal/Exception/Context.hs-boot
+++ b/src/GHC/Internal/Exception/Context.hs-boot
@@ -3,7 +3,7 @@
 module GHC.Internal.Exception.Context where
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 
 data ExceptionContext
 
diff --git a/src/GHC/Internal/Exception/Type.hs b/src/GHC/Internal/Exception/Type.hs
--- a/src/GHC/Internal/Exception/Type.hs
+++ b/src/GHC/Internal/Exception/Type.hs
@@ -246,10 +246,10 @@
 --    * The exception context
 --
 -- By default, 'uncaughtExceptionHandler' uses 'displayExceptionWithInfo' to print uncaught exceptions.
--- This default can be overriden with 'setUncaughtExceptionHandler', for
+-- This default can be overridden with 'setUncaughtExceptionHandler', for
 -- instance, to present custom error messages on exceptions to the user.
 --
--- @since base-4.21
+-- @since base-4.22
 displayExceptionWithInfo :: SomeException -> String
 displayExceptionWithInfo (SomeException e) =
     case displayExceptionContext ?exceptionContext of
diff --git a/src/GHC/Internal/Exception/Type.hs-boot b/src/GHC/Internal/Exception/Type.hs-boot
--- a/src/GHC/Internal/Exception/Type.hs-boot
+++ b/src/GHC/Internal/Exception/Type.hs-boot
@@ -2,7 +2,8 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 
 module GHC.Internal.Exception.Type
-  ( SomeException
+  ( Exception
+  , SomeException
   , divZeroException
   , overflowException
   , ratioZeroDenomException
@@ -10,7 +11,9 @@
   ) where
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
+
+class Exception e
 
 data SomeException
 divZeroException, overflowException,
diff --git a/src/GHC/Internal/Exts.hs b/src/GHC/Internal/Exts.hs
--- a/src/GHC/Internal/Exts.hs
+++ b/src/GHC/Internal/Exts.hs
@@ -28,13 +28,13 @@
 {- Note [Where do we export PrimOps]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Built in primops are automatically exported via the magical module
-GHC.Prim (See Note [GHC.Prim]).
-However we don't want users to use GHC.Prim directly. Among other reasons that
+GHC.Internal.Prim (See Note [GHC.Prim]).
+However we don't want users to use GHC.Internal.Prim directly. Among other reasons that
 would prevent us from giving those primops a regular haskell or cmm
 implementation in the future.
 
 So instead we provide a hirarchy of Modules through which we expose PrimOps.
-* ghc-internal:GHC.Exts.Internal re-exports GHC.Prim along with some other
+* ghc-internal:GHC.Exts.Internal re-exports GHC.Internal.Prim along with some other
   builtin functionality. It gives zero stability guarantee and is mostly inteded
   for ghc internal use.
 * ghc-experimental:GHC.PrimOps contains a more stable subset of GHC.Exts.Internal.
@@ -61,15 +61,15 @@
         Ptr(..), FunPtr(..),
 
         -- ** Other primitive types
-        module GHC.Types,
+        module GHC.Internal.Types,
 
         -- ** Legacy interface for arrays of arrays
         module GHC.Internal.ArrayArray,
 
         -- * Primitive operations
 
-        module GHC.Prim,
-        module GHC.Prim.Ext,
+        module GHC.Internal.Prim,
+        module GHC.Internal.Prim.Ext,
 
         -- ** Running 'RealWorld' state thread
         runRW#,
@@ -91,7 +91,6 @@
         sameMVar#,
         sameMutVar#,
         sameTVar#,
-        sameIOPort#,
         samePromptTag#,
 
         -- ** Compat wrapper
@@ -165,13 +164,13 @@
         maxTupleSize,
        ) where
 
-import GHC.Prim hiding ( coerce, dataToTagSmall#, dataToTagLarge#, whereFrom# )
+import GHC.Internal.Prim hiding ( coerce, dataToTagSmall#, dataToTagLarge#, whereFrom# )
   -- Hide dataToTagLarge# because it is expected to break for
   -- GHC-internal reasons in the near future, and shouldn't
   -- be exposed from base (not even GHC.Exts)
   -- whereFrom# is similarly internal.
 
-import GHC.Types
+import GHC.Internal.Types
   hiding ( IO   -- Exported from "GHC.IO"
          , Type -- Exported from "Data.Kind"
 
@@ -307,7 +306,7 @@
          Sum62#,
          Sum63#,
   )
-import qualified GHC.Prim.Ext
+import qualified GHC.Internal.Prim.Ext
 import GHC.Internal.ArrayArray
 import GHC.Internal.Base hiding ( coerce )
 import GHC.Internal.IO (seq#)
diff --git a/src/GHC/Internal/Float.hs b/src/GHC/Internal/Float.hs
--- a/src/GHC/Internal/Float.hs
+++ b/src/GHC/Internal/Float.hs
@@ -142,7 +142,7 @@
     , roundingMode#
 
       -- * Monomorphic equality operators
-      -- | See GHC.Classes#matching_overloaded_methods_in_rules
+      -- | See GHC.Internal.Classes#matching_overloaded_methods_in_rules
     , eqFloat, eqDouble
 
       -- * Internal
@@ -176,7 +176,7 @@
 import GHC.Internal.Arr
 import GHC.Internal.Float.RealFracMethods
 import GHC.Internal.Float.ConversionUtils
-import GHC.Num.BigNat
+import GHC.Internal.Bignum.BigNat
 
 infixr 8  **
 
@@ -282,8 +282,10 @@
     -- | a constant function, returning the number of digits of
     -- 'floatRadix' in the significand
     floatDigits         :: a -> Int
-    -- | a constant function, returning the lowest and highest values
-    -- the exponent may assume
+    -- | A constant function, returning the lowest and highest values
+    -- that @'exponent' x@ may assume for a normal @x@.
+    -- The relation to IEEE @emin@ and @emax@ is
+    -- @'floatRange' x = (emin + 1, emax + 1)@.
     floatRange          :: a -> (Int,Int)
     -- | The function 'decodeFloat' applied to a real floating-point
     -- number returns the significand expressed as an 'Integer' and an
@@ -1215,8 +1217,8 @@
 -- Converting from an Integer to a RealFloat
 ------------------------------------------------------------------------
 
-{-# SPECIALISE integerToBinaryFloat' :: Integer -> Float,
-                                        Integer -> Double #-}
+{-# SPECIALISE integerToBinaryFloat' :: Integer -> Float #-}
+{-# SPECIALISE integerToBinaryFloat' :: Integer -> Double #-}
 -- | Converts a positive integer to a floating-point value.
 --
 -- The value nearest to the argument will be returned.
@@ -1384,8 +1386,8 @@
 divisions as much as possible.
 -}
 
-{-# SPECIALISE fromRat'' :: Int -> Int -> Integer -> Integer -> Float,
-                            Int -> Int -> Integer -> Integer -> Double #-}
+{-# SPECIALISE fromRat'' :: Int -> Int -> Integer -> Integer -> Float #-}
+{-# SPECIALISE fromRat'' :: Int -> Int -> Integer -> Integer -> Double #-}
 fromRat'' :: RealFloat a => Int -> Int -> Integer -> Integer -> a
 -- Invariant: n and d strictly positive
 fromRat'' minEx@(I# me#) mantDigs@(I# md#) n d =
@@ -1794,7 +1796,7 @@
 castDoubleToWord64 (D# d#) = W64# (castDoubleToWord64# d#)
 
 -- See Note [Optimising conversions between numeric types]
--- in GHC.Num.Integer
+-- in GHC.Internal.Bignum.Integer
 {-# RULES
 
 "Int# -> Integer -> Float#"
diff --git a/src/GHC/Internal/Float/ConversionUtils.hs b/src/GHC/Internal/Float/ConversionUtils.hs
--- a/src/GHC/Internal/Float/ConversionUtils.hs
+++ b/src/GHC/Internal/Float/ConversionUtils.hs
@@ -22,7 +22,7 @@
 module GHC.Internal.Float.ConversionUtils ( elimZerosInteger, elimZerosInt# ) where
 
 import GHC.Internal.Base
-import GHC.Num.Integer
+import GHC.Internal.Bignum.Integer
 
 default ()
 
diff --git a/src/GHC/Internal/Float/RealFracMethods.hs b/src/GHC/Internal/Float/RealFracMethods.hs
--- a/src/GHC/Internal/Float/RealFracMethods.hs
+++ b/src/GHC/Internal/Float/RealFracMethods.hs
@@ -59,7 +59,7 @@
     , int2Float
     ) where
 
-import GHC.Num.Integer
+import GHC.Internal.Bignum.Integer
 
 import GHC.Internal.Base hiding (uncheckedIShiftRA64#, uncheckedIShiftL64#)
 import GHC.Internal.Num () -- instance Num Integer
diff --git a/src/GHC/Internal/Foreign/C/String/Encoding.hs b/src/GHC/Internal/Foreign/C/String/Encoding.hs
--- a/src/GHC/Internal/Foreign/C/String/Encoding.hs
+++ b/src/GHC/Internal/Foreign/C/String/Encoding.hs
@@ -55,7 +55,7 @@
 import GHC.Internal.Foreign.Marshal.Alloc
 import GHC.Internal.Foreign.ForeignPtr
 
-import GHC.Debug
+import GHC.Internal.Debug
 import GHC.Internal.List
 import GHC.Internal.Num
 import GHC.Internal.Base
diff --git a/src/GHC/Internal/Generics.hs b/src/GHC/Internal/Generics.hs
--- a/src/GHC/Internal/Generics.hs
+++ b/src/GHC/Internal/Generics.hs
@@ -733,22 +733,22 @@
 import GHC.Internal.Data.Either     ( Either (..) )
 import GHC.Internal.Data.Maybe      ( Maybe(..), fromMaybe )
 import GHC.Internal.Data.Ord        ( Down(..) )
-import GHC.Num.Integer ( Integer, integerToInt )
-import GHC.Prim        ( Addr#, Char#, Double#, Float#, Int#, Word# )
+import GHC.Internal.Bignum.Integer ( Integer, integerToInt )
+import GHC.Internal.Prim        ( Addr#, Char#, Double#, Float#, Int#, Word# )
 import GHC.Internal.Ptr         ( Ptr(..) )
-import GHC.Types
+import GHC.Internal.Types
 
 -- Needed for instances
 import GHC.Internal.Ix      ( Ix )
 import GHC.Internal.Base    ( Alternative(..), Applicative(..), Functor(..)
                    , Monad(..), MonadPlus(..), NonEmpty(..), String, coerce
                    , Semigroup(..), Monoid(..), Void )
-import GHC.Classes ( Eq(..), Ord(..) )
+import GHC.Internal.Classes ( Eq(..), Ord(..) )
 import GHC.Internal.Enum    ( Bounded, Enum )
 import GHC.Internal.Read    ( Read(..) )
 import GHC.Internal.Show    ( Show(..), showString, showChar, showParen, appPrec )
 import GHC.Internal.Stack.Types ( SrcLoc(..) )
-import GHC.Tuple   (Solo (..))
+import GHC.Internal.Tuple   (Solo (..))
 import GHC.Internal.Unicode ( GeneralCategory(..) )
 import GHC.Internal.Fingerprint.Type ( Fingerprint(..) )
 
@@ -1879,4 +1879,3 @@
   fromSing SDecidedLazy   = DecidedLazy
   fromSing SDecidedStrict = DecidedStrict
   fromSing SDecidedUnpack = DecidedUnpack
-
diff --git a/src/GHC/Internal/Heap/Closures.hs b/src/GHC/Internal/Heap/Closures.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Heap/Closures.hs
@@ -0,0 +1,658 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DeriveTraversable #-}
+-- Late cost centres introduce a thunk in the asBox function, which leads to
+-- an additional wrapper being added to any value placed inside a box.
+-- This can be removed once our boot compiler is no longer affected by #25212
+{-# OPTIONS_GHC -fno-prof-late  #-}
+{-# LANGUAGE NamedFieldPuns #-}
+
+module GHC.Internal.Heap.Closures (
+    -- * Closures
+      Closure
+    , GenClosure(..)
+    , getClosureInfoTbl
+    , getClosureInfoTbl_maybe
+    , getClosurePtrArgs
+    , getClosurePtrArgs_maybe
+    , PrimType(..)
+    , WhatNext(..)
+    , WhyBlocked(..)
+    , TsoFlags(..)
+    , allClosures
+    , closureSize
+
+    -- * Stack
+    , StgStackClosure
+    , GenStgStackClosure(..)
+    , StackFrame
+    , GenStackFrame(..)
+    , StackField
+    , GenStackField(..)
+
+    -- * Boxes
+    , Box(..)
+    , areBoxesEqual
+    , asBox
+    ) where
+
+import GHC.Internal.Base
+import GHC.Internal.Show
+
+import GHC.Internal.Heap.Constants
+#if defined(PROFILING)
+import GHC.Internal.Heap.InfoTable () -- see Note [No way-dependent imports]
+import GHC.Internal.Heap.InfoTableProf
+#else
+import GHC.Internal.Heap.InfoTable
+import GHC.Internal.Heap.InfoTableProf () -- see Note [No way-dependent imports]
+
+{-
+Note [No way-dependent imports]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+`ghc -M` currently assumes that the imports for a module are the same
+in every way.  This is arguably a bug, but breaking this assumption by
+importing different things in different ways can cause trouble.  For
+example, this module in the profiling way imports and uses
+GHC.Exts.Heap.InfoTableProf.  When it was not also imported in the
+vanilla way, there were intermittent build failures due to this module
+being compiled in the profiling way before GHC.Exts.Heap.InfoTableProf
+in the profiling way. (#15197)
+-}
+#endif
+
+import GHC.Internal.Heap.ProfInfo.Types
+
+import GHC.Internal.Data.Bits
+import GHC.Internal.Data.Foldable (Foldable, toList)
+import GHC.Internal.Data.Traversable (Traversable)
+import GHC.Internal.Int
+import GHC.Internal.Num
+import GHC.Internal.Real
+import GHC.Internal.Word
+import GHC.Internal.Exts
+import GHC.Internal.Generics
+import GHC.Internal.Numeric
+import GHC.Internal.Stack (HasCallStack)
+
+------------------------------------------------------------------------
+-- Boxes
+
+foreign import prim "aToWordzh" aToWord# :: Any -> Word#
+
+foreign import prim "reallyUnsafePtrEqualityUpToTag"
+    reallyUnsafePtrEqualityUpToTag# :: Any -> Any -> Int#
+
+-- | An arbitrary Haskell value in a safe Box. The point is that even
+-- unevaluated thunks can safely be moved around inside the Box, and when
+-- required, e.g. in 'getBoxedClosureData', the function knows how far it has
+-- to evaluate the argument.
+data Box = Box Any
+
+instance Show Box where
+-- From libraries/base/GHC/Ptr.lhs
+   showsPrec _ (Box a) rs =
+    -- unsafePerformIO (print "↓" >> pClosure a) `seq`
+    pad_out (showHex addr "") ++ (if tag>0 then "/" ++ show tag else "") ++ rs
+     where
+       ptr  = W# (aToWord# a)
+       tag  = ptr .&. fromIntegral tAG_MASK -- ((1 `shiftL` TAG_BITS) -1)
+       addr = ptr - tag
+       pad_out ls = '0':'x':ls
+
+-- |This takes an arbitrary value and puts it into a box.
+-- Note that calls like
+--
+-- > asBox (head list)
+--
+-- will put the thunk \"head list\" into the box, /not/ the element at the head
+-- of the list. For that, use careful case expressions:
+--
+-- > case list of x:_ -> asBox x
+asBox :: a -> Box
+asBox x = Box (unsafeCoerce# x)
+
+-- | Boxes can be compared, but this is not pure, as different heap objects can,
+-- after garbage collection, become the same object.
+areBoxesEqual :: Box -> Box -> IO Bool
+areBoxesEqual (Box a) (Box b) = case reallyUnsafePtrEqualityUpToTag# a b of
+    0# -> pure False
+    _  -> pure True
+
+
+------------------------------------------------------------------------
+-- Closures
+type Closure = GenClosure Box
+
+-- | This is the representation of a Haskell value on the heap. It reflects
+-- <https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/storage/Closures.h>
+--
+-- The data type is parametrized by `b`: the type to store references in.
+-- Usually this is a 'Box' with the type synonym 'Closure'.
+--
+-- All Heap objects have the same basic layout. A header containing a pointer to
+-- the info table and a payload with various fields. The @info@ field below
+-- always refers to the info table pointed to by the header. The remaining
+-- fields are the payload.
+--
+-- See
+-- <https://gitlab.haskell.org/ghc/ghc/wikis/commentary/rts/storage/heap-objects>
+-- for more information.
+data GenClosure b
+  = -- | A data constructor
+    ConstrClosure
+        { info       :: !StgInfoTable
+        , ptrArgs    :: ![b]            -- ^ Pointer arguments
+        , dataArgs   :: ![Word]         -- ^ Non-pointer arguments
+        , pkg        :: !String         -- ^ Package name
+        , modl       :: !String         -- ^ Module name
+        , name       :: !String         -- ^ Constructor name
+        }
+
+    -- | A function
+  | FunClosure
+        { info       :: !StgInfoTable
+        , ptrArgs    :: ![b]            -- ^ Pointer arguments
+        , dataArgs   :: ![Word]         -- ^ Non-pointer arguments
+        }
+
+    -- | A thunk, an expression not obviously in head normal form
+  | ThunkClosure
+        { info       :: !StgInfoTable
+        , ptrArgs    :: ![b]            -- ^ Pointer arguments
+        , dataArgs   :: ![Word]         -- ^ Non-pointer arguments
+        }
+
+    -- | A thunk which performs a simple selection operation
+  | SelectorClosure
+        { info       :: !StgInfoTable
+        , selectee   :: !b              -- ^ Pointer to the object being
+                                        --   selected from
+        }
+
+    -- | An unsaturated function application
+  | PAPClosure
+        { info       :: !StgInfoTable
+        , arity      :: !HalfWord       -- ^ Arity of the partial application
+        , n_args     :: !HalfWord       -- ^ Size of the payload in words
+        , fun        :: !b              -- ^ Pointer to a 'FunClosure'
+        , payload    :: ![b]            -- ^ Sequence of already applied
+                                        --   arguments
+        }
+
+    -- In GHCi, if Linker.h would allow a reverse lookup, we could for exported
+    -- functions fun actually find the name here.
+    -- At least the other direction works via "lookupSymbol
+    -- base_GHCziBase_zpzp_closure" and yields the same address (up to tags)
+    -- | A function application
+  | APClosure
+        { info       :: !StgInfoTable
+        , arity      :: !HalfWord       -- ^ Always 0
+        , n_args     :: !HalfWord       -- ^ Size of payload in words
+        , fun        :: !b              -- ^ Pointer to a 'FunClosure'
+        , payload    :: ![b]            -- ^ Sequence of already applied
+                                        --   arguments
+        }
+
+    -- | A suspended thunk evaluation
+  | APStackClosure
+        { info       :: !StgInfoTable
+        , fun        :: !b              -- ^ Function closure
+        , payload    :: ![b]            -- ^ Stack right before suspension
+        }
+
+    -- | A pointer to another closure, introduced when a thunk is updated
+    -- to point at its value
+  | IndClosure
+        { info       :: !StgInfoTable
+        , indirectee :: !b              -- ^ Target closure
+        }
+
+   -- | A byte-code object (BCO) which can be interpreted by GHC's byte-code
+   -- interpreter (e.g. as used by GHCi)
+  | BCOClosure
+        { info       :: !StgInfoTable
+        , instrs     :: !b              -- ^ A pointer to an ArrWords
+                                        --   of instructions
+        , literals   :: !b              -- ^ A pointer to an ArrWords
+                                        --   of literals
+        , bcoptrs    :: !b              -- ^ A pointer to an ArrWords
+                                        --   of byte code objects
+        , arity      :: !HalfWord       -- ^ The arity of this BCO
+        , size       :: !HalfWord       -- ^ The size of this BCO in words
+        , bitmap     :: ![Word]         -- ^ An StgLargeBitmap describing the
+                                        --   pointerhood of its args/free vars
+        }
+
+    -- | A thunk under evaluation by another thread
+  | BlackholeClosure
+        { info       :: !StgInfoTable
+        , indirectee :: !b              -- ^ The target closure
+        }
+
+    -- | A @ByteArray#@
+  | ArrWordsClosure
+        { info       :: !StgInfoTable
+        , bytes      :: !Word           -- ^ Size of array in bytes
+        , arrWords   :: ![Word]         -- ^ Array payload
+        }
+
+    -- | A @MutableByteArray#@
+  | MutArrClosure
+        { info       :: !StgInfoTable
+        , mccPtrs    :: !Word           -- ^ Number of pointers
+        , mccSize    :: !Word           -- ^ ?? Closures.h vs ClosureMacros.h
+        , mccPayload :: ![b]            -- ^ Array payload
+        -- Card table ignored
+        }
+
+    -- | A @SmallMutableArray#@
+    --
+    -- @since 8.10.1
+  | SmallMutArrClosure
+        { info       :: !StgInfoTable
+        , mccPtrs    :: !Word           -- ^ Number of pointers
+        , mccPayload :: ![b]            -- ^ Array payload
+        }
+
+  -- | An @MVar#@, with a queue of thread state objects blocking on them
+  | MVarClosure
+    { info       :: !StgInfoTable
+    , queueHead  :: !b              -- ^ Pointer to head of queue
+    , queueTail  :: !b              -- ^ Pointer to tail of queue
+    , value      :: !b              -- ^ Pointer to closure
+    }
+
+    -- | A @MutVar#@
+  | MutVarClosure
+        { info       :: !StgInfoTable
+        , var        :: !b              -- ^ Pointer to contents
+        }
+
+    -- | An STM blocking queue.
+  | BlockingQueueClosure
+        { info       :: !StgInfoTable
+        , link       :: !b              -- ^ ?? Here so it looks like an IND
+        , blackHole  :: !b              -- ^ The blackhole closure
+        , owner      :: !b              -- ^ The owning thread state object
+        , queue      :: !b              -- ^ ??
+        }
+
+  | WeakClosure
+        { info        :: !StgInfoTable
+        , cfinalizers :: !b
+        , key         :: !b
+        , value       :: !b
+        , finalizer   :: !b
+        , weakLink    :: !(Maybe b) -- ^ next weak pointer for the capability
+        }
+
+  -- | Representation of StgTSO: A Thread State Object. The values for
+  -- 'what_next', 'why_blocked' and 'flags' are defined in @Constants.h@.
+  | TSOClosure
+      { info                :: !StgInfoTable
+      -- pointers
+      , link                :: !b
+      , global_link         :: !b
+      , tsoStack            :: !b -- ^ stackobj from StgTSO
+      , trec                :: !b
+      , blocked_exceptions  :: !b
+      , bq                  :: !b
+      , thread_label        :: !(Maybe b)
+      -- values
+      , what_next           :: !WhatNext
+      , why_blocked         :: !WhyBlocked
+      , flags               :: ![TsoFlags]
+      , threadId            :: !Word64
+      , saved_errno         :: !Word32
+      , tso_dirty           :: !Word32 -- ^ non-zero => dirty
+      , alloc_limit         :: !Int64
+      , tot_stack_size      :: !Word32
+      , prof                :: !(Maybe StgTSOProfInfo)
+      }
+
+  -- | Representation of StgStack: The 'tsoStack ' of a 'TSOClosure'.
+  | StackClosure
+      { info            :: !StgInfoTable
+      , stack_size      :: !Word32 -- ^ stack size in *words*
+      , stack_dirty     :: !Word8 -- ^ non-zero => dirty
+      , stack_marking   :: !Word8
+      }
+
+    ------------------------------------------------------------
+    -- Unboxed unlifted closures
+
+    -- | Primitive Int
+  | IntClosure
+        { ptipe      :: PrimType
+        , intVal     :: !Int }
+
+    -- | Primitive Word
+  | WordClosure
+        { ptipe      :: PrimType
+        , wordVal    :: !Word }
+
+    -- | Primitive Int64
+  | Int64Closure
+        { ptipe      :: PrimType
+        , int64Val   :: !Int64 }
+
+    -- | Primitive Word64
+  | Word64Closure
+        { ptipe      :: PrimType
+        , word64Val  :: !Word64 }
+
+    -- | Primitive Addr
+  | AddrClosure
+        { ptipe      :: PrimType
+        , addrVal    :: !(Ptr ()) }
+
+    -- | Primitive Float
+  | FloatClosure
+        { ptipe      :: PrimType
+        , floatVal   :: !Float }
+
+    -- | Primitive Double
+  | DoubleClosure
+        { ptipe      :: PrimType
+        , doubleVal  :: !Double }
+
+    -----------------------------------------------------------
+    -- Anything else
+
+    -- | Another kind of closure
+  | OtherClosure
+        { info       :: !StgInfoTable
+        , hvalues    :: ![b]
+        , rawWords   :: ![Word]
+        }
+
+  | UnsupportedClosure
+        { info       :: !StgInfoTable
+        }
+
+    -- | A primitive word from a bitmap encoded stack frame payload
+    --
+    -- The type itself cannot be restored (i.e. it might represent a Word8#
+    -- or an Int#).
+  |  UnknownTypeWordSizedPrimitive
+        { wordVal :: !Word }
+  deriving (Show, Generic, Functor, Foldable, Traversable)
+
+-- | Get the info table for a heap closure, or Nothing for a prim value
+--
+-- @since 9.14.1
+getClosureInfoTbl_maybe :: GenClosure b -> Maybe StgInfoTable
+{-# INLINE getClosureInfoTbl_maybe #-} -- Ensure we can get rid of the just box
+getClosureInfoTbl_maybe closure = case closure of
+  ConstrClosure{info} ->Just info
+  FunClosure{info} ->Just info
+  ThunkClosure{info} ->Just info
+  SelectorClosure{info} ->Just info
+  PAPClosure{info} ->Just info
+  APClosure{info} ->Just info
+  APStackClosure{info} ->Just info
+  IndClosure{info} ->Just info
+  BCOClosure{info} ->Just info
+  BlackholeClosure{info} ->Just info
+  ArrWordsClosure{info} ->Just info
+  MutArrClosure{info} ->Just info
+  SmallMutArrClosure{info} ->Just info
+  MVarClosure{info} ->Just info
+  MutVarClosure{info} ->Just info
+  BlockingQueueClosure{info} ->Just info
+  WeakClosure{info} ->Just info
+  TSOClosure{info} ->Just info
+  StackClosure{info} ->Just info
+
+  IntClosure{} -> Nothing
+  WordClosure{} -> Nothing
+  Int64Closure{} -> Nothing
+  Word64Closure{} -> Nothing
+  AddrClosure{} -> Nothing
+  FloatClosure{} -> Nothing
+  DoubleClosure{} -> Nothing
+
+  OtherClosure{info} -> Just info
+  UnsupportedClosure {info} -> Just info
+
+  UnknownTypeWordSizedPrimitive{} -> Nothing
+
+-- | Partial version of getClosureInfoTbl_maybe for when we know we deal with a
+-- heap closure.
+--
+-- @since 9.14.1
+getClosureInfoTbl :: HasCallStack => GenClosure b -> StgInfoTable
+getClosureInfoTbl closure = case getClosureInfoTbl_maybe closure of
+  Just info -> info
+  Nothing -> error "getClosureInfoTbl - Closure without info table"
+
+-- | Get the info table for a heap closure, or Nothing for a prim value
+--
+-- @since 9.14.1
+getClosurePtrArgs_maybe :: GenClosure b -> Maybe [b]
+{-# INLINE getClosurePtrArgs_maybe #-} -- Ensure we can get rid of the just box
+getClosurePtrArgs_maybe closure = case closure of
+  ConstrClosure{ptrArgs} -> Just ptrArgs
+  FunClosure{ptrArgs} -> Just ptrArgs
+  ThunkClosure{ptrArgs} -> Just ptrArgs
+  SelectorClosure{} -> Nothing
+  PAPClosure{} -> Nothing
+  APClosure{} -> Nothing
+  APStackClosure{} -> Nothing
+  IndClosure{} -> Nothing
+  BCOClosure{} -> Nothing
+  BlackholeClosure{} -> Nothing
+  ArrWordsClosure{} -> Nothing
+  MutArrClosure{} -> Nothing
+  SmallMutArrClosure{} -> Nothing
+  MVarClosure{} -> Nothing
+  MutVarClosure{} -> Nothing
+  BlockingQueueClosure{} -> Nothing
+  WeakClosure{} -> Nothing
+  TSOClosure{} -> Nothing
+  StackClosure{} -> Nothing
+
+  IntClosure{} -> Nothing
+  WordClosure{} -> Nothing
+  Int64Closure{} -> Nothing
+  Word64Closure{} -> Nothing
+  AddrClosure{} -> Nothing
+  FloatClosure{} -> Nothing
+  DoubleClosure{} -> Nothing
+
+  OtherClosure{} -> Nothing
+  UnsupportedClosure{} -> Nothing
+
+  UnknownTypeWordSizedPrimitive{} -> Nothing
+
+-- | Partial version of getClosureInfoTbl_maybe for when we know we deal with a
+-- heap closure.
+--
+-- @since 9.14.1
+getClosurePtrArgs :: HasCallStack => GenClosure b -> [b]
+getClosurePtrArgs closure = case getClosurePtrArgs_maybe closure of
+  Just ptrs -> ptrs
+  Nothing -> error "getClosurePtrArgs - Closure without ptrArgs field"
+
+type StgStackClosure = GenStgStackClosure Box
+
+-- | A decoded @StgStack@ with `StackFrame`s
+--
+-- Stack related data structures (`GenStgStackClosure`, `GenStackField`,
+-- `GenStackFrame`) are defined separately from `GenClosure` as their related
+-- functions are very different. Though, both are closures in the sense of RTS
+-- structures, their decoding logic differs: While it's safe to keep a reference
+-- to a heap closure, the garbage collector does not update references to stack
+-- located closures.
+--
+-- Additionally, stack frames don't appear outside of the stack. Thus, keeping
+-- `GenStackFrame` and `GenClosure` separated, makes these types more precise
+-- (in the sense what values to expect.)
+data GenStgStackClosure b = GenStgStackClosure
+      { ssc_info            :: !StgInfoTable
+      , ssc_stack_size      :: !Word32 -- ^ stack size in *words*
+      , ssc_stack           :: ![GenStackFrame b]
+      }
+  deriving (Foldable, Functor, Generic, Show, Traversable)
+
+type StackField = GenStackField Box
+
+-- | Bitmap-encoded payload on the stack
+data GenStackField b
+    -- | A non-pointer field
+    = StackWord !Word
+    -- | A pointer field
+    | StackBox  !b
+  deriving (Foldable, Functor, Generic, Show, Traversable)
+
+type StackFrame = GenStackFrame Box
+
+-- | A single stack frame
+data GenStackFrame b =
+   UpdateFrame
+      { info_tbl           :: !StgInfoTable
+      , updatee            :: !b
+      }
+
+  | CatchFrame
+      { info_tbl            :: !StgInfoTable
+      , handler             :: !b
+      }
+
+  | CatchStmFrame
+      { info_tbl            :: !StgInfoTable
+      , catchFrameCode      :: !b
+      , handler             :: !b
+      }
+
+  | CatchRetryFrame
+      { info_tbl            :: !StgInfoTable
+      , running_alt_code    :: !Word
+      , first_code          :: !b
+      , alt_code            :: !b
+      }
+
+  | AtomicallyFrame
+      { info_tbl            :: !StgInfoTable
+      , atomicallyFrameCode :: !b
+      , result              :: !b
+      }
+
+  | UnderflowFrame
+      { info_tbl            :: !StgInfoTable
+      , nextChunk           :: !(GenStgStackClosure b)
+      }
+
+  | StopFrame
+      { info_tbl            :: !StgInfoTable }
+
+  | RetSmall
+      { info_tbl            :: !StgInfoTable
+      , stack_payload       :: ![GenStackField b]
+      }
+
+  | RetBig
+      { info_tbl            :: !StgInfoTable
+      , stack_payload       :: ![GenStackField b]
+      }
+
+  | RetFun
+      { info_tbl            :: !StgInfoTable
+      , retFunSize          :: !Word
+      , retFunFun           :: !b
+      , retFunPayload       :: ![GenStackField b]
+      }
+
+  | RetBCO
+      { info_tbl            :: !StgInfoTable
+      , bco                 :: !b -- ^ always a BCOClosure
+      , bcoArgs             :: ![GenStackField b]
+      }
+  | AnnFrame
+      { info_tbl            :: !StgInfoTable
+      , annotation          :: !b
+      }
+  deriving (Foldable, Functor, Generic, Show, Traversable)
+
+data PrimType
+  = PInt
+  | PWord
+  | PInt64
+  | PWord64
+  | PAddr
+  | PFloat
+  | PDouble
+  deriving (Eq, Show, Generic, Ord)
+
+data WhatNext
+  = ThreadRunGHC
+  | ThreadInterpret
+  | ThreadKilled
+  | ThreadComplete
+  | WhatNextUnknownValue Word16 -- ^ Please report this as a bug
+  deriving (Eq, Show, Generic, Ord)
+
+data WhyBlocked
+  = NotBlocked
+  | BlockedOnMVar
+  | BlockedOnMVarRead
+  | BlockedOnBlackHole
+  | BlockedOnRead
+  | BlockedOnWrite
+  | BlockedOnDelay
+  | BlockedOnSTM
+  | BlockedOnDoProc
+  | BlockedOnCCall
+  | BlockedOnCCall_Interruptible
+  | BlockedOnMsgThrowTo
+  | ThreadMigrating
+  | WhyBlockedUnknownValue Word16 -- ^ Please report this as a bug
+  deriving (Eq, Show, Generic, Ord)
+
+data TsoFlags
+  = TsoLocked
+  | TsoBlockx
+  | TsoInterruptible
+  | TsoStoppedOnBreakpoint
+  | TsoMarked
+  | TsoSqueezed
+  | TsoAllocLimit
+  | TsoStopNextBreakpoint
+  | TsoStopAfterReturn
+  | TsoFlagsUnknownValue Word32 -- ^ Please report this as a bug
+  deriving (Eq, Show, Generic, Ord)
+
+-- | For generic code, this function returns all referenced closures.
+allClosures :: GenClosure b -> [b]
+allClosures (ConstrClosure {..}) = ptrArgs
+allClosures (ThunkClosure {..}) = ptrArgs
+allClosures (SelectorClosure {..}) = [selectee]
+allClosures (IndClosure {..}) = [indirectee]
+allClosures (BlackholeClosure {..}) = [indirectee]
+allClosures (APClosure {..}) = fun:payload
+allClosures (PAPClosure {..}) = fun:payload
+allClosures (APStackClosure {..}) = fun:payload
+allClosures (BCOClosure {..}) = [instrs,literals,bcoptrs]
+allClosures (ArrWordsClosure {}) = []
+allClosures (MutArrClosure {..}) = mccPayload
+allClosures (SmallMutArrClosure {..}) = mccPayload
+allClosures (MutVarClosure {..}) = [var]
+allClosures (MVarClosure {..}) = [queueHead,queueTail,value]
+allClosures (FunClosure {..}) = ptrArgs
+allClosures (BlockingQueueClosure {..}) = [link, blackHole, owner, queue]
+allClosures (WeakClosure {..}) = [cfinalizers, key, value, finalizer] ++ GHC.Internal.Data.Foldable.toList weakLink
+allClosures (OtherClosure {..}) = hvalues
+allClosures _ = []
+
+-- | Get the size of the top-level closure in words.
+-- Includes header and payload. Does not follow pointers.
+--
+-- @since 8.10.1
+closureSize :: Box -> Int
+closureSize (Box x) = I# (closureSize# x)
diff --git a/src/GHC/Internal/Heap/Constants.hsc b/src/GHC/Internal/Heap/Constants.hsc
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Heap/Constants.hsc
@@ -0,0 +1,18 @@
+{-# LANGUAGE CPP #-}
+
+module GHC.Internal.Heap.Constants
+    ( wORD_SIZE
+    , tAG_MASK
+    , wORD_SIZE_IN_BITS
+    ) where
+
+#include "MachDeps.h"
+
+import GHC.Internal.Data.Bits
+import GHC.Internal.Int
+import GHC.Internal.Num
+
+wORD_SIZE, tAG_MASK, wORD_SIZE_IN_BITS :: Int
+wORD_SIZE = #const SIZEOF_HSWORD
+wORD_SIZE_IN_BITS = #const WORD_SIZE_IN_BITS
+tAG_MASK = (1 `shift` #const TAG_BITS) - 1
diff --git a/src/GHC/Internal/Heap/InfoTable.hsc b/src/GHC/Internal/Heap/InfoTable.hsc
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Heap/InfoTable.hsc
@@ -0,0 +1,82 @@
+module GHC.Internal.Heap.InfoTable
+    ( module GHC.Internal.Heap.InfoTable.Types
+    , itblSize
+    , peekItbl
+    , pokeItbl
+    ) where
+
+#include "Rts.h"
+
+import GHC.Internal.Base
+import GHC.Internal.Real
+import GHC.Internal.Enum
+
+import GHC.Internal.Heap.InfoTable.Types
+#if !defined(TABLES_NEXT_TO_CODE)
+import GHC.Internal.Heap.Constants
+import GHC.Internal.Data.Functor ((<$>))
+import GHC.Internal.Data.Maybe
+import GHC.Internal.Num (negate)
+#else
+import GHC.Internal.Data.Either
+import GHC.Internal.Foreign.Marshal.Array
+#endif
+import GHC.Internal.Foreign.Ptr
+import GHC.Internal.Foreign.Storable
+
+-------------------------------------------------------------------------
+-- Profiling specific code
+--
+-- The functions that follow all rely on PROFILING. They are duplicated in
+-- ghc-heap/GHC/Exts/Heap/InfoTableProf.hsc where PROFILING is defined. This
+-- allows hsc2hs to generate values for both profiling and non-profiling builds.
+
+-- | Read an InfoTable from the heap into a haskell type.
+-- WARNING: This code assumes it is passed a pointer to a "standard" info
+-- table. If tables_next_to_code is disabled, it will look 1 word before the
+-- start for the entry field.
+peekItbl :: Ptr StgInfoTable -> IO StgInfoTable
+peekItbl a0 = do
+#if !defined(TABLES_NEXT_TO_CODE)
+  let ptr = a0 `plusPtr` (negate wORD_SIZE)
+  entry' <- Just <$> (#peek struct StgInfoTable_, entry) ptr
+#else
+  let ptr = a0
+      entry' = Nothing
+#endif
+  ptrs'   <- (#peek struct StgInfoTable_, layout.payload.ptrs) ptr
+  nptrs'  <- (#peek struct StgInfoTable_, layout.payload.nptrs) ptr
+  tipe'   <- (#peek struct StgInfoTable_, type) ptr
+  srtlen' <- (#peek struct StgInfoTable_, srt) a0
+  return StgInfoTable
+    { entry  = entry'
+    , ptrs   = ptrs'
+    , nptrs  = nptrs'
+    , tipe   = toEnum (fromIntegral (tipe' :: HalfWord))
+    , srtlen = srtlen'
+    , code   = Nothing
+    }
+
+pokeItbl :: Ptr StgInfoTable -> StgInfoTable -> IO ()
+pokeItbl a0 itbl = do
+#if !defined(TABLES_NEXT_TO_CODE)
+  (#poke StgInfoTable, entry) a0 (fromJust (entry itbl))
+#endif
+  (#poke StgInfoTable, layout.payload.ptrs) a0 (ptrs itbl)
+  (#poke StgInfoTable, layout.payload.nptrs) a0 (nptrs itbl)
+  (#poke StgInfoTable, type) a0 (toHalfWord (fromEnum (tipe itbl)))
+  (#poke StgInfoTable, srt) a0 (srtlen itbl)
+#if defined(TABLES_NEXT_TO_CODE)
+  let code_offset = a0 `plusPtr` (#offset StgInfoTable, code)
+  case code itbl of
+    Nothing -> return ()
+    Just (Left xs) -> pokeArray code_offset xs
+    Just (Right xs) -> pokeArray code_offset xs
+#endif
+  where
+    toHalfWord :: Int -> HalfWord
+    toHalfWord i = fromIntegral i
+
+-- | Size in bytes of a standard InfoTable
+itblSize :: Int
+itblSize = (#size struct StgInfoTable_)
diff --git a/src/GHC/Internal/Heap/InfoTable/Types.hsc b/src/GHC/Internal/Heap/InfoTable/Types.hsc
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Heap/InfoTable/Types.hsc
@@ -0,0 +1,53 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module GHC.Internal.Heap.InfoTable.Types
+    ( StgInfoTable(..)
+    , EntryFunPtr
+    , HalfWord(..)
+    , ItblCodes
+    ) where
+
+#include "Rts.h"
+
+import GHC.Internal.Base
+import GHC.Internal.Generics
+import GHC.Internal.ClosureTypes
+import GHC.Internal.Foreign.Ptr
+import GHC.Internal.Foreign.Storable
+import GHC.Internal.Enum
+import GHC.Internal.Num
+import GHC.Internal.Word
+import GHC.Internal.Show
+import GHC.Internal.Real
+import GHC.Internal.Data.Either
+
+type ItblCodes = Either [Word8] [Word32]
+
+#include "ghcautoconf.h"
+-- Ultra-minimalist version specially for constructors
+#if SIZEOF_VOID_P == 8
+type HalfWord' = Word32
+#elif SIZEOF_VOID_P == 4
+type HalfWord' = Word16
+#else
+#error Unknown SIZEOF_VOID_P
+#endif
+
+newtype HalfWord = HalfWord HalfWord'
+    deriving newtype (Enum, Eq, Integral, Num, Ord, Real, Show, Storable)
+
+type EntryFunPtr = FunPtr (Ptr () -> IO (Ptr ()))
+
+-- | This is a somewhat faithful representation of an info table. See
+-- <https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/storage/InfoTables.h>
+-- for more details on this data structure.
+data StgInfoTable = StgInfoTable {
+   entry  :: Maybe EntryFunPtr, -- Just <=> not TABLES_NEXT_TO_CODE
+   ptrs   :: HalfWord,
+   nptrs  :: HalfWord,
+   tipe   :: ClosureType,
+   srtlen :: HalfWord,
+   code   :: Maybe ItblCodes -- Just <=> TABLES_NEXT_TO_CODE
+  } deriving (Eq, Show, Generic)
diff --git a/src/GHC/Internal/Heap/InfoTableProf.hsc b/src/GHC/Internal/Heap/InfoTableProf.hsc
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Heap/InfoTableProf.hsc
@@ -0,0 +1,75 @@
+module GHC.Internal.Heap.InfoTableProf
+    ( module GHC.Internal.Heap.InfoTable.Types
+    , itblSize
+    , peekItbl
+    , pokeItbl
+    ) where
+
+-- This file overrides InfoTable.hsc's implementation of peekItbl and pokeItbl.
+-- Manually defining PROFILING gives the #peek and #poke macros an accurate
+-- representation of StgInfoTable_ when hsc2hs runs.
+#define PROFILING
+#include "Rts.h"
+
+import GHC.Internal.Base
+import GHC.Internal.Real
+import GHC.Internal.Enum
+
+import GHC.Internal.Heap.InfoTable.Types
+#if !defined(TABLES_NEXT_TO_CODE)
+import GHC.Internal.Heap.Constants
+import GHC.Internal.Data.Functor ((<$>))
+import GHC.Internal.Data.Maybe
+import GHC.Internal.Num (negate)
+#else
+import GHC.Internal.Data.Either
+import GHC.Internal.Foreign.Marshal.Array
+#endif
+import GHC.Internal.Foreign.Ptr
+import GHC.Internal.Foreign.Storable
+
+-- | Read an InfoTable from the heap into a haskell type.
+-- WARNING: This code assumes it is passed a pointer to a "standard" info
+-- table. If tables_next_to_code is enabled, it will look 1 byte before the
+-- start for the entry field.
+peekItbl :: Ptr StgInfoTable -> IO StgInfoTable
+peekItbl a0 = do
+#if !defined(TABLES_NEXT_TO_CODE)
+  let ptr = a0 `plusPtr` (negate wORD_SIZE)
+  entry' <- Just <$> (#peek struct StgInfoTable_, entry) ptr
+#else
+  let ptr = a0
+      entry' = Nothing
+#endif
+  ptrs'   <- (#peek struct StgInfoTable_, layout.payload.ptrs) ptr
+  nptrs'  <- (#peek struct StgInfoTable_, layout.payload.nptrs) ptr
+  tipe'   <- (#peek struct StgInfoTable_, type) ptr
+  srtlen' <- (#peek struct StgInfoTable_, srt) a0
+  return StgInfoTable
+    { entry  = entry'
+    , ptrs   = ptrs'
+    , nptrs  = nptrs'
+    , tipe   = toEnum (fromIntegral (tipe' :: HalfWord))
+    , srtlen = srtlen'
+    , code   = Nothing
+    }
+
+pokeItbl :: Ptr StgInfoTable -> StgInfoTable -> IO ()
+pokeItbl a0 itbl = do
+#if !defined(TABLES_NEXT_TO_CODE)
+  (#poke StgInfoTable, entry) a0 (fromJust (entry itbl))
+#endif
+  (#poke StgInfoTable, layout.payload.ptrs) a0 (ptrs itbl)
+  (#poke StgInfoTable, layout.payload.nptrs) a0 (nptrs itbl)
+  (#poke StgInfoTable, type) a0 (fromEnum (tipe itbl))
+  (#poke StgInfoTable, srt) a0 (srtlen itbl)
+#if defined(TABLES_NEXT_TO_CODE)
+  let code_offset = a0 `plusPtr` (#offset StgInfoTable, code)
+  case code itbl of
+    Nothing -> return ()
+    Just (Left xs) -> pokeArray code_offset xs
+    Just (Right xs) -> pokeArray code_offset xs
+#endif
+
+itblSize :: Int
+itblSize = (#size struct StgInfoTable_)
diff --git a/src/GHC/Internal/Heap/ProfInfo/Types.hs b/src/GHC/Internal/Heap/ProfInfo/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Heap/ProfInfo/Types.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE DeriveGeneric #-}
+
+module GHC.Internal.Heap.ProfInfo.Types where
+
+import GHC.Internal.Base
+import GHC.Internal.Word
+import GHC.Internal.Generics
+import GHC.Internal.Show
+
+-- | This is a somewhat faithful representation of StgTSOProfInfo. See
+-- <https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/storage/TSO.h>
+-- for more details on this data structure.
+newtype StgTSOProfInfo = StgTSOProfInfo {
+    cccs :: Maybe CostCentreStack
+} deriving (Show, Generic, Eq, Ord)
+
+-- | This is a somewhat faithful representation of CostCentreStack. See
+-- <https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/prof/CCS.h>
+-- for more details on this data structure.
+data CostCentreStack = CostCentreStack {
+    ccs_ccsID :: Int,
+    ccs_cc :: CostCentre,
+    ccs_prevStack :: Maybe CostCentreStack,
+    ccs_indexTable :: Maybe IndexTable,
+    ccs_root :: Maybe CostCentreStack,
+    ccs_depth :: Word,
+    ccs_scc_count :: Word64,
+    ccs_selected :: Word,
+    ccs_time_ticks :: Word,
+    ccs_mem_alloc :: Word64,
+    ccs_inherited_alloc :: Word64,
+    ccs_inherited_ticks :: Word
+} deriving (Show, Generic, Eq, Ord)
+
+-- | This is a somewhat faithful representation of CostCentre. See
+-- <https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/prof/CCS.h>
+-- for more details on this data structure.
+data CostCentre = CostCentre {
+    cc_ccID :: Int,
+    cc_label :: String,
+    cc_module :: String,
+    cc_srcloc :: Maybe String,
+    cc_mem_alloc :: Word64,
+    cc_time_ticks :: Word,
+    cc_is_caf :: Bool,
+    cc_link :: Maybe CostCentre
+} deriving (Show, Generic, Eq, Ord)
+
+-- | This is a somewhat faithful representation of IndexTable. See
+-- <https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/prof/CCS.h>
+-- for more details on this data structure.
+data IndexTable = IndexTable {
+    it_cc :: CostCentre,
+    it_ccs :: Maybe CostCentreStack,
+    it_next :: Maybe IndexTable,
+    it_back_edge :: Bool
+} deriving (Show, Generic, Eq, Ord)
diff --git a/src/GHC/Internal/IO.hs b/src/GHC/Internal/IO.hs
--- a/src/GHC/Internal/IO.hs
+++ b/src/GHC/Internal/IO.hs
@@ -235,7 +235,7 @@
 -- | Execute an 'IO' action, adding the given 'ExceptionContext'
 -- to any thrown synchronous exceptions.
 --
--- @since base-2.20.0.0
+-- @since base-4.20.0.0
 annotateIO :: forall e a. ExceptionAnnotation e => e -> IO a -> IO a
 annotateIO ann (IO io) = IO (catch# io handler)
   where
diff --git a/src/GHC/Internal/IO.hs-boot b/src/GHC/Internal/IO.hs-boot
--- a/src/GHC/Internal/IO.hs-boot
+++ b/src/GHC/Internal/IO.hs-boot
@@ -3,8 +3,10 @@
 
 module GHC.Internal.IO where
 
-import GHC.Types
-import {-# SOURCE #-} GHC.Internal.Exception.Type (SomeException)
+import GHC.Internal.Stack.Types (HasCallStack)
+import GHC.Internal.Types
+import {-# SOURCE #-} GHC.Internal.Exception.Type (Exception, SomeException)
 
 mplusIO :: IO a -> IO a -> IO a
 mkUserError :: [Char] -> SomeException
+throwIO :: (HasCallStack, Exception e) => e -> IO a
diff --git a/src/GHC/Internal/IO/Buffer.hs b/src/GHC/Internal/IO/Buffer.hs
--- a/src/GHC/Internal/IO/Buffer.hs
+++ b/src/GHC/Internal/IO/Buffer.hs
@@ -223,10 +223,10 @@
   deriving Eq -- ^ @since base-4.2.0.0
 
 withBuffer :: Buffer e -> (Ptr e -> IO a) -> IO a
-withBuffer Buffer{ bufRaw=raw } f = withForeignPtr (castForeignPtr raw) f
+withBuffer Buffer{ bufRaw=raw } f = unsafeWithForeignPtr (castForeignPtr raw) f
 
 withRawBuffer :: RawBuffer e -> (Ptr e -> IO a) -> IO a
-withRawBuffer raw f = withForeignPtr (castForeignPtr raw) f
+withRawBuffer raw f = unsafeWithForeignPtr (castForeignPtr raw) f
 
 isEmptyBuffer :: Buffer e -> Bool
 isEmptyBuffer Buffer{ bufL=l, bufR=r } = l == r
diff --git a/src/GHC/Internal/IO/Encoding/CodePage.hs b/src/GHC/Internal/IO/Encoding/CodePage.hs
--- a/src/GHC/Internal/IO/Encoding/CodePage.hs
+++ b/src/GHC/Internal/IO/Encoding/CodePage.hs
@@ -16,7 +16,7 @@
 #if !defined(mingw32_HOST_OS)
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 
 #else
 import GHC.Internal.Base
diff --git a/src/GHC/Internal/IO/Encoding/CodePage/Table.hs b/src/GHC/Internal/IO/Encoding/CodePage/Table.hs
--- a/src/GHC/Internal/IO/Encoding/CodePage/Table.hs
+++ b/src/GHC/Internal/IO/Encoding/CodePage/Table.hs
@@ -35,7 +35,7 @@
 -- CP875.TXT
 module GHC.Internal.IO.Encoding.CodePage.Table where
 
-import GHC.Prim
+import GHC.Internal.Prim
 import GHC.Internal.Base
 import GHC.Internal.Word
 data ConvArray a = ConvArray Addr#
diff --git a/src/GHC/Internal/IO/Encoding/Iconv.hs b/src/GHC/Internal/IO/Encoding/Iconv.hs
--- a/src/GHC/Internal/IO/Encoding/Iconv.hs
+++ b/src/GHC/Internal/IO/Encoding/Iconv.hs
@@ -34,7 +34,7 @@
 #if defined(mingw32_HOST_OS)
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 
 #else
 
diff --git a/src/GHC/Internal/IO/Exception.hs b/src/GHC/Internal/IO/Exception.hs
--- a/src/GHC/Internal/IO/Exception.hs
+++ b/src/GHC/Internal/IO/Exception.hs
@@ -187,7 +187,8 @@
     showsPrec p (SomeAsyncException e) = showsPrec p e
 
 -- | @since base-4.7.0.0
-instance Exception SomeAsyncException
+instance Exception SomeAsyncException where
+    displayException (SomeAsyncException e) = displayException e
 
 -- | @since base-4.7.0.0
 asyncExceptionToException :: Exception e => e -> SomeException
@@ -438,6 +439,7 @@
          _  -> showString " (" . showString s . showString ")")
 
 assertError :: (?callStack :: CallStack) => Bool -> a -> a
+-- See Note [Overview of assertions] in GHC.Tc.Gen.Head
 assertError predicate v
   | predicate = v
   | otherwise = lazy $ unsafeDupablePerformIO $ do -- lazy: See Note [Strictness of assertError]
diff --git a/src/GHC/Internal/IO/Exception.hs-boot b/src/GHC/Internal/IO/Exception.hs-boot
--- a/src/GHC/Internal/IO/Exception.hs-boot
+++ b/src/GHC/Internal/IO/Exception.hs-boot
@@ -4,7 +4,7 @@
 module GHC.Internal.IO.Exception where
 
 import GHC.Internal.Base
-import GHC.Internal.Exception
+import {-# SOURCE #-} GHC.Internal.Exception.Type
 
 data IOException
 instance Exception IOException
diff --git a/src/GHC/Internal/IO/Handle/FD.hs b/src/GHC/Internal/IO/Handle/FD.hs
--- a/src/GHC/Internal/IO/Handle/FD.hs
+++ b/src/GHC/Internal/IO/Handle/FD.hs
@@ -368,11 +368,11 @@
   mkHandleFromFD fd fd_type filepath iomode is_socket enc
 
 
--- | Turn an existing file descriptor into a Handle.  This is used by
+-- | Turn an existing file descriptor into a 'Handle'.  This is used by
 -- various external libraries to make Handles.
 --
--- Makes a binary Handle.  This is for historical reasons; it should
--- probably be a text Handle with the default encoding and newline
+-- Makes a binary 'Handle'.  This is for historical reasons; it should
+-- probably be a text 'Handle' with the default encoding and newline
 -- translation instead.
 fdToHandle :: Posix.FD -> IO Handle
 fdToHandle fdint = do
@@ -389,8 +389,8 @@
    mkHandleFromFD fd fd_type fd_str iomode False{-non-block-}
                   Nothing -- bin mode
 
--- | Turn an existing Handle into a file descriptor. This function throws an
--- IOError if the Handle does not reference a file descriptor.
+-- | Turn an existing 'Handle' into a file descriptor. This function throws an
+-- 'IOError' if the 'Handle' does not reference a file descriptor.
 --
 -- @since base-4.10.0.0
 handleToFd :: Handle -> IO FD.FD
diff --git a/src/GHC/Internal/IO/Handle/Lock.hs b/src/GHC/Internal/IO/Handle/Lock.hs
--- a/src/GHC/Internal/IO/Handle/Lock.hs
+++ b/src/GHC/Internal/IO/Handle/Lock.hs
@@ -35,14 +35,20 @@
 --
 -- Things to be aware of:
 --
--- 1) This function may block inside a C call. If it does, in order to be able
+-- 1. This function may block inside a C call. If it does, in order to be able
 -- to interrupt it with asynchronous exceptions and/or for other threads to
 -- continue working, you MUST use threaded version of the runtime system.
 --
--- 2) The implementation uses 'LockFileEx' on Windows and 'flock' otherwise,
+-- 2. The implementation uses relies on any of a number of locking
+-- facilities, depending upon what the platform supports:
+--
+--   * 'LockFileEx' is used on Windows
+--   * On platforms that support it we use the @F_OFD_SETLK@ and @F_OFD_SETLKW@ @fnctl@s.
+--   * Otherwise we use @flock@
+--
 -- hence all of their caveats also apply here.
 --
--- 3) On non-Windows platforms that don't support 'flock' (e.g. Solaris) this
+-- 3. On non-Windows platforms that don't support 'flock' (e.g. Solaris) this
 -- function throws 'FileLockingNotImplemented'. We deliberately choose to not
 -- provide fcntl based locking instead because of its broken semantics.
 --
diff --git a/src/GHC/Internal/IO/Handle/Lock/Flock.hsc b/src/GHC/Internal/IO/Handle/Lock/Flock.hsc
--- a/src/GHC/Internal/IO/Handle/Lock/Flock.hsc
+++ b/src/GHC/Internal/IO/Handle/Lock/Flock.hsc
@@ -11,7 +11,7 @@
 
 #if !HAVE_FLOCK
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 #else
 
 #include <sys/file.h>
diff --git a/src/GHC/Internal/IO/Handle/Lock/LinuxOFD.hsc b/src/GHC/Internal/IO/Handle/Lock/LinuxOFD.hsc
--- a/src/GHC/Internal/IO/Handle/Lock/LinuxOFD.hsc
+++ b/src/GHC/Internal/IO/Handle/Lock/LinuxOFD.hsc
@@ -11,7 +11,7 @@
 
 #if !HAVE_OFD_LOCKING
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 #else
 
 -- Not only is this a good idea but it also works around #17950.
diff --git a/src/GHC/Internal/IO/Handle/Lock/Windows.hsc b/src/GHC/Internal/IO/Handle/Lock/Windows.hsc
--- a/src/GHC/Internal/IO/Handle/Lock/Windows.hsc
+++ b/src/GHC/Internal/IO/Handle/Lock/Windows.hsc
@@ -11,7 +11,7 @@
 
 #if !defined(mingw32_HOST_OS)
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 #else
 
 #include <windows.h>
diff --git a/src/GHC/Internal/IO/Handle/Types.hs-boot b/src/GHC/Internal/IO/Handle/Types.hs-boot
--- a/src/GHC/Internal/IO/Handle/Types.hs-boot
+++ b/src/GHC/Internal/IO/Handle/Types.hs-boot
@@ -3,6 +3,6 @@
 module GHC.Internal.IO.Handle.Types ( Handle ) where
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 
 data Handle
diff --git a/src/GHC/Internal/IO/Windows/Handle.hsc b/src/GHC/Internal/IO/Windows/Handle.hsc
--- a/src/GHC/Internal/IO/Windows/Handle.hsc
+++ b/src/GHC/Internal/IO/Windows/Handle.hsc
@@ -77,7 +77,7 @@
 import GHC.Internal.IO.Windows.Paths (getDevicePath)
 import GHC.Internal.IO.Handle.Internals (debugIO)
 import GHC.Internal.IORef
-import GHC.Internal.Event.Windows (LPOVERLAPPED, withOverlappedEx, IOResult(..))
+import GHC.Internal.Event.Windows (LPOVERLAPPED, withOverlappedEx)
 import GHC.Internal.Foreign.Ptr
 import GHC.Internal.Foreign.C.Types
 import GHC.Internal.Foreign.C.Error
@@ -465,10 +465,10 @@
                     -> IO (Maybe Int)
 hwndReadNonBlocking hwnd ptr offset bytes
   = do mngr <- Mgr.getSystemManager
-       val <- withOverlappedEx mngr "hwndReadNonBlocking" (toHANDLE hwnd)
+       Mgr.withException "hwndReadNonBlocking" $
+              withOverlappedEx mngr "hwndReadNonBlocking" (toHANDLE hwnd)
                                (isAsynchronous hwnd) offset (startCB ptr)
                                completionCB
-       return $ ioValue val
   where
     startCB inputBuf lpOverlapped = do
       debugIO ":: hwndReadNonBlocking"
@@ -511,10 +511,11 @@
 hwndWriteNonBlocking :: Io NativeHandle -> Ptr Word8 -> Word64 -> Int -> IO Int
 hwndWriteNonBlocking hwnd ptr offset bytes
   = do mngr <- Mgr.getSystemManager
-       val <- withOverlappedEx mngr "hwndReadNonBlocking" (toHANDLE hwnd)
-                               (isAsynchronous hwnd) offset (startCB ptr)
-                               completionCB
-       return $ fromIntegral $ ioValue val
+       fmap fromIntegral $
+           Mgr.withException "hwndWriteNonBlocking" $
+           withOverlappedEx mngr "hwndWriteNonBlocking" (toHANDLE hwnd)
+                            (isAsynchronous hwnd) offset (startCB ptr)
+                            completionCB
   where
     startCB :: Ptr a -> LPOVERLAPPED -> IO (Mgr.CbResult a1)
     startCB outBuf lpOverlapped = do
@@ -932,8 +933,7 @@
                -- handle.   For WinIO we always use FILE_FLAG_OVERLAPPED, which
                -- means we always issue asynchronous file operation using an
                -- OVERLAPPED structure.  All blocking, if required must be done
-               -- on the Haskell side by using existing mechanisms such as MVar
-               -- or IOPorts.
+               -- on the Haskell side by using existing mechanisms such as MVars.
                then #{const FILE_FLAG_OVERLAPPED}
                     -- I believe most haskell programs do sequential scans, so
                     -- optimize for the common case.  Though ideally, this would
diff --git a/src/GHC/Internal/IOPort.hs b/src/GHC/Internal/IOPort.hs
deleted file mode 100644
--- a/src/GHC/Internal/IOPort.hs
+++ /dev/null
@@ -1,128 +0,0 @@
-{-# LANGUAGE Unsafe #-}
-{-# LANGUAGE NoImplicitPrelude, MagicHash, UnboxedTuples #-}
-{-# OPTIONS_GHC -funbox-strict-fields #-}
-{-# OPTIONS_HADDOCK hide #-}
-
------------------------------------------------------------------------------
--- |
--- Module      :  GHC.Internal.IOPort
--- Copyright   :  (c) Tamar Christina 2019
--- License     :  see libraries/base/LICENSE
---
--- Maintainer  :  ghc-devs@haskell.org
--- Stability   :  internal
--- Portability :  non-portable (GHC Extensions)
---
--- The 'IOPort' type. This is a facility used by the Windows IO subsystem.
---
--- /The API of this module is unstable and not meant to be consumed by the general public./
--- If you absolutely must depend on it, make sure to use a tight upper
--- bound, e.g., @base < 4.X@ rather than @base < 5@, because the interface can
--- change rapidly without much warning.
---
--- We have strict rules with an I/O Port:
--- * writing more than once is an error
--- * reading more than once is an error
---
--- It gives us the ability to have one thread to block, wait for a result from
--- another thread and then being woken up. *Nothing* more.
---
--- This type is very much GHC internal. It might be changed or removed without
--- notice in future releases.
---
------------------------------------------------------------------------------
-
-module GHC.Internal.IOPort (
-        -- * IOPorts
-          IOPort(..)
-        , newIOPort
-        , newEmptyIOPort
-        , readIOPort
-        , writeIOPort
-        , doubleReadException
-    ) where
-
-import GHC.Internal.Base
-import GHC.Internal.Exception
-import GHC.Internal.Text.Show
-
-data IOPortException = IOPortException deriving Show
-
-instance Exception IOPortException where
-    displayException IOPortException = "IOPortException"
-
-
-doubleReadException :: SomeException
-doubleReadException = toException IOPortException
-
-data IOPort a = IOPort (IOPort# RealWorld a)
-{- ^
-An 'IOPort' is a synchronising variable, used
-for communication between concurrent threads, where one of the threads is
-controlled by an external state. e.g. by an I/O action that is serviced by the
-runtime.  It can be thought of as a box, which may be empty or full.
-
-It is mostly similar to the behavior of 'Control.Concurrent.MVar.MVar'
-except 'writeIOPort' doesn't block if the variable is full and the GC
-won't forcibly release the lock if it thinks
-there's a deadlock.
-
-The properties of IOPorts are:
-* Writing to an empty IOPort will not block.
-* Writing to an full  IOPort will not block. It might throw an exception.
-* Reading from an IOPort for the second time might throw an exception.
-* Reading from a full IOPort will not block, return the value and empty the port.
-* Reading from an empty IOPort will block until a write.
-* Reusing an IOPort (that is, reading or writing twice) is not supported
-  and might throw an exception. Even if reads and writes are
-  interleaved.
-
-This type is very much GHC internal. It might be changed or removed without
-notice in future releases.
-
--}
-
--- | @since base-4.1.0.0
-instance Eq (IOPort a) where
-        (IOPort ioport1#) == (IOPort ioport2#) =
-            isTrue# (sameIOPort# ioport1# ioport2#)
-
-
-
--- |Create an 'IOPort' which is initially empty.
-newEmptyIOPort  :: IO (IOPort a)
-newEmptyIOPort = IO $ \ s# ->
-    case newIOPort# s# of
-         (# s2#, svar# #) -> (# s2#, IOPort svar# #)
-
--- |Create an 'IOPort' which contains the supplied value.
-newIOPort :: a -> IO (IOPort a)
-newIOPort value =
-    newEmptyIOPort        >>= \ ioport ->
-    writeIOPort ioport value  >>
-    return ioport
-
--- |Atomically read the contents of the 'IOPort'.  If the 'IOPort' is
--- currently empty, 'readIOPort' will wait until it is full.  After a
--- 'readIOPort', the 'IOPort' is left empty.
---
--- There is one important property of 'readIOPort':
---
---   * Only a single threads can be blocked on an 'IOPort'.
---
-readIOPort :: IOPort a -> IO a
-readIOPort (IOPort ioport#) = IO $ \ s# -> readIOPort# ioport# s#
-
--- |Put a value into an 'IOPort'.  If the 'IOPort' is currently full,
--- 'writeIOPort' will throw an exception.
---
--- There is one important property of 'writeIOPort':
---
---   * Only a single thread can be blocked on an 'IOPort'.
---
-writeIOPort  :: IOPort a -> a -> IO Bool
-writeIOPort (IOPort ioport#) x = IO $ \ s# ->
-    case writeIOPort# ioport# x s# of
-        (# s, 0# #) -> (# s, False #)
-        (# s, _  #) -> (# s, True #)
-
diff --git a/src/GHC/Internal/InfoProv/Types.hsc b/src/GHC/Internal/InfoProv/Types.hsc
--- a/src/GHC/Internal/InfoProv/Types.hsc
+++ b/src/GHC/Internal/InfoProv/Types.hsc
@@ -29,7 +29,7 @@
 import GHC.Internal.IO.Encoding (utf8)
 import GHC.Internal.Foreign.Storable (peekByteOff)
 import GHC.Internal.ClosureTypes
-import GHC.Prim (whereFrom##)
+import GHC.Internal.Prim (whereFrom##)
 
 data InfoProv = InfoProv {
   ipName :: String,
diff --git a/src/GHC/Internal/Int.hs b/src/GHC/Internal/Int.hs
--- a/src/GHC/Internal/Int.hs
+++ b/src/GHC/Internal/Int.hs
@@ -30,7 +30,7 @@
         shiftRLInt8#, shiftRLInt16#, shiftRLInt32#,
 
         -- * Equality operators
-        -- | See GHC.Classes#matching_overloaded_methods_in_rules
+        -- | See GHC.Internal.Classes#matching_overloaded_methods_in_rules
         eqInt, neInt, gtInt, geInt, ltInt, leInt,
         eqInt8, neInt8, gtInt8, geInt8, ltInt8, leInt8,
         eqInt16, neInt16, gtInt16, geInt16, ltInt16, leInt16,
@@ -42,7 +42,7 @@
 import GHC.Internal.Data.Bits
 import GHC.Internal.Data.Maybe
 
-import GHC.Prim
+import GHC.Internal.Prim
 import GHC.Internal.Base
 
 import GHC.Internal.Enum
@@ -62,7 +62,7 @@
 data {-# CTYPE "HsInt8" #-} Int8 = I8# Int8#
 -- ^ 8-bit signed integer type
 
--- See GHC.Classes#matching_overloaded_methods_in_rules
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
 -- | @since base-2.01
 instance Eq Int8 where
     (==) = eqInt8
@@ -273,7 +273,7 @@
 data {-# CTYPE "HsInt16" #-} Int16 = I16# Int16#
 -- ^ 16-bit signed integer type
 
--- See GHC.Classes#matching_overloaded_methods_in_rules
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
 -- | @since base-2.01
 instance Eq Int16 where
     (==) = eqInt16
@@ -481,7 +481,7 @@
 data {-# CTYPE "HsInt32" #-} Int32 = I32# Int32#
 -- ^ 32-bit signed integer type
 
--- See GHC.Classes#matching_overloaded_methods_in_rules
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
 -- | @since base-2.01
 instance Eq Int32 where
     (==) = eqInt32
@@ -694,7 +694,7 @@
 data {-# CTYPE "HsInt64" #-} Int64 = I64# Int64#
 -- ^ 64-bit signed integer type
 
--- See GHC.Classes#matching_overloaded_methods_in_rules
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
 -- | @since base-2.01
 instance Eq Int64 where
     (==) = eqInt64
diff --git a/src/GHC/Internal/Integer.hs b/src/GHC/Internal/Integer.hs
--- a/src/GHC/Internal/Integer.hs
+++ b/src/GHC/Internal/Integer.hs
@@ -57,10 +57,10 @@
     hashInteger,
     ) where
 
-import GHC.Num.Integer (Integer)
-import qualified GHC.Num.Integer as I
-import GHC.Prim
-import GHC.Types
+import GHC.Internal.Bignum.Integer (Integer)
+import qualified GHC.Internal.Bignum.Integer as I
+import GHC.Internal.Prim
+import GHC.Internal.Types
 
 smallInteger :: Int# -> Integer
 smallInteger = I.integerFromInt#
diff --git a/src/GHC/Internal/Integer/Logarithms.hs b/src/GHC/Internal/Integer/Logarithms.hs
--- a/src/GHC/Internal/Integer/Logarithms.hs
+++ b/src/GHC/Internal/Integer/Logarithms.hs
@@ -9,10 +9,10 @@
    )
 where
 
-import qualified GHC.Num.Primitives as N
-import qualified GHC.Num.Integer    as N
-import GHC.Num.Integer (Integer)
-import GHC.Prim
+import qualified GHC.Internal.Bignum.Primitives as N
+import qualified GHC.Internal.Bignum.Integer    as N
+import GHC.Internal.Bignum.Integer (Integer)
+import GHC.Internal.Prim
 
 wordLog2# :: Word# -> Int#
 wordLog2# i = word2Int# (N.wordLog2# i)
diff --git a/src/GHC/Internal/IsList.hs b/src/GHC/Internal/IsList.hs
--- a/src/GHC/Internal/IsList.hs
+++ b/src/GHC/Internal/IsList.hs
@@ -69,7 +69,7 @@
   fromList (a:as) = a :| as
   fromList [] = errorWithoutStackTrace "NonEmpty.fromList: empty list"
 
-  toList ~(a :| as) = a : as
+  toList (a :| as) = a : as
 
 -- | @since base-4.8.0.0
 instance IsList Version where
diff --git a/src/GHC/Internal/Ix.hs b/src/GHC/Internal/Ix.hs
--- a/src/GHC/Internal/Ix.hs
+++ b/src/GHC/Internal/Ix.hs
@@ -25,7 +25,7 @@
 import GHC.Internal.Base
 import GHC.Internal.Real( fromIntegral )
 import GHC.Internal.Show
-import GHC.Tuple (Solo (..))
+import GHC.Internal.Tuple (Solo (..))
 
 -- | The 'Ix' class is used to map a contiguous subrange of values in
 -- a type onto integers.  It is used primarily for array indexing
diff --git a/src/GHC/Internal/JS/Prim.hs b/src/GHC/Internal/JS/Prim.hs
--- a/src/GHC/Internal/JS/Prim.hs
+++ b/src/GHC/Internal/JS/Prim.hs
@@ -41,10 +41,10 @@
 
 import           GHC.Internal.Unsafe.Coerce (unsafeCoerce)
 
-import           GHC.Prim
+import           GHC.Internal.Prim
 import qualified GHC.Internal.Exception as Ex
 import qualified GHC.Internal.Exts as Exts
-import qualified GHC.CString as GHC
+import qualified GHC.Internal.CString as GHC
 import           GHC.Internal.IO
 import           GHC.Internal.Data.Bool
 import           GHC.Internal.Base
diff --git a/src/GHC/Internal/JS/Prim/Internal/Build.hs b/src/GHC/Internal/JS/Prim/Internal/Build.hs
--- a/src/GHC/Internal/JS/Prim/Internal/Build.hs
+++ b/src/GHC/Internal/JS/Prim/Internal/Build.hs
@@ -5,7 +5,7 @@
 module GHC.Internal.JS.Prim.Internal.Build () where
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
+import GHC.Internal.Types ()
 
 #else
 {-# LANGUAGE ForeignFunctionInterface, JavaScriptFFI, GHCForeignImportPrim #-}
diff --git a/src/GHC/Internal/LanguageExtensions.hs b/src/GHC/Internal/LanguageExtensions.hs
--- a/src/GHC/Internal/LanguageExtensions.hs
+++ b/src/GHC/Internal/LanguageExtensions.hs
@@ -165,6 +165,8 @@
    | ExtendedLiterals
    | ListTuplePuns
    | MultilineStrings
+   | ExplicitLevelImports
+   | ImplicitStagePersistence
    deriving (Eq, Enum, Show, Generic, Bounded)
 -- 'Ord' and 'Bounded' are provided for GHC API users (see discussions
 -- in https://gitlab.haskell.org/ghc/ghc/merge_requests/2707 and
diff --git a/src/GHC/Internal/List.hs b/src/GHC/Internal/List.hs
--- a/src/GHC/Internal/List.hs
+++ b/src/GHC/Internal/List.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE CPP, NoImplicitPrelude, ScopedTypeVariables #-}
+{-# LANGUAGE NoImplicitPrelude, ScopedTypeVariables #-}
 {-# LANGUAGE BangPatterns #-}
 {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
 
@@ -46,7 +46,7 @@
 import GHC.Internal.Data.Maybe
 import GHC.Internal.Base
 import GHC.Internal.Num (Num(..))
-import GHC.Num.Integer (Integer)
+import GHC.Internal.Bignum.Integer (Integer)
 import GHC.Internal.Stack.Types (HasCallStack)
 
 infixl 9  !?, !!
@@ -208,11 +208,6 @@
 -- >>> last []
 -- *** Exception: Prelude.last: empty list
 last                    :: HasCallStack => [a] -> a
-#if defined(USE_REPORT_PRELUDE)
-last [x]                =  x
-last (_:xs)             =  last xs
-last []                 =  errorEmptyList "last"
-#else
 -- Use foldl to make last a good consumer.
 -- This will compile to good code for the actual GHC.Internal.List.last.
 -- (At least as long it is eta-expanded, otherwise it does not, #10260.)
@@ -222,7 +217,6 @@
 -- foldl.
 lastError :: HasCallStack => a
 lastError = errorEmptyList "last"
-#endif
 
 -- | \(\mathcal{O}(n)\). Return all the elements of a list except the last one.
 -- The list must be non-empty.
@@ -240,17 +234,11 @@
 -- >>> init []
 -- *** Exception: Prelude.init: empty list
 init                    :: HasCallStack => [a] -> [a]
-#if defined(USE_REPORT_PRELUDE)
-init [x]                =  []
-init (x:xs)             =  x : init xs
-init []                 =  errorEmptyList "init"
-#else
 -- eliminate repeated cases
 init []                 =  errorEmptyList "init"
 init (x:xs)             =  init' x xs
   where init' _ []     = []
         init' y (z:zs) = y : init' z zs
-#endif
 
 -- | \(\mathcal{O}(1)\). Test whether a list is empty.
 --
@@ -613,7 +601,7 @@
 -- See Note [scanl rewrite rules]
 {-# RULES
 "scanl'"  [~1] forall f a bs . scanl' f a bs =
-  build (\c n -> a `c` foldr (scanlFB' f c) (flipSeq n) bs a)
+  build (\c n -> a `seq` (a `c` foldr (scanlFB' f c) (flipSeq n) bs a))
 "scanlList'" [1] forall f a bs .
     foldr (scanlFB' f (:)) (flipSeq []) bs a = tail (scanl' f a bs)
  #-}
@@ -1091,11 +1079,6 @@
 -- >>> take 0 [1,2]
 -- []
 take                   :: Int -> [a] -> [a]
-#if defined(USE_REPORT_PRELUDE)
-take n _      | n <= 0 =  []
-take _ []              =  []
-take n (x:xs)          =  x : take (n-1) xs
-#else
 
 {- We always want to inline this to take advantage of a known length argument
 sign. Note, however, that it's important for the RULES to grab take, rather
@@ -1141,7 +1124,6 @@
   = \ m -> case m of
             1 -> x `c` n
             _ -> x `c` xs (m - 1)
-#endif
 
 -- | 'drop' @n xs@ returns the suffix of @xs@
 -- after the first @n@ elements, or @[]@ if @n >= 'length' xs@.
@@ -1169,11 +1151,6 @@
 -- >>> drop 0 [1,2]
 -- [1,2]
 drop                   :: Int -> [a] -> [a]
-#if defined(USE_REPORT_PRELUDE)
-drop n xs     | n <= 0 =  xs
-drop _ []              =  []
-drop n (_:xs)          =  drop (n-1) xs
-#else /* hack away */
 {-# INLINE drop #-}
 drop n ls
   | n <= 0     = ls
@@ -1185,7 +1162,6 @@
     unsafeDrop !_ []     = []
     unsafeDrop 1  (_:xs) = xs
     unsafeDrop m  (_:xs) = unsafeDrop (m - 1) xs
-#endif
 
 -- | 'splitAt' @n xs@ returns a tuple where first element is @xs@ prefix of
 -- length @n@ and second element is the remainder of the list:
@@ -1231,9 +1207,6 @@
 -- ([],[1,2,3])
 splitAt                :: Int -> [a] -> ([a],[a])
 
-#if defined(USE_REPORT_PRELUDE)
-splitAt n xs           =  (take n xs, drop n xs)
-#else
 splitAt n ls
   | n <= 0 = ([], ls)
   | otherwise          = splitAt' n ls
@@ -1244,7 +1217,6 @@
         splitAt' m  (x:xs) = (x:xs', xs'')
           where
             (xs', xs'') = splitAt' (m - 1) xs
-#endif /* USE_REPORT_PRELUDE */
 
 -- | 'span', applied to a predicate @p@ and a list @xs@, returns a tuple where
 -- first element is the longest prefix (possibly empty) of @xs@ of elements that
@@ -1322,15 +1294,11 @@
 -- >>> break (> 9) [1,2,3]
 -- ([1,2,3],[])
 break                   :: (a -> Bool) -> [a] -> ([a],[a])
-#if defined(USE_REPORT_PRELUDE)
-break p                 =  span (not . p)
-#else
 -- HBC version (stolen)
 break _ xs@[]           =  (xs, xs)
 break p xs@(x:xs')
            | p x        =  ([],xs)
            | otherwise  =  let (ys,zs) = break p xs' in (x:ys,zs)
-#endif
 
 -- | \(\mathcal{O}(n)\). 'reverse' @xs@ returns the elements of @xs@ in reverse order.
 -- @xs@ must be finite.
@@ -1359,14 +1327,10 @@
 -- >>> reverse [1..]
 -- * Hangs forever *
 reverse                 :: [a] -> [a]
-#if defined(USE_REPORT_PRELUDE)
-reverse                 =  foldl (flip (:)) []
-#else
 reverse l =  rev l []
   where
     rev []     a = a
     rev (x:xs) a = rev xs (x:a)
-#endif
 
 -- | 'and' returns the conjunction of a Boolean list. For the result to be
 -- 'True', the list must be finite; 'False', however, results from a 'False'
@@ -1392,9 +1356,6 @@
 -- >>> and (repeat True)
 -- * Hangs forever *
 and                     :: [Bool] -> Bool
-#if defined(USE_REPORT_PRELUDE)
-and                     =  foldr (&&) True
-#else
 and []          =  True
 and (x:xs)      =  x && and xs
 {-# NOINLINE [1] and #-}
@@ -1403,7 +1364,6 @@
 "and/build"     forall (g::forall b.(Bool->b->b)->b->b) .
                 and (build g) = g (&&) True
  #-}
-#endif
 
 -- | 'or' returns the disjunction of a Boolean list. For the result to be
 -- 'False', the list must be finite; 'True', however, results from a 'True'
@@ -1429,9 +1389,6 @@
 -- >>> or (repeat False)
 -- * Hangs forever *
 or                      :: [Bool] -> Bool
-#if defined(USE_REPORT_PRELUDE)
-or                      =  foldr (||) False
-#else
 or []           =  False
 or (x:xs)       =  x || or xs
 {-# NOINLINE [1] or #-}
@@ -1440,7 +1397,6 @@
 "or/build"      forall (g::forall b.(Bool->b->b)->b->b) .
                 or (build g) = g (||) False
  #-}
-#endif
 
 -- | Applied to a predicate and a list, 'any' determines if any element
 -- of the list satisfies the predicate. For the result to be
@@ -1465,9 +1421,6 @@
 -- >>> any (> 3) [0, -1..]
 -- * Hangs forever *
 any                     :: (a -> Bool) -> [a] -> Bool
-#if defined(USE_REPORT_PRELUDE)
-any p                   =  or . map p
-#else
 any _ []        = False
 any p (x:xs)    = p x || any p xs
 
@@ -1477,7 +1430,6 @@
 "any/build"     forall p (g::forall b.(a->b->b)->b->b) .
                 any p (build g) = g ((||) . p) False
  #-}
-#endif
 
 -- | Applied to a predicate and a list, 'all' determines if all elements
 -- of the list satisfy the predicate. For the result to be
@@ -1502,9 +1454,6 @@
 -- >>> all (> 3) [4..]
 -- * Hangs forever *
 all                     :: (a -> Bool) -> [a] -> Bool
-#if defined(USE_REPORT_PRELUDE)
-all p                   =  and . map p
-#else
 all _ []        =  True
 all p (x:xs)    =  p x && all p xs
 
@@ -1514,7 +1463,6 @@
 "all/build"     forall p (g::forall b.(a->b->b)->b->b) .
                 all p (build g) = g ((&&) . p) True
  #-}
-#endif
 
 -- | 'elem' is the list membership predicate, usually written in infix form,
 -- e.g., @x \`elem\` xs@.  For the result to be
@@ -1538,9 +1486,6 @@
 -- >>> 3 `elem` [4..]
 -- * Hangs forever *
 elem                    :: (Eq a) => a -> [a] -> Bool
-#if defined(USE_REPORT_PRELUDE)
-elem x                  =  any (== x)
-#else
 elem _ []       = False
 elem x (y:ys)   = x==y || elem x ys
 {-# NOINLINE [1] elem #-}
@@ -1548,7 +1493,6 @@
 "elem/build"    forall x (g :: forall b . (a -> b -> b) -> b -> b)
    . elem x (build g) = g (\ y r -> (x == y) || r) False
  #-}
-#endif
 
 -- | 'notElem' is the negation of 'elem'.
 --
@@ -1569,9 +1513,6 @@
 -- >>> 3 `notElem` [4..]
 -- * Hangs forever *
 notElem                 :: (Eq a) => a -> [a] -> Bool
-#if defined(USE_REPORT_PRELUDE)
-notElem x               =  all (/= x)
-#else
 notElem _ []    =  True
 notElem x (y:ys)=  x /= y && notElem x ys
 {-# NOINLINE [1] notElem #-}
@@ -1579,7 +1520,6 @@
 "notElem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b)
    . notElem x (build g) = g (\ y r -> (x /= y) && r) True
  #-}
-#endif
 
 -- | \(\mathcal{O}(n)\). 'lookup' @key assocs@ looks up a key in an association
 -- list.
@@ -1619,7 +1559,7 @@
 -- >>> concatMap (\i -> [-i, i]) [1, 2, 3]
 -- [-1,1,-2,2,-3,3]
 --
--- >>> concatMap ('replicate' 3) [0, 2, 4]
+-- >>> concatMap (replicate 3) [0, 2, 4]
 -- [0,0,0,2,2,2,4,4,4]
 concatMap               :: (a -> [b]) -> [a] -> [b]
 concatMap f             =  foldr ((++) . f) []
@@ -1677,14 +1617,6 @@
 --
 -- >>> ['a', 'b', 'c'] !! (-1)
 -- *** Exception: Prelude.!!: negative index
-#if defined(USE_REPORT_PRELUDE)
-(!!)                    :: [a] -> Int -> a
-xs     !! n | n < 0 =  errorWithoutStackTrace "Prelude.!!: negative index"
-[]     !! _         =  errorWithoutStackTrace "Prelude.!!: index too large"
-(x:_)  !! 0         =  x
-(_:xs) !! n         =  xs !! (n-1)
--- Prelude version is without HasCallStack to avoid building linear one
-#else
 (!!)                    :: HasCallStack => [a] -> Int -> a
 
 -- We don't really want the errors to inline with (!!).
@@ -1703,7 +1635,6 @@
   | otherwise = foldr (\x r k -> case k of
                                    0 -> x
                                    _ -> r (k-1)) tooLarge xs n
-#endif
 
 -- | List index (subscript) operator, starting from 0. Returns 'Nothing'
 -- if the index is out of bounds
@@ -1711,6 +1642,8 @@
 -- This is the total variant of the partial '!!' operator.
 --
 -- WARNING: This function takes linear time in the index.
+--
+-- @since base-4.19.0.0
 --
 -- ==== __Examples__
 --
diff --git a/src/GHC/Internal/Magic.hs b/src/GHC/Internal/Magic.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Magic.hs
@@ -0,0 +1,139 @@
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE StandaloneKindSignatures #-}
+{-# OPTIONS_HADDOCK print-explicit-runtime-reps #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  GHC.Internal.Magic
+-- Copyright   :  (c) The University of Glasgow 2009
+-- License     :  see libraries/ghc-internal/LICENSE
+--
+-- Maintainer  :  ghc-devs@haskell.org
+-- Stability   :  internal
+-- Portability :  non-portable (GHC Extensions)
+--
+-- GHC magic.
+--
+-- Use GHC.Exts from the base package instead of importing this
+-- module directly.
+--
+-----------------------------------------------------------------------------
+
+module GHC.Internal.Magic ( inline, noinline, lazy, oneShot, runRW#, DataToTag(..) ) where
+
+--------------------------------------------------
+--        See Note [magicIds] in GHC.Types.Id.Make
+--------------------------------------------------
+
+-- Here import TYPE explicitly from GHC.Internal.Types and not from GHC.Internal.Prim. This is
+-- because TYPE is not exported by the source Haskell module generated by
+-- genprimops which Haddock will typecheck (#15935).
+import GHC.Internal.Prim (State#, realWorld#, RealWorld, Int#)
+import GHC.Internal.Types (RuntimeRep(BoxedRep), TYPE, Levity, Constraint)
+
+-- | The call @inline f@ arranges that @f@ is inlined, regardless of
+-- its size. More precisely, the call @inline f@ rewrites to the
+-- right-hand side of @f@'s definition. This allows the programmer to
+-- control inlining from a particular call site rather than the
+-- definition site of the function (c.f. @INLINE@ pragmas).
+--
+-- This inlining occurs regardless of the argument to the call or the
+-- size of @f@'s definition; it is unconditional. The main caveat is
+-- that @f@'s definition must be visible to the compiler; it is
+-- therefore recommended to mark the function with an @INLINABLE@
+-- pragma at its definition so that GHC guarantees to record its
+-- unfolding regardless of size.
+--
+-- If no inlining takes place, the 'inline' function expands to the
+-- identity function in Phase zero, so its use imposes no overhead.
+{-# NOINLINE[0] inline #-}
+inline :: a -> a
+inline x = x
+
+-- | The call @noinline f@ arranges that @f@ will not be inlined.
+-- It is removed during CorePrep so that its use imposes no overhead
+-- (besides the fact that it blocks inlining.)
+noinline :: a -> a
+{-# NOINLINE noinline #-}  -- noinline is inlined manually in CorePrep
+noinline x = x
+
+-- | The 'lazy' function restrains strictness analysis a little. The
+-- call @lazy e@ means the same as @e@, but 'lazy' has a magical
+-- property so far as strictness analysis is concerned: it is lazy in
+-- its first argument, even though its semantics is strict. After
+-- strictness analysis has run, calls to 'lazy' are inlined to be the
+-- identity function.
+--
+-- This behaviour is occasionally useful when controlling evaluation
+-- order. Notably, 'lazy' is used in the library definition of
+-- 'Control.Parallel.par':
+--
+-- > par :: a -> b -> b
+-- > par x y = case (par# x) of _ -> lazy y
+--
+-- If 'lazy' were not lazy, 'Control.Parallel.par' would look strict in
+-- @y@ which would defeat the whole purpose of 'Control.Parallel.par'.
+lazy :: a -> a
+{-# NOINLINE lazy #-}  -- lazy is inlined manually in CorePrep
+lazy x = x
+-- Implementation note: its strictness and unfolding are over-ridden
+-- by the definition in GHC.Types.Id.Make; in both cases to nothing at all.
+-- That way, 'lazy' does not get inlined, and the strictness analyser
+-- sees it as lazy.  Then the worker/wrapper phase inlines it.
+-- Result: happiness
+
+
+-- | The 'oneShot' function can be used to give a hint to the compiler that its
+-- argument will be called at most once, which may (or may not) enable certain
+-- optimizations. It can be useful to improve the performance of code in continuation
+-- passing style.
+--
+-- If 'oneShot' is used wrongly, then it may be that computations whose result
+-- that would otherwise be shared are re-evaluated every time they are used. Otherwise,
+-- the use of `oneShot` is safe.
+--
+-- 'oneShot' is representation-polymorphic: the type variables may refer to lifted
+-- or unlifted types.
+oneShot :: forall (q :: RuntimeRep) (r :: RuntimeRep)
+                  (a :: TYPE q) (b :: TYPE r).
+           (a -> b) -> a -> b
+oneShot f = f
+-- Implementation note: This is wired in in GHC.Types.Id.Make, so the code here is
+-- mostly there to have a place for the documentation.
+
+-- | Apply a function to a @'State#' 'RealWorld'@ token. When manually applying
+-- a function to `realWorld#`, it is necessary to use @NOINLINE@ to prevent
+-- semantically undesirable floating. `runRW#` is inlined, but only very late
+-- in compilation after all floating is complete.
+
+-- 'runRW#' is levity-polymorphic: the result may have a lifted or
+-- unlifted type.
+
+runRW# :: forall (r :: RuntimeRep) (o :: TYPE r).
+          (State# RealWorld -> o) -> o
+-- See Note [runRW magic] in GHC.CoreToStg.Prep.
+{-# NOINLINE runRW# #-}  -- runRW# is inlined manually in CorePrep
+runRW# m = m realWorld#
+
+-- | @'dataToTag#'@ evaluates its argument and returns the index
+-- (starting at zero) of the constructor used to produce that
+-- argument.  Any algebraic data type with all of its constructors
+-- in scope may be used with @dataToTag#@.
+--
+-- >>> dataToTag# (Left ())
+-- 0#
+-- >>> dataToTag# (Right undefined)
+-- 1#
+type DataToTag :: forall {lev :: Levity}. TYPE (BoxedRep lev) -> Constraint
+-- See Note [DataToTag overview] in GHC.Tc.Instance.Class.
+--
+-- Ignoring DatatypeContexts, any generated DataToTag instance is
+-- equivalent to a function the user could have written themselves.
+-- So it does not get its own Unsafe module, unlike WithDict.
+class DataToTag a where
+  dataToTag# :: a -> Int#
diff --git a/src/GHC/Internal/Magic/Dict.hs b/src/GHC/Internal/Magic/Dict.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Magic/Dict.hs
@@ -0,0 +1,72 @@
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE ImpredicativeTypes #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}  -- See Note [withDict has an ambiguous type]
+{-# LANGUAGE Unsafe #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  GHC.Internal.Magic.Dict
+-- Copyright   :  (c) The University of Glasgow 2009
+-- License     :  see libraries/ghc-internal/LICENSE
+--
+-- Maintainer  :  ghc-devs@haskell.org
+-- Stability   :  internal
+-- Portability :  non-portable (GHC Extensions)
+--
+-- Defines the 'withDict' function. For more information, see
+-- @Note [withDict]@ in "GHC.Tc.Instance.Class" in GHC.
+-- The definition of 'withDict' is located in a separate module from
+-- "GHC.Internal.Magic" because 'withDict' is @Unsafe@ (it threatens type class
+-- coherence) while "GHC.Internal.Magic" is @Trustworthy@.
+--
+-- Use "GHC.Exts" from the @base@ package instead of importing this
+-- module directly.
+--
+-----------------------------------------------------------------------------
+
+module GHC.Internal.Magic.Dict (
+    WithDict( withDict )
+  ) where
+
+import GHC.Internal.Types (RuntimeRep, TYPE)
+
+-- | The constraint @'WithDict' cls meth@ can be solved when evidence for
+-- the constraint @cls@ can be provided in the form of a dictionary of
+-- type @meth@. This requires @cls@ to be a class constraint whose single
+-- method has type @meth@.
+--
+-- For more (important) details on how this works, see
+-- @Note [withDict]@ in "GHC.Tc.Instance.Class" in GHC.
+--
+--   @since 0.9.0
+class WithDict cls meth where
+  -- @'withDict' d f@ provides a way to call a type-class–overloaded function
+  -- @f@ by applying it to the supplied dictionary @d@.
+  --
+  -- 'withDict' can only be used if the type class has a single method with no
+  -- superclasses.
+  --
+  --   @since 0.9.0
+  withDict :: forall {rr :: RuntimeRep} (r :: TYPE rr). meth -> (cls => r) -> r
+
+{- Note [withDict has an ambiguous type]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The type of `withDict` is ambiguous.  Consider
+   foo :: forall cls meth. WithDict cls meth
+       => forall rr (r::rr). meth -> (cls => r) -> r
+   foo m k = withDict m k
+
+If we instantiate `withDict` with fresh unification variables, including cls0 for cls,
+there is nothing that forces the `cls` Wanted from the call to `k` to unify with the
+`cls0` Given from the call to `withDict`.  You have to give it a class argument:
+
+   foo m k = withDict @cls m k
+
+That's fine.  But it means we need -XAllowAmbiguousTypes for the withDict definition,
+at least with deep subsumption.
+-}
diff --git a/src/GHC/Internal/Maybe.hs b/src/GHC/Internal/Maybe.hs
--- a/src/GHC/Internal/Maybe.hs
+++ b/src/GHC/Internal/Maybe.hs
@@ -8,7 +8,7 @@
 where
 
 -- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Classes
+import GHC.Internal.Classes
 
 default ()
 
diff --git a/src/GHC/Internal/Natural.hs b/src/GHC/Internal/Natural.hs
--- a/src/GHC/Internal/Natural.hs
+++ b/src/GHC/Internal/Natural.hs
@@ -46,14 +46,14 @@
    )
 where
 
-import GHC.Prim
-import GHC.Types
+import GHC.Internal.Prim
+import GHC.Internal.Types
 import GHC.Internal.Maybe
-import GHC.Num.Natural (Natural)
-import GHC.Num.Integer (Integer)
-import qualified GHC.Num.BigNat  as B
-import qualified GHC.Num.Natural as N
-import qualified GHC.Num.Integer as I
+import GHC.Internal.Bignum.Natural (Natural)
+import GHC.Internal.Bignum.Integer (Integer)
+import qualified GHC.Internal.Bignum.BigNat  as B
+import qualified GHC.Internal.Bignum.Natural as N
+import qualified GHC.Internal.Bignum.Integer as I
 
 {-# COMPLETE NatS#, NatJ# #-}
 
diff --git a/src/GHC/Internal/Num.hs b/src/GHC/Internal/Num.hs
--- a/src/GHC/Internal/Num.hs
+++ b/src/GHC/Internal/Num.hs
@@ -21,8 +21,8 @@
    ( Num(..)
    , subtract
    , quotRemInteger
-   , module GHC.Num.Integer
-   , module GHC.Num.Natural
+   , module GHC.Internal.Bignum.Integer
+   , module GHC.Internal.Bignum.Natural
     -- reexported for backward compatibility
    , module GHC.Internal.Natural
    , module GHC.Internal.Integer
@@ -35,8 +35,8 @@
 import qualified GHC.Internal.Integer
 
 import GHC.Internal.Base
-import GHC.Num.Integer
-import GHC.Num.Natural
+import GHC.Internal.Bignum.Integer
+import GHC.Internal.Bignum.Natural
 
 infixl 7  *
 infixl 6  +, -
diff --git a/src/GHC/Internal/Num.hs-boot b/src/GHC/Internal/Num.hs-boot
--- a/src/GHC/Internal/Num.hs-boot
+++ b/src/GHC/Internal/Num.hs-boot
@@ -5,7 +5,7 @@
 -- For why this file exists
 -- See Note [Semigroup stimes cycle] in GHC.Internal.Base
 
-import GHC.Num.Integer (Integer)
+import GHC.Internal.Bignum.Integer (Integer)
 
 infixl 7  *
 infixl 6  +, -
diff --git a/src/GHC/Internal/Numeric.hs b/src/GHC/Internal/Numeric.hs
--- a/src/GHC/Internal/Numeric.hs
+++ b/src/GHC/Internal/Numeric.hs
@@ -174,13 +174,16 @@
 -- mutual module deps.
 
 {-# SPECIALIZE showEFloat ::
-        Maybe Int -> Float  -> ShowS,
+        Maybe Int -> Float  -> ShowS #-}
+{-# SPECIALIZE showEFloat ::
         Maybe Int -> Double -> ShowS #-}
 {-# SPECIALIZE showFFloat ::
-        Maybe Int -> Float  -> ShowS,
+        Maybe Int -> Float  -> ShowS #-}
+{-# SPECIALIZE showFFloat ::
         Maybe Int -> Double -> ShowS #-}
 {-# SPECIALIZE showGFloat ::
-        Maybe Int -> Float  -> ShowS,
+        Maybe Int -> Float  -> ShowS #-}
+{-# SPECIALIZE showGFloat ::
         Maybe Int -> Double -> ShowS #-}
 
 -- | Show a signed 'RealFloat' value
diff --git a/src/GHC/Internal/Numeric/Natural.hs b/src/GHC/Internal/Numeric/Natural.hs
--- a/src/GHC/Internal/Numeric/Natural.hs
+++ b/src/GHC/Internal/Numeric/Natural.hs
@@ -22,5 +22,5 @@
     , minusNaturalMaybe
     ) where
 
-import GHC.Num.Natural
+import GHC.Internal.Bignum.Natural
 import GHC.Internal.Natural (minusNaturalMaybe)
diff --git a/src/GHC/Internal/Pack.hs b/src/GHC/Internal/Pack.hs
--- a/src/GHC/Internal/Pack.hs
+++ b/src/GHC/Internal/Pack.hs
@@ -12,95 +12,20 @@
 -- Stability   :  internal
 -- Portability :  non-portable (GHC Extensions)
 --
--- ⚠ Warning: Starting @base-4.18@, this module is being deprecated.
--- See https://gitlab.haskell.org/ghc/ghc/-/issues/21461 for more information.
---
---
---
--- This module provides a small set of low-level functions for packing
--- and unpacking a chunk of bytes. Used by code emitted by the compiler
--- plus the prelude libraries.
---
--- The programmer level view of packed strings is provided by a GHC
--- system library PackedString.
+-- This function is just used by `rts_mkString`
 --
 -----------------------------------------------------------------------------
 
 module GHC.Internal.Pack
        (
-        -- (**) - emitted by compiler.
-
-        packCString#,
         unpackCString,
-        unpackCString#,
-        unpackNBytes#,
-        unpackFoldrCString#,  -- (**)
-        unpackAppendCString#,  -- (**)
        )
         where
 
 import GHC.Internal.Base
-import GHC.Internal.List ( length )
-import GHC.Internal.ST
 import GHC.Internal.Ptr
 
-data ByteArray ix              = ByteArray        ix ix ByteArray#
-data MutableByteArray s ix     = MutableByteArray ix ix (MutableByteArray# s)
-
 unpackCString :: Ptr a -> [Char]
 unpackCString a@(Ptr addr)
   | a == nullPtr  = []
   | otherwise      = unpackCString# addr
-
-packCString#         :: [Char]          -> ByteArray#
-packCString# str = case (packString str) of { ByteArray _ _ bytes -> bytes }
-
-packString :: [Char] -> ByteArray Int
-packString str = runST (packStringST str)
-
-packStringST :: [Char] -> ST s (ByteArray Int)
-packStringST str =
-  let len = length str  in
-  packNBytesST len str
-
-packNBytesST :: Int -> [Char] -> ST s (ByteArray Int)
-packNBytesST (I# length#) str =
-  {-
-   allocate an array that will hold the string
-   (not forgetting the NUL byte at the end)
-  -}
- new_ps_array (length# +# 1#) >>= \ ch_array ->
-   -- fill in packed string from "str"
- fill_in ch_array 0# str   >>
-   -- freeze the puppy:
- freeze_ps_array ch_array length#
- where
-  fill_in :: MutableByteArray s Int -> Int# -> [Char] -> ST s ()
-  fill_in arr_in# idx [] =
-   write_ps_array arr_in# idx (chr# 0#) >>
-   return ()
-
-  fill_in arr_in# idx (C# c : cs) =
-   write_ps_array arr_in# idx c  >>
-   fill_in arr_in# (idx +# 1#) cs
-
--- (Very :-) ``Specialised'' versions of some CharArray things...
-
-new_ps_array    :: Int# -> ST s (MutableByteArray s Int)
-write_ps_array  :: MutableByteArray s Int -> Int# -> Char# -> ST s ()
-freeze_ps_array :: MutableByteArray s Int -> Int# -> ST s (ByteArray Int)
-
-new_ps_array size = ST $ \ s ->
-    case (newByteArray# size s)   of { (# s2#, barr# #) ->
-    (# s2#, MutableByteArray bot bot barr# #) }
-  where
-    bot = errorWithoutStackTrace "new_ps_array"
-
-write_ps_array (MutableByteArray _ _ barr#) n ch = ST $ \ s# ->
-    case writeCharArray# barr# n ch s#  of { s2#   ->
-    (# s2#, () #) }
-
--- same as unsafeFreezeByteArray
-freeze_ps_array (MutableByteArray _ _ arr#) len# = ST $ \ s# ->
-    case unsafeFreezeByteArray# arr# s# of { (# s2#, frozen# #) ->
-    (# s2#, ByteArray 0 (I# len#) frozen# #) }
diff --git a/src/GHC/Internal/Prim/Exception.hs b/src/GHC/Internal/Prim/Exception.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Prim/Exception.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+-- | Primitive exceptions.
+--
+-- Users should not import this module.  It is GHC internal only.
+module GHC.Internal.Prim.Exception
+   ( raiseOverflow
+   , raiseUnderflow
+   , raiseDivZero
+   )
+where
+
+import GHC.Internal.Prim
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+import GHC.Internal.Types ()
+
+default () -- Double and Integer aren't available yet
+
+-- Note [Arithmetic exceptions]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- ghc-internal provides several functions to raise arithmetic exceptions
+-- (raiseDivZero, raiseUnderflow, raiseOverflow) that are wired-in the RTS.
+-- These exceptions are meant to be used by the package implementing arbitrary
+-- precision numbers (Natural,Integer). It can't depend on `base` package to
+-- raise exceptions in a normal way because it would create a dependency
+-- cycle (base <-> bignum package). See #14664
+--
+-- See also: Note [Wired-in exceptions are not CAFfy] in GHC.Core.Make.
+
+-- | Raise 'GHC.Exception.Type.overflowException'
+raiseOverflow :: a
+raiseOverflow = raiseOverflow# (# #)
+
+-- | Raise 'GHC.Exception.Type.underflowException'
+raiseUnderflow :: a
+raiseUnderflow = raiseUnderflow# (# #)
+
+-- | Raise 'GHC.Exception.Type.divZeroException'
+raiseDivZero :: a
+raiseDivZero = raiseDivZero# (# #)
diff --git a/src/GHC/Internal/Prim/Ext.hs b/src/GHC/Internal/Prim/Ext.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Prim/Ext.hs
@@ -0,0 +1,249 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+
+{-# OPTIONS_GHC -Wno-orphans -Wno-inline-rule-shadowing #-}
+
+-- We need platform defines (tests for mingw32 below).
+#include "ghcplatform.h"
+#include "MachDeps.h"
+
+-- See note [When do out-of-line primops go in primops.txt.pp]. More primops
+-- there are eligible according to the description below, but cannot yet be moved
+-- here because of superficial restrictions to `foreign import prim`. Hopefully
+-- that is fixed soon.
+
+-- | Extra C-- routines exposed from the RTS
+--
+-- Users should not import this module.  It is GHC internal only.  Use
+-- "GHC.Conc" instead.
+--
+-- Actual primops are emitted by the compiler itself. They are special bits of
+-- code with backend support. The foreign functions in this module aren't actual
+-- primops because the compiler doesn't care about them at all: they just are
+-- extra foreign C-- calls libraries can make into the RTS.
+--
+-- Note that 'GHC.Internal.Prim' has the same haddock section names as this module, but
+-- with descriptions. Consult that module's documentation for what each section means.
+-- are described over there.
+module GHC.Internal.Prim.Ext
+  (
+  -- * Misc
+    getThreadAllocationCounter#
+  -- * Delay\/wait operations
+#if defined(mingw32_HOST_OS)
+  , asyncRead#
+  , asyncWrite#
+  , asyncDoProc#
+#endif
+  ) where
+
+import GHC.Internal.Prim
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+import GHC.Internal.Types ()
+
+default () -- Double and Integer aren't available yet
+
+------------------------------------------------------------------------
+-- Delay/wait operations
+------------------------------------------------------------------------
+
+#if defined(mingw32_HOST_OS)
+
+-- | Asynchronously read bytes from specified file descriptor.
+foreign import prim "stg_asyncReadzh" asyncRead#
+  :: Int#
+  -> Int#
+  -> Int#
+  -> Addr#
+  -> State# RealWorld
+  -> (# State# RealWorld, Int#, Int# #)
+
+-- | Asynchronously write bytes from specified file descriptor.
+foreign import prim "stg_asyncWritezh" asyncWrite#
+  :: Int#
+  -> Int#
+  -> Int#
+  -> Addr#
+  -> State# RealWorld
+  -> (# State# RealWorld, Int#, Int# #)
+
+-- | Asynchronously perform procedure (first arg), passing it 2nd arg.
+foreign import prim "stg_asyncDoProczh" asyncDoProc#
+  :: Addr#
+  -> Addr#
+  -> State# RealWorld
+  -> (# State# RealWorld, Int#, Int# #)
+
+#endif
+
+------------------------------------------------------------------------
+-- Misc
+------------------------------------------------------------------------
+
+-- | Retrieves the allocation counter for the current thread.
+foreign import prim "stg_getThreadAllocationCounterzh" getThreadAllocationCounter#
+  :: State# RealWorld
+  -> (# State# RealWorld, Int64# #)
+
+------------------------------------------------------------------------
+-- Rules for primops that don't need to be built-in
+------------------------------------------------------------------------
+
+-- All these rules are used to remove useless casts:
+--
+--  1. passing through a type with at least the same bit size:
+--    e.g. Int8# -> Int# -> Int8#
+--         ==> id
+--
+--  2. passing through a (un)signed type of the same bit size:
+--    e.g. Word# -> Int# -> Word#
+--         ==> id
+--
+--  3. one of the previous cases with signedness change:
+--    e.g. Int8# -> Int# -> Word# -> Word8#
+--         ==> Int8# -> Word8#
+--
+
+
+-- case 1:
+-- ~~~~~~~
+
+{-# RULES
+
+"Int8# -> Int# -> Int8#"
+  forall x . intToInt8# (int8ToInt# x) = x
+
+"Int16# -> Int# -> Int16#"
+  forall x . intToInt16# (int16ToInt# x) = x
+
+"Int32# -> Int# -> Int32#"
+  forall x . intToInt32# (int32ToInt# x) = x
+
+
+"Word8# -> Word# -> Word8#"
+  forall x . wordToWord8# (word8ToWord# x) = x
+
+"Word16# -> Word# -> Word16#"
+  forall x . wordToWord16# (word16ToWord# x) = x
+
+"Word32# -> Word# -> Word32#"
+  forall x . wordToWord32# (word32ToWord# x) = x
+
+
+"Int# -> Int64# -> Int#"
+  forall x . int64ToInt# (intToInt64# x) = x
+
+"Word# -> Word64# -> Word#"
+  forall x . word64ToWord# (wordToWord64# x) = x
+
+#-}
+
+#if WORD_SIZE_IN_BITS == 64
+{-# RULES
+
+"Int64# -> Int# -> Int64#"
+  forall x . intToInt64# (int64ToInt# x) = x
+
+"Word64# -> Word# -> Word64#"
+  forall x . wordToWord64# (word64ToWord# x) = x
+
+#-}
+#endif
+
+
+-- case 2:
+-- ~~~~~~~
+
+{-# RULES
+
+"Word# -> Int# -> Word#"
+  forall x . int2Word# (word2Int# x) = x
+
+"Int# -> Word# -> Int#"
+  forall x . word2Int# (int2Word# x) = x
+
+"Int8# -> Word8# -> Int8#"
+  forall x . word8ToInt8# (int8ToWord8# x) = x
+
+"Word8# -> Int8# -> Word8#"
+  forall x . int8ToWord8# (word8ToInt8# x) = x
+
+"Int16# -> Word16# -> Int16#"
+  forall x . word16ToInt16# (int16ToWord16# x) = x
+
+"Word16# -> Int16# -> Word16#"
+  forall x . int16ToWord16# (word16ToInt16# x) = x
+
+"Int32# -> Word32# -> Int32#"
+  forall x . word32ToInt32# (int32ToWord32# x) = x
+
+"Word32# -> Int32# -> Word32#"
+  forall x . int32ToWord32# (word32ToInt32# x) = x
+
+"Int64# -> Word64# -> Int64#"
+  forall x . word64ToInt64# (int64ToWord64# x) = x
+
+"Word64# -> Int64# -> Word64#"
+  forall x . int64ToWord64# (word64ToInt64# x) = x
+
+#-}
+
+-- case 3:
+-- ~~~~~~~
+
+{-# RULES
+
+"Int8# -> Int# -> Word# -> Word8#"
+  forall x . wordToWord8# (int2Word# (int8ToInt# x)) = int8ToWord8# x
+
+"Int16# -> Int# -> Word# -> Word16#"
+  forall x . wordToWord16# (int2Word# (int16ToInt# x)) = int16ToWord16# x
+
+"Int32# -> Int# -> Word# -> Word32#"
+  forall x . wordToWord32# (int2Word# (int32ToInt# x)) = int32ToWord32# x
+
+"Word8# -> Word# -> Int# -> Int8#"
+  forall x . intToInt8# (word2Int# (word8ToWord# x)) = word8ToInt8# x
+
+"Word16# -> Word# -> Int# -> Int16#"
+  forall x . intToInt16# (word2Int# (word16ToWord# x)) = word16ToInt16# x
+
+"Word32# -> Word# -> Int# -> Int32#"
+  forall x . intToInt32# (word2Int# (word32ToWord# x)) = word32ToInt32# x
+
+"Word# -> Word64# -> Int64# -> Int#"
+  forall x. int64ToInt# (word64ToInt64# (wordToWord64# x)) = word2Int# x
+
+"Int# -> Int64# -> Word64# -> Word#"
+  forall x. word64ToWord# (int64ToWord64# (intToInt64# x)) = int2Word# x
+
+#-}
+
+#if WORD_SIZE_IN_BITS == 64
+{-# RULES
+"Int64# -> Int# -> Word# -> Word64#"
+  forall x . wordToWord64# (int2Word# (int64ToInt# x)) = int64ToWord64# x
+
+"Word64# -> Word# -> Int# -> Int64#"
+  forall x . intToInt64# (word2Int# (word64ToWord# x)) = word64ToInt64# x
+#-}
+#endif
+
+
+-- Push downcast into bitwise operations
+{-# RULES
+"word64ToWord#/and64#"
+  forall x y . word64ToWord# (and64# x y) = and# (word64ToWord# x) (word64ToWord# y)
+
+"word64ToWord#/or64#"
+  forall x y . word64ToWord# (or64# x y) = or# (word64ToWord# x) (word64ToWord# y)
+
+"word64ToWord#/xor64#"
+  forall x y . word64ToWord# (xor64# x y) = xor# (word64ToWord# x) (word64ToWord# y)
+
+#-}
diff --git a/src/GHC/Internal/Prim/Panic.hs b/src/GHC/Internal/Prim/Panic.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Prim/Panic.hs
@@ -0,0 +1,124 @@
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE EmptyCase #-}
+{-# LANGUAGE RankNTypes, KindSignatures #-}
+
+-- | Primitive panics.
+--
+-- Users should not import this module.  It is GHC internal only.
+module GHC.Internal.Prim.Panic
+   ( absentSumFieldError
+   , panicError
+   , absentError, absentConstraintError
+   )
+where
+
+import GHC.Internal.Prim
+import GHC.Internal.Magic
+import GHC.Internal.Types( Type )
+
+default () -- Double and Integer aren't available yet
+
+{-
+Note [Compiler error functions]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Note: this was written before the base/ghc-internal split and before ghc-prim
+was merged into ghc-internal. We could probably revisit this. See also
+W2 of Note [Tracking dependencies on primitives] in GHC.Internal.Base.
+
+Most error functions (such as pattern match failure) are defined
+in base:Control.Exception.Base.  But absentError# and absentSumFieldError#
+are defined here in the ghc-prim package for two reasons:
+
+* GHC itself generates calls to these functions as a result of
+  strictness analysis, over which the programmer has no control. So
+  it is hard to ensure that no such calls exist in the modules
+  compiled "before" Control.Base.Exception.  (E.g. when compiling
+  with -fdicts-strict.)
+
+* A consequence of defining them in ghc-prim is that the libraries
+  defining exceptions have not yet been built, so we can't make them
+  into proper Haskell exceptions.
+
+  However, if these functions are ever called, it's a /compiler/ error,
+  not a user error, so it seems acceptable that they cannot be caught.
+
+One might wonder why absentError doesn't just call panic#.
+For absent error we want to combine two parts, one static, one call site
+dependent into one error message. While for absentSumFieldError it's a
+static string.
+
+The easiest way to combine the two parts for absentError is to use a
+format string with `barf` in the RTS passing the *dynamic* part of the
+error as argument. There is no need to do any of this for
+absentSumFieldError as it's a static string there.
+
+The alternatives would be to:
+* Drop the call site specific information from absentError.
+  The call site specific information is at times very helpful for debugging
+  so I don't consider this an option.
+* Remove the common prefix. We would then need to include the prefix
+  in the call site specific string we pass to absentError. Increasing
+  code size for no good reason.
+
+Both of which seem worse than having an stg_absentError function specific to
+absentError to me.
+-}
+
+-- `stg_panic#` never returns but it can't just return `State# RealWorld` so we
+-- indicate that it returns `(# #)` too to make the compiler happy.
+-- See Note [Compiler error functions]
+foreign import prim "stg_paniczh" panic# :: Addr# -> State# RealWorld -> (# State# RealWorld, (# #) #)
+
+-- See Note [Compiler error functions]
+foreign import prim "stg_absentErrorzh" stg_absentError# :: Addr# -> State# RealWorld -> (# State# RealWorld, (# #) #)
+
+-- | Display the CString whose address is given as an argument and exit.
+panicError :: Addr# -> a
+panicError errmsg =
+  runRW# (\s ->
+    case panic# errmsg s of
+      (# _, _ #) -> -- This bottom is unreachable but we can't
+                    -- use an empty case lest the pattern match
+                    -- checker squawks.
+                    let x = x in x)
+
+-- | Closure introduced by GHC.Stg.Unarise for unused unboxed sum fields.
+--
+-- See Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make
+absentSumFieldError :: a
+absentSumFieldError = panicError "entered absent sum field!"#
+
+-- GHC.Core.Make.aBSENT_SUM_FIELD_ERROR_ID gives absentSumFieldError a bottoming
+-- demand signature. But if we ever inlined it (to a call to panicError) we'd
+-- lose that information.  Should not happen because absentSumFieldError is only
+-- introduced in Stg.Unarise, long after inlining has stopped, but it seems
+-- more direct simply to give it a NOINLINE pragma
+{-# NOINLINE absentSumFieldError #-}
+
+-- | Displays "Oops!  Entered absent arg" ++ errormsg and exits the program.
+{-# NOINLINE absentError #-}
+absentError :: forall (a :: Type). Addr# -> a
+absentError errmsg =
+  runRW# (\s ->
+    case stg_absentError# errmsg s of
+      (# _, _ #) -> -- This bottom is unreachable but we can't
+                    -- use an empty case lest the pattern match
+                    -- checker squawks.
+                    let x = x in x)
+
+{-# NOINLINE absentConstraintError #-}
+absentConstraintError :: forall (a :: Type). Addr# -> a
+-- We want to give this the type
+--    forall (a :: Constraint). Addr# -> a
+-- but Haskell source code doesn't allow functions that return Constraint
+-- So in this module we lie about the type.  This is fine because
+-- absentConstraintError is a wired-in Id with the desired Constraint-kinded
+-- type; the type in the interface file is never looked at.
+-- The only purpose of this definition is to give a function to call,
+-- and for that purpose, delegating to absentError is fine.
+absentConstraintError errmsg = absentError errmsg
diff --git a/src/GHC/Internal/Prim/PtrEq.hs b/src/GHC/Internal/Prim/PtrEq.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Prim/PtrEq.hs
@@ -0,0 +1,148 @@
+{-# LANGUAGE Unsafe #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE PolyKinds #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  GHC.Internal.Prim.PtrEq
+-- License     :  see libraries/ghc-internal/LICENSE
+--
+-- Maintainer  :  ghc-devs@haskell.org
+-- Stability   :  internal
+-- Portability :  non-portable (GHC Extensions)
+--
+-- Comparing underlying pointers for equality.
+--
+-- Use GHC.Exts from the base package instead of importing this
+-- module directly.
+--
+-----------------------------------------------------------------------------
+
+module GHC.Internal.Prim.PtrEq
+  ( reallyUnsafePtrEquality,
+    unsafePtrEquality#,
+    sameArray#,
+    sameMutableArray#,
+    sameSmallArray#,
+    sameSmallMutableArray#,
+    sameByteArray#,
+    sameMutableByteArray#,
+    sameMutVar#,
+    sameTVar#,
+    sameMVar#,
+    samePromptTag#,
+    eqStableName#
+  ) where
+
+import GHC.Internal.Prim
+import GHC.Internal.Types -- Also make implicit dependency known to build system
+  ( RuntimeRep(BoxedRep), UnliftedType )
+default () -- Double and Integer aren't available yet
+
+{- **********************************************************************
+*                                                                       *
+*                        Pointer equality                               *
+*                                                                       *
+********************************************************************** -}
+
+{- Note [Pointer equality operations]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Many primitive types - such as Array#, ByteArray#, MVar#, ... - are boxed:
+they are represented by pointers to the underlying data. It is thus possible
+to directly compare these pointers for equality, as opposed to comparing
+the underlying data that the pointers refer to (for instance, comparing
+two arrays element-wise).
+
+To do this, GHC provides the primop reallyUnsafePtrEquality#, which is
+both levity-polymorphic and heterogeneous. As its name indicates, it is an
+unsafe operation which can yield unpredictable results, as explained in
+Note [Pointer comparison operations] in primops.txt.pp
+
+For a more user-friendly interface, this module defines specialisations of
+the reallyUnsafePtrEquality# primop at various primitive types, such as
+Array#, ByteArray#, MVar#, ...
+-}
+
+-- | Compare the underlying pointers of two values for equality.
+--
+-- Returns @1@ if the pointers are equal and @0@ otherwise.
+--
+-- The two values must be of the same type, of kind 'Type'.
+-- See also 'GHC.Exts.reallyUnsafePtrEquality#', which doesn't have
+-- such restrictions.
+reallyUnsafePtrEquality :: a -> a -> Int#
+reallyUnsafePtrEquality = reallyUnsafePtrEquality#
+-- See Note [Pointer comparison operations]
+--   in primops.txt.pp
+
+-- | Compare the underlying pointers of two unlifted values for equality.
+--
+-- This is less dangerous than 'reallyUnsafePtrEquality',
+-- since the arguments are guaranteed to be evaluated.
+-- This means there is no risk of accidentally comparing
+-- a thunk.
+-- It's however still more dangerous than e.g. 'sameArray#'.
+--
+unsafePtrEquality# :: forall (a :: UnliftedType) (b :: UnliftedType). a -> b -> Int#
+unsafePtrEquality# = reallyUnsafePtrEquality#
+-- See Note [Pointer comparison operations]
+--   in primops.txt.pp
+
+-- | Compare the underlying pointers of two arrays.
+sameArray# :: forall {l} (a :: TYPE (BoxedRep l)). Array# a -> Array# a -> Int#
+sameArray# = unsafePtrEquality#
+
+-- | Compare the underlying pointers of two mutable arrays.
+sameMutableArray# :: forall {l} s (a :: TYPE (BoxedRep l)). MutableArray# s a -> MutableArray# s a -> Int#
+sameMutableArray# = unsafePtrEquality#
+
+-- | Compare the underlying pointers of two small arrays.
+sameSmallArray# :: forall {l} (a :: TYPE (BoxedRep l)). SmallArray# a -> SmallArray# a -> Int#
+sameSmallArray# = unsafePtrEquality#
+
+-- | Compare the underlying pointers of two small mutable arrays.
+sameSmallMutableArray# :: forall {l} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int#
+sameSmallMutableArray# = unsafePtrEquality#
+
+-- | Compare the pointers of two byte arrays.
+sameByteArray# :: ByteArray# -> ByteArray# -> Int#
+sameByteArray# = unsafePtrEquality#
+
+-- | Compare the underlying pointers of two mutable byte arrays.
+sameMutableByteArray# :: MutableByteArray# s -> MutableByteArray# s -> Int#
+sameMutableByteArray# = unsafePtrEquality#
+
+-- | Compare the underlying pointers of two 'MutVar#'s.
+sameMutVar# :: forall {l} s (a :: TYPE (BoxedRep l)). MutVar# s a -> MutVar# s a -> Int#
+sameMutVar# = unsafePtrEquality#
+
+-- | Compare the underlying pointers of two 'TVar#'s.
+sameTVar# :: forall {l} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int#
+sameTVar# = unsafePtrEquality#
+
+-- | Compare the underlying pointers of two 'MVar#'s.
+sameMVar# :: forall {l} s (a :: TYPE (BoxedRep l)). MVar# s a -> MVar# s a -> Int#
+sameMVar# = unsafePtrEquality#
+
+-- | Compare the underlying pointers of two 'PromptTag#'s.
+samePromptTag# :: forall a. PromptTag# a -> PromptTag# a -> Int#
+samePromptTag# = unsafePtrEquality#
+
+-- Note [Comparing stable names]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- A StableName# is actually a pointer to a stable name object (SNO)
+-- containing an index into the stable name table (SNT). We
+-- used to compare StableName#s by following the pointers to the
+-- SNOs and checking whether they held the same SNT indices. However,
+-- this is not necessary: there is a one-to-one correspondence
+-- between SNOs and entries in the SNT, so simple pointer equality
+-- does the trick.
+
+-- | Compare two stable names for equality.
+eqStableName# :: forall {k} {l} (a :: TYPE (BoxedRep k)) (b :: TYPE (BoxedRep l))
+              . StableName# a -> StableName# b -> Int#
+eqStableName# = unsafePtrEquality#
diff --git a/src/GHC/Internal/Profiling.hs b/src/GHC/Internal/Profiling.hs
--- a/src/GHC/Internal/Profiling.hs
+++ b/src/GHC/Internal/Profiling.hs
@@ -9,6 +9,8 @@
                      , startHeapProfTimer
                      , stopHeapProfTimer
                      , requestHeapCensus
+                       -- * Ticky counters (eventlog)
+                     , requestTickyCounterSamples
                      )where
 
 import GHC.Internal.Base
@@ -51,3 +53,11 @@
 -- @since base-4.16.0.0
 foreign import ccall stopHeapProfTimer :: IO ()
 
+-- | Request ticky counter samples to be written to the eventlog.
+--
+-- Note: This won't do anything unless you have specified RTS options on
+-- the command line to log ticky samples to the eventlog.
+--
+-- @since base-4.20.0.0
+
+foreign import ccall requestTickyCounterSamples :: IO ()
diff --git a/src/GHC/Internal/RTS/Flags.hsc b/src/GHC/Internal/RTS/Flags.hsc
--- a/src/GHC/Internal/RTS/Flags.hsc
+++ b/src/GHC/Internal/RTS/Flags.hsc
@@ -162,6 +162,8 @@
     , disableDelayedOsMemoryReturn :: Bool
     , internalCounters      :: Bool
     , linkerAlwaysPic       :: Bool
+    -- TODO: #25354 uncomment to expose this flag to base.
+    -- , linkerOptimistic      :: Bool
     , linkerMemBase         :: Word
       -- ^ address to ask the OS for memory for the linker, 0 ==> off
     , ioManager             :: IoManagerFlag
diff --git a/src/GHC/Internal/Read.hs b/src/GHC/Internal/Read.hs
--- a/src/GHC/Internal/Read.hs
+++ b/src/GHC/Internal/Read.hs
@@ -73,7 +73,7 @@
 import GHC.Internal.Arr
 import GHC.Internal.Word
 import GHC.Internal.List (filter)
-import GHC.Tuple (Solo (..))
+import GHC.Internal.Tuple (Solo (..))
 
 
 -- | @'readParen' 'True' p@ parses what @p@ parses, but surrounded with
diff --git a/src/GHC/Internal/Real.hs b/src/GHC/Internal/Real.hs
--- a/src/GHC/Internal/Real.hs
+++ b/src/GHC/Internal/Real.hs
@@ -96,7 +96,7 @@
                                    , underflowException
                                    , ratioZeroDenomException )
 
-import GHC.Num.BigNat (gcdInt,gcdWord)
+import GHC.Internal.Bignum.BigNat (gcdInt,gcdWord)
 
 infixr 8  ^, ^^
 infixl 7  /, `quot`, `rem`, `div`, `mod`
@@ -746,10 +746,9 @@
         | y0 == 0   = 1
         | otherwise = powImpl x0 y0
 
-{-# SPECIALISE powImpl ::
-        Integer -> Integer -> Integer,
-        Integer -> Int -> Integer,
-        Int -> Int -> Int #-}
+{-# SPECIALISE powImpl :: Integer -> Integer -> Integer #-}
+{-# SPECIALISE powImpl :: Integer -> Int -> Integer #-}
+{-# SPECIALISE powImpl :: Int -> Int -> Int #-}
 {-# INLINABLE powImpl #-}    -- See Note [Inlining (^)]
 powImpl :: (Num a, Integral b) => a -> b -> a
 -- powImpl : x0 ^ y0 = (x ^ y)
@@ -757,10 +756,9 @@
             | y == 1    = x
             | otherwise = powImplAcc (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
 
-{-# SPECIALISE powImplAcc ::
-        Integer -> Integer -> Integer -> Integer,
-        Integer -> Int -> Integer -> Integer,
-        Int -> Int -> Int -> Int #-}
+{-# SPECIALISE powImplAcc :: Integer -> Integer -> Integer -> Integer #-}
+{-# SPECIALISE powImplAcc :: Integer -> Int -> Integer -> Integer #-}
+{-# SPECIALISE powImplAcc :: Int -> Int -> Int -> Int #-}
 {-# INLINABLE powImplAcc #-}    -- See Note [Inlining (^)]
 powImplAcc :: (Num a, Integral b) => a -> b -> a -> a
 -- powImplAcc : x0 ^ y0 = (x ^ y) * z
diff --git a/src/GHC/Internal/Real.hs-boot b/src/GHC/Internal/Real.hs-boot
--- a/src/GHC/Internal/Real.hs-boot
+++ b/src/GHC/Internal/Real.hs-boot
@@ -5,8 +5,8 @@
 -- For why this file exists
 -- See Note [Semigroup stimes cycle] in GHC.Internal.Base
 
-import GHC.Classes (Ord)
-import GHC.Num.Integer (Integer)
+import GHC.Internal.Classes (Ord)
+import GHC.Internal.Bignum.Integer (Integer)
 
 import {-# SOURCE #-} GHC.Internal.Num (Num)
 import {-# SOURCE #-} GHC.Internal.Enum (Enum)
diff --git a/src/GHC/Internal/Records.hs b/src/GHC/Internal/Records.hs
--- a/src/GHC/Internal/Records.hs
+++ b/src/GHC/Internal/Records.hs
@@ -27,10 +27,7 @@
        ( HasField(..)
        ) where
 
--- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Types ()
-
-import GHC.Types (TYPE, Constraint)
+import GHC.Internal.Types (TYPE, Constraint)
 
 -- | Constraint representing the fact that the field @x@ belongs to
 -- the record type @r@ and has field type @a@.  This will be solved
diff --git a/src/GHC/Internal/Show.hs b/src/GHC/Internal/Show.hs
--- a/src/GHC/Internal/Show.hs
+++ b/src/GHC/Internal/Show.hs
@@ -53,7 +53,7 @@
 import GHC.Internal.List ((!!), foldr1, break)
 import GHC.Internal.Num
 import GHC.Internal.Stack.Types
-import GHC.Tuple (Solo (..))
+import GHC.Internal.Tuple (Solo (..))
 
 
 -- | The @shows@ functions return a function that prepends the
diff --git a/src/GHC/Internal/Stack/Annotation.hs b/src/GHC/Internal/Stack/Annotation.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Stack/Annotation.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module GHC.Internal.Stack.Annotation where
+
+import GHC.Internal.Base
+import GHC.Internal.Data.Typeable
+
+-- ----------------------------------------------------------------------------
+-- StackAnnotation
+-- ----------------------------------------------------------------------------
+
+-- | 'StackAnnotation's are types which can be pushed onto the call stack
+-- as the payload of 'AnnFrame' stack frames.
+--
+class StackAnnotation a where
+  displayStackAnnotation :: a -> String
+
+-- ----------------------------------------------------------------------------
+-- Annotations
+-- ----------------------------------------------------------------------------
+
+-- |
+-- The @SomeStackAnnotation@ type is the root of the stack annotation type hierarchy.
+-- When the call stack is annotated with a value of type @a@, behind the scenes it is
+-- encapsulated in a @SomeStackAnnotation@.
+--
+data SomeStackAnnotation where
+  SomeStackAnnotation :: forall a. (Typeable a, StackAnnotation a) => a -> SomeStackAnnotation
+
+instance StackAnnotation SomeStackAnnotation where
+  displayStackAnnotation (SomeStackAnnotation a) = displayStackAnnotation a
diff --git a/src/GHC/Internal/Stack/CloneStack.hs b/src/GHC/Internal/Stack/CloneStack.hs
--- a/src/GHC/Internal/Stack/CloneStack.hs
+++ b/src/GHC/Internal/Stack/CloneStack.hs
@@ -15,34 +15,20 @@
 -- @since base-4.17.0.0
 module GHC.Internal.Stack.CloneStack (
   StackSnapshot(..),
-  StackEntry(..),
   cloneMyStack,
   cloneThreadStack,
-  decode,
-  prettyStackEntry
   ) where
 
 import GHC.Internal.MVar
-import GHC.Internal.Data.Maybe (catMaybes)
 import GHC.Internal.Base
-import GHC.Internal.Foreign.Storable
 import GHC.Internal.Conc.Sync
-import GHC.Internal.IO (unsafeInterleaveIO)
-import GHC.Internal.InfoProv.Types (InfoProv (..), ipLoc, lookupIPE, StgInfoTable)
-import GHC.Internal.Num
-import GHC.Internal.Real (div)
 import GHC.Internal.Stable
-import GHC.Internal.Text.Show
-import GHC.Internal.Ptr
-import GHC.Internal.ClosureTypes
 
 -- | A frozen snapshot of the state of an execution stack.
 --
 -- @since base-4.17.0.0
 data StackSnapshot = StackSnapshot !StackSnapshot#
 
-foreign import prim "stg_decodeStackzh" decodeStack# :: StackSnapshot# -> State# RealWorld -> (# State# RealWorld, ByteArray# #)
-
 foreign import prim "stg_cloneMyStackzh" cloneMyStack# :: State# RealWorld -> (# State# RealWorld, StackSnapshot# #)
 
 foreign import prim "stg_sendCloneStackMessagezh" sendCloneStackMessage# :: ThreadId# -> StablePtr# PrimMVar -> State# RealWorld -> (# State# RealWorld, (# #) #)
@@ -205,64 +191,3 @@
   IO $ \s -> case sendCloneStackMessage# tid# ptr s of (# s', (# #) #) -> (# s', () #)
   freeStablePtr boxedPtr
   takeMVar resultVar
-
--- | Representation for the source location where a return frame was pushed on the stack.
--- This happens every time when a @case ... of@ scrutinee is evaluated.
-data StackEntry = StackEntry
-  { functionName :: String,
-    moduleName :: String,
-    srcLoc :: String,
-    closureType :: ClosureType
-  }
-  deriving (Show, Eq)
-
--- | Decode a 'StackSnapshot' to a stacktrace (a list of 'StackEntry').
--- The stack trace is created from return frames with according 'InfoProvEnt'
--- entries. To generate them, use the GHC flag @-finfo-table-map@. If there are
--- no 'InfoProvEnt' entries, an empty list is returned.
---
--- Please note:
---
---   * To gather 'StackEntry' from libraries, these have to be
---     compiled with @-finfo-table-map@, too.
---   * Due to optimizations by GHC (e.g. inlining) the stacktrace may change
---     with different GHC parameters and versions.
---   * The stack trace is empty (by design) if there are no return frames on
---     the stack. (These are pushed every time when a @case ... of@ scrutinee
---     is evaluated.)
---
--- @since base-4.17.0.0
-decode :: StackSnapshot -> IO [StackEntry]
-decode stackSnapshot = catMaybes `fmap` getDecodedStackArray stackSnapshot
-
-toStackEntry :: InfoProv -> StackEntry
-toStackEntry infoProv =
-  StackEntry
-  { functionName = ipLabel infoProv,
-    moduleName = ipMod infoProv,
-    srcLoc = ipLoc infoProv,
-    closureType = ipDesc infoProv
-  }
-
-getDecodedStackArray :: StackSnapshot -> IO [Maybe StackEntry]
-getDecodedStackArray (StackSnapshot s) =
-  IO $ \s0 -> case decodeStack# s s0 of
-    (# s1, arr #) ->
-      let n = I# (sizeofByteArray# arr) `div` wordSize - 1
-       in unIO (go arr n) s1
-  where
-    go :: ByteArray# -> Int -> IO [Maybe StackEntry]
-    go _stack (-1) = return []
-    go stack i = do
-      infoProv <- lookupIPE (stackEntryAt stack i)
-      rest <- unsafeInterleaveIO $ go stack (i-1)
-      return ((toStackEntry `fmap` infoProv) : rest)
-
-    stackEntryAt :: ByteArray# -> Int -> Ptr StgInfoTable
-    stackEntryAt stack (I# i) = Ptr (indexAddrArray# stack i)
-
-    wordSize = sizeOf (nullPtr :: Ptr ())
-
-prettyStackEntry :: StackEntry -> String
-prettyStackEntry (StackEntry {moduleName=mod_nm, functionName=fun_nm, srcLoc=loc}) =
-    "  " ++ mod_nm ++ "." ++ fun_nm ++ " (" ++ loc ++ ")"
diff --git a/src/GHC/Internal/Stack/Constants.hsc b/src/GHC/Internal/Stack/Constants.hsc
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Stack/Constants.hsc
@@ -0,0 +1,135 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module GHC.Internal.Stack.Constants where
+
+import GHC.Internal.Base
+import GHC.Internal.Enum
+import GHC.Internal.Num
+import GHC.Internal.Show
+import GHC.Internal.Real
+
+#include "Rts.h"
+#undef BLOCK_SIZE
+#undef MBLOCK_SIZE
+#undef BLOCKS_PER_MBLOCK
+#include "DerivedConstants.h"
+
+newtype ByteOffset = ByteOffset { offsetInBytes :: Int }
+  deriving newtype (Eq, Show, Integral, Real, Num, Enum, Ord)
+
+newtype WordOffset = WordOffset { offsetInWords :: Int }
+  deriving newtype (Eq, Show, Integral, Real, Num, Enum, Ord)
+
+offsetStgCatchFrameHandler :: WordOffset
+offsetStgCatchFrameHandler = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchFrame_handler) + (#size StgHeader)
+
+sizeStgCatchFrame :: Int
+sizeStgCatchFrame = bytesToWords $
+  (#const SIZEOF_StgCatchFrame_NoHdr) + (#size StgHeader)
+
+offsetStgCatchSTMFrameCode :: WordOffset
+offsetStgCatchSTMFrameCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchSTMFrame_code) + (#size StgHeader)
+
+offsetStgCatchSTMFrameHandler :: WordOffset
+offsetStgCatchSTMFrameHandler = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchSTMFrame_handler) + (#size StgHeader)
+
+sizeStgCatchSTMFrame :: Int
+sizeStgCatchSTMFrame = bytesToWords $
+  (#const SIZEOF_StgCatchSTMFrame_NoHdr) + (#size StgHeader)
+
+offsetStgUpdateFrameUpdatee :: WordOffset
+offsetStgUpdateFrameUpdatee = byteOffsetToWordOffset $
+  (#const OFFSET_StgUpdateFrame_updatee) + (#size StgHeader)
+
+sizeStgUpdateFrame :: Int
+sizeStgUpdateFrame = bytesToWords $
+  (#const SIZEOF_StgUpdateFrame_NoHdr) + (#size StgHeader)
+
+offsetStgAtomicallyFrameCode :: WordOffset
+offsetStgAtomicallyFrameCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgAtomicallyFrame_code) + (#size StgHeader)
+
+offsetStgAtomicallyFrameResult :: WordOffset
+offsetStgAtomicallyFrameResult = byteOffsetToWordOffset $
+  (#const OFFSET_StgAtomicallyFrame_result) + (#size StgHeader)
+
+sizeStgAtomicallyFrame :: Int
+sizeStgAtomicallyFrame = bytesToWords $
+  (#const SIZEOF_StgAtomicallyFrame_NoHdr) + (#size StgHeader)
+
+offsetStgCatchRetryFrameRunningAltCode :: WordOffset
+offsetStgCatchRetryFrameRunningAltCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchRetryFrame_running_alt_code) + (#size StgHeader)
+
+offsetStgCatchRetryFrameRunningFirstCode :: WordOffset
+offsetStgCatchRetryFrameRunningFirstCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchRetryFrame_first_code) + (#size StgHeader)
+
+offsetStgCatchRetryFrameAltCode :: WordOffset
+offsetStgCatchRetryFrameAltCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchRetryFrame_alt_code) + (#size StgHeader)
+
+sizeStgCatchRetryFrame :: Int
+sizeStgCatchRetryFrame = bytesToWords $
+  (#const SIZEOF_StgCatchRetryFrame_NoHdr) + (#size StgHeader)
+
+offsetStgRetFunFrameSize :: WordOffset
+-- StgRetFun has no header, but only a pointer to the info table at the beginning.
+offsetStgRetFunFrameSize = byteOffsetToWordOffset (#const OFFSET_StgRetFun_size)
+
+offsetStgRetFunFrameFun :: WordOffset
+offsetStgRetFunFrameFun = byteOffsetToWordOffset (#const OFFSET_StgRetFun_fun)
+
+offsetStgRetFunFramePayload :: WordOffset
+offsetStgRetFunFramePayload = byteOffsetToWordOffset (#const OFFSET_StgRetFun_payload)
+
+sizeStgRetFunFrame :: Int
+sizeStgRetFunFrame = bytesToWords (#const SIZEOF_StgRetFun)
+
+sizeStgAnnFrame :: Int
+sizeStgAnnFrame = bytesToWords $
+  (#const SIZEOF_StgAnnFrame_NoHdr) + (#size StgHeader)
+
+offsetStgAnnFrameAnn :: WordOffset
+offsetStgAnnFrameAnn = byteOffsetToWordOffset $
+  (#const OFFSET_StgAnnFrame_ann) + (#size StgHeader)
+
+offsetStgBCOFrameInstrs :: ByteOffset
+offsetStgBCOFrameInstrs = (#const OFFSET_StgBCO_instrs) + (#size StgHeader)
+
+offsetStgBCOFrameLiterals :: ByteOffset
+offsetStgBCOFrameLiterals = (#const OFFSET_StgBCO_literals) + (#size StgHeader)
+
+offsetStgBCOFramePtrs :: ByteOffset
+offsetStgBCOFramePtrs = (#const OFFSET_StgBCO_ptrs) + (#size StgHeader)
+
+offsetStgBCOFrameArity :: ByteOffset
+offsetStgBCOFrameArity = (#const OFFSET_StgBCO_arity) + (#size StgHeader)
+
+offsetStgBCOFrameSize :: ByteOffset
+offsetStgBCOFrameSize = (#const OFFSET_StgBCO_size) + (#size StgHeader)
+
+offsetStgClosurePayload :: WordOffset
+offsetStgClosurePayload = byteOffsetToWordOffset $
+  (#const OFFSET_StgClosure_payload) + (#size StgHeader)
+
+sizeStgClosure :: Int
+sizeStgClosure = bytesToWords (#size StgHeader)
+
+byteOffsetToWordOffset :: ByteOffset -> WordOffset
+byteOffsetToWordOffset = WordOffset . bytesToWords . fromInteger . toInteger
+
+bytesToWords :: Int -> Int
+bytesToWords b =
+  if b `mod` bytesInWord == 0 then
+      fromIntegral $ b `div` bytesInWord
+    else
+      error "Unexpected struct alignment!"
+
+bytesInWord :: Int
+bytesInWord = (#const SIZEOF_VOID_P)
+
diff --git a/src/GHC/Internal/Stack/ConstantsProf.hsc b/src/GHC/Internal/Stack/ConstantsProf.hsc
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Stack/ConstantsProf.hsc
@@ -0,0 +1,140 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module GHC.Internal.Stack.ConstantsProf where
+
+import GHC.Internal.Base
+import GHC.Internal.Enum
+import GHC.Internal.Num
+import GHC.Internal.Show
+import GHC.Internal.Real
+
+-- This file is a copy of GHC.Internal.Stack.Constants, but compiled with PROFILING
+-- defined, since hsc is only invoked once per build in the vanilla way.
+--
+-- Also see GHC.Internal.Heap.InfoTable{Prof}
+#define PROFILING
+#include "Rts.h"
+#undef BLOCK_SIZE
+#undef MBLOCK_SIZE
+#undef BLOCKS_PER_MBLOCK
+#include "DerivedConstants.h"
+
+newtype ByteOffset = ByteOffset { offsetInBytes :: Int }
+  deriving newtype (Eq, Show, Integral, Real, Num, Enum, Ord)
+
+newtype WordOffset = WordOffset { offsetInWords :: Int }
+  deriving newtype (Eq, Show, Integral, Real, Num, Enum, Ord)
+
+offsetStgCatchFrameHandler :: WordOffset
+offsetStgCatchFrameHandler = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchFrame_handler) + (#size StgHeader)
+
+sizeStgCatchFrame :: Int
+sizeStgCatchFrame = bytesToWords $
+  (#const SIZEOF_StgCatchFrame_NoHdr) + (#size StgHeader)
+
+offsetStgCatchSTMFrameCode :: WordOffset
+offsetStgCatchSTMFrameCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchSTMFrame_code) + (#size StgHeader)
+
+offsetStgCatchSTMFrameHandler :: WordOffset
+offsetStgCatchSTMFrameHandler = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchSTMFrame_handler) + (#size StgHeader)
+
+sizeStgCatchSTMFrame :: Int
+sizeStgCatchSTMFrame = bytesToWords $
+  (#const SIZEOF_StgCatchSTMFrame_NoHdr) + (#size StgHeader)
+
+offsetStgUpdateFrameUpdatee :: WordOffset
+offsetStgUpdateFrameUpdatee = byteOffsetToWordOffset $
+  (#const OFFSET_StgUpdateFrame_updatee) + (#size StgHeader)
+
+sizeStgUpdateFrame :: Int
+sizeStgUpdateFrame = bytesToWords $
+  (#const SIZEOF_StgUpdateFrame_NoHdr) + (#size StgHeader)
+
+offsetStgAtomicallyFrameCode :: WordOffset
+offsetStgAtomicallyFrameCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgAtomicallyFrame_code) + (#size StgHeader)
+
+offsetStgAtomicallyFrameResult :: WordOffset
+offsetStgAtomicallyFrameResult = byteOffsetToWordOffset $
+  (#const OFFSET_StgAtomicallyFrame_result) + (#size StgHeader)
+
+sizeStgAtomicallyFrame :: Int
+sizeStgAtomicallyFrame = bytesToWords $
+  (#const SIZEOF_StgAtomicallyFrame_NoHdr) + (#size StgHeader)
+
+offsetStgCatchRetryFrameRunningAltCode :: WordOffset
+offsetStgCatchRetryFrameRunningAltCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchRetryFrame_running_alt_code) + (#size StgHeader)
+
+offsetStgCatchRetryFrameRunningFirstCode :: WordOffset
+offsetStgCatchRetryFrameRunningFirstCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchRetryFrame_first_code) + (#size StgHeader)
+
+offsetStgCatchRetryFrameAltCode :: WordOffset
+offsetStgCatchRetryFrameAltCode = byteOffsetToWordOffset $
+  (#const OFFSET_StgCatchRetryFrame_alt_code) + (#size StgHeader)
+
+sizeStgCatchRetryFrame :: Int
+sizeStgCatchRetryFrame = bytesToWords $
+  (#const SIZEOF_StgCatchRetryFrame_NoHdr) + (#size StgHeader)
+
+offsetStgRetFunFrameSize :: WordOffset
+-- StgRetFun has no header, but only a pointer to the info table at the beginning.
+offsetStgRetFunFrameSize = byteOffsetToWordOffset (#const OFFSET_StgRetFun_size)
+
+offsetStgRetFunFrameFun :: WordOffset
+offsetStgRetFunFrameFun = byteOffsetToWordOffset (#const OFFSET_StgRetFun_fun)
+
+offsetStgRetFunFramePayload :: WordOffset
+offsetStgRetFunFramePayload = byteOffsetToWordOffset (#const OFFSET_StgRetFun_payload)
+
+sizeStgRetFunFrame :: Int
+sizeStgRetFunFrame = bytesToWords (#const SIZEOF_StgRetFun)
+
+sizeStgAnnFrame :: Int
+sizeStgAnnFrame = bytesToWords $
+  (#const SIZEOF_StgAnnFrame_NoHdr) + (#size StgHeader)
+
+offsetStgAnnFrameAnn :: WordOffset
+offsetStgAnnFrameAnn = byteOffsetToWordOffset $
+  (#const OFFSET_StgAnnFrame_ann) + (#size StgHeader)
+
+offsetStgBCOFrameInstrs :: ByteOffset
+offsetStgBCOFrameInstrs = (#const OFFSET_StgBCO_instrs) + (#size StgHeader)
+
+offsetStgBCOFrameLiterals :: ByteOffset
+offsetStgBCOFrameLiterals = (#const OFFSET_StgBCO_literals) + (#size StgHeader)
+
+offsetStgBCOFramePtrs :: ByteOffset
+offsetStgBCOFramePtrs = (#const OFFSET_StgBCO_ptrs) + (#size StgHeader)
+
+offsetStgBCOFrameArity :: ByteOffset
+offsetStgBCOFrameArity = (#const OFFSET_StgBCO_arity) + (#size StgHeader)
+
+offsetStgBCOFrameSize :: ByteOffset
+offsetStgBCOFrameSize = (#const OFFSET_StgBCO_size) + (#size StgHeader)
+
+offsetStgClosurePayload :: WordOffset
+offsetStgClosurePayload = byteOffsetToWordOffset $
+  (#const OFFSET_StgClosure_payload) + (#size StgHeader)
+
+sizeStgClosure :: Int
+sizeStgClosure = bytesToWords (#size StgHeader)
+
+byteOffsetToWordOffset :: ByteOffset -> WordOffset
+byteOffsetToWordOffset = WordOffset . bytesToWords . fromInteger . toInteger
+
+bytesToWords :: Int -> Int
+bytesToWords b =
+  if b `mod` bytesInWord == 0 then
+      fromIntegral $ b `div` bytesInWord
+    else
+      error "Unexpected struct alignment!"
+
+bytesInWord :: Int
+bytesInWord = (#const SIZEOF_VOID_P)
+
diff --git a/src/GHC/Internal/Stack/Decode.hs b/src/GHC/Internal/Stack/Decode.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Stack/Decode.hs
@@ -0,0 +1,589 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeInType #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+
+module GHC.Internal.Stack.Decode (
+  -- * High-level stack decoders
+  decode,
+  decodeStack,
+  decodeStackWithIpe,
+  -- * Stack decoder helpers
+  decodeStackWithFrameUnpack,
+  -- * StackEntry
+  StackEntry(..),
+  -- * Pretty printing
+  prettyStackEntry,
+  prettyStackFrameWithIpe,
+  )
+where
+
+import GHC.Internal.Base
+import GHC.Internal.Show
+import GHC.Internal.Real
+import GHC.Internal.Word
+import GHC.Internal.Num
+import GHC.Internal.Data.Bits
+import GHC.Internal.Data.Functor
+import GHC.Internal.Data.Maybe (catMaybes)
+import GHC.Internal.Data.List
+import GHC.Internal.Data.Tuple
+import GHC.Internal.Foreign.Ptr
+import GHC.Internal.Foreign.Storable
+import GHC.Internal.Exts
+import GHC.Internal.Unsafe.Coerce
+
+import GHC.Internal.ClosureTypes
+import GHC.Internal.Heap.Closures
+  ( Box (..),
+    StackFrame,
+    GenStackFrame (..),
+    StgStackClosure,
+    GenStgStackClosure (..),
+    StackField,
+    GenStackField(..)
+  )
+import GHC.Internal.Heap.Constants (wORD_SIZE_IN_BITS)
+import GHC.Internal.Stack.Annotation
+-- See Note [No way-dependent imports]
+#if defined(PROFILING)
+import GHC.Internal.Stack.Constants ()
+import GHC.Internal.Stack.ConstantsProf
+import GHC.Internal.Heap.InfoTable ()
+import GHC.Internal.Heap.InfoTableProf
+#else
+import GHC.Internal.Heap.InfoTable
+import GHC.Internal.Heap.InfoTableProf ()
+import GHC.Internal.Stack.Constants
+import GHC.Internal.Stack.ConstantsProf ()
+#endif
+import GHC.Internal.Stack.CloneStack
+import GHC.Internal.InfoProv.Types (InfoProv (..), ipLoc, lookupIPE)
+
+{- Note [Decoding the stack]
+   ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The stack is represented by a chain of StgStack closures. Each of these closures
+is subject to garbage collection. I.e. they can be moved in memory (in a
+simplified perspective) at any time.
+
+The array of closures inside an StgStack (that makeup the execution stack; the
+stack frames) is moved as bare memory by the garbage collector. References
+(pointers) to stack frames are not updated by the garbage collector.
+
+As the StgStack closure is moved as whole, the relative offsets inside it stay
+the same. (Though, the absolute addresses change!)
+
+Decoding
+========
+
+Stack frames are defined by their `StackSnapshot#` (`StgStack*` in RTS) and
+their relative offset. This tuple is described by `StackFrameLocation`.
+
+`StackFrame` is an ADT for decoded stack frames. Regarding payload and fields we
+have to deal with three cases:
+
+- If the payload can only be a closure, we put it in a `Box` for later decoding
+  by the heap closure functions.
+
+- If the payload can either be a closure or a word-sized value (this happens for
+  bitmap-encoded payloads), we use a `StackField` which is a sum type to
+  represent either a `Word` or a `Box`.
+
+- Fields that are just simple (i.e. non-closure) values are decoded as such.
+
+The decoding happens in two phases:
+
+1. The whole stack is decoded into `StackFrameLocation`s.
+
+2. All `StackFrameLocation`s are decoded into `StackFrame`s.
+
+`StackSnapshot#` parameters are updated by the garbage collector and thus safe
+to hand around.
+
+The head of the stack frame array has offset (index) 0. To traverse the stack
+frames the latest stack frame's offset is incremented by the closure size. The
+unit of the offset is machine words (32bit or 64bit.)
+
+IO
+==
+
+Unfortunately, ghc-heap decodes `Closure`s in `IO`. This leads to `StackFrames`
+also being decoded in `IO`, due to references to `Closure`s.
+
+Technical details
+=================
+
+- All access to StgStack/StackSnapshot# closures is made through Cmm code. This
+  keeps the closure from being moved by the garbage collector during the
+  operation.
+
+- As StgStacks are mainly used in Cmm and C code, much of the decoding logic is
+  implemented in Cmm and C. It's just easier to reuse existing helper macros and
+  functions, than reinventing them in Haskell.
+
+- Offsets and sizes of closures are imported from DerivedConstants.h via HSC.
+  This keeps the code very portable.
+-}
+
+foreign import prim "getUnderflowFrameNextChunkzh"
+  getUnderflowFrameNextChunk# ::
+    StackSnapshot# -> Word# -> StackSnapshot#
+
+getUnderflowFrameNextChunk :: StackSnapshot# -> WordOffset -> StackSnapshot
+getUnderflowFrameNextChunk stackSnapshot# index =
+  StackSnapshot (getUnderflowFrameNextChunk# stackSnapshot# (wordOffsetToWord# index))
+
+foreign import prim "getWordzh"
+  getWord# ::
+    StackSnapshot# -> Word# -> Word#
+
+getWord :: StackSnapshot# -> WordOffset -> Word
+getWord stackSnapshot# index =
+  W# (getWord# stackSnapshot# (wordOffsetToWord# index))
+
+foreign import prim "isArgGenBigRetFunTypezh" isArgGenBigRetFunType# :: StackSnapshot# -> Word# -> Int#
+
+isArgGenBigRetFunType :: StackSnapshot# -> WordOffset -> Bool
+isArgGenBigRetFunType stackSnapshot# index =
+  I# (isArgGenBigRetFunType# stackSnapshot# (wordOffsetToWord# index)) > 0
+
+-- | Gets contents of a `LargeBitmap` (@StgLargeBitmap@)
+--
+-- The first two arguments identify the location of the frame on the stack.
+-- Returned is the `Addr#` of the @StgWord[]@ (bitmap) and it's size.
+type LargeBitmapGetter = StackSnapshot# -> Word# -> (# Addr#, Word# #)
+
+foreign import prim "getLargeBitmapzh" getLargeBitmap# :: LargeBitmapGetter
+
+foreign import prim "getBCOLargeBitmapzh" getBCOLargeBitmap# :: LargeBitmapGetter
+
+foreign import prim "getRetFunLargeBitmapzh" getRetFunLargeBitmap# :: LargeBitmapGetter
+
+-- | Gets contents of a small bitmap (fitting in one @StgWord@)
+--
+-- The first two arguments identify the location of the frame on the stack.
+-- Returned is the bitmap and it's size.
+type SmallBitmapGetter = StackSnapshot# -> Word# -> (# Word#, Word# #)
+
+foreign import prim "getSmallBitmapzh" getSmallBitmap# :: SmallBitmapGetter
+
+foreign import prim "getRetFunSmallBitmapzh" getRetFunSmallBitmap# :: SmallBitmapGetter
+
+foreign import prim "getInfoTableAddrszh" getInfoTableAddrs# :: StackSnapshot# -> Word# -> (# Addr#, Addr# #)
+
+foreign import prim "getStackInfoTableAddrzh" getStackInfoTableAddr# :: StackSnapshot# -> Addr#
+
+-- | Get the 'StgInfoTable' of the stack frame.
+-- Additionally, provides 'InfoProv' for the 'StgInfoTable' if there is any.
+getInfoTableOnStack :: StackSnapshot# -> WordOffset -> IO (StgInfoTable, Maybe InfoProv)
+getInfoTableOnStack stackSnapshot# index =
+  let !(# itbl_struct#, itbl_ptr_ipe_key# #) = getInfoTableAddrs# stackSnapshot# (wordOffsetToWord# index)
+   in
+    (,) <$> peekItbl (Ptr itbl_struct#) <*> lookupIPE (Ptr itbl_ptr_ipe_key#)
+
+getInfoTableForStack :: StackSnapshot# -> IO StgInfoTable
+getInfoTableForStack stackSnapshot# =
+  peekItbl $
+    Ptr (getStackInfoTableAddr# stackSnapshot#)
+
+foreign import prim "getStackClosurezh"
+  getStackClosure# ::
+    StackSnapshot# -> Word# ->  Any
+
+foreign import prim "getStackFieldszh"
+  getStackFields# ::
+    StackSnapshot# -> Word32#
+
+getStackFields :: StackSnapshot# -> Word32
+getStackFields stackSnapshot# =
+  case getStackFields# stackSnapshot# of
+    sSize# -> W32# sSize#
+
+-- | `StackFrameLocation` of the top-most stack frame
+stackHead :: StackSnapshot# -> StackFrameLocation
+stackHead s# = (StackSnapshot s#, 0) -- GHC stacks are never empty
+
+-- | Advance to the next stack frame (if any)
+--
+-- The last `Int#` in the result tuple is meant to be treated as bool
+-- (has_next).
+foreign import prim "advanceStackFrameLocationzh"
+  advanceStackFrameLocation# ::
+    StackSnapshot# -> Word# -> (# StackSnapshot#, Word#, Int# #)
+
+-- | Advance to the next stack frame (if any)
+advanceStackFrameLocation :: StackFrameLocation -> Maybe StackFrameLocation
+advanceStackFrameLocation ((StackSnapshot stackSnapshot#), index) =
+  let !(# s', i', hasNext #) = advanceStackFrameLocation# stackSnapshot# (wordOffsetToWord# index)
+   in if I# hasNext > 0
+        then Just (StackSnapshot s', primWordToWordOffset i')
+        else Nothing
+  where
+    primWordToWordOffset :: Word# -> WordOffset
+    primWordToWordOffset w# = fromIntegral (W# w#)
+
+getClosureBox :: StackSnapshot# -> WordOffset -> Box
+getClosureBox stackSnapshot# index =
+        case getStackClosure# stackSnapshot# (wordOffsetToWord# index) of
+          -- c needs to be strictly evaluated, otherwise a thunk gets boxed (and
+          -- will later be decoded as such)
+          !c -> Box c
+
+-- | Representation of @StgLargeBitmap@ (RTS)
+data LargeBitmap = LargeBitmap
+  { largeBitmapSize :: Word,
+    largebitmapWords :: Ptr Word
+  }
+
+-- | Is a bitmap entry a closure pointer or a primitive non-pointer?
+data Pointerness = Pointer | NonPointer
+  deriving (Show)
+
+decodeLargeBitmap :: LargeBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [StackField]
+decodeLargeBitmap getterFun# stackSnapshot# index relativePayloadOffset = do
+  let largeBitmap = case getterFun# stackSnapshot# (wordOffsetToWord# index) of
+        (# wordsAddr#, size# #) -> LargeBitmap (W# size#) (Ptr wordsAddr#)
+  bitmapWords <- largeBitmapToList largeBitmap
+  pure $ decodeBitmaps
+          stackSnapshot#
+          (index + relativePayloadOffset)
+          (bitmapWordsPointerness (largeBitmapSize largeBitmap) bitmapWords)
+  where
+    largeBitmapToList :: LargeBitmap -> IO [Word]
+    largeBitmapToList LargeBitmap {..} =
+      cWordArrayToList largebitmapWords $
+        (usedBitmapWords . fromIntegral) largeBitmapSize
+
+    cWordArrayToList :: Ptr Word -> Int -> IO [Word]
+    cWordArrayToList ptr size = mapM (peekElemOff ptr) [0 .. (size - 1)]
+
+    usedBitmapWords :: Int -> Int
+    usedBitmapWords 0 = error "Invalid large bitmap size 0."
+    usedBitmapWords size = (size `div` fromIntegral wORD_SIZE_IN_BITS) + 1
+
+    bitmapWordsPointerness :: Word -> [Word] -> [Pointerness]
+    bitmapWordsPointerness size _ | size <= 0 = []
+    bitmapWordsPointerness _ [] = []
+    bitmapWordsPointerness size (w : wds) =
+      bitmapWordPointerness (min size (fromIntegral wORD_SIZE_IN_BITS)) w
+        ++ bitmapWordsPointerness (size - fromIntegral wORD_SIZE_IN_BITS) wds
+
+bitmapWordPointerness :: Word -> Word -> [Pointerness]
+bitmapWordPointerness 0 _ = []
+bitmapWordPointerness bSize bitmapWord =
+  ( if (bitmapWord .&. 1) /= 0
+      then NonPointer
+      else Pointer
+  )
+    : bitmapWordPointerness
+      (bSize - 1)
+      (bitmapWord `shiftR` 1)
+
+decodeBitmaps :: StackSnapshot# -> WordOffset -> [Pointerness] -> [StackField]
+decodeBitmaps stack# index ps =
+  zipWith toPayload ps [index ..]
+  where
+    toPayload :: Pointerness -> WordOffset -> StackField
+    toPayload p i = case p of
+      NonPointer -> StackWord (getWord stack# i)
+      Pointer -> StackBox (getClosureBox stack# i)
+
+decodeSmallBitmap :: SmallBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> [StackField]
+decodeSmallBitmap getterFun# stackSnapshot# index relativePayloadOffset =
+  let (bitmap, size) = case getterFun# stackSnapshot# (wordOffsetToWord# index) of
+        (# b#, s# #) -> (W# b#, W# s#)
+  in decodeBitmaps
+      stackSnapshot#
+      (index + relativePayloadOffset)
+      (bitmapWordPointerness size bitmap)
+
+unpackStackFrame :: StackFrameLocation -> IO StackFrame
+unpackStackFrame stackFrameLoc = do
+  unpackStackFrameTo stackFrameLoc
+    (\ info _ nextChunk -> do
+      stackClosure <- decodeStack nextChunk
+      pure $
+        UnderflowFrame
+          { info_tbl = info,
+            nextChunk = stackClosure
+          }
+    )
+    (\ frame _ -> pure frame)
+
+unpackStackFrameWithIpe :: StackFrameLocation -> IO [(StackFrame, Maybe InfoProv)]
+unpackStackFrameWithIpe stackFrameLoc = do
+  unpackStackFrameTo stackFrameLoc
+    (\ info mIpe nextChunk@(StackSnapshot stack#) -> do
+      framesWithIpe <- decodeStackWithIpe nextChunk
+      pure
+        [ ( UnderflowFrame
+            { info_tbl = info,
+              nextChunk =
+                GenStgStackClosure
+                  { ssc_info = info,
+                    ssc_stack_size = getStackFields stack#,
+                    ssc_stack = map fst framesWithIpe
+                  }
+            }
+          , mIpe
+          )
+        ]
+    )
+    (\ frame mIpe -> pure [(frame, mIpe)])
+
+unpackStackFrameTo ::
+  forall a .
+  StackFrameLocation ->
+  -- ^ Decode the given 'StackFrame'.
+  (StgInfoTable -> Maybe InfoProv -> StackSnapshot -> IO a) ->
+  -- ^ How to handle 'UNDERFLOW_FRAME's.
+  (StackFrame -> Maybe InfoProv -> IO a) ->
+  -- ^ How to handle all other 'StackFrame' values.
+  IO a
+unpackStackFrameTo (StackSnapshot stackSnapshot#, index) unpackUnderflowFrame finaliseStackFrame = do
+  (info, m_info_prov) <- getInfoTableOnStack stackSnapshot# index
+  unpackStackFrame' info
+    (unpackUnderflowFrame info m_info_prov)
+    (`finaliseStackFrame` m_info_prov)
+  where
+    unpackStackFrame' ::
+      StgInfoTable ->
+      (StackSnapshot -> IO a) ->
+      (StackFrame -> IO a) ->
+      IO a
+    unpackStackFrame' info mkUnderflowResult mkStackFrameResult =
+      case tipe info of
+        RET_BCO -> do
+          let bco' = getClosureBox stackSnapshot# (index + offsetStgClosurePayload)
+          -- The arguments begin directly after the payload's one element
+          bcoArgs' <- decodeLargeBitmap getBCOLargeBitmap# stackSnapshot# index (offsetStgClosurePayload + 1)
+          mkStackFrameResult
+            RetBCO
+              { info_tbl = info,
+                bco = bco',
+                bcoArgs = bcoArgs'
+              }
+        RET_SMALL ->
+          let payload' = decodeSmallBitmap getSmallBitmap# stackSnapshot# index offsetStgClosurePayload
+          in
+            mkStackFrameResult $
+              RetSmall
+                { info_tbl = info,
+                  stack_payload = payload'
+                }
+        RET_BIG -> do
+          payload' <- decodeLargeBitmap getLargeBitmap# stackSnapshot# index offsetStgClosurePayload
+          mkStackFrameResult $
+            RetBig
+              { info_tbl = info,
+                stack_payload = payload'
+              }
+        RET_FUN -> do
+          let retFunSize' = getWord stackSnapshot# (index + offsetStgRetFunFrameSize)
+              retFunFun' = getClosureBox stackSnapshot# (index + offsetStgRetFunFrameFun)
+          retFunPayload' <-
+            if isArgGenBigRetFunType stackSnapshot# index == True
+              then decodeLargeBitmap getRetFunLargeBitmap# stackSnapshot# index offsetStgRetFunFramePayload
+              else pure $ decodeSmallBitmap getRetFunSmallBitmap# stackSnapshot# index offsetStgRetFunFramePayload
+          mkStackFrameResult $
+            RetFun
+              { info_tbl = info,
+                retFunSize = retFunSize',
+                retFunFun = retFunFun',
+                retFunPayload = retFunPayload'
+              }
+        UPDATE_FRAME ->
+          let updatee' = getClosureBox stackSnapshot# (index + offsetStgUpdateFrameUpdatee)
+          in
+            mkStackFrameResult $
+              UpdateFrame
+                { info_tbl = info,
+                  updatee = updatee'
+                }
+        CATCH_FRAME -> do
+          let handler' = getClosureBox stackSnapshot# (index + offsetStgCatchFrameHandler)
+          mkStackFrameResult $
+            CatchFrame
+              { info_tbl = info,
+                handler = handler'
+              }
+        UNDERFLOW_FRAME -> do
+          let nextChunk' = getUnderflowFrameNextChunk stackSnapshot# index
+          mkUnderflowResult nextChunk'
+        STOP_FRAME -> mkStackFrameResult $ StopFrame {info_tbl = info}
+        ATOMICALLY_FRAME -> do
+          let atomicallyFrameCode' = getClosureBox stackSnapshot# (index + offsetStgAtomicallyFrameCode)
+              result' = getClosureBox stackSnapshot# (index + offsetStgAtomicallyFrameResult)
+          mkStackFrameResult $
+            AtomicallyFrame
+              { info_tbl = info,
+                atomicallyFrameCode = atomicallyFrameCode',
+                result = result'
+              }
+        CATCH_RETRY_FRAME ->
+          let running_alt_code' = getWord stackSnapshot# (index + offsetStgCatchRetryFrameRunningAltCode)
+              first_code' = getClosureBox stackSnapshot# (index + offsetStgCatchRetryFrameRunningFirstCode)
+              alt_code' = getClosureBox stackSnapshot# (index + offsetStgCatchRetryFrameAltCode)
+          in
+            mkStackFrameResult $
+              CatchRetryFrame
+                { info_tbl = info,
+                  running_alt_code = running_alt_code',
+                  first_code = first_code',
+                  alt_code = alt_code'
+                }
+        CATCH_STM_FRAME ->
+          let catchFrameCode' = getClosureBox stackSnapshot# (index + offsetStgCatchSTMFrameCode)
+              handler' = getClosureBox stackSnapshot# (index + offsetStgCatchSTMFrameHandler)
+          in
+            mkStackFrameResult $
+              CatchStmFrame
+                { info_tbl = info,
+                  catchFrameCode = catchFrameCode',
+                  handler = handler'
+                }
+        ANN_FRAME ->
+          let annotation = getClosureBox stackSnapshot# (index + offsetStgAnnFrameAnn)
+           in
+             mkStackFrameResult $
+               AnnFrame
+                { info_tbl = info,
+                  annotation = annotation
+                }
+        x -> error $ "Unexpected closure type on stack: " ++ show x
+
+-- | Unbox 'Int#' from 'Int'
+toInt# :: Int -> Int#
+toInt# (I# i) = i
+
+-- | Convert `Int` to `Word#`
+intToWord# :: Int -> Word#
+intToWord# i = int2Word# (toInt# i)
+
+wordOffsetToWord# :: WordOffset -> Word#
+wordOffsetToWord# wo = intToWord# (fromIntegral wo)
+
+-- ----------------------------------------------------------------------------
+-- Simplified source location representation of provenance information
+-- ----------------------------------------------------------------------------
+
+-- | Representation for the source location where a return frame was pushed on the stack.
+-- This happens every time when a @case ... of@ scrutinee is evaluated.
+data StackEntry = StackEntry
+  { functionName :: String,
+    moduleName :: String,
+    srcLoc :: String,
+    closureType :: ClosureType
+  }
+  deriving (Show, Eq)
+
+toStackEntry :: InfoProv -> StackEntry
+toStackEntry infoProv =
+  StackEntry
+  { functionName = ipLabel infoProv,
+    moduleName = ipMod infoProv,
+    srcLoc = ipLoc infoProv,
+    closureType = ipDesc infoProv
+  }
+
+-- ----------------------------------------------------------------------------
+-- Stack decoders
+-- ----------------------------------------------------------------------------
+
+-- | Decode a 'StackSnapshot' to a stacktrace (a list of 'StackEntry').
+-- The stack trace is created from return frames with according 'InfoProvEnt'
+-- entries. To generate them, use the GHC flag @-finfo-table-map@. If there are
+-- no 'InfoProvEnt' entries, an empty list is returned.
+--
+-- Please note:
+--
+--   * To gather 'StackEntry' from libraries, these have to be
+--     compiled with @-finfo-table-map@, too.
+--   * Due to optimizations by GHC (e.g. inlining) the stacktrace may change
+--     with different GHC parameters and versions.
+--   * The stack trace is empty (by design) if there are no return frames on
+--     the stack. (These are pushed every time when a @case ... of@ scrutinee
+--     is evaluated.)
+--
+-- @since base-4.17.0.0
+decode :: StackSnapshot -> IO [StackEntry]
+decode stackSnapshot =
+  (map toStackEntry . catMaybes . map snd . reverse) <$> decodeStackWithIpe stackSnapshot
+
+
+-- | Location of a stackframe on the stack
+--
+-- It's defined by the `StackSnapshot` (@StgStack@) and the offset to the bottom
+-- of the stack.
+type StackFrameLocation = (StackSnapshot, WordOffset)
+
+-- | Decode `StackSnapshot` to a `StgStackClosure`
+--
+-- The return value is the representation of the @StgStack@ itself.
+--
+-- See /Note [Decoding the stack]/.
+decodeStack :: StackSnapshot -> IO StgStackClosure
+decodeStack snapshot@(StackSnapshot stack#) = do
+  (stackInfo, ssc_stack) <- decodeStackWithFrameUnpack unpackStackFrame snapshot
+  pure
+    GenStgStackClosure
+      { ssc_info = stackInfo,
+        ssc_stack_size = getStackFields stack#,
+        ssc_stack = ssc_stack
+      }
+
+decodeStackWithIpe :: StackSnapshot -> IO [(StackFrame, Maybe InfoProv)]
+decodeStackWithIpe snapshot =
+  concat . snd <$> decodeStackWithFrameUnpack unpackStackFrameWithIpe snapshot
+
+-- ----------------------------------------------------------------------------
+-- Write your own stack decoder!
+-- ----------------------------------------------------------------------------
+
+decodeStackWithFrameUnpack :: (StackFrameLocation -> IO a) -> StackSnapshot -> IO (StgInfoTable, [a])
+decodeStackWithFrameUnpack unpackFrame (StackSnapshot stack#) = do
+  info <- getInfoTableForStack stack#
+  case tipe info of
+    STACK -> do
+      let sfls = stackFrameLocations stack#
+      stack' <- mapM unpackFrame sfls
+      pure (info, stack')
+    _ -> error $ "Expected STACK closure, got " ++ show info
+  where
+    stackFrameLocations :: StackSnapshot# -> [StackFrameLocation]
+    stackFrameLocations s# =
+      stackHead s#
+        : go (advanceStackFrameLocation (stackHead s#))
+      where
+        go :: Maybe StackFrameLocation -> [StackFrameLocation]
+        go Nothing = []
+        go (Just r) = r : go (advanceStackFrameLocation r)
+
+-- ----------------------------------------------------------------------------
+-- Pretty printing functions for stack entries, stack frames and provenance info
+-- ----------------------------------------------------------------------------
+
+prettyStackFrameWithIpe :: (StackFrame, Maybe InfoProv) -> Maybe String
+prettyStackFrameWithIpe (frame, mipe) =
+  case frame of
+    AnnFrame {annotation = Box someStackAnno } ->
+      case unsafeCoerce someStackAnno of
+        SomeStackAnnotation ann ->
+          Just $ displayStackAnnotation ann
+    _ ->
+      (prettyStackEntry . toStackEntry) <$> mipe
+
+prettyStackEntry :: StackEntry -> String
+prettyStackEntry (StackEntry {moduleName=mod_nm, functionName=fun_nm, srcLoc=loc}) =
+  mod_nm ++ "." ++ fun_nm ++ " (" ++ loc ++ ")"
diff --git a/src/GHC/Internal/Stack/Types.hs b/src/GHC/Internal/Stack/Types.hs
--- a/src/GHC/Internal/Stack/Types.hs
+++ b/src/GHC/Internal/Stack/Types.hs
@@ -13,7 +13,7 @@
 -- |
 -- Module      :  GHC.Internal.Stack.Types
 -- Copyright   :  (c) The University of Glasgow 2015
--- License     :  see libraries/ghc-prim/LICENSE
+-- License     :  see libraries/ghc-internal/LICENSE
 --
 -- Maintainer  :  ghc-devs@haskell.org
 -- Stability   :  internal
@@ -51,8 +51,8 @@
     which imports ‘GHC.Base‘ (libraries/base/GHC/Base.hs)
 -}
 
-import GHC.Classes (Eq)
-import GHC.Types (Char, Int)
+import GHC.Internal.Classes (Eq)
+import GHC.Internal.Types (Char, Int)
 
 default ()
 
@@ -217,8 +217,8 @@
   { srcLocPackage   :: [Char]
   , srcLocModule    :: [Char]
   , srcLocFile      :: [Char]
-  , srcLocStartLine :: Int
-  , srcLocStartCol  :: Int
-  , srcLocEndLine   :: Int
-  , srcLocEndCol    :: Int
+  , srcLocStartLine :: !Int
+  , srcLocStartCol  :: !Int
+  , srcLocEndLine   :: !Int
+  , srcLocEndCol    :: !Int
   } deriving Eq -- ^ @since base-4.9.0.0
diff --git a/src/GHC/Internal/System/Environment/ExecutablePath.hsc b/src/GHC/Internal/System/Environment/ExecutablePath.hsc
--- a/src/GHC/Internal/System/Environment/ExecutablePath.hsc
+++ b/src/GHC/Internal/System/Environment/ExecutablePath.hsc
@@ -73,7 +73,6 @@
 import GHC.Internal.Data.Functor
 import GHC.Internal.Foreign.C.Types
 import GHC.Internal.Foreign.C.Error
-import GHC.Internal.Foreign.C.String
 import GHC.Internal.Foreign.Marshal.Alloc
 import GHC.Internal.Foreign.Marshal.Array
 import GHC.Internal.Foreign.Ptr
diff --git a/src/GHC/Internal/System/Posix/Internals.hs b/src/GHC/Internal/System/Posix/Internals.hs
--- a/src/GHC/Internal/System/Posix/Internals.hs
+++ b/src/GHC/Internal/System/Posix/Internals.hs
@@ -556,6 +556,8 @@
    c_interruptible_open_ :: CFilePath -> CInt -> CMode -> IO CInt
 foreign import javascript interruptible "h$open"
    c_safe_open_ :: CFilePath -> CInt -> CMode -> IO CInt
+foreign import javascript interruptible "h$openat"
+   c_openat :: CInt -> CFilePath -> CInt -> CMode -> IO CInt
 foreign import javascript interruptible "h$base_read"
    c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize
 foreign import javascript interruptible "h$base_read"
diff --git a/src/GHC/Internal/TH/Lib.hs b/src/GHC/Internal/TH/Lib.hs
--- a/src/GHC/Internal/TH/Lib.hs
+++ b/src/GHC/Internal/TH/Lib.hs
@@ -22,6 +22,7 @@
 
 import GHC.Internal.TH.Syntax hiding (Role, InjectivityAnn)
 import qualified GHC.Internal.TH.Syntax as TH
+
 #ifdef BOOTSTRAP_TH
 import Control.Applicative(liftA, Applicative(..))
 import qualified Data.Kind as Kind (Type)
@@ -30,17 +31,18 @@
 import GHC.Exts (TYPE)
 import Prelude hiding (Applicative(..))
 #else
-import GHC.Internal.Base hiding (Type, Module, inline)
+import GHC.Internal.Base hiding (NonEmpty (..), Type, Module, inline)
 import GHC.Internal.Data.Foldable
 import GHC.Internal.Data.Functor
 import GHC.Internal.Data.Maybe
+import GHC.Internal.Data.NonEmpty (NonEmpty(..))
 import GHC.Internal.Data.Traversable (traverse, sequenceA)
 import GHC.Internal.Integer
 import GHC.Internal.List (zip)
 import GHC.Internal.Real
 import GHC.Internal.Show
 import GHC.Internal.Word
-import qualified GHC.Types as Kind (Type)
+import qualified GHC.Internal.Types as Kind (Type)
 #endif
 
 ----------------------------------------------------------
@@ -553,17 +555,30 @@
 pragOpaqueD :: Quote m => Name -> m Dec
 pragOpaqueD name = pure $ PragmaD $ OpaqueP name
 
-pragSpecD :: Quote m => Name -> m Type -> Phases -> m Dec
-pragSpecD n ty phases
+pragSpecED :: Quote m
+           => Maybe [m (TyVarBndr ())] -> [m RuleBndr]
+           -> m Exp
+           -> Phases
+           -> m Dec
+pragSpecED ty_bndrs tm_bndrs expr phases
   = do
-      ty1    <- ty
-      pure $ PragmaD $ SpecialiseP n ty1 Nothing phases
+      ty_bndrs1    <- traverse sequenceA ty_bndrs
+      tm_bndrs1    <- sequenceA tm_bndrs
+      expr1        <- expr
+      pure $ PragmaD $ SpecialiseEP ty_bndrs1 tm_bndrs1 expr1 Nothing phases
 
-pragSpecInlD :: Quote m => Name -> m Type -> Inline -> Phases -> m Dec
-pragSpecInlD n ty inline phases
+pragSpecInlED :: Quote m
+              => Maybe [m (TyVarBndr ())] -> [m RuleBndr]
+              -> m Exp
+              -> Inline
+              -> Phases
+              -> m Dec
+pragSpecInlED ty_bndrs tm_bndrs expr inl phases
   = do
-      ty1    <- ty
-      pure $ PragmaD $ SpecialiseP n ty1 (Just inline) phases
+      ty_bndrs1    <- traverse sequenceA ty_bndrs
+      tm_bndrs1    <- sequenceA tm_bndrs
+      expr1        <- expr
+      pure $ PragmaD $ SpecialiseEP ty_bndrs1 tm_bndrs1 expr1 (Just inl) phases
 
 pragSpecInstD :: Quote m => m Type -> m Dec
 pragSpecInstD ty
@@ -839,22 +854,6 @@
       t' <- t
       pure $ ImplicitParamT n t'
 
-{-# DEPRECATED classP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please use 'conT' and 'appT'." #-}
-classP :: Quote m => Name -> [m Type] -> m Pred
-classP cla tys
-  = do
-      tysl <- sequenceA tys
-      pure (foldl AppT (ConT cla) tysl)
-
-{-# DEPRECATED equalP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please see 'equalityT'." #-}
-equalP :: Quote m => m Type -> m Type -> m Pred
-equalP tleft tright
-  = do
-      tleft1  <- tleft
-      tright1 <- tright
-      eqT <- equalityT
-      pure (foldl AppT eqT [tleft1, tright1])
-
 promotedT :: Quote m => Name -> m Type
 promotedT = pure . PromotedT
 
@@ -877,20 +876,6 @@
 sourceLazy         = pure SourceLazy
 sourceStrict       = pure SourceStrict
 
-{-# DEPRECATED isStrict
-    ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",
-     "Example usage: 'bang noSourceUnpackedness sourceStrict'"] #-}
-{-# DEPRECATED notStrict
-    ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",
-     "Example usage: 'bang noSourceUnpackedness noSourceStrictness'"] #-}
-{-# DEPRECATED unpacked
-    ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",
-     "Example usage: 'bang sourceUnpack sourceStrict'"] #-}
-isStrict, notStrict, unpacked :: Quote m => m Strict
-isStrict = bang noSourceUnpackedness sourceStrict
-notStrict = bang noSourceUnpackedness noSourceStrictness
-unpacked = bang sourceUnpack sourceStrict
-
 bang :: Quote m => m SourceUnpackedness -> m SourceStrictness -> m Bang
 bang u s = do u' <- u
               s' <- s
@@ -901,16 +886,6 @@
 
 varBangType :: Quote m => Name -> m BangType -> m VarBangType
 varBangType v bt = (\(b, t) -> (v, b, t)) <$> bt
-
-{-# DEPRECATED strictType
-               "As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by 'BangType'. Please use 'bangType' instead." #-}
-strictType :: Quote m => m Strict -> m Type -> m StrictType
-strictType = bangType
-
-{-# DEPRECATED varStrictType
-               "As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by 'VarBangType'. Please use 'varBangType' instead." #-}
-varStrictType :: Quote m => Name -> m StrictType -> m VarStrictType
-varStrictType = varBangType
 
 -- * Type Literals
 
diff --git a/src/GHC/Internal/TH/Lift.hs b/src/GHC/Internal/TH/Lift.hs
--- a/src/GHC/Internal/TH/Lift.hs
+++ b/src/GHC/Internal/TH/Lift.hs
@@ -20,41 +20,26 @@
 -- | This module gives the definition of the 'Lift' class.
 --
 -- This is an internal module.
--- Please import "Language.Haskell.TH" or "Language.Haskell.TH.Syntax" instead!
+-- Please import "Language.Haskell.TH.Lift", "Language.Haskell.TH" or "Language.Haskell.TH.Syntax" instead!
 
 module GHC.Internal.TH.Lift
   ( Lift(..)
-  -- * Generic Lift implementations
-  , dataToQa
-  , dataToExpQ
-  , liftData
-  , dataToPatQ
   -- * Wired-in names
   , liftString
-  , trueName
-  , falseName
-  , nothingName
-  , justName
-  , leftName
-  , rightName
-  , nonemptyName
   )
   where
 
 import GHC.Internal.TH.Syntax
 import qualified GHC.Internal.TH.Lib as Lib (litE)  -- See wrinkle (W4) of Note [Tracking dependencies on primitives]
-import GHC.Internal.Lexeme ( startsVarSym, startsVarId )
 
 import GHC.Internal.Data.Either
-import GHC.Internal.Type.Reflection
 import GHC.Internal.Data.Bool
-import GHC.Internal.Base hiding (Type, Module, inline)
-import GHC.Internal.Data.Foldable
+import GHC.Internal.Base hiding (NonEmpty(..), Type, Module, inline)
+import GHC.Internal.Data.NonEmpty (NonEmpty(..))
 import GHC.Internal.Integer
 import GHC.Internal.Real
 import GHC.Internal.Word
 import GHC.Internal.Int
-import GHC.Internal.Data.Data hiding (Fixity)
 import GHC.Internal.Natural
 import GHC.Internal.ForeignPtr
 
@@ -85,6 +70,9 @@
 -- >   deriving Lift
 --
 -- Representation-polymorphic since /template-haskell-2.16.0.0/.
+--
+-- This is exposed both from the @template-haskell-lift@ and @template-haskell@ packages.
+-- Consider importing it from the more stable @template-haskell-lift@ if you don't need the full breadth of the @template-haskell@ interface.
 class Lift (t :: TYPE r) where
   -- | Turn a value into a Template Haskell expression, suitable for use in
   -- a splice.
@@ -291,21 +279,7 @@
 deriving instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g)
       => Lift (# a | b | c | d | e | f | g #)
 
-trueName, falseName :: Name
-trueName  = 'True
-falseName = 'False
 
-nothingName, justName :: Name
-nothingName = 'Nothing
-justName    = 'Just
-
-leftName, rightName :: Name
-leftName  = 'Left
-rightName = 'Right
-
-nonemptyName :: Name
-nonemptyName = '(:|)
-
 -----------------------------------------------------
 --
 --              Lifting the TH AST
@@ -440,147 +414,3 @@
 deriving instance Lift AnnLookup
 -- | @since template-haskell-2.22.1.0
 deriving instance Lift Extension
-
------------------------------------------------------
---
---              Generic Lift implementations
---
------------------------------------------------------
-
--- | 'dataToQa' is an internal utility function for constructing generic
--- conversion functions from types with 'Data' instances to various
--- quasi-quoting representations.  See the source of 'dataToExpQ' and
--- 'dataToPatQ' for two example usages: @mkCon@, @mkLit@
--- and @appQ@ are overloadable to account for different syntax for
--- expressions and patterns; @antiQ@ allows you to override type-specific
--- cases, a common usage is just @const Nothing@, which results in
--- no overloading.
-dataToQa  ::  forall m a k q. (Quote m, Data a)
-          =>  (Name -> k)
-          ->  (Lit -> m q)
-          ->  (k -> [m q] -> m q)
-          ->  (forall b . Data b => b -> Maybe (m q))
-          ->  a
-          ->  m q
-dataToQa mkCon mkLit appCon antiQ t =
-    case antiQ t of
-      Nothing ->
-          case constrRep constr of
-            AlgConstr _ ->
-                appCon (mkCon funOrConName) conArgs
-              where
-                funOrConName :: Name
-                funOrConName =
-                    case showConstr constr of
-                      "(:)"       -> Name (mkOccName ":")
-                                          (NameG DataName
-                                                (mkPkgName "ghc-prim")
-                                                (mkModName "GHC.Types"))
-                      con@"[]"    -> Name (mkOccName con)
-                                          (NameG DataName
-                                                (mkPkgName "ghc-prim")
-                                                (mkModName "GHC.Types"))
-                      con@('(':_) -> Name (mkOccName con)
-                                          (NameG DataName
-                                                (mkPkgName "ghc-prim")
-                                                (mkModName "GHC.Tuple"))
-
-                      -- Tricky case: see Note [Data for non-algebraic types]
-                      fun@(x:_)   | startsVarSym x || startsVarId x
-                                  -> mkNameG_v tyconPkg tyconMod fun
-                      con         -> mkNameG_d tyconPkg tyconMod con
-
-                  where
-                    tycon :: TyCon
-                    tycon = (typeRepTyCon . typeOf) t
-
-                    tyconPkg, tyconMod :: String
-                    tyconPkg = tyConPackage tycon
-                    tyconMod = tyConModule  tycon
-
-                conArgs :: [m q]
-                conArgs = gmapQ (dataToQa mkCon mkLit appCon antiQ) t
-            IntConstr n ->
-                mkLit $ IntegerL n
-            FloatConstr n ->
-                mkLit $ RationalL n
-            CharConstr c ->
-                mkLit $ CharL c
-        where
-          constr :: Constr
-          constr = toConstr t
-
-      Just y -> y
-
-
-{- Note [Data for non-algebraic types]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Class Data was originally intended for algebraic data types.  But
-it is possible to use it for abstract types too.  For example, in
-package `text` we find
-
-  instance Data Text where
-    ...
-    toConstr _ = packConstr
-
-  packConstr :: Constr
-  packConstr = mkConstr textDataType "pack" [] Prefix
-
-Here `packConstr` isn't a real data constructor, it's an ordinary
-function.  Two complications
-
-* In such a case, we must take care to build the Name using
-  mkNameG_v (for values), not mkNameG_d (for data constructors).
-  See #10796.
-
-* The pseudo-constructor is named only by its string, here "pack".
-  But 'dataToQa' needs the TyCon of its defining module, and has
-  to assume it's defined in the same module as the TyCon itself.
-  But nothing enforces that; #12596 shows what goes wrong if
-  "pack" is defined in a different module than the data type "Text".
-  -}
-
--- | 'dataToExpQ' converts a value to a 'Exp' representation of the
--- same value, in the SYB style. It is generalized to take a function
--- override type-specific cases; see 'liftData' for a more commonly
--- used variant.
-dataToExpQ  ::  (Quote m, Data a)
-            =>  (forall b . Data b => b -> Maybe (m Exp))
-            ->  a
-            ->  m Exp
-dataToExpQ = dataToQa varOrConE litE (foldl appE)
-    where
-          -- Make sure that VarE is used if the Constr value relies on a
-          -- function underneath the surface (instead of a constructor).
-          -- See #10796.
-          varOrConE s =
-            case nameSpace s of
-                 Just VarName      -> return (VarE s)
-                 Just (FldName {}) -> return (VarE s)
-                 Just DataName     -> return (ConE s)
-                 _ -> error $ "Can't construct an expression from name "
-                           ++ showName s
-          appE x y = do { a <- x; b <- y; return (AppE a b)}
-          litE c = return (LitE c)
-
--- | 'liftData' is a variant of 'lift' in the 'Lift' type class which
--- works for any type with a 'Data' instance.
-liftData :: (Quote m, Data a) => a -> m Exp
-liftData = dataToExpQ (const Nothing)
-
--- | 'dataToPatQ' converts a value to a 'Pat' representation of the same
--- value, in the SYB style. It takes a function to handle type-specific cases,
--- alternatively, pass @const Nothing@ to get default behavior.
-dataToPatQ  ::  (Quote m, Data a)
-            =>  (forall b . Data b => b -> Maybe (m Pat))
-            ->  a
-            ->  m Pat
-dataToPatQ = dataToQa id litP conP
-    where litP l = return (LitP l)
-          conP n ps =
-            case nameSpace n of
-                Just DataName -> do
-                    ps' <- sequence ps
-                    return (ConP n [] ps')
-                _ -> error $ "Can't construct a pattern from name "
-                          ++ showName n
diff --git a/src/GHC/Internal/TH/Quote.hs b/src/GHC/Internal/TH/Quote.hs
--- a/src/GHC/Internal/TH/Quote.hs
+++ b/src/GHC/Internal/TH/Quote.hs
@@ -30,6 +30,9 @@
 -- in defining a quasiquoter to be used for expressions, you would
 -- define a 'QuasiQuoter' with only 'quoteExp', and leave the other
 -- fields stubbed out with errors.
+--
+-- This is exposed both from the @template-haskell-quasiquoter@ and @template-haskell@ packages.
+-- Consider importing it from the more stable @template-haskell-quasiquoter@ if you don't need the full breadth of the @template-haskell@ interface.
 data QuasiQuoter = QuasiQuoter {
     -- | Quasi-quoter for expressions, invoked by quotes like @lhs = $[q|...]@
     quoteExp  :: String -> Q Exp,
diff --git a/src/GHC/Internal/TH/Syntax.hs b/src/GHC/Internal/TH/Syntax.hs
--- a/src/GHC/Internal/TH/Syntax.hs
+++ b/src/GHC/Internal/TH/Syntax.hs
@@ -32,7 +32,6 @@
 import Data.Data hiding (Fixity(..))
 import Data.IORef
 import System.IO.Unsafe ( unsafePerformIO )
-import GHC.IO.Unsafe    ( unsafeDupableInterleaveIO )
 import Control.Monad.IO.Class (MonadIO (..))
 import Control.Monad.Fix (MonadFix (..))
 import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO)
@@ -42,16 +41,18 @@
 import Data.Char        ( isAlpha, isAlphaNum, isUpper )
 import Data.List.NonEmpty ( NonEmpty(..) )
 import Data.Word
-import GHC.Generics     ( Generic )
 import qualified Data.Kind as Kind (Type)
-import GHC.Ptr          ( Ptr, plusPtr )
 import Foreign.ForeignPtr
 import Foreign.C.String
 import Foreign.C.Types
+import GHC.IO.Unsafe    ( unsafeDupableInterleaveIO )
+import GHC.Ptr          ( Ptr, plusPtr )
+import GHC.Generics     ( Generic )
 import GHC.Types        (TYPE, RuntimeRep(..))
 #else
-import GHC.Internal.Base hiding (Type, Module, sequence)
+import GHC.Internal.Base hiding (NonEmpty(..),Type, Module, sequence)
 import GHC.Internal.Data.Data hiding (Fixity(..))
+import GHC.Internal.Data.NonEmpty (NonEmpty(..))
 import GHC.Internal.Data.Traversable
 import GHC.Internal.Word
 import GHC.Internal.Generics (Generic)
@@ -76,7 +77,7 @@
 import GHC.Internal.MVar
 import GHC.Internal.IO.Exception
 import GHC.Internal.Unicode
-import qualified GHC.Types as Kind (Type)
+import qualified GHC.Internal.Types as Kind (Type)
 #endif
 import GHC.Internal.ForeignSrcLang
 import GHC.Internal.LanguageExtensions
@@ -429,8 +430,8 @@
 -- expressions:
 --
 -- >>> fmap ppr $ runQ (unTypeCode [| True == $( [| "foo" |] ) |])
--- GHC.Types.True GHC.Classes.== "foo"
--- >>> GHC.Types.True GHC.Classes.== "foo"
+-- GHC.Internal.Types.True GHC.Internal.Classes.== "foo"
+-- >>> GHC.Internal.Types.True GHC.Internal.Classes.== "foo"
 -- <interactive> error:
 --     • Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
 --     • In the second argument of ‘(==)’, namely ‘"foo"’
@@ -846,12 +847,6 @@
 addTopDecls :: [Dec] -> Q ()
 addTopDecls ds = Q (qAddTopDecls ds)
 
--- |
-addForeignFile :: ForeignSrcLang -> String -> Q ()
-addForeignFile = addForeignSource
-{-# DEPRECATED addForeignFile
-               "Use 'Language.Haskell.TH.Syntax.addForeignSource' instead"
-  #-} -- deprecated in 8.6
 
 -- | Emit a foreign file which will be compiled and linked to the object for
 -- the current module. Currently only languages that can be compiled with
@@ -1000,10 +995,10 @@
 sequenceQ = sequence
 
 oneName, manyName :: Name
--- | Synonym for @''GHC.Types.One'@, from @ghc-prim@.
-oneName  = mkNameG DataName "ghc-prim" "GHC.Types" "One"
--- | Synonym for @''GHC.Types.Many'@, from @ghc-prim@.
-manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many"
+-- | Synonym for @''GHC.Internal.Types.One'@, from @ghc-internal@.
+oneName  = mkNameG DataName "ghc-internal" "GHC.Internal.Types" "One"
+-- | Synonym for @''GHC.Internal.Types.Many'@, from @ghc-internal@.
+manyName = mkNameG DataName "ghc-internal" "GHC.Internal.Types" "Many"
 
 
 -----------------------------------------------------
@@ -1401,7 +1396,7 @@
 
 mk_tup_name :: Int -> NameSpace -> Bool -> Name
 mk_tup_name n space boxed
-  = Name (mkOccName tup_occ) (NameG space (mkPkgName "ghc-prim") tup_mod)
+  = Name (mkOccName tup_occ) (NameG space (mkPkgName "ghc-internal") tup_mod)
   where
     withParens thing
       | boxed     = "("  ++ thing ++ ")"
@@ -1411,7 +1406,7 @@
             | space == TcClsName = "Tuple" ++ show n ++ if boxed then "" else "#"
             | otherwise = withParens (replicate n_commas ',')
     n_commas = n - 1
-    tup_mod  = mkModName (if boxed then "GHC.Tuple" else "GHC.Types")
+    tup_mod  = mkModName (if boxed then "GHC.Internal.Tuple" else "GHC.Internal.Types")
     solo
       | space == DataName = "MkSolo"
       | otherwise = "Solo"
@@ -1436,7 +1431,7 @@
 
   | otherwise
   = Name (mkOccName sum_occ)
-         (NameG DataName (mkPkgName "ghc-prim") (mkModName "GHC.Types"))
+         (NameG DataName (mkPkgName "ghc-internal") (mkModName "GHC.Internal.Types"))
 
   where
     prefix     = "unboxedSumDataName: "
@@ -1455,7 +1450,7 @@
 
   | otherwise
   = Name (mkOccName sum_occ)
-         (NameG TcClsName (mkPkgName "ghc-prim") (mkModName "GHC.Types"))
+         (NameG TcClsName (mkPkgName "ghc-internal") (mkModName "GHC.Internal.Types"))
 
   where
     -- Synced with the definition of mkSumTyConOcc in GHC.Builtin.Types
@@ -2163,8 +2158,8 @@
             -- 'Inline' and 'RuleMatch'.
             | OpaqueP         Name
             -- ^ @{ {\-\# OPAQUE T #-} }@
-            | SpecialiseP     Name Type (Maybe Inline) Phases
-            -- ^ @{ {\-\# SPECIALISE [INLINE] [phases] T #-} }@
+            | SpecialiseEP    (Maybe [TyVarBndr ()]) [RuleBndr] Exp (Maybe Inline) Phases
+            -- ^ @{ {\-\# SPECIALISE [forall t_1 ... t_i]. [forall b_1 ... b_j] [INLINE] [phases] exp #-} }@
             | SpecialiseInstP Type
             -- ^ @{ {\-\# SPECIALISE instance I #-} }@
             | RuleP           String (Maybe [TyVarBndr ()]) [RuleBndr] Exp Exp Phases
diff --git a/src/GHC/Internal/Text/ParserCombinators/ReadP.hs b/src/GHC/Internal/Text/ParserCombinators/ReadP.hs
--- a/src/GHC/Internal/Text/ParserCombinators/ReadP.hs
+++ b/src/GHC/Internal/Text/ParserCombinators/ReadP.hs
@@ -74,7 +74,8 @@
 
 import GHC.Internal.Unicode ( isSpace )
 import GHC.Internal.List ( replicate, null )
-import GHC.Internal.Base hiding ( many )
+import GHC.Internal.Base hiding ( NonEmpty (..), many )
+import GHC.Internal.Data.NonEmpty ( NonEmpty (..) )
 
 import GHC.Internal.Control.Monad.Fail
 
diff --git a/src/GHC/Internal/Tuple.hs b/src/GHC/Internal/Tuple.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Tuple.hs
@@ -0,0 +1,600 @@
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE NoImplicitPrelude, PatternSynonyms, ExplicitNamespaces #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  GHC.Internal.Tuple
+-- Copyright   :  (c) The University of Glasgow 2001
+-- License     :  BSD-style (see the file libraries/ghc-internal/LICENSE)
+--
+-- Maintainer  :  libraries@haskell.org
+-- Stability   :  experimental
+-- Portability :  non-portable (GHC extensions)
+--
+-- The tuple data types
+--
+-- Users should not import this module.  It is GHC internal only.
+--
+-----------------------------------------------------------------------------
+
+module GHC.Internal.Tuple (
+  Tuple0, Tuple1,
+  Unit(..),
+  Solo (Solo, MkSolo), getSolo,
+  Tuple2(..),  Tuple3(..),  Tuple4(..),  Tuple5(..),  Tuple6(..),  Tuple7(..),  Tuple8(..),  Tuple9(..),
+  Tuple10(..), Tuple11(..), Tuple12(..), Tuple13(..), Tuple14(..), Tuple15(..), Tuple16(..), Tuple17(..), Tuple18(..), Tuple19(..),
+  Tuple20(..), Tuple21(..), Tuple22(..), Tuple23(..), Tuple24(..), Tuple25(..), Tuple26(..), Tuple27(..), Tuple28(..), Tuple29(..),
+  Tuple30(..), Tuple31(..), Tuple32(..), Tuple33(..), Tuple34(..), Tuple35(..), Tuple36(..), Tuple37(..), Tuple38(..), Tuple39(..),
+  Tuple40(..), Tuple41(..), Tuple42(..), Tuple43(..), Tuple44(..), Tuple45(..), Tuple46(..), Tuple47(..), Tuple48(..), Tuple49(..),
+  Tuple50(..), Tuple51(..), Tuple52(..), Tuple53(..), Tuple54(..), Tuple55(..), Tuple56(..), Tuple57(..), Tuple58(..), Tuple59(..),
+  Tuple60(..), Tuple61(..), Tuple62(..), Tuple63(..), Tuple64(..),
+) where
+
+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
+import GHC.Internal.Types ()
+
+default () -- Double and Integer aren't available yet
+
+-- | The unit datatype @Unit@ has one non-undefined member, the nullary
+-- constructor @()@.
+--
+-- @since 0.11.0
+--
+data Unit = ()
+
+-- The desugarer uses 1-tuples,
+-- but "Unit" is already used up for 0-tuples
+-- See Note [One-tuples] in GHC.Builtin.Types
+
+-- | @Solo@ is the canonical lifted 1-tuple, just like 'Tuple2' is the canonical
+-- lifted 2-tuple (pair) and 'Tuple3' is the canonical lifted 3-tuple (triple).
+--
+-- The most important feature of @Solo@ is that it is possible to force its
+-- "outside" (usually by pattern matching) without forcing its "inside",
+-- because it is defined as a datatype rather than a newtype. One situation
+-- where this can be useful is when writing a function to extract a value from
+-- a data structure. Suppose you write an implementation of arrays and offer
+-- only this function to index into them:
+--
+-- @
+-- index :: Array a -> Int -> a
+-- @
+--
+-- Now imagine that someone wants to extract a value from an array and store it
+-- in a lazy-valued finite map/dictionary:
+--
+-- @
+-- insert "hello" (arr `index` 12) m
+-- @
+--
+-- This can actually lead to a space leak. The value is not actually extracted
+-- from the array until that value (now buried in a map) is forced. That means
+-- the entire array may be kept live by just that value!  Often, the solution
+-- is to use a strict map, or to force the value before storing it, but for
+-- some purposes that's undesirable.
+--
+-- One common solution is to include an indexing function that can produce its
+-- result in an arbitrary @Applicative@ context:
+--
+-- @
+-- indexA :: Applicative f => Array a -> Int -> f a
+-- @
+--
+-- When using @indexA@ in a /pure/ context, @Solo@ serves as a handy
+-- @Applicative@ functor to hold the result. You could write a non-leaky
+-- version of the above example thus:
+--
+-- @
+-- case arr `indexA` 12 of
+--   Solo a -> insert "hello" a m
+-- @
+--
+-- While such simple extraction functions are the most common uses for
+-- unary tuples, they can also be useful for fine-grained control of
+-- strict-spined data structure traversals, and for unifying the
+-- implementations of lazy and strict mapping functions.
+data Solo a = MkSolo a
+
+-- This will have to wait for https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0065-type-infix.rst
+-- Otherwise the deprecation would apply to the data type as well.
+{-# DEPRECATED data Solo "The Solo constructor has been renamed to MkSolo to avoid punning." #-}
+pattern Solo :: a -> Solo a
+pattern Solo x = MkSolo x
+{-# COMPLETE Solo #-}
+
+-- | Extract the value from a 'Solo'. Very often, values should be extracted
+-- directly using pattern matching, to control just what gets evaluated when.
+-- @getSolo@ is for convenience in situations where that is not the case:
+--
+-- When the result is passed to a /strict/ function, it makes no difference
+-- whether the pattern matching is done on the \"outside\" or on the
+-- \"inside\":
+--
+-- @
+-- Data.Set.insert (getSolo sol) set === case sol of Solo v -> Data.Set.insert v set
+-- @
+--
+-- A traversal may be performed in 'Solo' in order to control evaluation
+-- internally, while using @getSolo@ to extract the final result. A strict
+-- mapping function, for example, could be defined
+--
+-- @
+-- map' :: Traversable t => (a -> b) -> t a -> t b
+-- map' f = getSolo . traverse ((Solo $!) . f)
+-- @
+getSolo :: Solo a -> a
+-- getSolo is a standalone function, rather than a record field of Solo,
+-- because Solo is a wired-in TyCon, and a wired-in TyCon that  has
+-- record fields is a bit more inconvenient than if it doesn't.
+-- (No other wired-in TyCon has record fields.)  So it seems easier
+-- to have getSolo as its own separate function (#20562)
+getSolo (MkSolo a) = a
+
+-- | A tuple of zero elements, a synonym for 'Unit'.
+--
+-- @since 0.11.0
+--
+type Tuple0 = Unit
+
+-- | A tuple of one element, a synonym for 'Solo'.
+--
+-- @since 0.11.0
+--
+type Tuple1 = Solo
+
+-- | A tuple of two elements.
+--
+-- @since 0.11.0
+--
+data Tuple2 a b = (a,b)
+
+-- | A tuple of three elements.
+--
+-- @since 0.11.0
+--
+data Tuple3 a b c = (a,b,c)
+
+-- | A tuple of four elements.
+--
+-- @since 0.11.0
+--
+data Tuple4 a b c d = (a,b,c,d)
+
+-- | A tuple of five elements.
+--
+-- @since 0.11.0
+--
+data Tuple5 a b c d e = (a,b,c,d,e)
+
+-- | A tuple of six elements.
+--
+-- @since 0.11.0
+--
+data Tuple6 a b c d e f = (a,b,c,d,e,f)
+
+-- | A tuple of seven elements.
+--
+-- @since 0.11.0
+--
+data Tuple7 a b c d e f g = (a,b,c,d,e,f,g)
+
+-- | A tuple of eight elements.
+--
+-- @since 0.11.0
+--
+data Tuple8 a b c d e f g h = (a,b,c,d,e,f,g,h)
+
+-- | A tuple of nine elements.
+--
+-- @since 0.11.0
+--
+data Tuple9 a b c d e f g h i = (a,b,c,d,e,f,g,h,i)
+
+-- | A tuple of ten elements.
+--
+-- @since 0.11.0
+--
+data Tuple10 a b c d e f g h i j = (a,b,c,d,e,f,g,h,i,j)
+
+-- | A tuple of eleven elements.
+--
+-- @since 0.11.0
+--
+data Tuple11 a b c d e f g h i j k = (a,b,c,d,e,f,g,h,i,j,k)
+
+-- | A tuple of twelve elements.
+--
+-- @since 0.11.0
+--
+data Tuple12 a b c d e f g h i j k l = (a,b,c,d,e,f,g,h,i,j,k,l)
+
+-- | A tuple of 13 elements.
+--
+-- @since 0.11.0
+--
+data Tuple13 a b c d e f g h i j k l m = (a,b,c,d,e,f,g,h,i,j,k,l,m)
+
+-- | A tuple of 14 elements.
+--
+-- @since 0.11.0
+--
+data Tuple14 a b c d e f g h i j k l m n = (a,b,c,d,e,f,g,h,i,j,k,l,m,n)
+
+-- | A tuple of 15 elements.
+--
+-- @since 0.11.0
+--
+data Tuple15 a b c d e f g h i j k l m n o = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)
+
+-- | A tuple of 16 elements.
+--
+-- @since 0.11.0
+--
+data Tuple16 a b c d e f g h i j k l m n o p = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
+
+-- | A tuple of 17 elements.
+--
+-- @since 0.11.0
+--
+data Tuple17 a b c d e f g h i j k l m n o p q = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q)
+
+-- | A tuple of 18 elements.
+--
+-- @since 0.11.0
+--
+data Tuple18 a b c d e f g h i j k l m n o p q r = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r)
+
+-- | A tuple of 19 elements.
+--
+-- @since 0.11.0
+--
+data Tuple19 a b c d e f g h i j k l m n o p q r s = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s)
+
+-- | A tuple of 20 elements.
+--
+-- @since 0.11.0
+--
+data Tuple20 a b c d e f g h i j k l m n o p q r s t = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t)
+
+-- | A tuple of 21 elements.
+
+--
+-- @since 0.11.0
+--
+data Tuple21 a b c d e f g h i j k l m n o p q r s t u = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u)
+
+-- | A tuple of 22 elements.
+--
+-- @since 0.11.0
+--
+data Tuple22 a b c d e f g h i j k l m n o p q r s t u v = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v)
+
+-- | A tuple of 23 elements.
+--
+-- @since 0.11.0
+--
+data Tuple23 a b c d e f g h i j k l m n o p q r s t u v w = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w)
+
+-- | A tuple of 24 elements.
+--
+-- @since 0.11.0
+--
+data Tuple24 a b c d e f g h i j k l m n o p q r s t u v w x = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x)
+
+-- | A tuple of 25 elements.
+--
+-- @since 0.11.0
+--
+data Tuple25 a b c d e f g h i j k l m n o p q r s t u v w x y = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y)
+
+-- | A tuple of 26 elements.
+--
+-- @since 0.11.0
+--
+data Tuple26 a b c d e f g h i j k l m n o p q r s t u v w x y z = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z)
+
+-- | A tuple of 27 elements.
+--
+-- @since 0.11.0
+--
+data Tuple27 a b c d e f g h i j k l m n o p q r s t u v w x y z a1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1)
+
+-- | A tuple of 28 elements.
+--
+-- @since 0.11.0
+--
+data Tuple28 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1)
+
+-- | A tuple of 29 elements.
+--
+-- @since 0.11.0
+--
+data Tuple29 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1)
+
+-- | A tuple of 30 elements.
+--
+-- @since 0.11.0
+--
+data Tuple30 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1)
+
+-- | A tuple of 31 elements.
+--
+-- @since 0.11.0
+--
+data Tuple31 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1)
+
+-- | A tuple of 32 elements.
+--
+-- @since 0.11.0
+--
+data Tuple32 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1)
+
+-- | A tuple of 33 elements.
+--
+-- @since 0.11.0
+--
+data Tuple33 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1)
+
+-- | A tuple of 34 elements.
+--
+-- @since 0.11.0
+--
+data Tuple34 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1)
+
+-- | A tuple of 35 elements.
+--
+-- @since 0.11.0
+--
+data Tuple35 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1)
+
+-- | A tuple of 36 elements.
+--
+-- @since 0.11.0
+--
+data Tuple36 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1)
+
+-- | A tuple of 37 elements.
+--
+-- @since 0.11.0
+--
+data Tuple37 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1)
+
+-- | A tuple of 38 elements.
+--
+-- @since 0.11.0
+--
+data Tuple38 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1)
+
+-- | A tuple of 39 elements.
+--
+-- @since 0.11.0
+--
+data Tuple39 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1)
+
+-- | A tuple of 40 elements.
+--
+-- @since 0.11.0
+--
+data Tuple40 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1)
+
+-- | A tuple of 41 elements.
+--
+-- @since 0.11.0
+--
+data Tuple41 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1)
+
+-- | A tuple of 42 elements.
+--
+-- @since 0.11.0
+--
+data Tuple42 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1)
+
+-- | A tuple of 43 elements.
+--
+-- @since 0.11.0
+--
+data Tuple43 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1)
+
+-- | A tuple of 44 elements.
+--
+-- @since 0.11.0
+--
+data Tuple44 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1)
+
+-- | A tuple of 45 elements.
+--
+-- @since 0.11.0
+--
+data Tuple45 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1)
+
+-- | A tuple of 46 elements.
+--
+-- @since 0.11.0
+--
+data Tuple46 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1)
+
+-- | A tuple of 47 elements.
+--
+-- @since 0.11.0
+--
+data Tuple47 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1)
+
+-- | A tuple of 48 elements.
+--
+-- @since 0.11.0
+--
+data Tuple48 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1)
+
+-- | A tuple of 49 elements.
+--
+-- @since 0.11.0
+--
+data Tuple49 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1)
+
+-- | A tuple of 50 elements.
+--
+-- @since 0.11.0
+--
+data Tuple50 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1)
+
+-- | A tuple of 51 elements.
+--
+-- @since 0.11.0
+--
+data Tuple51 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1)
+
+-- | A tuple of 52 elements.
+--
+-- @since 0.11.0
+--
+data Tuple52 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1)
+
+-- | A tuple of 53 elements.
+--
+-- @since 0.11.0
+--
+data Tuple53 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2)
+
+-- | A tuple of 54 elements.
+--
+-- @since 0.11.0
+--
+data Tuple54 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2)
+
+-- | A tuple of 55 elements.
+--
+-- @since 0.11.0
+--
+data Tuple55 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2)
+
+-- | A tuple of 56 elements.
+--
+-- @since 0.11.0
+--
+data Tuple56 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2)
+
+-- | A tuple of 57 elements.
+--
+-- @since 0.11.0
+--
+data Tuple57 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2)
+
+-- | A tuple of 58 elements.
+--
+-- @since 0.11.0
+--
+data Tuple58 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2)
+
+-- | A tuple of 59 elements.
+--
+-- @since 0.11.0
+--
+data Tuple59 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2)
+
+-- | A tuple of 60 elements.
+--
+-- @since 0.11.0
+--
+data Tuple60 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2)
+
+-- | A tuple of 61 elements.
+--
+-- @since 0.11.0
+--
+data Tuple61 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2,i2)
+
+-- | A tuple of 62 elements.
+--
+-- @since 0.11.0
+--
+data Tuple62 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 j2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2)
+
+-- | A tuple of 63 elements.
+--
+-- @since 0.11.0
+--
+data Tuple63 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2)
+
+-- | A tuple of 64 elements.
+--
+-- @since 0.11.0
+--
+data Tuple64 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+      r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2
+  = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
+     r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2)
diff --git a/src/GHC/Internal/Type/Reflection.hs b/src/GHC/Internal/Type/Reflection.hs
--- a/src/GHC/Internal/Type/Reflection.hs
+++ b/src/GHC/Internal/Type/Reflection.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE ExplicitNamespaces #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -37,9 +37,9 @@
       -- * Type representations
       -- ** Type-Indexed
     , I.TypeRep
-    , pattern I.TypeRep
+    , data I.TypeRep
     , I.typeOf
-    , pattern I.App, pattern I.Con, pattern I.Con', pattern I.Fun
+    , data I.App, data I.Con, data I.Con', data I.Fun
     , I.typeRepTyCon
     , I.rnfTypeRep
     , I.eqTypeRep
diff --git a/src/GHC/Internal/TypeError.hs b/src/GHC/Internal/TypeError.hs
--- a/src/GHC/Internal/TypeError.hs
+++ b/src/GHC/Internal/TypeError.hs
@@ -32,7 +32,7 @@
   ) where
 
 import GHC.Internal.Data.Bool
-import GHC.Types (TYPE, Constraint, Symbol)
+import GHC.Internal.Types (TYPE, Constraint, Symbol)
 
 {- Note [Custom type errors]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -162,7 +162,7 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 The class method `unsatisfiableLifted :: forall (a::Type). Unsatisfiable msg => a`
 works only for lifted types `a`.  What if we want an unsatisfiable value of type
-`Int#`, say?  The function `unsatisfiable` has a representation-polymoprhic type
+`Int#`, say?  The function `unsatisfiable` has a representation-polymorphic type
    unsatisfiable :: forall {rep} (msg :: ErrorMessage) (b :: TYPE rep).
                     Unsatisfiable msg => b
 and yet is defined in terms of `unsatisfiableLifted`.  How? By instantiating
diff --git a/src/GHC/Internal/TypeLits.hs b/src/GHC/Internal/TypeLits.hs
--- a/src/GHC/Internal/TypeLits.hs
+++ b/src/GHC/Internal/TypeLits.hs
@@ -37,7 +37,7 @@
 
 module GHC.Internal.TypeLits
   ( -- * Kinds
-    N.Natural, N.Nat, Symbol  -- Symbol is declared in GHC.Types in package ghc-prim
+    N.Natural, N.Nat, Symbol  -- Symbol is declared in GHC.Internal.Types
 
     -- * Linking type and value level
   , N.KnownNat(natSing), natVal, natVal'
@@ -57,7 +57,7 @@
   , SChar (UnsafeSChar)
       -- We export a pattern synonym instead of the real constructor:
       -- See Note [Preventing unsafe coercions for singleton types].
-  , pattern N.SNat, pattern SSymbol, pattern SChar
+  , data N.SNat, data SSymbol, data SChar
   , fromSNat, fromSSymbol, fromSChar
   , withSomeSNat, withSomeSSymbol, withSomeSChar
   , N.withKnownNat, withKnownSymbol, withKnownChar
@@ -80,13 +80,13 @@
 import GHC.Internal.Base ( Bool(..), Eq(..), Functor(..), Ord(..), Ordering(..), String
                 , (.), otherwise, withDict, Void, (++)
                 , errorWithoutStackTrace)
-import GHC.Types(Symbol, Char, TYPE, Coercible)
+import GHC.Internal.Types(Symbol, Char, TYPE, Coercible)
 import GHC.Internal.TypeError(ErrorMessage(..), TypeError)
 import GHC.Internal.Num(Integer, fromInteger)
 import GHC.Internal.Show(Show(..), appPrec, appPrec1, showParen, showString)
 import GHC.Internal.Read(Read(..))
 import GHC.Internal.Real(toInteger)
-import GHC.Prim(Proxy#)
+import GHC.Internal.Prim(Proxy#)
 import GHC.Internal.Data.Either (Either (..))
 import GHC.Internal.Data.Maybe (Maybe(..))
 import GHC.Internal.Data.Proxy (Proxy(..))
diff --git a/src/GHC/Internal/TypeLits/Internal.hs b/src/GHC/Internal/TypeLits/Internal.hs
--- a/src/GHC/Internal/TypeLits/Internal.hs
+++ b/src/GHC/Internal/TypeLits/Internal.hs
@@ -34,7 +34,7 @@
   ) where
 
 import GHC.Internal.Base(Ordering)
-import GHC.Types(Symbol, Char)
+import GHC.Internal.Types(Symbol, Char)
 
 -- | Comparison of type-level symbols, as a function.
 --
diff --git a/src/GHC/Internal/TypeNats.hs b/src/GHC/Internal/TypeNats.hs
--- a/src/GHC/Internal/TypeNats.hs
+++ b/src/GHC/Internal/TypeNats.hs
@@ -28,7 +28,7 @@
 
 module GHC.Internal.TypeNats
   ( -- * Nat Kind
-    Natural -- declared in GHC.Num.Natural in package ghc-bignum
+    Natural -- declared in GHC.Internal.Bignum.Natural
   , Nat
     -- * Linking type and value level
   , KnownNat(natSing), natVal, natVal'
@@ -40,7 +40,7 @@
   , SNat (UnsafeSNat)
       -- We export a pattern synonym instead of the real constructor:
       -- See Note [Preventing unsafe coercions for singleton types].
-  , pattern SNat
+  , data SNat
   , fromSNat
   , withSomeSNat
   , withKnownNat
@@ -56,11 +56,11 @@
 
 import GHC.Internal.Base( Eq(..), Functor(..), Ord(..), WithDict(..), (.), otherwise
                , Void, errorWithoutStackTrace, (++))
-import GHC.Types
-import GHC.Num.Natural(Natural)
+import GHC.Internal.Types
+import GHC.Internal.Bignum.Natural(Natural)
 import GHC.Internal.Show(Show(..), appPrec, appPrec1, showParen, showString)
 import GHC.Internal.Read(Read(..))
-import GHC.Prim(Proxy#)
+import GHC.Internal.Prim(Proxy#)
 import GHC.Internal.Data.Either(Either(..))
 import GHC.Internal.Data.Maybe(Maybe(..))
 import GHC.Internal.Data.Proxy (Proxy(..))
diff --git a/src/GHC/Internal/TypeNats/Internal.hs b/src/GHC/Internal/TypeNats/Internal.hs
--- a/src/GHC/Internal/TypeNats/Internal.hs
+++ b/src/GHC/Internal/TypeNats/Internal.hs
@@ -33,7 +33,7 @@
   ) where
 
 import GHC.Internal.Base(Ordering)
-import GHC.Num.Natural(Natural)
+import GHC.Internal.Bignum.Natural(Natural)
 
 -- | Comparison of type-level naturals, as a function.
 --
diff --git a/src/GHC/Internal/Types.hs b/src/GHC/Internal/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/GHC/Internal/Types.hs
@@ -0,0 +1,3677 @@
+{-# LANGUAGE MagicHash, NoImplicitPrelude, TypeFamilies, UnboxedTuples,
+             MultiParamTypeClasses, RoleAnnotations, CPP, TypeOperators,
+             PolyKinds, NegativeLiterals, DataKinds, ScopedTypeVariables,
+             TypeApplications, StandaloneKindSignatures, GADTs,
+             FlexibleInstances, UndecidableInstances, UnboxedSums #-}
+-- NegativeLiterals: see Note [Fixity of (->)]
+{-# OPTIONS_HADDOCK print-explicit-runtime-reps #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  GHC.Internal.Types
+-- Copyright   :  (c) The University of Glasgow 2009
+-- License     :  see libraries/ghc-internal/LICENSE
+--
+-- Maintainer  :  ghc-devs@haskell.org
+-- Stability   :  internal
+-- Portability :  non-portable (GHC Extensions)
+--
+-- GHC type definitions.
+-- Use GHC.Exts from the base package instead of importing this
+-- module directly.
+--
+-----------------------------------------------------------------------------
+
+module GHC.Internal.Types (
+        -- * Built-in types
+        Bool(..), Char(..), Int(..), Word(..),
+        Float(..), Double(..),
+        Ordering(..), IO(..),
+
+        List,   -- List( [], (:) )
+          -- List constructors are not exported
+          -- because they are built-in syntax
+
+        isTrue#,
+        SPEC(..),
+        Symbol,
+        Any,
+
+        -- * Type equality
+        type (~), type (~~), Coercible,
+
+        -- * Representation polymorphism
+        TYPE, CONSTRAINT,
+        Levity(..), RuntimeRep(..),
+        LiftedRep, UnliftedRep,
+        Type, UnliftedType, Constraint,
+          -- The historical type * should ideally be written as
+          -- `type *`, without the parentheses. But that's a true
+          -- pain to parse, and for little gain.
+        ZeroBitRep, ZeroBitType,
+        VecCount(..), VecElem(..),
+        Void#,
+
+        -- * Boxing constructors
+        DictBox( MkDictBox ),
+        WordBox( MkWordBox), IntBox( MkIntBox),
+        FloatBox( MkFloatBox), DoubleBox( MkDoubleBox),
+
+        -- * Multiplicity types
+        Multiplicity(..), MultMul,
+
+        -- * Runtime type representation
+        Module(..), TrName(..), TyCon(..), TypeLitSort(..),
+        KindRep(..), KindBndr,
+
+        -- * Unboxed tuples
+        Unit#,
+        Solo#(..),
+        Tuple0#,
+        Tuple1#,
+        Tuple2#,
+        Tuple3#,
+        Tuple4#,
+        Tuple5#,
+        Tuple6#,
+        Tuple7#,
+        Tuple8#,
+        Tuple9#,
+        Tuple10#,
+        Tuple11#,
+        Tuple12#,
+        Tuple13#,
+        Tuple14#,
+        Tuple15#,
+        Tuple16#,
+        Tuple17#,
+        Tuple18#,
+        Tuple19#,
+        Tuple20#,
+        Tuple21#,
+        Tuple22#,
+        Tuple23#,
+        Tuple24#,
+        Tuple25#,
+        Tuple26#,
+        Tuple27#,
+        Tuple28#,
+        Tuple29#,
+        Tuple30#,
+        Tuple31#,
+        Tuple32#,
+        Tuple33#,
+        Tuple34#,
+        Tuple35#,
+        Tuple36#,
+        Tuple37#,
+        Tuple38#,
+        Tuple39#,
+        Tuple40#,
+        Tuple41#,
+        Tuple42#,
+        Tuple43#,
+        Tuple44#,
+        Tuple45#,
+        Tuple46#,
+        Tuple47#,
+        Tuple48#,
+        Tuple49#,
+        Tuple50#,
+        Tuple51#,
+        Tuple52#,
+        Tuple53#,
+        Tuple54#,
+        Tuple55#,
+        Tuple56#,
+        Tuple57#,
+        Tuple58#,
+        Tuple59#,
+        Tuple60#,
+        Tuple61#,
+        Tuple62#,
+        Tuple63#,
+        Tuple64#,
+
+        -- * Unboxed sums
+        Sum2#,
+        Sum3#,
+        Sum4#,
+        Sum5#,
+        Sum6#,
+        Sum7#,
+        Sum8#,
+        Sum9#,
+        Sum10#,
+        Sum11#,
+        Sum12#,
+        Sum13#,
+        Sum14#,
+        Sum15#,
+        Sum16#,
+        Sum17#,
+        Sum18#,
+        Sum19#,
+        Sum20#,
+        Sum21#,
+        Sum22#,
+        Sum23#,
+        Sum24#,
+        Sum25#,
+        Sum26#,
+        Sum27#,
+        Sum28#,
+        Sum29#,
+        Sum30#,
+        Sum31#,
+        Sum32#,
+        Sum33#,
+        Sum34#,
+        Sum35#,
+        Sum36#,
+        Sum37#,
+        Sum38#,
+        Sum39#,
+        Sum40#,
+        Sum41#,
+        Sum42#,
+        Sum43#,
+        Sum44#,
+        Sum45#,
+        Sum46#,
+        Sum47#,
+        Sum48#,
+        Sum49#,
+        Sum50#,
+        Sum51#,
+        Sum52#,
+        Sum53#,
+        Sum54#,
+        Sum55#,
+        Sum56#,
+        Sum57#,
+        Sum58#,
+        Sum59#,
+        Sum60#,
+        Sum61#,
+        Sum62#,
+        Sum63#,
+
+    ) where
+
+import GHC.Internal.Prim
+
+infixr 5 :
+
+{- *********************************************************************
+*                                                                      *
+                  Functions
+*                                                                      *
+********************************************************************* -}
+
+infixr -1 ->
+{-
+Note [Fixity of (->)]
+~~~~~~~~~~~~~~~~~~~~~
+This declaration is important for :info (->) command (issue #10145)
+1) The parser parses -> as if it had lower fixity than 0,
+   so we conventionally use -1 (issue #15235).
+2) Fixities outside the 0-9 range are exceptionally allowed
+   for (->) (see checkPrecP in RdrHsSyn)
+3) The negative fixity -1 must be parsed as a single token,
+   hence this module requires NegativeLiterals.
+-}
+
+-- | The regular function type
+type (->) = FUN 'Many
+-- See Note [Linear types] in Multiplicity
+
+{- *********************************************************************
+*                                                                      *
+                  Kinds
+*                                                                      *
+********************************************************************* -}
+
+
+
+-- | The runtime representation of lifted types.
+type LiftedRep = 'BoxedRep 'Lifted
+
+-- | The runtime representation of unlifted types.
+type UnliftedRep = 'BoxedRep 'Unlifted
+
+-- | The runtime representation of a zero-width tuple,
+--   represented by no bits at all
+type ZeroBitRep = 'TupleRep '[]
+
+-------------------------
+-- | The kind of lifted constraints
+type Constraint = CONSTRAINT LiftedRep
+
+-- | The kind of types with lifted values. For example @Int :: Type@.
+type Type = TYPE LiftedRep
+
+-- | The kind of boxed, unlifted values, for example @Array#@ or a user-defined
+-- unlifted data type, using @-XUnliftedDataTypes@.
+type UnliftedType = TYPE UnliftedRep
+
+-- | The kind of the empty unboxed tuple type (# #)
+type ZeroBitType = TYPE ZeroBitRep
+
+-------------------------
+data Multiplicity = Many | One
+
+type family MultMul (a :: Multiplicity) (b :: Multiplicity) :: Multiplicity where
+  MultMul 'One x = x
+  MultMul x 'One = x
+  MultMul 'Many x = 'Many
+  MultMul x 'Many = 'Many
+
+{- *********************************************************************
+*                                                                      *
+                  Symbol
+*                                                                      *
+********************************************************************* -}
+
+-- | (Kind) This is the kind of type-level symbols.
+data Symbol
+
+-- Symbol is declared here because class IP needs it
+
+{- *********************************************************************
+*                                                                      *
+                  Any
+*                                                                      *
+********************************************************************* -}
+
+-- | The type constructor @Any :: forall k. k@ is a type to which you can unsafely coerce any type, and back.
+--
+-- For @unsafeCoerce@ this means for all lifted types @t@ that
+-- @unsafeCoerce (unsafeCoerce x :: Any) :: t@ is equivalent to @x@ and safe.
+--
+-- The same is true for *all* types when using
+-- @
+--   unsafeCoerce# :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
+--                   (a :: TYPE r1) (b :: TYPE r2).
+--                   a -> b
+-- @
+-- but /only/ if you instantiate @r1@ and @r2@ to the /same/ runtime representation.
+-- For example using @(unsafeCoerce# :: forall (a :: TYPE IntRep) (b :: TYPE IntRep). a -> b) x@
+-- is fine, but @(unsafeCoerce# :: forall (a :: TYPE IntRep) (b :: TYPE FloatRep). a -> b)@
+-- will likely cause seg-faults or worse.
+-- For this resason, users should always prefer unsafeCoerce over unsafeCoerce# when possible.
+--
+-- Here are some more examples:
+-- @
+--    bad_a1 :: Any @(TYPE 'IntRep)
+--    bad_a1 = unsafeCoerce# True
+--
+--    bad_a2 :: Any @(TYPE ('BoxedRep 'UnliftedRep))
+--    bad_a2 = unsafeCoerce# True
+-- @
+-- Here @bad_a1@ is bad because we started with @True :: (Bool :: Type)@, represented by a boxed heap pointer,
+-- and coerced it to @a1 :: Any @(TYPE 'IntRep)@, whose representation is a non-pointer integer.
+-- That's why we had to use `unsafeCoerce#`; it is really unsafe because it can change representations.
+-- Similarly @bad_a2@ is bad because although both @True@ and @bad_a2@ are represented by a heap pointer,
+-- @True@ is lifted but @bad_a2@ is not; bugs here may be rather subtle.
+--
+-- If you must use unsafeCoerce# to cast to `Any`, type annotations are recommended
+-- to make sure that @Any@ has the correct kind. As casting between different runtimereps is
+-- unsound. For example to cast a @ByteArray#@ to @Any@ you might use:
+-- @
+--    unsafeCoerce# b :: (Any :: TYPE ('BoxedRep 'Unlifted))
+-- @
+type family Any :: k where { }
+-- See Note [Any types] in GHC.Builtin.Types. Also, for a bit of history on Any see
+-- #10886. Note that this must be a *closed* type family: we need to ensure
+-- that this can't reduce to a `data` type for the results discussed in
+-- Note [Any types].
+
+{- *********************************************************************
+*                                                                      *
+                  Lists
+
+   NB: lists are built-in syntax, and hence not explicitly exported
+*                                                                      *
+********************************************************************* -}
+
+-- | The builtin linked list type.
+--
+-- In Haskell, lists are one of the most important data types as they are
+-- often used analogous to loops in imperative programming languages.
+-- These lists are singly linked, which makes them unsuited for operations
+-- that require \(\mathcal{O}(1)\) access. Instead, they are intended to
+-- be traversed.
+--
+-- You can use @List a@ or @[a]@ in type signatures:
+--
+-- > length :: [a] -> Int
+--
+-- or
+--
+-- > length :: List a -> Int
+--
+-- They are fully equivalent, and @List a@ will be normalised to @[a]@.
+--
+-- ==== Usage
+--
+-- Lists are constructed recursively using the right-associative constructor operator (or /cons/)
+-- @(:) :: a -> [a] -> [a]@, which prepends an element to a list,
+-- and the empty list @[]@.
+--
+-- @
+-- (1 : 2 : 3 : []) == (1 : (2 : (3 : []))) == [1, 2, 3]
+-- @
+--
+-- Lists can also be constructed using list literals
+-- of the form @[x_1, x_2, ..., x_n]@
+-- which are syntactic sugar and, unless @-XOverloadedLists@ is enabled,
+-- are translated into uses of @(:)@ and @[]@
+--
+-- 'Data.String.String' literals, like @"I &#x1F49C; hs"@, are translated into
+-- Lists of characters, @[\'I\', \' \', \'&#x1F49C;\', \' \', \'h\', \'s\']@.
+--
+-- ==== __Implementation__
+--
+-- Internally and in memory, all the above are represented like this,
+-- with arrows being pointers to locations in memory.
+--
+-- > ╭───┬───┬──╮   ╭───┬───┬──╮   ╭───┬───┬──╮   ╭────╮
+-- > │(:)│   │ ─┼──>│(:)│   │ ─┼──>│(:)│   │ ─┼──>│ [] │
+-- > ╰───┴─┼─┴──╯   ╰───┴─┼─┴──╯   ╰───┴─┼─┴──╯   ╰────╯
+-- >       v              v              v
+-- >       1              2              3
+--
+-- ==== __Examples__
+--
+-- @
+-- >>> [\'H\', \'a\', \'s\', \'k\', \'e\', \'l\', \'l\']
+-- \"Haskell\"
+-- @
+--
+-- @
+-- >>> 1 : [4, 1, 5, 9]
+-- [1,4,1,5,9]
+-- @
+--
+-- @
+-- >>> [] : [] : []
+-- [[],[]]
+-- @
+--
+-- @since 0.10.0
+--
+data List a = [] | a : List a
+
+
+{- *********************************************************************
+*                                                                      *
+                  Ordering
+*                                                                      *
+********************************************************************* -}
+
+data Ordering = LT | EQ | GT
+
+
+{- *********************************************************************
+*                                                                      *
+                  Int, Char, Word, Float, Double
+*                                                                      *
+********************************************************************* -}
+
+{- | The character type 'Char' represents Unicode codespace
+and its elements are code points as in definitions
+[D9 and D10 of the Unicode Standard](https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf#G2212).
+
+Character literals in Haskell are single-quoted: @\'Q\'@, @\'Я\'@ or @\'Ω\'@.
+To represent a single quote itself use @\'\\''@, and to represent a backslash
+use @\'\\\\\'@. The full grammar can be found in the section 2.6 of the
+[Haskell 2010 Language Report](https://www.haskell.org/definition/haskell2010.pdf#section.2.6).
+
+To specify a character by its code point one can use decimal, hexadecimal
+or octal notation: @\'\\65\'@, @\'\\x41\'@ and @\'\\o101\'@ are all alternative forms
+of @\'A\'@. The largest code point is @\'\\x10ffff\'@.
+
+There is a special escape syntax for ASCII control characters:
+
++-------------+-------------------+---------------------------+
+| Escape      | Alternatives      | Meaning                   |
++=============+===================+===========================+
+| @'\\NUL'@   | @'\\0'@           | null character            |
++-------------+-------------------+---------------------------+
+| @'\\SOH'@   | @'\\1'@           | start of heading          |
++-------------+-------------------+---------------------------+
+| @'\\STX'@   | @'\\2'@           | start of text             |
++-------------+-------------------+---------------------------+
+| @'\\ETX'@   | @'\\3'@           | end of text               |
++-------------+-------------------+---------------------------+
+| @'\\EOT'@   | @'\\4'@           | end of transmission       |
++-------------+-------------------+---------------------------+
+| @'\\ENQ'@   | @'\\5'@           | enquiry                   |
++-------------+-------------------+---------------------------+
+| @'\\ACK'@   | @'\\6'@           | acknowledge               |
++-------------+-------------------+---------------------------+
+| @'\\BEL'@   | @'\\7'@, @'\\a'@  | bell (alert)              |
++-------------+-------------------+---------------------------+
+| @'\\BS'@    | @'\\8'@, @'\\b'@  | backspace                 |
++-------------+-------------------+---------------------------+
+| @'\\HT'@    | @'\\9'@, @'\\t'@  | horizontal tab            |
++-------------+-------------------+---------------------------+
+| @'\\LF'@    | @'\\10'@, @'\\n'@ | line feed (new line)      |
++-------------+-------------------+---------------------------+
+| @'\\VT'@    | @'\\11'@, @'\\v'@ | vertical tab              |
++-------------+-------------------+---------------------------+
+| @'\\FF'@    | @'\\12'@, @'\\f'@ | form feed                 |
++-------------+-------------------+---------------------------+
+| @'\\CR'@    | @'\\13'@, @'\\r'@ | carriage return           |
++-------------+-------------------+---------------------------+
+| @'\\SO'@    | @'\\14'@          | shift out                 |
++-------------+-------------------+---------------------------+
+| @'\\SI'@    | @'\\15'@          | shift in                  |
++-------------+-------------------+---------------------------+
+| @'\\DLE'@   | @'\\16'@          | data link escape          |
++-------------+-------------------+---------------------------+
+| @'\\DC1'@   | @'\\17'@          | device control 1          |
++-------------+-------------------+---------------------------+
+| @'\\DC2'@   | @'\\18'@          | device control 2          |
++-------------+-------------------+---------------------------+
+| @'\\DC3'@   | @'\\19'@          | device control 3          |
++-------------+-------------------+---------------------------+
+| @'\\DC4'@   | @'\\20'@          | device control 4          |
++-------------+-------------------+---------------------------+
+| @'\\NAK'@   | @'\\21'@          | negative acknowledge      |
++-------------+-------------------+---------------------------+
+| @'\\SYN'@   | @'\\22'@          | synchronous idle          |
++-------------+-------------------+---------------------------+
+| @'\\ETB'@   | @'\\23'@          | end of transmission block |
++-------------+-------------------+---------------------------+
+| @'\\CAN'@   | @'\\24'@          | cancel                    |
++-------------+-------------------+---------------------------+
+| @'\\EM'@    | @'\\25'@          | end of medium             |
++-------------+-------------------+---------------------------+
+| @'\\SUB'@   | @'\\26'@          | substitute                |
++-------------+-------------------+---------------------------+
+| @'\\ESC'@   | @'\\27'@          | escape                    |
++-------------+-------------------+---------------------------+
+| @'\\FS'@    | @'\\28'@          | file separator            |
++-------------+-------------------+---------------------------+
+| @'\\GS'@    | @'\\29'@          | group separator           |
++-------------+-------------------+---------------------------+
+| @'\\RS'@    | @'\\30'@          | record separator          |
++-------------+-------------------+---------------------------+
+| @'\\US'@    | @'\\31'@          | unit separator            |
++-------------+-------------------+---------------------------+
+| @'\\SP'@    | @'\\32'@, @' '@   | space                     |
++-------------+-------------------+---------------------------+
+| @'\\DEL'@   | @'\\127'@         | delete                    |
++-------------+-------------------+---------------------------+
+
+[Data.Char](https://hackage.haskell.org/package/base/docs/Data-Char.html)
+provides utilities to work with 'Char'.
+
+-}
+data {-# CTYPE "HsChar" #-} Char = C# Char#
+
+-- | A fixed-precision integer type with at least the range @[-2^29 .. 2^29-1]@.
+-- The exact range for a given implementation can be determined by using
+-- 'Prelude.minBound' and 'Prelude.maxBound' from the 'Prelude.Bounded' class.
+data {-# CTYPE "HsInt" #-} Int = I# Int#
+
+-- |A 'Word' is an unsigned integral type, with the same size as 'Int'.
+data {-# CTYPE "HsWord" #-} Word = W# Word#
+
+-- | Single-precision floating point numbers.
+-- It is desirable that this type be at least equal in range and precision
+-- to the IEEE single-precision type.
+data {-# CTYPE "HsFloat" #-} Float = F# Float#
+
+-- | Double-precision floating point numbers.
+-- It is desirable that this type be at least equal in range and precision
+-- to the IEEE double-precision type.
+data {-# CTYPE "HsDouble" #-} Double = D# Double#
+
+
+{- *********************************************************************
+*                                                                      *
+                    IO
+*                                                                      *
+********************************************************************* -}
+
+{- |
+A value of type @'IO' a@ is a computation which, when performed,
+does some I\/O before returning a value of type @a@.
+
+There is really only one way to \"perform\" an I\/O action: bind it to
+@Main.main@ in your program.  When your program is run, the I\/O will
+be performed.  It isn't possible to perform I\/O from an arbitrary
+function, unless that function is itself in the 'IO' monad and called
+at some point, directly or indirectly, from @Main.main@.
+
+'IO' is a monad, so 'IO' actions can be combined using either the do-notation
+or the 'Prelude.>>' and 'Prelude.>>=' operations from the 'Prelude.Monad'
+class.
+-}
+newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
+
+
+{- *********************************************************************
+*                                                                      *
+                    (~) and Coercible
+
+*                                                                      *
+********************************************************************* -}
+
+{-
+Note [Kind-changing of (~) and Coercible]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+(~) and Coercible are tricky to define. To the user, they must appear as
+constraints, but we cannot define them as such in Haskell. But we also cannot
+just define them only in GHC.Internal.Prim (like (->)), because we need a real module
+for them, e.g. to compile the constructor's info table.
+
+Furthermore the type of MkCoercible cannot be written in Haskell
+(no syntax for ~#R).
+
+So we define them as regular data types in GHC.Internal.Types, and do magic in GHC.Builtin.Types,
+inside GHC, to change the kind and type.
+-}
+
+
+-- | Lifted, heterogeneous equality. By lifted, we mean that it
+-- can be bogus (deferred type error). By heterogeneous, the two
+-- types @a@ and @b@ might have different kinds. Because @~~@ can
+-- appear unexpectedly in error messages to users who do not care
+-- about the difference between heterogeneous equality @~~@ and
+-- homogeneous equality @~@, this is printed as @~@ unless
+-- @-fprint-equality-relations@ is set.
+--
+-- In @0.7.0@, the fixity was set to @infix 4@ to match the fixity of 'Data.Type.Equality.:~~:'.
+class a ~~ b
+
+  -- See also Note [The equality types story] in GHC.Builtin.Types.Prim
+
+-- | Lifted, homogeneous equality. By lifted, we mean that it
+-- can be bogus (deferred type error). By homogeneous, the two
+-- types @a@ and @b@ must have the same kinds.
+
+-- In @0.7.0@, the fixity was set to @infix 4@ to match the fixity of 'Data.Type.Equality.:~:'.
+class a ~ b
+
+infix 4 ~, ~~
+  -- See also Note [The equality types story] in GHC.Builtin.Types.Prim
+
+-- | @Coercible@ is a two-parameter class that has instances for types @a@ and @b@ if
+--      the compiler can infer that they have the same representation. This class
+--      does not have regular instances; instead they are created on-the-fly during
+--      type-checking. Trying to manually declare an instance of @Coercible@
+--      is an error.
+--
+--      Nevertheless one can pretend that the following three kinds of instances
+--      exist. First, as a trivial base-case:
+--
+--      @instance Coercible a a@
+--
+--      Furthermore, for every type constructor there is
+--      an instance that allows to coerce under the type constructor. For
+--      example, let @D@ be a prototypical type constructor (@data@ or
+--      @newtype@) with three type arguments, which have roles @nominal@,
+--      @representational@ resp. @phantom@. Then there is an instance of
+--      the form
+--
+--      @instance Coercible b b\' => Coercible (D a b c) (D a b\' c\')@
+--
+--      Note that the @nominal@ type arguments are equal, the
+--      @representational@ type arguments can differ, but need to have a
+--      @Coercible@ instance themself, and the @phantom@ type arguments can be
+--      changed arbitrarily.
+--
+--      The third kind of instance exists for every @newtype NT = MkNT T@ and
+--      comes in two variants, namely
+--
+--      @instance Coercible a T => Coercible a NT@
+--
+--      @instance Coercible T b => Coercible NT b@
+--
+--      This instance is only usable if the constructor @MkNT@ is in scope.
+--
+--      If, as a library author of a type constructor like @Set a@, you
+--      want to prevent a user of your module to write
+--      @coerce :: Set T -> Set NT@,
+--      you need to set the role of @Set@\'s type parameter to @nominal@,
+--      by writing
+--
+--      @type role Set nominal@
+--
+--      For more details about this feature, please refer to
+--      <http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/coercible.pdf Safe Coercions>
+--      by Joachim Breitner, Richard A. Eisenberg, Simon Peyton Jones and Stephanie Weirich.
+--
+-- @since 0.4.0
+class Coercible (a :: k) (b :: k)
+  -- See also Note [The equality types story] in GHC.Builtin.Types.Prim
+
+{- *********************************************************************
+*                                                                      *
+                   Bool, and isTrue#
+*                                                                      *
+********************************************************************* -}
+
+data {-# CTYPE "HsBool" #-} Bool = False | True
+
+{-# INLINE isTrue# #-}
+-- | Alias for 'tagToEnum#'. Returns True if its parameter is 1# and False
+--   if it is 0#.
+isTrue# :: Int# -> Bool   -- See Note [Optimizing isTrue#]
+isTrue# x = tagToEnum# x
+
+{- Note [Optimizing isTrue#]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Current definition of isTrue# is a temporary workaround. We would like to
+have functions isTrue# and isFalse# defined like this:
+
+    isTrue# :: Int# -> Bool
+    isTrue# 1# = True
+    isTrue# _  = False
+
+    isFalse# :: Int# -> Bool
+    isFalse# 0# = True
+    isFalse# _  = False
+
+These functions would allow us to safely check if a tag can represent True
+or False. Using isTrue# and isFalse# as defined above will not introduce
+additional case into the code. When we scrutinize return value of isTrue#
+or isFalse#, either explicitly in a case expression or implicitly in a guard,
+the result will always be a single case expression (given that optimizations
+are turned on). This results from case-of-case transformation. Consider this
+code (this is both valid Haskell and Core):
+
+case isTrue# (a ># b) of
+    True  -> e1
+    False -> e2
+
+Inlining isTrue# gives:
+
+case (case (a ># b) of { 1# -> True; _ -> False } ) of
+    True  -> e1
+    False -> e2
+
+Case-of-case transforms that to:
+
+case (a ># b) of
+  1# -> case True of
+          True  -> e1
+          False -> e2
+  _  -> case False of
+          True  -> e1
+          False -> e2
+
+Which is then simplified by case-of-known-constructor:
+
+case (a ># b) of
+  1# -> e1
+  _  -> e2
+
+While we get good Core here, the code generator will generate very bad Cmm
+if e1 or e2 do allocation. It will push heap checks into case alternatives
+which results in about 2.5% increase in code size. Until this is improved we
+just make isTrue# an alias to tagToEnum#. This is a temporary solution (if
+you're reading this in 2023 then things went wrong). See #8326.
+-}
+
+
+{- *********************************************************************
+*                                                                      *
+                    SPEC
+*                                                                      *
+********************************************************************* -}
+
+-- | 'SPEC' is used by GHC in the @SpecConstr@ pass in order to inform
+-- the compiler when to be particularly aggressive. In particular, it
+-- tells GHC to specialize regardless of size or the number of
+-- specializations. However, not all loops fall into this category.
+--
+-- Libraries can specify this by using 'SPEC' data type to inform which
+-- loops should be aggressively specialized. For example,
+-- instead of
+--
+-- > loop x where loop arg = ...
+--
+-- write
+--
+-- > loop SPEC x where loop !_ arg = ...
+--
+-- There is no semantic difference between 'SPEC' and 'SPEC2',
+-- we just need a type with two constructors lest it is optimised away
+-- before @SpecConstr@.
+--
+-- This type is reexported from "GHC.Exts" since GHC 9.0 and @base-4.15@.
+-- For compatibility with earlier releases import it from "GHC.Internal.Types"
+-- in @ghc-internal@ package.
+--
+-- @since 0.3.1.0
+--
+data SPEC = SPEC | SPEC2
+
+
+{- *********************************************************************
+*                                                                      *
+                    Levity polymorphism
+*                                                                      *
+********************************************************************* -}
+
+-- | Whether a boxed type is lifted or unlifted.
+data Levity = Lifted | Unlifted
+
+-- | GHC maintains a property that the kind of all inhabited types
+-- (as distinct from type constructors or type-level data) tells us
+-- the runtime representation of values of that type. This datatype
+-- encodes the choice of runtime value.
+-- Note that 'TYPE' is parameterised by 'RuntimeRep'; this is precisely
+-- what we mean by the fact that a type's kind encodes the runtime
+-- representation.
+--
+-- For boxed values (that is, values that are represented by a pointer),
+-- a further distinction is made, between lifted types (that contain ⊥),
+-- and unlifted ones (that don't).
+data RuntimeRep = VecRep VecCount VecElem   -- ^ a SIMD vector type
+                | TupleRep [RuntimeRep]     -- ^ An unboxed tuple of the given reps
+                | SumRep [RuntimeRep]       -- ^ An unboxed sum of the given reps
+                | BoxedRep Levity -- ^ boxed; represented by a pointer
+                | IntRep          -- ^ signed, word-sized value
+                | Int8Rep         -- ^ signed,  8-bit value
+                | Int16Rep        -- ^ signed, 16-bit value
+                | Int32Rep        -- ^ signed, 32-bit value
+                | Int64Rep        -- ^ signed, 64-bit value
+                | WordRep         -- ^ unsigned, word-sized value
+                | Word8Rep        -- ^ unsigned,  8-bit value
+                | Word16Rep       -- ^ unsigned, 16-bit value
+                | Word32Rep       -- ^ unsigned, 32-bit value
+                | Word64Rep       -- ^ unsigned, 64-bit value
+                | AddrRep         -- ^ A pointer, but /not/ to a Haskell value
+                | FloatRep        -- ^ a 32-bit floating point number
+                | DoubleRep       -- ^ a 64-bit floating point number
+
+-- RuntimeRep is intimately tied to TyCon.RuntimeRep (in GHC proper). See
+-- Note [RuntimeRep and PrimRep] in RepType.
+-- See also Note [Wiring in RuntimeRep] in GHC.Builtin.Types
+-- See also Note [TYPE and CONSTRAINT] in GHC.Builtin.Type.Prim
+
+-- | Length of a SIMD vector type
+data VecCount = Vec2
+              | Vec4
+              | Vec8
+              | Vec16
+              | Vec32
+              | Vec64
+-- Enum, Bounded instances in GHC.Internal.Enum
+
+-- | Element of a SIMD vector type
+data VecElem = Int8ElemRep
+             | Int16ElemRep
+             | Int32ElemRep
+             | Int64ElemRep
+             | Word8ElemRep
+             | Word16ElemRep
+             | Word32ElemRep
+             | Word64ElemRep
+             | FloatElemRep
+             | DoubleElemRep
+-- Enum, Bounded instances in GHC.Internal.Enum
+
+{-# DEPRECATED Void# "Void# is now an alias for the unboxed tuple (# #)." #-}
+type Void# = (# #)
+
+{- *********************************************************************
+*                                                                      *
+             Boxing data constructors
+*                                                                      *
+********************************************************************* -}
+
+-- These "boxing" data types allow us to wrap up a value of kind (TYPE rr)
+-- in a box of kind Type, for each rr.
+data LiftBox   (a :: TYPE UnliftedRep) = MkLiftBox a
+
+data IntBox    (a :: TYPE IntRep)      = MkIntBox a
+data Int8Box   (a :: TYPE Int8Rep)     = MkInt8Box a
+data Int16Box  (a :: TYPE Int16Rep)    = MkInt16Box a
+data Int32Box  (a :: TYPE Int32Rep)    = MkInt32Box a
+data Int64Box  (a :: TYPE Int64Rep)    = MkInt64Box a
+
+data WordBox   (a :: TYPE WordRep)     = MkWordBox a
+data Word8Box  (a :: TYPE Word8Rep)    = MkWord8Box a
+data Word16Box (a :: TYPE Word16Rep)   = MkWord16Box a
+data Word32Box (a :: TYPE Word32Rep)   = MkWord32Box a
+data Word64Box (a :: TYPE Word64Rep)   = MkWord64Box a
+
+data FloatBox  (a :: TYPE FloatRep)    = MkFloatBox a
+data DoubleBox (a :: TYPE DoubleRep)   = MkDoubleBox a
+
+-- | Data type `Dict` provides a simple way to wrap up a (lifted)
+--   constraint as a type
+data DictBox c where
+  MkDictBox :: c => DictBox c
+
+
+{- *********************************************************************
+*                                                                      *
+             Runtime representation of TyCon
+*                                                                      *
+********************************************************************* -}
+
+{- Note [Runtime representation of modules and tycons]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We generate a binding for M.$modName and M.$tcT for every module M and
+data type T.  Things to think about
+
+  - We want them to be economical on space; ideally pure data with no thunks.
+
+  - We do this for every module (except this module GHC.Internal.Types), so we can't
+    depend on anything else (eg string unpacking code)
+
+That's why we have these terribly low-level representations.  The TrName
+type lets us use the TrNameS constructor when allocating static data;
+but we also need TrNameD for the case where we are deserialising a TyCon
+or Module (for example when deserialising a TypeRep), in which case we
+can't conveniently come up with an Addr#.
+-}
+
+#include "MachDeps.h"
+
+data Module = Module
+                TrName   -- ^ Package name
+                TrName   -- ^ Module name
+
+data TrName
+  = TrNameS Addr#  -- ^ Static
+  | TrNameD [Char] -- ^ Dynamic
+
+-- | A de Bruijn index for a binder within a 'KindRep'.
+type KindBndr = Int
+
+-- | The representation produced by GHC for conjuring up the kind of a
+-- 'Data.Typeable.TypeRep'.
+
+-- See Note [Representing TyCon kinds: KindRep] in GHC.Tc.Instance.Typeable.
+data KindRep = KindRepTyConApp TyCon [KindRep]
+             | KindRepVar !KindBndr
+             | KindRepApp KindRep KindRep
+             | KindRepFun KindRep KindRep
+             | KindRepTYPE !RuntimeRep
+             | KindRepTypeLitS TypeLitSort Addr#
+             | KindRepTypeLitD TypeLitSort [Char]
+
+data TypeLitSort = TypeLitSymbol
+                 | TypeLitNat
+                 | TypeLitChar
+
+-- Show instance for TyCon found in GHC.Internal.Show
+data TyCon = TyCon Word64#    -- ^ Fingerprint (high)
+                   Word64#    -- ^ Fingerprint (low)
+                   Module     -- ^ Module in which this is defined
+                   TrName     -- ^ Type constructor name
+                   Int#       -- ^ How many kind variables do we accept?
+                   KindRep    -- ^ A representation of the type's kind
+
+{- *********************************************************************
+*                                                                      *
+             Unboxed tuples and sums
+*                                                                      *
+********************************************************************* -}
+
+type Unit# :: TYPE (TupleRep '[])
+data Unit# = (# #)
+
+type Solo# :: TYPE rep -> TYPE (TupleRep '[rep])
+data Solo# a = MkSolo# a
+
+type Tuple0# = Unit#
+type Tuple1# = Solo#
+
+type Tuple2# :: TYPE r1 -> TYPE r2 -> TYPE (TupleRep [r1, r2])
+data Tuple2# a b =
+  (# a,b #)
+type Tuple3# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE (TupleRep [r1, r2, r3])
+data Tuple3# a b c =
+  (# a,b,c #)
+type Tuple4# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE (TupleRep [r1, r2, r3, r4])
+data Tuple4# a b c d =
+  (# a,b,c,d #)
+type Tuple5# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE (TupleRep [r1, r2, r3, r4, r5])
+data Tuple5# a b c d e =
+  (# a,b,c,d,e #)
+type Tuple6# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6])
+data Tuple6# a b c d e f =
+  (# a,b,c,d,e,f #)
+type Tuple7# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7])
+data Tuple7# a b c d e f g =
+  (# a,b,c,d,e,f,g #)
+type Tuple8# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8])
+data Tuple8# a b c d e f g h =
+  (# a,b,c,d,e,f,g,h #)
+type Tuple9# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9])
+data Tuple9# a b c d e f g h i =
+  (# a,b,c,d,e,f,g,h,i #)
+type Tuple10# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10])
+data Tuple10# a b c d e f g h i j =
+  (# a,b,c,d,e,f,g,h,i,j #)
+type Tuple11# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11])
+data Tuple11# a b c d e f g h i j k =
+  (# a,b,c,d,e,f,g,h,i,j,k #)
+type Tuple12# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12])
+data Tuple12# a b c d e f g h i j k l =
+  (# a,b,c,d,e,f,g,h,i,j,k,l #)
+type Tuple13# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13])
+data Tuple13# a b c d e f g h i j k l m =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m #)
+type Tuple14# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14])
+data Tuple14# a b c d e f g h i j k l m n =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n #)
+type Tuple15# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15])
+data Tuple15# a b c d e f g h i j k l m n o =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o #)
+type Tuple16# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16])
+data Tuple16# a b c d e f g h i j k l m n o p =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p #)
+type Tuple17# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17])
+data Tuple17# a b c d e f g h i j k l m n o p q =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q #)
+type Tuple18# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18])
+data Tuple18# a b c d e f g h i j k l m n o p q r =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r #)
+type Tuple19# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19])
+data Tuple19# a b c d e f g h i j k l m n o p q r s =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s #)
+type Tuple20# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20])
+data Tuple20# a b c d e f g h i j k l m n o p q r s t =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t #)
+type Tuple21# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21])
+data Tuple21# a b c d e f g h i j k l m n o p q r s t u =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u #)
+type Tuple22# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22])
+data Tuple22# a b c d e f g h i j k l m n o p q r s t u v =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v #)
+type Tuple23# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23])
+data Tuple23# a b c d e f g h i j k l m n o p q r s t u v w =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w #)
+type Tuple24# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24])
+data Tuple24# a b c d e f g h i j k l m n o p q r s t u v w x =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x #)
+type Tuple25# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25])
+data Tuple25# a b c d e f g h i j k l m n o p q r s t u v w x y =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y #)
+type Tuple26# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26])
+data Tuple26# a b c d e f g h i j k l m n o p q r s t u v w x y z =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z #)
+type Tuple27# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27])
+data Tuple27# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1 #)
+type Tuple28# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28])
+data Tuple28# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1 #)
+type Tuple29# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29])
+data Tuple29# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1 #)
+type Tuple30# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30])
+data Tuple30# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1 #)
+type Tuple31# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31])
+data Tuple31# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1 #)
+type Tuple32# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32])
+data Tuple32# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1 #)
+type Tuple33# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33])
+data Tuple33# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1 #)
+type Tuple34# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34])
+data Tuple34# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1 #)
+type Tuple35# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35])
+data Tuple35# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1 #)
+type Tuple36# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36])
+data Tuple36# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1 #)
+type Tuple37# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37])
+data Tuple37# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1 #)
+type Tuple38# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38])
+data Tuple38# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1 #)
+type Tuple39# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39])
+data Tuple39# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1 #)
+type Tuple40# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40])
+data Tuple40# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1 #)
+type Tuple41# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41])
+data Tuple41# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1 #)
+type Tuple42# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42])
+data Tuple42# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1 #)
+type Tuple43# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43])
+data Tuple43# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1 #)
+type Tuple44# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44])
+data Tuple44# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1 #)
+type Tuple45# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45])
+data Tuple45# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1 #)
+type Tuple46# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46])
+data Tuple46# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1 #)
+type Tuple47# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47])
+data Tuple47# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1 #)
+type Tuple48# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48])
+data Tuple48# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1 #)
+type Tuple49# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49])
+data Tuple49# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1 #)
+type Tuple50# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50])
+data Tuple50# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1 #)
+type Tuple51# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51])
+data Tuple51# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1 #)
+type Tuple52# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52])
+data Tuple52# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1 #)
+type Tuple53# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53])
+data Tuple53# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2 #)
+type Tuple54# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54])
+data Tuple54# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2 #)
+type Tuple55# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55])
+data Tuple55# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2 #)
+type Tuple56# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 -> TYPE r56 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56])
+data Tuple56# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2,d2 #)
+type Tuple57# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 -> TYPE r56 -> TYPE r57 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57])
+data Tuple57# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2 #)
+type Tuple58# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58])
+data Tuple58# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2 #)
+type Tuple59# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59])
+data Tuple59# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2 #)
+type Tuple60# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE r60 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60])
+data Tuple60# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2 #)
+type Tuple61# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE r60 -> TYPE r61 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60, r61])
+data Tuple61# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2,i2 #)
+type Tuple62# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE r60 -> TYPE r61 -> TYPE r62 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60, r61, r62])
+data Tuple62# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2 #)
+type Tuple63# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE r60 -> TYPE r61 -> TYPE r62 -> TYPE r63 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60, r61, r62, r63])
+data Tuple63# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2 #)
+type Tuple64# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 ->
+  TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 ->
+  TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 ->
+  TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 ->
+  TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 ->
+  TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 ->
+  TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE r60 -> TYPE r61 -> TYPE r62 -> TYPE r63 -> TYPE r64 ->
+  TYPE (TupleRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22,
+  r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45,
+  r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60, r61, r62, r63, r64])
+data Tuple64# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1
+     r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2 =
+  (# a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,
+     u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2 #)
+
+{-
+Note [Unboxed sum with arity 64]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+While tuples are defined up to arity 64, sums can maximally have 63 alternatives.
+This is due to the Unique layout for unboxed sums, which allots only six bits
+for encoding the alternative.
+-}
+
+type Sum2# :: TYPE r1 -> TYPE r2 -> TYPE (SumRep [r1, r2])
+data Sum2# a b =
+    (# a | #)
+  | (# | b #)
+
+type Sum3# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE (SumRep [r1, r2, r3])
+data Sum3# a b c =
+    (# a | | #)
+  | (# | b | #)
+  | (# | | c #)
+
+type Sum4# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE (SumRep [r1, r2, r3, r4])
+data Sum4# a b c d =
+    (# a | | | #)
+  | (# | b | | #)
+  | (# | | c | #)
+  | (# | | | d #)
+
+type Sum5# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE (SumRep [r1, r2, r3, r4, r5])
+data Sum5# a b c d e =
+    (# a | | | | #)
+  | (# | b | | | #)
+  | (# | | c | | #)
+  | (# | | | d | #)
+  | (# | | | | e #)
+
+type Sum6# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6])
+data Sum6# a b c d e f =
+    (# a | | | | | #)
+  | (# | b | | | | #)
+  | (# | | c | | | #)
+  | (# | | | d | | #)
+  | (# | | | | e | #)
+  | (# | | | | | f #)
+
+type Sum7# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7])
+data Sum7# a b c d e f g =
+    (# a | | | | | | #)
+  | (# | b | | | | | #)
+  | (# | | c | | | | #)
+  | (# | | | d | | | #)
+  | (# | | | | e | | #)
+  | (# | | | | | f | #)
+  | (# | | | | | | g #)
+
+type Sum8# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8])
+data Sum8# a b c d e f g h =
+    (# a | | | | | | | #)
+  | (# | b | | | | | | #)
+  | (# | | c | | | | | #)
+  | (# | | | d | | | | #)
+  | (# | | | | e | | | #)
+  | (# | | | | | f | | #)
+  | (# | | | | | | g | #)
+  | (# | | | | | | | h #)
+
+type Sum9# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9])
+data Sum9# a b c d e f g h i =
+    (# a | | | | | | | | #)
+  | (# | b | | | | | | | #)
+  | (# | | c | | | | | | #)
+  | (# | | | d | | | | | #)
+  | (# | | | | e | | | | #)
+  | (# | | | | | f | | | #)
+  | (# | | | | | | g | | #)
+  | (# | | | | | | | h | #)
+  | (# | | | | | | | | i #)
+
+type Sum10# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10])
+data Sum10# a b c d e f g h i j =
+    (# a | | | | | | | | | #)
+  | (# | b | | | | | | | | #)
+  | (# | | c | | | | | | | #)
+  | (# | | | d | | | | | | #)
+  | (# | | | | e | | | | | #)
+  | (# | | | | | f | | | | #)
+  | (# | | | | | | g | | | #)
+  | (# | | | | | | | h | | #)
+  | (# | | | | | | | | i | #)
+  | (# | | | | | | | | | j #)
+
+type Sum11# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11])
+data Sum11# a b c d e f g h i j k =
+    (# a | | | | | | | | | | #)
+  | (# | b | | | | | | | | | #)
+  | (# | | c | | | | | | | | #)
+  | (# | | | d | | | | | | | #)
+  | (# | | | | e | | | | | | #)
+  | (# | | | | | f | | | | | #)
+  | (# | | | | | | g | | | | #)
+  | (# | | | | | | | h | | | #)
+  | (# | | | | | | | | i | | #)
+  | (# | | | | | | | | | j | #)
+  | (# | | | | | | | | | | k #)
+
+type Sum12# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12])
+data Sum12# a b c d e f g h i j k l =
+    (# a | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | #)
+  | (# | | | d | | | | | | | | #)
+  | (# | | | | e | | | | | | | #)
+  | (# | | | | | f | | | | | | #)
+  | (# | | | | | | g | | | | | #)
+  | (# | | | | | | | h | | | | #)
+  | (# | | | | | | | | i | | | #)
+  | (# | | | | | | | | | j | | #)
+  | (# | | | | | | | | | | k | #)
+  | (# | | | | | | | | | | | l #)
+
+type Sum13# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13])
+data Sum13# a b c d e f g h i j k l m =
+    (# a | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | #)
+  | (# | | | | | f | | | | | | | #)
+  | (# | | | | | | g | | | | | | #)
+  | (# | | | | | | | h | | | | | #)
+  | (# | | | | | | | | i | | | | #)
+  | (# | | | | | | | | | j | | | #)
+  | (# | | | | | | | | | | k | | #)
+  | (# | | | | | | | | | | | l | #)
+  | (# | | | | | | | | | | | | m #)
+
+type Sum14# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14])
+data Sum14# a b c d e f g h i j k l m n =
+    (# a | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | #)
+  | (# | | | | | | | h | | | | | | #)
+  | (# | | | | | | | | i | | | | | #)
+  | (# | | | | | | | | | j | | | | #)
+  | (# | | | | | | | | | | k | | | #)
+  | (# | | | | | | | | | | | l | | #)
+  | (# | | | | | | | | | | | | m | #)
+  | (# | | | | | | | | | | | | | n #)
+
+type Sum15# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15])
+data Sum15# a b c d e f g h i j k l m n o =
+    (# a | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | #)
+  | (# | | | | | | | | | j | | | | | #)
+  | (# | | | | | | | | | | k | | | | #)
+  | (# | | | | | | | | | | | l | | | #)
+  | (# | | | | | | | | | | | | m | | #)
+  | (# | | | | | | | | | | | | | n | #)
+  | (# | | | | | | | | | | | | | | o #)
+
+type Sum16# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16])
+data Sum16# a b c d e f g h i j k l m n o p =
+    (# a | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | #)
+  | (# | | | | | | | | | | | l | | | | #)
+  | (# | | | | | | | | | | | | m | | | #)
+  | (# | | | | | | | | | | | | | n | | #)
+  | (# | | | | | | | | | | | | | | o | #)
+  | (# | | | | | | | | | | | | | | | p #)
+
+type Sum17# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17])
+data Sum17# a b c d e f g h i j k l m n o p q =
+    (# a | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | #)
+  | (# | | | | | | | | | | | | | n | | | #)
+  | (# | | | | | | | | | | | | | | o | | #)
+  | (# | | | | | | | | | | | | | | | p | #)
+  | (# | | | | | | | | | | | | | | | | q #)
+
+type Sum18# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18])
+data Sum18# a b c d e f g h i j k l m n o p q r =
+    (# a | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | #)
+  | (# | | | | | | | | | | | | | | | p | | #)
+  | (# | | | | | | | | | | | | | | | | q | #)
+  | (# | | | | | | | | | | | | | | | | | r #)
+
+type Sum19# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19])
+data Sum19# a b c d e f g h i j k l m n o p q r s =
+    (# a | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | #)
+  | (# | | | | | | | | | | | | | | | | | r | #)
+  | (# | | | | | | | | | | | | | | | | | | s #)
+
+type Sum20# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20])
+data Sum20# a b c d e f g h i j k l m n o p q r s t =
+    (# a | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | #)
+  | (# | | | | | | | | | | | | | | | | | | | t #)
+
+type Sum21# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21])
+data Sum21# a b c d e f g h i j k l m n o p q r s t u =
+    (# a | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u #)
+
+type Sum22# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22])
+data Sum22# a b c d e f g h i j k l m n o p q r s t u v =
+    (# a | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v #)
+
+type Sum23# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23])
+data Sum23# a b c d e f g h i j k l m n o p q r s t u v w =
+    (# a | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w #)
+
+type Sum24# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24])
+data Sum24# a b c d e f g h i j k l m n o p q r s t u v w x =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x #)
+
+type Sum25# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25])
+data Sum25# a b c d e f g h i j k l m n o p q r s t u v w x y =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y #)
+
+type Sum26# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26])
+data Sum26# a b c d e f g h i j k l m n o p q r s t u v w x y z =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z #)
+
+type Sum27# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27])
+data Sum27# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 #)
+
+type Sum28# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28])
+data Sum28# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 #)
+
+type Sum29# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29])
+data Sum29# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 #)
+
+type Sum30# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30])
+data Sum30# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 #)
+
+type Sum31# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31])
+data Sum31# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 #)
+
+type Sum32# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32])
+data Sum32# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 #)
+
+type Sum33# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33])
+data Sum33# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 #)
+
+type Sum34# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34])
+data Sum34# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 #)
+
+type Sum35# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35])
+data Sum35# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 #)
+
+type Sum36# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36])
+data Sum36# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 #)
+
+type Sum37# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37])
+data Sum37# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 #)
+
+type Sum38# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38])
+data Sum38# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 #)
+
+type Sum39# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39])
+data Sum39# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 #)
+
+type Sum40# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40])
+data Sum40# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 #)
+
+type Sum41# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41])
+data Sum41# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 #)
+
+type Sum42# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42])
+data Sum42# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 #)
+
+type Sum43# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43])
+data Sum43# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 #)
+
+type Sum44# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44])
+data Sum44# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 #)
+
+type Sum45# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45])
+data Sum45# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 #)
+
+type Sum46# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46])
+data Sum46# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 #)
+
+type Sum47# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47])
+data Sum47# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 #)
+
+type Sum48# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48])
+data Sum48# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 #)
+
+type Sum49# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49])
+data Sum49# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 #)
+
+type Sum50# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50])
+data Sum50# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 #)
+
+type Sum51# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51])
+data Sum51# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 #)
+
+type Sum52# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52])
+data Sum52# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 #)
+
+type Sum53# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53])
+data Sum53# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 #)
+
+type Sum54# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54])
+data Sum54# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 #)
+
+type Sum55# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE r55 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54, r55])
+data Sum55# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c2 #)
+
+type Sum56# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE r55 -> TYPE r56 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56])
+data Sum56# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d2 #)
+
+type Sum57# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57])
+data Sum57# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c2 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e2 #)
+
+type Sum58# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58])
+data Sum58# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c2 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d2 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f2 #)
+
+type Sum59# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59])
+data Sum59# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c2 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d2 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e2 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g2 #)
+
+type Sum60# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE r60 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60])
+data Sum60# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c2 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d2 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e2 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f2 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h2 #)
+
+type Sum61# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE r60 -> TYPE r61 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60, r61])
+data Sum61# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c2 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d2 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e2 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f2 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g2 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i2 #)
+
+type Sum62# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE r60 -> TYPE r61 -> TYPE r62 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60, r61, r62])
+data Sum62# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c2 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d2 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e2 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f2 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g2 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h2 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j2 #)
+
+type Sum63# :: TYPE r1 -> TYPE r2 -> TYPE r3 -> TYPE r4 -> TYPE r5 -> TYPE r6 -> TYPE r7 -> TYPE r8 -> TYPE r9 -> TYPE r10 -> TYPE r11 -> TYPE r12 -> TYPE r13 -> TYPE r14 -> TYPE r15 -> TYPE r16 -> TYPE r17 -> TYPE r18 -> TYPE r19 -> TYPE r20 -> TYPE r21 -> TYPE r22 -> TYPE r23 -> TYPE r24 -> TYPE r25 -> TYPE r26 -> TYPE r27 -> TYPE r28 -> TYPE r29 -> TYPE r30 -> TYPE r31 -> TYPE r32 -> TYPE r33 -> TYPE r34 -> TYPE r35 -> TYPE r36 -> TYPE r37 -> TYPE r38 -> TYPE r39 -> TYPE r40 -> TYPE r41 -> TYPE r42 -> TYPE r43 -> TYPE r44 -> TYPE r45 -> TYPE r46 -> TYPE r47 -> TYPE r48 -> TYPE r49 -> TYPE r50 -> TYPE r51 -> TYPE r52 -> TYPE r53 -> TYPE r54 -> TYPE r55 -> TYPE r56 -> TYPE r57 -> TYPE r58 -> TYPE r59 -> TYPE r60 -> TYPE r61 -> TYPE r62 -> TYPE r63 -> TYPE (SumRep [r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60, r61, r62, r63])
+data Sum63# a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1 f1 g1 h1 i1 j1 k1 l1 m1 n1 o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 =
+    (# a | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | c | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | d | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | e | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | f | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | g | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | h | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | i | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | j | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | k | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | l | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | m | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | n | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | o | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | p | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | q | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | r | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | s | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | t | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | u | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | v | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | w | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | x | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | z | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | a1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | b1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | c1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j1 | | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k1 | | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | l1 | | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | m1 | | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n1 | | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | o1 | | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | p1 | | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | q1 | | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r1 | | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | s1 | | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t1 | | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | u1 | | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v1 | | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | w1 | | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | x1 | | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | y1 | | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | z1 | | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a2 | | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | b2 | | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | c2 | | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | d2 | | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e2 | | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f2 | | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | g2 | | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | h2 | | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | i2 | | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | j2 | #)
+  | (# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | k2 #)
diff --git a/src/GHC/Internal/Unicode/Bits.hs b/src/GHC/Internal/Unicode/Bits.hs
--- a/src/GHC/Internal/Unicode/Bits.hs
+++ b/src/GHC/Internal/Unicode/Bits.hs
@@ -32,7 +32,7 @@
 
 import GHC.Internal.Bits (finiteBitSize, popCount)
 import {-# SOURCE #-} GHC.Internal.ByteOrder
-import GHC.Prim
+import GHC.Internal.Prim
 import GHC.Internal.ST
 import GHC.Internal.Base
 import GHC.Internal.Num
diff --git a/src/GHC/Internal/Unicode/Char/DerivedCoreProperties.hs b/src/GHC/Internal/Unicode/Char/DerivedCoreProperties.hs
--- a/src/GHC/Internal/Unicode/Char/DerivedCoreProperties.hs
+++ b/src/GHC/Internal/Unicode/Char/DerivedCoreProperties.hs
@@ -1,5 +1,5 @@
 -- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell,
--- with data from: https://www.unicode.org/Public/16.0.0/ucd/DerivedCoreProperties.txt.
+-- with data from: https://www.unicode.org/Public/17.0.0/ucd/DerivedCoreProperties.txt.
 
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE MagicHash #-}
@@ -24,11 +24,11 @@
 isUppercase :: Char -> Bool
 isUppercase = \c -> let n = ord c in n >= 65 && n <= 127369 && lookupBit64 bitmap# n
   where
-    bitmap# = "\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\255\255\127\127\0\0\0\0\85\85\85\85\85\85\85\170\170\84\85\85\85\85\85\43\214\206\219\177\213\210\174\17\144\164\170\74\85\85\210\85\85\85\85\85\85\85\5\108\122\85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\69\128\64\215\254\255\251\15\0\0\0\128\28\85\85\85\144\230\255\255\255\255\255\255\0\0\0\0\0\0\85\85\85\85\1\84\85\85\85\85\85\85\171\42\85\85\85\85\85\85\85\85\85\85\85\85\254\255\255\255\127\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\255\255\255\255\255\231\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\21\64\85\85\85\85\85\85\85\85\85\85\85\85\0\255\0\63\0\255\0\255\0\63\0\170\0\255\0\0\0\0\0\0\0\0\0\15\0\15\0\15\0\31\0\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\132\56\39\62\80\61\15\192\32\0\0\0\255\255\0\0\8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\192\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\0\0\0\0\0\0\157\234\37\192\85\85\85\85\85\85\85\85\85\85\85\85\5\40\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\21\0\0\85\85\85\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84\85\84\85\85\85\85\85\85\85\0\106\85\40\69\85\85\125\95\85\245\26\65\21\0\0\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\247\255\247\55\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\208\100\222\63\0\0\0\255\255\255\3\0\0\176\231\223\31\0\0\0\123\95\252\1\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\0\255\255\255\1\0\0\0\252\255\255\7\0\0\0\240\255\255\31\0\0\0\192\255\255\127\0\0\0\0\255\255\255\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\255\255\255\3\255\255\255\3"#
+    bitmap# = "\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\255\255\127\127\0\0\0\0\85\85\85\85\85\85\85\170\170\84\85\85\85\85\85\43\214\206\219\177\213\210\174\17\144\164\170\74\85\85\210\85\85\85\85\85\85\85\5\108\122\85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\69\128\64\215\254\255\251\15\0\0\0\128\28\85\85\85\144\230\255\255\255\255\255\255\0\0\0\0\0\0\85\85\85\85\1\84\85\85\85\85\85\85\171\42\85\85\85\85\85\85\85\85\85\85\85\85\254\255\255\255\127\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\255\255\255\255\255\231\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\21\64\85\85\85\85\85\85\85\85\85\85\85\85\0\255\0\63\0\255\0\255\0\63\0\170\0\255\0\0\0\0\0\0\0\0\0\15\0\15\0\15\0\31\0\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\132\56\39\62\80\61\15\192\32\0\0\0\255\255\0\0\8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\192\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\0\0\0\0\0\0\157\234\37\192\85\85\85\85\85\85\85\85\85\85\85\85\5\40\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\21\0\0\85\85\85\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84\85\84\85\85\85\85\85\85\85\0\106\85\40\69\85\85\125\95\85\245\90\85\21\0\0\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\247\255\247\55\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\255\255\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\208\100\222\63\0\0\0\255\255\255\3\0\0\176\231\223\31\0\0\0\123\95\252\1\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\0\255\255\255\1\0\0\0\252\255\255\7\0\0\0\240\255\255\31\0\0\0\192\255\255\127\0\0\0\0\255\255\255\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\255\255\255\3\255\255\255\3"#
 
 {-# INLINE isLowercase #-}
 isLowercase :: Char -> Bool
 isLowercase = \c -> let n = ord c in n >= 97 && n <= 125251 && lookupBit64 bitmap# n
   where
-    bitmap# = "\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\4\32\4\0\0\0\128\255\255\127\255\170\170\170\170\170\170\170\85\85\171\170\170\170\170\170\212\41\49\36\78\42\45\81\230\64\82\85\181\170\170\41\170\170\170\170\170\170\170\250\147\133\170\255\255\255\255\255\255\255\255\239\255\255\255\255\1\3\0\0\0\31\0\0\0\0\0\0\0\0\0\0\0\32\0\0\0\0\0\138\60\0\0\1\0\0\240\255\255\255\127\227\170\170\170\47\25\0\0\0\0\0\0\255\255\255\255\255\255\170\170\170\170\2\168\170\170\170\170\170\170\84\213\170\170\170\170\170\170\170\170\170\170\170\170\0\0\0\0\0\0\255\255\255\255\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\234\191\170\170\170\170\170\170\170\170\170\170\170\170\255\0\63\0\255\0\255\0\63\0\255\0\255\0\255\63\255\0\255\0\255\0\223\64\220\0\207\0\255\0\220\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\128\0\0\255\31\0\0\0\0\0\0\0\0\0\0\0\0\0\196\8\0\0\128\16\50\192\67\0\0\0\0\255\255\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\98\21\218\63\170\170\170\170\170\170\170\170\170\170\170\170\26\80\8\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\170\170\170\170\170\42\0\0\170\170\170\58\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\168\170\171\170\170\170\170\170\170\170\255\149\170\80\186\170\170\130\160\170\10\37\170\10\0\0\92\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\255\3\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\127\0\248\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\128\255\251\255\251\27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\185\255\255\255\255\255\253\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\15\0\0\192\223\255\255\0\0\0\252\255\255\15\0\0\192\235\239\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\63\0\0\0\252\255\255\247\3\0\0\240\255\255\223\15\0\0\192\255\255\127\63\0\0\0\255\255\255\253\0\0\0\252\255\255\247\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\251\255\127\224\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\255\15"#
+    bitmap# = "\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\4\32\4\0\0\0\128\255\255\127\255\170\170\170\170\170\170\170\85\85\171\170\170\170\170\170\212\41\49\36\78\42\45\81\230\64\82\85\181\170\170\41\170\170\170\170\170\170\170\250\147\133\170\255\255\255\255\255\255\255\255\207\255\255\255\255\1\3\0\0\0\31\0\0\0\0\0\0\0\0\0\0\0\32\0\0\0\0\0\138\60\0\0\1\0\0\240\255\255\255\127\227\170\170\170\47\25\0\0\0\0\0\0\255\255\255\255\255\255\170\170\170\170\2\168\170\170\170\170\170\170\84\213\170\170\170\170\170\170\170\170\170\170\170\170\0\0\0\0\0\0\255\255\255\255\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\234\191\170\170\170\170\170\170\170\170\170\170\170\170\255\0\63\0\255\0\255\0\63\0\255\0\255\0\255\63\255\0\255\0\255\0\223\64\220\0\207\0\255\0\220\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\128\0\0\255\31\0\0\0\0\0\0\0\0\0\0\0\0\0\196\8\0\0\128\16\50\192\67\0\0\0\0\255\255\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\98\21\218\63\170\170\170\170\170\170\170\170\170\170\170\170\26\80\8\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\170\170\170\170\170\42\0\0\170\170\170\58\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\168\170\171\170\170\170\170\170\170\170\255\149\170\80\186\170\170\130\160\170\10\165\170\10\0\0\94\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\255\3\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\127\0\248\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\128\255\251\255\251\27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\185\255\255\255\255\255\253\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\248\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\15\0\0\192\223\255\255\0\0\0\252\255\255\15\0\0\192\235\239\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\63\0\0\0\252\255\255\247\3\0\0\240\255\255\223\15\0\0\192\255\255\127\63\0\0\0\255\255\255\253\0\0\0\252\255\255\247\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\251\255\127\224\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\255\15"#
 
diff --git a/src/GHC/Internal/Unicode/Char/UnicodeData/GeneralCategory.hs b/src/GHC/Internal/Unicode/Char/UnicodeData/GeneralCategory.hs
--- a/src/GHC/Internal/Unicode/Char/UnicodeData/GeneralCategory.hs
+++ b/src/GHC/Internal/Unicode/Char/UnicodeData/GeneralCategory.hs
@@ -1,5 +1,5 @@
 -- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell,
--- with data from: https://www.unicode.org/Public/16.0.0/ucd/UnicodeData.txt.
+-- with data from: https://www.unicode.org/Public/17.0.0/ucd/UnicodeData.txt.
 
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE MagicHash #-}
@@ -26,8 +26,8 @@
 lookup_bitmap :: Int -> Int
 lookup_bitmap n =
   (({- 4 -} if n < 72441 then (
-    ({- 4 -} if n < 19968 then (
-      ({- 4 -} if n < 9003 then (
+    ({- 4 -} if n < 19904 then (
+      ({- 4 -} if n < 8960 then (
         ({- 4 -} if n < 5024 then (
           ({- 4 -} if n < 1869 then (
             ({- 4 -} if n < 880 then (
@@ -65,115 +65,113 @@
               {- 4 -} ))
             {- 4 -} ))
           ) {- 4 -} else (
-          ({- 4 -} if n < 6320 then (
-            ({- 4 -} if n < 5867 then (
+          ({- 4 -} if n < 6265 then (
+            ({- 4 -} if n < 5792 then (
               ({- 4 -} if n < 5121 then (
                 ({- 1 -} if n < 5110 then (0) else (lookupIntN decompressed_table_10 (n - 5110)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 5741 then (4) else (
-                  ({- 1 -} if n < 5792 then (lookupIntN decompressed_table_11 (n - 5741)) else (4))
-                  {- 2 -}))
+                ({- 1 -} if n < 5741 then (4) else (lookupIntN decompressed_table_11 (n - 5741)))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 6068 then (
-                ({- 1 -} if n < 6016 then (lookupIntN decompressed_table_12 (n - 5867)) else (4))
+              ({- 4 -} if n < 6016 then (
+                ({- 1 -} if n < 5867 then (4) else (lookupIntN decompressed_table_12 (n - 5867)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 6212 then (lookupIntN decompressed_table_13 (n - 6068)) else (
-                  ({- 1 -} if n < 6265 then (4) else (lookupIntN decompressed_table_14 (n - 6265)))
+                ({- 2 -} if n < 6068 then (4) else (
+                  ({- 1 -} if n < 6212 then (lookupIntN decompressed_table_13 (n - 6068)) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 7531 then (
-              ({- 4 -} if n < 6688 then (
-                ({- 1 -} if n < 6390 then (4) else (lookupIntN decompressed_table_15 (n - 6390)))
+            ({- 4 -} if n < 7468 then (
+              ({- 4 -} if n < 6390 then (
+                ({- 1 -} if n < 6320 then (lookupIntN decompressed_table_14 (n - 6265)) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 6741 then (4) else (
-                  ({- 1 -} if n < 7468 then (lookupIntN decompressed_table_16 (n - 6741)) else (3))
+                ({- 2 -} if n < 6688 then (lookupIntN decompressed_table_15 (n - 6390)) else (
+                  ({- 1 -} if n < 6741 then (4) else (lookupIntN decompressed_table_16 (n - 6741)))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 7680 then (
-                ({- 1 -} if n < 7616 then (lookupIntN decompressed_table_17 (n - 7531)) else (5))
+              ({- 4 -} if n < 7616 then (
+                ({- 1 -} if n < 7531 then (3) else (lookupIntN decompressed_table_17 (n - 7531)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 8692 then (lookupIntN decompressed_table_18 (n - 7680)) else (
-                  ({- 1 -} if n < 8960 then (18) else (lookupIntN decompressed_table_19 (n - 8960)))
+                ({- 2 -} if n < 7680 then (5) else (
+                  ({- 1 -} if n < 8692 then (lookupIntN decompressed_table_18 (n - 7680)) else (18))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             {- 4 -} ))
           {- 4 -} ))
         ) {- 4 -} else (
-        ({- 4 -} if n < 10712 then (
-          ({- 4 -} if n < 9666 then (
-            ({- 4 -} if n < 9312 then (
-              ({- 4 -} if n < 9186 then (
-                ({- 1 -} if n < 9084 then (21) else (lookupIntN decompressed_table_20 (n - 9084)))
+        ({- 4 -} if n < 10649 then (
+          ({- 4 -} if n < 9655 then (
+            ({- 4 -} if n < 9258 then (
+              ({- 4 -} if n < 9084 then (
+                ({- 1 -} if n < 9003 then (lookupIntN decompressed_table_19 (n - 8960)) else (21))
                 ) {- 4 -} else (
-                ({- 1 -} if n < 9258 then (21) else (lookupIntN decompressed_table_21 (n - 9258)))
+                ({- 1 -} if n < 9186 then (lookupIntN decompressed_table_20 (n - 9084)) else (21))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 9450 then (
-                ({- 1 -} if n < 9372 then (10) else (21))
+              ({- 4 -} if n < 9372 then (
+                ({- 1 -} if n < 9312 then (lookupIntN decompressed_table_21 (n - 9258)) else (10))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 9472 then (10) else (
-                  ({- 1 -} if n < 9655 then (21) else (lookupIntN decompressed_table_22 (n - 9655)))
+                ({- 2 -} if n < 9450 then (21) else (
+                  ({- 1 -} if n < 9472 then (10) else (21))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 10088 then (
-              ({- 4 -} if n < 9728 then (
-                ({- 1 -} if n < 9720 then (21) else (18))
+            ({- 4 -} if n < 9840 then (
+              ({- 4 -} if n < 9720 then (
+                ({- 1 -} if n < 9666 then (lookupIntN decompressed_table_22 (n - 9655)) else (21))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 9839 then (21) else (
-                  ({- 1 -} if n < 9840 then (18) else (21))
+                ({- 2 -} if n < 9728 then (18) else (
+                  ({- 1 -} if n < 9839 then (21) else (18))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 10496 then (
-                ({- 1 -} if n < 10240 then (lookupIntN decompressed_table_23 (n - 10088)) else (21))
+              ({- 4 -} if n < 10240 then (
+                ({- 1 -} if n < 10088 then (21) else (lookupIntN decompressed_table_23 (n - 10088)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 10627 then (18) else (
-                  ({- 1 -} if n < 10649 then (lookupIntN decompressed_table_24 (n - 10627)) else (18))
+                ({- 2 -} if n < 10496 then (21) else (
+                  ({- 1 -} if n < 10627 then (18) else (lookupIntN decompressed_table_24 (n - 10627)))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             {- 4 -} ))
           ) {- 4 -} else (
-          ({- 4 -} if n < 12246 then (
-            ({- 4 -} if n < 11568 then (
-              ({- 4 -} if n < 11008 then (
-                ({- 1 -} if n < 10750 then (lookupIntN decompressed_table_25 (n - 10712)) else (18))
+          ({- 4 -} if n < 12032 then (
+            ({- 4 -} if n < 11264 then (
+              ({- 4 -} if n < 10750 then (
+                ({- 1 -} if n < 10712 then (18) else (lookupIntN decompressed_table_25 (n - 10712)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 11159 then (lookupIntN decompressed_table_26 (n - 11008)) else (
-                  ({- 1 -} if n < 11264 then (21) else (lookupIntN decompressed_table_27 (n - 11264)))
+                ({- 2 -} if n < 11008 then (18) else (
+                  ({- 1 -} if n < 11126 then (lookupIntN decompressed_table_26 (n - 11008)) else (21))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 11931 then (
-                ({- 1 -} if n < 11624 then (4) else (lookupIntN decompressed_table_28 (n - 11624)))
+              ({- 4 -} if n < 11624 then (
+                ({- 1 -} if n < 11568 then (lookupIntN decompressed_table_27 (n - 11264)) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 12020 then (21) else (
-                  ({- 1 -} if n < 12032 then (29) else (21))
+                ({- 2 -} if n < 11931 then (lookupIntN decompressed_table_28 (n - 11624)) else (
+                  ({- 1 -} if n < 12020 then (21) else (29))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 12593 then (
-              ({- 4 -} if n < 12439 then (
-                ({- 1 -} if n < 12353 then (lookupIntN decompressed_table_29 (n - 12246)) else (4))
+            ({- 4 -} if n < 12539 then (
+              ({- 4 -} if n < 12353 then (
+                ({- 1 -} if n < 12246 then (21) else (lookupIntN decompressed_table_29 (n - 12246)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 12449 then (lookupIntN decompressed_table_30 (n - 12439)) else (
-                  ({- 1 -} if n < 12539 then (4) else (lookupIntN decompressed_table_31 (n - 12539)))
+                ({- 2 -} if n < 12439 then (4) else (
+                  ({- 1 -} if n < 12449 then (lookupIntN decompressed_table_30 (n - 12439)) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 12992 then (
-                ({- 1 -} if n < 12687 then (4) else (lookupIntN decompressed_table_32 (n - 12687)))
+              ({- 4 -} if n < 12687 then (
+                ({- 1 -} if n < 12593 then (lookupIntN decompressed_table_31 (n - 12539)) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 13312 then (21) else (
-                  ({- 1 -} if n < 19904 then (4) else (21))
+                ({- 2 -} if n < 12992 then (lookupIntN decompressed_table_32 (n - 12687)) else (
+                  ({- 1 -} if n < 13312 then (21) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
@@ -181,117 +179,113 @@
           {- 4 -} ))
         {- 4 -} ))
       ) {- 4 -} else (
-      ({- 4 -} if n < 66718 then (
-        ({- 4 -} if n < 64110 then (
-          ({- 4 -} if n < 42726 then (
-            ({- 4 -} if n < 42128 then (
-              ({- 4 -} if n < 40982 then (
-                ({- 1 -} if n < 40981 then (4) else (3))
+      ({- 4 -} if n < 66176 then (
+        ({- 4 -} if n < 63744 then (
+          ({- 4 -} if n < 42656 then (
+            ({- 4 -} if n < 42125 then (
+              ({- 4 -} if n < 40981 then (
+                ({- 1 -} if n < 19968 then (21) else (4))
                 ) {- 4 -} else (
-                ({- 1 -} if n < 42125 then (4) else (29))
+                ({- 1 -} if n < 40982 then (3) else (4))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 42240 then (
-                ({- 1 -} if n < 42183 then (21) else (lookupIntN decompressed_table_33 (n - 42183)))
+              ({- 4 -} if n < 42183 then (
+                ({- 1 -} if n < 42128 then (29) else (21))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 42508 then (4) else (
-                  ({- 1 -} if n < 42656 then (lookupIntN decompressed_table_34 (n - 42508)) else (4))
+                ({- 2 -} if n < 42240 then (lookupIntN decompressed_table_33 (n - 42183)) else (
+                  ({- 1 -} if n < 42508 then (4) else (lookupIntN decompressed_table_34 (n - 42508)))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 44032 then (
-              ({- 4 -} if n < 43124 then (
-                ({- 1 -} if n < 43072 then (lookupIntN decompressed_table_35 (n - 42726)) else (4))
+            ({- 4 -} if n < 43968 then (
+              ({- 4 -} if n < 43072 then (
+                ({- 1 -} if n < 42726 then (4) else (lookupIntN decompressed_table_35 (n - 42726)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 43888 then (lookupIntN decompressed_table_36 (n - 43124)) else (
-                  ({- 1 -} if n < 43968 then (1) else (lookupIntN decompressed_table_37 (n - 43968)))
+                ({- 2 -} if n < 43124 then (4) else (
+                  ({- 1 -} if n < 43888 then (lookupIntN decompressed_table_36 (n - 43124)) else (1))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 55296 then (
-                ({- 1 -} if n < 55204 then (4) else (lookupIntN decompressed_table_38 (n - 55204)))
+              ({- 4 -} if n < 55204 then (
+                ({- 1 -} if n < 44032 then (lookupIntN decompressed_table_37 (n - 43968)) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 57344 then (27) else (
-                  ({- 1 -} if n < 63744 then (28) else (4))
+                ({- 2 -} if n < 55296 then (lookupIntN decompressed_table_38 (n - 55204)) else (
+                  ({- 1 -} if n < 57344 then (27) else (28))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             {- 4 -} ))
           ) {- 4 -} else (
-          ({- 4 -} if n < 64968 then (
-            ({- 4 -} if n < 64467 then (
-              ({- 4 -} if n < 64218 then (
-                ({- 1 -} if n < 64112 then (29) else (4))
+          ({- 4 -} if n < 64912 then (
+            ({- 4 -} if n < 64326 then (
+              ({- 4 -} if n < 64112 then (
+                ({- 1 -} if n < 64110 then (4) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 64326 then (lookupIntN decompressed_table_39 (n - 64218)) else (
-                  ({- 1 -} if n < 64434 then (4) else (lookupIntN decompressed_table_40 (n - 64434)))
-                  {- 2 -}))
+                ({- 1 -} if n < 64218 then (4) else (lookupIntN decompressed_table_39 (n - 64218)))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 64848 then (
-                ({- 1 -} if n < 64830 then (4) else (lookupIntN decompressed_table_41 (n - 64830)))
+              ({- 4 -} if n < 64467 then (
+                ({- 1 -} if n < 64434 then (4) else (lookupIntN decompressed_table_40 (n - 64434)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 64912 then (4) else (
-                  ({- 1 -} if n < 64914 then (29) else (4))
+                ({- 2 -} if n < 64830 then (4) else (
+                  ({- 1 -} if n < 64848 then (lookupIntN decompressed_table_41 (n - 64830)) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 65856 then (
-              ({- 4 -} if n < 65277 then (
-                ({- 1 -} if n < 65142 then (lookupIntN decompressed_table_42 (n - 64968)) else (4))
+            ({- 4 -} if n < 65664 then (
+              ({- 4 -} if n < 64968 then (
+                ({- 1 -} if n < 64914 then (21) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 65664 then (lookupIntN decompressed_table_43 (n - 65277)) else (
-                  ({- 1 -} if n < 65787 then (4) else (lookupIntN decompressed_table_44 (n - 65787)))
+                ({- 2 -} if n < 65142 then (lookupIntN decompressed_table_42 (n - 64968)) else (
+                  ({- 1 -} if n < 65277 then (4) else (lookupIntN decompressed_table_43 (n - 65277)))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 66046 then (
-                ({- 1 -} if n < 65909 then (9) else (lookupIntN decompressed_table_45 (n - 65909)))
+              ({- 4 -} if n < 65856 then (
+                ({- 1 -} if n < 65787 then (4) else (lookupIntN decompressed_table_44 (n - 65787)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 66176 then (29) else (
-                  ({- 1 -} if n < 66640 then (lookupIntN decompressed_table_46 (n - 66176)) else (4))
+                ({- 2 -} if n < 65909 then (9) else (
+                  ({- 1 -} if n < 66046 then (lookupIntN decompressed_table_45 (n - 65909)) else (29))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             {- 4 -} ))
           {- 4 -} ))
         ) {- 4 -} else (
-        ({- 4 -} if n < 68851 then (
-          ({- 4 -} if n < 67968 then (
-            ({- 4 -} if n < 67072 then (
-              ({- 4 -} if n < 66916 then (
-                ({- 1 -} if n < 66864 then (lookupIntN decompressed_table_47 (n - 66718)) else (4))
+        ({- 4 -} if n < 68787 then (
+          ({- 4 -} if n < 67515 then (
+            ({- 4 -} if n < 66916 then (
+              ({- 4 -} if n < 66718 then (
+                ({- 1 -} if n < 66640 then (lookupIntN decompressed_table_46 (n - 66176)) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 67008 then (lookupIntN decompressed_table_48 (n - 66916)) else (
-                  ({- 1 -} if n < 67060 then (4) else (29))
-                  {- 2 -}))
+                ({- 1 -} if n < 66864 then (lookupIntN decompressed_table_47 (n - 66718)) else (4))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 67515 then (
-                ({- 1 -} if n < 67383 then (4) else (lookupIntN decompressed_table_49 (n - 67383)))
+              ({- 4 -} if n < 67060 then (
+                ({- 1 -} if n < 67008 then (lookupIntN decompressed_table_48 (n - 66916)) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 67584 then (29) else (
-                  ({- 1 -} if n < 67904 then (lookupIntN decompressed_table_50 (n - 67584)) else (29))
+                ({- 2 -} if n < 67072 then (29) else (
+                  ({- 1 -} if n < 67383 then (4) else (lookupIntN decompressed_table_49 (n - 67383)))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 68608 then (
-              ({- 4 -} if n < 68352 then (
-                ({- 1 -} if n < 68024 then (4) else (lookupIntN decompressed_table_51 (n - 68024)))
+            ({- 4 -} if n < 68406 then (
+              ({- 4 -} if n < 67968 then (
+                ({- 1 -} if n < 67584 then (29) else (lookupIntN decompressed_table_50 (n - 67584)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 68406 then (4) else (
-                  ({- 1 -} if n < 68528 then (lookupIntN decompressed_table_52 (n - 68406)) else (29))
+                ({- 2 -} if n < 68024 then (4) else (
+                  ({- 1 -} if n < 68352 then (lookupIntN decompressed_table_51 (n - 68024)) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 68736 then (
-                ({- 1 -} if n < 68681 then (4) else (29))
+              ({- 4 -} if n < 68608 then (
+                ({- 1 -} if n < 68528 then (lookupIntN decompressed_table_52 (n - 68406)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 68787 then (0) else (
-                  ({- 1 -} if n < 68800 then (29) else (1))
+                ({- 2 -} if n < 68681 then (4) else (
+                  ({- 1 -} if n < 68736 then (29) else (0))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
@@ -299,37 +293,37 @@
           ) {- 4 -} else (
           ({- 4 -} if n < 70709 then (
             ({- 4 -} if n < 69635 then (
-              ({- 4 -} if n < 69216 then (
-                ({- 1 -} if n < 69008 then (lookupIntN decompressed_table_53 (n - 68851)) else (29))
+              ({- 4 -} if n < 68851 then (
+                ({- 1 -} if n < 68800 then (29) else (1))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 69317 then (lookupIntN decompressed_table_54 (n - 69216)) else (
-                  ({- 1 -} if n < 69372 then (29) else (lookupIntN decompressed_table_55 (n - 69372)))
+                ({- 2 -} if n < 69008 then (lookupIntN decompressed_table_53 (n - 68851)) else (
+                  ({- 1 -} if n < 69216 then (29) else (lookupIntN decompressed_table_54 (n - 69216)))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
               ({- 4 -} if n < 70210 then (
-                ({- 1 -} if n < 69688 then (4) else (lookupIntN decompressed_table_56 (n - 69688)))
+                ({- 1 -} if n < 69688 then (4) else (lookupIntN decompressed_table_55 (n - 69688)))
                 ) {- 4 -} else (
                 ({- 2 -} if n < 70272 then (29) else (
-                  ({- 1 -} if n < 70656 then (lookupIntN decompressed_table_57 (n - 70272)) else (4))
+                  ({- 1 -} if n < 70656 then (lookupIntN decompressed_table_56 (n - 70272)) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
             ({- 4 -} if n < 71740 then (
               ({- 4 -} if n < 71040 then (
-                ({- 1 -} if n < 70874 then (lookupIntN decompressed_table_58 (n - 70709)) else (29))
+                ({- 1 -} if n < 70874 then (lookupIntN decompressed_table_57 (n - 70709)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 71495 then (lookupIntN decompressed_table_59 (n - 71040)) else (
-                  ({- 1 -} if n < 71680 then (29) else (lookupIntN decompressed_table_60 (n - 71680)))
+                ({- 2 -} if n < 71495 then (lookupIntN decompressed_table_58 (n - 71040)) else (
+                  ({- 1 -} if n < 71680 then (29) else (lookupIntN decompressed_table_59 (n - 71680)))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
               ({- 4 -} if n < 72026 then (
-                ({- 1 -} if n < 71840 then (29) else (lookupIntN decompressed_table_61 (n - 71840)))
+                ({- 1 -} if n < 71840 then (29) else (lookupIntN decompressed_table_60 (n - 71840)))
                 ) {- 4 -} else (
                 ({- 2 -} if n < 72096 then (29) else (
-                  ({- 1 -} if n < 72368 then (lookupIntN decompressed_table_62 (n - 72096)) else (4))
+                  ({- 1 -} if n < 72368 then (lookupIntN decompressed_table_61 (n - 72096)) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
@@ -338,156 +332,152 @@
         {- 4 -} ))
       {- 4 -} ))
     ) {- 4 -} else (
-    ({- 4 -} if n < 122667 then (
-      ({- 4 -} if n < 94176 then (
-        ({- 4 -} if n < 78944 then (
-          ({- 4 -} if n < 73728 then (
-            ({- 4 -} if n < 72960 then (
-              ({- 4 -} if n < 72640 then (
-                ({- 1 -} if n < 72458 then (lookupIntN decompressed_table_63 (n - 72441)) else (29))
+    ({- 4 -} if n < 121520 then (
+      ({- 4 -} if n < 94088 then (
+        ({- 4 -} if n < 77824 then (
+          ({- 4 -} if n < 73563 then (
+            ({- 4 -} if n < 72640 then (
+              ({- 4 -} if n < 72544 then (
+                ({- 1 -} if n < 72458 then (lookupIntN decompressed_table_62 (n - 72441)) else (29))
                 ) {- 4 -} else (
-                ({- 1 -} if n < 72887 then (lookupIntN decompressed_table_64 (n - 72640)) else (29))
+                ({- 1 -} if n < 72552 then (lookupIntN decompressed_table_63 (n - 72544)) else (29))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 73440 then (
-                ({- 1 -} if n < 73130 then (lookupIntN decompressed_table_65 (n - 72960)) else (29))
+              ({- 4 -} if n < 72960 then (
+                ({- 1 -} if n < 72887 then (lookupIntN decompressed_table_64 (n - 72640)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 73563 then (lookupIntN decompressed_table_66 (n - 73440)) else (
-                  ({- 1 -} if n < 73648 then (29) else (lookupIntN decompressed_table_67 (n - 73648)))
+                ({- 2 -} if n < 73194 then (lookupIntN decompressed_table_65 (n - 72960)) else (
+                  ({- 1 -} if n < 73440 then (29) else (lookupIntN decompressed_table_66 (n - 73440)))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 75076 then (
-              ({- 4 -} if n < 74752 then (
-                ({- 1 -} if n < 74650 then (4) else (29))
+            ({- 4 -} if n < 74863 then (
+              ({- 4 -} if n < 73728 then (
+                ({- 1 -} if n < 73648 then (29) else (lookupIntN decompressed_table_67 (n - 73648)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 74863 then (9) else (
-                  ({- 1 -} if n < 74880 then (lookupIntN decompressed_table_68 (n - 74863)) else (4))
+                ({- 2 -} if n < 74650 then (4) else (
+                  ({- 1 -} if n < 74752 then (29) else (9))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 77809 then (
-                ({- 1 -} if n < 77712 then (29) else (4))
+              ({- 4 -} if n < 75076 then (
+                ({- 1 -} if n < 74880 then (lookupIntN decompressed_table_68 (n - 74863)) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 77824 then (lookupIntN decompressed_table_69 (n - 77809)) else (
-                  ({- 1 -} if n < 78896 then (4) else (lookupIntN decompressed_table_70 (n - 78896)))
+                ({- 2 -} if n < 77712 then (29) else (
+                  ({- 1 -} if n < 77809 then (4) else (lookupIntN decompressed_table_69 (n - 77809)))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             {- 4 -} ))
           ) {- 4 -} else (
-          ({- 4 -} if n < 93072 then (
-            ({- 4 -} if n < 90426 then (
-              ({- 4 -} if n < 82944 then (
-                ({- 1 -} if n < 82939 then (4) else (29))
+          ({- 4 -} if n < 92729 then (
+            ({- 4 -} if n < 82944 then (
+              ({- 4 -} if n < 78944 then (
+                ({- 1 -} if n < 78896 then (4) else (lookupIntN decompressed_table_70 (n - 78896)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 83527 then (4) else (
-                  ({- 1 -} if n < 90368 then (29) else (lookupIntN decompressed_table_71 (n - 90368)))
-                  {- 2 -}))
+                ({- 1 -} if n < 82939 then (4) else (29))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 92729 then (
-                ({- 1 -} if n < 92160 then (29) else (4))
+              ({- 4 -} if n < 90368 then (
+                ({- 1 -} if n < 83527 then (4) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 92784 then (lookupIntN decompressed_table_72 (n - 92729)) else (
-                  ({- 1 -} if n < 92863 then (4) else (lookupIntN decompressed_table_73 (n - 92863)))
+                ({- 2 -} if n < 90426 then (lookupIntN decompressed_table_71 (n - 90368)) else (
+                  ({- 1 -} if n < 92160 then (29) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 93952 then (
-              ({- 4 -} if n < 93562 then (
-                ({- 1 -} if n < 93504 then (29) else (lookupIntN decompressed_table_74 (n - 93504)))
+            ({- 4 -} if n < 93562 then (
+              ({- 4 -} if n < 92863 then (
+                ({- 1 -} if n < 92784 then (lookupIntN decompressed_table_72 (n - 92729)) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 93760 then (29) else (
-                  ({- 1 -} if n < 93851 then (lookupIntN decompressed_table_75 (n - 93760)) else (29))
+                ({- 2 -} if n < 93072 then (lookupIntN decompressed_table_73 (n - 92863)) else (
+                  ({- 1 -} if n < 93504 then (29) else (lookupIntN decompressed_table_74 (n - 93504)))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 94033 then (
-                ({- 1 -} if n < 94027 then (4) else (lookupIntN decompressed_table_76 (n - 94027)))
+              ({- 4 -} if n < 93952 then (
+                ({- 1 -} if n < 93760 then (29) else (lookupIntN decompressed_table_75 (n - 93760)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 94088 then (6) else (
-                  ({- 1 -} if n < 94112 then (lookupIntN decompressed_table_77 (n - 94088)) else (29))
+                ({- 2 -} if n < 94027 then (4) else (
+                  ({- 1 -} if n < 94033 then (lookupIntN decompressed_table_76 (n - 94027)) else (6))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             {- 4 -} ))
           {- 4 -} ))
         ) {- 4 -} else (
-        ({- 4 -} if n < 118724 then (
-          ({- 4 -} if n < 111356 then (
-            ({- 4 -} if n < 101641 then (
-              ({- 4 -} if n < 100344 then (
-                ({- 1 -} if n < 94208 then (lookupIntN decompressed_table_78 (n - 94176)) else (4))
+        ({- 4 -} if n < 118452 then (
+          ({- 4 -} if n < 110592 then (
+            ({- 4 -} if n < 101590 then (
+              ({- 4 -} if n < 94176 then (
+                ({- 1 -} if n < 94112 then (lookupIntN decompressed_table_77 (n - 94088)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 100352 then (29) else (
-                  ({- 1 -} if n < 101590 then (4) else (lookupIntN decompressed_table_79 (n - 101590)))
-                  {- 2 -}))
+                ({- 1 -} if n < 94208 then (lookupIntN decompressed_table_78 (n - 94176)) else (4))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 110592 then (
-                ({- 1 -} if n < 110576 then (29) else (lookupIntN decompressed_table_80 (n - 110576)))
+              ({- 4 -} if n < 101760 then (
+                ({- 1 -} if n < 101663 then (lookupIntN decompressed_table_79 (n - 101590)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 110883 then (4) else (
-                  ({- 1 -} if n < 110960 then (lookupIntN decompressed_table_81 (n - 110883)) else (4))
+                ({- 2 -} if n < 101875 then (4) else (
+                  ({- 1 -} if n < 110576 then (29) else (lookupIntN decompressed_table_80 (n - 110576)))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 118000 then (
-              ({- 4 -} if n < 113771 then (
-                ({- 1 -} if n < 113664 then (29) else (4))
+            ({- 4 -} if n < 113771 then (
+              ({- 4 -} if n < 110960 then (
+                ({- 1 -} if n < 110883 then (4) else (lookupIntN decompressed_table_81 (n - 110883)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 113828 then (lookupIntN decompressed_table_82 (n - 113771)) else (
-                  ({- 1 -} if n < 117760 then (29) else (21))
+                ({- 2 -} if n < 111356 then (4) else (
+                  ({- 1 -} if n < 113664 then (29) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 118452 then (
-                ({- 1 -} if n < 118016 then (lookupIntN decompressed_table_83 (n - 118000)) else (21))
+              ({- 4 -} if n < 117760 then (
+                ({- 1 -} if n < 113828 then (lookupIntN decompressed_table_82 (n - 113771)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 118528 then (29) else (
-                  ({- 1 -} if n < 118608 then (lookupIntN decompressed_table_84 (n - 118528)) else (21))
+                ({- 2 -} if n < 118000 then (21) else (
+                  ({- 1 -} if n < 118016 then (lookupIntN decompressed_table_83 (n - 118000)) else (21))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             {- 4 -} ))
           ) {- 4 -} else (
-          ({- 4 -} if n < 119488 then (
-            ({- 4 -} if n < 119214 then (
-              ({- 4 -} if n < 119030 then (
-                ({- 1 -} if n < 118784 then (29) else (21))
+          ({- 4 -} if n < 119362 then (
+            ({- 4 -} if n < 119081 then (
+              ({- 4 -} if n < 118724 then (
+                ({- 1 -} if n < 118608 then (lookupIntN decompressed_table_84 (n - 118452)) else (21))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 119081 then (lookupIntN decompressed_table_85 (n - 119030)) else (
-                  ({- 1 -} if n < 119141 then (21) else (lookupIntN decompressed_table_86 (n - 119141)))
+                ({- 2 -} if n < 118784 then (29) else (
+                  ({- 1 -} if n < 119030 then (21) else (lookupIntN decompressed_table_85 (n - 119030)))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 119296 then (
-                ({- 1 -} if n < 119275 then (21) else (29))
+              ({- 4 -} if n < 119214 then (
+                ({- 1 -} if n < 119141 then (21) else (lookupIntN decompressed_table_86 (n - 119141)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 119362 then (21) else (
-                  ({- 1 -} if n < 119366 then (lookupIntN decompressed_table_87 (n - 119362)) else (29))
+                ({- 2 -} if n < 119275 then (21) else (
+                  ({- 1 -} if n < 119296 then (29) else (21))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 120832 then (
-              ({- 4 -} if n < 119639 then (
-                ({- 1 -} if n < 119552 then (lookupIntN decompressed_table_88 (n - 119488)) else (21))
+            ({- 4 -} if n < 119673 then (
+              ({- 4 -} if n < 119488 then (
+                ({- 1 -} if n < 119366 then (lookupIntN decompressed_table_87 (n - 119362)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 119673 then (lookupIntN decompressed_table_89 (n - 119639)) else (
-                  ({- 1 -} if n < 119808 then (29) else (lookupIntN decompressed_table_90 (n - 119808)))
+                ({- 2 -} if n < 119552 then (lookupIntN decompressed_table_88 (n - 119488)) else (
+                  ({- 1 -} if n < 119639 then (21) else (lookupIntN decompressed_table_89 (n - 119639)))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 121399 then (
-                ({- 1 -} if n < 121344 then (21) else (5))
+              ({- 4 -} if n < 120832 then (
+                ({- 1 -} if n < 119808 then (29) else (lookupIntN decompressed_table_90 (n - 119808)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 121520 then (lookupIntN decompressed_table_91 (n - 121399)) else (
-                  ({- 1 -} if n < 122624 then (29) else (lookupIntN decompressed_table_92 (n - 122624)))
+                ({- 2 -} if n < 121344 then (21) else (
+                  ({- 1 -} if n < 121399 then (5) else (lookupIntN decompressed_table_91 (n - 121399)))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
@@ -495,77 +485,77 @@
           {- 4 -} ))
         {- 4 -} ))
       ) {- 4 -} else (
-      ({- 4 -} if n < 128891 then (
-        ({- 4 -} if n < 126133 then (
-          ({- 4 -} if n < 124112 then (
-            ({- 4 -} if n < 123024 then (
-              ({- 4 -} if n < 122928 then (
-                ({- 1 -} if n < 122880 then (29) else (lookupIntN decompressed_table_93 (n - 122880)))
+      ({- 4 -} if n < 128000 then (
+        ({- 4 -} if n < 125125 then (
+          ({- 4 -} if n < 123536 then (
+            ({- 4 -} if n < 122928 then (
+              ({- 4 -} if n < 122667 then (
+                ({- 1 -} if n < 122624 then (29) else (lookupIntN decompressed_table_92 (n - 122624)))
                 ) {- 4 -} else (
-                ({- 1 -} if n < 122990 then (3) else (lookupIntN decompressed_table_94 (n - 122990)))
+                ({- 1 -} if n < 122880 then (29) else (lookupIntN decompressed_table_93 (n - 122880)))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 123216 then (
-                ({- 1 -} if n < 123136 then (29) else (lookupIntN decompressed_table_95 (n - 123136)))
+              ({- 4 -} if n < 123024 then (
+                ({- 1 -} if n < 122990 then (3) else (lookupIntN decompressed_table_94 (n - 122990)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 123536 then (29) else (
-                  ({- 1 -} if n < 123648 then (lookupIntN decompressed_table_96 (n - 123536)) else (29))
+                ({- 2 -} if n < 123136 then (29) else (
+                  ({- 1 -} if n < 123216 then (lookupIntN decompressed_table_95 (n - 123136)) else (29))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 124928 then (
-              ({- 4 -} if n < 124368 then (
-                ({- 1 -} if n < 124154 then (lookupIntN decompressed_table_97 (n - 124112)) else (29))
+            ({- 4 -} if n < 124416 then (
+              ({- 4 -} if n < 124112 then (
+                ({- 1 -} if n < 123648 then (lookupIntN decompressed_table_96 (n - 123536)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 124416 then (lookupIntN decompressed_table_98 (n - 124368)) else (
-                  ({- 1 -} if n < 124896 then (29) else (lookupIntN decompressed_table_99 (n - 124896)))
+                ({- 2 -} if n < 124154 then (lookupIntN decompressed_table_97 (n - 124112)) else (
+                  ({- 1 -} if n < 124368 then (29) else (lookupIntN decompressed_table_98 (n - 124368)))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 125280 then (
-                ({- 1 -} if n < 125125 then (4) else (lookupIntN decompressed_table_100 (n - 125125)))
+              ({- 4 -} if n < 124672 then (
+                ({- 1 -} if n < 124608 then (29) else (lookupIntN decompressed_table_99 (n - 124608)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 126065 then (29) else (
-                  ({- 1 -} if n < 126124 then (10) else (lookupIntN decompressed_table_101 (n - 126124)))
+                ({- 2 -} if n < 124896 then (29) else (
+                  ({- 1 -} if n < 124928 then (lookupIntN decompressed_table_100 (n - 124896)) else (4))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             {- 4 -} ))
           ) {- 4 -} else (
-          ({- 4 -} if n < 127245 then (
-            ({- 4 -} if n < 126704 then (
-              ({- 4 -} if n < 126270 then (
-                ({- 1 -} if n < 126209 then (29) else (lookupIntN decompressed_table_102 (n - 126209)))
+          ({- 4 -} if n < 126706 then (
+            ({- 4 -} if n < 126209 then (
+              ({- 4 -} if n < 126065 then (
+                ({- 1 -} if n < 125280 then (lookupIntN decompressed_table_101 (n - 125125)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 126464 then (29) else (
-                  ({- 1 -} if n < 126652 then (lookupIntN decompressed_table_103 (n - 126464)) else (29))
+                ({- 2 -} if n < 126124 then (10) else (
+                  ({- 1 -} if n < 126133 then (lookupIntN decompressed_table_102 (n - 126124)) else (29))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 126976 then (
-                ({- 1 -} if n < 126706 then (18) else (29))
+              ({- 4 -} if n < 126464 then (
+                ({- 1 -} if n < 126270 then (lookupIntN decompressed_table_103 (n - 126209)) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 127024 then (lookupIntN decompressed_table_104 (n - 126976)) else (
-                  ({- 1 -} if n < 127124 then (21) else (lookupIntN decompressed_table_105 (n - 127124)))
+                ({- 2 -} if n < 126652 then (lookupIntN decompressed_table_104 (n - 126464)) else (
+                  ({- 1 -} if n < 126704 then (29) else (18))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 127995 then (
-              ({- 4 -} if n < 127462 then (
-                ({- 1 -} if n < 127406 then (21) else (29))
+            ({- 4 -} if n < 127406 then (
+              ({- 4 -} if n < 127024 then (
+                ({- 1 -} if n < 126976 then (29) else (lookupIntN decompressed_table_105 (n - 126976)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 127590 then (lookupIntN decompressed_table_106 (n - 127462)) else (
-                  ({- 1 -} if n < 127744 then (29) else (21))
+                ({- 2 -} if n < 127124 then (21) else (
+                  ({- 1 -} if n < 127245 then (lookupIntN decompressed_table_106 (n - 127124)) else (21))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 128728 then (
-                ({- 1 -} if n < 128000 then (20) else (21))
+              ({- 4 -} if n < 127590 then (
+                ({- 1 -} if n < 127462 then (29) else (lookupIntN decompressed_table_107 (n - 127462)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 128768 then (lookupIntN decompressed_table_107 (n - 128728)) else (
-                  ({- 1 -} if n < 128887 then (21) else (29))
+                ({- 2 -} if n < 127744 then (29) else (
+                  ({- 1 -} if n < 127995 then (21) else (20))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
@@ -573,38 +563,36 @@
           {- 4 -} ))
         ) {- 4 -} else (
         ({- 4 -} if n < 178208 then (
-          ({- 4 -} if n < 129939 then (
-            ({- 4 -} if n < 129280 then (
-              ({- 4 -} if n < 129040 then (
-                ({- 1 -} if n < 128986 then (21) else (lookupIntN decompressed_table_108 (n - 128986)))
+          ({- 4 -} if n < 129735 then (
+            ({- 4 -} if n < 129040 then (
+              ({- 4 -} if n < 128768 then (
+                ({- 1 -} if n < 128729 then (21) else (lookupIntN decompressed_table_108 (n - 128729)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 129096 then (21) else (
-                  ({- 1 -} if n < 129218 then (lookupIntN decompressed_table_109 (n - 129096)) else (29))
-                  {- 2 -}))
+                ({- 1 -} if n < 128986 then (21) else (lookupIntN decompressed_table_109 (n - 128986)))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 129679 then (
-                ({- 1 -} if n < 129620 then (21) else (lookupIntN decompressed_table_110 (n - 129620)))
+              ({- 4 -} if n < 129280 then (
+                ({- 1 -} if n < 129096 then (21) else (lookupIntN decompressed_table_110 (n - 129096)))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 129735 then (21) else (
-                  ({- 1 -} if n < 129792 then (lookupIntN decompressed_table_111 (n - 129735)) else (21))
+                ({- 2 -} if n < 129624 then (21) else (
+                  ({- 1 -} if n < 129678 then (lookupIntN decompressed_table_111 (n - 129624)) else (21))
                   {- 2 -}))
                 {- 4 -} ))
               {- 4 -} ))
             ) {- 4 -} else (
-            ({- 4 -} if n < 173792 then (
-              ({- 4 -} if n < 130032 then (
-                ({- 1 -} if n < 129940 then (29) else (21))
+            ({- 4 -} if n < 130043 then (
+              ({- 4 -} if n < 129939 then (
+                ({- 1 -} if n < 129792 then (lookupIntN decompressed_table_112 (n - 129735)) else (21))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 130042 then (8) else (
-                  ({- 1 -} if n < 131072 then (29) else (4))
+                ({- 2 -} if n < 129940 then (29) else (
+                  ({- 1 -} if n < 130032 then (21) else (lookupIntN decompressed_table_113 (n - 130032)))
                   {- 2 -}))
                 {- 4 -} ))
               ) {- 4 -} else (
-              ({- 4 -} if n < 177978 then (
-                ({- 1 -} if n < 173824 then (29) else (4))
+              ({- 4 -} if n < 173792 then (
+                ({- 1 -} if n < 131072 then (29) else (4))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 177984 then (29) else (
+                ({- 2 -} if n < 173824 then (29) else (
                   ({- 1 -} if n < 178206 then (4) else (29))
                   {- 2 -}))
                 {- 4 -} ))
@@ -614,7 +602,7 @@
           ({- 4 -} if n < 201552 then (
             ({- 4 -} if n < 192094 then (
               ({- 4 -} if n < 183984 then (
-                ({- 1 -} if n < 183970 then (4) else (29))
+                ({- 1 -} if n < 183982 then (4) else (29))
                 ) {- 4 -} else (
                 ({- 2 -} if n < 191457 then (4) else (
                   ({- 1 -} if n < 191472 then (29) else (4))
@@ -632,9 +620,9 @@
             ) {- 4 -} else (
             ({- 4 -} if n < 917760 then (
               ({- 4 -} if n < 917505 then (
-                ({- 1 -} if n < 205744 then (4) else (29))
+                ({- 1 -} if n < 210042 then (4) else (29))
                 ) {- 4 -} else (
-                ({- 2 -} if n < 917536 then (lookupIntN decompressed_table_112 (n - 917505)) else (
+                ({- 2 -} if n < 917536 then (lookupIntN decompressed_table_114 (n - 917505)) else (
                   ({- 1 -} if n < 917632 then (26) else (29))
                   {- 2 -}))
                 {- 4 -} ))
@@ -655,12 +643,12 @@
   )
   where
     decompressed_table_0 = "\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\22\17\17\17\19\17\17\17\13\14\17\18\17\12\17\17\8\8\8\8\8\8\8\8\8\8\17\17\18\18\18\17\17\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\13\17\14\20\11\20\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\13\18\14\18\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\25\22\17\19\19\19\19\21\17\20\21\4\15\18\26\21\20\21\18\10\10\20\1\17\17\20\10\4\16\10\10\10\17\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\18\0\0\0\0\0\0\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\18\1\1\1\1\1\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\0\1\0\1\0\1\1\1\0\0\1\0\1\0\0\1\0\0\0\1\1\0\0\0\0\1\0\0\1\0\0\0\1\1\1\0\0\1\0\0\1\0\1\0\1\0\0\1\0\1\1\0\1\0\0\1\0\0\0\1\0\1\0\0\1\1\4\0\1\1\1\4\4\4\4\0\2\1\0\2\1\0\2\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\0\2\1\0\1\0\0\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\1\1\1\1\1\0\0\1\0\0\1\1\0\1\0\0\0\0\1\0\1\0\1\0\1\0"#
-    decompressed_table_1 = "\4\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\20\20\20\20\3\3\3\3\3\3\3\3\3\3\3\3\20\20\20\20\20\20\20\20\20\20\20\20\20\20\3\3\3\3\3\20\20\20\20\20\20\20\3\20\3\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20"#
+    decompressed_table_1 = "\4\4\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\20\20\20\20\3\3\3\3\3\3\3\3\3\3\3\3\20\20\20\20\20\20\20\20\20\20\20\20\20\20\3\3\3\3\3\20\20\20\20\20\20\20\3\20\3\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20"#
     decompressed_table_2 = "\0\1\0\1\3\20\0\1\29\29\3\1\1\1\17\0\29\29\29\29\20\20\0\17\0\0\0\29\0\29\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\0\0\0\0\0\0\0\0\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\1\1\0\0\0\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\1\1\1\0\1\18\0\1\0\0\1\1"#
     decompressed_table_3 = "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\21\5\5\5\5\5\7\7\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\29\3\17\17\17\17\17\17\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\17\12\29\29\21\21\19\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\12\5\17\5\5\17\5\5\17\5\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\4\4\4\4\17\17\29\29\29\29\29\29\29\29\29\29\29\26\26\26\26\26\26\18\18\18\17\17\19\17\17\21\21\5\5\5\5\5\5\5\5\5\5\5\17\26\17\17\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\8\8\8\8\8\8\8\8\8\8\17\17\17\17\4\4\5"#
     decompressed_table_4 = "\17\4\5\5\5\5\5\5\5\26\21\5\5\5\5\5\5\3\3\5\5\21\5\5\5\5\4\4\8\8\8\8\8\8\8\8\8\8\4\4\4\21\21\4\17\17\17\17\17\17\17\17\17\17\17\17\17\17\29\26\4\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\29"#
-    decompressed_table_5 = "\5\5\5\5\5\5\5\5\5\5\5\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\5\3\3\21\17\17\17\3\29\29\5\19\19\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\3\5\5\5\5\5\5\5\5\5\3\5\5\5\3\5\5\5\5\5\29\29\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\29\29\17\29\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\20\4\4\4\4\4\4\29\26\26\29\29\29\29\29\5\5\5\5\5\5\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\26\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\6"#
-    decompressed_table_6 = "\5\6\5\4\6\6\6\5\5\5\5\5\5\5\5\6\6\6\6\5\6\6\4\5\5\5\5\5\5\5\4\4\4\4\4\4\4\4\4\4\5\5\17\17\8\8\8\8\8\8\8\8\8\8\17\3\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\6\29\4\4\4\4\4\4\4\4\29\29\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\29\29\29\4\4\4\4\29\29\5\4\6\6\6\5\5\5\5\29\29\6\6\29\29\6\6\5\4\29\29\29\29\29\29\29\29\6\29\29\29\29\4\4\29\4\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\4\4\19\19\10\10\10\10\10\10\21\19\4\17\5\29\29\5\5\6\29\4\4\4\4\4\4\29\29\29\29\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\29\4\4\29\4\4\29\29\5\29\6\6\6\5\5\29\29\29\29\5\5\29\29\5\5\5\29\29\29\5\29\29\29\29\29\29\29\4\4\4\4\29\4\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\5\5\4\4\4\5\17\29\29\29\29\29\29\29\29\29\29\5\5\6\29\4\4\4\4\4\4\4\4\4\29\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\29\29\5\4\6\6\6\5\5\5\5\5\29\5\5\6\29\6\6\5\29\29\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\17\19\29\29\29\29\29\29\29\4\5\5\5\5\5\5\29\5\6\6\29\4\4\4\4\4\4\4\4\29\29\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\29\29\5\4\6\5\6\5\5\5\5\29\29\6\6\29\29\6\6\5\29\29\29\29\29\29\29\5\5\6\29\29\29\29\4\4\29\4\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\21\4\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\5\4\29\4\4\4\4\4\4\29\29\29\4\4\4\29\4\4\4\4\29\29\29\4\4\29\4\29\4\4\29\29\29\4\4\29\29\29\4\4\4\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\6\6\5\6\6\29\29\29\6\6\6\29\6\6\6\5\29\29\4\29\29\29\29\29\29\6\29\29\29\29\29\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\10\10\10\21\21\21\21\21\21\19\21\29\29\29\29\29\5\6\6\6\5\4\4\4\4\4\4\4\4\29\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\5\4\5\5\5\6\6\6\6\29\5\5\5\29\5\5\5\5\29\29\29\29\29\29\29\5\5\29\4\4\4\29\29\4\29\29\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\29\17\10\10\10\10\10\10\10\21\4\5\6\6\17\4\4\4\4\4\4\4\4\29\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\29\29\5\4\6\5\6\6\6\6\6\29\5\6\6\29\6\6\5\5\29\29\29\29\29\29\29\6\6\29\29\29\29\29\29\4\4\29\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\29\4\4\6\29\29\29\29\29\29\29\29\29\29\29\29\5\5\6\6\4\4\4\4\4\4\4\4\4\29\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\4\6\6\6\5\5\5\5\29\6\6\6\29\6\6\6\5\4\21\29\29\29\29\4\4\4\6\10\10\10\10\10\10\10\4\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\10\10\10\10\10\10\10\10\10\21\4\4\4\4\4\4\29\5\6\6\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\29\4\29\29\4\4\4\4\4\4\4\29\29\29\5\29\29\29\29\6\6\6\5\5\5\29\5\29\6\6\6\6\6\6\6\6\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\6\6\17\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\4\4\5\5\5\5\5\5\5\29\29\29\29\19\4\4\4\4\4\4\3\5\5\5\5\5\5\5\5\17\8\8\8\8\8\8\8\8\8\8\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\29\4\29\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\29\4\4\4\4\4\4\4\4\4\4\5\4\4\5\5\5\5\5\5\5\5\5\4\29\29\4\4\4\4\4\29\3\29\5\5\5\5\5\5\5\29\8\8\8\8\8\8\8\8\8\8\29\29\4\4\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\21\21\21\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\21\17\21\21\21\5\5\21\21\21\21\21\21\8\8\8\8\8\8\8\8\8\8\10\10\10\10\10\10\10\10\10\10\21\5\21\5\21\5\13\14\13\14\6\6\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\6\5\5\5\5\5\17\5\5\4\4\4\4\4\5\5\5\5\5\5\5\5\5\5\5\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\21\21\21\21\21\21\21\21\5\21\21\21\21\21\21\29\21\21\17\17\17\17\17\21\21\21\21\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\5\5\5\5\6\5\5\5\5\5\5\6\5\5\6\6\5\5\4\8\8\8\8\8\8\8\8\8\8\17\17\17\17\17\17\4\4\4\4\4\4\6\6\5\5\4\4\4\4\5\5\5\4\6\6\6\4\4\6\6\6\6\6\6\6\4\4\4\5\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\6\5\5\6\6\6\6\6\6\5\4\6\8\8\8\8\8\8\8\8\8\8\6\6\6\5\21\21\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\0\29\29\29\29\29\0\29\29\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\17\3\1\1\1"#
+    decompressed_table_5 = "\5\5\5\5\5\5\5\5\5\5\5\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\5\3\3\21\17\17\17\3\29\29\5\19\19\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\3\5\5\5\5\5\5\5\5\5\3\5\5\5\3\5\5\5\5\5\29\29\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\29\29\17\29\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\20\4\4\4\4\4\4\4\26\26\29\29\29\29\29\5\5\5\5\5\5\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\26\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\6"#
+    decompressed_table_6 = "\5\6\5\4\6\6\6\5\5\5\5\5\5\5\5\6\6\6\6\5\6\6\4\5\5\5\5\5\5\5\4\4\4\4\4\4\4\4\4\4\5\5\17\17\8\8\8\8\8\8\8\8\8\8\17\3\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\6\29\4\4\4\4\4\4\4\4\29\29\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\29\29\29\4\4\4\4\29\29\5\4\6\6\6\5\5\5\5\29\29\6\6\29\29\6\6\5\4\29\29\29\29\29\29\29\29\6\29\29\29\29\4\4\29\4\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\4\4\19\19\10\10\10\10\10\10\21\19\4\17\5\29\29\5\5\6\29\4\4\4\4\4\4\29\29\29\29\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\29\4\4\29\4\4\29\29\5\29\6\6\6\5\5\29\29\29\29\5\5\29\29\5\5\5\29\29\29\5\29\29\29\29\29\29\29\4\4\4\4\29\4\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\5\5\4\4\4\5\17\29\29\29\29\29\29\29\29\29\29\5\5\6\29\4\4\4\4\4\4\4\4\4\29\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\29\29\5\4\6\6\6\5\5\5\5\5\29\5\5\6\29\6\6\5\29\29\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\17\19\29\29\29\29\29\29\29\4\5\5\5\5\5\5\29\5\6\6\29\4\4\4\4\4\4\4\4\29\29\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\29\29\5\4\6\5\6\5\5\5\5\29\29\6\6\29\29\6\6\5\29\29\29\29\29\29\29\5\5\6\29\29\29\29\4\4\29\4\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\21\4\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\5\4\29\4\4\4\4\4\4\29\29\29\4\4\4\29\4\4\4\4\29\29\29\4\4\29\4\29\4\4\29\29\29\4\4\29\29\29\4\4\4\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\6\6\5\6\6\29\29\29\6\6\6\29\6\6\6\5\29\29\4\29\29\29\29\29\29\6\29\29\29\29\29\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\10\10\10\21\21\21\21\21\21\19\21\29\29\29\29\29\5\6\6\6\5\4\4\4\4\4\4\4\4\29\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\5\4\5\5\5\6\6\6\6\29\5\5\5\29\5\5\5\5\29\29\29\29\29\29\29\5\5\29\4\4\4\29\4\4\29\29\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\29\17\10\10\10\10\10\10\10\21\4\5\6\6\17\4\4\4\4\4\4\4\4\29\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\29\29\5\4\6\5\6\6\6\6\6\29\5\6\6\29\6\6\5\5\29\29\29\29\29\29\29\6\6\29\29\29\29\29\4\4\4\29\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\29\4\4\6\29\29\29\29\29\29\29\29\29\29\29\29\5\5\6\6\4\4\4\4\4\4\4\4\4\29\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\4\6\6\6\5\5\5\5\29\6\6\6\29\6\6\6\5\4\21\29\29\29\29\4\4\4\6\10\10\10\10\10\10\10\4\4\4\5\5\29\29\8\8\8\8\8\8\8\8\8\8\10\10\10\10\10\10\10\10\10\21\4\4\4\4\4\4\29\5\6\6\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\29\4\29\29\4\4\4\4\4\4\4\29\29\29\5\29\29\29\29\6\6\6\5\5\5\29\5\29\6\6\6\6\6\6\6\6\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\6\6\17\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\4\4\5\5\5\5\5\5\5\29\29\29\29\19\4\4\4\4\4\4\3\5\5\5\5\5\5\5\5\17\8\8\8\8\8\8\8\8\8\8\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\29\4\29\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\29\4\4\4\4\4\4\4\4\4\4\5\4\4\5\5\5\5\5\5\5\5\5\4\29\29\4\4\4\4\4\29\3\29\5\5\5\5\5\5\5\29\8\8\8\8\8\8\8\8\8\8\29\29\4\4\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\21\21\21\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\21\17\21\21\21\5\5\21\21\21\21\21\21\8\8\8\8\8\8\8\8\8\8\10\10\10\10\10\10\10\10\10\10\21\5\21\5\21\5\13\14\13\14\6\6\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\6\5\5\5\5\5\17\5\5\4\4\4\4\4\5\5\5\5\5\5\5\5\5\5\5\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\21\21\21\21\21\21\21\21\5\21\21\21\21\21\21\29\21\21\17\17\17\17\17\21\21\21\21\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\5\5\5\5\6\5\5\5\5\5\5\6\5\5\6\6\5\5\4\8\8\8\8\8\8\8\8\8\8\17\17\17\17\17\17\4\4\4\4\4\4\6\6\5\5\4\4\4\4\5\5\5\4\6\6\6\4\4\6\6\6\6\6\6\6\4\4\4\5\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\6\5\5\6\6\6\6\6\6\5\4\6\8\8\8\8\8\8\8\8\8\8\6\6\6\5\21\21\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\0\29\29\29\29\29\0\29\29\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\17\3\1\1\1"#
     decompressed_table_7 = "\29\4\4\4\4\29\29\4\4\4\4\4\4\4\29\4\29\4\4\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\29\29\4\4\4\4\4\4\4\29\4\29\4\4\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29"#
     decompressed_table_8 = "\29\4\4\4\4\29\29"#
     decompressed_table_9 = "\29\29\5\5\5\17\17\17\17\17\17\17\17\17\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29"#
@@ -670,9 +658,9 @@
     decompressed_table_13 = "\5\5\6\5\5\5\5\5\5\5\6\6\6\6\6\6\6\6\5\6\6\5\5\5\5\5\5\5\5\5\5\5\17\17\17\3\17\17\17\19\4\5\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\10\10\10\10\10\10\10\10\10\10\29\29\29\29\29\29\17\17\17\17\17\17\12\17\17\17\17\5\5\5\26\5\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3"#
     decompressed_table_14 = "\29\29\29\29\29\29\29\4\4\4\4\4\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\4\29\29\29\29\29"#
     decompressed_table_15 = "\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\5\5\5\6\6\6\6\5\5\6\6\6\29\29\29\29\6\6\5\6\6\6\6\6\6\5\5\5\29\29\29\29\21\29\29\29\17\17\8\8\8\8\8\8\8\8\8\8\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\4\4\4\4\4\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\10\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\6\6\5\29\29\17\17"#
-    decompressed_table_16 = "\6\5\6\5\5\5\5\5\5\5\29\5\6\5\6\6\5\5\5\5\5\5\5\5\6\6\6\6\6\6\5\5\5\5\5\5\5\5\5\5\29\29\5\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\17\17\17\17\17\17\17\3\17\17\17\17\17\17\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\7\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\5\5\5\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\5\5\5\5\5\6\5\6\6\6\6\6\5\6\6\4\4\4\4\4\4\4\4\29\17\17\8\8\8\8\8\8\8\8\8\8\17\17\17\17\17\17\17\21\21\21\21\21\21\21\21\21\21\5\5\5\5\5\5\5\5\5\21\21\21\21\21\21\21\21\21\17\17\17\5\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\5\5\5\5\6\6\5\5\6\5\5\5\4\4\8\8\8\8\8\8\8\8\8\8\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\5\5\6\6\6\5\6\5\5\5\6\6\29\29\29\29\29\29\29\29\17\17\17\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\6\6\6\6\6\5\5\5\5\5\5\5\5\6\6\5\5\29\29\29\17\17\17\17\17\8\8\8\8\8\8\8\8\8\8\29\29\29\4\4\4\8\8\8\8\8\8\8\8\8\8\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\3\3\3\3\3\17\17\1\1\1\1\1\1\1\1\1\0\1\29\29\29\29\29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\29\0\0\0\17\17\17\17\17\17\17\17\29\29\29\29\29\29\29\29\5\5\5\17\5\5\5\5\5\5\5\5\5\5\5\5\5\6\5\5\5\5\5\5\5\4\4\4\4\5\4\4\4\4\4\4\5\4\4\6\5\5\4\29\29\29\29\29\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"#
+    decompressed_table_16 = "\6\5\6\5\5\5\5\5\5\5\29\5\6\5\6\6\5\5\5\5\5\5\5\5\6\6\6\6\6\6\5\5\5\5\5\5\5\5\5\5\29\29\5\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\17\17\17\17\17\17\17\3\17\17\17\17\17\17\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\7\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\29\5\5\5\5\5\5\5\5\5\5\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\5\5\5\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\5\5\5\5\5\6\5\6\6\6\6\6\5\6\6\4\4\4\4\4\4\4\4\29\17\17\8\8\8\8\8\8\8\8\8\8\17\17\17\17\17\17\17\21\21\21\21\21\21\21\21\21\21\5\5\5\5\5\5\5\5\5\21\21\21\21\21\21\21\21\21\17\17\17\5\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\5\5\5\5\6\6\5\5\6\5\5\5\4\4\8\8\8\8\8\8\8\8\8\8\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\5\5\6\6\6\5\6\5\5\5\6\6\29\29\29\29\29\29\29\29\17\17\17\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\6\6\6\6\6\5\5\5\5\5\5\5\5\6\6\5\5\29\29\29\17\17\17\17\17\8\8\8\8\8\8\8\8\8\8\29\29\29\4\4\4\8\8\8\8\8\8\8\8\8\8\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\3\3\3\3\3\17\17\1\1\1\1\1\1\1\1\1\0\1\29\29\29\29\29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\29\0\0\0\17\17\17\17\17\17\17\17\29\29\29\29\29\29\29\29\5\5\5\17\5\5\5\5\5\5\5\5\5\5\5\5\5\6\5\5\5\5\5\5\5\4\4\4\4\5\4\4\4\4\4\4\5\4\4\6\5\5\4\29\29\29\29\29\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"#
     decompressed_table_17 = "\1\1\1\1\1\1\1\1\1\1\1\1\1\3\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"#
-    decompressed_table_18 = "\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\1\1\1\1\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\1\1\1\1\1\1\29\29\0\0\0\0\0\0\29\29\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\1\1\1\1\1\1\29\29\0\0\0\0\0\0\29\29\1\1\1\1\1\1\1\1\29\0\29\0\29\0\29\0\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\29\29\1\1\1\1\1\1\1\1\2\2\2\2\2\2\2\2\1\1\1\1\1\1\1\1\2\2\2\2\2\2\2\2\1\1\1\1\1\1\1\1\2\2\2\2\2\2\2\2\1\1\1\1\1\29\1\1\0\0\0\0\2\20\1\20\20\20\1\1\1\29\1\1\0\0\0\0\2\20\20\20\1\1\1\1\29\29\1\1\0\0\0\0\29\20\20\20\1\1\1\1\1\1\1\1\0\0\0\0\0\20\20\20\29\29\1\1\1\29\1\1\0\0\0\0\2\20\20\29\22\22\22\22\22\22\22\22\22\22\22\26\26\26\26\26\12\12\12\12\12\12\17\17\15\16\13\15\15\16\13\15\17\17\17\17\17\17\17\17\23\24\26\26\26\26\26\22\17\17\17\17\17\17\17\17\17\15\16\17\17\17\17\11\11\17\17\17\18\13\14\17\17\17\17\17\17\17\17\17\17\17\18\17\11\17\17\17\17\17\17\17\17\17\17\22\26\26\26\26\26\29\26\26\26\26\26\26\26\26\26\26\10\3\29\29\10\10\10\10\10\10\18\18\18\13\14\3\10\10\10\10\10\10\10\10\10\10\18\18\18\13\14\29\3\3\3\3\3\3\3\3\3\3\3\3\3\29\29\29\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\7\7\7\7\5\7\7\7\5\5\5\5\5\5\5\5\5\5\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\0\21\21\21\21\0\21\21\1\0\0\0\1\1\0\0\0\1\21\0\21\21\18\0\0\0\0\0\21\21\21\21\21\21\0\21\0\21\0\21\0\0\0\0\21\1\0\0\0\0\1\4\4\4\4\1\21\21\1\1\0\0\18\18\18\18\18\0\1\1\1\1\21\18\21\21\1\21\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\0\1\9\9\9\9\10\21\21\29\29\29\29\18\18\18\18\18\21\21\21\21\21\18\18\21\21\21\21\18\21\21\18\21\21\18\21\21\21\21\21\21\21\18\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\18\18\21\21\18\21\18\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21"#
+    decompressed_table_18 = "\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\1\1\1\1\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\1\1\1\1\1\1\29\29\0\0\0\0\0\0\29\29\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\1\1\1\1\1\1\29\29\0\0\0\0\0\0\29\29\1\1\1\1\1\1\1\1\29\0\29\0\29\0\29\0\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\29\29\1\1\1\1\1\1\1\1\2\2\2\2\2\2\2\2\1\1\1\1\1\1\1\1\2\2\2\2\2\2\2\2\1\1\1\1\1\1\1\1\2\2\2\2\2\2\2\2\1\1\1\1\1\29\1\1\0\0\0\0\2\20\1\20\20\20\1\1\1\29\1\1\0\0\0\0\2\20\20\20\1\1\1\1\29\29\1\1\0\0\0\0\29\20\20\20\1\1\1\1\1\1\1\1\0\0\0\0\0\20\20\20\29\29\1\1\1\29\1\1\0\0\0\0\2\20\20\29\22\22\22\22\22\22\22\22\22\22\22\26\26\26\26\26\12\12\12\12\12\12\17\17\15\16\13\15\15\16\13\15\17\17\17\17\17\17\17\17\23\24\26\26\26\26\26\22\17\17\17\17\17\17\17\17\17\15\16\17\17\17\17\11\11\17\17\17\18\13\14\17\17\17\17\17\17\17\17\17\17\17\18\17\11\17\17\17\17\17\17\17\17\17\17\22\26\26\26\26\26\29\26\26\26\26\26\26\26\26\26\26\10\3\29\29\10\10\10\10\10\10\18\18\18\13\14\3\10\10\10\10\10\10\10\10\10\10\18\18\18\13\14\29\3\3\3\3\3\3\3\3\3\3\3\3\3\29\29\29\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\19\29\29\29\29\29\29\29\29\29\29\29\29\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\7\7\7\7\5\7\7\7\5\5\5\5\5\5\5\5\5\5\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\0\21\21\21\21\0\21\21\1\0\0\0\1\1\0\0\0\1\21\0\21\21\18\0\0\0\0\0\21\21\21\21\21\21\0\21\0\21\0\21\0\0\0\0\21\1\0\0\0\0\1\4\4\4\4\1\21\21\1\1\0\0\18\18\18\18\18\0\1\1\1\1\21\18\21\21\1\21\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\9\0\1\9\9\9\9\10\21\21\29\29\29\29\18\18\18\18\18\21\21\21\21\21\18\18\21\21\21\21\18\21\21\18\21\21\18\21\21\21\21\21\21\21\18\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\18\18\21\21\18\21\18\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21"#
     decompressed_table_19 = "\21\21\21\21\21\21\21\21\13\14\13\14\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\18\18\21\21\21\21\21\21\21\13\14"#
     decompressed_table_20 = "\18\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\18\18\18\18\18\18"#
     decompressed_table_21 = "\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
@@ -680,7 +668,7 @@
     decompressed_table_23 = "\13\14\13\14\13\14\13\14\13\14\13\14\13\14\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\18\18\18\18\18\13\14\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\13\14\13\14\13\14\13\14\13\14\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18"#
     decompressed_table_24 = "\13\14\13\14\13\14\13\14\13\14\13\14\13\14\13\14\13\14\13\14\13\14"#
     decompressed_table_25 = "\13\14\13\14\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\13\14"#
-    decompressed_table_26 = "\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\21\21\18\18\18\18\18\18\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29"#
+    decompressed_table_26 = "\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\18\21\21\18\18\18\18\18\18\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29"#
     decompressed_table_27 = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\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\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\1\0\0\0\1\1\0\1\0\1\0\1\0\0\0\0\1\0\1\1\0\1\1\1\1\1\1\3\3\0\0\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\21\21\21\21\21\21\0\1\0\1\5\5\5\0\1\29\29\29\29\29\17\17\17\17\10\17\17\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\29\1\29\29\29\29\29\1\29\29"#
     decompressed_table_28 = "\29\29\29\29\29\29\29\3\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\17\17\15\16\15\16\17\17\17\15\16\17\15\16\17\17\17\17\17\17\17\17\17\12\17\17\12\17\15\16\17\17\15\16\13\14\13\14\13\14\13\14\17\17\17\17\17\3\17\17\17\17\17\17\17\17\17\17\12\12\17\17\17\17\12\17\13\17\17\17\17\17\17\17\17\17\17\17\17\17\21\21\17\17\17\13\14\13\14\13\14\13\14\12\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29"#
     decompressed_table_29 = "\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\22\17\17\17\21\3\4\9\13\14\13\14\13\14\13\14\13\14\21\21\13\14\13\14\13\14\13\14\12\13\14\14\21\9\9\9\9\9\9\9\9\9\5\5\5\5\6\6\12\3\3\3\3\3\21\21\9\9\9\3\4\17\21\21\29"#
@@ -689,14 +677,14 @@
     decompressed_table_32 = "\29\21\21\10\10\10\10\21\21\21\21\21\21\21\21\21\21\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\21\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\10\10\10\10\10\10\10\10\10\10\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\10\10\10\10\10\10\10\10\21\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\10\10\10\10\10\10\10\10\10\10\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10"#
     decompressed_table_33 = "\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\3\3\3\3\3\17\17"#
     decompressed_table_34 = "\3\17\17\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\8\8\8\8\8\8\8\8\8\8\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\4\5\7\7\7\17\5\5\5\5\5\5\5\5\5\5\17\3\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\3\3\5\5"#
-    decompressed_table_35 = "\9\9\9\9\9\9\9\9\9\9\5\5\17\17\17\17\17\17\29\29\29\29\29\29\29\29\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\3\3\3\3\3\3\3\3\3\20\20\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\3\1\1\1\1\1\1\1\1\0\1\0\1\0\0\1\0\1\0\1\0\1\0\1\3\20\20\0\1\0\1\4\0\1\0\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\0\0\0\0\1\0\0\0\0\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\0\0\0\1\0\1\0\0\1\29\29\0\1\29\1\29\1\0\1\0\1\0\1\0\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\3\3\3\0\1\4\3\3\1\4\4\4\4\4\4\4\5\4\4\4\5\4\4\4\4\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\5\5\6\21\21\21\21\5\29\29\29\10\10\10\10\10\10\21\21\19\21\29\29\29\29\29\29"#
+    decompressed_table_35 = "\9\9\9\9\9\9\9\9\9\9\5\5\17\17\17\17\17\17\29\29\29\29\29\29\29\29\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\3\3\3\3\3\3\3\3\3\20\20\0\1\0\1\0\1\0\1\0\1\0\1\0\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\3\1\1\1\1\1\1\1\1\0\1\0\1\0\0\1\0\1\0\1\0\1\0\1\3\20\20\0\1\0\1\4\0\1\0\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\0\0\0\0\1\0\0\0\0\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\0\0\0\1\0\1\0\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\3\3\3\3\0\1\4\3\3\1\4\4\4\4\4\4\4\5\4\4\4\5\4\4\4\4\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\5\5\6\21\21\21\21\5\29\29\29\10\10\10\10\10\10\21\21\19\21\29\29\29\29\29\29"#
     decompressed_table_36 = "\17\17\17\17\29\29\29\29\29\29\29\29\6\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\6\6\6\6\6\6\6\6\6\6\6\6\6\5\5\29\29\29\29\29\29\29\29\17\17\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\4\4\4\4\4\4\17\17\17\4\17\4\4\5\8\8\8\8\8\8\8\8\8\8\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\17\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\5\5\5\6\6\29\29\29\29\29\29\29\29\29\29\29\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\5\5\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\6\5\5\5\5\6\6\5\5\6\6\6\17\17\17\17\17\17\17\17\17\17\17\17\17\29\3\8\8\8\8\8\8\8\8\8\8\29\29\29\29\17\17\4\4\4\4\4\5\3\4\4\4\4\4\4\4\4\4\8\8\8\8\8\8\8\8\8\8\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\6\6\5\5\6\6\5\5\29\29\29\29\29\29\29\29\29\4\4\4\5\4\4\4\4\4\4\4\4\5\6\29\29\8\8\8\8\8\8\8\8\8\8\29\29\17\17\17\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\4\4\4\4\4\4\21\21\21\4\6\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\4\5\5\5\4\4\5\5\4\4\4\4\4\5\5\4\5\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\3\17\17\4\4\4\4\4\4\4\4\4\4\4\6\5\5\6\6\17\17\4\3\3\6\5\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\29\29\4\4\4\4\4\4\29\29\4\4\4\4\4\4\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\20\3\3\3\3\1\1\1\1\1\1\1\1\1\3\20\20\29\29\29\29"#
     decompressed_table_37 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\5\6\6\5\6\6\17\6\5\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29"#
     decompressed_table_38 = "\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29"#
     decompressed_table_39 = "\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\1\1\1\1\1\1\1\29\29\29\29\29\29\29\29\29\29\29\29\1\1\1\1\1\29\29\29\29\29\4\5\4\4\4\4\4\4\4\4\4\4\18\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\29\4\29\4\4\29\4\4\29"#
-    decompressed_table_40 = "\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
+    decompressed_table_40 = "\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21"#
     decompressed_table_41 = "\14\13\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21"#
-    decompressed_table_42 = "\29\29\29\29\29\29\29\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\19\21\21\21\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\17\17\17\17\17\17\17\13\14\17\29\29\29\29\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\17\12\12\11\11\13\14\13\14\13\14\13\14\13\14\13\14\13\14\13\14\17\17\13\14\17\17\17\17\11\11\11\17\17\17\29\17\17\17\17\12\13\14\13\14\13\14\17\17\17\18\12\18\18\18\29\17\19\17\17\29\29\29\29\4\4\4\4\4\29"#
+    decompressed_table_42 = "\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\19\21\21\21\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\17\17\17\17\17\17\17\13\14\17\29\29\29\29\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\17\12\12\11\11\13\14\13\14\13\14\13\14\13\14\13\14\13\14\13\14\17\17\13\14\17\17\17\17\11\11\11\17\17\17\29\17\17\17\17\12\13\14\13\14\13\14\17\17\17\18\12\18\18\18\29\17\19\17\17\29\29\29\29\4\4\4\4\4\29"#
     decompressed_table_43 = "\29\29\26\29\17\17\17\19\17\17\17\13\14\17\18\17\12\17\17\8\8\8\8\8\8\8\8\8\8\17\17\18\18\18\17\17\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\13\17\14\20\11\20\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\13\18\14\18\13\14\17\13\14\17\17\4\4\4\4\4\4\4\4\4\4\3\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\3\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\4\4\4\4\4\4\29\29\4\4\4\4\4\4\29\29\4\4\4\4\4\4\29\29\4\4\4\29\29\29\19\19\18\20\21\19\19\29\21\18\18\18\18\21\21\29\29\29\29\29\29\29\29\29\29\26\26\26\21\21\29\29\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
     decompressed_table_44 = "\29\29\29\29\29\17\17\17\29\29\29\29\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\29\29\29\21\21\21\21\21\21\21\21\21"#
     decompressed_table_45 = "\10\10\10\10\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\10\10\21\21\21\29\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\5"#
@@ -704,22 +692,22 @@
     decompressed_table_47 = "\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\29\29\29\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29"#
     decompressed_table_48 = "\29\29\29\29\29\29\29\29\29\29\29\17\0\0\0\0\0\0\0\0\0\0\0\29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\0\0\0\0\0\0\0\29\0\0\29\1\1\1\1\1\1\1\1\1\1\1\29\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\29\1\1\1\1\1\1\1\29\1\1\29\29\29"#
     decompressed_table_49 = "\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\3\3\3\3\3\3\29\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\29\3\3\3\3\3\3\3\3\3"#
-    decompressed_table_50 = "\4\4\4\4\4\4\29\29\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\29\29\29\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\17\10\10\10\10\10\10\10\10\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\21\21\10\10\10\10\10\10\10\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29\10\10\10\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\29\29\29\29\29\10\10\10\10\10\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\10\10\10\10\10\10\29\29\29\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\17"#
+    decompressed_table_50 = "\4\4\4\4\4\4\29\29\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\29\29\29\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\17\10\10\10\10\10\10\10\10\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\21\21\10\10\10\10\10\10\10\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29\10\10\10\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\29\29\29\29\29\10\10\10\10\10\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\10\10\10\10\10\10\29\29\29\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
     decompressed_table_51 = "\29\29\29\29\10\10\4\4\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\29\29\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\4\5\5\5\29\5\5\29\29\29\29\29\5\5\5\5\4\4\4\4\29\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\5\5\5\29\29\29\29\5\10\10\10\10\10\10\10\10\10\29\29\29\29\29\29\29\17\17\17\17\17\17\17\17\17\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\10\10\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\10\10\10\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\21\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\29\29\29\29\10\10\10\10\10\17\17\17\17\17\17\17\29\29\29\29\29\29\29\29\29"#
     decompressed_table_52 = "\29\29\29\17\17\17\17\17\17\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\10\10\10\10\10\10\10\10\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\10\10\10\10\10\10\10\10\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29\29\10\10\10\10\10\10\10"#
     decompressed_table_53 = "\29\29\29\29\29\29\29\10\10\10\10\10\10\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\4\4\4\4\3\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\29\29\5\5\5\5\5\12\3\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\29\29\29\29\29\29\29\29\18\18"#
-    decompressed_table_54 = "\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\5\5\12\29\29\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4"#
-    decompressed_table_55 = "\5\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\10\10\10\10\10\10\10\10\10\10\4\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\5\5\5\10\10\10\10\17\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\10\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29\29\6\5\6"#
-    decompressed_table_56 = "\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\17\17\17\17\17\17\17\29\29\29\29\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\8\8\8\8\8\8\8\8\8\8\5\4\4\5\5\4\29\29\29\29\29\29\29\29\29\5\5\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\6\6\5\5\17\17\26\17\17\17\17\5\29\29\29\29\29\29\29\29\29\29\26\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\6\5\5\5\5\5\5\5\5\29\8\8\8\8\8\8\8\8\8\8\17\17\17\17\4\6\6\4\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\17\17\4\29\29\29\29\29\29\29\29\29\5\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\5\5\5\5\5\6\6\4\4\4\4\17\17\17\17\5\5\5\5\17\6\5\8\8\8\8\8\8\8\8\8\8\4\17\4\17\17\17\29\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\6\6\5\6\5\5\17\17\17\17\17\17\5\4\4\5"#
-    decompressed_table_57 = "\4\4\4\4\4\4\4\29\4\29\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\17\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\6\6\5\5\5\5\5\5\5\5\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\5\5\6\6\29\4\4\4\4\4\4\4\4\29\29\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\29\5\5\4\6\6\5\6\6\6\6\29\29\6\6\29\29\6\6\6\29\29\4\29\29\29\29\29\29\6\29\29\29\29\29\4\4\4\4\4\6\6\29\29\5\5\5\5\5\5\5\29\29\29\5\5\5\5\5\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\29\4\29\29\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\6\6\6\5\5\5\5\5\5\29\6\29\29\6\29\6\6\6\6\29\6\6\5\6\5\4\5\4\17\17\29\17\17\29\29\29\29\29\29\29\29\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
-    decompressed_table_58 = "\6\6\6\5\5\5\5\5\5\5\5\6\6\5\5\5\6\5\4\4\4\4\17\17\17\17\17\8\8\8\8\8\8\8\8\8\8\17\17\29\17\5\4\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\5\5\6\5\6\6\6\6\5\5\6\5\5\4\4\17\4\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8"#
-    decompressed_table_59 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\29\29\6\6\6\6\5\5\6\5\5\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\4\4\4\4\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\5\5\5\5\6\6\5\6\5\5\17\17\17\4\29\29\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\17\17\17\17\17\17\17\17\17\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\5\6\6\5\5\5\5\5\5\6\5\4\17\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\5\6\5\6\6\5\5\5\5\6\5\5\5\5\5\29\29\29\29\8\8\8\8\8\8\8\8\8\8\10\10\17\17\17\21\4\4\4\4\4\4\4"#
-    decompressed_table_60 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\5\5\5\5\5\6\5\5\17"#
-    decompressed_table_61 = "\0\0\0\0\0\0\0\0\0\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\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\8\8\8\8\8\8\8\8\8\8\10\10\10\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\29\29\4\29\29\4\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\6\6\6\29\6\6\29\29\5\5\6\5\4\6\4\6\5\17\17\17\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8"#
-    decompressed_table_62 = "\4\4\4\4\4\4\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\29\29\5\5\6\6\6\6\5\4\17\4\6\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\5\5\5\5\5\5\5\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\6\4\5\5\5\5\17\17\17\17\17\17\17\17\5\29\29\29\29\29\29\29\29\4\5\5\5\5\5\5\6\6\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\5\5\5\5\5\6\5\5\17\17\17\4\17\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29"#
-    decompressed_table_63 = "\29\29\29\29\29\29\29\17\17\17\17\17\17\17\17\17\17"#
+    decompressed_table_54 = "\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\5\5\12\29\29\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\3\4\4\29\29\29\29\29\29\29\29\17\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\5\5\5\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\10\10\10\10\10\10\10\10\10\10\4\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\5\5\5\10\10\10\10\17\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\10\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\29\29\6\5\6"#
+    decompressed_table_55 = "\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\17\17\17\17\17\17\17\29\29\29\29\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\8\8\8\8\8\8\8\8\8\8\5\4\4\5\5\4\29\29\29\29\29\29\29\29\29\5\5\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\6\6\5\5\17\17\26\17\17\17\17\5\29\29\29\29\29\29\29\29\29\29\26\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\6\5\5\5\5\5\5\5\5\29\8\8\8\8\8\8\8\8\8\8\17\17\17\17\4\6\6\4\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\17\17\4\29\29\29\29\29\29\29\29\29\5\5\6\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\5\5\5\5\5\6\6\4\4\4\4\17\17\17\17\5\5\5\5\17\6\5\8\8\8\8\8\8\8\8\8\8\4\17\4\17\17\17\29\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\6\6\5\6\5\5\17\17\17\17\17\17\5\4\4\5"#
+    decompressed_table_56 = "\4\4\4\4\4\4\4\29\4\29\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\17\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\6\6\5\5\5\5\5\5\5\5\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\5\5\6\6\29\4\4\4\4\4\4\4\4\29\29\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\29\5\5\4\6\6\5\6\6\6\6\29\29\6\6\29\29\6\6\6\29\29\4\29\29\29\29\29\29\6\29\29\29\29\29\4\4\4\4\4\6\6\29\29\5\5\5\5\5\5\5\29\29\29\5\5\5\5\5\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\29\4\29\29\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\6\6\6\5\5\5\5\5\5\29\6\29\29\6\29\6\6\6\6\29\6\6\5\6\5\4\5\4\17\17\29\17\17\29\29\29\29\29\29\29\29\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
+    decompressed_table_57 = "\6\6\6\5\5\5\5\5\5\5\5\6\6\5\5\5\6\5\4\4\4\4\17\17\17\17\17\8\8\8\8\8\8\8\8\8\8\17\17\29\17\5\4\4\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\5\5\6\5\6\6\6\6\5\5\6\5\5\4\4\17\4\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8"#
+    decompressed_table_58 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\29\29\6\6\6\6\5\5\6\5\5\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\17\4\4\4\4\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\5\5\5\5\6\6\5\6\5\5\17\17\17\4\29\29\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\17\17\17\17\17\17\17\17\17\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\6\5\6\6\5\5\5\5\5\5\6\5\4\17\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\5\6\5\6\6\5\5\5\5\6\5\5\5\5\5\29\29\29\29\8\8\8\8\8\8\8\8\8\8\10\10\17\17\17\21\4\4\4\4\4\4\4"#
+    decompressed_table_59 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\5\5\5\5\5\6\5\5\17"#
+    decompressed_table_60 = "\0\0\0\0\0\0\0\0\0\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\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\8\8\8\8\8\8\8\8\8\8\10\10\10\10\10\10\10\10\10\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\29\29\4\29\29\4\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\6\6\6\29\6\6\29\29\5\5\6\5\4\6\4\6\5\17\17\17\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8"#
+    decompressed_table_61 = "\4\4\4\4\4\4\4\4\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\5\5\5\5\29\29\5\5\6\6\6\6\5\4\17\4\6\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\5\5\5\5\5\5\5\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\6\4\5\5\5\5\17\17\17\17\17\17\17\17\5\29\29\29\29\29\29\29\29\4\5\5\5\5\5\5\6\6\5\5\5\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\5\5\5\5\5\5\6\5\5\17\17\17\4\17\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29\29\29"#
+    decompressed_table_62 = "\29\29\29\29\29\29\29\17\17\17\17\17\17\17\17\17\17"#
+    decompressed_table_63 = "\5\6\5\5\5\6\5\6"#
     decompressed_table_64 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\17\29\29\29\29\29\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\5\5\5\5\5\5\5\29\5\5\5\5\5\5\6\5\4\17\17\17\17\17\29\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\29\29\29\17\17\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\6\5\5\5\5\5\5\5\6\5\5\6\5\5"#
-    decompressed_table_65 = "\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\29\29\29\5\29\5\5\29\5\5\5\5\5\5\5\4\5\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\6\6\29\5\5\29\6\6\5\6\5\4\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8"#
+    decompressed_table_65 = "\4\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\29\29\29\5\29\5\5\29\5\5\5\5\5\5\5\4\5\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\4\4\4\4\4\4\29\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\6\6\6\29\5\5\29\6\6\5\6\5\4\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\4\4\29\29\29\29\8\8\8\8\8\8\8\8\8\8"#
     decompressed_table_66 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\6\6\17\17\29\29\29\29\29\29\29\5\5\4\6\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\6\6\5\5\5\5\5\29\29\29\6\6\5\6\5\17\17\17\17\17\17\17\17\17\17\17\17\17\8\8\8\8\8\8\8\8\8\8\5"#
     decompressed_table_67 = "\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\21\21\21\21\21\21\21\21\19\19\19\19\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\17"#
     decompressed_table_68 = "\29\17\17\17\17\17\29\29\29\29\29\29\29\29\29\29\29"#
@@ -729,16 +717,16 @@
     decompressed_table_72 = "\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\17\17"#
     decompressed_table_73 = "\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\5\5\5\5\5\17\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\5\5\5\17\17\17\17\17\21\21\21\21\3\3\3\3\17\21\29\29\29\29\29\29\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\10\10\10\10\10\10\10\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4"#
     decompressed_table_74 = "\3\3\3\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\3\17\17\17\8\8\8\8\8\8\8\8\8\8"#
-    decompressed_table_75 = "\0\0\0\0\0\0\0\0\0\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\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\17\17\17\17"#
+    decompressed_table_75 = "\0\0\0\0\0\0\0\0\0\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\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\17\17\17\17\29\29\29\29\29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\29\29\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
     decompressed_table_76 = "\29\29\29\29\5\4"#
     decompressed_table_77 = "\29\29\29\29\29\29\29\5\5\5\5\3\3\3\3\3\3\3\3\3\3\3\3\3"#
-    decompressed_table_78 = "\3\3\17\3\5\29\29\29\29\29\29\29\29\29\29\29\6\6\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
-    decompressed_table_79 = "\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4"#
+    decompressed_table_78 = "\3\3\17\3\5\29\29\29\29\29\29\29\29\29\29\29\6\6\3\3\9\9\9\29\29\29\29\29\29\29\29\29"#
+    decompressed_table_79 = "\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4"#
     decompressed_table_80 = "\3\3\3\3\29\3\3\3\3\3\3\3\29\3\3\29"#
     decompressed_table_81 = "\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\29\29\4\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\29\29\29\29\29\29\29\29"#
     decompressed_table_82 = "\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\4\4\4\4\4\4\4\4\4\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\29\29\21\5\5\17\26\26\26\26"#
-    decompressed_table_83 = "\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\29"#
-    decompressed_table_84 = "\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\29\29\29\29\29\29\29\29"#
+    decompressed_table_83 = "\8\8\8\8\8\8\8\8\8\8\21\21\21\29\29\29"#
+    decompressed_table_84 = "\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\18\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\29\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\29\29\29\29\29\29\29\29\29"#
     decompressed_table_85 = "\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29"#
     decompressed_table_86 = "\6\6\5\5\5\21\21\21\6\6\6\6\6\6\26\26\26\26\26\26\26\26\5\5\5\5\5\5\5\5\21\21\5\5\5\5\5\5\5\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\5\5\5\5"#
     decompressed_table_87 = "\5\5\5\21"#
@@ -753,20 +741,22 @@
     decompressed_table_96 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\5\5\8\8\8\8\8\8\8\8\8\8\29\29\29\29\29\19"#
     decompressed_table_97 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\3\5\5\5\5\8\8\8\8\8\8\8\8\8\8"#
     decompressed_table_98 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\5\5\4\8\8\8\8\8\8\8\8\8\8\29\29\29\29\17"#
-    decompressed_table_99 = "\4\4\4\4\4\4\4\29\4\4\4\4\29\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29"#
-    decompressed_table_100 = "\29\29\10\10\10\10\10\10\10\10\10\5\5\5\5\5\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\0\0\0\0\0\0\0\0\0\0\0\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\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\5\5\5\5\5\5\5\3\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\17\17"#
-    decompressed_table_101 = "\21\10\10\10\19\10\10\10\10"#
-    decompressed_table_102 = "\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\21\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10"#
-    decompressed_table_103 = "\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\29\4\29\29\4\29\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\29\4\29\4\29\29\29\29\29\29\4\29\29\29\29\4\29\4\29\4\29\4\4\4\29\4\4\29\4\29\29\4\29\4\29\4\29\4\29\4\29\4\4\29\4\29\29\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\4\4\29\4\4\4\4\29\4\29\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\4\4\4\29\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4"#
-    decompressed_table_104 = "\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29"#
-    decompressed_table_105 = "\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\29\10\10\10\10\10\10\10\10\10\10\10\10\10"#
-    decompressed_table_106 = "\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21"#
-    decompressed_table_107 = "\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29"#
-    decompressed_table_108 = "\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29"#
-    decompressed_table_109 = "\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\21\21"#
-    decompressed_table_110 = "\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29"#
-    decompressed_table_111 = "\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29"#
-    decompressed_table_112 = "\26\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
+    decompressed_table_99 = "\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\4\5\4\4\5\4\4\4\4\4\4\4\5\5\4\4\4\4\4\5\29\29\29\29\29\29\29\29\4\3"#
+    decompressed_table_100 = "\4\4\4\4\4\4\4\29\4\4\4\4\29\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29"#
+    decompressed_table_101 = "\29\29\10\10\10\10\10\10\10\10\10\5\5\5\5\5\5\5\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\0\0\0\0\0\0\0\0\0\0\0\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\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\5\5\5\5\5\5\5\3\29\29\29\29\8\8\8\8\8\8\8\8\8\8\29\29\29\29\17\17"#
+    decompressed_table_102 = "\21\10\10\10\19\10\10\10\10"#
+    decompressed_table_103 = "\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\21\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10"#
+    decompressed_table_104 = "\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\4\4\29\4\29\29\4\29\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\29\4\29\4\29\29\29\29\29\29\4\29\29\29\29\4\29\4\29\4\29\4\4\4\29\4\4\29\4\29\29\4\29\4\29\4\29\4\29\4\29\4\4\29\4\29\29\4\4\4\4\29\4\4\4\4\4\4\4\29\4\4\4\4\29\4\4\4\4\29\4\29\4\4\4\4\4\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\29\29\29\29\29\4\4\4\29\4\4\4\4\4\29\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4\4"#
+    decompressed_table_105 = "\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29"#
+    decompressed_table_106 = "\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\29\10\10\10\10\10\10\10\10\10\10\10\10\10"#
+    decompressed_table_107 = "\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21"#
+    decompressed_table_108 = "\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29"#
+    decompressed_table_109 = "\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29"#
+    decompressed_table_110 = "\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\21\21\29\29\29\29\29\29\29\29\29\29\29\29\29\29\18\18\18\18\18\18\18\18\18\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
+    decompressed_table_111 = "\29\29\29\29\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\21\21\21\21\21\21\21\21\21\21\21\29\29\29"#
+    decompressed_table_112 = "\29\21\29\29\29\29\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\21\29\29\21\21\21\21\21\21\21\21\21\21\21\21\29\29\29\29\21\21\21\21\21\21\21\21\21\21\29\29\29\29\29\29\29"#
+    decompressed_table_113 = "\8\8\8\8\8\8\8\8\8\8\21"#
+    decompressed_table_114 = "\26\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29\29"#
 
 
 
diff --git a/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleLowerCaseMapping.hs b/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleLowerCaseMapping.hs
--- a/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleLowerCaseMapping.hs
+++ b/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleLowerCaseMapping.hs
@@ -1,5 +1,5 @@
 -- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell,
--- with data from: https://www.unicode.org/Public/16.0.0/ucd/UnicodeData.txt.
+-- with data from: https://www.unicode.org/Public/17.0.0/ucd/UnicodeData.txt.
 
 {-# LANGUAGE NoImplicitPrelude, LambdaCase #-}
 {-# OPTIONS_HADDOCK hide #-}
@@ -1167,7 +1167,10 @@
   '\xa7c9' -> '\xa7ca'
   '\xa7cb' -> '\x264'
   '\xa7cc' -> '\xa7cd'
+  '\xa7ce' -> '\xa7cf'
   '\xa7d0' -> '\xa7d1'
+  '\xa7d2' -> '\xa7d3'
+  '\xa7d4' -> '\xa7d5'
   '\xa7d6' -> '\xa7d7'
   '\xa7d8' -> '\xa7d9'
   '\xa7da' -> '\xa7db'
@@ -1447,6 +1450,31 @@
   '\x16e5d' -> '\x16e7d'
   '\x16e5e' -> '\x16e7e'
   '\x16e5f' -> '\x16e7f'
+  '\x16ea0' -> '\x16ebb'
+  '\x16ea1' -> '\x16ebc'
+  '\x16ea2' -> '\x16ebd'
+  '\x16ea3' -> '\x16ebe'
+  '\x16ea4' -> '\x16ebf'
+  '\x16ea5' -> '\x16ec0'
+  '\x16ea6' -> '\x16ec1'
+  '\x16ea7' -> '\x16ec2'
+  '\x16ea8' -> '\x16ec3'
+  '\x16ea9' -> '\x16ec4'
+  '\x16eaa' -> '\x16ec5'
+  '\x16eab' -> '\x16ec6'
+  '\x16eac' -> '\x16ec7'
+  '\x16ead' -> '\x16ec8'
+  '\x16eae' -> '\x16ec9'
+  '\x16eaf' -> '\x16eca'
+  '\x16eb0' -> '\x16ecb'
+  '\x16eb1' -> '\x16ecc'
+  '\x16eb2' -> '\x16ecd'
+  '\x16eb3' -> '\x16ece'
+  '\x16eb4' -> '\x16ecf'
+  '\x16eb5' -> '\x16ed0'
+  '\x16eb6' -> '\x16ed1'
+  '\x16eb7' -> '\x16ed2'
+  '\x16eb8' -> '\x16ed3'
   '\x1e900' -> '\x1e922'
   '\x1e901' -> '\x1e923'
   '\x1e902' -> '\x1e924'
diff --git a/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleTitleCaseMapping.hs b/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleTitleCaseMapping.hs
--- a/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleTitleCaseMapping.hs
+++ b/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleTitleCaseMapping.hs
@@ -1,5 +1,5 @@
 -- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell,
--- with data from: https://www.unicode.org/Public/16.0.0/ucd/UnicodeData.txt.
+-- with data from: https://www.unicode.org/Public/17.0.0/ucd/UnicodeData.txt.
 
 {-# LANGUAGE NoImplicitPrelude, LambdaCase #-}
 {-# OPTIONS_HADDOCK hide #-}
@@ -1108,7 +1108,10 @@
   '\xa7c8' -> '\xa7c7'
   '\xa7ca' -> '\xa7c9'
   '\xa7cd' -> '\xa7cc'
+  '\xa7cf' -> '\xa7ce'
   '\xa7d1' -> '\xa7d0'
+  '\xa7d3' -> '\xa7d2'
+  '\xa7d5' -> '\xa7d4'
   '\xa7d7' -> '\xa7d6'
   '\xa7d9' -> '\xa7d8'
   '\xa7db' -> '\xa7da'
@@ -1468,6 +1471,31 @@
   '\x16e7d' -> '\x16e5d'
   '\x16e7e' -> '\x16e5e'
   '\x16e7f' -> '\x16e5f'
+  '\x16ebb' -> '\x16ea0'
+  '\x16ebc' -> '\x16ea1'
+  '\x16ebd' -> '\x16ea2'
+  '\x16ebe' -> '\x16ea3'
+  '\x16ebf' -> '\x16ea4'
+  '\x16ec0' -> '\x16ea5'
+  '\x16ec1' -> '\x16ea6'
+  '\x16ec2' -> '\x16ea7'
+  '\x16ec3' -> '\x16ea8'
+  '\x16ec4' -> '\x16ea9'
+  '\x16ec5' -> '\x16eaa'
+  '\x16ec6' -> '\x16eab'
+  '\x16ec7' -> '\x16eac'
+  '\x16ec8' -> '\x16ead'
+  '\x16ec9' -> '\x16eae'
+  '\x16eca' -> '\x16eaf'
+  '\x16ecb' -> '\x16eb0'
+  '\x16ecc' -> '\x16eb1'
+  '\x16ecd' -> '\x16eb2'
+  '\x16ece' -> '\x16eb3'
+  '\x16ecf' -> '\x16eb4'
+  '\x16ed0' -> '\x16eb5'
+  '\x16ed1' -> '\x16eb6'
+  '\x16ed2' -> '\x16eb7'
+  '\x16ed3' -> '\x16eb8'
   '\x1e922' -> '\x1e900'
   '\x1e923' -> '\x1e901'
   '\x1e924' -> '\x1e902'
diff --git a/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleUpperCaseMapping.hs b/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleUpperCaseMapping.hs
--- a/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleUpperCaseMapping.hs
+++ b/src/GHC/Internal/Unicode/Char/UnicodeData/SimpleUpperCaseMapping.hs
@@ -1,5 +1,5 @@
 -- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell,
--- with data from: https://www.unicode.org/Public/16.0.0/ucd/UnicodeData.txt.
+-- with data from: https://www.unicode.org/Public/17.0.0/ucd/UnicodeData.txt.
 
 {-# LANGUAGE NoImplicitPrelude, LambdaCase #-}
 {-# OPTIONS_HADDOCK hide #-}
@@ -1104,7 +1104,10 @@
   '\xa7c8' -> '\xa7c7'
   '\xa7ca' -> '\xa7c9'
   '\xa7cd' -> '\xa7cc'
+  '\xa7cf' -> '\xa7ce'
   '\xa7d1' -> '\xa7d0'
+  '\xa7d3' -> '\xa7d2'
+  '\xa7d5' -> '\xa7d4'
   '\xa7d7' -> '\xa7d6'
   '\xa7d9' -> '\xa7d8'
   '\xa7db' -> '\xa7da'
@@ -1464,6 +1467,31 @@
   '\x16e7d' -> '\x16e5d'
   '\x16e7e' -> '\x16e5e'
   '\x16e7f' -> '\x16e5f'
+  '\x16ebb' -> '\x16ea0'
+  '\x16ebc' -> '\x16ea1'
+  '\x16ebd' -> '\x16ea2'
+  '\x16ebe' -> '\x16ea3'
+  '\x16ebf' -> '\x16ea4'
+  '\x16ec0' -> '\x16ea5'
+  '\x16ec1' -> '\x16ea6'
+  '\x16ec2' -> '\x16ea7'
+  '\x16ec3' -> '\x16ea8'
+  '\x16ec4' -> '\x16ea9'
+  '\x16ec5' -> '\x16eaa'
+  '\x16ec6' -> '\x16eab'
+  '\x16ec7' -> '\x16eac'
+  '\x16ec8' -> '\x16ead'
+  '\x16ec9' -> '\x16eae'
+  '\x16eca' -> '\x16eaf'
+  '\x16ecb' -> '\x16eb0'
+  '\x16ecc' -> '\x16eb1'
+  '\x16ecd' -> '\x16eb2'
+  '\x16ece' -> '\x16eb3'
+  '\x16ecf' -> '\x16eb4'
+  '\x16ed0' -> '\x16eb5'
+  '\x16ed1' -> '\x16eb6'
+  '\x16ed2' -> '\x16eb7'
+  '\x16ed3' -> '\x16eb8'
   '\x1e922' -> '\x1e900'
   '\x1e923' -> '\x1e901'
   '\x1e924' -> '\x1e902'
diff --git a/src/GHC/Internal/Unicode/Version.hs b/src/GHC/Internal/Unicode/Version.hs
--- a/src/GHC/Internal/Unicode/Version.hs
+++ b/src/GHC/Internal/Unicode/Version.hs
@@ -18,8 +18,8 @@
 import {-# SOURCE #-} GHC.Internal.Data.Version
 
 -- | Version of Unicode standard used by @base@:
--- [16.0.0](https://www.unicode.org/versions/Unicode16.0.0/).
+-- [17.0.0](https://www.unicode.org/versions/Unicode17.0.0/).
 --
 -- @since base-4.15.0.0
 unicodeVersion :: Version
-unicodeVersion = makeVersion [16, 0, 0]
+unicodeVersion = makeVersion [17, 0, 0]
diff --git a/src/GHC/Internal/Wasm/Prim/Types.hs b/src/GHC/Internal/Wasm/Prim/Types.hs
--- a/src/GHC/Internal/Wasm/Prim/Types.hs
+++ b/src/GHC/Internal/Wasm/Prim/Types.hs
@@ -147,6 +147,7 @@
 -- the same 'JSVal', subsequent invocations are no-ops. You are
 -- strongly recommended to call 'freeJSVal' on short-lived
 -- intermediate 'JSVal' values for timely release of resources!
+{-# INLINE freeJSVal #-}
 freeJSVal :: JSVal -> IO ()
 freeJSVal v@(JSVal p) = do
   js_callback_unregister v
@@ -183,15 +184,16 @@
 -- eagerly once the resulting 'String' is forced, and the argument
 -- 'JSString' may be explicitly freed if no longer used.
 fromJSString :: JSString -> String
-fromJSString s = unsafeDupablePerformIO $ do
-  l <- js_stringLength s
-  fp <- mallocPlainForeignPtrBytes $ l * 3
-  withForeignPtr fp $ \buf -> do
-    l' <- js_encodeInto s buf $ l * 3
-    peekCStringLen utf8 (buf, l')
+fromJSString s = case js_stringLength s * 3 of
+  0 -> ""
+  max_len -> unsafePerformIO $ do
+    fptr <- mallocPlainForeignPtrBytes max_len
+    withForeignPtr fptr $ \ptr -> do
+      len <- js_encodeInto s ptr max_len
+      peekCStringLen utf8 (ptr, len)
 
 foreign import javascript unsafe "$1.length"
-  js_stringLength :: JSString -> IO Int
+  js_stringLength :: JSString -> Int
 
 foreign import javascript unsafe "(new TextEncoder()).encodeInto($1, new Uint8Array(__exports.memory.buffer, $2, $3)).written"
   js_encodeInto :: JSString -> Ptr a -> Int -> IO Int
diff --git a/src/GHC/Internal/Word.hs b/src/GHC/Internal/Word.hs
--- a/src/GHC/Internal/Word.hs
+++ b/src/GHC/Internal/Word.hs
@@ -38,7 +38,7 @@
     bitReverse64,
 
     -- * Equality operators
-    -- | See GHC.Classes#matching_overloaded_methods_in_rules
+    -- | See GHC.Internal.Classes#matching_overloaded_methods_in_rules
     eqWord, neWord, gtWord, geWord, ltWord, leWord,
     eqWord8, neWord8, gtWord8, geWord8, ltWord8, leWord8,
     eqWord16, neWord16, gtWord16, geWord16, ltWord16, leWord16,
@@ -48,7 +48,7 @@
 
 import GHC.Internal.Data.Maybe
 
-import GHC.Prim
+import GHC.Internal.Prim
 import GHC.Internal.Base
 
 import GHC.Internal.Bits
@@ -71,7 +71,7 @@
 
 -- ^ 8-bit unsigned integer type
 
--- See GHC.Classes#matching_overloaded_methods_in_rules
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
 -- | @since base-2.01
 instance Eq Word8 where
     (==) = eqWord8
@@ -261,7 +261,7 @@
 data {-# CTYPE "HsWord16" #-} Word16 = W16# Word16#
 -- ^ 16-bit unsigned integer type
 
--- See GHC.Classes#matching_overloaded_methods_in_rules
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
 -- | @since base-2.01
 instance Eq Word16 where
     (==) = eqWord16
@@ -493,7 +493,7 @@
 data {-# CTYPE "HsWord32" #-} Word32 = W32# Word32#
 -- ^ 32-bit unsigned integer type
 
--- See GHC.Classes#matching_overloaded_methods_in_rules
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
 -- | @since base-2.01
 instance Eq Word32 where
     (==) = eqWord32
@@ -681,7 +681,7 @@
 data {-# CTYPE "HsWord64" #-} Word64 = W64# Word64#
 -- ^ 64-bit unsigned integer type
 
--- See GHC.Classes#matching_overloaded_methods_in_rules
+-- See GHC.Internal.Classes#matching_overloaded_methods_in_rules
 -- | @since base-2.01
 instance Eq Word64 where
     (==) = eqWord64
