#!/usr/bin/env python3

########################################################################

# You can manually generate the dictionary containing the codons by
# running

# cat codons.txt | ./codons.py

# from this directory. Assuming you didn't move around anything, the use
# case is simply

# ./do.sh rosalind_answers.txt

# or if you want to skip the shell script

# cat rosalind_answers.txt | python3 fasta-stripper.py | python3 orf.py > ans.txt

# to get the answers printed to ans.txt.

########################################################################

import sys, pickle

codons = pickle.load(open("codons_dict.pickle", "rb"))
dna = {'A':'T', 'C':'G', 'G':'C', 'T':'A'}

def rc(s):
    """Generates the reverse complement of a DNA string."""
    r = list()
    g = ""
    for x in s:
        assert x in dna
        r += dna[x]
    for y in reversed(r):
        g += y
    return g

def dna2rna(s):
    """Takes in a string of DNA and returns it with as an RNA sequence
    (all Ts become Us)."""

    ret = ""
    for letter in map(lambda x: 'U' if x == 'T' else x, s):
        ret += letter
    return ret

def rna2aa(s):
    """Takes in a string of RNA and returns if as a list of their
    associated amino acids."""

    ret = list()
    for x in [s[i:i+3] for i in range(0, len(s), 3)]:
        if len(x) == 3:
            ret.append(codons[x])
        else:
            continue
    return ret

def aa_orfs(s):
    """Takes in a list of amino acids and outputs a list of lists
    of the open reading frames contained therein."""
    count = 0
    ret = list()
    while count < len(s):
        if s[count] == "M":
            # Once we hit a start codon, scan through until the
            # first stop codon.
            count_2 = 0
            for n in s[count:]:
                count_2 += 1
                if n == "Stop":
                    ret.append((count, count+count_2))
                    break
                else:
                    continue
        else:
            pass
        count += 1
    return ret

def orfs(s):
    """Takes in a list of amino acids and outputs a list of strings of
    their open reading frames."""

    orf_positions = aa_orfs(s)
    ret = list()
    for pair in orf_positions:
        orf = ""
        for x in s[pair[0]:pair[1]-1]:
            orf += x
        ret.append(orf)
    return ret

def candidates(s):
    """Takes in a DNA string and returns a list of all the possible
    open reading frames it has."""
    x = rna2aa(dna2rna(s[0:]))
    y = rna2aa(dna2rna(s[1:]))
    z = rna2aa(dna2rna(s[2:]))

    xr = rna2aa(dna2rna(rc(s)[0:]))
    yr = rna2aa(dna2rna(rc(s)[1:]))
    zr = rna2aa(dna2rna(rc(s)[2:]))
    ret = list(set(orfs(x) + orfs(y) + orfs(z)
                   + orfs(xr) + orfs(yr) + orfs(zr)))
    return ret
    
    

if __name__=="__main__":
    rna = ""
    for line in sys.stdin:
        for x in candidates(line.strip()):
            print(x)
