Problem:
Score : 900 points

Problem Statement

Takahashi has decided to give a string to his mother.

The value of a string T is the length of the longest common subsequence of T and T', where T' is the string obtained by reversing T.
That is, the value is the longest length of the following two strings that are equal: a subsequence of T (possibly non-contiguous), and a subsequence of T' (possibly non-contiguous).

Takahashi has a string S. He wants to give her mother a string of the highest possible value, so he would like to change at most K characters in S to any other characters in order to obtain a string of the highest possible value.
Find the highest possible value achievable.

Constraints

1 \leq |S| \leq 300

0 \leq K \leq |S|

S consists of lowercase English letters.

K is an integer.

Input

Input is given from Standard Input in the following format:

S
K

Output

Print the highest possible value achievable.

Sample Input 1

abcabcabc
1

Sample Output 1

7

Changing the first character to c results in cbcabcabc.
Let this tring be T, then one longest common subsequence of T and T' is cbabcbc, whose length is 7.

Sample Input 2

atcodergrandcontest
3

Sample Output 2

15

Solution in Rust (1.15.1) (judge verdict: Accepted)

#[allow(unused_imports)]
use std::io::{stdin, Read, StdinLock};
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::str::FromStr;
#[allow(unused_imports)]
use std::collections::{HashSet, HashMap, BinaryHeap, VecDeque};
#[allow(unused_imports)]
use std::vec::Vec;

#[allow(dead_code)]
const INF: i32 = 1000_000_000;
#[allow(dead_code)]
const INFLL: i64 = 1000_000_000_000_000_000;
#[allow(dead_code)]
const EPS: f64 = 1.0e-10;
#[allow(dead_code)]
const MOD: i32 = 1000_000_007;
#[allow(dead_code)]
const MODLL: i64 = 1000_000_007;

struct Scanner<'a> {
    cin: StdinLock<'a>,
}

#[allow(dead_code)]
impl<'a> Scanner<'a> {
    fn new(cin: StdinLock<'a>) -> Scanner<'a> {
        Scanner {cin: cin}
    }
    fn read1<T: FromStr>(&mut self) -> Option<T> {
        let token = self.cin.by_ref().bytes().map(|c| c.unwrap() as char)
                    .skip_while(|c| c.is_whitespace())
                    .take_while(|c| !c.is_whitespace())
                    .collect::<String>();
        token.parse::<T>().ok()
    }
    fn read<T: FromStr>(&mut self) -> T {
        self.read1().unwrap()
    }
}

fn solve(s: &Vec<char>, l: usize, r: usize, k: usize, mut dp: &mut Vec<Vec<Vec<i32>>>) -> i32 {
    if l > r {
        return 0
    }
    if dp[l][r][k] != -1 {
        return dp[l][r][k]
    }
    if l == r {
        dp[l][r][k] = 1;
        return 1
    }

    dp[l][r][k] = 0;
    if s[l] == s[r] {
        dp[l][r][k] = solve(&s, l + 1, r - 1, k, &mut dp) + 2;
    }
    if k + 1 < dp[0][0].len() {
        dp[l][r][k] = max(dp[l][r][k], solve(&s, l + 1, r - 1, k + 1, &mut dp) + 2);
    }
    dp[l][r][k] = max(dp[l][r][k], solve(&s, l + 1, r, k, &mut dp));
    dp[l][r][k] = max(dp[l][r][k], solve(&s, l, r - 1, k, &mut dp));

    dp[l][r][k]
}

fn main() {
    let cin = stdin();
    let cin = cin.lock();
    let mut sc = Scanner::new(cin);

    let (s, k): (String, usize) = (sc.read(), sc.read());
    let s: Vec<char> = s.chars().collect();
    let mut dp: Vec<Vec<Vec<i32>>> = vec![vec![vec![-1; k + 1]; s.len()]; s.len()];

    println!("{}", solve(&s, 0, s.len() - 1, 0, &mut dp));
}