# RNA secondary structure
# (strings are treated as one-index to match text)

matches = { 'A':'U', 'U':'A', 'C':'G', 'G':'C' }
MINSEP = 4   # separation between paired bases

rna = ' ' + raw_input('Enter original RNA: ').upper()   # one-indexed
n = len(rna)-1

opt = {}

# base cases
for start in range(1,len(rna)):
    opt[(start,start-1)] = 0
    opt[(start,start)] = 0


# calculate all subproblems of given width
for width in range(2,len(rna)+1):
    for i in range(1, len(rna)-width+1):
        # solve subproblem (i,j)
        j = i+width-1
        best = opt[(i,j-1)]   # default
        for t in range(i,j-MINSEP):
            if matches[rna[j]] == rna[t]:
                alternate = 1 + opt[(i,t-1)] + opt[(t+1,j-1)]
                if alternate>best:
                    best = alternate
        opt[(i,j)] = best




# print results
for i in range(len(rna)-1,0,-1):
    print '%2d=%s'%(i,rna[i]),
    for j in range(1,len(rna)+1):
        if not (i,j) in opt:
            col = '  '
        else:
            col = '%2d'%opt[(i,j)]
        print col,
    print

# print bottom axis
print
print '    ',
for j in range(1,len(rna)):
    print '%2d'%j,
print

print '    ',
for j in range(1,len(rna)):
    print '%2s'%rna[j],
print
    



def getSolution(i,j):
    possible = opt[ (i,j) ]
    if possible == 0:
        return []
    else:
        if opt[ (i,j-1) ] == possible:
            return getSolution(i,j-1)
        else:
            for t in range(i,j-MINSEP):
                if matches[rna[j]] == rna[t]:
                    alternate = 1 + opt[(i,t-1)] + opt[(t+1,j-1)]
                    if alternate == possible:
                        return getSolution(i,t-1) + [ (t,j) ] + \
                               getSolution(t+1,j-1)
        


print
print
print 'The maximum number of matches is', opt[(1,n)]
print
print 'Matches are', getSolution(1,n)






