Problem:
Score : 400 points

Problem Statement

We have a string s consisting of lowercase English letters.
Snuke can perform the following operation repeatedly:

Insert a letter x to any position in s of his choice, including the beginning and end of s.

Snuke's objective is to turn s into a palindrome.
Determine whether the objective is achievable. If it is achievable, find the minimum number of operations required.

Notes

A palindrome is a string that reads the same forward and backward.
For example, a, aa, abba and abcba are palindromes, while ab, abab and abcda are not.

Constraints

1 \leq |s| \leq 10^5

s consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

s

Output

If the objective is achievable, print the number of operations required.
If it is not, print -1 instead.

Sample Input 1

xabxa

Sample Output 1

2

One solution is as follows (newly inserted x are shown in bold):

xabxa → xaxbxa → xaxbxax

Sample Input 2

ab

Sample Output 2

-1

No sequence of operations can turn s into a palindrome.

Sample Input 3

a

Sample Output 3

0

s is a palindrome already at the beginning.

Sample Input 4

oxxx

Sample Output 4

3

One solution is as follows:

oxxx → xoxxx → xxoxxx → xxxoxxx

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

#![allow(non_snake_case)]

use std::io::{stdin, Read};
use std::str::FromStr;
fn read_option<T: FromStr>() -> Option<T> {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok()
}
fn read<T: FromStr>() -> T {
    let opt = read_option();
    opt.expect("failed to parse token")
}

fn main() {
    let S: String = read();
    // xを除いて回文じゃなかったら-1
    // 回文だったらある文字とある文字の間にxが何個あるかを回文と比較
    let non_x = S.replace("x", "");
    let non_x_rev: String = non_x.chars().rev().collect();
    if non_x != non_x_rev {
        println!("-1");
        return;
    }
    // 計算の都合上xを前後に足しておく
    let S = "x".to_string() + &S + "x";
    let chars: Vec<_> = S.chars().collect();
    let mut i = 0;
    let count = S.chars().count();
    let mut x_counts = vec![];
    while i < count {
        let mut skip_count = 0;
        while i < count && chars[i] == 'x' {
            skip_count += 1;
            i += 1;
        }
        x_counts.push(skip_count);
        i += 1;
    }
    let x_counts_rev: Vec<_> = x_counts.iter().rev().collect();
    let mut ans = 0;
    for (i, v) in x_counts.iter().enumerate() {
        ans += std::cmp::max(v, x_counts_rev[i]) - std::cmp::min(v, x_counts_rev[i]);
    }
    println!("{}", ans / 2);
}