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++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;

#ifdef BTK
#define DEBUG if(1)
#else
#define CIN_ONLY if(1)
struct cww {cww() {CIN_ONLY{ios::sync_with_stdio(false); cin.tie(0);}}
}star;
#define DEBUG if(0)
#endif

#define ALL(v) (v).begin(),(v).end()
#define REC(ret, ...) std::function<ret (__VA_ARGS__)>
template <typename T>inline bool chmin(T &l, T r){bool a = l>r; if (a)l = r; return a;}
template <typename T>inline bool chmax(T &l, T r){bool a = l<r; if (a)l = r; return a;}
template <typename T>istream& operator>>(istream &is, vector<T> &v){for (auto &it : v)is >> it;return is;}

class range {private: struct I { int x; int operator*() { return x; }bool operator!=(I& lhs) { return x<lhs.x; }void operator++() { ++x; } }; I i, n;public:range(int n) :i({ 0 }), n({ n }) {}range(int i, int n) :i({ i }), n({ n }) {}I& begin() { return i; }I& end() { return n; }};
typedef vector<int> V;
typedef vector<V> VV;
int col[612][612][2];
int N;
void coloring(int r, int c, int k, VV& edge) {
	for (auto &e : edge) {
		int nr = r + e[0];
		int nc = c + e[1];
		if (nr < 0 || N <= nr)continue;
		if (nc < 0 || N <= nc)continue;
		if (col[nr][nc][k] != -1)continue;
		col[nr][nc][k] = 1 - col[r][c][k];
		coloring(nr, nc, k, edge);
	}
}
int main() {
	LL latte, malta;
	cin >> N >> latte >> malta;
	N *= 2;
	vector<VV> e(2);
	for (int i : range(-N,N+1))for (int j : range(-N,N+1)) {
		if (i*i + j*j == latte)e[0].push_back({ i,j });
		if (i*i + j*j == malta)e[1].push_back({ i,j });
	}
	for (int i : range(N))for (int j : range(N))for (int k : range(2))col[i][j][k] = -1;
	for (int i : range(N))for (int j : range(N))for (int k : range(2))if (col[i][j][k] == -1) {
		col[i][j][k] = 0;
		coloring(i, j, k, e[k]);
	}
	int cnt[2][2] = { {0,0},{0,0} };
	for (int i : range(N))for (int j : range(N)) {
		cnt[col[i][j][0]][col[i][j][1]]++;
	}
	int ai = 0, aj = 0;
	for (int i : range(2))for (int j : range(2)) {
		if (cnt[ai][aj] < cnt[i][j])ai = i, aj = j;
	}
	int M = N * N / 4;
	for (int i : range(N))for (int j : range(N)) {
		if (col[i][j][0] == ai && col[i][j][1] == aj && M > 0) {
			cout << i << " " << j << endl;
			M--;
		}
	}

	return 0;
}