#include <bits/stdc++.h>
using namespace std;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }
#define watch(x) cout << (#x) << " is " << (x) << endl





using ll = long long;


const int maxn = 2003;

struct pt {
    ll x,y;
    void read() {
	cin>>x>>y;
    }
    pt operator-(const pt& o) const {
	return {x-o.x,y-o.y};
    }

    double ang() const {
	return atan2(y,x);
    }
};

int n;
vector<pt> v;
vector<int> a;
vector<int> label;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);


    cin>>n;
    v.resize(n);
    label.resize(n);
    
    for (int i=0; i<n; i++) {
	v[i].read();
	cin>>label[i];
	label[i]--;
	if (label[i]!=i) {
	    a.push_back(i);
	}
    }

    if (a.empty()) out(0);

    sort(a.begin(),a.end(), [&](int i, int j) {
	return v[i].x<v[j].x;
    });

    int f = a[0];
    a.erase(a.begin());

    // center around f, angular sort
    sort(a.begin(), a.end(), [&](int i, int j) {
	return (v[i]-v[f]).ang() < (v[j]-v[f]).ang();
    });


    // 1. go around the edges of the polygon, make all pts into 1 perm
    // 2. from f, give everyone their labels, like a tree

    vector<pair<int,int>> ans;
    auto Swap = [&](int i, int j) {
	ans.push_back({i,j});
	swap(label[i],label[j]);
    };

    for (int i=0; i+1<(int)a.size(); i++) {
	int idx = a[i];
	int idx2 = a[i+1];
	bool ok = false;
	int at = idx;
	for (int it=0; it<n+1; it++) {
	    if (at == idx2) ok = true;
	    at = label[at];
	}
	if (!ok) {
	    Swap(idx, idx2);
	}
    }


    while (label[f]!=f) {
	int myLabel = label[f];
	Swap(f, myLabel); // give myLabel to where it needs to be, forget about it
    }

    cout<<ans.size()<<"\n";
    for (auto p: ans) {
	cout<<p.first+1<<" "<<p.second+1<<"\n";
    }

    
    
    return 0;
}
