#include <iostream>
#include <vector>
#include <string.h>
#include <set>
#include <map>
#include <unordered_map>
#include <assert.h>
#include <algorithm>
#include <queue>
#include <bitset>
#include <stack>
#include <chrono>
#include <random>
#define all(x) x.begin(),x.end()
#define ff first
#define ss second
#define ll long long
#define INF 1000000000000000000
#define MOD 1000000007
#define rnd mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define FIO ios_base::sync_with_stdio(false); cin.tie(NULL);
#define uid uniform_int_distribution <int>
using namespace std;
// Read the question carefully and see all the given sample tests
// Think about the correctness before implementing

/*
 * abab
 * bbaa
 * Can we prove that if we swap only a or b it doesn't matter
 * 
 * aabbabab
 * bbaababa
 * 
 * */
 
set <int> st[26];
int main() {
	string s;
	cin >> s;
	int n = (int) s.size();
	vector <int> lf(26), rf(26);
	for (int i = 0; i < n; i++) {
		if (i < n / 2) 
			lf[s[i] - 'a']++;
		else
			rf[s[i] - 'a']++;
	}
	int c = 0;
	char extra = 'A';
	for (int i = 0; i < 26; i++) {
		if ((lf[i] + rf[i]) % 2 != 0) {
			extra = char(i + 'a');
			c++;
		}
	}
	if (c > 1 || (c == 1 && n % 2 == 0)) {
		cout << -1;
		return 0;
	}
	c = 0;
	ll ans = 0;
	vector <bool> mark(n);
	string ls, rs;
	for (int i = n / 2 - 1; i >= 0; i--) {
		if (lf[s[i] - 'a'] > rf[s[i] - 'a'] + (s[i] == extra)) {
			mark[i] = 1;
			ans += (n / 2 - 1 - i) - (int) ls.size();
			ls.push_back(s[i]);
			lf[s[i] - 'a']--;
			rf[s[i] - 'a']++;
		}
	}
	for (int i = n / 2; i < n; i++) {
		if (rf[s[i] - 'a'] > lf[s[i] - 'a'] + (s[i] == extra)) {
			mark[i] = 1;
			ans += (i - n / 2) - (int) rs.size(); 
			rs.push_back(s[i]);
			rf[s[i] - 'a']--;
			lf[s[i] - 'a']++;
		}
	}
	//assert (abs((int) ls.size() - (int) rs.size()) <= 1);
	cerr << ls << " " << rs << "\n";
	reverse(all(ls));
	ans += 1LL * (int) ls.size() * (int) rs.size();
	string newS = "";
	for (int i = 0; i < n; i++) {
		if (i == n / 2) {
			newS += rs;
			newS += ls;
		}
		if (!mark[i])
			newS += s[i];
	}
	s = newS;
	cerr << s << " " << ans << "\n";
	int remPos = -1;
	int ce = (int) count(all(s), extra);
	int cc = 0;
	for (int i = 0; i < n; i++) {
		if (s[i] == extra) {
			cc++;
			if (cc == (ce + 1) / 2) {
				remPos = i;
			}
		}
	}
	if (remPos != -1) {
		ans += abs(n / 2 - remPos);
		s.erase(s.begin() + remPos);
		n -= 1;
	}
	string a = s.substr(0, n / 2);
	string b = s.substr(n / 2);
	reverse(all(b));
	cerr << a << " " << b << "\n";
	string ta = a, tb = b;
	sort(all(ta));
	sort(all(tb));
	assert (ta == tb);
	// make a and b equal by swapping characters in b
	for (int i = 0; i < n / 2; i++) {
		st[b[i] - 'a'].insert(i);
	}
	/*
	 * aabb
	 * bbaa
	 * 
	 * */
	vector <int> tree(n + 1);
	auto getsum = [&](int id) {
		int res = 0;
		while(id > 0) {
			res += tree[id];
			id -= (id & -id);
		}
		return res;
	};
	auto update = [&](int id, int val) {
		while(id < n) {
			tree[id] += val;
			id += (id & -id);
		}
	};
	int l = 0;
	vector <bool> vis(n / 2, false);
	for (int i = 0; i < n / 2; i++) {
		while(l < n / 2 && vis[l]) {
			update(l + 1, -1);
			l++;
		}
		// assert(l != n / 2);
		int req = a[i] - 'a';
		auto it = st[req].lower_bound(l);
		// assert (it != st[req].end());
		int reqPos = *it;
		int net = (reqPos - l) - getsum(reqPos + 1);
		// cerr << net << " " << l << " " << reqPos << "\n";
		vis[reqPos] = 1;
		update(reqPos + 1, 1);
		st[req].erase(reqPos);
		ans += net;
	}
	cout << ans;
}


Measured memory_bytes: 6684