Skip to main content

WAI Extension: Carousel Schedule

Mirrored from the canonical text at commit 260cbd09 ().

Status: Draft. Registers the record wai.bearer.carousel: a publisher’s signed schedule of when each object of a group passes on a bearer instance, and with which application-layer forward error correction. On a bearer with no return path a receiver cannot ask for what it missed: it holds an object only if the passes it heard carried enough encoding symbols. The schedule says what was planned to be sent, in a jwp-receipts claim of class schedule (jwp-receipts §2.4.16, §4 here), signed by the group’s key beside the group receipt and the transmission claim of bearer-receipts §4. From it a verifier derives, for each object, when a receiver whose losses stay within a stated bound holds it (§6): the deadline a one-way bearer can promise, with the decoding failure the FEC code bounds. A receiver derives the passes it must listen to and when it may turn its radio off (§7). A later schedule adds passes to an earlier one without contradicting it (§4.5), and the receipts a receiver needs ride on the instance itself, so one that joins mid-carousel recovers them there (§8.1, §8.2). WAI defines no transport and no code: the codes are RaptorQ (RFC 6330), Raptor (RFC 5053) and Compact No-Code (RFC 5445), and the schedule declares their parameters. The reference implementation is the carousel module of wai-rs (feature carousel), with the class’s body in claim_receipt::schedule; the corpus is live-conformance/carousel/, and its second implementation is live-conformance/carousel_verify.py. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.

Texts read for this revision: RFC 6330 (RaptorQ) with its verified erratum 5548, RFC 5053 (Raptor), RFC 5445 (Compact No-Code), RFC 5052 §9.1 (block partitioning) and 3GPP TS 26.346 V19.3.0 §7.2.2 and §7.2.3. A clause number of one of them in this text is that text’s. §11 also cites the IETF’s IPR disclosures on RFC 5053, RFC 6330 and their drafts, read as the IETF datatracker shows them, and RFC 8179 §4.

1. Scope

In scope: the schedule claim and how a later one extends an earlier one (§4); how an object is divided into source blocks and symbols under each code (§5); when an object is held by a receiver whose losses stay within a bound, and the statements a verifier may check against it (§6); the passes a receiver listens to (§7); and what a publisher repeats on the instance for a receiver that joins mid-carousel, and whether what it acquired suffices (§8.1, §8.2).

Out of scope: encoding and decoding symbols, which are the codes’ own (RFC 6330 §5, RFC 5053 §5, RFC 5445 §3); a transport, and how symbols are packed into packets; a model of a channel. Every statement here holds for every pattern of loss within the stated bound (§2). Whether losses on a channel are independent, and how often a bound is exceeded, is a judgement about that channel, which a relying party makes and a schedule does not carry. Nothing here states presentation, and nothing here states that any receiver heard anything: that is a reconciliation’s (bearer-receipts §5).

Relationship to the core spec: wai.bearer.carousel is a record (SPEC §5): the schedule claim is a signed record a WAI tool emits and verifies. It names no payload format and is not dispatchable.

2. Terms

3. Why a schedule beside the receipt

The group receipt signs its objects and names no bearer (bearer-receipts §3); the transmission claim names the bearer instance and attests that the publisher transmitted the group, which on a bearer with no return path says nothing about any receiver. Between the two is what decides whether a receiver that heard part of a transmission holds an object: how often each object passes, for how long, and with how many repair symbols. That is a plan, made before anything is sent, and it is a statement of the publisher’s own:

The schedule attests a plan, not a transmission: that is the declaration’s, and the schedule stands only beside one (§6.2). Neither attests that any receiver heard anything.

4. The schedule claim (class: "schedule")

A publisher that transmits a group over a multicast or unidirectional bearer instance MAY declare its schedule there in a schedule claim, one per bearer instance. Its subject_type is receipt and its subject the group receipt’s link hash (jwp-receipts §3 step 3). It is signed by the key that signed the group. It attests that the publisher scheduled the passes it names, and nothing about what any sink received.

4.1 Body

membertypemeaning
bearer_idabsolute URIThe bearer instance (bearer-receipts §2): the bearer_id of the transmission claim it schedules.
objectsarrayThe objects scheduled, one entry each (below).
attestsstringMUST be "scheduled". Any string passes step 2; another value is refused at step 4.

Each entry of objects has exactly these members:

membertypemeaning
leaf_indexintegerThe object’s position in the group (jwp-receipts §2.2).
content_hash32 B hexThe object’s content hash (jwp-receipts §2.1): what a receiver that decodes the object checks it against.
fecstringThe code: raptorq (RFC 6330, FEC Encoding ID 6), raptor (RFC 5053, FEC Encoding ID 1) or no-code (RFC 5445, FEC Encoding ID 0).
otiobjectThe code’s object transmission information, as §5 reads it. For raptorq, exactly transfer_length (F), symbol_size (T), source_blocks (Z), sub_blocks (N) and alignment (Al), RFC 6330 §3.3.2 and §3.3.3. For raptor, the same members, RFC 5053 §3.2.2 and §3.2.3. For no-code, exactly transfer_length, symbol_size (the encoding symbol length) and max_block_length (the maximum source block length, in symbols), RFC 5445 §3.2.2.2. Each an integer.
repairintegerThe repair symbols of each source block sent in each pass, beyond its source symbols (§5.4).
esistringrepeat: every pass sends the same ESIs. advance: each pass sends ESIs no earlier pass sent (§5.4).
first_msintegerThe instant the first pass starts.
period_msintegerThe time from one pass’s start to the next’s.
duration_msintegerThe time each pass lasts.
countintegerThe number of passes.

fec and esi are read at jwp-receipts §3.1 step 2 against their enumerations, the members of oti against the code fec names, bearer_id as an absolute URI, and every integer as an unsigned 64-bit one (field_type).

4.2 Rules

Checked at jwp-receipts §3.1 step 4, in this order:

  1. attests MUST be "scheduled" (schedule_not_scheduled).
  2. objects has at least one entry, and its leaf_index values strictly increase (schedule_objects_malformed): one entry for each object scheduled, in group order.
  3. Each entry in order, the first of these to fail:
    1. its oti is one its code admits, §5.1, §5.2 or §5.5 (schedule_oti_invalid);
    2. its symbols are ones its code can name, §5.4 (schedule_symbols_invalid);
    3. its passes are well formed (schedule_passes_invalid): count and duration_ms are at least 1; with count at least 2, period_ms is at least duration_ms, so one pass of an object ends before its next starts; the last pass ends, first_ms + (count − 1) · period_ms + duration_ms, at or before 253,402,300,799,999 (9999-12-31T23:59:59.999Z); and the octets its passes send, bytes_sent (§5.4), are at most 253 − 1, the greatest integer a receipt states; each computed without overflow.

4.3 Against the group

Checked at jwp-receipts §3.1 step 6 against the group receipt the verifier holds, which has passed jwp-receipts §3 steps 1 and 2 and whose group_start is an RFC 3339 date-time (context_invalid otherwise; another receipt is context_mismatch), the object receipts it holds under that group, each of which has passed jwp-receipts §3 step 5, and the envelope bytes of those it holds. In order:

  1. the group’s link hash is the claim’s subject (schedule_subject_mismatch);
  2. the claim’s signer_pubkey is the group’s (schedule_signer_mismatch): only the publisher schedules its own transmission. A node schedules the instance it declares as its own under cache-authority §5.6, in the verdict that holds that instance, which replaces this step and no other; every other verdict reads the publisher’s schedules alone;
  3. every leaf_index is less than the group’s leaf_count (schedule_leaf_out_of_range);
  4. no entry’s first pass starts before the group does (schedule_before_group): ⌊first_ms / 1000⌋ is at least the seconds jwp-receipts §2.4.3 reads from group_start, its fraction dropped. Nothing can be sent before it exists;
  5. for each entry whose object receipt the verifier holds, the receipt’s content_hash is the entry’s (schedule_content_mismatch); and for each whose envelope bytes it holds, their length is oti.transfer_length (schedule_length_mismatch).

A schedule checked without the group stops at step 5 and is not counted by §6.

4.4 Authority

Confirmed under jwp-receipts §7, a schedule claim needs the authority schedule, which is not pinned-only and is not delivery. An origin gives it to the keys that publish its groups, as it gives transmission, and a node’s operator to the nodes that schedule their own instances (cache-authority §4.3).

4.5 Extending a schedule

A publisher MAY add to a schedule it has published, after a fade or for a longer transmission, by signing a later schedule of the same instance that extends it. Schedule B extends schedule A of one bearer_id when B has, for every entry of A, an entry of the same leaf_index that extends it; and an entry extends another when its passes begin with the other’s, at the same instants and sending the same symbols:

B MAY also have entries for objects A has none for. Every schedule extends itself, and a schedule that extends one that extends a third extends the third. B is held to §4.2 and §4.3 on its own, so rule 3.3 and §5.4’s bound on ESIs hold for its greater count.

Nothing A states is weakened by B, at any loss bound and overhead:

What does not extend an earlier schedule, and contradicts it, is §6.2 step 4’s: a schedule that drops an object, or withdraws, moves or changes a pass.

5. Blocks and symbols

5.1 RaptorQ

The oti of a raptorq entry, F, T, Z, N and Al, is one RFC 6330 admits when:

The object is then divided as RFC 6330 §4.4.1.2 divides it: (KL, KS, ZL, ZS) = Partition[Kt, Z], where Partition[I, J] = (⌈I / J⌉, ⌊I / J⌋, I − ⌊I / J⌋ · J, J − (I − ⌊I / J⌋ · J)). The first ZL source blocks have KL source symbols each and the remaining ZS have KS. Each symbol is T octets; the last source symbol of the object is padded to T.

5.2 Compact No-Code

The oti of a no-code entry, with L its transfer_length, E its symbol_size and B its max_block_length, is one RFC 5445 admits when L is from 1 to 248 − 1, E from 1 to 65,535 and B from 1 to 232 − 1 (RFC 5445 §3.2.2.2; an object of no octets has nothing to schedule), and the division of RFC 5052 §9.1 fits RFC 5445’s 16-bit source block number and encoding symbol ID (§3.2.1):

Every symbol is E octets but the object’s last, which holds what remains of L.

5.3 What a receiver needs

A block of K source symbols is held when a receiver can recover it:

An object is held when every one of its source blocks is.

5.4 The symbols a pass sends

Each pass sends, of each source block of K source symbols, m = K + repair encoding symbols:

An entry’s symbols are ones its code can name (§4.2 rule 3.2) when:

The octets an entry’s passes send, bytes_sent, are count · Σ m · T over its source blocks for raptorq and raptor, and count · L for no-code, whose last symbol is short.

5.5 Raptor

The oti of a raptor entry, F, T, Z, N and Al, is one RFC 5053 admits when:

The object is then divided as RFC 5053 §5.3.1.2 divides it, by the Partition[] of §5.1: (KL, KS, ZL, ZS) = Partition[Kt, Z]. The first ZL source blocks have KL source symbols each and the remaining ZS have KS. Each symbol is T octets. The last source symbol of the object is padded to T for encoding; RFC 5053 §5.3.2 lets a sender leave that padding out of a packet, and bytes_sent counts it. A limit a bearer sets on these values, as TS 26.346 §7.2.3 does on a sub-block’s size, is the bearer’s.

6. When an object is held

6.1 Inputs

The group receipt; the object receipts the verifier holds under it, each with its envelope bytes where it holds them; the transmission and schedule claims it holds about the group, each signer’s in the order of its chain; a loss bound L; and an overhead h.

6.2 Steps

The loss bound and overhead are checked first: L above 999,999 is loss_bound_invalid, and h other than 0, 1 or 2 is overhead_invalid; neither derives anything. Then:

  1. The group and its objects: bearer-receipts §6.2 steps 1 and 2.
  2. The claims: each claim, in order, under jwp-receipts §3.1 steps 1 to 5, then step 6: a transmission claim by bearer-receipts §4.3 and a schedule by §4.3 here. A claim of another class is context_mismatch at step 6. A claim refused at any step takes no further part.
  3. The declarations: bearer-receipts §6.2 step 4.
  4. The schedules: the accepted schedule claims by bearer_id, each instance’s in the order of their signer’s chain (§6.1), which §4.3 step 2 makes one chain. When one of them does not extend the one before it (§4.5), every schedule of that instance is set aside (schedule_contradicted): a publisher that drops an object from its plan for one transmission, or withdraws, moves or changes a pass, has stated neither plan, and a relying party holds no promise that can change under it. Otherwise the last of them is the instance’s schedule, and each before it with another body is extended: its passes are the first of the last one’s, and it takes no further part. Two with the same body are one. The instance’s schedules are then set aside at the first of these that holds: step 3 set aside the declarations of its bearer_id (bearer_contradicted); no declaration has its bearer_id (bearer_not_declared); its declaration’s bearer is bidirectional (schedule_on_bidirectional), since a receiver with a path back asks for what it lacks and is not served by a plan. Otherwise the instance’s schedule stands, and so does each before it with its body.
  5. Availability, for each entry of each standing schedule, by §6.3.

6.3 Availability

For an entry, pass j ends at the instant first_ms + (j − 1) · period_ms + duration_ms. For each source block of K source symbols, with m = K + repair and x = ⌊L · m / 1,000,000⌋ the most a receiver within L misses of it in one pass, the first pass after which a receiver within L holds the block is, under §5.3:

The object is available at the end of the greatest of its blocks’ passes, or is not available within the schedule if any block has none. A verifier reports for each entry its available_ms (or null), the pass, bytes_sent (§5.4), and, for raptorq, the RFC 6330 §5.8 bound at h as failure_one_in (100, 10,000 or 1,000,000). For raptor it is null, since RFC 5053 states no bound (§5.3); for no-code it is null, a block held being recovered exactly.

6.4 Statements offered about an object or a group

A verifier MAY be asked to check a statement, on a bearer instance, for a loss bound L and an overhead h:

A statement that holds says what the publisher planned: a receiver within L, hearing every pass the schedule names, holds the object by t, but for a decoding failure no more likely than failure_one_in states, and under raptor no bound is stated on that failure. It does not say the passes were sent (the declaration’s) or heard (a reconciliation’s).

A publisher’s own deadline for an object is its timeliness claim’s by_ms (timeliness §4.1); held by it, the statement is the publisher’s plan against its own deadline.

7. The passes a receiver listens to

A receiver that holds a standing schedule’s entry, the instant t it is at, its loss bound L, the overhead h it decodes at, and, for each source block, the number n of distinct encoding symbols of it that it holds (for no-code, of its source symbols), derives the passes to listen to. The loss bound and overhead are checked as §6.2 checks them, and a holding that does not give one number for each source block of the object, in the order §5.1 and §5.2 divide it into them, or that holds more source symbols of a no-code block than it has, is holding_invalid. Only passes that start at or after t count: a pass under way at t has sent symbols the receiver did not hear. A pass adds, to a block not held, with m and x as §6.3:

The passes are taken in order of their start. While some block is not held, the next pass is listened to if it adds to a block not held, each such block’s n growing by what it adds; the first pass that adds to none ends the plan. The plan is the passes listened to, each with its start and end; complete_ms, the instant the object is held: t when it already is, the last pass’s end when the passes listened to suffice, and null otherwise; and listen_ms, the sum of their durations: the time the receiver’s radio must be on. Outside those passes it MAY be off. Under repeat and no-code at most one pass adds anything certain within L, since after it a block lacks only symbols the receiver may miss again: a receiver that one pass does not complete is not certain to be held after any number, and keeps listening, if it does, on its own judgement of its channel. A receiver that acquires a schedule extending the one it plans with plans with the later from then on: what it holds still counts, since each pass sends what it did (§4.5).

8. Mappings

A bearer that carries files with FEC states the same parameters in its own description of each file, for its receivers: on FLUTE (RFC 6726) and the bearers built on it, the FEC Object Transmission Information of each file in the file delivery table. A schedule restates them, signed by the publisher, beside the group’s receipts, so a relying party with no access to the bearer can check a promise (§6.4) and a receiver can plan before it tunes (§7). A sink that holds both compares them; a difference is the bearer’s, and the sink reports it rather than choosing one. The bearer’s own repetition (its carousel of descriptions and files) is the schedule’s passes: a pass is one transmission of the object’s symbols, whatever the bearer calls it. A receiver of 3GPP MBMS download supports the Compact No-Code and Raptor schemes (TS 26.346 §7.2.2), so a schedule of such an instance names no-code or raptor.

8.1 In-band repetition

A receipt held only off the bearer reaches only a receiver that had another path to it, and a receiver on a bearer with no return path cannot ask. On an instance whose schedule stands, the publisher MUST send its in-band set on the instance itself, each part as bearer-receipts §9.1 carries it:

A chain holds every claim its key has signed, so a publisher SHOULD sign the groups it schedules with a key that signs little else, which its origin lists with delivery, transmission and schedule (jwp-receipts §7). A claim of the chain about another group is refused at step 6 against this group and breaks nothing: it is held, so the claims after it chain to it (jwp-receipts §3.1 step 5).

How often. A schedule’s interval is the least period_ms of its entries of two passes or more, or, where every entry has one pass, the least duration_ms. From the start of the schedule’s first pass to the end of its last, the publisher sends the whole set at least once in every span of that length. A receiver that joins in that time, and misses nothing of the set, holds it no later than one interval after it joins. The set’s files are outside every entry: their octets are not in bytes_sent, and the loss bound of §2 says nothing of them. A receiver that misses a copy takes the next.

An extension. A later schedule (§4.5) is in the set from when it is signed, chained after the one it extends. A receiver that held the earlier and acquires the later reads one schedule that stands, and one that joins afterwards reads both in the chain.

8.2 What a receiver acquired

A receiver that joined an instance, or a verifier given what it acquired, MAY check that it suffices. The inputs are the instance’s bearer_id, the group receipt, the claims in the order of their chain, and the key logs acquired, each keyed by the origin it names. §6.2 steps 1 to 4 run over the group receipt and the claims alone, with no object held and no claim held before the first; a group that fails is refused with its reason, and nothing is derived. Then, at the first of these that fails, the set is refused:

  1. no claim of it is refused at jwp-receipts §3.1 step 5 (inband_chain_incomplete), so it holds each signer’s chain from its head;
  2. a schedule of the instance stands (inband_not_scheduled);
  3. a key log acquired is held for the origin that schedule’s signer_id names, under jwp-receipts §7.2 rules 1 to 3, and lists the schedule’s key (inband_key_log_missing). A signer_id that names no origin has no log to carry, and is refused here.

Otherwise the set suffices, and a verifier reports each claim’s label and the interval of the schedule that stands as inband_ms. A set that suffices holds what a receiver needs to plan (§7) and to confirm. Confirming is bearer-receipts §8.3’s, under anchors the receiver already holds, so a log that lists the key as revoked still suffices here, and confirmation reports it. It does not say the publisher sent the set as §8.1 asks.

9. Reasons

The codes this extension adds, each with where it is raised:

reasonraised at
schedule_not_scheduled§4.2 rule 1
schedule_objects_malformed§4.2 rule 2
schedule_oti_invalid§4.2 rule 3.1
schedule_symbols_invalid§4.2 rule 3.2
schedule_passes_invalid§4.2 rule 3.3
schedule_subject_mismatch§4.3 step 1
schedule_signer_mismatch§4.3 step 2
schedule_leaf_out_of_range§4.3 step 3
schedule_before_group§4.3 step 4
schedule_content_mismatch§4.3 step 5
schedule_length_mismatch§4.3 step 5
schedule_contradicted§6.2 step 4
schedule_on_bidirectional§6.2 step 4
loss_bound_invalid§6.2, §7
overhead_invalid§6.2, §7
holding_invalid§7
object_not_scheduled§6.4
availability_not_within_schedule§6.4
availability_after_deadline§6.4
inband_chain_incomplete§8.2 check 1
inband_not_scheduled§8.2 check 2
inband_key_log_missing§8.2 check 3

A schedule also raises bearer_contradicted and bearer_not_declared (bearer-receipts §10) at §6.2 step 4; a group or object the codes of jwp-receipts §3.3; and a claim every code of jwp-receipts §3.1 steps 1 to 5 and those of step 6 named in §4.3 and bearer-receipts §4.3.

10. Conformance

live-conformance/carousel/ holds the corpus, written from fixed seeds by wai_carousel_vectors gen as vectors.json. It has:

A conforming verifier gives every case the outcome, the reason and everything else the corpus states. wai_carousel_vectors verify and the test tests/carousel.rs check that the file regenerates byte for byte, that wai-rs gives every case its outcome, that every reason of §9 appears, that §9 lists exactly the reference’s codes, and that Appendix A is the reference’s table. Against an independent implementation of RFC 6330, the test also requires the reference’s K′ and Partition[] to agree for every block size, and decodes each RaptorQ object a case holds available at a pass: it encodes the object under the entry’s parameters, drops in each pass the first ⌊L · m / 1,000,000⌋ symbols of each block (in the first pass, source symbols, so the decoder must decode), and requires the object back from what is left by that pass’s end. It does the same for each Raptor object against an independent implementation of RFC 5053, and on a fixed sample requires that decoder to fail on at least 1 block in 10 at K + 2, on at most 1 in 100 at the margin of h = 0, at most 1 in 10,000 at that of h = 1, and on none of 10,000 at that of h = 2. live-conformance/carousel_verify.py is the second implementation, written from this text: it shares no code with wai-rs; it verifies groups and objects with the JWP corpus’s second implementation (jwp-conformance/jwp_verify.py), claims through steps 1–5 with the claim corpus’s (claim-conformance/claim_verify.py), whose step 4 holds §4.2 with §5.1, §5.2, §5.4 and §5.5, and key logs with the signer corpus’s (signer-conformance/signer_verify.py); it reads Appendix A and §9 from this text, writes §4.3, §4.5, §5.3, §6, §7 and §8.2 itself, mutates copies of the corpus and requires every copy to fail, and drops each of its own checks in turn and requires the corpus to catch the weakened verifier.

11. Patents

The IETF holds disclosures of patents claimed to read on RaptorQ, all from one holder: #1292, #1511 and #1553 on the drafts of RFC 6330, #1958 on RFC 6330, and #2554 (19 March 2015), which updates #1958 and has not itself been updated. Its licensing declaration is written out in the holder’s words, not chosen from the disclosure form’s options, and gives two terms, by the product that implements the code:

Raptor (RFC 5053), which §4.1 names, has disclosures from the same holder and an earlier one: #615, #618, #702 and #734 on its drafts; #1185 (8 September 2009) on RFC 5053, which declared a reasonable and non-discriminatory licence with possible royalty or fee; and #1289, #1508, #1744 and #1957 (6 February 2013), each updating the one before. #1957 has not been updated, and gives the same two terms as #2554. The holder’s general licence statement, #1176 (20 July 2009), relates to no one document: it offers a non-exclusive licence on reasonable and non-discriminatory terms, on the basis of reciprocity, for the holder’s submissions that an IETF standard incorporates.

No disclosure relates to RFC 5445 or its draft, nor to RFC 5052, whose division §5.2 applies. The IETF takes no position on the validity or scope of any disclosed claim (RFC 8179 §4).

Therefore:

12. Security and privacy considerations

Appendix A. The values of K′

The column K′ of RFC 6330 Table 2 (§5.6), in increasing order, restated so that §5.3 can be applied from this text. The other columns of that table are the code’s, and nothing here uses them.

10, 12, 18, 20, 26, 30, 32, 36, 42, 46, 48, 49, 55, 60, 62, 69,
75, 84, 88, 91, 95, 97, 101, 114, 119, 125, 127, 138, 140, 149, 153, 160,
166, 168, 179, 181, 185, 187, 200, 213, 217, 225, 236, 242, 248, 257, 263, 269,
280, 295, 301, 305, 324, 337, 341, 347, 355, 362, 368, 372, 380, 385, 393, 405,
418, 428, 434, 447, 453, 466, 478, 486, 491, 497, 511, 526, 532, 542, 549, 557,
563, 573, 580, 588, 594, 600, 606, 619, 633, 640, 648, 666, 675, 685, 693, 703,
718, 728, 736, 747, 759, 778, 792, 802, 811, 821, 835, 845, 860, 870, 891, 903,
913, 926, 938, 950, 963, 977, 989, 1002, 1020, 1032, 1050, 1074, 1085, 1099, 1111, 1136,
1152, 1169, 1183, 1205, 1220, 1236, 1255, 1269, 1285, 1306, 1347, 1361, 1389, 1404, 1420, 1436,
1461, 1477, 1502, 1522, 1539, 1561, 1579, 1600, 1616, 1649, 1673, 1698, 1716, 1734, 1759, 1777,
1800, 1824, 1844, 1863, 1887, 1906, 1926, 1954, 1979, 2005, 2040, 2070, 2103, 2125, 2152, 2195,
2217, 2247, 2278, 2315, 2339, 2367, 2392, 2416, 2447, 2473, 2502, 2528, 2565, 2601, 2640, 2668,
2701, 2737, 2772, 2802, 2831, 2875, 2906, 2938, 2979, 3015, 3056, 3101, 3151, 3186, 3224, 3265,
3299, 3344, 3387, 3423, 3466, 3502, 3539, 3579, 3616, 3658, 3697, 3751, 3792, 3840, 3883, 3924,
3970, 4015, 4069, 4112, 4165, 4207, 4252, 4318, 4365, 4418, 4468, 4513, 4567, 4626, 4681, 4731,
4780, 4838, 4901, 4954, 5008, 5063, 5116, 5172, 5225, 5279, 5334, 5391, 5449, 5506, 5566, 5637,
5694, 5763, 5823, 5896, 5975, 6039, 6102, 6169, 6233, 6296, 6363, 6427, 6518, 6589, 6655, 6730,
6799, 6878, 6956, 7033, 7108, 7185, 7281, 7360, 7445, 7520, 7596, 7675, 7770, 7855, 7935, 8030,
8111, 8194, 8290, 8377, 8474, 8559, 8654, 8744, 8837, 8928, 9019, 9111, 9206, 9303, 9400, 9497,
9601, 9708, 9813, 9916, 10017, 10120, 10241, 10351, 10458, 10567, 10676, 10787, 10899, 11015, 11130, 11245,
11358, 11475, 11590, 11711, 11829, 11956, 12087, 12208, 12333, 12460, 12593, 12726, 12857, 13002, 13143, 13284,
13417, 13558, 13695, 13833, 13974, 14115, 14272, 14415, 14560, 14713, 14862, 15011, 15170, 15325, 15496, 15651,
15808, 15977, 16161, 16336, 16505, 16674, 16851, 17024, 17195, 17376, 17559, 17742, 17929, 18116, 18309, 18503,
18694, 18909, 19126, 19325, 19539, 19740, 19939, 20152, 20355, 20564, 20778, 20988, 21199, 21412, 21629, 21852,
22073, 22301, 22536, 22779, 23010, 23252, 23491, 23730, 23971, 24215, 24476, 24721, 24976, 25230, 25493, 25756,
26022, 26291, 26566, 26838, 27111, 27392, 27682, 27959, 28248, 28548, 28845, 29138, 29434, 29731, 30037, 30346,
30654, 30974, 31285, 31605, 31948, 32272, 32601, 32932, 33282, 33623, 33961, 34302, 34654, 35031, 35395, 35750,
36112, 36479, 36849, 37227, 37606, 37992, 38385, 38787, 39176, 39576, 39980, 40398, 40816, 41226, 41641, 42067,
42490, 42916, 43388, 43840, 44279, 44729, 45183, 45638, 46104, 46574, 47047, 47523, 48007, 48489, 48976, 49470,
49978, 50511, 51017, 51530, 52062, 52586, 53114, 53650, 54188, 54735, 55289, 55843, 56403