use proconio::input;
use rand::prelude::*;
use rand::{Rng, SeedableRng};
use std::collections::BTreeSet;

struct Timer {
    start_time: f64,
}

impl Timer {
    fn get_time_sec() -> f64 {
        let t = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap();
        t.as_secs() as f64 + t.subsec_nanos() as f64 * 1e-9
    }

    fn new() -> Timer {
        Timer {
            start_time: Self::get_time_sec(),
        }
    }

    fn get_elapsed_time_sec(self: &Self) -> f64 {
        Self::get_time_sec() - self.start_time
    }
}

struct State {
    base_score: i64,
    schedule: Vec<BTreeSet<i64>>,
    contests: Vec<u64>,
}

impl State {
    fn new(days: u64, sats: &Vec<Vec<i64>>, contests: Vec<u64>) -> Self {
        let mut base_score = 0;
        let mut schedule = vec![BTreeSet::<i64>::new(); 26];

        for day in 0usize..(days as usize) {
            let contest = contests[day as usize] as usize;
            base_score += sats[day][contest] as i64;
            schedule[contest].insert(day as i64);
        }

        State {
            base_score,
            schedule,
            contests,
        }
    }

    fn score(&self, days: i64, cs: &Vec<i64>) -> i64 {
        let mut score = self.base_score;

        for i in 0..cs.len() {
            let mut last = -1;

            for d in self.schedule[i].iter() {
                let x = d - last;
                let n = (x * (x - 1)) / 2;
                score -= cs[i] * n;
                last = *d;
            }
            let x = days - last;
            let n = (x * (x - 1)) / 2;
            score -= cs[i] * n;
        }

        score
    }

    fn change(&mut self, sats: &Vec<Vec<i64>>, day: usize, contest: usize) -> usize {
        let orig = self.contests[day as usize] as usize;

        self.base_score -= sats[day][orig];
        self.base_score += sats[day][contest];

        self.schedule[orig].remove(&(day as i64));
        self.schedule[contest].insert(day as i64);

        self.contests[day as usize] = contest as u64;

        orig
    }

    fn swap(&mut self, sats: &Vec<Vec<i64>>, day1: usize, day2: usize) {
        let c1 = self.contests[day1 as usize] as usize;
        let c2 = self.contests[day2 as usize] as usize;
        self.change(sats, day1, c2);
        self.change(sats, day2, c1);
    }
}

fn main() {
    let timer = Timer::new();

    input! { days: u64 };
    let mut cs = vec![0; 26];

    for i in 0..26 {
        input! {
            x: i64
        };

        cs[i] = x;
    }

    let mut sats = vec![vec![0; 26]; days as usize];
    for d in 0..days {
        for i in 0..26 {
            input! {
                s: i64
            };

            sats[d as usize][i as usize] = s;
        }
    }

    let mut ts = vec![0u64; days as usize];
    for i in 0..ts.len() {
        ts[i] = (i as u64) % 26;
    }

    let mut state = State::new(days, &sats, ts);
    let mut cur_score = state.score(days as i64, &cs);

    let seed = [1u8; 32];
    let mut rng: StdRng = SeedableRng::from_seed(seed);

    let start_temp: f64 = 2000.0;
    let end_temp: f64 = 500.0;

    let mut loop_count = 0;

    const TIME_LIMIT_SEC: f64 = 1.98;
    let mut temperture = start_temp;

    let max_move_offset = 60;
    let mut move_offset = max_move_offset;
    loop {
        loop_count += 1;

        if loop_count % 100 == 0 {
            let cur_time = timer.get_elapsed_time_sec();
            if cur_time > TIME_LIMIT_SEC {
                break;
            }
            temperture = start_temp + (end_temp - start_temp) * cur_time / TIME_LIMIT_SEC;

            move_offset = (max_move_offset as f64
                + (1.0 - max_move_offset as f64) * cur_time / TIME_LIMIT_SEC)
                as usize;
        }

        if loop_count % 2 == 0 {
            // Change a contest on a day.
            let day = rng.gen::<usize>() % (days as usize) as usize;
            let t = rng.gen::<usize>() % 26;

            let orig = state.change(&sats, day, t);

            let next_score = state.score(days as i64, &cs);
            let prob = ((next_score - cur_score) as f64 / temperture).exp();

            if prob > rng.gen_range(0.0, 1.0) {
                cur_score = next_score;
            } else {
                state.change(&sats, day, orig);
            }
        } else {
            // Swap contests of two days.
            let day_a = rng.gen::<usize>() % (days as usize - move_offset) as usize;
            let day_b = day_a + (rng.gen::<usize>() % move_offset);

            state.swap(&sats, day_a, day_b);

            let next_score = state.score(days as i64, &cs);
            let prob = ((next_score - cur_score) as f64 / temperture).exp();

            if prob > rng.gen_range(0.0, 1.0) {
                cur_score = next_score;
            } else {
                state.swap(&sats, day_a, day_b);
            }
        }
    }

    eprintln!("base_score: {}", state.base_score);
    eprintln!("total: {}", state.score(days as i64, &cs));

    for t in state.contests {
        println!("{}", t + 1);
    }
    eprintln!("loop_count={}", loop_count);
}


Measured memory_bytes: 3360