#ifndef LOCAL #pragma GCC optimize("O3") #endif #include using namespace std; #define sim template muu & operator<<( #define ris return *this #define R22(r) sim> typename enable_if<1 r sizeof(dud(0)),muu&>::type operator<<(c g) { sim> struct rge {c b, e;}; sim> rge range(c i, c j) {return {i, j};} sim> auto dud(c*r)->decltype(cerr << *r); sim> char dud(...); struct muu { #ifdef LOCAL stringstream a; ~muu() {cerr << a.str() << endl;} R22(<) a << boolalpha << g; ris;} R22(==) ris << range(begin(g), end(g));} sim, class b mor pair r) {ris << "(" << r.first << ", " << r.second << ")";} sim mor rge u) { a << "["; for (c i = u.b; i != u.e; ++i) *this << ", " + 2 * (i == u.b) << *i; ris << "]"; } #define qel(t) sim, class d, class...e mor t r) {ris << *(d*)&r;} qel(stack) qel(queue) qel(priority_queue) template r) { a << "("; int q = 0; apply([&](c...x){((*this << ", " + 2 * !q++ << x), ...);}, r); ris << ")"; } #else sim mor const c&){ris;} #endif }; #define imie(r...) "[" #r ": " << (r) << "] " #define arr(a, i) "[" #a imie(i) ": " << a[i] << "] " #define arr2(a, i, j) "[" #a imie(i) imie(j) ": " << a[i][j] << "] " #define range(a, b) "[[" #a ", " #b "): " << range(a, b) << "] " #define debug muu() << __FUNCTION__ << "#" << __LINE__ << ": " using ll = long long; using ld = long double; using unt = unsigned int; using pii = pair; using vpii = vector ; using ull = unsigned long long; using vi = vector; using Pii = pii; using vll = vector ; sim> void mini(c &a, const c& b) {if (a > b) a = b;} sim> void maxi(c &a, const c& b) {if (a < b) a = b;} const ll nax = (ll) 1e18 + 1; vll run(int len, int days, vi starts) { vll ans(len); //~ ans[0] = 1; for (int x : starts) ans[x] = 1; for (int i = 0; i < days; ++i) { vll ans2 = ans; for (int i = 1; i < len; ++i) { ans2[i] += ans[i - 1]; ans2[i - 1] += ans[i]; } ans = move(ans2); for (auto &x : ans) mini(x, nax); } return ans; } const int max_days = 100; int main() { debug imie(nax); map > at; for (int _ = 0; _ < 1000; ++_) { int len = _ < 10 ? 1 + _ : 1 + rand() % 200; vi start; if (_ < 10) start = {0}; else for (int c = 1 + rand() % 10; c; --c) start.push_back(rand() % len); auto r = run(len, max_days, start); for (int i = 0; i < len; ++i) { auto try_add = make_tuple(len, i, start); if (!at.count(r[i])) at[r[i]] = try_add; else mini(at[r[i]], try_add); } //~ vector ava; //~ for (auto &[x, _] : at) ava.push_back(x); //~ for (int i = 0; i + 1 < (int) ava.size(); ++i) cerr << ava[i + 1] / (ld) ava[i] << ", "; //~ cerr << endl; //~ debug imie(ava); } //~ debug imie(at); ll n; scanf("%lld", &n); map free; vector > cut; vpii harvest; int row = 0; while (n) { auto it = at.upper_bound(n); assert(it != at.begin()); it--; auto [len, i, start] = it->second; set starts(start.begin(), start.end()); for (int j = 0; j < len; ++j) { cut.emplace_back(pii(row, j), starts.count(j)); } harvest.emplace_back(row, i); row += 2; n -= it->first; } printf("%d\n", (int) cut.size()); cerr << imie(cut.size()) << endl; assert((int)cut.size() <= 200000); for (auto [p, c] : cut) printf("%d %d %d\n", p.first, p.second, c); printf("%d %d\n", (int) harvest.size(), max_days); assert((int)harvest.size() <= 10000); cerr << imie(harvest.size()) << endl; for (auto [x, y] : harvest) printf("%d %d\n", x, y); }