

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main{
	
	static Edge[] edge=new Edge[400005];
	static int cnt=0;//边数
	static int [] head=new int[400005];
	static int n,d,k;//点数，直径，最大度数
	static int num=0;//后期搜索过程需要的连上的节点名
    public static void main( String[] args ){
    	Scanner scan=new Scanner(System.in);
    	while(scan.hasNext()) {
    		Arrays.fill(head, 0);
    		n=scan.nextInt();
    		d=scan.nextInt();
    		k=scan.nextInt();
    		cnt=1;
    		
    		if(n<=d || (k==1 && n>2)) {//点数小于等于直径 或 深度不允许
    			System.out.println("NO");
    			continue;
    		}
    		
    		//先连一条直径为d的边,1-2-3-4-5-...-d-(d+1)
    		for(int i=1;i<=d;i++) 
    			add_edge(i, i+1);
    		
    		num = d+1;//dfs中每次+1
    		
    		for(int i=2;i<=d;i++) 
    			dfs(i,k-2,Math.min(i-1, d+1-i));//2到d这些点是一条直线，需要连到d+2,d+3那些点
    		
    		
    		if(num!=n) {
    			System.out.println("NO");
    			continue;
    		}
    		System.out.println("YES");
    		for(int i=1;i<=n;i++) {
    			for(int j=head[i];j!=0;j=edge[j].next)
    				System.out.println(i+" "+edge[j].to);
    		}
    	}
    }
    public static void add_edge(int u,int v) {//链式前向星添加边
    	Edge e=new Edge();
    	e.next=head[u];
    	e.to=v;
    	edge[cnt]=e;
    	head[u]=cnt;
    	cnt++;
    }
    public static void dfs(int u,int deg,int dep) {//u是当前节点，还能连接deg个新节点，还能连接长度为dep的链
    	if(num==n || deg==0 || dep==0)
    		return;
    	for(int i=0;i<deg && num<n;i++) {
    		num++;
    		add_edge(u, num);
    		dfs(num,k-1,dep-1);
    	}
    }
}

class Edge{
	int to;
	int next;
	
}
 	 						 	    	 		 	 	  			 	