#include <bits/stdc++.h>
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
int n,maxi;
int dist(int a,int b){
if(b>a)return b-a;
return b+2*n-a;
}
bool cmp(pair<pair<int,int>,int> a,pair<pair<int,int>,int> b){
return dist(maxi,a.first.first)<dist(maxi,b.first.first);
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin >> n;
vector<pair<pair<int,int>,int>> edge(n);
// de 0 al 2*n-1
vector<int> con(2*n);
vector<int> ind(2*n);
for(int i=0;i<n;i++){
cin >> edge[i].first.first >> edge[i].first.second;
edge[i].second=i;
if((edge[i].first.first+edge[i].first.second)&1){
int temp=edge[i].first.first,temp2=edge[i].first.second;
con[(temp+temp2)%(2*n)]++;
}
ind[edge[i].first.first]=ind[edge[i].first.second]=i;
}
for(int i=0;i<2*n;i++){
if(con[i]>con[maxi])maxi=i;
}
cout << n-con[maxi] << '\n';
for(int i=0;i<n;i++){
if((edge[i].first.first+edge[i].first.second)%(2*n)==maxi)continue;
// cambiar el second
cout << edge[i].second << ' ' << edge[i].first.second << ' ' << (maxi-edge[i].first.first+2*n)%(2*n) << '\n';
int pos=ind[edge[i].first.second];
int ante=edge[i].first.second;
edge[i].first.second=(maxi-edge[i].first.first+2*n)%(2*n);
while(pos!=i){
if(edge[pos].first.first==ante)swap(edge[pos].first.first,edge[pos].first.second);
cout << edge[pos].second << ' ' << edge[pos].first.second << ' ' << (maxi-edge[pos].first.first+2*n)%(2*n) << '\n';
ante=edge[pos].first.second;
int nuepos=ind[edge[pos].first.second];
edge[pos].first.second=(maxi-edge[pos].first.first+2*n)%(2*n);
pos=nuepos;
}
}
/*for(int i=0;i<n;i++){
if(dist(maxi,edge[i].first.first)>dist(maxi,edge[i].first.second))swap(edge[i].first.first,edge[i].first.second);
}
sort(ALL(edge),cmp);
for(int i=0;i<n;i++){
if((edge[i].first.first+edge[i].first.second)%(2*n)==maxi)continue;
cout << edge[i].second << ' ' << edge[i].first.second << ' ' << (maxi-edge[i].first.first+2*n)%(2*n) << '\n';
}*/
}