#include using namespace std; using Clock = chrono::steady_clock; constexpr int MAX_W = 300000; constexpr double TIME_LIMIT = 1.9; int edge_id(int n, int a, int b) { if (a > b) swap(a, b); if (b - a == n) return (a / n) * n + a % n; return n * (n - 1) + (a / n) * (n - 1) + a % n; } vector snake(int n) { vector p; for (int r = 0; r < n; ++r) { if (r % 2 == 0) for (int c = 0; c < n; ++c) p.push_back(r * n + c); else for (int c = n - 1; c >= 0; --c) p.push_back(r * n + c); } return p; } bool valid_marks(const vector& a, vector& seen, int stamp) { int m = a.size(); for (int j = 1; j < m; ++j) for (int i = 0; i < j; ++i) { int d = a[j] - a[i]; if (seen[d] == stamp) return false; seen[d] = stamp; } return true; } void output(int n, const vector& marks) { int m = marks.size(), unused = marks.back() + 1; vector ans(2 * n * (n - 1), unused); auto p = snake(n); for (int i = 0; i + 1 < m; ++i) ans[edge_id(n, p[i], p[i + 1])] = marks[i + 1] - marks[i]; int k = 0; for (int r = 0; r + 1 < n; ++r) { for (int c = 0; c < n; ++c) cout << (c ? " " : "") << ans[k++]; cout << '\n'; } for (int r = 0; r < n; ++r) { for (int c = 0; c + 1 < n; ++c) cout << (c ? " " : "") << ans[k++]; cout << '\n'; } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; int m = n * n; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); vector marks(m), seen(MAX_W); auto deadline = Clock::now() + chrono::duration_cast(chrono::duration(TIME_LIMIT)); int stamp = 0; while (Clock::now() < deadline) { marks[0] = 0; for (int i = 1; i < m; ++i) marks[i] = 1 + rng() % (MAX_W - 1); sort(marks.begin(), marks.end()); if (adjacent_find(marks.begin(), marks.end()) != marks.end()) continue; if (valid_marks(marks, seen, ++stamp)) { output(n, marks); return 0; } if (stamp == INT_MAX) { fill(seen.begin(), seen.end(), 0); stamp = 0; } } cout << -1 << '\n'; }