Problem:
Score : 1000 points

Problem Statement

You have two strings A = A_1 A_2 ... A_n and B = B_1 B_2 ... B_n of the same length consisting of 0 and 1.

You can transform A using the following operations in any order and as many times as you want:

Shift A by one character to the left (i.e., if A = A_1 A_2 ... A_n, replace A with A_2 A_3 ... A_n A_1).

Shift A by one character to the right (i.e., if A = A_1 A_2 ... A_n, replace A with A_n A_1 A_2 ... A_{n-1}).

Choose any i such that B_i = 1. Flip A_i (i.e., set A_i = 1 - A_i).

You goal is to make strings A and B equal.

Print the smallest number of operations required to achieve this, or -1 if the goal is unreachable.

Constraints

1 \leq |A| = |B| \leq 2,000

A and B consist of 0 and 1.

Input

Input is given from Standard Input in the following format:

A
B

Output

Print the smallest number of operations required to make strings A and B equal, or -1 if the goal is unreachable.

Sample Input 1

1010
1100

Sample Output 1

3

Here is one fastest way to achieve the goal:

Flip A_1: A = 0010

Shift A to the left: A = 0100

Flip A_1 again: A = 1100

Sample Input 2

1
0

Sample Output 2

-1

There is no way to flip the only bit in A.

Sample Input 3

11010
10001

Sample Output 3

4

Here is one fastest way to achieve the goal:

Shift A to the right: A = 01101

Flip A_5: A = 01100

Shift A to the left: A = 11000

Shift A to the left again: A = 10001

Sample Input 4

0100100
1111111

Sample Output 4

5

Flip A_1, A_3, A_4, A_6 and A_7 in any order.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <cctype>
#include <functional>
#include <ctime>
#include <cmath>
#include <limits>
#include <numeric>
#include <type_traits>
#include <iomanip>
#include <float.h>
#include <math.h>
using namespace std;
using ll = long long;


unsigned euclidean_gcd(unsigned a, unsigned b) {
    if (a < b) return euclidean_gcd(b, a);
    unsigned r;
    while ((r = a % b)) {
        a = b;
        b = r;
    }
    return b;
}

class UnionFind {
public:
    vector <ll> par;
    vector <ll> siz;
    UnionFind(ll sz_) : par(sz_), siz(sz_, 1LL) {
        for (ll i = 0; i < sz_; ++i) par[i] = i;
    }
    void init(ll sz_) {
        par.resize(sz_);
        siz.assign(sz_, 1LL);
        for (ll i = 0; i < sz_; ++i) par[i] = i;
    }
    ll root(ll x) {
        while (par[x] != x) {
            x = par[x] = par[par[x]];
        }
        return x;
    }
    bool merge(ll x, ll y) {
        x = root(x);
        y = root(y);
        if (x == y) return false;
        if (siz[x] < siz[y]) swap(x, y);
        siz[x] += siz[y];
        par[y] = x;
        return true;
    }

    bool issame(ll x, ll y) {
        return root(x) == root(y);
    }

    ll size(ll x) {
        return siz[root(x)];
    }
};

long long modpow(long long a, long long n, long long mod) {
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

long long modinv(long long a, long long mod) {
    return modpow(a, mod - 2, mod);
}

int main() {
    string a, b;
    cin >> a >> b;
    ll s = a.size();
    b += b+b+b+b;
    ll ans = 12345678;
    vector<ll> kyu;
    for (int i = 0; i < 5*s; i++) {
        if (b.at(i) == '1')kyu.push_back(i);
    }
    if (kyu.size() == 0) {
        for (int i = 0; i < s; i++) {
            if (a.at(i) == '1')kyu.push_back(i);
        }
            if (kyu.size() != 0) { cout << -1 << endl;}
            else cout << 0 << endl;

    }
    else {
        for (int i = 0; i < s; i++) {
            ll zans = 0;
            vector<ll> need_change;
            vector<pair<ll, ll>> ddd;
            for (int j = 0; j < s; j++) {
                if (a.at(j) != b.at(2 * s + i + j)) {
                    zans++;
                    need_change.push_back(2 * s + j);
                }
            }
            ans = min(zans + s + i, ans);
            zans += i;
            for (int j = 0; j < need_change.size(); j++) {
                int ng = kyu.size();
                int ok = 0;
                while (abs(ok - ng) > 1) {
                    int mid = (ok + ng) / 2;

                    if (need_change.at(j) >= kyu.at(mid)) ok = mid;
                    else ng = mid;
                }
                int ngg = 0;
                int okk = kyu.size();
                while (abs(okk - ngg) > 1) {
                    int midd = (okk + ngg) / 2;

                    if (need_change.at(j) <= kyu.at(midd)) okk = midd;
                    else ngg = midd;
                }
                if (kyu.at(okk) - need_change.at(j) <= i)continue;
                ddd.push_back(make_pair(need_change.at(j) - kyu.at(ok), kyu.at(okk) - need_change.at(j) - i));
            }
            sort(ddd.begin(), ddd.end());
            reverse(ddd.begin(), ddd.end());
            ll cost = 999999999;
            if (ddd.size() == 0)cost = 0;
            else {
                ll smax = 0;
                for (int j = 0; j < ddd.size() - 1; j++) {
                    if (ddd.at(j).first == ddd.at(j + 1).first) {
                        ddd.at(j + 1).second = ddd.at(j).second;
                        ddd.at(j).second = 0;
                    }
                }
                for (int j = 0; j < ddd.size(); j++) {

                    cost = min(2 * (ddd.at(j).first + smax), cost);
                    smax = max(smax, ddd.at(j).second);
                }
                zans += cost;
            }
            ans = min(zans, ans);
        }
        for (int i = 0; i < s; i++) {
            ll zans = 0;
            vector<ll> need_change;
            vector<pair<ll, ll>> ddd;
            for (int j = 0; j < s; j++) {
                if (a.at(j) != b.at(2 * s - i + j)) {
                    zans++;
                    need_change.push_back(2 * s + j);
                }
            }
            ans = min(zans + s + i, ans);
            zans += i;
            for (int j = 0; j < need_change.size(); j++) {
                int ng = kyu.size();
                int ok = 0;
                while (abs(ok - ng) > 1) {
                    int mid = (ok + ng) / 2;

                    if (need_change.at(j) >= kyu.at(mid)) ok = mid;
                    else ng = mid;
                }
                int ngg = 0;
                int okk = kyu.size();
                while (abs(okk - ngg) > 1) {
                    int midd = (okk + ngg) / 2;

                    if (need_change.at(j) <= kyu.at(midd)) okk = midd;
                    else ngg = midd;
                }
                if (need_change.at(j)-kyu.at(ok) <= i)continue;
                ddd.push_back(make_pair(kyu.at(okk)- need_change.at(j), need_change.at(j) - kyu.at(ok) - i));
            }
            sort(ddd.begin(), ddd.end());
            reverse(ddd.begin(), ddd.end());
            ll cost = 999999999;
            if (ddd.size() == 0)cost = 0;
            else {
                ll smax = 0;
                for (int j = 0; j < ddd.size() - 1; j++) {
                    if (ddd.at(j).first == ddd.at(j + 1).first) {
                        ddd.at(j + 1).second = ddd.at(j).second;
                        ddd.at(j).second = 0;
                    }
                }
                for (int j = 0; j < ddd.size(); j++) {

                    cost = min(2 * (ddd.at(j).first + smax), cost);
                    smax = max(smax, ddd.at(j).second);
                }
                zans += cost;
            }
            ans = min(zans, ans);
        }
        cout << ans << endl;
    }
}