#pragma GCC optimize("Ofast") #pragma GCC target("avx2,bmi2,lzcnt,fma") #include using namespace std; vector> solve(vector A, vector B, vector> E) { int N = A.size(); vector> conn(N); vector> adj(N, vector(N)); for(auto& [u, v]: E) { if(u > v) swap(u, v); conn[u].push_back(v), conn[v].push_back(u); adj[v][u] = adj[u][v] = 1; } sort(E.begin(), E.end()); priority_queue, vector>, greater>> Q; vector deg(N), color(N, -1); for(int i=0; i exist(conn[u].size()+1); for(int v: conn[u]) { Q.emplace(deg[v]--, v); if(color[v] != -1 && color[v] < (int)exist.size()) exist[color[v]] = 1; } for(int i=0; i<(int)exist.size(); ++i) if(!exist[i]) { color[u] = i; break; } assert(color[u] != -1); } int K = 1+*max_element(color.begin(), color.end()); vector> cliques(K); for(int i=0; i::iterator, vector::iterator)> hamiltonian = [&](vector::iterator st, vector::iterator ed) { int N = distance(st, ed); if(N == 1) return; auto mi = st + N / 2; hamiltonian(st, mi); hamiltonian(mi, ed); vector buffer; buffer.reserve(N); auto l = st, r = mi; while(l != mi || r != ed) { if(l == mi) buffer.push_back(*r++); else if(r == ed) buffer.push_back(*l++); else if(cmp(*l, *r)) buffer.push_back(*l++); else buffer.push_back(*r++); } copy(buffer.begin(), buffer.end(), st); return; }; auto exist = [&](int u, int v) { return cmp(u, v) && !adj[u][v]; }; vector> ans; for(int i=0; i=0; --k) { int v = cliques[i][k]; if(exist(v, u)) { ans.emplace_back(v, u); break; } } } } sort(ans.begin(), ans.end()); ans.erase(unique(ans.begin(), ans.end()), ans.end()); return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); int N, M; cin >> N >> M; vector A(N), B(N); for(int&x: A) cin >> x; for(int&x: B) cin >> x; vector> E(M); for(auto& [u, v]: E) { cin >> u >> v; --u; --v; } auto ret = solve(A, B, E); cout << ret.size() << '\n'; for(auto [a, b]: ret) cout << a+1 << " " << b+1 << '\n'; }