//
//  main.cpp
//
 
#include <algorithm>
#include <array>
#include <assert.h>
#include <functional>
#include <iostream>
#include <iomanip>
#include <limits>
#include <map>
#include <math.h>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
 
using namespace std;
 
using ll = long long;
using ull = unsigned long long;
 
template<typename T>
vector<T> make_vec_nd(T init, size_t size) {
	return vector<T>(size, init);
}
template<typename T, typename... Args>
auto make_vec_nd(T init, size_t size, Args... rest) {
	auto inner = make_vec_nd(init, rest...);
	return vector<decltype(inner)>(size, inner);
}

#define rep(i,a,b) for(ll i=(a);i<(b);i++)
#define rrep(i,a,b) for(ll i=(a)-1;i>=(b);i--)

template<typename Monoid>
struct SegmentTree {
	using Op = function<Monoid(const Monoid& lhs, const Monoid& rhs)>;
	size_t width;
	vector<Monoid> node;
	Op op;
	Monoid unit;
 
	SegmentTree(const vector<Monoid>& elems, Op op, Monoid unit)
	: op(op)
	, unit(unit) {
		width = 1;
		while (width < elems.size()) {
			width *= 2;
		}
		node.resize(2 * width - 1, unit);
		for (size_t i = 0; i < elems.size(); i++) {
			node[i + width - 1] = elems[i];
		}
		for (size_t i = width - 2; i != numeric_limits<size_t>::max(); i--) {
			node[i] = op(node[2 * i + 1], node[2 * i + 2]);
		}
	}
	void update(size_t idx, Monoid elem) {
		idx += width - 1;
		node[idx] = elem;
		while (idx >= 1) {
			idx = (idx - 1) / 2;
			node[idx] = op(node[2 * idx + 1], node[2 * idx + 2]);
		}
	}
	Monoid query(size_t a, size_t b, size_t root = 0) const {
		assert(0 <= a && b <= width);
		size_t left = root, right = root;
		while (left < width - 1) {
			left = 2 * left + 1;
		}
		left -= (width - 1);
		while (right < width - 1) {
			right = 2 * right + 2;
		}
		right -= (width - 1);
		right++;
		if (right <= a || b <= left) {
			return unit;
		}
		if (a <= left && right <= b) {
			return node[root];
		}
		Monoid ans_l = query(a, b, 2 * root + 1);
		Monoid ans_r = query(a, b, 2 * root + 2);
		return op(ans_l, ans_r);
	}
};

int main() {
	ll N;
	cin >> N;
	vector<ll> As(N);
	rep(i,0,N) {
		ll A;
		cin >> As[i];
	}
	vector<ll> Bs(N);
	rep(i,0,N) {
		cin >> Bs[i];
	}
	struct Card {
		ll idx;
		ll A;
		ll B;
	};
	vector<Card> cards(N);
	rep(i,0,N) {
		cards[i].idx = i;
		cards[i].A = As[i];
		cards[i].B = Bs[i];
	}
	ll even_cnt = (N%2==0) ? N/2 : (N/2+1);
	ll ans = numeric_limits<ll>::max();
	rep(even_pos,0,1<<N) {
		ll cnt = 0;
		rep(i,0,N) {
			if (even_pos & (1 << i)) {
				cnt++;
			}
		}
		if (cnt != even_cnt) {
			continue;
		}
		vector<Card> evens;
		vector<Card> odds;
		rep(i,0,N) {
			if (even_pos & (1 << i)) {
				evens.push_back(cards[i]);
			} else {
				odds.push_back(cards[i]);
			}
		}
		auto eval_at = [](ll pos, const Card& card) -> ll {
			if (card.idx % 2 == pos % 2) {
				return card.A;
			} else {
				return card.B;
			}
		};
		sort(evens.begin(), evens.end(), 
		[&eval_at](const auto& lhs, const auto& rhs){
			return eval_at(0, lhs) < eval_at(0, rhs);
		});
		sort(odds.begin(), odds.end(), 
		[&eval_at](const auto& lhs, const auto& rhs){
			return eval_at(1, lhs) < eval_at(1, rhs);
		});
		vector<Card> sorted;
		rep(i,0,N) {
			if (i%2 == 0) {
				sorted.push_back(evens[i/2]);
			} else {
				sorted.push_back(odds[i/2]);
			}
		}
		bool ok = true;
		rep(i,1,N) {
			if (eval_at(i-1, sorted[i-1]) > eval_at(i, sorted[i])) {
				ok = false;
				break;
			}
		}
		if (!ok) {
			continue;
		}
		SegmentTree<ll> tree(vector<ll>(N, 0), 
							 [](ll lhs, ll rhs){ return lhs + rhs; }, 
							 0);
		ll ans_loc = 0;
		rep(i,0,N) {
			ans_loc += sorted[i].idx + tree.query(sorted[i].idx, N) - i;
			tree.update(sorted[i].idx, 1);
		}
		ans = min(ans, ans_loc);
	}
	if (ans == numeric_limits<ll>::max()) {
		cout << -1 << endl;
	} else {
		cout << ans << endl;
	}
}


Measured memory_bytes: 384