#include <stdio.h>
#include <bits/stdc++.h>

#define FOR(i, n)     for(lli i = 0; i < (lli)(n); ++i)
#define FORU(i, j, k) for(lli i = (j); i <= (lli)(k); ++i)
#define FORD(i, j, k) for(lli i = (j); i >= (lli)(k); --i)

#define SQ(x) ((x)*(x))

#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back

using namespace std;

template<typename... As>
struct tpl : public std::tuple<As...> {
  using std::tuple<As...>::tuple;
  tpl(){}
  tpl(std::tuple<As...> const& b) { std::tuple<As...>::operator=(b); }

  template<typename T = tuple<As...> >
  typename tuple_element<0, T>::type const&
  x() const { return get<0>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<0, T>::type&
  x() { return get<0>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<1, T>::type const&
  y() const { return get<1>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<1, T>::type&
  y() { return get<1>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<2, T>::type const&
  z() const { return get<2>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<2, T>::type&
  z() { return get<2>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<3, T>::type const&
  w() const { return get<3>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<3, T>::type&
  w() { return get<3>(*this); }
};

using lli   = long long int;
using llu   = long long unsigned;

using pii   = tpl<lli, lli>;
using piii  = tpl<lli, lli, lli>;
using piiii = tpl<lli, lli, lli, lli>;
using vi    = vector<lli>;
using vii   = vector<pii>;
using viii  = vector<piii>;
using vvi   = vector<vi>;
using vvii  = vector<vii>;
using vviii = vector<viii>;

template<class T>
using min_queue = priority_queue<T, vector<T>, greater<T> >;
template<class T>
using max_queue = priority_queue<T>;

template<size_t... I>
struct my_index_sequence {
  using type = my_index_sequence;
  static constexpr array<size_t, sizeof...(I)> value = { {I...} };
};

namespace my_index_sequence_detail {
  template<typename I, typename J> struct concat;
  template<size_t... I, size_t... J>
  struct concat<my_index_sequence<I...>, my_index_sequence<J...> > :
    my_index_sequence<I..., (sizeof...(I)+J)...> { };
  template<size_t N> struct make_index_sequence :
    concat<typename make_index_sequence<N/2>::type, typename make_index_sequence<N-N/2>::type>::type { };
  template <> struct make_index_sequence<0> : my_index_sequence<>{};
  template <> struct make_index_sequence<1> : my_index_sequence<0>{};
}

template<class... A>
using my_index_sequence_for = typename my_index_sequence_detail::make_index_sequence<sizeof...(A)>::type;

template<class T, size_t... I>
void print_tuple(ostream& s, T const& a, my_index_sequence<I...>){
  using swallow = int[];
  (void)swallow{0, (void(s << (I == 0? "" : ", ") << get<I>(a)), 0)...};
}

template<class T>
ostream& print_collection(ostream& s, T const& a);
template<class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a);
template<class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a);
template<class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a);

template<class T, size_t I>
ostream& operator<<(ostream& s, array<T, I> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, vector<T> const& a) { return print_collection(s, a); }
template<class T, class U>
ostream& operator<<(ostream& s, multimap<T, U> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, multiset<T> const& a) { return print_collection(s, a); }
template<class T, class U>
ostream& operator<<(ostream& s, map<T, U> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, set<T> const& a) { return print_collection(s, a); }

template<class T>
ostream& print_collection(ostream& s, T const& a){
  s << '[';
  for(auto it = begin(a); it != end(a); ++it){
    s << *it;
    if(it != prev(end(a))) s << " ";
  }
  return s << ']';
}

template<class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a){
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}

template<class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a){
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}

template<class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a){
  return s << "(" << get<0>(a) << ", " << get<1>(a) << ")";
}

//------------------------------------------------------------------------------


int main(){
  ios::sync_with_stdio(0); cin.tie(0);
  lli n,d1,d2; cin>>n>>d1>>d2;

  srand(time(0));

  vii pts;
  FORU(i,0,2*n-1) FORU(j,0,2*n-1) {
    pts.eb(i,j);
  }

  function<void(vvi&,vii const&,lli,lli,lli)> dfs = [&](vvi& C, vii const& A, lli i, lli j, lli c) {
    if(C[i][j] != -1) {
      if(C[i][j] != c) assert(0);
      return;
    }
    C[i][j]=c;
    for(auto p : A) {
      lli x,y; tie(x,y) = p;
      x+=i; y+=j;
      if(x<0||x>=2*n) continue;
      if(y<0||y>=2*n) continue;
      dfs(C,A,x,y,c^1);
    }
  };
  vvi C1(2*n,vi(2*n,-1));
  vvi C2(2*n,vi(2*n,-1));

  vii A1, A2;
  FORU(i,-600,600) FORU(j,-600,600) if(i*i+j*j == d1) A1.eb(i,j);
  FORU(i,-600,600) FORU(j,-600,600) if(i*i+j*j == d2) A2.eb(i,j);


  FOR(i,2*n) FOR(j,2*n) if(C1[i][j] == -1) dfs(C1,A1,i,j,0);
  FOR(i,2*n) FOR(j,2*n) if(C2[i][j] == -1) dfs(C2,A2,i,j,0);

  map<tpl<int,int>, vii> M;
  FOR(i,2*n) FOR(j,2*n) M[mt(C1[i][j],C2[i][j])].eb(i,j);

  for(auto p : M) if((lli)p.second.size() >= n*n) {
      p.second.resize(n*n);
      for(auto q : p.second) {
        lli x,y; tie(x,y) = q;
        cout << x << " " << y << endl;
      }
      return 0;
    }

  // auto test = [&](vii A) -> vii {
  //   while(1) {
  //     FOR(i,2*n) FOR(j,2*n) E[i][j]=0;

  //     random_shuffle(all(pts));
  //     int rr=niter%4;
  //     niter+=1;
  //     if(rr==0) {
  //       stable_sort(all(pts),[&](auto p1, auto p2) {
  //           return SQ(p1.x())+SQ(p1.y())<SQ(p2.x())+SQ(p2.y());
  //         });
  //     }else if(rr==1) {
  //       stable_sort(all(pts),[&](auto p1, auto p2) {
  //           return SQ(p1.x())<SQ(p2.x());
  //         });
  //     } else if(rr==2){
  //       stable_sort(all(pts),[&](auto p1, auto p2) {
  //           return SQ(p1.y())<SQ(p2.y());
  //         });
  //     }else if(rr==3) {
  //       stable_sort(all(pts),[&](auto p1, auto p2) {
  //           return p1.x()+p1.y()<p2.x()+p2.y();
  //         });
  //     }
  //     vii ans;
  //     for(auto q : pts) {
  //       lli i,j; tie(i,j) = q;
  //       if(E[i][j]) continue;
  //       ans.eb(i,j);
  //       for(auto p : A1) {
  //         lli x,y; tie(x,y) = p;
  //         x+=i; y+=j;
  //         if(x<0||x>=2*n) continue;
  //         if(y<0||y>=2*n) continue;
  //         E[x][y] = 1;
  //       }
  //     }
  //     if((lli)ans.size() >= 2*n*n) {
  //       ans.resize(2*n*n);
  //       return ans;
  //     }
  //   }
  // };

  // auto ans1 = test(A1);
  // auto ans2 = test(A2);
  // set<pii> a1(all(ans1));
  // set<pii> a2(all(ans1));
  // for(auto p : a1) if(a2.count(p)) {
  //     lli x,y; tie(x,y) = p;
  //     cout << x << " " << y << endl;
  //   }
  return 0;
}


Measured memory_bytes: 63976