def add_carmichael_pfd(n):
    Lsub_n.append(n)
    this_n = len(Lsub_n)-1
    Lsub_pfd.append([(2,1)])
    
    #if (n+1) in primes_list:
    if sum(1 for div in divisorGen(n+1))==2:
        #first look if n+1 is prime, if yes add 
        Lsub_pfd[this_n].append((n+1,1)) 
    
    if n in powers_of_2_list:
        #also check if this new value is a power of 2
        Lsub_pfd[this_n].append((2,2+int(math.log(n,2))))
    #print Lsub_pfd
    
    divisors_fcn = list(divisorGen(n))
    
    #aggregate the prime fact decomps of the max_pfd for each divisor
    #merge like primes by keeping the max value for a
    p_list_fcn = []
    a_list_fcn = []
    for j in divisors_fcn:
        if j!=1 and j!=n:
            if j not in Lsub_n:
                add_carmichael_pfd(j)
            
            this_j = Lsub_n.index(j)
            for p_a_fcn in Lsub_pfd[this_j]:
                if len(p_a_fcn)>0:
                    if p_a_fcn[0] in p_list_fcn:
                        p_list_id_fcn = p_list_fcn.index(p_a_fcn[0]) 
                        a_list_fcn[p_list_id] = max(a_list_fcn[p_list_id_fcn],p_a_fcn[1])
                    else:
                        p_list_fcn.append(p_a_fcn[0]) 
                        a_list_fcn.append(p_a_fcn[1])
    #print p_list_fcn
    #print a_list_fcn
    
    for j in xrange(len(p_list_fcn)):
        if not p_list_fcn[j]==2:
            #p=2 has a different formula
            a_list_fcn[j] = max_pow( n / carmichael_1fact(p_list_fcn[j],a_list_fcn[j]) ,p_list_fcn[j]) + a_list_fcn[j]
         else:
             p_list.append(p_a[0]) 
             a_list.append(p_a[1])
 #print p_list
 #print a_list
 
 #check if any primes further divide n
 #also we calc Lsub[n] by iteratively multiplying by p**a as we determine the max power for a
 Lsub_list_next = 1
 for i in xrange(len(p_list)):
     #we know p**a divides n
     #check if p**(a+1) divides n
     #or just find b s.t. p**b divides (n/ p**a), so then max power is a+b
     if not p_list[i]==2:
         #p=2 has a different formula
         a_list[i] = max_pow( n / carmichael_1fact(p_list[i],a_list[i]) ,p_list[i]) + a_list[i]
     
     Lsub_list_next = Lsub_list_next * p_list[i]**a_list[i]
 Lsub_list.append(Lsub_list_next)
 
 #save the max_pfd
 Lsub_pfd[n]=[]
 for i in xrange(len(p_list)):
     Lsub_pfd[n].append((p_list[i],a_list[i]))
 
 if n%10000==0:
     print '\n' + 'done ' + str(n) + ', ~' + "{0:.1%}".format(float(n)/float(total)) 
     print len(str(max(Lsub_list)))
     
     last_time = t5
     t5 = time.time()
    # also we calc Lsub[n] by iteratively multiplying by p**a as we determine the max power for a
    Lsub_list_next = 1
    for i in xrange(len(p_list)):
        # we know p**a divides n
        # check if p**(a+1) divides n
        # or just find b s.t. p**b divides (n/ p**a), so then max power is a+b
        if p_list[i] == 2:
            if n % 4 == 0:
                a = 2 + int(math.log(n, 2))
            elif n % 2 == 0:
                a = 3
            else:
                a = 1

        else:
            a = max_pow(n / carmichael_1fact(p_list[i], 1), p_list[i]) + 1

        Lsub_list_next = Lsub_list_next * p_list[i] ** a

    if sum(1 for div in divisorGen(n + 1)) == 2:
        Lsub_list_next = Lsub_list_next * (n + 1)

    Lsub_list.append(Lsub_list_next)

    if n % 10000 == 0:
        print "\n" + "done " + str(n) + ", ~" + "{0:.1%}".format(float(n) / float(total))
        print len(str(max(Lsub_list)))

        last_time = t5
        t5 = time.time()
        print t5 - t3