pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Debug)]
pub struct Scanner<'a> {
    pub(crate) iter: std::str::SplitAsciiWhitespace<'a>,
}
impl<'a> Scanner<'a> {
    #[inline]
    pub fn new(s: &'a str) -> Self {
        let iter = s.split_ascii_whitespace();
        Self { iter }
    }
    #[inline]
    pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
        T::scan(&mut self.iter).unwrap()
    }
    #[inline]
    pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
        marker.mscan(&mut self.iter).unwrap()
    }
    #[inline]
    pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
        (0..size)
            .map(|_| T::scan(&mut self.iter).unwrap())
            .collect()
    }
    #[inline]
    pub fn scan_chars(&mut self) -> Vec<char> {
        self.iter.next().unwrap().chars().collect::<Vec<char>>()
    }
}
mod scanner_impls {
    use super::*;
    macro_rules !iter_scan_impls {($($t :ty ) *) =>{$(impl IterScan for $t {type Output =Self ;#[inline ] fn scan <'a ,I :Iterator <Item =&'a str >>(iter :&mut I ) ->Option <Self >{iter .next () ?.parse ::<$t >() .ok () } } ) *} ;}
    iter_scan_impls !(char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String ) ;
    macro_rules !iter_scan_tuple_impl {($($T :ident ) +) =>{impl <$($T :IterScan ) ,+>IterScan for ($($T ,) +) {type Output =($(<$T as IterScan >::Output ,) +) ;#[inline ] fn scan <'a ,It :Iterator <Item =&'a str >>(iter :&mut It ) ->Option <Self ::Output >{Some (($($T ::scan (iter ) ?,) +) ) } } } ;}
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl !(A B ) ;
    iter_scan_tuple_impl !(A B C ) ;
    iter_scan_tuple_impl !(A B C D ) ;
    iter_scan_tuple_impl !(A B C D E ) ;
    iter_scan_tuple_impl !(A B C D E F ) ;
    iter_scan_tuple_impl !(A B C D E F G ) ;
    iter_scan_tuple_impl !(A B C D E F G H ) ;
    iter_scan_tuple_impl !(A B C D E F G H I ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J K ) ;
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        phantom: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        fn next(&mut self) -> Option<Self::Item> {
            T::scan(&mut self.inner.iter)
        }
    }
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                phantom: std::marker::PhantomData,
            }
        }
    }
}
mod marker {
    use super::*;
    pub struct Usize1;
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            usize::scan(iter).map(|x| x.wrapping_sub(1))
        }
    }
    pub struct Isize1;
    impl IterScan for Isize1 {
        type Output = isize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            isize::scan(iter).map(|x| x.wrapping_sub(1))
        }
    }
}
#[macro_export]
macro_rules !min {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::min ($e ,min !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmin {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::min ($dst ,min !($($src ) ,+) ) ;$dst =x ;} } ;}
#[macro_export]
macro_rules !max {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::max ($e ,max !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmax {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::max ($dst ,max !($($src ) ,+) ) ;$dst =x ;} } ;}
#[derive(Clone, Debug)]
pub struct Xorshift {
    y: u64,
}
impl Xorshift {
    pub fn new(seed: u64) -> Self {
        Xorshift { y: seed }
    }
    pub fn time() -> Self {
        let seed = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .ok()
            .unwrap_or_default()
            .as_secs() as u64;
        Xorshift::new(seed)
    }
    #[inline]
    pub fn next(&mut self) -> u64 {
        self.y ^= self.y << 5;
        self.y ^= self.y >> 17;
        self.y ^= self.y << 11;
        self.y
    }
    #[inline]
    pub fn rand(&mut self, k: u64) -> u64 {
        self.next() % k
    }
    #[inline]
    pub fn rands(&mut self, k: u64, n: usize) -> Vec<u64> {
        (0..n).map(|_| self.rand(k)).collect::<Vec<_>>()
    }
    #[inline]
    pub fn randf(&mut self) -> f64 {
        const UPPER_MASK: u64 = 0x3FF0000000000000;
        const LOWER_MASK: u64 = 0xFFFFFFFFFFFFF;
        let tmp = UPPER_MASK | (self.next() & LOWER_MASK);
        let result: f64 = unsafe { std::mem::transmute(tmp) };
        result - 1.0
    }
    #[inline]
    pub fn gen_bool(&mut self, p: f64) -> bool {
        self.randf() < p
    }
}
impl Default for Xorshift {
    fn default() -> Self {
        Xorshift::new(0x2b992ddfa23249d6)
    }
}
impl Iterator for Xorshift {
    type Item = u64;
    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        Some(self.next())
    }
}
fn main() {
    #[allow(unused_imports)]
    use std::io::{Read as _, Write as _};
    let __out = std::io::stdout();
    let mut __in_buf = String::new();
    std::io::stdin().read_to_string(&mut __in_buf).unwrap();
    let mut __scanner = Scanner::new(&__in_buf);
    #[allow(unused_macros)]
    macro_rules !scan {() =>{scan !(usize ) } ;(($($t :tt ) ,*) ) =>{($(scan !($t ) ) ,*) } ;([$t :tt ;$len :expr ] ) =>{(0 ..$len ) .map (|_ |scan !($t ) ) .collect ::<Vec <_ >>() } ;({$t :tt =>$f :expr } ) =>{$f (scan !($t ) ) } ;(chars ) =>{__scanner .scan_chars () } ;($t :ty ) =>{__scanner .scan ::<$t >() } ;}
    let mut __out = std::io::BufWriter::new(__out.lock());
    #[allow(unused_macros)]
    macro_rules !print {($($arg :tt ) *) =>(::std ::write !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules !println {($($arg :tt ) *) =>(::std ::writeln !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules! echo {
        ($iter :expr ) => {
            echo!($iter, "\n")
        };
        ($iter :expr ,$sep :expr ) => {
            let mut iter = $iter;
            if let Some(item) = iter.next() {
                print!("{}", item);
            }
            for item in iter {
                print!("{}{}", $sep, item);
            }
            println!();
        };
    }

    let mut sa = SimuratedAnnealing::new();

    let mut rand = Xorshift::time();
    let input = scan!(Input);
    let t: Vec<_> = (0..D).map(|_| rand.rand(S as u64) as usize).collect();
    let mut best = t.clone();
    let mut state = input.init(t);

    let mut best_score = state.score;
    while !sa.is_end() {
        let old_score = state.score;
        if sa.iter_count % 2 == 0 {
            let d = rand.rand(D as u64) as usize;
            let p = state.t[d];
            let q = rand.rand(S as u64 - 1) as usize;
            let q = if q < p { q } else { q + 1 };
            state.change(d, q);
            if !sa.is_accepted(old_score as f64, state.score as f64) {
                state.change(d, p);
            }
        } else {
            let diff = rand.rand(15) + 1;
            let d1 = rand.rand(D as u64 - diff) as usize;
            let d2 = d1 + diff as usize;
            let (q1, q2) = (state.t[d1], state.t[d2]);
            if q1 == q2 {
                continue;
            }
            state.change(d1, q2);
            state.change(d2, q1);
            if !sa.is_accepted(old_score as f64, state.score as f64) {
                state.change(d1, q1);
                state.change(d2, q2);
            }
        }
        if best_score < state.score {
            best_score = state.score;
            best = state.t.clone();
        }
    }
    eprintln!("sa.iter_count = {:?}", sa.iter_count);
    eprintln!("best_score = {:?}", best_score + 1_000_000);
    echo!(best.iter().map(|x| x + 1));
}

const D: usize = 365;
const S: usize = 26;
pub struct Input {
    pub c: Vec<i64>,
    pub s: Vec<Vec<i64>>,
}
impl IterScan for Input {
    type Output = Self;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
        usize::scan(iter).unwrap();
        let c = (0..S).map(|_| i64::scan(iter).unwrap()).collect();
        let s = (0..D)
            .map(|_| (0..S).map(|_| i64::scan(iter).unwrap()).collect())
            .collect();
        Some(Input { c, s })
    }
}
impl Input {
    pub fn init(self, t: Vec<usize>) -> State {
        let mut score = 0i64;
        let mut last = vec![0; S];
        let mut table: Vec<Vec<usize>> = vec![vec![]; S];
        for (i, (s, &t)) in self.s.iter().zip(t.iter()).enumerate() {
            table[t].push(i + 1);
            score += s[t];
            last[t] = i + 1;
            score -= self
                .c
                .iter()
                .zip(last.iter())
                .map(|(&c, &l)| c * (i as i64 + 1 - l as i64))
                .sum::<i64>();
        }
        State {
            input: self,
            score,
            t,
            table,
        }
    }
}

pub struct State {
    pub input: Input,
    pub score: i64,
    pub t: Vec<usize>,
    pub table: Vec<Vec<usize>>,
}

impl State {
    pub fn change(&mut self, d: usize, q: usize) {
        let d1 = d + 1;
        let p = self.t[d];
        let i = self.table[p].iter().position(|&x| x == d1).unwrap();
        let pi = *self.table[p].get(i.wrapping_sub(1)).unwrap_or(&0);
        let ni = *self.table[p].get(i + 1).unwrap_or(&(D + 1));
        self.table[p].remove(i);
        self.score -= self.input.c[p] * ((d1 - pi) * (ni - d1)) as i64;
        let i = self.table[q]
            .iter()
            .position(|&x| x > d1)
            .unwrap_or(self.table[q].len());
        let pi = *self.table[q].get(i.wrapping_sub(1)).unwrap_or(&0);
        let ni = *self.table[q].get(i).unwrap_or(&(D + 1));
        self.table[q].insert(i, d1);
        self.score += self.input.c[q] * ((d1 - pi) * (ni - d1)) as i64;
        self.score -= self.input.s[d][p];
        self.score += self.input.s[d][q];
        self.t[d] = q;
    }
}

pub struct SimuratedAnnealing {
    pub iter_count: usize,
    pub now: std::time::Instant,
    pub time: f64,
    pub temperture: f64,
    pub log_table: Vec<f64>,
    pub rand: Xorshift,
}

impl SimuratedAnnealing {
    pub const IS_MAXIMIZE: bool = true;
    pub const START_TEMP: f64 = 3e3;
    pub const END_TEMP: f64 = 1e-2;
    pub const TEMP_RATIO: f64 = (Self::END_TEMP - Self::START_TEMP) / Self::TIME_LIMIT;
    pub const TIME_LIMIT: f64 = 1.99;
    pub const LOG_TABLE_SIZE: usize = 0x10000;
    pub const UPDATE_INTERVAL: usize = 0xff;

    pub fn new() -> Self {
        let now = std::time::Instant::now();
        let log_table = (0..Self::LOG_TABLE_SIZE)
            .map(|i| ((i * 2 + 1) as f64 / (Self::LOG_TABLE_SIZE * 2) as f64).ln())
            .collect();
        Self {
            iter_count: 0,
            now,
            time: 0.,
            temperture: Self::START_TEMP,
            log_table,
            rand: Xorshift::time(),
        }
    }
    pub fn is_accepted(&mut self, current_score: f64, next_score: f64) -> bool {
        let diff = if Self::IS_MAXIMIZE {
            next_score - current_score
        } else {
            current_score - next_score
        };
        diff >= 0.
            || diff
                > self.log_table[self.rand.rand(Self::LOG_TABLE_SIZE as u64) as usize]
                    * self.temperture
    }
    pub fn is_end(&mut self) -> bool {
        self.iter_count += 1;
        if self.iter_count & Self::UPDATE_INTERVAL == 0 {
            self.time = self.now.elapsed().as_secs_f64();
            self.temperture = Self::START_TEMP + Self::TEMP_RATIO * self.time;
            self.time >= Self::TIME_LIMIT
        } else {
            false
        }
    }
}


Measured memory_bytes: 3528