#include <bits/stdc++.h>
using namespace std;
long long find(long long x, vector<long long> &par) {
  if (par[x] == -1) {
    return x;
  }
  par[x] = find(par[x], par);
  return par[x];
}
void unite(long long x, long long y, vector<long long> &par,
           vector<long long> &rank) {
  long long p_x = find(x, par), p_y = find(y, par);
  if (rank[p_x] < rank[p_y]) {
    par[p_x] = p_y;
  } else {
    par[p_y] = p_x;
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  long long n, m1, m2;
  long long u, v, sum = 0;
  vector<long long> par1, par2, rank1, rank2;
  vector<pair<long long, long long>> res;
  cin >> n >> m1 >> m2;
  par1.resize(n, -1);
  par2.resize(n, -1);
  rank1.resize(n, 1);
  rank2.resize(n, 1);
  for (int i = 0; i < m1; i++) {
    cin >> u >> v;
    u--;
    v--;
    unite(u, v, par1, rank1);
  }
  for (int i = 0; i < m2; i++) {
    cin >> u >> v;
    u--;
    v--;
    unite(u, v, par2, rank2);
  }
  vector<long long> left, right;
  for (int i = 1; i < n; i++) {
    if (find(0, par1) != find(i, par1) && find(0, par2) != find(i, par2)) {
      unite(0, i, par1, rank1);
      unite(0, i, par2, rank2);
      res.push_back(make_pair(1, i + 1));
    } else if (find(0, par1) != find(i, par1)) {
      left.push_back(i);
    } else if (find(0, par2) != find(i, par2)) {
      right.push_back(i);
    }
  }
  while (left.size() > 0 && right.size() > 0) {
    long long i = left.size() - 1;
    long long j = right.size() - 1;
    if (find(left[i], par1) == find(0, par1)) {
      left.pop_back();
    } else if (find(right[j], par2) == find(0, par2)) {
      right.pop_back();
    } else {
      unite(left[i], right[j], par1, rank1);
      unite(left[i], right[j], par2, rank2);
      res.push_back(make_pair(left[i] + 1, right[j] + 1));
    }
  }
  cout << res.size() << endl;
  for (int i = 0; i < res.size(); i++) {
    cout << res[i].first << " " << res[i].second << endl;
  }
}
