#pragma GCC optimize("Ofast","unroll-loops") #pragma GCC target("bmi,bmi2,lzcnt,popcnt") #include #define all(a) a.begin(),a.end() #define len(a) (int)(a.size()) #define fir first #define sec second #define fi first #define se second #define mp make_pair #define pb push_back using namespace std; typedef pair pii; typedef long long ll; typedef long double ld; template bool umin(T &a, T b) { if (b < a) { a = b; return 1; } return 0; } template bool umax(T &a, T b) { if (a < b) { a = b; return 1; } return 0; } #ifdef KIVI #define DEBUG for (int _____DEBUG=1;_____DEBUG;_____DEBUG=0) #define LOG(...) prnt(#__VA_ARGS__" ::",__VA_ARGS__)< auto &prnt(Ts ...ts) { return ((cerr << ts << " "), ...); } #else #define DEBUG while (false) #define LOG(...) #endif const int max_n = 20, inf = 1000111222; const int max_v = max_n * max_n; int n, num[max_n][max_n]; vector> cells; ld rad; int r; bitset g[max_v], used; vector comp; void dfs(int v, const bitset &active, bitset &used, vector &comp) { used[v] = 1; comp.push_back(v); while (true) { int to = (g[v] & active & (~used))._Find_first(); if (to < cells.size()) { dfs(to, active, used, comp); } else { break; } } } int MX = 0; double start = clock(); bool is_tl() { static unsigned char its = 0; ++its; if (its == 0) { return (clock() - start) / CLOCKS_PER_SEC > 3.7; } return false; } void write_ans(bitset ans) { cout << ans.count() << "\n"; for (int v = 0; v < cells.size(); ++v) { if (ans[v] == 0) { continue; } cout << cells[v].first << " " << cells[v].second << "\n"; } exit(0); } bitset best_ans; void rec(bitset active, bitset cur, bitset &ans) { if (MX < ans.count()) { MX = ans.count(); best_ans = ans; LOG(MX); } if (is_tl()) { write_ans(best_ans); } if (cur.count() + active.count() <= ans.count()) { return; } if (!active.any()) { // LOG(cur.size()); ans = cur; return; } used.reset(); vector> comps; for (int v = active._Find_first(); v < cells.size(); v = active._Find_next(v)) { if (used[v]) { continue; } comp.clear(); dfs(v, active, used, comp); comps.push_back(comp); } if (comps.size() > 1) { for (auto comp : comps) { bitset nans, ncur, nactive; for (int v : comp) { nactive[v] = 1; } rec(nactive, ncur, nans); cur |= nans; } if (cur.count() > ans.count()) { ans = cur; } return; } pair mn(inf, inf); pair mx(-inf, -inf); for (int v = active._Find_first(); v < cells.size(); v = active._Find_next(v)) { int sz = (g[v] & active).count(); mn = min(mn, {sz, v}); mx = max(mx, {sz, v}); } if (mn.first <= 1) { cur[mn.second] = 1; active[mn.second] = 0; rec(active & (~g[mn.second]), cur, ans); cur[mn.second] = 0; return; } // if (mx.second == 2) { //// exit(47); // return; // } mx = mn; active[mx.second] = 0; { cur[mx.second] = 1; rec(active & (~g[mx.second]), cur, ans); cur[mx.second] = 0; } { rec(active, cur, ans); } } const bool debug = 0; int main() { // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); ios_base::sync_with_stdio(0); cin.tie(0); if (debug) { n = 20; rad = 2.501; } else { cin >> n >> rad; } r = (rad * 1000 + 0.5); ::memset(num, -1, sizeof(num)); bitset active; for (int i = 1; i < n; ++i) { for (int j = 1; j < n; ++j) { int d = min({i, n - i, j, n - j}); if (d * 1000 >= r) { // LOG(cells.size(), i, j); active[cells.size()] = 1; num[i][j] = cells.size(); cells.push_back({i, j}); } } } for (int i = 1; i < n; ++i) { for (int j = 1; j < n; ++j) { if (num[i][j] == -1) { continue; } for (int i2 = 1; i2 < n; ++i2) { for (int j2 = 1; j2 < n; ++j2) { if (num[i2][j2] == -1) { continue; } if (i2 == i && j2 == j) { continue; } // if (num[i][j] != 2 || num[i2][j2] != 6) { // continue; // } int dx = (i - i2), dy = (j - j2); long long tot = 1000000 * (dx * dx + dy * dy); if (tot < 4 * r * r) { // LOG(num[i][j], num[i2][j2]); g[num[i][j]][num[i2][j2]] = 1; } } } } } bitset cur, ans; rec(active, cur, ans); if (!debug) { write_ans(ans); } else { cerr << 1.0 * clock() / CLOCKS_PER_SEC << endl; } exit(0); }