// Arup Guha
// 11/16/2023
// Solution to 2022 SER D1/D2 Problem: Color Tubes

import java.util.*;

public class colortubes {
	
	public static int n;
	public static int[][] tubes;
	public static ArrayList<int[]> moves;
	
	public static void main(String[] args) {
	
		Scanner stdin = new Scanner(System.in);
		n = stdin.nextInt();
		tubes = new int[n+1][3];
		
		// Read input - index j=0 = bottom
		for (int i=0; i<n+1; i++)
			for (int j=0; j<3; j++)
				tubes[i][j] = stdin.nextInt();

		// Store moves here.
		moves = new ArrayList<int[]>();
		
		// So I know where stuff is.
		emptylast();
		
		// We will fix each tube, one by one, in order.
		for (int i=0; i<n-1; i++) {
			fix(i);
			emptylast();
		}
		
		// Ta da!
		System.out.println(moves.size());
		for (int i=0; i<moves.size(); i++)
			System.out.println( (moves.get(i)[0]+1)+" "+(moves.get(i)[1]+1));
	}
	
	// Fixes tube x.
	public static void fix(int x) {
		
		// Catch this case.
		if (rowdone(x)) return;
		
		// top = bottom but mid is off.
		if (tubes[x][0] == tubes[x][2]) {
			update(x+1, n);
			update(x, x+1);
			update(x, n);
			update(x+1, x);
			update(n, x+1);
			update(n, x);
		}
		
		// Just in case...
		if (rowdone(x)) return;
		
		// Just need to put the top one on.
		if (tubes[x][0] == tubes[x][1]) 
			fixtop(x);
		
		// Check if we're done!
		if (rowdone(x)) return;
		
		// Otherwise, this should do the trick.
		fixsecond(x);
		fix(x);
	}
	
	// Finds the last occurrence of item starting at tube sx.
	public static int[] getItemLoc(int sx, int item) {
		
		// will store result here.
		int myx = -1, myy = -1;
		
		// Just go looking for item.
		for (int r=sx; r<n; r++) {
			for (int c=0; c<3; c++) {
				if (tubes[r][c] == item) {
					myx = r;
					myy = c;
				}
			}
		}		
		
		// Ta da!
		return new int[]{myx, myy};
	}
	
	// Assumes starting state, fixes the top (assumes bottom 2 match on tube x).
	// Fixes the top of tube x assuming bottom 2 items are same.
	public static void fixtop(int x) {
		
		// Find the third item.
		int[] loc = getItemLoc(x+1, tubes[x][0]);
		int myx = loc[0], myy = loc[1];
		
		// Item on top. Fix it.
		if (myy == 2) {
			update(x, n);
			update(myx, x);
			update(n, myx);
		}
		
		// Item in middle. Fix it.
		else if (myy == 1) {
			for (int z=0; z<2; z++) update(myx, n);
			update(x, myx);
			update(n, x);
			update(n, myx);
		}
		
		// Item on bottom. Fix it.
		else {
			for (int z=0; z<3; z++) update(myx, n);
			update(x, myx);
			update(n, x);
			for (int z=0; z<2; z++) update(n, myx);
		}
	}
	
	// Assumes starting state. Will match second item in tube x to bottom item.
	public static void fixsecond(int x) {
		
		// Finds the last item that could match.
		int[] loc = getItemLoc(x+1, tubes[x][0]);
		int myx = loc[0], myy = loc[1];
		
		// Item on top. Fix it.
		if (myy == 2) {
			for (int z=0; z<2; z++) update(x, n);
			update(myx, x);
			update(n, myx);
			update(n, x);
		}
		
		// Item in middle. Fix it.
		else if (myy == 1) {
			for (int z=0; z<2; z++) update(x, n);
			update(myx, n);
			update(myx, x);
			for (int z=0; z<2; z++) update(n, myx);
			update(n, x);
		}
		
		// Item on bottom. Fix it.
		else {
			for (int z=0; z<3; z++) update(myx, n);
			for (int z=0; z<2; z++) update(x, myx);
			for (int z=0; z<2; z++) update(n, x);
			update(n, myx);
		}		
	}
	
	// Returns true iff tube x is done.
	public static boolean rowdone(int x) {
		return tubes[x][0] == tubes[x][1] && tubes[x][0] == tubes[x][2];
	}
	
	// Empties the last tube.
	public static void emptylast() {
	
		// Find which tubes have an empty slot, with multiplicity.
		int[] empty = new int[3];
		int k = 0;
		for (int i=0; i<n+1; i++)
			for (int j=0; j<3; j++)
				if (tubes[i][j] == 0)
					empty[k++] = i;
					
		// If a slot is empty that isn't the last, then there's something in the last
		// to move to it.
		for (int i=0; i<3; i++) 
			if (empty[i] != n) 
				update(n, empty[i]);
	}	
	
	// Updates the state of the tubes based on a move.
	public static void update(int s, int e) {
		
		// Add to list of moves.
		moves.add(new int[]{s,e});
		
		// Update tubes accordingly.
		int c1 = 2, c2 = 0;
		while (tubes[s][c1] == 0) c1--;
		while (tubes[e][c2] != 0) c2++;
		int tmp = tubes[s][c1];
		tubes[s][c1] = tubes[e][c2];
		tubes[e][c2] = tmp;
	}
}