Problem:
Distributing the Treasure
You are the leader of a treasure hunting team. Under your great direction, your team has made a big success in a quest, and got a lot of treasure. The only, but crucial, remaining issue is how to distribute the obtained treasure to the team members.
The excavated treasure includes a variety of precious items: gold ingots, jewelry with brilliant gem stones, exquisite craft works, etc. Each team member individually estimates the values of the items. The estimated values are consistent, in that, for any pair of two items, when some member estimates one to be strictly higher than the other, no member estimates oppositely, although some may give equal estimates.
All the members are sensible and thus understand the difficulty of even distribution of the items. Hence, no member will complain simply because, based on the member's own estimation, the sum of the values of the member's share is lower than that of another member's share. The members, however, may get angry if their own shares look unreasonably shabby compared to some other member's; what they cannot stand is when their own shares are estimated strictly lower than the share of that other member even after getting rid of one item with the least estimated value.
Your last mission as the leader is to decide who receives which items so that no member gets angry. Some of the members may receive nothing as long as they do not get angry.
Input
The input consists of a single test case of the following format.
$n$ $m$
$v_{1,1}$ $\cdots$ $v_{1,m}$
$\vdots$
$v_{n,1}$ $\cdots$ $v_{n,m}$
The first line of the input has two positive integers $n$ and $m$ whose product does not exceed $2 \times 10^5$; $n$ is the number of members of your treasure hunting team, and $m$ is the number of treasure items. The members and items are numbered $1$ through $n$ and $1$ through $m$, respectively. The $i$-th of the following $n$ lines has $m$ positive integers not exceeding $2 \times 10^5$ in descending order: $v_{i,1} \geq v_{i,2} \geq \cdots \geq v_{i,m}$. Here, $v_{i,j}$ is the value of the item $j$ estimated by the member $i$.
Output
If you can distribute the items to the members without making any member angry, output such a distribution in a line as $m$ positive integers $x_1, x_2, \ldots ,x_m$ separated by spaces. Here, $x_j = i$ means that the member $i$ receives the item $j$. If two or more such distributions exist, any of them shall be deemed correct. If there is no way to distribute the items without making any member angry, just output $0$ in a line.
Sample Input 1
2 3
4 2 1
3 3 3
Sample Output 1
1 2 1
Sample Input 2
1 7
64 32 16 8 4 2 1
Sample Output 2
1 1 1 1 1 1 1
Let $V_i(X)$ denote the sum of the values of items in the set $X$ estimated by the member $i$.
In Sample 1, $V_1(\{1, 3\})$ is $4 + 1 = 5$, $V1(\{2\})$ is $2$, $V_2(\{1, 3\})$ is $3 + 3 = 6$, and $V_2(\{2\})$ is $3$. The distribution shown as output does not make the member $1$ angry as $V_1(\{1, 3\}) \geq V_1(\{2\})$. T
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#define N 505
using namespace std;
typedef long long ll;

int n, m, bel[N], in[N], lst[N]; ll dis[N];
int col[200005];
vector<int> E[N];
vector<vector<int> > a; 
vector<vector<ll> > b;

int main() {
//	freopen("000.in", "r", stdin);
	scanf("%d %d", &n, &m);
	if (n >= m) {
		for (int i = 1; i <= m; i++) printf("%d ", i);
		return 0;
	}
	a.resize(n+1); b.resize(n+1);
	for (int i = 1; i <= n; i++) a[i].resize(m+1), b[i].resize(m+1);
	for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) 
		scanf("%d", &a[i][j]);
	for (int i = 1; i <= n; i++) bel[i] = i;
	for (int k = 1; k <= m; k++) {
		int p = 0;
		for (int j = 1; j <= n; j++) {
			bool flg = 0;
			for (int i = 1; i <= n; i++) if (b[i][bel[i]] < b[i][bel[j]]) { flg = 1; break; }
			if (!flg) { p = j; break; }
		}
		col[k] = bel[p];
		for (int i = 1; i <= n; i++) {
			b[i][bel[p]] += a[i][k];
			E[i].clear(); in[i] = 0;
		}
		for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) {
			if (j != p && b[i][bel[i]] < b[i][bel[j]]) {
				E[i].push_back(j); ++in[j];
			}
		}
		queue<int> q; memset(lst, 0, sizeof(lst));
		memset(dis, -0x3f, sizeof(dis)); dis[p] = 0;
		for (int i = 1; i <= n; i++) if (!in[i]) q.push(i);
		while (!q.empty()) {
			int x = q.front(); q.pop();
			for (auto y : E[x]) {
				if (dis[y] < dis[x]-b[x][bel[x]]+b[x][bel[y]]) {
					dis[y] = dis[x]-b[x][bel[x]]+b[x][bel[y]];
					lst[y] = x;
				}
				if (!--in[y]) q.push(y);
			}
		}
		int x = 0; ll mx = -1e18;
		for (int i = 1; i <= n; i++) {
			if (b[i][bel[i]] < b[i][bel[p]] && mx < dis[i]-b[i][bel[i]]+b[i][bel[p]]) {
				mx = dis[i]-b[i][bel[i]]+b[i][bel[p]];
				x = i;
			}
		}
		for (int _ = bel[p]; x; x = lst[x]) swap(_, bel[x]);
	}
	for (int i = 1; i <= m; i++) {
		for (int j = 1; j <= n; j++) if (col[i] == bel[j]) {
			printf("%d ", j); break;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 6592
final_rank: 2

code_snippet: // time complexity: O(N^2 * M) when N < M

#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

vector<int> solve(int N, int M, const vector<vector<int> >& V) {
	// step #1. initialization
	vector<int> A(M, -1);
	for (int i = 0; i < min(N, M); i++) {
		A[i] = i;
	}
	if (N >= M) {
		return A;
	}

	// step #2. envy-cycle elimination
	vector<int> p(N), last(N);
	vector<vector<long long> > s(N, vector<long long>(N));
	for (int i = 0; i < N; i++) {
		p[i] = i;
		last[i] = i;
		for (int j = 0; j < N; j++) {
			s[j][i] = V[j][i];
		}
	}
	for (int i = N; i < M; i++) {
		vector<vector<bool> > envy(N, vector<bool>(N, false));
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				envy[j][k] = (s[p[j]][j] < s[p[j]][k]);
			}
		}
		vector<int> vlist(N);
		for (int i = 0; i < N; i++) {
			vlist[i] = i;
		}
		vector<int> cur(N);
		vector<int> st;
		vector<bool> path(N, false);
		int pos = 0;
		path[pos] = true;
		st.push_back(pos);
		while (true) {
			while (cur[pos] != vlist.size() && !envy[vlist[cur[pos]]][pos]) {
				cur[pos]++;
			}
			if (cur[pos] == vlist.size()) {
				break;
			}
			pos = vlist[cur[pos]++];
			if (path[pos]) {
				vector<int> cycle = { pos };
				while (st.back() != pos) {
					path[st.back()] = false;
					cycle.push_back(st.back());
					st.pop_back();
				}
				cycle.push_back(pos);
				int csize = cycle.size() - 1;
				vector<int> np = p;
				for (int j = 0; j < csize; j++) {
					np[cycle[j + 1]] = p[cycle[j]];
					vlist.push_back(cycle[j]);
				}
				p = np;
				for (int j = 0; j < csize; j++) {
					for (int k = 0; k < N; k++) {
						envy[cycle[j]][k] = (s[p[cycle[j]]][cycle[j]] < s[p[cycle[j]]][k]);
					}
				}
			} else {
				path[pos] = true;
				st.push_back(pos);
			}
		}
		A[i] = pos;
		for (int j = 0; j < N; j++) {
			s[j][pos] += V[j][i];
		}
	}

	// step #3. final answer
	vector<int> B(M);
	for (int i = 0; i < M; i++) {
		B[i] = p[A[i]];
	}

	return B;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int N, M;
	cin >> N >> M;
	vector<vector<int> > V(N, vector<int>(M));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> V[i][j];
		}
	}
	vector<int> ans = solve(N, M, V);
	for (int i = 0; i < M; i++) {
		if (i != 0) {
			cout << ' ';
		}
		cout << ans[i] + 1;
	}
	cout << endl;
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 13984
final_rank: 3

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

vector<int> solve(int N, int M, const vector<vector<int> >& V) {
	// step #1. initialization
	vector<int> A(M, -1);
	for (int i = 0; i < min(N, M); i++) {
		A[i] = i;
	}
	if (N >= M) {
		return A;
	}

	// step #2. envy-cycle elimination
	vector<int> p(N), last(N);
	vector<vector<long long> > s(N, vector<long long>(N));
	for (int i = 0; i < N; i++) {
		p[i] = i;
		last[i] = i;
		for (int j = 0; j < N; j++) {
			s[j][i] = V[j][i];
		}
	}
	for (int i = N; i < M; i++) {
		vector<vector<bool> > envy(N, vector<bool>(N, false));
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				envy[j][k] = (s[p[j]][j] < s[p[j]][k]);
			}
		}
		vector<int> vlist(N);
		for (int i = 0; i < N; i++) {
			vlist[i] = i;
		}
		vector<int> cur(N);
		vector<int> st;
		vector<bool> path(N, false);
		int pos = 0;
		path[pos] = true;
		st.push_back(pos);
		while (true) {
			while (cur[pos] != vlist.size() && !envy[vlist[cur[pos]]][pos]) {
				cur[pos]++;
			}
			if (cur[pos] == vlist.size()) {
				break;
			}
			pos = vlist[cur[pos]++];
			if (path[pos]) {
				vector<int> cycle = { pos };
				while (st.back() != pos) {
					path[st.back()] = false;
					cycle.push_back(st.back());
					st.pop_back();
				}
				cycle.push_back(pos);
				int csize = cycle.size() - 1;
				vector<int> np = p;
				for (int j = 0; j < csize; j++) {
					np[cycle[j + 1]] = p[cycle[j]];
					vlist.push_back(cycle[j]);
				}
				p = np;
				for (int j = 0; j < csize; j++) {
					for (int k = 0; k < N; k++) {
						envy[cycle[j]][k] = (s[p[j]][j] < s[p[j]][k]);
					}
				}
			} else {
				path[pos] = true;
				st.push_back(pos);
			}
		}
		A[i] = pos;
		for (int j = 0; j < N; j++) {
			s[j][pos] += V[j][i];
		}
	}

	// step #3. final answer
	vector<int> B(M);
	for (int i = 0; i < M; i++) {
		B[i] = p[A[i]];
	}

	return B;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int N, M;
	cin >> N >> M;
	vector<vector<int> > V(N, vector<int>(M));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> V[i][j];
		}
	}
	vector<int> ans = solve(N, M, V);
	for (int i = 0; i < M; i++) {
		if (i != 0) {
			cout << ' ';
		}
		cout << ans[i] + 1;
	}
	cout << endl;
	return 0;
}
accuracy: 0.5793650793650794
time_ms: 70
memory_kb: 5552
final_rank: 4

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

vector<int> solve(int N, int M, const vector<vector<int> >& V) {
	// step #1. initialization
	vector<int> A(M, -1);
	for (int i = 0; i < min(N, M); i++) {
		A[i] = i;
	}
	if (N >= M) {
		return A;
	}

	// step #2. envy-cycle elimination
	vector<int> p(N), last(N);
	vector<vector<long long> > s(N, vector<long long>(N));
	for (int i = 0; i < N; i++) {
		p[i] = i;
		last[i] = i;
		for (int j = 0; j < N; j++) {
			s[j][i] = V[j][i];
		}
	}
	for (int i = N; i < M; i++) {
		vector<vector<bool> > envy(N, vector<bool>(N, false));
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				envy[k][j] = (s[p[j]][j] < s[p[j]][k]);
			}
		}
		vector<int> cur(N);
		vector<int> st;
		vector<bool> path(N, false);
		int pos = 0;
		path[pos] = true;
		st.push_back(pos);
		while (true) {
			while (cur[pos] != N && !envy[pos][cur[pos]]) {
				cur[pos]++;
			}
			if (cur[pos] == N) {
				break;
			}
			pos = cur[pos]++;
			if (path[pos]) {
				vector<int> cycle = { pos };
				while (st.back() != pos) {
					path[st.back()] = false;
					cycle.push_back(st.back());
					st.pop_back();
				}
				cycle.push_back(pos);
				vector<int> np = p;
				for (int j = 0; j < int(cycle.size()) - 1; j++) {
					np[cycle[j + 1]] = p[cycle[j]];
				}
				p = np;
			} else {
				path[pos] = true;
				st.push_back(pos);
			}
		}
		A[i] = pos;
		for (int j = 0; j < N; j++) {
			s[j][pos] += V[j][i];
		}
	}

	// step #3. final answer
	vector<int> B(M);
	for (int i = 0; i < M; i++) {
		B[i] = p[A[i]];
	}

	return B;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int N, M;
	cin >> N >> M;
	vector<vector<int> > V(N, vector<int>(M));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> V[i][j];
		}
	}
	vector<int> ans = solve(N, M, V);
	for (int i = 0; i < M; i++) {
		if (i != 0) {
			cout << ' ';
		}
		cout << ans[i] + 1;
	}
	cout << endl;
	return 0;
}
accuracy: 0.031746031746031744
time_ms: 60
memory_kb: 4776
final_rank: 5

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

vector<int> solve(int N, int M, const vector<vector<int> >& V) {
	// step #1. initialization
	vector<int> A(M, -1);
	for (int i = 0; i < min(N, M); i++) {
		A[i] = i;
	}
	if (N >= M) {
		return A;
	}

	// step #2. envy-cycle elimination
	vector<int> p(N), last(N);
	vector<vector<long long> > s(N, vector<long long>(N));
	for (int i = 0; i < N; i++) {
		p[i] = i;
		last[i] = i;
		for (int j = 0; j < N; j++) {
			s[j][i] = V[j][i];
		}
	}
	for (int i = N; i < M; i++) {
		vector<vector<bool> > envy(N, vector<bool>(N, false));
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				envy[j][k] = (s[p[k]][k] < s[p[k]][j]);
			}
		}
		vector<int> cur(N);
		vector<int> st;
		vector<bool> path(N, false);
		int pos = 0;
		path[pos] = true;
		st.push_back(pos);
		while (true) {
			while (cur[pos] != N && !envy[pos][cur[pos]]) {
				cur[pos]++;
			}
			if (cur[pos] == N) {
				break;
			}
			pos = cur[pos];
			if (path[pos]) {
				vector<int> cycle = { pos };
				while (st.back() != pos) {
					path[st.back()] = false;
					cycle.push_back(st.back());
					st.pop_back();
				}
				cycle.push_back(pos);
				vector<int> np = p;
				for (int j = 0; j < int(cycle.size()) - 1; j++) {
					np[cycle[j + 1]] = p[cycle[j]];
				}
				p = np;
			} else {
				path[pos] = true;
				st.push_back(pos);
			}
			cur[pos]++;
		}
		A[i] = pos;
		for (int j = 0; j < N; j++) {
			s[j][pos] += V[j][i];
		}
	}

	// step #3. final answer
	vector<int> B(M);
	for (int i = 0; i < M; i++) {
		B[i] = p[A[i]];
	}

	return B;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int N, M;
	cin >> N >> M;
	vector<vector<int> > V(N, vector<int>(M));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> V[i][j];
		}
	}
	vector<int> ans = solve(N, M, V);
	for (int i = 0; i < M; i++) {
		if (i != 0) {
			cout << ' ';
		}
		cout << ans[i] + 1;
	}
	cout << endl;
	return 0;
}
accuracy: 0.031746031746031744
time_ms: 90
memory_kb: 4692
final_rank: 6

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

vector<int> solve(int N, int M, const vector<vector<int> >& V) {
	// step #1. initialization
	vector<int> A(M, -1);
	for (int i = 0; i < min(N, M); i++) {
		A[i] = i;
	}
	if (N >= M) {
		return A;
	}

	// step #2. envy-cycle elimination
	vector<int> p(N), last(N);
	vector<vector<long long> > s(N, vector<long long>(N));
	for (int i = 0; i < N; i++) {
		p[i] = i;
		last[i] = i;
		for (int j = 0; j < N; j++) {
			s[j][i] = V[j][i];
		}
	}
	for (int i = N; i < M; i++) {
		vector<vector<bool> > envy(N, vector<bool>(N, false));
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				envy[j][k] = (s[p[k]][k] < s[p[k]][j]);
			}
		}
		vector<int> cur(N);
		vector<int> st;
		vector<bool> path(N, false);
		int pos = 0;
		path[pos] = true;
		st.push_back(pos);
		while (true) {
			while (cur[pos] != N && !envy[pos][cur[pos]]) {
				cur[pos]++;
			}
			if (cur[pos] == N) {
				break;
			}
			pos = cur[pos];
			if (path[pos]) {
				vector<int> cycle = { pos };
				while (st.back() != pos) {
					path[st.back()] = false;
					cycle.push_back(st.back());
					st.pop_back();
				}
				cycle.push_back(pos);
				vector<int> np = p;
				for (int j = 0; j < int(cycle.size()) - 1; j++) {
					np[cycle[j]] = p[cycle[j + 1]];
				}
				p = np;
			} else {
				path[pos] = true;
				st.push_back(pos);
			}
			cur[pos]++;
		}
		A[i] = pos;
		for (int j = 0; j < N; j++) {
			s[j][pos] += V[j][i];
		}
	}

	// step #3. final answer
	vector<int> B(M);
	for (int i = 0; i < M; i++) {
		B[i] = p[A[i]];
	}

	return B;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int N, M;
	cin >> N >> M;
	vector<vector<int> > V(N, vector<int>(M));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> V[i][j];
		}
	}
	vector<int> ans = solve(N, M, V);
	for (int i = 0; i < M; i++) {
		if (i != 0) {
			cout << ' ';
		}
		cout << ans[i] + 1;
	}
	cout << endl;
	return 0;
}
accuracy: 0.015873015873015872
time_ms: 90
memory_kb: 4672
final_rank: 7

code_snippet: #ifndef LOCAL
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#endif

#include <bits/stdc++.h>
using namespace std;

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> bool chmax(t&a,u b){if(a<b){a=b;return true;}else return false;}
template<class t,class u> bool chmin(t&a,u b){if(b<a){a=b;return true;}else return false;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

pi readpi(int off=0){
	int a,b;cin>>a>>b;
	return pi(a+off,b+off);
}

template<class t,class u>
void print(const pair<t,u>&p,int suc=1){
	print(p.a,2);
	print(p.b,suc);
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

template<class T>
void print_offset(const vector<T>&v,ll off,int suc=1){
	rep(i,v.size())
		print(v[i]+off,i==int(v.size())-1?suc:2);
}

template<class T,size_t N>
void print(const array<T,N>&v,int suc=1){
	rep(i,N)
		print(v[i],i==int(N)-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
ll mask(int i){
	return (ll(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
	static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
void myshuffle(vc<t>&a){
	rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

vvc<int> readGraph(int n,int m){
	vvc<int> g(n);
	rep(i,m){
		int a,b;
		cin>>a>>b;
		//sc.read(a,b);
		a--;b--;
		g[a].pb(b);
		g[b].pb(a);
	}
	return g;
}

vvc<int> readTree(int n){
	return readGraph(n,n-1);
}

void slv(){
	int n,m;cin>>n>>m;
	if(n>=m){
		vi ans(m);iota(all(ans),1);
		print(ans);
		return;
	}
	vvc<int> vs(n);
	rep(i,n)vs[i]=readvi(m);
	vvc<int> ls(n);
	vvc<int> w(n,vi(n));
	vi mt(n);iota(all(mt),0);
	vi buf;
	vi vis(n);
	int curtime=0;
	rep(step,m){
		dmp(step);
		while(1){
			dmp(mt);
			dmp(ls);
			dmp(w);
			curtime++;
			int v=rand_int(0,n-1);
			buf.clear();
			bool term=false;
			while(vis[v]<curtime){
				vis[v]=curtime;
				buf.pb(v);
				bool f=false;
				rep(nx,n){
					if(w[v][mt[nx]]>w[nx][mt[nx]]){
						v=nx;
						f=true;
						break;
					}
				}
				if(!f){
					term=true;
					break;
				}
			}
			if(!term){
				int pre=mt[v];
				while(1){
					int z=buf.back();buf.pop_back();
					swap(mt[z],pre);
					if(z==v)break;
				}
				continue;
			}else{
				ls[v].pb(step);
				rep(i,n)w[v][i]+=vs[i][step];
				break;
			}
		}
	}
	vi ans(m);
	rep(i,n)for(auto j:ls[i])ans[j]=mt[i];
	print_offset(ans,1);
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	
	//int t;cin>>t;rep(_,t)
	slv();
}
accuracy: 1
time_ms: 20
memory_kb: 7816
final_rank: 1