#include #define endl '\n' #define pb push_back #define mp make_pair #include using namespace std; const int maxx = 40; /// -1 up /// 1 down /// 1 right /// -1 left struct deal { int x, y, cut, plusone, freeout; deal(){}; deal(int _x, int _y, int _cut, int _plusone, int _freeout) { x = _x; y = _y; cut = _cut; plusone = _plusone; freeout = _freeout; } }; int typelr[maxx][maxx], typeud[maxx][maxx]; void precompute() { /// fig 1 typelr[1][0] = 1; typeud[1][0] = 1; typelr[1][1] = -1; typeud[1][1] = 1; typelr[1][2] = -1; typeud[1][2] = -1; typelr[1][3] = 1; typeud[1][3] = -1; /// fig 2; typelr[2][0] = 1; typeud[2][0] = 1; typelr[2][1] = -1; typeud[2][1] = 1; typelr[2][2] = -1; typeud[2][2] = -1; typelr[2][3] = 1; typeud[2][3] = -1; /// fig 4 typelr[4][0] = 1; typeud[4][1] = 1; typelr[4][2] = -1; typeud[4][3] = -1; } vector < pair < int, int > > g[maxx][maxx]; void fill_g() { g[0][0].pb(mp(-1, -1)); g[0][0].pb(mp(-1, 0)); g[0][0].pb(mp(0, -1)); g[0][0].pb(mp(0, 0)); g[0][1].pb(mp(-1, 0)); g[0][1].pb(mp(-1, 1)); g[0][1].pb(mp(0, 0)); g[0][1].pb(mp(0, 1)); g[0][2].pb(mp(0, 0)); g[0][2].pb(mp(0, 1)); g[0][2].pb(mp(1, 0)); g[0][2].pb(mp(1, 1)); g[0][3].pb(mp(0, -1)); g[0][3].pb(mp(0, 0)); g[0][3].pb(mp(1, -1)); g[0][3].pb(mp(1, 0)); // 1 g[1][0].pb(mp(-1, 0)); g[1][0].pb(mp(0, 0)); g[1][0].pb(mp(0, -1)); g[1][1].pb(mp(-1, 0)); g[1][1].pb(mp(0, 0)); g[1][1].pb(mp(0, 1)); g[1][2].pb(mp(1, 0)); g[1][2].pb(mp(0, 0)); g[1][2].pb(mp(0, 1)); g[1][3].pb(mp(1, 0)); g[1][3].pb(mp(0, 0)); g[1][3].pb(mp(0, -1)); // 2 g[2][0].pb(mp(-1, 0)); g[2][0].pb(mp(0, 0)); g[2][0].pb(mp(0, -1)); g[2][0].pb(mp(0, -2)); g[2][1].pb(mp(-2, 0)); g[2][1].pb(mp(-1, 0)); g[2][1].pb(mp(0, 0)); g[2][1].pb(mp(0, 1)); g[2][2].pb(mp(1, 0)); g[2][2].pb(mp(0, 0)); g[2][2].pb(mp(0, 1)); g[2][2].pb(mp(0, 2)); g[2][3].pb(mp(2, 0)); g[2][3].pb(mp(1, 0)); g[2][3].pb(mp(0, 0)); g[2][3].pb(mp(0, -1)); // 3 g[3][0].pb(mp(0, -3)); g[3][0].pb(mp(0, -2)); g[3][0].pb(mp(0, -1)); g[3][0].pb(mp(0, 0)); g[3][1].pb(mp(-3, 0)); g[3][1].pb(mp(-2, 0)); g[3][1].pb(mp(-1, 0)); g[3][1].pb(mp(0, 0)); g[3][2].pb(mp(0, 0)); g[3][2].pb(mp(0, 1)); g[3][2].pb(mp(0, 2)); g[3][2].pb(mp(0, 3)); g[3][3].pb(mp(0, 0)); g[3][3].pb(mp(1, 0)); g[3][3].pb(mp(2, 0)); g[3][3].pb(mp(3, 0)); // 4 g[4][0].pb(mp(-2, 0)); g[4][0].pb(mp(-1, 0)); g[4][0].pb(mp(0, 0)); g[4][0].pb(mp(-1, -1)); g[4][1].pb(mp(0, 0)); g[4][1].pb(mp(0, 1)); g[4][1].pb(mp(0, 2)); g[4][1].pb(mp(-1, 1)); g[4][2].pb(mp(2, 0)); g[4][2].pb(mp(1, 0)); g[4][2].pb(mp(0, 0)); g[4][2].pb(mp(1, 1)); g[4][3].pb(mp(0, 0)); g[4][3].pb(mp(0, -1)); g[4][3].pb(mp(0, -2)); g[4][3].pb(mp(1, -1)); } int taken[maxx][maxx]; long long n, type, side; long long a, b, c, d, e, f; bool isfree(int i, int j) { if(i < 1 || i > n)return false; if(j < 1 || j > n)return false; return (!taken[i][j]); } int orilr, oriud; long long cntcmp, cnthere; bool cmp(deal p1, deal p2) { cntcmp ++; if(p1.plusone != p2.plusone) { return (p1.plusone > p2.plusone); } if(p1.freeout != p2.freeout)return (p1.freeout > p2.freeout); if(p1.cut != p2.cut) { return (p1.cut > p2.cut); } if(oriud && p1.x != p2.x) { if(oriud == 1)return (p1.x > p2.x); else return (p1.x < p2.x); } if(orilr && p1.y != p2.y) { if(orilr == 1)return (p1.y > p2.y); else return (p1.y < p2.y); } //if(p1.x != p2.x)return (p1.x < p2.x); //return (p1.y < p2.y); if(p1.y != p2.y)return (p1.y < p2.y); return (p1.x < p2.x); } int impossible = 0; vector < pair < int, int > > ans; int cntrow[maxx], cntcol[maxx]; void calc() { memset(cntrow, 0, sizeof(cntrow)); memset(cntcol, 0, sizeof(cntcol)); for (int i = 1; i <= n; ++ i) { for (int j = 1; j <= n; ++ j) cntrow[i] += taken[i][j]; } for (int j = 1; j <= n; ++ j) { for (int i = 1; i <= n; ++ i) cntcol[j] += taken[i][j]; } } bool check(int i, int j) { if(i < 1 || i > n)return 1; if(j < 1 || j > n)return 1; return taken[i][j]; } int count_sides(int ii, int jj) { int sum = 0; for (auto &[x, y]: g[type][side]) { int xx = x + ii; int yy = y + jj; sum += check(xx-1, yy); sum += check(xx+1, yy); sum += check(xx, yy+1); sum += check(xx, yy-1); } return sum; } int delrow[maxx], delcol[maxx]; long long nxttype, nxtside; void find_nxt() { long long aa, bb, cc, dd, ee, ff; aa = a; bb = b; cc = c; dd = d; ee = e; ff = f; cc = (cc ^ aa) + bb; ff = (ff ^ dd) + ee; nxttype = cc % 5; nxtside = ff % 4; } bool isfreenow(int i, int j) { if(i < 1 || i > n)return false; if(j < 1 || j > n)return false; if(delrow[i])return true; if(delcol[j])return true; return (!taken[i][j]); } int find_place4nxt() { for (int i = 1; i <= n; ++ i) { for (int j = 1; j <= n; ++ j) { int nono = 0; for (auto &[x, y]: g[nxttype][nxtside]) { if(!isfreenow(x+i, y+j))nono = 1; } if(nono)continue; return 1; } } return 0; } int curr_freed; int visual(int ii, int jj) { curr_freed = 0; memset(delrow, 0, sizeof(delrow)); memset(delcol, 0, sizeof(delcol)); for (auto &[x, y]: g[type][side]) taken[x+ii][y+jj] = 1; calc(); for (int i = 1; i <= n; ++ i) { if(cntrow[i] == n) { delrow[i] = 1; curr_freed ++; } } for (int i = 1; i <= n; ++ i) { if(cntcol[i] == n) { delcol[i] = 1; curr_freed ++; } } int has_space = find_place4nxt(); for (auto &[x, y]: g[type][side]) taken[x+ii][y+jj] = 0; return has_space; } void find_place() { orilr = typelr[type][side]; oriud = typeud[type][side]; vector < deal > u; for (int i = 1; i <= n; ++ i) { for (int j = 1; j <= n; ++ j) { int nono = 0; for (auto &[x, y]: g[type][side]) { if(!isfree(x+i, y+j))nono = 1; } if(nono)continue; int bbb = visual(i, j); u.pb(deal(i, j, count_sides(i, j), bbb, curr_freed)); } } if(u.size() == 0) { impossible = 1; return; } sort(u.begin(), u.end(), cmp); int templatex, templatey; templatex = u[0].x; templatey = u[0].y; ans.pb(mp(templatex, templatey)); for (auto &[x, y]: g[type][side]) { assert(templatex + x <= n); assert(templatey + y <= n); taken[templatex + x][templatey + y] = 1; } } void del() { for (int i = 1; i <= n; ++ i) { if(cntrow[i] != n)continue; for (int j = 1; j <= n; ++ j) taken[i][j] = 0; } for (int j = 1; j <= n; ++ j) { if(cntcol[j] != n)continue; for (int i = 1; i <= n; ++ i) taken[i][j] = 0; } } void print() { for (int i = 1; i <= n; ++ i) { for (int j = 1; j <= n; ++ j) cout << taken[i][j] << " "; cout << endl; } cout << endl; } int main() { freopen("block.in", "r", stdin); freopen("block.out", "w", stdout); precompute(); fill_g(); cin >> n; cin >> a >> b >> c >> d >> e >> f; while(true) { c = (c ^ a) + b; f = (f ^ d) + e; type = c % 5; side = f % 4; find_nxt(); find_place(); calc(); del(); if((clock()/CLOCKS_PER_SEC > 4.8))break; if(impossible)break; } cout << ans.size() << endl; for (auto &[x, y]: ans) cout << x << " " << y << endl; return 0; }