use proconio::input;

// segtree{{{
mod segtree {
    #![warn(missing_docs)]
    #![warn(missing_doc_code_examples)]

    //! # TODO
    //!
    //! modint::Mint ã¨ã¯åˆ¥ crate ãªã®ã§ã™ãŒã€æœ¬å½“ã¯å”èª¿å‹•ä½œã‚’ã—ã¦ã„ãŸã ããŸã„ã§ã™ã€‚
    //! å…·ä½“çš„ã«ã¯ã€[`Zero`] ãƒˆãƒ¬ã‚¤ãƒˆã‚’ modint::Mint åž‹ã«å®Ÿè£…ã—ãŸã„ã§ã™ã€‚
    //!
    //! å°†æ¥çš„ã«ã¯ã€num_traits ã«ç›¸å½“ã™ã‚‹ã‚‚ã®ã‚’å®Ÿè£…ã—ã¦ãã‚Œã«ä¾å­˜ã™ã‚‹å¯èƒ½æ€§ãŒé«˜ã„ã§ã™ã€‚
    //! ãã‚Œã¯ã‚ã¾ã‚Šé›£ã—ã„ã“ã¨ã§ã¯ãªã„ã®ã§ã™ãŒã€ãƒ©ã‚¤ãƒ–ãƒ©ãƒªé–“ã®ä¾å­˜ã¯ã€
    //! ã‚³ãƒ³ãƒ†ã‚¹ãƒˆã®ã“ã¨ã‚’è€ƒãˆã‚‹ã¨å°‘ã—èºŠèº‡ã—ã¦ã—ã¾ã„ã¾ã™ã€‚
    //!
    //! é©åˆ‡ãª budnle ãƒ„ãƒ¼ãƒ«ã‚’ä½œã‚Œã‚‹ã¾ã§å¾…ã¤ã‹ã€
    //! å¾…ãŸãšã«ã¾ãšã¯ã‚³ãƒ”ãƒšã§å¯¾å‡¦ã™ã‚‹ã®ã‹ã¯æ‚©ã‚€ã¨ã“ã‚ã§ã™ã€‚
    //!
    //! ãã‚‚ãã‚‚ã‚³ãƒ¡ãƒ³ãƒˆã¨ãƒ†ã‚¹ãƒˆã‚’æ¶ˆã™ bundle ã¯ä½œã‚ŠãŸã„ã‚“ã§ã™ã‚ˆã­â€¦â€¦
    //!
    //! # TODO
    //!
    //! Entry ã‚’ä½¿ã†ã¨ãã‚Œã„ã«ã‹ã‘ã‚‹ã‹æ¤œè¨¼ã—ãŸã„ã§ã™ã€‚
    //!

    /// ã‚»ã‚°ãƒ„ãƒªãƒ¼ã®ä¸­ã«å…¥ã‚‹å€¤ã§ã™ã€‚
    pub trait SegValue: Clone + std::fmt::Debug {}

    impl<Value: Clone + std::fmt::Debug> SegValue for Value {}

    /// ã‚»ã‚°ãƒ„ãƒªãƒ¼æ¼”ç®—ã®æƒ…å ±ã§ã™ã€‚
    pub trait SegInfo {
        /// ã‚»ã‚°ãƒ„ãƒªãƒ¼ã®ä¸­ã«å…¥ã‚‹å€¤ã§ã™ã€‚
        type Value: SegValue;

        /// å˜ä½å…ƒã§ã™ã€‚
        fn id() -> Self::Value;

        /// ãƒžãƒ¼ã‚¸æ¼”ç®—ã§ã™ã€‚
        fn op(x: &Self::Value, y: &Self::Value) -> Self::Value;

        /// ãƒžãƒ¼ã‚¸æ¼”ç®—ã® Assign ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã™ã€‚
        fn op_assign(x: &mut Self::Value, y: &Self::Value) {
            *x = Self::op(x, y);
        }
    }

    /// ã‚¼ãƒ­ã§ã™ã€‚
    /// [`AddInfo`] ã§è¦æ±‚ã•ã‚Œã¾ã™ã€‚
    ///
    /// [`AddInfo`]: struct.AddInfo.html
    pub trait Zero {
        /// ã‚¼ãƒ­ã‚’è¿”ã—ã¾ã™ã€‚
        fn zero() -> Self;
    }
    macro_rules! impl_zero {
        ($($ty: ty)+) => { $(impl Zero for $ty { fn zero() -> Self { 0 } })+ };
    }
    impl_zero! {
        u8 u16 u32 u64 u128 usize
        i8 i16 i32 i64 i128 isize
    }
    /// æœ€å°å€¤ã‚’æŒã¤åž‹ã§ã™ã€‚
    /// æœ€å¤§å€¤ã‚»ã‚°ãƒ„ãƒªãƒ¼ã® [`SegInfo`] ã§ã‚ã‚‹ [`MaxInfo`] ã§è¦æ±‚ã•ã‚Œã¾ã™ã€‚
    ///
    /// [`SegInfo`]: trait.SegInfo.html
    /// [`MinMaxInfo`]: struct.MMaxInfo.html
    pub trait MinValue {
        /// æœ€å¤§å€¤ã‚’è¿”ã—ã¾ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// assert_eq!(std::u8::MIN, <u8 as segtree::MinValue>::min_value());
        /// ```
        fn min_value() -> Self;
    }
    macro_rules! impl_min {
        ($($ty: ident)+) => { $(impl MinValue for $ty { fn min_value() -> Self { std::$ty::MIN } })+ };
    }
    impl_min! {
        u8 u16 u32 u64 u128 usize
        i8 i16 i32 i64 i128 isize
    }

    /// æœ€å¤§å€¤ã‚’æŒã¤åž‹ã§ã™ã€‚[`MinInfo`] ã§è¦æ±‚ã•ã‚Œã¾ã™ã€‚
    ///
    /// [`MinInfo`]: struct.MinInfo.html
    pub trait MaxValue {
        /// æœ€å¤§å€¤ã‚’è¿”ã—ã¾ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// assert_eq!(std::u8::MAX, <u8 as segtree::MaxValue>::max_value());
        /// ```
        fn max_value() -> Self;
    }
    macro_rules! impl_max {
        ($($ty: ident)+) => { $(impl MaxValue for $ty { fn max_value() -> Self { std::$ty::MAX } })+ };
    }
    impl_max! {
        u8 u16 u32 u64 u128 usize
        i8 i16 i32 i64 i128 isize
    }

    /// åŠ ç®—ã‚»ã‚°ãƒ„ãƒªãƒ¼ã®ãŸã‚ã® [`SegInfo`] ã§ã™ã€‚
    ///
    /// # Example
    ///
    /// ```
    /// use segtree::{Segtree, AddInfo, segtree};
    ///
    /// let seg: Segtree::<AddInfo<u8>> = segtree![4, 6, 3];
    ///
    /// assert_eq!(seg.fold_all(), 13);
    /// ```
    ///
    /// [`SegInfo`]: trait.SegInfo.html
    ///
    pub struct AddInfo<Value: SegValue + std::ops::Add> {
        _marker: std::marker::PhantomData<Value>,
    }

    impl<Value: SegValue + Zero + std::ops::Add<Output = Value> + std::ops::AddAssign> SegInfo
        for AddInfo<Value>
    {
        type Value = Value;
        fn id() -> Self::Value {
            Self::Value::zero()
        }
        fn op(x: &Self::Value, y: &Self::Value) -> Self::Value {
            x.clone() + y.clone()
        }
        fn op_assign(x: &mut Self::Value, y: &Self::Value) {
            *x += y.clone()
        }
    }
    /// `Min` ã‚»ã‚°ãƒ„ãƒªãƒ¼ã®ãŸã‚ã® [`SegInfo`] ã§ã™ã€‚
    ///
    /// # Example
    ///
    /// ```
    /// use segtree::{Segtree, MinInfo, segtree};
    ///
    /// let seg: Segtree::<MinInfo<u8>> = segtree![4, 6, 3];
    ///
    /// assert_eq!(seg.fold_all(), 3);
    /// ```
    ///
    /// [`SegInfo`]: trait.SegInfo.html
    ///
    pub struct MinInfo<Value: SegValue + MaxValue + std::cmp::Ord> {
        _marker: std::marker::PhantomData<Value>,
    }
    impl<Value: SegValue + MaxValue + std::cmp::Ord> SegInfo for MinInfo<Value> {
        type Value = Value;
        fn id() -> Self::Value {
            Self::Value::max_value()
        }
        fn op(x: &Self::Value, y: &Self::Value) -> Self::Value {
            x.clone().min(y.clone())
        }
    }
    /// `Max` ã‚»ã‚°ãƒ„ãƒªãƒ¼ã®ãŸã‚ã® [`SegInfo`] ã§ã™ã€‚
    ///
    /// # Example
    ///
    /// ```
    /// use segtree::{Segtree, MaxInfo, segtree};
    ///
    /// let seg: Segtree::<MaxInfo<u8>> = segtree![4, 6, 3];
    ///
    /// assert_eq!(seg.fold_all(), 6);
    /// ```
    ///
    /// [`SegInfo`]: trait.SegInfo.html
    ///
    pub struct MaxInfo<Value: SegValue + MinValue + std::cmp::Ord> {
        _marker: std::marker::PhantomData<Value>,
    }
    impl<Value: SegValue + MinValue + std::cmp::Ord> SegInfo for MaxInfo<Value> {
        type Value = Value;
        fn id() -> Self::Value {
            Self::Value::min_value()
        }
        fn op(x: &Self::Value, y: &Self::Value) -> Self::Value {
            x.clone().max(y.clone())
        }
    }

    /// æœ¬ä½“ã§ã™ã€‚
    #[derive(Clone)]
    pub struct Segtree<Info: SegInfo>(Vec<Info::Value>);

    impl<Info: SegInfo> Segtree<Info> {
        /// é•·ã• `len` ã®é…åˆ—ã«å¯¾å¿œã™ã‚‹ã‚»ã‚°ãƒ„ãƒªãƒ¼ã‚’ä½œã‚Šã¾ã™ã€‚
        /// å†…éƒ¨çš„ã«ã¯ã€ã“ã‚Œã® 2 å€ã®é•·ã•ã® `Vec` ãŒæ§‹ç¯‰ã•ã‚Œã¾ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo};
        /// let seg = Segtree::<AddInfo<u8>>::new(3);
        /// ```
        ///
        pub fn new(len: usize) -> Self {
            Self(vec![Info::id(); 2 * len])
        }

        /// å¯¾å¿œã™ã‚‹é…åˆ—ãŒç©ºã§ã‚ã‚‹ã“ã¨ã‚’åˆ¤å®šã—ã¾ã™ã€‚
        /// å†…éƒ¨çš„ãªé…åˆ—ãŒç©ºã§ã‚ã‚‹ã“ã¨ã¨åŒå€¤ã§ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo};
        /// let seg = Segtree::<AddInfo<u8>>::new(0);
        /// assert!(seg.is_empty());
        /// ```
        ///
        pub fn is_empty(&self) -> bool {
            self.0.is_empty()
        }

        /// å¯¾å¿œã™ã‚‹é…åˆ—ã®é•·ã•ã‚’è¿”ã—ã¾ã™ã€‚
        /// å†…éƒ¨çš„é•·ã•ã®åŠåˆ†ã§ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo};
        /// let seg = Segtree::<AddInfo<u8>>::new(3);
        /// assert_eq!(seg.len(), 3);
        /// ```
        ///
        pub fn len(&self) -> usize {
            self.0.len() / 2
        }

        /// å¯¾å¿œã™ã‚‹é…åˆ—ã‚’ã‚¹ãƒ©ã‚¤ã‚¹ã®å‚ç…§ã¨ã—ã¦è¿”ã—ã¾ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo, segtree};
        /// let seg: Segtree<AddInfo<u8>> = segtree![4, 3, 6];
        /// assert_eq!(seg.as_slice(), [4, 3, 6]);
        /// ```
        ///
        pub fn as_slice(&self) -> &[Info::Value] {
            &self.0[self.len()..self.0.len()]
        }

        /// å¯¾å¿œã™ã‚‹é…åˆ—ã‚’èµ°æŸ»ã™ã‚‹ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚¿ã‚’è¿”ã—ã¾ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo, segtree};
        /// let seg: Segtree<AddInfo<u8>> = segtree![4, 3, 6];
        /// let mut iter = seg.iter();
        /// assert_eq!(*iter.next().unwrap(), 4);
        /// assert_eq!(*iter.next().unwrap(), 3);
        /// assert_eq!(*iter.next().unwrap(), 6);
        /// ```
        ///
        pub fn iter(&self) -> std::slice::Iter<Info::Value> {
            self.0[self.len()..self.0.len()].iter()
        }

        /// å¯¾å¿œã™ã‚‹é…åˆ—ã‚’ `Vec` ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo, segtree};
        /// let seg: Segtree<AddInfo<u8>> = segtree![4, 3, 6];
        /// assert_eq!(seg.vec(), vec![4, 3, 6]);
        /// ```
        ///
        pub fn vec(&self) -> Vec<Info::Value> {
            self.0[self.len()..self.0.len()].into()
        }

        /// æ·»å­— `i` ã®å ´æ‰€ã®å€¤ã‚’ `x` ã«ã‚»ãƒƒãƒˆã—ã¾ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo};
        /// let mut seg = Segtree::<AddInfo<u8>>::new(3);
        ///
        /// seg.set(2, 5);
        /// ```
        ///
        pub fn set(&mut self, i: usize, x: Info::Value) {
            let i = i + self.len();
            self.0[i] = x;
            self.rebuild_one_leaf(i);
        }

        /// æ·»å­— i ã®å ´æ‰€ã®å€¤ã‚’ç·¨é›†ã—ã¾ã™ã€‚
        ///
        /// # TODO
        ///
        /// `std::collections::BTreeMap::entry` ã®ã‚ˆã†ãªã“ã¨ã‚’ã™ã‚‹ã¨è‰¯ã‹ã£ãŸã‚Šã™ã‚‹ã®ã§ã—ã‚‡ã†ã‹ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo, segtree};
        /// let mut seg: Segtree::<AddInfo<u8>> = segtree![4, 6, 3];
        ///
        /// seg.modify(1, |x| *x -= 2);
        /// assert_eq!(seg.as_slice(), [4, 4, 3]);
        /// ```
        ///
        pub fn modify(&mut self, i: usize, f: impl Fn(&mut Info::Value)) {
            let i = i + self.len();
            f(&mut self.0[i]);
            self.rebuild_one_leaf(i);
        }

        /// æ·»å­— `l` ã‹ã‚‰ `r` ã¾ã§ã®åŠé–‹åŒºé–“ã§ã€ç•³ã¿è¾¼ã¿ã‚’ã—ã¾ã™ã€‚
        ///
        /// # Requirements
        ///
        /// `l <= r && r <= self.len()`
        ///
        /// é•åã™ã‚‹å ´åˆã¯ã€`assert` ã§è½ã¡ã‚‹ã‚ˆã†ã«ã—ã¦ã„ã¾ã™ã€‚
        ///
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo, segtree};
        ///
        /// let seg: Segtree<AddInfo<u8>> = segtree![4, 6, 3];
        ///
        /// for i in 0..3 {
        ///     for j in i..3 {
        ///         assert_eq!(seg.fold(i, j), seg[i..j].iter().sum::<u8>());
        ///     }
        /// }
        /// ```
        ///
        pub fn fold(&self, mut l: usize, mut r: usize) -> Info::Value {
            assert!(l <= r && r <= self.len());
            l += self.len();
            r += self.len();
            let mut fl = Info::id();
            let mut fr = Info::id();
            while l < r {
                if l % 2 == 1 {
                    Info::op_assign(&mut fl, &self.0[l]);
                    l += 1;
                }
                if r % 2 == 1 {
                    r -= 1;
                    Info::op_assign(&mut fr, &self.0[r]);
                }
                l /= 2;
                r /= 2;
            }
            Info::op(&fl, &fr)
        }

        /// å…¨åŒºé–“ã§ç•³ã¿è¾¼ã¿ã‚’ã—ã¾ã™ã€‚
        /// 2 å†ªã«åºƒã’ã¦ãŠã‚‰ãšã€ã¾ãŸå¯æ›æ€§ã‚‚ä»®å®šã—ã¦ãŠã‚‰ãšã§ã™ã‹ã‚‰ã€å¯¾æ•°æ™‚é–“ã‹ã‹ã‚Šã¾ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo, segtree};
        ///
        /// let seg: Segtree<AddInfo<u8>> = segtree![4, 6, 3];
        ///
        /// assert_eq!(seg.fold_all(), 13);
        /// ```
        ///
        pub fn fold_all(&self) -> Info::Value {
            self.fold(0, self.len())
        }

        fn rebuild_one_leaf(&mut self, mut i: usize) {
            i /= 2;
            while 0 != i {
                self.0[i] = Info::op(&self.0[2 * i], &self.0[2 * i + 1]);
                i /= 2
            }
        }

        fn rebuild(&mut self) {
            for i in (1..self.len()).rev() {
                self.0[i] = Info::op(&self.0[2 * i], &self.0[2 * i + 1]);
            }
        }
    }

    impl<Info: SegInfo> std::convert::From<Vec<Info::Value>> for Segtree<Info> {
        /// Vec ã‹ã‚‰æ§‹ç¯‰ã—ã¾ã™ã€‚
        ///
        /// # Example
        ///
        /// ```
        /// use segtree::{Segtree, AddInfo};
        /// let mut seg = Segtree::<AddInfo<u8>>::from(vec![3, 4, 6]);
        ///
        /// assert_eq!(seg.as_slice(), [3, 4, 6]);
        /// ```
        ///
        fn from(vec: Vec<Info::Value>) -> Self {
            let mut vec1 = Vec::with_capacity(vec.len() * 2);
            vec1.resize(vec.len(), Info::id());
            vec1.extend(vec);
            let mut seg = Self(vec1);
            seg.rebuild();
            seg
        }
    }

    impl<Info: SegInfo, I: std::slice::SliceIndex<[Info::Value]>> std::ops::Index<I> for Segtree<Info> {
        type Output = I::Output;

        /// å¯¾å¿œã™ã‚‹é…åˆ—ã®è¦ç´ ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ã™ã€‚
        ///
        /// # Examples
        ///
        /// ```
        /// use segtree::{segtree, Segtree, AddInfo};
        ///
        /// let seg: Segtree<AddInfo<u8>> = segtree![4, 6, 3];
        /// assert_eq!(seg[1], 6);
        ///
        /// let seg: Segtree<AddInfo<u8>> = segtree![4, 6, 3];
        /// assert_eq!(seg[1..=2], [6, 3]);
        /// ```
        ///
        #[inline]
        fn index(&self, index: I) -> &Self::Output {
            std::ops::Index::index(self.as_slice(), index)
        }
    }

    impl<Info: SegInfo> std::fmt::Debug for Segtree<Info> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.debug_list().entries(self.as_slice()).finish()
        }
    }

    /// `vec!` ãƒžã‚¯ãƒ­ã¨ `Segtree::from` ã‚’åˆæˆã§ã™ã€‚
    ///
    /// # Examples
    ///
    /// ```
    /// use segtree::{segtree, Segtree, AddInfo};
    ///
    /// let seg: Segtree<AddInfo<u8>> = segtree![4; 10];
    /// assert_eq!(seg.vec(), vec![4; 10]);
    ///
    /// let seg: Segtree<AddInfo<u8>> = segtree![4, 6, 3];
    /// assert_eq!(seg.vec(), vec![4, 6, 3]);
    /// ```
    ///
    #[macro_export]
    macro_rules! segtree {
        ($($elem:expr),*$(,)?) => {
            Segtree::from(vec![$($elem),*])
        };
        ($elem:expr; $n:expr) => {
            Segtree::from(vec![$elem; $n])
        };
    }

    #[cfg(test)]
    mod tests {
        use super::*;

        #[test]
        fn test_range_minimum_queries_sample_1() {
            let n = 3;
            let queries = vec![(0, 0, 1), (0, 1, 2), (0, 2, 3), (1, 0, 2), (1, 1, 2)];
            let mut ans = vec![];

            let mut seg: Segtree<MinInfo<u32>> = segtree![0; n];
            for (c, x, y) in queries {
                match c {
                    0 => {
                        let (i, x) = (x as usize, y);
                        seg.set(i, x);
                    }
                    1 => {
                        let (l, r) = (x as usize, y as usize + 1);
                        ans.push(seg.fold(l, r));
                    }
                    _ => panic!(),
                }
            }

            let expected = vec![1, 2];
            assert_eq!(ans, expected);
        }

        #[test]
        fn test_range_sum_queries_sample_1() {
            let n = 3;
            let queries = vec![(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 1, 2), (1, 2, 2)];
            let mut ans = vec![];

            let mut seg: Segtree<AddInfo<u32>> = segtree![0; n];
            for (c, x, y) in queries {
                match c {
                    0 => {
                        let (i, x) = (x as usize - 1, y);
                        seg.modify(i, |y| *y += x);
                    }
                    1 => {
                        let (l, r) = (x as usize - 1, y as usize);
                        ans.push(seg.fold(l, r));
                    }
                    _ => panic!(),
                }
            }

            let expected = vec![3, 2];
            assert_eq!(ans, expected);
        }
    }
}
//}}}

use segtree::{AddInfo, Segtree};

fn main() {
    input!(s: proconio::marker::Chars);
    let mut mul = vec![0; 26];
    s.iter().for_each(|&c| mul[(c as u8 - b'a') as usize] += 1);
    if 1 < mul.iter().copied().filter(|&x| x % 2 == 1).count() {
        println!("-1");
        std::process::exit(0);
    }
    let n = s.len();
    let mut left_count = 0;
    let mut right_count = 0;
    let mut ans = 0;
    let mut left = vec![vec![]; 26];
    let mut right = vec![vec![]; 26];
    let mut left_seq = vec![];
    let mut center = false;
    for c in s {
        let x = (c as u8 - b'a') as usize;
        if left[x].len() < mul[x] / 2 {
            left[x].push(left_count);
            left_seq.push((left_count, x));
            left_count += 1;
            ans += right_count;
            if center {
                ans += 1;
            }
        } else if mul[x] % 2 == 1 && !center {
            center = true;
            ans += right_count;
        } else {
            right[x].push(n / 2 - 1 - right_count);
            right_count += 1;
        }
    }

    let mut p = vec![0; n / 2];
    for (i, x) in left_seq {
        let j = right[x].pop().unwrap();
        p[i] = j;
    }

    let mut seg: Segtree<AddInfo<usize>> = segtree![0; n / 2];
    for x in p {
        ans += seg.fold(x, n / 2);
        seg.set(x, 1);
    }

    println!("{}", ans);
}


Measured memory_bytes: 6624