#pragma GCC optimize("Ofast", "unroll-loops")

// #define PRINT_PROGRESS // 提出時コメントアウト
// #define TEST_WITH_RANDOMCASE // 提出時コメントアウト
#define SHOW_RESULT // 提出時有効に

#include <bits/stdc++.h>

using namespace std;

#define K (26) // コンテストの種類

int D;
vector<int> c(K);
vector<vector<int>> s;

/* コンテストのタイプおよび日付は0-indexedで数える */

void input(void){
	cin >> D;
	for (auto& ci : c)
		cin >> ci;
	s.resize(D, vector<int>(K));
	for (int i = 0; i < D; ++i)
		for (auto& sij : s[i])
			cin >> sij;
}

void random_input(void){
	D = 365;
	for (auto& ci : c)
		ci = rand() % 101;
	s.resize(D, vector<int>(K));
	for (int i = 0; i < D; ++i)
		for (auto& sij : s[i])
			sij = rand() % 200001;
}

vector<int> t; // 暫定解
vector<set<int>> c_day(K); // c_day[i] : コンテストiが開催される日程
int score; // 暫定解のスコア

int calc_score(void){
	vector<int> lst_held(K, -1);
	int score = 0;
	for (int i = 0; i < D; ++i){
		score += s[i][t[i]];
		lst_held[t[i]] = i;
		for (int c_id = 0; c_id < K; ++c_id){
			score -= c[c_id] * (i - lst_held[c_id]);
		}
	}
	return score;
}

void init_t(void){
	t.resize(D);
#ifdef PRINT_PROGRESS
	cout << "    MAKING INITIAL SOLUTION..." << endl;
#endif
	//　初期解の生成
	// edit from here
	for (int i = 0; i < D; ++i){
		static int priority[K];
		for (int c_id = 0; c_id < K; ++c_id)
			priority[c_id] = s[i][c_id];
		/* for (int c_id = 0; c_id < K; ++c_id){
			for (int j = 0; j < K; ++j)
				if (c_id != j)
					priority[j] -= c[c_id];
		} */
		int mx = -(1 << 30), mx_id = -1;
		for (int c_id = 0; c_id < K; ++c_id)
			if (mx < priority[c_id])
				mx = priority[c_id], mx_id = c_id;
		t[i] = mx_id;
	}
	// edit end
#ifdef PRINT_PROGRESS
	cout << "    INITIAL SOLUTION : DONE." << endl;
#endif

	for (int c_id = 0; c_id < K; ++c_id)
		c_day[c_id].insert(-1);
	for (int i = 0; i < D; ++i)
		c_day[t[i]].insert(i);
	for (int c_id = 0; c_id < K; ++c_id)
		c_day[c_id].insert(D);

#ifdef PRINT_PROGRESS
	cout << "    INITIALIZE c_day : DONE." << endl;
#endif

	score = calc_score();
}

void print_t(void){
	for (auto ti : t)
		cout << (ti + 1) << endl;
}

// そのupdateによるgainが正なら実際にupdateし、updateしたかを返す
bool gain_update(int d, int c_id){
	int res = 0;
	// 消す処理
	int del_c = t[d];
	auto iter1 = c_day[del_c].lower_bound(d);
	int prv = *(--iter1); ++iter1;
	int nx = *(++iter1); --iter1;
	res -= s[d][del_c];
	res -= c[del_c] * (d - prv) * (nx - d);
	// 増やす処理
	auto iter2 = c_day[c_id].lower_bound(d);
	nx = *iter2;
	--iter2;
	prv = *iter2;
	res += c[c_id] * (d - prv) * (nx - d);
	res += s[d][c_id];
	if (res > 0 || (res > -1000 && rand() % 100 == 0)){
		c_day[del_c].erase(iter1);
		c_day[c_id].insert(d);
		t[d] = c_id;
		score += res;
		return true;
	}
	return false;
}

bool random_update(void){
	int change_dat = rand() % D;
	int change_to = rand() % K;
	return gain_update(change_dat, change_to);
}

int main(void){
	chrono::system_clock::time_point start, now;
	start = chrono::system_clock::now();

#ifdef PRINT_PROGRESS
	cout << "INPUT : START." << endl;
#endif
#ifdef TEST_WITH_RANDOMCASE
	random_input();
#else
	input();
#endif
#ifdef PRINT_PROGRESS
	cout << "INPUT : DONE." << endl;
	cout << "INITIALIZE : START." << endl;
#endif
	init_t();
#ifdef PRINT_PROGRESS
	cout << "INITIALIZE : DONE." << endl;
	cout << "INITIAL SCORE : " << score << endl;
#endif
	
	int loop = 0;
	int updated = 0;

	while (1){
		if (random_update()) ++updated;
		++loop;
		now = chrono::system_clock::now();
		double time = 
			static_cast<double>(chrono::duration_cast<chrono::microseconds>(now - start).count() / 1000.0);
		if (time > 1950) break;
	}

#ifdef PRINT_PROGRESS
	cout << "LOOP : " << loop << endl;
	cout << "UPDATED " << updated << " TIMES." << endl;
	cout << "FINAL SCORE : " << score << endl;
#endif

#ifdef SHOW_RESULT
	print_t();
#endif

	return 0;
}

Measured memory_bytes: 3704