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 C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		
		List<int> L1 = new List<int>();
		List<int> L2 = new List<int>();
		for(int i=0;i<N*2;i++){
			for(int j=0;j<N*2;j++){
				if(i*i+j*j == D1 || i*i + j*j == D2){
					L1.Add(i);L2.Add(j);
					L1.Add(-i);L2.Add(j);
					L1.Add(i);L2.Add(-j);
					L1.Add(-i);L2.Add(-j);
				}
			}
		}
		
		int r = 0;
		while(r*r*2 <= Math.Max(D1,D2)) r++;
		
		int[][] m = new int[2*N][];
		for(int i=0;i<2*N;i++){
			m[i] = new int[N*2];
		}
		
		int NN = N * 2;
		for(int i=0;i<NN;i+=2*r){
			for(int j=0;j<NN;j+=2*r){
				m[i][j] = 1;
				for(int ii=0;ii<L1.Count;ii++){
					int ny = L1[ii] + i;
					int nx = L2[ii] + j;
					if(InRange(ny,0,NN) && InRange(nx,0,NN)) m[ny][nx] = -1;
				}
			}
		}
		
		for(int i=0;i<NN;i++){
			for(int j=0;j<NN;j++){
				if(m[i][j] == 0){
					m[i][j] = 1;
					for(int ii=0;ii<L1.Count;ii++){
						int ny = L1[ii] + i;
						int nx = L2[ii] + j;
						if(InRange(ny,0,NN) && InRange(nx,0,NN)) m[ny][nx] = -1;
					}
				}
			}
		}	
		
		int cnt = 0;
		for(int i=0;i<NN;i++){
			for(int j=0;j<NN;j++){
				if(m[i][j] == 1){
					Console.WriteLine("{0} {1}", i, j);
					cnt++;
					if(cnt == N * N) return;
				}
			}
		}
		
		
		
		
	}
	
	bool InRange(int t, int l, int r){
		return l <= t && t < r;
	}
	
	int N;
	int D1,D2;
	public Sol(){
		var d = ria();
		N = d[0]; D1 = d[1]; D2 = d[2];
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}