import java.io.BufferedReader;
// import java.io.FileInputStream;
// import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.sqrt;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.fill;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;
import static java.util.Collections.reverse;

public class Main {
    FastScanner in;
    PrintWriter out;

    int n, d, k, cnt;
    int[] pdist, dist, graph;
    int[][] e;

    private void dfs(int v, int p) {
        pdist[v] = p == -1 ? 0 : max(pdist[p], dist[p]) + 1;

        while (cnt < n && graph[v] < k && max(pdist[v], dist[v]) < d) {
            e[0][cnt - 1] = v;
            int u = cnt++;
            e[1][u - 1] = u;
            graph[v]++;
            graph[u]++;
            dfs(u, v);
            dist[v] = max(dist[v], dist[u] + 1);
            if (pdist[v] + dist[v] > d)
                n = 1 / 0;
        }
    }

    private void solve() throws IOException {
        n = in.nextInt();
        d = in.nextInt();
        k = in.nextInt();

        graph = new int[n];
        pdist = new int[n];
        dist = new int[n];
        e = new int[2][n - 1];
        cnt = 1;
        dfs(0, -1);

        out.println(cnt == n && n > d ? "YES" : "NO");
        if (cnt == n && n > d)
            for (int i = 0; i < n - 1; i++)
                out.println(e[0][i] + 1 + " " + (e[1][i] + 1));
    }

    class FastScanner {
        StringTokenizer st;
        BufferedReader br;

        FastScanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        boolean hasNext() throws IOException {
            return br.ready() || (st != null && st.hasMoreTokens());
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        double nextDouble() throws IOException {
            return Double.parseDouble(next().replace(',', '.'));
        }

        String nextLine() throws IOException {
            return br.readLine();
        }

        boolean hasNextLine() throws IOException {
            return br.ready();
        }
    }

    private void run() throws IOException {
        in = new FastScanner(System.in); // new FastScanner(new FileInputStream(".in"));
        out = new PrintWriter(System.out); // new PrintWriter(new FileOutputStream(".out"));

        solve();

        out.flush();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }
}