#include <bits/stdc++.h>

using namespace std;

const int MX = 2005;
const double eps = 1e-8;
const double INF = 100000000.0;

struct dsu {

	int n, rt[MX];

	void init(int N) {
		n = N;
		for (int i = 1; i <= N; i++) rt[i] = i;
	}

	int find_rt(int u) {
		if (rt[u] != u) rt[u] = find_rt(rt[u]);
		return rt[u];
	}

	bool merge(int u, int v) {
		u = find_rt(u), v = find_rt(v);
		if (u == v) return 0;
		rt[v] = u;
		return 1;
	}

} U;

int N, lev[MX];

struct pnt {
	double x, y;
	pnt(double x = 0, double y = 0) : x(x), y(y) {}
	inline void input() {cin >> x >> y;}
	inline double calc(pnt p) {
		return atan2(y - p.y, x - p.x);
	}
} P[MX];

int id[MX], tot, root;
int ans, rlt[2][2 * MX];

int main() {
#ifndef ONLINE_JUDGE
	freopen("I", "r", stdin);
	freopen("O", "w", stdout);
#endif

	cin.tie(0); cout.tie(0);
	ios::sync_with_stdio(0);

	int i, j;
	cin >> N;
	U.init(N);
	double mn = INF;
	for (i = 1; i <= N; i++) {
		P[i].input();
		cin >> lev[i];
		if (P[i].x < mn && lev[i] != i) root = i, mn = P[i].x;
		U.merge(i, lev[i]);
	}
	if (fabs(mn - INF) < eps) {
		cout << "0\n";
		return 0;
	}
	for (i = 1; i <= N; i++)
		if (i != root && lev[i] != i)
			id[tot++] = i;
	sort(id, id + tot, [](int u, int v) {return P[u].calc(P[root]) < P[v].calc(P[root]);});
	for (i = 1; i < tot; i++) {
		int u = id[i - 1], v = id[i];
		if (U.merge(u, v)) {
			rlt[0][ans] = u, rlt[1][ans] = v, ans++;
			swap(lev[u], lev[v]);
		}
	}
	while (lev[root] != root) {
		rlt[0][ans] = lev[root], rlt[1][ans] = root, ans++;
		swap(lev[root], lev[lev[root]]);
	}
	cout << ans << '\n';
	for (i = 0; i < ans; i++) cout << rlt[0][i] << ' ' << rlt[1][i] << '\n';

	return 0;
}

				 	 				  	 		 		  			  	  	