#include <bits/stdc++.h>
#pragma GCCoptimize(2)
using namespace std;
clock_t C1, C2;
void TIMES() {}
void TIMEE() {}
long long qpow(long long a, long long b, long long mod) {
  long long res = 1;
  while (b) {
    if (b & 1) res = res * a % mod;
    a = a * a % mod;
    b >>= 1;
  }
  return res % mod;
}
void read(int &x) {
  x = 0;
  int f = 1;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = x * 10 + c - '0';
    c = getchar();
  }
  x *= f;
}
const int mod = 1e9 + 7;
const int MOD = 998244353;
const double PI = acos(-1);
const int inf = 0x3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const int M = 2e6 + 20;
const int N = 2e5 + 20;
int n, m1, m2;
struct bing {
  int f[N], num;
  void init() {
    for (int i = 1; i <= n; i++) f[i] = i;
  }
  int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
  bool check(int x, int y) {
    int f1 = find(x), f2 = find(y);
    return f1 == f2;
  }
  void merge(int x, int y) {
    int f1 = find(x), f2 = find(y);
    f[f1] = f2;
    num++;
  }
} G1, G2;
int main() {
  TIMES();
  srand(time(0));
  scanf("%d%d%d", &n, &m1, &m2);
  G1.init();
  G2.init();
  for (int i = 1; i <= m1; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    G1.merge(x, y);
  }
  for (int i = 1; i <= m2; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    G2.merge(x, y);
  }
  int tot = min(n - 1 - m1, n - 1 - m2);
  printf("%d\n", tot);
  queue<int> q1, q2;
  int cnt = 0;
  for (int i = 2; i <= n; i++)
    if (!G1.check(i, 1) && !G2.check(i, 1)) {
      printf("%d %d\n", 1, i);
      G1.merge(1, i);
      G2.merge(1, i);
      cnt++;
    }
  for (int i = 2; i <= n; i++) {
    bool t1 = G1.check(1, i), t2 = G2.check(1, i);
    if (!t1 && t2)
      q1.push(i);
    else if (t1 && !t2)
      q2.push(i);
  }
  for (int i = 1; i <= tot - cnt; i++) {
    while (!q1.empty() && G1.check(q1.front(), 1)) q1.pop();
    while (!q2.empty() && G2.check(q2.front(), 1)) q2.pop();
    if (q1.empty() || q2.empty()) break;
    printf("%d %d\n", q1.front(), q2.front());
    G1.merge(q1.front(), q2.front());
    G2.merge(q2.front(), q1.front());
    q1.pop();
    q2.pop();
  }
end:
  TIMEE();
  return 0;
}
