<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

170. Particles
time limit per test: 0.25 sec.
memory limit per test: 4096 KB
input: standard
output: standard



A new kind of elementary particles was discovered in recent physical experiments. These particles were named "buons". It was also discovered that there exist two types of buons, which were named "Y+" (psi +) and "Y-" (psi -) buons. It became known that buons tend to form chains. Moreover, a very interesting property of buons, named "going through", was discovered: if two buons with different types are neighbors in a chain, they can easily exchange places one with other.

Because one "going through" takes very short time, the order of buons in chain can quickly change. Now the physicists are interested, how many "goings through" must happen for one chain to become other.

You are to help them. Write a program, which determines the minimal number of "goings through" which will allow one chain to become other.

Input
First two lines of input contains strings of "+" and "-" characters, describing first and second buon chains. The "+" character stands for Y+ buon, and "-" character stands for Y- buon. The length of each string doesn't exceed 5000; moreover, there is at leat one buon in each chain.

Output
If it is possible to make the second chain from the first, using only "goings trough", write on the first line of output the minimal number K of "goings through" which are required. If it is impossible to make the secong chain from the first, output only integer "-1".

Sample test(s)

Input
++-+--+
-++--++

Output
4
Author:	NNSU #2 team
Resource:	Compiled from many sources
Date:

<|response|>
1. Abridged Problem Statement  
Given two strings A and B of equal length n (n ≤ 5000), each character is either '+' or '-'. You may repeatedly swap any adjacent pair “+-” into “-+”. Determine the minimum number of such swaps (called “goings through”) needed to transform A into B, or output –1 if it is impossible.

2. Key Observations  
- A swap only exchanges a ‘+’ and a ‘–’ when they are adjacent.  
- You can never change the relative order of the ‘+’ characters among themselves, nor the relative order of the ‘–’ characters among themselves.  
- Hence, transforming A into B is possible if and only if A and B have the same total number of ‘+’ characters (and thus the same number of ‘–’ characters).  
- If possible, label the ‘+’ characters in A from 1…k in left-to-right order, and do the same in B; likewise label the ‘–’ from 1…m in each string.  
- Each character in A has a unique matching character in B (the same label and same sign).  
- Build an array P of length n so that P[i] = index in B of the character that matches A[i].  
- Each adjacent swap of “+-” ↔ “-+” in A corresponds to swapping two adjacent entries in P. The minimum number of such adjacent swaps needed to reorder P into sorted order is exactly the inversion count of P.

3. Full Solution Approach  
a) Read strings A and B.  
b) Scan A to record two lists: posA = positions of '+'; negA = positions of '-'.  
   Do the same for B: posB, negB.  
c) If posA.size() ≠ posB.size(), print –1 and stop.  
d) We want to match the i-th plus in A to the i-th plus in B, and similarly each minus.  
   To build P in a single left-to-right pass on A, reverse posB and negB (so we can pop from the back).  
e) Initialize empty array P. For i = 0…n–1:  
   - If A[i] == '+', take idx = posB.back(), pop_back(), and append idx to P.  
   - Else (A[i] == '-'), take idx = negB.back(), pop_back(), and append idx to P.  
f) Compute the inversion count of P in O(n log n) by a merge-sort based routine.  
g) Print the inversion count.

4. C++ implementation
```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

string a, b;

void read() { cin >> a >> b; }

pair<vector<int>, vector<int>> get_pos_plus_minus(const string& s) {
    vector<int> pos, neg;
    for(int i = 0; i < (int)s.size(); i++) {
        if(s[i] == '+') {
            pos.push_back(i);
        } else {
            neg.push_back(i);
        }
    }
    return {pos, neg};
}

int64_t count_inversions(vector<int> a) {
    function<int64_t(vector<int>&, int, int)> merge_sort = [&](vector<int>& a,
                                                               int l, int r) {
        if(l == r) {
            return 0LL;
        }
        int m = (l + r) / 2;
        int64_t ans = merge_sort(a, l, m) + merge_sort(a, m + 1, r);
        vector<int> b;
        int i = l, j = m + 1;
        while(i <= m && j <= r) {
            if(a[i] <= a[j]) {
                b.push_back(a[i++]);
            } else {
                b.push_back(a[j++]);
                ans += m - i + 1;
            }
        }
        while(i <= m) {
            b.push_back(a[i++]);
        }
        while(j <= r) {
            b.push_back(a[j++]);
        }
        for(int i = l; i <= r; i++) {
            a[i] = b[i - l];
        }
        return ans;
    };

    return merge_sort(a, 0, a.size() - 1);
}

void solve() {
    // Adjacent swaps of unlike particles preserve the relative order of the
    // '+' particles among themselves and of the '-' particles among
    // themselves, so a transformation exists only if both strings have the
    // same count of each sign. When it does, the i-th '+' of a must become the
    // i-th '+' of b (likewise for '-'). Build the target permutation perm:
    // perm[i] is the final position (index in b) of the particle at position i
    // in a. The minimum number of adjacent swaps equals the number of
    // inversions of perm, counted with a merge sort.

    auto [pos_a, neg_a] = get_pos_plus_minus(a);
    auto [pos_b, neg_b] = get_pos_plus_minus(b);

    if(pos_a.size() != pos_b.size() || neg_a.size() != neg_b.size()) {
        cout << -1 << '\n';
        return;
    }

    reverse(pos_b.begin(), pos_b.end());
    reverse(neg_b.begin(), neg_b.end());
    vector<int> perm;
    for(int i = 0; i < (int)a.size(); i++) {
        if(a[i] == '+') {
            perm.push_back(pos_b.back());
            pos_b.pop_back();
        } else {
            perm.push_back(neg_b.back());
            neg_b.pop_back();
        }
    }

    cout << count_inversions(perm) << '\n';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

5. Python Implementation with Detailed Comments  
```python
import sys
sys.setrecursionlimit(10000)

def count_inversions(arr):
    # Merge-sort based inversion count
    def merge_sort(a, l, r):
        if l >= r:
            return 0
        m = (l + r) // 2
        inv = merge_sort(a, l, m) + merge_sort(a, m+1, r)
        temp = []
        i, j = l, m+1
        while i <= m and j <= r:
            if a[i] <= a[j]:
                temp.append(a[i])
                i += 1
            else:
                temp.append(a[j])
                j += 1
                inv += (m - i + 1)
        while i <= m:
            temp.append(a[i]); i += 1
        while j <= r:
            temp.append(a[j]); j += 1
        # copy back
        for k in range(l, r+1):
            a[k] = temp[k - l]
        return inv

    # Work on a copy if original must be preserved
    return merge_sort(arr, 0, len(arr)-1)

def main():
    A = sys.stdin.readline().strip()
    B = sys.stdin.readline().strip()
    n = len(A)

    posA = [i for i,ch in enumerate(A) if ch == '+']
    negA = [i for i,ch in enumerate(A) if ch == '-']
    posB = [i for i,ch in enumerate(B) if ch == '+']
    negB = [i for i,ch in enumerate(B) if ch == '-']

    # If counts differ, impossible
    if len(posA) != len(posB):
        print(-1)
        return

    # Reverse so pop() gives next match in left-to-right order
    posB.reverse()
    negB.reverse()

    P = []
    for ch in A:
        if ch == '+':
            P.append(posB.pop())
        else:
            P.append(negB.pop())

    # The answer is the inversion count of P
    print(count_inversions(P))

if __name__ == "__main__":
    main()
```