In [6]:
# -*- coding: utf-8 -*-

class Dtw(object):
    
    def __init__(self, seq1, seq2,
                 patterns = [(-1,-1), (-1,0), (0,-1)], 
                 weights = [{(0,0):2}, {(0,0):1}, {(0,0):1}], 
                 band_r=0.5):
        self._seq1 = seq1
        self._seq2 = seq2
        self._r = min(10, band_r*max(len(seq1), len(seq2)))
        assert len(patterns) == len(weights)
        self._patterns = patterns
        self._weights = weights
        self._map = {(-1, -1): 0}
    
    def get_distance(self, idx1, idx2):
        if idx1<0 or idx2<0 or idx1>=len(self._seq1) or idx2>=len(self._seq2):
            return 0
        return abs(self._seq1[idx1] - self._seq2[idx2])

    def calculate_path(self, idx1, idx2, pattern, weight):
        g = self.calculate(idx1+pattern[0], idx2+pattern[1])
        sum_d = 0
        for coor_offset, w in weight.items():
            i1, i2 = map(sum, zip((idx1, idx2), coor_offset))
            sum_d += self.get_distance(i1, i2)
        return g + sum_d

    def calculate(self, idx1, idx2):
        if (idx1, idx2) in self._map:
            return self._map[(idx1, idx2)]
        if idx1 < 0 or idx2 < 0 or abs(idx1-idx2) > self._r:
            return float('inf')
        min_prev_dp = float('inf')
        for i in range(len(self._patterns)):
            min_prev_dp = min(min_prev_dp, self.calculate_path(idx1, idx2, self._patterns[i], self._weights[i]))
        self._map[(idx1, idx2)] = min_prev_dp
        return self._map[(idx1, idx2)]
    
    @property
    def dtw_matrix_dict(self):
        return self._map

    def print_dtw_matrix(self):
        print('      '+' '.join(["{:^7d}".format(i) for i in range(len(self._seq2))]))
        for i in range(len(self._seq1)):
            str = "{:^4d}: ".format(i)
            for j in range(len(self._seq2)):
                if (i,j) not in self._map:
                    str += "{:^7s} ".format('-')
                else:
                    str += "{:^7.3f} ".format(self._map[(i,j)])
            print (str)
    
    def get_dtw(self):
        g = self.calculate(len(self._seq1)-1, len(self._seq2)-1)
        N = len(self._seq1) + len(self._seq2)
        return g/N

Main

Different patterns


In [3]:
PATTERNS_1 = [(0,-1), (-1,-1), (-1,0)]
WEIGHTS_SYM_1 = [{(0,0):1}, {(0,0):2}, {(0,0):1}] 
WEIGHTS_ASYM_1 = [{}, {(0,0):1}, {(0,0):1}] 
WEIGHTS_ASYM_1_2 = [{(0,0):100}, {(0,0):10}, {(0,0):1}] 

PATTERNS_2 = [(-1,-3), (-1,-2), (-1,-1), (-2,-1), (-3,-1)]
WEIGHTS_SYM_2 = [{(0,-2):2, (0,-1):1, (0,0):1}, \
                 {(0,-1):2, (0,0):1}, \
                 {(0,0):2}, \
                 {(-1,0):2, (0,0):1}, \
                 {(-2,0):2, (-1,0):1, (0,0):1}] 
WEIGHTS_ASYM_2 = [{(0,-2):1, (0,-1):1, (0,0):1/3}, \
                  {(0,-1):1, (0,0):1/2}, \
                  {(0,0):1}, \
                  {(-1,0):1, (0,0):1}, \
                  {(-2,0):1, (-1,0):1, (0,0):1}]

Initiation


In [4]:
import numpy as np
seq1 = [1, 1, 2, 9]*2
seq2 = [0, 1, 1, 2]*2

Z-Normalization


In [14]:
seq1 = (np.array(seq1)-np.mean(seq1))/np.std(seq1)
seq2 = (np.array(seq2)-np.mean(seq2))/np.std(seq2)

Calculate DTW

Symmetric Pattern 1

g(i, j) = min( g(i,j-1)+d(i,j), g(i-1,j-1)+2d(i,j), g(i-1,j)+d(i,j) )


In [15]:
d = Dtw(seq1, seq2, PATTERNS_1, WEIGHTS_SYM_1)
d.get_dtw()


Out[15]:
0.26160228246317752

In [16]:
d.print_dtw_matrix()


         0       1       2       3       4       5       6       7   
 0  :  0.742   1.414   2.087   4.174   4.915     -       -       -    
 1  :  1.483   1.414   2.087   4.174   4.915   5.588     -       -    
 2  :  2.524   1.788   1.788   3.576   4.616   4.990   5.364     -    
 3  :  5.657   3.507   3.507   2.093   5.226   6.335   6.709   5.669  
 4  :  6.398   4.180   4.180   4.180   2.834   3.507   4.180   6.267  
 5  :    -     4.852   4.852   6.267   3.576   3.507   4.180   6.267  
 6  :    -       -     5.226   6.640   4.616   3.881   3.881   5.669  
 7  :    -       -       -     5.531   7.750   5.600   5.600   4.186  

Asymmetric Pattern 2

g(i, j) = min( g(i,j-1), g(i-1,j-1)+d(i,j), g(i-1,j)+d(i,j) )


In [7]:
d = Dtw(seq1, seq2, PATTERNS_1, WEIGHTS_ASYM_1)
d.get_dtw()


Out[7]:
0.25730038274945188

In [10]:
d.print_dtw_matrix()


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-10-1c6f6ed3fef5> in <module>()
----> 1 d.print_dtw_matrix()

NameError: name 'd' is not defined

Symmetric Pattern 2


In [9]:
d = Dtw(seq1, seq2, PATTERNS_2, WEIGHTS_SYM_2)
d.get_dtw()


Out[9]:
0.26160228246317752

In [10]:
d.print_dtw_matrix()


         0       1       2       3       4       5       6       7   
 0  :  0.742   1.414   2.087    inf     inf      -       -       -    
 1  :  1.483   1.414   2.087   4.174   4.915   5.588     -       -    
 2  :  2.455   1.788   1.788   3.576   4.616   5.289     -       -    
 3  :   inf    3.507   3.507   2.093   5.226   6.335     -       -    
 4  :   inf    4.249   2.766   4.180   2.834   3.507   4.180     -    
 5  :    -     5.519   4.852   4.852   3.576   3.507   4.180     -    
 6  :    -       -       -       -     4.548   3.881   3.881     -    
 7  :    -       -       -       -       -       -       -     4.186  

Asymmetric Pattern 2


In [11]:
d = Dtw(seq1, seq2, PATTERNS_2, WEIGHTS_ASYM_2)
d.get_dtw()


Out[11]:
0.26160228246317752

In [12]:
d.print_dtw_matrix()


         0       1       2       3       4       5       6       7   
 0  :  0.742   1.414   2.087    inf     inf      -       -       -    
 1  :  1.483   1.414   2.087   4.174   4.915   5.588     -       -    
 2  :  2.455   1.788   1.788   3.576   4.616   5.289     -       -    
 3  :   inf    3.507   3.507   2.093   5.226   6.335     -       -    
 4  :   inf    4.249   2.766   4.180   2.834   3.507   4.180     -    
 5  :    -     5.519   4.852   4.852   3.576   3.507   4.180     -    
 6  :    -       -       -       -     4.548   3.881   3.881     -    
 7  :    -       -       -       -       -       -       -     4.186  

Implementation2


In [20]:
# -*- coding: utf-8 -*-

class Dtw(object):
    
    def __init__(self, seq1, seq2,
                 patterns = [(-1,-1), (-1,0), (0,-1)], 
                 weights = [{(0,0):2}, {(0,0):1}, {(0,0):1}], 
                 band_r=0.3):
        self._seq1 = seq1
        self._seq2 = seq2
        self.len_seq1 = len(seq1)
        self.len_seq2 = len(seq2)
        self.len_pattern = len(patterns)
        self.sum_w = [sum(ws.values()) for ws in weights]
        self._r = int(len(seq1)*band_r)
        assert len(patterns) == len(weights)
        self._patterns = patterns
        self._weights = weights
    
    def get_distance(self, i1, i2):
        return abs(self._seq1[i1] - self._seq2[i2])

    def calculate(self):
        g = list([float('inf')]*self.len_seq2 for i in range(self.len_seq1))
        cost = list([0]*self.len_seq2 for i in range(self.len_seq1))

        g[0][0] = 2*self.get_distance(0, 0)
        for i in range(self.len_seq1):
            for j in range(max(0,i-self._r), min(i+self._r+1, self.len_seq2)):
                for pat_i in range(self.len_pattern):
                    coor = (i+self._patterns[pat_i][0], j+self._patterns[pat_i][1])
                    if coor[0]<0 or coor[1]<0:
                        continue
                    dist = 0
                    for w_coor_offset, d_w in self._weights[pat_i].items():
                        w_coor = (i+w_coor_offset[0], j+w_coor_offset[1])
                        dist += d_w*self.get_distance(w_coor[0], w_coor[1])
                    this_val = g[coor[0]][coor[1]] + dist
                    this_cost = cost[coor[0]][coor[1]] + self.sum_w[pat_i]
                    if this_val < g[i][j]:
                        g[i][j] = this_val
                        cost[i][j] = this_cost
        return g[self.len_seq1-1][self.len_seq2-1]/cost[self.len_seq1-1][self.len_seq2-1], g, cost
    
    def print_table(self, tb):
        print('      '+' '.join(["{:^7d}".format(i) for i in range(self.len_seq2)]))
        for i in range(self.len_seq1):
            str = "{:^4d}: ".format(i)
            for j in range(self.len_seq2):
                str += "{:^7.3f} ".format(tb[i][j])
            print (str)

    def print_g_matrix(self):
        _, tb, _ = self.calculate()
        self.print_table(tb)

    def print_cost_matrix(self):
        _, _, tb = self.calculate()
        self.print_table(tb)
        
    def get_dtw(self):
        ans, _, _ = self.calculate()
        return ans

In [21]:
import numpy as np
seq1 = [1, 1, 2, 9]*2
seq2 = [0, 1, 1, 2]*2
seq1 = (np.array(seq1)-np.mean(seq1))/np.std(seq1)
seq2 = (np.array(seq2)-np.mean(seq2))/np.std(seq2)

In [22]:
d = Dtw(seq1, seq2, PATTERNS_1, WEIGHTS_ASYM_1)
d.get_dtw()


Out[22]:
0.69404687184108327

In [23]:
d.print_g_matrix()


         0       1       2       3       4       5       6       7   
 0  :  1.483   1.483   1.483    inf     inf     inf     inf     inf   
 1  :  2.225   2.156   2.156   2.156    inf     inf     inf     inf   
 2  :  3.265   2.529   2.529   2.529   2.529    inf     inf     inf   
 3  :   inf    4.249   4.249   2.834   2.834   2.834    inf     inf   
 4  :   inf     inf    4.921   4.921   3.576   3.507   3.507    inf   
 5  :   inf     inf     inf    7.008   4.317   4.180   4.180   4.180  
 6  :   inf     inf     inf     inf    5.358   4.553   4.553   4.553  
 7  :   inf     inf     inf     inf     inf    6.273   6.273   4.858  

In [24]:
d.print_cost_matrix()


         0       1       2       3       4       5       6       7   
 0  :  0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000  
 1  :  1.000   1.000   1.000   1.000   0.000   0.000   0.000   0.000  
 2  :  2.000   2.000   2.000   2.000   2.000   0.000   0.000   0.000  
 3  :  0.000   3.000   3.000   3.000   3.000   3.000   0.000   0.000  
 4  :  0.000   0.000   4.000   4.000   4.000   4.000   4.000   0.000  
 5  :  0.000   0.000   0.000   5.000   5.000   5.000   5.000   5.000  
 6  :  0.000   0.000   0.000   0.000   6.000   6.000   6.000   6.000  
 7  :  0.000   0.000   0.000   0.000   0.000   7.000   7.000   7.000  

Test another series


In [10]:
vec1=[1,7,2,3,6,9,4,1]
vec2=[1,8,8,8,2,7,7,7,0]
Dtw(vec1,vec2,PATTERNS_1,WEIGHTS_SYM_1).print_g_matrix()


---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-10-0f0970668e1d> in <module>()
      1 vec1=[1,7,2,3,6,9,4,1]
      2 vec2=[1,8,8,8,2,7,7,7,0]
----> 3 Dtw(vec1,vec2,PATTERNS_1,WEIGHTS_SYM_1).print_g_matrix()

<ipython-input-8-db6c15fab000> in print_g_matrix(self)
     52 
     53     def print_g_matrix(self):
---> 54         _, tb, _ = self.calculate()
     55         self.print_table(tb)
     56 

<ipython-input-8-db6c15fab000> in calculate(self)
     41                         g[i][j] = this_val
     42                         cost[i][j] = this_cost
---> 43         return g[self.len_seq1-1][self.len_seq2-1]/cost[self.len_seq1-1][self.len_seq2-1], g, cost
     44 
     45     def print_table(self, tb):

ZeroDivisionError: float division by zero

In [33]:
Dtw(vec1,vec2,PATTERNS_1,WEIGHTS_SYM_1).print_cost_matrix()


         0       1       2       3       4       5       6       7       8   
 0  :  0.000   1.000   2.000   3.000   4.000   5.000   6.000   7.000   8.000  
 1  :  1.000   2.000   3.000   4.000   5.000   6.000   7.000   8.000   9.000  
 2  :  2.000   3.000   4.000   5.000   6.000   7.000   8.000   9.000  10.000  
 3  :  3.000   4.000   5.000   6.000   7.000   8.000   9.000  10.000  11.000  
 4  :  4.000   5.000   6.000   7.000   8.000   9.000  10.000  11.000  12.000  
 5  :  5.000   6.000   7.000   8.000   9.000  10.000  11.000  12.000  13.000  
 6  :  6.000   7.000   8.000   9.000  10.000  11.000  12.000  13.000  14.000  
 7  :  7.000   8.000   9.000  10.000  11.000  12.000  13.000  14.000  15.000  

In [36]:
Dtw(vec1,vec2,PATTERNS_1,WEIGHTS_SYM_1).get_dtw()


Out[36]:
1.0666666666666667

In [34]:
Dtw(vec1, vec2, PATTERNS_1, WEIGHTS_ASYM_1_2).print_g_matrix()


         0       1       2       3       4       5       6       7       8   
 0  :  0.000  700.000 1400.000 2100.000 2200.000 2800.000 3400.000 4000.000 4100.000 
 1  :  6.000  10.000  110.000 210.000 710.000 710.000 710.000 710.000 1410.000 
 2  :  7.000  16.000  70.000  170.000 170.000 670.000 715.000 715.000 730.000 
 3  :  9.000  21.000  66.000  120.000 171.000 210.000 610.000 719.000 733.000 
 4  : 14.000  23.000  41.000  86.000  160.000 181.000 220.000 320.000 739.000 
 5  : 22.000  24.000  33.000  51.000  156.000 180.000 201.000 240.000 410.000 
 6  : 25.000  28.000  37.000  55.000  71.000  183.000 204.000 231.000 280.000 
 7  : 25.000  35.000  44.000  62.000  65.000  131.000 210.000 237.000 241.000 

In [35]:
Dtw(vec1, vec2, PATTERNS_1, WEIGHTS_ASYM_1_2).print_cost_matrix()


         0       1       2       3       4       5       6       7       8   
 0  :  0.000  100.000 200.000 300.000 400.000 500.000 600.000 700.000 800.000 
 1  :  1.000  10.000  110.000 210.000 310.000 410.000 510.000 610.000 710.000 
 2  :  2.000  11.000  20.000  120.000 220.000 320.000 511.000 611.000 620.000 
 3  :  3.000  12.000  21.000  30.000  221.000 230.000 330.000 612.000 621.000 
 4  :  4.000  13.000  22.000  31.000  40.000  231.000 240.000 340.000 622.000 
 5  :  5.000  14.000  23.000  32.000  41.000  50.000  241.000 250.000 350.000 
 6  :  6.000  15.000  24.000  33.000  42.000  51.000  242.000 251.000 260.000 
 7  :  7.000  16.000  25.000  34.000  43.000  52.000  243.000 252.000 261.000 

In [37]:
Dtw(vec1,vec2,PATTERNS_1,WEIGHTS_ASYM_1_2).get_dtw()


Out[37]:
0.9233716475095786

In [ ]:


In [47]:
from math import gcd
ct=0
for i in range(101):
    for j in range(i, 101):
        a = i
        b = j-i
        c = 100-j
        if gcd(a,gcd(b,c))==1:
            ct+=1
            print(a,b,c)


0 1 99
0 3 97
0 7 93
0 9 91
0 11 89
0 13 87
0 17 83
0 19 81
0 21 79
0 23 77
0 27 73
0 29 71
0 31 69
0 33 67
0 37 63
0 39 61
0 41 59
0 43 57
0 47 53
0 49 51
0 51 49
0 53 47
0 57 43
0 59 41
0 61 39
0 63 37
0 67 33
0 69 31
0 71 29
0 73 27
0 77 23
0 79 21
0 81 19
0 83 17
0 87 13
0 89 11
0 91 9
0 93 7
0 97 3
0 99 1
1 0 99
1 1 98
1 2 97
1 3 96
1 4 95
1 5 94
1 6 93
1 7 92
1 8 91
1 9 90
1 10 89
1 11 88
1 12 87
1 13 86
1 14 85
1 15 84
1 16 83
1 17 82
1 18 81
1 19 80
1 20 79
1 21 78
1 22 77
1 23 76
1 24 75
1 25 74
1 26 73
1 27 72
1 28 71
1 29 70
1 30 69
1 31 68
1 32 67
1 33 66
1 34 65
1 35 64
1 36 63
1 37 62
1 38 61
1 39 60
1 40 59
1 41 58
1 42 57
1 43 56
1 44 55
1 45 54
1 46 53
1 47 52
1 48 51
1 49 50
1 50 49
1 51 48
1 52 47
1 53 46
1 54 45
1 55 44
1 56 43
1 57 42
1 58 41
1 59 40
1 60 39
1 61 38
1 62 37
1 63 36
1 64 35
1 65 34
1 66 33
1 67 32
1 68 31
1 69 30
1 70 29
1 71 28
1 72 27
1 73 26
1 74 25
1 75 24
1 76 23
1 77 22
1 78 21
1 79 20
1 80 19
1 81 18
1 82 17
1 83 16
1 84 15
1 85 14
1 86 13
1 87 12
1 88 11
1 89 10
1 90 9
1 91 8
1 92 7
1 93 6
1 94 5
1 95 4
1 96 3
1 97 2
1 98 1
1 99 0
2 1 97
2 3 95
2 5 93
2 7 91
2 9 89
2 11 87
2 13 85
2 15 83
2 17 81
2 19 79
2 21 77
2 23 75
2 25 73
2 27 71
2 29 69
2 31 67
2 33 65
2 35 63
2 37 61
2 39 59
2 41 57
2 43 55
2 45 53
2 47 51
2 49 49
2 51 47
2 53 45
2 55 43
2 57 41
2 59 39
2 61 37
2 63 35
2 65 33
2 67 31
2 69 29
2 71 27
2 73 25
2 75 23
2 77 21
2 79 19
2 81 17
2 83 15
2 85 13
2 87 11
2 89 9
2 91 7
2 93 5
2 95 3
2 97 1
3 0 97
3 1 96
3 2 95
3 3 94
3 4 93
3 5 92
3 6 91
3 7 90
3 8 89
3 9 88
3 10 87
3 11 86
3 12 85
3 13 84
3 14 83
3 15 82
3 16 81
3 17 80
3 18 79
3 19 78
3 20 77
3 21 76
3 22 75
3 23 74
3 24 73
3 25 72
3 26 71
3 27 70
3 28 69
3 29 68
3 30 67
3 31 66
3 32 65
3 33 64
3 34 63
3 35 62
3 36 61
3 37 60
3 38 59
3 39 58
3 40 57
3 41 56
3 42 55
3 43 54
3 44 53
3 45 52
3 46 51
3 47 50
3 48 49
3 49 48
3 50 47
3 51 46
3 52 45
3 53 44
3 54 43
3 55 42
3 56 41
3 57 40
3 58 39
3 59 38
3 60 37
3 61 36
3 62 35
3 63 34
3 64 33
3 65 32
3 66 31
3 67 30
3 68 29
3 69 28
3 70 27
3 71 26
3 72 25
3 73 24
3 74 23
3 75 22
3 76 21
3 77 20
3 78 19
3 79 18
3 80 17
3 81 16
3 82 15
3 83 14
3 84 13
3 85 12
3 86 11
3 87 10
3 88 9
3 89 8
3 90 7
3 91 6
3 92 5
3 93 4
3 94 3
3 95 2
3 96 1
3 97 0
4 1 95
4 3 93
4 5 91
4 7 89
4 9 87
4 11 85
4 13 83
4 15 81
4 17 79
4 19 77
4 21 75
4 23 73
4 25 71
4 27 69
4 29 67
4 31 65
4 33 63
4 35 61
4 37 59
4 39 57
4 41 55
4 43 53
4 45 51
4 47 49
4 49 47
4 51 45
4 53 43
4 55 41
4 57 39
4 59 37
4 61 35
4 63 33
4 65 31
4 67 29
4 69 27
4 71 25
4 73 23
4 75 21
4 77 19
4 79 17
4 81 15
4 83 13
4 85 11
4 87 9
4 89 7
4 91 5
4 93 3
4 95 1
5 1 94
5 2 93
5 3 92
5 4 91
5 6 89
5 7 88
5 8 87
5 9 86
5 11 84
5 12 83
5 13 82
5 14 81
5 16 79
5 17 78
5 18 77
5 19 76
5 21 74
5 22 73
5 23 72
5 24 71
5 26 69
5 27 68
5 28 67
5 29 66
5 31 64
5 32 63
5 33 62
5 34 61
5 36 59
5 37 58
5 38 57
5 39 56
5 41 54
5 42 53
5 43 52
5 44 51
5 46 49
5 47 48
5 48 47
5 49 46
5 51 44
5 52 43
5 53 42
5 54 41
5 56 39
5 57 38
5 58 37
5 59 36
5 61 34
5 62 33
5 63 32
5 64 31
5 66 29
5 67 28
5 68 27
5 69 26
5 71 24
5 72 23
5 73 22
5 74 21
5 76 19
5 77 18
5 78 17
5 79 16
5 81 14
5 82 13
5 83 12
5 84 11
5 86 9
5 87 8
5 88 7
5 89 6
5 91 4
5 92 3
5 93 2
5 94 1
6 1 93
6 3 91
6 5 89
6 7 87
6 9 85
6 11 83
6 13 81
6 15 79
6 17 77
6 19 75
6 21 73
6 23 71
6 25 69
6 27 67
6 29 65
6 31 63
6 33 61
6 35 59
6 37 57
6 39 55
6 41 53
6 43 51
6 45 49
6 47 47
6 49 45
6 51 43
6 53 41
6 55 39
6 57 37
6 59 35
6 61 33
6 63 31
6 65 29
6 67 27
6 69 25
6 71 23
6 73 21
6 75 19
6 77 17
6 79 15
6 81 13
6 83 11
6 85 9
6 87 7
6 89 5
6 91 3
6 93 1
7 0 93
7 1 92
7 2 91
7 3 90
7 4 89
7 5 88
7 6 87
7 7 86
7 8 85
7 9 84
7 10 83
7 11 82
7 12 81
7 13 80
7 14 79
7 15 78
7 16 77
7 17 76
7 18 75
7 19 74
7 20 73
7 21 72
7 22 71
7 23 70
7 24 69
7 25 68
7 26 67
7 27 66
7 28 65
7 29 64
7 30 63
7 31 62
7 32 61
7 33 60
7 34 59
7 35 58
7 36 57
7 37 56
7 38 55
7 39 54
7 40 53
7 41 52
7 42 51
7 43 50
7 44 49
7 45 48
7 46 47
7 47 46
7 48 45
7 49 44
7 50 43
7 51 42
7 52 41
7 53 40
7 54 39
7 55 38
7 56 37
7 57 36
7 58 35
7 59 34
7 60 33
7 61 32
7 62 31
7 63 30
7 64 29
7 65 28
7 66 27
7 67 26
7 68 25
7 69 24
7 70 23
7 71 22
7 72 21
7 73 20
7 74 19
7 75 18
7 76 17
7 77 16
7 78 15
7 79 14
7 80 13
7 81 12
7 82 11
7 83 10
7 84 9
7 85 8
7 86 7
7 87 6
7 88 5
7 89 4
7 90 3
7 91 2
7 92 1
7 93 0
8 1 91
8 3 89
8 5 87
8 7 85
8 9 83
8 11 81
8 13 79
8 15 77
8 17 75
8 19 73
8 21 71
8 23 69
8 25 67
8 27 65
8 29 63
8 31 61
8 33 59
8 35 57
8 37 55
8 39 53
8 41 51
8 43 49
8 45 47
8 47 45
8 49 43
8 51 41
8 53 39
8 55 37
8 57 35
8 59 33
8 61 31
8 63 29
8 65 27
8 67 25
8 69 23
8 71 21
8 73 19
8 75 17
8 77 15
8 79 13
8 81 11
8 83 9
8 85 7
8 87 5
8 89 3
8 91 1
9 0 91
9 1 90
9 2 89
9 3 88
9 4 87
9 5 86
9 6 85
9 7 84
9 8 83
9 9 82
9 10 81
9 11 80
9 12 79
9 13 78
9 14 77
9 15 76
9 16 75
9 17 74
9 18 73
9 19 72
9 20 71
9 21 70
9 22 69
9 23 68
9 24 67
9 25 66
9 26 65
9 27 64
9 28 63
9 29 62
9 30 61
9 31 60
9 32 59
9 33 58
9 34 57
9 35 56
9 36 55
9 37 54
9 38 53
9 39 52
9 40 51
9 41 50
9 42 49
9 43 48
9 44 47
9 45 46
9 46 45
9 47 44
9 48 43
9 49 42
9 50 41
9 51 40
9 52 39
9 53 38
9 54 37
9 55 36
9 56 35
9 57 34
9 58 33
9 59 32
9 60 31
9 61 30
9 62 29
9 63 28
9 64 27
9 65 26
9 66 25
9 67 24
9 68 23
9 69 22
9 70 21
9 71 20
9 72 19
9 73 18
9 74 17
9 75 16
9 76 15
9 77 14
9 78 13
9 79 12
9 80 11
9 81 10
9 82 9
9 83 8
9 84 7
9 85 6
9 86 5
9 87 4
9 88 3
9 89 2
9 90 1
9 91 0
10 1 89
10 3 87
10 7 83
10 9 81
10 11 79
10 13 77
10 17 73
10 19 71
10 21 69
10 23 67
10 27 63
10 29 61
10 31 59
10 33 57
10 37 53
10 39 51
10 41 49
10 43 47
10 47 43
10 49 41
10 51 39
10 53 37
10 57 33
10 59 31
10 61 29
10 63 27
10 67 23
10 69 21
10 71 19
10 73 17
10 77 13
10 79 11
10 81 9
10 83 7
10 87 3
10 89 1
11 0 89
11 1 88
11 2 87
11 3 86
11 4 85
11 5 84
11 6 83
11 7 82
11 8 81
11 9 80
11 10 79
11 11 78
11 12 77
11 13 76
11 14 75
11 15 74
11 16 73
11 17 72
11 18 71
11 19 70
11 20 69
11 21 68
11 22 67
11 23 66
11 24 65
11 25 64
11 26 63
11 27 62
11 28 61
11 29 60
11 30 59
11 31 58
11 32 57
11 33 56
11 34 55
11 35 54
11 36 53
11 37 52
11 38 51
11 39 50
11 40 49
11 41 48
11 42 47
11 43 46
11 44 45
11 45 44
11 46 43
11 47 42
11 48 41
11 49 40
11 50 39
11 51 38
11 52 37
11 53 36
11 54 35
11 55 34
11 56 33
11 57 32
11 58 31
11 59 30
11 60 29
11 61 28
11 62 27
11 63 26
11 64 25
11 65 24
11 66 23
11 67 22
11 68 21
11 69 20
11 70 19
11 71 18
11 72 17
11 73 16
11 74 15
11 75 14
11 76 13
11 77 12
11 78 11
11 79 10
11 80 9
11 81 8
11 82 7
11 83 6
11 84 5
11 85 4
11 86 3
11 87 2
11 88 1
11 89 0
12 1 87
12 3 85
12 5 83
12 7 81
12 9 79
12 11 77
12 13 75
12 15 73
12 17 71
12 19 69
12 21 67
12 23 65
12 25 63
12 27 61
12 29 59
12 31 57
12 33 55
12 35 53
12 37 51
12 39 49
12 41 47
12 43 45
12 45 43
12 47 41
12 49 39
12 51 37
12 53 35
12 55 33
12 57 31
12 59 29
12 61 27
12 63 25
12 65 23
12 67 21
12 69 19
12 71 17
12 73 15
12 75 13
12 77 11
12 79 9
12 81 7
12 83 5
12 85 3
12 87 1
13 0 87
13 1 86
13 2 85
13 3 84
13 4 83
13 5 82
13 6 81
13 7 80
13 8 79
13 9 78
13 10 77
13 11 76
13 12 75
13 13 74
13 14 73
13 15 72
13 16 71
13 17 70
13 18 69
13 19 68
13 20 67
13 21 66
13 22 65
13 23 64
13 24 63
13 25 62
13 26 61
13 27 60
13 28 59
13 29 58
13 30 57
13 31 56
13 32 55
13 33 54
13 34 53
13 35 52
13 36 51
13 37 50
13 38 49
13 39 48
13 40 47
13 41 46
13 42 45
13 43 44
13 44 43
13 45 42
13 46 41
13 47 40
13 48 39
13 49 38
13 50 37
13 51 36
13 52 35
13 53 34
13 54 33
13 55 32
13 56 31
13 57 30
13 58 29
13 59 28
13 60 27
13 61 26
13 62 25
13 63 24
13 64 23
13 65 22
13 66 21
13 67 20
13 68 19
13 69 18
13 70 17
13 71 16
13 72 15
13 73 14
13 74 13
13 75 12
13 76 11
13 77 10
13 78 9
13 79 8
13 80 7
13 81 6
13 82 5
13 83 4
13 84 3
13 85 2
13 86 1
13 87 0
14 1 85
14 3 83
14 5 81
14 7 79
14 9 77
14 11 75
14 13 73
14 15 71
14 17 69
14 19 67
14 21 65
14 23 63
14 25 61
14 27 59
14 29 57
14 31 55
14 33 53
14 35 51
14 37 49
14 39 47
14 41 45
14 43 43
14 45 41
14 47 39
14 49 37
14 51 35
14 53 33
14 55 31
14 57 29
14 59 27
14 61 25
14 63 23
14 65 21
14 67 19
14 69 17
14 71 15
14 73 13
14 75 11
14 77 9
14 79 7
14 81 5
14 83 3
14 85 1
15 1 84
15 2 83
15 3 82
15 4 81
15 6 79
15 7 78
15 8 77
15 9 76
15 11 74
15 12 73
15 13 72
15 14 71
15 16 69
15 17 68
15 18 67
15 19 66
15 21 64
15 22 63
15 23 62
15 24 61
15 26 59
15 27 58
15 28 57
15 29 56
15 31 54
15 32 53
15 33 52
15 34 51
15 36 49
15 37 48
15 38 47
15 39 46
15 41 44
15 42 43
15 43 42
15 44 41
15 46 39
15 47 38
15 48 37
15 49 36
15 51 34
15 52 33
15 53 32
15 54 31
15 56 29
15 57 28
15 58 27
15 59 26
15 61 24
15 62 23
15 63 22
15 64 21
15 66 19
15 67 18
15 68 17
15 69 16
15 71 14
15 72 13
15 73 12
15 74 11
15 76 9
15 77 8
15 78 7
15 79 6
15 81 4
15 82 3
15 83 2
15 84 1
16 1 83
16 3 81
16 5 79
16 7 77
16 9 75
16 11 73
16 13 71
16 15 69
16 17 67
16 19 65
16 21 63
16 23 61
16 25 59
16 27 57
16 29 55
16 31 53
16 33 51
16 35 49
16 37 47
16 39 45
16 41 43
16 43 41
16 45 39
16 47 37
16 49 35
16 51 33
16 53 31
16 55 29
16 57 27
16 59 25
16 61 23
16 63 21
16 65 19
16 67 17
16 69 15
16 71 13
16 73 11
16 75 9
16 77 7
16 79 5
16 81 3
16 83 1
17 0 83
17 1 82
17 2 81
17 3 80
17 4 79
17 5 78
17 6 77
17 7 76
17 8 75
17 9 74
17 10 73
17 11 72
17 12 71
17 13 70
17 14 69
17 15 68
17 16 67
17 17 66
17 18 65
17 19 64
17 20 63
17 21 62
17 22 61
17 23 60
17 24 59
17 25 58
17 26 57
17 27 56
17 28 55
17 29 54
17 30 53
17 31 52
17 32 51
17 33 50
17 34 49
17 35 48
17 36 47
17 37 46
17 38 45
17 39 44
17 40 43
17 41 42
17 42 41
17 43 40
17 44 39
17 45 38
17 46 37
17 47 36
17 48 35
17 49 34
17 50 33
17 51 32
17 52 31
17 53 30
17 54 29
17 55 28
17 56 27
17 57 26
17 58 25
17 59 24
17 60 23
17 61 22
17 62 21
17 63 20
17 64 19
17 65 18
17 66 17
17 67 16
17 68 15
17 69 14
17 70 13
17 71 12
17 72 11
17 73 10
17 74 9
17 75 8
17 76 7
17 77 6
17 78 5
17 79 4
17 80 3
17 81 2
17 82 1
17 83 0
18 1 81
18 3 79
18 5 77
18 7 75
18 9 73
18 11 71
18 13 69
18 15 67
18 17 65
18 19 63
18 21 61
18 23 59
18 25 57
18 27 55
18 29 53
18 31 51
18 33 49
18 35 47
18 37 45
18 39 43
18 41 41
18 43 39
18 45 37
18 47 35
18 49 33
18 51 31
18 53 29
18 55 27
18 57 25
18 59 23
18 61 21
18 63 19
18 65 17
18 67 15
18 69 13
18 71 11
18 73 9
18 75 7
18 77 5
18 79 3
18 81 1
19 0 81
19 1 80
19 2 79
19 3 78
19 4 77
19 5 76
19 6 75
19 7 74
19 8 73
19 9 72
19 10 71
19 11 70
19 12 69
19 13 68
19 14 67
19 15 66
19 16 65
19 17 64
19 18 63
19 19 62
19 20 61
19 21 60
19 22 59
19 23 58
19 24 57
19 25 56
19 26 55
19 27 54
19 28 53
19 29 52
19 30 51
19 31 50
19 32 49
19 33 48
19 34 47
19 35 46
19 36 45
19 37 44
19 38 43
19 39 42
19 40 41
19 41 40
19 42 39
19 43 38
19 44 37
19 45 36
19 46 35
19 47 34
19 48 33
19 49 32
19 50 31
19 51 30
19 52 29
19 53 28
19 54 27
19 55 26
19 56 25
19 57 24
19 58 23
19 59 22
19 60 21
19 61 20
19 62 19
19 63 18
19 64 17
19 65 16
19 66 15
19 67 14
19 68 13
19 69 12
19 70 11
19 71 10
19 72 9
19 73 8
19 74 7
19 75 6
19 76 5
19 77 4
19 78 3
19 79 2
19 80 1
19 81 0
20 1 79
20 3 77
20 7 73
20 9 71
20 11 69
20 13 67
20 17 63
20 19 61
20 21 59
20 23 57
20 27 53
20 29 51
20 31 49
20 33 47
20 37 43
20 39 41
20 41 39
20 43 37
20 47 33
20 49 31
20 51 29
20 53 27
20 57 23
20 59 21
20 61 19
20 63 17
20 67 13
20 69 11
20 71 9
20 73 7
20 77 3
20 79 1
21 0 79
21 1 78
21 2 77
21 3 76
21 4 75
21 5 74
21 6 73
21 7 72
21 8 71
21 9 70
21 10 69
21 11 68
21 12 67
21 13 66
21 14 65
21 15 64
21 16 63
21 17 62
21 18 61
21 19 60
21 20 59
21 21 58
21 22 57
21 23 56
21 24 55
21 25 54
21 26 53
21 27 52
21 28 51
21 29 50
21 30 49
21 31 48
21 32 47
21 33 46
21 34 45
21 35 44
21 36 43
21 37 42
21 38 41
21 39 40
21 40 39
21 41 38
21 42 37
21 43 36
21 44 35
21 45 34
21 46 33
21 47 32
21 48 31
21 49 30
21 50 29
21 51 28
21 52 27
21 53 26
21 54 25
21 55 24
21 56 23
21 57 22
21 58 21
21 59 20
21 60 19
21 61 18
21 62 17
21 63 16
21 64 15
21 65 14
21 66 13
21 67 12
21 68 11
21 69 10
21 70 9
21 71 8
21 72 7
21 73 6
21 74 5
21 75 4
21 76 3
21 77 2
21 78 1
21 79 0
22 1 77
22 3 75
22 5 73
22 7 71
22 9 69
22 11 67
22 13 65
22 15 63
22 17 61
22 19 59
22 21 57
22 23 55
22 25 53
22 27 51
22 29 49
22 31 47
22 33 45
22 35 43
22 37 41
22 39 39
22 41 37
22 43 35
22 45 33
22 47 31
22 49 29
22 51 27
22 53 25
22 55 23
22 57 21
22 59 19
22 61 17
22 63 15
22 65 13
22 67 11
22 69 9
22 71 7
22 73 5
22 75 3
22 77 1
23 0 77
23 1 76
23 2 75
23 3 74
23 4 73
23 5 72
23 6 71
23 7 70
23 8 69
23 9 68
23 10 67
23 11 66
23 12 65
23 13 64
23 14 63
23 15 62
23 16 61
23 17 60
23 18 59
23 19 58
23 20 57
23 21 56
23 22 55
23 23 54
23 24 53
23 25 52
23 26 51
23 27 50
23 28 49
23 29 48
23 30 47
23 31 46
23 32 45
23 33 44
23 34 43
23 35 42
23 36 41
23 37 40
23 38 39
23 39 38
23 40 37
23 41 36
23 42 35
23 43 34
23 44 33
23 45 32
23 46 31
23 47 30
23 48 29
23 49 28
23 50 27
23 51 26
23 52 25
23 53 24
23 54 23
23 55 22
23 56 21
23 57 20
23 58 19
23 59 18
23 60 17
23 61 16
23 62 15
23 63 14
23 64 13
23 65 12
23 66 11
23 67 10
23 68 9
23 69 8
23 70 7
23 71 6
23 72 5
23 73 4
23 74 3
23 75 2
23 76 1
23 77 0
24 1 75
24 3 73
24 5 71
24 7 69
24 9 67
24 11 65
24 13 63
24 15 61
24 17 59
24 19 57
24 21 55
24 23 53
24 25 51
24 27 49
24 29 47
24 31 45
24 33 43
24 35 41
24 37 39
24 39 37
24 41 35
24 43 33
24 45 31
24 47 29
24 49 27
24 51 25
24 53 23
24 55 21
24 57 19
24 59 17
24 61 15
24 63 13
24 65 11
24 67 9
24 69 7
24 71 5
24 73 3
24 75 1
25 1 74
25 2 73
25 3 72
25 4 71
25 6 69
25 7 68
25 8 67
25 9 66
25 11 64
25 12 63
25 13 62
25 14 61
25 16 59
25 17 58
25 18 57
25 19 56
25 21 54
25 22 53
25 23 52
25 24 51
25 26 49
25 27 48
25 28 47
25 29 46
25 31 44
25 32 43
25 33 42
25 34 41
25 36 39
25 37 38
25 38 37
25 39 36
25 41 34
25 42 33
25 43 32
25 44 31
25 46 29
25 47 28
25 48 27
25 49 26
25 51 24
25 52 23
25 53 22
25 54 21
25 56 19
25 57 18
25 58 17
25 59 16
25 61 14
25 62 13
25 63 12
25 64 11
25 66 9
25 67 8
25 68 7
25 69 6
25 71 4
25 72 3
25 73 2
25 74 1
26 1 73
26 3 71
26 5 69
26 7 67
26 9 65
26 11 63
26 13 61
26 15 59
26 17 57
26 19 55
26 21 53
26 23 51
26 25 49
26 27 47
26 29 45
26 31 43
26 33 41
26 35 39
26 37 37
26 39 35
26 41 33
26 43 31
26 45 29
26 47 27
26 49 25
26 51 23
26 53 21
26 55 19
26 57 17
26 59 15
26 61 13
26 63 11
26 65 9
26 67 7
26 69 5
26 71 3
26 73 1
27 0 73
27 1 72
27 2 71
27 3 70
27 4 69
27 5 68
27 6 67
27 7 66
27 8 65
27 9 64
27 10 63
27 11 62
27 12 61
27 13 60
27 14 59
27 15 58
27 16 57
27 17 56
27 18 55
27 19 54
27 20 53
27 21 52
27 22 51
27 23 50
27 24 49
27 25 48
27 26 47
27 27 46
27 28 45
27 29 44
27 30 43
27 31 42
27 32 41
27 33 40
27 34 39
27 35 38
27 36 37
27 37 36
27 38 35
27 39 34
27 40 33
27 41 32
27 42 31
27 43 30
27 44 29
27 45 28
27 46 27
27 47 26
27 48 25
27 49 24
27 50 23
27 51 22
27 52 21
27 53 20
27 54 19
27 55 18
27 56 17
27 57 16
27 58 15
27 59 14
27 60 13
27 61 12
27 62 11
27 63 10
27 64 9
27 65 8
27 66 7
27 67 6
27 68 5
27 69 4
27 70 3
27 71 2
27 72 1
27 73 0
28 1 71
28 3 69
28 5 67
28 7 65
28 9 63
28 11 61
28 13 59
28 15 57
28 17 55
28 19 53
28 21 51
28 23 49
28 25 47
28 27 45
28 29 43
28 31 41
28 33 39
28 35 37
28 37 35
28 39 33
28 41 31
28 43 29
28 45 27
28 47 25
28 49 23
28 51 21
28 53 19
28 55 17
28 57 15
28 59 13
28 61 11
28 63 9
28 65 7
28 67 5
28 69 3
28 71 1
29 0 71
29 1 70
29 2 69
29 3 68
29 4 67
29 5 66
29 6 65
29 7 64
29 8 63
29 9 62
29 10 61
29 11 60
29 12 59
29 13 58
29 14 57
29 15 56
29 16 55
29 17 54
29 18 53
29 19 52
29 20 51
29 21 50
29 22 49
29 23 48
29 24 47
29 25 46
29 26 45
29 27 44
29 28 43
29 29 42
29 30 41
29 31 40
29 32 39
29 33 38
29 34 37
29 35 36
29 36 35
29 37 34
29 38 33
29 39 32
29 40 31
29 41 30
29 42 29
29 43 28
29 44 27
29 45 26
29 46 25
29 47 24
29 48 23
29 49 22
29 50 21
29 51 20
29 52 19
29 53 18
29 54 17
29 55 16
29 56 15
29 57 14
29 58 13
29 59 12
29 60 11
29 61 10
29 62 9
29 63 8
29 64 7
29 65 6
29 66 5
29 67 4
29 68 3
29 69 2
29 70 1
29 71 0
30 1 69
30 3 67
30 7 63
30 9 61
30 11 59
30 13 57
30 17 53
30 19 51
30 21 49
30 23 47
30 27 43
30 29 41
30 31 39
30 33 37
30 37 33
30 39 31
30 41 29
30 43 27
30 47 23
30 49 21
30 51 19
30 53 17
30 57 13
30 59 11
30 61 9
30 63 7
30 67 3
30 69 1
31 0 69
31 1 68
31 2 67
31 3 66
31 4 65
31 5 64
31 6 63
31 7 62
31 8 61
31 9 60
31 10 59
31 11 58
31 12 57
31 13 56
31 14 55
31 15 54
31 16 53
31 17 52
31 18 51
31 19 50
31 20 49
31 21 48
31 22 47
31 23 46
31 24 45
31 25 44
31 26 43
31 27 42
31 28 41
31 29 40
31 30 39
31 31 38
31 32 37
31 33 36
31 34 35
31 35 34
31 36 33
31 37 32
31 38 31
31 39 30
31 40 29
31 41 28
31 42 27
31 43 26
31 44 25
31 45 24
31 46 23
31 47 22
31 48 21
31 49 20
31 50 19
31 51 18
31 52 17
31 53 16
31 54 15
31 55 14
31 56 13
31 57 12
31 58 11
31 59 10
31 60 9
31 61 8
31 62 7
31 63 6
31 64 5
31 65 4
31 66 3
31 67 2
31 68 1
31 69 0
32 1 67
32 3 65
32 5 63
32 7 61
32 9 59
32 11 57
32 13 55
32 15 53
32 17 51
32 19 49
32 21 47
32 23 45
32 25 43
32 27 41
32 29 39
32 31 37
32 33 35
32 35 33
32 37 31
32 39 29
32 41 27
32 43 25
32 45 23
32 47 21
32 49 19
32 51 17
32 53 15
32 55 13
32 57 11
32 59 9
32 61 7
32 63 5
32 65 3
32 67 1
33 0 67
33 1 66
33 2 65
33 3 64
33 4 63
33 5 62
33 6 61
33 7 60
33 8 59
33 9 58
33 10 57
33 11 56
33 12 55
33 13 54
33 14 53
33 15 52
33 16 51
33 17 50
33 18 49
33 19 48
33 20 47
33 21 46
33 22 45
33 23 44
33 24 43
33 25 42
33 26 41
33 27 40
33 28 39
33 29 38
33 30 37
33 31 36
33 32 35
33 33 34
33 34 33
33 35 32
33 36 31
33 37 30
33 38 29
33 39 28
33 40 27
33 41 26
33 42 25
33 43 24
33 44 23
33 45 22
33 46 21
33 47 20
33 48 19
33 49 18
33 50 17
33 51 16
33 52 15
33 53 14
33 54 13
33 55 12
33 56 11
33 57 10
33 58 9
33 59 8
33 60 7
33 61 6
33 62 5
33 63 4
33 64 3
33 65 2
33 66 1
33 67 0
34 1 65
34 3 63
34 5 61
34 7 59
34 9 57
34 11 55
34 13 53
34 15 51
34 17 49
34 19 47
34 21 45
34 23 43
34 25 41
34 27 39
34 29 37
34 31 35
34 33 33
34 35 31
34 37 29
34 39 27
34 41 25
34 43 23
34 45 21
34 47 19
34 49 17
34 51 15
34 53 13
34 55 11
34 57 9
34 59 7
34 61 5
34 63 3
34 65 1
35 1 64
35 2 63
35 3 62
35 4 61
35 6 59
35 7 58
35 8 57
35 9 56
35 11 54
35 12 53
35 13 52
35 14 51
35 16 49
35 17 48
35 18 47
35 19 46
35 21 44
35 22 43
35 23 42
35 24 41
35 26 39
35 27 38
35 28 37
35 29 36
35 31 34
35 32 33
35 33 32
35 34 31
35 36 29
35 37 28
35 38 27
35 39 26
35 41 24
35 42 23
35 43 22
35 44 21
35 46 19
35 47 18
35 48 17
35 49 16
35 51 14
35 52 13
35 53 12
35 54 11
35 56 9
35 57 8
35 58 7
35 59 6
35 61 4
35 62 3
35 63 2
35 64 1
36 1 63
36 3 61
36 5 59
36 7 57
36 9 55
36 11 53
36 13 51
36 15 49
36 17 47
36 19 45
36 21 43
36 23 41
36 25 39
36 27 37
36 29 35
36 31 33
36 33 31
36 35 29
36 37 27
36 39 25
36 41 23
36 43 21
36 45 19
36 47 17
36 49 15
36 51 13
36 53 11
36 55 9
36 57 7
36 59 5
36 61 3
36 63 1
37 0 63
37 1 62
37 2 61
37 3 60
37 4 59
37 5 58
37 6 57
37 7 56
37 8 55
37 9 54
37 10 53
37 11 52
37 12 51
37 13 50
37 14 49
37 15 48
37 16 47
37 17 46
37 18 45
37 19 44
37 20 43
37 21 42
37 22 41
37 23 40
37 24 39
37 25 38
37 26 37
37 27 36
37 28 35
37 29 34
37 30 33
37 31 32
37 32 31
37 33 30
37 34 29
37 35 28
37 36 27
37 37 26
37 38 25
37 39 24
37 40 23
37 41 22
37 42 21
37 43 20
37 44 19
37 45 18
37 46 17
37 47 16
37 48 15
37 49 14
37 50 13
37 51 12
37 52 11
37 53 10
37 54 9
37 55 8
37 56 7
37 57 6
37 58 5
37 59 4
37 60 3
37 61 2
37 62 1
37 63 0
38 1 61
38 3 59
38 5 57
38 7 55
38 9 53
38 11 51
38 13 49
38 15 47
38 17 45
38 19 43
38 21 41
38 23 39
38 25 37
38 27 35
38 29 33
38 31 31
38 33 29
38 35 27
38 37 25
38 39 23
38 41 21
38 43 19
38 45 17
38 47 15
38 49 13
38 51 11
38 53 9
38 55 7
38 57 5
38 59 3
38 61 1
39 0 61
39 1 60
39 2 59
39 3 58
39 4 57
39 5 56
39 6 55
39 7 54
39 8 53
39 9 52
39 10 51
39 11 50
39 12 49
39 13 48
39 14 47
39 15 46
39 16 45
39 17 44
39 18 43
39 19 42
39 20 41
39 21 40
39 22 39
39 23 38
39 24 37
39 25 36
39 26 35
39 27 34
39 28 33
39 29 32
39 30 31
39 31 30
39 32 29
39 33 28
39 34 27
39 35 26
39 36 25
39 37 24
39 38 23
39 39 22
39 40 21
39 41 20
39 42 19
39 43 18
39 44 17
39 45 16
39 46 15
39 47 14
39 48 13
39 49 12
39 50 11
39 51 10
39 52 9
39 53 8
39 54 7
39 55 6
39 56 5
39 57 4
39 58 3
39 59 2
39 60 1
39 61 0
40 1 59
40 3 57
40 7 53
40 9 51
40 11 49
40 13 47
40 17 43
40 19 41
40 21 39
40 23 37
40 27 33
40 29 31
40 31 29
40 33 27
40 37 23
40 39 21
40 41 19
40 43 17
40 47 13
40 49 11
40 51 9
40 53 7
40 57 3
40 59 1
41 0 59
41 1 58
41 2 57
41 3 56
41 4 55
41 5 54
41 6 53
41 7 52
41 8 51
41 9 50
41 10 49
41 11 48
41 12 47
41 13 46
41 14 45
41 15 44
41 16 43
41 17 42
41 18 41
41 19 40
41 20 39
41 21 38
41 22 37
41 23 36
41 24 35
41 25 34
41 26 33
41 27 32
41 28 31
41 29 30
41 30 29
41 31 28
41 32 27
41 33 26
41 34 25
41 35 24
41 36 23
41 37 22
41 38 21
41 39 20
41 40 19
41 41 18
41 42 17
41 43 16
41 44 15
41 45 14
41 46 13
41 47 12
41 48 11
41 49 10
41 50 9
41 51 8
41 52 7
41 53 6
41 54 5
41 55 4
41 56 3
41 57 2
41 58 1
41 59 0
42 1 57
42 3 55
42 5 53
42 7 51
42 9 49
42 11 47
42 13 45
42 15 43
42 17 41
42 19 39
42 21 37
42 23 35
42 25 33
42 27 31
42 29 29
42 31 27
42 33 25
42 35 23
42 37 21
42 39 19
42 41 17
42 43 15
42 45 13
42 47 11
42 49 9
42 51 7
42 53 5
42 55 3
42 57 1
43 0 57
43 1 56
43 2 55
43 3 54
43 4 53
43 5 52
43 6 51
43 7 50
43 8 49
43 9 48
43 10 47
43 11 46
43 12 45
43 13 44
43 14 43
43 15 42
43 16 41
43 17 40
43 18 39
43 19 38
43 20 37
43 21 36
43 22 35
43 23 34
43 24 33
43 25 32
43 26 31
43 27 30
43 28 29
43 29 28
43 30 27
43 31 26
43 32 25
43 33 24
43 34 23
43 35 22
43 36 21
43 37 20
43 38 19
43 39 18
43 40 17
43 41 16
43 42 15
43 43 14
43 44 13
43 45 12
43 46 11
43 47 10
43 48 9
43 49 8
43 50 7
43 51 6
43 52 5
43 53 4
43 54 3
43 55 2
43 56 1
43 57 0
44 1 55
44 3 53
44 5 51
44 7 49
44 9 47
44 11 45
44 13 43
44 15 41
44 17 39
44 19 37
44 21 35
44 23 33
44 25 31
44 27 29
44 29 27
44 31 25
44 33 23
44 35 21
44 37 19
44 39 17
44 41 15
44 43 13
44 45 11
44 47 9
44 49 7
44 51 5
44 53 3
44 55 1
45 1 54
45 2 53
45 3 52
45 4 51
45 6 49
45 7 48
45 8 47
45 9 46
45 11 44
45 12 43
45 13 42
45 14 41
45 16 39
45 17 38
45 18 37
45 19 36
45 21 34
45 22 33
45 23 32
45 24 31
45 26 29
45 27 28
45 28 27
45 29 26
45 31 24
45 32 23
45 33 22
45 34 21
45 36 19
45 37 18
45 38 17
45 39 16
45 41 14
45 42 13
45 43 12
45 44 11
45 46 9
45 47 8
45 48 7
45 49 6
45 51 4
45 52 3
45 53 2
45 54 1
46 1 53
46 3 51
46 5 49
46 7 47
46 9 45
46 11 43
46 13 41
46 15 39
46 17 37
46 19 35
46 21 33
46 23 31
46 25 29
46 27 27
46 29 25
46 31 23
46 33 21
46 35 19
46 37 17
46 39 15
46 41 13
46 43 11
46 45 9
46 47 7
46 49 5
46 51 3
46 53 1
47 0 53
47 1 52
47 2 51
47 3 50
47 4 49
47 5 48
47 6 47
47 7 46
47 8 45
47 9 44
47 10 43
47 11 42
47 12 41
47 13 40
47 14 39
47 15 38
47 16 37
47 17 36
47 18 35
47 19 34
47 20 33
47 21 32
47 22 31
47 23 30
47 24 29
47 25 28
47 26 27
47 27 26
47 28 25
47 29 24
47 30 23
47 31 22
47 32 21
47 33 20
47 34 19
47 35 18
47 36 17
47 37 16
47 38 15
47 39 14
47 40 13
47 41 12
47 42 11
47 43 10
47 44 9
47 45 8
47 46 7
47 47 6
47 48 5
47 49 4
47 50 3
47 51 2
47 52 1
47 53 0
48 1 51
48 3 49
48 5 47
48 7 45
48 9 43
48 11 41
48 13 39
48 15 37
48 17 35
48 19 33
48 21 31
48 23 29
48 25 27
48 27 25
48 29 23
48 31 21
48 33 19
48 35 17
48 37 15
48 39 13
48 41 11
48 43 9
48 45 7
48 47 5
48 49 3
48 51 1
49 0 51
49 1 50
49 2 49
49 3 48
49 4 47
49 5 46
49 6 45
49 7 44
49 8 43
49 9 42
49 10 41
49 11 40
49 12 39
49 13 38
49 14 37
49 15 36
49 16 35
49 17 34
49 18 33
49 19 32
49 20 31
49 21 30
49 22 29
49 23 28
49 24 27
49 25 26
49 26 25
49 27 24
49 28 23
49 29 22
49 30 21
49 31 20
49 32 19
49 33 18
49 34 17
49 35 16
49 36 15
49 37 14
49 38 13
49 39 12
49 40 11
49 41 10
49 42 9
49 43 8
49 44 7
49 45 6
49 46 5
49 47 4
49 48 3
49 49 2
49 50 1
49 51 0
50 1 49
50 3 47
50 7 43
50 9 41
50 11 39
50 13 37
50 17 33
50 19 31
50 21 29
50 23 27
50 27 23
50 29 21
50 31 19
50 33 17
50 37 13
50 39 11
50 41 9
50 43 7
50 47 3
50 49 1
51 0 49
51 1 48
51 2 47
51 3 46
51 4 45
51 5 44
51 6 43
51 7 42
51 8 41
51 9 40
51 10 39
51 11 38
51 12 37
51 13 36
51 14 35
51 15 34
51 16 33
51 17 32
51 18 31
51 19 30
51 20 29
51 21 28
51 22 27
51 23 26
51 24 25
51 25 24
51 26 23
51 27 22
51 28 21
51 29 20
51 30 19
51 31 18
51 32 17
51 33 16
51 34 15
51 35 14
51 36 13
51 37 12
51 38 11
51 39 10
51 40 9
51 41 8
51 42 7
51 43 6
51 44 5
51 45 4
51 46 3
51 47 2
51 48 1
51 49 0
52 1 47
52 3 45
52 5 43
52 7 41
52 9 39
52 11 37
52 13 35
52 15 33
52 17 31
52 19 29
52 21 27
52 23 25
52 25 23
52 27 21
52 29 19
52 31 17
52 33 15
52 35 13
52 37 11
52 39 9
52 41 7
52 43 5
52 45 3
52 47 1
53 0 47
53 1 46
53 2 45
53 3 44
53 4 43
53 5 42
53 6 41
53 7 40
53 8 39
53 9 38
53 10 37
53 11 36
53 12 35
53 13 34
53 14 33
53 15 32
53 16 31
53 17 30
53 18 29
53 19 28
53 20 27
53 21 26
53 22 25
53 23 24
53 24 23
53 25 22
53 26 21
53 27 20
53 28 19
53 29 18
53 30 17
53 31 16
53 32 15
53 33 14
53 34 13
53 35 12
53 36 11
53 37 10
53 38 9
53 39 8
53 40 7
53 41 6
53 42 5
53 43 4
53 44 3
53 45 2
53 46 1
53 47 0
54 1 45
54 3 43
54 5 41
54 7 39
54 9 37
54 11 35
54 13 33
54 15 31
54 17 29
54 19 27
54 21 25
54 23 23
54 25 21
54 27 19
54 29 17
54 31 15
54 33 13
54 35 11
54 37 9
54 39 7
54 41 5
54 43 3
54 45 1
55 1 44
55 2 43
55 3 42
55 4 41
55 6 39
55 7 38
55 8 37
55 9 36
55 11 34
55 12 33
55 13 32
55 14 31
55 16 29
55 17 28
55 18 27
55 19 26
55 21 24
55 22 23
55 23 22
55 24 21
55 26 19
55 27 18
55 28 17
55 29 16
55 31 14
55 32 13
55 33 12
55 34 11
55 36 9
55 37 8
55 38 7
55 39 6
55 41 4
55 42 3
55 43 2
55 44 1
56 1 43
56 3 41
56 5 39
56 7 37
56 9 35
56 11 33
56 13 31
56 15 29
56 17 27
56 19 25
56 21 23
56 23 21
56 25 19
56 27 17
56 29 15
56 31 13
56 33 11
56 35 9
56 37 7
56 39 5
56 41 3
56 43 1
57 0 43
57 1 42
57 2 41
57 3 40
57 4 39
57 5 38
57 6 37
57 7 36
57 8 35
57 9 34
57 10 33
57 11 32
57 12 31
57 13 30
57 14 29
57 15 28
57 16 27
57 17 26
57 18 25
57 19 24
57 20 23
57 21 22
57 22 21
57 23 20
57 24 19
57 25 18
57 26 17
57 27 16
57 28 15
57 29 14
57 30 13
57 31 12
57 32 11
57 33 10
57 34 9
57 35 8
57 36 7
57 37 6
57 38 5
57 39 4
57 40 3
57 41 2
57 42 1
57 43 0
58 1 41
58 3 39
58 5 37
58 7 35
58 9 33
58 11 31
58 13 29
58 15 27
58 17 25
58 19 23
58 21 21
58 23 19
58 25 17
58 27 15
58 29 13
58 31 11
58 33 9
58 35 7
58 37 5
58 39 3
58 41 1
59 0 41
59 1 40
59 2 39
59 3 38
59 4 37
59 5 36
59 6 35
59 7 34
59 8 33
59 9 32
59 10 31
59 11 30
59 12 29
59 13 28
59 14 27
59 15 26
59 16 25
59 17 24
59 18 23
59 19 22
59 20 21
59 21 20
59 22 19
59 23 18
59 24 17
59 25 16
59 26 15
59 27 14
59 28 13
59 29 12
59 30 11
59 31 10
59 32 9
59 33 8
59 34 7
59 35 6
59 36 5
59 37 4
59 38 3
59 39 2
59 40 1
59 41 0
60 1 39
60 3 37
60 7 33
60 9 31
60 11 29
60 13 27
60 17 23
60 19 21
60 21 19
60 23 17
60 27 13
60 29 11
60 31 9
60 33 7
60 37 3
60 39 1
61 0 39
61 1 38
61 2 37
61 3 36
61 4 35
61 5 34
61 6 33
61 7 32
61 8 31
61 9 30
61 10 29
61 11 28
61 12 27
61 13 26
61 14 25
61 15 24
61 16 23
61 17 22
61 18 21
61 19 20
61 20 19
61 21 18
61 22 17
61 23 16
61 24 15
61 25 14
61 26 13
61 27 12
61 28 11
61 29 10
61 30 9
61 31 8
61 32 7
61 33 6
61 34 5
61 35 4
61 36 3
61 37 2
61 38 1
61 39 0
62 1 37
62 3 35
62 5 33
62 7 31
62 9 29
62 11 27
62 13 25
62 15 23
62 17 21
62 19 19
62 21 17
62 23 15
62 25 13
62 27 11
62 29 9
62 31 7
62 33 5
62 35 3
62 37 1
63 0 37
63 1 36
63 2 35
63 3 34
63 4 33
63 5 32
63 6 31
63 7 30
63 8 29
63 9 28
63 10 27
63 11 26
63 12 25
63 13 24
63 14 23
63 15 22
63 16 21
63 17 20
63 18 19
63 19 18
63 20 17
63 21 16
63 22 15
63 23 14
63 24 13
63 25 12
63 26 11
63 27 10
63 28 9
63 29 8
63 30 7
63 31 6
63 32 5
63 33 4
63 34 3
63 35 2
63 36 1
63 37 0
64 1 35
64 3 33
64 5 31
64 7 29
64 9 27
64 11 25
64 13 23
64 15 21
64 17 19
64 19 17
64 21 15
64 23 13
64 25 11
64 27 9
64 29 7
64 31 5
64 33 3
64 35 1
65 1 34
65 2 33
65 3 32
65 4 31
65 6 29
65 7 28
65 8 27
65 9 26
65 11 24
65 12 23
65 13 22
65 14 21
65 16 19
65 17 18
65 18 17
65 19 16
65 21 14
65 22 13
65 23 12
65 24 11
65 26 9
65 27 8
65 28 7
65 29 6
65 31 4
65 32 3
65 33 2
65 34 1
66 1 33
66 3 31
66 5 29
66 7 27
66 9 25
66 11 23
66 13 21
66 15 19
66 17 17
66 19 15
66 21 13
66 23 11
66 25 9
66 27 7
66 29 5
66 31 3
66 33 1
67 0 33
67 1 32
67 2 31
67 3 30
67 4 29
67 5 28
67 6 27
67 7 26
67 8 25
67 9 24
67 10 23
67 11 22
67 12 21
67 13 20
67 14 19
67 15 18
67 16 17
67 17 16
67 18 15
67 19 14
67 20 13
67 21 12
67 22 11
67 23 10
67 24 9
67 25 8
67 26 7
67 27 6
67 28 5
67 29 4
67 30 3
67 31 2
67 32 1
67 33 0
68 1 31
68 3 29
68 5 27
68 7 25
68 9 23
68 11 21
68 13 19
68 15 17
68 17 15
68 19 13
68 21 11
68 23 9
68 25 7
68 27 5
68 29 3
68 31 1
69 0 31
69 1 30
69 2 29
69 3 28
69 4 27
69 5 26
69 6 25
69 7 24
69 8 23
69 9 22
69 10 21
69 11 20
69 12 19
69 13 18
69 14 17
69 15 16
69 16 15
69 17 14
69 18 13
69 19 12
69 20 11
69 21 10
69 22 9
69 23 8
69 24 7
69 25 6
69 26 5
69 27 4
69 28 3
69 29 2
69 30 1
69 31 0
70 1 29
70 3 27
70 7 23
70 9 21
70 11 19
70 13 17
70 17 13
70 19 11
70 21 9
70 23 7
70 27 3
70 29 1
71 0 29
71 1 28
71 2 27
71 3 26
71 4 25
71 5 24
71 6 23
71 7 22
71 8 21
71 9 20
71 10 19
71 11 18
71 12 17
71 13 16
71 14 15
71 15 14
71 16 13
71 17 12
71 18 11
71 19 10
71 20 9
71 21 8
71 22 7
71 23 6
71 24 5
71 25 4
71 26 3
71 27 2
71 28 1
71 29 0
72 1 27
72 3 25
72 5 23
72 7 21
72 9 19
72 11 17
72 13 15
72 15 13
72 17 11
72 19 9
72 21 7
72 23 5
72 25 3
72 27 1
73 0 27
73 1 26
73 2 25
73 3 24
73 4 23
73 5 22
73 6 21
73 7 20
73 8 19
73 9 18
73 10 17
73 11 16
73 12 15
73 13 14
73 14 13
73 15 12
73 16 11
73 17 10
73 18 9
73 19 8
73 20 7
73 21 6
73 22 5
73 23 4
73 24 3
73 25 2
73 26 1
73 27 0
74 1 25
74 3 23
74 5 21
74 7 19
74 9 17
74 11 15
74 13 13
74 15 11
74 17 9
74 19 7
74 21 5
74 23 3
74 25 1
75 1 24
75 2 23
75 3 22
75 4 21
75 6 19
75 7 18
75 8 17
75 9 16
75 11 14
75 12 13
75 13 12
75 14 11
75 16 9
75 17 8
75 18 7
75 19 6
75 21 4
75 22 3
75 23 2
75 24 1
76 1 23
76 3 21
76 5 19
76 7 17
76 9 15
76 11 13
76 13 11
76 15 9
76 17 7
76 19 5
76 21 3
76 23 1
77 0 23
77 1 22
77 2 21
77 3 20
77 4 19
77 5 18
77 6 17
77 7 16
77 8 15
77 9 14
77 10 13
77 11 12
77 12 11
77 13 10
77 14 9
77 15 8
77 16 7
77 17 6
77 18 5
77 19 4
77 20 3
77 21 2
77 22 1
77 23 0
78 1 21
78 3 19
78 5 17
78 7 15
78 9 13
78 11 11
78 13 9
78 15 7
78 17 5
78 19 3
78 21 1
79 0 21
79 1 20
79 2 19
79 3 18
79 4 17
79 5 16
79 6 15
79 7 14
79 8 13
79 9 12
79 10 11
79 11 10
79 12 9
79 13 8
79 14 7
79 15 6
79 16 5
79 17 4
79 18 3
79 19 2
79 20 1
79 21 0
80 1 19
80 3 17
80 7 13
80 9 11
80 11 9
80 13 7
80 17 3
80 19 1
81 0 19
81 1 18
81 2 17
81 3 16
81 4 15
81 5 14
81 6 13
81 7 12
81 8 11
81 9 10
81 10 9
81 11 8
81 12 7
81 13 6
81 14 5
81 15 4
81 16 3
81 17 2
81 18 1
81 19 0
82 1 17
82 3 15
82 5 13
82 7 11
82 9 9
82 11 7
82 13 5
82 15 3
82 17 1
83 0 17
83 1 16
83 2 15
83 3 14
83 4 13
83 5 12
83 6 11
83 7 10
83 8 9
83 9 8
83 10 7
83 11 6
83 12 5
83 13 4
83 14 3
83 15 2
83 16 1
83 17 0
84 1 15
84 3 13
84 5 11
84 7 9
84 9 7
84 11 5
84 13 3
84 15 1
85 1 14
85 2 13
85 3 12
85 4 11
85 6 9
85 7 8
85 8 7
85 9 6
85 11 4
85 12 3
85 13 2
85 14 1
86 1 13
86 3 11
86 5 9
86 7 7
86 9 5
86 11 3
86 13 1
87 0 13
87 1 12
87 2 11
87 3 10
87 4 9
87 5 8
87 6 7
87 7 6
87 8 5
87 9 4
87 10 3
87 11 2
87 12 1
87 13 0
88 1 11
88 3 9
88 5 7
88 7 5
88 9 3
88 11 1
89 0 11
89 1 10
89 2 9
89 3 8
89 4 7
89 5 6
89 6 5
89 7 4
89 8 3
89 9 2
89 10 1
89 11 0
90 1 9
90 3 7
90 7 3
90 9 1
91 0 9
91 1 8
91 2 7
91 3 6
91 4 5
91 5 4
91 6 3
91 7 2
91 8 1
91 9 0
92 1 7
92 3 5
92 5 3
92 7 1
93 0 7
93 1 6
93 2 5
93 3 4
93 4 3
93 5 2
93 6 1
93 7 0
94 1 5
94 3 3
94 5 1
95 1 4
95 2 3
95 3 2
95 4 1
96 1 3
96 3 1
97 0 3
97 1 2
97 2 1
97 3 0
98 1 1
99 0 1
99 1 0

In [ ]:
from math import gcd
ct=0
for i in range(101):
    for j in range(i, 101):
        a = i
        b = j-i
        c = 100-j
        if gcd(a,gcd(b,c))!=1:
            continue
            ct+=1
print(ct)