# include <bits/stdc++.h>
using namespace std;

const int MAXN=400000+5;
int n,d,k,cnt,ban;
typedef pair<int,int> P;
vector<P> V;

void dfs(int u,int step,int e){
	if(cnt>=n||step==ban) return;
	for(int i=1;i<=e;i++){
		V.push_back(make_pair(u,cnt+1));cnt+=1;
		dfs(cnt,step+1,k-1);
	}
}

int main(){
	scanf("%d%d%d",&n,&d,&k);
	for(int i=1;i<=d;i++){
		V.push_back(make_pair(i,i+1));
	}
	if(d&1){
		int e=k-2;cnt=d+1;ban=d/2;
		for(int i=(d+1)/2+1;i<=d+1;i++)
			e+=(i==(d+1)),dfs(i,i-((d+1)/2+1),e);
		for(int i=(d+1)/2;i>0;i--)
			e+=(i==1),dfs(i,(d+1)/2-i,e);
	}
	else {
		int e=k-2;cnt=d+1;ban=d/2;
		for(int i=(d+1)/2+1;i<=d+1;i++)
			e+=(i==d+1),dfs(i,i-(d+1)/2-1,e);
		for(int i=(d+1)/2;i>0;i--)
			e+=(i==1),dfs(i,(d+1)/2-i+1,e);
	}
	if(cnt<n||n<=d) printf("NO\n");
	else {
		printf("YES\n");
		for(int i=0;i<n-1;i++){
			printf("%d %d\n",V[i].first,V[i].second);
		}
	}
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

const int MAXN=400000+5;
int n,d,k,cnt,ban;
typedef pair<int,int> P;
vector<P> V;

void dfs(int u,int step,int e){
	if(cnt>=n||step==ban) return;
	for(int i=1;i<=e;i++){
		V.push_back(make_pair(u,cnt+1));cnt+=1;
		dfs(cnt,step+1,k-1);
	}
}

int main(){
	scanf("%d%d%d",&n,&d,&k);
	for(int i=1;i<=d;i++){
		V.push_back(make_pair(i,i+1));
	}
	if(d&1){
		int e=k-2;cnt=d+1;ban=d/2;
		for(int i=(d+1)/2+1;i<=d+1;i++)
			e+=(i==(d+1)),dfs(i,i-((d+1)/2+1),e);
		for(int i=(d+1)/2;i>0;i--)
			e+=(i==1),dfs(i,(d+1)/2-i,e);
	}
	else {
		int e=k-2;cnt=d+1;ban=d/2;
		for(int i=(d+1)/2+1;i<=d+1;i++)
			e+=(i==d+1),dfs(i,i-(d+1)/2-1,e);
		for(int i=(d+1)/2;i>0;i--)
			e+=(i==1),dfs(i,(d+1)/2-i+1,e);
	}
	if(cnt<n) printf("NO\n");
	else {
		printf("YES\n");
		for(int i=0;i<n-1;i++){
			printf("%d %d\n",V[i].first,V[i].second);
		}
	}
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

const int MAXN=400000+5;
int n,d,k,cnt,ban;
typedef pair<int,int> P;
vector<P> V;

void dfs(int u,int step,int e){
	if(cnt>=n||step>=ban) return;
	for(int i=1;i<=e;i++){
		if(cnt>=n) return;
		V.push_back(make_pair(u,cnt+1));cnt+=1;
		dfs(cnt,step+1,k-1);
	}
}

int main(){
	scanf("%d%d%d",&n,&d,&k);
	for(int i=1;i<=d;i++){
		V.push_back(make_pair(i,i+1));
	}
	if(d&1){
		int e=k-2;cnt=d+1;ban=d/2;
		for(int i=(d+1)/2+1;i<=d+1;i++)
			e+=(i==(d+1)),dfs(i,i-((d+1)/2+1),e);
		e=k-2;
		for(int i=(d+1)/2;i>0;i--)
			e+=(i==1),dfs(i,(d+1)/2-i,e);
	}
	else {
		int e=k-2;cnt=d+1;ban=d/2;
		for(int i=(d+1)/2+1;i<=d+1;i++)
			e+=(i==d+1),dfs(i,i-(d+1)/2-1,e);
		e=k-2;
		for(int i=(d+1)/2;i>0;i--)
			e+=(i==1),dfs(i,(d+1)/2-i+1,e);
	}
	if(cnt<n||n<=d) printf("NO\n");
	else {
		printf("YES\n");
		for(int i=0;i<n-1;i++){
			printf("%d %d\n",V[i].first,V[i].second);
		}
	}
	return 0;
}


# include <bits/stdc++.h>
using namespace std;

const int MAXN=400000+5;
int n,d,k,cnt,ban;
typedef pair<int,int> P;
vector<P> V;

void dfs(int u,int step,int e){
	if(cnt>=n||step>=ban) return;
	for(int i=1;i<=e;i++){
		if(cnt>=n) return;
		V.push_back(make_pair(u,cnt+1));cnt+=1;
		dfs(cnt,step+1,k-1);
	}
}

int main(){
	scanf("%d%d%d",&n,&d,&k);
	for(int i=1;i<=d;i++){
		V.push_back(make_pair(i,i+1));
	}
	if(d&1){
		int e=k-2;cnt=d+1;ban=d/2;
		for(int i=(d+1)/2+1;i<=d+1;i++)
			e+=(i==(d+1)),dfs(i,i-((d+1)/2+1),e);
		e=k-2;
		for(int i=(d+1)/2;i>0;i--)
			e+=(i==1),dfs(i,(d+1)/2-i,e);
	}
	else {
		int e=k-2;cnt=d+1;ban=d/2;
		for(int i=(d+1)/2+1;i<=d+1;i++)
			e+=(i==d+1),dfs(i,i-(d+1)/2-1,e);
		e=k-2;
		for(int i=(d+1)/2;i>0;i--)
			e+=(i==1),dfs(i,(d+1)/2-i+1,e);
	}
	if(k==1){
		if(n!=2||d!=1) printf("NO\n");
		else printf("YES\n1 2\n");
		return 0;
	}
	if(cnt<n||n<=d) printf("NO\n");
	else {
		printf("YES\n");
		for(int i=0;i<n-1;i++){
			printf("%d %d\n",V[i].first,V[i].second);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 1e6 + 10;
int fa[maxn], dep[maxn], depmax, size[maxn], cnt;
int n, d, k, vis[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	if(k == 1 && n == 2 && d == 1)
		return printf("YES\n1 2"), 0;
	if(k == 1 || d >= n)
		return puts("NO"), 0;
	depmax = d / 2 + 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		fa[i] = i - 1;
		dep[i] = dep[i - 1] + 1;
		++ size[i - 1];
		vis[i] = 1;
	}
	cnt = depmax + d % 2 + 1;
	fa[cnt] = 1;
	dep[cnt] = dep[1] + 1;
	++ size[1];
	while(dep[cnt] < depmax)
	{
		if(cnt > n) return printf("NO"), 0;
		fa[cnt + 1] = cnt;
		dep[cnt + 1] = dep[cnt] + 1;
		++ size[cnt];
		++ cnt;
	}
	For(i, 1, n)
	{
		while(size[i] + (i != 1) < k && fa[i] && (dep[i] < depmax || size[i] || ((d % 2 == 1) && vis[i] && dep[i] <= depmax)))
		{
			++ cnt;
			fa[cnt] = i;
			dep[cnt] = dep[i] + 1;
			++ size[i];
			vis[cnt] = vis[i];
			if(cnt >= n)
				break;
		}
	}
	if(cnt < n)
		return puts("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", i, fa[i]);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 5;
vector<int> son[maxn];
int n, d, k, cnt, dep[maxn], now, ovo;
int fa[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	int depmax = d / 2 + 1;
	now = 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		if(son[i - 1].size() + (i - 1 != 1) < k && fa[i - 1] && (dep[i - 1] < depmax || son[i - 1].size()))
		{
			son[i - 1]. push_back(i);
			fa[i] = i - 1;
			dep[i] = dep[fa[i]] + 1;
		}
	}
	cnt = depmax + d % 2 + 1;
	if(son[1].size() < k && fa[1] && (dep[1] < depmax || son[1].size()))
	{
		son[fa[cnt] = 1].push_back(cnt);
		dep[cnt] = dep[1] + 1;
	}
	if(cnt > n + 1)
		return printf("NO"), 0;
	For(i, 1, depmax - 2)
	{
		if(cnt + i > n)
			return printf("NO"), 0;
		if(son[cnt + i - 1].size() + (cnt + i - 1 != 1) < k && fa[cnt + i - 1] && (dep[cnt + i - 1] < depmax || son[cnt + i - 1].size()))
		{
			son[fa[cnt + i] = cnt + i - 1].push_back(cnt + i);
			dep[cnt + i] = dep[cnt + i - 1] + 1;
		}
	}
	For(i, 1, n + 1)
		if(!fa[i])
		{
			cnt = i;
			break;
		}
	while(cnt <= n && now <= n)
	{
		if(son[now].size() + (now != 1) < k && fa[now] && (dep[now] < depmax || son[now].size()))
		{
			son[now].push_back(cnt);
			fa[cnt] = now;
			dep[cnt] = dep[fa[cnt]] + 1;
			cnt ++;
		}
		else
			now ++;
	}
	if(cnt <= n)
		return printf("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", fa[i], i);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 5;
vector<int> son[maxn];
int n, d, k, cnt, dep[maxn], now, ovo;
int fa[maxn], vis[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	if(n == 2 && d == 1 && k == 1)
		return printf("YES\n1 2"), 0;
	if(k == 1)
		return printf("NO"), 0;
	int depmax = d / 2 + 1;
	now = 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		son[i - 1]. push_back(i);
		fa[i] = i - 1;
		dep[i] = dep[fa[i]] + 1;
		vis[i] = 1;
	}
	cnt = depmax + d % 2 + 1;
	if(cnt > n + 1)
		return printf("NO"), 0;
	son[fa[cnt] = 1].push_back(cnt);
	dep[cnt] = dep[1] + 1;
	cnt ++;
	while(dep[cnt - 1] < depmax)
	{
		if(cnt > n)
			return printf("NO"), 0;
		son[fa[cnt] = cnt - 1].push_back(cnt);
		dep[cnt] = dep[cnt - 1] + 1;
		cnt ++;
	}
	while(cnt <= n && now <= n)
	{
		if(son[now].size() + (now != 1) < k && fa[now] && (dep[now] < depmax || son[now].size() || (dep[now] + vis[now] <= depmax + d % 2)))
		{
			son[now].push_back(cnt);
			fa[cnt] = now;
			dep[cnt] = dep[fa[cnt]] + 1;
			cnt ++;
		}
		else
			now ++;
	}
	if(cnt <= n)
		return printf("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", fa[i], i);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 5;
vector<int> son[maxn];
int n, d, k, cnt, dep[maxn], now, ovo;
int fa[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	if(k == 1 && d != 1)
		return printf("NO"), 0;
	if(k == 1 && d == 1)
		return printf("YES"), 0;
	int depmax = d / 2 + 1;
	now = 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		son[i - 1]. push_back(i);
		fa[i] = i - 1;
		dep[i] = dep[fa[i]] + 1;
	}
	cnt = depmax + d % 2 + 1;
	if(cnt > n + 1)
		return printf("NO"), 0;
	son[fa[cnt] = 1].push_back(cnt);
	dep[cnt] = dep[1] + 1;
	cnt ++;
	while(dep[cnt - 1] < depmax)
	{
		if(cnt > n)
			return printf("NO"), 0;
		son[fa[cnt] = cnt - 1].push_back(cnt);
		dep[cnt] = dep[cnt - 1] + 1;
		cnt ++;
	}
	while(cnt <= n && now <= n)
	{
		if(son[now].size() + (now != 1) < k && fa[now] && (dep[now] < depmax || son[now].size()))
		{
			son[now].push_back(cnt);
			fa[cnt] = now;
			dep[cnt] = dep[fa[cnt]] + 1;
			cnt ++;
		}
		else
			now ++;
	}
	if(cnt <= n)
		return printf("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", fa[i], i);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 5;
vector<int> son[maxn];
int n, d, k, cnt, dep[maxn], now, ovo;
int fa[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	int depmax = d / 2 + 1;
	now = 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		son[i - 1]. push_back(i);
		fa[i] = i - 1;
		dep[i] = dep[fa[i]] + 1;
	}
	cnt = depmax + d % 2 + 1;
	son[fa[cnt] = 1].push_back(cnt);
	dep[cnt] = dep[1] + 1;
	if(cnt > n + 1)
		return printf("NO"), 0;
	For(i, 1, depmax - 2)
	{
		if(cnt + i > n)
			return printf("NO"), 0;
		son[fa[cnt + i] = cnt + i - 1].push_back(cnt + i);
		dep[cnt + i] = dep[cnt + i - 1] + 1;
	}
	For(i, 1, n + 1)
		if(!fa[i])
		{
			cnt = i;
			break;
		}
	while(cnt <= n && now <= n)
	{
		if(son[now].size() + (now != 1) < k && fa[now] && (dep[now] < depmax || son[now].size()))
		{
			son[now].push_back(cnt);
			fa[cnt] = now;
			dep[cnt] = dep[fa[cnt]] + 1;
			cnt ++;
		}
		else
			now ++;
	}
	if(cnt <= n)
		return printf("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", fa[i], i);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 5;
vector<int> son[maxn];
int n, d, k, cnt, dep[maxn], now, ovo;
int fa[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	int depmax = d / 2 + 1;
	now = 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		son[i - 1]. push_back(i);
		fa[i] = i - 1;
		dep[i] = dep[fa[i]] + 1;
	}
	cnt = depmax + d % 2 + 1;
	son[fa[cnt] = 1].push_back(cnt);
	dep[cnt] = dep[1] + 1;
	For(i, 1, depmax - 2)
	{
		if(cnt + i > n)
			return printf("NO"), 0;
		son[fa[cnt + i] = cnt + i - 1].push_back(cnt + i);
		dep[cnt + i] = dep[cnt + i - 1] + 1;
	}
	For(i, 1, n)
		if(!fa[i])
		{
			cnt = i;
			break;
		}
	while(cnt <= n && now <= n)
	{
		if(son[now].size() + (now != 1) < k && fa[now] && (dep[now] < depmax || son[now].size()))
		{
			son[now].push_back(cnt);
			fa[cnt] = now;
			dep[cnt] = dep[fa[cnt]] + 1;
			cnt ++;
		}
		else
			now ++;
	}
	if(cnt < n)
		return printf("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", fa[i], i);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 5;
vector<int> son[maxn];
int n, d, k, cnt, dep[maxn], now, ovo;
int fa[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	int depmax = d / 2 + 1;
	now = 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		son[i - 1]. push_back(i);
		fa[i] = i - 1;
		dep[i] = dep[fa[i]] + 1;
	}
	cnt = depmax + d % 2 + 1;
	son[fa[cnt] = 1].push_back(cnt);
	dep[cnt] = dep[1] + 1;
	For(i, 1, depmax - 2)
	{
		if(cnt + i > n)
			return printf("NO"), 0;
		son[fa[cnt + i] = cnt + i - 1].push_back(cnt + i);
		dep[cnt + i] = dep[cnt + i - 1] + 1;
	}
	For(i, 1, n + 1)
		if(!fa[i])
		{
			cnt = i;
			break;
		}
	while(cnt <= n && now <= n)
	{
		if(son[now].size() + (now != 1) < k && fa[now] && (dep[now] < depmax || son[now].size()))
		{
			son[now].push_back(cnt);
			fa[cnt] = now;
			dep[cnt] = dep[fa[cnt]] + 1;
			cnt ++;
		}
		else
			now ++;
	}
	if(cnt <= n)
		return printf("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", fa[i], i);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 1e6 + 10;
int fa[maxn], dep[maxn], depmax, size[maxn], cnt;
int n, d, k, vis[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	if(k == 1 && n == 2 && d == 1)
		return printf("YES\n1 2"), 0;
	if(d == 1 || k == 1 || d >= n)
		return puts("NO"), 0;
	depmax = d / 2 + 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		fa[i] = i - 1;
		dep[i] = dep[i - 1] + 1;
		++ size[i - 1];
		vis[i] = 1;
	}
	cnt = depmax + d % 2 + 1;
	fa[cnt] = 1;
	dep[cnt] = dep[1] + 1;
	++ size[1];
	while(dep[cnt] < depmax)
	{
		if(cnt > n) return printf("NO"), 0;
		fa[cnt + 1] = cnt;
		dep[cnt + 1] = dep[cnt] + 1;
		++ size[cnt];
		++ cnt;
	}
	For(i, 1, n)
	{
		while(size[i] + (i != 1) < k && fa[i] && (dep[i] < depmax || size[i] || ((d % 2 == 1) && vis[i] && dep[i] <= depmax)))
		{
			++ cnt;
			fa[cnt] = i;
			dep[cnt] = dep[i] + 1;
			++ size[i];
			vis[cnt] = vis[i];
			if(cnt >= n)
				break;
		}
	}
	if(cnt < n)
		return puts("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", i, fa[i]);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 1e6 + 10;
int fa[maxn], dep[maxn], depmax, size[maxn], cnt;
int n, d, k, vis[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	if(k == 1 && n == 2 && d == 1)
		return printf("YES\n1 2"), 0;
	if(d == 1 || d >= n)
		return puts("NO"), 0;
	depmax = d / 2 + 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		fa[i] = i - 1;
		dep[i] = dep[i - 1] + 1;
		++ size[i - 1];
		vis[i] = 1;
	}
	cnt = depmax + d % 2 + 1;
	fa[cnt] = 1;
	dep[cnt] = dep[1] + 1;
	++ size[1];
	while(dep[cnt] < depmax)
	{
		if(cnt > n) return printf("NO"), 0;
		fa[cnt + 1] = cnt;
		dep[cnt + 1] = dep[cnt] + 1;
		++ size[cnt];
		++ cnt;
	}
	For(i, 1, n)
	{
		while(size[i] + (i != 1) < k && fa[i] && (dep[i] < depmax || size[i] || ((d % 2 == 1) && vis[i] && dep[i] <= depmax)))
		{
			++ cnt;
			fa[cnt] = i;
			dep[cnt] = dep[i] + 1;
			++ size[i];
			vis[cnt] = vis[i];
			if(cnt >= n)
				break;
		}
	}
	if(cnt < n)
		return puts("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", i, fa[i]);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 10;
int fa[maxn], dep[maxn], depmax, size[maxn], cnt;
int n, d, k, vis[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	if(k == 1 && n == 2 && d == 1)
		return printf("YES\n1 2"), 0;
	if(d == 1 || d >= n)
		return puts("NO"), 0;
	depmax = d / 2 + 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		fa[i] = i - 1;
		dep[i] = dep[i - 1] + 1;
		++ size[i - 1];
		vis[i] = 1;
	}
	cnt = depmax + d % 2 + 1;
	fa[cnt] = 1;
	dep[cnt] = dep[1] + 1;
	++ size[1];
	while(dep[cnt] < depmax)
	{
		fa[cnt + 1] = cnt;
		dep[cnt + 1] = dep[cnt] + 1;
		++ size[cnt];
		++ cnt;
	}
	For(i, 1, n)
	{
		while(size[i] + (i != 1) < k && fa[i] && (dep[i] < depmax || size[i] || ((d % 2 == 1) && vis[i] && dep[i] <= depmax)))
		{
			++ cnt;
			fa[cnt] = i;
			dep[cnt] = dep[i] + 1;
			++ size[i];
			vis[cnt] = vis[i];
			if(cnt >= n)
				break;
		}
	}
	if(cnt < n)
		return puts("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", i, fa[i]);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 1e6 + 10;
int fa[maxn], dep[maxn], depmax, size[maxn], cnt;
int n, d, k, vis[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	if(n == 2 && d == 1)
		return printf("YES\n1 2"), 0;
	if(d == 1 || k == 1 || d >= n)
		return puts("NO"), 0;
	depmax = d / 2 + 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		fa[i] = i - 1;
		dep[i] = dep[i - 1] + 1;
		++ size[i - 1];
		vis[i] = 1;
	}
	cnt = depmax + d % 2 + 1;
	fa[cnt] = 1;
	dep[cnt] = dep[1] + 1;
	++ size[1];
	while(dep[cnt] < depmax)
	{
		if(cnt > n) return printf("NO"), 0;
		fa[cnt + 1] = cnt;
		dep[cnt + 1] = dep[cnt] + 1;
		++ size[cnt];
		++ cnt;
	}
	For(i, 1, n)
	{
		while(size[i] + (i != 1) < k && fa[i] && (dep[i] < depmax || size[i] || ((d % 2 == 1) && vis[i] && dep[i] <= depmax)))
		{
			++ cnt;
			fa[cnt] = i;
			dep[cnt] = dep[i] + 1;
			++ size[i];
			vis[cnt] = vis[i];
			if(cnt >= n)
				break;
		}
	}
	if(cnt < n)
		return puts("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", i, fa[i]);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 5;
vector<int> son[maxn];
int n, d, k, cnt, dep[maxn], now, ovo;
int fa[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	int depmax = d / 2 + 1;
	now = 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		son[i - 1]. push_back(i);
		fa[i] = i - 1;
		dep[i] = dep[fa[i]] + 1;
	}
	cnt = depmax + d % 2 + 1;
	if(cnt > n + 1)
		return printf("NO"), 0;
	if(son[1].size() < k && fa[1] && (dep[1] < depmax || son[1].size()))
	{
		son[fa[cnt] = 1].push_back(cnt);
		dep[cnt] = dep[1] + 1;
		cnt ++;
	}
	while(dep[cnt - 1] < depmax)
	{
		if(cnt > n + 1)
			return printf("NO"), 0;
		if(son[cnt - 1].size() + (cnt - 1 != 1) < k && fa[cnt - 1] && (dep[cnt - 1] < depmax || son[cnt - 1].size()))
		{
			son[fa[cnt] = cnt - 1].push_back(cnt);
			dep[cnt] = dep[cnt - 1] + 1;
			cnt ++;
		}
	}
	while(cnt <= n && now <= n)
	{
		if(son[now].size() + (now != 1) < k && fa[now] && (dep[now] < depmax || son[now].size()))
		{
			son[now].push_back(cnt);
			fa[cnt] = now;
			dep[cnt] = dep[fa[cnt]] + 1;
			cnt ++;
		}
		else
			now ++;
	}
	if(cnt <= n)
		return printf("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", fa[i], i);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 5;
vector<int> son[maxn];
int n, d, k, cnt, dep[maxn], now, ovo;
int fa[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	if(n == 2 && d == 1 && k == 1)
		return printf("YES"), 0;
	if(k == 1)
		return printf("NO"), 0;
	int depmax = d / 2 + 1;
	now = 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		son[i - 1]. push_back(i);
		fa[i] = i - 1;
		dep[i] = dep[fa[i]] + 1;
	}
	cnt = depmax + d % 2 + 1;
	if(cnt > n + 1)
		return printf("NO"), 0;
	son[fa[cnt] = 1].push_back(cnt);
	dep[cnt] = dep[1] + 1;
	cnt ++;
	while(dep[cnt - 1] < depmax)
	{
		if(cnt > n)
			return printf("NO"), 0;
		son[fa[cnt] = cnt - 1].push_back(cnt);
		dep[cnt] = dep[cnt - 1] + 1;
		cnt ++;
	}
	while(cnt <= n && now <= n)
	{
		if(son[now].size() + (now != 1) < k && fa[now] && (dep[now] < depmax || son[now].size()))
		{
			son[now].push_back(cnt);
			fa[cnt] = now;
			dep[cnt] = dep[fa[cnt]] + 1;
			cnt ++;
		}
		else
			now ++;
	}
	if(cnt <= n)
		return printf("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", fa[i], i);
	return 0;
}


#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)

using namespace std;

const int maxn = 4e5 + 5;
vector<int> son[maxn];
int n, d, k, cnt, dep[maxn], now, ovo;
int fa[maxn];

int main()
{
//	freopen("E.in", "r", stdin);
//	freopen("E.out", "w", stdout);
	cin >> n >> d >> k;
	if(n == 2 && d == 1 && k == 1)
		return printf("YES\n1 2"), 0;
	if(k == 1)
		return printf("NO"), 0;
	int depmax = d / 2 + 1;
	now = 1, fa[1] = 1, dep[1] = 1;
	For(i, 2, depmax + d % 2)
	{
		son[i - 1]. push_back(i);
		fa[i] = i - 1;
		dep[i] = dep[fa[i]] + 1;
	}
	cnt = depmax + d % 2 + 1;
	if(cnt > n + 1)
		return printf("NO"), 0;
	son[fa[cnt] = 1].push_back(cnt);
	dep[cnt] = dep[1] + 1;
	cnt ++;
	while(dep[cnt - 1] < depmax)
	{
		if(cnt > n)
			return printf("NO"), 0;
		son[fa[cnt] = cnt - 1].push_back(cnt);
		dep[cnt] = dep[cnt - 1] + 1;
		cnt ++;
	}
	while(cnt <= n && now <= n)
	{
		if(son[now].size() + (now != 1) < k && fa[now] && (dep[now] < depmax || son[now].size()))
		{
			son[now].push_back(cnt);
			fa[cnt] = now;
			dep[cnt] = dep[fa[cnt]] + 1;
			cnt ++;
		}
		else
			now ++;
	}
	if(cnt <= n)
		return printf("NO"), 0;
	puts("YES");
	For(i, 2, n)
		printf("%d %d\n", fa[i], i);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }

const int maxn=(int)4e5+5;

int n,d,k,todo;

int deg[maxn];
vector<pair<int, int>> ans;

void add_nodes(int cur, int dst) {
  if (dst == d) return;
  if (todo > n) return;

  while (deg[cur]<k) {
    if (todo > n) return;
    ans.push_back({cur, todo});
    deg[cur]++;
    deg[todo]++;
    todo++;
    if (todo > n) return;
    add_nodes(todo-1,dst+1);

    if (todo > n) return;
  }
}

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

  cin>>n>>d>>k;

  if (n<d) out("NO");

  // diam is 1...d
  for (int i=1; i<=d; i++) {
    deg[i]++; deg[i+1]++;
    ans.push_back({i, i+1});
    todo = i+1+1;
  }

  // 1 2 3 4
  for (int i=2; i<=d; i++) {
    if (todo > n) break;
    add_nodes(i,d+1-i);
  }

  if (todo <= n) out("NO");

  cout<<"YES"<<endl;
  for (auto edge: ans) cout<<edge.first<<" "<<edge.second<<endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }

const int maxn=(int)4e5+5;

int n,d,k,todo;

int deg[maxn];
vector<pair<int, int>> ans;

void add_nodes(int cur, int dst) {
  if (dst == d) return;
  if (todo > n) return;

  while (deg[cur]<k) {
    if (todo > n) return;
    ans.push_back({cur, todo});
    deg[cur]++;
    deg[todo]++;
    todo++;
    if (todo > n) return;
    add_nodes(todo-1,dst+1);

    if (todo > n) return;
  }
}

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

  cin>>n>>d>>k;

  if (n<d) out("NO");

  // diam is 1...d
  for (int i=1; i<=d; i++) {
    deg[i]++; deg[i+1]++;
    ans.push_back({i, i+1});
    todo = i+1+1;
  }

  // 1 2 3 4
  for (int i=2; i<=d; i++) {
    if (todo > n) break;
    add_nodes(i,max(i-1,d+1-i));
  }

  if (todo <= n) out("NO");

  cout<<"YES"<<endl;
  for (auto edge: ans) cout<<edge.first<<" "<<edge.second<<endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }

const int maxn=(int)4e5+5;

int n,d,k,todo;

int deg[maxn];
vector<pair<int, int>> ans;

void add_nodes(int cur, int dst) {
  if (dst == d) return;
  if (todo > n) return;

  while (deg[cur]<k) {
    ans.push_back({cur, todo});
    deg[cur]++;
    deg[todo]++;
    todo++;
    add_nodes(todo-1,dst+1);

    if (todo > n) return;
  }
}

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

  cin>>n>>d>>k;
  todo = d+2;

  // diam is 1...d
  for (int i=1; i<=d; i++) {
    deg[i]++; deg[i+1]++;
    ans.push_back({i, i+1});
  }

  // 1 2 3 4
  for (int i=2; i<=d; i++) {
    if (todo > n) break;
    add_nodes(i,d+1-i);
  }

  if (todo <= n) out("NO");

  cout<<"YES"<<endl;
  for (auto edge: ans) cout<<edge.first<<" "<<edge.second<<endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }

const int maxn=(int)4e5+5;

int n,d,k,todo;

int deg[maxn];
vector<pair<int, int>> ans;

void add_nodes(int cur, int dst) {
  if (dst == d) return;
  if (todo > n) return;

  while (deg[cur]<k) {
    if (todo > n) return;
    ans.push_back({cur, todo});
    deg[cur]++;
    deg[todo]++;
    todo++;
    if (todo > n) return;
    add_nodes(todo-1,dst+1);

    if (todo > n) return;
  }
}

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

  cin>>n>>d>>k;

  if (n<=d) out("NO");

  // diam is 1...d
  for (int i=1; i<=d; i++) {
    deg[i]++; deg[i+1]++;
    ans.push_back({i, i+1});
    todo = i+1+1;
  }

  // 1 2 3 4
  for (int i=2; i<=d; i++) {
    if (todo > n) break;
    add_nodes(i,max(i-1,d+1-i));
  }

  if (todo <= n) out("NO");

  cout<<"YES"<<endl;
  for (auto edge: ans) cout<<edge.first<<" "<<edge.second<<endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }

const int maxn=(int)4e5+5;

int n,d,k,todo;

int deg[maxn];
vector<pair<int, int>> ans;

void add_nodes(int cur, int dst) {
  if (dst == d) return;
  if (todo > n) return;

  while (deg[cur]<k) {
    if (todo > n) return;
    ans.push_back({cur, todo});
    deg[cur]++;
    deg[todo]++;
    todo++;
    if (todo > n) return;
    add_nodes(todo-1,dst+1);

    if (todo > n) return;
  }
}

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

  cin>>n>>d>>k;

  if (n<=d) out("NO");
  if (k==1 && n>2) out("NO");

  // diam is 1...d
  for (int i=1; i<=d; i++) {
    deg[i]++; deg[i+1]++;
    ans.push_back({i, i+1});
    todo = i+1+1;
  }

  // 1 2 3 4
  for (int i=2; i<=d; i++) {
    if (todo > n) break;
    add_nodes(i,max(i-1,d+1-i));
  }

  if (todo <= n) out("NO");

  cout<<"YES"<<endl;
  for (auto edge: ans) cout<<edge.first<<" "<<edge.second<<endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }

const int maxn=(int)4e5+5;

int n,d,k,todo;

int deg[maxn];
vector<pair<int, int>> ans;

void add_nodes(int cur, int dst) {
  if (dst == d) return;
  if (todo > n) return;

  while (deg[cur]<k) {
    if (todo > n) return;
    ans.push_back({cur, todo});
    deg[cur]++;
    deg[todo]++;
    todo++;
    if (todo > n) return;
    add_nodes(todo-1,dst+1);

    if (todo > n) return;
  }
}

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

  cin>>n>>d>>k;

  // diam is 1...d
  for (int i=1; i<=d; i++) {
    deg[i]++; deg[i+1]++;
    ans.push_back({i, i+1});
    todo = i+1+1;
  }

  // 1 2 3 4
  for (int i=2; i<=d; i++) {
    if (todo > n) break;
    add_nodes(i,d+1-i);
  }

  if (todo <= n) out("NO");

  cout<<"YES"<<endl;
  for (auto edge: ans) cout<<edge.first<<" "<<edge.second<<endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }

const int maxn=(int)4e5+5;

int n,d,k,todo;

int deg[maxn];
vector<pair<int, int>> ans;

void add_nodes(int cur, int dst) {
  if (dst == d) return;
  if (todo > n) return;

  while (deg[cur]<k) {
    ans.push_back({cur, todo});
    deg[cur]++;
    deg[todo]++;
    todo++;
    add_nodes(todo-1,dst+1);

    if (todo > n) return;
  }
}

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

  cin>>n>>d>>k;

  // diam is 1...d
  for (int i=1; i<=d; i++) {
    deg[i]++; deg[i+1]++;
    ans.push_back({i, i+1});
    todo = i+1+1;
  }

  // 1 2 3 4
  for (int i=2; i<=d; i++) {
    if (todo > n) break;
    add_nodes(i,d+1-i);
  }

  if (todo <= n) out("NO");

  cout<<"YES"<<endl;
  for (auto edge: ans) cout<<edge.first<<" "<<edge.second<<endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }

const int maxn=(int)4e5+5;

int n,d,k,todo;

int deg[maxn];
vector<pair<int, int>> ans;

void add_nodes(int cur, int dst) {
  if (dst == d) return;
  if (todo > n) return;

  while (deg[cur]<k) {
    if (todo > n) return;
    ans.push_back({cur, todo});
    deg[cur]++;
    deg[todo]++;
    todo++;
    if (todo > n) return;
    add_nodes(todo-1,dst+1);

    if (todo > n) return;
  }
}

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

  cin>>n>>d>>k;

  if (n<d) out("NO");

  // diam is 1...d
  for (int i=1; i<=d; i++) {
    deg[i]++; deg[i+1]++;
    ans.push_back({i, i+1});
    todo = i+1+1;
  }

  // 1 2 3 4
  for (int i=2; i<=d-1; i++) {
    if (todo > n) break;
    add_nodes(i,d+1-i);
  }

  if (todo <= n) out("NO");

  cout<<"YES"<<endl;
  for (auto edge: ans) cout<<edge.first<<" "<<edge.second<<endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }

const int maxn=(int)4e5+5;

int n,d,k,todo;

int deg[maxn];
vector<pair<int, int>> ans;

void add_nodes(int cur, int dst) {
  if (dst == d) return;
  if (todo > n) return;

  while (deg[cur]<k) {
    if (todo > n) return;
    ans.push_back({cur, todo});
    deg[cur]++;
    deg[todo]++;
    todo++;
    if (todo > n) return;
    add_nodes(todo-1,dst+1);

    if (todo > n) return;
  }
}

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

  cin>>n>>d>>k;

  if (d<n) out("NO");

  // diam is 1...d
  for (int i=1; i<=d; i++) {
    deg[i]++; deg[i+1]++;
    ans.push_back({i, i+1});
    todo = i+1+1;
  }

  // 1 2 3 4
  for (int i=2; i<=d; i++) {
    if (todo > n) break;
    add_nodes(i,d+1-i);
  }

  if (todo <= n) out("NO");

  cout<<"YES"<<endl;
  for (auto edge: ans) cout<<edge.first<<" "<<edge.second<<endl;

  return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>
#include <limits>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <unordered_map>

using namespace std;

#define len(x) ((int)x.size())

typedef pair<pair<int, int>, int> iii;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;

int n, d, k;
vii edges;

bool comp(const iii &a, const iii &b) {
  if (a.first.first == b.first.first) {
    return a.first.second > b.first.second;
  }
  return a.first.first < b.first.first;
}

bool canMake() {
  if (k == 1 && n > 2) {
    return false;
  }

  int diameter = 0;

  //set<iii, comp> order; // grau, vertice

  int n_aux = 1;
  int g = 1;
  for (g = 1; g < n && diameter < d; g++) {
    edges.emplace_back(ii(g, g + 1));
    diameter++;
    n_aux++;
  }

  /*for (ii el : edges) {
    printf("inicial %d %d\n", el.first, el.second);
  }*/

  deque<iii> order;
  int put = 1;
  for (int i = 2; i < g; i++) {
    order.emplace_back(iii(ii(2, put), i));
    if (g % 2 == 0) {
      if (i == (g / 2) || i == (g / 2) + 1) {
        put -= (i == ((g / 2) + 1));
      } else if (i > (g / 2) + 1) {
        put--;
      } else {
        put++;
      }
    } else {
      if (i > (g / 2)) {
        put--;
      } else put++;
    }
  }

  /*for (iii el : order) {
    printf("vert %d (%d, %d)\n", el.second, el.first.first, el.first.second);
  }*/

  n_aux++;
  while (!order.empty() && n_aux <= n) {
    iii now = *order.begin(); order.pop_front();
    int v = now.second;
    int grau = now.first.first;
    int qtdPermitida = now.first.second;
    //printf("  olhando vertice %d grau %d qtd %d\n", v, grau, qtdPermitida);
    if (qtdPermitida == 0) {
      continue;
    }
    while (grau < k && n_aux <= n) {
      //printf("adicionei %d %d\n", v, n_aux);
      edges.emplace_back(ii(v, n_aux));
      order.emplace_back(iii(ii(1, qtdPermitida - 1), n_aux));
      n_aux++;
      grau++;
    }
  }

  //printf("n_aux eh %d\n", n_aux);
  //return true;
  return n_aux >= n;
}
int main() {
#ifndef DEBUG
  ios::sync_with_stdio(0);
  cin.tie(0); cout.tie(0);
#endif

  cin >> n >> d >> k;

  bool ans = canMake();
  printf("%s\n", ans ? "Yes" : "No");
  if (ans) {
    for (ii ed : edges) {
      cout << ed.first << " " << ed.second << '\n';
    }
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>
#include <limits>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <unordered_map>

using namespace std;

#define len(x) ((int)x.size())

typedef pair<pair<int, int>, int> iii;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;

int n, d, k;
vii edges;

bool comp(const iii &a, const iii &b) {
  if (a.first.first == b.first.first) {
    return a.first.second > b.first.second;
  }
  return a.first.first < b.first.first;
}

bool canMake() {
  if ((k == 1 && n > 2) || n == d) {
    return false;
  }

  int diameter = 0;

  //set<iii, comp> order; // grau, vertice

  int n_aux = 1;
  int g = 1;
  for (g = 1; g < n && diameter < d; g++) {
    edges.emplace_back(ii(g, g + 1));
    diameter++;
    n_aux++;
  }

  /*for (ii el : edges) {
    printf("inicial %d %d\n", el.first, el.second);
  }*/

  deque<iii> order;
  int put = 1;
  for (int i = 2; i < g; i++) {
    order.emplace_back(iii(ii(2, put), i));
    if (g % 2 == 0) {
      if (i == (g / 2) || i == (g / 2) + 1) {
        put -= (i == ((g / 2) + 1));
      } else if (i > (g / 2) + 1) {
        put--;
      } else {
        put++;
      }
    } else {
      if (i > (g / 2)) {
        put--;
      } else put++;
    }
  }

  /*for (iii el : order) {
    printf("vert %d (%d, %d)\n", el.second, el.first.first, el.first.second);
  }*/

  n_aux++;
  while (!order.empty() && n_aux <= n) {
    iii now = *order.begin(); order.pop_front();
    int v = now.second;
    int grau = now.first.first;
    int qtdPermitida = now.first.second;
    //printf("  olhando vertice %d grau %d qtd %d\n", v, grau, qtdPermitida);
    if (qtdPermitida == 0) {
      continue;
    }
    while (grau < k && n_aux <= n) {
      //printf("adicionei %d %d\n", v, n_aux);
      edges.emplace_back(ii(v, n_aux));
      order.emplace_back(iii(ii(1, qtdPermitida - 1), n_aux));
      n_aux++;
      grau++;
    }
  }

  //printf("n_aux eh %d\n", n_aux);
  //return true;
  return n_aux >= n;
}
int main() {
#ifndef DEBUG
  ios::sync_with_stdio(0);
  cin.tie(0); cout.tie(0);
#endif

  cin >> n >> d >> k;

  bool ans = canMake();
  if (ans) {
    cout << "YES\n";
    for (ii ed : edges) {
      cout << ed.first << " " << ed.second << '\n';
    }
  } else {
    cout << "NO\n";
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>
#include <limits>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <unordered_map>

using namespace std;

#define len(x) ((int)x.size())

typedef pair<pair<int, int>, int> iii;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;

int n, d, k;
vii edges;

bool comp(const iii &a, const iii &b) {
  if (a.first.first == b.first.first) {
    return a.first.second > b.first.second;
  }
  return a.first.first < b.first.first;
}

bool canMake() {
  if (((k == 1 && n > 2)) || d >= n) {
    return false;
  }

  int diameter = 0;
  int n_aux = 1;
  int g = 1;
  for (g = 1; g < n && diameter < d; g++) {
    edges.emplace_back(ii(g, g + 1));
    diameter++;
    n_aux++;
  }

  /*for (ii el : edges) {
    printf("inicial %d %d\n", el.first, el.second);
  }*/

  deque<iii> order;
  int put = 1;
  for (int i = 2; i < g; i++) {
    order.emplace_back(iii(ii(2, put), i));
    if (g % 2 == 0) {
      if (i == (g / 2) || i == (g / 2) + 1) {
        put -= (i == ((g / 2) + 1));
      } else if (i > (g / 2) + 1) {
        put--;
      } else {
        put++;
      }
    } else {
      if (i > (g / 2)) {
        put--;
      } else put++;
    }
  }

  /*puts("");
  for (iii el : order) {
    printf("vert %d (%d, %d)\n", el.second, el.first.first, el.first.second);
  }*/

  while (!order.empty() && n_aux < n) {
    iii now = *order.begin(); order.pop_front();
    int v = now.second;
    int grau = now.first.first;
    int qtdPermitida = now.first.second;
    //printf("  olhando vertice %d grau %d qtd %d\n", v, grau, qtdPermitida);
    if (qtdPermitida == 0) {
      continue;
    }
    while (grau < k && n_aux < n) {
      n_aux++;
      //printf("adicionei %d %d\n", v, n_aux);
      edges.emplace_back(ii(v, n_aux));
      order.emplace_back(iii(ii(1, qtdPermitida - 1), n_aux));
      grau++;
    }
  }

  //printf("n_aux eh %d\n", n_aux);
  //return true;
  return n_aux >= n;
}
int main() {
#ifndef DEBUG
  ios::sync_with_stdio(0);
  cin.tie(0); cout.tie(0);
#endif

  cin >> n >> d >> k;

  bool ans = canMake();
  if (ans) {
    cout << "YES\n";
    for (ii ed : edges) {
      cout << ed.first << " " << ed.second << '\n';
    }
  } else {
    cout << "NO\n";
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>
#include <limits>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <unordered_map>

using namespace std;

#define len(x) ((int)x.size())

typedef pair<pair<int, int>, int> iii;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;

int n, d, k;
vii edges;

bool comp(const iii &a, const iii &b) {
  if (a.first.first == b.first.first) {
    return a.first.second > b.first.second;
  }
  return a.first.first < b.first.first;
}

bool canMake() {
  if (k == 1 && n > 2) {
    return false;
  }

  int diameter = 0;

  //set<iii, comp> order; // grau, vertice

  int n_aux = 1;
  int g = 1;
  for (g = 1; g < n && diameter < d; g++) {
    edges.emplace_back(ii(g, g + 1));
    diameter++;
    n_aux++;
  }

  /*for (ii el : edges) {
    printf("inicial %d %d\n", el.first, el.second);
  }*/

  deque<iii> order;
  int put = 1;
  for (int i = 2; i < g; i++) {
    order.emplace_back(iii(ii(2, put), i));
    if (g % 2 == 0) {
      if (i == (g / 2) || i == (g / 2) + 1) {
        put -= (i == ((g / 2) + 1));
      } else if (i > (g / 2) + 1) {
        put--;
      } else {
        put++;
      }
    } else {
      if (i > (g / 2)) {
        put--;
      } else put++;
    }
  }

  /*for (iii el : order) {
    printf("vert %d (%d, %d)\n", el.second, el.first.first, el.first.second);
  }*/

  n_aux++;
  while (!order.empty() && n_aux <= n) {
    iii now = *order.begin(); order.pop_front();
    int v = now.second;
    int grau = now.first.first;
    int qtdPermitida = now.first.second;
    //printf("  olhando vertice %d grau %d qtd %d\n", v, grau, qtdPermitida);
    if (qtdPermitida == 0) {
      continue;
    }
    while (grau < k && n_aux <= n) {
      //printf("adicionei %d %d\n", v, n_aux);
      edges.emplace_back(ii(v, n_aux));
      order.emplace_back(iii(ii(1, qtdPermitida - 1), n_aux));
      n_aux++;
      grau++;
    }
  }

  //printf("n_aux eh %d\n", n_aux);
  //return true;
  return n_aux >= n;
}
int main() {
#ifndef DEBUG
  ios::sync_with_stdio(0);
  cin.tie(0); cout.tie(0);
#endif

  cin >> n >> d >> k;

  bool ans = canMake();
  printf("%s\n", ans ? "YES" : "NO");
  if (ans) {
    for (ii ed : edges) {
      cout << ed.first << " " << ed.second << '\n';
    }
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>
#include <limits>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <unordered_map>

using namespace std;

#define len(x) ((int)x.size())

typedef pair<pair<int, int>, int> iii;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;

int n, d, k;
vii edges;

bool comp(const iii &a, const iii &b) {
  if (a.first.first == b.first.first) {
    return a.first.second > b.first.second;
  }
  return a.first.first < b.first.first;
}

bool canMake() {
  if (k == 1 && n > 2) {
    return false;
  }

  int diameter = 0;

  //set<iii, comp> order; // grau, vertice

  int n_aux = 1;
  int g = 1;
  for (g = 1; g < n && diameter < d; g++) {
    edges.emplace_back(ii(g, g + 1));
    diameter++;
    n_aux++;
  }

  /*for (ii el : edges) {
    printf("inicial %d %d\n", el.first, el.second);
  }*/

  deque<iii> order;
  int put = 1;
  for (int i = 2; i < g; i++) {
    order.emplace_back(iii(ii(2, put), i));
    if (g % 2 == 0) {
      if (i == (g / 2) || i == (g / 2) + 1) {
        put -= (i == ((g / 2) + 1));
      } else if (i > (g / 2) + 1) {
        put--;
      } else {
        put++;
      }
    } else {
      if (i > (g / 2)) {
        put--;
      } else put++;
    }
  }

  /*for (iii el : order) {
    printf("vert %d (%d, %d)\n", el.second, el.first.first, el.first.second);
  }*/

  n_aux++;
  while (!order.empty() && n_aux <= n) {
    iii now = *order.begin(); order.pop_front();
    int v = now.second;
    int grau = now.first.first;
    int qtdPermitida = now.first.second;
    //printf("  olhando vertice %d grau %d qtd %d\n", v, grau, qtdPermitida);
    if (qtdPermitida == 0) {
      continue;
    }
    while (grau < k && n_aux <= n) {
      //printf("adicionei %d %d\n", v, n_aux);
      edges.emplace_back(ii(v, n_aux));
      order.emplace_back(iii(ii(1, qtdPermitida - 1), n_aux));
      n_aux++;
      grau++;
    }
  }

  //printf("n_aux eh %d\n", n_aux);
  //return true;
  return n_aux >= n;
}
int main() {
#ifndef DEBUG
  ios::sync_with_stdio(0);
  cin.tie(0); cout.tie(0);
#endif

  cin >> n >> d >> k;

  bool ans = canMake();
  if (ans) {
    cout << "YES\n";
    for (ii ed : edges) {
      cout << ed.first << " " << ed.second << '\n';
    }
  } else {
    cout << "NO\n";
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>
#include <limits>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <unordered_map>

using namespace std;

#define len(x) ((int)x.size())

typedef pair<pair<int, int>, int> iii;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;

int n, d, k;
vii edges;

bool comp(const iii &a, const iii &b) {
  if (a.first.first == b.first.first) {
    return a.first.second > b.first.second;
  }
  return a.first.first < b.first.first;
}

bool canMake() {
  if (d >= n) {
    return false;
  }

  int diameter = 0;
  int n_aux = 1;
  int g = 1;
  for (g = 1; g < n && diameter < d; g++) {
    edges.emplace_back(ii(g, g + 1));
    diameter++;
    n_aux++;
  }

  /*for (ii el : edges) {
    printf("inicial %d %d\n", el.first, el.second);
  }*/

  deque<iii> order;
  int put = 1;
  for (int i = 2; i < g; i++) {
    order.emplace_back(iii(ii(2, put), i));
    if (g % 2 == 0) {
      if (i == (g / 2) || i == (g / 2) + 1) {
        put -= (i == ((g / 2) + 1));
      } else if (i > (g / 2) + 1) {
        put--;
      } else {
        put++;
      }
    } else {
      if (i > (g / 2)) {
        put--;
      } else put++;
    }
  }

  /*puts("");
  for (iii el : order) {
    printf("vert %d (%d, %d)\n", el.second, el.first.first, el.first.second);
  }*/

  while (!order.empty() && n_aux < n) {
    iii now = *order.begin(); order.pop_front();
    int v = now.second;
    int grau = now.first.first;
    int qtdPermitida = now.first.second;
    //printf("  olhando vertice %d grau %d qtd %d\n", v, grau, qtdPermitida);
    if (qtdPermitida == 0) {
      continue;
    }
    while (grau < k && n_aux < n) {
      n_aux++;
      //printf("adicionei %d %d\n", v, n_aux);
      edges.emplace_back(ii(v, n_aux));
      order.emplace_back(iii(ii(1, qtdPermitida - 1), n_aux));
      grau++;
    }
  }

  //printf("n_aux eh %d\n", n_aux);
  //return true;
  return n_aux >= n;
}
int main() {
#ifndef DEBUG
  ios::sync_with_stdio(0);
  cin.tie(0); cout.tie(0);
#endif

  cin >> n >> d >> k;

  bool ans = canMake();
  if (ans) {
    cout << "YES\n";
    for (ii ed : edges) {
      cout << ed.first << " " << ed.second << '\n';
    }
  } else {
    cout << "NO\n";
  }
  return 0;
}


	#include <bits/stdc++.h>
	using namespace std ;
	#define ll long long int
	#define pb push_back
	#define ff first
	#define dobara(i,a,b) for(int (i) = (a); (i) < (b); (i)++)
	#define ss second
	#define S(x) scanf("%d",&x)
	#define SL(x) scanf("%lld",&x)
	#define M 1000000007
	#define sz(x) (int)x.size()
	#define all(a) (a).begin(),(a).end()
	int depth[400005] , used[400005] , leaf[400005] , unt[400005] ;
	int main()
	{
	   int n , diam , deg ;
	   cin>>n>>diam>>deg ;
	   if(deg==1)
	   {
	   	  if(diam==n-1)
	   	  {
	   	  	 cout<<"YES\n" ;
	   	  	 for(int i=1;i<=n-1;i++)
	   	  	 {
	   	  	 	cout<<i<<" "<<i+1<<"\n" ;
	   	  	 }
	   	  }
	   	  else
	   	  {
	   	  	cout<<"NO\n" ;
	   	  }
	   }
	   else
	   {
	   	  vector<pair<int,int> > v  ;
	   	  depth[1]=1 ;
	   	  int node=1 ;
	   	  int mx=1 ;
	   	  used[1]=1 ;
	   	  int x ;
	      if(diam%2)
	      {
	          x=(diam)/2 +1 ;
	          if(1+x>n)
	          {
	          	 cout<<"NO\n" ;
	          	 exit(0) ;
	          }
	         for(int i=2;i<=1+x;i++)
	         {
	         	v.pb({i-1,i}) ;
	         	unt[i]++ ;
	         	unt[i-1]++ ;
	         	depth[i]=depth[i-1]+1 ;
	         	mx=max(mx,depth[i]) ;
	         	used[i]=1 ;
	         }
	         leaf[1+x]=1 ;
	         node=1+x+1 ;
	         if(node-1+x-1>n)
	         {
	         	cout<<"NO\n" ;
	         	exit(0) ;
	         }
	         int d=deg-1  ;
	         while(d--)
	         {
	            //node++ ;
	            int p=1 ;
	            for(int i=1;i<=x-1 && node<n+1;i++)
	            {
	            	v.pb({p,node}) ;
	            	used[node]=1 ;
	            	unt[p]++ ;
	            	unt[node]++ ;
	            	depth[node]=depth[p]+1 ;
	            	if(i==x-1)
	            	{
	            		leaf[node]=1 ;
	            	}
	            	p=node ;
	            	node++ ;
	            }
	         }
	         int flg=1 ;
	         for(int i=2;i<=n;i++)
	         {
	         	int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node==n+1)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  for(int j=depth[i];j<mx && node<n+1;j++)
	         			  {
	         			  	v.pb({p,node}) ;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==mx)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	         }
	         for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	      else
	      {
	         x=diam/2 ;
	         int p=1 ;
	         node=2 ;
	         int flg=1 ;
	         int cnt=2 ;
	         while(cnt--)
	         {
	         	p=1 ;
	         	if(node-1+x>n)
	         	{
	         		cout<<"NO\n" ;
	         		exit(0) ;
	         	}
	         for(int i=1;i<=x;i++)
	         {
	         	v.pb({p,node}) ;
	         	used[node]=1 ;
	         	if(i==x)
	         	{
	         		leaf[node]=1  ;
	         	}
	         	unt[p]++ ;
	         	unt[node]++ ;
	         	depth[node]=depth[p]+1 ;
	         	p=node ;
	         	mx=max(mx,depth[node]) ;
	         	node++ ;
	         }
	        }
	        for(int i=1;i<=n;i++)
	        {
	           int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node==n+1)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  for(int j=depth[i];j<mx && node<n+1;j++)
	         			  {
	         			  	v.pb({p,node}) ;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==mx)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	        }
	        for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	   }
	}


	#include <bits/stdc++.h>
	using namespace std ;
	#define ll long long int
	#define pb push_back
	#define ff first
	#define dobara(i,a,b) for(int (i) = (a); (i) < (b); (i)++)
	#define ss second
	#define S(x) scanf("%d",&x)
	#define SL(x) scanf("%lld",&x)
	#define M 1000000007
	#define sz(x) (int)x.size()
	#define all(a) (a).begin(),(a).end()
	int depth[400005] , used[400005] , leaf[400005] , unt[400005] , lucky[400005] ;
	int main()
	{
	   int n , diam , deg ;
	   cin>>n>>diam>>deg ;
	   if(deg==1)
	   {
	   	  if(diam==n-1)
	   	  {
	   	  	 cout<<"YES\n" ;
	   	  	 for(int i=1;i<=n-1;i++)
	   	  	 {
	   	  	 	cout<<i<<" "<<i+1<<"\n" ;
	   	  	 }
	   	  }
	   	  else
	   	  {
	   	  	cout<<"NO\n" ;
	   	  }
	   }
	   else
	   {
	   	  vector<pair<int,int> > v  ;
	   	  depth[1]=1 ;
	   	  int node=1 ;
	   	  int mx=1 ;
	   	  used[1]=1 ;
	   	  int x ;
	      if(diam%2)
	      {
	          x=(diam)/2 +1 ;
	          if(1+x>n)
	          {
	          	 cout<<"NO\n" ;
	          	 exit(0) ;
	          }
	         for(int i=2;i<=1+x;i++)
	         {
	         	v.pb({i-1,i}) ;
	         	lucky[i]=1 ;
	         	unt[i]++ ;
	         	unt[i-1]++ ;
	         	depth[i]=depth[i-1]+1 ;
	         	mx=max(mx,depth[i]) ;
	         	used[i]=1 ;
	         }
	         leaf[1+x]=1 ;
	         node=1+x+1 ;
	         if(node-1+x-1>n)
	         {
	         	cout<<"NO\n" ;
	         	exit(0) ;
	         }
	         int d=deg-1  ;
	         while(d--)
	         {
	            //node++ ;
	            int p=1 ;
	            for(int i=1;i<=x-1 && node<n+1;i++)
	            {
	            	v.pb({p,node}) ;
	            	used[node]=1 ;
	            	unt[p]++ ;
	            	unt[node]++ ;
	            	depth[node]=depth[p]+1 ;
	            	if(i==x-1)
	            	{
	            		leaf[node]=1 ;
	            	}
	            	p=node ;
	            	node++ ;
	            }
	         }
	         int flg=1 ;
	         for(int i=2;i<=n;i++)
	         {
	         	int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node==n+1)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  int lmt=mx-(!lucky[i]) ;
	         			  for(int j=depth[i];j<lmt && node<n+1;j++)
	         			  {
	         			  	if(lucky[i])
	         			  		lucky[node]=1 ;
	         			  	v.pb({p,node}) ;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==lmt-1)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	         }
	         for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	      else
	      {
	         x=diam/2 ;
	         int p=1 ;
	         node=2 ;
	         int flg=1 ;
	         int cnt=2 ;
	         while(cnt--)
	         {
	         	p=1 ;
	         	if(node-1+x>n)
	         	{
	         		cout<<"NO\n" ;
	         		exit(0) ;
	         	}
	         for(int i=1;i<=x;i++)
	         {
	         	v.pb({p,node}) ;
	        // 	cout<<p<<" "<<node<<endl;
	         	used[node]=1 ;
	         	if(i==x)
	         	{
	         		leaf[node]=1  ;
	         	}
	         	unt[p]++ ;
	         	unt[node]++ ;
	         	depth[node]=depth[p]+1 ;
	         	p=node ;
	         	mx=max(mx,depth[node]) ;
	         	node++ ;
	         }
	        }
	        //cout<<"HRHE\n";
	        for(int i=1;i<=n;i++)
	        {
	           int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node>=n+1)
	         		break ;
	         	if(used[i]==0)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  for(int j=depth[i];j<mx && node<n+1;j++)
	         			  {
	         			  	v.pb({p,node}) ;
	         			//  cout<<p<<" "<<node<<endl;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==mx-1)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	        }
	        //cout<<"HRHE"<<endl ;
	        for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	   }
	}


	#include <bits/stdc++.h>
	using namespace std ;
	#define ll long long int
	#define pb push_back
	#define ff first
	#define dobara(i,a,b) for(int (i) = (a); (i) < (b); (i)++)
	#define ss second
	#define S(x) scanf("%d",&x)
	#define SL(x) scanf("%lld",&x)
	#define M 1000000007
	#define sz(x) (int)x.size()
	#define all(a) (a).begin(),(a).end()
	int depth[400005] , used[400005] , leaf[400005] , unt[400005] ;
	int main()
	{
	   int n , diam , deg ;
	   cin>>n>>diam>>deg ;
	   if(deg==1)
	   {
	   	  if(diam==n-1)
	   	  {
	   	  	 cout<<"YES\n" ;
	   	  	 for(int i=1;i<=n-1;i++)
	   	  	 {
	   	  	 	cout<<i<<" "<<i+1<<"\n" ;
	   	  	 }
	   	  }
	   	  else
	   	  {
	   	  	cout<<"NO\n" ;
	   	  }
	   }
	   else
	   {
	   	  vector<pair<int,int> > v  ;
	   	  depth[1]=1 ;
	   	  int node=1 ;
	   	  int mx=1 ;
	   	  used[1]=1 ;
	   	  int x ;
	      if(diam%2)
	      {
	          x=(diam)/2 +1 ;
	          if(1+x>n)
	          {
	          	 cout<<"NO\n" ;
	          	 exit(0) ;
	          }
	         for(int i=2;i<=1+x;i++)
	         {
	         	v.pb({i-1,i}) ;
	         	unt[i]++ ;
	         	unt[i-1]++ ;
	         	depth[i]=depth[i-1]+1 ;
	         	mx=max(mx,depth[i]) ;
	         	used[i]=1 ;
	         }
	         leaf[1+x]=1 ;
	         node=1+x+1 ;
	         if(node-1+x-1>n)
	         {
	         	cout<<"NO\n" ;
	         	exit(0) ;
	         }
	         int d=deg-1  ;
	         while(d--)
	         {
	            //node++ ;
	            int p=1 ;
	            for(int i=1;i<=x-1 && node<n+1;i++)
	            {
	            	v.pb({p,node}) ;
	            	used[node]=1 ;
	            	unt[p]++ ;
	            	unt[node]++ ;
	            	depth[node]=depth[p]+1 ;
	            	if(i==x-1)
	            	{
	            		leaf[node]=1 ;
	            	}
	            	p=node ;
	            	node++ ;
	            }
	         }
	         int flg=1 ;
	         for(int i=2;i<=n;i++)
	         {
	         	int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node==n+1)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  for(int j=depth[i];j<mx && node<n+1;j++)
	         			  {
	         			  	v.pb({p,node}) ;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==mx-1)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	         }
	         for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	      else
	      {
	         x=diam/2 ;
	         int p=1 ;
	         node=2 ;
	         int flg=1 ;
	         int cnt=2 ;
	         while(cnt--)
	         {
	         	p=1 ;
	         	if(node-1+x>n)
	         	{
	         		cout<<"NO\n" ;
	         		exit(0) ;
	         	}
	         for(int i=1;i<=x;i++)
	         {
	         	v.pb({p,node}) ;
	        // 	cout<<p<<" "<<node<<endl;
	         	used[node]=1 ;
	         	if(i==x)
	         	{
	         		leaf[node]=1  ;
	         	}
	         	unt[p]++ ;
	         	unt[node]++ ;
	         	depth[node]=depth[p]+1 ;
	         	p=node ;
	         	mx=max(mx,depth[node]) ;
	         	node++ ;
	         }
	        }
	        //cout<<"HRHE\n";
	        for(int i=1;i<=n;i++)
	        {
	           int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node>=n+1)
	         		break ;
	         	if(used[i]==0)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  for(int j=depth[i];j<mx && node<n+1;j++)
	         			  {
	         			  	v.pb({p,node}) ;
	         			//  cout<<p<<" "<<node<<endl;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==mx-1)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	        }
	        //cout<<"HRHE"<<endl ;
	        for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	   }
	}


	#include <bits/stdc++.h>
	using namespace std ;
	#define ll long long int
	#define pb push_back
	#define ff first
	#define dobara(i,a,b) for(int (i) = (a); (i) < (b); (i)++)
	#define ss second
	#define S(x) scanf("%d",&x)
	#define SL(x) scanf("%lld",&x)
	#define M 1000000007
	#define sz(x) (int)x.size()
	#define all(a) (a).begin(),(a).end()
	int depth[400005] , used[400005] , leaf[400005] , unt[400005] , lucky[400005] ;
	int main()
	{
	   int n , diam , deg ;
	   cin>>n>>diam>>deg ;
	   if(deg==1)
	   {
	   	  if(diam==1 && n==2)
	   	  {
	   	  	 cout<<"YES\n" ;
	   	  	 for(int i=1;i<=n-1;i++)
	   	  	 {
	   	  	 	cout<<i<<" "<<i+1<<"\n" ;
	   	  	 }
	   	  }
	   	  else
	   	  {
	   	  	cout<<"NO\n" ;
	   	  }
	   }
	   else
	   {
	   	  vector<pair<int,int> > v  ;
	   	  depth[1]=1 ;
	   	  int node=1 ;
	   	  int mx=1 ;
	   	  used[1]=1 ;
	   	  int x ;
	      if(diam%2)
	      {
	          x=(diam)/2 +1 ;
	          if(1+x>n)
	          {
	          	 cout<<"NO\n" ;
	          	 exit(0) ;
	          }
	         for(int i=2;i<=1+x;i++)
	         {
	         	v.pb({i-1,i}) ;
	         	lucky[i]=1 ;
	         	unt[i]++ ;
	         	unt[i-1]++ ;
	         	depth[i]=depth[i-1]+1 ;
	         	mx=max(mx,depth[i]) ;
	         	used[i]=1 ;
	         }
	         leaf[1+x]=1 ;
	         node=1+x+1 ;
	         if(node-1+x-1>n)
	         {
	         	cout<<"NO\n" ;
	         	exit(0) ;
	         }
	         int d=deg-1  ;
	         while(d--)
	         {
	            //node++ ;
	            int p=1 ;
	            for(int i=1;i<=x-1 && node<n+1;i++)
	            {
	            	v.pb({p,node}) ;
	            	used[node]=1 ;
	            	unt[p]++ ;
	            	unt[node]++ ;
	            	depth[node]=depth[p]+1 ;
	            	if(i==x-1)
	            	{
	            		leaf[node]=1 ;
	            	}
	            	p=node ;
	            	node++ ;
	            }
	         }
	         int flg=1 ;
	         for(int i=2;i<=n;i++)
	         {
	         	int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node==n+1)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  int lmt=mx-(!lucky[i]) ;
	         			  for(int j=depth[i];j<lmt && node<n+1;j++)
	         			  {
	         			  	if(lucky[i])
	         			  		lucky[node]=1 ;
	         			  	v.pb({p,node}) ;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==lmt-1)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	         }
	         for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	      else
	      {
	         x=diam/2 ;
	         int p=1 ;
	         node=2 ;
	         int flg=1 ;
	         int cnt=2 ;
	         while(cnt--)
	         {
	         	p=1 ;
	         	if(node-1+x>n)
	         	{
	         		cout<<"NO\n" ;
	         		exit(0) ;
	         	}
	         for(int i=1;i<=x;i++)
	         {
	         	v.pb({p,node}) ;
	        // 	cout<<p<<" "<<node<<endl;
	         	used[node]=1 ;
	         	if(i==x)
	         	{
	         		leaf[node]=1  ;
	         	}
	         	unt[p]++ ;
	         	unt[node]++ ;
	         	depth[node]=depth[p]+1 ;
	         	p=node ;
	         	mx=max(mx,depth[node]) ;
	         	node++ ;
	         }
	        }
	        //cout<<"HRHE\n";
	        for(int i=1;i<=n;i++)
	        {
	           int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node>=n+1)
	         		break ;
	         	if(used[i]==0)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  for(int j=depth[i];j<mx && node<n+1;j++)
	         			  {
	         			  	v.pb({p,node}) ;
	         			//  cout<<p<<" "<<node<<endl;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==mx-1)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	        }
	        //cout<<"HRHE"<<endl ;
	        for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	   }
	}


	#include <bits/stdc++.h>
	using namespace std ;
	#define ll long long int
	#define pb push_back
	#define ff first
	#define dobara(i,a,b) for(int (i) = (a); (i) < (b); (i)++)
	#define ss second
	#define S(x) scanf("%d",&x)
	#define SL(x) scanf("%lld",&x)
	#define M 1000000007
	#define sz(x) (int)x.size()
	#define all(a) (a).begin(),(a).end()
	int depth[400005] , used[400005] , leaf[400005] , unt[400005] ;
	int main()
	{
	   int n , diam , deg ;
	   cin>>n>>diam>>deg ;
	   if(deg==1)
	   {
	   	  if(diam==n-1)
	   	  {
	   	  	 cout<<"YES\n" ;
	   	  	 for(int i=1;i<=n-1;i++)
	   	  	 {
	   	  	 	cout<<i<<" "<<i+1<<"\n" ;
	   	  	 }
	   	  }
	   	  else
	   	  {
	   	  	cout<<"NO\n" ;
	   	  }
	   }
	   else
	   {
	   	  vector<pair<int,int> > v  ;
	   	  depth[1]=1 ;
	   	  int node=1 ;
	   	  int mx=1 ;
	   	  used[1]=1 ;
	   	  int x ;
	      if(diam%2)
	      {
	          x=(diam)/2 +1 ;
	          if(1+x>n)
	          {
	          	 cout<<"NO\n" ;
	          	 exit(0) ;
	          }
	         for(int i=2;i<=1+x;i++)
	         {
	         	v.pb({i-1,i}) ;
	         	unt[i]++ ;
	         	unt[i-1]++ ;
	         	depth[i]=depth[i-1]+1 ;
	         	mx=max(mx,depth[i]) ;
	         	used[i]=1 ;
	         }
	         leaf[1+x]=1 ;
	         node=1+x+1 ;
	         if(node-1+x-1>n)
	         {
	         	cout<<"NO\n" ;
	         	exit(0) ;
	         }
	         int d=deg-1  ;
	         while(d--)
	         {
	            //node++ ;
	            int p=1 ;
	            for(int i=1;i<=x-1;i++)
	            {
	            	v.pb({p,node}) ;
	            	used[node]=1 ;
	            	unt[p]++ ;
	            	unt[node]++ ;
	            	depth[node]=depth[p]+1 ;
	            	if(i==x-1)
	            	{
	            		leaf[node]=1 ;
	            	}
	            	p=node ;
	            	node++ ;
	            }
	         }
	         int flg=1 ;
	         for(int i=2;i<=n;i++)
	         {
	         	int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node==n+1)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  for(int j=depth[i];j<mx && node<n+1;j++)
	         			  {
	         			  	v.pb({p,node}) ;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==mx)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	         }
	         for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	      else
	      {
	         x=diam/2 ;
	         int p=1 ;
	         node=2 ;
	         int flg=1 ;
	         int cnt=2 ;
	         while(cnt--)
	         {
	         	p=1 ;
	         for(int i=1;i<=x;i++)
	         {
	         	v.pb({p,node}) ;
	         	used[node]=1 ;
	         	if(i==x)
	         	{
	         		leaf[node]=1  ;
	         	}
	         	unt[p]++ ;
	         	unt[node]++ ;
	         	depth[node]=depth[p]+1 ;
	         	p=node ;
	         	mx=max(mx,depth[node]) ;
	         	node++ ;
	         }
	        }
	        for(int i=1;i<=n;i++)
	        {
	           int rem=deg-unt[i] ;
	         	//cout<<i<<" "<<rem<<endl;
	         	if(node==n+1)
	         		break ;
	         	if(rem>0)
	         	{
	         		if(used[i]==1 && leaf[i]!=1)
	         		{
	         			while(rem-- && node<n+1)
	         			{
	         			  int p=i ;
	         			  for(int j=depth[i];j<mx && node<n+1;j++)
	         			  {
	         			  	v.pb({p,node}) ;
	         			  	used[node]=1 ;
	         			  	unt[p]++ ;
	         			  	unt[node]++ ;
	         			  	depth[node]=depth[p]+1 ;
	         			  	if(j==mx)
	         			  	{
	         			  		leaf[node]=1 ;
	         			  	}
	         			  	p=node ;
	         			  	node++ ;
	         			  }
	         			}
	         		}
	         	}
	        }
	        for(int j=1;j<=n;j++)
	         {
	         	if(!used[j])
	         		flg=0 ;
	         }
	         if(!flg)
	         {
	         	cout<<"NO\n"  ;
	         }
	         else
	         {
	         	cout<<"YES\n" ;
	         	for(int m=0;m<v.size();m++)
	         	{
	         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
	         	}
	         }
	      }
	   }
	}


#include <bits/stdc++.h>
using namespace std ;
#define ll long long int
#define pb push_back
#define ff first
#define dobara(i,a,b) for(int (i) = (a); (i) < (b); (i)++)
#define ss second
#define S(x) scanf("%d",&x)
#define SL(x) scanf("%lld",&x)
#define M 1000000007
#define sz(x) (int)x.size()
#define all(a) (a).begin(),(a).end()
int depth[400005] , used[400005] , leaf[400005] , unt[400005] ;
int main()
{
   int n , diam , deg ;
   cin>>n>>diam>>deg ;
   if(deg==1)
   {
   	  if(diam==n-1)
   	  {
   	  	 cout<<"YES\n" ;
   	  	 for(int i=1;i<=n-1;i++)
   	  	 {
   	  	 	cout<<i<<" "<<i+1<<"\n" ;
   	  	 }
   	  }
   	  else
   	  {
   	  	cout<<"NO\n" ;
   	  }
   }
   else
   {
   	  vector<pair<int,int> > v  ;
   	  depth[1]=1 ;
   	  int node=1 ;
   	  int mx=1 ;
   	  used[1]=1 ;
   	  int x ;
      if(diam%2)
      {
          x=(diam)/2 +1 ;
         for(int i=2;i<=1+x;i++)
         {
         	v.pb({i-1,i}) ;
         	unt[i]++ ;
         	unt[i-1]++ ;
         	depth[i]=depth[i-1]+1 ;
         	mx=max(mx,depth[i]) ;
         	used[i]=1 ;
         }
         leaf[1+x]=1 ;
         node=1+x+1 ;
         int d=deg-1  ;
         while(d--)
         {
            //node++ ;
            int p=1 ;
            for(int i=1;i<=x-1;i++)
            {
            	v.pb({p,node}) ;
            	used[node]=1 ;
            	unt[p]++ ;
            	unt[node]++ ;
            	depth[node]=depth[p]+1 ;
            	if(i==x-1)
            	{
            		leaf[node]=1 ;
            	}
            	p=node ;
            	node++ ;
            }
         }
         int flg=1 ;
         for(int i=2;i<=n;i++)
         {
         	int rem=deg-unt[i] ;
         	//cout<<i<<" "<<rem<<endl;
         	if(node==n+1)
         		break ;
         	if(rem>0)
         	{
         		if(used[i]==1 && leaf[i]!=1)
         		{
         			while(rem-- && node<n+1)
         			{
         			  int p=i ;
         			  for(int j=depth[i];j<mx && node<n+1;j++)
         			  {
         			  	v.pb({p,node}) ;
         			  	used[node]=1 ;
         			  	unt[p]++ ;
         			  	unt[node]++ ;
         			  	depth[node]=depth[p]+1 ;
         			  	if(j==mx)
         			  	{
         			  		leaf[node]=1 ;
         			  	}
         			  	p=node ;
         			  	node++ ;
         			  }
         			}
         		}
         	}
         }
         for(int j=1;j<=n;j++)
         {
         	if(!used[j])
         		flg=0 ;
         }
         if(!flg)
         {
         	cout<<"NO\n"  ;
         }
         else
         {
         	cout<<"YES\n" ;
         	for(int m=0;m<v.size();m++)
         	{
         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
         	}
         }
      }
      else
      {
         x=diam/2 ;
         int p=1 ;
         node=2 ;
         int flg=1 ;
         int cnt=2 ;
         while(cnt--)
         {
         	p=1 ;
         for(int i=1;i<=x;i++)
         {
         	v.pb({p,node}) ;
         	used[node]=1 ;
         	if(i==x)
         	{
         		leaf[node]=1  ;
         	}
         	unt[p]++ ;
         	unt[node]++ ;
         	depth[node]=depth[p]+1 ;
         	p=node ;
         	mx=max(mx,depth[node]) ;
         	node++ ;
         }
        }
        for(int i=1;i<=n;i++)
        {
           int rem=deg-unt[i] ;
         	//cout<<i<<" "<<rem<<endl;
         	if(node==n+1)
         		break ;
         	if(rem>0)
         	{
         		if(used[i]==1 && leaf[i]!=1)
         		{
         			while(rem-- && node<n+1)
         			{
         			  int p=i ;
         			  for(int j=depth[i];j<mx && node<n+1;j++)
         			  {
         			  	v.pb({p,node}) ;
         			  	used[node]=1 ;
         			  	unt[p]++ ;
         			  	unt[node]++ ;
         			  	depth[node]=depth[p]+1 ;
         			  	if(j==mx)
         			  	{
         			  		leaf[node]=1 ;
         			  	}
         			  	p=node ;
         			  	node++ ;
         			  }
         			}
         		}
         	}
        }
        for(int j=1;j<=n;j++)
         {
         	if(!used[j])
         		flg=0 ;
         }
         if(!flg)
         {
         	cout<<"NO\n"  ;
         }
         else
         {
         	cout<<"YES\n" ;
         	for(int m=0;m<v.size();m++)
         	{
         		cout<<v[m].ff<<" "<<v[m].ss<<"\n" ;
         	}
         }
      }
   }
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int N, D, K;
vector<int> dist;
queue<int> q;
vector<vector<int>> adj;

void add_edge(int a, int b) {
    adj[a].push_back(b);
    adj[b].push_back(a);
}

void bfs() {
    for (int i = 0; i <= D; i++) {
        dist.push_back(D / 2 - min(i, D - i));
        q.push(i);

        if (i < D)
            add_edge(i, i + 1);
    }

    while (!q.empty()) {
        int current = q.front();
        q.pop();

        if (dist[current] >= D / 2)
            continue;

        while ((int) adj[current].size() < K && (int) dist.size() < N) {
            int neighbor = dist.size();
            dist.push_back(dist[current] + 1);
            add_edge(current, neighbor);
            q.push(neighbor);
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> N >> D >> K;
    adj.resize(N);
    bfs();

    if ((int) dist.size() != N) {
        cout << "NO" << '\n';
        return 0;
    }

    cout << "YES" << '\n';

    for (int i = 0; i < N; i++)
        for (int neighbor : adj[i])
            if (i < neighbor)
                cout << i + 1 << ' ' << neighbor + 1 << '\n';

    return 0;
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int N, D, K;
vector<int> dist;
queue<int> q;
vector<vector<int>> adj;

void add_edge(int a, int b) {
    adj[a].push_back(b);
    adj[b].push_back(a);
}

void bfs() {
    dist.push_back(0);
    q.push(0);

    // Add two sources when D is odd.
    if (D % 2 == 1 && N > 1) {
        dist.push_back(0);
        add_edge(0, 1);
        q.push(1);
    }

    while (!q.empty()) {
        int current = q.front();
        q.pop();

        if (dist[current] >= D / 2)
            continue;

        while ((int) adj[current].size() < K && (int) dist.size() < N) {
            int neighbor = dist.size();
            dist.push_back(dist[current] + 1);
            add_edge(current, neighbor);
            q.push(neighbor);
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> N >> D >> K;
    adj.resize(N);
    bfs();

    if ((int) dist.size() < N) {
        cout << "NO" << '\n';
        return 0;
    }

    cout << "YES" << '\n';

    for (int i = 0; i < N; i++)
        for (int neighbor : adj[i])
            if (i < neighbor)
                cout << i + 1 << ' ' << neighbor + 1 << '\n';

    return 0;
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int N, D, K;
vector<int> dist;
queue<int> q;
vector<vector<int>> adj;

void add_edge(int a, int b) {
    adj[a].push_back(b);
    adj[b].push_back(a);
}

void bfs() {
    if (D > N - 1)
        return;

    for (int i = 0; i <= D; i++) {
        dist.push_back(D / 2 - min(i, D - i));
        q.push(i);

        if (i < D)
            add_edge(i, i + 1);
    }

    while (!q.empty()) {
        int current = q.front();
        q.pop();

        if (dist[current] >= D / 2)
            continue;

        while ((int) adj[current].size() < K && (int) dist.size() < N) {
            int neighbor = dist.size();
            dist.push_back(dist[current] + 1);
            add_edge(current, neighbor);
            q.push(neighbor);
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> N >> D >> K;
    adj.resize(N);
    bfs();

    if ((int) dist.size() != N) {
        cout << "NO" << '\n';
        return 0;
    }

    cout << "YES" << '\n';

    for (int i = 0; i < N; i++)
        for (int neighbor : adj[i])
            if (i < neighbor)
                cout << i + 1 << ' ' << neighbor + 1 << '\n';

    return 0;
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int N, D, K;
vector<int> dist;
queue<int> q;
vector<vector<int>> adj;

void add_edge(int a, int b) {
    adj[a].push_back(b);
    adj[b].push_back(a);
}

void bfs() {
    if (D > N - 1)
        return;

    if (K == 1 && D > 1)
        return;

    for (int i = 0; i <= D; i++) {
        dist.push_back(D / 2 - min(i, D - i));
        q.push(i);

        if (i < D)
            add_edge(i, i + 1);
    }

    while (!q.empty()) {
        int current = q.front();
        q.pop();

        if (dist[current] >= D / 2)
            continue;

        while ((int) adj[current].size() < K && (int) dist.size() < N) {
            int neighbor = dist.size();
            dist.push_back(dist[current] + 1);
            add_edge(current, neighbor);
            q.push(neighbor);
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> N >> D >> K;
    adj.resize(N);
    bfs();

    if ((int) dist.size() != N) {
        cout << "NO" << '\n';
        return 0;
    }

    cout << "YES" << '\n';

    for (int i = 0; i < N; i++)
        for (int neighbor : adj[i])
            if (i < neighbor)
                cout << i + 1 << ' ' << neighbor + 1 << '\n';

    return 0;
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int N, D, K;
vector<int> dist;
queue<int> q;
vector<vector<int>> adj;

void add_edge(int a, int b) {
    adj[a].push_back(b);
    adj[b].push_back(a);
}

bool bfs() {
    if (D > N - 1)
        return false;

    if (K == 1 && D > 1)
        return false;

    adj.resize(N);

    for (int i = 0; i <= D; i++) {
        dist.push_back(D / 2 - min(i, D - i));
        q.push(i);

        if (i < D)
            add_edge(i, i + 1);
    }

    while (!q.empty()) {
        int current = q.front();
        q.pop();

        if (dist[current] >= D / 2)
            continue;

        while ((int) adj[current].size() < K && (int) dist.size() < N) {
            int neighbor = dist.size();
            dist.push_back(dist[current] + 1);
            add_edge(current, neighbor);
            q.push(neighbor);
        }
    }

    return (int) dist.size() == N;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> N >> D >> K;

    if (!bfs()) {
        cout << "NO" << '\n';
        return 0;
    }

    cout << "YES" << '\n';

    for (int i = 0; i < N; i++)
        for (int neighbor : adj[i])
            if (i < neighbor)
                cout << i + 1 << ' ' << neighbor + 1 << '\n';

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define MX 400005
#define MOD 1000000007
#define LL long long int
#define PII pair<int,int>
#define PBB pair<bool,bool>
vector<int>v[MX];
int n,d,k,tot;

PBB rec(int s,int myl,int reml)
{
    //cout<<s<<" "<<myl<<" "<<reml<<endl;
    if(reml<=0 && tot==n) return  PBB({true,true});
    else if(reml<=0) return PBB({true,false});
    else if(tot==n) return  PBB({false,true});

    bool flag1 = false,flag2 = false;
    if(s==1)
    {
        tot++;
        v[s].push_back(tot);
        PBB pb = rec(tot,myl+1,reml-1);
        flag1 |= pb.first;
        flag2 |= pb.second;
    }
    else
    {
        bool f = true;
        for(int i=1; i<k; i++)
        {
            if(tot==n)
            {
                flag2 |= true;
                break;
            }

            tot++;
            v[s].push_back(tot);

            if(f)
            {
                PBB pb = rec(tot,myl+1,reml-1);
                flag1 |= pb.first;
                flag2 |= pb.second;
                f = false;
            }
            else
            {
                int x = (d/2);
                PBB pb;
                if(myl<=x)  pb = rec(tot,myl+1,myl-1);
                else if(myl==(x+(d%2))) pb = rec(tot,myl+1,myl-2);
                else    pb = rec(tot,myl+1,d-myl-1);

                flag1 |= pb.first;
                flag2 |= pb.second;
            }
        }
    }
    return  PBB({flag1,flag2});
}

int main()
{
    cin >> n >> d >> k;
    tot = 1;
    PBB pb = rec(1,0,d);
    if(pb.first && pb.second)
    {
        puts("YES");
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<(int)v[i].size(); j++)
            {
                printf("%d %d\n",i,v[i][j]);
            }
        }
    }
    else    puts("NO");
    return  0;
}


#include<bits/stdc++.h>
using namespace std;

#define MX 400005
#define MOD 1000000007
#define LL long long int
#define PII pair<int,int>
vector<int>v[MX];
int n,d,k,tot;

void rec(int s,int l)
{
    if(!l || tot>=n)  return;
    if(s==1)
    {
        tot++;
        v[s].push_back(tot);
        rec(2,l-1);
    }
    else
    {
        bool f = true;
        for(int i=1; i<=k; i++)
        {
            if(tot>=n)  break;
            tot++;
            v[s].push_back(tot);
            if(f)   rec(tot,l-1);
            else    rec(tot,d-l);
        }
    }
    return;
}

int main()
{
    cin >> n >> d >> k;
    /*LL x = (d-1)*k;
    x += 2;
    cout<<x<<endl;
    if(x<n)
    {
        puts("NO");
        exit(0);
    }*/

    //solve();
    tot = 1;
    rec(1,d);
    if(tot>=n)
    {
        puts("YES");
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<(int)v[i].size(); j++)
            {
                printf("%d %d\n",i,v[i][j]);
            }
        }
    }
    else    puts("NO");
    return  0;
}


#include<bits/stdc++.h>
using namespace std;

#define MX 400005
#define MOD 1000000007
#define LL long long int
#define PII pair<int,int>
#define PBB pair<bool,bool>
vector<int>v[MX];
int n,d,k,tot;

PBB rec(int s,int myl,int reml,bool subBranch)
{
    //cout<<s<<" "<<myl<<" "<<reml<<endl;
    if(reml<=0 && tot==n) return  PBB({true,true});
    else if(reml<=0) return PBB({true,false});
    else if(tot==n) return  PBB({false,true});

    bool flag1 = false,flag2 = false;
    if(s==1)
    {
        tot++;
        v[s].push_back(tot);
        PBB pb = rec(tot,myl+1,reml-1,false);
        flag1 |= pb.first;
        flag2 |= pb.second;
    }
    else
    {
        bool f = true;
        for(int i=1; i<k; i++)
        {
            if(tot==n)
            {
                flag2 |= true;
                break;
            }

            tot++;
            v[s].push_back(tot);

            if(subBranch)
            {
                PBB pb = rec(tot,myl+1,reml-1,true);
                flag1 |= pb.first;
                flag2 |= pb.second;
            }
            else
            {
                if(f)
                {
                    PBB pb = rec(tot,myl+1,reml-1,false);
                    flag1 |= pb.first;
                    flag2 |= pb.second;
                    f = false;
                }
                else
                {
                    int x = (d/2);
                    PBB pb;
                    if(myl<=x)  pb = rec(tot,myl+1,myl-1,true);
                    else if(myl==(x+(d%2))) pb = rec(tot,myl+1,myl-2,true);
                    else    pb = rec(tot,myl+1,d-myl-1,true);

                    flag1 |= pb.first;
                    flag2 |= pb.second;
                }
            }
        }
    }
    return  PBB({flag1,flag2});
}

int main()
{
    cin >> n >> d >> k;
    tot = 1;
    PBB pb = rec(1,0,d,false);
    if(pb.first && pb.second)
    {
        puts("YES");
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<(int)v[i].size(); j++)
            {
                printf("%d %d\n",i,v[i][j]);
            }
        }
    }
    else    puts("NO");
    return  0;
}


#include<bits/stdc++.h>
using namespace std;

#define MX 400005
#define MOD 1000000007
#define LL long long int
#define PII pair<int,int>
vector<int>v[MX];
int n,d,k,tot;

void rec(int s,int myl,int reml)
{
    //cout<<s<<" "<<myl<<" "<<reml<<endl;
    if(reml<=0 || tot>=n)   return;
    else if(s==1)
    {
        tot++;
        v[s].push_back(tot);
        rec(tot,myl+1,reml-1);
    }
    else
    {
        bool f = true;
        for(int i=1; i<k; i++)
        {
            if(tot>=n)  break;

            tot++;
            v[s].push_back(tot);

            if(f)
            {
                rec(tot,myl+1,reml-1);
                f = false;
            }
            else
            {
                int x = (d/2);
                if(myl<=x)  rec(tot,myl+1,myl-1);
                else if(myl==(x+(d%2))) rec(tot,myl+1,myl-2);
                else    rec(tot,myl+1,d-myl-1);
            }
        }
    }
    return;
}

int main()
{
    cin >> n >> d >> k;
    tot = 1;
    rec(1,0,d);
    if(tot>=n)
    {
        puts("YES");
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<(int)v[i].size(); j++)
            {
                printf("%d %d\n",i,v[i][j]);
            }
        }
    }
    else    puts("NO");
    return  0;
}


#include<bits/stdc++.h>
using namespace std;

#define MX 400005
#define MOD 1000000007
#define LL long long int
#define PII pair<int,int>
vector<int>v[MX];
int n,d,k,tot;

bool rec(int s,int l)
{
    if(!l || tot>=n)  return    false;
    if(s==1)
    {
        tot++;
        v[s].push_back(tot);
        rec(2,l-1);
    }
    else
    {

        bool f = true,g = true;
        for(int i=1; i<k; i++)
        {
            if(tot>=n)  break;
            tot++;
            v[s].push_back(tot);

            if(f)   rec(tot,l-1);
            else if((l-1)!=0)    rec(tot,d-l);
            f = false;
        }
    }
    return  true;
}

int main()
{
    cin >> n >> d >> k;
    /*LL x = (d-1)*k;
    x += 2;
    cout<<x<<endl;
    if(x<n)
    {
        puts("NO");
        exit(0);
    }*/

    //solve();
    tot = 1;
    rec(1,d);
    if(tot>=n)
    {
        puts("YES");
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<(int)v[i].size(); j++)
            {
                printf("%d %d\n",i,v[i][j]);
            }
        }
    }
    else    puts("NO");
    return  0;
}


#include<bits/stdc++.h>
using namespace std;

#define MX 400005
#define MOD 1000000007
#define LL long long int
#define PII pair<int,int>
vector<LL>v[MX];
LL n,d,k,tot;

void rec(LL s,LL l)
{
    if(!l || tot>=n)  return;
    if(s==1)
    {
        tot++;
        v[s].push_back(tot);
        rec(2,l-1);
    }
    else
    {
        bool f = true;
        for(LL i=1; i<=k; i++)
        {
            if(tot>=n)  break;
            tot++;
            v[s].push_back(tot);
            if(f)   rec(tot,l-1);
            else    rec(tot,d-l);
        }
    }
    return;
}

int main()
{
    cin >> n >> d >> k;
    /*LL x = (d-1)*k;
    x += 2;
    cout<<x<<endl;
    if(x<n)
    {
        puts("NO");
        exit(0);
    }*/

    //solve();
    tot = 1;
    rec(1,d);
    if(tot>=n)
    {
        puts("YES");
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<(int)v[i].size(); j++)
            {
                printf("%lld %lld\n",i,v[i][j]);
            }
        }
    }
    else    puts("NO");
    return  0;
}


#include<bits/stdc++.h>
using namespace std;

#define MX 400005
#define MOD 1000000007
#define LL long long int
#define PII pair<int,int>
vector<int>v[MX];
int n,d,k,tot;

void rec(int s,int l,bool mxl)
{
    //cout<<s<<" fuck "<<l<<" "<<mxl<<endl;
    if(l<=0 || tot>=n)    return;
    if(s==1)
    {
        tot++;
        v[s].push_back(tot);
        rec(2,l-1,true);
    }
    else
    {
        bool f = true;
        for(int i=1; i<k; i++)
        {
            if(tot>=n)  break;
            if(f)
            {
                tot++;
                v[s].push_back(tot);
                rec(tot,l-1,true);
            }
            else if(min(d-l,l-1))
            {
                tot++;
                v[s].push_back(tot);
                rec(tot,min(d-l,l-1),false);
            }
            else if(min(d-l,l-1)==0 && mxl)
            {
                tot++;
                v[s].push_back(tot);
            }
            f = false;
        }
    }
    return;
}

int main()
{
    cin >> n >> d >> k;
    tot = 1;
    rec(1,d,true);
    if(tot>=n)
    {
        puts("YES");
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<(int)v[i].size(); j++)
            {
                printf("%d %d\n",i,v[i][j]);
            }
        }
    }
    else    puts("NO");
    return  0;
}


#include<bits/stdc++.h>
using namespace std;

#define MX 400005
#define MOD 1000000007
#define LL long long int
#define PII pair<int,int>
vector<LL>v[MX];
LL n,d,k,tot;

void rec(LL s,LL l)
{
    if(!l || tot>=n)  return;
    if(s==1)
    {
        tot++;
        v[s].push_back(tot);
        rec(2,l-1);
    }
    else
    {
        bool f = true;
        for(LL i=1; i<=k; i++)
        {
            if(tot>=n)  break;
            tot++;
            v[s].push_back(tot);
            if(f)   rec(tot,l-1);
            else    rec(tot,d-l);
        }
    }
    return;
}

int main()
{
    cin >> n >> d >> k;
    /*LL x = (d-1)*k;
    x += 2;
    cout<<x<<endl;
    if(x<n)
    {
        puts("NO");
        exit(0);
    }*/

    //solve();
    tot = 1;
    rec(1,d);
    if(tot>=n)
    {
        puts("YES");
        for(LL i=1; i<=n; i++)
        {
            for(LL j=0; j<(int)v[i].size(); j++)
            {
                printf("%lld %lld\n",i,v[i][j]);
            }
        }
    }
    else    puts("NO");
    return  0;
}


#include<bits/stdc++.h>
using namespace std;

#define MX 400005
#define MOD 1000000007
#define LL long long int
#define PII pair<int,int>
vector<int>v[MX];
int n,d,k,tot;

void rec(int s,int l)
{
    if(!l || tot>=n)    return;
    if(s==1)
    {
        tot++;
        v[s].push_back(tot);
        rec(2,l-1);
    }
    else
    {
        bool f = true;
        for(int i=1; i<k; i++)
        {
            if(tot>=n)  break;
            tot++;
            v[s].push_back(tot);

            if(f)   rec(tot,l-1);
            else    rec(tot,min(d-l,l-1));
            f = false;
        }
    }
    return;
}

int main()
{
    cin >> n >> d >> k;
    tot = 1;
    rec(1,d);
    if(tot>=n)
    {
        puts("YES");
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<(int)v[i].size(); j++)
            {
                printf("%d %d\n",i,v[i][j]);
            }
        }
    }
    else    puts("NO");
    return  0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define forn(i,n) for(int (i)=0;(i)<(n);(i)++)
#define F first
#define S second
#define pi pair<int,int>
#define pll pair<ll,ll>
#define all(x) (x).begin(),(x).end()
#define fill(x,a) fill((x).begin(),(x).end(),(a))
#define setbitcount __builtin_popcount
#define isodd __builtin_parity
#define clz __builtin_clz
#define ctz __builtin_ctz
#define pque priority_queue
#define vi vector<int>
#define vvi vector<vector<int>>
#define vll vector<ll>
#define vvll vector<vector<ll>>
#define vpi vector<pi>
#define vvpi vector<vector<pi>>
#define vpll vector<pll>
#define vvpll vector<vector<pll>>
#define pb push_back
#define mp make_pair
#define pln cout<<"\n";
#define endl "\n"
#define OPTIMISED ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
using namespace __gnu_pbds;
mt19937 rng32(chrono::steady_clock::now().time_since_epoch().count());
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> pbds;
typedef  long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ll inf9=1e9,inf18=1e18,inf6=1e6,inf14=1e14;
const ll mod7=inf9+7,mod9=inf9+9;
const int modi=998244353;
clock_t time_p=clock();
void clk()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
int n,d,k;
vpi edges;
int add(int v,int last,int rem,int deg)
{
	if(rem==0)return last;
	forn(i,deg)
	{
		edges.pb(mp(v,last+1));
		last++;
		last=add(last,last,rem-1,k-1);
	}
	return last;
}
int main()
{
	OPTIMISED
	cin>>n>>d>>k;
	if(n==1)
	{
		if(d==0)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
		return 0;
	}
	if(n==2)
	{
		if(k>=1 && d==1){cout<<"YES"<<endl;cout<<"1 2"<<endl;}
		else cout<<"NO"<<endl;
		return 0;
	}
	if(d>n-1)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	for(int i=1;i<=d;i++)
	{
		edges.pb(mp(i,i+1));
	}
	int last=d+1;
	for(int i=2;i<=d;i++)
	{
		if(last>n)break;
		int maxlevel=min(i-1,d+1-i);
		last=add(i,last,maxlevel,k-2);
	}
	if(last<n)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	cout<<"YES"<<endl;
	for(auto it:edges){if(it.F<=n && it.S<=n)cout<<it.F<<" "<<it.S<<endl;}
	clk();
    return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define forn(i,n) for(int (i)=0;(i)<(n);(i)++)
#define F first
#define S second
#define pi pair<int,int>
#define pll pair<ll,ll>
#define all(x) (x).begin(),(x).end()
#define fill(x,a) fill((x).begin(),(x).end(),(a))
#define setbitcount __builtin_popcount
#define isodd __builtin_parity
#define clz __builtin_clz
#define ctz __builtin_ctz
#define pque priority_queue
#define vi vector<int>
#define vvi vector<vector<int>>
#define vll vector<ll>
#define vvll vector<vector<ll>>
#define vpi vector<pi>
#define vvpi vector<vector<pi>>
#define vpll vector<pll>
#define vvpll vector<vector<pll>>
#define pb push_back
#define mp make_pair
#define pln cout<<"\n";
#define endl "\n"
#define OPTIMISED ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
using namespace __gnu_pbds;
mt19937 rng32(chrono::steady_clock::now().time_since_epoch().count());
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> pbds;
typedef  long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ll inf9=1e9,inf18=1e18,inf6=1e6,inf14=1e14;
const ll mod7=inf9+7,mod9=inf9+9;
const int modi=998244353;
clock_t time_p=clock();
void clk()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
int n,d,k;
vpi edges;
int add(int v,int last,int rem,int deg)
{
	if(rem==0 || deg<=0)return last;
	forn(i,deg)
	{
		if(last>n)break;
		edges.pb(mp(v,last+1));
		last++;
		last=add(last,last,rem-1,k-1);
	}
	return last;
}
int main()
{
	OPTIMISED
	cin>>n>>d>>k;
	if(n==1)
	{
		if(d==0)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
		return 0;
	}
	if(n==2)
	{
		if(k>=1 && d==1){cout<<"YES"<<endl;cout<<"1 2"<<endl;}
		else cout<<"NO"<<endl;
		return 0;
	}
	if(1ll*n*k<1ll*(2*(n-1)))
	{
		cout<<"NO"<<endl;
		return 0;
	}
	if(d>n-1)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	for(int i=1;i<=d;i++)
	{
		edges.pb(mp(i,i+1));
	}
	int last=d+1;
	for(int i=2;i<=d;i++)
	{
		if(last>n)break;
		int maxlevel=min(i-1,d+1-i);
		last=add(i,last,maxlevel,k-2);
	}
	if(last<n)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	cout<<"YES"<<endl;
	for(auto it:edges){if(it.F<=n && it.S<=n)cout<<it.F<<" "<<it.S<<endl;}
	clk();
    return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define forn(i,n) for(int (i)=0;(i)<(n);(i)++)
#define F first
#define S second
#define pi pair<int,int>
#define pll pair<ll,ll>
#define all(x) (x).begin(),(x).end()
#define fill(x,a) fill((x).begin(),(x).end(),(a))
#define setbitcount __builtin_popcount
#define isodd __builtin_parity
#define clz __builtin_clz
#define ctz __builtin_ctz
#define pque priority_queue
#define vi vector<int>
#define vvi vector<vector<int>>
#define vll vector<ll>
#define vvll vector<vector<ll>>
#define vpi vector<pi>
#define vvpi vector<vector<pi>>
#define vpll vector<pll>
#define vvpll vector<vector<pll>>
#define pb push_back
#define mp make_pair
#define pln cout<<"\n";
#define endl "\n"
#define OPTIMISED ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
using namespace __gnu_pbds;
mt19937 rng32(chrono::steady_clock::now().time_since_epoch().count());
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> pbds;
typedef  long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ll inf9=1e9,inf18=1e18,inf6=1e6,inf14=1e14;
const ll mod7=inf9+7,mod9=inf9+9;
const int modi=998244353;
clock_t time_p=clock();
void clk()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
int n,d,k;
vpi edges;
int add(int v,int last,int rem,int deg)
{
	if(rem==0)return last;
	forn(i,deg)
	{
		edges.pb(mp(v,last+1));
		last++;
		last=add(last,last,rem-1,k-1);
	}
	return last;
}
int main()
{
	OPTIMISED
	cin>>n>>d>>k;
	if(n==1)
	{
		if(d==0)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
		return 0;
	}
	if(n==2)
	{
		if(k>=1 && d==1){cout<<"YES"<<endl;cout<<"1 2"<<endl;}
		else cout<<"NO"<<endl;
		return 0;
	}
	if(d>n-1)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	for(int i=1;i<=d;i++)
	{
		edges.pb(mp(i,i+1));
	}
	int last=d+1;
	for(int i=2;i<=d;i++)
	{
		int maxlevel=min(i-1,d+1-i);
		last=add(i,last,maxlevel,k-2);
	}
	if(last<n)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	cout<<"YES"<<endl;
	for(auto it:edges){if(it.F<=n && it.S<=n)cout<<it.F<<" "<<it.S<<endl;}
	clk();
    return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define forn(i,n) for(int (i)=0;(i)<(n);(i)++)
#define F first
#define S second
#define pi pair<int,int>
#define pll pair<ll,ll>
#define all(x) (x).begin(),(x).end()
#define fill(x,a) fill((x).begin(),(x).end(),(a))
#define setbitcount __builtin_popcount
#define isodd __builtin_parity
#define clz __builtin_clz
#define ctz __builtin_ctz
#define pque priority_queue
#define vi vector<int>
#define vvi vector<vector<int>>
#define vll vector<ll>
#define vvll vector<vector<ll>>
#define vpi vector<pi>
#define vvpi vector<vector<pi>>
#define vpll vector<pll>
#define vvpll vector<vector<pll>>
#define pb push_back
#define mp make_pair
#define pln cout<<"\n";
#define endl "\n"
#define OPTIMISED ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
using namespace __gnu_pbds;
mt19937 rng32(chrono::steady_clock::now().time_since_epoch().count());
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> pbds;
typedef  long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ll inf9=1e9,inf18=1e18,inf6=1e6,inf14=1e14;
const ll mod7=inf9+7,mod9=inf9+9;
const int modi=998244353;
clock_t time_p=clock();
void clk()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
int n,d,k;
vpi edges;
int add(int v,int last,int rem,int deg)
{
	if(rem==0 || deg<=0)return last;
	forn(i,deg)
	{
		edges.pb(mp(v,last+1));
		last++;
		last=add(last,last,rem-1,k-1);
	}
	return last;
}
int main()
{
	OPTIMISED
	cin>>n>>d>>k;
	if(n==1)
	{
		if(d==0)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
		return 0;
	}
	if(n==2)
	{
		if(k>=1 && d==1){cout<<"YES"<<endl;cout<<"1 2"<<endl;}
		else cout<<"NO"<<endl;
		return 0;
	}
	if(n*k<2*(n-1))
	{
		cout<<"NO"<<endl;
		return 0;
	}
	if(d>n-1)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	for(int i=1;i<=d;i++)
	{
		edges.pb(mp(i,i+1));
	}
	int last=d+1;
	for(int i=2;i<=d;i++)
	{
		if(last>n)break;
		int maxlevel=min(i-1,d+1-i);
		last=add(i,last,maxlevel,k-2);
	}
	if(last<n)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	cout<<"YES"<<endl;
	for(auto it:edges){if(it.F<=n && it.S<=n)cout<<it.F<<" "<<it.S<<endl;}
	clk();
    return 0;
}