import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.util.LinkedList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Vadim
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskE {
        int n;
        int treeId = 1;
        int k;
        StringBuilder res = new StringBuilder();

        void addNodes(Node parent) {
            if (parent.h == 0 || n == 0)
                return;
            if (parent.children != null)
                for (GraphUtil.Node x : parent.children) {
                    Node child = (Node) x;
                    addNodes(child);
                }
            for (int i = 0; i < parent.rem && n > 0; i++) {
                n--;
                Node child = new Node(treeId++, parent.id, k - 1, parent.h - 1);
                res.append(parent.id + 1).append(' ').append(child.id + 1).append('\n');
                addNodes(child);
            }
            parent.rem = 0;
        }

        public void solve(int testNumber, FastScanner in, PrintWriter out) {

            n = in.ni();
            int d = in.ni();
            k = in.ni();
            int left = d / 2;
            int right = d - left;
            Node root = new Node(0, 0, k, right);
            n--;
            Node parent = root;
            try {
                for (int i = 0; i < right; i++) {
                    if (parent.rem == 0 || n == 0)
                        throw new WrongException();
                    parent.rem--;
                    Node child = new Node(treeId++, parent.id, k - 1, parent.h - 1);
                    res.append(parent.id + 1).append(' ').append(child.id + 1).append('\n');
                    parent.add(child);
                    parent = child;
                    n--;
                }
                parent = root;
                root.h = left;
                for (int i = 0; i < left; i++) {
                    if (parent.rem == 0 || n == 0)
                        throw new WrongException();
                    parent.rem--;
                    Node child = new Node(treeId++, parent.id, k - 1, parent.h - 1);
                    res.append(parent.id + 1).append(' ').append(child.id + 1).append('\n');
                    parent.add(child);
                    parent = child;
                    n--;
                }
                addNodes(root);
                if (n != 0)
                    out.println("NO");
                else {
                    out.println("YES");
                    out.println(res.toString());
                }
            } catch (WrongException e) {
                out.println("NO");
            }
        }

        class Node extends GraphUtil.Node {
            int rem = 0;
            int h = 0;

            public Node(int id, int parent) {
                super(id, parent);
            }

            public Node(int id, int parent, int rem, int h) {
                super(id, parent);
                this.rem = rem;
                this.h = h;
            }

        }

        class WrongException extends Exception {
        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String ns() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    String rl = in.readLine();
                    if (rl == null) {
                        return null;
                    }
                    st = new StringTokenizer(rl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int ni() {
            return Integer.parseInt(ns());
        }

    }

    static class GraphUtil {
        public static class Node {
            public int id;
            public int parent;
            public List<GraphUtil.Node> children;

            public Node(int id, int parent) {
                this.id = id;
                this.parent = parent;
            }

            public void add(GraphUtil.Node child) {
                if (children == null) children = new LinkedList<>();
                children.add(child);
            }

        }

    }
}

