#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <iterator>
#include <numeric>
#include <cstdint>
#include <cmath>
#include <bitset>
#include <string>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <random>
#include <chrono>

#define N_TIMES(i, n)     for ( uint64_t i = 0;     i <  n; ++i )
#define N_TIMES_REV(i, n) for (  int64_t i = n - 1; i >= 0; --i )

template<typename T> using maximum_heap = std::priority_queue<T, std::vector<T>, std::less<T>>;
template<typename T> using minimum_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template<typename T>
std::istream& operator>>(std::istream &is, std::vector<T> &v)
{
  for (typename std::vector<T>::size_type i = 0; i < v.size(); ++i) {
    is >> v[i];
  }
  return is;
}

const uint64_t TIMEOUT_MS = 2000;
const uint64_t TIMEOUT_MS_EPS = 20;

template<uint64_t TIMEOUT_MS = 2000, uint64_t TIMEOUT_MS_EPS = 50>
class TimeoutManagerBase {
private:
  std::chrono::system_clock::time_point _start;

public:
  TimeoutManagerBase() : _start(std::chrono::system_clock::now()) {}

  bool timeout(uint64_t eps_ms = TIMEOUT_MS_EPS) {
    uint64_t time_duration = static_cast<uint64_t>(
      std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now() - _start
      ).count()
    );
    return time_duration < (TIMEOUT_MS - eps_ms);
  }
};

typedef TimeoutManagerBase<TIMEOUT_MS, TIMEOUT_MS_EPS> TimeoutManager;

class UniformRandomIntegerGenerator
{
private:
  std::random_device _seed_device;
  std::default_random_engine _engine;
  std::uniform_int_distribution<uint64_t> _dist;

public:
  UniformRandomIntegerGenerator(uint64_t lower_bound = 0, uint64_t upper_bound = 100)
    : _engine(_seed_device()) 
    , _dist(std::uniform_int_distribution<uint64_t>(lower_bound, upper_bound))
  {}
  uint64_t get() { return _dist(_engine); }
};

using namespace std;

const uint64_t M = 26;

uint64_t diff_abs(uint64_t a, uint64_t b)
{
  return a >= b ? a - b : b - a;
}

int main()
{
  TimeoutManager timeout_manager;

  uint64_t D;
  cin >> D;

  vector<int64_t> c(M);
  cin >> c;

  vector<vector<int64_t>> s(D, vector<int64_t>(M));
  N_TIMES(d, D) { cin >> s[d]; }

  // last[m]はタイプmのコンテストが開催された日の集合。
  // greaterでソートしたので，last[m].lower_bound(d) (1 <= d <= D)である日付dより前に開催された日がわかる。
  vector<set<uint64_t>> last(M);
  N_TIMES(m, M) {
    last[m].insert(0);
    last[m].insert(D + 1);
  }

  // 満足度の低下の合計はコンテストのタイプごとに，開催日の集合があればdに依存せず計算可能。
  vector<int64_t> dissatisfied(M, 0);

  // 満足度の低下をコンテストのタイプごとにまとめて計算。
  auto calc_dissatisfied = [&](uint64_t m) {
    uint64_t total = 0, prev = 0;
    for (uint64_t d : last[m]) {
      uint64_t diff_d = d - prev;
      uint64_t diff_d_sum = diff_d * (diff_d - 1) / 2;
      total += c[m] * diff_d_sum;
      prev = d;
    }
    return total;
  };

  // スコアの計算
  auto calc_score = [&](const vector<int64_t> &t) {
    int64_t score = 0;
    N_TIMES(d, D) {
      score += s[d][t[d]];
      last[t[d]].insert(d + 1);
    }

    N_TIMES(m, M) {
      dissatisfied[m] = calc_dissatisfied(m);
      score -= dissatisfied[m];
    }
    return score;
  };

  // B問題を踏まえて貪欲法で解く。
  // 各d日目で最もスコアが最大となるような選択を行う。
  auto greedy = [&] () {
    int64_t S = 0;
    vector<uint64_t> t(D, 0);
    vector<uint64_t> greedy_last(M, 0);

    N_TIMES(d, D) {
      int64_t max_T = -1e+16, max_q = -1;
      N_TIMES(q, M) {
        int64_t T = s[d][q];
        N_TIMES(m, M) {
          // last[q].insert(d + 1), greedy_last[q] == d + 1を仮定
          if (m == q) { continue; }
          T -= c[m] * ((d + 1) - greedy_last[m]);
        }

        if (max_T < T) {
          max_T = T;
          max_q = q;
        }
      }

      t[d] = max_q;
      greedy_last[t[d]] = d + 1;
      last[t[d]].insert(d + 1);
      S += max_T;
    }

    N_TIMES(m, M) {
      dissatisfied[m] = calc_dissatisfied(m);
    }

    return make_pair(S, t);
  };

  pair<int64_t, vector<uint64_t>> ret = greedy();
  int64_t S = ret.first;
  vector<uint64_t> t = ret.second;

  // C問題を踏まえて局所探索法で解く。

  // dとqをランダムに選び，改善されるなら更新する。
  auto query_change = [&](uint64_t d, uint64_t q) {
    auto calc_diff = [&] (uint64_t m1, uint64_t m2) {
      int64_t T = 0;

      T -= s[d][m1];
      last[m1].erase(d + 1);

      T += dissatisfied[m1];
      int64_t Pa = calc_dissatisfied(m1);
      T -= Pa;

      T += s[d][m2];
      last[m2].insert(d + 1);

      T += dissatisfied[m2];
      int64_t Pb = calc_dissatisfied(m2);
      T -= Pb;

      return make_tuple(T, Pa, Pb);
    };

    tuple<int64_t, int64_t, int64_t> ret = calc_diff(t[d], q);
    int64_t T = get<0>(ret);

    if (T <= 0) { // rollback
      last[t[d]].insert(d + 1);
      last[q].erase(d + 1);
    } else {
      t[d] = q;
      dissatisfied[t[d]] = get<1>(ret);
      dissatisfied[q]    = get<2>(ret);
      S += T;
    }

    return S;
  };

  // d1とd2をランダムに選びコンテストタイプを交換，改善されるなら更新する。
  auto query_swap = [&](uint64_t d1, uint64_t d2) {
    auto calc_diff = [&] (uint64_t d, uint64_t m1, uint64_t m2) {
      int64_t T = 0;

      T -= s[d][m1];
      last[m1].erase(d + 1);

      T += dissatisfied[m1];
      int64_t Pa = calc_dissatisfied(m1);
      T -= Pa;

      T += s[d][m2];
      last[m2].insert(d + 1);

      T += dissatisfied[m2];
      int64_t Pb = calc_dissatisfied(m2);
      T -= Pb;

      return make_tuple(T, Pa, Pb);
    };

    pair<int64_t, int64_t> old_dissatisfied = make_pair(dissatisfied[t[d1]], dissatisfied[t[d2]]);

    tuple<int64_t, int64_t, int64_t> ret1 = calc_diff(d1, t[d1], t[d2]);
    dissatisfied[t[d2]] = get<1>(ret1);
    dissatisfied[t[d1]] = get<2>(ret1);

    tuple<int64_t, int64_t, int64_t> ret2 = calc_diff(d2, t[d2], t[d1]);
    int64_t T = get<0>(ret1) + get<0>(ret2);

    if (T <= 0) { // rollback
      last[t[d1]].insert(d1 + 1);
      last[t[d1]].erase(d2 + 1);
      last[t[d2]].insert(d2 + 1);
      last[t[d2]].erase(d1 + 1);

      dissatisfied[t[d1]] = old_dissatisfied.first;
      dissatisfied[t[d2]] = old_dissatisfied.second;
    } else {
      swap(t[d1], t[d2]);
      dissatisfied[t[d1]] = get<1>(ret2);
      dissatisfied[t[d2]] = get<2>(ret2);
      S += T;
    }

    return S;
  };

  UniformRandomIntegerGenerator dist_type(0, 1);
  UniformRandomIntegerGenerator dist_d(0, D - 1);
  UniformRandomIntegerGenerator dist_q(0, M - 1);
  while (timeout_manager.timeout()) {
    if (dist_type.get() == 0) {
      uint64_t d = dist_d.get(), q = dist_q.get();
      query_change(d, q);
    } else {
      int64_t d1 = dist_d.get();
      int64_t d2_lb = max(static_cast<int64_t>(0), d1 - 16), d2_ub = min(static_cast<int64_t>(D - 1), d1 + 16);
      int64_t d2 = UniformRandomIntegerGenerator(d2_lb, d2_ub).get();
      query_swap(d1, d2);
    }
  }

  N_TIMES(d, D) { cout << (t[d] + 1) << endl; }

  return 0;
}

Measured memory_bytes: 3736