#include <bits/stdc++.h>

using namespace std;

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

typedef pair<int, int> Point;
#define x first
#define y second

int n, d1, d2;
int col1[N][N], col2[N][N];

bool inbound(int x, int y) {
    return 0 <= x && x < 2 * n && 0 <= y && y < 2 * n;
}

int main() {
    ios::sync_with_stdio(false);
    cout.tie(0);

    cin >> n >> d1 >> d2;

    set<Point> mht1, mht2;

    // if (!(d1 & 1)) {
        for (int i = 0; i * i <= d1; i++) {
            int j = sqrt(d1 - i * i);
            if (i * i + j * j == d1) {
                for (int k = 0; k < 4; k++) {
                    mht1.insert({i * dx[k], j * dy[k]});
                }
            }
        }
    // }
    for (int i = 0; i * i <= d2; i++) {
        int j = sqrt(d2 - i * i);
        if (i * i + j * j == d2) {
            for (int k = 0; k < 4; k++) {
                mht2.insert({i * dx[k], j * dy[k]});
            }
        }
    }

    set<Point> st1, st2;

    for (int i = 0; i < 2 * n; i++) {
        for (int j = 0; j < 2 * n; j++) {
            st1.insert({i, j});
            st2.insert({i, j});
        }
    }

    set<Point>::iterator it;
    queue<Point> q;

    memset(col1, -1, sizeof(col1));
    for (it = st1.begin(); it != st1.end(); ++it) {
        q.push({it->first, it->second});
        col1[it->first][it->second] = 0;

        while (!q.empty()) {
            Point p = q.front(); q.pop();
            for (auto e: mht1) {
                int xx = p.x + e.x, yy = p.y + e.y;
                if (inbound(xx, yy)) {
                    assert(col1[xx][yy] != col1[p.x][p.y]);
                    if (col1[xx][yy] != -1) continue;
                    col1[xx][yy] = col1[p.x][p.y] ^ 1;
                    q.push({xx, yy});
                    st1.erase({xx, yy});
                }
            }
        }
    }

    memset(col2, -1, sizeof(col2));
    for (it = st2.begin(); it != st2.end(); ++it) {
        q.push({it->first, it->second});
        col2[it->first][it->second] = 0;

        while (!q.empty()) {
            Point p = q.front(); q.pop();
            for (auto e: mht2) {
                int xx = p.x + e.x, yy = p.y + e.y;
                if (inbound(xx, yy)) {
                    assert(col2[xx][yy] != col2[p.x][p.y]);
                    if (col2[xx][yy] != -1) continue;
                    col2[xx][yy] = col2[p.x][p.y] ^ 1;
                    q.push({xx, yy});
                    st2.erase({xx, yy});
                }
            }
        }
    }

    int cnt[2][2] = {0};
    for (int i = 0; i < 2 * n; i++) {
        for (int j = 0; j < 2 * n; j++) {
            cnt[col1[i][j]][col2[i][j]]++;
        }
    }

    int c1, c2;
    bool ok = false;
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            if (cnt[i][j] >= n * n) {
                c1 = i, c2 = j;
                ok = true;
                break;
            }
        }
        if (ok) break;
    }

    // for (int i = 0; i < 2 * n; i++) {
    //     for (int j = 0; j < 2 * n; j++) {
    //         cout << col1[i][j] << ' ';
    //     }
    //     cout << endl;
    // }

    // for (int i = 0; i < 2 * n; i++) {
    //     for (int j = 0; j < 2 * n; j++) {
    //         cout << col2[i][j] << ' ';
    //     }
    //     cout << endl;
    // }

    int ct = 0;
    for (int i = 0; i < 2 * n; i++) {
        for (int j = 0; j < 2 * n; j++) {
            if (col1[i][j] == c1 && col2[i][j] == c2) {
                cout << i << ' ' << j << endl;
                ct++;
                if (ct == n * n) return 0;
            }
        }
    }
}

Measured memory_bytes: 38528