#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <random>
#include <utility>
#include <vector>
using namespace std;

// For every requested bridge:
// Build many small components first, then add one long interval that
// contains the whole prefix created so far and bridges all of them.

int main(int argc, char* argv[]) {
    assert(argc == 5);
    int N = atoi(argv[1]);
    int requested_bridges = atoi(argv[2]);
    int MAXR = atoi(argv[3]);
    int seed = atoi(argv[4]);
    assert(N >= 1);

    if (N == 1) {
        cout << 1 << '\n' << "0 1\n";
        return 0;
    }

    mt19937 rng(seed);

    int bridges = max(1, requested_bridges);
    bridges = min(bridges, max(1, N / 5));

    int components = (N - bridges) / 2;
    int extra = N - bridges - 2 * components;
    assert(components >= 2 * bridges);
    assert(extra == 0 || extra == 1);

    vector<int> stage_sizes(bridges, 2);
    int remaining = components - 2 * bridges;
    for (int i = 0; i < remaining; i++) {
        stage_sizes[(int)(rng() % (unsigned)bridges)]++;
    }
    shuffle(stage_sizes.begin(), stage_sizes.end(), rng);

    vector<pair<int, int>> intervals;
    intervals.reserve((size_t)N);

    int block = 0;
    for (int stage = 0; stage < bridges; stage++) {
        for (int rep = 0; rep < stage_sizes[stage]; rep++) {
            intervals.push_back({4 * block, 4 * block + 3});
            intervals.push_back({4 * block + 1, 4 * block + 2});
            if (extra > 0) {
                intervals.push_back({4 * block, 4 * block + 2});
                extra--;
            }
            block++;
        }

        intervals.push_back({0, 4 * block - 1});
    }

    assert((int)intervals.size() == N);
    assert(4 * block - 1 <= MAXR);

    cout << N << '\n';
    for (auto [l, r] : intervals) {
        cout << l << ' ' << r << '\n';
    }
    return 0;
}
