#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int tc, n, m1, m2, Par[N], Par1[N];
int find_set(int v) { return v == Par[v] ? v : Par[v] = find_set(Par[v]); }
int find_set1(int v) { return v == Par1[v] ? v : Par1[v] = find_set1(Par1[v]); }
void union_sets(int a, int b) {
  a = find_set(a);
  b = find_set(b);
  if (a > b) swap(a, b);
  Par[b] = a;
}
void union_sets1(int a, int b) {
  a = find_set1(a);
  b = find_set1(b);
  if (a > b) swap(a, b);
  Par1[b] = a;
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(0);
  cin >> n >> m1 >> m2;
  for (int i = 1; i <= n; i++) Par[i] = Par1[i] = i;
  while (m1--) {
    int u, v;
    cin >> u >> v;
    union_sets(u, v);
  }
  while (m2--) {
    int u, v;
    cin >> u >> v;
    union_sets1(u, v);
  }
  vector<pair<int, int>> Ans;
  for (int i = 2; i <= n; i++) {
    int u = find_set(i), v = find_set1(i);
    if (u != 1 && v != 1) {
      Ans.push_back({1, i});
      Par[u] = Par1[v] = 1;
    }
  }
  vector<int> First, Second;
  for (int i = 2; i <= n; i++) {
    int u = find_set(i), v = find_set1(i);
    if (u == i) First.push_back(i);
    if (v == i) Second.push_back(i);
  }
  int mn = min(First.size(), Second.size());
  cout << Ans.size() + mn << "\n";
  for (auto i : Ans) cout << i.first << " " << i.second << "\n";
  for (int i = 0; i < mn; i++) {
    cout << First[i] << " " << Second[i] << "\n";
  }
  return 0;
}
