use proconio::input;
use rand::prelude::*;
use std::collections::BTreeSet;
use std::time::Instant;
fn main() {
    let start = Instant::now();
    let mut rng = thread_rng();
    let info = Info::read();
    let contest = (0..info.day).map(|_| rng.gen_range(0, 26)).collect();
    let mut state = State::from(&info, contest);
    let mut score = state.score;
    let mut answer = state.contest.clone();
    const T0: f64 = 2e3;
    const T1: f64 = 6e2;
    let mut temp = T0;
    let mut count = 0;
    loop {
        if count & 0b_0111_1111 == 0 {
            let time = start.elapsed().as_secs_f64() / 1.97;
            if time >= 1.0 {
                break;
            }
            temp = T0.powf(1.0 - time) * T1.powf(time);
        }
        count += 1;
        let old_score = state.score;
        let prob = |score| {
            if score >= old_score {
                1.0
            } else {
                f64::exp((score - old_score) as f64 / temp)
            }
        };
        if rng.gen_bool(0.5) {
            let date = rng.gen_range(0, info.day);
            let contest = rng.gen_range(0, 26);
            let oldcont = state.contest[date];
            state.update(&info, date, contest);
            if !rng.gen_bool(prob(state.score)) {
                state.update(&info, date, oldcont);
            }
        } else {
            let date1 = rng.gen_range(0, info.day);
            let date2 = rng.gen_range(0, info.day);
            let cont1 = state.contest[date1];
            let cont2 = state.contest[date2];
            state.update(&info, date1, cont2);
            state.update(&info, date2, cont1);
            if !rng.gen_bool(prob(state.score)) {
                state.update(&info, date1, cont1);
                state.update(&info, date2, cont2);
            }
        }
        if state.score > score {
            answer = state.contest.clone();
            score = state.score;
        }
    }
    for contest in answer {
        println!("{}", contest + 1);
    }
    eprintln!("time {}", start.elapsed().as_millis());
    eprintln!("count {}", count);
    eprintln!("score {}", state.score);
}
impl State {
    fn from(info: &Info, contest: Vec<usize>) -> Self {
        let mut date = vec![BTreeSet::new(); 26];
        for (d, &contest) in contest.iter().enumerate() {
            date[contest].insert(d + 1);
        }
        let score = info.score(&contest);
        Self { contest, date, score }
    }
    fn update(&mut self, info: &Info, date: usize, contest: usize) {
        let date1 = date + 1;
        let oldcont = self.contest[date];
        self.contest[date] = contest;
        let remove_loss = |contest: usize| {
            let &prev = self.date[contest].range(..date1).next_back().unwrap_or(&0);
            let &next = self.date[contest].range(date1 + 1..).next().unwrap_or(&(info.day + 1));
            let loss = |a, b| ((b - a) * (b - a - 1) / 2) as i32;
            let loss = loss(prev, next) - loss(prev, date1) - loss(date1, next);
            info.dec[contest] * loss
        };
        self.score -= remove_loss(oldcont) - remove_loss(contest);
        self.score += info.inc[date][contest] - info.inc[date][oldcont];
        self.date[oldcont].remove(&date1);
        self.date[contest].insert(date1);
    }
}
impl Info {
    fn read() -> Self {
        input!(day: usize, dec: [i32; 26], inc: [[i32; 26]; day]);
        Self { day, dec, inc }
    }
    fn score(&self, contest: &[usize]) -> i32 {
        let mut last = vec![0; 26];
        contest.iter().enumerate().fold(0, |score, (date, &contest)| {
            last[contest] = date + 1;
            (0..26).fold(score + self.inc[date][contest], |score, contest| {
                score - self.dec[contest] * (date + 1 - last[contest]) as i32
            })
        })
    }
}
struct State {
    contest: Vec<usize>,
    date: Vec<BTreeSet<usize>>,
    score: i32,
}
struct Info {
    day: usize,
    dec: Vec<i32>,
    inc: Vec<Vec<i32>>,
}


Measured memory_bytes: 3368