#![allow(unused_imports)]
#![allow(non_snake_case)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), std::io::stderr());
            writeln!(err, "{} = {:?}", e, $e).unwrap()
        })*
    };
}

fn calc_score(c: &Vec<i64>, t: &Vec<usize>, s: &Vec<Vec<i64>>) -> i64 {
    let d = s.len();
    let mut score = 0;
    let mut last = vec![0; 26];
    for i in 0..d {
        score += s[i][t[i]];
        last[t[i]] = i + 1;
        for qi in 0..26 {
            score -= c[qi] * (i as i64 + 1 - last[qi] as i64);
        }
    }
    score
}

fn main() {
    let d = read::<usize>();
    let c = read_vec::<i64>();
    let mut s = vec![vec![]; d];
    for i in 0..d {
        s[i] = read_vec::<i64>();
    }

    let mut answers = vec![];

    for i in 0..d {
        let mut max_idx = 0;
        for j in 0..26 {
            if s[i][j] > s[i][max_idx] {
                max_idx = j;
            }
        }
        answers.push(max_idx);
    }
    let mut cur_score = search(&c, &mut answers, &s);
    let mut xor = Xorshift::new();
    for initi in 0..0 {
        let mut r_answers = vec![0; d];
        for i in 0..d {
            r_answers[i] = xor.next() as usize % 26;
        }
        let score = search(&c, &mut r_answers, &s);
        if score > cur_score {
            cur_score = score;
            answers = r_answers;
        }
    }

    for ans in answers {
        println!("{}", ans + 1);
    }
    debug!(cur_score);
}

fn search(c: &Vec<i64>, t: &mut Vec<usize>, s: &Vec<Vec<i64>>) -> i64 {
    let mut cur_score = calc_score(&c, &t, &s);
    let mut xor = Xorshift::new();
    let round_num = 250000;
    // let round_num = 1500;
    let mut change_times = 1;
    let d = t.len();
    for ri in 0..round_num {
        if round_num == 100000 {
            change_times = 1;
        }
        let mut changes = vec![];
        for ci in 0..change_times {
            let rd = xor.next() as usize % d;
            let rq = xor.next() as usize % 26;
            let prev = t[rd];
            changes.push((rd, prev));
            t[rd] = rq;
        }

        let score = calc_score(&c, &t, &s);
        let temp = (round_num as f64 - ri as f64 - 1.0) / (round_num as f64 - 1.0) * 1200.0 + 10.0;
        let prob = ((score as f64 - cur_score as f64) / temp).exp();
        let j = xor.randf();
        // debug!(score as f64 - cur_score as f64, temp, prob, j);
        if score > cur_score || j <= prob {
            cur_score = score;
        } else {
            for (rd, prev) in changes.into_iter().rev() {
                t[rd] = prev;
            }
        }
    }
    cur_score
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

#[derive(Debug)]
pub struct Xorshift {
    seed: u64,
}
impl Xorshift {
    pub fn new() -> Xorshift {
        Xorshift {
            seed: 0xf0fb588ca2196dac,
        }
    }
    pub fn with_seed(seed: u64) -> Xorshift {
        Xorshift { seed: seed }
    }
    #[inline]
    pub fn next(&mut self) -> u64 {
        self.seed = self.seed ^ (self.seed << 13);
        self.seed = self.seed ^ (self.seed >> 7);
        self.seed = self.seed ^ (self.seed << 17);
        self.seed
    }
    #[inline]
    pub fn rand(&mut self, m: u64) -> u64 {
        self.next() % m
    }

    pub fn randf(&mut self) -> f64 {
        use std::mem;
        const UPPER_MASK: u64 = 0x3FF0000000000000;
        const LOWER_MASK: u64 = 0xFFFFFFFFFFFFF;
        let tmp = UPPER_MASK | (self.next() & LOWER_MASK);
        let result: f64 = unsafe { mem::transmute(tmp) };
        result - 1.0
    }
}


Measured memory_bytes: 3320