Background

The applications of the hypergeometric distribution are very similar to those of the binomial distribution. However, there is a fundamental difference: In the binomial, the probability of a success is equal from trial to trial (sampling with replacement), while in the hypergeometric, the probability of a succes may not be the same from trial to trial (sampling without replacement). Therefore, if the population shrinks each time, the probability for each observation will change.

The applications of the hypergeometric distribution are very common, especially where sampling without replacement is necessary. For example, where the sampling is performed at the expense of the item being tested; that is, the item is destroyed and cannot be replaced.

The expected value and variance of the hypergeometric distribution \(H (x\mid m, n, k)\) are \[E(X) = k \frac{m}{m + n}\] and \[Var(X) = k \frac{m}{m + n} \cdot \frac{m + n - k}{m + n} \cdot \frac{n}{m + n -1}\]

where:

\(k\) is the size of the sample.

\(m\) is the number of successes in the population.

\(n\) is the number of failures in the population.

Probability Mass Function

The “standard” formula for the probability mass function of \(x\) successes is:

\[P(X = x) = H (x\mid m,M, k) = \frac{\dbinom{m}{x} \dbinom{M - m}{k - x}}{\dbinom{M}{k}}\] where:

\(x\) is the number of successes of the sample

\(M\) is the size of the population.

\(k\) is the size of the sample or the number of trials.

\(m\) is the number of successes in the population.

Note that \(M\), the size of the population contains \(m\) successes and \(n\) failures, then \(M = m + n\), therefore, we can redefine the formula based on the number of successes and failures:

\[P(X = x) = H (x\mid m, n, k) = \frac{\dbinom{m}{x} \dbinom{n}{k - x}}{\dbinom{m+n}{k}}\] In R the probability mass function is denoted by dhyper:

dhyper(x, m, n, k, log = FALSE)

where:

x is the number of successes in the sample.

m is the number of successes in the population.

n is the number of failures in the population.

k is the size of the sample or the number of trials.

Example:

A homeowner plants 6 bulbs selected at random from a box containing 5 tulip bulbs and 4 daffodil bulbs. What is the probability that he planted 2 daffodil bulbs and 4 tulip bulbs?

\(x =\) 2, \(m =\) 4, \(n =\) 5, \(k =\) 6,

\[P(X = 2) = H (2\mid 4, 5, 6) = \frac{\dbinom{4}{2} \dbinom{5}{6-2}}{\dbinom{4 + 5}{6}} = \frac{5}{14} \approx 0.36\]

dhyper(x = 2, m = 4, n = 5, k = 6)
[1] 0.3571429
library(ggplot2)
library(dplyr)
density = dhyper(x = 1:6, m = 4, n = 5, k = 6)
data.frame(daffodil = 1:6, density) %>%
  mutate(daffodil2 = ifelse(daffodil == 2, "x = 2", "other")) %>%
ggplot(aes(x = factor(daffodil), y = density, fill = daffodil2)) +
  geom_col() +
    geom_text(
    aes(label = round(density,2), y = density + 0.01),
    position = position_dodge(0.9),
    size = 3,
    vjust = 0
  ) +
  labs(title = "PMF of X = x",
       subtitle = "Hypergeometric(m = 4, n = 5, k = 6)",
       x = "Number of daffodil bulbs (x)",
       y = "Density")

The same result is obtained with:

\(x =4\), \(m =5\), \(n = 4\), \(k =\) 6,

\[H (4\mid 5, 4, 6) = \frac{\dbinom{5}{4} \dbinom{4}{6-4}}{\dbinom{4+5}{6}} = \frac {5}{14} \approx 0.36\]

dhyper(x = 4, m = 5, n = 4, k = 6)
[1] 0.3571429
density = dhyper(x = 1:6, m = 5, n = 4, k = 6)
data.frame(tulip = 1:6, density) %>%
  mutate(tulip4 = ifelse(tulip == 4, "x = 4", "other")) %>%
ggplot(aes(x = factor(tulip), y = density, fill = tulip4)) +
  geom_col() +
  geom_text(
    aes(label = round(density,2), y = density + 0.01),
    position = position_dodge(0.9),
    size = 3,
    vjust = 0
  ) +
  labs(title = "PMF of X = x",
       subtitle = "Hypergeometric(m = 5, n = 4, k = 6)",
       x = "Number of tulip bulbs (x)",
       y = "Density")

The Cumulative Distribution Function

The cumulative distribution function or the probability that \(X\) will take a value less than or equal to \(x\) is:

\[P[X\leq x] =\sum_{x_i \leq x} H(x_i\mid m, n, k)\]

In R the distribution function is denoted by phyper

phyper(q, m, n, k, lower.tail = TRUE, log.p = FALSE)

Example:

A storeroom just received a shipment of 13 paper graters. Shortly after they were received, the manufacturer called to report that he had inadvertently shipped 5 defective units. The owner of the storeroom decided to test 4 of the 13 paper graters she received. Assume the samples are drawn without replacement.

What is the probability that 3 or less units are defective?

phyper(q = 3, m = 5, n = 8, k = 4)
[1] 0.993007

The same result can be obtained with the probability mass function:

sum(dhyper(x = c(0:3), m = 5, n = 8, k = 4))
[1] 0.993007

What is the probability that more than 2 units are defective?

phyper(q = 2, m = 5, n = 8, k = 4, lower.tail = FALSE)
[1] 0.1188811

or returning the area in the left tail of the distribution:

1 - phyper(q = 2, m = 5, n = 8, k = 4, lower.tail = TRUE)
[1] 0.1188811

The same result can be obtained with the probability mass function:

sum(dhyper(x = c(3:13), m = 5, n = 8, k = 4))
[1] 0.1188811

Quantile Function

The \(p^{th}\) quantile is the smallest value of Hypergeometric ramdom variable \(X\) such that \(P(X \leq x) \geq p\).

The syntax to compute the quantiles of Hypergeometric distribution using R is qhyper(p,m,n,k)

The function qhyper gives \(100 \times p^{th}\) quantile of Hypergeometric distribution for given value.

A company produces and ships 16 personal computers knowing that 5 of them have defective wiring. The company that purchased the computers is going to thoroughly test four of the computers. The purchasing company can detect the defective wiring.

What is the value of \(c\), if \(P(X \leq) \geq 0.90\)?

We need to find the value of c such a that \(P(X\leq c) \geq 0.90\). That is we need to find the 60th quantile of given Hypergeometric distribution.

qhyper(p = 0.90, m = 5, n = 11, k = 4)
[1] 2

Random Variates

We need to generate 100 random observations from Hypergeometric distribution with m = 5, n = 11 and k = 4.

rhyper(nn = 100, m = 5, n = 11, k = 4) 
  [1] 1 2 2 3 2 0 0 1 1 1 0 2 1 2 1 1 0 1 1 2 2 1 1 0 2 1 2 1 2 1 0 1 3 1 1 1 2 2
 [39] 0 1 1 0 2 2 1 2 3 0 2 2 1 3 1 2 0 0 1 2 1 1 2 2 2 2 0 0 1 2 2 1 1 0 2 1 3 1
 [77] 2 2 1 3 1 2 1 0 1 2 1 0 1 0 1 2 0 2 2 1 1 3 0 2

Miscellaneous exercises

1. A CD contains 10 songs; 6 are classical and 4 are rock and roll. In a sample of 3 songs, what is the probability that exactly 2 are classical? Assume the samples are drawn without replacement.

dhyper(x = 2, m = 6, n = 4, k = 3)
[1] 0.5

2. Keith’s Florists has 15 delivery trucks, used mainly to deliver flowers and flower arrangements in the Greenville, South Carolina, area. Of these 15 trucks, 6 have brake problems. A sample of 5 trucks is randomly selected. What is the probability that 2 of those tested have defective brakes?

dhyper(x = 2, m = 6, n = 9, k = 5)
[1] 0.4195804

3. If 7 cards are dealt from an ordinary deck of 52 playing cards, what is the probability that

a) exactly 2 of them will be face cards?

\[ P(X = 2) = H (2\mid 12, 40, 7) = \frac{\dbinom{12}{2} \dbinom{40}{7 - 2}}{\dbinom{12+40}{7}} \approx 0.32\] Solving this probability directly with the choose function:

(choose(n = 12, k = 2) * choose(n = 40, k = 5)) / choose(n = 52, k = 7)
[1] 0.3246154

The same result can be obtained using dhyper:

dhyper(x = 2, m = 12, n = 40, k = 7)
[1] 0.3246154

b) at least 1 of them will be a queen?

\[P(X \geq 1) = 1 - P(X = 0) = 1 - H (0\mid 4, 48, 7) = 1-\frac{\dbinom{4}{0} \dbinom{48}{7 - 0}}{\dbinom{48+4}{7}} \approx 0.45\]

1 - (choose(n = 4, k = 0) * choose(n = 48, k = 7)) / choose(n = 52, k = 7)
[1] 0.4496445

Using the built-in Hypergeometric {stats} functions of R:

sum(dhyper(x = 1:4, m = 4, n = 48, k = 7))
[1] 0.4496445
phyper(q = 0, m = 4, n = 48, k = 7, lower.tail = FALSE)
[1] 0.4496445

4. A company is interested in evaluating its current inspection procedure for shipments of 50 identical items. The procedure is to take a sample of 5 and pass the shipment if no more than 2 are found to be defective. What proportion of shipments with 20% defectives will be accepted?

The number of defectives in a shipment is \(50 \times 20\% = 10\). Therefore, \(m = 10\), \(n = 40\), \(k = 5\).

The probability that a shipment will be accepted with 20% defective items is \(P[X\leq2]\)

\[P[X\leq2] =\sum_{x=0}^2 H(x_i\mid 10, 40, 5)\]

sum(dhyper(x = 0:2, m = 10, n = 40, k = 5)) # density function
[1] 0.9517397
phyper(q = 2, m = 10, n = 40, k = 5) # distribution function
[1] 0.9517397

5. An annexation suit against a county subdivision of 1200 residences is being considered by a neighboring city. If the occupants of half the residences object to being annexed, what is the probability that in a random sample of 10 at least 3 favor the annexation suit?

phyper(q = 2, m = 600, n = 600, k = 10, lower.tail = FALSE)
[1] 0.9460455

6. A nationwide survey of 17,000 college seniors by the University of Michigan revealed that almost 70% disapprove of daily pot smoking. If 18 of these seniors are selected at random and asked their opinion, what is the probability that more than 9 but fewer than 14 disapprove of smoking pot daily?

We can sum the probabilities from more than 9 (10), to fewer than 14 (13):

sum(dhyper(x = 10:13, m = 17000 * 0.7, n = 17000 * 0.3, k = 18))
[1] 0.6079669

There is another approach to get the same probability: using the distribution function combined with the diff function that calculates the difference between successive elements of a vector, in this way we can get the difference in cumulative probabilities:

diff(phyper(q = c(9, 13), m = 17000 * 0.7, n = 17000 * 0.3, k = 18, lower.tail = TRUE))
[1] 0.6079669

This is equivalent to:

phyper(q = 13, m = 17000 * 0.7, n = 17000 * 0.3, k = 18, lower.tail = TRUE) - phyper(q = 9, m = 17000 * 0.7, n = 17000 * 0.3, k = 18, lower.tail = TRUE)
[1] 0.6079669

Also equivalent to:

diff(phyper(q = c(13, 9), m = 17000 * 0.7, n = 17000 * 0.3, k = 18, lower.tail = FALSE))
[1] 0.6079669

7. A foreign student club lists as its members 2 Canadians, 3 Japanese, 5 Italians, and 2 Germans. If a committee of 4 is selected at random, find the probability that * all nationalities are represented

(choose(2, 1) * choose(3, 1) * choose(5, 1) * choose(2, 1)) / choose(12, 4)
[1] 0.1212121

8. Biologists doing studies in a particular environment often tag and release subjects in order to estimate the size of a population or the prevalence of certain features in the population. Ten animals of a certain population thought to be extinct (or near extinction) are caught, tagged, and released in a certain region. After a period of time, a random sample of 15 of this type of animal is selected in the region. What is the probability that 5 of those selected are tagged if there are 25 animals of this type in the region?

\[P(X=5) = H(0\mid 10, 15, 15) = \frac{\dbinom{10}{5} \dbinom{15}{15 - 5}}{\dbinom{10+15}{15}}\]

dhyper(x = 5, m = 10 , n = 15 , k = 15)
[1] 0.2315116

9. A government task force suspects that some manufacturing companies are in violation of federal pollution regulations with regard to dumping a certain type of product. Twenty firms are under suspicion but not all can be inspected. Suppose that 3 of the firms are in violation.

a) What is the probability that inspection of 5 firms will find no violations?

\[P(X=0) = H(0\mid 3, 17, 5) = \frac{\dbinom{3}{0} \dbinom{17}{5-0}}{\dbinom{3 + 17}{5}}\]

dhyper(x = 0, m = 3, n = 17, k = 5)
[1] 0.3991228

b) What is the probability that the plan above will find two violations?

\[P(X=2) = H(2\mid 3, 17, 5) = \frac{\dbinom{3}{2} \dbinom{17}{5-2}}{\dbinom{3 + 17}{5}}\]

dhyper(x = 2, m = 3, n = 17, k = 5)
[1] 0.1315789

10. To avoid detection at customs, a traveler places 6 narcotic tablets in a bottle containing 9 vitamin tablets that are similar in appearance. If the customs official selects 3 of the tablets at random for analysis, what is the probability that the traveler will be arrested for illegal possession of narcotics?

\[P(X \geq 1) = \sum_{x=1}^{6} H(x_i\mid 6, 9, 3)\]

sum(dhyper(x = 1:6, m = 6, n = 9, k = 3))
[1] 0.8153846

Same as:

phyper(q = 0, m = 6, n = 9, k = 3, lower.tail = FALSE) 
[1] 0.8153846

Another approach to the problem is: \[P(X \geq 1) = 1 - P(X = 0) = 1 - H(0 \mid 6, 9, 3) \]

1 - dhyper(x = 0, m = 6, n = 9, k = 3)
[1] 0.8153846

11. From a lot of 10 missiles, 4 are selected at random and fired. If the lot contains 3 defective missiles that will not fire, what is the probability that (a) all 4 will fire?

\[P(X=4) = H(4\mid 7, 3, 4) = \frac{\dbinom{7}{4} \dbinom{3}{4-4}}{\dbinom{7+3}{4}}\]

dhyper(x = 4, m = 7, n = 3, k = 4)
[1] 0.1666667

(b) at most 2 will not fire?

\[P(X \leq 2) = \sum_{x=0}^{2} H(x_i\mid 3, 7, 4)\]

sum(dhyper(x = 0:2, m = 3, n = 7, k = 4))
[1] 0.9666667

Or what is the same:

phyper(q = 2, m = 3, n = 7, k = 4)
[1] 0.9666667

12. A manufacturing company uses an acceptance scheme on items from a production line before they are shipped. The plan is a two-stage one. Boxes of 25 items are readied for shipment, and a sample of 3 items is tested for defectives. If any defectives are found, the entire box is sent back for 100% screening. If no defectives are found, the box is shipped.

a) What is the probability that a box containing 3 defectives will be shipped?

dhyper(x = 0, m = 3, n = 22, k = 3)
[1] 0.6695652

b) What is the probability that a box containing only 1 defective will be sent back for screening?

dhyper(x = 1, m = 1, n = 24, k = 3)
[1] 0.12

References

Lind, Douglas A, William G Marchal, and Samuel Adam Wathen. 2012. Statistical Techniques in Business & Economics. New York, NY: McGraw-Hill/Irwin,

Myers, R, S Myers, R Walpole, and K Ye. 2012. “Probability & Statistics for Engineers and Scientists, Ninth Editon.” Pearson.

LS0tCnRpdGxlOiAiVGhlIEh5cGVyZ2VvbWV0cmljIERpc3RyaWJ1dGlvbiIKYXV0aG9yOiAiWGF2aWVyIEppbcOpbmV6LUFsYsOhbiIKIyBkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZC8lbS8lWSAlICVIOiVNOiVTJylgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogIGh0bWxfZG9jdW1lbnQ6CiAgICBrZWVwX21kOiB5ZXMKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIHBkZl9kb2N1bWVudDogZGVmYXVsdApiaWJsaW9ncmFwaHk6IHNjaG9sYXIuYmliCm5vY2l0ZTogJ0AqJwotLS0KCiMgQmFja2dyb3VuZCAKVGhlIGFwcGxpY2F0aW9ucyBvZiB0aGUgaHlwZXJnZW9tZXRyaWMgZGlzdHJpYnV0aW9uIGFyZSB2ZXJ5IHNpbWlsYXIgdG8gdGhvc2Ugb2YgdGhlIGJpbm9taWFsIGRpc3RyaWJ1dGlvbi4gSG93ZXZlciwgdGhlcmUgaXMgYSBmdW5kYW1lbnRhbCBkaWZmZXJlbmNlOiBJbiB0aGUgIGJpbm9taWFsLCB0aGUgcHJvYmFiaWxpdHkgb2YgYSBzdWNjZXNzIGlzIGVxdWFsIGZyb20gdHJpYWwgdG8gdHJpYWwgKHNhbXBsaW5nIHdpdGggcmVwbGFjZW1lbnQpLCB3aGlsZSBpbiB0aGUgaHlwZXJnZW9tZXRyaWMsIHRoZSBwcm9iYWJpbGl0eSBvZiBhIHN1Y2NlcyBtYXkgbm90IGJlIHRoZSBzYW1lIGZyb20gdHJpYWwgdG8gdHJpYWwgKHNhbXBsaW5nIHdpdGhvdXQgcmVwbGFjZW1lbnQpLiBUaGVyZWZvcmUsIGlmIHRoZSBwb3B1bGF0aW9uIHNocmlua3MgZWFjaCB0aW1lLCB0aGUgcHJvYmFiaWxpdHkgZm9yIGVhY2ggb2JzZXJ2YXRpb24gd2lsbCBjaGFuZ2UuCgpUaGUgYXBwbGljYXRpb25zIG9mIHRoZSBoeXBlcmdlb21ldHJpYyBkaXN0cmlidXRpb24gYXJlIHZlcnkgY29tbW9uLCBlc3BlY2lhbGx5IHdoZXJlIHNhbXBsaW5nIHdpdGhvdXQgcmVwbGFjZW1lbnQgaXMgbmVjZXNzYXJ5LiBGb3IgZXhhbXBsZSwgd2hlcmUgdGhlIHNhbXBsaW5nIGlzIHBlcmZvcm1lZCBhdCB0aGUgZXhwZW5zZSBvZiB0aGUgaXRlbSBiZWluZyB0ZXN0ZWQ7IHRoYXQgaXMsIHRoZSBpdGVtIGlzIGRlc3Ryb3llZCBhbmQgY2Fubm90IGJlIHJlcGxhY2VkLgoKVGhlIGV4cGVjdGVkIHZhbHVlIGFuZCB2YXJpYW5jZSBvZiB0aGUgaHlwZXJnZW9tZXRyaWMgZGlzdHJpYnV0aW9uICRIICh4XG1pZCBtLCBuLCBrKSQgYXJlCiQkRShYKSA9IGsgXGZyYWN7bX17bSArIG59JCQgYW5kICQkVmFyKFgpID0gayBcZnJhY3ttfXttICsgbn0gXGNkb3QgXGZyYWN7bSArIG4gLSBrfXttICsgbn0gXGNkb3QgXGZyYWN7bn17bSArIG4gLTF9JCQgCgp3aGVyZToKCiRrJCBpcyB0aGUgc2l6ZSBvZiB0aGUgc2FtcGxlLgoKJG0kIGlzIHRoZSBudW1iZXIgb2Ygc3VjY2Vzc2VzIGluIHRoZSBwb3B1bGF0aW9uLgoKJG4kIGlzIHRoZSBudW1iZXIgb2YgZmFpbHVyZXMgaW4gdGhlIHBvcHVsYXRpb24uCgojIFByb2JhYmlsaXR5IE1hc3MgRnVuY3Rpb24gCgpUaGUgInN0YW5kYXJkIiBmb3JtdWxhIGZvciB0aGUgcHJvYmFiaWxpdHkgbWFzcyBmdW5jdGlvbiBvZiAkeCQgc3VjY2Vzc2VzIGlzOgoKJCRQKFggPSB4KSA9IEggKHhcbWlkIG0sTSwgaykgPSBcZnJhY3tcZGJpbm9te219e3h9IFxkYmlub217TSAtIG19e2sgLSB4fX17XGRiaW5vbXtNfXtrfX0kJAp3aGVyZToKCiR4JCBpcyB0aGUgbnVtYmVyIG9mIHN1Y2Nlc3NlcyBvZiB0aGUgc2FtcGxlCgokTSQgaXMgdGhlIHNpemUgb2YgdGhlIHBvcHVsYXRpb24uCgokayQgaXMgdGhlIHNpemUgb2YgdGhlIHNhbXBsZSBvciB0aGUgbnVtYmVyIG9mIHRyaWFscy4KCiRtJCBpcyB0aGUgbnVtYmVyIG9mIHN1Y2Nlc3NlcyBpbiB0aGUgcG9wdWxhdGlvbi4KCgoKTm90ZSB0aGF0ICRNJCwgdGhlIHNpemUgb2YgdGhlIHBvcHVsYXRpb24gY29udGFpbnMgJG0kIHN1Y2Nlc3NlcyBhbmQgJG4kIGZhaWx1cmVzLCB0aGVuICRNID0gbSArIG4kLCB0aGVyZWZvcmUsIHdlIGNhbiByZWRlZmluZSB0aGUgZm9ybXVsYSBiYXNlZCBvbiB0aGUgbnVtYmVyIG9mIHN1Y2Nlc3NlcyBhbmQgZmFpbHVyZXM6CgokJFAoWCA9IHgpID0gSCAoeFxtaWQgbSwgbiwgaykgPSBcZnJhY3tcZGJpbm9te219e3h9IFxkYmlub217bn17ayAtIHh9fXtcZGJpbm9te20rbn17a319JCQKSW4gYFJgIHRoZSBwcm9iYWJpbGl0eSBtYXNzIGZ1bmN0aW9uIGlzIGRlbm90ZWQgYnkgYGRoeXBlcmA6CgpgYGB7ciBldmFsPUZBTFNFfQpkaHlwZXIoeCwgbSwgbiwgaywgbG9nID0gRkFMU0UpCmBgYAoKd2hlcmU6CgpgeGAgaXMgdGhlIG51bWJlciBvZiBzdWNjZXNzZXMgaW4gdGhlIHNhbXBsZS4KCmBtYCBpcyB0aGUgbnVtYmVyIG9mIHN1Y2Nlc3NlcyBpbiB0aGUgcG9wdWxhdGlvbi4KCmBuYCBpcyB0aGUgbnVtYmVyIG9mIGZhaWx1cmVzIGluIHRoZSBwb3B1bGF0aW9uLgoKYGtgIGlzIHRoZSBzaXplIG9mIHRoZSBzYW1wbGUgb3IgdGhlIG51bWJlciBvZiB0cmlhbHMuCgoKCkV4YW1wbGU6CgoqQSBob21lb3duZXIgcGxhbnRzIDYgYnVsYnMgc2VsZWN0ZWQgYXQgcmFuZG9tIGZyb20gYSBib3ggY29udGFpbmluZyA1IHR1bGlwIGJ1bGJzIGFuZCA0IGRhZmZvZGlsIGJ1bGJzLiBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IGhlIHBsYW50ZWQgMiBkYWZmb2RpbCBidWxicyBhbmQgNCB0dWxpcCBidWxicz8qCgokeCA9JCAyLAokbSA9JCA0LAokbiA9JCA1LAokayA9JCA2LAoKCgokJFAoWCA9IDIpID0gSCAoMlxtaWQgNCwgNSwgNikgPSBcZnJhY3tcZGJpbm9tezR9ezJ9IFxkYmlub217NX17Ni0yfX17XGRiaW5vbXs0ICsgNX17Nn19ID0gXGZyYWN7NX17MTR9IFxhcHByb3ggMC4zNiQkCgoKYGBge3J9CmRoeXBlcih4ID0gMiwgbSA9IDQsIG4gPSA1LCBrID0gNikKYGBgCgoKYGBge3IgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpkZW5zaXR5ID0gZGh5cGVyKHggPSAxOjYsIG0gPSA0LCBuID0gNSwgayA9IDYpCmRhdGEuZnJhbWUoZGFmZm9kaWwgPSAxOjYsIGRlbnNpdHkpICU+JQogIG11dGF0ZShkYWZmb2RpbDIgPSBpZmVsc2UoZGFmZm9kaWwgPT0gMiwgInggPSAyIiwgIm90aGVyIikpICU+JQpnZ3Bsb3QoYWVzKHggPSBmYWN0b3IoZGFmZm9kaWwpLCB5ID0gZGVuc2l0eSwgZmlsbCA9IGRhZmZvZGlsMikpICsKICBnZW9tX2NvbCgpICsKICAgIGdlb21fdGV4dCgKICAgIGFlcyhsYWJlbCA9IHJvdW5kKGRlbnNpdHksMiksIHkgPSBkZW5zaXR5ICsgMC4wMSksCiAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksCiAgICBzaXplID0gMywKICAgIHZqdXN0ID0gMAogICkgKwogIGxhYnModGl0bGUgPSAiUE1GIG9mIFggPSB4IiwKICAgICAgIHN1YnRpdGxlID0gIkh5cGVyZ2VvbWV0cmljKG0gPSA0LCBuID0gNSwgayA9IDYpIiwKICAgICAgIHggPSAiTnVtYmVyIG9mIGRhZmZvZGlsIGJ1bGJzICh4KSIsCiAgICAgICB5ID0gIkRlbnNpdHkiKQpgYGAKClRoZSBzYW1lIHJlc3VsdCBpcyBvYnRhaW5lZCB3aXRoOgoKJHggPTQkLAokbSA9NSQsCiRuID0gNCQsCiRrID0kIDYsCgoKJCRIICg0XG1pZCA1LCA0LCA2KSA9IFxmcmFje1xkYmlub217NX17NH0gXGRiaW5vbXs0fXs2LTR9fXtcZGJpbm9tezQrNX17Nn19ID0gXGZyYWMgezV9ezE0fSBcYXBwcm94IDAuMzYkJAoKCmBgYHtyfQpkaHlwZXIoeCA9IDQsIG0gPSA1LCBuID0gNCwgayA9IDYpCmBgYAoKYGBge3J9CmRlbnNpdHkgPSBkaHlwZXIoeCA9IDE6NiwgbSA9IDUsIG4gPSA0LCBrID0gNikKZGF0YS5mcmFtZSh0dWxpcCA9IDE6NiwgZGVuc2l0eSkgJT4lCiAgbXV0YXRlKHR1bGlwNCA9IGlmZWxzZSh0dWxpcCA9PSA0LCAieCA9IDQiLCAib3RoZXIiKSkgJT4lCmdncGxvdChhZXMoeCA9IGZhY3Rvcih0dWxpcCksIHkgPSBkZW5zaXR5LCBmaWxsID0gdHVsaXA0KSkgKwogIGdlb21fY29sKCkgKwogIGdlb21fdGV4dCgKICAgIGFlcyhsYWJlbCA9IHJvdW5kKGRlbnNpdHksMiksIHkgPSBkZW5zaXR5ICsgMC4wMSksCiAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksCiAgICBzaXplID0gMywKICAgIHZqdXN0ID0gMAogICkgKwogIGxhYnModGl0bGUgPSAiUE1GIG9mIFggPSB4IiwKICAgICAgIHN1YnRpdGxlID0gIkh5cGVyZ2VvbWV0cmljKG0gPSA1LCBuID0gNCwgayA9IDYpIiwKICAgICAgIHggPSAiTnVtYmVyIG9mIHR1bGlwIGJ1bGJzICh4KSIsCiAgICAgICB5ID0gIkRlbnNpdHkiKQpgYGAKCgojIFRoZSBDdW11bGF0aXZlIERpc3RyaWJ1dGlvbiBGdW5jdGlvbgoKVGhlIGN1bXVsYXRpdmUgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uIG9yIHRoZSBwcm9iYWJpbGl0eSB0aGF0ICRYJCB3aWxsIHRha2UgYSB2YWx1ZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJHgkIGlzOgoKJCRQW1hcbGVxIHhdID1cc3VtX3t4X2kgXGxlcSB4fSBIKHhfaVxtaWQgbSwgbiwgaykkJAoKCkluIGBSYCB0aGUgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uIGlzIGRlbm90ZWQgYnkgYHBoeXBlcmAKCmBgYHtyIGV2YWw9RkFMU0V9CnBoeXBlcihxLCBtLCBuLCBrLCBsb3dlci50YWlsID0gVFJVRSwgbG9nLnAgPSBGQUxTRSkKYGBgCgpFeGFtcGxlOiAKCipBIHN0b3Jlcm9vbSBqdXN0IHJlY2VpdmVkIGEgc2hpcG1lbnQgb2YgMTMgcGFwZXIgZ3JhdGVycy4gU2hvcnRseSBhZnRlciB0aGV5IHdlcmUgcmVjZWl2ZWQsIHRoZSBtYW51ZmFjdHVyZXIgY2FsbGVkIHRvIHJlcG9ydCB0aGF0IGhlIGhhZCBpbmFkdmVydGVudGx5IHNoaXBwZWQgNSBkZWZlY3RpdmUgdW5pdHMuIFRoZSBvd25lciBvZiB0aGUgc3RvcmVyb29tIGRlY2lkZWQgdG8gdGVzdCA0IG9mIHRoZSAxMyBwYXBlciBncmF0ZXJzIHNoZSByZWNlaXZlZC4gQXNzdW1lIHRoZSBzYW1wbGVzIGFyZSBkcmF3biB3aXRob3V0IHJlcGxhY2VtZW50LioKCipXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IDMgb3IgbGVzcyB1bml0cyBhcmUgZGVmZWN0aXZlPyoKCmBgYHtyfQpwaHlwZXIocSA9IDMsIG0gPSA1LCBuID0gOCwgayA9IDQpCmBgYApUaGUgc2FtZSByZXN1bHQgY2FuIGJlIG9idGFpbmVkIHdpdGggdGhlIHByb2JhYmlsaXR5IG1hc3MgZnVuY3Rpb246CgpgYGB7cn0Kc3VtKGRoeXBlcih4ID0gYygwOjMpLCBtID0gNSwgbiA9IDgsIGsgPSA0KSkKYGBgCgoKKldoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgbW9yZSB0aGFuIDIgdW5pdHMgYXJlIGRlZmVjdGl2ZT8qCgpgYGB7cn0KcGh5cGVyKHEgPSAyLCBtID0gNSwgbiA9IDgsIGsgPSA0LCBsb3dlci50YWlsID0gRkFMU0UpCmBgYApvciByZXR1cm5pbmcgdGhlIGFyZWEgaW4gdGhlIGxlZnQgdGFpbCBvZiB0aGUgZGlzdHJpYnV0aW9uOgoKYGBge3J9CjEgLSBwaHlwZXIocSA9IDIsIG0gPSA1LCBuID0gOCwgayA9IDQsIGxvd2VyLnRhaWwgPSBUUlVFKQpgYGAKClRoZSBzYW1lIHJlc3VsdCBjYW4gYmUgb2J0YWluZWQgd2l0aCB0aGUgcHJvYmFiaWxpdHkgbWFzcyBmdW5jdGlvbjoKYGBge3J9CnN1bShkaHlwZXIoeCA9IGMoMzoxMyksIG0gPSA1LCBuID0gOCwgayA9IDQpKQpgYGAKCiMgUXVhbnRpbGUgRnVuY3Rpb24KClRoZSAkcF57dGh9JCBxdWFudGlsZSBpcyB0aGUgc21hbGxlc3QgdmFsdWUgb2YgSHlwZXJnZW9tZXRyaWMgcmFtZG9tIHZhcmlhYmxlICRYJCBzdWNoIHRoYXQgJFAoWCBcbGVxIHgpIFxnZXEgcCQuCgpUaGUgc3ludGF4IHRvIGNvbXB1dGUgdGhlIHF1YW50aWxlcyBvZiBIeXBlcmdlb21ldHJpYyBkaXN0cmlidXRpb24gdXNpbmcgUiBpcyBgcWh5cGVyKHAsbSxuLGspYAoKVGhlIGZ1bmN0aW9uIGBxaHlwZXJgIGdpdmVzICQxMDAgXHRpbWVzIHBee3RofSQgcXVhbnRpbGUgb2YgSHlwZXJnZW9tZXRyaWMgZGlzdHJpYnV0aW9uIGZvciBnaXZlbiB2YWx1ZS4KCgoKQSBjb21wYW55IHByb2R1Y2VzIGFuZCBzaGlwcyAxNiBwZXJzb25hbCBjb21wdXRlcnMga25vd2luZyB0aGF0IDUgb2YgdGhlbSBoYXZlIGRlZmVjdGl2ZSB3aXJpbmcuIFRoZSBjb21wYW55IHRoYXQgcHVyY2hhc2VkIHRoZSBjb21wdXRlcnMgaXMgZ29pbmcgdG8gdGhvcm91Z2hseSB0ZXN0IGZvdXIgb2YgdGhlIGNvbXB1dGVycy4gVGhlIHB1cmNoYXNpbmcgY29tcGFueSBjYW4gZGV0ZWN0IHRoZSBkZWZlY3RpdmUgd2lyaW5nLgoKV2hhdCBpcyB0aGUgdmFsdWUgb2YgJGMkLCBpZiAkUChYIFxsZXEpIFxnZXEgMC45MCQ/CgpXZSBuZWVkIHRvIGZpbmQgdGhlIHZhbHVlIG9mIGMgc3VjaCBhIHRoYXQgJFAoWFxsZXEgYykgXGdlcSAwLjkwJC4gVGhhdCBpcyB3ZSBuZWVkIHRvIGZpbmQgdGhlIDYwdGggcXVhbnRpbGUgb2YgZ2l2ZW4gSHlwZXJnZW9tZXRyaWMgZGlzdHJpYnV0aW9uLgoKYGBge3J9CnFoeXBlcihwID0gMC45MCwgbSA9IDUsIG4gPSAxMSwgayA9IDQpCmBgYAoKCgojIFJhbmRvbSBWYXJpYXRlcwoKV2UgbmVlZCB0byBnZW5lcmF0ZSAxMDAgcmFuZG9tIG9ic2VydmF0aW9ucyBmcm9tIEh5cGVyZ2VvbWV0cmljIGRpc3RyaWJ1dGlvbiB3aXRoIGBtID0gNSwgbiA9IDExIGFuZCBrID0gNGAuCgpgYGB7cn0Kcmh5cGVyKG5uID0gMTAwLCBtID0gNSwgbiA9IDExLCBrID0gNCkgCmBgYAoKCgojIE1pc2NlbGxhbmVvdXMgZXhlcmNpc2VzIAoKKioxLioqICpBIENEIGNvbnRhaW5zIDEwIHNvbmdzOyA2IGFyZSBjbGFzc2ljYWwgYW5kIDQgYXJlIHJvY2sgYW5kIHJvbGwuIEluIGEgc2FtcGxlIG9mIDMgc29uZ3MsIHdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgZXhhY3RseSAyIGFyZSBjbGFzc2ljYWw/IEFzc3VtZSB0aGUgc2FtcGxlcyBhcmUgZHJhd24gd2l0aG91dCByZXBsYWNlbWVudC4qCmBgYHtyfQpkaHlwZXIoeCA9IDIsIG0gPSA2LCBuID0gNCwgayA9IDMpCmBgYAoKKioyLioqICpLZWl0aOKAmXMgRmxvcmlzdHMgaGFzIDE1IGRlbGl2ZXJ5IHRydWNrcywgdXNlZCBtYWlubHkgdG8gZGVsaXZlciBmbG93ZXJzIGFuZCBmbG93ZXIgYXJyYW5nZW1lbnRzIGluIHRoZSBHcmVlbnZpbGxlLCBTb3V0aCBDYXJvbGluYSwgYXJlYS4gT2YgdGhlc2UgMTUgdHJ1Y2tzLCA2IGhhdmUgYnJha2UgcHJvYmxlbXMuIEEgc2FtcGxlIG9mIDUgdHJ1Y2tzIGlzIHJhbmRvbWx5IHNlbGVjdGVkLiBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IDIgb2YgdGhvc2UgdGVzdGVkIGhhdmUgZGVmZWN0aXZlIGJyYWtlcz8qCmBgYHtyfQpkaHlwZXIoeCA9IDIsIG0gPSA2LCBuID0gOSwgayA9IDUpCmBgYAoKKiozLioqICpJZiA3IGNhcmRzIGFyZSBkZWFsdCBmcm9tIGFuIG9yZGluYXJ5IGRlY2sgb2YgNTIgcGxheWluZyBjYXJkcywgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCoKCiphKSBleGFjdGx5IDIgb2YgdGhlbSB3aWxsIGJlIGZhY2UgY2FyZHM/KgoKJCQgUChYID0gMikgPSBIICgyXG1pZCAxMiwgNDAsIDcpID0gXGZyYWN7XGRiaW5vbXsxMn17Mn0gXGRiaW5vbXs0MH17NyAtIDJ9fXtcZGJpbm9tezEyKzQwfXs3fX0gXGFwcHJveCAwLjMyJCQKU29sdmluZyB0aGlzIHByb2JhYmlsaXR5IGRpcmVjdGx5IHdpdGggdGhlIGBjaG9vc2VgIGZ1bmN0aW9uOgoKYGBge3J9CihjaG9vc2UobiA9IDEyLCBrID0gMikgKiBjaG9vc2UobiA9IDQwLCBrID0gNSkpIC8gY2hvb3NlKG4gPSA1MiwgayA9IDcpCmBgYAoKVGhlIHNhbWUgcmVzdWx0IGNhbiBiZSBvYnRhaW5lZCB1c2luZyBgZGh5cGVyYDoKYGBge3J9CmRoeXBlcih4ID0gMiwgbSA9IDEyLCBuID0gNDAsIGsgPSA3KQpgYGAKCgoqYikgYXQgbGVhc3QgMSBvZiB0aGVtIHdpbGwgYmUgYSBxdWVlbj8qCgokJFAoWCBcZ2VxIDEpID0gMSAtIFAoWCA9IDApID0gMSAtICBIICgwXG1pZCA0LCA0OCwgNykgPSAxLVxmcmFje1xkYmlub217NH17MH0gXGRiaW5vbXs0OH17NyAtIDB9fXtcZGJpbm9tezQ4KzR9ezd9fSBcYXBwcm94IDAuNDUkJAoKYGBge3J9CjEgLSAoY2hvb3NlKG4gPSA0LCBrID0gMCkgKiBjaG9vc2UobiA9IDQ4LCBrID0gNykpIC8gY2hvb3NlKG4gPSA1MiwgayA9IDcpCmBgYAoKVXNpbmcgdGhlICpidWlsdC1pbiogYEh5cGVyZ2VvbWV0cmljIHtzdGF0c31gIGZ1bmN0aW9ucyBvZiAqKlIqKjoKYGBge3J9CnN1bShkaHlwZXIoeCA9IDE6NCwgbSA9IDQsIG4gPSA0OCwgayA9IDcpKQpgYGAKCmBgYHtyfQpwaHlwZXIocSA9IDAsIG0gPSA0LCBuID0gNDgsIGsgPSA3LCBsb3dlci50YWlsID0gRkFMU0UpCmBgYAoKCgoqKjQuKiogKkEgY29tcGFueSBpcyBpbnRlcmVzdGVkIGluIGV2YWx1YXRpbmcgaXRzIGN1cnJlbnQgaW5zcGVjdGlvbiBwcm9jZWR1cmUgZm9yIHNoaXBtZW50cyBvZiA1MCBpZGVudGljYWwgaXRlbXMuIFRoZSBwcm9jZWR1cmUgaXMgdG8gdGFrZSBhIHNhbXBsZSBvZiA1IGFuZCBwYXNzIHRoZSBzaGlwbWVudCBpZiBubyBtb3JlIHRoYW4gMiBhcmUgZm91bmQgdG8gYmUgZGVmZWN0aXZlLiBXaGF0IHByb3BvcnRpb24gb2Ygc2hpcG1lbnRzIHdpdGggMjAlIGRlZmVjdGl2ZXMgd2lsbCBiZSBhY2NlcHRlZD8qCgpUaGUgbnVtYmVyIG9mIGRlZmVjdGl2ZXMgaW4gYSBzaGlwbWVudCBpcyAkNTAgXHRpbWVzIDIwXCUgPSAxMCQuIFRoZXJlZm9yZSwgJG0gPSAxMCQsICRuID0gNDAkLCAkayA9IDUkLgoKVGhlIHByb2JhYmlsaXR5IHRoYXQgYSBzaGlwbWVudCB3aWxsIGJlIGFjY2VwdGVkIHdpdGggMjBcJSBkZWZlY3RpdmUgaXRlbXMgaXMgJFBbWFxsZXEyXSQKCiQkUFtYXGxlcTJdID1cc3VtX3t4PTB9XjIgSCh4X2lcbWlkIDEwLCA0MCwgNSkkJApgYGB7cn0Kc3VtKGRoeXBlcih4ID0gMDoyLCBtID0gMTAsIG4gPSA0MCwgayA9IDUpKSAjIGRlbnNpdHkgZnVuY3Rpb24KcGh5cGVyKHEgPSAyLCBtID0gMTAsIG4gPSA0MCwgayA9IDUpICMgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uCmBgYAoKCioqNS4qKiAqQW4gYW5uZXhhdGlvbiBzdWl0IGFnYWluc3QgYSBjb3VudHkgc3ViZGl2aXNpb24gb2YgMTIwMCByZXNpZGVuY2VzIGlzIGJlaW5nIGNvbnNpZGVyZWQgYnkgYSBuZWlnaGJvcmluZyBjaXR5LiBJZiB0aGUgb2NjdXBhbnRzIG9mIGhhbGYgdGhlIHJlc2lkZW5jZXMgb2JqZWN0IHRvIGJlaW5nIGFubmV4ZWQsIHdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgaW4gYSByYW5kb20gc2FtcGxlIG9mIDEwIGF0IGxlYXN0IDMgZmF2b3IgdGhlIGFubmV4YXRpb24gc3VpdD8qCgpgYGB7cn0KcGh5cGVyKHEgPSAyLCBtID0gNjAwLCBuID0gNjAwLCBrID0gMTAsIGxvd2VyLnRhaWwgPSBGQUxTRSkKYGBgCgoqKjYuKiogKkEgbmF0aW9ud2lkZSBzdXJ2ZXkgb2YgMTcsMDAwIGNvbGxlZ2Ugc2VuaW9ycyBieSB0aGUgVW5pdmVyc2l0eSBvZiBNaWNoaWdhbiByZXZlYWxlZCB0aGF0IGFsbW9zdCA3MCUgZGlzYXBwcm92ZSBvZiBkYWlseSBwb3Qgc21va2luZy4gSWYgMTggb2YgdGhlc2Ugc2VuaW9ycyBhcmUgc2VsZWN0ZWQgYXQgcmFuZG9tIGFuZCBhc2tlZCB0aGVpciBvcGluaW9uLCB3aGF0IGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IG1vcmUgdGhhbiA5IGJ1dCBmZXdlciB0aGFuIDE0IGRpc2FwcHJvdmUgb2Ygc21va2luZyBwb3QgZGFpbHk/KgoKV2UgY2FuIHN1bSB0aGUgcHJvYmFiaWxpdGllcyBmcm9tIG1vcmUgdGhhbiA5ICgxMCksIHRvIGZld2VyIHRoYW4gMTQgKDEzKToKYGBge3J9CnN1bShkaHlwZXIoeCA9IDEwOjEzLCBtID0gMTcwMDAgKiAwLjcsIG4gPSAxNzAwMCAqIDAuMywgayA9IDE4KSkKYGBgClRoZXJlIGlzIGFub3RoZXIgYXBwcm9hY2ggdG8gZ2V0IHRoZSBzYW1lIHByb2JhYmlsaXR5OiB1c2luZyB0aGUgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uIGNvbWJpbmVkIHdpdGggdGhlIGBkaWZmYCBmdW5jdGlvbiB0aGF0IGNhbGN1bGF0ZXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBzdWNjZXNzaXZlIGVsZW1lbnRzIG9mIGEgdmVjdG9yLCBpbiB0aGlzIHdheSB3ZSBjYW4gZ2V0IHRoZSBkaWZmZXJlbmNlIGluIGN1bXVsYXRpdmUgcHJvYmFiaWxpdGllczoKCmBgYHtyfQpkaWZmKHBoeXBlcihxID0gYyg5LCAxMyksIG0gPSAxNzAwMCAqIDAuNywgbiA9IDE3MDAwICogMC4zLCBrID0gMTgsIGxvd2VyLnRhaWwgPSBUUlVFKSkKYGBgClRoaXMgaXMgZXF1aXZhbGVudCB0bzoKYGBge3J9CnBoeXBlcihxID0gMTMsIG0gPSAxNzAwMCAqIDAuNywgbiA9IDE3MDAwICogMC4zLCBrID0gMTgsIGxvd2VyLnRhaWwgPSBUUlVFKSAtIHBoeXBlcihxID0gOSwgbSA9IDE3MDAwICogMC43LCBuID0gMTcwMDAgKiAwLjMsIGsgPSAxOCwgbG93ZXIudGFpbCA9IFRSVUUpCmBgYApBbHNvIGVxdWl2YWxlbnQgdG86CmBgYHtyfQpkaWZmKHBoeXBlcihxID0gYygxMywgOSksIG0gPSAxNzAwMCAqIDAuNywgbiA9IDE3MDAwICogMC4zLCBrID0gMTgsIGxvd2VyLnRhaWwgPSBGQUxTRSkpCmBgYAoKCgoqKjcuKiogKkEgZm9yZWlnbiBzdHVkZW50IGNsdWIgbGlzdHMgYXMgaXRzIG1lbWJlcnMgMiBDYW5hZGlhbnMsIDMgSmFwYW5lc2UsIDUgSXRhbGlhbnMsIGFuZCAyIEdlcm1hbnMuIElmIGEgY29tbWl0dGVlIG9mIDQgaXMgc2VsZWN0ZWQgYXQgcmFuZG9tLCBmaW5kIHRoZSBwcm9iYWJpbGl0eSB0aGF0KgoqICphbGwgbmF0aW9uYWxpdGllcyBhcmUgcmVwcmVzZW50ZWQqCmBgYHtyfQooY2hvb3NlKDIsIDEpICogY2hvb3NlKDMsIDEpICogY2hvb3NlKDUsIDEpICogY2hvb3NlKDIsIDEpKSAvIGNob29zZSgxMiwgNCkKYGBgCgoqKjguKiogKkJpb2xvZ2lzdHMgZG9pbmcgc3R1ZGllcyBpbiBhIHBhcnRpY3VsYXIgZW52aXJvbm1lbnQgb2Z0ZW4gdGFnIGFuZCByZWxlYXNlIHN1YmplY3RzIGluIG9yZGVyIHRvIGVzdGltYXRlIHRoZSBzaXplIG9mIGEgcG9wdWxhdGlvbiBvciB0aGUgcHJldmFsZW5jZSBvZiBjZXJ0YWluIGZlYXR1cmVzIGluIHRoZSBwb3B1bGF0aW9uLiBUZW4gYW5pbWFscyBvZiBhIGNlcnRhaW4gcG9wdWxhdGlvbiB0aG91Z2h0IHRvIGJlIGV4dGluY3QgKG9yIG5lYXIgZXh0aW5jdGlvbikgYXJlIGNhdWdodCwgdGFnZ2VkLCBhbmQgcmVsZWFzZWQgaW4gYSBjZXJ0YWluIHJlZ2lvbi4gQWZ0ZXIgYSBwZXJpb2Qgb2YgdGltZSwgYSByYW5kb20gc2FtcGxlIG9mIDE1IG9mIHRoaXMgdHlwZSBvZiBhbmltYWwgaXMgc2VsZWN0ZWQgaW4gdGhlIHJlZ2lvbi4gV2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCA1IG9mIHRob3NlIHNlbGVjdGVkIGFyZSB0YWdnZWQgaWYgdGhlcmUgYXJlIDI1IGFuaW1hbHMgb2YgdGhpcyB0eXBlIGluIHRoZSByZWdpb24/KgoKCiQkUChYPTUpID0gSCgwXG1pZCAxMCwgMTUsIDE1KSA9IFxmcmFje1xkYmlub217MTB9ezV9IFxkYmlub217MTV9ezE1IC0gNX19e1xkYmlub217MTArMTV9ezE1fX0kJApgYGB7cn0KZGh5cGVyKHggPSA1LCBtID0gMTAgLCBuID0gMTUgLCBrID0gMTUpCmBgYAoKKio5LioqICpBIGdvdmVybm1lbnQgdGFzayBmb3JjZSBzdXNwZWN0cyB0aGF0IHNvbWUgbWFudWZhY3R1cmluZyBjb21wYW5pZXMgYXJlIGluIHZpb2xhdGlvbiBvZiBmZWRlcmFsIHBvbGx1dGlvbiByZWd1bGF0aW9ucyB3aXRoIHJlZ2FyZCB0byBkdW1waW5nIGEgY2VydGFpbiB0eXBlIG9mIHByb2R1Y3QuIFR3ZW50eSBmaXJtcyBhcmUgdW5kZXIgc3VzcGljaW9uIGJ1dCBub3QgYWxsIGNhbiBiZSBpbnNwZWN0ZWQuIFN1cHBvc2UgdGhhdCAzIG9mIHRoZSBmaXJtcyBhcmUgaW4gdmlvbGF0aW9uLioKCiphKSBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IGluc3BlY3Rpb24gb2YgNSBmaXJtcyB3aWxsIGZpbmQgbm8gdmlvbGF0aW9ucz8qCgokJFAoWD0wKSA9IEgoMFxtaWQgMywgMTcsIDUpID0gXGZyYWN7XGRiaW5vbXszfXswfSBcZGJpbm9tezE3fXs1LTB9fXtcZGJpbm9tezMgKyAxN317NX19JCQKCmBgYHtyfQpkaHlwZXIoeCA9IDAsIG0gPSAzLCBuID0gMTcsIGsgPSA1KQpgYGAKCipiKSBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IHRoZSBwbGFuIGFib3ZlIHdpbGwgZmluZCB0d28gdmlvbGF0aW9ucz8qCgokJFAoWD0yKSA9IEgoMlxtaWQgMywgMTcsIDUpID0gXGZyYWN7XGRiaW5vbXszfXsyfSBcZGJpbm9tezE3fXs1LTJ9fXtcZGJpbm9tezMgKyAxN317NX19JCQKCmBgYHtyfQpkaHlwZXIoeCA9IDIsIG0gPSAzLCBuID0gMTcsIGsgPSA1KQpgYGAKCgoqKjEwLioqICpUbyBhdm9pZCBkZXRlY3Rpb24gYXQgY3VzdG9tcywgYSB0cmF2ZWxlciBwbGFjZXMgNiBuYXJjb3RpYyB0YWJsZXRzIGluIGEgYm90dGxlIGNvbnRhaW5pbmcgOSB2aXRhbWluIHRhYmxldHMgdGhhdCBhcmUgc2ltaWxhciBpbiBhcHBlYXJhbmNlLiBJZiB0aGUgY3VzdG9tcyBvZmZpY2lhbCBzZWxlY3RzIDMgb2YgdGhlIHRhYmxldHMgYXQgcmFuZG9tIGZvciBhbmFseXNpcywgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCB0aGUgdHJhdmVsZXIgd2lsbCBiZSBhcnJlc3RlZCBmb3IgaWxsZWdhbCBwb3NzZXNzaW9uIG9mIG5hcmNvdGljcz8qCgokJFAoWCBcZ2VxIDEpID0gXHN1bV97eD0xfV57Nn0gSCh4X2lcbWlkIDYsIDksIDMpJCQKCmBgYHtyfQpzdW0oZGh5cGVyKHggPSAxOjYsIG0gPSA2LCBuID0gOSwgayA9IDMpKQpgYGAKClNhbWUgYXM6CgpgYGB7cn0KcGh5cGVyKHEgPSAwLCBtID0gNiwgbiA9IDksIGsgPSAzLCBsb3dlci50YWlsID0gRkFMU0UpIApgYGAKCgoKQW5vdGhlciBhcHByb2FjaCB0byB0aGUgcHJvYmxlbSBpczoKJCRQKFggXGdlcSAxKSA9IDEgLSBQKFggPSAwKSA9IDEgLSBIKDAgXG1pZCA2LCA5LCAzKSAgJCQKYGBge3J9CjEgLSBkaHlwZXIoeCA9IDAsIG0gPSA2LCBuID0gOSwgayA9IDMpCmBgYAoKKioxMS4qKiAqRnJvbSBhIGxvdCBvZiAxMCBtaXNzaWxlcywgNCBhcmUgc2VsZWN0ZWQgYXQgcmFuZG9tIGFuZCBmaXJlZC4gSWYgdGhlIGxvdCBjb250YWlucyAzIGRlZmVjdGl2ZSBtaXNzaWxlcyB0aGF0IHdpbGwgbm90IGZpcmUsIHdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQqCiooYSkgYWxsIDQgd2lsbCBmaXJlPyoKCiQkUChYPTQpID0gSCg0XG1pZCA3LCAzLCA0KSA9IFxmcmFje1xkYmlub217N317NH0gXGRiaW5vbXszfXs0LTR9fXtcZGJpbm9tezcrM317NH19JCQKCmBgYHtyfQpkaHlwZXIoeCA9IDQsIG0gPSA3LCBuID0gMywgayA9IDQpCmBgYAoKKihiKSBhdCBtb3N0IDIgd2lsbCBub3QgZmlyZT8qCgokJFAoWCBcbGVxIDIpID0gXHN1bV97eD0wfV57Mn0gSCh4X2lcbWlkIDMsIDcsIDQpJCQKCmBgYHtyfQpzdW0oZGh5cGVyKHggPSAwOjIsIG0gPSAzLCBuID0gNywgayA9IDQpKQpgYGAKT3Igd2hhdCBpcyB0aGUgc2FtZToKCmBgYHtyfQpwaHlwZXIocSA9IDIsIG0gPSAzLCBuID0gNywgayA9IDQpCmBgYAoKCioqMTIuKiogQSBtYW51ZmFjdHVyaW5nIGNvbXBhbnkgdXNlcyBhbiBhY2NlcHRhbmNlIHNjaGVtZSBvbiBpdGVtcyBmcm9tIGEgcHJvZHVjdGlvbiBsaW5lIGJlZm9yZSB0aGV5IGFyZSBzaGlwcGVkLiBUaGUgcGxhbiBpcyBhIHR3by1zdGFnZSBvbmUuIEJveGVzIG9mIDI1IGl0ZW1zIGFyZSByZWFkaWVkIGZvciBzaGlwbWVudCwgYW5kIGEgc2FtcGxlIG9mIDMgaXRlbXMgaXMgdGVzdGVkIGZvciBkZWZlY3RpdmVzLiBJZiBhbnkgZGVmZWN0aXZlcyBhcmUgZm91bmQsIHRoZSBlbnRpcmUgYm94IGlzIHNlbnQgYmFjayBmb3IgMTAwJSBzY3JlZW5pbmcuIApJZiBubyBkZWZlY3RpdmVzIGFyZSBmb3VuZCwgdGhlIGJveCBpcyBzaGlwcGVkLgoKKmEpIFdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgYSBib3ggY29udGFpbmluZyAzIGRlZmVjdGl2ZXMgd2lsbCBiZSAKc2hpcHBlZD8qCgoKYGBge3J9CmRoeXBlcih4ID0gMCwgbSA9IDMsIG4gPSAyMiwgayA9IDMpCmBgYAoKKmIpIFdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgYSBib3ggY29udGFpbmluZyBvbmx5IDEgZGVmZWN0aXZlIHdpbGwgYmUgc2VudCBiYWNrIGZvciBzY3JlZW5pbmc/KgoKYGBge3J9CmRoeXBlcih4ID0gMSwgbSA9IDEsIG4gPSAyNCwgayA9IDMpCmBgYAoKCiMgUmVmZXJlbmNlcwoKCg==