/** Roman Kolganov, March 2019 */

#include <bits/stdc++.h>

using namespace std;

const int N = 250;
vector<int> g[N];
int mate[N];
int state[N];
int p[N];
int dsu_rank[N];
int repr[N];
int tree_prev[N];
int edge_from[N];
int edge_to[N];
int left_mark[N];
int right_mark[N];
int current_mark = 0;

int get(int v) {
	return p[v] == v ? v : (p[v] = get(p[v]));
}

void join(int u, int v) {
	u = get(u);
	v = get(v);
	if (dsu_rank[v] < dsu_rank[u]) {
		swap(u, v);
	}
	p[u] = v;
	if (dsu_rank[v] == dsu_rank[u]) {
		++dsu_rank[v];
	}
}

void promote(int v) {
	repr[get(v)] = v;
}

int base(int v) {
	return repr[get(v)];
}

void get_path(int from, int to, list<int>& path, bool rev) {
	if (from == to || (state[from] == 0 && mate[from] == 0)) {
		path.push_front(from);
		return;
	}
	if (state[from] == 0) {
		if (rev) {
			path.push_front(from);
			path.push_front(mate[from]);
			get_path(tree_prev[mate[from]], to, path, rev);
		} else {
			get_path(tree_prev[mate[from]], to, path, rev);
			path.push_front(mate[from]);
			path.push_front(from);
		}
		return;
	}
	if (rev) {
		path.push_front(from);
		get_path(edge_from[from], mate[from], path, !rev);
		get_path(edge_to[from], to, path, rev);
	} else {
		get_path(edge_to[from], to, path, rev);
		get_path(edge_from[from], mate[from], path, !rev);
		path.push_front(from);
	}
}

void augment(auto& path) {
	while (!path.empty()) {
		int x = path.front();
		path.pop_front();
		int y = path.front();
		path.pop_front();
		mate[x] = y;
		mate[y] = x;
	}
}

void shrink(vector<int>& cycle, int v, int b, int from, int to) {
	for (int w = base(v); w != b; w = base(tree_prev[mate[w]])) {
		join(b, w);
		join(b, mate[w]);
		promote(b);
		edge_from[mate[w]] = from;
		edge_to[mate[w]] = to;
		cycle.push_back(mate[w]);
	}
}

bool dfs(int v) {
	for (int u : g[v]) {
		if (base(u) == base(v) || state[base(u)] == 1) {
			continue;
		}
		if (state[u] == -1) {
			if (mate[u] != 0) {
				state[u] = 1;
				tree_prev[u] = v;
				state[mate[u]] = 0;
				if (dfs(mate[u])) {
					return true;
				}
			} else {
				list<int> path;
				get_path(v, 0, path, false);
				path.push_front(u);
				augment(path);
				return true;
			}
		} else {
			vector<int> cycle;
			int cv = base(v);
			int cu = base(u);
			++current_mark;
			left_mark[cu] = current_mark;
			right_mark[cv] = current_mark;
			while (left_mark[cv] != current_mark && right_mark[cu] != current_mark) {
				if (mate[cu] != 0) {
					cu = base(tree_prev[mate[cu]]);
					left_mark[cu] = current_mark;
				}
				if (mate[cv] != 0) {
					cv = base(tree_prev[mate[cv]]);
					right_mark[cv] = current_mark;
				}
			}
			int b = left_mark[cv] == current_mark ? cv : cu;
			shrink(cycle, v, b, v, u);
			shrink(cycle, u, b, u, v);
			for (int w : cycle) {
				if (dfs(w)) {
					return true;
				}
			}
		}
	}
	return false;
}

int main() {
	//freopen("schedule.in", "r", stdin);
	//freopen("schedule.out", "w", stdout);
	ios_base::sync_with_stdio(false); cin.tie(nullptr);

	int n;
	cin >> n;
	int x, y;
	while (cin >> x >> y) {
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for (int v = 1; v <= n; ++v) {
		if (mate[v] != 0) {
			continue;
		}
		fill_n(state + 1, n, -1);
		fill_n(dsu_rank + 1, n, 0);
		iota(p + 1, p + n + 1, 1);
		iota(repr + 1, repr + n + 1, 1);
		state[v] = 0;
		dfs(v);
	}
	vector<pair<int, int>> matching;
	for (int v = 1; v <= n; ++v) {
		if (mate[v] != 0) {
			matching.emplace_back(v, mate[v]);
			mate[mate[v]] = 0;
		}
	}
	cout << matching.size() * 2 << '\n';
	for (auto [v, u] : matching) {
		cout << v << ' ' << u << '\n';
	}
}