/*
    IHC011: Simulated Annealing, SA

    山登り法2(112,357,759)、山登り法1(79,318,139)、貪欲法2(104,195,466)、貪欲法1(62,634,806) の続き

	IHC013: minimum cost circulation

*/
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(n);++i)
#define ALL(A) A.begin(), A.end()
#define SUBMIT 1

using namespace std;

typedef long long ll;
typedef pair<ll, int> P;

#if !SUBMIT
const double TIME_LIMIT = 2.10 * 2.0;
const int64_t CYCLES_PER_SEC = 2000000000;	// for Local
//const int64_t CYCLES_PER_SEC = 2400000000;	// for server
#else
const double TIME_LIMIT = 2.10;
const int64_t CYCLES_PER_SEC = 2800000000;	// for SUBMIT
#endif

unsigned Rand(){ 
	static unsigned x=123456789;
	static unsigned y=362436069;
	static unsigned z=521288629;
	static unsigned w=88675123; 
	unsigned t=x^(x<<11);
	x=y; y=z; z=w;

	return w=(w^(w>>19))^(t^(t>>8));
}

struct Timer {
	int64_t start;
	int counter;
	double t;

	Timer() {
		reset();
	}

	void plus(double a){
		start -= a * CYCLES_PER_SEC;
	}

	int64_t getCycle() {
		uint32_t low, high;
		__asm__ volatile ("rdtsc" : "=a" (low), "=d" (high));
		return ((int64_t)low) | ((int64_t)high << 32);
	}

	void reset(){
		counter = 0;
		start = getCycle();
		t = 0.0;
	}

	double get(){
		return t = (double)(getCycle() - start) / CYCLES_PER_SEC;
	}
};
const int MAX_V = 400;

struct edge{
	int to;
	ll cap;
	ll init;
	ll cost;
	int rev;
};

class Graph{
public:
	vector<vector<edge>> es;
	vector<ll> ex;
	vector<ll> p;
	vector<int> iter;

	Graph(int n){
		es.clear(); es.resize(n, vector<edge>());
		ex.clear(); ex.resize(n, 0LL);
		p.clear(); p.resize(n, 0LL);
		iter.clear(); iter.resize(n, 0);
	}

	~Graph(){
		es.clear();
		ex.clear();
		p.clear();
		iter.clear();
	}

	void add(int v, int to, ll cap, ll cost){
		int fwd = (int)es[v].size();
		int rev = (int)es[to].size();
		es[v].push_back((edge){to, cap, cap, cost, rev});
		es[to].push_back((edge){v, 0LL, 0LL, -cost, fwd});
	}

	bool is_admissible(int v, edge e){
		return e.cap > 0LL && e.cost + p[v] - p[e.to] < 0LL;
	}

	bool solve(void){
		int n = (int)es.size();
		ll eps = 0LL;
		rep (v, n){
			rep (i, (int)es[v].size()){
				edge& e = es[v][i];
				e.cost *= (ll)n;
				if (eps < e.cost){
					eps = e.cost;
				} // end if
			} // end rep
		} // end rep

		stack<int> st;
		bool visit[n] = {false};
		bool ok = true;
		rep (i, (int)ex.size()){
			ok &= (ex[i] == 0LL);
		} // end rep

		bool refine = true;
		while(refine){
			eps = max(eps / 8LL, 1LL);
			if (ok && fitting()){
				break;
			} // end if

			rep (v, n){
				for (int i = 0; i < (int)es[v].size(); i++){
					edge& e = es[v][i];
					if (is_admissible(v, e)){
						ex[e.to] += e.cap;
						ex[v] -= e.cap;
						es[e.to][e.rev].cap += e.cap;
						es[v][i].cap = 0LL;
					} // end if
				} // end for
			} // end rep

			for(;;){
				rep (v, n){
					iter[v] = 0;
					if (ex[v] > 0LL){
						visit[v] = true;
						st.push(v);
					}else{
						visit[v] = false;
					} // end if
				} // end rep
				
				if (st.empty()){
					break;
				} // end if

				while (!st.empty()){
					int v = st.top(); st.pop();
					rep (i, (int)es[v].size()){
						edge& e = es[v][i];
						if (!visit[e.to] && is_admissible(v,e)){
							visit[e.to] = true;
							st.push(e.to);
						} // end if
					} // end rep
				} // end while

				bool ok1 = true;
				rep (i, n){
					if (visit[i]){
						rep (j, (int)es[i].size()){
							edge& e = es[i][j];
							ok1 &= (e.cap <= 0LL || visit[e.to]);
						} // end rep
					} // end if
				} // end rep

				if (ok1){
					refine = false;
					break;
				} // end if

				rep (i, n){
					if (visit[i]){
						p[i] -= eps;
					} // end if
				} // end rep

				rep (v, n){
					while (ex[v] > 0LL){
						ll f = dfs(v, ex[v]);
						if (f == 0LL){
							break;
						}else{
							ex[v] -= f;
						} // end if
					} // end while
				} // end rep
			} // end for
			ok = true;
		} // end while

		rep (v, (int)es.size()){
			rep (i, (int)es[v].size()){
				edge& e = es[v][i];
				e.cost /= n;
			} // end rep
		} // end rep
		
		return ok;
	}
	
	ll dfs(int v, ll f){
		if (ex[v] < 0LL){
			ll d = min(f, -ex[v]);	
			ex[v] += d;
			return d;
		} // end if

		while(iter[v] < (int)es[v].size()){
			edge& e = es[v][iter[v]];
			if (is_admissible(v,e)){
				ll d = dfs(e.to, min(f, e.cap));
				if (d > 0LL){
					es[v][iter[v]].cap -= d;
					es[e.to][e.rev].cap += d;
					return d;
				} // end if
			} // end if
			iter[v] += 1;
		} // end while
		return 0;
	}

	bool fitting(void){
		int n = (int)es.size();
		vector<ll> d(n, 0LL);
		rep (i, n){
			d[i] = p[i] / n;
		} // end rep
		vector<int> d2(n, 0LL);
		rep (v, n){
			d2[v] = (d[v] * (ll)n - p[v] + 1LL);
		} // end rep
		bool fixed[n] = {false};
		
		priority_queue<P, vector<P> > que;
		rep (v, n){
			que.push(P(-d2[v],v));
		} // end rep

		while(!que.empty()){
			P some = que.top(); que.pop();
			int v = some.second;
			if (fixed[v]) continue;
			rep (i, (int)es[v].size()){
				edge& e = es[v][i];
				if (e.cap > 0){
					int tmp = d2[v] + e.cost + p[v] - p[e.to] + 1;
					d2[e.to] = min(d2[e.to], tmp);
					if (fixed[e.to]){
						return false;
					} // end if
					d[e.to] = d[v] + e.cost / n;
					que.push(P(-d2[e.to], e.to));
				} // end if
			} // end rep
		} // end while
		p = d;
		return true;
	}

	int val(void){
		int tot = 0;
		rep (v, (int)es.size()){
			rep (i, (int)es[v].size()){
				edge& e = es[v][i];
				if (e.cap < e.init){
					tot += (e.init - e.cap) * e.cost;
				} // end if
			} // end rep
		} // end rep
		return tot;
	}
};


class IHC{
public:
	vector<int> solve(int _D, vector<int> _c, vector<vector<int>> _s){
		init(_D,_c,_s);

		out = geneRes();
		int score = calcScore(out);
		bestScore = score;

		improve_flow();

/*
        int iter = 0;
        int restore = 0;

		double T0 = 2e3;
		double T1 = 6e2;
		double TL = TIME_LIMIT;

		double T = T0;
//		while((currentTime = timer.get()) < TIME_LIMIT){
		while(1){
			iter++;
			if (iter % 100 == 0){
				double t = timer.get() / TL;
				if (t >= 1.0){
					break;
				} // end if
				T = pow(T0, 1.0 - t) * pow(T1, t);
			} // end if

            int r = Rand() % 2;
            if (r == 0){ // 1-point change
                int day = (Rand() % D) + 1;
                int post = Rand() % 26;
				if (c[post] == 0) continue;
                int prev = out[day];
                int diff = diffScore(day, post);
                score += diff;
                if (accept((double)diff,T)){
#if DEBUG1
                    cerr << "currentTime: " << timer.get() << " score: " << score << endl;
#endif
                    bestScore = score;
			    }else{ // restore
                    score -= diff;
                    out[day] = prev;
                    st[post].erase(day);
                    st[prev].insert(day);
                    restore++;
			    } // end if
            }else{ // 2-points swap
                int d1 = (Rand() % (D-2)) + 1;
                int d2 = min(D, d1 + (int)(Rand() % 16));
                int prev1 = out[d1];
                int prev2 = out[d2];
				if (c[prev1] == 0 || c[prev2] == 0) continue;
                int diff1 = diffScore(d1, prev2);
                int diff2 = diffScore(d2, prev1);
                score += diff1 + diff2;
                if (accept((double)(diff1 + diff2),T)){
#if DEBUG1
                    cerr << "currentTime: " << timer.get() << " score: " << score << endl;
#endif
                    bestScore = score;
                }else{ // restore
                    score -= diff1 + diff2;
                    out[d1] = prev1;
                    out[d2] = prev2;
                    st[prev2].erase(d1);
                    st[prev1].insert(d1);
                    st[prev1].erase(d2);
                    st[prev2].insert(d2);                  
                } // end if
            } // end if
		} // end while
		cerr << "iter: " << iter << " ratio: " << (double)restore / (double)iter * 100.0 << " bestScore: " << bestScore << endl;
*/
		return makeSolution(out);
	}
		
private:

	Timer timer;
	double startTime;
	double endTime;
	double currentTime;

	int D;
	vector<int> c;
	vector<vector<int>> s;
	vector<int> out;

	vector<int> last;
	set<int> st[26];
	vector<int> sat;

	int bestScore;

    double Log[32768];

	void improve_flow(void){
		int cnt = 0;
		while((currentTime = timer.get()) < 0.4){
			cnt += 1;
			vector<vector<int>> ps(26, vector<int>());
			vector<int> idx(D, 0);
			rep (d, D){
				idx[d] = (int)ps[out[d]].size();
				ps[out[d]].push_back(d);
			} // end rep
			
			bool del[D] = {false};
			vector<int> tmp(D, 0);
			rep (i, D){
				tmp[i] = i;
			} // end rep
			random_shuffle(ALL(tmp));

			rep (i, D){
				int c = tmp[i];
				rep (a, 20){
					for (int d = c - a; d < c + a; ++d){
						if (d >= D || d < 0 || del[d] || (idx[d] > 0 && del[ps[out[d]][idx[d] - 1]]) || (idx[d] + 1 < (int)ps[out[d]].size() && del[ps[out[d]][idx[d] + 1]])){
							continue;
						} // end if
						del[d] = true;
					} // end for
				} // end rep
			} // end rep

			vector<int> vs; vs.clear();
			vector<int> vid(D, -1);
			rep (d, D){
				if (del[d]){
					vid[d] = (int)vs.size();
					vs.push_back(d);
				} // end if
			} // end rep

			Graph g((int)vs.size() * 2 + 27);
			rep (v, (int)vs.size()){
				int i = out[vs[v]];
				g.ex[v] = 1LL;
				g.ex[(int)vs.size() + v] = -1LL;
				int d = vs[v];
				int prev = (idx[d] - 1 >= 0 ? ps[out[d]][idx[d] - 1] : 0);
				int next = (idx[d] + 1 < (int)ps[out[d]].size() ? ps[out[d]][idx[d] + 1] : D);
				for (int d = prev + 1; d < next; d++){
					if (vid[d] != 0){
						g.add(v, (int)vs.size() + vid[d], 1, (cost(prev, d) + cost(d, next)) * c[i] - s[d][i]);
					} // end if
				} // end for
				g.add(v, (int)vs.size() * 2 + 26, 1, cost(prev, next) * c[i]);
				rep (j, 26){
					int p = -1;
					rep (k, (int)ps[j].size()){
						int a = ps[j][k];
						if (a >= d){
							p = k;
						} // end if
					} // end rep
					if (p < 0 || (p < (int)ps[j].size() && del[ps[j][p]])){
						continue;
					} // end if
					if (p - 1 < 0 || (p - 1 < (int)ps[j].size() && del[ps[j][p-1]])){
						continue;
					} // end if

					int prev = (p - 1 >= 0 ? ps[j][p-1] : 0);
					int next = (p < D ? ps[j][p] : D);
					g.add((int)vs.size() * 2 + j, (int)vs.size() + v, 1LL, (cost(prev,d) + cost(d,next) - cost(prev, next)) * c[j] - s[d][j]);
				} // end rep
			} // end rep

			rep (i, 26){
				g.ex[(int)vs.size() * 2 + i] = 1;
				g.add((int)vs.size() * 2 + i, (int)vs.size() * 2 + 26, 1, 0);
			} // end rep

			g.ex[(int)vs.size() * 2 + 26] = -26LL;
			g.solve();

			vector<int> out_old = out;
			rep (v, (int)vs.size()){
				rep (i, (int)g.es[v].size()){
					edge& e = g.es[v][i];
					if (e.cap < e.init && e.to < (int)vs.size() * 2){
						out[vs[e.to - (int)vs.size()]] = out_old[vs[v]];
					} // end if
				} // end rep
			} // end rep

			rep (i, 26){
				rep (j, (int)g.es[(int)vs.size() * 2 + i].size()){
					edge& e = g.es[(int)vs.size() * 2 + i][j];
					if (e.cap < e.init && e.to < (int)vs.size() * 2){
						out[vs[e.to - (int)vs.size()]] = i;
					} // end if
				} // end rep
			} // end rep
		} // end while
	}


	int compute_score(void){
		int score = (int)1e6;
		vector<int> last(26, 0);
		rep (d, D){
			last[out[d]] = d + 1;
			rep (i, 26){
				score -= (d + 1 - last[i]) * c[i];
			} // end rep
			score += s[d][out[d]];
		} // end rep
		return score;
	}

	int cost(int a, int b){
		int d = b - a;
		return (d * (d - 1) / 2);
	}


    bool accept(double deltaScore, double T){
        if (deltaScore > -1e-9){
            return true;
        } //end if

        assert(deltaScore < 0.0);
        assert(T >= 0.0);

        double t = deltaScore / T;

        if (t < -5.0){
            return false;
        } // end if

        if (Log[Rand() & 32767] < t){
            return true;
        } // end if

        return false;
    }

	int diffScore(int day, int post){
		int prev = out[day];
		st[prev].erase(day);

		auto itrp = st[prev].lower_bound(day);
		auto itrq = st[post].lower_bound(day);
		int rp = *itrp, rq = *itrq;
		itrp--;
		itrq--;
		int lp = *itrp, lq = *itrq;

		int diff = s[day-1][post] - s[day-1][prev];
		diff -= (day - lp) * (rp - day) * c[prev];
		diff += (day - lq) * (rq - day) * c[post];

        out[day] = post;
        st[post].insert(day);

		return diff;
	}

	int calcScore(vector<int> out){
		for (int d = 1; d <= D; d++){
			st[out[d]].insert(d);
			sat[d] = sat[d-1] + s[d-1][out[d]];
			last[out[d]] = d;
			rep (j, 26){
				sat[d] -= (d - last[j]) * c[j];
        	} // end rep
    	} // end for
        int res = sat[D];
//        cerr << "score: " << res << endl;
		return res;
	}

	vector<int> makeSolution(vector<int> out){
		vector<int> ret(D, 0);
		rep (i, D){
			ret[i] = out[i+1] + 1;
		} // end rep
		return ret;
	}

	vector<int> geneRes(void){
		vector<int> res(D+1, 0);
		for (int d = 1; d <= D; d++){
			res[d] = Rand() % 26;
		} // end rep
		return res;
	}

	void init(int _D, vector<int> _c, vector<vector<int>> _s){
		startTime = timer.get();
		endTime = TIME_LIMIT;
		D = _D;
		c = _c;
		s = _s;
		out.clear(); out.resize(D+1, 0);
		last.clear(); last.resize(26, 0);
		rep (i, 26){
			st[i].clear();
		} // end rep
		rep (i, 26){
			st[i].insert(0);
			st[i].insert(D+1);
    	} // end rep		
		sat.clear(); sat.resize(D + 1, 0);
        int sz = (int)sizeof(Log) / sizeof(Log[0]);
        rep (i, sz){
            Log[i] = log((i + 0.5) / (double)sz);
        } // end rep
	}
};

int main()
{
	IHC ihc;

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	int D; cin >> D;
	vector<int> c(26, 0);
	rep (i, 26){
		cin >> c[i];
	} // end rep
	vector<vector<int>> s(D, vector<int>(26, 0));
	rep (i, D){
		rep (j, 26){
			cin >> s[i][j];
		} // end rep
	} // end rep

	vector<int> ret = ihc.solve(D,c,s);
	rep (i, (int)ret.size()){
		cout << ret[i] << endl;
	} // end rep

	return 0;
}


Measured memory_bytes: 5408