use std::collections::BTreeSet;

const N: usize = 26;

#[derive(Debug)]
struct G {
    D: usize,
    C: Vec<i64>,
    S: Vec<Vec<i64>>,
}

impl G {
    fn main(&self, mut sc: io::Scanner<impl std::io::Read>) {
        let mut ini: Vec<usize> = vec![];
        for _ in 0..self.D {
            ini.push(sc.next::<usize>().wrapping_sub(1)); // prob B
        }
        let sl = Sol::new(self, ini);
    }
}

struct Sol<'a> {
    g: &'a G,
    tr: BTreeSet<P>,
    t: Vec<usize>, // length = d.
    score: i64,
}

#[derive(Ord, PartialOrd, PartialEq, Eq, Copy, Clone)]
struct P(usize, usize);

fn key(day: usize, kind: usize) -> P {
    P(kind, day)
}
impl P {
    fn day(self) -> usize {
        self.1
    }
    fn kind(self) -> usize {
        self.0
    }
}

impl<'a> Sol<'a> {
    fn prev(&self, day: usize, ty: usize) -> Option<usize> {
        let before = self.tr.range(..key(day, ty));
        let x = before.last()?;
        if x.kind() != ty {
            return None;
        }
        Some(x.day())
    }
    fn new(g: &G, init: Vec<usize>) -> Sol {
        let mut res = Sol {
            g: g,
            tr: BTreeSet::new(),
            t: vec![],
            score: 0,
        };
        for i in 0..g.D {
            res.tr.insert(key(i, init[i]));
            res.t.push(init[i]);
            for j in 0..N {
                if init[i] == j {
                    res.score += g.S[i][j];
                } else {
                    let lst = res.prev(i, j);
                    if let Some(x) = lst {
                        res.score -= ((i - x) as i64) * g.C[j];
                    } else {
                        res.score -= ((i + 1) as i64) * g.C[j];
                    }
                }
            }
            println!("{}", res.score);
        }
        res
    }
}

fn main() {
    let mut sc = io::Scanner::new(std::io::stdin());
    let d: usize = sc.next(); // 365
    let mut c: Vec<i64> = vec![];
    for _ in 0..N {
        c.push(sc.next())
    }
    let mut s = vec![vec![]; d];
    for i in 0..d {
        for _ in 0..N {
            s[i].push(sc.next());
        }
    }
    G { D: d, C: c, S: s }.main(sc);
}

mod io {

    /// Scanner
    ///
    /// # Example
    /// ```
    /// use contest::io::Scanner;
    /// let mut sc = Scanner::new("1 2 \n\n \r\t \n 3".as_bytes());
    /// assert_eq!("1".to_string(), sc.next::<String>());
    /// let v = sc.nexts(2);
    /// assert_eq!(2i32, v[0]);
    /// assert_eq!(3i32, v[1]);
    ///
    /// // To create a scanner from stdin:
    /// Scanner::new(std::io::stdin());
    /// ```
    use std;
    use std::io;
    use std::io::BufRead;

    pub struct Scanner<R: io::Read> {
        br: io::BufReader<R>,
        // Read tokens are stored in reversed order per line.
        buf: Vec<String>,
    }

    pub fn new<R: io::Read>(r: R) -> Scanner<R> {
        Scanner::new(r)
    }

    impl<R: io::Read> Scanner<R> {
        #[inline]
        pub fn new(r: R) -> Scanner<R> {
            Scanner {
                br: io::BufReader::new(r),
                buf: vec![],
            }
        }
        #[inline]
        pub fn next<T>(&mut self) -> T
        where
            T: std::str::FromStr,
            T::Err: std::fmt::Debug,
        {
            self.next_string()
                .map(|s| s.parse::<T>().expect("Parse failed: "))
                .expect("Unexpected EOF")
        }
        #[inline]
        pub fn nexts<T>(&mut self, n: i32) -> Vec<T>
        where
            T: std::str::FromStr,
            T::Err: std::fmt::Debug,
        {
            let mut res = vec![];
            for _ in 0..n {
                res.push(self.next());
            }
            res
        }
        fn next_string(&mut self) -> Option<String> {
            self.buf.pop().or_else(|| match self.update() {
                true => self.next_string(),
                false => None,
            })
        }
        #[inline]
        fn update(&mut self) -> bool {
            let mut s = String::new();
            let res = self.br.read_line(&mut s);
            match res.expect("I/O error.") {
                0 => false,
                _ => {
                    self.buf = s.split_whitespace().map(|x| x.to_string()).rev().collect();
                    true
                }
            }
        }
    }

    #[test]
    fn test_next() {
        let mut sc = new("hoge".as_bytes());
        let s: String = sc.next();
        assert_eq!("hoge", s);
    }
}


Measured memory_bytes: 2316