#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <random>
#include <vector>

using namespace std;

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

    mt19937 rng(seed);

    int blocks = requested_blocks <= 0 ? 1 : min(requested_blocks, N);
    vector<int> block_sizes(blocks, 1);

    vector<int> weights(blocks);
    for (int i = 0; i < blocks; i++) {
        weights[i] = blocks - i;
    }
    discrete_distribution<int> pick_block(weights.begin(), weights.end());
    for (int i = blocks; i < N; i++) {
        block_sizes[pick_block(rng)]++;
    }

    cout << N << '\n';

    int left = 0;
    int next_right = N + 1;
    for (int size : block_sizes) {
        int block_high = next_right + size - 1;
        for (int offset = 0; offset < size; offset++) {
            cout << left << ' ' << block_high - offset << '\n';
            left++;
        }
        next_right = block_high + 1;
    }

    assert(left == N);
    assert(next_right - 1 <= 2 * N);
    return 0;
}
