#include <bits/stdc++.h>
#pragma GCC optimize(2)
namespace ucp {
template <typename T>
void Min(T& a, T b) {
  if (a > b) a = b;
}
template <typename T>
void Max(T& a, T b) {
  if (a < b) a = b;
}
inline int read() {
  int sign, data = 0;
  char ch = 0;
  while ((ch != '-') && ch < '0' || ch > '9') ch = getchar();
  if (ch == '-') {
    sign = -1;
    ch = getchar();
  } else
    sign = 1;
  while (ch >= '0' && ch <= '9') {
    data = data * 10 + ch - '0';
    ch = getchar();
  }
  return data * sign;
}
inline void print(int x) {
  if (x / 10) print(x / 10);
  putchar(x % 10 + '0');
}
}  // namespace ucp
using namespace std;
using namespace ucp;
const int mxint = 0x3f3f3f3f;
const long long mxll = 1e16;
const int lim = 5e5 + 10;
const int maxn = 1e5 + 10;
const int maxm = 4e5 + 10;
const int N = 3e4 + 1000;
const long long mod = 1e9 + 7;
const double mxdb = 1e18;
const double eps = 1e-7;
int n, d, k;
vector<pair<int, int> > edge;
int tot;
void dfs(int u, int h, int lim) {
  if (h >= lim) return;
  int d;
  if (h == 0)
    d = 2;
  else
    d = 1;
  for (; d < k && tot <= n; ++d) {
    edge.push_back(make_pair(u, ++tot));
    dfs(tot, h + 1, lim);
  }
}
int main() {
  scanf("%d%d%d", &n, &d, &k);
  if (n <= d || (k == 1 && d > 1)) {
    puts("NO");
    return 0;
  }
  tot = 1;
  for (int i = 1; i <= d; ++i) {
    edge.push_back(make_pair(i, i + 1));
    ++tot;
  }
  for (int i = 2; i <= d; ++i) dfs(i, 0, min(i - 1, d - i + 1));
  printf("tot=%d n=%d\n", tot, n);
  if (tot < n) {
    puts("NO");
    return 0;
  }
  puts("YES");
  for (int i = 0; i < edge.size(); ++i) {
    printf("%d %d\n", edge[i].first, edge[i].second);
  }
  return 0;
}
