#include <bits/stdc++.h>
using namespace std;
struct DSU {
  long long int n;
  vector<long long int> p;
  DSU(long long int N) {
    n = N;
    p.assign(n + 1, -1);
    for (int i = 0; i <= n; i++) p[i] = i;
  }
  long long int Find(long long int src) {
    if (p[src] == src) return src;
    return p[src] = Find(p[src]);
  }
  void Merge(long long int u, long long int v) {
    u = Find(u), v = Find(v);
    if (u != v) p[v] = u;
  }
};
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long int t = 1;
  while (t--) {
    long long int n, m1, m2;
    cin >> n >> m1 >> m2;
    DSU e1(n + 1), e2(n + 1);
    while (m1--) {
      long long int a, b;
      cin >> a >> b;
      e1.Merge(a, b);
    }
    while (m2--) {
      long long int a, b;
      cin >> a >> b;
      e2.Merge(a, b);
    }
    vector<pair<long long int, long long int>> ans;
    for (int i = 1; i <= n; i++) {
      if (e1.Find(1) != e1.Find(i) && e2.Find(1) != e2.Find(i)) {
        ans.push_back({1, i});
        e1.Merge(1, i);
        e2.Merge(1, i);
      }
    }
    long long int l = 1, r = 1;
    while (l <= n && r <= n) {
      while (l <= n && e1.Find(1) == e1.Find(l)) l++;
      while (r <= n && e2.Find(1) == e2.Find(r)) r++;
      if (l > n || r > n) break;
      ans.push_back({l, r});
      e1.Merge(l, r);
      e2.Merge(l, r);
    }
    cout << ans.size() << "\n";
    for (auto [x, y] : ans) cout << x << " " << y << "\n";
  }
  return 0;
}
