#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

#define REP(i, n) for(int i = 0; i < (int)(n); ++i)
#define FOR(i, m, n) for(int i = (int)(m); i < (int)(n); ++i)

struct edge{ int to, cost; };

int main()
{
    int L;
    cin >> L;

    // 2^r <= L なる最大の r を求める
    int tmp = L, r = 0;
    while(tmp > 1){ 
        tmp /= 2;
        ++r;
    }

    int N = r+1, M = 0;
    vector<vector<edge>> G(N);
    // i -> i+1 に 0 と 2^i の辺を張ることで
    // 0 ~ 2^r-1 までの経路を作れる
    REP(i, N-1){
        G[i].push_back({i+1, 0});
        G[i].push_back({i+1, (int) pow(2, i)});
        M += 2;
    }

    // 残りの辺を張る
    for(int i = N-2; i >= 0; --i){
        int length = L - pow(2, i);
        if( length >= pow(2, r)){
            G[i].push_back({N-1, length});
            L -= pow(2, i);
            ++M;
        }
    }

    cout << N << " " << M << endl;
    REP(i, N){
        for(auto e: G[i]) cout << i+1 << " " << e.to+1 << " " << e.cost << endl;
    }

    return 0;
}