Term = Struct.new(:coeff, :ix1, :ix2) do
end

MAX_DIGITS = 16

def toLong(digits, reverse)
    sum = 0
    if reverse then
        i = digits.length - 1
        while i >=0
            sum = sum  *10 + digits[i]
            i = i - 1
        end
    else
        i = 0
        while i < digits.length
            sum = sum * 10 + digits[i]
            i = i + 1
        end
    end
    return sum
end

def isSquare(n)
    root = Math.sqrt(n).to_i
    return root * root == n
end

def seq(from, to, step)
    res = []
    i = from
    while i <= to
        res << i
        i = i + step
    end
    return res
end

def format_number(number)
  number.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
end

def main
    pow = 1
    allTerms = []
    for i in 0 .. MAX_DIGITS - 2
        allTerms << []
    end
    for r in 2 .. MAX_DIGITS
        terms = []
        pow = pow * 10
        pow1 = pow
        pow2 = 1
        i1 = 0
        i2 = r - 1
        while i1 < i2
            terms << Term.new(pow1 - pow2, i1, i2)
            pow1 = (pow1 / 10).to_i
            pow2 = pow2 * 10
            i1 = i1 + 1
            i2 = i2 - 1
        end
        allTerms[r - 2] = terms
    end
    
    fml = {
        0 =>[[2, 2], [8, 8]],
        1 =>[[6, 5], [8, 7]],
        4 =>[[4, 0]],
        6 =>[[6, 0], [8, 2]]
    }
    
    dmd = {}
    for i in 0 .. 99
        a = [(i / 10).to_i, (i % 10)]
        d = a[0] - a[1]
        if dmd.include?(d) then
            dmd[d] << a
        else
            dmd[d] = [a]
        end
    end
    fl = [0, 1, 4, 6]
    dl = seq(-9, 9, 1) 
    zl = [0]           
    el = seq(-8, 8, 2) 
    ol = seq(-9, 9, 2) 
    il = seq(0, 9, 1)
    rares = []
    lists = []
    for i in 0 .. 3
        lists << []
    end
    fl.each_with_index { |f, i|
        lists[i] = [[f]]
    }
    digits = []
    count = 0

    
    
    fnpr = lambda { |cand, di, dis, indices, nmr, nd, level|
        if level == dis.length then
            digits[indices[0][0]] = fml[cand[0]][di[0]][0]
            digits[indices[0][1]] = fml[cand[0]][di[0]][1]
            le = di.length
            if nd % 2 == 1 then
                le = le - 1
                digits[(nd / 2).to_i] = di[le]
            end
            di[1 .. le - 1].each_with_index { |d, i|
                digits[indices[i + 1][0]] = dmd[cand[i + 1]][d][0]
                digits[indices[i + 1][1]] = dmd[cand[i + 1]][d][1]
            }
            r = toLong(digits, true)
            npr = nmr + 2 * r
            if not isSquare(npr) then
                return
            end
            count = count + 1
            print  % [count]
            n = toLong(digits, false)
            print  % [format_number(n)]
            rares << n
        else
            for num in dis[level]
                di[level] = num
                fnpr.call(cand, di, dis, indices, nmr, nd, level + 1)
            end
        end
    }

    
    fnmr = lambda { |cand, list, indices, nd, level|
        if level == list.length then
            nmr = 0
            nmr2 = 0
            allTerms[nd - 2].each_with_index { |t, i|
                if cand[i] >= 0 then
                    nmr = nmr + t.coeff * cand[i]
                else
                    nmr2 = nmr2 = t.coeff * -cand[i]
                    if nmr >= nmr2 then
                        nmr = nmr - nmr2
                        nmr2 = 0
                    else
                        nmr2 = nmr2 - nmr
                        nmr = 0
                    end
                end
            }
            if nmr2 >= nmr then
                return
            end
            nmr = nmr - nmr2
            if not isSquare(nmr) then
                return
            end
            dis = []
            dis << seq(0, fml[cand[0]].length - 1, 1)
            for i in 1 .. cand.length - 1
                dis << seq(0, dmd[cand[i]].length - 1, 1)
            end
            if nd % 2 == 1 then
                dis << il.dup
            end
            di = []
            for i in 0 .. dis.length - 1
                di << 0
            end
            fnpr.call(cand, di, dis, indices, nmr, nd, 0)
        else
            for num in list[level]
                cand[level] = num
                fnmr.call(cand, list, indices, nd, level + 1)
            end
        end
    }

    
    for nd in 2 .. 10
        digits = []
        for i in 0 .. nd - 1
            digits << 0
        end
        if nd == 4 then
            lists[0] << zl.dup
            lists[1] << ol.dup
            lists[2] << el.dup
            lists[3] << ol.dup
        elsif allTerms[nd - 2].length > lists[0].length then
            for i in 0 .. 3
                lists[i] << dl.dup
            end
        end
        indices = []
        for t in allTerms[nd - 2]
            indices << [t.ix1, t.ix2]
        end
        for list in lists
            cand = []
            for i in 0 .. list.length - 1
                cand << 0
            end
            fnmr.call(cand, list, indices, nd, 0)
        end
        print  % [nd]
    end

    rares.sort()
    print  % [MAX_DIGITS]
    rares.each_with_index { |rare, i|
        print  % [i + 1, format_number(rare)]
    }
end

main()