#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <functional>
#include <bitset>
#include <cassert>
using namespace std;
using ll = long long;

class LazySegmentTree {
	// TODO: Change Monid and Operator, their identity, their product, and the action.
	using Monoid = ll;
	const Monoid INI_MONOID = 0;
	Monoid monoid_product(const Monoid &a, const Monoid &b) {
		return a + b;
	}

	using Operator = ll;
	const Operator INI_OPERATOR = 0;
	// p(q(a)) (i.e., not q(p(a)))
	Operator operator_product(const Operator &p, const Operator &q) {
		return p + q;
	}

	// a |-> b = (p, n)(a)
	// n: Length of the range.
	Monoid act(const Operator &p, int n, const Monoid &a) {
		return p*n + a;
	}


	int num;
	vector<Monoid> dat_mono;
	vector<Operator> dat_op;

public:
	LazySegmentTree(int n) {
		num = 1;
		while (num < n) num *= 2;
		dat_mono = vector<Monoid>(2 * num, INI_MONOID);
		dat_op = vector<Operator>(2 * num, INI_OPERATOR);
	}

	LazySegmentTree(const vector<Monoid> &m) : LazySegmentTree(m.size()) {
		int n = m.size();
		for (int i = 0; i < n; i++) {
			dat_mono[num - 1 + i] = m[i];
		}
		for (int i = num - 2; i >= 0; i--) {
			dat_mono[i] = monoid_product(dat_mono[2 * i + 1], dat_mono[2 * i + 2]);
		}
	}

	// Apply the operator q to the range [a, b).
	// k: The index of the node.
	// Call like apply(q, a, b)
	void apply(Operator q, int a, int b, int k = 0, int left = 0, int right = -1) {
		if (right < 0) right = num;
		if (right <= a || b <= left) return;
		if (a <= left && right <= b) {
			dat_mono[k] = act(q, right - left, dat_mono[k]);
			dat_op[k] = operator_product(q, dat_op[k]);
			return;
		}
		apply(dat_op[k], left, left + (right - left) / 2, 2 * k + 1, left, left + (right - left) / 2); // Left side
		apply(dat_op[k], left + (right - left) / 2, right, 2 * k + 2, left + (right - left) / 2, right); // Right side
		dat_op[k] = INI_OPERATOR;
		apply(q, a, b, 2 * k + 1, left, left + (right - left) / 2); // Left side
		apply(q, a, b, 2 * k + 2, left + (right - left) / 2, right); // Right side
		dat_mono[k] = monoid_product(dat_mono[2 * k + 1], dat_mono[2 * k + 2]);
	}

	// Get the value of the range [a, b).
	// k: The index of the node.
	// [left, right): The range corresponds to the k-th node.
	// Call like getval(a, b).
	Monoid getval(int a, int b, int k = 0, int left = 0, int right = -1) {
		if (right < 0) right = num;
		if (right <= a || b <= left) return INI_MONOID;
		if (a <= left && right <= b) return dat_mono[k];
		Monoid vleft = getval(a, b, 2 * k + 1, left, left + (right - left) / 2); // Left side
		Monoid vright = getval(a, b, 2 * k + 2, left + (right - left) / 2, right); // Right side
		return act(dat_op[k], max(0, min(b, right) - max(a, left)), monoid_product(vleft, vright));
	}
};


int main() {
	string s; cin >> s;
	int n = s.size();
	vector<int> cnt(30);
	for (char c : s) cnt[c - 'a']++;
	int odd = 0;
	for (int i = 0; i <= 'z' - 'a'; i++) odd += cnt[i] & 1;
	if (n % 2 != odd) {
		cout << -1 << endl;
		return 0;
	}

	vector<deque<int>> ids(30);
	for (int i = 0; i < n; i++) ids[s[i] - 'a'].push_back(i);
	LazySegmentTree segl(n), segr(n);
	ll ans = 0;
	for (int i = 0; i < n / 2; i++) {
		int mi = 1e9, minc;
		for (int c = 0; c <= 'z' - 'a'; c++) {
			if (ids[c].empty()) continue;
			if (ids[c].front() == ids[c].back()) continue;

			int left = ids[c].front(), right = ids[c].back();
			int sc = left + (n - 1 - right) + segl.getval(left, left + 1) + segr.getval(right, right + 1);

			if (sc < mi) {
				mi = sc;
				minc = c;
			}
		}

		int left = ids[minc].front(), right = ids[minc].back();
		ids[minc].pop_front(); ids[minc].pop_back();
		ans += mi;
		segl.apply(-1, left + 1, n);
		segr.apply(-1, 0, left);
		segr.apply(-1, 0, right);
		segl.apply(-1, right + 1, n);
	}
	cout << ans << endl;
	return 0;
}


Measured memory_bytes: 19716