#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <utility>
#include <cstdlib>
#include <memory>
#include <queue>
#include <cassert>
#include <cmath>
#include <ctime>
#include <complex>
#include <bitset>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <numeric>

using namespace std;

#define ws ws_____________________
#define y1 y1_____________________
#define y0 y0_____________________
#define left left_________________
#define right right_______________
#define next next_________________
#define prev prev_________________
#define hash hash_________________

#define pb push_back
#define fst first
#define snd second
#define mp make_pair 
#define sz(C) ((int) (C).size())
#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; --i)
#define all(C) begin(C), end(C)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef long double ld;
typedef complex<double> cd;

#ifdef LOCAL
#define eprintf(args...) fprintf(stderr, args), fflush(stderr)
#else
#define eprintf(...) ;
#endif

#define FILE_NAME "a"

#define TEST 0

const int A = 26;

vi s;

bool read() {
#if !TEST
	string t;
	if  (!getline(cin, t)) {
		return 0;
	}
	s.resize(sz(t));
	forn(i, sz(t)) {
		s[i] = t[i] - 'a';
	}
#else
	const int n = 1 + rand() % 10;
	s.resize(n);
	forn(i, n) {
		s[i] = rand() % A;
	}
#endif
	return 1;
}

struct FenwTree {
	vi t;

	FenwTree(int n = 0) {
		t.assign(n, 0);
	}

	int get(int r) {
		int s = 0;
		for (int i = r; i >= 0; i &= i + 1, --i) {
			s += t[i];
		}
		return s;
	}

	int get(int l, int r) {
		if  (l > r) {
			return 0;
		}
		return get(r) - get(l - 1);
	}

	void upd(int pos, int val) {
		for (int i = pos; i < sz(t); i |= i + 1) {
			t[i] += val;
		}
	}
};

ll old_solve() {
	vi cnt(A);
	for (int c : s) {
		++cnt[c];
	}

	int odd_c = -1;
	forn(c, A) {
		if  (cnt[c] & 1) {
			if  (odd_c != -1) {
				return -1;
			}
			odd_c = c;
		}
	}

	ll ans = 0;
	if  (odd_c != -1) {
		{
			int ptr = 0;
			forn(i, sz(s)) {
				if  (s[i] == odd_c) {
					const int need_pos = sz(s) / 2 - cnt[odd_c] / 2 + ptr;
					int pos = i;
					while (pos > need_pos) {
						assert(s[pos] != s[pos - 1]);
						swap(s[pos], s[pos - 1]);
						--pos;
						++ans;
					}
					++ptr;
					if  (ptr > cnt[odd_c] / 2) {
						break;
					}
				}
			}
		}
		{
			int ptr = 0;
			ford(i, sz(s)) {
				if  (s[i] == odd_c) {
					const int need_pos = sz(s) / 2 + cnt[odd_c] / 2 - ptr;
					int pos = i;
					while (pos < need_pos) {
						assert(s[pos] != s[pos + 1]);
						swap(s[pos], s[pos + 1]);
						++pos;
						++ans;
					}
					++ptr;
					if  (ptr > cnt[odd_c] / 2) {
						break;
					}
				}
			}
		}
	}

	vvi poses(A);
	forn(i, sz(s)) {
		poses[s[i]].pb(i);
	}

	vi other(sz(s), -1);
	forn(c, A) {
		forn(i, sz(poses[c]) / 2) {
			const int pos = poses[c][i];
			const int pos2 = poses[c][sz(poses[c]) - 1 - i];
			assert(pos < pos2);
			other[pos] = pos2;
			other[pos2] = pos;
		}
	}

	// not intersecting
	{
		int seen = 0;
		forn(i, sz(s)) {
			if  (other[i] == -1) {
				assert(i == sz(s) / 2);
				continue;
			}
			if  (other[i] > i) {
				ans += seen * 2;
			} else {
				++seen;
			}
		}
	}

	// intersecting
	{
		FenwTree T(sz(s));
		forn(i, sz(s)) {
			if  (other[i] == -1) {
				assert(i == sz(s) / 2);
				continue;
			}
			if  (other[i] > i) {
				ans += T.get(i + 1, other[i] - 1);
				T.upd(other[i], +1);
			}
		}
	}

	if  (odd_c != -1) {
		// left from center
		{
			int seen = 0;
			forn(i, sz(s) / 2) {
				assert(other[i] != -1);
				if  (other[i] < i) {
					++seen;
				}
			}
			ans += seen;
		}

		// right from center
		{
			int seen = 0;
			for (int i = sz(s) / 2 + 1; i < sz(s); ++i) {
				assert(other[i] != -1);
				if  (i < other[i]) {
					++seen;
				}
			}
			ans += seen;
		}
	}

	return ans;
}

ll new_solve() {
	vi cnt(A);
	for (int c : s) {
		++cnt[c];
	}

	int odd_c = -1;
	forn(c, A) {
		if  (cnt[c] & 1) {
			if  (odd_c != -1) {
				return -1;
			}
			odd_c = c;
		}
	}

	vvi poses(A);
	forn(i, sz(s)) {
		poses[s[i]].pb(i);
	}

	vi other(sz(s), -1);
	forn(c, A) {
		forn(i, sz(poses[c]) / 2) {
			const int pos = poses[c][i];
			const int pos2 = poses[c][sz(poses[c]) - 1 - i];
			assert(pos < pos2);
			other[pos] = pos2;
			other[pos2] = pos;
		}
	}

	vi fin(sz(s), -1);
	int seen = 0;
	forn(i, sz(s)) {
		if  (i < other[i]) {
			fin[i] = seen;
			fin[other[i]] = sz(s) - 1 - seen;
			++seen;
		}
	}
	forn(i, sz(s)) {
		if  (fin[i] == -1) {
			assert(s[i] == odd_c);
			fin[i] = sz(s) / 2;
			break;
		}
	}

	ll ans = 0;
	FenwTree T(sz(s));
	forn(i, sz(s)) {
		ans += T.get(fin[i] + 1, sz(s) - 1);
		T.upd(fin[i], +1);
	}

	return ans;
}

int main() {
#ifdef LOCAL
	freopen(FILE_NAME ".in", "r", stdin);
	// freopen(FILE_NAME ".out", "w", stdout);
#endif

#if TEST
	while (1) {
		read();

		eprintf("s:\n");
		forn(i, sz(s)) {
			eprintf("%c", 'a'+s[i]);
		}
		eprintf("\n");

		solve();
	}
#endif

	while (read()) {
		printf("%lld\n", new_solve());
	}

#ifdef LOCAL
	eprintf("Time: %.10f\n", (double) clock() / CLOCKS_PER_SEC);
#endif
	return 0;
}


Measured memory_bytes: 4668