import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskA solver = new TaskA();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskA {

        public void solve(int testNumber, InputReader input, PrintWriter out) {
            int n = input.nextInt();
            int[][] arr = new int[n + 1][n + 1];
            // read the input
            for (int i = 0; i < n - 1; i++) {
                arr[input.nextInt()][input.nextInt()] = 1;
            }

            int rowWithOne = -1, emptyCol = -1, lastCol = n, lastRow = n;
            boolean hasOne;
            ArrayList<String> swaps = new ArrayList<>();
            while (lastCol != 1 && lastRow != 1) {
                if (isAllBellow(arr)) {
                    break;
                }
                //find the empty col if the last col has one
                for (int i = 1; i <= lastCol; i++) {
                    hasOne = false;
                    for (int j = 1; j <= lastRow; j++) {
                        if (arr[j][i] == 1) {
                            hasOne = true;
                            break;
                        }
                    }
                    if (!hasOne) {
                        emptyCol = i;
                        break;
                    }
                }

                // swap the last col with the empty col
                if (emptyCol != lastCol) {
                    swapCols(arr, emptyCol, lastCol);
                    swaps.add("2 " + emptyCol + " " + lastCol);
                }
                lastCol--; // reduce the last col by 1

                // find the row with one and swap it with the last row
                for (int i = 1; i <= lastRow; i++) {
                    hasOne = false;
                    for (int j = 1; j <= lastCol; j++) {
                        if (arr[i][j] == 1) {
                            hasOne = true;
                            break;
                        }
                    }

                    if (hasOne = true) {
                        rowWithOne = i;
                        break;
                    }
                }

                //swap the row with the last row
                if (rowWithOne != lastRow) {
                    swapRows(arr, rowWithOne, lastRow);
                    swaps.add("1 " + rowWithOne + " " + lastRow);
                }
                lastRow--; // reduce the last row by 1
            }
            // print
            out.println(swaps.size());
            for (String s : swaps) {
                out.println(s);
            }

        }

        public static boolean isAllBellow(int[][] arr) {
            for (int i = 1; i < arr.length; i++) {
                for (int j = 1; j < arr.length; j++) {
                    if (arr[i][j] == 1 && i <= j) {
                        return false;
                    }
                }
            }
            return true;
        }

        public static void swapCols(int[][] arr, int a, int b) {
            int t;
            for (int i = 1; i < arr.length; i++) {
                t = arr[i][a];
                arr[i][a] = arr[i][b];
                arr[i][b] = t;
            }
        }

        public static void swapRows(int[][] arr, int a, int b) {
            int[] temp = Arrays.copyOf(arr[a], arr.length);
            arr[a] = Arrays.copyOf(arr[b], arr.length);
            arr[b] = temp;

        }

    }

    static class InputReader {

        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskA solver = new TaskA();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskA {

        public void solve(int testNumber, InputReader input, PrintWriter out) {
            int n = input.nextInt();
            int[][] arr = new int[n + 1][n + 1];
            // read the input
            for (int i = 0; i < n - 1; i++) {
                arr[input.nextInt()][input.nextInt()] = 1;
            }

            int rowWithOne = -1, emptyCol , lastCol = n, lastRow = n;
            boolean hasOne;
            ArrayList<String> swaps = new ArrayList<>();
         //   print(arr);
            while (lastCol != 1 && lastRow != 1) {
                if (isAllBellow(arr)) {
                    break;
                }
                emptyCol = -1;
                //find the empty col if the last col has one
                for (int i = 1 ;i<lastCol  ; i++) {
                    hasOne = false;
                    for (int j = 1; j <= lastRow; j++) {
                        if (arr[j][i] == 1) {
                            hasOne = true;
                            break;
                        }
                    }
                    if (!hasOne) {
                        emptyCol = i;
                        break;
                    }
                }

                // swap the last col with the empty col
                if (emptyCol !=-1) {
                    swapCols(arr, emptyCol, lastCol);
                    swaps.add("2 " + emptyCol + " " + lastCol);
                   // System.out.println(("2 " + emptyCol + " " + lastCol));
                   // print(arr);
                }
                lastCol--; // reduce the last col by 1

                // find the row with one and swap it with the last row
                for (int i = 1; i <= lastRow; i++) {
                    hasOne = false;
                    for (int j = 1; j <= lastCol; j++) {
                        if (arr[i][j] == 1) {
                            hasOne = true;
                            break;
                        }
                    }

                    if (hasOne) {
                        rowWithOne = i;
                        break;
                    }
                }

                //swap the row with the last row
                if (rowWithOne != lastRow) {
                    swapRows(arr, rowWithOne, lastRow);
                    swaps.add("1 " + rowWithOne + " " + lastRow);
                  //  System.out.println(("2 " + emptyCol + " " + lastCol));
                  //  print(arr);
                }
                lastRow--; // reduce the last row by 1
            }
            // print
            out.println(swaps.size());
            for (String s : swaps) {
                out.println(s);
            }

        }

        public static boolean isAllBellow(int[][] arr) {
            for (int i = 1; i < arr.length; i++) {
                for (int j = 1; j < arr.length; j++) {
                    if (arr[i][j] == 1 && i <= j) {
                        return false;
                    }
                }
            }
            return true;
        }

        public static void swapCols(int[][] arr, int a, int b) {
            int t;
            for (int i = 1; i < arr.length; i++) {
                t = arr[i][a];
                arr[i][a] = arr[i][b];
                arr[i][b] = t;
            }
        }

        public static void swapRows(int[][] arr, int a, int b) {
            int[] temp = Arrays.copyOf(arr[a], arr.length);
            arr[a] = Arrays.copyOf(arr[b], arr.length);
            arr[b] = temp;
        }

        public static void print (int arr[][]){
            for (int i = 1; i < arr.length; i++) {
                for (int j = 1; j < arr.length; j++) {
                    System.out.print(arr[i][j]+" ");
                }
                System.out.println("");
            }
        }

    }

    static class InputReader {

        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.lang.Long;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Problem statement: http://codeforces.com/problemset/problem/431/D
 *
 * @author thepham
 *
 */

public class C_Round_163_Div2 {
	static long Mod = 1000000007;
	static int[][][] dp;
	static int max = 100000;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int[]row = new int[n];
		int[]col = new int[n];
		Point[]data = new Point[n - 1];

		for(int i = 0; i < n - 1; i++){
			data[i] = new Point(in.nextInt() - 1, in.nextInt() - 1);
			row[data[i].x]++;
			col[data[i].y]++;
		}
		int start = 0;
		int count = 0;
		StringBuilder builder = new StringBuilder();
		for(int i = 0; i < n; i++){

				if(start == 0){
					for(int j = i ; j < n; j++){
						if(row[j] == 0){
							count++;
							row[j] = row[i];
							row[i] = 0;

							for(int k = 0; k < n - 1;k++){
								if(data[k].x == i){
									data[k].x = j;
								}else if(data[k].x == j){
									data[k].x = i;
								}
							}
							builder.append(1 + " " + (i + 1) + " " + (j + 1)).append("\n");
							break;
						}
					}
				}else{
					int nxt = -1;
					int max = -1;
					for(int j = i; j < n; j++){
						if(row[j] <= start){

							for(int k = 0; k < n - 1; k++ ){
								if(data[k].x == j && data[k].y >= (start - 1)){
									if(nxt == -1 || max == -1 || col[max] < col[data[k].y]){
										nxt = j;
										max = data[k].y;
									}
								}
							}
							if(nxt == -1){
								nxt = j;
							}
						}
					}
					if(nxt != -1){
						count++;
						builder.append(1 + " " + (i + 1) + " " + (nxt + 1)).append("\n");
						for(int k = 0; k < n - 1;k++){
							if(data[k].x == i){
								data[k].x = nxt;
							}else if(data[k].x == nxt){
								data[k].x = i;
							}
						}
						if(max != -1){
							for(int k = 0; k < n - 1;k++){
								if(data[k].y == max){
									data[k].y =start - 1;
								}else if(data[k].y == start - 1 ){
									data[k].y = max;
								}
							}
						}
						builder.append(2 + " " + (start) + " " + (max + 1)).append("\n");
					}
				}

			start++;
		}
		out.println(count);
		out.println(builder.toString());
		out.close();
	}

	static long min(long a, long b) {
		if (a > b) {
			return b;
		}
		return a;
	}

	public static int[] buildKMP(String val) {
		int[] data = new int[val.length() + 1];
		int i = 0;
		int j = -1;
		data[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(i) != val.charAt(j)) {
				j = data[j];
			}
			i++;
			j++;

			data[i] = j;
			// System.out.println(val + " " + i + " " + data[i]);
		}
		return data;
	}

	static int find(int index, int[] u) {
		if (u[index] != index) {
			return u[index] = find(u[index], u);
		}
		return index;
	}

	static int crossProduct(Point a, Point b) {
		return a.x * b.y + a.y * b.x;
	}

	static long squareDist(Point a) {
		long x = a.x;
		long y = a.y;
		return x * x + y * y;
	}

	static Point minus(Point a, Point b) {
		return new Point(a.x - b.x, a.y - b.y);
	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return "{" + x + " " + y + "}";
		}

	}

	static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static class FT {

		int[] data;

		FT(int n) {
			data = new int[n];
		}

		public void update(int index, int value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public int get(int index) {
			int result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(
			// new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.lang.Long;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Problem statement: http://codeforces.com/problemset/problem/431/D
 *
 * @author thepham
 *
 */

public class C_Round_163_Div2 {
	static long Mod = 1000000007;
	static int[][][] dp;
	static int max = 100000;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int[] row = new int[n];
		int[] col = new int[n];
		Point[] data = new Point[n - 1];

		for (int i = 0; i < n - 1; i++) {
			data[i] = new Point(in.nextInt() - 1, in.nextInt() - 1);
			row[data[i].x]++;
			col[data[i].y]++;
		}

		int count = 0;
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < n; i++) {
			int max = -1;
			for (int j = i; j < n; j++) {
				if (max == -1 || col[max] < col[j]) {
					max = j;
				}
			}
			if (max != i && max != -1) {
				count++;
				int tmp = col[max];
				col[max] = col[i];
				col[i] = tmp;
				for (Point p : data) {
					if (p.y == max) {
						p.y = i;
					} else if (p.y == i) {
						p.y = max;
					}
				}
				builder.append(2 + " " + (i + 1) + " " + (max + 1))
						.append("\n");
			}

		}
		for (int i = 0; i < n; i++) {
			int min = -1;

			int[] c = new int[n];
			for (Point p : data) {
				if (p.y >= i ) {
					c[p.x]++;
				}
			}
			for (int j = i; j < n; j++) {
				if (min == -1 || c[j] < c[min]) {
					min = j;
				}
			}
			if (min != i && min != -1) {
				count++;
				int tmp = row[min];
				row[min] = row[i];
				row[i] = tmp;
				for (Point p : data) {
					if (p.x == min) {
						p.x = i;
					} else if (p.x == i) {
						p.x = min;
					}
				}
				builder.append(1 + " " + (i + 1) + " " + (min + 1))
						.append("\n");
			}

		}
		out.println(count);
		out.println(builder.toString());
		out.close();
	}

	static long min(long a, long b) {
		if (a > b) {
			return b;
		}
		return a;
	}

	public static int[] buildKMP(String val) {
		int[] data = new int[val.length() + 1];
		int i = 0;
		int j = -1;
		data[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(i) != val.charAt(j)) {
				j = data[j];
			}
			i++;
			j++;

			data[i] = j;
			// System.out.println(val + " " + i + " " + data[i]);
		}
		return data;
	}

	static int find(int index, int[] u) {
		if (u[index] != index) {
			return u[index] = find(u[index], u);
		}
		return index;
	}

	static int crossProduct(Point a, Point b) {
		return a.x * b.y + a.y * b.x;
	}

	static long squareDist(Point a) {
		long x = a.x;
		long y = a.y;
		return x * x + y * y;
	}

	static Point minus(Point a, Point b) {
		return new Point(a.x - b.x, a.y - b.y);
	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return "{" + x + " " + y + "}";
		}

	}

	static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static class FT {

		int[] data;

		FT(int n) {
			data = new int[n];
		}

		public void update(int index, int value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public int get(int index) {
			int result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(
			// new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.lang.Long;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Problem statement: http://codeforces.com/problemset/problem/431/D
 *
 * @author thepham
 *
 */

public class C_Round_163_Div2 {
	static long Mod = 1000000007;
	static int[][][] dp;
	static int max = 100000;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int[] row = new int[n];
		int[] col = new int[n];
		Point[] data = new Point[n - 1];

		for (int i = 0; i < n - 1; i++) {
			data[i] = new Point(in.nextInt() - 1, in.nextInt() - 1);
			row[data[i].x]++;
			col[data[i].y]++;
		}

		int count = 0;
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < n; i++) {
			int max = -1;
			for(int j = i; j < n; j++ ){
				if(max == -1 || col[max] < col[j]){
					max = j;
				}
			}
			if(max != i && max != -1){
				count++;
				int tmp = col[max];
				col[max] = col[i];
				col[i] = tmp;
				builder.append(2  + " " + (i + 1) + " " + (max + 1)).append("\n");
			}

		}
		for (int i = n - 1; i >= 0; i--) {
			int max = -1;
			for(int j = i; j >= 0; j-- ){
				if(max == -1 || row[max] < row[j]){
					max = j;
				}
			}
			if(max != i && max != -1){
				count++;
				int tmp = row[max];
				row[max] = row[i];
				row[i] = tmp;
				builder.append(1  + " " + (i + 1) + " " + (max + 1)).append("\n");
			}

		}
		out.println(count);
		out.println(builder.toString());
		out.close();
	}

	static long min(long a, long b) {
		if (a > b) {
			return b;
		}
		return a;
	}

	public static int[] buildKMP(String val) {
		int[] data = new int[val.length() + 1];
		int i = 0;
		int j = -1;
		data[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(i) != val.charAt(j)) {
				j = data[j];
			}
			i++;
			j++;

			data[i] = j;
			// System.out.println(val + " " + i + " " + data[i]);
		}
		return data;
	}

	static int find(int index, int[] u) {
		if (u[index] != index) {
			return u[index] = find(u[index], u);
		}
		return index;
	}

	static int crossProduct(Point a, Point b) {
		return a.x * b.y + a.y * b.x;
	}

	static long squareDist(Point a) {
		long x = a.x;
		long y = a.y;
		return x * x + y * y;
	}

	static Point minus(Point a, Point b) {
		return new Point(a.x - b.x, a.y - b.y);
	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return "{" + x + " " + y + "}";
		}

	}

	static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static class FT {

		int[] data;

		FT(int n) {
			data = new int[n];
		}

		public void update(int index, int value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public int get(int index) {
			int result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(
			// new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.lang.Long;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Problem statement: http://codeforces.com/problemset/problem/431/D
 *
 * @author thepham
 *
 */

public class C_Round_163_Div2 {
	static long Mod = 1000000007;
	static int[][][] dp;
	static int max = 100000;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int[] row = new int[n];
		int[] col = new int[n];
		Point[] data = new Point[n - 1];

		for (int i = 0; i < n - 1; i++) {
			data[i] = new Point(in.nextInt() - 1, in.nextInt() - 1);
			row[data[i].x]++;
			col[data[i].y]++;
		}
		int start = 0;
		int count = 0;
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < n; i++) {

			if (start == 0) {
				for (int j = i; j < n; j++) {
					if (row[j] == 0) {

						row[j] = row[i];
						row[i] = 0;

						for (int k = 0; k < n - 1; k++) {
							if (data[k].x == i) {
								data[k].x = j;
							} else if (data[k].x == j) {
								data[k].x = i;
							}
						}
						if (i != j) {
							count++;
							builder.append(1 + " " + (i + 1) + " " + (j + 1))
									.append("\n");
							break;
						}
					}
				}
			} else {
				int nxt = -1;
				int max = -1;
				for (int j = i; j < n; j++) {
					if (row[j] <= start) {

						for (int k = 0; k < n - 1; k++) {
							if (data[k].x == j && data[k].y >= (start - 1)) {
								if (nxt == -1 || max == -1
										|| col[max] < col[data[k].y]) {
									nxt = j;
									max = data[k].y;
								}
							}
						}
						if (nxt == -1) {
							nxt = j;
						}
					}
				}
				if (nxt != -1) {
					if (i != nxt) {
						count++;
						builder.append(1 + " " + (i + 1) + " " + (nxt + 1))
								.append("\n");
						for (int k = 0; k < n - 1; k++) {
							if (data[k].x == i) {
								data[k].x = nxt;
							} else if (data[k].x == nxt) {
								data[k].x = i;
							}
						}
					}
					if (max != start - 1) {
						if (max != -1) {
							for (int k = 0; k < n - 1; k++) {
								if (data[k].y == max) {
									data[k].y = start - 1;
								} else if (data[k].y == start - 1) {
									data[k].y = max;
								}
							}
						}
						builder.append(2 + " " + (start) + " " + (max + 1))
								.append("\n");
					}
				}
			}

			start++;
		}
		out.println(count);
		out.println(builder.toString());
		out.close();
	}

	static long min(long a, long b) {
		if (a > b) {
			return b;
		}
		return a;
	}

	public static int[] buildKMP(String val) {
		int[] data = new int[val.length() + 1];
		int i = 0;
		int j = -1;
		data[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(i) != val.charAt(j)) {
				j = data[j];
			}
			i++;
			j++;

			data[i] = j;
			// System.out.println(val + " " + i + " " + data[i]);
		}
		return data;
	}

	static int find(int index, int[] u) {
		if (u[index] != index) {
			return u[index] = find(u[index], u);
		}
		return index;
	}

	static int crossProduct(Point a, Point b) {
		return a.x * b.y + a.y * b.x;
	}

	static long squareDist(Point a) {
		long x = a.x;
		long y = a.y;
		return x * x + y * y;
	}

	static Point minus(Point a, Point b) {
		return new Point(a.x - b.x, a.y - b.y);
	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return "{" + x + " " + y + "}";
		}

	}

	static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static class FT {

		int[] data;

		FT(int n) {
			data = new int[n];
		}

		public void update(int index, int value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public int get(int index) {
			int result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(
			// new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.lang.Long;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Problem statement: http://codeforces.com/problemset/problem/431/D
 *
 * @author thepham
 *
 */

public class C_Round_163_Div2 {
	static long Mod = 1000000007;
	static int[][][] dp;
	static int max = 100000;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int[] row = new int[n];
		int[] col = new int[n];
		Point[] data = new Point[n - 1];

		for (int i = 0; i < n - 1; i++) {
			data[i] = new Point(in.nextInt() - 1, in.nextInt() - 1);
			row[data[i].x]++;
			col[data[i].y]++;
		}

		int count = 0;
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < n; i++) {
			int max = -1;
			for(int j = i; j < n; j++ ){
				if(max == -1 || col[max] <= col[j]){
					max = j;
				}
			}
			if(max != i && max != -1){
				count++;
				int tmp = col[max];
				col[max] = col[i];
				col[i] = tmp;
				builder.append(2  + " " + (i + 1) + " " + (max + 1)).append("\n");
			}

		}
		for (int i = 0; i< n; i++) {
			int min = -1;
			for(int j = i; j < n; j++ ){
				if(min == -1 || row[min] > row[j]){
					min = j;
				}
			}
			if(min != i && min != -1){
				count++;
				int tmp = row[min];
				row[min] = row[i];
				row[i] = tmp;
				builder.append(1  + " " + (i + 1) + " " + (min + 1)).append("\n");
			}

		}
		out.println(count);
		out.println(builder.toString());
		out.close();
	}

	static long min(long a, long b) {
		if (a > b) {
			return b;
		}
		return a;
	}

	public static int[] buildKMP(String val) {
		int[] data = new int[val.length() + 1];
		int i = 0;
		int j = -1;
		data[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(i) != val.charAt(j)) {
				j = data[j];
			}
			i++;
			j++;

			data[i] = j;
			// System.out.println(val + " " + i + " " + data[i]);
		}
		return data;
	}

	static int find(int index, int[] u) {
		if (u[index] != index) {
			return u[index] = find(u[index], u);
		}
		return index;
	}

	static int crossProduct(Point a, Point b) {
		return a.x * b.y + a.y * b.x;
	}

	static long squareDist(Point a) {
		long x = a.x;
		long y = a.y;
		return x * x + y * y;
	}

	static Point minus(Point a, Point b) {
		return new Point(a.x - b.x, a.y - b.y);
	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return "{" + x + " " + y + "}";
		}

	}

	static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static class FT {

		int[] data;

		FT(int n) {
			data = new int[n];
		}

		public void update(int index, int value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public int get(int index) {
			int result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(
			// new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.lang.Long;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Problem statement: http://codeforces.com/problemset/problem/431/D
 *
 * @author thepham
 *
 */

public class C_Round_163_Div2 {
	static long Mod = 1000000007;
	static int[][][] dp;
	static int max = 100000;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int[]row = new int[n];
		int[]col = new int[n];
		Point[]data = new Point[n - 1];

		for(int i = 0; i < n - 1; i++){
			data[i] = new Point(in.nextInt() - 1, in.nextInt() - 1);
			row[data[i].x]++;
			col[data[i].y]++;
		}
		int start = 0;
		int count = 0;
		StringBuilder builder = new StringBuilder();
		for(int i = 0; i < n; i++){

				if(start == 0){
					for(int j = i + 1; j < n; j++){
						if(row[j] == 0){
							count++;
							row[j] = row[i];
							row[i] = 0;

							for(int k = 0; k < n - 1;k++){
								if(data[k].x == i){
									data[k].x = j;
								}else if(data[k].x == j){
									data[k].x = i;
								}
							}
							builder.append(1 + " " + (i + 1) + " " + (j + 1)).append("\n");
							break;
						}
					}
				}else{
					int nxt = -1;
					int max = -1;
					for(int j = i + 1; j < n; j++){
						if(row[j] <= start){

							for(int k = 0; k < n - 1; k++ ){
								if(data[k].x == j && data[k].y >= (start - 1)){
									if(nxt == -1 || max == -1 || col[max] < col[data[k].y]){
										nxt = j;
										max = data[k].y;
									}
								}
							}
							if(nxt == -1){
								nxt = j;
							}
						}
					}
					if(nxt != -1){
						count++;
						builder.append(1 + " " + (i + 1) + " " + (nxt + 1)).append("\n");
						for(int k = 0; k < n - 1;k++){
							if(data[k].x == i){
								data[k].x = nxt;
							}else if(data[k].x == nxt){
								data[k].x = i;
							}
						}
						if(max != -1){
							for(int k = 0; k < n - 1;k++){
								if(data[k].y == max){
									data[k].y =start - 1;
								}else if(data[k].y == start - 1 ){
									data[k].y = max;
								}
							}
						}
						builder.append(2 + " " + (start) + " " + (max + 1)).append("\n");
					}
				}

			start++;
		}
		out.println(count);
		out.println(builder.toString());
		out.close();
	}

	static long min(long a, long b) {
		if (a > b) {
			return b;
		}
		return a;
	}

	public static int[] buildKMP(String val) {
		int[] data = new int[val.length() + 1];
		int i = 0;
		int j = -1;
		data[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(i) != val.charAt(j)) {
				j = data[j];
			}
			i++;
			j++;

			data[i] = j;
			// System.out.println(val + " " + i + " " + data[i]);
		}
		return data;
	}

	static int find(int index, int[] u) {
		if (u[index] != index) {
			return u[index] = find(u[index], u);
		}
		return index;
	}

	static int crossProduct(Point a, Point b) {
		return a.x * b.y + a.y * b.x;
	}

	static long squareDist(Point a) {
		long x = a.x;
		long y = a.y;
		return x * x + y * y;
	}

	static Point minus(Point a, Point b) {
		return new Point(a.x - b.x, a.y - b.y);
	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return "{" + x + " " + y + "}";
		}

	}

	static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static class FT {

		int[] data;

		FT(int n) {
			data = new int[n];
		}

		public void update(int index, int value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public int get(int index) {
			int result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(
			// new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.lang.Long;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Problem statement: http://codeforces.com/problemset/problem/431/D
 *
 * @author thepham
 *
 */

public class C_Round_163_Div2 {
	static long Mod = 1000000007;
	static int[][][] dp;
	static int max = 100000;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int[] row = new int[n];
		int[] col = new int[n];
		Point[] data = new Point[n - 1];

		for (int i = 0; i < n - 1; i++) {
			data[i] = new Point(in.nextInt() - 1, in.nextInt() - 1);
			row[data[i].x]++;
			col[data[i].y]++;
		}

		int count = 0;
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < n; i++) {
			int max = -1;
			for(int j = i; j < n; j++ ){
				if(max == -1 || col[max] < col[j]){
					max = j;
				}
			}
			if(max != i && max != -1){
				count++;
				int tmp = col[max];
				col[max] = col[i];
				col[i] = tmp;
				builder.append(2  + " " + (i + 1) + " " + (max + 1));
			}

		}
		for (int i = n - 1; i >= 0; i--) {
			int max = -1;
			for(int j = i; j >= 0; j-- ){
				if(max == -1 || row[max] < row[j]){
					max = j;
				}
			}
			if(max != i && max != -1){
				count++;
				int tmp = row[max];
				row[max] = row[i];
				row[i] = tmp;
				builder.append(1  + " " + (i + 1) + " " + (max + 1));
			}

		}
		out.println(count);
		out.println(builder.toString());
		out.close();
	}

	static long min(long a, long b) {
		if (a > b) {
			return b;
		}
		return a;
	}

	public static int[] buildKMP(String val) {
		int[] data = new int[val.length() + 1];
		int i = 0;
		int j = -1;
		data[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(i) != val.charAt(j)) {
				j = data[j];
			}
			i++;
			j++;

			data[i] = j;
			// System.out.println(val + " " + i + " " + data[i]);
		}
		return data;
	}

	static int find(int index, int[] u) {
		if (u[index] != index) {
			return u[index] = find(u[index], u);
		}
		return index;
	}

	static int crossProduct(Point a, Point b) {
		return a.x * b.y + a.y * b.x;
	}

	static long squareDist(Point a) {
		long x = a.x;
		long y = a.y;
		return x * x + y * y;
	}

	static Point minus(Point a, Point b) {
		return new Point(a.x - b.x, a.y - b.y);
	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return "{" + x + " " + y + "}";
		}

	}

	static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static class FT {

		int[] data;

		FT(int n) {
			data = new int[n];
		}

		public void update(int index, int value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public int get(int index) {
			int result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(
			// new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.lang.Long;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Problem statement: http://codeforces.com/problemset/problem/431/D
 *
 * @author thepham
 *
 */

public class C_Round_163_Div2 {
	static long Mod = 1000000007;
	static int[][][] dp;
	static int max = 100000;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int[] row = new int[n];
		int[] col = new int[n];
		Point[] data = new Point[n - 1];

		for (int i = 0; i < n - 1; i++) {
			data[i] = new Point(in.nextInt() - 1, in.nextInt() - 1);
			row[data[i].x]++;
			col[data[i].y]++;
		}
		int start = 0;
		int count = 0;
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < n; i++) {

			if (start == 0) {
				for (int j = i; j < n; j++) {
					if (row[j] == 0) {

						row[j] = row[i];
						row[i] = 0;

						for (int k = 0; k < n - 1; k++) {
							if (data[k].x == i) {
								data[k].x = j;
							} else if (data[k].x == j) {
								data[k].x = i;
							}
						}
						if (i != j) {
							count++;
							builder.append(1 + " " + (i + 1) + " " + (j + 1))
									.append("\n");
							break;
						}
					}
				}
			} else {
				int nxt = -1;
				int max = -1;
				for (int j = i; j < n; j++) {
					if (row[j] <= start) {

						for (int k = 0; k < n - 1; k++) {
							if (data[k].x == j && data[k].y >= (start - 1)) {
								if (nxt == -1 || max == -1
										|| col[max] < col[data[k].y]) {
									nxt = j;
									max = data[k].y;
								}
							}
						}
						if (nxt == -1) {
							nxt = j;
						}
					}
				}
				if (nxt != -1) {
					if (i != nxt) {
						count++;
						builder.append(1 + " " + (i + 1) + " " + (nxt + 1))
								.append("\n");
						for (int k = 0; k < n - 1; k++) {
							if (data[k].x == i) {
								data[k].x = nxt;
							} else if (data[k].x == nxt) {
								data[k].x = i;
							}
						}
					}
					if (max != start - 1) {
						count++;
						if (max != -1) {
							for (int k = 0; k < n - 1; k++) {
								if (data[k].y == max) {
									data[k].y = start - 1;
								} else if (data[k].y == start - 1) {
									data[k].y = max;
								}
							}
						}
						builder.append(2 + " " + (start) + " " + (max + 1))
								.append("\n");
					}
				}
			}

			start++;
		}
		out.println(count);
		out.println(builder.toString());
		out.close();
	}

	static long min(long a, long b) {
		if (a > b) {
			return b;
		}
		return a;
	}

	public static int[] buildKMP(String val) {
		int[] data = new int[val.length() + 1];
		int i = 0;
		int j = -1;
		data[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(i) != val.charAt(j)) {
				j = data[j];
			}
			i++;
			j++;

			data[i] = j;
			// System.out.println(val + " " + i + " " + data[i]);
		}
		return data;
	}

	static int find(int index, int[] u) {
		if (u[index] != index) {
			return u[index] = find(u[index], u);
		}
		return index;
	}

	static int crossProduct(Point a, Point b) {
		return a.x * b.y + a.y * b.x;
	}

	static long squareDist(Point a) {
		long x = a.x;
		long y = a.y;
		return x * x + y * y;
	}

	static Point minus(Point a, Point b) {
		return new Point(a.x - b.x, a.y - b.y);
	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return "{" + x + " " + y + "}";
		}

	}

	static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static class FT {

		int[] data;

		FT(int n) {
			data = new int[n];
		}

		public void update(int index, int value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public int get(int index) {
			int result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(
			// new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.lang.Long;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Problem statement: http://codeforces.com/problemset/problem/431/D
 *
 * @author thepham
 *
 */

public class C_Round_163_Div2 {
	static long Mod = 1000000007;
	static int[][][] dp;
	static int max = 100000;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int[] row = new int[n];
		int[] col = new int[n];
		Point[] data = new Point[n - 1];

		for (int i = 0; i < n - 1; i++) {
			data[i] = new Point(in.nextInt() - 1, in.nextInt() - 1);
			row[data[i].x]++;
			col[data[i].y]++;
		}
		int start = 0;
		int count = 0;
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < n; i++) {

			if (start == 0) {
				for (int j = i; j < n; j++) {
					if (row[j] == 0) {

						row[j] = row[i];
						row[i] = 0;

						for (int k = 0; k < n - 1; k++) {
							if (data[k].x == i) {
								data[k].x = j;
							} else if (data[k].x == j) {
								data[k].x = i;
							}
						}
						if (i != j) {
							count++;
							builder.append(1 + " " + (i + 1) + " " + (j + 1))
									.append("\n");
							break;
						}
					}
				}
			} else {
				int nxt = -1;
				int max = -1;
				for (int j = i; j < n; j++) {
					if (row[j] <= start) {

						for (int k = 0; k < n - 1; k++) {
							if (data[k].x == j && data[k].y >= (start - 1)) {
								if (nxt == -1 || max == -1
										|| col[max] < col[data[k].y]) {
									nxt = j;
									max = data[k].y;
								}
							}
						}
						if (nxt == -1) {
							nxt = j;
						}
					}
				}
				if (nxt != -1) {
					if (i != nxt) {
						count++;
						builder.append(1 + " " + (i + 1) + " " + (nxt + 1))
								.append("\n");
						for (int k = 0; k < n - 1; k++) {
							if (data[k].x == i) {
								data[k].x = nxt;
							} else if (data[k].x == nxt) {
								data[k].x = i;
							}
						}
					}
					if (max != start - 1) {

						if (max != -1) {
							for (int k = 0; k < n - 1; k++) {
								if (data[k].y == max) {
									data[k].y = start - 1;
								} else if (data[k].y == start - 1) {
									data[k].y = max;
								}
							}
							count++;
							builder.append(2 + " " + (start) + " " + (max + 1))
									.append("\n");
						}

					}
				}
			}

			start++;
		}
		out.println(count);
		out.println(builder.toString());
		out.close();
	}

	static long min(long a, long b) {
		if (a > b) {
			return b;
		}
		return a;
	}

	public static int[] buildKMP(String val) {
		int[] data = new int[val.length() + 1];
		int i = 0;
		int j = -1;
		data[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(i) != val.charAt(j)) {
				j = data[j];
			}
			i++;
			j++;

			data[i] = j;
			// System.out.println(val + " " + i + " " + data[i]);
		}
		return data;
	}

	static int find(int index, int[] u) {
		if (u[index] != index) {
			return u[index] = find(u[index], u);
		}
		return index;
	}

	static int crossProduct(Point a, Point b) {
		return a.x * b.y + a.y * b.x;
	}

	static long squareDist(Point a) {
		long x = a.x;
		long y = a.y;
		return x * x + y * y;
	}

	static Point minus(Point a, Point b) {
		return new Point(a.x - b.x, a.y - b.y);
	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		public String toString() {
			return "{" + x + " " + y + "}";
		}

	}

	static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static class FT {

		int[] data;

		FT(int n) {
			data = new int[n];
		}

		public void update(int index, int value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public int get(int index) {
			int result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(
			// new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}

}


import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.PrintWriter;

public class Main {

    static InputReader in = new InputReader(System.in);
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
        int n = in.nextInt();
        int[][] matrix = new int[n][n];

        for (int i = 0; i < n - 1; i++) {
            matrix[in.nextInt() - 1][in.nextInt() - 1] = 1;
        }

        int count = 0;
        String Lines = "";
        loop:
        for (int i = n - 1; i > -1; i--) {

            int indexCol = checkCol(matrix, i);
            if (indexCol != -1 && i != indexCol) {
                Lines += ("2 " + (i + 1) + " " + (indexCol + 1)) + "\n";
                changeCol(matrix, i, indexCol);
                count++;
            }

            int indexRow = checkRow(matrix, i);
            if (indexRow != -1 && i != indexRow) {
                Lines += ("1 " + (i + 1) + " " + (indexRow + 1)) + "\n";
                changeRow(matrix, i, indexRow);
                count++;
            }
        }
        System.out.println(count);
        System.out.print(Lines);

//        for (int i = 0; i < n; i++) {
//            for (int j = 0; j < n; j++) {
//                System.out.print(matrix[i][j] + " ");
//            }
//            System.out.println();
//        }
    }

    public static void changeRow(int[][] matrix, int i, int newindex) {
        int[] temp = matrix[i];
        matrix[i] = matrix[newindex];
        matrix[newindex] = temp;
    }

    public static void changeCol(int[][] matrix, int j, int newindex) {
        for (int k = 0; k < matrix.length; k++) {
            int temp = matrix[k][j];
            matrix[k][j] = matrix[k][newindex];
            matrix[k][newindex] = temp;
        }
    }

    public static int checkCol(int[][] matrix, int L) {
        for (int i = 0; i <= L; i++) {
            boolean check = true;
            for (int j = 0; j <= L; j++) {
                if (matrix[j][i] == 1) {
                    check = false;
                    break;
                }
            }
            if (check) {
                return i;
            }
        }
        return -1;
    }

    public static int checkRow(int[][] matrix, int L) {
        for (int i = 0; i <= L; i++) {
            for (int j = 0; j <= L; j++) {
                if (matrix[i][j] == 1) {
                    return i;
                }
            }
        }
        return -1;
    }

    static class InputReader {

        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}


import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.PrintWriter;

public class Main {

    static InputReader in = new InputReader(System.in);
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
        int n = in.nextInt();
        int[][] matrix = new int[n][n];

        for (int i = 0; i < n - 1; i++) {
            matrix[in.nextInt() - 1][in.nextInt() - 1] = 1;
        }

        int count = 0;
        String Lines = "";
        loop:
        for (int i = n - 1; i > -1; i--) {

            int indexCol = checkCol(matrix, i);
            if (indexCol != -1) {
                Lines += ("2 " + (i) + " " + (indexCol + 1)) + "\n";
                changeCol(matrix, i, indexCol);
                count++;
            }

            int indexRow = checkRow(matrix, i);
            if (indexRow != -1) {
                Lines += ("1 " + (i) + " " + (indexRow)) + "\n";
                changeRow(matrix, i, indexRow);
                count++;
            }
        }
        System.out.println(count);
        System.out.print(Lines);

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void changeRow(int[][] matrix, int i, int newindex) {
        int[] temp = matrix[i];
        matrix[i] = matrix[newindex];
        matrix[newindex] = temp;
    }

    public static void changeCol(int[][] matrix, int j, int newindex) {
        for (int k = 0; k < matrix.length; k++) {
            int temp = matrix[k][j];
            matrix[k][j] = matrix[k][newindex];
            matrix[k][newindex] = temp;
        }
    }

    public static int checkCol(int[][] matrix, int L) {
        for (int i = 0; i <= L; i++) {
            boolean check = true;
            for (int j = 0; j <= L; j++) {
                if (matrix[j][i] == 1) {
                    check = false;
                    break;
                }
            }
            if (check) {
                return i;
            }
        }
        return -1;
    }

    public static int checkRow(int[][] matrix, int L) {
        for (int i = 0; i <= L; i++) {
            for (int j = 0; j <= L; j++) {
                if (matrix[i][j] == 1) {
                    return i;
                }
            }
        }
        return -1;
    }

    static class InputReader {

        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}


import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.PrintWriter;

public class Main {

    static InputReader in = new InputReader(System.in);
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
        int n = in.nextInt();
        int[][] matrix = new int[n][n];

        for (int i = 0; i < n - 1; i++) {
            matrix[in.nextInt() - 1][in.nextInt() - 1] = 1;
        }

        int count = 0;
        String Lines = "";
        loop:
        for (int i = n - 1; i > -1; i--) {

            int indexCol = checkCol(matrix, i);
            if (indexCol != -1 && i != indexCol) {
                Lines += ("2 " + (i) + " " + (indexCol)) + "\n";
                changeCol(matrix, i, indexCol);
                count++;
            }

            int indexRow = checkRow(matrix, i);
            if (indexRow != -1 && i != indexRow) {
                Lines += ("1 " + (i) + " " + (indexRow)) + "\n";
                changeRow(matrix, i, indexRow);
                count++;
            }
        }
        System.out.println(count);
        System.out.print(Lines);

//        for (int i = 0; i < n; i++) {
//            for (int j = 0; j < n; j++) {
//                System.out.print(matrix[i][j] + " ");
//            }
//            System.out.println();
//        }
    }

    public static void changeRow(int[][] matrix, int i, int newindex) {
        int[] temp = matrix[i];
        matrix[i] = matrix[newindex];
        matrix[newindex] = temp;
    }

    public static void changeCol(int[][] matrix, int j, int newindex) {
        for (int k = 0; k < matrix.length; k++) {
            int temp = matrix[k][j];
            matrix[k][j] = matrix[k][newindex];
            matrix[k][newindex] = temp;
        }
    }

    public static int checkCol(int[][] matrix, int L) {
        for (int i = 0; i <= L; i++) {
            boolean check = true;
            for (int j = 0; j <= L; j++) {
                if (matrix[j][i] == 1) {
                    check = false;
                    break;
                }
            }
            if (check) {
                return i;
            }
        }
        return -1;
    }

    public static int checkRow(int[][] matrix, int L) {
        for (int i = 0; i <= L; i++) {
            for (int j = 0; j <= L; j++) {
                if (matrix[i][j] == 1) {
                    return i;
                }
            }
        }
        return -1;
    }

    static class InputReader {

        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}


import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.PrintWriter;

public class Main {

    static InputReader in = new InputReader(System.in);
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
        int n = in.nextInt();
        int[][] matrix = new int[n][n];

        for (int i = 0; i < n - 1; i++) {
            matrix[in.nextInt() - 1][in.nextInt() - 1] = 1;
        }

        int count = 0;
        String Lines = "";
        loop:
        for (int i = n - 1; i > -1; i--) {

            int indexCol = checkCol(matrix, i);
            if (indexCol != -1) {
                Lines += ("2 " + (i + 1) + " " + (indexCol)) + "\n";
                changeCol(matrix, i, indexCol);
                count++;
            }

            int indexRow = checkRow(matrix, i);
            if (indexRow != -1) {
                Lines += ("1 " + (i + 1) + " " + (indexRow)) + "\n";
                changeRow(matrix, i, indexRow);
                count++;
            }
        }
        System.out.println(count);
        System.out.print(Lines);
    }

    public static void changeRow(int[][] matrix, int i, int newindex) {
        int[] temp = matrix[i];
        matrix[i] = matrix[newindex];
        matrix[newindex] = temp;
    }

    public static void changeCol(int[][] matrix, int j, int newindex) {
        for (int k = 0; k < matrix.length; k++) {
            int temp = matrix[k][j];
            matrix[k][j] = matrix[k][newindex];
            matrix[k][newindex] = temp;
        }
    }

    public static int checkCol(int[][] matrix, int L) {
        for (int i = 0; i <= L; i++) {
            boolean check = true;
            for (int j = 0; j <= L; j++) {
                if (matrix[j][i] == 1) {
                    check = false;
                    break;
                }
            }
            if (check) {
                return i;
            }
        }
        return -1;
    }

    public static int checkRow(int[][] matrix, int L) {
        for (int i = 0; i <= L; i++) {
            for (int j = 0; j <= L; j++) {
                if (matrix[i][j] == 1) {
                    return i;
                }
            }
        }
        return -1;
    }

    static class InputReader {

        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}


import java.util.ArrayList;
import java.util.Scanner;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author DELL
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static int[][] matrix;
    public static void main(String[] args) {
        // TODO code application logic here
        Scanner in = new Scanner(System.in);
        int n = in.nextInt()+1;
        matrix = new int[n][n];
        for(int i = 1; i<=n-2; i++){
            matrix[in.nextInt()][in.nextInt()] = 1;
        }
        if(checkMatrix()){
            System.out.println("0");
            return;
        }

        //print();
        ArrayList<String> op1 = new ArrayList();
        ArrayList<String> op2 = new ArrayList();
        while(n != 1){
            for(int c = 1 ; c< n-1; c++){
                boolean emtyCol = true;
                for(int r = 1; r<n; r++){
                    if(matrix[r][c] == 1){
                       //System.out.println("Emty col: "+c+" ");
                       emtyCol =  false;
                       break;
                    }
                }
                if(emtyCol){
                   //System.out.println("Emty col: "+c+" ");
                   swapCol(c, n-1);
                   op2.add("2 "+c+" "+(n-1));
                   break;
                }
            }
            //print();
            boolean LastrowWith1 = false;
            for(int c = 1; c< n; c++){
                if(matrix[n-1][c] == 1){
                    LastrowWith1 = true;
                    break;
                }
            }
            if(!LastrowWith1){
                for(int r = 1 ; r<n-1; r++){
                    for(int c = 1; c<n; c++){
                        if(matrix[r][c] == 1){
                           LastrowWith1 = true;
                           break;
                        }
                    }
                    if(LastrowWith1){
                        //System.out.println("Emty row: "+r+" ");
                        swapRow(r, n-1);
                        op1.add("1 "+r+" "+(n-1));
                        //print();
                        break;
                    }
                }
            }

            n = n-1;
        }
        System.out.println(op1.size()+op2.size());
        for(int i = 0; i<op1.size(); i++)
            System.out.println(op1.get(i));
        for(int i = 0; i<op2.size(); i++)
            System.out.println(op2.get(i));

    }

    public static void swapRow(int r1, int r2){
        int[] temp = matrix[r1];
        matrix[r1] = matrix[r2];
        matrix[r2] = temp;
    }
    public static void swapCol(int c1, int c2){
        for(int r = 1; r<matrix.length; r++){
            matrix[r][c1] = matrix[r][c2];
            matrix[r][c2] = 0;
        }
    }
    public static void print(){
        for(int i = 1; i<matrix.length; i++){
            for(int j = 1; j<matrix.length; j++){
                System.out.print(matrix[i][j]+"");

            }
            System.out.println("");
        }
        System.out.println("");
    }

    public static boolean checkMatrix(){
        int count = 0;
        for(int i = 1; i<matrix.length; i++){
            for(int j = 1; j<i; j++){
                if(matrix[i][j] == 1)
                    count++;
            }
        }
        return (count == (matrix.length-2) );

    }
}


/*
Name: Abdulaziz Waleed Alshememry
ID: 1537869
E-Mail: azzoz_4_ever@outlook.com
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main {

    static String answer = "";
    static int[][] matrix;
    static int counter;

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader input = new InputReader(inputStream);
        PrintWriter output = new PrintWriter(outputStream);
        int n = input.nextInt();
        matrix = new int[n][n];
        int[] rows = new int[n];
        int[] columns = new int[n];
        for (int i = 0; i < n - 1; i++) {
            int row = input.nextInt() - 1;
            int column = input.nextInt() - 1;
            matrix[row][column] = 1;
            columns[column]++;
        }
        doSelectionSortC(columns);
        for (int i = 0; i < matrix.length; i++) {
            for (int j = matrix[i].length - 1; j >= 0; j--) {
                if (matrix[i][j] == 1) {
                    rows[i] = j + 1;
                    break;
                }
            }
        }
        doSelectionSortR(rows);
        output.println(counter);
        output.print(answer);

        output.close();
    }

    public static void swapColumns(int x, int y) {
        for (int i = 0; i < matrix.length; i++) {
            int temp = matrix[i][x];
            matrix[i][x] = matrix[i][y];
            matrix[i][y] = temp;
        }
    }

    static void doSelectionSortR(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int index = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[index]) {
                    index = j;
                }
            }
            if (index != i) {
                counter++;
                answer += "1 " + (i + 1) + " " + (index + 1) + "\n";
                int temp = arr[index];
                arr[index] = arr[i];
                arr[i] = temp;
            }
        }
    }

    static void doSelectionSortC(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int index = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] > arr[index]) {
                    index = j;
                }
            }
            if (index != i) {
                counter++;
                swapColumns(i, index);
                answer += "2 " + (i + 1) + " " + (index + 1) + "\n";
                int temp = arr[index];
                arr[index] = arr[i];
                arr[i] = temp;
            }
        }
    }

    static class InputReader {

        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public String nextLine() throws IOException {
            return reader.readLine();
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

    }
}


/*
Name: Abdulaziz Waleed Alshememry
ID: 1537869
E-Mail: azzoz_4_ever@outlook.com
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main {

    static String answer = "";
    static int[][] matrix;
    static int counter;

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader input = new InputReader(inputStream);
        PrintWriter output = new PrintWriter(outputStream);
        int n = input.nextInt();
        matrix = new int[n][n];
        Row[] rows = new Row[n];
        Column[] columns = new Column[n];
        for (int i = 0; i < rows.length; i++) {
            rows[i] = new Row(i + 1);
            columns[i] = new Column(i + 1);
        }
        for (int i = 0; i < n - 1; i++) {
            int row = input.nextInt() - 1;
            int column = input.nextInt() - 1;
            matrix[row][column] = 1;
            columns[column].incrementOne();
        }
//        Arrays.sort(columns);
        doSelectionSort(columns);
        for (int i = 0; i < matrix.length; i++) {
            for (int j = matrix[i].length - 1; j >= 0; j--) {
                if (matrix[i][j] == 1) {
                    rows[i].rightMost = j + 1;
                    break;
                }
            }
        }
        //Arrays.sort(rows);
        doSelectionSort(rows);
        /*
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                answer += matrix[i][j];
            }
            answer += "\n";
            //answer += "ROW: idx: " + rows[i].idx + " rightmost: " + rows[i].rightMost + "\n";
            //answer += "COLUMN: idx " + columns[i].idx + " num1: " + columns[i].numOfOne + "\n";
        }
         */
        output.println(counter);
        output.print(answer);

        output.close();
    }

    public static void swapColumns(int x, int y) {
        for (int i = 0; i < matrix.length; i++) {
            int temp = matrix[i][x];
            matrix[i][x] = matrix[i][y];
            matrix[i][y] = temp;
        }
    }

    public static void swapRows(int x, int y) {
        int[] temp = matrix[x];
        matrix[x] = matrix[y];
        matrix[y] = temp;
    }

    static class InputReader {

        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public String nextLine() throws IOException {
            return reader.readLine();
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

    }

    static class Column implements Comparable<Column> {

        int numOfOne;
        int idx;

        Column(int idx) {
            this.idx = idx;
        }

        void incrementOne() {
            numOfOne++;
        }

        @Override
        public int compareTo(Column t) {
            if (t.numOfOne - this.numOfOne == 0) {
                return 0;
            } else {
                if ((this.numOfOne > t.numOfOne && this.idx > t.idx) || (this.numOfOne < t.numOfOne && this.idx < t.idx)) {
                    counter++;
                    answer += "2 " + this.idx + " " + t.idx + "\n";
                    int temp = this.idx;
                    this.idx = t.idx;
                    t.idx = temp;
                    swapColumns(this.idx - 1, t.idx - 1);
                }
                return t.numOfOne - this.numOfOne;
            }
        }
    }

    static class Row implements Comparable<Row> {

        int idx;
        int rightMost;

        Row(int idx) {
            this.idx = idx;
        }

        @Override
        public int compareTo(Row t) {
            answer += "1 " + this.idx + " " + t.idx + "\n";
            if (t.rightMost == this.rightMost) {
                answer += ("ha\n");
                int temp = this.idx;
                this.idx = t.idx;
                t.idx = temp;
                return 0;
            } else {
                if ((t.rightMost > this.rightMost && t.idx < this.idx) || (t.rightMost < this.rightMost && t.idx > this.idx)) {
                    counter++;
                    int temp = this.idx;
                    this.idx = t.idx;
                    t.idx = temp;
                    swapRows(this.idx - 1, t.idx - 1);
                }
                return this.rightMost - t.rightMost;
            }
        }
    }

    static void doSelectionSort(Row[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int index = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j].rightMost < arr[index].rightMost) {
                    index = j;
                }
            }
            if (index != i) {

                counter++;
                swapRows(i, index);
                answer += "1 " + (i + 1) + " " + (index + 1) + "\n";
                Row temp = arr[index];
                arr[index] = arr[i];
                arr[i] = temp;
            }
        }
    }

    static void doSelectionSort(Column[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int index = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j].numOfOne > arr[index].numOfOne) {
                    index = j;
                }
            }
            if (index != i) {
                counter++;
                swapColumns(i, index);
                answer += "2 " + (i + 1) + " " + (index + 1) + "\n";
                Column temp = arr[index];
                arr[index] = arr[i];
                arr[i] = temp;
            }
        }
    }
}


import java.io.*;
import java.util.*;

public class practice {
	static class Reader
    {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public Reader()
        {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public Reader(String file_name) throws IOException
        {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException
        {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1)
            {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException
        {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do
            {
                ret = ret * 10 + c - '0';
            }  while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException
        {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException
        {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');

            if (c == '.')
            {
                while ((c = read()) >= '0' && c <= '9')
                {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException
        {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException
        {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException
        {
            if (din == null)
                return;
            din.close();
        }
    }

		public static void main(String[] args) throws IOException {
			Reader scn=new Reader();
			int n=scn.nextInt(),x=1;
			int[][] arr=new int[1001][2];
			int[][] ans=new int[5001][3];
			for(int i=1;i<n;i++){
				arr[i][0]=scn.nextInt();arr[i][1]=scn.nextInt();
			}
			for(int i=1;i<n;i++){
				if(arr[i][0]!=(i+1)){
					for(int j=i+1;j<n;j++){
						if(arr[j][0]==arr[i][0])arr[j][0]=i+1;
						else if(arr[j][0]==i+1)arr[j][0]=arr[i][0];
					}
					ans[x][0]=1;ans[x][1]=arr[i][0];ans[x][2]=i+1;arr[i][0]=i+1;
					x++;
				}
				if(arr[i][1]>i){
					for(int j=i+1;j<=n;j++){
						if(arr[j][1]==arr[i][1])arr[j][1]=i;
						else if(arr[j][1]==i)arr[j][1]=arr[i][1];
					}
					ans[x][0]=2;ans[x][1]=arr[i][1];ans[x][2]=i;arr[i][0]=i;
					x++;
				}
			}
			System.out.println(x-1);
			for(int i=1;i<x;i++){
				System.out.println(ans[i][0]+" "+ans[i][1]+" "+ans[i][2]);
			}

		}
	}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Nafiur Rahman Khadem Shafin 🙂
 */
public class Main {
	public static void main (String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader (inputStream);
		PrintWriter out = new PrintWriter (outputStream);
		TaskC solver = new TaskC ();
		solver.solve (1, in, out);
		out.close ();
	}

	static class TaskC {
		public void solve (int testNumber, InputReader in, PrintWriter out) {
			/*
			 * wtf? difficulty 6 😱 ? The only weak point seems to be the fact that number of '1' is <n so you can keep
			 * them on
			 * different cols or different rows if you want. I guess best will be to keep them on both different rows and
			 * differnt cols
			 * but zei duita ek row te ba ek col e ache tader jiboneo alada korte parbi na. kajei beshi paknami kore lav nai
			 * . One rough
			 * plan is to: row gulake sort kore new oi row te 1 er shonkhyar ascending order erpor col gulake sort kore new
			 * ulta vabe
			 * but the problem is when zokhon dui row ba col er shoman hobe tokhon dekha lagbe kontar shuru kothay. Even if
			 * this method
			 * is correct the biggest problem is how the hell am I gonna output the number of steps before performing the
			 * steps as string
			 * concat is very much slow. One superb way is to make an string array.
			 */
			int n = in.nextInt ();
			int[] x = new int[n+5], y = new int[n+5], cntx = new int[n+5], cnty = new int[n+5], mnx = new int[n+5], mny =
																															new int[n+
																																			5];
			for (int i = 0; i<n+4; i++) {
				Arrays.fill (mnx, Integer.MAX_VALUE);
				Arrays.fill (mny, Integer.MAX_VALUE);
			}
			for (int i = 0; i<n-1; i++) {
				x[i] = in.nextInt ();
				y[i] = in.nextInt ();
				cntx[--x[i]]++;
				cnty[--y[i]]++;
				mny[x[i]] = Math.min (mny[x[i]], y[i]);
			}

			int[][] mtrx = new int[n+5][n+5];
			for (int i = 0; i<n-1; i++) {
				mtrx[x[i]][y[i]] = 1;
			}

		/*System.out.println ("initial matrix:");
		for (int i = 0; i<n; i++) {
			for (int j = 0; j<n; j++) {
				System.out.print (mtrx[i][j]+" ");
			}
			System.out.println ();
		}*/

			int ns = 0;
			String[] res = new String[100000];
			for (int i = 0; i<n-1; i++) {
				int mnidx = i;
				for (int j = i+1; j<n; j++) {
					if (cntx[j]<cntx[mnidx] || (cntx[j] == cntx[mnidx] && mny[j]<mny[mnidx])) {
//					System.out.println ("dhuksi row "+j+" "+mnidx+" "+cntx[j]+" "+cntx[mnidx]+" "+mny[j]+" "+mny[mnidx]);
						mnidx = j;
					}
				}
				if (mnidx != i) {
					cntx[i] = (cntx[i]^cntx[mnidx])^(cntx[mnidx] = cntx[i]);
					mny[i] = (mny[i]^mny[mnidx])^(mny[mnidx] = mny[i]);
					res[ns++] = ("1 "+(i+1)+" "+(mnidx+1));

					for (int j = 0; j<n; j++) {
						mtrx[i][j] = (mtrx[i][j]^mtrx[mnidx][j])^(mtrx[mnidx][j] = mtrx[i][j]);
					}
				}
			}

		/*System.out.println ("row operation shesh");
		for (int i = 0; i<n; i++) {
			for (int j = 0; j<n; j++) {
				System.out.print (mtrx[i][j]+" ");
			}
			System.out.println ();
		}*/

			for (int i = 0; i<n; i++) {
				for (int j = 0; j<n; j++) {
					if (mtrx[j][i] == 1) {
						mnx[i] = j;
//					System.out.println ("mnx of "+i+": "+j);
						break;
					}
				}
			}

			for (int i = 0; i<n-1; i++) {
				int mxidx = i;
				for (int j = i+1; j<n; j++) {
					if (cnty[j]>cnty[mxidx] || (cnty[j] == cnty[mxidx] && mnx[j]<mnx[mxidx])) {
//					System.out.println ("dhuksi col "+j+" "+mxidx+" "+cnty[j]+" "+cnty[mxidx]+" "+mnx[j]+" "+mnx[mxidx]);
						mxidx = j;
					}
				}
				if (mxidx != i) {
					cnty[i] = (cnty[i]^cnty[mxidx])^(cnty[mxidx] = cnty[i]);
					mnx[i] = (mnx[i]^mnx[mxidx])^(mnx[mxidx] = mnx[i]);
					res[ns++] = ("2 "+(i+1)+" "+(mxidx+1));

					for (int j = 0; j<n; j++) {
						mtrx[j][i] = (mtrx[j][i]^mtrx[j][mxidx])^(mtrx[j][mxidx] = mtrx[j][i]);
					}
				}
			}
			out.println (ns);
			for (int i = 0; i<ns; i++) {
				out.println (res[i]);
			}

		/*System.out.println ("final answer");
		for (int i = 0; i<n; i++) {
			for (int j = 0; j<n; j++) {
				System.out.print (mtrx[i][j]+" ");
			}
			System.out.println ();
		}*/
		}

	}

	static class InputReader implements AutoCloseable {
		private BufferedReader reader;
		private StringTokenizer tokenizer;

		public InputReader (InputStream stream) {
			reader = new BufferedReader (new InputStreamReader (stream));
			tokenizer = null;
		}

		public String next () {
			while (tokenizer == null || !tokenizer.hasMoreTokens ()) {
				try {
					String str;
					if ((str = reader.readLine ()) != null) tokenizer = new StringTokenizer (str);
					else return null;//to detect eof
				} catch (IOException e) {
					throw new RuntimeException (e);
				}
			}
			return tokenizer.nextToken ();
		}

		public int nextInt () {
			return Integer.parseInt (next ());
		}

		public void close () throws Exception {
			reader.close ();
		}

	}
}