#include <bits/stdc++.h>
using namespace std;
bool mat[1001][1001];
struct Move {
  Move() {}
  Move(int _type, int _i, int _j) {
    type = _type;
    i = _i;
    j = _j;
  }
  int type;
  int i, j;
};
vector<Move> v;
vector<Move>::iterator it;
int main() {
  int n, colSum[1001], rowDistToR[1001];
  int r, c, i, j, idx, swapCnt;
  v.reserve(10000);
  while (scanf("%d", &n) != EOF) {
    memset(colSum, 0, sizeof(colSum));
    memset(rowDistToR, 0, sizeof(rowDistToR));
    memset(mat, 0, sizeof(mat));
    v.clear();
    for ((i) = 1; (i) <= (n - 1); (i)++) {
      scanf("%d %d", &r, &c);
      colSum[c]++;
      rowDistToR[r] = max(rowDistToR[r], c);
      mat[c][r] = true;
    }
    swapCnt = 0;
    for (i = 1; i < n; i++) {
      idx = max_element(colSum + i, colSum + n + 1) - colSum;
      if (idx != i) {
        v.push_back(Move(2, i, idx));
        swap(colSum[i], colSum[idx]);
        swap(mat[i], mat[idx]);
        swapCnt++;
      }
    }
    for (i = 1; i < n; i++)
      for (j = n; j > 0; j--)
        if (mat[j][i]) {
          rowDistToR[i] = j;
          break;
        }
    for (i = 1; i < n; i++) {
      idx = min_element(rowDistToR + i, rowDistToR + n + 1) - rowDistToR;
      if (idx != i) {
        v.push_back(Move(1, i, idx));
        swap(rowDistToR[i], rowDistToR[idx]);
        swapCnt++;
      }
    }
    printf("%d\n", swapCnt);
    for (it = v.begin(); it != v.end(); it++)
      printf("%d %d %d\n", it->type, it->i, it->j);
  }
  return 0;
}
