'''
Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are
all figurate (polygonal) numbers and are generated by the following formulae:

Triangle	P3,n=n(n+1)/2	    1, 3, 6, 10, 15, ...
Square	 	P4,n=n2	 	    1, 4, 9, 16, 25, ...
Pentagonal	P5,n=n(3n1)/2	    1, 5, 12, 22, 35, ...
Hexagonal	P6,n=n(2n1)	    1, 6, 15, 28, 45, ...
Heptagonal	P7,n=n(5n3)/2	    1, 7, 18, 34, 55, ...
Octagonal	P8,n=n(3n2)	    1, 8, 21, 40, 65, ...
The ordered set of three 4-digit numbers: 8128, 2882, 8281, has three
interesting properties.

The set is cyclic, in that the last two digits of each number is the first two
digits of the next number (including the last number with the first).
Each polygonal type: triangle (P3,127=8128), square (P4,91=8281), and
pentagonal (P5,44=2882), is represented by a different number in the set.
This is the only set of 4-digit numbers with this property.
Find the sum of the only ordered set of six cyclic 4-digit numbers for which
each polygonal type: triangle, square, pentagonal, hexagonal, heptagonal, and
octagonal, is represented by a different number in the set.
'''
from itertools import permutations

def P(i,n):
    if i == 3: return (n*n+n)/2
    if i == 4: return n*n
    if i == 5 :return (3*n*n-n)/2
    if i == 6: return 2*n*n-n
    if i == 7: return (5*n*n-3*n)/2
    return 3*n*n-2*n    #i = 8

limits = ((45,141),(32,100),(26,82),(23,71),(21,64),(19,59))
PStr,P2 = {},{}

#PStr will contain all 4 digit numbers generated by the function P
#P2 will contain a list of numbers that has the same front 2 digits
#example: P2[3]['10'] = ['1035','1081']
for i in xrange(3,9):
    PStr[i],P2[i] = [],{}
    for n in xrange(limits[i-3][0],limits[i-3][1]):
        PStr[i].append(str(P(i,n)))
    for n in PStr[i]:
        try: P2[i][n[:2]].append(n)
        except: P2[i][n[:2]] = [n]

solutionSum = 0
for o in permutations((3,4,5,6,7,8),6):
    for n1 in PStr[o[0]]:
        if P2[o[1]].has_key(n1[2:]):
            for n2 in P2[o[1]][n1[2:]]:
                if P2[o[2]].has_key(n2[2:]):
                    for n3 in P2[o[2]][n2[2:]]:
                        if P2[o[3]].has_key(n3[2:]):
                            for n4 in P2[o[3]][n3[2:]]:
                                if P2[o[4]].has_key(n4[2:]):
                                    for n5 in P2[o[4]][n4[2:]]:
                                        if P2[o[5]].has_key(n5[2:]):
                                            for n6 in P2[o[5]][n5[2:]]:
                                                if n1[:2] == n6[2:]:
                                                    for s in [n1,n2,n3,n4,n5,n6]:
                                                        solutionSum += int(s)
                                                    print solutionSum
                                                    quit()
