#!/usr/bin/python3

import sys

class ModClass:
    def __init__(self, m, r):
        self.m = m
        self.r = r % m

    def clone(self):
        return ModClass(self.m, self.r)

    def is_even(self):
        '''True or False; None if it cannot tell'''

        m_even = (self.m & 1) == 0
        r_even = (self.r & 1) == 0

        if m_even:
            if r_even:
                return True
            return False
        return None

    def collatz(self):
        '''Residue class after one iteration
        of the "reduced" Collatz process
        (it uses the rule (3n+1)/2 for odds, instead of just 3n+1);
        None if it cannot tell what to do next'''

        even = self.is_even()
        if even is None:
            return None

        if even:
            return ModClass(self.m >> 1, self.r >> 1)

        return ModClass((self.m * 3) >> 1, (self.r * 3 + 1) >> 1)

    def __repr__(self):
        if self.m == 1:
            return 'any' # instead of "1k+0"; meaning, "cannot tell"

        return '{}k+{}'.format(self.m, self.r)

if __name__ == '__main__':
    def usage():
        print('Usage:', sys.argv[0], '[-v]', 'm', 'r')
        sys.exit(1)

    opt_verbose = False

    args = sys.argv[1:]
    if args and args[0] == '-v':
        opt_verbose = True
        args = args[1:]

    if len(args) != 2:
        usage()
    try:
        m = int(args[0])
        r = int(args[1])
    except Exception as e:
        print(e)
        usage()

    c0 = ModClass(m, r)
    vector = []

    c = c0.clone()
    even = c.is_even()
    while even is not None:
        if opt_verbose:
            print('... Iteration', len(vector), 'class', c)

        vector.append(0 if even else 1)
        c = c.collatz()
        even = c.is_even()

    print('Known beginning of the parity vector for {}:'.format(c0))
    print(vector)
    iters = len(vector)
    print('Class after', iters,
          'iteration{}:'.format('' if iters == 1 else 's'), c)
