

import java.util.*;
import java.io.*;
import java.math.*;

public class Test5 {

    static int n,d,k, vertnum,mid;
    static ArrayList<Integer>[] l;
    static int[] st;
    static int[] depth;

    public static void main(String[] z) throws Exception{
        PrintWriter pw = new PrintWriter(System.out);
        StreamTokenizer tok = new StreamTokenizer(new InputStreamReader(System.in));
        Scanner s = new Scanner(System.in);
        n = s.nextInt();
        d = s.nextInt();
        k = s.nextInt();
        l = new ArrayList[n];
        for(int q=0; q<n; q++) l[q] = new ArrayList<>();
        st = new int[n];
        depth = new int[n];
        Arrays.fill(st,2);
        st[0] = 1;
        st[n-1] = 1;
        mid = (int)Math.ceil((d+1)/2.0);
        if(d>n-1 | (d==1 & k+1<n) | (k==1 & n>2)) pw.print("NO");
        else if(d==n-1) for(int q=0; q<d; q++) pw.println((q+1)+" "+(q+2));
        else{
            for(int q=0; q<d+1; q++){
                if(q<1) {l[q].add(1); depth[q]=0;}
                else if(q==d) {l[q].add(d-1); depth[q]=0;}
                else{
                    depth[q] = (d%2>0 ? q<mid ? depth[q-1]+1 : q>mid ? depth[q-1]-1 : depth[mid-1] : q<mid ? depth[q-1]+1 : depth[q-1]-1);
                    l[q].add(q-1);
                    l[q].add(q+1);
                }
            }
            vertnum = d+1;
            for(int q=1; q<d & vertnum<n; q++){
                if(depth[q]>0 & st[q]<k){
                    createTree(q, depth[q]);
                }
            }
            if(vertnum<n){
                pw.print("NO\n");
            }
            else{
                pw.println("YES");
                for(int q=0; q<n; q++){
                    int si3e = l[q].size();
                    for(int w=0; w<l[q].size(); w++){
                        pw.println((q+1)+" "+(l[q].get(w)+1));
                        l[l[q].get(w)].remove((Object)q);
                    }
                }
            }
        }
        pw.flush();
    }

    static void createTree(int stvert, int dep){
        if(vertnum<n) {
            int need = k - st[stvert];
            for (int q = 0; q < need && vertnum<n; q++) {
                l[stvert].add(vertnum);
                l[vertnum].add(stvert);
                st[vertnum] = 1;
                vertnum++;
                if(dep>1 & vertnum<n) {
                    createTree(vertnum-1, dep-1);
                }
            }
            st[stvert] = l[stvert].size();
        }
    }

    static class PyraSort {

        private static int heapSize;

        public static void sort(int[] a) {
            buildHeap(a);
            while (heapSize > 1) {
                swap(a, 0, heapSize - 1);
                heapSize--;
                heapify(a, 0);
            }
        }

        private static void buildHeap(int[] a) {
            heapSize = a.length;
            for (int i = a.length / 2; i >= 0; i--) {
                heapify(a, i);
            }
        }

        private static void heapify(int[] a, int i) {
            int l = 2 * i + 2;
            int r = 2 * i + 1;
            int largest = i;
            if (l < heapSize && a[i] < a[l]) {
                largest = l;
            }
            if (r < heapSize && a[largest] < a[r]) {
                largest = r;
            }
            if (i != largest) {
                swap(a, i, largest);
                heapify(a, largest);
            }
        }

        private static void swap(int[] a, int i, int j) {
            a[i] ^= a[j] ^= a[i];
            a[j] ^= a[i];
        }
    }
}
