#include using namespace std; int N, M, K; vector> keep; void print_no() { cout << "No\n"; } void print_yes() { cout << "Yes\n"; for (int u = 1; u <= N; ++u) { for (int v = u + 1; v <= N; ++v) { if (!keep[u][v]) { cout << u << ' ' << v << '\n'; } } } } int main() { cin >> N >> M >> K; int T = N * (N - 1) / 2; int E = T - M; // number of edges to keep keep.assign(N + 1, vector(N + 1, false)); if (K == 1) { if (E == 0) { print_no(); return 0; } keep[1][N] = true; E--; for (int u = 1; u <= N && E > 0; ++u) { for (int v = u + 1; v <= N && E > 0; ++v) { if (u == 1 && v == N) continue; keep[u][v] = true; E--; } } print_yes(); return 0; } // K >= 2. int U = N - K - 1; int min_keep = K; // WRONG: // Extra vertices are connected only to 1 and 2. // The correct upper bound should be K + 3*U + U*(U-1)/2. int max_keep = K + 2 * U + U * (U - 1) / 2; if (!(min_keep <= E && E <= max_keep)) { print_no(); return 0; } // Keep the mandatory path 1 - 2 - ... - K - N. for (int i = 1; i < K; ++i) { keep[i][i + 1] = true; E--; } keep[K][N] = true; E--; vector> free_edges; // WRONG: // Each extra vertex is connected only to 1 and 2. // It should be connectable to up to three consecutive path vertices. for (int x = K + 1; x <= N - 1; ++x) { free_edges.push_back({1, x}); free_edges.push_back({2, x}); } // Extra vertices can be connected freely among themselves. for (int x = K + 1; x <= N - 1; ++x) { for (int y = x + 1; y <= N - 1; ++y) { free_edges.push_back({x, y}); } } for (auto [u, v] : free_edges) { if (E == 0) break; keep[u][v] = true; E--; } print_yes(); return 0; }