def chain_add(seq, end):
    a = len(seq)
    for i in range(end-a):
        seq += chr(48+(ord(seq[i])+ord(seq[i+1]))%32%10)
    return seq

def sequent(seq):
    res = [0]*len(seq);seq=list(seq)
    for z in range(len(seq)):
        b=min(range(len(seq)),key=lambda i:seq[i])
        res[b]=z
        seq[b]="~"
    return res

def transpose(text, keys, disrupt=False):
    if disrupt:
        num_rows, len_last = divmod(len(text),len(keys))
        num_rows+=1
        if len_last==0:len_last=len(keys)
        d_rows = []
        for i in range(num_rows):
            d_rows += [[]]
        text_index = 0
        current_row = 0
        stop_key = 0
        stop_index = keys.index(stop_key)
        while current_row < num_rows:
            d_rows[current_row]=list(text[text_index:text_index+stop_index])
            text_index+=stop_index
            stop_index+=1
            if stop_index>len(keys):
                stop_key=(stop_key+1)%len(keys)
                stop_index=keys.index(stop_key)
            current_row+=1
        current_row = 0
        stop_key = 0
        stop_len = len(keys)-keys.index(stop_key)
        while current_row < num_rows:
            d_rows[current_row]+=list(text[text_index:text_index+stop_len])
            text_index+=stop_len
            stop_len-=1
            if stop_len<1:
                stop_key+=1
                stop_len=len(keys)-keys.index(stop_key)
                current_row+=1
            current_row+=1
        d_rows[-1]+=['']*(len(keys)-len(d_rows[-1]))
        columns = []
        for j in range(len(keys)):
            columns+=[''.join(i[j]for i in d_rows)]
    else:
        columns = ['']*len(keys)
        for t in range(len(text)):
            columns[t%len(keys)]+=text[t]
    res = [0]*len(keys)
    for index in range(len(keys)):
        res[keys[index]]=columns[index]
    return''.join(res)

def checkerboard(message, seq, word, null):
    trans = {".":seq[-2:], "#":seq[-1]*2};m=65;res=''
    for i in range(len(word)):
        trans[word[i]]=seq[i]
        for z in[0,1]:
            while chr(m)in word:
                m+=1
            trans[chr(m)]=seq[z-2]+seq[i];m+=1
    while m<90:
        for i in seq[len(word):]:
            for z in[0,1]:
                while chr(m)in word:
                    m+=1
                trans[chr(m)]=seq[z-2]+i;m+=1
    for i in message:
        if i.isdigit():
            res+=i
        else:
            res+=trans[i]
    return res+null[:-len(res)%5]

def vic_cipher(message, keyword, phrase, date, agent, m_id, null):
    s1=sequent(phrase[:10])
    s2=sequent(phrase[10:20])
    a=g=t=""
    for i in range(5):
        a+=str((int(m_id[i])-int(date[i]))%10)
    a=chain_add(a,10)
    for i in range(10):
        g+=str((int(a[i])+int(s1[i]))%10)
    for i in range(10):
        t+=str(s2[int(g[i])])
    u=chain_add(t,60)[10:]
    p=agent+int(u[-2])
    q=agent+int(u[-1])
    seqT=sequent(t)
    v=transpose(u,seqT)
    k1=sequent(v[:p])
    k2=sequent(v[p:p+q])
    c=''.join(str(i)for i in sequent(u[40:]))
    x=checkerboard(message,c,keyword,null)
    y=transpose(x,k1)
    z=transpose(y,k2,1)
    e=[z[5*i:5*-~i]for i in range(-(-len(z)//5))]
    return' '.join(e[:1-int(date[-1])]+[m_id]+e[1-int(date[-1]):])

print(vic_cipher("HINGELSE.MOVETOSAFEHOUSEFOXTROT#3#..WEAREDISCOVERED.TAKEWHATYOUCAN.BURNEVERYT",\
"SENATORI","THEFIRSTPRINCIPLEIST","3172016",9,"47921","4561"))