#include <bits/stdc++.h>
using namespace std;
int n, d, k;
struct Edge {
  int a;
  int b;
};
std::vector<Edge> edges;
struct Node {
  int id;
  int degree;
  int depth;
  int parents;
  std::vector<int> next;
};
Node nodes[400010];
int main() {
  scanf("%d%d%d", &n, &d, &k);
  if (n == 1) {
    if (d == 1)
      printf("YES\n");
    else
      printf("NO\n");
    return 0;
  }
  if (k == 1) {
    if (n == 2 && d == 2) {
      printf("YES\n");
      printf("1 2\n");
    } else
      printf("NO\n");
    return 0;
  }
  if (n < d) {
    printf("NO\n");
    return 0;
  }
  std::queue<int> q;
  edges.clear();
  Edge newEdge;
  for (int i = 1; i <= d - 1; i++) {
    newEdge.a = i;
    newEdge.b = i + 1;
    edges.push_back(newEdge);
    nodes[i].degree = 1;
    nodes[i].id = i;
    nodes[i].depth = i;
    nodes[i].next.push_back(i + 1);
    q.push(i);
  }
  nodes[d].degree = 1;
  nodes[d].id = d;
  nodes[d].depth = d;
  q.push(d);
  for (int i = 2; i <= d - 1; i++) nodes[i].degree++;
  int pNextNode = d + 1;
  int pCurNode;
  while (!q.empty()) {
    pCurNode = q.front();
    q.pop();
    if (nodes[pCurNode].depth >= d) continue;
    while (nodes[pCurNode].degree < k) {
      newEdge.a = pCurNode;
      newEdge.b = pNextNode;
      edges.push_back(newEdge);
      nodes[pCurNode].next.push_back(pNextNode);
      nodes[pCurNode].degree++;
      nodes[pNextNode].id = pNextNode;
      nodes[pNextNode].degree = 1;
      nodes[pNextNode].depth = nodes[pCurNode].depth + 1;
      if (pCurNode != 1) q.push(pNextNode);
      pNextNode++;
      if (pNextNode > n) break;
    }
    if (pNextNode > n) break;
  }
  if (pNextNode > n) {
    printf("YES\n");
    for (int i = 0; i < edges.size(); i++)
      printf("%d %d\n", edges[i].a, edges[i].b);
  } else {
    printf("NO\n");
  }
  return 0;
}
