%:pragma GCC optimize("Ofast")
  %:pragma GCC optimize("inline")
#include <bits/stdc++.h>
#define rint register int
#define fo(i, n) for(rint i = 1; i <= (n); i ++)
#define out(x) cerr << #x << " = " << x << "\n"
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); ++ it)
  using namespace std;
// by piano
template<typename tp> inline void read(tp &x) {
  x = 0;char c = getchar(); bool f = 0;
  for(; c < '0' || c > '9'; f |= (c == '-'), c = getchar());
  for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
  if(f) x = -x;
}
#define P pair<int, int>
#define fi first
#define se second
const int N = 633;
vector<P> vec;
int n, d1, d2;
int col1[N][N], col2[N][N], col[N][N];
inline void dfs(int x, int y, int fff) {
  if(col[x][y] != -1) return ;
  col[x][y] = fff;
  for(auto v: vec) {
    int dx = x + v.first;
    int dy = y + v.second;
    if(dx < 0 || dx >= 2 * n || dy < 0 || dy >= 2 * n)
       continue;
    dfs(dx, dy, fff ^ 1);
  }
}               

inline void cal(int d) {
  vec.clear();
  for(int dx = -2 * n + 1; dx < 2 * n; dx ++) {
    for(int dy = -2 * n + 1; dy < 2 * n; dy ++) {
      if(dx * dx + dy * dy == d)
        vec.push_back(P(dx, dy));
    }
  }
  memset(col, -1, sizeof col);
  for(int x = 0; x < 2 * n; x ++)
    for(int y = 0; y < 2 * n; y ++)
      dfs(x, y, 0);
}
main(void) {
  read(n); read(d1); read(d2);
  cal(d1); memcpy(col1, col, sizeof col);
  cal(d2); memcpy(col2, col, sizeof col);
  for(int k1 = 0; k1 < 2; k1 ++) {
    for(int k2 = 0; k2 < 2; k2 ++) {
      int cnt = 0;
      for(int x = 0; x < 2 * n; x ++) {
        for(int y = 0; y < 2 * n; y ++)
          if(col1[x][y] == k1 && col2[x][y] == k2)
            ++ cnt;
      }
      if(cnt >= n * n) {
        int res = n * n;
        for(int x = 0; x < 2 * n; x ++) 
          for(int y = 0; y < 2 * n; y ++)
            if(col1[x][y] == k1 && col2[x][y] == k2) {
              -- res;
              cout << x << " " << y << "\n";
              if(res == 0) return 0;
            }
      }
    }
  }
}

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <limits.h>
#include <math.h>
#include <functional>
#include <bitset>
#include <iomanip>

#define repeat(i,n) for (long long i = 0; (i) < (n); ++ (i))
#define debug(x) cerr << #x << ": " << x << '\n'
#define debugArray(x,n) for(long long i = 0; (i) < (n); ++ (i)) cerr << #x << "[" << i << "]: " << x[i] << '\n'
#define debugArrayP(x,n) for(long long i = 0; (i) < (n); ++ (i)) cerr << #x << "[" << i << "]: " << x[i].first<< " " << x[i].second << '\n'

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> Pii;
typedef vector<int> vint;
typedef vector<ll> vll;
const ll INF = INT_MAX;
const ll MOD = 1e9+7;

int fld[700][700];

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll N,D[2];cin>>N>>D[0]>>D[1];
  int d[2]={0,0};
  repeat(k,2){
    while(!(D[k]&1)){
      d[k]++;
      D[k]/=2;
    }
    D[k]<<=d[k];
  }
  //debugArray(d,2);
  vector<Pii> ans;
  repeat(i,2*N){
    repeat(j,2*N){
      bool isok=true;
      repeat(k,2){
        if(d[k]&1){
          isok &= !((i/(1<<((d[k]-1)/2)))&1);
        }else{
          isok &= !((i/(1<<(d[k]/2))+j/(1<<(d[k]/2)))&1);
        }
      }
      if(isok){
        fld[i][j]=1;
        ans.push_back({i,j});
      }
    }
  }
  /*
  if(ans.size()<N*N){
    cerr<<"!!!!!!!"<<endl;
    return 0;
  }
  */
/*
  repeat(i,2*N){
    repeat(j,2*N){
      cerr<<fld[i][j];
    }
    cerr<<endl;
  }
*/
  repeat(i,N*N){
    cout << ans[i].first<<" "<<ans[i].second<<endl;
  }
  return 0;
}
