Problem:
Score : 800 points

Problem Statement

Takahashi is doing a research on sets of points in a plane.
Takahashi thinks a set S of points in a coordinate plane is a good set when S satisfies both of the following conditions:

The distance between any two points in S is not \sqrt{D_1}.

The distance between any two points in S is not \sqrt{D_2}.

Here, D_1 and D_2 are positive integer constants that Takahashi specified.

Let X be a set of points (i,j) on a coordinate plane where i and j are integers and satisfy 0 ≤ i,j < 2N.

Takahashi has proved that, for any choice of D_1 and D_2, there exists a way to choose N^2 points from X so that the chosen points form a good set.
However, he does not know the specific way to choose such points to form a good set.
Find a subset of X whose size is N^2 that forms a good set.

Constraints

1 ≤ N ≤ 300

1 ≤ D_1 ≤ 2×10^5

1 ≤ D_2 ≤ 2×10^5

All values in the input are integers.

Input

Input is given from Standard Input in the following format:

N D_1 D_2

Output

Print N^2 distinct points that satisfy the condition in the following format:

x_1 y_1
x_2 y_2
:
x_{N^2} y_{N^2}

Here, (x_i,y_i) represents the i-th chosen point.
0 ≤ x_i,y_i < 2N must hold, and they must be integers.
The chosen points may be printed in any order.
In case there are multiple possible solutions, you can output any.

Sample Input 1

2 1 2

Sample Output 1

0 0
0 2
2 0
2 2

Among these points, the distance between 2 points is either 2 or 2\sqrt{2}, thus it satisfies the condition.

Sample Input 2

3 1 5

Sample Output 2

0 0
0 2
0 4
1 1
1 3
1 5
2 0
2 2
2 4

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)

import java.util.*;

class Main{
	
	public static void main(String args[]){

		Scanner sc = new Scanner(System.in);
		
		int N = sc.nextInt();
		int D1 = sc.nextInt();
		int D2 = sc.nextInt();

		ArrayList<Point> BAN = new ArrayList<>();
		ArrayList<Point> ANS = new ArrayList<>();

		for(int d=0;d<=Math.sqrt(D1);d++){
			for(int e=d;e<=Math.sqrt(D1);e++){
				if(Math.pow(d,2) + Math.pow(e,2) == D1){
					BAN.add(new Point(d,e));
					if(d!=e) BAN.add(new Point(e,d));
				}
			}
		}
		for(int d=0;d<=Math.sqrt(D2);d++){
			for(int e=d;e<=Math.sqrt(D2);e++){
				if(Math.pow(d,2) + Math.pow(e,2) == D2){
					BAN.add(new Point(d,e));
					if(d!=e) BAN.add(new Point(e,d));
				}
			}
		}

		int x = 0,y = 0;
		ANS.add(new Point(x,y));
		System.out.println(x+" "+y);

		int turn = 1;
		outside:while(turn<Math.pow(N,2)){
			x++;
			if(x==2*N){
				x = 0;
				y++;
			}
			for(int a=0;a<ANS.size();a++){
				
				if(BAN.indexOf(new Point(x-ANS.get(a).x,y-ANS.get(a).y)) != -1) continue outside;
			}

				System.out.println(x+" "+y);
				ANS.add(new Point(x,y));
				/*int bsize = BAN.size();
				for(int b=0;b<bsize;b++){
					int i = BAN.get(b).x;
					int j = BAN.get(b).y;
					if(x+i<=2*N && y+j<=2*N && BAN.indexOf(new Point(x+i,y+j)) == -1){
					 BAN.add(new Point(x+i,y+j));
					}
					if(x-i>=0 && y+j<=2*N && BAN.indexOf(new Point(x-i,y+j)) == -1){
					 BAN.add(new Point(x-i,y+j));
					}
					if(x+i<=2*N && y-j>0 && BAN.indexOf(new Point(x+i,y-j)) == -1){
					 BAN.add(new Point(x+i,y-j));
					} 
				}*/
				turn++;
			

			
		}

	}

	static class Point{
		int x,y;
		Point(int x,int y){
			this.x = x;
			this.y = y;
		}
		public boolean equals(Object obj){
	    Point t = (Point)obj;
	    Integer tx = t.x;
	    Integer ty = t.y;

		if(x==tx && y==ty) return true;
		else return false;
		}
	}
}