Update Sample Transform implementation (#2588)

diff --git a/include/avif/internal.h b/include/avif/internal.h
index ccee529..426d8e4 100644
--- a/include/avif/internal.h
+++ b/include/avif/internal.h
@@ -179,28 +179,37 @@
     // Operands.
     AVIF_SAMPLE_TRANSFORM_CONSTANT = 0,
     AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX = 1,
+    AVIF_SAMPLE_TRANSFORM_FIRST_INPUT_IMAGE_ITEM_INDEX = 1,
+    AVIF_SAMPLE_TRANSFORM_LAST_INPUT_IMAGE_ITEM_INDEX = 32,
 
-    // Operators. L is the left operand. R is the right operand if there are two operands.
-    AVIF_SAMPLE_TRANSFORM_NEGATE = 2,     // S = -L
-    AVIF_SAMPLE_TRANSFORM_ABSOLUTE = 3,   // S = |L|
-    AVIF_SAMPLE_TRANSFORM_SUM = 4,        // S = L + R
-    AVIF_SAMPLE_TRANSFORM_DIFFERENCE = 5, // S = L - R
-    AVIF_SAMPLE_TRANSFORM_PRODUCT = 6,    // S = L * R
-    AVIF_SAMPLE_TRANSFORM_DIVIDE = 7,     // S = R==0 ? L : floor(L / R)
-    AVIF_SAMPLE_TRANSFORM_AND = 8,        // S = L & R
-    AVIF_SAMPLE_TRANSFORM_OR = 9,         // S = L | R
-    AVIF_SAMPLE_TRANSFORM_XOR = 10,       // S = L ^ R
-    AVIF_SAMPLE_TRANSFORM_NOT = 11,       // S = ~L
-    AVIF_SAMPLE_TRANSFORM_MSB = 12,       // S = L<=0 ? 0 : floor(log2(L))
-    AVIF_SAMPLE_TRANSFORM_POW = 13,       // S = L==0 ? 0 : pow(L, R)
-    AVIF_SAMPLE_TRANSFORM_MIN = 14,       // S = L<=R ? L : R
-    AVIF_SAMPLE_TRANSFORM_MAX = 15,       // S = L<=R ? R : L
-    AVIF_SAMPLE_TRANSFORM_RESERVED
+    // Unary operators. L is the operand.
+    AVIF_SAMPLE_TRANSFORM_FIRST_UNARY_OPERATOR = 64,
+    AVIF_SAMPLE_TRANSFORM_NEGATION = 64, // S = -L
+    AVIF_SAMPLE_TRANSFORM_ABSOLUTE = 65, // S = |L|
+    AVIF_SAMPLE_TRANSFORM_NOT = 66,      // S = ~L
+    AVIF_SAMPLE_TRANSFORM_BSR = 67,      // S = L<=0 ? 0 : truncate(log2(L))
+    AVIF_SAMPLE_TRANSFORM_LAST_UNARY_OPERATOR = 67,
+
+    // Binary operators. L is the left operand. R is the right operand.
+    AVIF_SAMPLE_TRANSFORM_FIRST_BINARY_OPERATOR = 128,
+    AVIF_SAMPLE_TRANSFORM_SUM = 128,        // S = L + R
+    AVIF_SAMPLE_TRANSFORM_DIFFERENCE = 129, // S = L - R
+    AVIF_SAMPLE_TRANSFORM_PRODUCT = 130,    // S = L * R
+    AVIF_SAMPLE_TRANSFORM_QUOTIENT = 131,   // S = R==0 ? L : truncate(L / R)
+    AVIF_SAMPLE_TRANSFORM_AND = 132,        // S = L & R
+    AVIF_SAMPLE_TRANSFORM_OR = 133,         // S = L | R
+    AVIF_SAMPLE_TRANSFORM_XOR = 134,        // S = L ^ R
+    AVIF_SAMPLE_TRANSFORM_POW = 135,        // S = L==0 ? 0 : truncate(pow(L, R))
+    AVIF_SAMPLE_TRANSFORM_MIN = 136,        // S = L<=R ? L : R
+    AVIF_SAMPLE_TRANSFORM_MAX = 137,        // S = L<=R ? R : L
+    AVIF_SAMPLE_TRANSFORM_LAST_BINARY_OPERATOR = 137,
+
+    AVIF_SAMPLE_TRANSFORM_RESERVED = 138
 } avifSampleTransformTokenType;
 
 typedef struct avifSampleTransformToken
 {
-    uint8_t type;                // avifSampleTransformTokenType
+    avifSampleTransformTokenType type;
     int32_t constant;            // If type is AVIF_SAMPLE_TRANSFORM_CONSTANT.
                                  // Only 32-bit (bit_depth=2) constants are supported.
     uint8_t inputImageItemIndex; // If type is AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX. 1-based.
diff --git a/src/read.c b/src/read.c
index 4173726..1f75461 100644
--- a/src/read.c
+++ b/src/read.c
@@ -2115,14 +2115,24 @@
         avifSampleTransformToken * token = (avifSampleTransformToken *)avifArrayPush(expression);
         AVIF_CHECKERR(token != NULL, AVIF_RESULT_OUT_OF_MEMORY);
 
-        AVIF_CHECKERR(avifROStreamRead(s, &token->type, /*size=*/1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) token;
-        if (token->type == AVIF_SAMPLE_TRANSFORM_CONSTANT) {
+        uint8_t tokenValue;
+        AVIF_CHECKERR(avifROStreamRead(s, &tokenValue, /*size=*/1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) token;
+        if (tokenValue == AVIF_SAMPLE_TRANSFORM_CONSTANT) {
+            token->type = AVIF_SAMPLE_TRANSFORM_CONSTANT;
             // Two's complement representation is assumed here.
             uint32_t constant;
             AVIF_CHECKERR(avifROStreamReadU32(s, &constant), AVIF_RESULT_BMFF_PARSE_FAILED); // signed int(1<<(bit_depth+3)) constant;
-            token->constant = *(int32_t *)&constant; // maybe =(int32_t)constant; is enough
-        } else if (token->type == AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX) {
-            AVIF_CHECKERR(avifROStreamRead(s, &token->inputImageItemIndex, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) input_image_item_index;
+            token->constant = (int32_t)constant;
+        } else if (tokenValue <= AVIF_SAMPLE_TRANSFORM_LAST_INPUT_IMAGE_ITEM_INDEX) {
+            AVIF_ASSERT_OR_RETURN(tokenValue >= AVIF_SAMPLE_TRANSFORM_FIRST_INPUT_IMAGE_ITEM_INDEX);
+            token->type = AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX;
+            token->inputImageItemIndex = tokenValue;
+        } else if (tokenValue >= AVIF_SAMPLE_TRANSFORM_FIRST_UNARY_OPERATOR && tokenValue <= AVIF_SAMPLE_TRANSFORM_LAST_UNARY_OPERATOR) {
+            token->type = (avifSampleTransformTokenType)tokenValue; // unary operator
+        } else if (tokenValue >= AVIF_SAMPLE_TRANSFORM_FIRST_BINARY_OPERATOR && tokenValue <= AVIF_SAMPLE_TRANSFORM_LAST_BINARY_OPERATOR) {
+            token->type = (avifSampleTransformTokenType)tokenValue; // binary operator
+        } else {
+            token->type = AVIF_SAMPLE_TRANSFORM_RESERVED;
         }
     }
     AVIF_CHECKERR(avifROStreamRemainingBytes(s) == 0, AVIF_RESULT_BMFF_PARSE_FAILED);
@@ -2138,8 +2148,9 @@
 {
     BEGIN_STREAM(s, raw, rawLen, diag, "Box[sato]");
 
-    uint8_t version, bitDepth;
-    AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &version, /*bitCount=*/6), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(6) version = 0;
+    uint8_t version, reserved, bitDepth;
+    AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &version, /*bitCount=*/2), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(2) version = 0;
+    AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &reserved, /*bitCount=*/4), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(4) reserved;
     AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &bitDepth, /*bitCount=*/2), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(2) bit_depth;
     AVIF_CHECKERR(version == 0, AVIF_RESULT_NOT_IMPLEMENTED);
     AVIF_CHECKERR(bitDepth == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32, AVIF_RESULT_NOT_IMPLEMENTED);
diff --git a/src/sampletransform.c b/src/sampletransform.c
index 5210366..2a20502 100644
--- a/src/sampletransform.c
+++ b/src/sampletransform.c
@@ -21,13 +21,15 @@
             AVIF_CHECK(token->inputImageItemIndex != 0);
             AVIF_CHECK(token->inputImageItemIndex <= numInputImageItems);
         }
-        if (token->type == AVIF_SAMPLE_TRANSFORM_CONSTANT || token->type == AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX) {
+        if (token->type < AVIF_SAMPLE_TRANSFORM_FIRST_UNARY_OPERATOR) {
+            // Likely an operand.
             ++stackSize;
-        } else if (token->type == AVIF_SAMPLE_TRANSFORM_NEGATE || token->type == AVIF_SAMPLE_TRANSFORM_ABSOLUTE ||
-                   token->type == AVIF_SAMPLE_TRANSFORM_NOT || token->type == AVIF_SAMPLE_TRANSFORM_MSB) {
+        } else if (token->type < AVIF_SAMPLE_TRANSFORM_FIRST_BINARY_OPERATOR) {
+            // Likely a unary operator.
             AVIF_CHECK(stackSize >= 1);
             // Pop one and push one.
         } else {
+            // Likely a binary operator.
             AVIF_CHECK(stackSize >= 2);
             --stackSize; // Pop two and push one.
         }
@@ -131,7 +133,7 @@
             // The second image represents the 4 least significant bits of the reconstructed, bit-depth-extended output image.
             AVIF_ASSERT_OR_RETURN(avifPushInputImageItem(expression, 2));
             AVIF_ASSERT_OR_RETURN(avifPushConstant(expression, 16));
-            AVIF_ASSERT_OR_RETURN(avifPushOperator(expression, AVIF_SAMPLE_TRANSFORM_DIVIDE));
+            AVIF_ASSERT_OR_RETURN(avifPushOperator(expression, AVIF_SAMPLE_TRANSFORM_QUOTIENT));
         }
         AVIF_ASSERT_OR_RETURN(avifPushOperator(expression, AVIF_SAMPLE_TRANSFORM_SUM));
         return AVIF_RESULT_OK;
@@ -198,13 +200,13 @@
 static int32_t avifSampleTransformOperation32bOneOperand(int32_t operand, uint8_t operator)
 {
     switch (operator) {
-        case AVIF_SAMPLE_TRANSFORM_NEGATE:
+        case AVIF_SAMPLE_TRANSFORM_NEGATION:
             return avifSampleTransformClamp32b(-(int64_t)operand);
         case AVIF_SAMPLE_TRANSFORM_ABSOLUTE:
             return operand >= 0 ? operand : avifSampleTransformClamp32b(-(int64_t)operand);
         case AVIF_SAMPLE_TRANSFORM_NOT:
             return ~operand;
-        case AVIF_SAMPLE_TRANSFORM_MSB: {
+        case AVIF_SAMPLE_TRANSFORM_BSR: {
             if (operand <= 0) {
                 return 0;
             }
@@ -230,7 +232,7 @@
             return avifSampleTransformClamp32b(leftOperand - rightOperand);
         case AVIF_SAMPLE_TRANSFORM_PRODUCT:
             return avifSampleTransformClamp32b(leftOperand * rightOperand);
-        case AVIF_SAMPLE_TRANSFORM_DIVIDE:
+        case AVIF_SAMPLE_TRANSFORM_QUOTIENT:
             return rightOperand == 0 ? leftOperand : leftOperand / rightOperand;
         case AVIF_SAMPLE_TRANSFORM_AND:
             return leftOperand & rightOperand;
@@ -315,8 +317,8 @@
                         const uint8_t * row = avifImagePlane(image, c) + avifImagePlaneRowBytes(image, c) * y;
                         AVIF_ASSERT_OR_RETURN(stackSize < stackCapacity);
                         stack[stackSize++] = avifImageUsesU16(image) ? ((const uint16_t *)row)[x] : row[x];
-                    } else if (token->type == AVIF_SAMPLE_TRANSFORM_NEGATE || token->type == AVIF_SAMPLE_TRANSFORM_ABSOLUTE ||
-                               token->type == AVIF_SAMPLE_TRANSFORM_NOT || token->type == AVIF_SAMPLE_TRANSFORM_MSB) {
+                    } else if (token->type == AVIF_SAMPLE_TRANSFORM_NEGATION || token->type == AVIF_SAMPLE_TRANSFORM_ABSOLUTE ||
+                               token->type == AVIF_SAMPLE_TRANSFORM_NOT || token->type == AVIF_SAMPLE_TRANSFORM_BSR) {
                         AVIF_ASSERT_OR_RETURN(stackSize >= 1);
                         stack[stackSize - 1] = avifSampleTransformOperation32bOneOperand(stack[stackSize - 1], token->type);
                         // Pop one and push one.
diff --git a/src/write.c b/src/write.c
index 14dd7c8..6ab66e1 100644
--- a/src/write.c
+++ b/src/write.c
@@ -1066,19 +1066,21 @@
 #if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
 static avifResult avifEncoderWriteSampleTransformTokens(avifRWStream * s, const avifSampleTransformExpression * expression)
 {
-    AVIF_ASSERT_OR_RETURN(expression->count <= 256);
+    AVIF_ASSERT_OR_RETURN(expression->count <= 255);
     AVIF_CHECKRES(avifRWStreamWriteU8(s, (uint8_t)expression->count)); // unsigned int(8) token_count;
 
     for (uint32_t t = 0; t < expression->count; ++t) {
         const avifSampleTransformToken * token = &expression->tokens[t];
-        AVIF_CHECKRES(avifRWStreamWriteU8(s, token->type)); // unsigned int(8) token;
 
         if (token->type == AVIF_SAMPLE_TRANSFORM_CONSTANT) {
-            // TODO(yguyon): Verify two's complement representation is guaranteed here.
-            const uint32_t constant = *(const uint32_t *)&token->constant;
+            AVIF_CHECKRES(avifRWStreamWriteU8(s, token->type)); // unsigned int(8) token;
+            const uint32_t constant = (uint32_t)token->constant;
             AVIF_CHECKRES(avifRWStreamWriteU32(s, constant)); // signed int(1<<(bit_depth+3)) constant;
         } else if (token->type == AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX) {
-            AVIF_CHECKRES(avifRWStreamWriteU8(s, token->inputImageItemIndex)); // unsigned int(8) input_image_item_index;
+            AVIF_CHECKRES(avifRWStreamWriteU8(s, token->inputImageItemIndex)); // unsigned int(8) token;
+        } else {
+            // Operator.
+            AVIF_CHECKRES(avifRWStreamWriteU8(s, token->type)); // unsigned int(8) token;
         }
     }
     return AVIF_RESULT_OK;
@@ -1088,7 +1090,8 @@
 {
     avifRWStream s;
     avifRWStreamStart(&s, data);
-    AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/6)); // unsigned int(6) version = 0;
+    AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/2)); // unsigned int(2) version = 0;
+    AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/4)); // unsigned int(4) reserved;
     // AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32 is necessary because the two input images
     // once combined use 16-bit unsigned values, but intermediate results are stored in signed integers.
     AVIF_CHECKRES(avifRWStreamWriteBits(&s, AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32, /*bitCount=*/2)); // unsigned int(2) bit_depth;
@@ -1450,7 +1453,7 @@
     if (encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_8B_8B) {
         if (isBase) {
             AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 8, planes));
-            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_DIVIDE, 256, planes));
+            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_QUOTIENT, 256, planes));
         } else {
             AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 8, planes));
             AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_AND, 255, planes));
@@ -1458,7 +1461,7 @@
     } else if (encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_4B) {
         if (isBase) {
             AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 12, planes));
-            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_DIVIDE, 16, planes));
+            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_QUOTIENT, 16, planes));
         } else {
             AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 8, planes));
             AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_AND, 15, planes));
@@ -1487,7 +1490,7 @@
                       AVIF_RESULT_NOT_IMPLEMENTED);
         if (isBase) {
             AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 12, planes));
-            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_DIVIDE, 16, planes));
+            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_QUOTIENT, 16, planes));
         } else {
             AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 8, planes));
             avifCodec * codec = NULL;
diff --git a/tests/gtest/avif16bittest.cc b/tests/gtest/avif16bittest.cc
index 7baf546..337c47f 100644
--- a/tests/gtest/avif16bittest.cc
+++ b/tests/gtest/avif16bittest.cc
@@ -87,7 +87,7 @@
         {AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX, 0,
          /*inputImageItemIndex=*/1},
         {AVIF_SAMPLE_TRANSFORM_CONSTANT, 1 << shift, 0},
-        {AVIF_SAMPLE_TRANSFORM_DIVIDE, 0, 0}};
+        {AVIF_SAMPLE_TRANSFORM_QUOTIENT, 0, 0}};
     ASSERT_EQ(avifImageApplyOperations(
                   image_no_sato.get(), AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32,
                   /*numTokens=*/3, tokens, /*numInputImageItems=*/1,
diff --git a/tests/gtest/avifsampletransformtest.cc b/tests/gtest/avifsampletransformtest.cc
index 79de749..1305380 100644
--- a/tests/gtest/avifsampletransformtest.cc
+++ b/tests/gtest/avifsampletransformtest.cc
@@ -30,7 +30,7 @@
   }
   void AddOperator(avifSampleTransformTokenType op) {
     avifSampleTransformToken& token = AddToken();
-    token.type = static_cast<uint8_t>(op);
+    token.type = op;
   }
 
   int32_t Apply() const {
@@ -158,10 +158,10 @@
 
 INSTANTIATE_TEST_SUITE_P(
     Operations, SampleTransformOperationTest,
-    testing::Values(Op(AVIF_SAMPLE_TRANSFORM_NEGATE, 1, 0),
-                    Op(AVIF_SAMPLE_TRANSFORM_NEGATE, -1, 1),
-                    Op(AVIF_SAMPLE_TRANSFORM_NEGATE, 0, 0),
-                    Op(AVIF_SAMPLE_TRANSFORM_NEGATE, -256, 255),
+    testing::Values(Op(AVIF_SAMPLE_TRANSFORM_NEGATION, 1, 0),
+                    Op(AVIF_SAMPLE_TRANSFORM_NEGATION, -1, 1),
+                    Op(AVIF_SAMPLE_TRANSFORM_NEGATION, 0, 0),
+                    Op(AVIF_SAMPLE_TRANSFORM_NEGATION, -256, 255),
                     Op(AVIF_SAMPLE_TRANSFORM_ABSOLUTE, 1, 1),
                     Op(AVIF_SAMPLE_TRANSFORM_ABSOLUTE, -1, 1),
                     Op(AVIF_SAMPLE_TRANSFORM_ABSOLUTE, 256, 255),
@@ -176,8 +176,8 @@
                     Op(-1, AVIF_SAMPLE_TRANSFORM_DIFFERENCE, 1, 0),
                     Op(1, AVIF_SAMPLE_TRANSFORM_PRODUCT, 1, 1),
                     Op(2, AVIF_SAMPLE_TRANSFORM_PRODUCT, 3, 6),
-                    Op(1, AVIF_SAMPLE_TRANSFORM_DIVIDE, 1, 1),
-                    Op(2, AVIF_SAMPLE_TRANSFORM_DIVIDE, 3, 0),
+                    Op(1, AVIF_SAMPLE_TRANSFORM_QUOTIENT, 1, 1),
+                    Op(2, AVIF_SAMPLE_TRANSFORM_QUOTIENT, 3, 0),
                     Op(1, AVIF_SAMPLE_TRANSFORM_AND, 1, 1),
                     Op(1, AVIF_SAMPLE_TRANSFORM_AND, 2, 0),
                     Op(7, AVIF_SAMPLE_TRANSFORM_AND, 15, 7),
@@ -186,10 +186,10 @@
                     Op(1, AVIF_SAMPLE_TRANSFORM_XOR, 3, 2),
                     Op(AVIF_SAMPLE_TRANSFORM_NOT, 254, 0),
                     Op(AVIF_SAMPLE_TRANSFORM_NOT, -1, 0),
-                    Op(AVIF_SAMPLE_TRANSFORM_MSB, 0, 0),
-                    Op(AVIF_SAMPLE_TRANSFORM_MSB, -1, 0),
-                    Op(AVIF_SAMPLE_TRANSFORM_MSB, 61, 5),
-                    Op(AVIF_SAMPLE_TRANSFORM_MSB,
+                    Op(AVIF_SAMPLE_TRANSFORM_BSR, 0, 0),
+                    Op(AVIF_SAMPLE_TRANSFORM_BSR, -1, 0),
+                    Op(AVIF_SAMPLE_TRANSFORM_BSR, 61, 5),
+                    Op(AVIF_SAMPLE_TRANSFORM_BSR,
                        std::numeric_limits<int32_t>::max(), 30),
                     Op(2, AVIF_SAMPLE_TRANSFORM_POW, 4, 16),
                     Op(4, AVIF_SAMPLE_TRANSFORM_POW, 2, 16),