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-----
4

-----Sample Output-----
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.

Difficulty: interview

Starter code:

Solutions:
import math

l = int(input()) - 1
n = int(math.log2(l + 1) + 1)
res = []
for i in range(n - 1):
    res.append([i + 1, i + 2, 0])
    res.append([i + 1, i + 2, 2 ** i])
i = n - 2
while l > 2 ** (n - 1) - 1:
    t = l - 2 ** i + 1
    if t > 2 ** (n - 1) - 1:
        res.append([i + 1, n, t])
        l = t - 1
    i -= 1
print((n, len(res)))
for i in range(len(res)):
    print((res[i][0],res[i][1],res[i][2]))


L=int(input())
l=0
pp=0
tmp=L
while tmp>0:l+=1;pp+=tmp%2;tmp//=2
print(l,l*2-3+pp)
for i in range(1,l):
  print(i,i+1,0)
  a=1<<i-1
  print(i,i+1,a)
  if L&a:L-=a;print(i,l,L)

def main():
    L = int(input())
    r = 0
    while 2 ** (r+1) <= L:
        r += 1
    assert r < 20
    N = r + 1
    edges = list()
    for i in range(1, N):
        edges.append((i, i + 1, 0))
        edges.append((i, i + 1, 2**(i - 1)))
    for t in range(N - 1, 0, -1):
        if L - 2**(t - 1) >= 2**r:
            edges.append((t, N, L - 2**(t - 1)))
            L -= 2**(t - 1)
    print('{} {}'.format(N, len(edges)))
    for e in edges:
        print(' '.join(map(str, e)))


def __starting_point():
    main()
__starting_point()

l=int(input())
for i in range(1,21):
	if 2**i>l:
		r=i-1
		break
ans=[]
for i in range(r):
	ans.append((i+1,i+2,0))
	ans.append((i+1,i+2,2**i))
now=2**r-1
for i in range(r,0,-1):
	if 2**(i-1)+now<=l-1:
		ans.append((i,r+1,now+1))
		now+=2**(i-1)
print(r+1,len(ans))
for x in ans:
	print(*x)

import math

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

M = 2*(N-1)

# print(N, )
edges = []
for i in range(N-1):
    edges.append('{0} {1} {2}'.format((i+1) , (i+2), 0))
    
for i in range(N-1):
    edges.append('{0} {1} {2}'.format((i+1) , (i+2), 2**i))

node = L-2**(N-1)
X = 2**(N-1)

while node > 0:
    M += 1
    t = int(math.log2(node))+1
    edges.append('{0} {1} {2}'.format(t, N, X))
    node -= 2**(t-1)
    X += 2**(t-1)
    
output = """{0} {1}
{2}""".format(N,M,'\n'.join(edges))
print(output)

# 解説を参考に作成
# import sys
# sys.setrecursionlimit(10 ** 6)
# import bisect
# from collections import deque
# from decorator import stop_watch
# 
# 
# @stop_watch
def solve(L):
    import math
    N = int(math.log2(L))
    grahp = []
    for i in range(1, N + 1):
        grahp.append([i, i + 1, 0])
        grahp.append([i, i + 1, 2 ** (i - 1)])
    for i in range(N, 0, -1):
        if L - 2 ** (i - 1) >= 2 ** N:
            L = L - 2 ** (i - 1)
            grahp.append([i, N + 1, L])
    M = len(grahp)

    print(N + 1, M)
    [print(' '.join([str(i) for i in g])) for g in grahp]



def __starting_point():
    # S = input()
    L = int(input())
    # N, M = map(int, input().split())
    # A = [int(i) for i in input().split()]
    # B = [int(i) for i in input().split()]
    # AB = [[int(i) for i in input().split()] for _ in range(N)]
    solve(L)

    # # test
    # from random import randint
    # from func import random_str
    # solve()

__starting_point()

# coding: utf-8
import sys

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

L = ir()
edges = []
length = L.bit_length()
for i in range(1, length):
    edges.append((i, i+1, 2**(i-1)))
    edges.append((i, i+1, 0))

# 2**(length-1)-1までの数は完了
# Lに近い切れ端から処理していく
for i in range(length-1):
    if L >> i & 1:
        L -= 2 ** i
        edges.append((i+1, length, L))

print((length, len(edges)))
for x in edges:
    print((*x))



def get_node(num):
    now_num = 1
    count = 1
    while 1:
        if now_num > num:
            count -= 1
            break
        count += 1
        now_num *= 2
    return count

def get_ans_data(node_num):
    ans_data = []
    for i in range(1, node_num):
        data = [i, i + 1, 2**(i - 1)]
        data2 = [i, i + 1, 0]
        ans_data.append(data)
        ans_data.append(data2)
    return ans_data

def main():
    num = int(input())

    node_num = get_node(num)
    ans_data = get_ans_data(node_num)

    now_path = 2 ** (node_num - 1)
    now_num = node_num - 1


    for i in range(now_num, 0, -1):
        now_data = 2 ** (i - 1)
        if num - now_data >= now_path:
            ans_data.append((i, node_num, num - now_data))
            num -= now_data

    print((node_num, len(ans_data)))
    for data in ans_data:
        print((' '.join(list(map(str, data)))))


def __starting_point():
    main()

__starting_point()

import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(10 ** 9)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7

# MOD = 998244353


L = int(sys.stdin.buffer.readline())
# 2べきなら2個ずつ辺を張ればOK
V = L.bit_length()
ans = []
for v in range(V - 1):
    ans.append((v, v + 1, 0))
    ans.append((v, v + 1, 2 ** v))

pos = V - 2
w = 1 << L.bit_length() - 1
while pos >= 0:
    if L & (1 << pos):
        ans.append((pos, V - 1, w))
        w |= L & (1 << pos)
    pos -= 1
E = len(ans)
print((V, E))
for r in ans:
    v, u, w = r
    v += 1
    u += 1
    print((v, u, w))


from math import log2


L = int(input())
r = int(log2(L))
N = r + 1
edge = []
for i in range(r):
    edge.append((i + 1, i + 2, 2 ** i))
    edge.append((i + 1, i + 2, 0))
for t in range(N - 1, 0, -1):
    s = L - 2 ** (t - 1)
    if s >= 2 ** r:
        edge.append((t, N, s))
        L = s

print((N, len(edge)))
for e in edge:
    print((*e))


L = int(input())
N = len(bin(L)[2:])
R = 1 << N - 1
UVW = sum([[(i, i+1, 0), (i, i+1, 1<<i-1)] for i in range(1, N)], [])
for i, s in enumerate(bin(L)[:2:-1], 1):
    if s == "1":
        UVW.append((i, N, R))
        R += 1 << i - 1

print(N, len(UVW))
for t in UVW:
    print(*t)

import sys
import math

input_methods=['clipboard','file','key']
using_method=1
input_method=input_methods[using_method]

tin=lambda : map(int, input().split())
lin=lambda : list(IN())
mod=1000000007

#+++++

def main():
	L = int(input())
	#b , c = tin()
	#s = input()
	v = int(math.log2(L))
	#pa(v)
	num_p = v
	path_info=[]
	for i in range(v):
		path_info.append([i,i+1,0])
		path_info.append([i,i+1,2**i])
	
	#for li in path_info:
	#	print(*li)
	
	nokori = L - (2 ** v)
	
	#print(nokori)
	for i in range(v+1):
		m = v - i
		if 2 ** m <= nokori:
			path_info.append([m, v, L - nokori])
			nokori -= 2 ** m
	print(v+1, len(path_info))
	for l in path_info:
		f,t,w = l
		print(*[f+1, t+1, w])
	
	
#+++++
isTest=False

def pa(v):
	if isTest:
		print(v)
		
def input_clipboard():
	import clipboard
	input_text=clipboard.get()
	input_l=input_text.splitlines()
	for l in input_l:
		yield l

def __starting_point():
	if sys.platform =='ios':
		if input_method==input_methods[0]:
			ic=input_clipboard()
			input = lambda : ic.__next__()
		elif input_method==input_methods[1]:
			sys.stdin=open('inputFile.txt')
		else:
			pass
		isTest=True
	else:
		pass
		#input = sys.stdin.readline
			
	ret = main()
	if ret is not None:
		print(ret)
__starting_point()

# mada dame datta.
def main():
    L = int(input())
    b = bin(L)[2:]
    bl = len(b)
    r = []
    for i in range(bl-1):
        r.append((i+1, i+2, 0))
        r.append((i+1, i+2, 2**i))
    if L == 2**(bl-1):
        pr(r)
        return
    end = bl
    for i in reversed(list(range(1, end))):
        if L - 2**(i-1) >= 2**(end-1):
            r.append((i, end, L-2**(i-1)))
            L -= 2**(i-1)
    pr(r)
def pr(r):
    m = 0
    for i in r:
        m = max(m, i[1])
    print((m, len(r)))
    for i in r:
        print((i[0], i[1], i[2]))
main()


#!/usr/bin/env python3
import sys


def solve(L: int):
    sL = "{:b}".format(L)
    N = len(sL)
    M = 2 * (N - 1) + sL.count("1") - 1
    print((N, M))
    for i in range(N - 1):
        print((i + 1, i + 2, 0))
        print((i + 1, i + 2, 2 ** i))
    for i, c in enumerate(reversed(sL[1:])):
        if c == "0":
            continue
        print((i + 1, N, int(sL[:-i - 1], 2) * 2 ** (i + 1)))


def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    L = int(next(tokens))  # type: int
    solve(L)


def __starting_point():
    main()

__starting_point()

L = int(input())

print((L.bit_length(), 2*(L.bit_length()-1) + (bin(L)[3:]).count('1')))
for i in range(L.bit_length()-1,0,-1):
    print((i,i+1,0))
    print((i,i+1,1<<(i-1)))
    if (L >> i-1) & 1:
        print((i,L.bit_length(),L>>i<<i))


import sys

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

# L と 2 ** n の差
L = ir()
length = L.bit_length()
edges = []
for i in range(1, length):
    edges.append((i, i+1, 0))
    edges.append((i, i+1, 2**(i-1)))

for i in range(length-1):
    if L >> i & 1:
        L -= 2**i
        edges.append((i+1, length, L))

print((length, len(edges)))
for e in edges:
    print((*e))

# 56


import sys
from math import log2, floor

L = int(sys.stdin.readline().rstrip())

def main():
    n = floor(log2(L)) + 1
    m = 2 * (n - 1)
    edges = []
    for i in range(1, n):
        edges.append((i, i+1, 0))
        edges.append((i, i+1, 2**(i-1)))
    
    cur = 2 ** (n - 1)
    q = L - cur
    for i in range(1, n):
        q, r = divmod(q, 2)
        if not r:
            continue
        else:
            edges.append((i, n, cur))
            cur += 2 ** (i - 1)
            m += 1
    
    yield (n, m)
    for e in edges:
        yield e

def __starting_point():
    ans = main()
    for i in ans:
        print(*i, sep=' ')
__starting_point()

L = int(input())
edges = []

p2 = 1
N = 1

""" 2べきのとき多重辺
   0     0     0     0  ...
1 === 2 === 3 === 4 === 5 ...
   1     2     4     8  ...
"""
while L >= p2 * 2:
    N += 1
    p2 *= 2
    edges.append((N - 1, N, 0))
    edges.append((N - 1, N, 2 ** (N - 2)))

rest = L - p2
tmp = p2
for i in range(N, -1, -1):
    if (rest >> i) & 1:
        edges.append((i + 1, N, tmp))
        tmp += 2 ** i

M = len(edges)
# assert N <= 20 and M <= 60
print((N, M))
for edge in edges:
    print((*edge))


def f(k,L,p): 
  m = L
  while m%3 > 0:
    p += [[k+1,20,(m-1)*(3**k)]]
    m = m-1
  if m == 0:
    print(20,len(p))
    for l in p:
      print(" ".join([str(t) for t in l]))
    return
  for i in range(3):
    p += [[k+1,k+2,i*(3**k)]]
  m = m//3
  if m > 0:
    return f(k+1,m,p)




f(0,int(input()),[])

L=int(input())
n=L.bit_length()
if L==2**n:
  n+=1
path=[]
for i in range(1,n):
  path.append([i,i+1,0])
  path.append([i,i+1,2**(i-1)])
k=(L-1)-(2**(n-1)-1)
cur=2**(n-1)
while k>0:
  if k==1:
    kk=1
  else:
    kk=k.bit_length()
  path.append([kk,n,cur])
  cur+=2**(kk-1)
  k=L-cur
print(n,len(path))
for p in path:
  print(*p)

import copy
n = int(input())
a = [2**x for x in range(0,21) ]
b = 0
for i, name in enumerate(a):
    b_copy = copy.deepcopy(b)
    b = name
    if b > n:
        break

ans = []
ans_l = []
c = n - b_copy
for j in range(i-1)[::-1]:
    if a[j] <= c:
        c -= a[j]
        ans.append(j)
        ans_l.append(b_copy)
        b_copy += a[j]

N = i
H = 0
A = []

for k in range(1, i):
    A.append([k, k+1, 0])
    A.append([k, k+1, 2**(k-1) ])
    H += 2
    if k-1 in ans:
        A.append([k, N, ans_l[ans.index(k-1)]])
        H += 1

print(" ".join([str(N), str(H)]))
for kk in A:
    print(" ".join(list(map(str, kk))))

L = int(input())

Lbin = (bin(L)[2:])[::-1]
N = len(Lbin)
M = 2 * (N - 1) + Lbin.count("1") - 1
print(N, M)

for i in range(0, N - 1):
    print(i + 1, i + 2, 0)
    print(i + 1, i + 2, 2 ** i)

weight = L
for i in range(0, N - 1):
    if Lbin[i] == '1':  # 2^iの位
        weight -= 2 ** i
        print(i + 1, N, weight)

#
# 　　  ⋀_⋀　 
#　　  (･ω･)  
# .／ Ｕ ∽ Ｕ＼
#  │＊　合　＊│
#  │＊　格　＊│ 
#  │＊　祈　＊│ 
#  │＊　願　＊│ 
#  │＊　　　＊│ 
#      ￣
#
import sys
sys.setrecursionlimit(10**6)
input=sys.stdin.readline
from math import floor,sqrt,factorial,hypot,log #log2ないｙｐ
from heapq import heappop, heappush, heappushpop
from collections import Counter,defaultdict,deque
from itertools import accumulate,permutations,combinations,product,combinations_with_replacement
from bisect import bisect_left,bisect_right
from copy import deepcopy
from fractions import gcd
from random import randint
def ceil(a,b): return (a+b-1)//b
inf=float('inf')
mod = 10**9+7
def pprint(*A): 
    for a in A:     print(*a,sep='\n')
def INT_(n): return int(n)-1
def MI(): return map(int,input().split())
def MF(): return map(float, input().split())
def MI_(): return map(INT_,input().split())
def LI(): return list(MI())
def LI_(): return [int(x) - 1 for x in input().split()]
def LF(): return list(MF())
def LIN(n:int): return [I() for _ in range(n)]
def LLIN(n: int): return [LI() for _ in range(n)]
def LLIN_(n: int): return [LI_() for _ in range(n)]
def LLI(): return [list(map(int, l.split() )) for l in input()]
def I(): return int(input())
def F(): return float(input())
def ST(): return input().replace('\n', '')
def main():
    L=I()
    power = 1
    N = 1
    while power<<1 <= L:
        power<<=1
        N+=1
    
    ans = []
    for i in range(N-1):
        ans.append((i+1,i+2,0))
        ans.append((i+1,i+2,1<<i))
    for i in range(N-1)[::-1]:
        X=L-(1<<i)
        if(X>=power): #X<(1<<N)ならダブる
            ans.append((i+1,N,X))
            L-=1<<i
    M=len(ans)
    print(N,M)
    for a in ans:
        print(*a)
def __starting_point():
    main()
__starting_point()

import numpy as np

L = int(input())

branches = []
# ノード数は (2^n - 1) のときに 1 増える
node_count = int(np.log2(L)) + 1

# (0, 1), (0, 2), (0, 4), ... って2個ずつブランチ引く。
# これで 0 から 2^n - 1 (< L) まで作れる
for n in range(node_count - 1):
    branches.append((n, n + 1, 0))
    branches.append((n, n + 1, 2 ** n))

# これが '1' のノードから最後まで線を引きたい
byte_list = list(reversed(format(L, 'b')))[:-1]
# 長さはそれっぽい感じにする
a = 2 ** (node_count - 1)
for i in reversed(list(range(len(byte_list)))):
    if byte_list[i] == '1':
        branches.append((i, node_count - 1, a))
        a += 2 ** i

print((node_count, len(branches)))
for u, v, w in branches:
    print((u + 1, v + 1, w))


L=int(input())
n=len(str(bin(L)))-3
e=[]
for i in range(n):
    e.append((i+1, i+2, 0))
    e.append((i+1, i+2, 2**(n-i-1)))
h=2**n
for i, c in enumerate(str(bin((L)))[2:]):
    if c=="1"and i:
        e.append((1,i+1,h))
        h+=2**(n-i)
print(n+1,len(e))
for i in e:print(*i)

def gen_graph(i,step,L):
  # index iから始める
  # 0からweight*(L-1)までのL種の長さを作る
  if L == 1:
    return [i],[]
  v,e = gen_graph(i+1,2*step,L//2)
  v = [i] + v
  e = e + [(i,i+1,0),(i,i+1,step)]
  # (0 or 1)+(L//2種の偶数)が作れている
  if L%2 == 0:
    return v,e
  e.append((i,v[-1],step*(L-1)))
  return v,e

L = int(input())

v,e = gen_graph(1,1,L)
print((len(v),len(e)))
for a,b,c in e:
  print((a,b,c))




#!/usr/bin/env python3
import sys


def solve(L: int):
    tmp = L
    a = []
    while tmp > 0:
        a.append(tmp)
        tmp //= 2
    a.reverse()
    #print(a)
    e = []
    for i in range(1, len(a)):
        e.append([i, i + 1, 0])
        e.append([i, i + 1, a[i - 1]])
        if a[i] % 2 > 0:
            e.append([1, i + 1, a[i] - 1])
    print((len(a), len(e)))
    for t in e:
        print((t[0], t[1], t[2]))
    return


def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    L = int(next(tokens))  # type: int
    solve(L)

def __starting_point():
    main()

__starting_point()

L = int(input())

b = bin(L-1)[2:]
l = len(b)
out = []
for i in range(1,l+1):
    out.append([i,i+1,0])
for i in range(2,l+1):
    out.append([i,i+1,1<<(l-i)])

if not "0" in b:
    out.append([1,2,1<<(l-1)])
    b = ""
while len(b)>0 and b != "0":
    if b[-1] == "0":
        out.append([1,len(b)+1,int((b+"0"*l)[:l],2)])
        b = bin(int(b,2)-1)[2:]
    b = b[:-1]

if l < 20:
    print(l+1,len(out))
    for sub in out:
        print(" ".join(map(str,sub)))
else:
    print(l,len(out)-1)
    for u,v,w in out[1:]:
        u = max(1,u-1)
        v = max(1,v-1)
        print(u,v,w)

L = int(input())

r = 0
while 2 ** r <= L:
    r += 1

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

# 2**(r-1) ～ L-1 のPATHがない。

n = 2 ** (r - 1)

###
while True:
    d = L - 1 - n + 1
    if d <= 0:
        break
    zi = 0
    while 2 ** (zi) <= d:
        zi += 1

    E.append((zi, r, n))
    n = n + 2 ** (zi - 1)

print(("{} {}".format(r, len(E))))

for e in E:
    print(("{} {} {}".format(e[0], e[1], e[2])))


l = int(input())
l -= 1
to = [[] for _ in range(14)]
for i in range(1, 13):
    to[i].append((i + 1, 0 * 3 ** (12 - i)))
    to[i].append((i + 1, 1 * 3 ** (12 - i)))
    to[i].append((i + 1, 2 * 3 ** (12 - i)))
d = []
l_upto = []
t = l
s = 0
for i in range(13):
    d.append(t % 3)
    s += (t % 3) * 3 ** i
    l_upto.append(s)
    t //= 3

for i, t in enumerate(d):
    for s in range(t + (i == 0)):
        to[0].append((13 - i, l - l_upto[i] + 3 ** i * s))
print((14, sum(map(len, to))))
for i in range(len(to)):
    for j, cost in to[i]:
        print((i + 1, j + 1, cost))



def solve(l):
    n = 0
    while 2**n <= l:
        n += 1
    E = []
    for i in range(n-1, -1, -1):
        x = 2**i
        if i != n-1:
            E.append((i, i+1, 0))
            E.append((i, i+1, x))
        if l - x >= 2**(n-1):
            E.append((i, n-1, l-x))
            l -= x
    print(n, len(E))
    for u, v, x in E:
        print(u+1, v+1, x)

l = int(input())
solve(l)


L = int(input())

digit = L.bit_length()  # 必要なビット数(頂点数)

if 2**digit > L :
    digit -= 1

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

L = L - 2**digit  # 残り本数

tmp = 0
for i in range(digit, 0, -1) :
    if L - 2**(i - 1) >= 0 :
        ans.append([i, digit+1, 2**digit + tmp])
        L -= 2**(i - 1)
        tmp += 2**(i - 1)

print(digit+1, len(ans))
for a in ans :
    print(*a)

def main():
    l=int(input())
    n=1
    while (1<<n)<=l:
        n+=1
    ans=[]
    for i in range(n-1):
        ans.append([i,i+1,0])
        ans.append([i,i+1,1<<i])
    l-=1<<(n-1)
    val=1<<(n-1)
    for p in range(n-2,-1,-1):
        if l>=(1<<p):
            ans.append([p,n-1,val])
            val+=1<<p
            l-=1<<p
    print(n,len(ans))
    for a,b,c in ans:
        print(a+1,b+1,c)
main()

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

res = []

for i in range(N - 1):
    res.append((i + 1, i + 2, 1 << i))
    res.append((i + 1, i + 2, 0))

n = 1 << (i + 1)
m = L - n

for i in reversed(range(m.bit_length())):
    if (m >> i) & 1:
        m %= (1 << i)
        res.append((i + 1, N, n))
        n += (1 << i)


print(N, len(res))

for i in range(len(res)):
    print(*res[i])

L = t = int(input())
X = []
B = 4
while L:
    X.append(L%B)
    L//=B

E = []
N = len(X)*2
for i, x in enumerate(X[:-1]):
    r = B**i
    t -= r*x
    for k in range(0, x):
        E.append((2*i+1, 2*i+2, r*k))

    E.append((2*i+2, 2*i+3, 0))

    for k in range(x, B):
        E.append((2*i+1, 2*i+3, r*k))

    E.append((2*i+2, N, t))

for k in range(0, X[-1]):
    E.append((N-1, N, B**(len(X)-1)*k))

print(N, len(E))
for e in E:
    print(*e)

import math


l = int(input())
node = int(math.log2(l)) + 1
edges = []

for _from in range(1, node):
    edges.append([_from, _from+1, 0])
    edges.append([_from, _from+1, 2**(_from-1)])

count = 2 ** (node-1)
lack = l - count
length = 2 ** (node-1)

for _from in range(node-1, 0, -1):
    if not lack:
        break
    add_line = 2 ** (_from-1)
    if add_line > lack:
        continue
    edges.append([_from, node, length])
    lack -= add_line
    length += add_line

print((node, len(edges)))
for _from, to, length in edges:
    print((_from, to, length))


import math
L = int(input())
r = math.floor(math.log2(L))
N = r+1
graph = []
for i in range(1,r+1):
    graph.append([i,i+1,0])
    graph.append([i,i+1,2**(i-1)])
for t in range(N-1,0,-1):
    if L-2**(t-1) >= 2**r:
        graph.append([t,N,L-2**(t-1)])
        L -= 2**(t-1)

print((N,len(graph)))
for g in graph:
    print((*g))


l=int(input())
n=len(bin(l-1))-2 #頂点数
V=[]
if all([(l-1)>>i&1 for i in range(n)]):
    n+=1
    for i in range(n-1):
        V.append([i+1,i+2,0])
        V.append([i+1,i+2,2**(n-i-2)])


else:
    for i in range(n-1):
        V.append([i+1,i+2,0])
        V.append([i+1,i+2,2**(n-i-2)])

    now=2**(n-1)
    for i in range(n-2):
        if (l-1)>>(n-i-2)&1:
            V.append([1,i+2,now])
            now+=2**(n-i-2)
    if (l-1)&1:
        V.append([1,n-1,now])
    else:
        V.append([1,n,now])
print(n,len(V))
for v in V:
    print(*v)

import sys
input = sys.stdin.readline

L = int(input())
ans = [[1,2,0],[1,2,1]]#L=2の答え
S=1
T=2
def recursion(x):
    nonlocal T
    if x == 2:
        return
    
    if x%2==1:
        recursion(x-1)
        ans.append([S,T,x-1])
        
    else:
        recursion(x//2)
        for i in range(len(ans)):
            ans[i][2] = 2*ans[i][2]
        T += 1
        ans.append([T-1,T,0])
        ans.append([T-1,T,1])
    return

recursion(L)
print((T,len(ans)))
for i,j,k in ans:
    print((i,j,k))
        




L = int(input())

N = 1
l = L
while l // 2 >= 1:
    N += 1
    l //= 2

G = [[] for _ in range(N + 1)]

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

M = 2 * (N - 1)
tmp = 2 ** (N - 1)

for i in range(N - 2, -1, -1):
    if (L >> i) & 1:
        G[1].append([N - i, tmp])
        tmp += 2 ** i
        M += 1

if N > 20 or M > 60:
    print ('error')

print (N, M)
for i in range(1, N):
    for j in G[i]:
        print (i, *j)

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

node = [i for i in range(1, N + 1)]
edge = []

for x, y in zip(node[:-1], node[1:]):
    edge.append((x, y, 0))

x = 1
while L > 1:
    if L & 1:
        L -= 1
        edge.append((x, N, L))
    else:
        L //= 2
        edge.append((x, x + 1, L))
        x += 1

print(N, len(edge))
for e in edge:
    print(*e)

L = int(input())

N = L.bit_length()

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

now = 2**(N - 1)

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

M = sum(len(edges[i]) for i in range(N))
print(N, M)

for i in range(N):
    for to, cost in edges[i]:
        print(i + 1, to + 1, cost)

L = int(input())

N = L.bit_length()

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

s = 2 ** (N - 1)
for i in reversed(list(range(N - 1))):
    if (L >> i) & 1:
        E.append((i + 1, N, s))
        s += 2 ** i

print((N, len(E)))
for a, b, c in E:
    print((a, b, c))


# from https://atcoder.jp/contests/abc108/submissions/4342595
import math


def main():
    l = int(input())
    n = math.floor(math.log2(l)) + 1
    e = []
    for v in range(n-1):
        v2 = 2 ** v
        e.append([v + 1, v + 2, 0])
        e.append([v + 1, v + 2, v2])
        if (l >> v) & 1:
            e.append([v + 1, n, l - v2])
            l -= v2
    print((n, len(e)))
    for x in e:
        print((*x))


main()


from math import log2
L=int(input())
ans=[]
i=1
while True:
    if 2**i>L:
        last=i
        break
    ans.append([i,i+1,2**(i-1)])
    ans.append([i,i+1,0])
    i+=1
"""for i in ans:
    print(i)
print(last)"""
num=2**(last-1)
a=L-num
while a>0:
    ans.append([int(log2(a))+1,last,num])
    num+=2**(int(log2(a)))
    a=L-num
print((last,len(ans)))
for i in ans:
    print((*i))


L=int(input())

ans = []
m = 0
add = -1
mask = 0xffffff
for i in range(24):
    mask >>= 1
    d = 24 - i - 1
    if ((~mask) & L) != 0:
        if add == -1:
            n = d+1
            add = 1 << d
            b = 1
            # [0, 2^d) の範囲
            for i in range(1,d+1):
                ans.append(str(i) + " " + str(i+1) + " 0")
                ans.append(str(i) + " " + str(i+1) + " " + str(b))
                b *= 2
                m += 2
        else :
            ans.append(str(d+1) + " " + str(n) + " " + str(add))
            add += (1 << d)
            m += 1
        L &= mask
#    print(" ",d,L,mask)
print((n,m))
for i in ans:
    print(i)



L = int(input())
def digits_count(n):
  cnt = 0
  while n != 0:
    cnt += 1
    n //= 2
  return cnt
def doubling(n, m):
  y = 1
  base = n
  while m != 0:
    if m % 2 == 1:
      y *= base
    base *= base
    m //= 2
  return y
m = digits_count(L)
A = [0 for _ in range(m)]
for i in range(m, 0, -1):
  A[i-1] = L % 2
  L //= 2
binomial = [1 for _ in range(m)]
for i in range(1, m):
  binomial[i] = binomial[i-1] * 2
vert = [[i*m+i+1, binomial[i]] for i in range(m-1)]
vert = vert[:] + [[i*m+i+1, 0] for i in range(m-1)]
S = doubling(2, m - 1)
for i in range(1, m):
  if A[i] == 1:
    vert.append([(m-i-1)*m+m-1, S])
    S += binomial[m-i-1]
print(m, len(vert))
for i in vert:
  print(i[0] // m + 1, i[0] % m + 1, i[1])

L = int(input())
v = list(map(int,bin(L)[:2:-1]))
N = len(v)+1
edges = []
unit = 1
for i in range(N-1):
    L -= unit*v[i]
    edges.append((i+1, i+2, 0))
    edges.append((i+1, i+2, unit))
    if v[i]:
        edges.append((i+1, N, L))
    unit *= 2

print(N, len(edges))
for a, b, c in edges:
    print(a, b, c)

l = int(input())

v_count = 1
additional_e = []
while True:
  if l == 1:
    break
  elif l%2 == 0:
    l = l//2
    v_count += 1 
  elif l%2 == 1:
    l -= 1
    additional_e.append(v_count)

print((v_count, (v_count-1)*2 + len(additional_e)))

for i in range(1,v_count):
  print((i, i+1, 0))
  print((i, i+1, 2**(i-1)))

num = 2**(v_count-1)

for i in additional_e[::-1]:
  print((i, v_count, num))
  num = num + (2**(i-1))



L = int(input())
k = 1
power = 4
while L >= power:
    k += 1
    power *= 2

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

N = k+1
l = power
rest = L - l
while rest > 0:
    power = 1
    k = 0
    while rest >= power * 2:
        power *= 2
        k += 1
    ans.append([1, N-k, l])
    l += power
    rest -= power

print(*[N, len(ans)])
for i in ans:
    print(*i)

import sys
sys.setrecursionlimit(100000000)
def input():
    return sys.stdin.readline()[:-1]
from bisect import *
from collections import *
from heapq import *
from math import *

L = int(input())
n = int(log(L, 2))
es = []
m = min(n, 19)
for i in range(1, 20):
    es.append((i, i+1, 0))
for i in range(m):
    es.append((i+1, i+2, 1<<i))
t = L-(1<<m)
for i in range(20):
    if (t>>i) & 1:
        L -= 1<<i
        es.append((i+1, 20, L))
print((20, len(es)))
for u, v, c in es:
    print((u, v, c))


L = int(input())
n = L.bit_length()
ans = []
for i in range(1,n):
  ans.append((i,i+1,0))
  ans.append((i,i+1,2**(n-i-1)))
binL = bin(L)
for i in range(1,n):
  if binL[i+2] == "1":
    mask = int(binL[:i+2],2)<<(n-i)
    ans.append((1,i+1,L&mask))
print(n,len(ans))
for edge in ans:
  print(*edge)

#!/usr/bin/env python3
import sys
from math import *
from itertools import *
from collections import *
from functools import *
try:
    from math import gcd
except Exception:
    from fractions import gcd



def solve(L: int):
    r = 0
    while (2 ** r) <= L:
        r += 1
    r -= 1

    edges = []
    nodes = list(range(1, r+2))
    for s, d in zip(nodes, nodes[1:]):
        edges.append((s, d, 0))
        edges.append((s, d, 2 ** (s - 1)))

    base = 2 ** r
    for n in list(reversed(nodes))[1:]:
        c = 2 ** (n - 1)
        if base <= (L - c):
            edges.append((n, nodes[-1], L - c))
            L -= c
    ret = ['{} {}'.format(r + 1, len(edges))]  + ['{} {} {}'.format(s, d, c) for s, d, c in edges]
    return '\n'.join(ret)


def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    L = int(next(tokens))  # type: int
    result = solve(L)
    print(result)

def __starting_point():
    main()

__starting_point()

###############################################################################

from sys import stdout
from bisect import bisect_left as binl
from copy import copy, deepcopy


mod = 1


def intin():
    input_tuple = input().split()
    if len(input_tuple) <= 1:
        return int(input_tuple[0])
    return tuple(map(int, input_tuple))


def intina():
    return [int(i) for i in input().split()]


def intinl(count):
    return [intin() for _ in range(count)]


def modadd(x, y):
    nonlocal mod
    return (x + y) % mod


def modmlt(x, y):
    nonlocal mod
    return (x * y) % mod


def lcm(x, y):
    while y != 0:
        z = x % y
        x = y
        y = z
    return x


def combination(x, y):
    assert(x >= y)

    if y > x // 2:
        y = x - y

    ret = 1

    for i in range(0, y):
        j = x - i
        i = i + 1

        ret = ret * j
        ret = ret // i

    return ret


def get_divisors(x):
    retlist = []
    for i in range(1, int(x**0.5) + 3):
        if x % i == 0:
            retlist.append(i)
            retlist.append(x // i)
    return retlist


def get_factors(x):
    retlist = []
    for i in range(2, int(x**0.5) + 3):
        while x % i == 0:
            retlist.append(i)
            x = x // i
    retlist.append(x)
    return retlist


def make_linklist(xylist):
    linklist = {}
    for a, b in xylist:
        linklist.setdefault(a, [])
        linklist.setdefault(b, [])
        linklist[a].append(b)
        linklist[b].append(a)
    return linklist


def calc_longest_distance(linklist, v=1):
    distance_list = {}
    distance_count = 0
    distance = 0
    vlist_previous = []
    vlist = [v]
    nodecount = len(linklist)

    while distance_count < nodecount:
        vlist_next = []
        for v in vlist:
            distance_list[v] = distance
            distance_count += 1
            vlist_next.extend(linklist[v])
        distance += 1
        vlist_to_del = vlist_previous
        vlist_previous = vlist
        vlist = list(set(vlist_next) - set(vlist_to_del))

    max_distance = -1
    max_v = None
    for v, distance in list(distance_list.items()):
        if distance > max_distance:
            max_distance = distance
            max_v = v

    return (max_distance, max_v)


def calc_tree_diameter(linklist, v=1):
    _, u = calc_longest_distance(linklist, v)
    distance, _ = calc_longest_distance(linklist, u)
    return distance


###############################################################################


def main():
    L = intin()

    r = 0
    while True:
        if 2**(r+1) > L:
            break
        r += 1

    n = r + 1

    path_list = []
    path_list.extend([(i + 1, i + 2, 0) for i in range(r)])
    path_list.extend([(i + 1, i + 2, 2**i) for i in range(r)])

    remain = L - 2**r
    next = 2**r

    for i in reversed(list(range(r))):
        if remain >= 2**i:
            path_list.append((i + 1, n, next))
            remain -= 2**i
            next += 2**i

    print(('%d %d' % (n, len(path_list))))
    for path in path_list:
        print(('%d %d %d' % path))


def __starting_point():
    main()

__starting_point()

#!/usr/bin/env python3

import math

l = int(input())

r = math.floor(math.log2(l))

num_vertex = 0
num_edge = 0

num_vertex += r+1

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


for i in reversed(list(range(r+1))):
    if l-2**i >= 2**r:
        print_list.append([i+1, r+1, l-2**i])
        l -= 2**i
        num_edge += 1

print((num_vertex, num_edge))
for i in print_list:
    print((*i))


L=int(input());n=len(str(bin(L)))-3;e=[];h=2**n
for i in range(1,n+1):
  e+=[(i,i+1,0),(i,i+1,2**(n-i))]
  if 2**(n-i)&L:e+=[(1,i+1,h)];h+=2**(n-i)
print(n+1,len(e))
for v in e:print(*v)

n = int(input())
ans = []
count = 1
two = 1
for i in range(20):
    if two*2 <= n:
        count += 1
        ans.append([count-1,count,0])
        ans.append([count-1,count,two])
        two *= 2
    else:
        break

for i in range(count,0,-1):
    if n - pow(2,i-1) >= two:
        
        ans.append([i,count,n-pow(2,i-1)])
        n -= pow(2,i-1)
print((count,len(ans)))
for i in ans:
    print((*i))


l=int(input())
d=l.bit_length()
g=[]
for i in range(d-1):
  g.append((i+1,i+2,0))
  g.append((i+1,i+2,2**(d-i-2)))
s=1<<(d-1)
for i in range(d-1)[::-1]:
  if (1<<i)&l:
    g.append((1,d-i,s))
    s+=1<<i
print(d,len(g))
for u,v,c in g:
  print(u,v,c)

l = int(input())
n = 0
while 2**n <= l:
  n += 1
p = []
for i in range(1, n):
  p.append((i, i + 1, 0))
  p.append((i, i + 1, 2**(i-1)))
  if l // (2**(i-1)) % 2 == 1:
    p.append((i, n, l // 2**i * 2**i))
m = len(p)
print((n, m))
for i in p:
  print((*i))


L = int(input())
N = L.bit_length()
res = []
for i in range(N - 1):
    res.append((i + 1, i + 2, 0))
    res.append((i + 1, i + 2, 2**i))
rem = L - 2**(N - 1) 
k = 2**(N - 1)
for i in range(rem.bit_length())[::-1]:
    if (rem >> i) & 1:
        res.append((i + 1, N, k))
        k += 2**i
print(N, len(res))
for r in res:
    print(*r)

import math

L = int(input())

N = math.floor(math.log2(L)) + 1

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

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

print(N, len(edge))
for e in edge:
  print(str(e).lstrip('(').rstrip(')').replace(',', ''))

l=int(input())
k=l
cnt=0
while k>1:
    k//=2
    cnt+=1
edge=[[] for _ in range(cnt)]
e=2*cnt
for i in range(cnt):
    edge[i].append((i+1,0))
    edge[i].append((i+1,2**i))
for i in reversed(range(cnt)):
    if l-2**i>=2**cnt:
        edge[i].append((cnt,l-2**i))
        l-=2**i
        e+=1
print(cnt+1,e)
for i in range(cnt):
    for j,d in edge[i]:
        print(i+1,j+1,d)

from itertools import dropwhile
l=int(input())
k=[(l>>i & 1) for i in range(20)][::-1]
k=list(dropwhile(lambda x:x==0,k))
#print(k)
n=len(k)
path=[]
for i in range(n-1):
    path.append((i+1,i+2,0))
    path.append((i+1,i+2,2**i))

path_len=2**(n-1)
for i in range(1,n):
    if k[i]:
        x=n-1-i
        path.append((x+1,n,path_len))
        path_len+=(2**x)

m=len(path)
print(n,m)
for i in path:
    print(i[0],i[1],i[2])

L = int(input())

paths = []
n = 2
v = 1
while n <= L:
    paths.append((v, v+1, 0))
    paths.append((v, v+1, n//2))
    v += 1
    n *= 2
n //= 2

vlast = v
nn = n
ll = L - n

while ll > 0:
    if ll >= n:
        paths.append((v, vlast, nn))
        ll -= n
        nn += n
    n //= 2
    v -= 1

print((vlast, len(paths)))
for e in paths:
    print((*e))


L = int(input())
b = format(L, 'b')
n = len(b)
m = 2 * (n - 1) + b.count('1') - 1
print(n, m)
for i in range(1, n):
    print(i, i + 1, 0)
    print(i, i + 1, 2 ** (i - 1))
w = 2 ** (n - 1)
for j in range(20,-1,-1):
    if (L - w) >> j & 1:
        print(j + 1, n, w)
        w += 2 ** j

l = int(input())
s = bin(l)[2:]
n = len(s)
m = 0
ans = []
for i in range(n-1):
    ans.append([i+1, i+2, 0])
    ans.append([i+1, i+2, 2**(n-2-i)])
    m += 2
imp = 2**(n-1)
for i in range(n-1, 0, -1):
    if s[i] == '1':
        ans.append([1, i+1, imp])
        m += 1
        imp += 2 ** (n-1-i)
print(n, m)
for x in ans:
    print(' '.join(list(map(str, x))))

# D - All Your Paths are Different Lengths

L = int(input())

N = 2
while 2**N-1 <= L-1:
    N += 1

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

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

print(N, len(edge))
for x in edge:
    print(*x)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# 終了後に解説を見て解けた
# パス数が２のべき乗であれば簡単にグラフを構築できることに気付きたかった。
#
# 本番中は、10進法で考えて 頂点1と頂点2の間を辺{0, 100, 200, ..., 900}で繋ぎ、頂点2と頂点3の間を辺{0, 10, ..., 90}で繋ぎ、
# などという事を考えていたが、それ以上進展させることが難しかった。


import array
from bisect import *
from collections import *
import fractions
import heapq 
from itertools import *
import math
import random
import re
import string
import sys

L = int(input())

v = 1
edges = []  # (from, to, cost)

# L = 37の場合を例にとりコメントを付与
# まず長さ0 ~ 31までのパスを作成する。
#   頂点1 -> 頂点2を0の辺と1の辺で結ぶ
#   頂点2 -> 頂点3を0の辺と2の辺で結ぶ
#   頂点3 -> 頂点4を0の辺と4の辺で結ぶ
#   頂点4 -> 頂点5を0の辺と8の辺で結ぶ
#   頂点5 -> 頂点6を0の辺と16の辺で結ぶ
n = 2
cost = 1
while n <= L:
    edges.append((v, v+1, 0))
    edges.append((v, v+1, cost))
    cost *= 2
    v += 1
    n *= 2

# 頂点6をv_sink(最終到達点)とする
v_sink = v

# ここから先、長さ32, 33, 34, 35, 36のパスを生成することになる。
# 頂点3と頂点6を、32の辺で直でつなぐと、長さ32, 33, 34, 35のパスが作れる。
# 頂点1と頂点6を、36の辺で直でつなぐと、長さ36のパスが作れる。
n //= 2
N = n
L -= N

while L > 0:
    if L >= n:
        edges.append((v, v_sink, N))
        L -= n
        N += n
    n //= 2
    v -= 1

print(v_sink, len(edges))
for e in edges:
    print(*e)

# 頂点は0番から始まるとして、出力時に+1する
def graph(L):
    beki = 1
    for n in range(20):
        beki *= 2
        if beki > L: break

    ans = []
    Li = 1
    for i in range(n):
        ans += [(i + 1, i + 2, 0)]
        ans += [(i + 1, i + 2, Li)]
        Li *= 2

    Lnext = Li
    nokori_kosu = L - Li
    i = n - 1
    way_i = Li // 2
    while nokori_kosu > 0:
        while way_i > nokori_kosu:
            way_i //= 2
            i -= 1
        ans += [(i + 1, n + 1, Lnext)]
        Lnext += way_i
        nokori_kosu -= way_i
    print((n + 1, len(ans)))
    for x in ans:
        print((*x))


L = int(input())
graph(L)


L = int(input())


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


X = L - 2 ** (N - 1)
dist = 2 ** (N - 1)
for i in reversed(list(range(X.bit_length()))):
    if X & (1 << i):
        ans.append((0, N - i - 1, dist))
        dist += (2 ** i)


print((N, len(ans)))
for a, b, d in ans:
    print((a + 1, b + 1, d))


import math
l = int(input())

# l -= 1
n = math.floor(math.log2(l)) + 1
edge = []
for i in range(1, n):
    edge.append((i, i+1, 0))
for j, i in enumerate(reversed(list(range(1, n)))):
    edge.append((i, i+1, 2**j))

l2 = l - 2**(n-1)
c = 2**(n-1)
# print("test", c, l2)
while l2 > 0:
    l_mini = 1
    while l_mini * 2 <= l2:
        l_mini *= 2
    # print("test", c, l2, int(math.log2(l_mini)))
    edge.append((1, n-int(math.log2(l_mini)), c))
    l2 -= l_mini
    c += l_mini

print((n, len(edge)))
for i in range(len(edge)):
    print((*edge[i]))


L = int(input())
N = L.bit_length()
res = []
for i in range(N - 1):
  res.append((i + 1, i + 2, 0))
  res.append((i + 1, i + 2, 2**i))
rem = L - 2**(N - 1) 
k = 2**(N - 1)
for i in range(rem.bit_length())[::-1]:
  if (rem >> i) & 1:
    res.append((i + 1, N, k))
    k += 2**i
print(N, len(res))
for r in res:
  print(*r)

import sys
import math
from collections import defaultdict

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N):
    read_all = [tuple(map(int, input().split())) for _ in range(N)]
    return map(list,zip(*read_all))

#################

L = I()

N = math.floor(math.log2(L))+1
M = 0
edge = []
for i in range(N-1):
    edge.append([i,i+1,0])
    edge.append([i,i+1,2**i])
    M += 2
for i in range(N-1)[::-1]:
    if L-2**i >= 2**(N-1):
        edge.append([i,N-1,L-2**i])
        M += 1
        L -= 2**i

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

#import math
L = int(input())
#r = math.floor(math.log2(L))
r = L.bit_length()-1
N = r+1
graph = []
append = graph.append
for i in range(1,r+1):
    append([i,i+1,0])
    append([i,i+1,2**(i-1)])

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

print((N,len(graph)))
for g in graph:
    print((*g))


l = int(input())
n = l.bit_length()
edge = list()
for i in range(1,n):
  edge.append((i,i+1,0))
  edge.append((i,i+1,1<<(i-1)))
t = l - (1<<(n-1))
cnt = (n-1)*2
while t:
  m = t.bit_length()
  edge.append((m,n,l-t))
  t -= (1<<m-1)
  cnt += 1
print(n,cnt)
for t in edge:
  print(*t)

# D - All Your Paths are Different Lengths

L = int(input())
r = 0
while pow(2, r+1) <= L:
    r += 1

N = r + 1 

edge = []
for i in range(N-1): 
    edge.append((i+1, i+2, 0))
    edge.append((i+1, i+2, pow(2, i)))

M = r * 2
remain = L - pow(2, r)

for i in range(N-1)[::-1]:
    if remain < pow(2, i):
        continue
    else:
        edge.append((i+1, N, L-remain))
        M += 1
        remain -= pow(2, i)

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

l = int(input())
n = len(bin(l)) - 3
tmp = 2 ** n
print((n + 1, 2 * n + bin(l)[3:].count('1')))
for i in range(n):
    print((i+1, i+2, 0))
    print((i+1, i+2, 2 ** i))
    if l & (1<<i):
        print((i+1, n+1, tmp))
        tmp += 2 ** i



#18:55
l = int(input())
s = bin(l)[2:]
n = len(s)
m = 0
ans = []
for i in range(n-1):
  ans.append([i+1,i+2,0])
  ans.append([i+1,i+2,2**(n-2-i)])
  m += 2
#print(ans,m)
imp = 2 ** (n-1)
for i in range(n-1,0,-1):
  if s[i] == '1':
    ans.append([1,i+1,imp])
    m += 1
    imp += 2 ** (n-1-i)
print(n,m)
for x in ans:
  print(' '.join(list(map(str,x))))

L = int(input())
r = 0
answer = []

while 2**r <= L:
    r += 1
N = r

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


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

answer.insert(0,[N,len(answer)])

for ans in answer:
    print(*ans)

import sys

input = sys.stdin.readline


def main():
    L = int(input())

    Lstr = bin(L)[2:]

    N = len(Lstr)
    M = (N - 1) * 2 + (Lstr.count("1") - 1)

    print((N, M))
    c = 1
    for i in range(1, N):
        print((i, i + 1, c))
        print((i, i + 1, 0))
        c *= 2

    c = 2 ** (N - 1)
    for i, v in enumerate(Lstr[::-1]):
        if i == N - 1:
            continue
        if v == "1":
            print((i + 1, N, c))
            c += 2 ** i



def __starting_point():
    main()

__starting_point()

def in_list(l, l_t, a):
    l[a] = l_t


ans_list = [[] for _ in range(60)]
p = 0

l = int(input())
bin_str = format(l, '020b')
for i in range(20):
    c = 0
    if c == 0 and str(bin_str)[i] == '1':
        c = 1
        n = 20-i
        k = i
        break;
for j in range(1, n):
    in_list(ans_list, [j, j+1, 0], p)
    p += 1
    in_list(ans_list, [j, j+1, 2**(n-1-j)], p)
    p += 1
c = 2**(n-1)

for m in range(k+1, 20):
    if str(bin_str[m]) == '1':
        in_list(ans_list, [1, n+m-20+1, c], p)
        p += 1
        c += 2 ** (19-m)

print(n, p)
for q in range(p):
    print(ans_list[q][0], ans_list[q][1], ans_list[q][2])

L = int(input())
for i in range(21):
    if 2**i > L:
        r = i-1
        break
        
N = r+1
ans = []
for i in range(1, N):
    ans.append([str(i), str(i+1), str(2**(i-1))])
    ans.append([str(i), str(i+1), str(0)])

t = N-1
while t >= 1:
    if L-2**(t-1) >= 2**r:
        ans.append([str(t), str(N), str(L-2**(t-1))])
        L -= 2**(t-1)
    t -= 1
        
print(N, len(ans))
for i in range(len(ans)):
    print(" ".join(ans[i]))

L = int(input())
v = 1
edges = []
n = 2
cost = 1
while n <=L:
    edges.append((v,v+1,0))
    edges.append((v,v+1,cost))
    cost *=2
    v += 1
    n*=2
goal = v
n //=2
N = n
L-=N
while L>0:
    if L>=n:
        edges.append((v,goal,N))
        L-=n
        N+=n
    n //=2
    v-=1
print(goal,len(edges))
for e in edges:
    print(*e)

import math
L=int(input())

N=int(math.log(L,2))

print(N+1,bin(L)[3:].count("1")+2*N)


for i in range(1,N+1):
    print(i,i+1,0)
    print( i, i+1 , 2**(i-1) )


tmp=2**N
for i in range(N,0,-1):
    if tmp+2**(i-1)-1<=L-1:
        print(i,N+1,tmp)
        tmp=tmp+2**(i-1)

L = int(input())
N = len(str(bin(L)))-3
E = []

for n in range(N):
  E.append((n+1,n+2,0))
  E.append((n+1,n+2,2**(N-n-1)))
  
H = 2**N

for i,c in enumerate(str(bin((L)))[2:]):
    if c=="1" and i:
      E.append((1,i+1,H))
      H+=2**(N-i)

print((N+1,len(E)))
for e in E:
  print((*e))


L = int(input())

N = len(bin(L)[2:])
M = 2*(N-1) + bin(L)[3:].count("1")
print(N, M)

for i in range(1, N):
  print(i, i+1, 0)
  print(i, i+1, 2**(i-1))

temp = L
for i in range(1, N):
  if bin(L)[-i] == "1":
    print(i, N, temp-2**(i-1))
    temp -= 2**(i-1)

L = int(input())

N = len(str(bin(L)))-2

bitL = [0] *20
splitL  = [0] * 20
sumL = [0] * 20

for i in range(19,-1,-1):
  if L % 2 == 1:
    bitL[i] = 1
  L = L // 2

for i in range(19,-1,-1):
  splitL[i] = int(bitL[i]) * 2**(19-i)

for i in range(20):

  if i == 0:
    sumL[i] = splitL[i]
  else:
    sumL[i] =splitL[i]+sumL[i-1]

#print(splitL)
#print(sumL)
#print(bitL)

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


for i in range(21-N,20):
  if bitL[i] == 1:
    edge.append([20-i,N,sumL[i-1]])


print(N,len(edge))

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


from collections import deque
L = int(input())

Lbin = (bin(L)[2:])[::-1]
N = len(Lbin)
M = 0
E = deque()

for i in range(0, N - 1):
    E.append(((i + 1, i + 2), 0))
    E.append(((i + 1, i + 2), 2 ** i))
    M += 2

weight = L
for i in range(0, N - 1):
    if Lbin[i] == '1':  # 2^iの位
        weight -= 2 ** i
        E.append(((i + 1, N), weight))
        M += 1

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


from math import log2,floor
L = int(input())
ans = []

r = floor(log2(L))

for i in range(r):
    ans.append('{} {} {}'.format(i+1,i+2,0))
    ans.append('{} {} {}'.format(i+1,i+2,2**i))

for t in range(r-1,-1,-1):
    if 2**r <= L-2**t:
        ans.append('{} {} {}'.format(t+1,r+1,L-2**t))
        L -= 2**t

print('{} {}'.format(r+1,len(ans)))
for s in ans:
    print(s)

n=int(input())
cnt=0
while 2**cnt-1<n:
  cnt+=1
cnt-=1
graph=[]
for i in range(cnt):
  graph.append((1+i,2+i,2**i))
  graph.append((1+i,2+i,0))
existmax=2**cnt-1
for i in range(1,cnt+1)[::-1]:
    if 2**(i-1)-1+existmax+1<=n-1:
        graph.append((i,cnt+1,existmax+1))
        existmax=existmax+1+2**(i-1)-1
L=len(graph)
print((cnt+1,L))
for i in graph:
  print((*i))


def main():
    L = int(input())
    n = 1
    while 2**n <= L:
        n += 1
    n -= 1
    ans = []
    for i in range(1, n+1):
        ans.append([i, i+1, 0])
        ans.append([i, i+1, 2**(i-1)])
    for i in reversed(range(1, n+1)):
        if L-2**(i-1) >= 2**n:
            ans.append([i, n+1, L-2**(i-1)])
            L -= 2**(i-1)
    print(n+1, len(ans))
    for u, v, w in ans:
        print(u, v, w)

def __starting_point():
    main()
__starting_point()

import math
l=int(input())
n=int(math.log2(l)+1)
E=[]
for i in range(n-1):
    E.append([i+1,i+2,0])
    E.append([i+1,i+2,2**i])
i=n-2
while l>2**(n-1):
    t=l-2**i
    if t>2**(n-1)-1:
        E.append([i+1,n,t])
        l=t
    i-=1
print((n,len(E)))
for i in range(len(E)):
    print((*E[i]))


L=int(input())
l=0
pp=0
tmp=L
while tmp>0:l+=1;pp+=tmp%2;tmp//=2
print(l,l*2-3+pp)
for i in range(1,l):
  print(i,i+1,0)
  a=1<<(i-1)
  print(i,i+1,a)
  if L&a:L-=a;print(i,l,L)

L=int(input())-1
for i in range(1,21):
    if 2**i>L+1:
        N=i
        break
M=2*(N-1)
l=[]
for i in range(1,N):
    l.append((i,i+1,2**(i-1)))
    l.append((i,i+1,0))
L-=2**(N-1)-1
t=2**(N-1)
for i in range(N-1,-1,-1):
    if 2**i<=L:
        l.append((i+1,N,t))
        L-=2**i
        t+=2**i
        M+=1
print(N,M)
for i in l:
    print(*i)

import sys
sys.setrecursionlimit(10000000)
MOD = 10 ** 9 + 7
INF = 10 ** 15

def main():
    L = int(input())
    edges = []
    vertex = 1
    flag = True
    before = -1
    for i in range(19,-1,-1):
        if (L>>i)&1:
            if flag:
                flag = False
                vertex = i + 1
                for j in range(1,vertex):
                    edges.append((j,j + 1,0))
                    edges.append((j,j + 1,1<<(j - 1)))
                before = 1<<i
            else:
                edges.append((i + 1,vertex,before))
                before += 1<<i
    print(vertex,len(edges))
    for t in edges:
        print(*t)
def __starting_point():
    main()
__starting_point()

import math
l=int(input())-1
n=int(math.log2(l+1)+1)
E=[]
for i in range(n-1):
    E.append([i+1,i+2,0])
    E.append([i+1,i+2,2**i])
i=n-2
while l>2**(n-1)-1:
    t=l-2**i+1
    if t>2**(n-1)-1:
        E.append([i+1,n,t])
        l=t-1
    i-=1
print(n,len(E))
for i in range(len(E)):
    print(*E[i])

L = int(input())

N = L.bit_length()
n = []
for i in range(1, N):
    n += [[i, i + 1, 0], [i, i + 1, 2**(i - 1)]]
v = 2**(N - 1) - 1
while L - 1 - v > 0:
    b = min(N - 1, (L - 1 - v).bit_length())
    n += [[b, N, v + 1]]
    v += 2**(b - 1)
M = len(n)
print((N, M))
for _ in n:
    print((*_))


l = int(input())
# l = 1000000
r = 1
while 2 ** r <= l:
    r += 1
r = min(19, r - 1)
# print(r)

n = r + 1
# print(n)

ts = [i for i in range(1, n)]
ts.reverse()
# print(ts)

m = (n - 1) * 2

points = {}

for t in ts:
    a = l - 2 ** (t - 1)
    b = 2 ** r
    if a >= b:
        points[t] = a
        l -= 2 ** (t - 1)

m += len(points)
print((n, m))
for i in range(1, (n - 1) * 2 + 1):
    p = (i - 1) // 2 + 1
    if i % 2 == 0:
        print((p, p + 1, 0))
    else:
        print((p, p + 1, 2 ** (p - 1)))

for k in list(points.keys()):
    print((k, n, points[k]))


from math import log2

L = int(input())
n = int(log2(L))
print((n + 1, format(L, "b").count("1") - 1 + 2 * n))
Li = 1
for i in range(n):
    print((i + 1, i + 2, 0))
    print((i + 1, i + 2, Li))
    Li *= 2
mask = 2
for i in range(n):
    if L >> i & 1:
        print((i + 1, n + 1, L - (L & mask - 1)))
    mask *= 2


import sys
import math

input_methods=['clipboard','file','key']
using_method=1
input_method=input_methods[using_method]

tin=lambda : list(map(int, input().split()))
lin=lambda : list(IN())
mod=1000000007

#+++++

def main():
	L = int(input())
	#b , c = tin()
	#s = input()
	v = int(math.log2(L))
	#pa(v)
	num_p = v
	path_info=[]
	for i in range(v):
		path_info.append([i,i+1,0])
		path_info.append([i,i+1,2**i])
	
	#for li in path_info:
	#	print(*li)
	
	nokori = L - (2 ** v)
	
	#print(nokori)
	for i in range(v+1):
		m = v - i
		if 2 ** m <= nokori:
			path_info.append([m, v, L - nokori])
			nokori -= 2 ** m
	print((v+1, len(path_info)))
	for l in path_info:
		f,t,w = l
		print((*[f+1, t+1, w]))
	
	
#+++++
isTest=False

def pa(v):
	if isTest:
		print(v)
		
def input_clipboard():
	import clipboard
	input_text=clipboard.get()
	input_l=input_text.splitlines()
	for l in input_l:
		yield l

def __starting_point():
	if sys.platform =='ios':
		if input_method==input_methods[0]:
			ic=input_clipboard()
			input = lambda : ic.__next__()
		elif input_method==input_methods[1]:
			sys.stdin=open('inputFile.txt')
		else:
			pass
		isTest=True
	else:
		pass
		#input = sys.stdin.readline
			
	ret = main()
	if ret is not None:
		print(ret)

__starting_point()