This is the easy version of the problem. The only difference between the two versions is the constraint on n. You can make hacks only if all versions of the problem are solved.

A forest is an undirected graph without cycles (not necessarily connected).

Mocha and Diana are friends in Zhijiang, both of them have a forest with nodes numbered from 1 to n, and they would like to add edges to their forests such that: 

  * After adding edges, both of their graphs are still forests. 
  * They add the same edges. That is, if an edge (u, v) is added to Mocha's forest, then an edge (u, v) is added to Diana's forest, and vice versa. 



Mocha and Diana want to know the maximum number of edges they can add, and which edges to add.

Input

The first line contains three integers n, m_1 and m_2 (1 ≤ n ≤ 1000, 0 ≤ m_1, m_2 < n) — the number of nodes and the number of initial edges in Mocha's forest and Diana's forest.

Each of the next m_1 lines contains two integers u and v (1 ≤ u, v ≤ n, u ≠ v) — the edges in Mocha's forest.

Each of the next m_2 lines contains two integers u and v (1 ≤ u, v ≤ n, u ≠ v) — the edges in Diana's forest.

Output

The first line contains only one integer h, the maximum number of edges Mocha and Diana can add (in each forest).

Each of the next h lines contains two integers u and v (1 ≤ u, v ≤ n, u ≠ v) — the edge you add each time.

If there are multiple correct answers, you can print any one of them.

Examples

Input


3 2 2
1 2
2 3
1 2
1 3


Output


0


Input


5 3 2
5 4
2 1
4 3
4 3
1 4


Output


1
2 4


Input


8 1 2
1 7
2 6
1 5


Output


5
5 2
2 3
3 4
4 7
6 8

Note

In the first example, we cannot add any edge.

In the second example, the initial forests are as follows.

<image>

We can add an edge (2, 4).

<image>

Difficulty: MEDIUM
Tags: Graph algorithms

Constructive algorithms

Complete search

Greedy algorithms

Tree algorithms

Spanning trees
Skill types: Complete search

Greedy algorithms

Starter code:

Solutions:
import sys, os, io
from sys import stdin
import math
from collections import defaultdict
from heapq import heappush, heappop, heapify
from bisect import bisect_left, bisect_right
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
alphabets = list('abcdefghijklmnopqrstuvwxyz')
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

def ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			l.append(int(i))
			n = n / i
	if n > 2:
		l.append(n)
	return list(set(l))

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def sieveForSmallestPrimeFactor():
	MAXN = 100001
	spf = [0 for i in range(MAXN)]
	spf[1] = 1
	for i in range(2, MAXN):
		spf[i] = i
	for i in range(4, MAXN, 2):
		spf[i] = 2
	for i in range(3, math.ceil(math.sqrt(MAXN))):
		if spf[i] == i:
			for j in range(i * i, MAXN, i):
				if spf[j] == j:
					spf[j] = i
	return spf

def getPrimeFactorizationLOGN(x):
	spf = sieveForSmallestPrimeFactor()
	ret = list()
	while x != 1:
		ret.append(spf[x])
		x = x // spf[x]
	return ret

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime

def si():
	return input()

def divideCeil(n, x):
	if n % x == 0:
		return n // x
	return n // x + 1

def ii():
	return int(input())

def li():
	return list(map(int, input().split()))
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class DisjointSetUnion:

	def __init__(self, n):
		self.parent = list(range(n))
		self.size = [1] * n
		self.num_sets = n

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		(a, b) = (self.find(a), self.find(b))
		if a != b:
			if self.size[a] < self.size[b]:
				(a, b) = (b, a)
			self.num_sets -= 1
			self.parent[b] = a
			self.size[a] += self.size[b]

	def set_size(self, a):
		return self.size[self.find(a)]

	def __len__(self):
		return self.num_sets

class UnionFind:

	def __init__(self, n):
		self.parent = list(range(n))

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		self.parent[self.find(b)] = self.find(a)
(n, m1, m2) = li()
adj1 = [[] for i in range(n)]
adj2 = [[] for i in range(n)]
dsu1 = DisjointSetUnion(n)
dsu2 = DisjointSetUnion(n)
for i in range(m1):
	(a, b) = li()
	a -= 1
	b -= 1
	adj1[a].append(b)
	adj1[b].append(a)
	dsu1.union(a, b)
for i in range(m2):
	(a, b) = li()
	a -= 1
	b -= 1
	adj2[a].append(b)
	adj2[b].append(a)
	dsu2.union(a, b)
ans = []
for i in range(n):
	for j in range(i + 1, n):
		p1 = dsu1.find(i)
		p2 = dsu1.find(j)
		if p1 == p2:
			continue
		p1 = dsu2.find(i)
		p2 = dsu2.find(j)
		if p1 == p2:
			continue
		ans.append([i + 1, j + 1])
		dsu1.union(i, j)
		dsu2.union(i, j)
print(len(ans))
for i in ans:
	print(*i)


import sys
import math
from collections import deque, Counter
from sys import stdin
int1 = lambda x: int(x) - 1
inp = lambda : int(input())
mi = lambda : map(int, input().split())
li = lambda : list(mi())
mi1 = lambda : map(int1, input().split())
li1 = lambda : list(mi1())
mis = lambda : map(str, input().split())
lis = lambda : list(mis())
stinput = lambda : stdin.readline()[:-1]
stinp = lambda : int(stinput())
stmi = lambda : map(int, stdin.readline().split())
stli = lambda : list(stmi())
stmi1 = lambda : map(int1, stdin.readline().split())
stli1 = lambda : list(stmi1())
stmis = lambda : stdin.readline()[:-1]
pr = print
from collections import defaultdict
mod = 10 ** 9 + 7
Mod = 998244353
INF = 10 ** 18
ans = 0
from collections import defaultdict

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return len(self.roots())

	def all_group_members(self):
		group_members = defaultdict(list)
		for member in range(self.n):
			group_members[self.find(member)].append(member)
		return group_members

	def __str__(self):
		return '\n'.join((f'{r}: {m}' for (r, m) in self.all_group_members().items()))
(n, a, b) = mi()
uf = UnionFind(n)
uf2 = UnionFind(n)
for i in range(a):
	(x, y) = mi1()
	uf.union(x, y)
for j in range(b):
	(x, y) = mi1()
	uf2.union(x, y)
ans = []
for i in range(n):
	for j in range(i + 1, n):
		if uf.same(i, j) == False and uf2.same(i, j) == False:
			ans.append((i + 1, j + 1))
			uf.union(i, j)
			uf2.union(i, j)
print(len(ans))
for (i, j) in ans:
	print(i, j)


import os
import sys
import math
import collections
import functools
import itertools
import heapq
import bisect
from io import BytesIO, IOBase
from typing import Union

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
ALPHA = 'abcde'
MOD = 10 ** 9 + 7
EPS = 1e-06

def Ceil(a, b):
	return a // b + int(a % b > 0)

def INT():
	return int(input())

def STR():
	return input()

def INTS():
	return tuple(map(int, input().split()))

def ARRINT():
	return [int(i) for i in input().split()]

def ARRSTR():
	return [i for i in input().split()]

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n
		self.group = n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		self.group -= 1
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return self.group

	def all_group_members(self):
		dic = {r: [] for r in self.roots()}
		for i in range(self.n):
			dic[self.find(i)].append(i)
		return dic

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
(n, m1, m2) = INTS()
uf1 = UnionFind(n)
uf2 = UnionFind(n)
for _ in range(m1):
	(x, y) = INTS()
	uf1.union(x - 1, y - 1)
for _ in range(m2):
	(x, y) = INTS()
	uf2.union(x - 1, y - 1)
res = []
for i in range(n):
	for j in range(i + 1, n):
		if not uf1.same(i, j) and (not uf2.same(i, j)):
			uf1.union(i, j)
			uf2.union(i, j)
			res += [(i + 1, j + 1)]
print(len(res))
for i in range(len(res)):
	print(*res[i])


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
(n, e1, e2) = [int(x) for x in input().split()]

class dsu:

	def __init__(self, n):
		self.n = n
		self.parent = [-1 for x in range(n + 1)]
		self.rank = [0 for x in range(n + 1)]

	def find_root(self, currnode):
		if self.parent[currnode] == -1:
			return currnode
		self.parent[currnode] = self.find_root(self.parent[currnode])
		return self.parent[currnode]

	def union(self, a, b):
		root_a = self.find_root(a)
		root_b = self.find_root(b)
		if root_b == root_a:
			return
		if self.rank[root_b] > self.rank[root_a]:
			self.parent[root_a] = root_b
		elif self.rank[root_b] < self.rank[root_a]:
			self.parent[root_b] = root_a
		else:
			self.parent[root_b] = root_a
			self.rank[root_a] += 1
		return
moca = dsu(n)
dina = dsu(n)
s = set()
for i in range(e1):
	(a, b) = [int(x) for x in input().split()]
	moca.union(a, b)
for i in range(e2):
	(a, b) = [int(x) for x in input().split()]
	dina.union(a, b)
ans = []
for a in range(1, n + 1):
	for b in range(a + 1, n + 1):
		if moca.find_root(a) != moca.find_root(b) and dina.find_root(a) != dina.find_root(b):
			ans.append((a, b))
			dina.union(a, b)
			moca.union(a, b)
print(len(ans))
for (a, b) in ans:
	sys.stdout.write(f'{a} {b}\n')


import sys
from math import factorial, gcd
from collections import Counter, deque, defaultdict
from bisect import bisect_left, bisect_right
from heapq import heappop, heappush, heapify, nlargest, nsmallest
from itertools import groupby
from copy import deepcopy
MOD = 10 ** 9 + 7
INF = float('inf')
rl = lambda : list(map(int, sys.stdin.readline().split()))
rs = lambda : sys.stdin.readline().strip()

def find(x, parent):
	if parent[x] == -1:
		return x
	parent[x] = find(parent[x], parent)
	return parent[x]

def union(x, y, parent):
	rootX = find(x, parent)
	rootY = find(y, parent)
	if rootX == rootY:
		return False
	parent[rootX] = rootY
	return True
(n, m1, m2) = rl()
parent1 = [-1] * (n + 1)
parent2 = [-1] * (n + 1)
for _ in range(m1):
	(u, v) = rl()
	union(u, v, parent1)
for _ in range(m2):
	(u, v) = rl()
	union(u, v, parent2)
ans = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if find(i, parent1) != find(j, parent1) and find(i, parent2) != find(j, parent2):
			union(i, j, parent1)
			union(i, j, parent2)
			ans.append((i, j))
print(len(ans))
for (u, v) in ans:
	print(u, v)


class UnionFind:
	rank = []
	parent = []
	n = 0

	def __init__(self, n):
		self.n = n
		self.rank = [1] * n
		self.parent = [0] * n
		for i in range(n):
			self.parent[i] = i

	def get(self, a):
		self.parent[a] = a if self.parent[a] == a else self.get(self.parent[a])
		return self.parent[a]

	def merge(self, a, b):
		a = self.get(a)
		b = self.get(b)
		if a == b:
			return
		if self.rank[a] == self.rank[b]:
			self.rank[a] += 1
		if self.rank[a] > self.rank[b]:
			self.parent[b] = a
		else:
			self.parent[a] = b
(n, n1, n2) = map(int, input().split(' '))
u1 = UnionFind(n)
u2 = UnionFind(n)
for i in range(n1):
	(a, b) = map(int, input().split(' '))
	a -= 1
	b -= 1
	u1.merge(a, b)
for i in range(n2):
	(a, b) = map(int, input().split(' '))
	a -= 1
	b -= 1
	u2.merge(a, b)
ans = []
for i in range(n):
	for j in range(n):
		if u1.get(i) != u1.get(j) and u2.get(i) != u2.get(j):
			ans.append((i + 1, j + 1))
			u1.merge(i, j)
			u2.merge(i, j)
print(len(ans))
for x in ans:
	print(*x)


class disjointSet:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.rank = [0] * n

	def findParent(self, u):
		if self.parent[u] != u:
			self.parent[u] = self.findParent(self.parent[u])
		return self.parent[u]

	def union(self, u, v):
		u = self.findParent(u)
		v = self.findParent(v)
		if self.rank[u] > self.rank[v]:
			self.parent[v] = u
		elif self.rank[u] < self.rank[v]:
			self.parent[u] = v
		else:
			self.rank[u] += 1
			self.parent[v] = u
(n, m1, m2) = map(int, input().split())
m = max(m1, m2)
set1 = disjointSet(n)
set2 = disjointSet(n)
for _ in range(m1):
	(u, v) = map(int, input().split())
	set1.union(u - 1, v - 1)
for _ in range(m2):
	(u, v) = map(int, input().split())
	set2.union(u - 1, v - 1)
print(n - 1 - m)
for i in range(n):
	if m == n - 1:
		break
	for j in range(i + 1, n):
		if m == n - 1:
			break
		if set1.findParent(i) != set1.findParent(j) and set2.findParent(i) != set2.findParent(j):
			set1.union(i, j)
			set2.union(i, j)
			m += 1
			print(i + 1, j + 1)


import sys
input = sys.stdin.readline

class DSU:

	def __init__(self, n):
		self.uf = {i: i for i in range(n)}
		self.rank = {i: 1 for i in range(n)}

	def find(self, x):
		if self.uf[x] != x:
			self.uf[x] = self.find(self.uf[x])
		return self.uf[x]

	def union(self, x, y):
		(px, py) = (self.find(x), self.find(y))
		if px != py:
			if self.rank[px] > self.rank[py]:
				(px, py) = (py, px)
			self.rank[py] += self.rank[px]
			self.uf[px] = py
			return True
		return False
(n, m1, m2) = map(int, input().split())
(dsu1, dsu2) = (DSU(n), DSU(n))
seen = set()
for _ in range(m1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	if a > b:
		(a, b) = (b, a)
	seen.add((a, b))
	dsu1.union(a, b)
for _ in range(m2):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	if a > b:
		(a, b) = (b, a)
	seen.add((a, b))
	dsu2.union(a, b)
cnt = 0
ans = []
for i in range(n):
	for j in range(i + 1, n):
		if dsu1.find(i) != dsu1.find(j) and dsu2.find(i) != dsu2.find(j):
			dsu1.union(i, j)
			dsu2.union(i, j)
			cnt += 1
			ans.append((i + 1, j + 1))
print(cnt)
for a in ans:
	print(*a)


class DisjointSet:

	def __init__(self, n):
		self.parent = [-1] * n
		self.forest = n

	def find(self, u):
		if self.parent[u] == -1:
			return u
		self.parent[u] = self.find(self.parent[u])
		return self.parent[u]

	def union(self, u, v):
		(p1, p2) = (self.find(u), self.find(v))
		if p1 == p2:
			return
		self.parent[p1] = p2
		self.forest -= 1
(n, m1, m2) = list(map(int, input().split()))
(ds1, ds2) = (DisjointSet(n), DisjointSet(n))
for _ in range(m1):
	(u, v) = list(map(int, input().split()))
	ds1.union(u - 1, v - 1)
for _ in range(m2):
	(u, v) = list(map(int, input().split()))
	ds2.union(u - 1, v - 1)
r = []
for i in range(n):
	for j in range(n):
		if i == j or ds1.find(i) == ds1.find(j) or ds2.find(i) == ds2.find(j):
			continue
		ds1.union(i, j)
		ds2.union(i, j)
		r.append((i, j))
print(len(r))
for (u, v) in r:
	print(u + 1, v + 1)


from sys import stdin, stdout

def get_list():
	return list(map(int, stdin.readline().strip().split()))

def get_int():
	return int(stdin.readline())

def get_ints():
	return map(int, stdin.readline().strip().split())

def get_string():
	return stdin.readline()

def printn(n):
	stdout.write(str(n) + '\n')

class DSU:

	def __init__(self, n):
		self.par = list(range(0, n + 1))
		self.sz = [1] * n

	def find(self, x):
		if x == self.par[x]:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, u, v):
		u = self.find(u)
		v = self.find(v)
		if u == v:
			return
		if u > v:
			(u, v) = (v, u)
		self.par[v] = u

	def check(self, u, v):
		u = self.find(u)
		v = self.find(v)
		if v == u:
			return False
		return True

def solve():
	(n, m1, m2) = get_ints()
	g1 = DSU(n + 2)
	g2 = DSU(n + 2)
	while m1:
		m1 -= 1
		(u, v) = get_ints()
		g1.union(u, v)
	while m2:
		m2 -= 1
		(u, v) = get_ints()
		g2.union(u, v)
	tup = []
	p1 = []
	p2 = []
	for i in range(2, n + 1):
		if g1.check(1, i) and g2.check(1, i):
			tup.append((1, i))
			g1.union(1, i)
			g2.union(1, i)
		if g1.find(i) != 1:
			p1.append(i)
		if g2.find(i) != 1:
			p2.append(i)
	while p1 and p2:
		if g1.find(p1[-1]) == 1 and g2.find(p1[-1]) == 1:
			p1.pop(-1)
			continue
		if g1.find(p2[-1]) == 1 and g2.find(p2[-1]) == 1:
			p2.pop(-1)
			continue
		tup.append((p1[-1], p2[-1]))
		g1.union(p1[-1], p2[-1])
		g2.union(p1[-1], p2[-1])
		continue
	printn(len(tup))
	for ans in tup:
		print(ans[0], ans[1])
solve()


class dsu:

	def __init__(self, size: int) -> None:
		self.parents = [-1 for _ in range(size)]
		self.sizes = [1 for _ in range(size)]

	def find(self, x: int) -> int:
		if self.parents[x] == -1:
			return x
		self.parents[x] = self.find(self.parents[x])
		return self.parents[x]

	def union(self, x: int, y: int) -> bool:
		x_root = self.find(x)
		y_root = self.find(y)
		if x_root == y_root:
			return False
		if self.sizes[x_root] < self.sizes[y_root]:
			(x_root, y_root) = (y_root, x_root)
		self.parents[y_root] = x_root
		self.sizes[x_root] += self.sizes[y_root]
		return True

	def connected(self, x: int, y: int) -> bool:
		return self.find(x) == self.find(y)
(n, m1, m2) = [int(i) for i in input().split()]
dsu1 = dsu(n)
dsu2 = dsu(n)
for i in range(m1):
	(p, q) = [int(i) - 1 for i in input().split()]
	dsu1.union(p, q)
for i in range(m2):
	(p, q) = [int(i) - 1 for i in input().split()]
	dsu2.union(p, q)
delta = []
bset = set(range(n))
while bset:
	k = bset.pop()
	d = set()
	for i in bset:
		d = set()
		if not (dsu1.connected(k, i) or dsu2.connected(k, i)):
			dsu1.union(k, i)
			dsu2.union(k, i)
			delta.append((k, i))
			d.add(i)
	bset.symmetric_difference(d)
print(len(delta))
for i in delta:
	print(i[0] + 1, i[1] + 1)


(n, m1, m2) = map(int, input().split())
parents1 = [i for i in range(n + 1)]
parents2 = [i for i in range(n + 1)]

def findParent(x, p):
	if p[x] == x:
		return x
	return findParent(p[x], p)

def addEdge(a, b, p):
	k = findParent(a, p)
	l = findParent(b, p)
	if k != l:
		p[l] = k

def NotaCyclic(u, v, p):
	p1 = findParent(u, p)
	p2 = findParent(v, p)
	if p1 != p2:
		return True
	return False
while m1:
	(a, b) = map(int, input().split())
	addEdge(a, b, parents1)
	m1 -= 1
while m2:
	(a, b) = map(int, input().split())
	addEdge(a, b, parents2)
	m2 -= 1
ans = 0
A = []
for i in range(1, n):
	for j in range(i + 1, n + 1):
		if NotaCyclic(i, j, parents1) and NotaCyclic(i, j, parents2):
			addEdge(i, j, parents1)
			addEdge(i, j, parents2)
			A.append([i, j])
			ans += 1
print(ans)
for i in range(len(A)):
	print(*A[i])


class UnionFind:

	def __init__(self, n):
		self.par = [-1] * n
		self.rank = [0] * n

	def Find(self, x):
		if self.par[x] < 0:
			return x
		else:
			self.par[x] = self.Find(self.par[x])
			return self.par[x]

	def Unite(self, x, y):
		x = self.Find(x)
		y = self.Find(y)
		if x != y:
			if self.rank[x] < self.rank[y]:
				self.par[y] += self.par[x]
				self.par[x] = y
			else:
				self.par[x] += self.par[y]
				self.par[y] = x
				if self.rank[x] == self.rank[y]:
					self.rank[x] += 1

	def Same(self, x, y):
		return self.Find(x) == self.Find(y)

	def Size(self, x):
		return -self.par[self.Find(x)]
import sys
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(n, m1, m2) = map(int, input().split())
uf1 = UnionFind(n)
for i in range(m1):
	(u, v) = map(int, input().split())
	(u, v) = (u - 1, v - 1)
	uf1.Unite(u, v)
uf2 = UnionFind(n)
for i in range(m2):
	(u, v) = map(int, input().split())
	(u, v) = (u - 1, v - 1)
	uf2.Unite(u, v)
E = []
for i in range(n):
	for j in range(n):
		if i == j:
			continue
		if not uf1.Same(i, j) and (not uf2.Same(i, j)):
			E.append((i, j))
			uf1.Unite(i, j)
			uf2.Unite(i, j)
print(len(E))
for i in range(len(E)):
	(u, v) = E[i]
	print(u + 1, v + 1)


from collections import defaultdict, deque, Counter
from sys import stdin, stdout
from heapq import heappush, heappop
import math
import io
import os
import math
import bisect

def isPrime(x):
	for i in range(2, x):
		if i * i > x:
			break
		if x % i == 0:
			return False
	return True

def ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			l.append(int(i))
			n = n / i
	if n > 2:
		l.append(n)
	return list(set(l))

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def sieve(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime

def digits(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def ceil(n, x):
	if n % x == 0:
		return n // x
	return n // x + 1

def mapin():
	return [int(x) for x in input().split()]

class DisjointSetUnion:

	def __init__(self, n):
		self.parent = list(range(n))
		self.size = [1] * n
		self.num_sets = n

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		(a, b) = (self.find(a), self.find(b))
		if a != b:
			if self.size[a] < self.size[b]:
				(a, b) = (b, a)
			self.num_sets -= 1
			self.parent[b] = a
			self.size[a] += self.size[b]
			return 1
		return 0

	def union2(self, a, b):
		(a, b) = (self.find(a), self.find(b))
		if a != b:
			return 1
		return 0

	def set_size(self, a):
		return self.size[self.find(a)]

	def __len__(self):
		return self.num_sets

	def parenta(self):
		return self.parent
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
t = 1
for _ in range(t):
	(n, m1, m2) = mapin()
	A = DisjointSetUnion(n)
	B = DisjointSetUnion(n)
	for i in range(m1):
		(u, v) = mapin()
		A.union(u - 1, v - 1)
	for i in range(m2):
		(u, v) = mapin()
		B.union(u - 1, v - 1)
	ans = []
	for i in range(n):
		for j in range(n):
			temp = A.union2(i, j)
			temp2 = B.union2(i, j)
			if temp == 1 and temp2 == 1:
				A.union(i, j)
				B.union(i, j)
				ans.append([i + 1, j + 1])
	print(len(ans))
	for i in ans:
		print(*i)


class DisjointSet:

	def __init__(self, n):
		self.node = [x for x in range(n)]

	def find(self, v):
		if self.node[v] == v:
			return v
		self.node[v] = self.find(self.node[v])
		return self.node[v]

	def merge(self, v1, v2):
		v1 = self.find(v1)
		v2 = self.find(v2)
		if v1 != v2:
			self.node[v2] = v1
(n, m1, m2) = map(int, input().split())
forest1 = DisjointSet(n)
forest2 = DisjointSet(n)
for _ in range(m1):
	(a, b) = map(lambda x: int(x) - 1, input().split())
	forest1.merge(a, b)
for _ in range(m2):
	(a, b) = map(lambda x: int(x) - 1, input().split())
	forest2.merge(a, b)
ans = []
for i in range(n):
	for j in range(n):
		if forest1.find(i) != forest1.find(j) and forest2.find(i) != forest2.find(j):
			ans.append((i + 1, j + 1))
			forest1.merge(i, j)
			forest2.merge(i, j)
print(len(ans))
for _ in ans:
	print(*_)


[n, m1, m2] = [int(x) for x in input().split()]
mAdj = []
dAdj = []
for i in range(n):
	mAdj.append([])
	dAdj.append([])
for i in range(m1):
	[a, b] = [int(x) for x in input().split()]
	mAdj[a - 1].append(b - 1)
	mAdj[b - 1].append(a - 1)
for i in range(m2):
	[a, b] = [int(x) for x in input().split()]
	dAdj[a - 1].append(b - 1)
	dAdj[b - 1].append(a - 1)
mComp = [-1] * n
dComp = [-1] * n

def getComp(adj, comp):
	visited = [0] * n
	cc = -1
	for i in range(n):
		if visited[i] == 0:
			cc += 1
			stack = [i]
			visited[i] = 1
			comp[i] = cc
			while len(stack) > 0:
				p = stack.pop()
				for x in adj[p]:
					if visited[x] == 0:
						stack.append(x)
						visited[x] = 1
						comp[x] = cc
getComp(mAdj, mComp)
getComp(dAdj, dComp)

def changeComp(comp, x, y):
	for i in range(n):
		if comp[i] == y:
			comp[i] = x
ans = []
for i in range(n):
	for j in range(i + 1, n):
		if dComp[i] != dComp[j] and mComp[i] != mComp[j]:
			ans.append((i, j))
			changeComp(dComp, dComp[i], dComp[j])
			changeComp(mComp, mComp[i], mComp[j])
print(len(ans))
for (a, b) in ans:
	print(a + 1, b + 1)


class UnoinFind(object):

	def __init__(self, n):
		self.__findset = [i for i in range(n + 1)]
		self.__rank = [1 for i in range(n + 1)]

	def find(self, x):
		if self.__findset[x] != x:
			self.__findset[x] = self.find(self.__findset[x])
		return self.__findset[x]

	def union(self, p, q):
		p_root = self.find(p)
		q_root = self.find(q)
		if self.__rank[p_root] < self.__rank[q_root]:
			self.__findset[p_root] = q_root
		elif self.__rank[p_root] > self.__rank[q_root]:
			self.__findset[q_root] = p_root
		else:
			self.__findset[p_root] = q_root
			self.__rank[q_root] += 1

	def is_connected(self, p, q):
		if self.find(p) == self.find(q):
			return True
		return False
(n, m1, m2) = map(int, input().split())
U1 = UnoinFind(n)
U2 = UnoinFind(n)
for _ in range(m1):
	(u, v) = map(int, input().split())
	U1.union(u, v)
for _ in range(m2):
	(u, v) = map(int, input().split())
	U2.union(u, v)
ans = []
stack1 = []
stack2 = []
for i in range(2, n + 1):
	flag1 = U1.is_connected(1, i)
	flag2 = U2.is_connected(1, i)
	if not (flag1 or flag2):
		ans.append((1, i))
		U1.union(1, i)
		U2.union(1, i)
	elif flag1:
		stack1.append(i)
	elif flag2:
		stack2.append(i)
while stack1 != [] and stack2 != []:
	if U1.is_connected(1, stack2[-1]):
		stack2.pop()
		continue
	if U2.is_connected(1, stack1[-1]):
		stack1.pop()
		continue
	ans.append((stack1[-1], stack2[-1]))
	U1.union(stack1[-1], stack2[-1])
	U2.union(stack1[-1], stack2[-1])
	stack1.pop()
	stack2.pop()
print(len(ans))
for pair in ans:
	print(*pair)


(On, Pig, Cow) = map(int, input().split())

class Farm:

	def __init__(self):
		self.Fa = [i for i in range(0, On)]

	def fa(self, x):
		if self.Fa[x] == x:
			return x
		self.Fa[x] = self.fa(self.Fa[x])
		return self.Fa[x]

	def merge(self, a, b):
		if a < b:
			(a, b) = (b, a)
		self.Fa[self.fa(a)] = self.fa(b)
PigFarm = Farm()
CowFarm = Farm()
for i in range(Pig):
	(a, b) = map(int, input().split())
	PigFarm.merge(a - 1, b - 1)
for i in range(Cow):
	(a, b) = map(int, input().split())
	CowFarm.merge(a - 1, b - 1)
ans = []
for i in range(1, On):
	Piggy = PigFarm.fa(i)
	Cowwy = CowFarm.fa(i)
	if Piggy and Cowwy:
		ans.append((0, i))
		PigFarm.merge(0, i)
		CowFarm.merge(0, i)
LonelyAnimals = {'Pig': [], 'Cow': []}
for i in range(1, On):
	Piggy = PigFarm.fa(i)
	Cowwy = CowFarm.fa(i)
	if not Piggy and Cowwy == i:
		LonelyAnimals['Cow'].append(Cowwy)
	elif not Cowwy and Piggy == i:
		LonelyAnimals['Pig'].append(Piggy)
for i in range(On):
	if len(LonelyAnimals['Cow']) == i or len(LonelyAnimals['Pig']) == i:
		break
	ans.append((LonelyAnimals['Cow'][i], LonelyAnimals['Pig'][i]))
print(len(ans))
for (i, j) in ans:
	print(i + 1, j + 1)


import sys
input = sys.stdin.readline
(n, m1, m2) = list(map(int, input().split()))
inp1 = [list(map(int, input().split())) for i in range(m1)]
inp2 = [list(map(int, input().split())) for i in range(m2)]
arr1 = [i for i in range(n)]
arr2 = [i for i in range(n)]
for (i, j) in inp1:
	(x, y) = (arr1[i - 1], arr1[j - 1])
	for t in range(len(arr1)):
		if arr1[t] == max(x, y):
			arr1[t] = min(x, y)
		elif arr1[t] > max(x, y):
			arr1[t] -= 1
for (i, j) in inp2:
	(x, y) = (arr2[i - 1], arr2[j - 1])
	for t in range(len(arr2)):
		if arr2[t] == max(x, y):
			arr2[t] = min(x, y)
		elif arr2[t] > max(x, y):
			arr2[t] -= 1
if n == 1:
	print(0)
	exit()
num_op = min(max(arr1), max(arr2))
print(num_op)
for i in range(num_op):
	(i1, i2, i3, i4) = (arr1.index(0), arr1.index(1), arr2.index(0), arr2.index(1))
	stop = 0
	for x in (i1, i2, i3, i4):
		for y in (i1, i2, i3, i4):
			if x != y:
				if arr1[x] != arr1[y] and arr2[x] != arr2[y]:
					stop = 1
					break
		if stop == 1:
			break
	(s1, s2) = (x, y)
	(x, y) = (arr1[x], arr1[y])
	for t in range(len(arr1)):
		if arr1[t] == max(x, y):
			arr1[t] = min(x, y)
		elif arr1[t] > max(x, y):
			arr1[t] -= 1
	(x, y) = (s1, s2)
	(x, y) = (arr2[x], arr2[y])
	for t in range(len(arr2)):
		if arr2[t] == max(x, y):
			arr2[t] = min(x, y)
		elif arr2[t] > max(x, y):
			arr2[t] -= 1
	(x, y) = (s1, s2)
	print(str(x + 1) + ' ' + str(y + 1))


from sys import stdin, stdout
from bisect import bisect_left, bisect_right
from math import ceil, floor, log, gcd
from collections import Counter, deque
from heapq import heappush, heappop, heapify
from operator import mul
from functools import reduce

class Dsu:

	def __init__(self, n):
		self.groups = n
		self.parent = list(range(n))
		self.rank = [1] * n

	def find(self, x):
		while x != self.parent[x]:
			self.parent[x] = self.parent[self.parent[x]]
			x = self.parent[x]
		return x

	def uni(self, x, y):
		(px, py) = (self.find(x), self.find(y))
		if px == py:
			return
		if self.rank[py] > self.rank[px]:
			(px, py) = (py, px)
		self.parent[py] = px
		self.rank[px] += self.rank[py]
		self.groups -= 1

	def get_size(self, x):
		return self.rank[self.find(x)]

def choose(n, r):
	r = min(r, n - r)
	numer = reduce(mul, range(n, n - r, -1), 1)
	denom = reduce(mul, range(1, r + 1), 1)
	return numer // denom

def re():
	return stdin.readline().rstrip()

def ints():
	return map(int, re().split())
mod = 1000000007

def solve():
	(n, mi, ni) = ints()
	miku = Dsu(n + 1)
	nino = Dsu(n + 1)
	for i in range(mi):
		(x, y) = ints()
		miku.uni(x, y)
	for i in range(ni):
		(x, y) = ints()
		nino.uni(x, y)
	ans = []
	for i in range(1, n + 1):
		for j in range(i + 1, n + 1):
			if miku.find(i) != miku.find(j) and nino.find(i) != nino.find(j):
				miku.uni(i, j)
				nino.uni(i, j)
				ans.append([i, j])
	print(len(ans))
	for x in ans:
		print(*x)
solve()


from sys import stdin, stdout
input = stdin.readline
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

def dfs(start, val, par):
	vis.add(start)
	if val:
		xx[start] = kk
		pivot2[-1].append(start)
		for i in g2[start]:
			if i not in vis:
				dfs(i, val, par)
	else:
		yy[start] = kk
		pivot1[-1].append(start)
		for i in g1[start]:
			if i not in vis:
				dfs(i, val, par)
t = 1
for _ in range(t):
	(n, x, y) = map(int, input().split())
	all = set()
	g1 = [[] for i in range(n)]
	g2 = [[] for i in range(n)]
	for i in range(x):
		(a, b) = map(int, input().split())
		all.add((a - 1, b - 1))
		g1[a - 1].append(b - 1)
		g1[b - 1].append(a - 1)
	for i in range(y):
		(a, b) = map(int, input().split())
		all.add((a - 1, b - 1))
		g2[a - 1].append(b - 1)
		g2[b - 1].append(a - 1)
	pivot1 = []
	pivot2 = []
	vis = set()
	xx = [-1 for i in range(n)]
	yy = [-1 for i in range(n)]
	kk = 0
	for i in range(n):
		if i not in vis:
			kk += 1
			pivot1.append([])
			dfs(i, 0, i)
	vis = set()
	kk = 0
	for i in range(n):
		if i not in vis:
			kk += 1
			pivot2.append([])
			dfs(i, 1, i)
	ans = []
	for i in range(n):
		for j in range(n):
			if xx[i] != xx[j] and yy[i] != yy[j]:
				ans.append((i + 1, j + 1))
				k = xx[j]
				for p in range(n):
					if xx[p] == k:
						xx[p] = xx[i]
				k = yy[j]
				for p in range(n):
					if yy[p] == k:
						yy[p] = yy[i]
	print(len(ans))
	for i in ans:
		stdout.write(str(i[0]) + ' ' + str(i[1]) + '\n')


def solve():
	(N, m1, m2) = map(int, input().split())
	parentsa = [i for i in range(N)]
	ranka = [0 for i in range(N)]
	parentsb = [i for i in range(N)]
	rankb = [0 for i in range(N)]
	for i in range(m1):
		(a, b) = map(int, input().split())
		union(a - 1, b - 1, parentsa, ranka)
	for i in range(m2):
		(a, b) = map(int, input().split())
		union(a - 1, b - 1, parentsb, rankb)
	ret = []
	for i in range(N):
		for j in range(i + 1, N):
			if find(parentsa, i) != find(parentsa, j) and find(parentsb, i) != find(parentsb, j):
				ret.append([i, j])
				union(i, j, parentsa, ranka)
				union(i, j, parentsb, rankb)
	print(len(ret))
	for (x, y) in ret:
		print(x + 1, y + 1)

def find(parents, node):
	if parents[node] != node:
		parents[node] = find(parents, parents[node])
		return parents[node]
	else:
		return node

def union(first, second, parents, rank):
	pf = find(parents, first)
	ps = find(parents, second)
	if pf != ps:
		if rank[pf] > rank[ps]:
			rank[pf] += 1
			parents[ps] = pf
		else:
			rank[ps] += 1
			parents[pf] = ps
solve()


from sys import *
input = stdin.readline
import random
from bisect import *
import math
from collections import *
import operator
from heapq import *
from itertools import *
inf = 10 ** 18
mod = 10 ** 9 + 7

def dfs1(n, v):
	vis1[n] = v
	for child in mocha[n]:
		if vis1[child] == 0:
			dfs1(child, v)

def dfs2(n, v):
	vis2[n] = v
	for child in diana[n]:
		if vis2[child] == 0:
			dfs2(child, v)
(n, m1, m2) = map(int, input().split())
mocha = defaultdict(list)
diana = defaultdict(list)
for _ in range(m1):
	(u, v) = map(int, input().split())
	mocha[u].append(v)
	mocha[v].append(u)
for _ in range(m2):
	(u, v) = map(int, input().split())
	diana[u].append(v)
	diana[v].append(u)
vis1 = [0] * (n + 1)
vis2 = [0] * (n + 1)
cnt = 1
for i in range(1, n + 1):
	if vis1[i] == 0:
		dfs1(i, cnt)
		cnt += 1
cnt = 1
for i in range(1, n + 1):
	if vis2[i] == 0:
		dfs2(i, cnt)
		cnt += 1
ans = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if vis1[i] != vis1[j] and vis2[i] != vis2[j]:
			temp1 = vis1[j]
			temp2 = vis2[j]
			ans.append((i, j))
			for k in range(1, n + 1):
				if vis1[k] == temp1:
					vis1[k] = vis1[i]
				if vis2[k] == temp2:
					vis2[k] = vis2[i]
print(len(ans))
for i in ans:
	print(*i)


import math, sys
from collections import defaultdict, deque
import bisect as bi

def yes():
	print('YES')

def no():
	print('NO')

def I():
	return int(sys.stdin.readline())

def In():
	return map(int, sys.stdin.readline().split())

def Sn():
	return sys.stdin.readline().strip()

def dict(a):
	d = {}
	for x in a:
		if d.get(x, -1) != -1:
			d[x] += 1
		else:
			d[x] = 1
	return d

def find_gt(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	else:
		return -1

class DSU:

	def __init__(self, n):
		self.parent = [i for i in range(n + 1)]
		self.rank = [0 for i in range(n + 1)]

	def find_set(self, v):
		if v == self.parent[v]:
			return v
		self.parent[v] = self.find_set(self.parent[v])
		return self.parent[v]

	def union(self, a, b):
		a = self.find_set(a)
		b = self.find_set(b)
		if a != b:
			if self.rank[a] < self.rank[b]:
				(a, b) = (b, a)
			self.parent[b] = a
			if self.rank[a] == self.rank[b]:
				self.rank[a] += 1
			return True
		return False

def main():
	try:
		(n, m1, m2) = In()
		dsu1 = DSU(n)
		dsu2 = DSU(n)
		for i in range(m1):
			(a, b) = In()
			dsu1.union(a, b)
		for i in range(m2):
			(a, b) = In()
			dsu2.union(a, b)
		ans = []
		for i in range(1, n + 1):
			for j in range(i, n + 1):
				if dsu1.find_set(i) != dsu1.find_set(j) and dsu2.find_set(i) != dsu2.find_set(j):
					dsu1.union(i, j)
					dsu2.union(i, j)
					ans.append((i, j))
		print(len(ans))
		for x in ans:
			print(*x)
	except:
		pass
M = 998244353
P = 1000000007
for _ in range(1):
	main()


from collections import Counter, deque
import string
import math
import bisect
import sys
from fractions import Fraction

def array_int():
	return [int(i) for i in sys.stdin.readline().split()]

def vary(arrber_of_variables):
	if arrber_of_variables == 1:
		return int(sys.stdin.readline())
	if arrber_of_variables >= 2:
		return map(int, sys.stdin.readline().split())

def makedict(var):
	return dict(Counter(var))

def root(i, arr):
	while i != arr[i]:
		i = arr[i]
		arr[i] = arr[arr[i]]
	return i

def update(i, j, arr):
	r1 = root(i, arr)
	r2 = root(j, arr)
	arr[r1] = r2
for _ in range(1):
	(n, m1, m2) = vary(3)
	mocha = [i for i in range(n + 1)]
	diana = [i for i in range(n + 1)]
	for i in range(m1):
		(u, v) = vary(2)
		update(u, v, mocha)
	for i in range(m2):
		(u, v) = vary(2)
		update(u, v, diana)
	pt = []
	for i in range(1, n + 1):
		for j in range(i + 1, n + 1):
			if root(i, mocha) != root(j, mocha) and root(j, diana) != root(i, diana):
				update(i, j, mocha)
				update(i, j, diana)
				pt.append([i, j])
	print(len(pt))
	for i in pt:
		print(*i)


from collections import deque
(n, m1, m2) = map(int, input().split())
(g1, g2) = ([[] for i in range(n)], [[] for i in range(n)])
for i in range(m1):
	(u, v) = map(int, input().split())
	g1[u - 1].append(v - 1)
	g1[v - 1].append(u - 1)
for i in range(m2):
	(u, v) = map(int, input().split())
	g2[u - 1].append(v - 1)
	g2[v - 1].append(u - 1)
parent1 = {}
parent2 = {}
vis = [0] * n
for i in range(n):
	if not vis[i]:
		q = deque()
		q.append(i)
		while q:
			e = q.popleft()
			parent1[e] = i
			for j in g1[e]:
				if not vis[j]:
					vis[j] = 1
					q.append(j)
vis = [0] * n
for i in range(n):
	if not vis[i]:
		q = deque()
		q.append(i)
		while q:
			e = q.popleft()
			parent2[e] = i
			for j in g2[e]:
				if not vis[j]:
					vis[j] = 1
					q.append(j)

def find(u, parent, r):
	if parent[u] == u:
		return (u, r)
	return find(parent[u], parent, r + 1)
ans = []
for i in range(n):
	for j in range(i + 1, n):
		(r1, rank1) = find(i, parent1, 1)
		(r2, rank2) = find(j, parent1, 1)
		if r1 != r2:
			(s1, h1) = find(i, parent2, 1)
			(s2, h2) = find(j, parent2, 1)
			if s1 != s2:
				ans.append([i, j])
				if rank1 < rank2:
					parent1[r1] = r2
				else:
					parent1[r2] = r1
				if h1 < h2:
					parent2[s1] = s2
				else:
					parent2[s2] = s1
print(len(ans))
for i in ans:
	print(i[0] + 1, i[1] + 1)


def findParent(x, p):
	if p[x] == x:
		return x
	return findParent(p[x], p)

def addEdge(a, b, p):
	k = findParent(a, p)
	l = findParent(b, p)
	if k != l:
		p[l] = k
(n, m1, m2) = map(int, input().split())
parents1 = [i for i in range(n + 1)]
parents2 = [i for i in range(n + 1)]
while m1:
	(a, b) = map(int, input().split())
	addEdge(a, b, parents1)
	m1 -= 1
while m2:
	(a, b) = map(int, input().split())
	addEdge(a, b, parents2)
	m2 -= 1
ans = 0
A = []
for i in range(1, n):
	for j in range(i + 1, n + 1):
		if findParent(i, parents1) != findParent(j, parents1) and findParent(i, parents2) != findParent(j, parents2):
			addEdge(i, j, parents1)
			addEdge(i, j, parents2)
			A.append([i, j])
			ans += 1
print(ans)
for i in range(len(A)):
	print(*A[i])


(n, m1, m2) = map(int, input().split())
root1 = [i for i in range(n + 1)]
root2 = [i for i in range(n + 1)]

def find(x, root):
	while root[x] != x:
		temp = root[x]
		root[x] = root[temp]
		x = temp
	return root[x]

def union(x, y, root):
	a = find(x, root)
	b = find(y, root)
	root[a] = b
for i in range(m1):
	(x, y) = map(int, input().split())
	union(x, y, root1)
for i in range(m2):
	(x, y) = map(int, input().split())
	union(x, y, root2)
edge = []
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if i != j:
			if find(i, root1) != find(j, root1) and find(i, root2) != find(j, root2):
				edge.append([i, j])
				union(i, j, root1)
				union(i, j, root2)
if edge:
	print(len(edge))
	for i in range(len(edge)):
		print(*edge[i])
else:
	print(0)


import sys
input = sys.stdin.readline

def find(i, v):
	if v == par[i][v]:
		return v
	par[i][v] = find(i, par[i][v])
	return par[i][v]

def join(i, u, v):
	u = find(i, u)
	v = find(i, v)
	if u == v:
		return
	if sz[i][u] < sz[i][v]:
		(u, v) = (v, u)
	par[i][v] = u
	sz[i][u] += sz[i][v]
(n, m1, m2) = map(int, input().split())
par = [[i for i in range(n + 1)] for j in range(2)]
sz = [[1 for i in range(n + 1)] for j in range(2)]
for i in range(m1):
	(u, v) = map(int, input().split())
	join(0, u, v)
for i in range(m2):
	(u, v) = map(int, input().split())
	join(1, u, v)
ans = []
for _ in range(n):
	comp = [[] for j in range(n + 1)]
	for j in range(1, n + 1):
		comp[find(0, j)].append((find(1, j), j))
	rem = []
	for j in range(1, n + 1):
		if comp[j]:
			comp[j].sort()
			gay = []
			for i in range(len(comp[j])):
				if i == 0:
					gay.append(comp[j][i])
				elif comp[j][i][0] != comp[j][i - 1][0]:
					gay.append(comp[j][i])
			rem.append(gay)
	st = []
	no = []
	for gay in rem:
		if len(gay) >= 2 and (not st):
			st = gay
		else:
			no.append(gay[0])
	if st:
		found = False
		for (a, b) in st:
			for (u, v) in no:
				if a != u:
					ans.append((b, v))
					join(0, b, v)
					join(1, b, v)
					found = True
					break
			if found:
				break
	else:
		no.sort()
		found = False
		for i in range(len(no) - 1):
			if no[i][0] != no[i + 1][0]:
				ans.append((no[i][1], no[i + 1][1]))
				join(0, no[i][1], no[i + 1][1])
				join(1, no[i][1], no[i + 1][1])
				found = True
				break
	if not found:
		break
print(len(ans))
for (u, v) in ans:
	print(u, v)


import sys
import math
import bisect
from sys import stdin, stdout
from math import gcd, floor, sqrt, log
from collections import defaultdict as dd
from bisect import bisect_left as bl, bisect_right as br
from collections import Counter
from collections import defaultdict as dd
from collections import defaultdict as dd
flush = lambda : stdout.flush()
stdstr = lambda : stdin.readline()
stdint = lambda : int(stdin.readline())
stdpr = lambda x: stdout.write(str(x))
stdmap = lambda : map(int, stdstr().split())
stdarr = lambda : list(map(int, stdstr().split()))
mod = 1000000007

class UnionFind:

	def __init__(self, n):
		self.parent = list(range(n))

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		self.parent[self.find(b)] = self.find(a)
(n, m1, m2) = stdmap()
d1 = UnionFind(n)
d2 = UnionFind(n)
for i in range(m1):
	(a, b) = stdmap()
	a -= 1
	b -= 1
	d1.union(a, b)
for j in range(m2):
	(a, b) = stdmap()
	a -= 1
	b -= 1
	d2.union(a, b)
res = []
for i in range(n):
	for j in range(i + 1, n):
		c1 = d1.find(i)
		c2 = d1.find(j)
		x1 = d2.find(i)
		x2 = d2.find(j)
		if c1 == c2 or x2 == x1:
			continue
		else:
			res.append([i + 1, j + 1])
			d1.union(i, j)
			d2.union(i, j)
print(len(res))
for j in res:
	print(*j)


import sys, math
import heapq
from collections import deque
input = sys.stdin.readline
hqp = heapq.heappop
hqs = heapq.heappush

def ip():
	return int(input())

def fp():
	return float(input())

def sp():
	return str(input().rstrip())

def mip():
	return map(int, input().split())

def msp():
	return map(str, input().split())

def lmip():
	return list(map(int, input().split()))

def lmsp():
	return list(map(str, input().split()))

def gcd(x, y):
	while y:
		(x, y) = (y, x % y)
	return x

def lcm(x, y):
	return x * y // gcd(x, y)

def isprime(x):
	if x == 1:
		return False
	for i in range(2, int(x ** 0.5) + 1):
		if x % i == 0:
			return False
	return True

def find(x):
	if x == p[x]:
		return x
	q = find(p[x])
	p[x] = q
	return q

def union(x, y):
	x = find(x)
	y = find(y)
	if x != y:
		p[y] = x

def find2(x):
	if x == p2[x]:
		return x
	q = find2(p2[x])
	p2[x] = q
	return q

def union2(x, y):
	x = find2(x)
	y = find2(y)
	if x != y:
		p2[y] = x
(n, m1, m2) = mip()
p = [i for i in range(n + 1)]
p2 = [i for i in range(n + 1)]
for i in range(m1):
	(u, v) = mip()
	union(u, v)
for i in range(m2):
	(u, v) = mip()
	union2(u, v)
ans = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if find(i) != find(j) and find2(i) != find2(j):
			ans.append([i, j])
			union(i, j)
			union2(i, j)
print(len(ans))
for i in range(len(ans)):
	print(*ans[i])


import sys
input = sys.stdin.readline

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n
		self.group = n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		self.group -= 1
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return self.group

	def all_group_members(self):
		dic = {r: [] for r in self.roots()}
		for i in range(self.n):
			dic[self.find(i)].append(i)
		return dic

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))

def main():
	(n, m1, m2) = map(int, input().split())
	UF1 = UnionFind(n)
	UF2 = UnionFind(n)
	for _ in range(m1):
		(u, v) = map(int, input().split())
		UF1.union(u - 1, v - 1)
	for _ in range(m2):
		(u, v) = map(int, input().split())
		UF2.union(u - 1, v - 1)
	ans = []
	for i in range(n):
		for j in range(i + 1, n):
			if not UF1.same(i, j) and (not UF2.same(i, j)):
				UF1.union(i, j)
				UF2.union(i, j)
				ans.append((i + 1, j + 1))
	print(len(ans))
	for row in ans:
		print(*row)
for _ in range(1):
	main()


from sys import *
input = stdin.readline

class UnionFind:

	def __init__(self, n):
		self.parent = list(range(n))

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		self.parent[self.find(b)] = self.find(a)

def check(u, v, dsu):
	if u == dsu.find(v) or v == dsu.find(u) or dsu.find(u) == dsu.find(v):
		return False
	return True
(n, m1, m2) = map(int, input().split())
(dsu1, dsu2) = (UnionFind(n + 1), UnionFind(n + 1))
for i in range(m1):
	(u, v) = map(int, input().split())
	dsu1.union(u, v)
for j in range(m2):
	(u, v) = map(int, input().split())
	dsu2.union(u, v)
ans = []
for i in range(1, n):
	for j in range(i + 1, n + 1):
		if check(i, j, dsu1) and check(i, j, dsu2):
			dsu1.union(i, j)
			dsu2.union(i, j)
			ans.append((i, j))
print(len(ans))
for i in ans:
	print(*i)


class DisjointSet:

	def __init__(self, n):
		self.__fa = [i for i in range(n + 1)]
		self.__group = n

	def __father(self, u):
		if self.__fa[u] == u:
			return u
		v = self.__father(self.__fa[u])
		self.__fa[u] = v
		return v

	def size(self):
		return self.__group

	def same(self, u, v):
		return self.__father(u) == self.__father(v)

	def add(self, u, v):
		u = self.__father(u)
		v = self.__father(v)
		if u == v:
			raise ValueError
		self.__fa[u] = v
		self.__group -= 1

def main():
	(n, m1, m2) = [int(word) for word in input().strip().split()]
	mocha = DisjointSet(n)
	diana = DisjointSet(n)
	for i in range(m1):
		(u, v) = [int(word) for word in input().strip().split()]
		mocha.add(u, v)
	for i in range(m2):
		(u, v) = [int(word) for word in input().strip().split()]
		diana.add(u, v)
	ans = []
	flag = False
	for i in range(1, n + 1):
		if flag:
			break
		for j in range(i + 1, n + 1):
			if mocha.same(i, j) or diana.same(i, j):
				continue
			mocha.add(i, j)
			diana.add(i, j)
			ans.append(str(i) + ' ' + str(j))
			if mocha.size() == 1 or diana.size() == 1:
				flag = True
				break
	print(len(ans))
	for s in ans:
		print(s)
main()


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import ceil

def prod(a, mod=10 ** 9 + 7):
	ans = 1
	for each in a:
		ans = ans * each % mod
	return ans

def gcd(x, y):
	while y:
		(x, y) = (y, x % y)
	return x

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y

class DisjointSetUnion:

	def __init__(self, n):
		self.parent = [*range(n + 1)]
		self.size = [1] * (n + 1)
		(self.min, self.max) = ([*range(n + 1)], [*range(n + 1)])
		self.count = n

	def get(self, a):
		if self.parent[a] == a:
			return a
		x = a
		while a != self.parent[a]:
			a = self.parent[a]
		while x != self.parent[x]:
			(self.parent[x], x) = (a, self.parent[x])
		return a

	def union(self, a, b):
		(a, b) = (self.get(a), self.get(b))
		if a != b:
			if self.size[a] > self.size[b]:
				(a, b) = (b, a)
			self.parent[a] = b
			self.size[b] += self.size[a]
			self.min[b] = min(self.min[a], self.min[b])
			self.max[b] = max(self.max[a], self.max[b])
			self.count -= 1

	def count_sets(self):
		return self.count
for _ in range(int(input()) if not True else 1):
	(n, m1, m2) = map(int, input().split())
	graph = []
	graph2 = []
	dsu1 = DisjointSetUnion(n)
	dsu2 = DisjointSetUnion(n)
	for i in range(m1):
		(x, y) = map(int, input().split())
		dsu1.union(x, y)
	for i in range(m2):
		(x, y) = map(int, input().split())
		dsu2.union(x, y)
	ans = []
	for x in range(1, n + 1):
		for y in range(1, n + 1):
			if dsu1.get(x) != dsu1.get(y) and dsu2.get(x) != dsu2.get(y):
				dsu1.union(x, y)
				dsu2.union(x, y)
				ans += [[x, y]]
	print(len(ans))
	for (x, y) in ans:
		print(x, y)


from sys import stdin
from collections import defaultdict
ii = lambda : int(input())
di = lambda : defaultdict(lambda : 0)
mi = lambda : map(int, stdin.readline().strip().split())

def find(parent, u):
	while parent[u] != u:
		u = parent[u]
	return u
(n, m1, m2) = mi()
(e, p1, p2) = ([[0] * (n + 1) for i in range(n + 1)], [i for i in range(n + 1)], [i for i in range(n + 1)])
for i in range(m1):
	(u, v) = mi()
	e[u][v] = e[v][u] = 1
	p1[find(p1, u)] = find(p1, v)
for i in range(m2):
	(u, v) = mi()
	e[u][v] = e[v][u] = 1
	p2[find(p2, u)] = find(p2, v)
ans = []
for i in range(1, n):
	for j in range(i + 1, n + 1):
		if not e[i][j]:
			if find(p1, i) != find(p1, j) and find(p2, i) != find(p2, j):
				ans.append([i, j])
				p1[find(p1, i)] = find(p1, j)
				p2[find(p2, i)] = find(p2, j)
print(len(ans))
for i in ans:
	print(*i)


def root(i, arr):
	while i != arr[i]:
		i = arr[i]
		arr[i] = arr[arr[i]]
	return i

def update(i, j, arr):
	r1 = root(i, arr)
	r2 = root(j, arr)
	arr[r1] = r2
(n, m1, m2) = map(int, input().split())
arr1 = [i for i in range(n + 1)]
arr2 = [i for i in range(n + 1)]
for i in range(m1):
	(a, b) = map(int, input().split())
	update(a, b, arr1)
for i in range(m2):
	(a, b) = map(int, input().split())
	update(a, b, arr2)
res = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if root(i, arr1) != root(j, arr1):
			if root(i, arr2) != root(j, arr2):
				update(i, j, arr1)
				update(i, j, arr2)
				res.append([i, j])
print(len(res))
for ls in res:
	print(*ls)


from sys import stdin
input = stdin.readline

def dfs1(v, x):
	used1[v] = x
	for i in u1[v]:
		if not used1[i]:
			dfs1(i, x)

def dfs2(v, x):
	used2[v] = x
	for i in u2[v]:
		if not used2[i]:
			dfs2(i, x)
(n, m1, m2) = map(int, input().split())
u1 = []
u2 = []
for i in range(n):
	u1.append([])
	u2.append([])
for i in range(m1):
	(a, b) = map(lambda z: int(z) - 1, input().split())
	u1[a].append(b)
	u1[b].append(a)
for i in range(m2):
	(a, b) = map(lambda z: int(z) - 1, input().split())
	u2[a].append(b)
	u2[b].append(a)
used1 = [0] * n
used2 = [0] * n
cmp1 = cmp2 = 1
for i in range(n):
	if not used1[i]:
		dfs1(i, cmp1)
		cmp1 += 1
	if not used2[i]:
		dfs2(i, cmp2)
		cmp2 += 1
s1 = []
for i in range(cmp1):
	s1.append(set([i]))
s2 = []
for i in range(cmp2):
	s2.append(set([i]))
ans = []
for i in range(n):
	for j in range(i + 1, n):
		if s1[used1[i]].isdisjoint(s1[used1[j]]) and s2[used2[i]].isdisjoint(s2[used2[j]]):
			s1[used1[i]].update(s1[used1[j]])
			s2[used2[i]].update(s2[used2[j]])
			s1[used1[j]].update(s1[used1[i]])
			s2[used2[j]].update(s2[used2[i]])
			ans.append(str(i + 1) + ' ' + str(j + 1))
print(len(ans))
print('\n'.join(ans))


import math
import heapq
import string
from collections import deque
from bisect import bisect, bisect_left, bisect_right, insort
import sys
input = sys.stdin.readline
S = lambda : input()
I = lambda : int(S())
M = lambda : map(int, S().split())
L = lambda : list(M())
H = 1000000000 + 7
(n, m1, m2) = M()
adj1 = [[] for i in range(n)]
adj2 = [[] for i in range(n)]
for i in range(m1):
	(a, b) = M()
	adj1[a - 1].append(b - 1)
	adj1[b - 1].append(a - 1)
for i in range(m2):
	(a, b) = M()
	adj2[a - 1].append(b - 1)
	adj2[b - 1].append(a - 1)

def dfs(i, v, adj, l):
	for j in range(len(adj[i])):
		if v[adj[i][j]] == 0:
			l.append(adj[i][j])
			v[adj[i][j]] = 1
			dfs(adj[i][j], v, adj, l)
v1 = [0] * n
cc1 = []
for i in range(n):
	if v1[i] == 0:
		l1 = [i]
		v1[i] = 1
		dfs(i, v1, adj1, l1)
		cc1.append(l1)
v2 = [0] * n
cc2 = []
for i in range(n):
	if v2[i] == 0:
		l2 = [i]
		v2[i] = 1
		dfs(i, v2, adj2, l2)
		cc2.append(l2)
a1 = [0] * n
a2 = [0] * n
for i in range(len(cc1)):
	for j in cc1[i]:
		a1[j] = i
for i in range(len(cc2)):
	for j in cc2[i]:
		a2[j] = i
ans = []
for i in range(n):
	for j in range(i + 1, n):
		if a1[i] != a1[j] and a2[i] != a2[j]:
			(t1, t2) = (a1[i], a2[i])
			for k in range(n):
				if a1[k] == t1:
					a1[k] = a1[j]
			for k in range(n):
				if a2[k] == t2:
					a2[k] = a2[j]
			ans.append([i + 1, j + 1])
print(len(ans))
for i in ans:
	print(*i)


import os
import sys
import math
from io import BytesIO, IOBase
import io
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
from collections import deque
from collections import Counter
import threading
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class SegmentTree:

	def __init__(self, data, default=0, func=lambda a, b: math.gcd(a, b)):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class SegmentTree1:

	def __init__(self, data, default=0, func=lambda a, b: a + b):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)
MOD = 10 ** 9 + 7

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD
mod = 10 ** 9 + 7
omod = 998244353
prime = [True for i in range(11)]
prime[0] = prime[1] = False

def SieveOfEratosthenes(n=10):
	p = 2
	c = 0
	while p <= n:
		if prime[p] == True:
			c += 1
			for i in range(p, n + 1, p):
				prime[i] = False
		p += 1

class DSU:

	def __init__(self, R, C):
		self.par = range(R * C + 1)
		self.rnk = [0] * (R * C + 1)
		self.sz = [1] * (R * C + 1)

	def find(self, x):
		if self.par[x] != x:
			self.par[x] = self.find(self.par[x])
		return self.par[x]

	def union(self, x, y):
		(xr, yr) = (self.find(x), self.find(y))
		if xr == yr:
			return
		if self.rnk[xr] < self.rnk[yr]:
			(xr, yr) = (yr, xr)
		if self.rnk[xr] == self.rnk[yr]:
			self.rnk[xr] += 1
		self.par[yr] = xr
		self.sz[xr] += self.sz[yr]

	def size(self, x):
		return self.sz[self.find(x)]

	def top(self):
		return self.size(len(self.sz) - 1) - 1

class LazySegTree:

	def __init__(self, _op, _e, _mapping, _composition, _id, v):

		def set(p, x):
			assert 0 <= p < _n
			p += _size
			for i in range(_log, 0, -1):
				_push(p >> i)
			_d[p] = x
			for i in range(1, _log + 1):
				_update(p >> i)

		def get(p):
			assert 0 <= p < _n
			p += _size
			for i in range(_log, 0, -1):
				_push(p >> i)
			return _d[p]

		def prod(l, r):
			assert 0 <= l <= r <= _n
			if l == r:
				return _e
			l += _size
			r += _size
			for i in range(_log, 0, -1):
				if l >> i << i != l:
					_push(l >> i)
				if r >> i << i != r:
					_push(r >> i)
			sml = _e
			smr = _e
			while l < r:
				if l & 1:
					sml = _op(sml, _d[l])
					l += 1
				if r & 1:
					r -= 1
					smr = _op(_d[r], smr)
				l >>= 1
				r >>= 1
			return _op(sml, smr)

		def apply(l, r, f):
			assert 0 <= l <= r <= _n
			if l == r:
				return
			l += _size
			r += _size
			for i in range(_log, 0, -1):
				if l >> i << i != l:
					_push(l >> i)
				if r >> i << i != r:
					_push(r - 1 >> i)
			l2 = l
			r2 = r
			while l < r:
				if l & 1:
					_all_apply(l, f)
					l += 1
				if r & 1:
					r -= 1
					_all_apply(r, f)
				l >>= 1
				r >>= 1
			l = l2
			r = r2
			for i in range(1, _log + 1):
				if l >> i << i != l:
					_update(l >> i)
				if r >> i << i != r:
					_update(r - 1 >> i)

		def _update(k):
			_d[k] = _op(_d[2 * k], _d[2 * k + 1])

		def _all_apply(k, f):
			_d[k] = _mapping(f, _d[k])
			if k < _size:
				_lz[k] = _composition(f, _lz[k])

		def _push(k):
			_all_apply(2 * k, _lz[k])
			_all_apply(2 * k + 1, _lz[k])
			_lz[k] = _id
		_n = len(v)
		_log = _n.bit_length()
		_size = 1 << _log
		_d = [_e] * (2 * _size)
		_lz = [_id] * _size
		for i in range(_n):
			_d[_size + i] = v[i]
		for i in range(_size - 1, 0, -1):
			_update(i)
		self.set = set
		self.get = get
		self.prod = prod
		self.apply = apply
MIL = 1 << 20

def makeNode(total, count):
	return total * MIL + count

def getTotal(node):
	return math.floor(node / MIL)

def getCount(node):
	return node - getTotal(node) * MIL
nodeIdentity = makeNode(0.0, 0.0)

def nodeOp(node1, node2):
	return node1 + node2
	return makeNode(getTotal(node1) + getTotal(node2), getCount(node1) + getCount(node2))
identityMapping = -1

def mapping(tag, node):
	if tag == identityMapping:
		return node
	count = getCount(node)
	return makeNode(tag * count, count)

def composition(mapping1, mapping2):
	return mapping1 if mapping1 != identityMapping else mapping2

def memodict(f):

	class memodict(dict):

		def __missing__(self, key):
			ret = self[key] = f(key)
			return ret
	return memodict().__getitem__

def pollard_rho(n):
	if n & 1 == 0:
		return 2
	if n % 3 == 0:
		return 3
	s = (n - 1 & 1 - n).bit_length() - 1
	d = n >> s
	for a in [2, 325, 9375, 28178, 450775, 9780504, 1795265022]:
		p = pow(a, d, n)
		if p == 1 or p == n - 1 or a % n == 0:
			continue
		for _ in range(s):
			prev = p
			p = p * p % n
			if p == 1:
				return math.gcd(prev - 1, n)
			if p == n - 1:
				break
		else:
			for i in range(2, n):
				(x, y) = (i, (i * i + 1) % n)
				f = math.gcd(abs(x - y), n)
				while f == 1:
					(x, y) = ((x * x + 1) % n, (y * y + 1) % n)
					y = (y * y + 1) % n
					f = math.gcd(abs(x - y), n)
				if f != n:
					return f
	return n

@memodict
def prime_factors(n):
	if n <= 1:
		return Counter()
	f = pollard_rho(n)
	return Counter([n]) if f == n else prime_factors(f) + prime_factors(n // f)

def distinct_factors(n):
	factors = [1]
	for (p, exp) in prime_factors(n).items():
		factors += [p ** i * factor for factor in factors for i in range(1, exp + 1)]
	return factors

def all_factors(n):
	(small, large) = ([], [])
	for i in range(1, int(n ** 0.5) + 1, 2 if n & 1 else 1):
		if not n % i:
			small.append(i)
			large.append(n // i)
	if small[-1] == large[-1]:
		large.pop()
	large.reverse()
	small.extend(large)
	return small

def binarySearch(arr, n, key):
	left = 0
	right = n - 1
	mid = 0
	res = n
	while left <= right:
		mid = (right + left) // 2
		if arr[mid] > key:
			res = mid
			right = mid - 1
		else:
			left = mid + 1
	return res

def binarySearch1(arr, n, key):
	left = 0
	right = n - 1
	mid = 0
	res = -1
	while left <= right:
		mid = (right + left) // 2
		if arr[mid] > key:
			right = mid - 1
		else:
			res = mid
			left = mid + 1
	return res

def parent(p, i):
	if p[i] == -1:
		return i
	if p[i] != -1:
		return parent(p, p[i])
t = 1
for _ in range(t):
	(n, m1, m2) = map(int, input().split())
	p1 = [-1] * (n + 1)
	p2 = [-1] * (n + 1)
	r1 = [0] * (n + 1)
	r2 = [0] * (n + 1)
	for i in range(m1):
		(x, y) = map(int, input().split())
		ind1 = parent(p1, x)
		ind2 = parent(p1, y)
		if r1[ind1] > r1[ind2]:
			p1[ind2] = ind1
		elif r1[ind1] < r1[ind2]:
			p1[ind1] = ind2
		else:
			p1[ind1] = ind2
			r1[ind2] += 1
	for i in range(m2):
		(x, y) = map(int, input().split())
		ind1 = parent(p2, x)
		ind2 = parent(p2, y)
		if r2[ind1] > r2[ind2]:
			p2[ind2] = ind1
		elif r2[ind1] < r2[ind2]:
			p2[ind1] = ind2
		else:
			p2[ind1] = ind2
			r2[ind2] += 1
	ans = []
	for i in range(1, n):
		for j in range(i + 1, n + 1):
			ind1 = parent(p1, i)
			ind2 = parent(p1, j)
			ind3 = parent(p2, i)
			ind4 = parent(p2, j)
			if ind1 == ind2 or ind3 == ind4:
				continue
			if r1[ind1] > r1[ind2]:
				p1[ind2] = ind1
			elif r1[ind1] < r1[ind2]:
				p1[ind1] = ind2
			else:
				p1[ind1] = ind2
				r1[ind2] += 1
			if r2[ind3] > r2[ind4]:
				p2[ind4] = ind3
			elif r2[ind3] < r2[ind4]:
				p2[ind3] = ind4
			else:
				p2[ind3] = ind4
				r2[ind4] += 1
			ans.append([i, j])
	print(len(ans))
	for i in ans:
		print(*i)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class UnoinFind(object):

	def __init__(self, n):
		self.__findset = [i for i in range(n + 1)]
		self.__rank = [1 for i in range(n + 1)]

	def find(self, x):
		if self.__findset[x] != x:
			self.__findset[x] = self.find(self.__findset[x])
		return self.__findset[x]

	def union(self, p, q):
		p_root = self.find(p)
		q_root = self.find(q)
		if self.__rank[p_root] < self.__rank[q_root]:
			self.__findset[p_root] = q_root
		elif self.__rank[p_root] > self.__rank[q_root]:
			self.__findset[q_root] = p_root
		else:
			self.__findset[p_root] = q_root
			self.__rank[q_root] += 1

	def is_connected(self, p, q):
		if self.find(p) == self.find(q):
			return True
		return False
(n, m1, m2) = map(int, input().split())
U1 = UnoinFind(n)
U2 = UnoinFind(n)
for _ in range(m1):
	(u, v) = map(int, input().split())
	U1.union(u, v)
for _ in range(m2):
	(u, v) = map(int, input().split())
	U2.union(u, v)
ans = []
stack1 = []
stack2 = []
for i in range(2, n + 1):
	flag1 = U1.is_connected(1, i)
	flag2 = U2.is_connected(1, i)
	if not (flag1 or flag2):
		ans.append((1, i))
		U1.union(1, i)
		U2.union(1, i)
	elif flag1:
		stack1.append(i)
	elif flag2:
		stack2.append(i)
while stack1 != [] and stack2 != []:
	if U1.is_connected(1, stack2[-1]):
		stack2.pop()
		continue
	if U2.is_connected(1, stack1[-1]):
		stack1.pop()
		continue
	ans.append((stack1[-1], stack2[-1]))
	U1.union(stack1[-1], stack2[-1])
	U2.union(stack1[-1], stack2[-1])
	stack1.pop()
	stack2.pop()
print(len(ans))
for pair in ans:
	print(*pair)


for m in range(1, 2):
	(n, m1, m2) = list(map(int, input().split()))
	arrm1 = [2]
	arrm2 = [2]
	dicm1 = [i for i in range(1, n + 1)]
	dicm2 = list(dicm1)
	ans = []
	count = 0

	def find(a, arr):
		if arr[a] < 0:
			return a
		return find(arr[a], arr)

	def fill(a, b, arrm1, dicm1):
		a = find(a, arrm1)
		b = find(b, arrm1)
		if a != b:
			if arrm1[a] <= arrm1[b]:
				arrm1[a] += arrm1[b]
				arrm1[b] = a
			else:
				arrm1[b] += arrm1[a]
				arrm1[a] = b
	for i in range(n):
		arrm1.append(-1)
		arrm2.append(-1)
	for i in range(m1):
		(a, b) = list(map(int, input().split()))
		fill(a, b, arrm1, dicm1)
	for i in range(m2):
		(a, b) = list(map(int, input().split()))
		fill(a, b, arrm2, dicm2)
	if len(dicm1) == 1 or len(dicm2) == 1:
		print(0)
	else:
		for i in range(1, n + 1):
			for j in range(1, n + 1):
				if i == j:
					continue
				a1 = find(i, arrm1)
				b1 = find(j, arrm1)
				a2 = find(i, arrm2)
				b2 = find(j, arrm2)
				if a1 == b1 or a2 == b2:
					continue
				else:
					ans.append([i, j])
					count += 1
					fill(a1, b1, arrm1, dicm1)
					fill(a2, b2, arrm2, dicm2)
		print(count)
		for i in range(count):
			print(ans[i][0], ans[i][1])


def findParent(V, P):
	while V != P[V]:
		P[V] = P[P[V]]
		V = P[V]
	return V

def union(A, B, R, P):
	A = findParent(A, P)
	B = findParent(B, P)
	if R[A] > R[B]:
		P[B] = A
	elif R[B] > R[A]:
		P[A] = B
	else:
		P[B] = A
		R[A] += 1
import sys, collections
input = sys.stdin.readline
(N, M1, M2) = map(int, input().split())
P1 = [i for i in range(N + 1)]
R1 = [0 for i in range(N + 1)]
P2 = [i for i in range(N + 1)]
R2 = [0 for i in range(N + 1)]
for i in range(M1):
	(U, V) = map(int, input().split())
	union(U, V, R1, P1)
for i in range(M2):
	(U, V) = map(int, input().split())
	union(U, V, R2, P2)
C = 0
ANS = []
for i in range(1, N + 1):
	for j in range(i + 1, N + 1):
		if findParent(i, P1) != findParent(j, P1) and findParent(i, P2) != findParent(j, P2):
			C += 1
			ANS.append([i, j])
			union(i, j, R1, P1)
			union(i, j, R2, P2)
print(C)
for i in ANS:
	print(*i)


from math import *

def il():
	return list(map(int, input().split()))

def ii():
	return int(input())

def imi():
	return map(int, input().split())

def gcd(a, b):
	return cgcd(min(a, b), max(a, b))

def cgcd(a, b):
	if a == 0:
		return b
	return gcd(b % a, a)

def sti(i):
	return m - d - n + i

def chek(l, r, L, R, sta):
	if l % 2 == 0:
		if l == r - 1:
			return gcd(L, R)
		L = gcd(L, sta[l + 1])
	if r % 2 == 1:
		R = gcd(R, sta[r - 1])
	return chek(l // 2, r // 2, L, R, sta)
for _ in range(1):
	(n, m1, m2) = imi()
	mr = [0] * (n + 1)
	dr = [0] * (n + 1)
	x = 1
	for i in range(m1):
		(u, v) = imi()
		a = max(mr[u], mr[v])
		b = min(mr[u], mr[v])
		if a == 0:
			mr[u] = mr[v] = x
			x += 1
		elif b == 0:
			mr[u] = mr[v] = a
		else:
			for j in range(n):
				if mr[j] == a:
					mr[j] = b
	x = 1
	for i in range(m2):
		(u, v) = imi()
		a = max(dr[u], dr[v])
		b = min(dr[u], dr[v])
		if a == 0:
			dr[u] = dr[v] = x
			x += 1
		elif b == 0:
			dr[u] = dr[v] = a
		else:
			for j in range(n):
				if dr[j] == a:
					dr[j] = b
	li = []
	h = 0
	for i in range(1, n + 1):
		x = max(mr) + 1
		y = max(dr) + 1
		for j in range(i + 1, n + 1):
			if mr[i] == 0 and dr[i] == 0 or (mr[i] != mr[j] and dr[i] != dr[j]):
				h += 1
				li.append([i, j])
				u = i
				v = j
				a = max(mr[u], mr[v])
				b = min(mr[u], mr[v])
				if a == 0:
					mr[u] = mr[v] = x
					x += 1
				elif b == 0:
					mr[u] = mr[v] = a
				else:
					for j in range(1, n + 1):
						if mr[j] == a:
							mr[j] = b
				a = max(dr[u], dr[v])
				b = min(dr[u], dr[v])
				if a == 0:
					dr[u] = dr[v] = y
					y += 1
				elif b == 0:
					dr[u] = dr[v] = a
				else:
					for j in range(1, n + 1):
						if dr[j] == a:
							dr[j] = b
	print(h)
	for i in li:
		print(*i)


(n, m1, m2) = map(int, input().split())
r = {}
x = {}
t = {}
y = {}
for i in range(1, n + 1):
	r[i] = i
	x[i] = {i}
	t[i] = i
	y[i] = {i}
for i in range(m1):
	(q, w) = map(int, input().split())
	if r[q] < r[w]:
		(q, w) = (w, q)
	for j in x[r[w]]:
		r[j] = r[q]
		x[r[q]].add(j)
for i in range(m2):
	(q, w) = map(int, input().split())
	if t[q] < t[w]:
		(q, w) = (w, q)
	for j in y[t[w]]:
		t[j] = t[q]
		y[t[q]].add(j)
z = set()
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if r[i] != r[j] and t[i] != t[j]:
			z.add((i, j))
			for k in x[r[i]]:
				r[k] = r[j]
				x[r[j]].add(k)
			for k in y[t[i]]:
				t[k] = t[j]
				y[t[j]].add(k)
print(len(z))
for i in z:
	print(*i)


def find(x):
	if x != parents[x]:
		parents[x] = find(parents[x])
	return parents[x]

def union(x, y):
	parents[find(x)] = find(y)
(n, m1, m2) = map(int, input().split())
parents = list(range(n * 2 + 1))
for _ in range(m1):
	(u, v) = map(int, input().split())
	union(u, v)
for _ in range(m2):
	(u, v) = map(int, input().split())
	(u, v) = (u + n, v + n)
	union(u, v)
ret = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if find(i) != find(j) and find(i + n) != find(j + n):
			ret.append((i, j))
			union(i, j)
			union(i + n, j + n)
print(len(ret))
for r in ret:
	print(*r)


from collections import defaultdict, deque

def par(p, x):
	while x != p[x]:
		p_id = p[x]
		p[x] = p[p_id]
		x = p[x]
	return x
(n, m1, m2) = map(int, input().split(' '))
adj1 = [[] for i in range(n + 1)]
adj2 = [[] for i in range(n + 1)]
for i in range(m1):
	(u, v) = map(int, input().split(' '))
	adj1[u].append(v)
	adj1[v].append(u)
for i in range(m2):
	(u, v) = map(int, input().split(' '))
	adj2[u].append(v)
	adj2[v].append(u)
cnt = 1
vis = [0 for i in range(n + 1)]
p1 = [i for i in range(n + 1)]
for i in range(1, n + 1):
	if vis[i] == 0:
		vis[i] = 1
		dq = deque([])
		dq.append(i)
		while len(dq) > 0:
			x = dq.pop()
			p1[x] = i
			for j in adj1[x]:
				if vis[j] == 0:
					vis[j] = 1
					dq.append(j)
		cnt += 1
cnt = 1
vis = [0 for i in range(n + 1)]
p2 = [i for i in range(n + 1)]
for i in range(1, n + 1):
	if vis[i] == 0:
		vis[i] = 1
		dq = deque([])
		dq.append(i)
		while len(dq) > 0:
			x = dq.pop()
			p2[x] = i
			for j in adj2[x]:
				if vis[j] == 0:
					vis[j] = 1
					dq.append(j)
		cnt += 1
c = 0
ans = []
vis1 = [[0 for i in range(n + 1)] for i in range(n + 1)]
vis2 = [[0 for i in range(n + 1)] for i in range(n + 1)]
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		x = par(p1, i)
		y = par(p1, j)
		if x == y:
			continue
		g = par(p2, i)
		h = par(p2, j)
		if g == h:
			continue
		c += 1
		ans.append([i, j])
		p1[y] = p1[x]
		p2[h] = p2[g]
print(c)
for i in ans:
	print(*i)


import sys
input = sys.stdin.readline
(n, m1, m2) = map(int, input().split())
Group1 = [i for i in range(n + 1)]
Nodes1 = [1] * (n + 1)

def find1(x):
	while Group1[x] != x:
		x = Group1[x]
	return x

def Union1(x, y):
	if find1(x) != find1(y):
		if Nodes1[find1(x)] < Nodes1[find1(y)]:
			Nodes1[find1(y)] += Nodes1[find1(x)]
			Nodes1[find1(x)] = 0
			Group1[find1(x)] = find1(y)
		else:
			Nodes1[find1(x)] += Nodes1[find1(y)]
			Nodes1[find1(y)] = 0
			Group1[find1(y)] = find1(x)
Group2 = [i for i in range(n + 1)]
Nodes2 = [1] * (n + 1)

def find2(x):
	while Group2[x] != x:
		x = Group2[x]
	return x

def Union2(x, y):
	if find2(x) != find2(y):
		if Nodes2[find2(x)] < Nodes2[find2(y)]:
			Nodes2[find2(y)] += Nodes2[find2(x)]
			Nodes2[find2(x)] = 0
			Group2[find2(x)] = find2(y)
		else:
			Nodes2[find2(x)] += Nodes2[find2(y)]
			Nodes2[find2(y)] = 0
			Group2[find2(y)] = find2(x)
for i in range(m1):
	(a, b) = map(int, input().split())
	Union1(a, b)
for i in range(m2):
	(a, b) = map(int, input().split())
	Union2(a, b)
ANS = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if find1(i) != find1(j) and find2(i) != find2(j):
			ANS.append((i, j))
			Union1(i, j)
			Union2(i, j)
print(len(ANS))
for (x, y) in ANS:
	print(x, y)


def naiveSolve():
	return

class UnionFind:

	def __init__(self, n):
		self.parent = list(range(n))

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		self.parent[self.find(b)] = self.find(a)

def main():
	(n, mM, mD) = readIntArr()
	ufM = UnionFind(n)
	ufD = UnionFind(n)
	for _ in range(mM):
		(u, v) = readIntArr()
		u -= 1
		v -= 1
		ufM.union(u, v)
	for __ in range(mD):
		(u, v) = readIntArr()
		u -= 1
		v -= 1
		ufD.union(u, v)
	add = []
	for u in range(n):
		for v in range(u + 1, n):
			if ufM.find(u) != ufM.find(v) and ufD.find(u) != ufD.find(v):
				add.append((u + 1, v + 1))
				ufM.union(u, v)
				ufD.union(u, v)
	print(len(add))
	multiLineArrayOfArraysPrint(add)
	return
import sys
input = sys.stdin.buffer.readline

def oneLineArrayPrint(arr):
	print(' '.join([str(x) for x in arr]))

def multiLineArrayPrint(arr):
	print('\n'.join([str(x) for x in arr]))

def multiLineArrayOfArraysPrint(arr):
	print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))

def readIntArr():
	return [int(x) for x in input().split()]

def makeArr(defaultValFactory, dimensionArr):
	dv = defaultValFactory
	da = dimensionArr
	if len(da) == 1:
		return [dv() for _ in range(da[0])]
	else:
		return [makeArr(dv, da[1:]) for _ in range(da[0])]

def queryInteractive(x):
	print('{}'.format(x))
	sys.stdout.flush()
	return int(input())

def answerInteractive(ans):
	print('! {}'.format(ans))
	sys.stdout.flush()
inf = float('inf')
MOD = 998244353
from math import gcd, floor, ceil
for _abc in range(1):
	main()


import sys
input = sys.stdin.readline

def inp():
	return int(input())

def input_list():
	return list(map(int, input().split()))

def input_string():
	s = input()
	return list(s[:len(s) - 1])

def input_int_gen():
	return map(int, input().split())

def find(data, i):
	if data[i] != -1:
		data[i] = find(data, data[i])
		return data[i]
	return i

def union(data, i, j):
	(pi, pj) = (find(data, i), find(data, j))
	if pi != pj:
		data[pi] = pj

def connected(data, i, j):
	return find(data, i) == find(data, j)
from collections import defaultdict
(n, m1, m2) = input_int_gen()
if m1 == n - 1 or m2 == n - 1:
	print(0)
	exit()
to_add = min(n - 1 - m1, n - 1 - m2)
print(to_add)
added = []
edgesA = defaultdict(set)
edgesB = defaultdict(set)
disabledA = defaultdict(set)
disabledB = defaultdict(set)
dsA = defaultdict(lambda : -1)
dsB = defaultdict(lambda : -1)
for _ in range(m1):
	(a, b) = input_int_gen()
	edgesA[a].add(b)
	edgesA[b].add(a)
	union(dsA, a, b)
for _ in range(m2):
	(a, b) = input_int_gen()
	edgesB[a].add(b)
	edgesB[b].add(a)
	union(dsB, a, b)
for i in range(1, n):
	for j in range(i, n + 1):
		if not connected(dsA, i, j) and (not connected(dsB, i, j)):
			added.append((i, j))
			print(i, j)
			union(dsA, i, j)
			union(dsB, i, j)
			to_add -= 1
			if to_add == 0:
				exit()


import types
_atcoder_code = "\n# Python port of AtCoder Library.\n\n__version__ = '0.0.1'\n"
atcoder = types.ModuleType('atcoder')
exec(_atcoder_code, atcoder.__dict__)
_atcoder_dsu_code = "\nimport typing\n\n\nclass DSU:\n    '''\n    Implement (union by size) + (path halving)\n\n    Reference:\n    Zvi Galil and Giuseppe F. Italiano,\n    Data structures and algorithms for disjoint set union problems\n    '''\n\n    def __init__(self, n: int = 0) -> None:\n        self._n = n\n        self.parent_or_size = [-1] * n\n\n    def merge(self, a: int, b: int) -> int:\n        assert 0 <= a < self._n\n        assert 0 <= b < self._n\n\n        x = self.leader(a)\n        y = self.leader(b)\n\n        if x == y:\n            return x\n\n        if -self.parent_or_size[x] < -self.parent_or_size[y]:\n            x, y = y, x\n\n        self.parent_or_size[x] += self.parent_or_size[y]\n        self.parent_or_size[y] = x\n\n        return x\n\n    def same(self, a: int, b: int) -> bool:\n        assert 0 <= a < self._n\n        assert 0 <= b < self._n\n\n        return self.leader(a) == self.leader(b)\n\n    def leader(self, a: int) -> int:\n        assert 0 <= a < self._n\n\n        parent = self.parent_or_size[a]\n        while parent >= 0:\n            if self.parent_or_size[parent] < 0:\n                return parent\n            self.parent_or_size[a], a, parent = (\n                self.parent_or_size[parent],\n                self.parent_or_size[parent],\n                self.parent_or_size[self.parent_or_size[parent]]\n            )\n\n        return a\n\n    def size(self, a: int) -> int:\n        assert 0 <= a < self._n\n\n        return -self.parent_or_size[self.leader(a)]\n\n    def groups(self) -> typing.List[typing.List[int]]:\n        leader_buf = [self.leader(i) for i in range(self._n)]\n\n        result: typing.List[typing.List[int]] = [[] for _ in range(self._n)]\n        for i in range(self._n):\n            result[leader_buf[i]].append(i)\n\n        return list(filter(lambda r: r, result))\n"
atcoder.dsu = types.ModuleType('atcoder.dsu')
exec(_atcoder_dsu_code, atcoder.dsu.__dict__)
import sys
IS_INTERACTIVE = False
input = input
if not IS_INTERACTIVE:
	(*data,) = sys.stdin.read().split('\n')[::-1]

	def input():
		return data.pop()

def fprint(*args, **kwargs):
	print(*args, **kwargs, flush=True)

def eprint(*args, **kwargs):
	print(*args, **kwargs, file=sys.stderr)

def dfs(g, v, colors):
	for w in g[v]:
		if colors[w] == -1:
			colors[w] = colors[v]
			dfs(g, w, colors)

def colorize(g, colors):
	cur_color = 0
	for i in range(len(colors)):
		if colors[i] == -1:
			dfs(g1, i, colors)
			cur_color += 1
(n, m1, m2) = map(int, input().split())
colors1 = [-1] * n
colors2 = [-1] * n
g1 = [[] for _ in range(m1)]
g2 = [[] for _ in range(m2)]
dsu1 = atcoder.dsu.DSU(n)
dsu2 = atcoder.dsu.DSU(n)
e1 = set()
for i in range(m1):
	(a, b) = map(int, input().split())
	if a > b:
		(a, b) = (b, a)
	a -= 1
	b -= 1
	e1.add((a, b))
	dsu1.merge(a, b)
e2 = set()
for i in range(m2):
	(a, b) = map(int, input().split())
	if a > b:
		(a, b) = (b, a)
	a -= 1
	b -= 1
	e2.add((a, b))
	dsu2.merge(a, b)
ans = []
for i in range(n):
	for j in range(i + 1, n):
		if (i, j) not in e1 and (i, j) not in e2 and (dsu1.leader(i) != dsu1.leader(j)) and (dsu2.leader(i) != dsu2.leader(j)):
			e1.add((i, j))
			e2.add((i, j))
			ans.append((i, j))
			dsu1.merge(i, j)
			dsu2.merge(i, j)
print(len(ans))
for (i, j) in ans:
	print(i + 1, j + 1)


from __future__ import division, print_function
import os, sys
from io import BytesIO, IOBase
if sys.version_info[0] < 3:
	from __builtin__ import xrange as range
	from future_builtins import ascii, filter, hex, map, oct, zip
from bisect import bisect_left as lower_bound, bisect_right as upper_bound

def so():
	return int(input())

def st():
	return input()

def mj():
	return map(int, input().strip().split(' '))

def msj():
	return map(str, input().strip().split(' '))

def le():
	return list(map(int, input().split()))

def lebe():
	return list(map(int, input()))

def dmain():
	sys.setrecursionlimit(1000000)
	threading.stack_size(1024000)
	thread = threading.Thread(target=main)
	thread.start()

def joro(L):
	return ''.join(map(str, L))

def decimalToBinary(n):
	return bin(n).replace('0b', '')

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def npr(n, r):
	return factorial(n) // factorial(n - r) if n >= r else 0

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(n - r)) if n >= r else 0

def lower_bound(li, num):
	answer = -1
	start = 0
	end = len(li) - 1
	while start <= end:
		middle = (end + start) // 2
		if li[middle] >= num:
			answer = middle
			end = middle - 1
		else:
			start = middle + 1
	return answer

def upper_bound(li, num):
	answer = -1
	start = 0
	end = len(li) - 1
	while start <= end:
		middle = (end + start) // 2
		if li[middle] <= num:
			answer = middle
			start = middle + 1
		else:
			end = middle - 1
	return answer

def abs(x):
	return x if x >= 0 else -x

def binary_search(li, val, lb, ub):
	ans = -1
	while lb <= ub:
		mid = (lb + ub) // 2
		if li[mid] > val:
			ub = mid - 1
		elif val > li[mid]:
			lb = mid + 1
		else:
			ans = mid
			break
	return ans

def kadane(x):
	sum_so_far = 0
	current_sum = 0
	for i in x:
		current_sum += i
		if current_sum < 0:
			current_sum = 0
		else:
			sum_so_far = max(sum_so_far, current_sum)
	return sum_so_far

def pref(li):
	pref_sum = [0]
	for i in li:
		pref_sum.append(pref_sum[-1] + i)
	return pref_sum

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	li = []
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	for p in range(2, len(prime)):
		if prime[p]:
			li.append(p)
	return li

def primefactors(n):
	factors = []
	while n % 2 == 0:
		factors.append(2)
		n //= 2
	for i in range(3, int(sqrt(n)) + 1, 2):
		while n % i == 0:
			factors.append(i)
			n //= i
	if n > 2:
		factors.append(n)
	return factors

def read():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')

def tr(n):
	return n * (n + 1) // 2

def fb(k, L):
	if k == L[k]:
		return k
	L[k] = fb(L[k], L)
	return L[k]

def usa(a, b, Y, Z):
	a = fb(a, Y)
	b = fb(b, Y)
	if a != b:
		if Z[a] < Z[b]:
			(a, b) = (b, a)
		Y[b] = a
		Z[a] += Z[b]

def iu():
	import sys
	input = sys.stdin.buffer.readline
	import math as my
	(n, a, b) = mj()
	A = [0] * (n + 1)
	B = [0] * (n + 1)
	C = [0] * (n + 1)
	D = [0] * (n + 1)
	E = []
	F = []
	for i in range(1, n + 1):
		B[i] = 1
		D[i] = 1
		A[i] = i
		C[i] = i
	for i in range(a):
		(u, v) = mj()
		if fb(u, A) != fb(v, A):
			usa(u, v, A, B)
	for i in range(b):
		(p, q) = mj()
		if fb(p, C) != fb(q, C):
			usa(p, q, C, D)
	for i in range(1, n + 1):
		for j in range(1 + i, n + 1):
			if fb(i, C) != fb(j, C) and fb(i, A) != fb(j, A):
				E.append(i)
				F.append(j)
				usa(i, j, C, D)
				usa(i, j, A, B)
	print(len(E))
	for i in range(len(E)):
		print(E[i], F[i])

def main():
	for i in range(1):
		iu()
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


from sys import stdin, stderr

def rl():
	return [int(w) for w in stdin.readline().split()]

def connect(c, u, v):
	if len(c[u]) < len(c[v]):
		(u, v) = (v, u)
	cv = c[v]
	for w in cv:
		c[w] = c[u]
	c[u] += cv
(n, m1, m2) = rl()
c1 = [[i] for i in range(n)]
c2 = [[i] for i in range(n)]
for _ in range(m1):
	(u, v) = rl()
	connect(c1, u - 1, v - 1)
for _ in range(m2):
	(u, v) = rl()
	connect(c2, u - 1, v - 1)
r = []
for u in range(n):
	for v in range(n):
		if c1[u] is c1[v] or c2[u] is c2[v]:
			continue
		connect(c1, u, v)
		connect(c2, u, v)
		r.append((u, v))
print(len(r))
for (u, v) in r:
	print(u + 1, v + 1)


import sys
input = sys.stdin.readline

def I():
	return input().strip()

def II():
	return int(input().strip())

def LI():
	return [*map(int, input().strip().split())]
import copy, string, math, time, functools, random, fractions
from heapq import heappush, heappop, heapify
from bisect import bisect_left, bisect_right
from collections import deque, defaultdict, Counter, OrderedDict
from itertools import permutations, combinations, groupby
from operator import itemgetter
from itertools import chain, combinations

def root(a, parent):
	if a == parent[a]:
		return a
	parent[a] = root(parent[a], parent)
	return parent[a]

def connect(a, b, parent):
	a = root(a, parent)
	b = root(b, parent)
	if a != b:
		parent[b] = a
for _ in range(1):
	(n, m1, m2) = LI()
	d = defaultdict(lambda : True)
	(parA, parB) = ([x for x in range(n)], [x for x in range(n)])
	for i in range(m1):
		(l, r) = LI()
		connect(l - 1, r - 1, parA)
	for i in range(m2):
		(l, r) = LI()
		connect(l - 1, r - 1, parB)
	ans = []
	for i in range(n):
		for j in range(n):
			if i == j:
				continue
			if root(i, parA) != root(j, parA) and root(i, parB) != root(j, parB):
				ans.append((i, j))
				connect(i, j, parA)
				connect(i, j, parB)
	print(len(ans))
	for (i, j) in ans:
		print(i + 1, j + 1)


from sys import stdin, stdout, setrecursionlimit
stdin.readline

def mp():
	return list(map(int, stdin.readline().strip().split()))

def it():
	return int(stdin.readline().strip())
from collections import defaultdict as dd, Counter as C, deque
from math import ceil, gcd, sqrt, factorial, log2, floor
from bisect import bisect_right as br, bisect_left as bl
from heapq import *
mod = 10 ** 9 + 7
inf = 1 << 60

class Dsu:

	def __init__(self, n):
		self.parent = [0] * (n + 1)

	def makeSet(self):
		for i in range(1, n + 1):
			self.parent[i] = i

	def findParent(self, node):
		if node == self.parent[node]:
			return node
		self.parent[node] = self.findParent(self.parent[node])
		return self.parent[node]

	def union(self, u, v):
		u_parent = self.findParent(u)
		v_parent = self.findParent(v)
		if u_parent != v_parent:
			self.parent[v_parent] = u_parent
		else:
			return -1

	def check_component(self, u, v):
		if self.findParent(u) != self.findParent(v):
			print('Both belongs to different components')
		else:
			print('same component')

	def reUnion(self, u, v):
		pass
(n, m1, m2) = mp()
d1 = Dsu(n)
d2 = Dsu(n)
d1.makeSet()
d2.makeSet()
flag = 0
for i in range(m1):
	(u, v) = list(map(int, input().split()))
	if d1.union(u, v) == -1:
		flag = 1
for i in range(m2):
	(u, v) = list(map(int, input().split()))
	if d2.union(u, v) == -1:
		flag = 1
if flag:
	print(0)
	exit()
v = []
for i in range(1, n):
	for j in range(i + 1, n + 1):
		y = d1.findParent(j)
		y1 = d1.findParent(y)
		x = d2.findParent(j)
		x1 = d2.findParent(x)
		if d1.union(i, j) == -1:
			d1.parent[y] = y1
		elif d2.union(i, j) == -1:
			d2.parent[x] = x1
			d1.parent[y] = y1
		else:
			d1.union(i, j)
			d2.union(i, j)
			v.append([i, j])
print(len(v))
for i in range(len(v)):
	print(*v[i])


import typing

class UnionFind:

	def __init__(self, n: int) -> typing.NoReturn:
		self.__a = [-1] * n

	def find(self, u: int) -> int:
		a = self.__a
		if a[u] < 0:
			return u
		a[u] = self.find(a[u])
		return a[u]

	def unite(self, u: int, v: int) -> typing.NoReturn:
		u = self.find(u)
		v = self.find(v)
		if u == v:
			return
		a = self.__a
		if a[u] > a[v]:
			(u, v) = (v, u)
		a[u] += a[v]
		a[v] = u

	def same(self, u: int, v: int) -> bool:
		return self.find(u) == self.find(v)

def solve(n: int, uv1: typing.List[typing.Iterator[int]], uv2: typing.List[typing.Iterator[int]]) -> typing.NoReturn:
	uf1 = UnionFind(n)
	uf2 = UnionFind(n)
	for (u, v) in uv1:
		uf1.unite(u, v)
	for (u, v) in uv2:
		uf2.unite(u, v)
	res = []
	for i in range(n - 1):
		for j in range(i + 1, n):
			if uf1.same(i, j) or uf2.same(i, j):
				continue
			uf1.unite(i, j)
			uf2.unite(i, j)
			res.append((i + 1, j + 1))
	print(len(res))
	for x in res:
		print(*x)

def main() -> typing.NoReturn:
	(n, m1, m2) = map(int, input().split())
	uv1 = [map(lambda x: int(x) - 1, input().split()) for _ in range(m1)]
	uv2 = [map(lambda x: int(x) - 1, input().split()) for _ in range(m2)]
	solve(n, uv1, uv2)
main()


import bisect
import heapq
import math
import collections
import sys
import copy
from functools import reduce
import decimal
from io import BytesIO, IOBase
import os
import itertools
import functools
from types import GeneratorType
sys.setrecursionlimit(10 ** 9)
decimal.getcontext().rounding = decimal.ROUND_HALF_UP
graphDict = collections.defaultdict
queue = collections.deque

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		to = f(*args, **kwargs)
		if stack:
			return to
		else:
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						return to
					to = stack[-1].send(to)
	return wrappedfunc

class Graphs:

	def __init__(self):
		self.graph = graphDict(set)

	def add_edge(self, u, v):
		self.graph[u].add(v)
		self.graph[v].add(u)

	def dfs_utility(self, nodes, visited_nodes):
		visited_nodes.add(nodes)
		for neighbour in self.graph[nodes]:
			if neighbour not in visited_nodes:
				self.dfs_utility(neighbour, visited_nodes)

	def dfs(self, node):
		Visited = set()
		self.dfs_utility(i, Visited)

	def bfs(self, node):
		visited = set()
		if node not in visited:
			queue.append(node)
			visited.add(node)
		while queue:
			parent = queue.popleft()
			print(parent)
			for item in self.graph[parent]:
				if item not in visited:
					queue.append(item)
					visited.add(item)

class Tree:

	def __init__(self, data):
		self.data = data
		self.left = None
		self.right = None

def inorder(node, lis):
	if node:
		inorder(node.left, lis)
		lis.append(node.data)
		inorder(node.right, lis)
	return lis

def leaf_node_sum(root):
	if root is None:
		return 0
	if root.left is None and root.right is None:
		return root.data
	return leaf_node_sum(root.left) + leaf_node_sum(root.right)

def hight(root):
	if root is None:
		return -1
	if root.left is None and root.right is None:
		return 0
	return max(hight(root.left), hight(root.right)) + 1

def rounding(n):
	return int(decimal.Decimal(f'{n}').to_integral_value())

def factors(n):
	return set(reduce(list.__add__, ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0), []))

def p_sum(array):
	return list(itertools.accumulate(array))
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self, **kwargs):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))

def inp():
	return sys.stdin.readline().strip()

def map_inp(v_type):
	return map(v_type, inp().split())

def list_inp(v_type):
	return list(map_inp(v_type))

class UnionFind:
	parents = []
	sizes = []
	count = 0

	def __init__(self, n):
		self.count = n
		self.parents = [i for i in range(n)]
		self.sizes = [1 for i in range(n)]

	def find(self, i):
		if self.parents[i] == i:
			return i
		else:
			self.parents[i] = self.find(self.parents[i])
			return self.parents[i]

	def unite(self, i, j):
		root_i = self.find(i)
		root_j = self.find(j)
		if root_i == root_j:
			return
		elif root_i < root_j:
			self.parents[root_j] = root_i
			self.sizes[root_i] += self.sizes[root_j]
		else:
			self.parents[root_i] = root_j
			self.sizes[root_j] += self.sizes[root_i]

	def same(self, i, j):
		return self.find(i) == self.find(j)

	def size(self, i):
		return self.sizes[self.find(i)]

	def group_count(self):
		return len(set((self.find(i) for i in range(self.count))))
(n, m1, m2) = map_inp(int)
d = UnionFind(n)
m = UnionFind(n)
seen = [False] * n
for i in range(m1):
	(a, b) = map_inp(int)
	d.unite(a - 1, b - 1)
for i in range(m2):
	(a, b) = map_inp(int)
	m.unite(a - 1, b - 1)
can_add = 0
pairs = []
for i in range(n - 1):
	if seen[i]:
		continue
	seen[i] = True
	for j in range(i + 1, n):
		if d.same(i, j) or m.same(i, j):
			continue
		can_add += 1
		d.unite(i, j)
		m.unite(i, j)
		pairs.append([i + 1, j + 1])
		seen[j] = True
print(can_add)
for item in pairs:
	print(*item)


def find_root(x, g):
	if x not in g:
		g[x] = x
		return x
	L = [x]
	while x != g[x]:
		x = g[x]
		L.append(x)
	for y in L:
		g[y] = x
	return x

def process(n, g1, g2):
	roots1 = {}
	roots2 = {}
	for (a, b) in g1:
		if a not in roots1 and b not in roots1:
			roots1[a] = min(a, b)
			roots1[b] = min(a, b)
		elif a not in roots1:
			b1 = find_root(b, roots1)
			roots1[a] = b1
		elif b not in roots1:
			a1 = find_root(a, roots1)
			roots1[b] = a1
		else:
			a1 = find_root(a, roots1)
			b1 = find_root(b, roots1)
			roots1[a1] = b1
	for (a, b) in g2:
		if a not in roots2 and b not in roots2:
			roots2[a] = min(a, b)
			roots2[b] = min(a, b)
		elif a not in roots2:
			b1 = find_root(b, roots2)
			roots2[a] = b1
		elif b not in roots2:
			a1 = find_root(a, roots2)
			roots2[b] = a1
		else:
			a1 = find_root(a, roots2)
			b1 = find_root(b, roots2)
			roots2[a1] = b1
	answer = []
	for i in range(1, n + 1):
		for j in range(i + 1, n + 1):
			r1 = find_root(i, roots1)
			r2 = find_root(i, roots2)
			r3 = find_root(j, roots1)
			r4 = find_root(j, roots2)
			if r1 != r3 and r2 != r4:
				answer.append([i, j])
				roots1[r1] = r3
				roots2[r2] = r4
	return answer
(n, m1, m2) = [int(x) for x in input().split()]
g1 = []
for i in range(m1):
	(u, v) = [int(x) for x in input().split()]
	g1.append([u, v])
g2 = []
for i in range(m2):
	(u, v) = [int(x) for x in input().split()]
	g2.append([u, v])
answer = process(n, g1, g2)
print(len(answer))
for (a, b) in answer:
	print(f'{a} {b}')


import sys
input = sys.stdin.readline

def find(parents, x):
	if parents[x] != x:
		return find(parents, parents[x])
	return x

def union(parents, x, y):
	parent_x = find(parents, x)
	parent_y = find(parents, y)
	parents[parent_y] = parent_x
(n, m1, m2) = map(int, input().split())
parents_a = [i for i in range(n + 1)]
parents_b = [i for i in range(n + 1)]
edges_a = {}
edges_b = {}
for i in range(m1):
	(u, v) = map(int, input().split())
	if u < v:
		(u, v) = (v, u)
	edges_a[u, v] = 0
	union(parents_a, u, v)
for i in range(m2):
	(u, v) = map(int, input().split())
	if u < v:
		(u, v) = (v, u)
	edges_b[u, v] = 0
	union(parents_b, u, v)
c = 0
out = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		(u, v) = (i, j)
		if (u, v) in edges_a or (u, v) in edges_b:
			continue
		x_a = find(parents_a, u)
		y_a = find(parents_a, v)
		x_b = find(parents_b, u)
		y_b = find(parents_b, v)
		if x_a != y_a and x_b != y_b:
			c += 1
			union(parents_a, u, v)
			union(parents_b, u, v)
			out.append((u, v))
print(c)
for i in out:
	print(i[0], i[1])


(n, n1, n2) = map(int, input().split())
rank1 = [0] * n
par1 = [-1] * n
rank2 = [0] * n
par2 = [-1] * n

def find(par, x):
	if par[x] == -1:
		return x
	res = find(par, par[x])
	par[x] = res
	return res
for i in range(n1):
	(x, y) = map(int, input().split())
	a = find(par1, x - 1)
	b = find(par1, y - 1)
	if a != b:
		if rank1[a] < rank1[b]:
			par1[a] = b
		elif rank1[b] < rank1[a]:
			par1[b] = a
		else:
			rank1[b] += 1
			par1[a] = b
for i in range(n2):
	(x, y) = map(int, input().split())
	a = find(par2, x - 1)
	b = find(par2, y - 1)
	if a != b:
		if rank2[a] < rank2[b]:
			par2[a] = b
		elif rank2[a] > rank2[b]:
			par2[b] = a
		else:
			par2[b] = a
			rank2[a] += 1
ans = []
co = 0
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if i != j:
			x = i
			y = j
			a = find(par1, x - 1)
			b = find(par1, y - 1)
			c = find(par2, x - 1)
			d = find(par2, y - 1)
			if a != b and c != d:
				ans.append([i, j])
				co += 1
				if c != d:
					if rank2[c] < rank2[d]:
						par2[c] = d
					elif rank2[c] > rank2[d]:
						par2[d] = c
					else:
						par2[c] = d
						rank2[d] += 1
				if a != b:
					if rank1[a] < rank1[b]:
						par1[a] = b
					elif rank1[b] < rank1[a]:
						par1[b] = a
					else:
						rank1[b] += 1
						par1[a] = b
print(co)
for i in ans:
	print(*i)


(n, m1, m2) = map(int, input().split())
(parent1, parent2) = ([i for i in range(n)], [i for i in range(n)])
(rank1, rank2) = ([0 for x in range(n)], [0 for x in range(n)])

def find1(x):
	if parent1[x] != x:
		parent1[x] = find1(parent1[x])
	return parent1[x]

def find2(x):
	if parent2[x] != x:
		parent2[x] = find2(parent2[x])
	return parent2[x]

def union1(x, y):
	(rootx, rooty) = (find1(x), find1(y))
	if rank1[rooty] < rank1[rootx]:
		parent1[rooty] = rootx
	elif rank1[rooty] > rank1[rootx]:
		parent1[rootx] = rooty
	else:
		parent1[rooty] = rootx
		rank1[rootx] += 1

def union2(x, y):
	(rootx, rooty) = (find2(x), find2(y))
	if rank2[rooty] < rank2[rootx]:
		parent2[rooty] = rootx
	elif rank2[rooty] > rank2[rootx]:
		parent2[rootx] = rooty
	else:
		parent2[rooty] = rootx
		rank2[rootx] += 1
edgeSet1 = set()
edgeSet2 = set()
for edge in range(m1):
	(u, v) = map(int, input().split())
	union1(u - 1, v - 1)
	edgeSet1.add((u - 1, v - 1))
for edge in range(m2):
	(u, v) = map(int, input().split())
	union2(u - 1, v - 1)
	edgeSet2.add((u - 1, v - 1))
count = 0
ans = []
for node1 in range(n):
	for node2 in range(n):
		if find1(node1) != find1(node2):
			if find2(node1) != find2(node2):
				union1(node1, node2)
				union2(node1, node2)
				count += 1
				ans.append((node1 + 1, node2 + 1))
print(count)
for (u, v) in ans:
	print(u, v)


def get(Array, Item):
	if Array[Item] == Item:
		return Item
	Array[Item] = get(Array, Array[Item])
	return Array[Item]

def union(Array, a, b):
	a = get(Array, a)
	b = get(Array, b)
	Array[a] = b
ans = 0
ansl = []
(n, m1, m2) = map(int, input().split(' '))
Mocha = [i for i in range(0, n + 1)]
Diana = [i for i in range(0, n + 1)]
for _ in range(m1):
	(a, b) = map(int, input().split(' '))
	union(Mocha, a, b)
for _ in range(m2):
	(a, b) = map(int, input().split(' '))
	union(Diana, a, b)
for i in range(1, n + 1):
	for i2 in range(1, i):
		if get(Mocha, i) != get(Mocha, i2) and get(Diana, i) != get(Diana, i2):
			ans += 1
			union(Mocha, i, i2)
			union(Diana, i, i2)
			ansl.append(i)
			ansl.append(i2)
print(ans)
if ans != 0:
	for i in range(0, len(ansl), 2):
		print(f'{ansl[i]} {ansl[i + 1]}')


from sys import stdin
input = stdin.readline
(n, m1, m2) = map(int, input().split())
(d1, d2) = (dict(), dict())
for x in range(1, n + 1):
	d1[x] = set()
	d2[x] = set()
for x in range(m1):
	(a, b) = map(int, input().split())
	tmp = d1[a] | d1[b]
	tmp.add(a)
	tmp.add(b)
	for t in tmp:
		d1[t] = tmp
for x in range(m2):
	(a, b) = map(int, input().split())
	tmp = d2[a] | d2[b]
	tmp.add(a)
	tmp.add(b)
	for t in tmp:
		d2[t] = tmp
res = []
for x in range(1, n + 1):
	for y in range(x + 1, n + 1):
		if x not in d1[y] and x not in d2[y]:
			res.append([x, y])
			tmp = d1[x] | d1[y]
			tmp.add(x)
			tmp.add(y)
			for t in tmp:
				d1[t] = tmp
			tmp = d2[x] | d2[y]
			tmp.add(x)
			tmp.add(y)
			for t in tmp:
				d2[t] = tmp
print(len(res))
for (x, y) in res:
	print(x, y)


import random as rnd
(n, m1, m2) = [int(s) for s in input().split()]

def get_root(nodes, node):
	link = nodes[node]['link']
	if link != node:
		root = get_root(nodes, link)
		nodes[node]['link'] = root
		return root
	else:
		return node
nodes1 = [{'link': i, 'rank': 0} for i in range(n)]
nodes2 = [{'link': i, 'rank': 0} for i in range(n)]

def unite(nodes, edge):
	root1 = get_root(nodes, edge[0])
	root2 = get_root(nodes, edge[1])
	if nodes[root1]['rank'] < nodes[root2]['rank']:
		nodes[root1]['link'] = root2
	elif nodes[root1]['rank'] > nodes[root2]['rank']:
		nodes[root2]['link'] = root1
	else:
		nodes[root1]['link'] = root2
		nodes[root2]['rank'] += 1
for _ in range(m1):
	(v1, v2) = [int(s) - 1 for s in input().split()]
	unite(nodes1, (v1, v2))
for _ in range(m2):
	(v1, v2) = [int(s) - 1 for s in input().split()]
	unite(nodes2, (v1, v2))
res = min(n - m1 - 1, n - m2 - 1)
print(res)
while res > 0:
	l = rnd.randint(0, n - 1)
	r = rnd.randint(0, n - 1)
	if l != r:
		if get_root(nodes1, l) != get_root(nodes1, r) and get_root(nodes2, l) != get_root(nodes2, r):
			unite(nodes1, (l, r))
			unite(nodes2, (l, r))
			res -= 1
			print(str(l + 1) + ' ' + str(r + 1))


import sys, os
from io import BytesIO, IOBase
from math import floor, gcd, fabs, factorial, fmod, sqrt, inf, log
from collections import defaultdict as dd, deque
from heapq import merge, heapify, heappop, heappush, nsmallest
from bisect import bisect_left as bl, bisect_right as br, bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(stdin, stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
mod = pow(10, 9) + 7
mod2 = 998244353

def inp():
	return stdin.readline().strip()

def iinp():
	return int(inp())

def out(var, end='\n'):
	stdout.write(str(var) + '\n')

def outa(*var, end='\n'):
	stdout.write(' '.join(map(str, var)) + end)

def lmp():
	return list(mp())

def mp():
	return map(int, inp().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(m, val) for j in range(n)]

def ceil(a, b):
	return (a + b - 1) // b
S1 = 'abcdefghijklmnopqrstuvwxyz'
S2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

def isprime(x):
	if x <= 1:
		return False
	if x in (2, 3):
		return True
	if x % 2 == 0:
		return False
	for i in range(3, int(sqrt(x)) + 1, 2):
		if x % i == 0:
			return False
	return True

class DSU:

	def __init__(self, size):
		self.size = size
		self.rank = [1] * self.size
		self.parent = list(range(size))

	def find(self, ind):
		if self.parent[ind] != ind:
			self.parent[ind] = self.find(self.parent[ind])
		return self.parent[ind]

	def union(self, ind1, ind2):
		p1 = self.find(ind1)
		p2 = self.find(ind2)
		if p1 == p2:
			return
		if self.rank[p1] >= self.rank[p2]:
			self.parent[p2] = p1
			if self.rank[p1] == self.rank[p2]:
				self.rank[p1] += 1
		else:
			self.parent[p1] = p2

def dfs(node, edges, vis, dsu):
	stk = [node]
	while stk:
		node = stk.pop()
		for child in edges[node]:
			if not vis[child]:
				dsu.union(node, child)
				vis[child] = 1
				stk.append(child)
(n, m1, m2) = mp()
edgesA = l2d(n + 1, 0)
edgesB = l2d(n + 1, 0)
for i in range(m1):
	(a, b) = sorted(mp())
	edgesA[a].append(b)
	edgesA[b].append(a)
for i in range(m2):
	(a, b) = sorted(mp())
	edgesB[a].append(b)
	edgesB[b].append(a)
dsuA = DSU(n + 1)
visA = l1d(n + 1)
for i in range(1, n + 1):
	if not visA[i]:
		visA[i] = 1
		dfs(i, edgesA, visA, dsuA)
dsuB = DSU(n + 1)
visB = l1d(n + 1)
for i in range(1, n + 1):
	if not visB[i]:
		visB[i] = 1
		dfs(i, edgesB, visB, dsuB)
ansl = []
for i in range(1, n):
	for j in range(i + 1, n + 1):
		pai = dsuA.find(i)
		paj = dsuA.find(j)
		pbi = dsuB.find(i)
		pbj = dsuB.find(j)
		if pai != paj and pbi != pbj:
			dsuA.union(i, j)
			dsuB.union(i, j)
			ansl.append((i, j))
print(len(ansl))
for i in ansl:
	print(*i)


from sys import stdin
input = lambda : stdin.readline().strip()
lin = lambda : list(map(int, input().split()))
iin = lambda : int(input())
main = lambda : map(int, input().split())
from math import ceil, sqrt, factorial, log
from collections import deque
from bisect import bisect_left
mod = 998244353
mod = 1000000007

def dfs(graph, n):
	visited = [0 for i in range(n + 1)]
	d = []
	for i in range(1, n + 1):
		if visited[i] == 0:
			x = set()
			stack = [i]
			while stack:
				a = stack.pop()
				if visited[a] == 0:
					x.add(a)
					for i in graph[a]:
						if visited[i] == 0:
							stack.append(i)
					visited[a] = 1
			d.append(x)
	return d

def solve(we):
	(n, m1, m2) = main()
	graph1 = {i: [] for i in range(1, n + 1)}
	graph2 = {i: [] for i in range(1, n + 1)}
	for i in range(m1):
		(a, b) = main()
		graph1[a].append(b)
		graph1[b].append(a)
	for i in range(m2):
		(a, b) = main()
		graph2[a].append(b)
		graph2[b].append(a)
	d1 = dfs(graph1, n)
	d2 = dfs(graph2, n)
	a1 = [0 for i in range(n + 1)]
	a2 = [0 for i in range(n + 1)]
	for i in range(len(d1)):
		for j in d1[i]:
			a1[j] = i
	for i in range(len(d2)):
		for j in d2[i]:
			a2[j] = i
	ans = []
	for i in range(1, n + 1):
		for j in range(i + 1, n + 1):
			if a1[i] != a1[j] and a2[i] != a2[j]:
				ans.append([i, j])
				if min(a1[i], a1[j]) == a1[i]:
					for k in d1[a1[j]]:
						a1[k] = a1[i]
				else:
					for k in d1[a1[i]]:
						a1[k] = a1[j]
				if min(a2[i], a2[j]) == a2[i]:
					for k in d2[a2[j]]:
						a2[k] = a2[i]
				else:
					for k in d2[a2[i]]:
						a2[k] = a2[j]
	print(len(ans))
	for i in ans:
		print(*i)
qwe = 1
for _ in range(qwe):
	solve(_ + 1)


def var():
	return map(int, input().split())

def a():
	return list(map(int, input().split()))
import math
import copy
from collections import defaultdict, deque
(n, m1, m2) = var()

def find_parent(x, parent):
	if parent[x] == -1:
		return x
	parent[x] = find_parent(parent[x], parent)
	return parent[x]

def union(p_x, p_y, parent, rank):
	if rank[p_x] > rank[p_y]:
		parent[p_y] = p_x
	elif rank[p_x] < rank[p_y]:
		parent[p_x] = p_y
	else:
		parent[p_x] = p_y
		rank[p_y] += 1
parent1 = [-1] * (n + 1)
rank1 = [0] * (n + 1)
parent2 = [-1] * (n + 1)
rank2 = [0] * (n + 1)
dic = defaultdict(set)
for i in range(m1):
	(x, y) = var()
	p_x = find_parent(x, parent1)
	p_y = find_parent(y, parent1)
	dic[x].add(y)
	dic[y].add(x)
	union(p_x, p_y, parent1, rank1)
for i in range(m2):
	(x, y) = var()
	dic[x].add(y)
	dic[y].add(x)
	p_x = find_parent(x, parent2)
	p_y = find_parent(y, parent2)
	union(p_x, p_y, parent2, rank2)
count = 0
ans = []
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if i != j and j not in dic[i]:
			p_x1 = find_parent(i, parent1)
			p_y1 = find_parent(j, parent1)
			p_x2 = find_parent(i, parent2)
			p_y2 = find_parent(j, parent2)
			if p_x1 == p_y1 or p_x2 == p_y2:
				continue
			count += 1
			union(p_x1, p_y1, parent1, rank1)
			union(p_x2, p_y2, parent2, rank2)
			dic[i].add(j)
			dic[j].add(i)
			ans.append([i, j])
if count:
	print(count)
	for i in ans:
		print(i[0], i[1])
else:
	print(0)


class UnoinFind(object):

	def __init__(self, n):
		self.__findset = [i for i in range(n + 1)]
		self.__rank = [1 for i in range(n + 1)]

	def find(self, x):
		if self.__findset[x] != x:
			self.__findset[x] = self.find(self.__findset[x])
		return self.__findset[x]

	def union(self, p, q):
		p_root = self.find(p)
		q_root = self.find(q)
		if self.__rank[p_root] < self.__rank[q_root]:
			self.__findset[p_root] = q_root
		elif self.__rank[p_root] > self.__rank[q_root]:
			self.__findset[q_root] = p_root
		else:
			self.__findset[p_root] = q_root
			self.__rank[q_root] += 1

	def is_connected(self, p, q):
		if self.find(p) == self.find(q):
			return True
		return False
(n, m1, m2) = map(int, input().split())
U1 = UnoinFind(n)
U2 = UnoinFind(n)
for _ in range(m1):
	(u, v) = map(int, input().split())
	U1.union(u, v)
for _ in range(m2):
	(u, v) = map(int, input().split())
	U2.union(u, v)
ans = []
for i in range(1, n):
	for j in range(i + 1, n + 1):
		if not (U1.is_connected(i, j) or U2.is_connected(i, j)):
			ans.append((i, j))
			U1.union(i, j)
			U2.union(i, j)
print(len(ans))
for pair in ans:
	print(*pair)


import sys
input = sys.stdin.readline

def get_root(s):
	v = []
	while not s == root[s]:
		v.append(s)
		s = root[s]
	for i in v:
		root[i] = s
	return s

def unite(s, t):
	(rs, rt) = (get_root(s), get_root(t))
	if not rs ^ rt:
		return
	if rank[s] == rank[t]:
		rank[rs] += 1
	if rank[s] >= rank[t]:
		root[rt] = rs
		size[rs] += size[rt]
	else:
		root[rs] = rt
		size[rt] += size[rs]
	return

def same(s, t):
	return True if get_root(s) == get_root(t) else False
(n, m1, m2) = map(int, input().split())
root = [i for i in range(2 * n + 1)]
rank = [1 for _ in range(2 * n + 1)]
size = [1 for _ in range(2 * n + 1)]
for _ in range(m1):
	(u, v) = map(int, input().split())
	unite(u, v)
for _ in range(m2):
	(u, v) = map(int, input().split())
	unite(u + n, v + n)
h = 0
ans = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if not same(i, j) and (not same(i + n, j + n)):
			h += 1
			unite(i, j)
			unite(i + n, j + n)
			ans.append((i, j))
print(h)
for (u, v) in ans:
	print(u, v)


from collections import deque
import heapq
from math import sqrt
import operator
from operator import itemgetter
import sys
import copy
inf_var = 0
if inf_var == 1:
	inf = open('input.txt', 'r')
else:
	inf = sys.stdin
input = inf.readline

def read_one_int():
	return int(input().rstrip('\n'))

def read_one_float():
	return float(input().rstrip('\n'))

def read_list_of_ints():
	res = [int(val) for val in input().rstrip('\n').split(' ')]
	return res

def read_str():
	return input().rstrip()

def find_set(parents, v):
	if parents[v] == v:
		return v
	parents[v] = find_set(parents, parents[v])
	return parents[v]

def union_sets(a, b, sizes, parents):
	if sizes[a] < sizes[b]:
		(a, b) = (b, a)
	sizes[a] += sizes[b]
	parents[b] = a

def main():
	(vert_cnt, edges_1_cnt, edges_2_cnt) = read_list_of_ints()
	dsu_1 = [i for i in range(vert_cnt)]
	sizes_1 = [1] * vert_cnt
	dsu_2 = [i for i in range(vert_cnt)]
	sizes_2 = [1] * vert_cnt
	for _ in range(edges_1_cnt):
		(u, v) = read_list_of_ints()
		v = find_set(dsu_1, v - 1)
		u = find_set(dsu_1, u - 1)
		union_sets(v, u, sizes_1, dsu_1)
	for _ in range(edges_2_cnt):
		(u, v) = read_list_of_ints()
		v = find_set(dsu_2, v - 1)
		u = find_set(dsu_2, u - 1)
		union_sets(v, u, sizes_2, dsu_2)
	edges = []
	for i in range(vert_cnt - 1):
		for j in range(i + 1, vert_cnt):
			a1 = find_set(dsu_1, i)
			b1 = find_set(dsu_1, j)
			if a1 != b1:
				a2 = find_set(dsu_2, i)
				b2 = find_set(dsu_2, j)
				if a2 != b2:
					union_sets(a1, b1, sizes_1, dsu_1)
					union_sets(a2, b2, sizes_2, dsu_2)
					edges.append((i + 1, j + 1))
	print(len(edges))
	for edge in edges:
		print(' '.join(map(str, edge)))
main()


def find_set(v, parent):
	if v == parent[v]:
		return v
	parent[v] = find_set(parent[v], parent)
	return parent[v]

def union_set(a, b, size, parent):
	a = find_set(a, parent)
	b = find_set(b, parent)
	if a != b:
		(a, b) = (b, a)
	parent[b] = a
	size[a] = size[a] + size[b]
(n, m1, m2) = map(int, input().split())
a1 = [i for i in range(n + 1)]
sz1 = [1 for i in range(n + 1)]
a2 = [i for i in range(n + 1)]
sz2 = [1 for i in range(n + 1)]
for i in range(m1):
	(a, b) = map(int, input().split())
	union_set(a, b, sz1, a1)
for i in range(m2):
	(a, b) = map(int, input().split())
	union_set(a, b, sz2, a2)
fn = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		p = find_set(i, a1)
		q = find_set(j, a1)
		r = find_set(i, a2)
		s = find_set(j, a2)
		if p != q and r != s:
			fn.append([i, j])
			union_set(i, j, sz1, a1)
			union_set(i, j, sz2, a2)
print(len(fn))
for i in fn:
	print(*i)


import math
from collections import *
from bisect import *
from heapq import *

def findPar(node, parent):
	if node != parent[node]:
		parent[node] = findPar(parent[node], parent)
	return parent[node]

def union(u, v, rank, parent):
	u = findPar(u, parent)
	v = findPar(v, parent)
	if u == v:
		return
	if rank[u] == rank[v]:
		parent[u] = v
		rank[v] += 1
	elif rank[u] < rank[v]:
		parent[u] = v
	else:
		parent[v] = u
(n, m1, m2) = map(int, input().split())
parent1 = [i for i in range(n + 1)]
rank1 = [0] * (n + 1)
parent2 = [i for i in range(n + 1)]
rank2 = [0] * (n + 1)
for i in range(m1):
	(u, v) = map(int, input().split())
	union(u, v, rank1, parent1)
for i in range(m2):
	(u, v) = map(int, input().split())
	union(u, v, rank2, parent2)
cnt = 0
ans = []
for i in range(1, n):
	for j in range(i + 1, n + 1):
		if findPar(i, parent1) != findPar(j, parent1) and findPar(i, parent2) != findPar(j, parent2):
			union(i, j, rank1, parent1)
			union(i, j, rank2, parent2)
			cnt += 1
			ans.append([i, j])
print(cnt)
for elm in ans:
	print(elm[0], end=' ')
	print(elm[1])


def gcd(a, b):
	return b if a == 0 else gcd(b % a, a)

def lcm(a, b):
	return a / gcd(a, b) * b
mini = 100000
tests = 1
mod = 10 ** 9 + 7

def getParent(d, i):
	if d[i] == -1:
		return i
	else:
		return getParent(d, d[i])
while tests:
	tests -= 1
	a = {}
	b = {}
	arr = list(map(int, input().split()))
	(n, m1, m2) = (arr[0], arr[1], arr[2])
	for i in range(n):
		a[i + 1] = -1
		b[i + 1] = -1
	while m1:
		m1 -= 1
		arr = list(map(int, input().split()))
		(a1, b1) = (arr[0], arr[1])
		a[getParent(a, max(a1, b1))] = getParent(a, min(a1, b1))
	while m2:
		m2 -= 1
		arr = list(map(int, input().split()))
		(a1, b1) = (arr[0], arr[1])
		b[getParent(b, max(a1, b1))] = getParent(b, min(a1, b1))
	ct = 0
	ans = []
	for i in range(1, n + 1):
		for j in range(i + 1, n + 1):
			if i != j and (a[i] == -1 or b[i] == -1):
				pia = getParent(a, i)
				pja = getParent(a, j)
				pib = getParent(b, i)
				pjb = getParent(b, j)
				if (pia != pja or (pia == -1 and pja == -1)) and (pib != pjb or (pib == -1 and pjb == -1)):
					a[getParent(a, max(i, j))] = getParent(a, min(i, j))
					b[getParent(b, max(i, j))] = getParent(b, min(i, j))
					ans.append([i, j])
	print(len(ans))
	for i in ans:
		print(i[0], i[1])


import sys, io, os
BUFSIZE = 8192

class FastIO(io.IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = io.BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(io.IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
MOD = 1000000007
from collections import defaultdict as dd, Counter, deque

def si():
	return input()

def ii():
	return int(input())

def li():
	return list(map(int, input().split()))

def mi():
	return map(int, input().split())

def sout(v):
	print(v, end=' ')

def d2b(n):
	return bin(n).replace('0b', '')

def twod(n, m, num):
	return [[num for x in range(m)] for y in range(n)]

def vow():
	return ['a', 'e', 'i', 'o', 'u']

def let():
	return [chr(i) for i in range(97, 123)]

def gcd(x, y):
	while y:
		(x, y) = (y, x % y)
	return x

def ispow2(x):
	return x and (not x & x - 1)

def prime_factors(n):
	i = 2
	factors = []
	while i * i <= n:
		if n % i:
			i += 1
		else:
			n //= i
			factors.append(i)
	if n > 1:
		factors.append(n)
	return list(factors)

def binary_search(arr, low, high, x):
	if high >= low:
		mid = (high + low) // 2
		if arr[mid] == x:
			return mid
		elif arr[mid] > x:
			return binary_search(arr, low, mid - 1, x)
		else:
			return binary_search(arr, mid + 1, high, x)
	else:
		return -1

def sieve(n):
	primes = []
	least_prime_divs = [0] * (n + 1)
	for i in range(2, n + 1):
		if not least_prime_divs[i]:
			least_prime_divs[i] = i
			primes.append(i)
		for p in primes:
			if i * p > n or p > least_prime_divs[i]:
				break
			least_prime_divs[i * p] = p
	return primes

def parent(per, vis, par, arr):
	for i in range(1, n + 1):
		if not vis[i]:
			arr[0] = 1
			dfs(per, vis, i, par, i, arr)
			par[i] = -1 * arr[0]

def dfs(g, vis, s, par, source, arr):
	vis[s] = True
	for i in g[s]:
		if not vis[i]:
			par[i] = source
			arr[0] += 1
			dfs(g, vis, i, par, source, arr)

def Find(node, par):
	if par[node] < 0:
		return node
	a = Find(par[node], par)
	return a

def Union(par, node, mainParent):
	par[mainParent] += par[node]
	par[node] = mainParent
(n, m1, m2) = mi()
mo = dd(list)
di = dd(list)
vism = [False for _ in range(n + 1)]
visd = [False for _ in range(n + 1)]
parm = [-1 for _ in range(n + 1)]
pard = [-1 for _ in range(n + 1)]
for _ in range(m1):
	(x, y) = mi()
	mo[x].append(y)
	mo[y].append(x)
for _ in range(m2):
	(x, y) = mi()
	di[x].append(y)
	di[y].append(x)
arr = [1]
parent(mo, vism, parm, arr)
parent(di, visd, pard, arr)
ans = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		par1 = Find(i, parm)
		par2 = Find(j, parm)
		if parm[i] > 0:
			parm[i] = par1
		if parm[j] > 0:
			parm[j] = par2
		if par1 != par2:
			par3 = Find(i, pard)
			par4 = Find(j, pard)
			if pard[i] > 0:
				pard[i] = par3
			if pard[j] > 0:
				pard[j] = par4
			if par3 != par4:
				ans.append([i, j])
				if abs(parm[par1]) > abs(parm[par2]):
					Union(parm, par2, par1)
				else:
					Union(parm, par1, par2)
				if abs(pard[par3]) > abs(pard[par4]):
					Union(pard, par4, par3)
				else:
					Union(pard, par3, par4)
print(len(ans))
for i in range(len(ans)):
	print(*ans[i])


import collections as _collections
import random as _random
import sys as _sys

def _main():
	[tests_n] = [1]
	for i_test in range(tests_n):
		[n, m_1, m_2] = _read_ints()
		edges_1 = tuple(_read_n_egdes(m_1))
		edges_2 = tuple(_read_n_egdes(m_2))
		random = _random.Random(_random.SystemRandom().getrandbits(256))
		new_edges = add_max_edges_n(n, edges_1, edges_2, random=random)
		print(len(new_edges))
		for (u, v) in new_edges:
			print(u + 1, v + 1)

def add_max_edges_n(nodes_n, edges_1, edges_2, *, random):
	colors_1 = DSU.from_equivalence_relations(edges_1, nodes_n=nodes_n)
	colors_2 = DSU.from_equivalence_relations(edges_2, nodes_n=nodes_n)
	del edges_1, edges_2
	new_edges = _try_add_random_edges(nodes_n, colors_1, colors_2, random, max_failed_attempts_n=16)
	for u in range(nodes_n):
		for v in range(u + 1, nodes_n):
			if not colors_1.is_same_owner(u, v) and (not colors_2.is_same_owner(u, v)):
				new_edges.append((u, v))
				colors_1.merge_owners(u, v)
				colors_2.merge_owners(u, v)
	return new_edges

def _try_add_random_edges(nodes_n, colors_1, colors_2, random, *, max_failed_attempts_n):
	new_edges = []
	failed_attempts_n = 0
	while min(colors_1.get_owners_n(), colors_2.get_owners_n()) > 1 and failed_attempts_n < max_failed_attempts_n:
		curr_colors = random.choice([colors_1, colors_2])
		owner_1 = curr_colors.choose_random_owner(random)
		owner_2 = None
		while owner_2 is None or owner_2 == owner_1:
			owner_2 = curr_colors.choose_random_owner(random)
		u = random.choice(curr_colors.get_group_by_owner(owner_1))
		v = random.choice(curr_colors.get_group_by_owner(owner_1))
		if not colors_1.is_same_owner(u, v) and (not colors_2.is_same_owner(u, v)):
			new_edges.append((u, v))
			colors_1.merge_owners(u, v)
			colors_2.merge_owners(u, v)
			failed_attempts_n = 0
		else:
			failed_attempts_n += 1
	return new_edges

class DSU:

	def __init__(self, nodes_n):
		self._parents = list(range(nodes_n))
		self._owners = ChoosableSet(self._parents)
		self._groups_by_owners = {owner: [owner] for owner in self._parents}

	def _is_owner(self, node):
		return node == self._parents[node]

	def _get_owner(self, node):
		to_fix = []
		while not self._is_owner(node):
			to_fix.append(node)
			node = self._parents[node]
		for x in to_fix:
			self._parents[x] = node
		return node

	def is_same_owner(self, node_1, node_2):
		return self._get_owner(node_1) == self._get_owner(node_2)

	def merge_owners(self, node_1, node_2):
		node_1 = self._get_owner(node_1)
		node_2 = self._get_owner(node_2)
		assert node_1 != node_2
		self._parents[node_2] = node_1
		self._owners.discard(node_2)
		old_groups = [self._groups_by_owners[node_1], self._groups_by_owners[node_2]]
		del self._groups_by_owners[node_1], self._groups_by_owners[node_2]
		(lower_group, higher_group) = sorted(old_groups, key=len)
		higher_group.extend(lower_group)
		lower_group.clear()
		self._groups_by_owners[node_1] = higher_group

	def get_group_by_owner(self, owner):
		return self._groups_by_owners[owner]

	def get_owners_n(self):
		return len(self._owners)

	def choose_random_owner(self, random):
		return self._owners.choice(random)

	@classmethod
	def from_equivalence_relations(cls, equivalence_relations, *, nodes_n):
		self = cls(nodes_n)
		for (u, v) in equivalence_relations:
			if not self.is_same_owner(u, v):
				self.merge_owners(u, v)
		return self

class ChoosableSet:

	def __init__(self, initial_elements=()):
		self._elements_as_set = set(initial_elements)
		self._elements_as_list = list(self._elements_as_set)
		self._removed = set()

	def __len__(self):
		return len(self._elements_as_set) - len(self._removed)

	def add(self, element):
		self._removed.discard(element)
		if element not in self._elements_as_set:
			self._elements_as_set.add(element)
			self._elements_as_list.append(element)

	def discard(self, element):
		self._removed.add(element)
		if len(self._removed) * 2 > len(self._elements_as_set):
			self._elements_as_set -= self._removed
			self._elements_as_list = [x for x in self._elements_as_list if x not in self._removed]
			self._removed = set()

	def choice(self, random):
		result = random.choice(self._elements_as_list)
		while result in self._removed:
			result = random.choice(self._elements_as_list)
		return result

def _read_n_egdes(edges_n):
	edges = (_read_ints() for i_edge in range(edges_n))
	edges = ((u - 1, v - 1) for (u, v) in edges)
	return edges

def _read_ints():
	return map(int, _read_string().split())

def _read_string():
	result = _sys.stdin.readline()
	assert result and result[-1] == '\n'
	return result[:-1]
_main()


from sys import stdin, setrecursionlimit
input = stdin.readline
setrecursionlimit(10 ** 5)

def dfs(p, num, adj, c):
	c[p] = num
	for i in adj[p]:
		if c[i] == 0:
			dfs(i, num, adj, c)

def answer():
	num1 = 1
	for i in range(n):
		if c1[i + 1] == 0:
			dfs(i + 1, num1, adj1, c1)
			num1 += 1
	num2 = 1
	for i in range(n):
		if c2[i + 1] == 0:
			dfs(i + 1, num2, adj2, c2)
			num2 += 1
	ans = []
	for i in range(1, n + 1):
		for j in range(i + 1, n + 1):
			if c1[i] != c1[j] and c2[i] != c2[j]:
				ans.append([i, j])
				temp1 = c1[j]
				temp2 = c2[j]
				for x in range(n + 1):
					if c1[x] == temp1:
						c1[x] = c1[i]
					if c2[x] == temp2:
						c2[x] = c2[i]
	print(len(ans))
	for x in ans:
		print(*x)
for T in range(1):
	(n, m1, m2) = map(int, input().split())
	adj1 = [[] for i in range(n + 1)]
	for i in range(m1):
		(u, v) = map(int, input().split())
		adj1[u].append(v)
		adj1[v].append(u)
	adj2 = [[] for i in range(n + 1)]
	for j in range(m2):
		(u, v) = map(int, input().split())
		adj2[u].append(v)
		adj2[v].append(u)
	c1 = [0] * (n + 1)
	c2 = [0] * (n + 1)
	answer()


import math, os, io
from sys import stdin, stdout
from collections import Counter, deque, defaultdict
from itertools import product

class UnionFind:

	def __init__(self, n):
		self.arr = [i for i in range(n + 1)]
		self.rank = [0] * (n + 1)
		self.n = n

	def find(self, v):
		if self.arr[v] != v:
			self.arr[v] = self.find(self.arr[v])
		return self.arr[v]

	def union(self, u, v):
		(pu, pv) = (self.find(u), self.find(v))
		if pu == pv:
			return
		if self.rank[pu] > self.rank[pv]:
			self.arr[pv] = pu
		elif self.rank[pv] > self.rank[pu]:
			self.arr[pu] = pv
		else:
			self.arr[pu] = pv
			self.rank[pu] += 1

def getList(method=int):
	return list(map(method, input().split()))

def getInt():
	return int(input())

def solve():
	(n, m1, m2) = getList()
	(mdsu, ddsu) = (UnionFind(n), UnionFind(n))
	for i in range(m1):
		(u, v) = getList()
		mdsu.union(u, v)
	for i in range(m2):
		(u, v) = getList()
		ddsu.union(u, v)
	ans = []
	for i in range(1, n + 1):
		for j in range(i + 1, n + 1):
			if mdsu.find(i) != mdsu.find(j) and ddsu.find(i) != ddsu.find(j):
				ans.append((i, j))
				mdsu.union(i, j)
				ddsu.union(i, j)
	print(len(ans))
	for (u, v) in ans:
		print(u, v)
solve()


import sys
from sys import stdin
from bisect import bisect_left, bisect_right
from collections import defaultdict, deque, namedtuple
from math import gcd, ceil, floor
from itertools import combinations, permutations

def find(p, x):
	if p[x] != x:
		p[x] = find(p, p[x])
	return p[x]

def main():
	(n, m1, m2) = map(int, input().split())
	p1 = [i for i in range(n)]
	for i in range(m1):
		(a, b) = map(int, input().split())
		a -= 1
		b -= 1
		(x, y) = (find(p1, a), find(p1, b))
		if x != y:
			p1[y] = x
	p2 = [i for i in range(n)]
	for i in range(m2):
		(a, b) = map(int, input().split())
		a -= 1
		b -= 1
		(x, y) = (find(p2, a), find(p2, b))
		if x != y:
			p2[y] = x
	for i in range(n):
		find(p1, i)
		find(p2, i)
	ans = 0
	es = []
	for i in range(n):
		for j in range(n):
			if i == j:
				continue
			x1 = find(p1, i)
			y1 = find(p1, j)
			if x1 == y1:
				continue
			x2 = find(p2, i)
			y2 = find(p2, j)
			if x2 == y2:
				continue
			p1[y1] = x1
			p2[y2] = x2
			ans += 1
			es.append([i, j])
	print(ans)
	for (a, b) in es:
		print(f'{a + 1} {b + 1}')
	return
main()


import math
import os
import sys
from sys import *
from decimal import *
from io import BytesIO, IOBase
from itertools import accumulate, combinations, permutations, combinations_with_replacement, product
from collections import *
import random
M = 10 ** 9 + 7
import heapq
import bisect
from functools import lru_cache
from queue import PriorityQueue
if sys.version_info[0] < 3:
	from __builtin__ import xrange as range
	from future_builtins import ascii, filter, hex, map, oct, zip
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def fsep():
	return map(float, inp().split())

def inpu():
	return int(inp())

def luckynumber(x, n, a):
	if x > 0:
		a.append(x)
	if x > 10 ** 9:
		return a
	elif x < 1000000000000.0:
		luckynumber(x * 10 + 4, n, a)
		luckynumber(x * 10 + 7, n, a)

def lcm(a, b):
	return a * b // math.gcd(a, b)

def query1(l, r):
	if l >= r:
		return -1
	print('?', l + 1, r + 1)
	sys.stdout.flush()
	return int(input()) - 1

def answer(p):
	print('!', p + 1)
	sys.stdout.flush()
	exit()

def rse(arr, n):
	stack = []
	ans = []
	for i in range(n - 1, -1, -1):
		if len(stack) == 0:
			ans.append(n)
		else:
			while len(stack) != 0:
				if stack[-1][0] >= arr[i]:
					stack.pop()
				else:
					break
			if len(stack) == 0:
				ans.append(n)
			else:
				ans.append(stack[-1][1])
		stack.append([arr[i], i])
	ans.reverse()
	return ans

def lse(arr, n):
	stack = []
	ans = []
	for i in range(n):
		if len(stack) == 0:
			ans.append(-1)
		else:
			while len(stack) != 0:
				if stack[-1][0] >= arr[i]:
					stack.pop()
				else:
					break
			if len(stack) == 0:
				ans.append(-1)
			else:
				ans.append(stack[-1][1])
		stack.append([arr[i], i])
	return ans

def mah(arr):
	max1 = 0
	p = rse(arr, len(arr))
	q = lse(arr, len(arr))
	for i in range(len(arr)):
		a = (p[i] - q[i] - 1) * arr[i]
		max1 = max(a, max1)
	return max1

def maxSumIS(arr, n):
	msis = arr.copy()
	for i in range(1, n):
		for j in range(i):
			if arr[i] > arr[j] and msis[i] < msis[j] + arr[i]:
				msis[i] = msis[j] + arr[i]
	c = max(msis)
	p = 5
	return c

def binarysearch2(arr, target):
	lo = 0
	hi = len(arr) - 1
	while lo <= hi:
		mid = (lo + hi) // 2
		if arr[mid] == target:
			if mid != len(arr) - 1:
				if arr[mid + 1] != target:
					return mid
				else:
					lo += 1
			else:
				return mid
			continue
		if arr[mid] > target:
			hi = mid - 1
		else:
			lo = mid + 1

def nge(arr, n):
	stack = []
	ans = []
	for i in range(n - 1, -1, -1):
		if len(stack) == 0:
			ans.append(-1)
		else:
			while len(stack) > 0:
				if stack[-1][0] < arr[i]:
					stack.pop()
				else:
					break
			if len(stack) == 0:
				ans.append(-1)
			else:
				ans.append(stack[-1][1])
		stack.append([arr[i], i])
	ans.reverse()
	return ans

def alperm(nums, path, result):
	if not nums:
		result.add(tuple(path))
		return
	for i in range(0, len(nums)):
		alperm(nums[:i] + nums[i + 1:], path + [nums[i]], result)
	return result

def minsum(arr, n, m, res, l):
	if n == 1 and m == 1:
		res += arr[0][0]
		l.append(res)
	else:
		if n != 1:
			p = res + arr[n - 1][m - 1]
			minsum(arr, n - 1, m, p, l)
		if m != 1:
			p = res + arr[n - 1][m - 1]
			minsum(arr, n, m - 1, p, l)
	return min(l)

def find_shortest_path(graph, start, end, path):
	path = path + [start]
	if start == end:
		return path
	if start not in graph:
		return None
	shortest = None
	for node in graph[start]:
		if node not in path:
			newpath = find_shortest_path(graph, node, end, path)
			if newpath:
				if not shortest or len(newpath) < len(shortest):
					shortest = newpath
	return shortest

def find(arr, i):
	while i != arr[i]:
		i = arr[i]
		arr[i] = arr[arr[i]]
	return i

def union(i, j, parent):
	(u, v) = (find(parent, i), find(parent, j))
	if u != v:
		parent[u] = v

def main():
	t = 1
	for _ in range(t):
		(n, m1, m2) = map(int, input().split())
		arr1 = [i for i in range(n + 1)]
		arr2 = [j for j in range(n + 1)]
		for i in range(m1):
			(u, v) = sep()
			union(u, v, arr1)
		for i in range(m2):
			(u, v) = sep()
			union(u, v, arr2)
		ans = 0
		l = []
		for i in range(1, n + 1):
			for j in range(i + 1, n + 1):
				if find(arr1, i) != find(arr1, j) and find(arr2, i) != find(arr2, j):
					union(i, j, arr1)
					union(i, j, arr2)
					ans += 1
					l.append([i, j])
		print(ans)
		for i in l:
			print(*i)
main()


import os
import sys
from io import BytesIO, IOBase
import math
from collections import Counter

def update_node(node, val, edges):
	while True:
		tmp = edges[node]
		edges[node] = find_root(val, edges)
		if node == edges[node]:
			break
		node = tmp

def find_root(node, edges):
	while node != edges[node]:
		node = edges[node]
	return node

def func(n, m1_edges, m2_edges):
	result = []
	for i in range(1, n + 1):
		for j in range(i + 1, n + 1):
			val1 = find_root(i, m1_edges)
			val2 = find_root(j, m1_edges)
			val3 = find_root(i, m2_edges)
			val4 = find_root(j, m2_edges)
			if val1 != val2 and val3 != val4:
				result.append([i, j])
				if val1 > val2:
					update_node(i, j, m1_edges)
				else:
					update_node(j, i, m1_edges)
				if val3 > val4:
					update_node(i, j, m2_edges)
				else:
					update_node(j, i, m2_edges)
	print(len(result))
	for val in result:
		print(val[0], val[1])

def main():
	(n, m1, m2) = [int(i) for i in parse_input().split()]
	m1_edges = {}
	for i in range(1, n + 1):
		m1_edges[i] = i
	m2_edges = {}
	for i in range(1, n + 1):
		m2_edges[i] = i
	for i in range(m1):
		array = [int(i) for i in parse_input().split()]
		if m1_edges[array[1]] > m1_edges[array[0]]:
			update_node(array[1], array[0], m1_edges)
		elif m1_edges[array[1]] < m1_edges[array[0]]:
			update_node(array[0], array[1], m1_edges)
	for i in range(m2):
		array = [int(i) for i in parse_input().split()]
		if m2_edges[array[1]] > m2_edges[array[0]]:
			update_node(array[1], array[0], m2_edges)
		elif m2_edges[array[1]] < m2_edges[array[0]]:
			update_node(array[0], array[1], m2_edges)
	func(n, m1_edges, m2_edges)
parse_input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import os.path
from math import gcd, floor, ceil
from collections import *
import sys
mod = 1000000007
INF = float('inf')

def st():
	return list(sys.stdin.readline().strip())

def li():
	return list(map(int, sys.stdin.readline().split()))

def mp():
	return map(int, sys.stdin.readline().split())

def inp():
	return int(sys.stdin.readline())

def pr(n):
	return sys.stdout.write(str(n) + '\n')

def prl(n):
	return sys.stdout.write(str(n) + ' ')
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')

def find(a, par):
	x = []
	while a != par[a]:
		x.append(a)
		a = par[a]
	for i in x:
		par[i] = a
	return a

def merge(X, Y, par, size):
	if X == Y:
		return 0
	if size[X] > size[Y]:
		par[Y] = X
		size[X] += size[Y]
	else:
		par[X] = Y
		size[Y] += size[X]
	return 1
(n, m1, m2) = mp()
par1 = {i: i for i in range(1, n + 1)}
par2 = dict(par1)
size1 = [1] * (n + 1)
size2 = list(size1)
for i in range(m1):
	(a, b) = mp()
	merge(find(a, par1), find(b, par1), par1, size1)
for i in range(m2):
	(a, b) = mp()
	merge(find(a, par2), find(b, par2), par2, size2)
ans = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		A = find(i, par1)
		B = find(j, par1)
		C = find(i, par2)
		D = find(j, par2)
		if A != B and C != D:
			merge(A, B, par1, size1)
			merge(C, D, par2, size2)
			ans.append((i, j))
pr(len(ans))
for i in ans:
	print(*i)


import sys
input = sys.stdin.readline

def find(x):
	if x != path[x]:
		path[x] = find(path[x])
	return path[x]

def union(x, y):
	path[find(x)] = find(y)
(n, m1, m2) = map(int, input().split())
(path, ans) = ([i for i in range(n * 2 + 1)], [])
for _ in range(m1):
	(u, v) = map(int, input().split())
	union(u, v)
for _ in range(m2):
	(u, v) = map(int, input().split())
	(u, v) = (u + n, v + n)
	union(u, v)
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if find(i) != find(j) and find(i + n) != find(j + n):
			ans.append([i, j])
			union(i, j)
			union(i + n, j + n)
print(len(ans))
for edge in ans:
	print(*edge)


import sys
from math import ceil, floor, modf, sqrt
from collections import deque
from heapq import heappush, heappop, heapify

def get_ints():
	return map(int, sys.stdin.readline().strip().split())

def get_array():
	return list(get_ints())

def input():
	return sys.stdin.readline().strip()

def gcd(x, y):
	while y:
		(x, y) = (y, x % y)
	return x

class DisjointSetUnion:

	def __init__(self, n):
		self.parent = list(range(n))
		self.size = [1] * n
		self.num_sets = n

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		(a, b) = (self.find(a), self.find(b))
		if a != b:
			if self.size[a] < self.size[b]:
				(a, b) = (b, a)
			self.num_sets -= 1
			self.parent[b] = a
			self.size[a] += self.size[b]

	def set_size(self, a):
		return self.size[self.find(a)]

	def __len__(self):
		return self.num_sets
(n, m1, m2) = get_ints()
dsu1 = DisjointSetUnion(n)
dsu2 = DisjointSetUnion(n)
for i in range(m1):
	(a, b) = get_ints()
	a -= 1
	b -= 1
	dsu1.union(a, b)
for i in range(m2):
	(a, b) = get_ints()
	a -= 1
	b -= 1
	dsu2.union(a, b)
ans = []
count = 0
for i in range(0, n):
	for j in range(i + 1, n):
		if dsu1.find(i) != dsu1.find(j) and dsu2.find(i) != dsu2.find(j):
			count += 1
			ans.append([i + 1, j + 1])
			dsu1.union(i, j)
			dsu2.union(i, j)
print(count)
for i in ans:
	print(*i)


from sys import stdin
input = stdin.readline

class dsu:

	def __init__(self, n):
		self.p = [0] * (n + 1)
		self.rank = [0] * (n + 1)
		for i in range(1, n + 1):
			self.p[i] = i

	def find(self, node):
		if self.p[node] == node:
			return node
		self.p[node] = self.find(self.p[node])
		return self.p[node]

	def union(self, u, v):
		(u, v) = (self.find(u), self.find(v))
		if self.rank[u] == self.rank[v]:
			self.p[v] = u
			self.rank[u] += 1
		elif self.rank[u] > self.rank[v]:
			self.p[v] = u
		else:
			self.p[u] = v

def answer():
	a = dsu(n)
	for i in range(m1):
		(u, v) = map(int, input().split())
		a.union(u, v)
	b = dsu(n)
	for i in range(m2):
		(u, v) = map(int, input().split())
		b.union(u, v)
	ans = []
	for i in range(1, n + 1):
		for j in range(1, n + 1):
			if a.find(i) != a.find(j) and b.find(i) != b.find(j):
				ans.append([i, j])
				a.union(i, j)
				b.union(i, j)
	print(len(ans))
	for x in ans:
		print(*x)
for T in range(1):
	(n, m1, m2) = map(int, input().split())
	answer()


def getp(p, v):
	if p[v] == v:
		return v
	p[v] = getp(p, p[v])
	return p[v]

def solve():
	(n, m1, m2) = map(int, input().split())
	p1 = list(range(n + 1))
	p2 = list(range(n + 1))
	r = []
	for i in range(m1):
		(u, v) = map(int, input().split())
		u = getp(p1, u)
		v = getp(p1, v)
		p1[u] = v
	for i in range(m2):
		(u, v) = map(int, input().split())
		u = getp(p2, u)
		v = getp(p2, v)
		p2[u] = v
	for i in range(1, n + 1):
		for j in range(1, i):
			u = getp(p1, i)
			v = getp(p1, j)
			if u != v:
				x = getp(p2, i)
				y = getp(p2, j)
				if x != y:
					p1[u] = v
					p2[x] = y
					r.append((i, j))
	print(len(r))
	for (u, v) in r:
		print(u, v)
solve()


class DSU:

	def __init__(self, n):
		self.components = n
		self.par = [i for i in range(n)]
		self.size = [1] * n

	def find(self, x):
		if self.par[x] != x:
			return self.find(self.par[x])
		return self.par[x]

	def union(self, x, y):
		p1 = self.find(x)
		p2 = self.find(y)
		if p1 == p2:
			return
		if self.size[p1] > self.size[p2]:
			self.size[p1] += self.size[p2]
			self.par[p2] = p1
			return
		self.size[p2] += self.size[p1]
		self.par[p1] = p2
		return

	def get_size(self, x):
		return self.size[self.find(x)]
(n, m1, m2) = map(int, input().split())
dsu1 = DSU(n)
dsu2 = DSU(n)
for i in range(m1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	dsu1.union(a, b)
for i in range(m2):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	dsu2.union(a, b)
res = []
for i in range(n):
	for j in range(i + 1, n):
		(p, q) = (dsu1.find(i), dsu1.find(j))
		(p1, q1) = (dsu2.find(i), dsu2.find(j))
		if p != q and p1 != q1:
			res.append([1 + i, 1 + j])
			dsu1.union(i, j)
			dsu2.union(i, j)
print(len(res))
for j in res:
	print(*j)


def naiveSolve():
	return

class UnionFind:

	def __init__(self, n):
		self.parent = list(range(n))

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		self.parent[self.find(b)] = self.find(a)

def main():
	(n, m1, m2) = readIntArr()
	uf1 = UnionFind(n + 1)
	uf2 = UnionFind(n + 2)
	for _ in range(m1):
		(u, v) = readIntArr()
		uf1.union(u, v)
	for _ in range(m2):
		(u, v) = readIntArr()
		uf2.union(u, v)
	ans = []
	for u in range(1, n + 1):
		if uf1.find(1) != uf1.find(u) and uf2.find(1) != uf2.find(u):
			ans.append((1, u))
			uf1.union(1, u)
			uf2.union(1, u)
	u1 = 1
	u2 = 1
	while True:
		while u1 <= n and uf1.find(1) == uf1.find(u1):
			u1 += 1
		while u2 <= n and uf2.find(1) == uf2.find(u2):
			u2 += 1
		if u1 <= n and u2 <= n:
			ans.append((u1, u2))
			uf1.union(u1, 1)
			uf2.union(u2, 2)
		else:
			break
	print(len(ans))
	multiLineArrayOfArraysPrint(ans)
	return
import sys
input = sys.stdin.buffer.readline

def oneLineArrayPrint(arr):
	print(' '.join([str(x) for x in arr]))

def multiLineArrayPrint(arr):
	print('\n'.join([str(x) for x in arr]))

def multiLineArrayOfArraysPrint(arr):
	print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))

def readIntArr():
	return [int(x) for x in input().split()]

def makeArr(defaultValFactory, dimensionArr):
	dv = defaultValFactory
	da = dimensionArr
	if len(da) == 1:
		return [dv() for _ in range(da[0])]
	else:
		return [makeArr(dv, da[1:]) for _ in range(da[0])]

def queryInteractive(x):
	print('{}'.format(x))
	sys.stdout.flush()
	return int(input())

def answerInteractive(ans):
	print('! {}'.format(ans))
	sys.stdout.flush()
inf = float('inf')
MOD = 998244353
from math import gcd, floor, ceil
for _abc in range(1):
	main()


import sys
from functools import reduce
from collections import defaultdict, deque
import heapq
read_line = lambda : sys.stdin.readline().strip()
read_array_int = lambda : list(map(int, read_line().split()))
read_array_float = lambda : list(map(float, read_line().split()))
read_array_string = lambda : list(read_line().split())

class DSU:

	def __init__(self, size) -> None:
		self.n = size
		self.parent = [i for i in range(self.n)]

	def find_parent(self, u):
		if self.parent[u] == u:
			return u
		par = self.find_parent(self.parent[u])
		self.parent[u] = par
		return par

	def join(self, u, v):
		par1 = self.find_parent(u)
		par2 = self.find_parent(v)
		self.parent[par2] = par1

def solve(test_num):
	(n, m1, m2) = read_array_int()
	d1 = DSU(n)
	d2 = DSU(n)
	for i in range(m1):
		(u, v) = read_array_int()
		(u, v) = (u - 1, v - 1)
		d1.join(u, v)
	for i in range(m2):
		(u, v) = read_array_int()
		(u, v) = (u - 1, v - 1)
		d2.join(u, v)
	res = []
	for i in range(n):
		for j in range(n):
			if not d1.find_parent(i) == d1.find_parent(j) and (not d2.find_parent(i) == d2.find_parent(j)):
				d1.join(i, j)
				d2.join(i, j)
				res.append((i + 1, j + 1))
	print(len(res))
	for r in res:
		print(*r)
t = 1
for test_case_num in range(t):
	solve(test_case_num)


import sys as _sys

def _main():
	[tests_n] = [1]
	for i_test in range(tests_n):
		[n, m_1, m_2] = _read_ints()
		edges_1 = tuple(_read_n_egdes(m_1))
		edges_2 = tuple(_read_n_egdes(m_2))
		new_edges = add_max_edges_n(n, edges_1, edges_2)
		print(len(new_edges))
		for (u, v) in new_edges:
			print(u + 1, v + 1)

def add_max_edges_n(nodes_n, edges_1, edges_2):
	colors_1 = _build_dsu_by_edges(edges_1, nodes_n)
	colors_2 = _build_dsu_by_edges(edges_2, nodes_n)
	del edges_1, edges_2
	new_edges = []
	for u in range(nodes_n):
		for v in range(u + 1, nodes_n):
			if not _same_owner(colors_1, u, v) and (not _same_owner(colors_2, u, v)):
				new_edges.append((u, v))
				_merge_owners(colors_1, u, v)
				_merge_owners(colors_2, u, v)
	return new_edges

def _build_dsu_by_edges(edges, nodes_n):
	colors = list(range(nodes_n))
	for (u, v) in edges:
		_merge_owners(colors, u, v)
	return colors

def _same_owner(colors, node_1, node_2):
	return _get_owner(colors, node_1) == _get_owner(colors, node_2)

def _merge_owners(colors, node_1, node_2):
	node_1 = _get_owner(colors, node_1)
	node_2 = _get_owner(colors, node_2)
	colors[node_2] = node_1

def _get_owner(colors, node):
	to_fix = []
	while node != colors[node]:
		to_fix.append(node)
		node = colors[node]
	for x in to_fix:
		colors[x] = node
	return node

def _read_n_egdes(edges_n):
	edges = (_read_ints() for i_edge in range(edges_n))
	edges = ((u - 1, v - 1) for (u, v) in edges)
	return edges

def _read_ints():
	return map(int, _read_string().split())

def _read_string():
	result = _sys.stdin.readline()
	assert result and result[-1] == '\n'
	return result[:-1]
_main()


from sys import stdin
inp = stdin.readline
(n, m1, m2) = map(int, inp().split())
group1 = [0 for i in range(n)]
group2 = [0 for i in range(n)]
new = 0
for _ in range(m1):
	(s, f) = map(int, inp().split())
	s -= 1
	f -= 1
	if group1[s] > 0:
		if group1[f] > 0:
			for i in range(n):
				if group1[i] == group1[f] and i != f:
					group1[i] = group1[s]
			group1[f] = group1[s]
		else:
			group1[f] = group1[s]
	elif group1[f] > 0:
		group1[s] = group1[f]
	else:
		new += 1
		(group1[s], group1[f]) = (new, new)
for i in range(n):
	if group1[i] == 0:
		new += 1
		group1[i] = new
new = 0
for _ in range(m2):
	(s, f) = map(int, inp().split())
	s -= 1
	f -= 1
	if group2[s] > 0:
		if group2[f] > 0:
			for i in range(n):
				if group2[i] == group2[f] and i != f:
					group2[i] = group2[s]
			group2[f] = group2[s]
		else:
			group2[f] = group2[s]
	elif group2[f] > 0:
		group2[s] = group2[f]
	else:
		new += 1
		(group2[s], group2[f]) = (new, new)
for i in range(n):
	if group2[i] == 0:
		new += 1
		group2[i] = new
print(n - 1 - max(m1, m2))
for i in range(n):
	a = group1[i]
	for j in range(i, n):
		if group1[i] != group1[j] and group2[i] != group2[j]:
			print(i + 1, j + 1)
			for k in range(n):
				if group2[k] == group2[j] and k != j:
					group2[k] = group2[i]
				if group1[k] == group1[j] and k != j:
					group1[k] = group1[i]
			group2[j] = group2[i]
			group1[j] = group1[i]
			break


class UnionFindSet(object):

	def __init__(self, data_list):
		self.father_dict = {}
		self.size_dict = {}
		for node in data_list:
			self.father_dict[node] = node
			self.size_dict[node] = 1

	def find_head(self, node):
		father = self.father_dict[node]
		if node != father:
			father = self.find_head(father)
		self.father_dict[node] = father
		return father

	def is_same_set(self, node_a, node_b):
		return self.find_head(node_a) == self.find_head(node_b)

	def union(self, node_a, node_b):
		if node_a is None or node_b is None:
			return
		a_head = self.find_head(node_a)
		b_head = self.find_head(node_b)
		if a_head != b_head:
			a_set_size = self.size_dict[a_head]
			b_set_size = self.size_dict[b_head]
			if a_set_size >= b_set_size:
				self.father_dict[b_head] = a_head
				self.size_dict[a_head] = a_set_size + b_set_size
			else:
				self.father_dict[a_head] = b_head
				self.size_dict[b_head] = a_set_size + b_set_size
(n, m1, m2) = (int(i) for i in input().split())
u1 = UnionFindSet(range(1, n + 1))
u2 = UnionFindSet(range(1, n + 1))
for i in range(m1):
	(a, b) = (int(i) for i in input().split())
	u1.union(a, b)
for i in range(m2):
	(a, b) = (int(i) for i in input().split())
	u2.union(a, b)
ans = []
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if not u1.is_same_set(i, j) and (not u2.is_same_set(i, j)):
			u1.union(i, j)
			u2.union(i, j)
			ans.append((i, j))
print(len(ans))
for i in ans:
	print(*i)


import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def unionfind(root, group):
	son = root
	while root != group[root]:
		root = group[root]
	while group[son] != root:
		temp = group[son]
		group[son] = root
		son = group[temp]
	return root

def main(t):
	(n, p, q) = map(int, input().split())
	groupa = [i for i in range(n)]
	groupb = [i for i in range(n)]
	for _ in range(p):
		(u, v) = map(int, input().split())
		root1 = unionfind(u - 1, groupa)
		root2 = unionfind(v - 1, groupa)
		groupa[max(root1, root2)] = min(root1, root2)
	for _ in range(q):
		(u, v) = map(int, input().split())
		root1 = unionfind(u - 1, groupb)
		root2 = unionfind(v - 1, groupb)
		groupb[max(root1, root2)] = min(root1, root2)
	for i in range(n):
		unionfind(i, groupa)
		unionfind(i, groupb)
	count = 0
	ans = []
	for i in range(n - 1):
		for j in range(i + 1, n):
			root1a = unionfind(i, groupa)
			root2a = unionfind(j, groupa)
			root1b = unionfind(i, groupb)
			root2b = unionfind(j, groupb)
			if root1a == root2a or root1b == root2b:
				continue
			count += 1
			ans.append([i + 1, j + 1])
			groupa[max(root1a, root2a)] = min(root1a, root2a)
			groupb[max(root1b, root2b)] = min(root1b, root2b)
	print(count)
	for ele in ans:
		print(ele[0], ele[1])
T = 1
t = 1
while t <= T:
	main(t)
	t += 1


from sys import setrecursionlimit
setrecursionlimit(10 ** 6)

class Solution:

	def __init__(self, n):
		self.parent = [-1 for i in range(n + 1)]
		self.s = [1 for i in range(n + 1)]

	def merge(self, b, c):
		bb = self.findparent(b)
		cc = self.findparent(c)
		if self.s[bb] > self.s[cc]:
			self.parent[cc] = bb
			self.s[cc] += self.s[bb]
		else:
			self.parent[bb] = cc
			self.s[bb] += self.s[cc]

	def findparent(self, x):
		if self.parent[x] == -1:
			return x
		self.parent[x] = self.findparent(self.parent[x])
		return self.parent[x]

	def find(self, b, c):
		if self.findparent(b) == self.findparent(c):
			return True
		return False
(n, m1, m2) = map(int, input().split())
forest1 = Solution(n)
forest2 = Solution(n)
for i in range(m1):
	(u, v) = map(int, input().split())
	forest1.merge(u, v)
for i in range(m2):
	(u, v) = map(int, input().split())
	forest2.merge(u, v)
ans = 0
arr = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if forest1.find(i, j) == False and forest2.find(i, j) == False:
			forest2.merge(i, j)
			forest1.merge(i, j)
			arr.append([i, j])
			ans += 1
print(ans)
for a in arr:
	print(*a)


import queue
from math import *
import sys
from collections import *
from random import *
sys.setrecursionlimit(99999)
eps = sys.float_info.epsilon
P = 2
INF = 1000000000.0 + 1
MOD = 1000000007

def is_prime(n):
	if n == 0 or n == 1:
		return False
	d = 2
	while d * d <= n:
		if n % d == 0:
			return False
		d += 1
	return True

def sum_of_digits(n):
	res = 0
	while n != 0:
		res += n % 10
		n //= 10
	return res

def div_up(n, k):
	if n % k == 0:
		return n // k
	else:
		return n // k + 1

def num_len(n, base):
	if n == 0:
		return 1
	return int(floor(log(n, base) + 1))

def dfs_sample(graph, cl, p, v):
	cl[v] = 1
	for to in graph[v]:
		if cl[to] == 1 and p[v] != to:
			pass
		elif cl[to] == 0:
			p[to] = v
			dfs_sample(graph, cl, p, to)
	cl[v] = 2

def down(a):
	for i in range(1, len(a)):
		if a[i] > a[i - 1]:
			return False
	return True

def up(a):
	for i in range(1, len(a)):
		if a[i] < a[i - 1]:
			return False
	return True

def code(c):
	return ord(c) - 32

def _hash_(s):
	(res, p) = (0, 1)
	for i in range(len(s)):
		res += code(s[i]) * p
		res %= MOD
		p *= P
		p %= MOD
	return res % MOD

def sum_twodim(matrix):
	res = 0
	for i in matrix:
		for j in i:
			res += j
	return res

def find_root(x, p):
	if x == p[x]:
		return x
	else:
		p[x] = find_root(p[x], p)
		return p[x]

def make_set(x, p):
	p[x] = x

def union(x, y, p):
	a = find_root(x, p)
	b = find_root(y, p)
	if a != b:
		p[b] = a

def solve():
	(n, m1, m2) = map(int, input().split())
	p1 = [i for i in range(n + 1)]
	p2 = [i for i in range(n + 1)]
	for i in range(m1):
		(u, v) = map(int, input().split())
		union(u, v, p1)
	for i in range(m2):
		(u, v) = map(int, input().split())
		union(u, v, p2)
	h = 0
	ans = []
	for v1 in range(1, n + 1):
		for v2 in range(v1 + 1, n + 1):
			if find_root(v1, p1) != find_root(v2, p1) and find_root(v1, p2) != find_root(v2, p2):
				h += 1
				ans.append((v1, v2))
				union(v1, v2, p1)
				union(v1, v2, p2)
	print(h)
	for i in ans:
		print(*i)
solve()

def debug():
	pass


(n, m1, m2) = map(int, input().split())

def getfa(fa, x):
	if fa[x] == x:
		return x
	else:
		fa[x] = getfa(fa, fa[x])
		return fa[x]
fa1 = [i for i in range(n + 1)]
fa2 = [i for i in range(n + 1)]
for i in range(m1):
	(u, v) = map(int, input().split())
	t1 = getfa(fa1, u)
	t2 = getfa(fa1, v)
	fa1[t1] = t2
for i in range(m2):
	(u, v) = map(int, input().split())
	t1 = getfa(fa2, u)
	t2 = getfa(fa2, v)
	fa2[t1] = t2
res = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		t1 = getfa(fa1, i)
		t2 = getfa(fa1, j)
		if t1 != t2:
			t3 = getfa(fa2, i)
			t4 = getfa(fa2, j)
			if t3 != t4:
				res.append((i, j))
				fa1[t1] = t2
				fa2[t3] = t4
print(len(res))
for i in range(len(res)):
	print(res[i][0], res[i][1])


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return len(self.roots())

	def all_group_members(self):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))

	def all_family_count(self):
		return [-min(0, x) for (i, x) in enumerate(self.parents)]

	def memberlist(self):
		self.L = [set() for _ in range(self.n)]
		for i in range(self.n):
			if self.parents[i] < 0:
				self.L[i].add(i)
			else:
				self.L[self.find(i)].add(i)
		return self.L
sr = lambda : input()
ir = lambda : int(sr())
lr = lambda : list(map(int, sr().split()))
inf = 10 ** 18
mod = 998244353
(n, m1, m2) = lr()
uf1 = UnionFind(n)
uf2 = UnionFind(n)
for m in range(m1):
	(u, v) = lr()
	u -= 1
	v -= 1
	(u, v) = (min(u, v), max(u, v))
	uf1.union(u, v)
for m in range(m2):
	(u, v) = lr()
	u -= 1
	v -= 1
	(u, v) = (min(u, v), max(u, v))
	uf2.union(u, v)
ans = []
for i in range(n - 1):
	for j in range(i + 1, n):
		if not uf1.same(i, j) and (not uf2.same(i, j)):
			ans.append([i + 1, j + 1])
			uf1.union(i, j)
			uf2.union(i, j)
print(len(ans))
for (i, j) in ans:
	print(i, j)


from sys import stdin, setrecursionlimit
setrecursionlimit(1005)
input = stdin.readline

def find(u, p):
	if p[u] == u:
		return u
	p[u] = find(p[u], p)
	return p[u]

def union(u, v, p):
	a = find(u, p)
	b = find(v, p)
	if a != b:
		p[a] = b
		return True
	return False
(n, m1, m2) = map(int, input().split())
Ap = list(range(n))
Bp = list(range(n))
for _ in range(m1):
	(u, v) = map(int, input().split())
	union(u - 1, v - 1, Ap)
for _ in range(m2):
	(u, v) = map(int, input().split())
	union(u - 1, v - 1, Bp)
answer = []
for i in range(n - 1):
	for j in range(i + 1, n):
		if find(i, Ap) != find(j, Ap) and find(i, Bp) != find(j, Bp):
			union(i, j, Ap)
			union(i, j, Bp)
			answer.append((i + 1, j + 1))
print(len(answer))
for (a, b) in answer:
	print(a, b)


def find(node, link, size):
	while node != link[node]:
		node = link[node]
	return node

def same(a, b, link, size):
	return find(a, link, size) == find(b, link, size)

def unite(node1, node2, link, size):
	(a, b) = (find(node1, link, size), find(node2, link, size))
	if size[a] < size[b]:
		(a, b) = (b, a)
	size[a] += size[b]
	link[b] = a
from collections import defaultdict
g1 = defaultdict(list)
g2 = defaultdict(list)
(n, m1, m2) = map(int, input().split(' '))
link1 = [i for i in range(n)]
size1 = [1 for i in range(n)]
link2 = [i for i in range(n)]
size2 = [1 for i in range(n)]
for _ in range(m1):
	(u, v) = map(int, input().split(' '))
	u = u - 1
	v = v - 1
	unite(u, v, link1, size1)
for _ in range(m2):
	(u, v) = map(int, input().split(' '))
	u = u - 1
	v = v - 1
	unite(u, v, link2, size2)
ans = 0
res = []
for i in range(n):
	for j in range(n):
		if i != j:
			if same(i, j, link1, size1) == False and same(i, j, link2, size2) == False:
				unite(i, j, link1, size1)
				unite(i, j, link2, size2)
				ans = ans + 1
				res.append([i + 1, j + 1])
			else:
				pass
		else:
			pass
print(ans)
for (u, v) in res:
	print(u, v)


(n, m1, m2) = map(int, input().split())
ma = {}
mf = {}
da = {}
df = {}
for i in range(1, n + 1):
	ma[i] = i
	mf[i] = {i}
	da[i] = i
	df[i] = {i}
for i in range(m1):
	(u, v) = map(int, input().split())
	if ma[u] < ma[v]:
		(u, v) = (v, u)
	for j in mf[ma[v]]:
		ma[j] = ma[u]
		mf[ma[u]].add(j)
for i in range(m2):
	(u, v) = map(int, input().split())
	if da[u] < da[v]:
		(u, v) = (v, u)
	for j in df[da[v]]:
		da[j] = da[u]
		df[da[u]].add(j)
ans = set()
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if ma[i] != ma[j] and da[i] != da[j]:
			ans.add((i, j))
			for k in mf[ma[i]]:
				ma[k] = ma[j]
				mf[ma[j]].add(k)
			for k in df[da[i]]:
				da[k] = da[j]
				df[da[j]].add(k)
print(len(ans))
for i in ans:
	print(*i)


import sys as _sys

def _main():
	[tests_n] = [1]
	for i_test in range(tests_n):
		[n, m_1, m_2] = _read_ints()
		edges_1 = tuple(_read_n_egdes(m_1))
		edges_2 = tuple(_read_n_egdes(m_2))
		new_edges = add_max_edges_n(n, edges_1, edges_2)
		print(len(new_edges))
		for (u, v) in new_edges:
			print(u + 1, v + 1)

def add_max_edges_n(nodes_n, edges_1, edges_2):
	edges_1 = list(edges_1)
	edges_2 = list(edges_2)
	new_edges = []
	colors_1 = _build_colors(nodes_n, edges_1)
	colors_2 = _build_colors(nodes_n, edges_2)
	for u in range(nodes_n):
		for v in range(u + 1, nodes_n):
			if colors_1[u] != colors_1[v] and colors_2[u] != colors_2[v]:
				new_edges.append((u, v))
				edges_1.append((u, v))
				edges_2.append((u, v))
				colors_1 = _build_colors(nodes_n, edges_1)
				colors_2 = _build_colors(nodes_n, edges_2)
	return new_edges

def _build_colors(nodes_n, edges):
	colors = list(range(nodes_n))

	def get_owner(node):
		to_fix = []
		while node != colors[node]:
			to_fix.append(node)
			node = colors[node]
		for x in to_fix:
			colors[x] = node
		return node
	for (u, v) in edges:
		u = get_owner(u)
		v = get_owner(v)
		colors[v] = colors[u]
	for node in range(nodes_n):
		get_owner(node)
	return colors

def _read_n_egdes(edges_n):
	edges = (_read_ints() for i_edge in range(edges_n))
	edges = ((u - 1, v - 1) for (u, v) in edges)
	return edges

def _read_ints():
	return map(int, _read_string().split())

def _read_string():
	result = _sys.stdin.readline()
	assert result and result[-1] == '\n'
	return result[:-1]
_main()


import sys
import io
import math
import collections
import decimal
import itertools
import bisect
import heapq

def input():
	return sys.stdin.readline()[:-1]
INF = 10 ** 10

class UnionFind:
	parents = []
	sizes = []
	count = 0

	def __init__(self, n):
		self.count = n
		self.parents = [i for i in range(n)]
		self.sizes = [1 for i in range(n)]

	def find(self, i):
		if self.parents[i] == i:
			return i
		else:
			self.parents[i] = self.find(self.parents[i])
			return self.parents[i]

	def unite(self, i, j):
		root_i = self.find(i)
		root_j = self.find(j)
		if root_i == root_j:
			return
		elif root_i < root_j:
			self.parents[root_j] = root_i
			self.sizes[root_i] += self.sizes[root_j]
		else:
			self.parents[root_i] = root_j
			self.sizes[root_j] += self.sizes[root_i]

	def same(self, i, j):
		return self.find(i) == self.find(j)

	def size(self, i):
		return self.sizes[self.find(i)]

	def group_count(self):
		return len(set((self.find(i) for i in range(self.count))))
(N, M1, M2) = map(int, input().split())
uf1 = UnionFind(N)
uf2 = UnionFind(N)
seen = [False] * N
for _ in range(M1):
	(u, v) = map(int, input().split())
	u -= 1
	v -= 1
	uf1.unite(u, v)
for _ in range(M2):
	(u, v) = map(int, input().split())
	u -= 1
	v -= 1
	uf2.unite(u, v)
result = []
for k in range(N - 1):
	if seen[k]:
		continue
	seen[k] = True
	for i in range(k + 1, N):
		if uf1.same(k, i) or uf2.same(k, i):
			pass
		else:
			result.append((k, i))
			uf1.unite(k, i)
			uf2.unite(k, i)
			seen[i] = True
print(len(result))
if result:
	for (u, v) in result:
		print(u + 1, v + 1)


import math
(n, m1, m2) = [int(x) for x in input().split()]
s = []
dic1 = {}
dic2 = {}
for i in range(n):
	dic1.update({i + 1: []})
	dic2.update({i + 1: []})
for i in range(m1):
	(a, b) = [int(x) for x in input().split()]
	dic1[a].append(b)
	dic1[b].append(a)
for i in range(m2):
	(a, b) = [int(x) for x in input().split()]
	dic2[a].append(b)
	dic2[b].append(a)
a = []
for i in range(1, n + 1):
	flag = 0
	for j in a:
		if i in j:
			flag = 1
			break
	if flag == 1:
		continue
	v = [i]
	s = []
	s.extend(dic1[i])
	while len(s) != 0:
		x = s.pop()
		v.append(x)
		r = dic1[x]
		for j in r:
			if j in v:
				continue
			s.append(j)
	a.append(v)
b = []
for i in range(1, n + 1):
	flag = 0
	for j in b:
		if i in j:
			flag = 1
			break
	if flag == 1:
		continue
	v = [i]
	s = []
	s.extend(dic2[i])
	while len(s) != 0:
		x = s.pop()
		v.append(x)
		r = dic2[x]
		for j in r:
			if j in v:
				continue
			s.append(j)
	b.append(v)
val = len(a)
v = []
for i in range(1, n):
	p = None
	q = None
	for k in a:
		if i in k:
			p = k
			break
	for k in b:
		if i in k:
			q = k
			break
	for j in range(i + 1, n + 1):
		if j in p or j in q:
			continue
		r = None
		s = None
		for k in a:
			if j in k:
				r = k
				break
		for k in b:
			if j in k:
				s = k
				break
		v.append([i, j])
		p.extend(r)
		q.extend(s)
		a.remove(r)
		b.remove(s)
print(val - len(a))
for i in v:
	print(*i)


import sys
input = sys.stdin.buffer.readline

class Union_Find:

	def __init__(self, n):
		self.n = n
		self.parent = list(range(n + 1))
		self.size = [1] * (n + 1)

	def find_parent(self, a):
		if self.parent[a] == a:
			return a
		self.parent[a] = self.find_parent(self.parent[a])
		return self.parent[a]

	def union_sets(self, a, b, t):
		a = self.find_parent(a)
		b = self.find_parent(b)
		if a != b:
			if t == 0:
				return 1
			if self.size[a] < self.size[b]:
				(a, b) = (b, a)
			self.parent[b] = a
			self.size[a] += self.size[b]
		elif t == 0:
			return 0
(n, m1, m2) = map(int, input().split())
mocha = Union_Find(n)
diana = Union_Find(n)
for i in range(m1):
	(a, b) = map(int, input().split())
	mocha.union_sets(a, b, 1)
for i in range(m2):
	(a, b) = map(int, input().split())
	diana.union_sets(a, b, 1)
added_edges = []
for i in range(1, n + 1):
	for j in range(i + 1, n + 1):
		if mocha.union_sets(i, j, 0) and diana.union_sets(i, j, 0):
			mocha.union_sets(i, j, 1)
			diana.union_sets(i, j, 1)
			added_edges.append([i, j])
print(len(added_edges))
for edge in added_edges:
	print(*edge)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

class RangeQuery:

	def __init__(self, data, func=min):
		self.func = func
		self._data = _data = [list(data)]
		(i, n) = (1, len(_data[0]))
		while 2 * i <= n:
			prev = _data[-1]
			_data.append([func(prev[j], prev[j + i]) for j in range(n - 2 * i + 1)])
			i <<= 1

	def query(self, start, stop):
		depth = (stop - start).bit_length() - 1
		return self.func(self._data[depth][start], self._data[depth][stop - (1 << depth)])

	def __getitem__(self, idx):
		return self._data[0][idx]

def check(st, n, k):
	for i in range(n - k + 1):
		g = st.query(i, i + k)
		if g > 1:
			return True
	return False

class UnionFindSet(object):

	def __init__(self, data_list):
		self.parent = {}
		self.size = {}
		for node in data_list:
			self.parent[node] = node
			self.size[node] = 1

	def head(self, node):
		parent = self.parent[node]
		if node != parent:
			parent = self.head(parent)
		self.parent[node] = parent
		return parent

	def is_same(self, a, b):
		return self.head(a) == self.head(b)

	def union(self, a, b):
		if a is None or b is None:
			return
		a_head = self.head(a)
		b_head = self.head(b)
		if a_head != b_head:
			a_size = self.size[a]
			b_size = self.size[b]
			if a_size >= b_size:
				self.parent[b_head] = a_head
				self.size[a_head] = a_size + b_size
			else:
				self.parent[a_head] = b_head
				self.size[b_head] = a_size + b_size
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from collections import defaultdict, deque
from math import ceil, floor, sqrt, log2, gcd, pi
from heapq import heappush, heappop
from fractions import Fraction
from bisect import bisect_left, bisect
import sys
abc = 'abcdefghijklmnopqrstuvwxyz'
ABC = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
(n, a, b) = map(int, input().split())
dsu1 = UnionFindSet(range(1, n + 1))
dsu2 = UnionFindSet(range(1, n + 1))
for i in range(a):
	(u, v) = map(int, input().split())
	dsu1.union(u, v)
for i in range(b):
	(u, v) = map(int, input().split())
	dsu2.union(u, v)
ans = []
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if not dsu1.is_same(i, j) and (not dsu2.is_same(i, j)):
			ans.append([i, j])
			dsu1.union(i, j)
			dsu2.union(i, j)
print(len(ans))
for i in ans:
	print(*i)


(n, m1, m2) = map(int, input().split())
p1 = [i for i in range(n + 1)]
p2 = [i for i in range(n + 1)]
for i in range(m1):
	(a, b) = map(int, input().split())
	if p1[a] > p1[b]:
		(a, b) = (b, a)
	old = p1[b]
	new = p1[a]
	for j in range(1, n + 1):
		if p1[j] == old:
			p1[j] = new
for i in range(m2):
	(a, b) = map(int, input().split())
	if a > b:
		(a, b) = (b, a)
	old = p2[b]
	new = p2[a]
	for j in range(1, n + 1):
		if p2[j] == old:
			p2[j] = new
total = 0
x = []
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if i != j:
			if p1[i] - p1[j] != 0 and p2[i] - p2[j] != 0:
				(a, b) = (min(p1[i], p1[j]), max(p1[i], p1[j]))
				for k in range(1, n + 1):
					if p1[k] == b:
						p1[k] = a
				(a, b) = (min(p2[i], p2[j]), max(p2[i], p2[j]))
				for k in range(1, n + 1):
					if p2[k] == b:
						p2[k] = a
				total += 1
				x.append([i, j])
print(total)
for i in range(total):
	print(*x[i])


import math
import os
import sys
from io import BytesIO, IOBase
from types import GeneratorType
from collections import defaultdict
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def find(u):
	if parent1[u] == u:
		return u
	parent1[u] = find(parent1[u])
	return parent1[u]

def union(a, b):
	u = parent1[a]
	v = parent1[b]
	if size1[u] > size1[v]:
		parent1[v] = u
		size1[u] += size1[v]
	else:
		parent1[u] = v
		size1[v] += size1[u]

def find2(u):
	if parent2[u] == u:
		return u
	parent2[u] = find2(parent2[u])
	return parent2[u]

def union2(a, b):
	u = parent2[a]
	v = parent2[b]
	if size2[u] > size2[v]:
		parent2[v] = u
		size2[u] += size2[v]
	else:
		parent2[u] = v
		size2[v] += size2[u]
(n, m1, m2) = map(int, input().split())
parent1 = [i for i in range(n + 1)]
size1 = [1 for i in range(n + 1)]
parent2 = [i for i in range(n + 1)]
size2 = [1 for i in range(n + 1)]
for j in range(m1):
	(u, v) = map(int, input().split())
	if find(u) != find(v):
		union(u, v)
for j in range(m2):
	(u, v) = map(int, input().split())
	if find2(u) != find2(v):
		union2(u, v)
edges = []
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if i != j:
			if find(i) != find(j):
				if find2(i) != find2(j):
					union(i, j)
					union2(i, j)
					edges.append([i, j])
print(len(edges))
for j in edges:
	print(*j)


import random as _random
import sys as _sys

def _main():
	[tests_n] = [1]
	for i_test in range(tests_n):
		[n, m_1, m_2] = _read_ints()
		edges_1 = tuple(_read_n_egdes(m_1))
		edges_2 = tuple(_read_n_egdes(m_2))
		random = _random.Random(_random.SystemRandom().getrandbits(256))
		new_edges = add_max_edges_n(n, edges_1, edges_2, random=random)
		print(len(new_edges))
		for (u, v) in new_edges:
			print(u + 1, v + 1)

def add_max_edges_n(nodes_n, edges_1, edges_2, *, random):
	colors_1 = _build_dsu_by_edges(edges_1, nodes_n)
	colors_2 = _build_dsu_by_edges(edges_2, nodes_n)
	del edges_1, edges_2
	new_edges = _try_add_random_edges(nodes_n, colors_1, colors_2, random, max_failed_attempts_n=16)
	for u in range(nodes_n):
		for v in range(u + 1, nodes_n):
			if not _same_owner(colors_1, u, v) and (not _same_owner(colors_2, u, v)):
				new_edges.append((u, v))
				_merge_owners(colors_1, u, v)
				_merge_owners(colors_2, u, v)
	return new_edges

def _try_add_random_edges(nodes_n, colors_1, colors_2, random, *, max_failed_attempts_n):
	new_edges = []
	if nodes_n < 2:
		return new_edges
	failed_attempts_n = 0
	while failed_attempts_n < max_failed_attempts_n:
		u = random.randrange(nodes_n - 1)
		v = random.randrange(u + 1, nodes_n)
		if not _same_owner(colors_1, u, v) and (not _same_owner(colors_2, u, v)):
			new_edges.append((u, v))
			_merge_owners(colors_1, u, v)
			_merge_owners(colors_2, u, v)
			failed_attempts_n = 0
		else:
			failed_attempts_n += 1
	return new_edges

def _build_dsu_by_edges(edges, nodes_n):
	colors = list(range(nodes_n))
	for (u, v) in edges:
		_merge_owners(colors, u, v)
	for node in range(nodes_n):
		_get_owner(colors, node)
	return colors

def _same_owner(colors, node_1, node_2):
	return _get_owner(colors, node_1) == _get_owner(colors, node_2)

def _merge_owners(colors, node_1, node_2):
	node_1 = _get_owner(colors, node_1)
	node_2 = _get_owner(colors, node_2)
	colors[node_2] = node_1

def _get_owner(colors, node):
	to_fix = []
	while node != colors[node]:
		to_fix.append(node)
		node = colors[node]
	for x in to_fix:
		colors[x] = node
	return node

def _read_n_egdes(edges_n):
	edges = (_read_ints() for i_edge in range(edges_n))
	edges = ((u - 1, v - 1) for (u, v) in edges)
	return edges

def _read_ints():
	return map(int, _read_string().split())

def _read_string():
	result = _sys.stdin.readline()
	assert result and result[-1] == '\n'
	return result[:-1]
_main()