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<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
/// {{{ DEBUG --- ///
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { if(&o == &cerr) { o << '{'; for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? ", " : ""); o << "}"; } else { for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? " " : ""); } return o; }
#ifdef DEBUG
#ifdef USE_COUT
#define dump(...) (cout<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<make_tuple(__VA_ARGS__)<<"\n")
#else
#define dump(...) (cerr<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<make_tuple(__VA_ARGS__)<<"\n")
#endif
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
#else
#define dump(...) (0)
#endif
/// }}}--- ///

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

int f[2][700][700];
vector<int> ddx[2], ddy[2];
int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int n, d[2];
  cin >> n >> d[0] >> d[1];
  for(int j = 0; j < 2; j++) {
    for(int i = 0; i <= 601; i++) {
      int k = d[j] - i * i;
      if(k < 0) continue;
      int kk = sqrt(k);
      if(kk * kk != k) continue;
      ddx[j].emplace_back(i);
      ddy[j].emplace_back(kk);
    }
  }
  for(int k = 0; k < 2; k++) {
    for(int i = 0; i < 2*n; i++) for(int j = 0; j < 2*n; j++) if(f[k][i][j] == 0) {
      f[k][i][j] = 1;
      queue<pair<int, int>> q;
      q.emplace(i, j);
      while(q.size()) {
        int ii = q.front().first, jj = q.front().second;
        q.pop();
        for(int t = 0; t < ddx[k].size(); t++) {
          for(int d = 0; d < 8; d++) {
            int ni = ii + dx[d] * ddx[k][t];
            int nj = jj + dy[d] * ddy[k][t];
            if(ni < 0 || nj < 0 || ni >= 2*n || nj >= 2*n) continue;
            if(f[k][ni][nj] != 0) continue;
            f[k][ni][nj] = 3 - f[k][ii][jj];
            q.emplace(ni, nj);
          }
        }
      }
    }
  }
  vector<pair<int, int>> ans;
  for(int k = 1; k <= 2; k++) for(int l = 1; l <= 2; l++) {
    ans.clear();
    for(int i = 0; i < 2*n; i++) for(int j = 0; j < 2*n; j++) {
      if(f[0][i][j] == k && f[1][i][j] == l) ans.emplace_back(i, j);
    }
    if(ans.size() >= n * n) goto out;
  }
  out:
  assert(0);
  assert(ans.size() >= n * n);
  for(int i = 0; i < n * n; i++) cout << ans[i].first << " " << ans[i].second << endl;
}