#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <algorithm>
#include <utility>
#include <functional>
#include <cstring>
#include <queue>
#include <stack>
#include <math.h>
#include <iterator>
#include <vector>
#include <string>
#include <set>
#include <math.h>
#include <iostream>
#include <random>
#include<map>
#include <iomanip>
#include <time.h>
#include <stdlib.h>
#include <list>
#include <typeinfo>
#include <list>
#include <set>
#include <cassert>
#include<fstream>
#include <unordered_map>
#include <complex>
#include <cctype>
#include <bitset>
using namespace std;
typedef string::const_iterator State;
#define Ma_PI 3.141592653589793
const long double eps = 1e-12;
#define LONG_INF 1e18
#define GOLD 1.61803398874989484820458
#define MAX_MOD 1000000007LL
#define GYAKU 500000004LL
#define MOD 998244353LL
#define seg_size 262144*2
#define REP(a,b) for(long long a = 0;a < b;++a)
long long bad[700][700] = {};
vector<pair<int,int>> vertexs[2][700][700];
int visited[2][700][700];
int coloring[2][700][700];
int main() {
	long long n, d[2];
	cin >> n;
	REP(q, 2) {
		cin >> d[q];
	}
	REP(itr, 2) {
		for (long long a = 0; a * a <= d[itr]; ++a) {
			long long b = sqrt(d[itr] - a * a);
			if (b * b + a * a != d[itr]) continue;
			for (int q = 0; q < 2 * n; ++q) {
				for (int j = 0; j < 2 * n; ++j) {
					if (bad[q][j] == 1) continue;
					int xe[4] = { 1,1,-1,-1 };
					int ye[4] = { 1,-1,1,-1 };
					REP(t, 4) {
						int now_x = q + xe[t] * a;
						int now_y = j + ye[t] * b;
						if (now_x >= 0 && now_x < 2 * n && now_y >= 0 && now_y < 2 * n) {
							if (bad[now_x][now_y] == 1) continue;
							vertexs[itr][q][j].push_back(make_pair(now_x, now_y));
							vertexs[itr][now_x][now_y].push_back(make_pair(q, j));
						}
					}
				}
			}
		}
		for (int q = 0; q < 2 * n; ++q) {
			for (int j = 0; j < 2 * n; ++j) {
				if (visited[itr][q][j] == 0 && bad[q][j] == 0) {
					queue<pair<int, int>> next;
					next.push(make_pair(q, j));
					visited[itr][q][j] = 1;
					vector<pair<int, int>> used;
					int cnt[2] = {};
					while (next.empty() == false) {
						pair<int, int> now = next.front();
						next.pop();
						used.push_back(now);
						REP(i, vertexs[itr][now.first][now.second].size()) {
							pair<int, int> going = vertexs[itr][now.first][now.second][i];
							if (visited[itr][going.first][going.second] == 0) {
								visited[itr][going.first][going.second] = 1;
								coloring[itr][going.first][going.second] = (coloring[itr][now.first][now.second] + 1) % 2;
								cnt[coloring[itr][going.first][going.second]]++;
								next.push(going);
							}
						}
					}
					int yusen = 1;
					if (cnt[0] < cnt[1]) {
						yusen = 0;
					}
					REP(q, used.size()) {
						if (coloring[itr][used[q].first][used[q].second] == yusen) {
							bad[used[q].first][used[q].second] = 1;
						}
					}
				}
			}
		}
	}
	int cnt = 0;
	REP(q, 2 * n) {
		REP(j, 2 * n) {
			if (bad[q][j] == 0) {
				cnt++;
				if (cnt <= n * n) {
					cout << q << " " << j << endl;
				}
			}
		}
	}
}
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#include<assert.h>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
#define SZ(x) ((int)x.size())
using namespace std;
inline LL read()
{
	LL f=1,x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int stack[20];
template<typename T>inline void write(T x)
{
	if(x<0){putchar('-');x=-x;}
    if(!x){putchar('0');return;}
    int top=0;
    while(x)stack[++top]=x%10,x/=10;
    while(top)putchar(stack[top--]+'0');
}
template<typename T>inline void pr1(T x){write(x);putchar(' ');}
template<typename T>inline void pr2(T x){write(x);putchar('\n');}
template<typename T>inline void chkmin(T &x,T y){x=x<y?x:y;}
template<typename T>inline void chkmax(T &x,T y){x=x>y?x:y;}
const int MAXN=305;
int col[2][2*MAXN][2*MAXN],n,D1,D2;
vector<pii> fac[2];
bool in(int x,int y){return x>=0&&x<2*n&&y>=0&&y<2*n;}
void DFS(int x,int y,int o)
{
	for(auto p:fac[o])for(int u=-1;u<=1;u++)if(u)for(int v=-1;v<=1;v++)if(v)
		if(in(x+u*p.first,y+v*p.second))
		{
			int ux=x+u*p.first,uy=y+v*p.second;
			if(col[o][ux][uy]!=-1)continue;
			col[o][ux][uy]=col[o][x][y]^1;DFS(ux,uy,o);
		}
}
void color(int o)
{
	memset(col[o],-1,sizeof(col[o]));
	for(int i=0;i<2*n;i++)for(int j=0;j<2*n;j++)if(col[o][i][j]==-1)
		col[o][i][j]=0,DFS(i,j,o);
}
int sqr(int x){return x*x;}
int dis(pii u,pii v){return sqr(u.first-v.first)+sqr(u.second-v.second);}
vector<pii> ans[2][2];
int main()
{
	n=read();D1=read();D2=read();
	for(int i=0;i*i<=D1;i++)if(floor(sqrt(D1-i*i))==ceil(sqrt(D1-i*i)))fac[0].emplace_back(mp(i,sqrt(D1-i*i)));
	for(int i=0;i*i<=D2;i++)if(floor(sqrt(D2-i*i))==ceil(sqrt(D2-i*i)))fac[1].emplace_back(mp(i,sqrt(D2-i*i)));
	color(0);color(1);
	for(int i=0;i<2*n;i++)for(int j=0;j<2*n;j++)
		ans[col[0][i][j]][col[1][i][j]].emplace_back(mp(i,j));
	for(int i=0;i<=1;i++)for(int j=0;j<=1;j++)if(SZ(ans[i][j])>=n*n)
	{
//		for(auto p:ans[i][j])for(auto q:ans[i][j])
//			assert(dis(p,q)!=D1&&dis(p,q)!=D2);
		int cnt=0;
		for(auto p:ans[i][j])
		{
			pr1(p.first),pr2(p.second);
			++cnt;if(cnt==n*n)break;
		}
		return 0;
	}
	return 0;
}
