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: Runtime Error)

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#define mp make_pair
#define pb push_back
using namespace std;

typedef long long li;
template<class T>inline void read(T &x) {
  x = 0;
  T tmp = 1;
  char c = getchar();
  while ((c < '0' || c > '9') && c != '-') c = getchar();
  if (c == '-') tmp = -1, c = getchar();
  while (c >= '0' && c <= '9')
    x = (x << 1) + (x << 3) + c - '0', c = getchar();
  x *= tmp;
}
template<class T>inline void Max(T &x, T y) {
  if (y > x) x = y;
}
template<class T>inline void Min(T &x, T y) {
  if (y < x) x = y;
}

const int N = 310, M = 2e5 + 10;
int n, d1, d2;
bool b[N << 1][N << 1];

const int dx[] = {1, 1, -1, -1};
const int dy[] = {-1, 1, -1, 1};

queue<pair<int, int> > q;
vector<pair<int, int> > g, ans;

inline bool out(int x, int y) {
  return x < 0 || y < 0 || x >= (n << 1) || y >= (n << 1);
}

int main(void) {
  read(n), read(d1), read(d2);
  for (int i = 0; i < (n << 1); ++i)
    for (int j = 0; j < (n << 1); ++j)
      q.push(mp(i, j));
  for (int i = 0; i < 450; ++i)
    for (int j = 0; j < 450; ++j) {
      int now = i * i + j * j;
      if (now == d1 || now == d2) {
	for (int t = 0; t < 4; ++t)
	  g.pb(mp(i * dx[t], j * dy[t]));
      }
    }
  while (!q.empty() && (int)ans.size() < n * n) {
    int x = q.front().first;
    int y = q.front().second;
    q.pop();
    for (; b[x][y] && !q.empty();
	 x = q.front().first, y = q.front().second, q.pop());
    if (b[x][y]) continue;
    ans.pb(mp(x, y));
    for (int i = 0; i < (int)g.size(); ++i) {
      int tmpx = g[i].first + x, tmpy = g[i].second + y;
      if (out(tmpx, tmpy) || b[tmpx][tmpy]) continue;
      b[tmpx][tmpy] = 1;
    }
  }
  if ((int)ans.size() < n * n) throw;
  for (int i = 0; i < (int)ans.size(); ++i)
    printf("%d %d\n", ans[i].first, ans[i].second);

  return 0;
}