The square-ten tree decomposition of an array is defined as follows:

The lowest (${0}^{t h}$) level of the square-ten tree consists of single array elements in their natural order.
The $k^{th}$ level (starting from $1$) of the square-ten tree consists of subsequent array subsegments of length $10^{2^{k-1}}$ in their natural order. Thus, the $1^{st}$ level contains subsegments of length $10^{2^{1-1}}=10$, the $2^{nd}$ level contains subsegments of length $10^{2^{2-1}}=100$, the $3^{rd}$ level contains subsegments of length $10^{2^{3-1}}=10000$, etc.

In other words, every $k^{th}$ level (for every $k\geq1$) of square-ten tree consists of array subsegments indexed as: 
$\left[1,\:10^{2^{k-1}}\right],\left[10^{2^{k-1}}+1,\:2\cdot10^{2^{k-1}}\right],...,\left[i\cdot10^{2^{k-1}}+1,\:(i+1)\cdot10^{2^{k-1}}\right],...$
Level $\mbox{0}$ consists of array subsegments indexed as $[1,\:1],[2,\:2],\ldots,[i,\:i],\ldots$.

The image below depicts the bottom-left corner (i.e., the first $\textbf{128}$ array elements) of the table representing a square-ten tree. The levels are numbered from bottom to top:

Task 

Given the borders of array subsegment $[L,R]$, find its decomposition into a minimal number of nodes of a square-ten tree. In other words, you must find a subsegment sequence $[l_1,r_1],[l_2,r_2],\ldots,[l_m,r_m]$ such as $l_{i+1}=r_{i}+1$ for every $1\leq i\lt m$, $l_1=L$, $r_m=R$, where every $[l_i,r_i]$ belongs to any of the square-ten tree levels and $m$ is minimal amongst all such variants.

Input Format

The first line contains a single integer denoting $\boldsymbol{\mbox{L}}$. 

The second line contains a single integer denoting $\mbox{R}$.

Constraints

$1\leq L\leq R\leq10^{10^6}$
The numbers in input do not contain leading zeroes.

Output Format

As soon as array indices are too large, you should find a sequence of $m$ square-ten tree level numbers, $s_1,s_2,\ldots,s_m$, meaning that subsegment $[l_i,r_i]$ belongs to the $s_i^{th}$ level of the square-ten tree. 

Print this sequence in the following compressed format: 

On the first line, print the value of $n$ (i.e., the compressed sequence block count). 
For each of the $n$ subsequent lines, print $2$ space-separated integers, $t_i$ and $c_i$ ($t_i\geq0$, $c_i\geq1$), meaning that the number $t_i$ appears consequently $c_i$ times in sequence $\boldsymbol{\mathrm{~S~}}$. Blocks should be listed in the order they appear in the sequence. In other words, $s_{1},s_{2},\ldots,s_{c_{1}}$ should be equal to $\boldsymbol{t_1}$, $\textbf{s}_{c_1+1},\textbf{s}_{c_1+2},\cdots,\textbf{s}_{c_1+c_2}$ should be equal to $t_2$, etc.

Thus $\sum\limits_{i=1}^{n}c_{i}=m$ must be true and $t_i\neq t_{i+1}$ must be true for every $1\leq i\lt n$. All numbers should be printed without leading zeroes.

Sample Input 0
1
10

Sample Output 0
1
1 1

Explanation 0

Segment $[1,10]$ belongs to level $1$ of the square-ten tree.

Source: hackerrank | Difficulty: MEDIUM_HARD
Tags: Tree algorithms


Solutions:
L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


from sys import stderr

def sub1(x):
	for (i, c) in enumerate(reversed(x)):
		if c != '0':
			return x[:-i - 1] + str(int(c) - 1) + '9' * i
	assert False

def treeints(lo, hi):
	lo = sub1(lo)
	lo = '0' * (len(hi) - len(lo)) + lo
	loarr = [int(lo[-1])]
	hiarr = [hi[-1]]
	maxarr = [10]
	curlen = 1
	last = len(lo) - 1
	while last > 0:
		first = max(0, last - curlen)
		loarr.append(int(lo[first:last]))
		hiarr.append(hi[first:last])
		maxarr.append(10 ** curlen)
		curlen *= 2
		last = first
	while loarr[-1] == hiarr[-1]:
		loarr.pop()
		hiarr.pop()
	ans = []
	carry = 0
	for lvl in range(len(loarr) - 1):
		elt = loarr[lvl] + carry
		maxelt = maxarr[lvl]
		if elt == 0 or elt == maxelt:
			continue
		ans.append((lvl, maxelt - elt))
		carry = 1
	cnt = int(hiarr[-1]) - loarr[-1] - carry
	if cnt != 0:
		ans.append((len(loarr) - 1, cnt))
	for lvl in range(len(loarr) - 2, -1, -1):
		q = hiarr[lvl].lstrip('0')
		if q == '':
			continue
		if ans and ans[-1][0] == lvl:
			cnt0 = ans[-1][1]
			ans[-1] = (lvl, int(cnt0) + int(q))
		else:
			ans.append((lvl, q))
	return ans
lo = input().strip()
hi = input().strip()
compsec = treeints(lo, hi)
print(len(compsec))
for (lvl, cnt) in compsec:
	print(lvl, cnt)


l = input()
r = input()
ld = []
rd = []
powers = []
levels = []
powten = 10
level = 0
d = 1
while r != '':
	if l == '':
		ld.append(0)
	else:
		ld.append(int(l[-d:]))
	rr = r[-d:]
	j = 0
	while j < d and rr[j] == '0':
		j += 1
	rd.append(rr[j:])
	l = l[:-d]
	r = r[:-d]
	powers.append(powten)
	levels.append(level)
	level += 1
	if level > 1:
		d *= 2
	if level > 1:
		powten *= powten
m = 1
for i in range(0, level):
	d = (powers[i] + ld[i] - m) % powers[i]
	if ld[i] < m:
		m = 1
	else:
		m = 0
	ld[i] = d
s = level - 1
while ld[s] == rd[s]:
	s -= 1
t = []
c = []
rs = int(rd[s])
i = 0
while i < s and ld[i] == 0:
	i += 1
if i < s:
	c.append(powers[i] - ld[i])
	t.append(i)
	i += 1
	while i < s:
		if powers[i] - ld[i] - 1 > 0:
			c.append(powers[i] - ld[i] - 1)
			t.append(i)
		i += 1
	if rs - ld[s] - 1 > 0:
		c.append(rs - ld[s] - 1)
		t.append(s)
else:
	c.append(rs - ld[s])
	t.append(s)
for i in range(s - 1, -1, -1):
	if rd[i] != '':
		c.append(rd[i])
		t.append(i)
n = len(t)
print(n)
for i in range(0, n):
	print(t[i], c[i])


import math
(L, R) = (input(), input())

def to_i(ch):
	return ord(ch) - 48

def to_c(i):
	return chr(i + 48)

def rindex(S, i):
	if i < len(S):
		return to_i(S[-i - 1])
	return 0

def out(k, arr):
	return
subtrahend = 11
next_subtrahend = 10
(b, e) = (0, 0)
pairs = []
max_k = 1
if len(R) > 1:
	max_k = math.floor(math.log2(len(R) - 1)) + 1
	for k in range(0, max_k):
		b = e
		e = 2 ** k
		if e >= len(R):
			break
		need_print = False
		arr = bytearray()
		for j in range(b, e):
			l = rindex(L, j)
			s = (subtrahend - l) % 10
			if s:
				need_print = True
			arr.append(s)
			if subtrahend == 11:
				if l == 0:
					subtrahend = 10
				elif l == 1:
					subtrahend = 10
				else:
					subtrahend = 9
			elif subtrahend == 10:
				if l:
					subtrahend = 9
		if need_print:
			while len(arr) and arr[-1] == 0:
				arr.pop()
			pairs.append((k, arr[::-1]))
			out(k, arr)
	arr = bytearray()
	need_print = False
	subtrahend = 10
	if len(pairs) == 0:
		subtrahend = 11
	b = 2 ** (max_k - 1)
	for j in range(b, len(R)):
		r = rindex(R, j)
		l = rindex(L, j)
		s = (subtrahend + r - l - 1) % 10
		subtrahend = 10 + (subtrahend + r - l - 1) // 10
		arr.append(s)
		if s:
			need_print = True
		if r:
			e = j + 1
			break
	for j in range(e, len(R)):
		need_print = True
		l = rindex(L, j)
		r = rindex(R, j)
		arr.append((subtrahend + r - l - 1) % 10)
		subtrahend = 10 + (subtrahend + r - l - 1) // 10
	while len(arr) and arr[-1] == 0:
		arr.pop()
	if len(arr):
		pairs.append((max_k, arr[::-1]))
		out(max_k, arr)
b = 2 ** (max_k - 1)
for k in range(max_k - 1, -1, -1):
	e = b
	b = 0
	if k:
		b = 2 ** (k - 1)
	arr = bytearray()
	ee = b - 1
	for j in range(min(e, len(R)) - 1, b - 1, -1):
		if rindex(R, j):
			ee = j
			break
	for j in range(ee, b - 1, -1):
		arr.append(rindex(R, j))
	if len(arr):
		pairs.append((k, arr))
		out(k, arr[::-1])
print(len(pairs))
for p in pairs:
	print(p[0], end=' ')
	for x in p[1]:
		print(x, end='')
	print('')


def string_plus(n, m, carry=0):
	n = n[::-1]
	m = m[::-1]
	ptr = 0
	result = []
	if len(m) > len(n):
		(m, n) = (n, m)
	while ptr < len(m):
		r = int(n[ptr]) + int(m[ptr]) + carry
		if r > 9:
			r -= 10
			carry = 1
		else:
			carry = 0
		result.append(str(r))
		ptr += 1
	while ptr < len(n):
		if carry == 0:
			result.append(n[ptr:][::-1])
			break
		else:
			r = int(n[ptr]) + carry
			if r > 9:
				r -= 10
				carry = 1
			else:
				carry = 0
			result.append(str(r))
			ptr += 1
	if carry:
		result.append('1')
	return ''.join(result[::-1])

def string_minus(n, m, carry=0):
	n = n[::-1]
	m = m[::-1]
	ptr = 0
	result = []
	while ptr < len(m):
		r = int(n[ptr]) - (int(m[ptr]) + carry)
		if r < 0:
			r += 10
			carry = 1
		else:
			carry = 0
		result.append(str(r))
		ptr += 1
	while ptr < len(n):
		if carry == 0:
			result.append(n[ptr:][::-1])
			break
		else:
			r = int(n[ptr]) - carry
			if r < 0:
				r += 10
				carry = 1
			else:
				carry = 0
			result.append(str(r))
			ptr += 1
	return ''.join(result[::-1])

def encoding_minus(n):
	k = 1
	for i in range(1, len(n) + 1):
		t = int(n[-i])
		if t:
			n[-i] = str(t - 1)
			break
		else:
			n[-i] = str(10 ** k - 1)
		if i > 1:
			k *= 2

def square_ten_encode(n):
	ptr = 1
	k = 1
	remaining = len(n) - 1
	encoding = [n[0]]
	while remaining:
		if remaining > k:
			remaining -= k
			encoding.append(n[ptr:ptr + k][::-1])
		else:
			remaining = 0
			encoding.append(n[ptr:][::-1])
		ptr += k
		k *= 2
	return encoding[::-1]

def square_ten_complement(n, m):
	k = 1
	carry = 0
	comp = []
	for i in range(0, m):
		if i < len(n):
			curr = string_plus(n[i], str(carry))
		else:
			curr = str(carry)
		if curr != '0':
			carry = 1
		else:
			comp.append('0')
			continue
		comp.append(string_minus('1' + '0' * k, curr))
		if i > 0:
			k *= 2
	return comp

def square_ten_reduce(L, R):
	if len(L) == len(R):
		for i in range(len(L)):
			a = L[i]
			b = R[i]
			if a == b:
				L[i] = '0'
				R[i] = '0'
			else:
				R[i] = string_minus(R[i], L[i])
				L[i] = '0'
				break
		while L and L[0] == '0':
			L.pop(0)
		while R and R[0] == '0':
			R.pop(0)

def square_ten_assemble(left, right):
	a = list(zip(range(0, len(left)), left))
	b = list(zip(range(len(right) - 1, -1, -1), right))
	if a and b and (a[-1][0] == b[0][0]):
		a[-1] = (a[-1][0], string_plus(a[-1][1], b[0][1]))
		b = b[1:]
	s = [x for x in a + b if x[1].lstrip('0') != '']
	print(len(s))
	for (x, y) in s:
		print(x, y.lstrip('0'))
import sys
L = input().strip()
R = input().strip()
L_encode = square_ten_encode(L[::-1])
encoding_minus(L_encode)
R_encode = square_ten_encode(R[::-1])
square_ten_reduce(L_encode, R_encode)
if len(L_encode) > 1 or (L_encode and L_encode[0] != '0'):
	R_encode[0] = string_minus(R_encode[0], str(1))
	while R_encode and R_encode[0] == '0':
		R_encode.pop(0)
m = len(R_encode)
left = square_ten_complement(L_encode[::-1], m - 1)
right = R_encode
square_ten_assemble(left, right)


def sqt(x):
	return 10 ** (2 ** (x - 1) if x > 0 else 1)

def solve(x, y):
	a = convert(x)
	b = convert(y)
	length = len(a) - 1
	end = 0
	for i in reversed(range(0, length)):
		if a[i] == b[i]:
			a[i] = b[i] = 0
		else:
			end = i
			break
	a = list(map(int, a))
	output = []
	for i in range(0, end):
		if a[i] == 0:
			continue
		v = sqt(i) - a[i]
		if v > 0:
			output.append((i, v))
		a[i + 1] += 1
	check = 0
	bend = int(b[end])
	if a[end] != bend:
		output.append((end, bend - a[end]))
	else:
		check = len(output)
	for i in reversed(range(0, end)):
		if not all((v == '0' for v in b[i])):
			output.append((i, b[i]))
	if check and check < len(output):
		(i1, v1) = output[check - 1]
		(i2, v2) = output[check]
		if i1 == i2:
			output[check] = (i1, v1 + int(v2))
			del output[check - 1]
	print(len(output))
	for (i, v) in output:
		print(i, v)

def convert(x):
	size = 22
	a = [0] * size
	length = len(x)
	step = 1
	i = 0
	while length > 0:
		start = max(0, length - step)
		a[i] = x[start:length].lstrip('0')
		if a[i] == '':
			a[i] = '0'
		length = start
		if i > 0:
			step *= 2
		i += 1
	return a
a = input().strip()
b = input().strip()
for i in reversed(range(0, len(a))):
	if a[i] != '0':
		a = a[0:i] + chr(ord(a[i]) - 1) + a[i + 1:]
		break
	else:
		a = a[0:i] + '9' + a[i + 1:]
solve(a, b)


import math
L = input()
R = input()
L = L.replace('\n', '')
R = R.replace('\n', '')

def add(s1, s2):
	remains = 0
	step = 10
	s = ''
	l1 = len(s1)
	l2 = len(s2)
	length = max(l1, l2)
	inv = min(l1, l2)
	i = 0
	while i < int(length / step) + 1:
		num1 = int(s1[l1 - (i + 1) * step:l1 - i * step]) if l1 - (i + 1) * step > 0 else int(s1[:l1 - i * step]) if l1 - i * step > 0 else 0
		num2 = int(s2[l2 - (i + 1) * step:l2 - i * step]) if l2 - (i + 1) * step > 0 else int(s2[:l2 - i * step]) if l2 - i * step > 0 else 0
		temp = str((num1 + num2 + remains) % 10 ** step)
		while len(temp) < step:
			temp = '0' + temp
		s = temp + s
		remains = 1 if num1 + num2 + remains >= 10 ** step else 0
		i += 1
		if i > inv + 1 and remains == 0:
			s = s1[:l1 - i * step] + s if l1 - i * step > 0 else s2[:l2 - i * step] + s if l2 - i * step > 0 else s
			break
	while len(s) > 1 and s[0] == '0':
		s = s[1:]
	return s

def minus(s1, s2):
	s = ''
	remains = 0
	step = 10
	l1 = len(s1)
	l2 = len(s2)
	i = 0
	length = l1
	inv = l2
	while i < int(length / step) + 1:
		num1 = int(s1[l1 - (i + 1) * step:l1 - i * step]) if l1 - (i + 1) * step > 0 else int(s1[:l1 - i * step]) if l1 - i * step > 0 else 0
		num2 = int(s2[l2 - (i + 1) * step:l2 - i * step]) if l2 - (i + 1) * step > 0 else int(s2[:l2 - i * step]) if l2 - i * step > 0 else 0
		temp = str((num1 - num2 - remains) % 10 ** step)
		while len(temp) < step:
			temp = '0' + temp
		s = temp + s
		remains = 1 if num1 - num2 - remains < 0 else 0
		i += 1
		if i > int(inv / step) + 1 and remains == 0:
			s = s1[:l1 - i * step] + s if l1 - i * step > 0 else s
			break
	while len(s) > 1 and s[0] == '0':
		s = s[1:]
	return s

def order(level):
	if level > 0:
		return 2 ** (level - 1)
	else:
		return 0

def zeros(n):
	s = ''
	for i in range(n):
		s += '0'
	return s

def compare(s1, s2):
	if len(s1) > len(s2):
		return 1
	elif len(s1) < len(s2):
		return -1
	else:
		i = 0
		step = 8
		while 1:
			if i > len(s1) - 1:
				result = 0
				break
			elif int(s1[i:i + step]) > int(s2[i:i + step]):
				result = 1
				break
			elif int(s1[i:i + step]) < int(s2[i:i + step]):
				result = -1
				break
			else:
				i += step
		return result

def div10(s, l):
	result = True
	n = len(s)
	i = 0
	if s != '0':
		while i < l:
			if s[n - i - 1] == '0':
				i += 1
			else:
				result = False
				break
	return result

def remove0(s):
	step = 10
	while len(s) > 10 and int(s[0:10]) == 0:
		s = s[10:]
	while len(s) > 1 and s[0] == '0':
		s = s[1:]
	return s

def Ten_square(L, R):
	t = []
	c = []
	size = max(len(R), len(L))
	level = int(math.log2(size)) + 1
	LT = minus(L, '1')
	while 1:
		if div10(LT, level):
			HLR = LT[:len(LT) - order(level)] if len(LT) > order(level) else '0'
		else:
			HLR = add(LT[:len(LT) - order(level)], '1') if len(LT) > order(level) else '1'
		HRL = R[:len(R) - order(level)]
		if level == 0:
			break
		elif compare(HRL, HLR) > 0:
			break
		else:
			level -= 1
	t.append(level)
	c.append(minus(HRL, HLR))
	if level > 0:
		if len(L) > order(level) and HLR[-1] == L[len(L) - order(level) - 1]:
			lead = ''
		elif len(L) <= order(level) and HLR == '0':
			lead = ''
		else:
			lead = '1'
		LR = lead + zeros(order(level)) if lead != '' else '0'
		L = L[-order(level):] if len(L) > order(level) else L
		while len(L) > 1 and L[0] == '0':
			L = L[1:]
		if compare(LR, L) >= 0:
			(t1, c1) = Ten_square(L, LR)
			t1.extend(t)
			c1.extend(c)
			t = t1
			c = c1
		RL = '1'
		R = R[-order(level):]
		R = remove0(R)
		if compare(R, RL) >= 0:
			(t2, c2) = Ten_square(RL, R)
			t.extend(t2)
			c.extend(c2)
	return (t, c)
(t, c) = Ten_square(L, R)
print(len(t))
for i in range(len(t)):
	print('%d %s' % (t[i], c[i]))


def add(a, b):
	if a.startswith('-'):
		return sub(b, a.lstrip('-'))
	if b.startswith('-'):
		return sub(a, b.lstrip('-'))
	n = max(len(a), len(b))
	a = [int(i) for i in a.zfill(n)]
	b = [int(i) for i in b.zfill(n)]
	r = [0] * n
	c = 0
	for i in range(n - 1, -1, -1):
		(c, r[i]) = divmod(a[i] + b[i] + c, 10)
	return ('1' if c else '') + ''.join(map(str, r))

def sub(a, b):
	n = max(len(a), len(b))
	amin = a.startswith('-')
	bmin = b.startswith('-')
	(a, b) = (a.lstrip('-'), b.lstrip('-'))
	if not amin and bmin:
		return add(a, b)
	if amin and bmin:
		return '-' + sub(b, a)
	if amin and (not bmin):
		return '-' + add(a, b)
	al = [int(i) for i in a.zfill(n)]
	bl = [int(i) for i in b.zfill(n)]
	if al < bl:
		return '-' + sub(b, a)
	(a, b) = (al, bl)
	r = [0] * n
	c = 0
	for i in range(n - 1, -1, -1):
		(r[i], c) = ((a[i] - b[i] - c) % 10, int(a[i] < b[i] + c))
	return ''.join(map(str, r))

def decompose(s):
	flip = False
	if s.startswith('-'):
		s = add('1' + '0' * (len(s) - 1), s)
		flip = True
	for i in range(len(P)):
		n = sum(P[:-i] if i else P)
		m = sum(P[:-1 - i])
		x = s[-n:-m] if m else s[-n:]
		x = x.lstrip('0')
		if x:
			if i == 0 and flip:
				yield (len(P) - 1 - i, sub(x, '1' + '0' * len(x)))
			else:
				yield (len(P) - 1 - i, x)

def uncommon(a, b):
	n = max(len(a), len(b))
	a = a.zfill(n)
	b = b.zfill(n)
	for i in range(n):
		if a[i] != b[i]:
			break
	return (a[i:], b[i:])
(l, r) = (input(), input())
(l, r) = uncommon(l, r)
P = [1, 1]
while sum(P) < len(r):
	P.append(P[-1] * 2)
fp = '1' + '0' * sum(P[:-1])
x = list(decompose(sub(fp, sub(l, '1'))))
y = list(decompose(sub(r, fp)))
if x and y and (x[0][0] == y[0][0]):
	x[0] = (x[0][0], add(x[0][1], y[0][1]))
	y = y[1:]
res = [(k, n.lstrip('0')) for (k, n) in x[::-1] + y if n.lstrip('0')]
print(len(res))
for (k, n) in res:
	print(k, n)


import os
import sys
import time

def intervalPower(k_):
	return 2 ** (k_ - 1) if k_ != 0 else 1

def getMaxK(list_v_):
	res = 0
	while len(list_v_) > intervalPower(res):
		kl = intervalPower(res)
		res += 1
	return res - 1

def add(list_v_, add_v_):
	if len(list_v_) < len(add_v_):
		return add(add_v_, list_v_)
	i = 0
	while i < len(add_v_):
		r = int(add_v_[len(add_v_) - 1 - i]) + int(list_v_[len(list_v_) - 1 - i])
		if r < 10:
			list_v_[len(list_v_) - 1 - i] = str(r)
		else:
			list_v_[len(list_v_) - 1 - i] = str(r % 10)
			ri = len(add_v_) - 2 - i
			if ri >= 0:
				add_v_[ri] = str(int(add_v_[ri]) + r // 10)
			else:
				add_v_.insert(0, str(r // 10))
				if len(add_v_) > len(list_v_):
					list_v_.insert(0, '0')
		i += 1
	return list_v_

def deduct(list_v_, ded_v_):
	i = 0
	if len(list_v_) >= 10:
		if list_v_ == ['1'] + ['0'] * (len(list_v_) - 1):
			list_v_ = ['9'] * (len(list_v_) - 1)
			ded_v_ = deduct(ded_v_, ['1'])
			if ded_v_ == ['0']:
				return list_v_
			else:
				return deduct(list_v_, ded_v_)
	while i < len(ded_v_):
		r = int(list_v_[len(list_v_) - 1 - i]) - int(ded_v_[len(ded_v_) - 1 - i])
		if r > 0:
			list_v_[len(list_v_) - 1 - i] = str(r)
		elif r == 0:
			list_v_[len(list_v_) - 1 - i] = '0'
		else:
			list_v_[len(list_v_) - 1 - i] = str(10 + r)
			ri = len(ded_v_) - 2 - i
			if ri >= 0:
				ded_v_[ri] = str(int(ded_v_[ri]) + 1)
			else:
				ded_v_.insert(0, str(1))
		i += 1
	if list_v_ == ['0'] * len(list_v_):
		return ['0']
	while len(list_v_):
		if list_v_[0] == '0':
			list_v_.pop(0)
		else:
			return list_v_
	return ['0']

def level_remainder(k_, r_):
	sz = intervalPower(k_ + 1) - intervalPower(k_)
	res = ['9'] * sz
	rr = deduct(r_, ['1'])
	if rr == ['0']:
		return res
	res = deduct(res, r_)
	if res == ['0'] * len(res):
		return ['0']
	while len(res):
		if res[0] == '0':
			res.pop(0)
		else:
			return res
	return ['0']

def moreThenZero(list_v):
	if len(list_v) == 1:
		return int(list_v[0]) > 0
	if len(list_v) > 1:
		return True

def goToOnePosition(L):
	res = L[:]
	remainder = int(res[len(res) - 1])
	if remainder == 0:
		return add(res, list(str(1)))
	elif remainder == 1:
		return res
	return add(res, list(str(11 - remainder)))

def getDownRem(arr_, dec_power_):
	if len(arr_) <= dec_power_:
		return arr_
	else:
		res = arr_[len(arr_) - dec_power_:]
		if res == ['0'] * len(res):
			return ['0']
		while len(res):
			if res[0] == '0':
				res.pop(0)
			else:
				return res
		return ['0']

def getUpRem(arr, power):
	if len(arr) <= power:
		return ['0']
	else:
		res = arr[:len(arr) - power]
		if res == ['0'] * len(res):
			return ['0']
		while len(res):
			if res[0] == '0':
				res.pop(0)
			else:
				return res
		return ['0']

def goUp(L, lk, max_k):
	out = []
	L_in_one_position = goToOnePosition(L)
	if L != L_in_one_position:
		first_d = list2int(L[len(L) - 1:])
		out.append(('0', str(11 - list2int(L[len(L) - 1:])) if first_d != 0 else '1'))
	k = 1
	up_remainder = getUpRem(L_in_one_position, 1)
	while k <= max_k:
		down_remainder = getDownRem(up_remainder, intervalPower(k))
		if moreThenZero(down_remainder):
			if k != max_k:
				out.append((str(k), ''.join(level_remainder(k, down_remainder))))
				up_remainder = add(['1'] + ['0'] * intervalPower(k), up_remainder)
			else:
				out.append((str(k), ''.join(deduct(lk, down_remainder))))
				break
		power_delta = intervalPower(k + 1) - intervalPower(k)
		up_remainder = getUpRem(up_remainder, power_delta)
		k += 1
	if len(out) == 0:
		out.append((str(max_k), ''.join(lk)))
	return out

def goDown(R, max_k):
	out = []
	remainder = getDownRem(R, intervalPower(max_k))
	if remainder == ['0'] * len(remainder):
		return out
	k = max_k - 1
	r = []
	while k >= 0:
		r = getUpRem(remainder, intervalPower(k)) if k > 0 else remainder
		if moreThenZero(r):
			out.append((str(k), ''.join(r)))
		remainder = getDownRem(remainder, intervalPower(k))
		k -= 1
	return out

def list2int(segment_):
	return int(''.join(segment_))

def calc(L, R):
	if L == R:
		return [(0, 1)]
	if len(R) - len(L) <= 1:
		if abs(list2int(R[len(R) - 2:]) - list2int(L[len(L) - 2:])) <= 10 and R[:len(R) - 2] == L[:len(L) - 2]:
			R_remaind = list2int(R[len(R) - 1:])
			L_remaind = list2int(L[len(L) - 1:])
			if not (R_remaind == 0 and L_remaind == 1):
				return [(0, R_remaind - L_remaind)]
			else:
				return [(1, 1)]
	max_k_R = getMaxK(R)
	up_info = goUp(L, getUpRem(R, intervalPower(max_k_R)), max_k_R)
	down_info = goDown(R, max_k_R)
	return up_info + down_info
debug = False
L = 42
R = 1024
if not debug:
	L = list(input())
	R = list(input())
out = calc(L, R)
print(len(out))
for p in out:
	print('%s %s' % (p[0], p[1]))


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


def subs(s1, s2, o):
	len1 = len(s1)
	len2 = len(s2)
	overflow = False
	index = 0
	list1 = list(s1)
	for i in range(len1 - 1, -1, -1):
		index = len2 - len1 + i
		if overflow:
			overflow = False
			if list1[i] == '0':
				list1[i] = '9'
				overflow = True
			else:
				list1[i] = chr(ord(list1[i]) - 1)
		if index >= 0:
			c = ord(list1[i]) - ord(s2[index]) - o
			o = 0
			if c < 0:
				overflow = True
				c += 10
			c += ord('0')
			list1[i] = chr(c)
	firstNonZero = 0
	for i in range(0, len1):
		if list1[i] == '0':
			firstNonZero += 1
		else:
			break
	return ''.join(list1[firstNonZero:])
L = input()
R = input()
pL = ['0'] * 21
pR = ['0'] * 21
pL[0] = L[-1]
pR[0] = R[-1]
k = 1
lower = 0
m = 0
lenL = len(L)
lenR = len(R)
num = 0
for i in range(1, 21):
	lower = lenL - 2 * k
	m = lenL - k
	if m > k:
		m = k
	if m <= 0:
		break
	if lower <= 0:
		lower = 0
	pL[i] = L[lower:lower + m]
	firstNonZero = 0
	for j in range(0, len(pL[i])):
		if pL[i][j] == '0':
			firstNonZero += 1
		else:
			break
	pL[i] = pL[i][firstNonZero:]
	if pL[i] == '':
		pL[i] = '0'
	k *= 2
k = 1
for i in range(1, 21):
	lower = lenR - 2 * k
	m = lenR - k
	if m > k:
		m = k
	if m <= 0:
		break
	if lower <= 0:
		lower = 0
	pR[i] = R[lower:lower + m]
	firstNonZero = 0
	for j in range(0, len(pR[i])):
		if pR[i][j] == '0':
			firstNonZero += 1
		else:
			break
	pR[i] = pR[i][firstNonZero:]
	if pR[i] == '':
		pR[i] = '0'
	k *= 2
highestDiff = 20
for highestDiff in range(20, 0, -1):
	if pL[highestDiff] != pR[highestDiff]:
		break
queue = []
limit = 0
overflow = 0
for i in range(0, highestDiff):
	t = 0
	if i == 0:
		if pL[0] == '0':
			num += 1
			queue.append('0 1\n')
			continue
		if pL[0] == '1':
			continue
		overflow = 1
		limit = '11'
	else:
		if pL[i] == '0' and overflow == 0:
			continue
		if overflow == 1:
			limit = '9' * 2 ** (i - 1)
		else:
			limit = '1' + '0' * 2 ** (i - 1)
	overflow = 0
	if pL[i] == limit:
		pL[i] = '0'
		overflow = 1
		continue
	num += 1
	queue.append(str(i) + ' ')
	queue.append(subs(limit, pL[i], 0))
	queue.append('\n')
	pL[i] = '0'
	overflow = 1
if pL[highestDiff] != pR[highestDiff]:
	num += 1
	queue.append(str(highestDiff) + ' ')
	queue.append(subs(pR[highestDiff], pL[highestDiff], overflow))
	queue.append('\n')
for i in range(highestDiff - 1, -1, -1):
	if pR[i] != '0':
		num += 1
		queue.append(str(i) + ' ')
		queue.append(pR[i])
		queue.append('\n')
print(num)
for s in queue:
	print(s, end='')


from collections import deque
from functools import lru_cache
from itertools import dropwhile
from math import floor, log10, log2

def main(l, r):
	if l == r:
		print(1)
		print(0, 1)
		return
	seq = []
	n = len(r)
	l = l.zfill(n)
	k_max = g(n)
	(i, j) = ij(k_max, n)
	while l[i:j] == r[i:j]:
		k_max -= 1
		(i, j) = ij(k_max, n)
	ret = 0
	for k in range(k_max):
		(i, j) = ij(k, n)
		s = l[i:j]
		if k == 0:
			v = int(s)
			if v == 1:
				ret = 0
				continue
			if v == 0:
				seq.append((0, 1))
				ret = 0
				continue
			seq.append((0, 10 - v + 1))
			ret = 1
			continue
		(m, ret) = comp(s, ret)
		if len(m) > 0:
			seq.append((k, m))
	(i, j) = ij(k_max, n)
	s = l[i:j]
	s2 = r[i:j]
	d = deque()
	for i in range(len(s) - 1, -1, -1):
		v = int(s[i]) + ret
		v2 = int(s2[i])
		if v2 >= v:
			ret = 0
			d.appendleft(str(v2 - v))
		else:
			ret = 1
			d.appendleft(str(10 - (v - v2)))
	s = ''.join(dropwhile(lambda n: n == '0', d))
	if len(s) > 0:
		seq.append((k_max, s))
	for k in range(k_max - 1, -1, -1):
		(i, j) = ij(k, n)
		s = r[i:j].lstrip('0')
		if len(s) == 0:
			continue
		if seq[-1][0] == k:
			seq[-1] = (k, int(seq[-1][1]) + int(s))
		else:
			seq.append((k, s))
	print(len(seq))
	for (k, times) in seq:
		print(k, times)

def ij(k, n):
	if k == 0:
		return (max(0, n - 1), n)
	i = 2 ** (k - 1)
	j = 2 ** k
	return (max(0, n - j), n - i)

def f(k):
	if k < 2:
		return 10
	return 10 ** 2 ** (k - 1)

def g(n):
	if n == 1:
		return 0
	return floor(log2(n - 1)) + 1

def comp(s, ret):
	mapping = {('0', 0): ('0', 0), ('1', 0): ('9', 1), ('2', 0): ('8', 1), ('3', 0): ('7', 1), ('4', 0): ('6', 1), ('5', 0): ('5', 1), ('6', 0): ('4', 1), ('7', 0): ('3', 1), ('8', 0): ('2', 1), ('9', 0): ('1', 1), ('0', 1): ('9', 1), ('1', 1): ('8', 1), ('2', 1): ('7', 1), ('3', 1): ('6', 1), ('4', 1): ('5', 1), ('5', 1): ('4', 1), ('6', 1): ('3', 1), ('7', 1): ('2', 1), ('8', 1): ('1', 1), ('9', 1): ('0', 1)}
	d = deque()
	for i in range(len(s) - 1, -1, -1):
		n = s[i]
		(k, ret) = mapping[n, ret]
		d.appendleft(k)
	return (''.join(dropwhile(lambda n: n == '0', d)), ret)
main(input(), input())


import math
(L, R) = (input(), input())

def to_i(ch):
	return ord(ch) - 48

def to_c(i):
	return chr(i + 48)

def rindex(S, i):
	if i < len(S):
		return to_i(S[-i - 1])
	return 0

def out(k, arr):
	return
subtrahend = 11
next_subtrahend = 10
(b, e) = (0, 0)
pairs = []
max_k = 1
if len(R) > 1:
	max_k = math.floor(math.log2(len(R) - 1)) + 1
	for k in range(0, max_k):
		b = e
		e = 2 ** k
		if e >= len(R):
			break
		need_print = False
		arr = bytearray()
		for j in range(b, e):
			l = rindex(L, j)
			s = (subtrahend - l) % 10
			if s:
				need_print = True
			arr.append(s)
			if subtrahend == 11:
				if l == 0:
					subtrahend = 10
				elif l == 1:
					subtrahend = 10
				else:
					subtrahend = 9
			elif subtrahend == 10:
				if l:
					subtrahend = 9
		if need_print:
			while len(arr) and arr[-1] == 0:
				arr.pop()
			pairs.append((k, arr[::-1]))
			out(k, arr)
	arr = bytearray()
	need_print = False
	subtrahend = 10
	if len(pairs) == 0:
		subtrahend = 11
	b = 2 ** (max_k - 1)
	for j in range(b, len(R)):
		r = rindex(R, j)
		l = rindex(L, j)
		s = (subtrahend + r - l - 1) % 10
		subtrahend = 10 + (subtrahend + r - l - 1) // 10
		arr.append(s)
		if s:
			need_print = True
		if r:
			e = j + 1
			break
	for j in range(e, len(R)):
		need_print = True
		l = rindex(L, j)
		r = rindex(R, j)
		arr.append((subtrahend + r - l - 1) % 10)
		subtrahend = 10 + (subtrahend + r - l - 1) // 10
	while len(arr) and arr[-1] == 0:
		arr.pop()
	if len(arr):
		pairs.append((max_k, arr[::-1]))
		out(max_k, arr)
b = 2 ** (max_k - 1)
for k in range(max_k - 1, -1, -1):
	e = b
	b = 0
	if k:
		b = 2 ** (k - 1)
	arr = bytearray()
	ee = b - 1
	for j in range(min(e, len(R)) - 1, b - 1, -1):
		if rindex(R, j):
			ee = j
			break
	for j in range(ee, b - 1, -1):
		arr.append(rindex(R, j))
	if len(arr):
		pairs.append((k, arr))
		out(k, arr[::-1])
print(len(pairs))
for p in pairs:
	print(p[0], end=' ')
	for x in p[1]:
		print(x, end='')
	print('')


import math
(L, R) = (input(), input())

def to_i(ch):
	return ord(ch) - 48

def to_c(i):
	return chr(i + 48)

def rindex(S, i):
	if i < len(S):
		return to_i(S[-i - 1])
	return 0

def out(k, arr):
	return
subtrahend = 11
next_subtrahend = 10
(b, e) = (0, 0)
pairs = []
max_k = 1
if len(R) > 1:
	max_k = math.floor(math.log2(len(R) - 1)) + 1
	for k in range(0, max_k):
		b = e
		e = 2 ** k
		if e >= len(R):
			break
		need_print = False
		arr = bytearray()
		for j in range(b, e):
			l = rindex(L, j)
			s = (subtrahend - l) % 10
			if s:
				need_print = True
			arr.append(s)
			if subtrahend == 11:
				if l == 0:
					subtrahend = 10
				elif l == 1:
					subtrahend = 10
				else:
					subtrahend = 9
			elif subtrahend == 10:
				if l:
					subtrahend = 9
		if need_print:
			while len(arr) and arr[-1] == 0:
				arr.pop()
			pairs.append((k, arr[::-1]))
			out(k, arr)
	arr = bytearray()
	need_print = False
	subtrahend = 10
	if len(pairs) == 0:
		subtrahend = 11
	b = 2 ** (max_k - 1)
	for j in range(b, len(R)):
		r = rindex(R, j)
		l = rindex(L, j)
		s = (subtrahend + r - l - 1) % 10
		subtrahend = 10 + (subtrahend + r - l - 1) // 10
		arr.append(s)
		if s:
			need_print = True
		if r:
			e = j + 1
			break
	for j in range(e, len(R)):
		need_print = True
		l = rindex(L, j)
		r = rindex(R, j)
		arr.append((subtrahend + r - l - 1) % 10)
		subtrahend = 10 + (subtrahend + r - l - 1) // 10
	while len(arr) and arr[-1] == 0:
		arr.pop()
	if len(arr):
		pairs.append((max_k, arr[::-1]))
		out(max_k, arr)
b = 2 ** (max_k - 1)
for k in range(max_k - 1, -1, -1):
	e = b
	b = 0
	if k:
		b = 2 ** (k - 1)
	arr = bytearray()
	ee = b - 1
	for j in range(min(e, len(R)) - 1, b - 1, -1):
		if rindex(R, j):
			ee = j
			break
	for j in range(ee, b - 1, -1):
		arr.append(rindex(R, j))
	if len(arr):
		pairs.append((k, arr))
		out(k, arr[::-1])
print(len(pairs))
for p in pairs:
	print(p[0], end=' ')
	for x in p[1]:
		print(x, end='')
	print('')


import os
import sys
import time

def intervalPower(k_):
	return 2 ** (k_ - 1) if k_ != 0 else 1

def getMaxK(list_v_):
	res = 0
	while len(list_v_) > intervalPower(res):
		kl = intervalPower(res)
		res += 1
	return res - 1

def add(list_v_, add_v_):
	if len(list_v_) < len(add_v_):
		return add(add_v_, list_v_)
	i = 0
	while i < len(add_v_):
		r = int(add_v_[len(add_v_) - 1 - i]) + int(list_v_[len(list_v_) - 1 - i])
		if r < 10:
			list_v_[len(list_v_) - 1 - i] = str(r)
		else:
			list_v_[len(list_v_) - 1 - i] = str(r % 10)
			ri = len(add_v_) - 2 - i
			if ri >= 0:
				add_v_[ri] = str(int(add_v_[ri]) + r // 10)
			else:
				add_v_.insert(0, str(r // 10))
				if len(add_v_) > len(list_v_):
					list_v_.insert(0, '0')
		i += 1
	return list_v_

def deduct(list_v_, ded_v_):
	i = 0
	if len(list_v_) >= 10:
		if list_v_ == ['1'] + ['0'] * (len(list_v_) - 1):
			list_v_ = ['9'] * (len(list_v_) - 1)
			ded_v_ = deduct(ded_v_, ['1'])
			if ded_v_ == ['0']:
				return list_v_
			else:
				return deduct(list_v_, ded_v_)
	while i < len(ded_v_):
		r = int(list_v_[len(list_v_) - 1 - i]) - int(ded_v_[len(ded_v_) - 1 - i])
		if r > 0:
			list_v_[len(list_v_) - 1 - i] = str(r)
		elif r == 0:
			list_v_[len(list_v_) - 1 - i] = '0'
		else:
			list_v_[len(list_v_) - 1 - i] = str(10 + r)
			ri = len(ded_v_) - 2 - i
			if ri >= 0:
				ded_v_[ri] = str(int(ded_v_[ri]) + 1)
			else:
				ded_v_.insert(0, str(1))
		i += 1
	if list_v_ == ['0'] * len(list_v_):
		return ['0']
	while len(list_v_):
		if list_v_[0] == '0':
			list_v_.pop(0)
		else:
			return list_v_
	return ['0']

def level_remainder(k_, r_):
	sz = intervalPower(k_ + 1) - intervalPower(k_)
	res = ['9'] * sz
	rr = deduct(r_, ['1'])
	if rr == ['0']:
		return res
	res = deduct(res, r_)
	if res == ['0'] * len(res):
		return ['0']
	while len(res):
		if res[0] == '0':
			res.pop(0)
		else:
			return res
	return ['0']

def moreThenZero(list_v):
	if len(list_v) == 1:
		return int(list_v[0]) > 0
	if len(list_v) > 1:
		return True

def goToOnePosition(L):
	res = L[:]
	remainder = int(res[len(res) - 1])
	if remainder == 0:
		return add(res, list(str(1)))
	elif remainder == 1:
		return res
	return add(res, list(str(11 - remainder)))

def getDownRem(arr_, dec_power_):
	if len(arr_) <= dec_power_:
		return arr_
	else:
		res = arr_[len(arr_) - dec_power_:]
		if res == ['0'] * len(res):
			return ['0']
		while len(res):
			if res[0] == '0':
				res.pop(0)
			else:
				return res
		return ['0']

def getUpRem(arr, power):
	if len(arr) <= power:
		return ['0']
	else:
		res = arr[:len(arr) - power]
		if res == ['0'] * len(res):
			return ['0']
		while len(res):
			if res[0] == '0':
				res.pop(0)
			else:
				return res
		return ['0']

def goUp(L, lk, max_k):
	out = []
	L_in_one_position = goToOnePosition(L)
	if L != L_in_one_position:
		first_d = list2int(L[len(L) - 1:])
		out.append(('0', str(11 - list2int(L[len(L) - 1:])) if first_d != 0 else '1'))
	k = 1
	up_remainder = getUpRem(L_in_one_position, 1)
	while k <= max_k:
		down_remainder = getDownRem(up_remainder, intervalPower(k))
		if moreThenZero(down_remainder):
			if k != max_k:
				out.append((str(k), ''.join(level_remainder(k, down_remainder))))
				up_remainder = add(['1'] + ['0'] * intervalPower(k), up_remainder)
			else:
				out.append((str(k), ''.join(deduct(lk, down_remainder))))
				break
		power_delta = intervalPower(k + 1) - intervalPower(k)
		up_remainder = getUpRem(up_remainder, power_delta)
		k += 1
	if len(out) == 0:
		out.append((str(max_k), ''.join(lk)))
	return out

def goDown(R, max_k):
	out = []
	remainder = getDownRem(R, intervalPower(max_k))
	if remainder == ['0'] * len(remainder):
		return out
	k = max_k - 1
	r = []
	while k >= 0:
		r = getUpRem(remainder, intervalPower(k)) if k > 0 else remainder
		if moreThenZero(r):
			out.append((str(k), ''.join(r)))
		remainder = getDownRem(remainder, intervalPower(k))
		k -= 1
	return out

def list2int(segment_):
	return int(''.join(segment_))

def calc(L, R):
	if L == R:
		return [(0, 1)]
	if len(R) - len(L) <= 1:
		if abs(list2int(R[len(R) - 2:]) - list2int(L[len(L) - 2:])) <= 10 and R[:len(R) - 2] == L[:len(L) - 2]:
			R_remaind = list2int(R[len(R) - 1:])
			L_remaind = list2int(L[len(L) - 1:])
			if not (R_remaind == 0 and L_remaind == 1):
				return [(0, R_remaind - L_remaind)]
			else:
				return [(1, 1)]
	max_k_R = getMaxK(R)
	up_info = goUp(L, getUpRem(R, intervalPower(max_k_R)), max_k_R)
	down_info = goDown(R, max_k_R)
	return up_info + down_info
debug = False
L = 42
R = 1024
if not debug:
	L = list(input())
	R = list(input())
out = calc(L, R)
print(len(out))
for p in out:
	print('%s %s' % (p[0], p[1]))


import math
L = input()
R = input()
kofN = lambda n: 0 if len(n) == 1 else int(math.log2(len(n) - 1)) + 1
ktoi = lambda k: 0 if k == 0 else 2 ** (k - 1)
kthofN = lambda k, n: n[-1] if k == 0 else n[-ktoi(k + 1):-ktoi(k)]
chdict = {47: '1', 48: '0', 58: '0'}
for i in range(49, 58):
	chdict[i] = chr(48 + 58 - i)
k = 0
S = ''
d = ord(L[-1])
carry = 0 if d <= 49 else 1
n = 0
if d != 49:
	S += '0 ' + chdict[d - 1] + '\n'
	n += 1
kR = kofN(R)
maxind = 1
ind = 2
maxind = 2
k = 1
lenL = len(L)
lenR = len(R)
aux = ''
zero = True
while k != kR:
	d = ord(L[-ind]) + carry if ind <= lenL else 48 + carry
	ch = chdict[d]
	zero &= ch == '0'
	aux += ch
	carry = 0 if ch == '0' and carry == 0 else 1
	ind += 1
	if ind > maxind:
		if not zero:
			n += 1
			S += str(k) + ' '
			z = True
			for c in aux[::-1]:
				z &= c == '0'
				if not z:
					S += c
			S += '\n'
		aux = ''
		maxind <<= 1
		k += 1
		zero = True
	if k == kR:
		if not zero:
			n += 1
			S += str(k) + ' '
			z = True
			for c in aux[::-1]:
				z &= c == '0'
				if not z:
					S += c
			S += '\n'
		break
if k == kR:
	while True:
		l = 48 if ind > lenL or L[-ind] == '0' else ord(L[-ind])
		r = ord(R[-ind])
		d = (r - (l + carry)) % 10 + 48
		ch = chr(d)
		zero &= ch == '0'
		aux += ch
		carry = 0 if r >= l + carry else 1
		ind += 1
		if ind > lenR:
			n += 1
			S += str(k) + ' '
			z = True
			for c in aux[::-1]:
				z &= c == '0'
				if not z:
					S += c
			S += '\n'
			break
elif k < kR:
	S += str(kR) + ' ' + R[-1 << kR:-1 << kR - 1] + '\n'
	n += 1
if kR > 1:
	lind = 1 << kR - 2
	find = 1 << kR - 1
	z = True
	for k in range(kR - 1, -1, -1):
		aux = ''
		for c in R[-find:-lind]:
			z &= c == '0'
			if not z:
				aux += c
		if not z:
			n += 1
			S += str(k) + ' ' + aux + '\n'
		lind >>= 1
		find >>= 1
		z = True
if R[-1] != '0':
	n += 1
	S += '0 ' + R[-1]
print(n)
print(S, end='')


import sys

def stt(left, right):
	zero = ord('0')
	one = ord('1')
	nine = ord('9')
	li = len(left) - 1
	ri = len(right) - 1
	x = ord(left[li])
	while zero > x or nine < x:
		li -= 1
		x = ord(left[li])
	li += 1
	x = ord(right[ri])
	while zero > x or nine < x:
		ri -= 1
		x = ord(right[ri])
	ri += 1
	lb = 0
	span = 1
	if li == ri:
		while span:
			temp = min(li, lb + span)
			while left[lb:temp] == right[lb:temp]:
				if li == temp:
					return [('0', '1')]
				lb = temp
				span <<= 1
				temp = min(li, lb + span)
			span >>= 1
	nri = ri - 1
	nli = li - 1
	if lb == nri:
		c = chr(one + ord(right[nri]) - ord(left[nli]))
		return [('0', c)]
	x = right[nri]
	rightside = []
	if '0' != x:
		rightside.append(('0', x))
	x = left[nli]
	carry = False
	leftside = []
	if '1' != x:
		c = '1' if '0' == x else chr(107 - ord(x))
		carry = c != '1'
		leftside.append(('0', c))

	def addone(arg):
		j = len(arg) - 1
		while 57 == c[j]:
			c[j] = 48
			j -= 1
		c[j] += 1
	(ri, nri) = (nri, max(lb, nri - 1))
	(li, nli) = (nli, max(lb, nli - 1))
	i = 1
	d = 1
	while lb < nri:
		x = right[nri:ri].lstrip('0')
		if x:
			rightside.append((str(i), x))
		if carry:
			x = left[nli:li].encode().zfill(d)
			if x.lstrip(b'9'):
				c = ''.join(('9876543210'[b - 48] for b in x))
				leftside.append((str(i), c.lstrip('0')))
		else:
			x = left[nli:li]
			if x.lstrip('0'):
				c = bytearray((b'9876543210'[b - 48] for b in x.encode().zfill(d)))
				addone(c)
				leftside.append((str(i), c.lstrip(b'0').decode()))
				carry = True
		i += 1
		d <<= 1
		(ri, nri) = (nri, max(0, nri - d))
		(li, nli) = (nli, max(0, nli - d))

	def subtract(big, small, carry):
		j = len(big)
		offset = j - len(small)
		while j > offset:
			j -= 1
			x = 48 + big[j] - small[j - offset]
			if carry:
				carry = False
				x -= 1
			if 48 > x:
				carry = True
				x += 10
			big[j] = x
		if j and carry:
			j -= 1
			while 48 == big[j]:
				big[j] = 57
				j -= 1
			big[j] -= 1
	big = bytearray(right[nri:ri], 'ascii')
	small = left[nli:li].encode()
	subtract(big, small, carry)
	big = big.lstrip(b'0').decode()
	if big:
		leftside.append((str(i), big))
	elif leftside and rightside:
		if leftside[-1][0] == rightside[-1][0]:

			def addpair(lx, rx):
				(ix, sx) = (rx, lx) if len(lx) < len(rx) else (lx, rx)
				result = bytearray(b'0')
				result.extend(ix)
				j = len(result)
				offset = j - len(sx)
				carry = False
				while j > offset:
					j -= 1
					x = result[j] + sx[j - offset] - 48
					if carry:
						carry = False
						x += 1
					if 57 < x:
						carry = True
						x -= 10
					result[j] = x
				if carry:
					j -= 1
					while 57 == result[j]:
						result[j] = 48
						j -= 1
					result[j] += 1
				return result
			level = leftside[-1][0]
			c = addpair(leftside.pop()[1].encode(), rightside.pop()[1].encode())
			leftside.append((level, c.lstrip(b'0').decode()))
	leftside.extend(reversed(rightside))
	return leftside

def main():
	left = sys.stdin.readline()
	right = sys.stdin.readline()
	block_list = stt(left, right)
	print(len(block_list))
	for (level, count) in block_list:
		print(level, end=' ')
		print(count)
main()


def add(s1, s2):
	ans = []
	k1 = len(s1) - 1
	k2 = len(s2) - 1
	rollover = 0
	while k1 >= 0 and k2 >= 0:
		x = int(s1[k1]) + int(s2[k2]) + rollover
		(rollover, x) = divmod(x, 10)
		ans.append(str(x))
		k1 -= 1
		k2 -= 1
	while k1 >= 0:
		x = int(s1[k1]) + rollover
		(rollover, x) = divmod(x, 10)
		ans.append(str(x))
		k1 -= 1
	while k2 >= 0:
		x = int(s2[k2]) + rollover
		(rollover, x) = divmod(x, 10)
		ans.append(str(x))
		k2 -= 1
	if rollover == 1:
		ans.append('1')
	return ''.join(ans[::-1])

def segments(s):
	ans = []
	level = 0
	k2 = len(s)
	k1 = k2 - 1
	while k1 >= 0:
		for k in range(k1, k2):
			if s[k] != '0':
				ans.append((level, s[k:k2]))
				break
		level += 1
		n = 1 << level - 1
		k2 = k1
		k1 -= n
	for k in range(k2):
		if s[k] != '0':
			ans.append((level, s[k:k2]))
			break
	return ans
s1 = input()
s2 = input()
if len(s1) == len(s2):
	for k in range(len(s1)):
		if s1[k] != s2[k]:
			break
	else:
		print(1)
		print(0, 1)
		exit()
	s1 = s1[k:]
	s2 = s2[k:]
else:
	s1 = '0' * (len(s2) - len(s1)) + s1
s1 = add(''.join((str((int(s2[0]) - 1 if k == 0 else 9) - int(x)) for (k, x) in enumerate(s1))), '2')
s2 = s2[1:]
ans1 = segments(s1)
ans2 = segments(s2)
if ans1 and ans2 and (ans1[-1][0] == ans2[-1][0]):
	(level, cnt) = ans2.pop()
	ans1[-1] = (level, add(ans1[-1][1], cnt))
ans1.extend(ans2[::-1])
print(len(ans1))
for (level, cnt) in ans1:
	print(level, cnt)


import sys

def removeLeadingZero(A):
	B = A.lstrip('0')
	if len(B) == 0:
		B = '0'
	return B

def f(A, res):
	if A == '0' * len(A):
		return
	res.append([0, A[-1:]])
	R = len(A) - 1
	for level in range(1, 21):
		T = 2 ** (level - 1)
		res.append([level, removeLeadingZero(A[max(0, R - T):R])])
		R -= T
		if R <= 0:
			return

def minus(A, B):
	B = '0' * (len(A) - len(B)) + B
	C = []
	for i in range(-1, -len(A) - 1, -1):
		C.append(ord(A[i]) - ord(B[i]))
	car = 0
	for i in range(len(C)):
		C[i] -= car
		if C[i] < 0:
			C[i] += 10
			car = 1
		else:
			car = 0
	C.reverse()
	return ''.join(map(str, C))

def plus(A, B):
	A = A[::-1]
	B = B[::-1]
	mx = max(len(A), len(B)) + 1
	A = A + '0' * (mx - len(A))
	B = B + '0' * (mx - len(B))
	C = []
	for i in range(mx):
		C.append(ord(A[i]) - ord('0') + ord(B[i]) - ord('0'))
	car = 0
	for i in range(len(C)):
		C[i] += car
		if C[i] >= 10:
			C[i] -= 10
			car = 1
		else:
			car = 0
	C.reverse()
	return removeLeadingZero(''.join(map(str, C)))

def bigger(A, B):
	A = A[::-1]
	B = B[::-1]
	la = len(A)
	lb = len(B)
	while la > 0 and A[la - 1] == '0':
		la -= 1
	while lb > 0 and B[lb - 1] == '0':
		lb -= 1
	if la != lb:
		return la > lb
	for i in range(la - 1, -1, -1):
		if ord(A[i]) > ord(B[i]):
			return True
		if ord(A[i]) < ord(B[i]):
			return False
	return True
A = input().strip()
B = input().strip()
assert removeLeadingZero(A) == A
assert removeLeadingZero(B) == B
assert A.isdigit() and B.isdigit()
assert bigger(B, A)
A = '0' * (len(B) - len(A)) + A
if len(B) == 1:
	print(1)
	print(0, int(B) - int(A) + 1)
	sys.exit(0)
resL = []
resR = []
for level in range(20, 0, -1):
	T = 2 ** (level - 1)
	if len(B) < T:
		continue
	C1 = B[:-T] + '0' * (T - 1) + '0'
	C2 = B[:-T] + '0' * (T - 1) + '1'
	if bigger(C2, A):
		f(minus(C2, A), resL)
		f(minus(B, C1), resR)
		resR.reverse()
		break
res = list(filter(lambda i: i[1] > '0', resL + resR))
for i in range(1, len(res)):
	if res[i][0] == res[i - 1][0]:
		res[i][1] = plus(res[i][1], res[i - 1][1])
		res = res[:i - 1] + res[i:]
		break
print(len(res))
for i in res:
	print(i[0], i[1])


import math
l = input()
r = input()
for i in range(len(l)):
	if l[len(l) - i - 1] != '0':
		break
l = l[:len(l) - i - 1] + str(int(l[len(l) - i - 1]) - 1) + '9' * i
l = '0' * (len(r) - len(l)) + l
if len(r) == 1:
	toprint = [[0, str(int(r) - int(l))]]
else:
	lastdig = l[-1]
	carry = 0
	if lastdig != '0':
		toprint = [[0, str(10 - int(lastdig))]]
		carry = 1
	else:
		toprint = []
	numdig = 1
	level = 1
	while len(r) > 2 * numdig:
		thestr = ''
		isneeded = False
		for i in range(numdig, 2 * numdig):
			if carry == 0:
				if l[-i - 1] == '0':
					thestr += '0'
					carry = 0
				else:
					isneeded = True
					thestr += str(10 - int(l[-i - 1]))
					carry = 1
			elif l[-i - 1] == '9':
				thestr += '0'
				carry = 1
			else:
				isneeded = True
				thestr += str(9 - int(l[-i - 1]))
		thestr = ''.join(list(reversed(list(thestr))))
		if isneeded:
			toprint.append([level, thestr])
		numdig *= 2
		level += 1
	thestr = ''
	isneeded = False
	for i in range(len(l) - numdig - 1, -1, -1):
		ldig = int(l[i]) + carry
		rdig = int(r[i])
		carry = 0 if rdig >= ldig else 1
		thestr += str((rdig - ldig) % 10)
		if (rdig - ldig) % 10 != 0:
			isneeded = True
	thestr = ''.join(list(reversed(list(thestr))))
	if isneeded:
		toprint.append([level, thestr])
	level -= 1
	numdig //= 2
	while level > 0:
		isneeded = False
		for i in range(-2 * numdig, -numdig):
			if r[i] != '0':
				isneeded = True
		if isneeded:
			toprint.append([level, r[-2 * numdig:-numdig]])
		numdig //= 2
		level -= 1
	if r[-1] != '0':
		toprint.append([0, r[-1]])
print(len(toprint))
for [a, b] in toprint:
	while len(b) > 0 and b[0] == '0':
		b = b[1:]
	print('%d %s' % (a, b))


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)


L = input()
R = input()
d = len(R)
level = 0
n = 1
tree = [n]
while d >= n + 1:
	tree.append(n)
	level += 1
	n = 2 ** level

def breakdown(N, k):
	if k == 0:
		return [int(N)]
	div = tree[k]
	chunks = breakdown(N[-div:], k - 1)
	chunks.append(N[:-div].lstrip('0') or 0)
	return chunks
divL = breakdown(L, level)
divR = breakdown(R, level)
seq = []
carry = 0
for (k, n) in enumerate(map(int, divL)):
	if k == 0:
		carry = -1
	n += carry
	carry = 0
	if k < level:
		if n > 0:
			n = 10 ** tree[k] - n
			carry = 1
		elif n < 0:
			n = 1
		seq.append((k, n))
if n != 0:
	divR[k] = int(divR[k]) - n
	while divR[-1] == 0:
		del divR[-1]
		n = seq.pop()[1]
		if n != 0:
			divR[-1] = int(divR[-1]) + n
seq.extend(reversed(list(enumerate(divR))))
seq = [s for s in seq if s[1] != 0]
print(len(seq))
for s in seq:
	print(*s)