import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
	public static void main(String args[])
	{
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		dataC str[]=new dataC[n+1];
		str[0]=new dataC();
		for(int i=1;i<=n;i++)
		{
			str[i]=new dataC();
			str[i].x=sc.nextInt();
			str[i].y=sc.nextInt();
			str[i].z=sc.nextInt();
			str[i].id=i;
		}
		Arrays.sort(str,1,n+1,new Comparator<dataC>()
				{
					public int compare(dataC a,dataC b)
					{
						if(a.x!=b.x) return a.x<b.x?-1:1;
						if(a.y!=b.y) return a.y<b.y?-1:1;
						return a.z<b.z?-1:1;
					}
				});
		boolean vis[]=new boolean[n+1];
		Arrays.fill(vis, false);
		for(int i=1;i<=n-1;i++)
		{
			if(str[i].x==str[i+1].x&&str[i].y==str[i+1].y)
			{
				vis[i]=true;vis[i+1]=true;
				System.out.println(str[i].id+" "+str[i+1].id);
				i++;
			}
		}
		for(int i=1;i<=n-1;i++)
		{
			if(vis[i]) continue;
			int j=i+1;
			while(vis[j]) j++;
			if(j<=n&&str[i].x==str[j].x)
			{
				vis[i]=true;vis[j]=true;
				System.out.println(str[i].id+" "+str[j].id);
				i=j;
			}
		}
		for(int i=1;i<=n-1;i++)
		{
			if(vis[i])
				continue;
			int j=i+1;
			while(vis[j])
				j++;
			System.out.println(str[i].id+" "+str[j].id);
			vis[i]=true;vis[j]=true;
			i=j;
		}
	}

}
class dataC
{
	int x,y,z,id;
}


import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
	public static void main(String args[])
	{
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		dataC str[]=new dataC[n+1];
		str[0]=new dataC();
		for(int i=1;i<=n;i++)
		{
			str[i]=new dataC();
			str[i].x=sc.nextInt();
			str[i].y=sc.nextInt();
			str[i].z=sc.nextInt();
			str[i].id=i;
		}
		Arrays.sort(str,1,n+1,new Comparator<dataC>()
				{
					public int compare(dataC a,dataC b)
					{
						if(a.x!=b.x) return a.x<b.x?-1:1;
						if(a.y!=b.y) return a.y<b.y?-1:1;
						return a.z<b.z?-1:1;
					}
				});
		boolean vis[]=new boolean[n+1];
		Arrays.fill(vis, false);
		for(int i=1;i<=n-1;i++)
		{
			if(str[i].x==str[i+1].x&&str[i].y==str[i+1].y)
			{
				vis[i]=true;vis[i+1]=true;
				System.out.println(str[i].id+" "+str[i+1].id);
				i++;
			}
		}
		for(int i=1;i<=n-1;i++)
		{
			if(vis[i]) continue;
			int j=i+1;
			while(j<=n&&vis[j]) j++;
			if(j<=n&&str[i].y==str[j].y)
			{
				vis[i]=true;vis[j]=true;
				System.out.println(str[i].id+" "+str[j].id);
				i=j;
			}
		}
		for(int i=1;i<=n-1;i++)
		{
			if(vis[i])
				continue;
			int j=i+1;
			while(vis[j])
				j++;
			System.out.println(str[i].id+" "+str[j].id);
			vis[i]=true;vis[j]=true;
			i=j;
		}
	}

}
class dataC
{
	int x,y,z,id;
}


import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
	public static void main(String args[])
	{
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		dataC str[]=new dataC[n+1];
		str[0]=new dataC();
		for(int i=1;i<=n;i++)
		{
			str[i]=new dataC();
			str[i].x=sc.nextInt();
			str[i].y=sc.nextInt();
			str[i].z=sc.nextInt();
			str[i].id=i;
		}
		Arrays.sort(str,1,n+1,new Comparator<dataC>()
				{
					public int compare(dataC a,dataC b)
					{
						if(a.x!=b.x) return a.x<b.x?-1:1;
						if(a.y!=b.y) return a.y<b.y?-1:1;
						return a.z<b.z?-1:1;
					}
				});
		boolean vis[]=new boolean[n+1];
		Arrays.fill(vis, false);
		for(int i=1;i<=n-1;i++)
		{
			if(str[i].x==str[i+1].x&&str[i].y==str[i+1].y)
			{
				vis[i]=true;vis[i+1]=true;
				System.out.println(str[i].id+" "+str[i+1].id);
				i++;
			}
		}
		for(int i=1;i<=n-1;i++)
		{
			if(vis[i]) continue;
			int j=i+1;
			while(vis[j]) j++;
			if(j<=n&&str[i].x==str[j].x)
			{
				vis[i]=true;vis[j]=true;
				System.out.println(str[i].id+" "+str[j].id);
				i=j;
			}
		}
		for(int i=1;i<=n-1;i++)
		{
			if(vis[i])
				continue;
			int j=i+1;
			while(vis[j])
				j++;
			System.out.println(str[i].id+" "+str[j].id);
			vis[i]=true;vis[j]=true;
			i=j;
		}
	}

}
class dataC
{
	int x,y,z,id;
}


import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
	public static void main(String args[])
	{
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		dataC str[]=new dataC[n+1];
		str[0]=new dataC();
		for(int i=1;i<=n;i++)
		{
			str[i]=new dataC();
			str[i].x=sc.nextInt();
			str[i].y=sc.nextInt();
			str[i].z=sc.nextInt();
			str[i].id=i;
		}
		Arrays.sort(str,1,n+1,new Comparator<dataC>()
				{
					public int compare(dataC a,dataC b)
					{
						if(a.x!=b.x) return a.x<b.x?-1:1;
						if(a.y!=b.y) return a.y<b.y?-1:1;
						return a.z<b.z?-1:1;
					}
				});
		boolean vis[]=new boolean[n+1];
		Arrays.fill(vis, false);
		for(int i=1;i<=n-1;i++)
		{
			if(str[i].x==str[i+1].x&&str[i].y==str[i+1].y)
			{
				vis[i]=true;vis[i+1]=true;
				System.out.println(str[i].id+" "+str[i+1].id);
				i++;
			}
		}
		for(int i=1;i<=n-1;i++)
		{
			if(vis[i]) continue;
			int j=i+1;
			while(vis[j]) j++;
			if(str[i].x==str[j].x)
			{
				vis[i]=true;vis[j]=true;
				System.out.println(str[i].id+" "+str[j].id);
				i=j;
			}
		}
		for(int i=1;i<=n-1;i++)
		{
			if(vis[i])
				continue;
			int j=i+1;
			while(vis[j])
				j++;
			System.out.println(str[i].id+" "+str[j].id);
			vis[i]=true;vis[j]=true;
			i=j;
		}
	}

}
class dataC
{
	int x,y,z,id;
}


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

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	void work() {
		int n=in.nextInt();
		int[][] A=new int[n][4];
		for(int i=0;i<n;i++) {
			int x=in.nextInt();
			int y=in.nextInt();
			int z=in.nextInt();
			A[i]=new int[] {x,y,z,i+1};
		}
		Arrays.sort(A,new Comparator<int[]>() {
			public int compare(int[] arr1,int[] arr2) {
				if(arr1[0]==arr2[0]) {
					if(arr1[1]==arr2[1]) {
						return arr1[2]-arr2[2];
					}else {
						return arr1[1]-arr2[1];
					}
				}else {
					return arr1[0]-arr2[0];
				}
			}
		});
		boolean[] vis=new boolean[n];
		for(int i=0,j=1;i<n;) {
			if(vis[i]) {
				i++;
				continue;
			}
			j=i+1;
			while(j<n&&vis[j]) {
				j++;
			}
			if(j<n&&A[i][0]==A[j][0]&&A[i][1]==A[j][1]) {//相邻先消掉
				out.println(A[i][3]+" "+A[j][3]);
				vis[i]=true;
				vis[j]=true;
			}
			i=j;
		}
		for(int i=0,j=1;i<n;) {
			if(vis[i]) {
				i++;
				continue;
			}
			j=i+1;
			while(j<n&&vis[j]) {
				j++;
			}
			if(j<n&&A[i][0]==A[j][0]) {//相邻先消掉
				out.println(A[i][3]+" "+A[j][3]);
				vis[i]=true;
				vis[j]=true;
			}
			i=j;
		}
		for(int i=0,j=1;i<n;) {
			if(vis[i]) {
				j=i+1;
				i++;
				continue;
			}
			j=i+1;
			while(j<n&&vis[j]) {
				j++;
			}
			if(j<n) {
				out.println(A[i][3]+" "+A[j][3]);
				vis[i]=true;
				vis[j]=true;
			}
			i=j;
		}
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

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

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


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

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	void work() {
		int n=in.nextInt();
		int[][] A=new int[n][4];
		for(int i=0;i<n;i++) {
			int x=in.nextInt();
			int y=in.nextInt();
			int z=in.nextInt();
			A[i]=new int[] {x,y,z,i+1};
		}
		Arrays.sort(A,new Comparator<int[]>() {
			public int compare(int[] arr1,int[] arr2) {
				if(arr1[0]==arr2[0]) {
					if(arr1[1]==arr2[1]) {
						return arr1[2]-arr2[2];
					}else {
						return arr1[1]-arr2[1];
					}
				}else {
					return arr1[0]-arr2[0];
				}
			}
		});

		for(int i=n/2-1;i>=0;i--) {
			out.println(A[i][3]+" "+A[n-1-i][3]);
		}
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

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

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


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

public class Main {
	static Scanner sc = new Scanner(System.in);
	static PrintWriter out = new PrintWriter(System.out);
	static Point[] arr;

	static Point solveZ(ArrayList<Point> a) {
		Collections.sort(a, (o1, o2) -> Integer.compare(o1.z, o2.z));
		for (int i = 0; i < a.size() - 1; i += 2) {
			int u = a.get(i).id, v = a.get(i + 1).id;
			out.println(u + " " + v);
		}

		return (a.size() % 2 == 0) ? null : a.get(a.size() - 1);

	}

	static ArrayList<Point> solveY(ArrayList<Point> a) {
		TreeMap<Integer, ArrayList<Point>> byy = new TreeMap<>();
		for (Point p : a) {
			ArrayList<Point> val = byy.getOrDefault(p.y, new ArrayList<>());
			val.add(p);
			byy.put(p.y, val);
		}

		ArrayList<Point> rem = new ArrayList<>();
		for (Map.Entry<Integer, ArrayList<Point>> e : byy.entrySet()) {
			Point p = solveZ(e.getValue());
			if (p != null)
				rem.add(p);
		}

		return rem;
	}

	static void solveX() {
		TreeMap<Integer, ArrayList<Point>> byx = new TreeMap<>();
		for (int i = 0; i < arr.length; i++) {
			ArrayList<Point> val = byx.getOrDefault(arr[i].x, new ArrayList<>());
			val.add(arr[i]);
			byx.put(arr[i].x, val);
		}

		ArrayList<Point> rem = new ArrayList<>();

		for (Map.Entry<Integer, ArrayList<Point>> e : byx.entrySet()) {
			rem.addAll(solveY(e.getValue()));
		}

		for (int i = 0; i < rem.size() - 1; i += 2) {
			int u = rem.get(i).id, v = rem.get(i + 1).id;
			out.println(u + " " + v);
		}
	}

	public static void main(String[] args) throws Exception {
		int n = sc.nextInt();
		arr = new Point[n];
		for (int i = 0; i < n; i++) {
			int x = sc.nextInt(), y = sc.nextInt(), z = sc.nextInt();
			arr[i] = new Point(x, y, z, i);
		}

		solveX();

		out.close();
	}

	static class Point {
		int x, y, z, id;

		public Point(int x, int y, int z, int id) {
			this.x = x;
			this.y = y;
			this.z = z;
			this.id = id + 1;
		}
	}
}

class Scanner {
	StringTokenizer st;
	BufferedReader br;

	public Scanner(InputStream system) {
		br = new BufferedReader(new InputStreamReader(system));
	}

	public Scanner(String file) throws Exception {
		br = new BufferedReader(new FileReader(file));
	}

	public String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

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

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

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

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


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

public class Main {
	static Scanner sc = new Scanner(System.in);
	static PrintWriter out = new PrintWriter(System.out);

	public static void main(String[] args) throws Exception {
		int n = sc.nextInt();
		Point arr[] = new Point[n];
		for (int i = 0; i < n; i++) {
			int x = sc.nextInt(), y = sc.nextInt(), z = sc.nextInt();
			arr[i] = new Point(x, y, z, i + 1);
		}
		Arrays.sort(arr);
		for (int i = 0; i < n - 1; i += 2) {
			out.println(arr[i].idx + " " + arr[i + 1].idx);
		}

		out.close();
	}

	static class Point implements Comparable<Point> {
		int x, y, z, idx;

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

		public int compareTo(Point o) {
			if (x == o.x && y == o.y)
				return Integer.compare(z, o.z);
			if (x == o.x)
				return Integer.compare(y, o.y);
			return Integer.compare(x, o.x);
		}
	}
}

class Scanner {
	StringTokenizer st;
	BufferedReader br;

	public Scanner(InputStream system) {
		br = new BufferedReader(new InputStreamReader(system));
	}

	public Scanner(String file) throws Exception {
		br = new BufferedReader(new FileReader(file));
	}

	public String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

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

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

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

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


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

public class Main {
	static Scanner sc = new Scanner(System.in);
	static PrintWriter out = new PrintWriter(System.out);
	static Point[] arr;

	static Point solveZ(ArrayList<Point> a) {
		Collections.sort(a, (o1, o2) -> Integer.compare(o1.z, o2.z));
		for (int i = 0; i < a.size() - 1; i += 2) {
			int u = a.get(i).id, v = a.get(i + 1).id;
			out.println(u + " " + v);
		}

		return (a.size() % 2 == 0) ? null : a.get(a.size() - 1);

	}

	static Point solveY(ArrayList<Point> a) {
		TreeMap<Integer, ArrayList<Point>> byy = new TreeMap<>();
		for (Point p : a) {
			ArrayList<Point> val = byy.getOrDefault(p.y, new ArrayList<>());
			val.add(p);
			byy.put(p.y, val);
		}

		ArrayList<Point> rem = new ArrayList<>();

		for (Map.Entry<Integer, ArrayList<Point>> e : byy.entrySet()) {
			Point p = solveZ(e.getValue());
			if (p != null)
				rem.add(p);
		}

		for (int i = 0; i < rem.size() - 1; i += 2) {
			int u = rem.get(i).id, v = rem.get(i + 1).id;
			out.println(u + " " + v);
		}

		return (rem.size() % 2 == 0) ? null : rem.get(rem.size() - 1);

	}

	static void solveX() {
		TreeMap<Integer, ArrayList<Point>> byx = new TreeMap<>();
		for (int i = 0; i < arr.length; i++) {
			ArrayList<Point> val = byx.getOrDefault(arr[i].x, new ArrayList<>());
			val.add(arr[i]);
			byx.put(arr[i].x, val);
		}

		ArrayList<Point> rem = new ArrayList<>();

		for (Map.Entry<Integer, ArrayList<Point>> e : byx.entrySet()) {
			Point p = solveY(e.getValue());
			if(p != null) rem.add(p);
		}

		for (int i = 0; i < rem.size() - 1; i += 2) {
			int u = rem.get(i).id, v = rem.get(i + 1).id;
			out.println(u + " " + v);
		}
	}

	public static void main(String[] args) throws Exception {
		int n = sc.nextInt();
		arr = new Point[n];
		for (int i = 0; i < n; i++) {
			int x = sc.nextInt(), y = sc.nextInt(), z = sc.nextInt();
			arr[i] = new Point(x, y, z, i);
		}

		solveX();

		out.close();
	}

	static class Point {
		int x, y, z, id;

		public Point(int x, int y, int z, int id) {
			this.x = x;
			this.y = y;
			this.z = z;
			this.id = id + 1;
		}

		public String toString() {
			return "" + id;
		}
	}
}

class Scanner {
	StringTokenizer st;
	BufferedReader br;

	public Scanner(InputStream system) {
		br = new BufferedReader(new InputStreamReader(system));
	}

	public Scanner(String file) throws Exception {
		br = new BufferedReader(new FileReader(file));
	}

	public String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

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

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

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

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


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

public class Main {
	static Scanner sc = new Scanner(System.in);
	static PrintWriter out = new PrintWriter(System.out);
	static Point[] arr;

	static Point solveZ(ArrayList<Point> a) {
		Collections.sort(a, (o1, o2) -> Integer.compare(o1.z, o2.z));
		for (int i = 0; i < a.size() - 1; i += 2) {
			int u = a.get(i).id, v = a.get(i + 1).id;
			out.println(u + " " + v);
		}

		return (a.size() % 2 == 0) ? null : a.get(a.size() - 1);

	}

	static Point solveY(ArrayList<Point> a) {
		TreeMap<Integer, ArrayList<Point>> byy = new TreeMap<>();
		for (Point p : a) {
			ArrayList<Point> val = byy.getOrDefault(p.y, new ArrayList<>());
			val.add(p);
			byy.put(p.y, val);
		}

		ArrayList<Point> rem = new ArrayList<>();
		for (Map.Entry<Integer, ArrayList<Point>> e : byy.entrySet()) {
			Point p = solveZ(e.getValue());
			if (p != null)
				rem.add(p);
		}

		for (int i = 0; i < a.size() - 1; i += 2) {
			int u = a.get(i).id, v = a.get(i + 1).id;
			out.println(u + " " + v);
		}

		return (a.size() % 2 == 0) ? null : a.get(a.size() - 1);

	}

	static void solveX() {
		TreeMap<Integer, ArrayList<Point>> byx = new TreeMap<>();
		for (int i = 0; i < arr.length; i++) {
			ArrayList<Point> val = byx.getOrDefault(arr[i].x, new ArrayList<>());
			val.add(arr[i]);
			byx.put(arr[i].x, val);
		}

		ArrayList<Point> rem = new ArrayList<>();

		for (Map.Entry<Integer, ArrayList<Point>> e : byx.entrySet()) {
			Point p = solveY(e.getValue());
			if(p != null) rem.add(p);
		}

		for (int i = 0; i < rem.size() - 1; i += 2) {
			int u = rem.get(i).id, v = rem.get(i + 1).id;
			out.println(u + " " + v);
		}
	}

	public static void main(String[] args) throws Exception {
		int n = sc.nextInt();
		arr = new Point[n];
		for (int i = 0; i < n; i++) {
			int x = sc.nextInt(), y = sc.nextInt(), z = sc.nextInt();
			arr[i] = new Point(x, y, z, i);
		}

		solveX();

		out.close();
	}

	static class Point {
		int x, y, z, id;

		public Point(int x, int y, int z, int id) {
			this.x = x;
			this.y = y;
			this.z = z;
			this.id = id + 1;
		}
	}
}

class Scanner {
	StringTokenizer st;
	BufferedReader br;

	public Scanner(InputStream system) {
		br = new BufferedReader(new InputStreamReader(system));
	}

	public Scanner(String file) throws Exception {
		br = new BufferedReader(new FileReader(file));
	}

	public String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

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

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

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

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


import java.io.*;
import java.nio.CharBuffer;
import java.util.*;

public class P1237C2 {

    public static void main(String[] args) {
        SimpleScanner scanner = new SimpleScanner(System.in);
        PrintWriter writer = new PrintWriter(System.out);

        int n = scanner.nextInt();
        TreeMap<Integer, TreeMap<Integer, ArrayList<int[]>>> xMap = new TreeMap<>();
        for (int i = 0; i < n; ++i) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            int z = scanner.nextInt();
            xMap.putIfAbsent(x, new TreeMap<>());
            TreeMap<Integer, ArrayList<int[]>> yMap = xMap.get(x);
            yMap.putIfAbsent(y, new ArrayList<>());
            ArrayList<int[]> zList = yMap.get(y);
            zList.add(new int[]{z, i + 1});
        }
        ArrayList<Integer> xList = new ArrayList<>();
        for (Map.Entry<Integer, TreeMap<Integer, ArrayList<int[]>>> xEntry : xMap.entrySet()) {
            TreeMap<Integer, ArrayList<int[]>> yMap = xEntry.getValue();
            ArrayList<Integer> yList = new ArrayList<>();
            for (Map.Entry<Integer, ArrayList<int[]>> yEntry : yMap.entrySet()) {
                ArrayList<int[]> zList = yEntry.getValue();
                zList.sort(Comparator.comparingInt(o -> o[0]));
                for (int i = 0; i < zList.size() - 1; i += 2)
                    writer.println(zList.get(i)[1] + " " + zList.get(i + 1)[1]);
                if (zList.size() % 2 == 1)
                    yList.add(zList.get(zList.size() - 1)[1]);
            }
            for (int i = 0; i < yList.size() - 1; i += 2)
                writer.println(yList.get(i) + " " + yList.get(i + 1));
            if (yList.size() % 2 == 1)
                xList.add(yList.get(yList.size() - 1));
        }
        for (int i = 0; i < xList.size() - 1; i += 2)
            writer.println(xList.get(i) + " " + xList.get(i + 1));
        writer.close();
    }

    private static long dis(int[] x, int[] y, int[] z, int i, int j) {
        long dx = Math.abs(x[i] - x[j]);
        long dy = Math.abs(y[i] - y[j]);
        long dz = Math.abs(z[i] - z[j]);
        return dx * dx + dy * dy + dz * dz;
    }

    private static class SimpleScanner {

        private static final int BUFFER_SIZE = 10240;

        private Readable in;
        private CharBuffer buffer;
        private boolean eof;

        private SimpleScanner(InputStream in) {
            this.in = new BufferedReader(new InputStreamReader(in));
            buffer = CharBuffer.allocate(BUFFER_SIZE);
            buffer.limit(0);
            eof = false;
        }

        private char read() {
            if (!buffer.hasRemaining()) {
                buffer.clear();
                int n;
                try {
                    n = in.read(buffer);
                } catch (IOException e) {
                    n = -1;
                }
                if (n <= 0) {
                    eof = true;
                    return '\0';
                }
                buffer.flip();
            }
            return buffer.get();
        }

        private void checkEof() {
            if (eof)
                throw new NoSuchElementException();
        }

        private char nextChar() {
            checkEof();
            char b = read();
            checkEof();
            return b;
        }

        private String next() {
            char b;
            do {
                b = read();
                checkEof();
            } while (Character.isWhitespace(b));
            StringBuilder sb = new StringBuilder();
            do {
                sb.append(b);
                b = read();
            } while (!eof && !Character.isWhitespace(b));
            return sb.toString();
        }

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

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

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


import java.io.*;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.TreeMap;

public class P1237C2 {

    public static void main(String[] args) {
        SimpleScanner scanner = new SimpleScanner(System.in);
        PrintWriter writer = new PrintWriter(System.out);

        int n = scanner.nextInt();
        TreeMap<Integer, TreeMap<Integer, ArrayList<int[]>>> xMap = new TreeMap<>();
        for (int i = 0; i < n; ++i) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            int z = scanner.nextInt();
            xMap.putIfAbsent(x, new TreeMap<>());
            TreeMap<Integer, ArrayList<int[]>> yMap = xMap.get(x);
            yMap.putIfAbsent(y, new ArrayList<>());
            ArrayList<int[]> zList = yMap.get(y);
            zList.add(new int[]{z, i + 1});
        }
        ArrayList<Integer> xList = new ArrayList<>();
        for (Map.Entry<Integer, TreeMap<Integer, ArrayList<int[]>>> xEntry : xMap.entrySet()) {
            TreeMap<Integer, ArrayList<int[]>> yMap = xEntry.getValue();
            ArrayList<Integer> yList = new ArrayList<>();
            for (Map.Entry<Integer, ArrayList<int[]>> yEntry : yMap.entrySet()) {
                ArrayList<int[]> zList = yEntry.getValue();
                for (int i = 0; i < zList.size() - 1; i += 2)
                    writer.println(zList.get(i)[1] + " " + zList.get(i + 1)[1]);
                if (zList.size() % 2 == 1)
                    yList.add(zList.get(zList.size() - 1)[1]);
            }
            for (int i = 0; i < yList.size() - 1; i += 2)
                writer.println(yList.get(i) + " " + yList.get(i + 1));
            if (yList.size() % 2 == 1)
                xList.add(yList.get(yList.size() - 1));
        }
        for (int i = 0; i < xList.size() - 1; i += 2)
            writer.println(xList.get(i) + " " + xList.get(i + 1));
        writer.close();
    }

    private static long dis(int[] x, int[] y, int[] z, int i, int j) {
        long dx = Math.abs(x[i] - x[j]);
        long dy = Math.abs(y[i] - y[j]);
        long dz = Math.abs(z[i] - z[j]);
        return dx * dx + dy * dy + dz * dz;
    }

    private static class SimpleScanner {

        private static final int BUFFER_SIZE = 10240;

        private Readable in;
        private CharBuffer buffer;
        private boolean eof;

        private SimpleScanner(InputStream in) {
            this.in = new BufferedReader(new InputStreamReader(in));
            buffer = CharBuffer.allocate(BUFFER_SIZE);
            buffer.limit(0);
            eof = false;
        }

        private char read() {
            if (!buffer.hasRemaining()) {
                buffer.clear();
                int n;
                try {
                    n = in.read(buffer);
                } catch (IOException e) {
                    n = -1;
                }
                if (n <= 0) {
                    eof = true;
                    return '\0';
                }
                buffer.flip();
            }
            return buffer.get();
        }

        private void checkEof() {
            if (eof)
                throw new NoSuchElementException();
        }

        private char nextChar() {
            checkEof();
            char b = read();
            checkEof();
            return b;
        }

        private String next() {
            char b;
            do {
                b = read();
                checkEof();
            } while (Character.isWhitespace(b));
            StringBuilder sb = new StringBuilder();
            do {
                sb.append(b);
                b = read();
            } while (!eof && !Character.isWhitespace(b));
            return sb.toString();
        }

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

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

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


import java.io.*;
import java.nio.CharBuffer;
import java.util.NoSuchElementException;

public class P1237C1 {

    public static void main(String[] args) {
        SimpleScanner scanner = new SimpleScanner(System.in);
        PrintWriter writer = new PrintWriter(System.out);

        int n = scanner.nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        int[] z = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = scanner.nextInt();
            y[i] = scanner.nextInt();
            z[i] = scanner.nextInt();
        }
        boolean[] removed = new boolean[n];
        for (int i = 0; i < n; ++i) {
            if (!removed[i]) {
                long min = Long.MAX_VALUE;
                int k = -1;
                for (int j = i + 1; j < n; ++j) {
                    if (!removed[j]) {
                        long d = dis(x, y, z, i, j);
                        if (d < min) {
                            min = d;
                            k = j;
                        }
                    }
                }
                removed[i] = removed[k] = true;
                writer.println((i + 1) + " " + (k + 1));
            }
        }
        writer.close();
    }

    private static long dis(int[] x, int[] y, int[] z, int i, int j) {
        long dx = Math.abs(x[i] - x[j]);
        long dy = Math.abs(y[i] - y[j]);
        long dz = Math.abs(z[i] - z[j]);
        return dx * dx + dy * dy + dz * dz;
    }

    private static class SimpleScanner {

        private static final int BUFFER_SIZE = 10240;

        private Readable in;
        private CharBuffer buffer;
        private boolean eof;

        private SimpleScanner(InputStream in) {
            this.in = new BufferedReader(new InputStreamReader(in));
            buffer = CharBuffer.allocate(BUFFER_SIZE);
            buffer.limit(0);
            eof = false;
        }

        private char read() {
            if (!buffer.hasRemaining()) {
                buffer.clear();
                int n;
                try {
                    n = in.read(buffer);
                } catch (IOException e) {
                    n = -1;
                }
                if (n <= 0) {
                    eof = true;
                    return '\0';
                }
                buffer.flip();
            }
            return buffer.get();
        }

        private void checkEof() {
            if (eof)
                throw new NoSuchElementException();
        }

        private char nextChar() {
            checkEof();
            char b = read();
            checkEof();
            return b;
        }

        private String next() {
            char b;
            do {
                b = read();
                checkEof();
            } while (Character.isWhitespace(b));
            StringBuilder sb = new StringBuilder();
            do {
                sb.append(b);
                b = read();
            } while (!eof && !Character.isWhitespace(b));
            return sb.toString();
        }

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

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

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


import java.io.*;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.NoSuchElementException;

public class P1237C2 {

    public static void main(String[] args) {
        SimpleScanner scanner = new SimpleScanner(System.in);
        PrintWriter writer = new PrintWriter(System.out);

        int n = scanner.nextInt();
        ArrayList<int[]> points = new ArrayList<>(n);
        for (int i = 0; i < n; ++i) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            int z = scanner.nextInt();
            points.add(new int[]{x, y, z, i + 1});
        }
        points.sort(new Comparator<int[]>() {
            @Override
            public int compare(int[] p, int[] q) {
                if (p[0] != q[0])
                    return p[0] - q[0];
                if (p[1] != q[1])
                    return p[1] - q[1];
                return p[2] - q[2];
            }
        });
        for (int i = 0; i < n; i += 2) {
            writer.println(points.get(i)[3] + " " + points.get(i + 1)[3]);
        }
        writer.close();
    }

    private static long dis(int[] x, int[] y, int[] z, int i, int j) {
        long dx = Math.abs(x[i] - x[j]);
        long dy = Math.abs(y[i] - y[j]);
        long dz = Math.abs(z[i] - z[j]);
        return dx * dx + dy * dy + dz * dz;
    }

    private static class SimpleScanner {

        private static final int BUFFER_SIZE = 10240;

        private Readable in;
        private CharBuffer buffer;
        private boolean eof;

        private SimpleScanner(InputStream in) {
            this.in = new BufferedReader(new InputStreamReader(in));
            buffer = CharBuffer.allocate(BUFFER_SIZE);
            buffer.limit(0);
            eof = false;
        }

        private char read() {
            if (!buffer.hasRemaining()) {
                buffer.clear();
                int n;
                try {
                    n = in.read(buffer);
                } catch (IOException e) {
                    n = -1;
                }
                if (n <= 0) {
                    eof = true;
                    return '\0';
                }
                buffer.flip();
            }
            return buffer.get();
        }

        private void checkEof() {
            if (eof)
                throw new NoSuchElementException();
        }

        private char nextChar() {
            checkEof();
            char b = read();
            checkEof();
            return b;
        }

        private String next() {
            char b;
            do {
                b = read();
                checkEof();
            } while (Character.isWhitespace(b));
            StringBuilder sb = new StringBuilder();
            do {
                sb.append(b);
                b = read();
            } while (!eof && !Character.isWhitespace(b));
            return sb.toString();
        }

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

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

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


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

public class Solution {
	public static void main (String[] args)throws IOException{
	    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	    int n = Integer.parseInt(br.readLine());
	    int arr[][] = new int[n][4];

	    for(int i=0;i<n;i++)
	    {
            String k[] = br.readLine().split(" ");
            arr[i][0] = Integer.parseInt(k[0]);
            arr[i][1] = Integer.parseInt(k[1]);
            arr[i][2] = Integer.parseInt(k[2]);
            arr[i][3] = i+1;
	    }
	    Arrays.sort(arr,new Comparator<int[]>(){
	        public int compare(int a[],int b[])
	        {
	            if(a[2]>b[2])return 1;
	            else if(a[2]==b[2])
	            {
	                if(a[1]>b[1])return 1;
	                else if(a[1]==b[1])
	                {
	                    if(a[0]>b[0])return 1;
	                }
	            }
	            return -1;
	        }
	    });
	    StringBuilder sb = new StringBuilder();
	    boolean b[] = new boolean[n];
	    for(int i=0;i<n-1;i++)
	    {
	        //System.out.println(arr[i][0]+" "+arr[i][1]+" "+arr[i][2]+" "+arr[i][3]);
	        if(b[i])continue;
	        if(arr[i][1]==arr[i+1][1] && arr[i][2]==arr[i+1][2])
	        {
	            sb.append(arr[i][3]+" "+arr[i+1][3]+"\n");
	            b[i]=true;
	            b[i+1]=true;
	        }
	    }
	    for(int i=0;i<n;i++)
	    {
	        if(b[i])continue;
	        int j = i+1;
	        while(b[j])j++;
	        sb.append(arr[i][3]+" "+arr[j][3]+"\n");
	        b[i]=true;
	        b[j]=true;
	        i=j;
	    }
        System.out.println(sb);
	}
}


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

public class Solution {
	public static void main (String[] args)throws IOException{
	    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	    int n = Integer.parseInt(br.readLine());
	    int arr[][] = new int[n][4];

	    for(int i=0;i<n;i++)
	    {
            String k[] = br.readLine().split(" ");
            arr[i][0] = Integer.parseInt(k[0]);
            arr[i][1] = Integer.parseInt(k[1]);
            arr[i][2] = Integer.parseInt(k[2]);
            arr[i][3] = i+1;
	    }
	    Arrays.sort(arr,new Comparator<int[]>(){
	        public int compare(int a[],int b[])
	        {
	            if(a[2]>b[2])return 1;
	            else if(a[2]==b[2])
	            {
	                if(a[1]>b[1])return 1;
	                else if(a[1]==b[1])
	                {
	                    if(a[0]>b[0])return 1;
	                }
	            }
	            return -1;
	        }
	    });
	    StringBuilder sb = new StringBuilder();
	    boolean b[] = new boolean[n];
	    for(int i=0;i<n-1;i++)
	    {
	        //System.out.println(arr[i][0]+" "+arr[i][1]+" "+arr[i][2]+" "+arr[i][3]);
	        if(b[i])continue;
	        if(arr[i][1]==arr[i+1][1] && arr[i][2]==arr[i+1][2])
	        {
	            sb.append(arr[i][3]+" "+arr[i+1][3]+"\n");
	            b[i]=true;
	            b[i+1]=true;
	        }
	    }
	    for(int i=0;i<n;i++)
	    {
	        if(b[i])continue;
	        int j = i+1;
	        while(j<n && b[j])j++;
	        if(j==n)break;
	        if(arr[i][2]==arr[j][2]){
    	        sb.append(arr[i][3]+" "+arr[j][3]+"\n");
    	        b[i]=true;
    	        b[j]=true;
    	        i=j;
	        }
	        else i=j-1;
	    }
	    for(int i=0;i<n;i++)
	    {
	        if(b[i])continue;
	        int j = i+1;
	        while(b[j])j++;
	        sb.append(arr[i][3]+" "+arr[j][3]+"\n");
    	        b[i]=true;
    	        b[j]=true;
    	        i=j;
	    }
        System.out.println(sb);
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

public class C {

	static final PrintWriter out = new PrintWriter(System.out);

	public static void main(String[] args) throws IOException {
		MyScanner sc = new MyScanner();
		int N = sc.nextInt();
		List<Point> points = new ArrayList<>(N);
		for (int i = 0; i < N; i++) {
			int x = sc.nextInt();
			int y = sc.nextInt();
			int z = sc.nextInt();
			points.add(new Point(x, y, z, i + 1));
		}
		Collections.sort(points, (p1, p2) -> {
			int cmp = Integer.compare(p1.x, p2.x);
			if (cmp != 0) return cmp;
			cmp = Integer.compare(p1.y, p2.y);
			if (cmp != 0) return cmp;
			return Integer.compare(p1.z, p2.z);
		});

		List<Point> got = new ArrayList<>();
		int from = 0;
		for (int i = 1; i < N; i++) {
			if (points.get(i).x != points.get(from).x) {
				Point tmp = samePlane(points.subList(from, i));
				if (tmp != null) got.add(tmp);
				from = i;
			}
		}
		Point tmp = samePlane(points.subList(from, N));
		if (tmp != null) got.add(tmp);
		sameLine(got);

		out.flush();
	}

	static void print(Point a, Point b) {
		out.println(a.id + " " + b.id);
	}

	static Point samePlane(List<Point> points) {
		List<Point> got = new ArrayList<>();
		int from = 0;
		for (int i = 1; i < points.size(); i++) {
			if (points.get(i).y != points.get(from).y) {
				Point tmp = sameLine(points.subList(from, i));
				if (tmp != null) got.add(tmp);
				from = i;
			}
		}
		Point tmp = sameLine(points.subList(from, points.size()));
		if (tmp != null) got.add(tmp);
		return sameLine(got);
	}

	static Point sameLine(List<Point> points) {
		for (int i = 0; i + 1 < points.size(); i+=2) {
			print(points.get(i), points.get(i + 1));
		}
		return points.size() % 2 == 1 ? points.get(points.size() - 1) : null;
	}

	static class Point {
		int x, y, z, id;

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

	static class MyScanner {
		private BufferedReader br;
		private StringTokenizer tokenizer;

		public MyScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		public String next() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					tokenizer = new StringTokenizer(br.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.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.util.Comparator;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
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);
        TaskC1 solver = new TaskC1();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC1 {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int[][] p = new int[n][4];
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < 3; ++j) {
                    p[i][j] = in.nextInt();
                }
                p[i][3] = i + 1;
            }
            Arrays.sort(p, new Comparator<int[]>() {

                public int compare(int[] o1, int[] o2) {
                    for (int i = 0; i < o1.length; ++i) if (o1[i] != o2[i]) return o1[i] - o2[i];
                    return 0;
                }
            });
            boolean[] alive = new boolean[n];
            Arrays.fill(alive, true);
            for (int i = 0; i < n; ++i)
                if (alive[i]) {
                    int j = i + 1;
                    while (!alive[j]) ++j;
                    int diff = 0;
                    while (p[i][diff] == p[j][diff]) ++diff;
                    int k = j;
                    while (k < n && p[k][diff] == p[j][diff]) ++k;
                    int bestScore = Integer.MAX_VALUE;
                    int bt = -1;
                    for (int t = j; t < k; ++t)
                        if (alive[t]) {
                            int score = 0;
                            for (int u = 0; u < 3; ++u) score += Math.abs(p[i][u] - p[t][u]);
                            if (score < bestScore) {
                                bestScore = score;
                                bt = t;
                            }
                        }
                    alive[i] = false;
                    alive[bt] = false;
                    out.println(p[i][3] + " " + p[bt][3]);
                }
        }

    }

    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());
        }

    }
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 20 * 1000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	shuffle(a, a + n, rnd);
	used.reset();
	used.flip();
	forn(_, n / 2){
		int pa = used._Find_first();
		int pb = used._Find_next(pa);
		for (int j = used._Find_next(pb); j < min(MAGIC, n); j = used._Find_next(j)) if (in(a[j], a[pa], a[pb])){
			pa = j;
			swap(pa, pb);
		}
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		used[pa] = 0;
		used[pb] = 0;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 5000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	shuffle(a, a + n, rnd);
	vector<pt> res;
	int fr = -1;
	forn(i, n){
		int cur = i;
		fore(j, max(0, sz(res) - MAGIC), sz(res)) if (in(a[cur], a[res[j].x], a[res[j].y]))
			swap(cur, res[j].y);
		if (fr != -1){
			res.pb(mp(cur, fr));
			fr = -1;
		}
		else{
			fr = cur;
		}
	}
	for (auto it : res){
		printf("%d %d\n", a[it.x].i + 1, a[it.y].i + 1);
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 20 * 1000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	shuffle(a, a + n, rnd);
	used.reset();
	used.flip();
	forn(_, n / 2){
		int pa = used._Find_first();
		int pb = used._Find_next(pa);
		for (int j = used._Find_next(pb + 1), cnt = 0; cnt < min(MAGIC, n); j = used._Find_next(j + 1), ++cnt) if (in(a[j], a[pa], a[pb])){
			pa = j;
			swap(pa, pb);
		}
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		used[pa] = 0;
		used[pb] = 0;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 20 * 1000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	sort(a, a + n, [](const point &a, const point &b){
		return a.x + a.y + a.z < b.x + b.y + b.z;
	});
	used.reset();
	used.flip();
	forn(_, n / 2){
		int pa = used._Find_first();
		int pb = used._Find_next(pa);
		for (int j = used._Find_next(pb); j < min(MAGIC, n); j = used._Find_next(j)) if (in(a[j], a[pa], a[pb]))
			pb = j;
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		used[pa] = 0;
		used[pb] = 0;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

bool in(int a, int b, int c){
	return b <= a && a <= c;
}

bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

void solve() {
	shuffle(a, a + n, rnd);
	while (n > 0){
		int pa = 0;
		int pb = 1;
		fore(j, 2, n) if (in(a[j], a[pa], a[pb]))
			pb = j;
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		int m = 0;
		forn(j, n) if (j != pa && j != pb)
			a[m++] = a[j];
		n -= 2;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

void solve() {
	shuffle(a, a + n, rnd);
	while (n > 0){
		int pa = 0;
		int pb = 1;
		fore(j, 2, n) if (in(a[j], a[pa], a[pb]))
			pb = j;
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		int m = 0;
		forn(j, n) if (j != pa && j != pb)
			a[m++] = a[j];
		n -= 2;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 1000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

void solve() {
	shuffle(a, a + n, rnd);
	while (n > 0){
		int pa = 0;
		int pb = 1;
		fore(j, 2, min(n, MAGIC)) if (in(a[j], a[pa], a[pb]))
			pb = j;
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		int m = 0;
		forn(j, n) if (j != pa && j != pb)
			a[m++] = a[j];
		n -= 2;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;
 //asd
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 20 * 1000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	shuffle(a, a + n, rnd);
	used.reset();
	used.flip();
	forn(_, n / 2){
		int pa = used._Find_first();
		int pb = used._Find_next(pa);
		for (int j = used._Find_next(pb); j < min(MAGIC, n); j = used._Find_next(j)) if (in(a[j], a[pa], a[pb]))
			pb = j;
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		used[pa] = 0;
		used[pb] = 0;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 2000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	shuffle(a, a + n, rnd);
	vector<pt> res;
	int fr = -1;
	forn(i, n){
		int cur = i;
		fore(j, max(0, sz(res) - MAGIC), sz(res)) if (in(a[cur], a[res[j].x], a[res[j].y]))
			swap(cur, res[j].y);
		if (fr != -1){
			res.pb(mp(cur, fr));
			fr = -1;
		}
		else{
			fr = cur;
		}
	}
	for (auto it : res){
		printf("%d %d\n", a[it.x].i + 1, a[it.y].i + 1);
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 5 * 1000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	shuffle(a, a + n, rnd);
	used.reset();
	used.flip();
	forn(i, n / 2){
		int pa = used._Find_first();
		int pb = used._Find_next(pa);
		for (int j = used._Find_next(pb), cnt = 0; cnt < min(MAGIC, n - (i + 1) * 2); j = used._Find_next(j), ++cnt) if (in(a[j], a[pa], a[pb])){
			pa = j;
			swap(pa, pb);
		}
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		used[pa] = 0;
		used[pb] = 0;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 20 * 1000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	sort(a, a + n, [](const point &a, const point &b){
		return a.x + a.y + a.z < b.x + b.y + b.z;
	});
	used.reset();
	used.flip();
	forn(_, n / 2){
		int pa = used._Find_first();
		int pb = used._Find_next(pa);
		for (int j = used._Find_next(pb); j < min(MAGIC, n); j = used._Find_next(j)) if (in(a[j], a[pa], a[pb])){
			pa = j;
			swap(pa, pb);
		}
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		used[pa] = 0;
		used[pb] = 0;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 3000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	shuffle(a, a + n, rnd);
	vector<pt> res;
	int fr = -1;
	forn(i, n){
		int cur = i;
		fore(j, max(0, sz(res) - MAGIC), sz(res)) if (in(a[cur], a[res[j].x], a[res[j].y]))
			swap(cur, res[j].y);
		if (fr != -1){
			res.pb(mp(cur, fr));
			fr = -1;
		}
		else{
			fr = cur;
		}
	}
	for (auto it : res){
		printf("%d %d\n", a[it.x].i + 1, a[it.y].i + 1);
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 2000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	vector<pt> res;
	sort(a, a + n, [](const point &a, const point &b){
		if (a.x != b.x)
			return a.x < b.x;
		if (a.y != b.y)
			return a.y < b.y;
		return a.z < b.z;
	});
	set<pair<pt, pt>> q;
	forn(i, n - 1) q.insert(mp(mp(abs(a[i].x - a[i + 1].x), abs(a[i].y - a[i + 1].y)), mp(abs(a[i].z - a[i + 1].z), i)));
	forn(_, n / 2){
		auto it = *q.begin();
		int i = it.y.y - 1;
		if (i >= 0 && q.count(mp(mp(abs(a[i].x - a[i + 1].x), abs(a[i].y - a[i + 1].y)), mp(abs(a[i].z - a[i + 1].z), i))))
			q.erase(q.find(mp(mp(abs(a[i].x - a[i + 1].x), abs(a[i].y - a[i + 1].y)), mp(abs(a[i].z - a[i + 1].z), i))));
		++i;
		if (q.count(mp(mp(abs(a[i].x - a[i + 1].x), abs(a[i].y - a[i + 1].y)), mp(abs(a[i].z - a[i + 1].z), i))))
			q.erase(q.find(mp(mp(abs(a[i].x - a[i + 1].x), abs(a[i].y - a[i + 1].y)), mp(abs(a[i].z - a[i + 1].z), i))));
		++i;
		if (i < n - 1 && q.count(mp(mp(abs(a[i].x - a[i + 1].x), abs(a[i].y - a[i + 1].y)), mp(abs(a[i].z - a[i + 1].z), i))))
			q.erase(q.find(mp(mp(abs(a[i].x - a[i + 1].x), abs(a[i].y - a[i + 1].y)), mp(abs(a[i].z - a[i + 1].z), i))));
		--i;
		res.pb(mp(i, i + 1));
	}
	for (auto it : res){
		printf("%d %d\n", a[it.x].i + 1, a[it.y].i + 1);
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 10;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	sort(a, a + n, [](const point &a, const point &b){
		if (a.x != b.x) return a.x < b.x;
		if (a.y != b.y) return a.y < b.y;
		return a.z < b.z;
	});
	used.reset();
	used.flip();
	forn(i, n / 2){
		int pa = used._Find_first();
		int pb = used._Find_next(pa);
		for (int j = used._Find_next(pb), cnt = 0; cnt < min(MAGIC, n - (i + 1) * 2); j = used._Find_next(j), ++cnt) if (in(a[j], a[pa], a[pb])){
			pa = j;
			swap(pa, pb);
		}
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		used[pa] = 0;
		used[pb] = 0;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 1000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

void solve() {
	sort(a, a + n, [](const point &a, const point &b){
		if (a.x != b.x) return a.x < b.x;
		if (a.y != b.y) return a.y < b.y;
		return a.z < b.z;
	});
	forn(i, n / 2){
		int pa = 2 * i;
		int pb = 2 * i + 1;
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = int(1e9) + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 50 * 1000 + 13;
const int MAGIC = 10 * 1000;

struct point{
	int x, y, z, i;
};

int n;
point a[N];

bool read () {
	if (scanf("%d", &n) != 1)
		return false;
	forn(i, n){
		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
		a[i].i = i;
	}
	return true;
}

inline bool in(int a, int b, int c){
	if (b > c) swap(b, c);
	return b <= a && a <= c;
}

inline bool in(const point &a, const point &b, const point &c){
	return in(a.x, b.x, c.x) && in(a.y, b.y, c.y) && in(a.z, b.z, c.z);
}

bitset<N> used;

void solve() {
	shuffle(a, a + n, rnd);
	used.reset();
	used.flip();
	forn(_, n / 2){
		int pa = used._Find_first();
		int pb = used._Find_next(pa);
		for (int j = used._Find_next(pb + 1), cnt = 0; cnt < min(MAGIC, n); j = used._Find_next(j + 1), ++cnt) if (in(a[j], a[pa], a[pb])){
			pa = j;
			swap(pa, pb);
		}
		printf("%d %d\n", a[pa].i + 1, a[pb].i + 1);
		used[pa] = 0;
		used[pb] = 0;
	}
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();
#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

#ifdef _DEBUG
	while(read()) {
#else
	if(read()) {
#endif
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include <iostream>
 #include <queue>

using namespace std;
 int main(){

int a;
     cin >> a;

int price,quality;
     for( int i = 0; i <a; i++ ) {
       cin >> price;
       cin >> quality;
       if(price != quality){
         cout<<"Happy Alex";
         return(0);
       }else{
       cout<<"Poor Alex";
       return(0);
     }
}
}


#include <iostream>

#include <vector>
#include <string>

using namespace std;

int main(){
    int n;
    cin >> n;
    vector<pair<int, int>> laptops;
    for (int i = 0; i < n; ++i) {
        int a, b;
        cin >> a >> b;
        laptops.push_back({a, b});
    }
    for (int i = 0; i < n; ++i) {
        if (laptops[i].first < laptops[i].second){
            cout << "Happy Alex";
            return 0;
        }
    }
    cout << "Poor Alex";
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define endl '\n'

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    vector<pair<int, int> > v;
    for (int i = 0; i < n; ++i) {
        int start, finish;
        cin >> start >> finish;
        v.push_back(make_pair(start, finish));
    }
    sort(v.begin(), v.end());

    for (int i = 0; i < n - 1; i++) {
        if (v[i].first < v[i + 1].first && v[i].second > v[i + 1].second) {
            cout << "Happy Alex" << endl;
            return 0;
        }
    }
    cout << "Poor Alex" << endl;
}


include "bits/stdc++.h"
using namespace std;
using namespace std;
int main() {
    int n,a,b;
    cin>>n;
    for (int i=0;i<n;i++){
        cin>>a>>b;
        if (a!=b){
            cout<<"Happy Alex";
            return 0;
        }
    }
    cout<<"Poor Alex";
}


#include <bits/stdc++.h>
using namespace std;
int main(){
   int n,t,k;
   int a,b;
   while(cin>>n)&& n!=-1){
        k=0;
        for(int i=0;i<n;i++){
            cin >>a>>b;
            if(a!=b){
                k=1;
            }
        }
        if(k){
            cout<<"Happy Alex"<<endl;
        }
        else{
            cout<<"Poor Alex"<<endl;
        }
    }
   return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main() {
	ios::sync_with_stdio();
	cin.tie(0);

    int n;
    cin >> n;

    vector<pair<int, int>> v;

    for (int i = 0; i < n; i++) {
        int a, b;
        cin >> a >> b;
        v.push_back({a, b});
    }

    sort(v.begin(), v.end());

    for (int i = 0; i < n - 1; i++) {
        if (v[i].second > v[i + 1].first) {
            cout << "Poor Alex" << '\n';
            return 0;
        }
    }
    cout << "Happy Alex" << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define endl '\n';

typedef long long ll;
typedef pair<int, int> pii;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n; cin >> n;
    bool alex = false;
    for (int i = 0; i < n; ++i) {
        int a, b;
        cin >> a >> b;
        if ( b > a) {
            alex = true;
        }
    }
    if(alex) {
        cout << "Happy Alex" << endl;
    } else {
        cout << "Poor Alex" << endl;
    }
}


#include <iostream>
using namespace std;
int n, a, b;
bool qq = false;
int main() {
    cin >> n;
    int arr1[n];
    int arr2[n];
    for (int i = 0; i < n; i++) {
        cin >> a >> b;
        arr1[i] = a;
        arr2[i] = b;
    }
        for(int j=0; j<n; j++){
        for(int k = j+1; k<n; k++ ){
            if(arr1[j]<arr1[k] && arr2[j]>arr2[k]) {
                qq = true;
}
        }
}
    if(qq = true){
        cout << "Happy Alex";}
        else{
    cout << "Sad Alex";
    }
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define endl '\n'

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    vector<pair<int, int> > v;
    for (int i = 0; i < n; ++i) {
        int start, finish;
        cin >> start >> finish;
        v.push_back(make_pair(start, finish));
    }
    sort(v.begin(), v.end());

    for (int i = 0; i < n - 1; ++i) {
        if (v[i].second > v[i + 1].first) {
            cout << "Poor Alex" << endl;
            return 0;
        }
    }
    cout << "Happy Alex" << endl;
}


  #include <iostream>

using namespace std;
int main(){
int a;
cin >> a;
int quality[1000010];
int price[1000010];
for( int i = 0; i <a; i++ ) {
  cin >> price[i];
  cin >> quality[i];

  if (price[0]<price[1] && quality[0]>quality[1]){
    cout<<"Happy Alex";
    return(0);
}
}
cout<<"Poor Alex";
}


#include <iostream>
using namespace std;
int n, a, b;
int main() {
    cin >> n;
    int arr1[n];
    int arr2[n];
    for (int i = 0; i < n; i++) {
        cin >> a >> b;
        arr1[i] = a;
        arr2[i] = b;
    }
        for(int j=0; j<n; j++){
        for(int k = j+1; k<n; k++ ){
            if(arr1[j]<=arr1[k] && arr2[j]>arr2[k] || arr1[j]<arr1[k] && arr2[j]>=arr2[k]) {
                cout<< "Happy Alex";
            }
            else{
                cout<<"Sad Alex";//
            }
        }
        }
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define endl '\n'

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    vector<pair<int, int> > v;
    for (int i = 0; i < n; ++i) {
        int start, finish;
        cin >> start >> finish;
        v.push_back(make_pair(start, finish));
    }
    sort(v.begin(), v.end());

    for (int i = 0; i < n - 1; ++i) {
        if (v[i].first > v[i + 1].first && v[i].second < v[i+i].second) {
            cout << "Poor Alex" << endl;
            return 0;
        }
    }
    cout << "Happy Alex" << endl;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define endl '\n'

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    vector<pair<int, int> > v;
    for (int i = 0; i < n; ++i) {
        int start, finish;
        cin >> start >> finish;
        v.push_back(make_pair(start, finish));
    }
    sort(v.begin(), v.end());

    for (int i = 0; i < n - 1; ++i) {
        if (v[i].first < v[i + 1].first && v[i].second > v[i+i].second) {
            cout << "Poor Alex" << endl;
            return 0;
        }
    }
    cout << "Happy Alex" << endl;
}


//You are given two arrays A and B consisting of integers, sorted in non-decreasing order.
//Check whether it is possible to choose k numbers in array A and choose m numbers in array B so that any number chosen in the first array is strictly
//less than any number chosen in the second array.

  #include <iostream>
  #include <queue>

using namespace std;
  int main(){

int a;
      cin >> a;

int price,quality;
      for( int i = 0; i <a; i++ ) {
        cin >> price;
        cin >> quality;
        if(price>quality){
          cout<<"Happy Alex";
        }else
        cout<<"Poor Alex";
}
}


#include <iostream>
using namespace std;
int n, a, b;
int main() {
    cin >> n;
    int arr1[n];
    int arr2[n];
    for (int i = 0; i < n; i++) {
        cin >> a >> b;
        arr1[i] = a;
        arr2[i] = b;
    }
        for(int j=0; j<n; j++){
        for(int k = j+1; k<n; k++ ){
            if(arr1[j]<=arr1[k] && arr2[j]>arr2[k] || arr1[j]<arr1[k] && arr2[j]>=arr2[k]) {
                cout<< "Happy Alex";
            }
            else{
                cout<<"Sad Alex";
            }
        }
        }
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define endl '\n'

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    vector<pair<int, int> > v;
    for (int i = 0; i < n; ++i) {
        int start, finish;
        cin >> start >> finish;
        v.push_back(make_pair(start, finish));
    }
    sort(v.begin(), v.end());

    for (int i = 0; i < n - 1; ++i) {
        if (v[i].first >= v[i + 1].first && v[i].second <= v[i+i].second) {
            cout << "Poor Alex" << endl;
            return 0;
        }
    }
    cout << "Happy Alex" << endl;
}


#include <iostream>
using namespace std;
int n, a, b;
int main() {
    cin >> n;
    int arr1[n];
    int arr2[n];
    for (int i = 0; i < n; i++) {
        cin >> a >> b;
        arr1[i] = a;
        arr2[i] = b;
    }
        for(int j=0; j<n; j++){
        for(int k = j+1; k<n; k++ ){
            if(arr1[j]<arr1[k] && arr2[j]>arr2[k]) {
                cout<< "Happy Alex";
            }
            else{
                cout<<"Sad Alex";
            }
        }
        }
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
int main(){
	ll int t,i,a[100000],b[100000];
	cin>>t;
	for(i=0;i<t;i++)
    {
        cin>>a[i]>>b[i];

    }
        for(i=0;i<t;i++)
            if(a[i]!=b[i])
            break;
        if(i<t)
            cout<<"Happy Alex";
        else
        cout<<"Poor Alex";
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t,flag=0,a,b,m,n;
	cin>>t;
	while(t--)
	{
		 a,b;
		cin>>a>>b;
	/*	if(a<m&&b>n)
		{
		//	cout<<"Happy Alex"<<endl;
		flag=1;
		break;
		}*/
		if(t==1
		)
		{
			m=a;
			n=b;
		}

	}
	if(a<m&&b>n)
	cout<<"Happy Alex"<<endl;
	else
	cout<<"Poor Alex"<<endl;

}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    int a[t];
    int b[t];
   for(int i=0;i<n;i++)
    {
        cin>>a[i]>>b[i];
    }
    int flag1=0,flag2=0;
    for(int i=0;i<t-1;i++)
    {
        if(a[i]<a[i+1])
        {
            flag1=1;

        }
        else
        {
           flag1=0;
           break;
        }
    }
    for(int i=0;i<t-1;i++)
    {
        if(a[i]<a[i+1])
        {
            flag2=1;

        }
        else
        {
           flag2=0;
           break;
        }
    }
    if(flag1==1&&flag2==1)
    {
        cout<<"Happy Alex"<<endl;

    }
    else
    {
        cout<<"Poor Alex"<<endl;
    }
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long int n,i;
    cin>>n;
    long long int a[1000],b[1000];
    for(i=0;i<n;i++)
    {
        cin>>a[i]>>b[i];
    }
    for(i=0;i<n;i++)
    {
        if(a[i]!=b[i])
            break;

    }
    if(i<n)
    {
        cout<<"Happy Alex"<<endl;
    }
    else
    {
        cout<<"Poor Alex"<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
int main()
{
long long int t;
cin>>t;

long long int a[t],b[t];
long long int i=0;
while(t--)
{
	cin>>a[i]>>b[i];
	i++;
}
int flag1=1,flag2=1;
sort(a,a+i);
//sort(b,b+i);
for(int j=0;j<i-1;j++)
{
	if(!(a[j]<a[j+1]))
	{
		flag1=0;
		break;
	}
	if(!(b[j]>b[j+1]))
	{
		flag2=0;
		break;
	}
}
if(flag1==1&&flag2==1)
{
	cout<<"Happy Alex";
}
else
{
	cout<<"Poor Alex";
}
}


#include<bits/stdc++.h>
#include<string.h>
using namespace std;
#define ll long long
int main(){
	ll int t,i,a[100000],b[100000];
	cin>>t;
	for(i=0;i<t;i++)
    {
        cin>>a[i]>>b[i];

    }
        for(i=0;i<t;i++)
            if(a[i]!=b[i])
            break;
        if(i<n)
            cout<<"Happy Alex";
        else
        cout<<"Poor Alex";
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t,i=0;

	cin>>t;
	int n=t;
	int a[n],b[n];
	while(t--)
	{

		cin>>a[i]>>b[i];
		i++;

	}
	if((a[0]<a[1])&&(b[0]>b[1]))
	{
		cout<<"Happy Alex";
	}
	else
	{
		cout<<"Poor Alex";
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
long long int t;
cin>>t;

long long int a[t],b[t];
long long int i=0;
while(t--)
{
	cin>>a[i]>>b[i];
	i++;
}
int flag1=1,flag2=1;
for(int j=0;j<i-1;j++)
{
	if(!(a[j]<a[j+1]))
	{
		flag1=0;
		break;
	}
	if(!(b[j]>b[j+1]))
	{
		flag2=0;
		break;
	}
}
if(flag1==1&&flag2==1)
{
	cout<<"Happy Alex";
}
else
{
	cout<<"Poor Alex";
}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,i;
    cin>>n;
    int a[n],b[n];
    for(int i=0;i<n;i++)
    {
        cin>>a[i]>>b[i];
    }
    for(int i=0;i<n;i++)
    {
        if(a[i]!=b[i])
            break;

    }
    if(i<n)
    {
        cout<<"Happy Alex"<<endl;
    }
    else
    {
        cout<<"Poor Alex"<<endl;
    }

}


#include<bits/stdc++.h>
#include<string.h>
using namespace std;
#define ll long long
int main(){
	lli nt t,i,a[100000],b[100000];
	cin>>t;
	for(i=0;i<t;i++)
    {
        cin>>a[i]>>b[i];}
        for(i=0;i<t;i++)
            if(a[i]!=b[i])
            break;
        if(i<t)
            cout<<"Happy Alex";
        else
        cout<<"Poor Alex";
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    int a[t];
    int b[t];
   for(int i=0;i<t;i++)
    {
        cin>>a[i]>>b[i];
    }
    int flag1=0,flag2=0;
    for(int i=0;i<t-1;i++)
    {
        if(a[i]<a[i+1])
        {
            flag1=1;

        }
        else
        {
           flag1=0;
           break;
        }
    }
    for(int i=0;i<t-1;i++)
    {
        if(a[i]<a[i+1])
        {
            flag2=1;

        }
        else
        {
           flag2=0;
           break;
        }
    }
    if(flag1==1&&flag2==1)
    {
        cout<<"Happy Alex"<<endl;

    }
    else
    {
        cout<<"Poor Alex"<<endl;
    }
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    int a[t];
    int b[t];
   for(int i=0;i<n;i++)
    {
        cin>>a[i]>>b[i];
    }
    int flag1=0,flag2=0;
    for(int i=0;i<t-1;i++)
    {
        if(a[i]<a[i+1])
        {
            flag1=1;

        }
        else
        {
           flag1=0;
           break;
        }
    }
    for(int i=0;i<t-1;i++)
    {
        if(a[i]<a[i+1])
        {
            flag2=1;

        }
        else
        {
           flag2=0;
           break;
        }
    }
    if(flag1==1&&flag2==1)
    {
        cout<<"Happy alex!"<<endl;

    }
    else
    {
        cout<<"Poor alex!"<<endl;
    }
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;

int a[t],b[t];
int i=0;
while(t--)
{
	cin>>a[i]>>b[i];
	i++;
}
int flag1=1,flag2=1;
for(int j=0;j<i-1;j++)
{
	if(!(a[j]<a[j+1]))
	{
		flag1=0;
		break;
	}
	if(!(b[j]>b[j+1]))
	{
		flag2=0;
		break;
	}
}
if(flag1==1&&flag2==1)
{
	cout<<"Happy Alex";
}
else
{
	cout<<"Poor Alex";
}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t,i=0;

	cin>>t;
	int n=t;
	int k=t/2;
	int a[n],b[n];
	while(k--)
	{

		cin>>a[i]>>b[i];
		i++;
		cin>>a[i]>>b[i];

	}
	if((a[0]<a[1])&&(b[0]>b[1]))
	{
		cout<<"Happy Alex";
	}
	else
	{
		cout<<"Poor Alex";
	}
}


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

int p[100000], q[100000], i, j, x, n, pr, kw, w;
bool ye;

int main(){

    cin >> n;
    for (i=1; i<=n; i++) {
      cin >> pr >> kw;
      p[i]=pr;
      q[i]=kw;
    }
    for (x=1; x<=n-1; x++) {
      for (i=x+1; i<=n; i++) {
        if ((p[x]>p[i] and q[i]>q[x]) or (p[x]<p[i] and q[i]<q[x])) {
          cout << "Happy Alex";
          ye = true;
        }
      }
    }
    if (ye==false) {
      cout << "Poor Alex";
    }

}


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

int p[100000], q[100000], i, j, x, n, pr, kw, w;
bool ye;

int main(){

    cin >> n;
    for (i=1; i<=n; i++) {
      cin >> pr >> kw;
      p[i]=pr;
      q[i]=kw;
    }
    for (x=1; x<=n; x++) {
      if (ye==false) {
        for (i=x; i<=n; i++) {
          if ((p[i]<p[x] and q[i]>q[x]) or (p[i]>p[x] and q[i]<q[x])) {
            cout << "Happy Alex";
            ye = true;
            break;
          }
        }
      }
    }
    if (ye==false) {
      cout << "Poor Alex";
    }

}


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

int p[100000], q[100000], i, j, x, n, pr, kw, w;
bool ye;

int main(){

    cin >> n;
    for (i=1; i<=n; i++) {
      cin >> pr >> kw;
      p[i]=pr;
      q[i]=kw;
    }
    for (x=1; x<=n; x++) {
      if (ye==false) {
        for (i=x; i<=n; i++) {
          if ((p[i]<p[x] and q[i]>q[x]) or (p[i]>p[x] and q[i]<q[x])) {
            cout << "Happy Alex";
            ye = true;
            break;
          }
        }
      }
      else {
        break;
      }
    }
    if (ye==false) {
      cout << "Poor Alex";
    }

}


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

int p[100000], q[100000], i, j, x, n, pr, kw, w;
bool ye;

int main(){

    cin >> n;
    for (i=1; i<=n; i++) {
      cin >> pr >> kw;
      p[i]=pr;
      q[i]=kw;
    }
    for (x=1; x<=n; x++) {
      for (i=x; i<=n; i++) {
        if ((p[i]<p[x] and q[i]>q[x]) or (p[i]>p[x] and q[i]<q[x])) {
          cout << "Happy Alex";
          ye = true;
        }
      }
    }
    if (ye==false) {
      cout << "Poor Alex";
    }

}


#include <iostream>
using namespace std;

int n, i, p, q, lt[200000];
bool out;

int main () {
   cin >> n;
   for (i=1; i<=n; i++) {
    cin >> p >> q;
    lt[p]=q;
   }
   for (i=2; i<=n; i++) {
    if (lt[i]<lt[i-1]) {
      cout << "Happy Alex" << endl;
      out=true;
      break;
    }
   }
   if (out==false) {
    cout << "Poor Alex" << endl;
   }
}


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

int n, i, j, p[100005], q[100005], a, b;
bool y;

int main(){

   cin >> n;
   for (i=1; i<=n; i++) {
    cin >> a >> b;
    p[i]=a;
    q[i]=b;
   }
   for (i=1; i<=n; i++) {
    for (j=i; j<=n; j++) {
      if (p[i]>p[j]) {
        a=p[i];
        p[i]=p[j];
        p[j]=a;
        b=q[i];
        q[i]=q[j];
        q[j]=b;
      }
    }
   }
   for (i=1; i<=n-1; i++) {
    if (q[i+1]<q[i] and y==false) {
      cout << "Happy Alex";
      y=true;
      break;
    }
   }
   if (y==false) {
    cout << "Poor Alex";
   }

}


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

int n, i, j, p[100005], q[100005], a, b;
bool y;

int main(){
   ios_base::sync_with_stdio(0); cin.tie(NULL);
   cin >> n;
   for (i=1; i<=n; i++) {
    cin >> a >> b;
    p[i]=a;
    q[i]=b;
   }
   for (i=1; i<=n; i++) {
    for (j=i; j<=n; j++) {
      if (p[i]>p[j]) {
        a=p[i];
        p[i]=p[j];
        p[j]=a;
        b=q[i];
        q[i]=q[j];
        q[j]=b;
      }
    }
   }
   for (i=1; i<=n-1; i++) {
    if (q[i+1]<q[i] and y==false) {
      cout << "Happy Alex";
      y=true;
      break;
    }
   }
   if (y==false) {
    cout << "Poor Alex";
   }

}


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

int n, i, j, p[100005], q[100005], a, b;
bool y;

int main(){

   cin >> n;
   for (i=1; i<=n; i++) {
    cin >> a >> b;
    p[i]=a;
    q[i]=b;
   }
   for (i=1; i<=n; i++) {
    for (j=i; j<=n; j++) {
      if (p[i]>p[j]) {
        a=p[i];
        p[i]=p[j];
        p[j]=a;
        b=q[i];
        q[i]=q[j];
        q[j]=b;
      }
    }
   }
   for (i=1; i<=n-1; i++) {
    if (q[i+1]<q[i] and y==false) {
      cout << "Happy Alex";
      y=true;
    }
   }
   if (y==false) {
    cout << "Poor Alex";
   }

}


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

int n, i, j, p[100005], q[100005], a, b;
bool y;

int main(){
   ios_base::sync_with_stdio(0); cin.tie(NULL);
   cin >> n;
   for (i=1; i<=n; i++) {
    cin >> a >> b;
    p[i]=a;
    q[i]=b;
   }
   for (i=1; i<=n; i++) {
    for (j=i; j<=n; j++) {
      if (p[i]>p[j]) {
        a=p[i];
        p[i]=p[j];
        p[j]=a;
        b=q[i];
        q[i]=q[j];
        q[j]=b;
      }
    }
   }
   for (i=1; i<=n-1; i++) {
    if (q[i+1]<q[i] and y==false) {
      cout << "Happy Alex";
      y=true;
    }
   }
   if (y==false) {
    cout << "Poor Alex";
   }

}


#include <iostream>
using namespace std;

int n, i, p, q, lt[200000];
bool out;

int main () {
   cin >> n;
   for (i=1; i<=n; i++) {
    cin >> p >> q;
    lt[p]=q;
   }
   for (i=2; i<=n; i++) {
    if (lt[i]<lt[i-1]) {
      cout << "Happy Alex" << endl;
      out=true;
    }
   }
   if (out==false) {
    cout << "Poor Alex" << endl;
   }
}


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

int p[100000], q[100000], i, j, x, n, pr, kw, w;
bool ye;

int main(){

    cin >> n;
    for (i=1; i<=n; i++) {
      cin >> pr >> kw;
      p[i]=pr;
      q[i]=kw;
    }
    for (x=1; x<=n-1; x++) {
      for (i=x+1; i<=n; i++) {
        if (p[i]<p[x]) {
          j=p[i];
          p[i]=p[x];
          p[x]=j;
          w=q[i];
          q[i]=q[x];
          q[x]=w;
        }
      }
    }
    ye=false;
    for (i=1; i<=n-1; i++) {
      if (ye==false) {
        for (j=i+1; j<=n; j++) {
          if (q[j]<q[i]) {
            cout << "Happy Alex";
            ye=true;
            break;
          }
        }
      }
    }
    if (ye==false) {
      cout << "Poor Alex";
    }

}


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

int n, i, j, p[100005], q[100005], a, b;
bool y;

int main(){

   cin >> n;
   for (i=1; i<=n; i++) {
    cin >> a >> b;
    p[i]=a;
    q[i]=b;
   }
   for (i=1; i<=n; i++) {
    for (j=i; j<=n; j++) {
      if (p[i]>p[j]) {
        a=p[i];
        p[i]=p[j];
        p[j]=a;
        b=q[i];
        q[i]=q[j];
        q[j]=b;
      }
    }
   }
   for (i=1; i<=n-1; i++) {
    if (q[i+1]<q[i]) {
      cout << "Happy Alex";
      y=true;
    }
   }
   if (y==false) {
    cout << "Poor Alex";
   }

}


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

int n, i, j, p[100005], q[100005], a, b;
bool y;

int main(){

   cin >> n;
   for (i=1; i<=n; i++) {
    cin >> a >> b;
    p[i]=a;
    q[i]=b;
   }
   for (i=1; i<=n; i++) {
    for (j=i; j<=n; j++) {
      if (p[i]>p[j]) {
        a=p[i];
        p[i]=p[j];
        p[j]=a;
        b=q[i];
        q[i]=q[j];
        q[j]=b;
      }
    }
   }
   for (i=1; i<=n-1; i++) {
    if (q[i+1]<q[i]) {
      cout << "Happy Alex";
      break;
    }
   }
   if (y==false) {
    cout << "Poor Alex";
   }

}


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

int p[100000], q[100000], i, j, x, n, pr, kw, w;
bool ye;

int main(){

    cin >> n;
    for (i=1; i<=n; i++) {
      cin >> pr >> kw;
      p[i]=pr;
      q[i]=kw;
    }
    for (x=1; x<=n-1; x++) {
      for (i=x+1; i<=n; i++) {
        if (p[i]<p[x]) {
          j=p[i];
          p[i]=p[x];
          p[x]=j;
          w=q[i];
          q[i]=q[x];
          q[x]=w;
        }
      }
    }
    ye=false;
    for (i=1; i<=n-1; i++) {
      if (q[i]>q[i+1]) {
        cout << "Happy Alex";
        ye=true;
        break;
      }
    }
    if (ye==false) {
      cout << "Poor Alex";
    }

}