Problem:
 Score : 700 points    Problem Statement You are given an integer L . Construct a directed graph that satisfies the conditions below. The graph may contain multiple edges between the same pair of vertices. It can be proved that such a graph always exists.   The number of vertices, N , is at most 20 . The vertices are given ID numbers from 1 to N .  The number of edges, M , is at most 60 . Each edge has an integer length between 0 and 10^6 (inclusive).  Every edge is directed from the vertex with the smaller ID to the vertex with the larger ID. That is, 1,2,...,N is one possible topological order of the vertices.  There are exactly L different paths from Vertex 1 to Vertex N . The lengths of these paths are all different, and they are integers between 0 and L-1 .   Here, the length of a path is the sum of the lengths of the edges contained in that path, and two paths are considered different when the sets of the edges contained in those paths are different.      Constraints  2 \leq L \leq 10^6  L is an integer.         Input Input is given from Standard Input in the following format:  L       Output In the first line, print N and M , the number of the vertices and edges in your graph.
In the i -th of the following M lines, print three integers u_i,v_i and w_i , representing the starting vertex, the ending vertex and the length of the i -th edge.
If there are multiple solutions, any of them will be accepted.        Sample Input 1 4      Sample Output 1 8 10
1 2 0
2 3 0
3 4 0
1 5 0
2 6 0
3 7 0
4 8 0
5 6 1
6 7 1
7 8 1  In the graph represented by the sample output, there are four paths from Vertex 1 to N=8 :   1 → 2 → 3 → 4 → 8 with length 0  1 → 2 → 3 → 7 → 8 with length 1  1 → 2 → 6 → 7 → 8 with length 2  1 → 5 → 6 → 7 → 8 with length 3   There are other possible solutions.       Sample Input 2 5      Sample Output 2 5 7
1 2 0
2 3 1
3 4 0
4 5 0
2 4 0
1 3 3
3 5 1

Solution (Python):
import sys

class paiza_fmt_input:
    def __init__(self):
        self.cur = 0
        self.all_input = []

    def input_all(self):
        for line in sys.stdin:
            self.all_input.append(line)

    def get_one_line_with_split(self):
        input_cur = self.all_input[self.cur]
        self.cur += 1
        splitted_input = input_cur.split()
        return splitted_input

def get_bit_list(num):
    bit_list = []
    for i in range(64):
        if (num >> i) & 1:
            bit_list.append(i)
    return bit_list



def solve(inputs):
    line1_input = list(map(int, inputs.get_one_line_with_split()))
    path_num = line1_input[0]
    bit_list = get_bit_list(path_num)
    

    max_bit = bit_list[-1]
    

    dags = []
    for i in range(max_bit):
        dags.append([i+1, i+2, 0])
        dags.append([i+1, i+2, pow(2, i)])
    

    end_node_no = bit_list[-1] + 1
    bit_list.pop()
    ofs_num_cur = pow(2, max_bit)
    while True:
        if not bit_list:
            break
        bit = bit_list.pop()

        dags.append([bit+1, end_node_no, ofs_num_cur])
        ofs_num_cur += pow(2, bit)
    

    
    print(end_node_no, len(dags))
    for dag in dags:
        print(*dag)





inputs = paiza_fmt_input()
inputs.input_all()
solve(inputs)

Solution (Python):
L = int(input())
num = 2
start = 1
end = 2
path = [[1, 2, 0], [1, 2, 1]]
func = []
def plus1(s, t, n):
	global num
	path.append([s, t, n])
	num += 1

def times2(s, t, n):
	global end, num
	for edge in path:
		edge[2] *= 2
	path.append([t, t+1, 0])
	path.append([t, t+1, 1])
	end += 1
	num *= 2

while L > 2:
	if L % 2 == 1:
		func.append(plus1)
		L -= 1
	else:
		func.append(times2)
		L //= 2
func.reverse()

for f in func:
	f(start, end, num)

print(end, len(path))
for u, v, w in path:
	print(u, v, w)

Solution (Python):
l = input()
k = 0
while 2 ** (k + 1) <= l:
	k += 1
n = k + 1
e = []
for i in range(k):
	e.append((i + 1, i + 2, 0))
	e.append((i + 1, i + 2, 2 ** i))

for i in range(k):
	if l >> i & 1:
		e.append((i + 1, n, (l - 1) >> (i + 1) << (i + 1)))

print n, len(e)
for x, y, z in e:
	print x, y, z

Solution (Python):
import sys


L=int(input())-1
if L==1:
    print(2,2)
    print(1,2,0)
    print(1,2,1)
    sys.exit()

M=0
threelist=[]
j=1
i=1
while i<=10**6:
    i=3**j-1
    threelist.append(i)
    j+=1


threelist=threelist[::-1]

j=0
while True:
    if L>=threelist[j]:
       break
    else:
        j+=1

node=len(threelist)-j

PATH=[]
for i in range(2,2+node):
    PATH.append((i,i+1,0))

    PATH.append((i,i+1,3**(node+2-i-1)))
    PATH.append((i,i+1,2*3**(node+2-i-1)))
    M+=3

while L>0:
    j=0
    while True:
        if L>=threelist[j]:
            break
        else:
            j+=1

    k=len(threelist)-j
    rest=L-(3**k-1)

    PATH.append((1,node+2-k,rest))
    M+=1

    L=rest-1

    if L==0:
        PATH.append((1,node+2,0))
        M+=1
        break
    if L==1:
        PATH.append((1,node+2,0))
        PATH.append((1,node+2,1))
        M+=2
        break

print(node+2,M)
for pa in PATH:
    print(pa[0],pa[1],pa[2])

Solution (Python):
L = int(input())
N = len(bin(L)) - 2 
nodes = []
for i in range(N - 1):
    u1, v1, w1 = i + 1, i + 2, 0
    u2, v2, w2 = i + 1, i + 2, (1 << i)
    nodes.append([u1, v1, w1])
    nodes.append([u2, v2, w2])
for i in range(1, N):
    if (L >> (i - 1)) & 1 == 1:
        u, v, w = i, N, (L >> i ) << i
        nodes.append([u, v, w])
M = len(nodes)
print(N, M)
for i in range(M):
    u, v, w = nodes[i]
    print(u, v, w)

Solution (Python):
import math

L = int(input())
n = int(math.log2(L))
N = n + 1

edges = []
for i in range(1, N):
    edges.append((i, i + 1, 0))
    edges.append((i, i + 1, 2 ** (n - i)))

res = L - 2 ** n
bits = format(res, '0' + str(n) + 'b')
weight = 2 ** n
for i, bit in enumerate(bits):
    if int(bit):
        edges.append((1, i + 2, weight))
        weight += 2 ** (n - i - 1)

print(N, len(edges))
for row in edges:
    print(*row)

Solution (Python):


l = int(input())


for i in range(21):
    if 2**i >l:
        n = i
        break

m = (n-1)*2

s = l-2**(n-1)
value = 2**(n-1)

path_add = [0 for i in range(n-1)]
path_add_value = [0 for i in range(n-1)]

for i in range(n-1):
    if s >= 2**(n-2-i):
        s -= 2**(n-2-i)
        path_add[-(i+1)] = 1
        path_add_value[-(i+1)]=value
        value += 2**(n-2-i)

print(n,m+sum(path_add))
for i in range(n-1):
    print(i+1,i+2,0)
    print(i+1,i+2,2**i)

for i in range(n-1):
    if path_add[i] == 1:
        print(i+1, n, path_add_value[i])

Solution (Python):
import math
L = int(input())
N = math.floor(math.log2(L))+1
M = N*2-2

add_path = []
for i in range(1,N)[::-1]:
    if L-2**(i-1) >= 2**(N-1):
        add_path.append([i, L-2**(i-1)])
        L -= 2**(i-1)

print(N, M+len(add_path))
[print(i, i+1, 2**(i-1)*j) for i in range(1,N) for j in range(2)]
[print(i[0], N, i[1]) for i in add_path]

Solution (Python):
import math
L = int(input())
N = math.floor(math.log2(L))+1

M = N*2-2
add_path = []
for i in range(1,N)[::-1]:
    if L-2**(i-1) >= 2**(N-1):
        add_path.append([i, L-2**(i-1)]); L -= 2**(i-1)
print(N, M+len(add_path))
for i in range(1,N):
    print(i, i+1, 0)
    print(i, i+1, 2**(i-1))
for i in add_path:
    print(i[0], N, i[1])

Solution (Python):
import math
L = int(input())
s = int(math.log2(L))
N = s+1

count = 0
graph = []
for i in range(N-1,0,-1):
    if L - 2 ** (i-1) >= 2 ** s:
        graph.append([i, N ,L-2 ** (i-1)])
        L = L - 2 ** (i-1)
        count += 1

print(N, end = ' ')
print(2*(N-1)+count)



for i in range(N,1,-1):
    print(i-1, end = ' ')
    print(i, end = ' ')
    print(0)
    print(i - 1, end=' ')
    print(i, end=' ')
    print(2 ** (i-2))

for i in range(len(graph)):
    print(graph[i][0], end = ' ')
    print(graph[i][1], end = ' ')
    print(graph[i][2])

Solution (Python):
L = int(input())
for i in range(20):
    if 2**i > L: N = i; break
else: N = 20
M = N*2-2
add_path = []
for i in range(1,N)[::-1]:
    if L-2**(i-1) >= 2**(N-1): add_path.append([i, L-2**(i-1)]); L -= 2**(i-1)
print(N, M+len(add_path))
for i in range(1,N):
    print(i, i+1, 0); print(i, i+1, 2**(i-1))
for i in add_path:
    print(i[0], N, i[1])

Solution (Python):
l=int(input())
ll=l
l3=[]
while True:
    if ll//3==0:
        l3.append(ll)
        break
    else:
        l3.append(ll%3)
        ll=ll//3
N=len(l3)+1
edge=[]
for i in range(1,len(l3)):
    edge.append([i,i+1,0])
    edge.append([i,i+1,1*3**(i-1)])
    edge.append([i,i+1,2*3**(i-1)])

a=0
for i in range(len(l3)):
    for j in range(l3[i]):
        edge.append([i+1,N,j*3**i+a])
    a+=l3[i]*3**i

print(N,len(edge))
for i in edge:
    print(i[0],i[1],i[2])

Solution (Python):
L = int(input())

def power2(i):
    power = 0
    while i > 1:
        i //= 2
        power += 1
    return power

r = power2(L)
N = r + 1
M = []
for i in range(1, N):
    M.append([i, i+1, 0])
    M.append([i, i+1, 2**(i-1)])

for i in range(N-1, 0, -1):
    if L - 2 ** (i-1) >= 2 ** r:
        M.append([i, N, L-2**(i-1)])
        L -= 2**(i-1)
M.sort()
print(N, len(M))
for i in M:
    print(i[0], i[1], i[2])

Solution (Python):
from collections import defaultdict,deque
import sys,heapq,bisect,math,itertools,string,queue,datetime
sys.setrecursionlimit(10**8)
INF = float('inf')
mod = 10**9+7
eps = 10**-7
def inp(): return int(input())
def inpl(): return list(map(int, input().split()))
def inpls(): return list(input().split())

L = int(input())
N = L.bit_length()

Lines = []
for i in range(1,N):
	Lines.append([i,i+1,0])
	Lines.append([i,i+1,1<<(N-i-1)])

tmp = 1<<(N-1)
for k in reversed(range(N-1)):
	if L>>k & 1:
		Lines.append([1,N-k,tmp])
		tmp += 1<<k

print(N,len(Lines))
for a,zu,nyan in Lines:
	print(a,zu,nyan)

Solution (Python):
l=int(input())
for i in range(21):
  if 2 ** i > l:
    n = i
    break

m = (n - 1) * 2
  
s = l -  2 ** (n - 1)
value = 2 ** (n - 1)

path_add = [0 for i in range(n - 1)]
path_add_value = [0 for i in range(n - 1)]

for i in range(n - 1):
  if s >= 2 ** (n - 2 - i) :
    s -= 2 ** (n - 2 - i)
    path_add[-(i + 1)] = 1
    path_add_value[-(i + 1)] = value
    value += 2 ** (n - 2 - i)
  



  
print(n, m + sum(path_add))
for i in range(n - 1):
  print(i + 1, i + 2, 0)
  print(i + 1, i + 2, 2 ** i)
  
for i in range(n - 1):
  if path_add[i] == 1:
    print(i + 1, n, path_add_value[i])

Solution (Python):



from math import log, floor

L = int(input())

N = floor(log(L, 2)) + 1
edge = []


for i in range(1, N):
    edge.append((i, i+1, 0))


for i in range(1, N):
    edge.append((i, i+1, 2**(i-1)))


X = 2 ** (N-1)


while L > X:
    r = floor(log(L - X, 2))
    edge.append((r + 1, N, X))
    X += 2 ** r


M = len(edge)
print(N, M)
for e in edge:
    print(' '.join(map(str, e)))

Solution (Python):


from math import log2, floor

L = int(input())

N = floor(log2(L)) + 1
edge = []


for i in range(1, N):
    edge.append((i, i+1, 0))


for i in range(1, N):
    edge.append((i, i+1, 2**(i-1)))


X = 2 ** (N-1)


while L > X:
    r = floor(log2(L - X))
    edge.append((r + 1, N, X))
    X += 2 ** r


M = len(edge)
print(N, M)
for e in edge:
    print(' '.join(map(str, e)))

Solution (Python):
L = int(input())
ans = []


N = len(bin(L)[2:])


for i in range(N - 1)[::-1]:
    ans.append([i + 1, i + 2, 2 ** (N - i - 2)])
    ans.append([i + 1, i + 2, 0])


need = L - (2 ** (N - 1))


cost = list(range(2 ** (N - 1), 2 ** (N -1) + need))


marker = 0


bit = bin(need)[2:][::-1]


for i in range(len(bit)):
    if bit[i] != "1":
        continue

    
    ans.append([1, N - i, cost[marker]])

    
    marker += 2 ** i

print(N, len(ans))
for a in ans:
    print(" ".join(map(str, a)))

Solution (Python):
L = int(input())
N = L.bit_length()
C = []
for i in range(N-1):
    C.append((N-i-1, N-i, 1 << i))
    C.append((N-i-1, N-i, 0))
v = 1
for i in range(N-1):
    if v & L:
        L ^= v
        C.append((1, N-i, L))
    v <<= 1
print(N, len(C))
for x, y, z in C:
    print(x, y, z)

Solution (Python):
import math
L = int(input())
r = int(math.log2(L))

res = []
for i in range(1, r+1):
    res.append([i, i+1, 0])
    res.append([i, i+1, 2**(i-1)])

for t in range(r, 0, -1):
    if L >= 2**r + 2**(t-1):
        L -= 2**(t-1)
        res.append([t, r+1, L])

print(r+1, len(res))
for i in range(len(res)):
    print(res[i][0], res[i][1], res[i][2])

Solution (Python):
from math import log2
n = int(input())
r, ans  = int(log2(n)), []
for i in range(1,r+1):
    ans.append([i,i+1,2**(i-1)])
for i in range(r, 0, -1):
    if n - 2**(i-1) >= 2**r:
        ans.append([i, r+1, n-2**(i-1)])
        n -= 2**(i-1)
print(r+1, len(ans)+r)
for i in range(1,r+1):
    print(i, i+1, 0)
for i,j,k in ans:
    print(i, j, k)

Solution (Python):
import math

L = int(input())
n = int(math.log2(L))

dag = []
for i in range(1, n+1):
    dag.append(' '.join(map(str, [i, i+1, 2**(i-1)])))
    dag.append(' '.join(map(str, [i, i+1, 0])))

for i in range(n, 0, -1):
    if L - 2**(i-1) >= 2**n:
        L -= 2**(i-1)
        dag.append(' '.join(map(str, [i, n+1, L])))

print(n+1, len(dag))
print('\n'.join(dag))

Solution (Python):
def d_all_your_paths_are_different_lengths(L):
    
    
    
    do = []  
    while L > 2:
        if L % 2 == 0:
            do.append('*2')
            L >>= 1
        else:
            do.append('+1')
            L -= 1
    do.reverse()

    
    vertex = 2  
    edge = [[1, 2, 0], [1, 2, 1]]  
    l = 2
    for op in do:
        if op == '*2':
            
            edge = [[v1, v2, c * 2] for v1, v2, c in edge]
            edge.append([vertex, vertex + 1, 0])
            edge.append([vertex, vertex + 1, 1])
            vertex += 1
            l *= 2
        elif op == '+1':
            
            edge.append([1, vertex, l])
            l += 1

    
    ans = '{} {}\n'.format(vertex, len(edge))
    ans += '\n'.join([' '.join(map(str, row)) for row in edge])
    return ans

L = int(input())
print(d_all_your_paths_are_different_lengths(L))

Solution (Python):
def d_all_your_paths_are_different_lengths(L):
    do = []
    while L > 2:
        if L % 2 == 0:
            do.append('*2')
            L >>= 1
        else:
            do.append('+1')
            L -= 1
    do.reverse()

    vertex = 2
    l = 2
    edge = [[1, 2, 0], [1, 2, 1]]
    for op in do:
        if op == '*2':
            edge = [[v1, v2, c * 2] for v1, v2, c in edge]
            edge.append([vertex, vertex + 1, 0])
            edge.append([vertex, vertex + 1, 1])
            vertex += 1
            l *= 2
        elif op == '+1':
            edge.append([1, vertex, l])
            l += 1

    ans = '{} {}\n'.format(vertex, len(edge))
    ans += '\n'.join([' '.join(map(str, row)) for row in edge])
    return ans

L = int(input())
print(d_all_your_paths_are_different_lengths(L))

Solution (Python):
L = int(input()) - 1

N = []
n = 0

for i in range(20):
  if 2 ** i - 1 > L:
    break
  n = i

c = 2 ** n - 1
d = 2 ** (n - 1)
m = 2 * n
n += 1

for i in range(n-1, 0, -1):
  A = [(i, i+1, 0), (i, i+1, d)]
  if L - (d - 1) > c:
    L -= d
    m += 1
    A.append((i, n, L+1))
  N.append(A)
  d //= 2
  
print(n, m)
for a in N:
  for b in a:
    print(*b)

Solution (Python):
def iin(): return int(input())

l = iin()
stack = []

ans = [[1, 2, 0]]
x = l
while True:
    if x == 1:
        break
    
    
    
    while x % 2 == 0 and x > 2:
        x //= 2
        stack.append('*2')
    if x == 1:
        break
    x -= 1
    stack.append('+1')

last_v_num = 2
x = 1
while len(stack) > 0:
    op = stack.pop()

    if op == '+1':
        x += 1
        ans.append([1, last_v_num, x - 1])
    elif op == '*2':
        x *= 2
        for i in range(len(ans)):
            ans[i][2] *= 2
        
        ans.append([last_v_num, last_v_num + 1, 0])
        ans.append([last_v_num, last_v_num + 1, 1])
        last_v_num += 1

N = last_v_num
M = len(ans)
print(N, M)
for u, v, w in ans:
   print(u, v, w)

Solution (Python):
L = int(input())

p = 0
ans = []
while(L >= 2 ** (p + 1)):
    ans.append([p + 1, p + 2, 2 ** p])
    ans.append([p + 1, p + 2, 0])
    p += 1

endN = p + 1

tmp = 2 ** p
L -= tmp

while(L != 0):
    p = 0
    while(L - 2 ** p >= 0):
        p += 1

    ans.append([p, endN, tmp])
    L -= 2 ** (p - 1)
    tmp += 2**(p - 1)



print(endN, len(ans))
for a, b, c in ans:
    print(a, b, c)

Solution (Python):
from math import log2
n = int(input())
r,ans = int(log2(n)),[]
for i in range(1,r+1): ans.append([i,i+1,2**(i-1)])
for i in range(r,0,-1):
	if n-2**(i-1)>=2**r:
		ans.append([i,r+1,n-2**(i-1)])
		n-=2**(i-1)
print(r+1,len(ans)+r)
for i in range(1,r+1): print(i,i+1,0)
for i,j,k in ans: print(i,j,k)

Solution (Python):
L = int(input())

x = L

xs1 = []
xs2 = []
xs3 = []

for i in range(19):
    c = 18 - i
    xs1.append((i + 1, i + 2, 0))



b = 0

for i in range(20):
    n = 19 - i
    r = 2 ** n
    if x >= r:
        m = n
        x -= r
        b += r
        
        break




for i in range(i + 1, 20):
    n = 19 - i
    r = 2 ** n
    if x >= r:
        xs3.append((n + 1, 20, b))
        x -= r
        b += r
        

for i in range(m):
    xs2.append((i + 1, i + 2, 2**i))

xs = xs1 + xs2 + xs3

print(20, len(xs))

for x in xs:
    print(*x)

Solution (Python):
l = int(input())
r = len(bin(l)[2:])-1

w = 2**r
outlist = []

for t in range(r,0, -1):
    if l - 2**r >= 2**(t-1):
        outlist.append("{} {} {}".format(t, r+1, w))
        w += 2**(t-1)
        l = l-2**(t-1)

print(r+1, len(outlist)+2*r)
for i in range(1, r+1):
    print("{} {} 0".format(i, i+1))
    print("{} {} {}".format(i, i+1, 2**(i-1)))
for j in outlist:
    print(j)

Solution (Python):
l = int(input())

p = 0
while True:
    if 2**p > l:
        p -= 1
        break
    else:
        p += 1
        
n = p+1
m = 2*p
ans = []
for i in range(1, n):
    ans.append([i, i+1, 0])
    ans.append([i, i+1, 2**(i-1)])
    
while l > 2**p:
    for i in range(n-1, 0, -1):
        if l-2**(i-1) >= 2**p:
            ans.append([i, n, l-2**(i-1)])
            l = l-2**(i-1)
            m += 1
            break

print(n, m)
for a in ans:
    print(' '.join(list(map(str, a))))

Solution (Python):
import math

L = int(input())
r = math.floor(math.log2(L))
N = r + 1

E_list = []

for i in range(1, N):
    E_list.append((i, i+1, 0))
    E_list.append((i, i+1, 2**(r - i)))
    if L - 2**(N-i-1) >= 2**r:
        E_list.append((1, i+1, L - 2**(N-i-1)))
        L -= 2**(N-i-1)

M = len(E_list)

print(N, M)
for e in E_list:
    print(e[0], e[1], e[2])

Solution (Python):
L = int(input())

def decompose(L):
    if L < 2:
        assert L == 1
        return []
    r = L % 2
    return [r] + decompose((L - r) // 2)

dec = decompose(L)

N = len(dec) + 1
edge = []

base = 1
for i in range(len(dec) - 1, -1, -1):
    for w in range(2):
        edge.append((i+1, i+2, w * base))
    base *= 2
    for w in range(dec[i]):
        edge.append((i+1, N, base + w))
    base += dec[i]

M = len(edge)
print(N, M)
for e in edge:
    print(' '.join(map(str, e)))

Solution (Python):
import math
l = int(input())
r = math.floor(math.log2(l))
n = r+1
pow2r = pow(2, r)
lst = list([i, i+1, 0] for i in range(1, n)) + list([i, i+1, pow(2, i-1)] for i in range(1, n))
for i in range(1, n)[::-1]:
    p = pow(2, i-1)
    if l - p >= pow2r:
        lst.append([i, n, l-p])
        l -= p
print(n, len(lst))
for u, v, w in lst:
    print(u, v, w)

Solution (Python):
L = int(input())

def decompose(L):
    if L < 3:
        return [L]
    r = L % 3
    return [r] + decompose((L - r) // 3)

dec = decompose(L)

N = len(dec) + 1
edge = []

for w in range(dec[-1]):
    edge.append((N-1, N, w))

base = dec[-1]
for i in range(len(dec) - 2, -1, -1):
    for w in range(3):
        edge.append((i+1, i+2, w * base))
    base = 3 * base
    for w in range(dec[i]):
        edge.append((i+1, N, base + w))
    base += dec[i]

M = len(edge)
print(N, M)
for e in edge:
    print(' '.join(map(str, e)))

Solution (Python):
import math

L = int(input())
r = int(math.log2(L))


vertex = r + 1
edge = 2 * r
res = []
for i in range(1,r+1):
    res.append([i,i+1,0])
    res.append([i,i+1,2**(i-1)])

for i in range(r,0,-1):
    if L-2**(i-1)>=2**r:
        L -= 2**(i-1)
        res.append([i,vertex,L])
        edge += 1

print(vertex,edge)
for l in res:
    print(*l)

Solution (Python):
l = int(input())

if l <= 60:
    n = 2
    print(n, l)
    for i in range(l):
        print(1, n, i)
    exit()

p = []
temp = l
while temp > 0:
    p.append(temp % 2)
    temp //= 2

ans = []
res = []
n = len(p)
temp = 1
for i in range(n - 1):
    ans.append([i + 1, i + 2, 0])
    ans.append([i + 1, i + 2, temp])
    temp *= 2

m = l - temp + 1
s = n
fuga = temp
while m > 0 and s > 0:
    
    if m > temp:
        m -= temp
        ans.append([s, n, fuga])
        fuga += temp
        
    temp //= 2
    s -= 1

print(n, len(ans))
t = 1
for x in ans:
    print(x[0], x[1], x[2])

Solution (Python):

import sys
import math
import numpy as np
import itertools


l = int(input())
a=[]
n=0
while l > 0:
    a.append(l%2)
    l=l//2
    n += 1

aa=0
for k in range(n):
    aa += a[k]
print(n,2*(n-1)+aa-1)
for k in range(1,n):
    print(k,k+1,0)
    print(k,k+1,2**(k-1))
p=2**(n-1)
for k in range(n-2,-1,-1):
    if a[k]==1:
        print(k+1,n,p)
        p=p+2**(k)

Solution (Python):
L = int(input())

bL = bin(L)[2:]

N = len(bL)
L = 2 * (N-1) + bL[1:].count('1')
print(N, L)

for i, b in enumerate(bL[1:]):
    if b == '1':
        print(1, i+2, 0)

M, m = 0, 0
for i, b in enumerate(bL[:0:-1]):
    add = M - m + 1
    if b == '1':
        print(N-i-1, N-i, add)
        print(N-i-1, N-i, 2*add)
        m += add
        M += 2 * add
    else:
        print(N-i-1, N-i, 0)
        print(N-i-1, N-i, add)
        M += add