Repository: VividCortex/gohistogram
Branch: master
Commit: 60139467e8ce
Files: 11
Total size: 87.2 KB
Directory structure:
gitextract_sbeqx0k_/
├── .github/
│ ├── ISSUE_TEMPLATE.md
│ └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .whitesource
├── LICENSE
├── README.md
├── histogram.go
├── histogram_test.go
├── numerichistogram.go
├── sample_data_test.go
└── weightedhistogram.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
Before you file an issue, please consider:
We only accept pull requests for minor fixes or improvements. This includes:
* Small bug fixes
* Typos
* Documentation or comments
Please open issues to discuss new features. Pull requests for new features will be rejected,
so we recommend forking the repository and making changes in your fork for your use case.
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
Before you create a pull request, please consider:
We only accept pull requests for minor fixes or improvements. This includes:
* Small bug fixes
* Typos
* Documentation or comments
Please open issues to discuss new features. Pull requests for new features will be rejected,
so we recommend forking the repository and making changes in your fork for your use case.
================================================
FILE: .gitignore
================================================
\#*
.\#*
================================================
FILE: .whitesource
================================================
{
"settingsInheritedFrom": "VividCortex/whitesource-config@master"
}
================================================
FILE: LICENSE
================================================
Copyright (c) 2013 VividCortex
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# gohistogram - Histograms in Go

This package provides [Streaming Approximate Histograms](https://vividcortex.com/blog/2013/07/08/streaming-approximate-histograms/)
for efficient quantile approximations.
The histograms in this package are based on the algorithms found in
Ben-Haim & Yom-Tov's *A Streaming Parallel Decision Tree Algorithm*
([PDF](http://jmlr.org/papers/volume11/ben-haim10a/ben-haim10a.pdf)).
Histogram bins do not have a preset size. As values stream into
the histogram, bins are dynamically added and merged.
Another implementation can be found in the Apache Hive project (see
[NumericHistogram](http://hive.apache.org/docs/r0.11.0/api/org/apache/hadoop/hive/ql/udf/generic/NumericHistogram.html)).
An example:

The accurate method of calculating quantiles (like percentiles) requires
data to be sorted. Streaming histograms make it possible to approximate
quantiles without sorting (or even individually storing) values.
NumericHistogram is the more basic implementation of a streaming
histogram. WeightedHistogram implements bin values as exponentially-weighted
moving averages.
A maximum bin size is passed as an argument to the constructor methods. A
larger bin size yields more accurate approximations at the cost of increased
memory utilization and performance.
A picture of kittens:

## Getting started
### Using in your own code
$ go get github.com/VividCortex/gohistogram
```go
import "github.com/VividCortex/gohistogram"
```
### Running tests and making modifications
Get the code into your workspace:
$ cd $GOPATH
$ git clone git@github.com:VividCortex/gohistogram.git ./src/github.com/VividCortex/gohistogram
You can run the tests now:
$ cd src/github.com/VividCortex/gohistogram
$ go test .
## API Documentation
Full source documentation can be found [here][godoc].
[godoc]: http://godoc.org/github.com/VividCortex/gohistogram
## Contributing
We only accept pull requests for minor fixes or improvements. This includes:
* Small bug fixes
* Typos
* Documentation or comments
Please open issues to discuss new features. Pull requests for new features will be rejected,
so we recommend forking the repository and making changes in your fork for your use case.
## License
Copyright (c) 2013 VividCortex
Released under MIT License. Check `LICENSE` file for details.
================================================
FILE: histogram.go
================================================
package gohistogram
// Copyright (c) 2013 VividCortex, Inc. All rights reserved.
// Please see the LICENSE file for applicable license terms.
// Histogram is the interface that wraps the Add and Quantile methods.
type Histogram interface {
// Add adds a new value, n, to the histogram. Trimming is done
// automatically.
Add(n float64)
// Quantile returns an approximation.
Quantile(n float64) (q float64)
// String returns a string reprentation of the histogram,
// which is useful for printing to a terminal.
String() (str string)
}
type bin struct {
value float64
count float64
}
================================================
FILE: histogram_test.go
================================================
package gohistogram
// Copyright (c) 2013 VividCortex, Inc. All rights reserved.
// Please see the LICENSE file for applicable license terms.
import (
"math"
"testing"
)
func approx(x, y float64) bool {
return math.Abs(x-y) < 0.2
}
func TestHistogram(t *testing.T) {
h := NewHistogram(160)
for _, val := range testData {
h.Add(float64(val))
}
if h.Count() != 14999 {
t.Errorf("Expected h.Count() to be 14999, got %v", h.Count())
}
if firstQ := h.Quantile(0.25); !approx(firstQ, 14) {
t.Errorf("Expected 25th percentile to be %v, got %v", 14, firstQ)
}
if median := h.Quantile(0.5); !approx(median, 18) {
t.Errorf("Expected 50th percentile to be %v, got %v", 18, median)
}
if thirdQ := h.Quantile(0.75); !approx(thirdQ, 22) {
t.Errorf("Expected 75th percentile to be %v, got %v", 22, thirdQ)
}
if cdf := h.CDF(18); !approx(cdf, 0.5) {
t.Errorf("Expected CDF(median) to be %v, got %v", 0.5, cdf)
}
if cdf := h.CDF(22); !approx(cdf, 0.75) {
t.Errorf("Expected CDF(3rd quartile) to be %v, got %v", 0.75, cdf)
}
}
func TestWeightedHistogram(t *testing.T) {
h := NewWeightedHistogram(160, 1)
for _, val := range testData {
h.Add(float64(val))
}
if firstQ := h.Quantile(0.25); !approx(firstQ, 14) {
t.Errorf("Expected 25th percentile to be %v, got %v", 14, firstQ)
}
if median := h.Quantile(0.5); !approx(median, 18) {
t.Errorf("Expected 50th percentile to be %v, got %v", 18, median)
}
if thirdQ := h.Quantile(0.75); !approx(thirdQ, 22) {
t.Errorf("Expected 75th percentile to be %v, got %v", 22, thirdQ)
}
if cdf := h.CDF(18); !approx(cdf, 0.5) {
t.Errorf("Expected CDF(median) to be %v, got %v", 0.5, cdf)
}
if cdf := h.CDF(22); !approx(cdf, 0.75) {
t.Errorf("Expected CDF(3rd quartile) to be %v, got %v", 0.75, cdf)
}
}
================================================
FILE: numerichistogram.go
================================================
package gohistogram
// Copyright (c) 2013 VividCortex, Inc. All rights reserved.
// Please see the LICENSE file for applicable license terms.
import (
"fmt"
)
type NumericHistogram struct {
bins []bin
maxbins int
total uint64
}
// NewHistogram returns a new NumericHistogram with a maximum of n bins.
//
// There is no "optimal" bin count, but somewhere between 20 and 80 bins
// should be sufficient.
func NewHistogram(n int) *NumericHistogram {
return &NumericHistogram{
bins: make([]bin, 0),
maxbins: n,
total: 0,
}
}
func (h *NumericHistogram) Add(n float64) {
defer h.trim()
h.total++
for i := range h.bins {
if h.bins[i].value == n {
h.bins[i].count++
return
}
if h.bins[i].value > n {
newbin := bin{value: n, count: 1}
head := append(make([]bin, 0), h.bins[0:i]...)
head = append(head, newbin)
tail := h.bins[i:]
h.bins = append(head, tail...)
return
}
}
h.bins = append(h.bins, bin{count: 1, value: n})
}
func (h *NumericHistogram) Quantile(q float64) float64 {
count := q * float64(h.total)
for i := range h.bins {
count -= float64(h.bins[i].count)
if count <= 0 {
return h.bins[i].value
}
}
return -1
}
// CDF returns the value of the cumulative distribution function
// at x
func (h *NumericHistogram) CDF(x float64) float64 {
count := 0.0
for i := range h.bins {
if h.bins[i].value <= x {
count += float64(h.bins[i].count)
}
}
return count / float64(h.total)
}
// Mean returns the sample mean of the distribution
func (h *NumericHistogram) Mean() float64 {
if h.total == 0 {
return 0
}
sum := 0.0
for i := range h.bins {
sum += h.bins[i].value * h.bins[i].count
}
return sum / float64(h.total)
}
// Variance returns the variance of the distribution
func (h *NumericHistogram) Variance() float64 {
if h.total == 0 {
return 0
}
sum := 0.0
mean := h.Mean()
for i := range h.bins {
sum += (h.bins[i].count * (h.bins[i].value - mean) * (h.bins[i].value - mean))
}
return sum / float64(h.total)
}
func (h *NumericHistogram) Count() float64 {
return float64(h.total)
}
// trim merges adjacent bins to decrease the bin count to the maximum value
func (h *NumericHistogram) trim() {
for len(h.bins) > h.maxbins {
// Find closest bins in terms of value
minDelta := 1e99
minDeltaIndex := 0
for i := range h.bins {
if i == 0 {
continue
}
if delta := h.bins[i].value - h.bins[i-1].value; delta < minDelta {
minDelta = delta
minDeltaIndex = i
}
}
// We need to merge bins minDeltaIndex-1 and minDeltaIndex
totalCount := h.bins[minDeltaIndex-1].count + h.bins[minDeltaIndex].count
mergedbin := bin{
value: (h.bins[minDeltaIndex-1].value*
h.bins[minDeltaIndex-1].count +
h.bins[minDeltaIndex].value*
h.bins[minDeltaIndex].count) /
totalCount, // weighted average
count: totalCount, // summed heights
}
head := append(make([]bin, 0), h.bins[0:minDeltaIndex-1]...)
tail := append([]bin{mergedbin}, h.bins[minDeltaIndex+1:]...)
h.bins = append(head, tail...)
}
}
// String returns a string reprentation of the histogram,
// which is useful for printing to a terminal.
func (h *NumericHistogram) String() (str string) {
str += fmt.Sprintln("Total:", h.total)
for i := range h.bins {
var bar string
for j := 0; j < int(float64(h.bins[i].count)/float64(h.total)*200); j++ {
bar += "."
}
str += fmt.Sprintln(h.bins[i].value, "\t", bar)
}
return
}
================================================
FILE: sample_data_test.go
================================================
package gohistogram
// Copyright (c) 2013 VividCortex, Inc. All rights reserved.
// Please see the LICENSE file for applicable license terms.
var testData = []int{
8,
13,
17,
16,
15,
14,
14,
20,
16,
54,
34,
19,
15,
19,
17,
14,
15,
10,
10,
9,
10,
12,
20,
17,
12,
10,
15,
15,
11,
13,
16,
11,
17,
17,
18,
20,
25,
16,
19,
31,
83,
57,
10,
12,
13,
19,
10,
39,
20,
10,
11,
3,
13,
14,
15,
11,
12,
17,
16,
13,
15,
15,
12,
16,
13,
25,
14,
11,
26,
24,
37,
14,
15,
10,
22,
16,
19,
33,
11,
10,
31,
18,
13,
18,
11,
15,
11,
19,
13,
14,
12,
9,
16,
24,
14,
19,
16,
12,
37,
17,
25,
15,
15,
13,
8,
18,
26,
34,
9,
11,
12,
29,
16,
16,
8,
10,
9,
22,
17,
18,
19,
11,
15,
13,
16,
28,
17,
19,
111,
117,
32,
27,
14,
13,
9,
14,
22,
31,
18,
17,
15,
16,
17,
11,
11,
4,
13,
17,
18,
17,
11,
12,
16,
16,
14,
19,
18,
54,
18,
15,
27,
12,
10,
11,
17,
24,
16,
17,
12,
20,
22,
9,
17,
19,
30,
16,
10,
12,
13,
21,
14,
15,
20,
21,
16,
20,
9,
55,
40,
12,
17,
18,
20,
17,
14,
35,
16,
21,
26,
17,
16,
9,
11,
9,
9,
17,
11,
17,
10,
12,
12,
12,
20,
14,
26,
19,
36,
21,
22,
12,
12,
13,
14,
14,
14,
20,
16,
11,
18,
13,
13,
16,
14,
11,
12,
13,
13,
13,
15,
14,
16,
17,
14,
11,
17,
14,
29,
16,
38,
17,
11,
13,
17,
17,
28,
15,
14,
13,
19,
15,
11,
15,
11,
10,
16,
15,
13,
14,
15,
11,
16,
16,
17,
9,
8,
31,
100,
146,
76,
12,
12,
12,
14,
9,
34,
11,
17,
24,
16,
17,
15,
15,
21,
14,
18,
14,
9,
22,
14,
19,
18,
12,
16,
7,
21,
31,
19,
11,
18,
15,
13,
14,
12,
27,
17,
15,
19,
20,
23,
21,
8,
23,
12,
16,
14,
15,
21,
12,
9,
17,
20,
17,
13,
25,
12,
82,
48,
18,
20,
24,
14,
11,
15,
26,
13,
17,
23,
14,
32,
20,
18,
11,
16,
12,
15,
17,
11,
14,
19,
16,
14,
15,
13,
17,
37,
99,
30,
18,
18,
12,
9,
15,
15,
29,
10,
16,
10,
17,
15,
15,
9,
9,
14,
8,
17,
10,
21,
22,
12,
15,
18,
12,
11,
15,
48,
17,
29,
11,
18,
21,
11,
8,
13,
18,
16,
11,
13,
21,
19,
12,
11,
15,
18,
15,
17,
16,
13,
17,
17,
8,
8,
9,
8,
17,
27,
14,
14,
11,
14,
19,
17,
24,
13,
15,
9,
12,
17,
14,
18,
12,
7,
10,
21,
18,
13,
13,
11,
27,
17,
16,
23,
15,
15,
72,
117,
76,
26,
33,
11,
13,
11,
29,
75,
16,
15,
15,
18,
13,
11,
11,
17,
4,
13,
17,
12,
9,
16,
28,
12,
14,
11,
12,
19,
70,
17,
13,
13,
19,
14,
11,
21,
27,
9,
21,
17,
17,
12,
12,
14,
10,
16,
16,
13,
13,
17,
14,
8,
12,
14,
11,
20,
14,
29,
32,
48,
16,
12,
16,
23,
11,
17,
31,
17,
16,
12,
14,
22,
10,
12,
7,
20,
9,
18,
14,
17,
10,
22,
17,
20,
16,
14,
15,
28,
18,
18,
18,
15,
13,
16,
17,
38,
14,
6,
13,
11,
23,
17,
16,
9,
13,
17,
13,
15,
15,
20,
28,
18,
22,
18,
7,
15,
57,
77,
30,
15,
15,
16,
13,
19,
14,
24,
11,
21,
17,
17,
11,
12,
20,
17,
10,
10,
13,
17,
14,
10,
13,
11,
20,
9,
11,
12,
44,
66,
30,
13,
18,
15,
13,
10,
28,
14,
13,
11,
15,
12,
13,
14,
15,
12,
10,
12,
11,
13,
22,
17,
17,
15,
14,
13,
22,
17,
50,
18,
13,
13,
14,
14,
10,
16,
18,
11,
21,
13,
23,
14,
25,
11,
13,
8,
7,
16,
14,
19,
11,
10,
18,
18,
8,
20,
14,
18,
20,
13,
20,
20,
11,
12,
14,
31,
13,
11,
14,
8,
14,
9,
13,
14,
22,
20,
9,
21,
7,
17,
12,
13,
20,
18,
15,
12,
23,
33,
46,
23,
15,
14,
14,
17,
13,
19,
20,
13,
19,
15,
10,
3,
14,
15,
18,
15,
16,
11,
22,
13,
18,
18,
14,
20,
13,
12,
26,
11,
11,
12,
12,
18,
11,
9,
26,
17,
18,
15,
12,
14,
13,
13,
11,
14,
17,
15,
7,
17,
19,
10,
13,
11,
15,
18,
22,
19,
18,
20,
41,
16,
16,
18,
20,
18,
37,
17,
15,
30,
16,
16,
32,
21,
12,
20,
17,
19,
13,
10,
17,
9,
18,
21,
16,
19,
12,
45,
44,
24,
18,
17,
14,
13,
17,
18,
24,
7,
26,
20,
17,
14,
21,
15,
16,
21,
14,
14,
11,
9,
15,
18,
11,
17,
16,
16,
19,
30,
15,
18,
11,
15,
13,
13,
13,
20,
18,
8,
14,
10,
15,
8,
17,
17,
17,
8,
11,
18,
16,
10,
16,
15,
16,
12,
15,
10,
31,
25,
25,
13,
15,
12,
16,
20,
20,
19,
22,
15,
14,
20,
12,
14,
14,
11,
11,
10,
18,
14,
15,
19,
10,
13,
24,
12,
22,
18,
80,
67,
85,
14,
15,
12,
18,
22,
9,
17,
9,
10,
9,
14,
15,
13,
11,
15,
21,
12,
20,
18,
22,
20,
14,
18,
16,
15,
14,
17,
21,
21,
17,
13,
9,
19,
12,
10,
34,
13,
15,
20,
11,
23,
17,
11,
15,
12,
15,
15,
11,
19,
20,
14,
14,
21,
13,
17,
19,
20,
60,
22,
15,
12,
12,
12,
10,
12,
20,
10,
13,
11,
21,
15,
20,
16,
9,
11,
17,
22,
7,
15,
18,
12,
17,
19,
14,
17,
15,
23,
23,
24,
15,
18,
16,
15,
21,
31,
17,
21,
13,
13,
10,
20,
20,
21,
15,
19,
16,
13,
12,
16,
14,
10,
15,
17,
24,
16,
63,
143,
109,
66,
16,
15,
17,
19,
15,
14,
16,
12,
18,
13,
18,
21,
13,
12,
16,
13,
19,
13,
8,
17,
11,
6,
13,
11,
13,
20,
36,
23,
20,
20,
18,
19,
16,
16,
19,
10,
12,
17,
12,
26,
14,
10,
17,
12,
8,
13,
10,
13,
15,
15,
22,
15,
22,
18,
16,
36,
49,
16,
20,
12,
10,
16,
14,
21,
15,
10,
14,
13,
25,
18,
17,
14,
18,
23,
18,
24,
14,
15,
18,
28,
16,
18,
23,
18,
21,
76,
34,
17,
14,
22,
22,
21,
15,
34,
16,
31,
24,
22,
7,
18,
13,
18,
21,
14,
18,
17,
18,
13,
15,
16,
21,
16,
23,
20,
81,
124,
32,
21,
17,
14,
16,
20,
21,
22,
19,
18,
17,
17,
22,
18,
11,
20,
12,
22,
20,
30,
16,
13,
19,
18,
14,
13,
56,
21,
17,
18,
13,
21,
26,
15,
20,
15,
17,
15,
13,
12,
17,
15,
16,
19,
12,
15,
15,
12,
20,
17,
19,
23,
17,
20,
25,
24,
24,
26,
29,
25,
21,
13,
24,
19,
78,
22,
22,
14,
24,
22,
18,
15,
16,
18,
7,
15,
16,
13,
11,
35,
21,
19,
16,
19,
16,
64,
38,
16,
16,
21,
18,
16,
13,
9,
11,
16,
15,
14,
13,
25,
18,
18,
9,
31,
13,
16,
13,
19,
18,
25,
9,
21,
15,
20,
16,
41,
62,
58,
11,
23,
13,
17,
16,
34,
14,
15,
20,
14,
20,
12,
17,
13,
24,
17,
18,
22,
17,
19,
9,
15,
19,
17,
10,
17,
34,
43,
32,
14,
14,
12,
12,
11,
16,
23,
14,
13,
20,
10,
15,
20,
19,
19,
16,
17,
22,
16,
25,
19,
17,
18,
16,
18,
17,
13,
132,
202,
174,
25,
13,
20,
24,
12,
33,
20,
13,
16,
19,
17,
13,
26,
5,
11,
13,
16,
22,
13,
19,
15,
22,
17,
22,
18,
13,
54,
87,
51,
13,
13,
14,
17,
10,
14,
32,
22,
16,
13,
19,
16,
19,
18,
21,
16,
22,
21,
18,
19,
15,
24,
13,
18,
16,
28,
19,
38,
16,
18,
17,
17,
19,
11,
16,
22,
18,
18,
16,
15,
15,
19,
18,
19,
14,
14,
13,
17,
14,
19,
24,
16,
20,
22,
9,
18,
25,
26,
26,
14,
13,
16,
13,
13,
22,
50,
17,
24,
16,
24,
19,
15,
19,
18,
18,
18,
18,
19,
8,
12,
9,
21,
18,
21,
19,
4,
39,
32,
22,
10,
22,
12,
20,
15,
13,
19,
15,
18,
25,
16,
22,
16,
18,
10,
16,
19,
16,
14,
10,
15,
16,
16,
15,
14,
9,
18,
43,
12,
21,
11,
18,
13,
15,
16,
16,
15,
20,
23,
17,
18,
19,
15,
13,
15,
15,
17,
15,
15,
19,
15,
13,
23,
22,
17,
9,
31,
46,
30,
30,
16,
18,
15,
10,
21,
17,
15,
15,
10,
14,
13,
12,
23,
18,
19,
21,
17,
15,
13,
13,
15,
22,
17,
13,
16,
20,
47,
16,
23,
16,
14,
11,
14,
18,
23,
12,
25,
17,
23,
16,
16,
19,
13,
14,
10,
11,
16,
28,
23,
19,
19,
11,
15,
24,
23,
31,
42,
18,
18,
11,
18,
14,
14,
22,
21,
10,
13,
17,
15,
23,
16,
21,
15,
11,
23,
15,
18,
19,
11,
17,
24,
16,
22,
18,
11,
84,
159,
80,
12,
10,
20,
23,
17,
24,
55,
12,
20,
7,
16,
21,
12,
18,
22,
18,
18,
12,
16,
20,
13,
19,
26,
18,
22,
25,
23,
33,
28,
14,
21,
10,
24,
25,
15,
42,
18,
17,
24,
37,
16,
10,
11,
13,
14,
24,
19,
21,
22,
17,
32,
15,
17,
26,
18,
20,
43,
49,
22,
18,
20,
21,
21,
18,
27,
18,
17,
18,
12,
20,
17,
20,
17,
12,
15,
24,
26,
16,
15,
15,
27,
17,
12,
24,
20,
16,
64,
32,
18,
21,
37,
24,
22,
19,
29,
22,
18,
19,
15,
14,
14,
12,
14,
20,
16,
16,
21,
10,
16,
15,
19,
22,
20,
10,
13,
47,
16,
27,
15,
21,
14,
16,
20,
26,
15,
17,
19,
18,
21,
23,
13,
15,
10,
15,
11,
18,
19,
22,
15,
18,
12,
24,
30,
21,
18,
18,
20,
16,
15,
11,
10,
14,
22,
15,
20,
12,
17,
14,
11,
20,
27,
19,
14,
17,
13,
15,
14,
10,
12,
17,
18,
11,
21,
16,
35,
30,
42,
31,
34,
19,
24,
24,
21,
21,
23,
19,
17,
24,
25,
16,
19,
20,
19,
15,
18,
21,
21,
18,
27,
26,
34,
26,
23,
26,
130,
200,
165,
90,
23,
19,
31,
13,
28,
16,
22,
27,
16,
21,
22,
24,
17,
11,
13,
23,
23,
26,
22,
22,
17,
21,
19,
26,
20,
41,
107,
112,
101,
34,
38,
33,
34,
37,
76,
31,
29,
20,
44,
23,
29,
24,
25,
25,
27,
23,
26,
35,
28,
41,
24,
24,
30,
36,
29,
65,
43,
51,
29,
26,
20,
28,
21,
29,
22,
20,
18,
16,
15,
14,
18,
21,
21,
15,
21,
20,
18,
18,
17,
19,
20,
19,
19,
13,
34,
50,
29,
34,
34,
31,
33,
40,
39,
43,
37,
31,
40,
39,
41,
39,
41,
48,
39,
42,
44,
36,
43,
39,
44,
41,
37,
36,
37,
39,
57,
42,
45,
31,
25,
28,
27,
19,
27,
24,
31,
23,
24,
22,
24,
23,
16,
14,
15,
15,
15,
17,
13,
17,
16,
15,
19,
16,
13,
18,
46,
21,
24,
24,
28,
29,
32,
40,
56,
28,
33,
35,
37,
29,
31,
34,
37,
34,
36,
34,
36,
30,
42,
36,
43,
41,
47,
50,
43,
70,
153,
78,
42,
35,
34,
41,
26,
31,
54,
16,
25,
27,
19,
25,
15,
25,
17,
15,
19,
19,
24,
30,
28,
12,
23,
22,
34,
22,
18,
64,
36,
64,
55,
37,
48,
47,
56,
77,
49,
55,
47,
54,
55,
51,
57,
45,
55,
49,
46,
46,
39,
45,
45,
51,
50,
53,
45,
48,
65,
78,
56,
48,
43,
37,
27,
28,
23,
34,
26,
25,
22,
26,
27,
24,
23,
15,
21,
22,
23,
18,
17,
18,
14,
19,
15,
18,
13,
19,
76,
143,
136,
34,
28,
39,
41,
53,
55,
53,
56,
52,
62,
56,
55,
52,
57,
70,
53,
58,
59,
55,
65,
67,
57,
57,
56,
59,
55,
54,
68,
60,
62,
45,
49,
51,
29,
32,
46,
22,
20,
27,
24,
29,
25,
20,
27,
23,
16,
22,
19,
24,
19,
24,
22,
18,
29,
32,
24,
44,
37,
51,
29,
32,
40,
48,
50,
62,
106,
46,
65,
50,
41,
62,
67,
48,
53,
65,
49,
61,
64,
65,
46,
55,
55,
68,
53,
51,
59,
132,
49,
59,
74,
69,
51,
52,
69,
80,
76,
60,
61,
50,
41,
46,
44,
29,
30,
32,
38,
18,
33,
28,
21,
30,
25,
29,
27,
25,
41,
104,
47,
26,
20,
17,
25,
27,
21,
32,
23,
24,
29,
23,
23,
30,
26,
26,
23,
28,
28,
29,
19,
22,
26,
25,
18,
23,
23,
22,
29,
78,
35,
30,
23,
26,
25,
23,
33,
20,
21,
22,
27,
27,
24,
24,
23,
21,
33,
22,
21,
25,
17,
31,
32,
21,
25,
15,
23,
24,
102,
85,
27,
24,
21,
29,
25,
19,
26,
22,
16,
19,
29,
16,
23,
20,
21,
31,
22,
25,
25,
22,
17,
28,
28,
19,
22,
24,
20,
42,
53,
38,
19,
20,
19,
22,
20,
15,
25,
28,
33,
21,
26,
23,
37,
20,
25,
31,
22,
22,
31,
17,
27,
16,
20,
22,
18,
29,
26,
115,
95,
27,
25,
25,
16,
18,
18,
31,
12,
5,
23,
17,
10,
15,
11,
16,
23,
19,
30,
21,
19,
22,
22,
20,
19,
30,
18,
28,
24,
98,
119,
49,
17,
12,
17,
34,
21,
36,
21,
20,
18,
18,
15,
14,
19,
19,
16,
12,
25,
14,
13,
19,
14,
19,
13,
15,
20,
20,
42,
47,
33,
17,
20,
19,
18,
22,
17,
20,
15,
22,
20,
17,
26,
16,
21,
24,
19,
17,
22,
15,
26,
16,
26,
20,
16,
21,
18,
21,
32,
25,
23,
21,
21,
21,
22,
19,
31,
30,
20,
18,
15,
16,
38,
16,
24,
21,
19,
24,
24,
20,
34,
26,
22,
16,
27,
55,
143,
115,
19,
24,
19,
15,
25,
18,
42,
14,
18,
16,
27,
14,
18,
27,
23,
18,
15,
22,
15,
21,
13,
10,
15,
15,
18,
17,
11,
76,
162,
142,
28,
17,
23,
14,
19,
25,
21,
21,
20,
15,
23,
26,
15,
29,
13,
16,
21,
16,
18,
31,
9,
15,
15,
13,
18,
21,
27,
34,
22,
21,
14,
18,
23,
18,
14,
21,
20,
16,
19,
22,
25,
16,
19,
19,
20,
23,
21,
17,
9,
20,
16,
17,
20,
24,
18,
26,
76,
34,
40,
15,
21,
23,
13,
16,
15,
20,
22,
22,
15,
24,
17,
15,
14,
21,
8,
14,
26,
14,
14,
13,
13,
12,
16,
19,
22,
25,
40,
21,
17,
16,
12,
15,
17,
19,
26,
17,
17,
26,
19,
21,
16,
22,
16,
13,
21,
11,
24,
17,
24,
16,
21,
21,
22,
16,
16,
60,
28,
30,
17,
13,
17,
18,
18,
16,
21,
21,
25,
14,
26,
26,
22,
22,
15,
22,
24,
24,
36,
12,
21,
21,
29,
13,
13,
22,
20,
57,
15,
18,
16,
24,
17,
19,
12,
44,
19,
23,
16,
16,
21,
17,
23,
13,
34,
17,
27,
20,
16,
20,
23,
13,
22,
19,
21,
17,
30,
51,
46,
18,
14,
18,
14,
18,
20,
19,
22,
19,
26,
15,
17,
36,
20,
22,
18,
21,
22,
16,
21,
19,
18,
21,
16,
20,
15,
23,
74,
176,
216,
197,
66,
20,
15,
18,
20,
22,
16,
17,
18,
16,
24,
15,
21,
16,
22,
26,
17,
15,
25,
26,
24,
11,
17,
13,
18,
22,
109,
83,
54,
15,
17,
14,
31,
20,
33,
24,
13,
18,
16,
22,
14,
20,
17,
17,
13,
25,
16,
18,
16,
13,
20,
13,
20,
20,
19,
46,
50,
20,
19,
12,
17,
23,
25,
15,
30,
20,
14,
19,
14,
17,
21,
23,
11,
21,
19,
21,
17,
16,
19,
9,
13,
17,
15,
17,
13,
26,
17,
22,
12,
18,
14,
21,
17,
29,
17,
21,
26,
15,
22,
28,
16,
12,
27,
21,
19,
27,
23,
19,
21,
13,
18,
20,
31,
21,
43,
98,
53,
23,
19,
15,
16,
6,
16,
21,
13,
17,
20,
20,
21,
17,
17,
18,
17,
17,
21,
11,
15,
20,
20,
19,
18,
19,
26,
22,
100,
144,
27,
39,
23,
21,
18,
18,
31,
24,
24,
13,
18,
21,
23,
14,
15,
18,
23,
22,
13,
19,
19,
23,
17,
19,
15,
15,
28,
34,
110,
153,
142,
19,
18,
20,
16,
22,
54,
20,
21,
26,
24,
15,
23,
11,
20,
15,
12,
22,
21,
28,
22,
16,
17,
28,
20,
26,
18,
27,
36,
21,
13,
21,
15,
23,
19,
22,
23,
17,
18,
24,
19,
25,
18,
12,
13,
20,
7,
15,
18,
15,
14,
20,
18,
15,
16,
20,
24,
21,
27,
19,
28,
32,
24,
15,
15,
57,
29,
20,
16,
21,
16,
23,
21,
17,
20,
17,
23,
18,
17,
20,
20,
27,
22,
17,
15,
16,
69,
74,
52,
49,
27,
21,
20,
15,
18,
21,
17,
25,
15,
21,
19,
17,
19,
16,
22,
24,
23,
20,
22,
16,
23,
18,
26,
12,
19,
18,
36,
20,
26,
14,
21,
30,
16,
20,
25,
20,
20,
23,
20,
14,
20,
21,
13,
24,
16,
21,
26,
21,
19,
15,
14,
17,
17,
17,
26,
17,
61,
29,
20,
11,
16,
18,
21,
26,
18,
18,
19,
24,
30,
23,
19,
23,
17,
21,
19,
12,
14,
13,
14,
17,
19,
14,
17,
23,
27,
100,
29,
16,
20,
22,
24,
13,
16,
23,
19,
16,
21,
12,
16,
19,
22,
17,
13,
15,
19,
21,
24,
16,
31,
32,
22,
15,
16,
18,
42,
83,
31,
22,
22,
46,
21,
17,
15,
24,
17,
22,
20,
23,
28,
23,
21,
16,
27,
23,
26,
23,
25,
17,
23,
19,
16,
17,
16,
17,
45,
23,
18,
19,
22,
18,
21,
20,
45,
25,
19,
27,
30,
19,
20,
17,
15,
10,
22,
23,
15,
21,
16,
23,
20,
20,
17,
19,
13,
48,
41,
27,
13,
20,
13,
15,
22,
15,
17,
19,
13,
22,
20,
18,
17,
19,
21,
21,
21,
27,
12,
21,
9,
15,
18,
29,
23,
17,
15,
27,
20,
19,
15,
17,
20,
16,
21,
26,
12,
25,
26,
16,
18,
17,
24,
19,
14,
10,
28,
19,
22,
24,
13,
18,
19,
18,
17,
22,
28,
43,
24,
18,
17,
17,
17,
16,
15,
18,
20,
23,
26,
17,
20,
15,
15,
12,
15,
21,
17,
14,
12,
28,
17,
14,
17,
26,
18,
14,
64,
20,
13,
15,
13,
22,
18,
30,
31,
8,
17,
21,
23,
14,
17,
12,
18,
18,
18,
19,
15,
9,
23,
20,
19,
19,
23,
18,
19,
72,
27,
21,
21,
19,
20,
19,
21,
10,
26,
16,
17,
19,
16,
19,
24,
17,
22,
20,
15,
14,
13,
22,
14,
15,
18,
18,
18,
18,
17,
46,
32,
11,
21,
19,
13,
18,
26,
28,
21,
25,
25,
16,
16,
30,
35,
13,
17,
18,
26,
15,
27,
23,
25,
19,
20,
19,
15,
19,
48,
38,
32,
17,
17,
20,
18,
25,
24,
35,
18,
20,
14,
22,
19,
26,
21,
21,
17,
25,
20,
26,
23,
18,
15,
26,
23,
19,
20,
14,
38,
44,
36,
24,
21,
31,
23,
22,
43,
23,
18,
21,
20,
22,
44,
17,
19,
23,
20,
30,
17,
21,
24,
22,
35,
25,
20,
21,
22,
29,
93,
31,
25,
32,
24,
31,
25,
12,
43,
22,
32,
37,
28,
19,
20,
19,
23,
31,
18,
21,
18,
35,
21,
27,
23,
22,
28,
31,
27,
49,
34,
27,
25,
27,
16,
17,
28,
26,
55,
25,
22,
24,
19,
31,
19,
21,
20,
18,
28,
28,
20,
31,
17,
22,
20,
17,
30,
17,
29,
47,
35,
55,
26,
28,
19,
26,
22,
55,
24,
25,
25,
31,
27,
24,
26,
20,
20,
17,
19,
23,
13,
24,
22,
19,
17,
17,
20,
18,
113,
51,
25,
17,
18,
27,
21,
23,
27,
28,
27,
19,
29,
31,
24,
31,
15,
17,
27,
20,
22,
23,
17,
25,
24,
30,
19,
17,
26,
71,
59,
30,
24,
19,
28,
24,
15,
17,
17,
18,
22,
20,
19,
13,
19,
21,
17,
22,
15,
15,
16,
23,
18,
20,
11,
16,
17,
20,
24,
76,
42,
51,
17,
21,
16,
8,
15,
46,
13,
21,
19,
22,
14,
19,
18,
18,
23,
18,
17,
22,
20,
21,
14,
16,
12,
20,
16,
14,
29,
90,
17,
18,
17,
15,
21,
18,
19,
24,
19,
19,
15,
16,
19,
18,
25,
17,
17,
16,
21,
21,
19,
12,
19,
19,
21,
22,
20,
14,
33,
24,
17,
15,
20,
25,
17,
24,
26,
27,
21,
14,
20,
26,
30,
13,
19,
22,
16,
19,
17,
19,
26,
15,
17,
20,
19,
20,
20,
33,
15,
24,
14,
18,
20,
20,
24,
18,
39,
17,
19,
19,
17,
20,
18,
19,
16,
22,
15,
21,
17,
10,
19,
19,
27,
15,
13,
15,
19,
37,
52,
14,
17,
17,
18,
19,
19,
27,
13,
14,
15,
15,
19,
14,
15,
11,
15,
18,
20,
18,
9,
24,
18,
21,
18,
11,
14,
16,
13,
82,
27,
51,
24,
14,
19,
27,
12,
16,
13,
16,
21,
11,
18,
18,
21,
21,
12,
16,
12,
13,
13,
28,
10,
12,
15,
23,
11,
18,
24,
68,
27,
21,
15,
17,
15,
14,
19,
39,
19,
8,
20,
21,
18,
10,
15,
20,
11,
14,
19,
11,
15,
23,
28,
16,
17,
11,
22,
18,
67,
125,
115,
73,
24,
8,
19,
15,
16,
16,
19,
18,
14,
20,
21,
20,
14,
16,
11,
16,
20,
11,
12,
11,
17,
22,
9,
14,
15,
20,
78,
43,
18,
15,
17,
13,
19,
13,
21,
13,
11,
15,
17,
11,
12,
12,
20,
15,
14,
11,
22,
10,
21,
15,
13,
14,
11,
20,
14,
43,
28,
34,
14,
13,
11,
16,
16,
13,
20,
14,
13,
16,
22,
13,
15,
19,
19,
21,
22,
20,
21,
18,
21,
14,
21,
19,
25,
18,
19,
46,
16,
14,
15,
13,
20,
14,
17,
22,
14,
18,
19,
14,
17,
15,
13,
17,
15,
16,
20,
11,
19,
18,
19,
8,
13,
14,
17,
11,
25,
59,
21,
18,
17,
15,
11,
11,
12,
18,
19,
10,
9,
14,
18,
17,
15,
26,
18,
13,
13,
11,
20,
19,
14,
10,
15,
17,
15,
14,
69,
27,
16,
21,
16,
17,
17,
19,
18,
15,
8,
15,
12,
11,
18,
12,
18,
11,
18,
13,
21,
10,
25,
21,
21,
10,
11,
18,
15,
21,
47,
37,
54,
13,
17,
18,
16,
15,
40,
13,
14,
17,
18,
17,
15,
17,
14,
25,
18,
23,
13,
20,
23,
17,
17,
29,
11,
16,
15,
39,
28,
15,
9,
19,
15,
13,
12,
18,
17,
16,
16,
29,
16,
15,
17,
21,
14,
16,
13,
22,
24,
21,
9,
18,
14,
11,
15,
25,
21,
47,
15,
19,
18,
16,
19,
16,
12,
28,
19,
17,
25,
19,
12,
22,
15,
17,
20,
14,
17,
15,
19,
12,
13,
10,
17,
15,
20,
14,
40,
19,
23,
18,
19,
13,
8,
12,
19,
16,
22,
12,
13,
14,
22,
18,
15,
20,
13,
16,
12,
16,
27,
15,
12,
23,
18,
16,
15,
19,
24,
34,
15,
8,
12,
17,
16,
12,
31,
15,
17,
11,
12,
15,
9,
24,
20,
14,
9,
19,
13,
25,
19,
14,
17,
10,
19,
10,
15,
41,
42,
75,
9,
14,
14,
17,
14,
19,
16,
14,
15,
14,
12,
14,
17,
12,
15,
15,
17,
16,
18,
22,
22,
14,
18,
12,
11,
18,
13,
45,
43,
18,
12,
21,
17,
20,
15,
27,
10,
16,
24,
15,
23,
26,
12,
16,
18,
22,
21,
7,
17,
9,
11,
14,
14,
15,
21,
9,
23,
17,
19,
14,
13,
19,
13,
24,
17,
39,
15,
24,
20,
18,
14,
12,
14,
15,
14,
14,
15,
11,
11,
13,
17,
22,
19,
12,
22,
14,
23,
49,
21,
14,
11,
16,
13,
14,
44,
19,
19,
17,
12,
22,
20,
14,
13,
13,
14,
14,
21,
16,
18,
18,
13,
14,
9,
24,
20,
14,
120,
146,
92,
12,
15,
17,
12,
17,
38,
18,
18,
11,
15,
16,
12,
11,
14,
17,
14,
18,
13,
19,
13,
13,
16,
14,
19,
12,
15,
33,
75,
29,
26,
13,
17,
14,
14,
13,
13,
17,
18,
9,
19,
19,
10,
12,
14,
10,
21,
17,
14,
20,
17,
11,
17,
14,
20,
13,
21,
109,
129,
140,
21,
22,
11,
21,
11,
27,
16,
21,
14,
16,
17,
22,
16,
21,
23,
17,
20,
12,
19,
23,
8,
16,
20,
24,
19,
22,
31,
27,
40,
13,
15,
22,
16,
16,
18,
20,
19,
17,
22,
24,
18,
16,
14,
14,
18,
16,
20,
20,
19,
17,
14,
16,
13,
20,
20,
23,
27,
39,
33,
16,
5,
25,
22,
20,
32,
18,
18,
19,
13,
15,
23,
16,
26,
21,
16,
20,
21,
19,
21,
18,
16,
21,
25,
24,
17,
20,
39,
19,
20,
16,
14,
23,
25,
20,
37,
20,
20,
21,
19,
18,
24,
21,
20,
21,
20,
19,
22,
25,
17,
12,
14,
17,
19,
21,
15,
60,
66,
20,
18,
23,
30,
20,
20,
37,
15,
24,
18,
19,
24,
21,
18,
21,
17,
27,
20,
17,
18,
17,
20,
18,
25,
14,
21,
18,
24,
68,
54,
30,
24,
25,
20,
20,
21,
60,
21,
25,
29,
23,
21,
22,
26,
22,
19,
16,
19,
22,
36,
22,
22,
13,
19,
27,
21,
20,
87,
126,
54,
21,
23,
20,
28,
13,
33,
25,
21,
20,
13,
20,
19,
13,
23,
12,
25,
17,
14,
24,
17,
12,
13,
16,
24,
16,
19,
18,
66,
29,
23,
24,
15,
19,
17,
17,
22,
19,
17,
26,
28,
15,
17,
28,
20,
24,
18,
20,
24,
24,
15,
17,
19,
26,
19,
12,
24,
82,
60,
44,
25,
10,
18,
24,
22,
17,
27,
20,
25,
16,
20,
26,
20,
18,
28,
20,
15,
13,
18,
18,
18,
28,
17,
18,
24,
19,
24,
39,
67,
20,
20,
30,
18,
20,
24,
38,
28,
36,
18,
19,
21,
20,
23,
17,
22,
21,
25,
25,
20,
16,
28,
25,
21,
21,
26,
22,
39,
34,
25,
23,
26,
21,
17,
17,
20,
28,
25,
21,
25,
19,
35,
21,
20,
20,
24,
19,
24,
20,
21,
20,
18,
20,
17,
17,
22,
22,
60,
93,
68,
13,
15,
19,
26,
20,
37,
27,
19,
22,
21,
21,
19,
23,
21,
16,
18,
13,
23,
26,
21,
18,
18,
13,
12,
20,
13,
37,
47,
30,
20,
21,
11,
22,
23,
17,
26,
21,
9,
17,
19,
10,
22,
21,
13,
23,
15,
15,
21,
22,
16,
12,
12,
17,
14,
18,
14,
25,
21,
21,
13,
26,
17,
21,
23,
47,
19,
18,
26,
10,
21,
24,
11,
25,
22,
13,
18,
30,
28,
16,
21,
20,
13,
13,
17,
15,
71,
88,
45,
23,
21,
15,
16,
20,
19,
52,
22,
17,
18,
12,
21,
23,
12,
16,
19,
14,
10,
10,
17,
17,
13,
15,
21,
18,
12,
12,
37,
24,
20,
21,
21,
13,
19,
23,
25,
19,
17,
20,
21,
13,
15,
21,
19,
23,
14,
13,
12,
16,
18,
16,
20,
16,
19,
17,
15,
22,
60,
80,
112,
20,
24,
15,
11,
21,
21,
15,
24,
15,
24,
18,
18,
18,
16,
21,
18,
15,
10,
16,
19,
19,
23,
18,
15,
16,
20,
35,
137,
45,
14,
16,
25,
17,
14,
26,
16,
15,
19,
11,
15,
13,
18,
11,
14,
15,
10,
16,
15,
13,
15,
10,
10,
15,
13,
9,
24,
7,
17,
17,
14,
8,
11,
15,
9,
24,
14,
17,
11,
9,
12,
12,
17,
10,
18,
18,
20,
15,
12,
15,
19,
19,
16,
18,
13,
14,
27,
37,
14,
11,
15,
20,
11,
14,
18,
13,
15,
10,
10,
19,
14,
17,
12,
11,
18,
4,
19,
12,
11,
11,
14,
14,
5,
15,
15,
16,
24,
16,
18,
14,
13,
13,
19,
17,
35,
14,
16,
14,
11,
15,
17,
11,
18,
17,
12,
7,
21,
14,
20,
11,
15,
15,
14,
14,
18,
22,
72,
36,
10,
16,
17,
13,
17,
8,
20,
15,
11,
17,
16,
8,
14,
14,
14,
11,
11,
12,
14,
15,
16,
14,
16,
17,
13,
15,
16,
18,
95,
25,
11,
9,
12,
16,
14,
29,
17,
14,
17,
16,
7,
7,
7,
9,
16,
12,
9,
12,
14,
20,
10,
19,
11,
20,
10,
17,
17,
24,
13,
13,
13,
10,
16,
14,
18,
29,
25,
15,
10,
13,
10,
9,
23,
13,
19,
9,
21,
13,
18,
20,
21,
9,
17,
16,
16,
28,
36,
23,
37,
25,
17,
13,
22,
29,
10,
22,
6,
12,
28,
16,
18,
16,
15,
6,
13,
27,
20,
12,
15,
24,
14,
15,
20,
24,
13,
12,
40,
40,
25,
22,
23,
17,
20,
12,
24,
24,
18,
16,
15,
20,
31,
21,
15,
24,
22,
24,
24,
18,
29,
18,
20,
20,
30,
20,
22,
18,
47,
19,
24,
25,
19,
27,
20,
21,
25,
18,
19,
18,
18,
27,
15,
24,
27,
28,
16,
18,
15,
17,
18,
25,
16,
23,
25,
24,
16,
26,
64,
19,
27,
15,
18,
17,
19,
9,
27,
9,
36,
22,
17,
14,
22,
17,
21,
25,
16,
12,
16,
20,
19,
16,
20,
17,
22,
15,
20,
58,
71,
16,
13,
24,
16,
15,
18,
19,
24,
17,
18,
20,
12,
22,
17,
18,
16,
16,
19,
11,
19,
16,
15,
22,
24,
16,
17,
16,
14,
75,
69,
37,
14,
21,
17,
24,
20,
20,
19,
26,
29,
11,
17,
23,
17,
22,
15,
16,
18,
23,
21,
15,
17,
15,
18,
20,
21,
16,
21,
19,
27,
16,
16,
17,
25,
8,
16,
28,
15,
12,
16,
13,
18,
28,
14,
25,
15,
15,
16,
16,
19,
13,
19,
15,
18,
18,
15,
16,
43,
24,
15,
22,
20,
23,
22,
21,
26,
23,
17,
19,
10,
23,
28,
25,
19,
14,
17,
16,
14,
21,
15,
15,
20,
17,
19,
17,
17,
24,
118,
76,
31,
22,
15,
10,
22,
20,
41,
17,
17,
18,
20,
20,
18,
14,
24,
14,
16,
13,
16,
24,
20,
20,
13,
25,
16,
21,
20,
38,
25,
26,
20,
26,
24,
15,
10,
13,
26,
24,
21,
19,
22,
25,
16,
20,
21,
16,
17,
25,
19,
14,
17,
17,
24,
22,
20,
20,
17,
81,
144,
17,
24,
20,
20,
15,
26,
29,
20,
19,
15,
6,
14,
14,
13,
12,
16,
17,
22,
18,
15,
23,
26,
19,
24,
22,
16,
15,
22,
25,
27,
28,
17,
16,
20,
18,
17,
19,
16,
14,
9,
12,
20,
20,
12,
28,
16,
16,
10,
19,
26,
21,
12,
27,
19,
24,
18,
17,
43,
18,
23,
13,
20,
15,
15,
17,
15,
21,
20,
23,
13,
18,
14,
16,
19,
13,
13,
11,
16,
15,
18,
22,
5,
16,
21,
14,
25,
19,
50,
27,
21,
23,
17,
25,
12,
19,
33,
19,
20,
22,
16,
22,
19,
18,
12,
21,
26,
15,
13,
16,
20,
23,
18,
19,
22,
12,
15,
28,
18,
35,
22,
19,
20,
22,
15,
21,
26,
19,
19,
17,
25,
19,
25,
25,
15,
20,
25,
16,
15,
11,
15,
12,
19,
16,
14,
21,
18,
72,
96,
21,
20,
6,
16,
22,
24,
12,
19,
18,
21,
20,
19,
17,
20,
28,
22,
27,
28,
25,
19,
23,
24,
22,
23,
17,
22,
17,
21,
115,
176,
182,
110,
18,
20,
15,
17,
48,
26,
19,
14,
22,
20,
17,
21,
27,
19,
18,
19,
27,
18,
25,
12,
21,
26,
19,
18,
22,
47,
120,
82,
25,
22,
19,
17,
16,
20,
59,
15,
22,
24,
6,
27,
24,
34,
30,
18,
27,
25,
16,
19,
24,
31,
20,
22,
19,
21,
12,
46,
27,
47,
18,
16,
12,
20,
23,
25,
20,
12,
24,
19,
29,
16,
17,
24,
22,
22,
13,
24,
18,
27,
23,
26,
8,
22,
23,
26,
31,
102,
73,
23,
13,
24,
28,
20,
19,
43,
16,
17,
21,
24,
22,
34,
23,
21,
21,
18,
15,
10,
19,
24,
23,
21,
18,
22,
22,
17,
34,
20,
36,
20,
22,
19,
19,
17,
19,
15,
18,
14,
18,
24,
23,
23,
11,
22,
20,
18,
26,
24,
16,
19,
20,
22,
18,
16,
22,
18,
75,
19,
31,
20,
15,
28,
22,
21,
64,
13,
24,
21,
15,
18,
22,
12,
21,
18,
20,
21,
23,
25,
22,
10,
16,
23,
18,
24,
10,
62,
46,
24,
16,
10,
18,
17,
26,
20,
27,
15,
20,
23,
18,
27,
19,
18,
17,
19,
16,
25,
25,
30,
19,
13,
20,
15,
19,
18,
28,
48,
25,
19,
17,
19,
17,
17,
17,
43,
24,
22,
24,
18,
24,
21,
23,
12,
22,
21,
20,
14,
14,
20,
19,
28,
14,
16,
17,
24,
29,
135,
108,
24,
21,
20,
22,
13,
21,
45,
31,
23,
22,
15,
18,
11,
23,
19,
15,
21,
15,
13,
16,
27,
18,
20,
13,
16,
20,
16,
51,
33,
17,
18,
25,
18,
12,
21,
13,
20,
15,
20,
15,
18,
23,
21,
20,
19,
11,
17,
19,
13,
17,
20,
15,
16,
14,
21,
2,
15,
60,
5,
23,
22,
12,
18,
20,
16,
19,
24,
11,
20,
15,
22,
17,
19,
21,
25,
18,
20,
19,
13,
20,
20,
14,
21,
15,
22,
13,
37,
33,
45,
19,
23,
18,
18,
21,
20,
14,
19,
19,
17,
28,
21,
16,
22,
26,
24,
16,
17,
13,
21,
25,
20,
14,
18,
13,
17,
17,
68,
16,
27,
17,
13,
8,
14,
18,
28,
17,
22,
16,
15,
13,
14,
18,
13,
12,
19,
19,
16,
16,
24,
18,
11,
20,
14,
18,
16,
21,
16,
31,
13,
17,
18,
20,
17,
20,
20,
29,
16,
18,
14,
12,
17,
14,
13,
15,
12,
18,
18,
12,
18,
19,
23,
25,
12,
18,
13,
48,
21,
2,
15,
14,
23,
18,
11,
22,
17,
11,
19,
23,
24,
20,
15,
19,
22,
21,
17,
23,
19,
18,
23,
15,
21,
11,
18,
13,
20,
46,
25,
23,
29,
22,
21,
15,
20,
34,
16,
21,
21,
16,
18,
20,
26,
23,
20,
15,
22,
17,
17,
17,
18,
12,
19,
15,
17,
14,
29,
108,
37,
18,
25,
14,
23,
19,
23,
28,
18,
21,
20,
21,
25,
14,
19,
26,
18,
18,
28,
17,
17,
14,
23,
22,
17,
20,
16,
19,
55,
23,
29,
22,
22,
19,
22,
24,
30,
27,
17,
18,
19,
22,
16,
16,
16,
12,
16,
23,
19,
12,
26,
21,
20,
17,
18,
23,
22,
21,
94,
35,
23,
15,
20,
17,
23,
21,
19,
26,
19,
17,
22,
20,
22,
18,
9,
22,
19,
19,
19,
17,
19,
12,
21,
21,
12,
21,
23,
50,
54,
26,
20,
17,
19,
23,
23,
18,
11,
20,
10,
18,
17,
15,
18,
28,
16,
16,
16,
20,
27,
26,
22,
27,
21,
15,
23,
14,
28,
124,
95,
20,
20,
19,
23,
14,
24,
51,
19,
20,
27,
22,
18,
21,
17,
21,
15,
23,
16,
16,
14,
18,
12,
17,
19,
22,
16,
17,
33,
59,
34,
21,
15,
27,
22,
16,
26,
22,
14,
22,
11,
19,
12,
24,
15,
17,
20,
18,
22,
14,
20,
15,
20,
21,
24,
22,
17,
22,
25,
21,
25,
21,
17,
12,
21,
25,
33,
31,
33,
22,
22,
19,
17,
15,
19,
23,
22,
26,
18,
13,
21,
17,
25,
25,
24,
18,
22,
25,
75,
34,
25,
14,
24,
15,
18,
20,
28,
18,
18,
21,
26,
14,
12,
18,
25,
20,
22,
26,
20,
17,
22,
14,
19,
22,
22,
16,
24,
75,
102,
21,
12,
20,
16,
11,
23,
21,
20,
23,
14,
25,
28,
15,
20,
19,
15,
24,
21,
15,
22,
25,
17,
11,
17,
22,
19,
16,
18,
63,
45,
16,
20,
25,
18,
24,
22,
32,
19,
16,
21,
18,
17,
13,
17,
13,
21,
20,
22,
24,
18,
13,
24,
21,
18,
29,
19,
27,
34,
19,
29,
22,
19,
27,
30,
11,
20,
18,
19,
25,
17,
22,
19,
21,
12,
16,
23,
13,
15,
18,
14,
28,
17,
18,
16,
23,
29,
28,
79,
17,
33,
27,
25,
23,
13,
26,
26,
25,
25,
22,
17,
17,
32,
21,
15,
20,
18,
16,
16,
16,
15,
12,
16,
23,
24,
20,
29,
16,
46,
32,
18,
13,
22,
15,
18,
15,
5,
19,
17,
20,
14,
19,
22,
16,
17,
13,
18,
18,
16,
14,
23,
14,
13,
19,
20,
16,
15,
94,
53,
22,
14,
19,
20,
19,
25,
16,
58,
22,
26,
22,
25,
19,
15,
17,
20,
20,
23,
19,
11,
19,
17,
25,
18,
19,
13,
23,
25,
46,
23,
23,
19,
20,
20,
20,
15,
37,
14,
14,
15,
23,
17,
22,
19,
18,
21,
22,
18,
21,
17,
18,
16,
25,
11,
18,
15,
18,
47,
30,
36,
22,
24,
22,
19,
12,
18,
30,
13,
18,
21,
16,
18,
19,
14,
22,
20,
14,
19,
19,
27,
21,
17,
10,
18,
26,
18,
23,
80,
163,
74,
15,
17,
18,
17,
26,
59,
20,
19,
24,
21,
25,
23,
18,
17,
17,
16,
18,
20,
17,
22,
17,
20,
12,
21,
25,
20,
37,
105,
119,
15,
20,
24,
18,
23,
24,
63,
64,
36,
23,
20,
19,
14,
17,
13,
19,
19,
21,
15,
17,
13,
11,
18,
16,
21,
15,
18,
60,
32,
28,
22,
20,
15,
21,
20,
24,
15,
15,
21,
19,
20,
20,
14,
15,
17,
25,
16,
29,
19,
16,
19,
26,
14,
21,
17,
14,
22,
112,
34,
19,
15,
14,
17,
20,
15,
26,
19,
11,
15,
16,
28,
15,
18,
17,
23,
13,
10,
18,
14,
26,
19,
12,
15,
15,
21,
19,
37,
22,
22,
22,
20,
20,
17,
21,
34,
22,
18,
16,
13,
20,
16,
17,
18,
20,
14,
20,
21,
17,
14,
16,
17,
20,
20,
22,
19,
13,
66,
35,
24,
24,
19,
16,
18,
19,
30,
21,
22,
21,
23,
24,
18,
17,
24,
23,
17,
12,
17,
19,
20,
21,
16,
15,
25,
25,
16,
34,
40,
34,
23,
18,
15,
14,
18,
17,
65,
19,
24,
27,
18,
21,
26,
19,
23,
24,
22,
18,
22,
17,
21,
17,
21,
16,
14,
16,
17,
51,
19,
25,
14,
4,
17,
16,
17,
23,
18,
17,
19,
16,
17,
22,
22,
20,
22,
12,
15,
15,
10,
25,
13,
9,
11,
20,
18,
22,
21,
64,
32,
24,
22,
13,
20,
20,
18,
39,
20,
18,
18,
28,
13,
17,
20,
18,
19,
13,
16,
16,
21,
16,
18,
16,
22,
24,
22,
13,
57,
5,
46,
22,
16,
15,
15,
13,
19,
50,
19,
16,
16,
19,
21,
18,
16,
11,
17,
20,
21,
21,
17,
25,
15,
14,
18,
18,
20,
20,
60,
18,
25,
19,
22,
17,
12,
19,
21,
16,
20,
17,
17,
19,
14,
22,
17,
15,
22,
14,
22,
28,
15,
14,
24,
25,
12,
10,
20,
32,
74,
25,
19,
24,
13,
19,
18,
16,
33,
14,
9,
22,
18,
19,
18,
22,
19,
20,
18,
14,
20,
25,
16,
19,
15,
23,
14,
19,
18,
70,
75,
26,
18,
20,
13,
17,
19,
30,
17,
16,
18,
21,
16,
22,
22,
16,
15,
18,
15,
21,
17,
22,
14,
21,
22,
21,
23,
15,
22,
52,
43,
33,
19,
20,
16,
14,
14,
21,
16,
20,
13,
14,
15,
17,
18,
17,
21,
14,
19,
15,
24,
24,
9,
18,
18,
20,
12,
12,
56,
26,
23,
18,
18,
20,
20,
20,
15,
50,
18,
23,
23,
13,
16,
23,
19,
16,
20,
12,
15,
13,
26,
19,
15,
15,
18,
23,
19,
14,
31,
76,
14,
16,
21,
20,
15,
15,
25,
26,
21,
17,
21,
18,
24,
20,
17,
16,
20,
19,
20,
18,
26,
18,
14,
27,
18,
21,
28,
22,
112,
101,
31,
22,
17,
27,
15,
15,
27,
13,
16,
14,
18,
20,
19,
24,
19,
17,
14,
20,
13,
20,
19,
13,
20,
21,
15,
12,
14,
51,
25,
19,
20,
22,
24,
24,
18,
75,
29,
13,
19,
26,
23,
18,
9,
10,
13,
9,
19,
23,
22,
16,
18,
12,
15,
18,
19,
20,
35,
33,
14,
14,
19,
17,
20,
17,
20,
20,
19,
16,
19,
15,
19,
20,
24,
20,
21,
23,
19,
15,
23,
18,
19,
13,
20,
16,
30,
9,
60,
26,
23,
11,
15,
16,
21,
15,
17,
17,
17,
15,
16,
23,
22,
15,
18,
13,
13,
21,
12,
11,
21,
17,
23,
21,
19,
21,
15,
43,
112,
156,
100,
19,
22,
23,
18,
22,
30,
20,
15,
16,
15,
24,
20,
15,
19,
15,
15,
19,
15,
20,
20,
18,
13,
18,
16,
7,
18,
76,
22,
25,
23,
18,
21,
19,
19,
26,
16,
11,
17,
16,
15,
8,
23,
14,
18,
19,
15,
22,
13,
15,
13,
23,
18,
14,
31,
28,
35,
36,
34,
24,
12,
18,
20,
12,
15,
28,
9,
9,
17,
10,
23,
15,
15,
12,
13,
17,
16,
19,
18,
17,
14,
22,
19,
14,
23,
16,
33,
29,
25,
16,
21,
13,
13,
16,
33,
22,
19,
22,
24,
18,
20,
17,
17,
15,
19,
22,
20,
20,
16,
17,
16,
20,
14,
16,
15,
23,
52,
102,
15,
12,
17,
23,
25,
14,
26,
21,
19,
22,
12,
13,
25,
22,
29,
17,
15,
13,
19,
19,
16,
13,
14,
18,
12,
18,
14,
55,
42,
46,
15,
14,
16,
12,
13,
11,
20,
22,
20,
13,
16,
13,
20,
18,
14,
18,
20,
15,
24,
13,
17,
16,
18,
19,
22,
14,
19,
41,
36,
18,
9,
17,
20,
12,
21,
15,
25,
16,
18,
20,
21,
13,
19,
13,
22,
20,
21,
16,
18,
9,
14,
18,
20,
11,
20,
18,
39,
27,
25,
22,
20,
20,
22,
14,
19,
22,
19,
20,
15,
24,
21,
21,
21,
25,
23,
17,
14,
21,
16,
15,
20,
17,
15,
16,
22,
32,
59,
17,
17,
8,
20,
20,
18,
24,
32,
20,
14,
20,
15,
16,
13,
16,
25,
24,
25,
19,
20,
8,
15,
16,
16,
17,
21,
18,
19,
43,
39,
24,
22,
17,
26,
21,
21,
20,
36,
16,
13,
18,
16,
15,
25,
16,
23,
14,
18,
22,
28,
23,
16,
27,
20,
23,
20,
15,
18,
36,
20,
16,
19,
24,
18,
25,
22,
25,
22,
11,
13,
14,
18,
20,
14,
17,
16,
10,
15,
16,
19,
13,
17,
22,
26,
21,
20,
15,
48,
35,
54,
14,
20,
17,
15,
21,
13,
27,
21,
16,
16,
16,
14,
16,
17,
22,
15,
21,
16,
12,
16,
20,
14,
20,
18,
17,
15,
19,
48,
101,
38,
26,
17,
23,
17,
16,
19,
17,
19,
22,
18,
18,
20,
19,
18,
21,
18,
9,
15,
12,
21,
18,
18,
12,
17,
19,
27,
9,
55,
28,
23,
13,
21,
21,
27,
22,
31,
11,
19,
13,
14,
18,
12,
20,
15,
25,
14,
26,
23,
20,
23,
27,
22,
22,
18,
23,
27,
29,
73,
28,
15,
18,
26,
14,
19,
15,
24,
19,
19,
19,
20,
14,
18,
22,
19,
15,
17,
21,
11,
18,
22,
23,
20,
24,
21,
28,
22,
85,
37,
22,
18,
20,
19,
22,
15,
41,
26,
14,
29,
16,
16,
17,
19,
19,
15,
16,
13,
23,
16,
21,
12,
15,
17,
27,
13,
16,
61,
120,
101,
19,
21,
16,
27,
10,
14,
15,
23,
24,
18,
16,
16,
18,
22,
14,
16,
19,
15,
12,
21,
17,
14,
18,
18,
19,
23,
20,
43,
21,
24,
22,
21,
16,
22,
15,
28,
15,
11,
17,
18,
17,
16,
19,
10,
15,
11,
17,
18,
19,
22,
14,
21,
17,
23,
13,
17,
56,
28,
30,
13,
17,
26,
18,
20,
30,
18,
20,
23,
12,
18,
14,
21,
22,
20,
16,
15,
15,
23,
23,
13,
17,
11,
19,
22,
17,
13,
117,
110,
21,
22,
17,
17,
18,
17,
47,
17,
14,
16,
18,
21,
21,
17,
10,
17,
15,
19,
15,
19,
21,
24,
20,
23,
19,
23,
21,
61,
147,
141,
27,
18,
10,
18,
18,
19,
25,
17,
15,
17,
17,
20,
15,
12,
13,
20,
22,
23,
14,
25,
19,
17,
20,
16,
18,
25,
27,
61,
15,
19,
16,
18,
20,
18,
13,
37,
19,
13,
13,
23,
19,
20,
13,
16,
20,
24,
17,
16,
14,
17,
14,
17,
19,
16,
17,
12,
39,
60,
29,
17,
21,
15,
24,
19,
18,
21,
24,
13,
15,
16,
23,
20,
15,
23,
24,
22,
12,
18,
21,
20,
21,
16,
20,
18,
20,
16,
72,
61,
34,
11,
25,
19,
17,
24,
33,
23,
11,
21,
21,
16,
17,
22,
21,
14,
19,
13,
17,
17,
20,
24,
22,
2,
7,
19,
13,
35,
141,
136,
18,
18,
21,
20,
20,
24,
23,
15,
22,
13,
22,
20,
23,
18,
20,
17,
25,
12,
16,
22,
24,
22,
19,
13,
19,
19,
26,
50,
27,
50,
32,
26,
15,
14,
17,
23,
15,
18,
20,
20,
26,
27,
25,
20,
17,
14,
20,
14,
15,
18,
16,
12,
25,
21,
13,
13,
16,
109,
24,
20,
16,
18,
11,
14,
15,
18,
17,
18,
20,
18,
19,
22,
19,
15,
22,
22,
17,
20,
18,
20,
20,
19,
18,
18,
17,
22,
35,
61,
31,
7,
19,
12,
14,
18,
20,
29,
18,
25,
21,
11,
16,
19,
21,
10,
19,
15,
21,
17,
19,
17,
11,
19,
19,
20,
22,
17,
66,
99,
115,
31,
19,
17,
18,
16,
30,
25,
16,
19,
15,
21,
23,
19,
18,
15,
15,
22,
20,
15,
24,
27,
15,
20,
22,
18,
14,
20,
52,
19,
19,
18,
19,
26,
29,
15,
50,
24,
18,
24,
10,
25,
16,
16,
18,
27,
16,
19,
22,
24,
21,
22,
17,
20,
17,
19,
17,
60,
26,
16,
20,
22,
17,
17,
22,
20,
21,
20,
15,
17,
18,
17,
25,
19,
15,
18,
17,
16,
14,
32,
27,
14,
17,
19,
21,
20,
20,
69,
26,
21,
11,
16,
14,
20,
20,
25,
26,
9,
13,
15,
20,
21,
11,
10,
16,
14,
17,
22,
19,
15,
17,
23,
20,
15,
20,
14,
28,
33,
27,
17,
21,
16,
23,
23,
21,
23,
19,
14,
13,
14,
19,
15,
22,
15,
19,
16,
14,
16,
13,
18,
16,
16,
11,
10,
19,
13,
47,
26,
23,
23,
16,
21,
19,
15,
22,
20,
21,
17,
25,
22,
14,
22,
27,
18,
21,
22,
18,
19,
19,
19,
25,
18,
23,
22,
21,
22,
75,
29,
25,
21,
24,
26,
20,
31,
44,
23,
25,
16,
16,
21,
7,
19,
12,
23,
18,
19,
23,
21,
22,
19,
13,
13,
22,
21,
17,
38,
64,
35,
19,
17,
27,
19,
12,
19,
43,
17,
16,
22,
18,
17,
18,
19,
16,
21,
19,
18,
18,
21,
21,
23,
17,
12,
13,
20,
18,
88,
100,
87,
21,
26,
18,
20,
21,
39,
14,
19,
20,
19,
24,
27,
20,
21,
20,
30,
20,
23,
21,
26,
26,
23,
17,
23,
19,
23,
17,
43,
54,
30,
20,
20,
18,
18,
29,
43,
24,
16,
29,
21,
22,
18,
28,
18,
23,
17,
16,
27,
25,
14,
23,
22,
24,
21,
21,
27,
52,
54,
15,
21,
15,
23,
28,
23,
41,
18,
21,
14,
14,
20,
21,
29,
19,
18,
18,
24,
16,
18,
22,
17,
22,
21,
22,
15,
22,
23,
53,
118,
96,
26,
21,
21,
21,
19,
26,
17,
18,
24,
20,
27,
21,
31,
20,
16,
21,
17,
14,
31,
23,
10,
19,
20,
10,
18,
18,
41,
35,
19,
26,
17,
17,
13,
26,
20,
31,
18,
17,
31,
4,
27,
21,
22,
19,
13,
28,
16,
21,
21,
24,
17,
14,
18,
18,
22,
30,
84,
81,
51,
19,
19,
17,
17,
18,
62,
44,
16,
21,
20,
24,
22,
15,
18,
21,
20,
17,
20,
23,
22,
32,
19,
14,
14,
16,
19,
51,
101,
33,
20,
16,
22,
18,
19,
19,
20,
20,
20,
17,
17,
22,
19,
12,
20,
16,
13,
18,
17,
14,
11,
16,
25,
16,
17,
20,
22,
17,
21,
24,
22,
8,
20,
17,
20,
33,
17,
25,
20,
24,
19,
14,
31,
15,
22,
19,
19,
22,
22,
4,
22,
27,
21,
24,
24,
18,
54,
66,
44,
24,
22,
22,
21,
23,
19,
37,
19,
24,
19,
20,
18,
21,
20,
16,
19,
12,
25,
23,
21,
15,
20,
17,
18,
21,
18,
14,
67,
82,
23,
19,
16,
14,
13,
15,
22,
26,
5,
18,
24,
26,
20,
19,
19,
15,
20,
25,
14,
20,
15,
17,
19,
16,
19,
12,
14,
16,
36,
24,
14,
13,
22,
19,
28,
22,
61,
23,
23,
24,
18,
17,
11,
18,
14,
21,
20,
26,
22,
12,
21,
13,
17,
23,
17,
16,
15,
30,
6,
24,
17,
21,
16,
19,
19,
37,
74,
50,
17,
23,
23,
16,
13,
20,
21,
25,
24,
19,
16,
22,
24,
19,
13,
13,
26,
23,
20,
41,
29,
8,
13,
19,
18,
15,
10,
41,
18,
15,
16,
13,
10,
24,
15,
17,
21,
19,
21,
18,
15,
18,
18,
25,
15,
23,
18,
24,
42,
61,
41,
17,
25,
13,
18,
18,
27,
15,
16,
16,
16,
13,
18,
16,
18,
15,
20,
30,
18,
28,
22,
17,
19,
23,
18,
15,
16,
16,
85,
117,
29,
12,
17,
21,
16,
21,
38,
18,
11,
15,
13,
16,
24,
19,
18,
17,
15,
18,
15,
20,
21,
19,
22,
23,
20,
15,
22,
34,
107,
58,
19,
15,
28,
18,
16,
10,
48,
19,
15,
24,
28,
14,
13,
22,
19,
16,
9,
24,
18,
21,
17,
17,
27,
18,
19,
18,
17,
111,
150,
95,
18,
20,
16,
23,
16,
33,
10,
22,
22,
19,
24,
23,
29,
14,
23,
26,
21,
22,
11,
23,
18,
35,
26,
14,
21,
19,
18,
30,
35,
8,
12,
25,
15,
13,
21,
20,
18,
19,
15,
18,
19,
22,
18,
12,
24,
22,
8,
32,
14,
19,
20,
15,
17,
21,
23,
22,
36,
47,
26,
23,
20,
9,
21,
18,
29,
20,
20,
28,
25,
23,
23,
19,
19,
21,
22,
16,
19,
20,
14,
23,
14,
18,
12,
18,
19,
50,
146,
30,
15,
18,
18,
25,
16,
38,
22,
17,
14,
16,
21,
28,
18,
20,
19,
17,
15,
20,
21,
16,
18,
33,
14,
15,
19,
15,
20,
44,
12,
13,
16,
20,
18,
16,
12,
44,
13,
24,
23,
10,
21,
13,
15,
13,
10,
31,
17,
20,
13,
18,
18,
16,
18,
12,
20,
11,
29,
28,
42,
15,
12,
16,
24,
19,
15,
18,
9,
20,
13,
19,
12,
14,
22,
16,
17,
12,
12,
17,
13,
13,
28,
14,
14,
15,
19,
15,
35,
24,
17,
14,
18,
15,
19,
13,
52,
19,
20,
17,
22,
19,
21,
16,
15,
11,
18,
17,
14,
14,
13,
16,
18,
15,
15,
20,
12,
21,
92,
16,
10,
7,
8,
14,
15,
14,
42,
18,
6,
13,
18,
16,
14,
12,
18,
11,
14,
9,
18,
14,
24,
17,
9,
18,
20,
21,
10,
47,
150,
89,
19,
16,
19,
28,
13,
21,
19,
21,
12,
15,
13,
29,
19,
11,
14,
15,
10,
15,
16,
19,
24,
21,
16,
17,
14,
11,
11,
30,
17,
14,
18,
14,
16,
11,
22,
18,
12,
15,
20,
15,
14,
20,
17,
18,
22,
15,
11,
20,
15,
19,
9,
13,
16,
14,
23,
22,
30,
34,
20,
13,
22,
16,
18,
21,
17,
49,
11,
22,
15,
11,
20,
14,
11,
17,
12,
13,
15,
23,
12,
9,
20,
15,
13,
15,
14,
15,
69,
28,
23,
13,
14,
20,
19,
19,
21,
16,
11,
17,
16,
13,
13,
13,
15,
12,
14,
11,
18,
20,
11,
18,
7,
16,
10,
19,
14,
29,
25,
16,
15,
11,
9,
13,
15,
15,
65,
15,
18,
15,
24,
18,
20,
15,
18,
17,
25,
25,
15,
16,
16,
17,
28,
18,
17,
16,
13,
81,
60,
68,
13,
15,
16,
13,
23,
16,
19,
10,
18,
16,
16,
21,
18,
20,
20,
22,
19,
9,
17,
11,
17,
18,
18,
11,
19,
13,
14,
53,
17,
20,
13,
18,
3,
11,
14,
17,
17,
19,
21,
18,
19,
20,
13,
13,
18,
12,
11,
21,
16,
27,
15,
15,
13,
15,
18,
14,
65,
32,
21,
17,
15,
10,
15,
14,
15,
19,
18,
17,
17,
19,
24,
21,
22,
17,
11,
16,
12,
13,
18,
23,
22,
29,
19,
10,
12,
18,
94,
86,
29,
13,
20,
21,
16,
17,
27,
20,
23,
20,
17,
17,
21,
19,
12,
15,
24,
27,
16,
21,
22,
15,
19,
13,
17,
17,
19,
23,
37,
23,
18,
10,
10,
20,
18,
21,
33,
21,
18,
22,
23,
24,
26,
22,
25,
28,
22,
16,
15,
21,
14,
15,
21,
12,
14,
21,
15,
57,
49,
27,
27,
27,
22,
16,
26,
14,
36,
23,
20,
24,
23,
29,
28,
18,
28,
16,
23,
24,
21,
16,
19,
24,
19,
17,
23,
22,
23,
111,
25,
34,
23,
17,
22,
10,
29,
43,
21,
12,
24,
18,
16,
16,
22,
19,
20,
21,
13,
18,
12,
14,
13,
19,
15,
25,
21,
23,
82,
25,
17,
15,
26,
18,
19,
20,
15,
28,
25,
22,
18,
25,
14,
17,
14,
18,
15,
14,
12,
17,
23,
16,
17,
18,
19,
7,
20,
18,
31,
54,
20,
20,
21,
11,
13,
12,
41,
13,
14,
21,
16,
14,
17,
24,
21,
23,
19,
20,
15,
19,
23,
15,
17,
26,
22,
17,
30,
39,
60,
27,
15,
20,
14,
14,
22,
13,
57,
21,
10,
23,
14,
20,
21,
16,
14,
14,
14,
26,
21,
10,
13,
20,
15,
21,
19,
18,
22,
64,
76,
17,
20,
14,
17,
19,
11,
27,
18,
21,
20,
10,
18,
21,
26,
21,
10,
17,
21,
29,
33,
19,
29,
26,
23,
19,
23,
16,
22,
70,
44,
50,
20,
23,
14,
20,
27,
76,
31,
12,
21,
12,
16,
22,
15,
13,
18,
12,
23,
21,
13,
21,
11,
14,
10,
21,
19,
10,
36,
32,
9,
20,
12,
14,
8,
9,
22,
15,
17,
12,
25,
13,
12,
19,
18,
14,
20,
17,
17,
13,
18,
18,
9,
17,
12,
14,
19,
11,
46,
14,
38,
16,
15,
8,
21,
28,
39,
52,
21,
13,
20,
13,
19,
10,
14,
19,
15,
16,
17,
10,
17,
18,
12,
22,
15,
16,
25,
23,
24,
29,
24,
19,
18,
18,
15,
15,
41,
20,
30,
9,
13,
14,
21,
15,
18,
7,
16,
10,
11,
20,
14,
16,
23,
12,
22,
14,
26,
105,
17,
26,
26,
20,
20,
22,
13,
36,
19,
15,
24,
20,
17,
23,
17,
14,
28,
14,
19,
18,
16,
16,
22,
18,
11,
19,
21,
13,
33,
58,
34,
21,
20,
15,
18,
18,
26,
26,
4,
21,
21,
24,
20,
10,
10,
21,
21,
20,
18,
20,
15,
12,
25,
21,
19,
20,
21,
11,
77,
18,
32,
12,
20,
18,
22,
13,
11,
12,
11,
16,
18,
27,
24,
21,
29,
13,
26,
23,
28,
20,
29,
21,
14,
19,
18,
13,
30,
25,
92,
18,
17,
15,
12,
23,
21,
27,
24,
21,
18,
13,
8,
15,
27,
19,
20,
8,
16,
19,
17,
16,
17,
23,
16,
16,
16,
19,
17,
66,
52,
23,
16,
17,
14,
17,
13,
28,
18,
14,
13,
11,
19,
19,
24,
17,
13,
12,
17,
24,
14,
18,
14,
14,
13,
18,
20,
11,
13,
58,
23,
14,
16,
16,
14,
21,
14,
50,
7,
8,
12,
13,
23,
14,
3,
18,
30,
10,
21,
12,
9,
13,
10,
12,
21,
15,
24,
12,
32,
29,
18,
15,
16,
15,
19,
17,
10,
31,
9,
13,
15,
17,
12,
13,
13,
10,
14,
14,
7,
16,
18,
14,
17,
13,
13,
11,
16,
17,
41,
20,
20,
15,
19,
16,
10,
15,
27,
11,
11,
27,
17,
20,
15,
14,
23,
18,
18,
16,
13,
10,
19,
18,
25,
20,
12,
12,
17,
15,
44,
22,
14,
13,
13,
14,
27,
12,
17,
17,
18,
9,
17,
23,
26,
14,
19,
14,
19,
9,
7,
20,
18,
19,
11,
13,
15,
24,
13,
37,
144,
149,
40,
13,
12,
11,
22,
10,
26,
14,
14,
13,
15,
17,
18,
15,
15,
15,
18,
20,
13,
15,
8,
17,
16,
13,
13,
18,
7,
29,
14,
19,
17,
15,
16,
11,
12,
17,
19,
21,
10,
22,
16,
11,
13,
12,
14,
8,
14,
16,
11,
9,
11,
28,
16,
12,
16,
14,
31,
52,
40,
11,
20,
16,
24,
17,
10,
14,
10,
17,
15,
12,
17,
11,
19,
11,
12,
16,
14,
7,
12,
14,
16,
16,
16,
13,
16,
9,
64,
88,
11,
11,
11,
15,
13,
14,
22,
12,
10,
11,
15,
10,
19,
15,
13,
18,
16,
15,
23,
18,
16,
18,
22,
20,
21,
14,
20,
20,
35,
40,
21,
11,
11,
10,
15,
15,
25,
16,
23,
15,
19,
12,
21,
17,
11,
13,
16,
20,
19,
10,
16,
15,
16,
19,
16,
15,
14,
8,
35,
18,
21,
17,
22,
15,
16,
17,
34,
15,
17,
14,
12,
23,
11,
20,
16,
20,
15,
23,
15,
20,
12,
15,
20,
19,
19,
16,
18,
124,
132,
16,
26,
15,
19,
17,
15,
23,
15,
29,
26,
15,
18,
24,
18,
20,
14,
15,
19,
11,
17,
14,
18,
17,
10,
18,
16,
8,
41,
14,
19,
14,
12,
7,
9,
18,
16,
18,
18,
15,
20,
17,
20,
13,
15,
21,
15,
13,
8,
27,
15,
16,
12,
21,
16,
16,
31,
13,
49,
50,
19,
27,
23,
19,
11,
12,
23,
11,
18,
10,
7,
11,
9,
20,
14,
11,
10,
21,
16,
14,
8,
10,
14,
17,
9,
8,
15,
41,
49,
19,
4,
8,
16,
12,
14,
13,
17,
16,
11,
22,
19,
23,
15,
22,
16,
11,
21,
25,
10,
20,
14,
17,
14,
11,
13,
11,
14,
59,
18,
22,
12,
19,
18,
14,
16,
44,
19,
31,
18,
15,
12,
18,
25,
15,
10,
12,
21,
19,
18,
18,
19,
12,
20,
17,
15,
18,
29,
139,
143,
14,
12,
8,
13,
24,
15,
45,
16,
4,
18,
12,
18,
10,
19,
29,
18,
14,
23,
22,
22,
15,
17,
15,
19,
17,
11,
14,
50,
104,
58,
12,
12,
17,
15,
25,
30,
13,
9,
10,
17,
20,
16,
16,
18,
16,
12,
19,
15,
9,
19,
11,
16,
18,
14,
7,
15,
11,
67,
31,
41,
21,
14,
7,
13,
15,
17,
9,
8,
12,
10,
10,
16,
13,
28,
7,
13,
14,
18,
12,
13,
9,
9,
19,
16,
15,
25,
56,
129,
13,
19,
17,
16,
12,
10,
14,
25,
15,
10,
22,
22,
18,
11,
24,
14,
16,
14,
15,
21,
8,
12,
13,
17,
18,
21,
9,
21,
56,
15,
23,
13,
16,
9,
11,
10,
56,
9,
14,
22,
16,
20,
30,
13,
17,
9,
11,
16,
19,
16,
14,
19,
7,
14,
19,
18,
18,
25,
20,
34,
24,
8,
19,
12,
27,
24,
32,
15,
13,
19,
24,
10,
17,
16,
10,
16,
9,
17,
13,
14,
19,
18,
14,
11,
27,
23,
19,
85,
69,
19,
20,
14,
11,
12,
8,
28,
18,
16,
9,
10,
14,
20,
23,
19,
16,
17,
15,
16,
11,
16,
14,
14,
16,
10,
17,
13,
25,
48,
23,
23,
17,
15,
16,
11,
11,
60,
19,
16,
23,
17,
11,
16,
14,
19,
26,
10,
19,
12,
14,
11,
13,
13,
14,
20,
18,
14,
68,
153,
193,
97,
18,
13,
17,
28,
19,
47,
15,
22,
11,
15,
17,
19,
9,
13,
14,
12,
15,
18,
20,
17,
7,
15,
17,
15,
21,
15,
69,
63,
11,
18,
11,
20,
17,
13,
40,
18,
10,
10,
13,
12,
19,
9,
12,
18,
13,
16,
11,
18,
15,
22,
16,
12,
22,
21,
15,
45,
104,
24,
10,
22,
15,
15,
27,
11,
19,
13,
12,
9,
8,
9,
6,
18,
14,
15,
12,
6,
18,
26,
21,
26,
26,
19,
14,
24,
12,
18,
27,
47,
14,
19,
19,
25,
17,
36,
43,
22,
9,
9,
19,
13,
15,
18,
21,
9,
18,
16,
8,
16,
14,
8,
19,
11,
22,
10,
18,
58,
28,
17,
14,
15,
25,
8,
19,
29,
27,
16,
23,
19,
13,
28,
21,
14,
17,
17,
19,
29,
14,
16,
7,
17,
23,
22,
16,
11,
39,
88,
68,
17,
6,
15,
22,
27,
23,
14,
17,
11,
12,
17,
19,
9,
12,
16,
14,
22,
15,
15,
14,
15,
15,
21,
21,
15,
17,
21,
31,
20,
26,
27,
17,
21,
16,
15,
42,
20,
15,
24,
17,
23,
21,
24,
15,
22,
20,
15,
6,
13,
26,
22,
23,
18,
24,
17,
20,
41,
58,
24,
27,
23,
20,
25,
17,
17,
63,
11,
9,
17,
23,
11,
17,
22,
11,
23,
10,
15,
13,
13,
20,
9,
16,
22,
15,
16,
28,
108,
104,
57,
16,
22,
22,
19,
23,
27,
15,
17,
20,
24,
21,
19,
20,
27,
26,
18,
27,
19,
21,
16,
18,
24,
15,
28,
16,
20,
29,
116,
64,
19,
23,
29,
20,
31,
13,
49,
16,
13,
26,
17,
20,
16,
19,
24,
28,
21,
23,
25,
18,
21,
18,
17,
22,
19,
22,
23,
4,
44,
28,
12,
23,
20,
22,
23,
22,
37,
18,
23,
25,
25,
17,
12,
20,
29,
26,
25,
16,
23,
30,
26,
20,
18,
28,
25,
20,
18,
70,
42,
26,
22,
21,
23,
26,
30,
64,
47,
27,
24,
18,
20,
23,
18,
21,
18,
15,
25,
26,
22,
18,
25,
23,
24,
14,
16,
19,
29,
75,
26,
26,
23,
12,
18,
21,
21,
29,
18,
18,
13,
22,
15,
19,
12,
16,
21,
23,
29,
34,
15,
15,
19,
22,
22,
14,
24,
15,
56,
32,
42,
18,
12,
8,
19,
20,
42,
15,
19,
20,
25,
22,
19,
22,
19,
16,
14,
14,
17,
25,
14,
19,
24,
18,
16,
18,
13,
17,
43,
33,
20,
24,
24,
12,
12,
10,
75,
14,
20,
12,
14,
14,
13,
10,
12,
10,
20,
23,
16,
20,
16,
22,
17,
17,
12,
13,
12,
32,
37,
19,
18,
13,
12,
11,
15,
16,
18,
16,
16,
8,
15,
13,
19,
14,
12,
17,
24,
12,
13,
23,
19,
15,
21,
12,
20,
15,
28,
90,
41,
28,
24,
12,
16,
14,
22,
17,
16,
16,
16,
15,
17,
19,
16,
20,
26,
13,
11,
23,
12,
23,
18,
10,
18,
15,
11,
21,
19,
67,
21,
17,
17,
20,
15,
12,
15,
40,
12,
22,
18,
8,
11,
17,
15,
19,
12,
13,
14,
21,
14,
11,
12,
18,
20,
12,
17,
20,
36,
88,
34,
16,
12,
13,
14,
14,
20,
22,
11,
10,
10,
13,
18,
20,
17,
9,
15,
21,
17,
17,
19,
14,
14,
28,
18,
18,
14,
12,
34,
27,
13,
17,
20,
14,
16,
24,
39,
16,
14,
14,
16,
28,
15,
24,
19,
17,
14,
20,
20,
13,
23,
19,
16,
19,
21,
14,
11,
37,
35,
15,
9,
23,
15,
12,
14,
15,
14,
19,
18,
12,
10,
15,
16,
19,
19,
11,
20,
21,
16,
16,
12,
16,
13,
15,
14,
17,
14,
41,
40,
15,
15,
14,
21,
19,
18,
31,
18,
17,
18,
16,
17,
12,
14,
11,
22,
15,
18,
20,
14,
18,
15,
20,
19,
20,
18,
20,
26,
35,
50,
22,
16,
19,
12,
13,
15,
29,
24,
18,
13,
17,
11,
16,
21,
29,
22,
12,
16,
12,
12,
13,
16,
25,
16,
13,
10,
10,
39,
99,
26,
21,
14,
19,
13,
13,
37,
17,
14,
14,
16,
21,
13,
6,
12,
13,
9,
9,
14,
14,
11,
15,
15,
8,
19,
11,
11,
17,
134,
84,
46,
9,
15,
20,
14,
12,
13,
13,
15,
19,
13,
12,
17,
14,
13,
15,
14,
21,
21,
21,
20,
17,
13,
18,
17,
19,
26,
52,
40,
14,
27,
10,
16,
21,
17,
13,
14,
11,
13,
14,
13,
13,
10,
15,
9,
15,
16,
23,
15,
16,
15,
22,
21,
20,
13,
28,
17,
25,
12,
18,
22,
15,
16,
13,
14,
32,
6,
15,
13,
15,
12,
15,
19,
20,
14,
18,
11,
16,
16,
19,
10,
17,
22,
14,
10,
7,
21,
28,
23,
19,
9,
16,
19,
11,
18,
23,
8,
18,
14,
9,
13,
17,
18,
16,
8,
26,
19,
11,
8,
10,
9,
7,
20,
13,
11,
19,
38,
31,
31,
39,
40,
29,
9,
10,
24,
15,
9,
13,
21,
13,
19,
12,
11,
9,
17,
15,
13,
12,
16,
15,
13,
16,
15,
18,
15,
18,
37,
27,
6,
13,
8,
14,
13,
17,
67,
17,
16,
16,
16,
19,
10,
14,
10,
15,
14,
10,
15,
14,
14,
16,
11,
9,
17,
16,
13,
43,
22,
19,
12,
16,
15,
16,
8,
13,
25,
14,
14,
29,
12,
20,
11,
12,
9,
16,
13,
10,
14,
18,
30,
17,
11,
18,
12,
10,
16,
42,
17,
32,
15,
20,
13,
14,
16,
42,
16,
16,
21,
14,
16,
11,
15,
14,
18,
20,
10,
15,
4,
16,
13,
15,
15,
12,
28,
14,
62,
165,
84,
12,
16,
7,
18,
13,
15,
29,
11,
18,
18,
9,
12,
11,
12,
16,
11,
17,
19,
14,
10,
13,
14,
16,
15,
11,
16,
18,
24,
23,
11,
14,
9,
11,
13,
9,
34,
14,
11,
9,
11,
12,
12,
15,
12,
26,
9,
17,
10,
16,
13,
8,
11,
17,
7,
6,
11,
24,
69,
19,
16,
10,
12,
12,
9,
14,
11,
13,
13,
17,
7,
12,
19,
16,
10,
5,
16,
13,
10,
8,
11,
11,
14,
16,
8,
14,
8,
44,
51,
16,
7,
14,
15,
21,
10,
20,
30,
8,
14,
18,
15,
29,
17,
11,
8,
11,
11,
15,
14,
14,
16,
11,
18,
12,
8,
11,
11,
12,
15,
26,
22,
14,
6,
14,
6,
31,
7,
15,
14,
11,
6,
12,
15,
16,
14,
17,
21,
6,
12,
14,
12,
10,
10,
16,
13,
13,
11,
62,
13,
11,
15,
12,
14,
9,
13,
18,
17,
13,
12,
9,
10,
9,
18,
10,
12,
10,
15,
12,
15,
14,
20,
14,
9,
8,
7,
14,
42,
40,
25,
8,
11,
14,
22,
12,
19,
22,
11,
17,
15,
12,
4,
10,
11,
8,
18,
10,
12,
10,
16,
11,
17,
15,
7,
8,
18,
9,
57,
13,
25,
17,
13,
12,
13,
11,
20,
12,
14,
10,
11,
9,
12,
11,
16,
14,
9,
12,
23,
10,
14,
6,
16,
20,
8,
19,
12,
31,
69,
26,
15,
7,
12,
20,
14,
14,
16,
13,
12,
14,
8,
9,
8,
14,
10,
11,
12,
14,
4,
14,
15,
11,
12,
14,
11,
14,
9,
47,
125,
21,
14,
5,
15,
14,
7,
20,
16,
15,
12,
10,
8,
18,
13,
13,
18,
8,
11,
19,
10,
11,
20,
12,
13,
5,
21,
10,
7,
20,
17,
14,
11,
15,
24,
10,
10,
61,
12,
14,
15,
15,
10,
11,
17,
13,
14,
14,
11,
19,
12,
17,
14,
14,
27,
18,
11,
13,
32,
50,
12,
8,
14,
7,
10,
16,
10,
23,
23,
14,
15,
18,
15,
14,
16,
23,
9,
6,
8,
8,
14,
8,
16,
10,
8,
17,
10,
19,
18,
14,
12,
8,
10,
12,
20,
9,
12,
8,
26,
16,
5,
16,
17,
8,
15,
8,
15,
11,
14,
11,
16,
14,
7,
12,
11,
10,
11,
23,
45,
61,
41,
11,
14,
20,
17,
13,
18,
20,
13,
19,
9,
18,
9,
13,
16,
16,
15,
14,
13,
11,
9,
11,
16,
13,
13,
18,
9,
49,
15,
12,
18,
15,
9,
8,
8,
19,
18,
16,
16,
6,
17,
14,
20,
8,
15,
16,
8,
17,
8,
10,
16,
15,
18,
24,
18,
11,
18,
90,
94,
126,
65,
12,
11,
16,
24,
38,
14,
13,
17,
15,
13,
16,
12,
13,
11,
10,
22,
12,
14,
9,
9,
8,
15,
17,
10,
13,
54,
90,
135,
115,
13,
16,
13,
8,
16,
15,
16,
10,
12,
20,
10,
9,
21,
26,
22,
10,
12,
12,
21,
14,
21,
8,
15,
17,
16,
11,
37,
12,
25,
10,
12,
10,
12,
20,
30,
16,
12,
9,
10,
14,
14,
7,
6,
13,
10,
15,
9,
12,
12,
17,
17,
8,
19,
7,
10,
16,
28,
17,
15,
8,
23,
10,
13,
17,
13,
9,
15,
12,
15,
9,
17,
15,
12,
16,
10,
14,
21,
13,
7,
10,
10,
14,
11,
17,
14,
77,
109,
72,
10,
18,
12,
12,
12,
28,
57,
26,
18,
19,
35,
15,
17,
17,
13,
11,
21,
16,
17,
16,
16,
18,
7,
13,
12,
10,
16,
20,
17,
19,
10,
17,
5,
12,
26,
22,
14,
12,
13,
11,
11,
10,
11,
11,
11,
16,
11,
8,
11,
19,
18,
12,
10,
14,
7,
11,
32,
44,
34,
8,
16,
17,
12,
16,
17,
67,
21,
20,
12,
24,
7,
10,
15,
11,
17,
12,
12,
18,
21,
12,
11,
8,
13,
18,
9,
8,
34,
11,
17,
16,
8,
8,
16,
12,
21,
9,
20,
10,
13,
12,
15,
11,
9,
15,
10,
25,
10,
15,
14,
18,
16,
12,
11,
13,
11,
20,
16,
16,
23,
9,
21,
12,
18,
18,
15,
15,
4,
15,
13,
14,
12,
20,
11,
18,
17,
13,
9,
11,
13,
24,
20,
16,
15,
17,
25,
72,
104,
167,
175,
10,
12,
18,
8,
23,
17,
11,
12,
14,
15,
12,
10,
14,
18,
13,
19,
21,
24,
22,
12,
15,
15,
12,
16,
12,
10,
34,
16,
20,
17,
10,
11,
15,
12,
51,
28,
16,
18,
7,
3,
13,
14,
18,
15,
8,
13,
10,
12,
14,
10,
13,
11,
15,
13,
20,
22,
44,
24,
15,
11,
11,
12,
21,
14,
25,
17,
14,
13,
18,
10,
25,
22,
13,
10,
19,
9,
18,
11,
20,
22,
20,
24,
15,
15,
10,
46,
43,
24,
15,
14,
11,
24,
14,
15,
16,
12,
26,
12,
14,
16,
15,
20,
13,
17,
17,
11,
16,
11,
15,
20,
22,
13,
10,
14,
11,
26,
10,
5,
9,
6,
17,
8,
21,
26,
18,
11,
14,
12,
13,
10,
19,
9,
11,
13,
17,
23,
14,
12,
16,
17,
13,
21,
14,
28,
50,
147,
42,
36,
18,
11,
14,
19,
25,
65,
18,
12,
16,
17,
12,
10,
16,
6,
19,
17,
20,
8,
12,
12,
19,
26,
13,
10,
11,
12,
22,
23,
9,
9,
13,
13,
13,
12,
31,
12,
13,
14,
14,
11,
13,
12,
16,
5,
8,
19,
17,
17,
17,
12,
30,
19,
10,
17,
24,
40,
32,
17,
12,
15,
10,
15,
12,
16,
31,
22,
16,
16,
8,
8,
17,
11,
15,
10,
9,
10,
17,
17,
18,
14,
13,
17,
16,
15,
10,
92,
148,
20,
13,
10,
12,
12,
12,
12,
26,
13,
18,
20,
11,
16,
9,
7,
19,
20,
15,
8,
12,
22,
14,
27,
16,
18,
10,
14,
22,
24,
26,
11,
10,
14,
14,
21,
12,
62,
62,
16,
13,
14,
14,
16,
12,
5,
16,
12,
21,
16,
19,
17,
13,
12,
9,
15,
18,
10,
65,
32,
10,
22,
11,
21,
22,
17,
29,
18,
13,
9,
12,
17,
20,
9,
13,
24,
10,
16,
19,
13,
19,
13,
21,
14,
14,
14,
13,
20,
48,
31,
12,
10,
13,
8,
16,
16,
32,
8,
5,
17,
11,
11,
11,
19,
11,
13,
16,
18,
13,
15,
11,
17,
13,
19,
13,
13,
4,
22,
23,
20,
13,
15,
15,
15,
16,
11,
18,
15,
9,
16,
10,
16,
7,
15,
10,
11,
14,
16,
11,
16,
12,
11,
8,
16,
12,
12,
13,
49,
136,
92,
82,
15,
12,
11,
16,
15,
14,
17,
11,
15,
14,
17,
13,
17,
17,
13,
13,
15,
19,
13,
15,
28,
13,
10,
22,
8,
17,
30,
17,
8,
10,
9,
15,
12,
5,
23,
9,
16,
16,
9,
9,
9,
8,
14,
11,
10,
12,
9,
8,
15,
14,
19,
12,
14,
21,
13,
43,
35,
16,
11,
18,
13,
17,
9,
11,
11,
15,
19,
16,
10,
10,
15,
13,
11,
12,
22,
12,
22,
21,
16,
9,
18,
14,
27,
14,
20,
82,
155,
118,
15,
11,
12,
7,
9,
22,
13,
6,
13,
19,
10,
16,
19,
13,
13,
9,
17,
17,
17,
19,
27,
20,
14,
21,
10,
17,
14,
59,
11,
19,
20,
17,
12,
18,
11,
16,
15,
21,
23,
16,
13,
16,
11,
10,
16,
11,
16,
9,
13,
11,
11,
14,
13,
14,
11,
8,
50,
24,
65,
12,
12,
21,
15,
10,
14,
13,
20,
9,
9,
15,
15,
15,
14,
12,
15,
23,
9,
21,
18,
10,
19,
13,
21,
16,
14,
15,
25,
10,
25,
12,
20,
16,
18,
18,
35,
18,
15,
19,
14,
6,
16,
25,
13,
14,
13,
13,
26,
11,
17,
17,
21,
10,
16,
14,
10,
24,
25,
21,
26,
17,
18,
10,
7,
16,
35,
16,
12,
11,
11,
17,
13,
6,
16,
12,
16,
17,
11,
11,
11,
11,
19,
12,
16,
10,
11,
22,
94,
59,
18,
15,
15,
18,
15,
18,
18,
15,
7,
11,
17,
13,
11,
9,
11,
13,
20,
11,
15,
9,
16,
16,
7,
18,
9,
10,
14,
12,
32,
9,
15,
9,
16,
28,
15,
32,
14,
18,
18,
16,
20,
8,
23,
23,
19,
12,
15,
16,
14,
21,
19,
16,
16,
13,
7,
17,
50,
48,
16,
16,
12,
22,
19,
21,
8,
22,
16,
11,
12,
17,
18,
13,
11,
14,
27,
24,
25,
16,
12,
8,
11,
22,
21,
15,
22,
29,
75,
36,
59,
18,
25,
20,
16,
13,
48,
24,
22,
23,
18,
10,
18,
18,
11,
14,
18,
11,
13,
15,
25,
15,
15,
26,
24,
21,
30,
53,
47,
26,
16,
20,
18,
13,
14,
14,
25,
12,
13,
15,
16,
13,
26,
16,
16,
15,
19,
14,
18,
15,
22,
15,
23,
10,
15,
8,
16,
5,
58,
27,
17,
18,
20,
24,
24,
40,
21,
25,
12,
18,
22,
17,
22,
24,
15,
10,
15,
22,
19,
22,
20,
15,
22,
17,
16,
23,
29,
82,
37,
27,
18,
17,
23,
25,
12,
26,
18,
25,
20,
12,
12,
12,
27,
13,
22,
20,
21,
16,
27,
23,
19,
15,
12,
23,
20,
8,
64,
60,
33,
17,
19,
23,
17,
12,
23,
29,
21,
17,
12,
18,
17,
11,
16,
24,
20,
25,
21,
19,
18,
15,
31,
18,
24,
21,
16,
26,
20,
23,
43,
18,
16,
11,
19,
17,
38,
10,
9,
25,
15,
16,
17,
18,
19,
18,
13,
14,
19,
20,
22,
8,
27,
27,
12,
18,
21,
26,
22,
30,
21,
23,
16,
21,
16,
13,
20,
24,
11,
16,
17,
18,
19,
18,
16,
26,
16,
14,
17,
23,
22,
16,
17,
24,
18,
10,
18,
43,
25,
12,
19,
15,
14,
15,
16,
26,
26,
13,
13,
21,
17,
27,
21,
13,
11,
16,
13,
13,
17,
19,
10,
18,
24,
17,
19,
18,
19,
102,
106,
12,
13,
10,
14,
12,
19,
49,
25,
17,
18,
12,
30,
9,
18,
9,
14,
19,
24,
17,
16,
16,
18,
17,
20,
20,
22,
19,
38,
38,
18,
16,
14,
7,
19,
9,
24,
25,
13,
10,
19,
27,
14,
16,
12,
10,
16,
15,
16,
15,
11,
13,
23,
20,
10,
20,
15,
16,
119,
64,
21,
16,
18,
18,
14,
14,
35,
17,
16,
14,
13,
15,
16,
16,
14,
18,
20,
23,
15,
19,
17,
20,
18,
22,
18,
13,
19,
39,
44,
22,
28,
17,
19,
19,
6,
13,
22,
15,
13,
18,
21,
25,
14,
20,
21,
13,
18,
20,
19,
14,
18,
20,
12,
14,
18,
11,
18,
28,
24,
22,
17,
19,
9,
15,
18,
37,
13,
13,
11,
20,
9,
8,
12,
11,
8,
8,
12,
24,
16,
9,
15,
11,
14,
13,
18,
22,
31,
27,
33,
15,
15,
17,
10,
16,
18,
21,
15,
14,
16,
18,
12,
14,
15,
9,
19,
8,
11,
18,
15,
11,
20,
12,
29,
13,
14,
15,
32,
18,
16,
16,
14,
13,
7,
14,
18,
13,
10,
13,
18,
9,
16,
19,
11,
9,
15,
18,
12,
11,
14,
19,
13,
10,
14,
20,
16,
20,
62,
13,
16,
12,
18,
16,
18,
12,
15,
11,
11,
19,
15,
20,
13,
9,
11,
15,
13,
10,
15,
11,
12,
7,
15,
15,
21,
21,
18,
57,
131,
14,
11,
15,
12,
11,
13,
20,
19,
6,
16,
9,
14,
13,
16,
22,
11,
10,
12,
23,
21,
22,
22,
10,
9,
15,
13,
15,
14,
25,
30,
26,
18,
19,
23,
24,
15,
37,
49,
16,
11,
12,
9,
16,
7,
15,
12,
9,
11,
9,
20,
10,
14,
10,
15,
15,
8,
11,
18,
58,
12,
14,
9,
12,
12,
11,
13,
15,
15,
18,
9,
15,
24,
10,
11,
9,
14,
7,
20,
19,
13,
16,
16,
17,
15,
20,
17,
15,
31,
47,
23,
14,
12,
21,
17,
18,
12,
15,
17,
24,
17,
13,
16,
21,
14,
16,
12,
19,
14,
15,
9,
10,
16,
15,
14,
11,
10,
14,
53,
91,
82,
16,
13,
11,
14,
9,
22,
10,
15,
13,
18,
6,
10,
7,
19,
18,
15,
11,
9,
19,
5,
11,
15,
21,
24,
12,
10,
31,
81,
21,
12,
12,
24,
12,
11,
9,
10,
16,
9,
12,
17,
16,
15,
15,
18,
7,
21,
10,
18,
18,
19,
10,
10,
13,
15,
10,
10,
63,
66,
25,
13,
16,
7,
15,
15,
27,
14,
14,
10,
15,
15,
16,
9,
15,
9,
19,
12,
14,
9,
18,
17,
17,
18,
11,
18,
14,
16,
36,
15,
13,
13,
12,
13,
12,
11,
31,
14,
9,
13,
19,
12,
22,
12,
12,
12,
15,
17,
8,
17,
13,
18,
7,
12,
15,
14,
14,
54,
51,
54,
15,
9,
19,
12,
13,
17,
13,
14,
13,
17,
18,
15,
12,
9,
11,
15,
17,
13,
8,
11,
19,
24,
22,
14,
14,
13,
17,
21,
12,
15,
15,
10,
15,
10,
11,
17,
11,
19,
19,
13,
16,
21,
12,
8,
9,
11,
9,
23,
21,
21,
11,
12,
13,
20,
10,
17,
9,
30,
35,
35,
15,
22,
13,
15,
26,
47,
11,
14,
21,
10,
10,
14,
5,
15,
13,
15,
12,
9,
13,
17,
20,
12,
14,
9,
17,
11,
74,
51,
10,
6,
10,
19,
16,
19,
19,
17,
11,
17,
13,
16,
18,
13,
10,
10,
18,
12,
10,
9,
16,
17,
12,
13,
16,
12,
14,
16,
108,
26,
22,
24,
6,
10,
16,
20,
33,
10,
14,
13,
14,
15,
13,
20,
11,
8,
12,
14,
8,
12,
13,
13,
10,
12,
10,
15,
14,
33,
81,
31,
15,
12,
10,
12,
15,
18,
68,
34,
8,
13,
9,
15,
13,
14,
7,
12,
14,
9,
9,
14,
15,
20,
12,
9,
11,
13,
10,
53,
19,
30,
12,
15,
12,
25,
14,
17,
14,
15,
14,
14,
12,
13,
13,
8,
17,
20,
7,
14,
25,
13,
12,
16,
17,
19,
9,
12,
24,
29,
22,
6,
12,
16,
15,
10,
7,
22,
15,
15,
10,
10,
9,
9,
20,
12,
7,
11,
12,
14,
22,
16,
21,
20,
16,
18,
21,
20,
35,
116,
37,
28,
19,
9,
12,
15,
12,
26,
20,
15,
11,
12,
18,
13,
19,
24,
14,
22,
16,
11,
25,
23,
19,
8,
16,
15,
21,
21,
33,
16,
19,
17,
12,
15,
16,
14,
37,
15,
17,
22,
18,
13,
19,
14,
14,
19,
17,
19,
11,
7,
20,
16,
17,
16,
20,
15,
16,
42,
35,
20,
30,
17,
17,
16,
18,
18,
19,
15,
16,
22,
9,
16,
13,
8,
14,
20,
10,
20,
19,
20,
13,
10,
16,
9,
10,
25,
17,
31,
16,
20,
24,
5,
13,
17,
9,
34,
12,
9,
19,
23,
19,
10,
17,
12,
15,
11,
16,
16,
20,
14,
18,
17,
17,
13,
17,
10,
27,
47,
24,
23,
22,
22,
23,
16,
17,
17,
18,
18,
15,
18,
13,
20,
18,
10,
8,
18,
15,
14,
19,
13,
14,
31,
17,
8,
9,
15,
65,
19,
20,
17,
17,
24,
13,
14,
25,
7,
21,
11,
18,
12,
17,
8,
19,
10,
11,
13,
17,
8,
25,
12,
23,
10,
11,
17,
7,
19,
70,
15,
23,
7,
10,
14,
13,
14,
19,
11,
10,
19,
16,
17,
13,
15,
15,
14,
15,
13,
16,
19,
15,
15,
11,
19,
14,
15,
16,
26,
18,
12,
12,
10,
9,
8,
15,
10,
17,
16,
19,
13,
15,
15,
16,
19,
13,
16,
15,
12,
14,
9,
6,
11,
12,
16,
11,
13,
7,
21,
31,
16,
10,
8,
17,
14,
12,
12,
13,
14,
23,
11,
13,
19,
12,
21,
10,
11,
20,
16,
21,
19,
15,
7,
20,
16,
21,
16,
10,
36,
15,
17,
14,
14,
9,
18,
11,
23,
15,
16,
11,
11,
10,
13,
11,
14,
4,
16,
16,
16,
7,
20,
13,
16,
15,
13,
15,
18,
61,
32,
48,
16,
16,
8,
15,
17,
15,
12,
10,
14,
15,
13,
15,
16,
12,
12,
11,
16,
16,
9,
20,
16,
21,
14,
18,
17,
13,
12,
88,
98,
18,
13,
10,
14,
11,
8,
25,
14,
10,
16,
9,
18,
18,
18,
13,
29,
11,
12,
10,
13,
11,
7,
12,
25,
16,
18,
10,
15,
30,
17,
14,
23,
16,
19,
12,
6,
44,
22,
7,
10,
17,
10,
15,
9,
13,
15,
11,
11,
9,
9,
16,
16,
14,
24,
14,
13,
21,
27,
120,
30,
11,
9,
25,
16,
18,
16,
13,
12,
10,
15,
21,
11,
13,
12,
14,
12,
12,
20,
14,
22,
15,
20,
14,
22,
13,
15,
7,
40,
21,
16,
23,
27,
22,
10,
16,
16,
19,
14,
20,
13,
15,
25,
15,
18,
13,
17,
14,
18,
16,
20,
14,
16,
20,
16,
13,
15,
24,
46,
17,
15,
17,
10,
16,
19,
24,
67,
14,
4,
14,
19,
15,
14,
16,
10,
12,
12,
15,
13,
16,
12,
10,
16,
21,
13,
18,
20,
86,
28,
53,
12,
17,
15,
15,
10,
23,
14,
15,
19,
25,
12,
10,
15,
11,
13,
14,
20,
19,
15,
16,
10,
15,
17,
21,
19,
15,
20,
39,
20,
18,
16,
13,
17,
12,
26,
23,
20,
10,
25,
18,
14,
16,
12,
18,
15,
12,
14,
18,
9,
27,
16,
18,
14,
15,
17,
12,
51,
94,
24,
14,
14,
21,
18,
14,
26,
18,
18,
23,
19,
16,
15,
20,
11,
16,
19,
25,
14,
20,
11,
5,
15,
15,
20,
13,
21,
11,
43,
34,
21,
14,
9,
11,
14,
24,
16,
19,
28,
25,
26,
15,
16,
17,
9,
24,
17,
19,
15,
12,
14,
23,
9,
15,
19,
18,
23,
38,
40,
27,
13,
18,
12,
16,
12,
18,
44,
27,
10,
14,
19,
8,
14,
14,
15,
18,
16,
17,
12,
20,
18,
15,
15,
15,
16,
20,
18,
34,
32,
69,
17,
12,
19,
20,
5,
22,
14,
29,
20,
14,
14,
17,
17,
13,
11,
17,
12,
12,
11,
17,
13,
9,
14,
17,
15,
22,
13,
26,
18,
21,
16,
14,
7,
9,
10,
28,
16,
13,
14,
16,
33,
6,
15,
14,
16,
16,
20,
16,
18,
16,
10,
13,
18,
14,
18,
23,
49,
147,
39,
14,
11,
11,
22,
15,
16,
35,
21,
13,
14,
12,
11,
5,
14,
12,
17,
10,
19,
18,
13,
17,
11,
14,
15,
12,
16,
19,
58,
64,
42,
16,
19,
19,
14,
12,
31,
12,
17,
19,
13,
16,
15,
18,
14,
10,
11,
21,
17,
12,
18,
11,
6,
14,
12,
30,
16,
82,
18,
19,
16,
13,
15,
16,
17,
12,
14,
18,
19,
18,
10,
19,
11,
14,
11,
18,
12,
18,
10,
10,
18,
19,
17,
20,
8,
21,
21,
32,
22,
14,
21,
10,
17,
10,
13,
17,
14,
15,
7,
13,
12,
17,
20,
12,
8,
12,
13,
14,
10,
13,
19,
17,
10,
10,
22,
13,
25,
79,
21,
12,
20,
17,
18,
9,
12,
26,
18,
24,
19,
29,
12,
16,
9,
19,
13,
12,
11,
11,
9,
12,
18,
11,
19,
7,
17,
15,
43,
22,
14,
20,
10,
12,
16,
10,
15,
9,
21,
16,
16,
13,
18,
20,
19,
15,
15,
12,
8,
20,
10,
12,
12,
12,
10,
18,
13,
20,
85,
51,
35,
12,
12,
16,
12,
12,
28,
14,
18,
15,
9,
14,
18,
13,
11,
15,
22,
10,
13,
24,
9,
15,
18,
21,
20,
14,
18,
30,
24,
23,
18,
20,
18,
11,
13,
14,
11,
15,
10,
19,
10,
13,
17,
15,
17,
14,
11,
15,
9,
18,
19,
22,
21,
11,
14,
13,
12,
24,
19,
19,
8,
18,
17,
21,
9,
19,
9,
10,
14,
16,
20,
8,
19,
10,
15,
18,
14,
14,
11,
12,
15,
9,
11,
14,
19,
13,
22,
121,
107,
15,
17,
12,
12,
13,
11,
12,
12,
16,
14,
9,
18,
8,
19,
20,
11,
7,
8,
18,
11,
17,
25,
8,
17,
18,
13,
14,
67,
41,
18,
19,
12,
9,
17,
15,
15,
14,
14,
17,
9,
18,
16,
13,
18,
13,
9,
17,
19,
20,
15,
25,
14,
13,
16,
19,
12,
14,
60,
23,
23,
16,
18,
12,
21,
15,
43,
22,
18,
25,
17,
15,
10,
17,
14,
13,
16,
10,
13,
10,
9,
19,
14,
16,
15,
17,
16,
68,
64,
50,
16,
17,
11,
15,
15,
35,
12,
18,
16,
9,
27,
15,
13,
21,
13,
20,
12,
13,
11,
12,
20,
17,
17,
22,
12,
13,
27,
107,
86,
14,
14,
23,
14,
20,
20,
34,
22,
11,
17,
13,
4,
8,
13,
12,
7,
8,
14,
6,
9,
9,
17,
13,
18,
16,
14,
15,
21,
16,
37,
13,
12,
20,
10,
12,
10,
11,
15,
19,
15,
7,
12,
13,
12,
19,
12,
6,
11,
22,
15,
15,
13,
13,
10,
10,
10,
20,
30,
13,
12,
12,
11,
13,
9,
13,
69,
32,
13,
18,
8,
17,
15,
13,
13,
8,
15,
11,
12,
16,
14,
13,
12,
12,
15,
12,
17,
49,
11,
10,
17,
12,
18,
15,
13,
20,
12,
14,
16,
17,
20,
21,
8,
14,
14,
13,
14,
9,
17,
14,
20,
15,
17,
13,
11,
19,
10,
78,
60,
15,
16,
16,
13,
17,
14,
25,
11,
17,
25,
15,
14,
17,
6,
16,
20,
12,
11,
16,
20,
13,
10,
10,
22,
18,
20,
20,
35,
104,
17,
15,
13,
15,
16,
25,
20,
18,
13,
13,
18,
15,
24,
14,
13,
13,
13,
19,
9,
18,
14,
16,
18,
11,
12,
17,
15,
24,
73,
25,
30,
19,
10,
18,
14,
14,
21,
18,
16,
13,
15,
14,
27,
9,
12,
18,
14,
14,
13,
16,
11,
18,
10,
15,
12,
11,
13,
42,
75,
31,
12,
10,
10,
10,
10,
21,
15,
21,
19,
12,
15,
8,
13,
14,
8,
18,
10,
21,
16,
11,
3,
16,
11,
8,
13,
12,
11,
23,
17,
13,
21,
16,
13,
15,
20,
19,
13,
18,
24,
9,
15,
10,
13,
13,
18,
15,
14,
12,
15,
14,
12,
16,
19,
20,
18,
18,
24,
41,
19,
14,
10,
11,
19,
16,
9,
25,
9,
7,
15,
22,
15,
12,
10,
18,
19,
10,
11,
11,
21,
10,
18,
19,
11,
11,
14,
11,
39,
60,
14,
12,
11,
17,
12,
24,
17,
18,
8,
14,
15,
9,
12,
24,
10,
10,
14,
17,
15,
9,
16,
15,
10,
14,
19,
14,
16,
20,
49,
22,
19,
9,
16,
13,
9,
8,
19,
26,
11,
15,
18,
16,
11,
11,
9,
12,
9,
14,
16,
16,
20,
11,
18,
10,
11,
21,
10,
19,
113,
143,
124,
15,
9,
18,
16,
20,
15,
14,
14,
15,
15,
15,
18,
13,
12,
11,
10,
14,
13,
9,
13,
20,
12,
10,
10,
20,
11,
31,
19,
14,
9,
14,
13,
21,
12,
12,
27,
14,
28,
14,
15,
20,
20,
10,
11,
13,
16,
14,
11,
18,
11,
18,
10,
13,
18,
12,
12,
70,
25,
12,
10,
28,
11,
19,
12,
17,
12,
11,
12,
15,
24,
12,
7,
15,
10,
13,
19,
23,
16,
12,
18,
15,
15,
17,
14,
16,
36,
76,
19,
11,
13,
13,
15,
14,
18,
22,
13,
20,
10,
12,
18,
15,
8,
14,
7,
12,
14,
11,
19,
11,
11,
8,
13,
22,
13,
10,
39,
21,
30,
16,
21,
16,
13,
19,
52,
15,
14,
20,
11,
15,
16,
18,
17,
16,
18,
13,
24,
10,
22,
9,
16,
14,
16,
26,
19,
43,
129,
152,
85,
21,
23,
21,
16,
21,
16,
13,
16,
16,
22,
11,
15,
18,
22,
16,
15,
11,
18,
16,
7,
7,
11,
9,
13,
15,
19,
24,
17,
28,
13,
11,
14,
13,
14,
19,
16,
8,
21,
16,
14,
27,
17,
15,
10,
16,
14,
12,
16,
9,
8,
}
================================================
FILE: weightedhistogram.go
================================================
// Package gohistogram contains implementations of weighted and exponential histograms.
package gohistogram
// Copyright (c) 2013 VividCortex, Inc. All rights reserved.
// Please see the LICENSE file for applicable license terms.
import "fmt"
// A WeightedHistogram implements Histogram. A WeightedHistogram has bins that have values
// which are exponentially weighted moving averages. This allows you keep inserting large
// amounts of data into the histogram and approximate quantiles with recency factored in.
type WeightedHistogram struct {
bins []bin
maxbins int
total float64
alpha float64
}
// NewWeightedHistogram returns a new WeightedHistogram with a maximum of n bins with a decay factor
// of alpha.
//
// There is no "optimal" bin count, but somewhere between 20 and 80 bins should be
// sufficient.
//
// Alpha should be set to 2 / (N+1), where N represents the average age of the moving window.
// For example, a 60-second window with an average age of 30 seconds would yield an
// alpha of 0.064516129.
func NewWeightedHistogram(n int, alpha float64) *WeightedHistogram {
return &WeightedHistogram{
bins: make([]bin, 0),
maxbins: n,
total: 0,
alpha: alpha,
}
}
func ewma(existingVal float64, newVal float64, alpha float64) (result float64) {
result = newVal*(1-alpha) + existingVal*alpha
return
}
func (h *WeightedHistogram) scaleDown(except int) {
for i := range h.bins {
if i != except {
h.bins[i].count = ewma(h.bins[i].count, 0, h.alpha)
}
}
}
func (h *WeightedHistogram) Add(n float64) {
defer h.trim()
for i := range h.bins {
if h.bins[i].value == n {
h.bins[i].count++
defer h.scaleDown(i)
return
}
if h.bins[i].value > n {
newbin := bin{value: n, count: 1}
head := append(make([]bin, 0), h.bins[0:i]...)
head = append(head, newbin)
tail := h.bins[i:]
h.bins = append(head, tail...)
defer h.scaleDown(i)
return
}
}
h.bins = append(h.bins, bin{count: 1, value: n})
}
func (h *WeightedHistogram) Quantile(q float64) float64 {
count := q * h.total
for i := range h.bins {
count -= float64(h.bins[i].count)
if count <= 0 {
return h.bins[i].value
}
}
return -1
}
// CDF returns the value of the cumulative distribution function
// at x
func (h *WeightedHistogram) CDF(x float64) float64 {
count := 0.0
for i := range h.bins {
if h.bins[i].value <= x {
count += float64(h.bins[i].count)
}
}
return count / h.total
}
// Mean returns the sample mean of the distribution
func (h *WeightedHistogram) Mean() float64 {
if h.total == 0 {
return 0
}
sum := 0.0
for i := range h.bins {
sum += h.bins[i].value * h.bins[i].count
}
return sum / h.total
}
// Variance returns the variance of the distribution
func (h *WeightedHistogram) Variance() float64 {
if h.total == 0 {
return 0
}
sum := 0.0
mean := h.Mean()
for i := range h.bins {
sum += (h.bins[i].count * (h.bins[i].value - mean) * (h.bins[i].value - mean))
}
return sum / h.total
}
func (h *WeightedHistogram) Count() float64 {
return h.total
}
func (h *WeightedHistogram) trim() {
total := 0.0
for i := range h.bins {
total += h.bins[i].count
}
h.total = total
for len(h.bins) > h.maxbins {
// Find closest bins in terms of value
minDelta := 1e99
minDeltaIndex := 0
for i := range h.bins {
if i == 0 {
continue
}
if delta := h.bins[i].value - h.bins[i-1].value; delta < minDelta {
minDelta = delta
minDeltaIndex = i
}
}
// We need to merge bins minDeltaIndex-1 and minDeltaIndex
totalCount := h.bins[minDeltaIndex-1].count + h.bins[minDeltaIndex].count
mergedbin := bin{
value: (h.bins[minDeltaIndex-1].value*
h.bins[minDeltaIndex-1].count +
h.bins[minDeltaIndex].value*
h.bins[minDeltaIndex].count) /
totalCount, // weighted average
count: totalCount, // summed heights
}
head := append(make([]bin, 0), h.bins[0:minDeltaIndex-1]...)
tail := append([]bin{mergedbin}, h.bins[minDeltaIndex+1:]...)
h.bins = append(head, tail...)
}
}
// String returns a string reprentation of the histogram,
// which is useful for printing to a terminal.
func (h *WeightedHistogram) String() (str string) {
str += fmt.Sprintln("Total:", h.total)
for i := range h.bins {
var bar string
for j := 0; j < int(float64(h.bins[i].count)/float64(h.total)*200); j++ {
bar += "."
}
str += fmt.Sprintln(h.bins[i].value, "\t", bar)
}
return
}
gitextract_sbeqx0k_/ ├── .github/ │ ├── ISSUE_TEMPLATE.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .whitesource ├── LICENSE ├── README.md ├── histogram.go ├── histogram_test.go ├── numerichistogram.go ├── sample_data_test.go └── weightedhistogram.go
SYMBOL INDEX (27 symbols across 4 files)
FILE: histogram.go
type Histogram (line 7) | type Histogram interface
type bin (line 20) | type bin struct
FILE: histogram_test.go
function approx (line 11) | func approx(x, y float64) bool {
function TestHistogram (line 15) | func TestHistogram(t *testing.T) {
function TestWeightedHistogram (line 41) | func TestWeightedHistogram(t *testing.T) {
FILE: numerichistogram.go
type NumericHistogram (line 10) | type NumericHistogram struct
method Add (line 28) | func (h *NumericHistogram) Add(n float64) {
method Quantile (line 52) | func (h *NumericHistogram) Quantile(q float64) float64 {
method CDF (line 67) | func (h *NumericHistogram) CDF(x float64) float64 {
method Mean (line 79) | func (h *NumericHistogram) Mean() float64 {
method Variance (line 94) | func (h *NumericHistogram) Variance() float64 {
method Count (line 109) | func (h *NumericHistogram) Count() float64 {
method trim (line 114) | func (h *NumericHistogram) trim() {
method String (line 148) | func (h *NumericHistogram) String() (str string) {
function NewHistogram (line 20) | func NewHistogram(n int) *NumericHistogram {
FILE: weightedhistogram.go
type WeightedHistogram (line 12) | type WeightedHistogram struct
method scaleDown (line 42) | func (h *WeightedHistogram) scaleDown(except int) {
method Add (line 50) | func (h *WeightedHistogram) Add(n float64) {
method Quantile (line 77) | func (h *WeightedHistogram) Quantile(q float64) float64 {
method CDF (line 92) | func (h *WeightedHistogram) CDF(x float64) float64 {
method Mean (line 104) | func (h *WeightedHistogram) Mean() float64 {
method Variance (line 119) | func (h *WeightedHistogram) Variance() float64 {
method Count (line 134) | func (h *WeightedHistogram) Count() float64 {
method trim (line 138) | func (h *WeightedHistogram) trim() {
method String (line 178) | func (h *WeightedHistogram) String() (str string) {
function NewWeightedHistogram (line 28) | func NewWeightedHistogram(n int, alpha float64) *WeightedHistogram {
function ewma (line 37) | func ewma(existingVal float64, newVal float64, alpha float64) (result fl...
Condensed preview — 11 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (121K chars).
[
{
"path": ".github/ISSUE_TEMPLATE.md",
"chars": 360,
"preview": "Before you file an issue, please consider:\n\nWe only accept pull requests for minor fixes or improvements. This includes:"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 368,
"preview": "Before you create a pull request, please consider:\n\nWe only accept pull requests for minor fixes or improvements. This i"
},
{
"path": ".gitignore",
"chars": 8,
"preview": "\\#*\n.\\#*"
},
{
"path": ".whitesource",
"chars": 70,
"preview": "{\n \"settingsInheritedFrom\": \"VividCortex/whitesource-config@master\"\n}"
},
{
"path": "LICENSE",
"chars": 1055,
"preview": "Copyright (c) 2013 VividCortex\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this sof"
},
{
"path": "README.md",
"chars": 2565,
"preview": "# gohistogram - Histograms in Go\n\n 2013 VividCortex, Inc. All rights reserved.\n// Please see the LICENSE file for app"
},
{
"path": "histogram_test.go",
"chars": 1781,
"preview": "package gohistogram\n\n// Copyright (c) 2013 VividCortex, Inc. All rights reserved.\n// Please see the LICENSE file for app"
},
{
"path": "numerichistogram.go",
"chars": 3458,
"preview": "package gohistogram\n\n// Copyright (c) 2013 VividCortex, Inc. All rights reserved.\n// Please see the LICENSE file for app"
},
{
"path": "sample_data_test.go",
"chars": 74615,
"preview": "package gohistogram\n\n// Copyright (c) 2013 VividCortex, Inc. All rights reserved.\n// Please see the LICENSE file for app"
},
{
"path": "weightedhistogram.go",
"chars": 4434,
"preview": "// Package gohistogram contains implementations of weighted and exponential histograms.\npackage gohistogram\n\n// Copyrigh"
}
]
About this extraction
This page contains the full source code of the VividCortex/gohistogram GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 11 files (87.2 KB), approximately 49.5k tokens, and a symbol index with 27 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.