import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.string;

void main() {
    auto L = readln.chomp.to!int;
    L -= 1;
    int N = L.bsr + 1;
    auto A = new int[](N);
    auto G = new Tuple!(int, int)[][](N);

    if (L <= 10) {
        writeln(2, " ", L+1);
        foreach (i; 0..L+1) {
            writeln(1, " ", 2, " ", i);
        }
        return;
    }

    foreach (i; 0..N) {
        A[i] = L % 2;
        L /= 2;
    }

    foreach (i; 1..N) {
        G[i] ~= tuple(i+1, 0);
    }

    foreach (i; 1..N) {
        G[i] ~= tuple(i+1, 1<<(N-i-1));
    }


    int tmp = 1 << (N - 1);

    foreach (i; 1..N) {
        if (A[N-i-1] == 1) {
            int to = i + 1;
            if (to > N) to = N;
            G[0] ~= tuple(to, tmp);
            tmp += 1 << (N-i-1);
        }
    }

    G[0] ~= tuple(N, tmp);
    G[1] ~= G[0];
    G[0] = [];

    writeln(N, " ", N.iota.map!(i => G[i].length).sum);
    foreach (i; 1..N) {
        foreach (j; G[i]) {
            writeln(i, " ", j[0], " ", j[1]);
        }
    }
}
