#include<bits/stdc++.h>
using namespace std;
const int M=998244353;
const long long inf=101010101010101ll;
const int N=1000005;
int n,i,j,k,f[N],m,u,x[N],y[N],p[N],id[N];
struct str{
	int u,v;
};
vector<str> ans;
int Find(int x)
{
	return f[x]?f[x]=Find(f[x]):x;
}
void uniot(int x,int y)
{
	int u=Find(x),v=Find(y);
	if(u!=v)
		f[u]=v;
}
bool cmp(int a,int b)
{
	return 1ll*(x[a]-x[u])*(y[b]-y[u])-1ll*(y[a]-y[u])*(x[b]-x[u])<0;
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
#endif
	scanf("%d",&n);
	for(i=1;i<=n;++i)
	{
		scanf("%d %d %d",&x[i],&y[i],&p[i]);
		if(p[i]!=i)
			if(u==0||x[u]>x[i])
				u=i;
	}
	if(u!=0)
	{
		for(i=1;i<=n;++i)
			if(p[i]!=i&&i!=u)
				id[++k]=i;
		for(i=1;i<=n;++i)
			for(j=p[i];j!=i;j=p[j])
				uniot(i,j);
		sort(id+1,id+1+k,cmp);
		for(i=1;i<k;++i)
			if(Find(id[i])!=Find(id[i+1]))
			{
				uniot(id[i],id[i+1]);
				ans.push_back({id[i],id[i+1]});
				swap(p[id[i]],p[id[i+1]]);
			}
		while(p[u]!=u)
		{
			ans.push_back({p[u],u});
			swap(p[p[u]],p[u]);
		}
	}
	printf("%d\n",ans.size());
	for(auto it:ans)
		printf("%d %d\n",it.u,it.v);
}
