#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
using ll = long long;
using ull = unsigned long long; 
using pii =  pair<int, int>;
using pll =  pair<long long, long long>;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(x) (x).begin(),(x).end()
constexpr char ln =  '\n';
constexpr long long MOD = 1000000007LL;
//constexpr long long MOD = 998244353LL;
template<class T, class U> inline bool chmax(T &a, U b) { if (a < b) { a = b; return true;} return false; }
template<class T, class U> inline bool chmin(T &a, U b) { if (a > b) { a = b; return true;} return false; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
struct SegmentTree {
    int N;
    vector<T> node;

    SegmentTree() = default;
    SegmentTree(vector<T> &v) {init(v);}

    void init(vector<T> &v) {
        N = 1;
        int sz = v.size();
        while (N < sz) N *= 2;
        node.assign(2*N,0);
        for (int i = 0; i < sz; i++) node[i+N] = v[i];
        for (int i = N-1; i >= 1; i--) node[i] = node[i<<1|0] + node[i<<1|1];
    }

    void update(int x, T val) { // (0-indexed)
        x += N;
        node[x] += val;
        while (x > 1) {
            x >>= 1;
            node[x] = node[x<<1|0] + node[x<<1|1];
        }
    }

    T get(int l, int r) { // [l, r) (0-indexed)
        if (l >= r) return 0;
        T res = 0;
        l += N; r += N;
        while (l < r) {
            if (l & 1) res += node[l++];
            l >>= 1;
            if (r & 1) res += node[--r];
            r >>= 1;
        }
        return res;
    }

    T operator[](int x) {return node[x+N];}
};

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    string S; cin >> S;
    int N = S.size();

    vector<vector<int>> G(26);
    rep(i,N) G[S[i]-'a'].emplace_back(i);
    int z = 0;
    rep(i,26) {
        if (int(G[i].size())&1) z++;
    }
    if (z > 1) {
        cout << -1 << ln;
        return 0;
    }

    vector<int> L,R;
    rep(i,26) {
        if (G[i].empty()) continue;
        int l = 0;
        int r = G[i].size()-1;
        while (l <= r) {
            L.emplace_back(G[i][l]);
            R.emplace_back(G[i][r]);
            l++;
            r--;
        }
    }
    int M = L.size();
    vector<pii> A;
    rep(i,M) A.emplace_back(L[i],i);
    sort(all(A));
    set<pii> dic;
    int cur = 0;
    vector<int> cnt(N+1);
    ll p = 0, q = 0, v = 0;
    vector<int> arr(N);
    SegmentTree<int> seg(arr);
    rep(i,N) {
        cnt[i+1] = cnt[i];
        if (cur < M and A[cur].first==i) {
            if (i==R[A[cur].second]) v = M-1-dic.size();
            dic.emplace(R[A[cur].second],A[cur].second);
            p += cnt[i+1];
            seg.update(i,1);
            cur++;
        }
        if (!dic.empty() and dic.begin()->first==i) {
            int l = L[dic.begin()->second];
            q += seg.get(l+1,i);
            cnt[i+1]++;
            seg.update(l,-1);
            dic.erase(dic.begin());
        }
    }
    cout << p*2+q-v << ln;
}

Measured memory_bytes: 11276