結果
問題 | No.2263 Perms |
ユーザー |
|
提出日時 | 2023-04-07 22:26:43 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 38 ms / 2,000 ms |
コード長 | 38,305 bytes |
コンパイル時間 | 3,011 ms |
コンパイル使用メモリ | 237,688 KB |
最終ジャッジ日時 | 2025-02-12 01:48:06 |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 39 |
ソースコード
#include <bits/stdc++.h>using i32 = int;using u32 = unsigned int;using i64 = long long;using u64 = unsigned long long;using i128 = __int128_t;using u128 = __uint128_t;using f64 = double;using f80 = long double;using f128 = __float128;constexpr i32 operator"" _i32(u64 v) { return v; }constexpr u32 operator"" _u32(u64 v) { return v; }constexpr i64 operator"" _i64(u64 v) { return v; }constexpr u64 operator"" _u64(u64 v) { return v; }constexpr f64 operator"" _f64(f80 v) { return v; }constexpr f80 operator"" _f80(f80 v) { return v; }using Istream = std::istream;using Ostream = std::ostream;using Str = std::string;template<typename T>using Lt = std::less<T>;template<typename T>using Gt = std::greater<T>;template<int n>using BSet = std::bitset<n>;template<typename T1, typename T2>using Pair = std::pair<T1, T2>;template<typename... Ts>using Tup = std::tuple<Ts...>;template<typename T, int N>using Arr = std::array<T, N>;template<typename... Ts>using Deq = std::deque<Ts...>;template<typename... Ts>using Set = std::set<Ts...>;template<typename... Ts>using MSet = std::multiset<Ts...>;template<typename... Ts>using USet = std::unordered_set<Ts...>;template<typename... Ts>using UMSet = std::unordered_multiset<Ts...>;template<typename... Ts>using Map = std::map<Ts...>;template<typename... Ts>using MMap = std::multimap<Ts...>;template<typename... Ts>using UMap = std::unordered_map<Ts...>;template<typename... Ts>using UMMap = std::unordered_multimap<Ts...>;template<typename... Ts>using Vec = std::vector<Ts...>;template<typename... Ts>using Stack = std::stack<Ts...>;template<typename... Ts>using Queue = std::queue<Ts...>;template<typename T>using MaxHeap = std::priority_queue<T>;template<typename T>using MinHeap = std::priority_queue<T, Vec<T>, Gt<T>>;constexpr bool LOCAL = false;constexpr bool OJ = not LOCAL;template<typename T>static constexpr T OjLocal(T oj, T local){return LOCAL ? local : oj;}template<typename T>constexpr T LIMMIN = std::numeric_limits<T>::min();template<typename T>constexpr T LIMMAX = std::numeric_limits<T>::max();template<typename T>constexpr T INF = (LIMMAX<T> - 1) / 2;template<typename T>constexpr T PI = T{3.141592653589793238462643383279502884};template<typename T = u64>constexpr T TEN(int n){return n == 0 ? T{1} : TEN<T>(n - 1) * T{10};}template<typename T>constexpr bool chmin(T& a, const T& b){return (a > b ? (a = b, true) : false);}template<typename T>constexpr bool chmax(T& a, const T& b){return (a < b ? (a = b, true) : false);}template<typename T>constexpr T floorDiv(T x, T y){assert(y != 0);if (y < 0) { x = -x, y = -y; }return x >= 0 ? x / y : (x - y + 1) / y;}template<typename T>constexpr T ceilDiv(T x, T y){assert(y != 0);if (y < 0) { x = -x, y = -y; }return x >= 0 ? (x + y - 1) / y : x / y;}template<typename T, typename I>constexpr T powerMonoid(T v, I n, const T& e){assert(n >= 0);if (n == 0) { return e; }return (n % 2 == 1 ? v * powerMonoid(v, n - 1, e) : powerMonoid(v * v, n / 2, e));}template<typename T, typename I>constexpr T powerInt(T v, I n){return powerMonoid(v, n, T{1});}template<typename Vs, typename V>constexpr void fillAll(Vs& arr, const V& v){if constexpr (std::is_convertible<V, Vs>::value) {arr = v;} else {for (auto& subarr : arr) { fillAll(subarr, v); }}}template<typename Vs>constexpr void sortAll(Vs& vs){std::sort(std::begin(vs), std::end(vs));}template<typename Vs, typename C>constexpr void sortAll(Vs& vs, C comp){std::sort(std::begin(vs), std::end(vs), comp);}template<typename Vs>constexpr void reverseAll(Vs& vs){std::reverse(std::begin(vs), std::end(vs));}template<typename Vs>constexpr Vs reversed(const Vs& vs){auto rvs = vs;reverseAll(rvs);return rvs;}template<typename V, typename Vs>constexpr V sumAll(const Vs& vs){if constexpr (std::is_convertible<Vs, V>::value) {return static_cast<V>(vs);} else {V ans = 0;for (const auto& v : vs) { ans += sumAll<V>(v); }return ans;}}template<typename Vs>constexpr int minInd(const Vs& vs){return std::min_element(std::begin(vs), std::end(vs)) - std::begin(vs);}template<typename Vs>constexpr int maxInd(const Vs& vs){return std::max_element(std::begin(vs), std::end(vs)) - std::begin(vs);}template<typename Vs, typename V>constexpr int lbInd(const Vs& vs, const V& v){return std::lower_bound(std::begin(vs), std::end(vs), v) - std::begin(vs);}template<typename Vs, typename V>constexpr int ubInd(const Vs& vs, const V& v){return std::upper_bound(std::begin(vs), std::end(vs), v) - std::begin(vs);}template<typename Vs, typename V>constexpr void plusAll(Vs& vs, const V& v){for (auto& v_ : vs) { v_ += v; }}template<typename Vs>constexpr void concat(Vs& vs1, const Vs& vs2){std::copy(std::begin(vs2), std::end(vs2), std::back_inserter(vs1));}template<typename Vs>constexpr void concatted(const Vs& vs1, const Vs& vs2){auto vs = vs1;concat(vs, vs2);return vs;}template<typename T, typename F>constexpr Vec<T> genVec(int n, F gen){Vec<T> ans;std::generate_n(std::back_inserter(ans), n, gen);return ans;}template<typename T = int>constexpr Vec<T> iotaVec(int n, T offset = 0){Vec<T> ans(n);std::iota(std::begin(ans), std::end(ans), offset);return ans;}template<typename Vs>constexpr void rearrange(Vs& vs, const Vec<int>& is){auto vs_ = vs;for (int i = 0; i < (int)is.size(); i++) { vs[i] = vs_[is[i]]; }}inline Vec<int> reversePerm(const Vec<int>& is){auto ris = is;for (int i = 0; i < (int)is.size(); i++) { ris[is[i]] = i; }return ris;}inline Ostream& operator<<(Ostream& os, i128 v){bool minus = false;if (v < 0) { minus = true, v = -v; }Str ans;if (v == 0) { ans = "0"; }while (v) { ans.push_back('0' + v % 10), v /= 10; }std::reverse(ans.begin(), ans.end());return os << (minus ? "-" : "") << ans;}inline Ostream& operator<<(Ostream& os, u128 v){Str ans;if (v == 0) { ans = "0"; }while (v) { ans.push_back('0' + v % 10), v /= 10; }std::reverse(ans.begin(), ans.end());return os << ans;}constexpr int popCount(u64 v) { return v ? __builtin_popcountll(v) : 0; }constexpr int topBit(u64 v) { return v == 0 ? -1 : 63 - __builtin_clzll(v); }constexpr int lowBit(u64 v) { return v == 0 ? 64 : __builtin_ctzll(v); }constexpr int bitWidth(u64 v) { return topBit(v) + 1; }constexpr u64 bitCeil(u64 v) { return v ? (1_u64 << bitWidth(v - 1)) : 1_u64; }constexpr u64 bitFloor(u64 v) { return v ? (1_u64 << topBit(v)) : 0_u64; }constexpr bool hasSingleBit(u64 v) { return (v > 0) and ((v & (v - 1)) == 0); }constexpr bool isBitOn(u64 mask, int ind) { return (mask >> ind) & 1_u64; }constexpr bool isBitOff(u64 mask, int ind) { return not isBitOn(mask, ind); }constexpr u64 bitMask(int bitWidth) { return (bitWidth == 64 ? ~0_u64 : (1_u64 << bitWidth) - 1); }constexpr u64 bitMask(int start, int end) { return bitMask(end - start) << start; }template<typename F>struct Fix : F{constexpr Fix(F&& f) : F{std::forward<F>(f)} {}template<typename... Args>constexpr auto operator()(Args&&... args) const{return F::operator()(*this, std::forward<Args>(args)...);}};class irange{private:struct itr{constexpr itr(i64 start = 0, i64 step = 1) : m_cnt{start}, m_step{step} {}constexpr bool operator!=(const itr& it) const { return m_cnt != it.m_cnt; }constexpr i64 operator*() { return m_cnt; }constexpr itr& operator++() { return m_cnt += m_step, *this; }i64 m_cnt, m_step;};i64 m_start, m_end, m_step;public:static constexpr i64 cnt(i64 start, i64 end, i64 step){if (step == 0) { return -1; }const i64 d = (step > 0 ? step : -step);const i64 l = (step > 0 ? start : end);const i64 r = (step > 0 ? end : start);i64 n = (r - l) / d + ((r - l) % d ? 1 : 0);if (l >= r) { n = 0; }return n;}constexpr irange(i64 start, i64 end, i64 step = 1): m_start{start}, m_end{m_start + step * cnt(start, end, step)}, m_step{step}{assert(step != 0);}constexpr itr begin() const { return itr{m_start, m_step}; }constexpr itr end() const { return itr{m_end, m_step}; }};constexpr irange rep(i64 end) { return irange(0, end, 1); }constexpr irange per(i64 rend) { return irange(rend - 1, -1, -1); }class Scanner{public:Scanner(Istream& is = std::cin) : m_is{is} { m_is.tie(nullptr)->sync_with_stdio(false); }template<typename T>T val(){T v;return m_is >> v, v;}template<typename T>T val(T offset){return val<T>() - offset;}template<typename T>Vec<T> vec(int n){return genVec<T>(n, [&]() { return val<T>(); });}template<typename T>Vec<T> vec(int n, T offset){return genVec<T>(n, [&]() { return val<T>(offset); });}template<typename T>Vec<Vec<T>> vvec(int n, int m){return genVec<Vec<T>>(n, [&]() { return vec<T>(m); });}template<typename T>Vec<Vec<T>> vvec(int n, int m, const T offset){return genVec<Vec<T>>(n, [&]() { return vec<T>(m, offset); });}template<typename... Args>auto tup(){return Tup<Args...>{val<Args>()...};}template<typename... Args>auto tup(const Args&... offsets){return Tup<Args...>{val<Args>(offsets)...};}private:Istream& m_is;};inline Scanner in;class Printer{public:Printer(Ostream& os = std::cout) : m_os{os} { m_os << std::fixed << std::setprecision(15); }template<typename... Args>int operator()(const Args&... args){return dump(args...), 0;}template<typename... Args>int ln(const Args&... args){return dump(args...), m_os << '\n', 0;}template<typename... Args>int el(const Args&... args){return dump(args...), m_os << std::endl, 0;}int YES(bool b = true) { return ln(b ? "YES" : "NO"); }int NO(bool b = true) { return YES(not b); }int Yes(bool b = true) { return ln(b ? "Yes" : "No"); }int No(bool b = true) { return Yes(not b); }private:template<typename T>void dump(const T& v){m_os << v;}template<typename T>void dump(const Vec<T>& vs){for (int i : rep(vs.size())) { m_os << (i ? " " : ""), dump(vs[i]); }}template<typename T>void dump(const Vec<Vec<T>>& vss){for (int i : rep(vss.size())) { m_os << (i ? "\n" : ""), dump(vss[i]); }}template<typename T, typename... Ts>int dump(const T& v, const Ts&... args){return dump(v), m_os << ' ', dump(args...), 0;}Ostream& m_os;};inline Printer out;template<typename T, int n, int i = 0>auto ndVec(int const (&szs)[n], const T x = T{}){if constexpr (i == n) {return x;} else {return std::vector(szs[i], ndVec<T, n, i + 1>(szs, x));}}template<typename T, typename F>inline T binSearch(T ng, T ok, F check){while (std::abs(ok - ng) > 1) {const T mid = (ok + ng) / 2;(check(mid) ? ok : ng) = mid;}return ok;}template<typename T>constexpr Pair<T, T> extgcd(const T a, const T b) // [x,y] -> ax+by=gcd(a,b){static_assert(std::is_signed_v<T>, "Signed integer is allowed.");assert(a != 0 or b != 0);if (a >= 0 and b >= 0) {if (a < b) {const auto [y, x] = extgcd(b, a);return {x, y};}if (b == 0) { return {1, 0}; }const auto [x, y] = extgcd(b, a % b);return {y, x - (a / b) * y};} else {auto [x, y] = extgcd(std::abs(a), std::abs(b));if (a < 0) { x = -x; }if (b < 0) { y = -y; }return {x, y};}}template<typename T>constexpr T inverse(const T a, const T mod) // ax=gcd(a,M) (mod M){assert(a > 0 and mod > 0);auto [x, y] = extgcd(a, mod);if (x <= 0) { x += mod; }return x;}template<u32 mod_, u32 root_, u32 max2p_>class modint{template<typename U = u32&>static U modRef(){static u32 s_mod = 0;return s_mod;}template<typename U = u32&>static U rootRef(){static u32 s_root = 0;return s_root;}template<typename U = u32&>static U max2pRef(){static u32 s_max2p = 0;return s_max2p;}public:static_assert(mod_ <= LIMMAX<i32>, "mod(signed int size) only supported!");static constexpr bool isDynamic() { return (mod_ == 0); }template<typename U = const u32>static constexpr std::enable_if_t<mod_ != 0, U> mod(){return mod_;}template<typename U = const u32>static std::enable_if_t<mod_ == 0, U> mod(){return modRef();}template<typename U = const u32>static constexpr std::enable_if_t<mod_ != 0, U> root(){return root_;}template<typename U = const u32>static std::enable_if_t<mod_ == 0, U> root(){return rootRef();}template<typename U = const u32>static constexpr std::enable_if_t<mod_ != 0, U> max2p(){return max2p_;}template<typename U = const u32>static std::enable_if_t<mod_ == 0, U> max2p(){return max2pRef();}template<typename U = u32>static void setMod(std::enable_if_t<mod_ == 0, U> m){assert(1 <= m and m <= LIMMAX<i32>);modRef() = m;sinvRef() = {1, 1};factRef() = {1, 1};ifactRef() = {1, 1};}template<typename U = u32>static void setRoot(std::enable_if_t<mod_ == 0, U> r){rootRef() = r;}template<typename U = u32>static void setMax2p(std::enable_if_t<mod_ == 0, U> m){max2pRef() = m;}constexpr modint() : m_val{0} {}constexpr modint(i64 v) : m_val{normll(v)} {}constexpr void setRaw(u32 v) { m_val = v; }constexpr modint operator-() const { return modint{0} - (*this); }constexpr modint& operator+=(const modint& m){m_val = norm(m_val + m.val());return *this;}constexpr modint& operator-=(const modint& m){m_val = norm(m_val + mod() - m.val());return *this;}constexpr modint& operator*=(const modint& m){m_val = normll((i64)m_val * (i64)m.val() % (i64)mod());return *this;}constexpr modint& operator/=(const modint& m) { return *this *= m.inv(); }constexpr modint operator+(const modint& m) const{auto v = *this;return v += m;}constexpr modint operator-(const modint& m) const{auto v = *this;return v -= m;}constexpr modint operator*(const modint& m) const{auto v = *this;return v *= m;}constexpr modint operator/(const modint& m) const{auto v = *this;return v /= m;}constexpr bool operator==(const modint& m) const { return m_val == m.val(); }constexpr bool operator!=(const modint& m) const { return not(*this == m); }friend Istream& operator>>(Istream& is, modint& m){i64 v;return is >> v, m = v, is;}friend Ostream& operator<<(Ostream& os, const modint& m) { return os << m.val(); }constexpr u32 val() const { return m_val; }template<typename I>constexpr modint pow(I n) const{return powerInt(*this, n);}constexpr modint inv() const { return inverse<i32>(m_val, mod()); }static modint sinv(u32 n){auto& is = sinvRef();for (u32 i = (u32)is.size(); i <= n; i++) { is.push_back(-is[mod() % i] * (mod() / i)); }return is[n];}static modint fact(u32 n){auto& fs = factRef();for (u32 i = (u32)fs.size(); i <= n; i++) { fs.push_back(fs.back() * i); }return fs[n];}static modint ifact(u32 n){auto& ifs = ifactRef();for (u32 i = (u32)ifs.size(); i <= n; i++) { ifs.push_back(ifs.back() * sinv(i)); }return ifs[n];}static modint perm(int n, int k) { return k > n or k < 0 ? modint{0} : fact(n) * ifact(n - k); }static modint comb(int n, int k){return k > n or k < 0 ? modint{0} : fact(n) * ifact(n - k) * ifact(k);}private:static Vec<modint>& sinvRef(){static Vec<modint> is{1, 1};return is;}static Vec<modint>& factRef(){static Vec<modint> fs{1, 1};return fs;}static Vec<modint>& ifactRef(){static Vec<modint> ifs{1, 1};return ifs;}static constexpr u32 norm(u32 x) { return x < mod() ? x : x - mod(); }static constexpr u32 normll(i64 x) { return norm(u32(x % (i64)mod() + (i64)mod())); }u32 m_val;};using modint_1000000007 = modint<1000000007, 5, 1>;using modint_998244353 = modint<998244353, 3, 23>;template<int id>using modint_dynamic = modint<0, 0, id>;template<typename T = int>class Graph{struct Edge{Edge() = default;Edge(int i, int t, T c) : id{i}, to{t}, cost{c} {}int id;int to;T cost;operator int() const { return to; }};public:Graph(int n) : m_v{n}, m_edges(n) {}void addEdge(int u, int v, bool bi = false){assert(0 <= u and u < m_v);assert(0 <= v and v < m_v);m_edges[u].emplace_back(m_e, v, 1);if (bi) { m_edges[v].emplace_back(m_e, u, 1); }m_e++;}void addEdge(int u, int v, const T& c, bool bi = false){assert(0 <= u and u < m_v);assert(0 <= v and v < m_v);m_edges[u].emplace_back(m_e, v, c);if (bi) { m_edges[v].emplace_back(m_e, u, c); }m_e++;}const Vec<Edge>& operator[](const int u) const{assert(0 <= u and u < m_v);return m_edges[u];}Vec<Edge>& operator[](const int u){assert(0 <= u and u < m_v);return m_edges[u];}int v() const { return m_v; }int e() const { return m_e; }friend Ostream& operator<<(Ostream& os, const Graph& g){for (int u : rep(g.v())) {for (const auto& [id, v, c] : g[u]) {os << "[" << id << "]: ";os << u << "->" << v << "(" << c << ")\n";}}return os;}Vec<T> sizes(int root = 0) const{const int N = v();assert(0 <= root and root < N);Vec<T> ss(N, 1);Fix([&](auto dfs, int u, int p) -> void {for ([[maybe_unused]] const auto& [_temp_name_0, v, c] : m_edges[u]) {if (v == p) { continue; }dfs(v, u);ss[u] += ss[v];}})(root, -1);return ss;}Vec<T> depths(int root = 0) const{const int N = v();assert(0 <= root and root < N);Vec<T> ds(N, 0);Fix([&](auto dfs, int u, int p) -> void {for ([[maybe_unused]] const auto& [_temp_name_1, v, c] : m_edges[u]) {if (v == p) { continue; }ds[v] = ds[u] + c;dfs(v, u);}})(root, -1);return ds;}Vec<int> parents(int root = 0) const{const int N = v();assert(0 <= root and root < N);Vec<int> ps(N, -1);Fix([&](auto dfs, int u, int p) -> void {for ([[maybe_unused]] const auto& [_temp_name_2, v, c] : m_edges[u]) {if (v == p) { continue; }ps[v] = u;dfs(v, u);}})(root, -1);return ps;}private:int m_v;int m_e = 0;Vec<Vec<Edge>> m_edges;};using namespace std;struct UnionFind{vector<int> data;UnionFind() = default;explicit UnionFind(size_t sz) : data(sz, -1) {}bool unite(int x, int y){x = find(x), y = find(y);if (x == y)return false;if (data[x] > data[y])swap(x, y);data[x] += data[y];data[y] = x;return true;}int find(int k){if (data[k] < 0)return (k);return data[k] = find(data[k]);}int size(int k){return -data[find(k)];}bool same(int x, int y){return find(x) == find(y);}vector<vector<int>> groups(){int n = (int)data.size();vector<vector<int>> ret(n);for (int i = 0; i < n; i++) {ret[find(i)].emplace_back(i);}ret.erase(remove_if(begin(ret),end(ret),[&](const vector<int>& v) { return v.empty(); }),end(ret));return ret;}};/*** @brief Bipartite Flow(二部グラフのフロー)* @docs docs/bipartite-flow.md*/struct BipartiteFlow{size_t n, m, time_stamp;vector<vector<int>> g, rg;vector<int> match_l, match_r, dist, used, alive;bool matched;public:explicit BipartiteFlow(size_t n, size_t m): n(n),m(m),time_stamp(0),g(n),rg(m),match_l(n, -1),match_r(m, -1),used(n),alive(n, 1),matched(false){}void add_edge(int u, int v){g[u].push_back(v);rg[v].emplace_back(u);}vector<pair<int, int>> max_matching(){matched = true;for (;;) {build_augment_path();++time_stamp;int flow = 0;for (int i = 0; i < (int)n; i++) {if (match_l[i] == -1)flow += find_min_dist_augment_path(i);}if (flow == 0)break;}vector<pair<int, int>> ret;for (int i = 0; i < (int)n; i++) {if (match_l[i] >= 0)ret.emplace_back(i, match_l[i]);}return ret;}/* http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3198 */void erase_edge(int a, int b){if (match_l[a] == b) {match_l[a] = -1;match_r[b] = -1;}g[a].erase(find(begin(g[a]), end(g[a]), b));rg[b].erase(find(begin(rg[b]), end(rg[b]), a));}/* http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0334 */vector<pair<int, int>> lex_max_matching(){if (!matched)max_matching();for (auto& vs : g)sort(begin(vs), end(vs));vector<pair<int, int>> es;for (int i = 0; i < (int)n; i++) {if (match_l[i] == -1 || alive[i] == 0) {continue;}match_r[match_l[i]] = -1;match_l[i] = -1;++time_stamp;find_augment_path(i);alive[i] = 0;es.emplace_back(i, match_l[i]);}return es;}vector<int> min_vertex_cover(){auto visited = find_residual_path();vector<int> ret;for (int i = 0; i < (int)(n + m); i++) {if (visited[i] ^ (i < (int)n)) {ret.emplace_back(i);}}return ret;}/* https://atcoder.jp/contests/utpc2013/tasks/utpc2013_11 */vector<int> lex_min_vertex_cover(const vector<int>& ord){assert(ord.size() == n + m);auto res = build_risidual_graph();vector<vector<int>> r_res(n + m + 2);for (int i = 0; i < (int)(n + m + 2); i++) {for (auto& j : res[i])r_res[j].emplace_back(i);}queue<int> que;vector<int> visited(n + m + 2, -1);auto expand_left = [&](int t) {if (visited[t] != -1)return;que.emplace(t);visited[t] = 1;while (!que.empty()) {int idx = que.front();que.pop();for (auto& to : r_res[idx]) {if (visited[to] != -1)continue;visited[to] = 1;que.emplace(to);}}};auto expand_right = [&](int t) {if (visited[t] != -1)return;que.emplace(t);visited[t] = 0;while (!que.empty()) {int idx = que.front();que.pop();for (auto& to : res[idx]) {if (visited[to] != -1)continue;visited[to] = 0;que.emplace(to);}}};expand_right(n + m);expand_left(n + m + 1);vector<int> ret;for (auto& t : ord) {if (t < (int)n) {expand_left(t);if (visited[t] & 1)ret.emplace_back(t);} else {expand_right(t);if (~visited[t] & 1)ret.emplace_back(t);}}return ret;}vector<int> max_independent_set(){auto visited = find_residual_path();vector<int> ret;for (int i = 0; i < (int)(n + m); i++) {if (visited[i] ^ (i >= (int)n)) {ret.emplace_back(i);}}return ret;}vector<pair<int, int>> min_edge_cover(){auto es = max_matching();for (int i = 0; i < (int)n; i++) {if (match_l[i] >= 0) {continue;}if (g[i].empty()) {return {};}es.emplace_back(i, g[i][0]);}for (int i = 0; i < (int)m; i++) {if (match_r[i] >= 0) {continue;}if (rg[i].empty()) {return {};}es.emplace_back(rg[i][0], i);}return es;}// left: [0,n), right: [n,n+m), S: n+m, T: n+m+1vector<vector<int>> build_risidual_graph(){if (!matched)max_matching();const size_t S = n + m;const size_t T = n + m + 1;vector<vector<int>> ris(n + m + 2);for (int i = 0; i < (int)n; i++) {if (match_l[i] == -1)ris[S].emplace_back(i);elseris[i].emplace_back(S);}for (int i = 0; i < (int)m; i++) {if (match_r[i] == -1)ris[i + n].emplace_back(T);elseris[T].emplace_back(i + n);}for (int i = 0; i < (int)n; i++) {for (auto& j : g[i]) {if (match_l[i] == j)ris[j + n].emplace_back(i);elseris[i].emplace_back(j + n);}}return ris;}private:vector<int> find_residual_path(){auto res = build_risidual_graph();queue<int> que;vector<int> visited(n + m + 2);que.emplace(n + m);visited[n + m] = true;while (!que.empty()) {int idx = que.front();que.pop();for (auto& to : res[idx]) {if (visited[to])continue;visited[to] = true;que.emplace(to);}}return visited;}void build_augment_path(){queue<int> que;dist.assign(g.size(), -1);for (int i = 0; i < (int)n; i++) {if (match_l[i] == -1) {que.emplace(i);dist[i] = 0;}}while (!que.empty()) {int a = que.front();que.pop();for (auto& b : g[a]) {int c = match_r[b];if (c >= 0 && dist[c] == -1) {dist[c] = dist[a] + 1;que.emplace(c);}}}}bool find_min_dist_augment_path(int a){used[a] = time_stamp;for (auto& b : g[a]) {int c = match_r[b];if (c < 0|| (used[c] != (int)time_stamp && dist[c] == dist[a] + 1&& find_min_dist_augment_path(c))) {match_r[b] = a;match_l[a] = b;return true;}}return false;}bool find_augment_path(int a){used[a] = time_stamp;for (auto& b : g[a]) {int c = match_r[b];if (c < 0|| (alive[c] == 1 && used[c] != (int)time_stamp&& find_augment_path(c))) {match_r[b] = a;match_l[a] = b;return true;}}return false;}};/*** @brief Eulerian Trail(オイラー路)* @docs docs/eulerian-trail.md*/template<bool directed>struct EulerianTrail{vector<vector<pair<int, int>>> g;vector<pair<int, int>> es;int M;vector<int> used_vertex, used_edge, deg;explicit EulerianTrail(int V) : g(V), M(0), used_vertex(V), deg(V) {}void add_edge(int a, int b){es.emplace_back(a, b);g[a].emplace_back(b, M);if (directed) {deg[a]++;deg[b]--;} else {g[b].emplace_back(a, M);deg[a]++;deg[b]++;}M++;}pair<int, int> get_edge(int idx) const{return es[idx];}vector<vector<int>> enumerate_eulerian_trail(){if (directed) {for (auto& p : deg)if (p != 0)return {};} else {for (auto& p : deg)if (p & 1)return {};}used_edge.assign(M, 0);vector<vector<int>> ret;for (int i = 0; i < (int)g.size(); i++) {if (g[i].empty() || used_vertex[i])continue;ret.emplace_back(go(i));}return ret;}vector<vector<int>> enumerate_semi_eulerian_trail(){UnionFind uf(g.size());for (auto& p : es)uf.unite(p.first, p.second);vector<vector<int>> group(g.size());for (int i = 0; i < (int)g.size(); i++)group[uf.find(i)].emplace_back(i);vector<vector<int>> ret;used_edge.assign(M, 0);for (auto& vs : group) {if (vs.empty())continue;int latte = -1, malta = -1;if (directed) {for (auto& p : vs) {if (abs(deg[p]) > 1) {return {};} else if (deg[p] == 1) {if (latte >= 0)return {};latte = p;}}} else {for (auto& p : vs) {if (deg[p] & 1) {if (latte == -1)latte = p;else if (malta == -1)malta = p;elsereturn {};}}}ret.emplace_back(go(latte == -1 ? vs.front() : latte));if (ret.back().empty())ret.pop_back();}return ret;}vector<int> go(int s){stack<pair<int, int>> st;vector<int> ord;st.emplace(s, -1);while (!st.empty()) {int idx = st.top().first;used_vertex[idx] = true;if (g[idx].empty()) {ord.emplace_back(st.top().second);st.pop();} else {auto e = g[idx].back();g[idx].pop_back();if (used_edge[e.second])continue;used_edge[e.second] = true;st.emplace(e);}}ord.pop_back();reverse(ord.begin(), ord.end());return ord;}};/*** @brief Bipartite Graph Edge Coloring(二部グラフの辺彩色)* @docs docs/bipartite-graph-edge-coloring.md* @see https://ei1333.hateblo.jp/entry/2020/08/25/015955*/struct BipariteGraphEdgeColoring{private:vector<vector<int>> ans;vector<int> A, B;int L, R;struct RegularGraph{int k{}, n{};vector<int> A, B;};RegularGraph g;static UnionFind contract(valarray<int>& deg, int k){using pi = pair<int, int>;priority_queue<pi, vector<pi>, greater<>> que;for (int i = 0; i < (int)deg.size(); i++) {que.emplace(deg[i], i);}UnionFind uf(deg.size());while (que.size() > 1) {auto p = que.top();que.pop();auto q = que.top();que.pop();if (p.first + q.first > k)continue;p.first += q.first;uf.unite(p.second, q.second);que.emplace(p);}return uf;}RegularGraph build_k_regular_graph(){valarray<int> deg[2];deg[0] = valarray<int>(L);deg[1] = valarray<int>(R);for (auto& p : A)deg[0][p]++;for (auto& p : B)deg[1][p]++;int k = max(deg[0].max(), deg[1].max());/* step 1 */UnionFind uf[2];uf[0] = contract(deg[0], k);uf[1] = contract(deg[1], k);vector<int> id[2];int ptr[] = {0, 0};id[0] = vector<int>(L);id[1] = vector<int>(R);for (int i = 0; i < L; i++)if (uf[0].find(i) == i)id[0][i] = ptr[0]++;for (int i = 0; i < R; i++)if (uf[1].find(i) == i)id[1][i] = ptr[1]++;/* step 2 */int N = max(ptr[0], ptr[1]);deg[0] = valarray<int>(N);deg[1] = valarray<int>(N);/* step 3 */vector<int> C, D;C.reserve(N * k);D.reserve(N * k);for (int i = 0; i < (int)A.size(); i++) {int u = id[0][uf[0].find(A[i])];int v = id[1][uf[1].find(B[i])];C.emplace_back(u);D.emplace_back(v);deg[0][u]++;deg[1][v]++;}int j = 0;for (int i = 0; i < N; i++) {while (deg[0][i] < k) {while (deg[1][j] == k)++j;C.emplace_back(i);D.emplace_back(j);++deg[0][i];++deg[1][j];}}return {k, N, C, D};}void rec(const vector<int>& ord, int k){if (k == 0) {return;} else if (k == 1) {ans.emplace_back(ord);return;} else if ((k & 1) == 0) {EulerianTrail<false> et(g.n + g.n);for (auto& p : ord)et.add_edge(g.A[p], g.B[p] + g.n);auto paths = et.enumerate_eulerian_trail();vector<int> path;for (auto& ps : paths) {for (auto& e : ps)path.emplace_back(ord[e]);}vector<int> beet[2];for (int i = 0; i < (int)path.size(); i++) {beet[i & 1].emplace_back(path[i]);}rec(beet[0], k / 2);rec(beet[1], k / 2);} else {BipartiteFlow flow(g.n, g.n);for (auto& i : ord)flow.add_edge(g.A[i], g.B[i]);flow.max_matching();vector<int> beet;ans.emplace_back();for (auto& i : ord) {if (flow.match_l[g.A[i]] == g.B[i]) {flow.match_l[g.A[i]] = -1;ans.back().emplace_back(i);} else {beet.emplace_back(i);}}rec(beet, k - 1);}}public:explicit BipariteGraphEdgeColoring() : L(0), R(0) {}void add_edge(int a, int b){A.emplace_back(a);B.emplace_back(b);L = max(L, a + 1);R = max(R, b + 1);}vector<vector<int>> build(){g = build_k_regular_graph();vector<int> ord(g.A.size());iota(ord.begin(), ord.end(), 0);rec(ord, g.k);vector<vector<int>> res;for (int i = 0; i < (int)ans.size(); i++) {res.emplace_back();for (auto& j : ans[i])if (j < (int)A.size())res.back().emplace_back(j);}return res;}};int main(){const auto [N, M] = in.tup<int, int>();const auto Ass = in.vvec<int>(N, N);Vec<int> lds(N,0), rds(N, 0);Vec<Pair<int, int>> es;for (int i : rep(N)) {for (int j : rep(N)) {lds[i] += Ass[i][j];rds[j] += Ass[i][j];}}for (int i : rep(N)) {if (lds[i] != M) {return out.ln(-1);}if (rds[i] != M) {return out.ln(-1);}}BipariteGraphEdgeColoring g;for (int i : rep(N)) {for (int j : rep(N)) {for (auto _temp_name_3 [[maybe_unused]] : rep(Ass[i][j])) {g.add_edge(i, j);es.push_back({i, j});}}}const auto vss = g.build();for (const auto& vs : vss) {Vec<int> Ps(N, -1);for (int ei : vs) {const auto [i, j] = es[ei];Ps[i] = j;}plusAll(Ps, 1);out.ln(Ps);}return 0;}