//#pragma warning(disable:4996)
#include <iostream>
#include <vector>
#include <limits.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <limits.h>
#include <queue>
#include <map>
#include <set>
#include <iomanip>
#include <bitset>
#include <cassert>
#include <random>
#include <functional>
#include <stack>
#include <iomanip>
#include <cassert>
//#include <boost/multiprecision/cpp_int.hpp>
#include <complex>
#include <cstdio>
#include <list>
#include <bitset>
//#include <stdio.h>

//< in.txt > out.txt
using namespace std;
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
const long long MOD = 1e9+7;
const long long INF = 1e15;
typedef long long LL;
typedef long double LD;
//typedef boost::multiprecision::cpp_int bigint;
typedef pair<LL, LL> PLL;
typedef pair<int, int> PI;
typedef pair<LD, LL> pdl;
typedef pair<LD, LD> pdd;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef vector<int> VI;
typedef vector<vector<int>> VVI;
typedef unsigned long long ULL;

//TT(T,T):=モノイドの乗算
//require Monoid
template<class T>
class Segtree {
private:
	vector<T> seg;
	LL RN;
	typedef function<T(T, T)> TT;
	TT f;
	T te;
public:
	Segtree(LL N, TT _f, T e) :te(e) {
		RN = 1;
		while (RN < N)RN *= 2;
		seg.resize(2 * RN, te);
		f = _f;
	}
	Segtree(vector<T>& V, TT _f, T e) :te(e) {
		LL N = V.size();
		RN = 1;
		while (RN < N)RN *= 2;
		seg.resize(2 * RN, te);
		f = _f;
		for (LL n = 0; n < N; n++) seg[RN + n] = V[n];
		for (LL k = RN - 1; k >= 1; k--) {
			seg[k] = f(seg[2 * k], seg[2 * k + 1]);
		}
	}
	//set n-th as x(0 index!!!!!)
	void set(LL n, T x) {
		seg[RN + n] = x;
		n = (RN + n) / 2;
		while (n >= 1) {
			seg[n] = f(seg[2 * n], seg[2 * n + 1]);
			n /= 2;
		}
	}
	//change n-th number p to x*p(0 index!!!!!)
	void addl(LL n, T x) {
		seg[RN + n] = f(x, seg[RN + n]);
		n = (RN + n) / 2;
		while (n >= 1) {
			seg[n] = f(seg[2 * n], seg[2 * n + 1]);
			n /= 2;
		}
	}
	//change n-th number p to p*x(0 index!!!!!)
	void addr(LL n, T x) {
		seg[RN + n] = f(seg[RN + n], x);
		n = (RN + n) / 2;
		while (n >= 1) {
			seg[n] = f(seg[2 * n], seg[2 * n + 1]);
			n /= 2;
		}
	}
	//get [l,r] (0 index!!!!!)
	T get(LL l, LL r) {
		T ansl = te, ansr = te;
		r++;
		l += RN;
		r += RN;
		while (l < r) {
			if (l & 1) {
				ansl = f(ansl, seg[l]);
				l++;
			}
			if (r & 1) {
				r--;
				ansr = f(seg[r], ansr);
			}
			l >>= 1;
			r >>= 1;
		}
		return f(ansl, ansr);
	}
	//get n-th number(0 index!!!!!)
	T get(LL n) {
		return seg[RN + n];
	}
	T operator[](LL n) {
		return seg[RN + n];
	}
};

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	string str;
	cin >> str;
	int N = str.size();
	VI S(N, 0);
	for (int n = 0; n < N; n++) {
		S[n] = str[n] - 'a';
	}
	VVI count(26);
	for (int n = 0; n < N; n++) {
		count[S[n]].push_back(n);
	}
	int mod1 = 0;
	for (int c = 0; c < 26; c++) {
		mod1 += (count[c].size() % 2);
	}
	if (mod1 != N % 2) {
		cout << -1 << "\n";
		return 0;
	}
	int mod1pos = 0;
	if (N % 2 == 1) {
		for (int c = 0; c < 26; c++) {
			if (count[c].size() % 2 == 1) {
				mod1pos = count[c][count[c].size() / 2];
			}
		}
	}
	VI pos(N);
	VI pushed(26, 0);
	int p = 0;
	int n = 0;
	for (; n < N / 2; n++) {
		while (pushed[S[p]] >= count[S[p]].size()/2)p++;
		pos[n] = p;
		pushed[S[p]]++;
		p++;
	}
	if (N % 2 == 1) {
		pos[N / 2] = mod1pos;
		pushed[S[mod1pos]]++;
	}
	n = (N + 1) / 2;
	for (; n < N; n++) {
		int c = S[pos[N - 1 - n]];
		pos[n] = count[c][pushed[c]];
		pushed[c]++;
	}
	Segtree<int> seg(N, [](int a, int b) {return a + b; }, 0);
	VI order(N);
	for (int n = 0; n < N; n++)order[n] = n;
	sort(order.begin(), order.end(), [&](int a, int b) {
		return pos[a] > pos[b];
	});
	LL ans = 0;
	for (int i = 0; i < N; i++) {
		n = order[i];
		if(n > 0)ans += (LL)seg.get(0, n - 1);
		seg.set(n, 1);
	}
	cout << ans << "\n";
	return 0;
}


Measured memory_bytes: 8584