#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <numeric>
#include <queue>
#include <stack>
#include <map> 
#include <set>
#include <string>
#include <functional>
#include <list>
#include <random>
#include <time.h>
#include <iomanip>
#include <assert.h>
#include <numeric>
#include <new>
#include <sstream>
#include <complex>
#include <ctime>
#define BIT(nr) (1ULL << (nr))
//#define int long long
#define ll long long
#define double complex<long double>
#define mod 1000000007
#define MAXN (int)1e+5 * 2+1
#define LL_MAX 9223372036854775807	
#define LL_HALFMAX 9223372036854775807 / 2	
#define MIN -(9223372036854775807 / 2)
#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
#define ALLOF(c) (c).begin(), (c).end()
#define REPS(i,x) for(int i=1;i<=(int)(x);i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RREPS(i,x) for(int i=((int)(x));i>0;i--)
#define repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define mp make_pair
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }

using namespace std;

namespace mmlib {

	template <typename T1, typename T2>
	struct Pair {
		Pair() {}
		Pair(const Pair&) = default;
		Pair(Pair&&) = default;
		Pair& operator=(const Pair&) = default;
		Pair(const T1& f, const T2& s) : first(f), second(s) {}
		Pair(T1&& f, T2&& s) : first(f), second(s) {}

		T1 first;
		T2 second;
	};

	template <typename T, unsigned int N>
	class Vector {
	public:
		template <class Itr>
		void assign(Itr first, Itr last) {
			size_ = 0;
			while (first != last) {
				assert(size_ < N);
				m_[size_++] = *first++;
			}
		}

		void assign(size_t n, const T& v) {
			assert(n < N);
			size_ = n;
			while (n--) m_[n] = v;
		}

		void assign(std::initializer_list<T> il) { assign(il.begin(), il.end()); }

		void resize(size_t n) {
			assert(0 <= n);
			assert(n < N);
			size_ = n;
		}

		T* begin() { return m_.begin(); };
		const T* begin() const { return m_.begin(); };

		T* end() { return m_.begin() + size_; };
		const T* end() const { return m_.begin() + size_; };

		void clear() { size_ = 0; };

		size_t size() const { return size_; };

		void push_back(const T& v) {
			assert(size_ < N);
			m_[size_++] = v;
		}

		void pop_back() {
			assert(size_ != 0);
			size_--;
		}

		T& front() {
			assert(0 < size_);
			return *m_.begin();
		}

		const T& front() const {
			assert(0 < size_);
			return *m_.begin();
		}

		T& back() {
			assert(0 < size_);
			return *(m_.begin() + size_ - 1);
		}

		const T& back() const {
			assert(0 < size_);
			return *(m_.begin() + size_ - 1);
		}

		T& operator[](size_t pos) {
			assert(pos < size_);
			return m_[pos];
		}

		const T& operator[](size_t pos) const {
			assert(pos < size_);
			return m_[pos];
		}

	private:
		std::array<T, N> m_;
		uint32_t size_ = 0;
	};

	template <typename T, int N, class Compare = std::less<T> >
	class Ranking {
	public:
		void on_rankout(std::function<void(const T&)> op) { on_pop_min_ = op; }

		bool is_rankin(const T& value) {
			return m_.size() < N ? true : Compare()(min_element(), value);
		}

		void push(const T& value) {
			m_.insert(value);
			if (size() == N) {
				on_pop_min_(min_element());
				pop_min();
			}
		}

		T min_element() {
			assert(!empty());
			return *m_.begin();
		}

		const T& min_element() const {
			assert(!empty());
			return *m_.begin();
		}

		T max_element() {
			assert(!empty());
			return *m_.rbegin();
		}

		const T& max_element() const {
			assert(!empty());
			return *m_.rbegin();
		}

		void pop_min() {
			//assert(!empty());
			//Work Around: g++ -pthread -DNDEBUG -march=haswell -std=c++14 ./main.cpp -O2  build breaks Search Result
			if (empty()) {
				std::cerr << "Something Wrong." << std::endl;
			}
			m_.erase(m_.begin());
		}

		void pop_max() {
			assert(!empty());
			m_.erase(--m_.end());
		}

		bool empty() const { return m_.empty(); }

		size_t size() const { return m_.size(); }

		void clear() { m_.clear(); }

		const std::multiset<T>& data() const { return m_; }

	private:
		std::multiset<T> m_;
		std::function<void(const T&)> on_pop_min_;
	};


}  // namespace mmlib

// 1-indexed にする
const int TYPES = 26;

class Node {
public:
	int64_t score;
	// contests[i]: i日目に行われたコンテスト 1-indexed
	vector<uint8_t> contests;
	// last[i]: コンテストi が最後に行われた日 1-indexed
	vector<uint16_t> last;

	Node() :
		contests(1, 0),
		last(27, 0),
		score(0)
	{}

	// contestId を末尾に追加した時のスコアを計算する
	int chal(const vector<int>& c, const vector<vector<int>> s, uint8_t contestId) {
		int day = contests.size();
		int add = s[day][contestId];
		int beforeLast = last[contestId];
		last[contestId] = day;

		int sub = 0;
		REPS(i, TYPES) {
			sub += c[i] * (day - last[i]);
		}

		last[contestId] = beforeLast;
		return score + add - sub + score;
	}

	// contestId を末尾に追加する
	int add(const vector<int>& c, const vector<vector<int>> s, uint8_t contestId) {
		int day = contests.size();
		int add = s[day][contestId];
		last[contestId] = day;

		int sub = 0;
		REPS(i, TYPES) {
			sub += c[i] * (day - last[i]);
		}

		int newscore = score + add - sub;
		score += newscore;
		contests.push_back(contestId);
		return score;
	}

	bool operator<(const Node& right) const {
		return score < right.score;
	}
};

// 変数名は問題Aに準ずる、 t はコンテストの開催計画を表す
int CalcScore(const int& D, const vector<int>& c, const vector<vector<int>> s, const vector<int>& t, vector<int>* pOutResult) {
	assert(t.size() == pOutResult->size());

	int score = 0;
	vector<int> lastDay(TYPES + 1, 0);

	REPS(d, D) {
		int add = s[d][t[d]];
		lastDay[t[d]] = d;
		int sub = 0;

		REPS(i, TYPES) {
			sub += c[i] * (d - lastDay[i]);
		}
		score += add;
		score -= sub;
		pOutResult->at(d) = score;
	}

	return score;
}

Node ChokudaiSearch(const int& D, const vector<int>& c, const vector<vector<int>> s)
{
	const int BeamWidth = 10;
	const int BeamDepth = D + 1;
	const int loopCnt = 1;
	Node tmpNode;

	mmlib::Ranking<Node, BeamWidth> chokudaiData[366];
	rep(i, 366) {
		chokudaiData[i].on_rankout([](Node n) {});
	}

	chokudaiData[0].push(Node());

	int startTime = clock();
	while (clock() - startTime < 170 * CLOCKS_PER_SEC / 100) {
	//rep(dum2, 100){
		// 1回の時間計測に対し loopcnt 回ループをまわす
		rep(dumm, loopCnt) {
			rep(i, 366) {
				// 最終日が終わってたらbreak
				if (i == D) {
					break;
				}
				auto &prev = chokudaiData[i];
				auto &next = chokudaiData[i + 1];

				if (prev.empty()) continue;

				// 最高のノードをとってくる
				auto node = prev.max_element();
				prev.pop_max();

				// 全コンテストをためす
				REPS(contestId, TYPES) {
					int chalScore = node.chal(c, s, contestId);
					tmpNode.score = chalScore;
					if (next.is_rankin(tmpNode)) {
						tmpNode = node;
						tmpNode.add(c, s, contestId);
						next.push(tmpNode);
					}
				}
			}
		}
	}

	return chokudaiData[D].max_element();

}



signed main() {

	int D;
	cin >> D;

	vector<int> c(TYPES + 1, 0);
	vector<vector<int>> s(D + 1, vector<int>(TYPES + 1, 0));

	REPS(i, TYPES) {
		cin >> c[i];
	}

	REPS(i, D) {
		REPS(j, TYPES) {
			cin >> s[i][j];
		}
	}

	// Dにちめまで chokudai サーチをする
	auto res = ChokudaiSearch(D, c, s);

	REPS(i, D) {
		cout << (int)res.contests[i] << "\n";
	}

	return 0;
}

Measured memory_bytes: 4912