#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <array>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <queue>
#include <bitset>
#include <tuple>
#include <cmath>
#include <complex>
#include <algorithm>
#include <utility>
#include <regex>
#include <cstdint>
#include <numeric>
#include <functional>
#include <cassert>

using namespace std;
using ll = int64_t;
using ull = uint64_t;

constexpr ll INF = 1'000'000'000'000'000'000;
namespace utils{
    template<class T, class Compare> using p_queue = priority_queue<T, vector<T>, Compare>;
    template<class T> using min_queue = p_queue<T, greater<T>>;
    template<class T> using max_queue = p_queue<T, less<T>>;

    template<class T> bool min_update(T& X, const T& A){ if(X > A) {X = A; return true;} return false; }
    template<class T> bool max_update(T& X, const T& A){ if(X < A) {X = A; return true;} return false; }
    using V_Set = unordered_set<int>;
    using E_Set = unordered_map<int, V_Set>;

    ll operator"" _64(unsigned long long x){ return ll(x); }

    ull operator"" _64u(unsigned long long x){ return ull(x); }

#define ALL(x) begin(x), end(x)
#define rALL(x) rbegin(x), rend(x)
}
using namespace utils;

class segtree{
    ll N;
    using val_type = pair<int, int>;
    vector<val_type > dat;

    val_type query(int a, int b, int k, int l, int r){
        if(r <= a || b <= l) return {-1, -1};

        if(a <= l && r <= b) return dat[k];

        auto mid = (l+r) / 2;
        auto vl = query(a, b, k*2 + 1, l, mid);
        auto vr = query(a, b, k*2 + 2, mid, r);

        return std::max(vl, vr);
    }

public:
    explicit segtree(int n) :dat() {
        N = 1;
        while(N < n) N *= 2;

        dat.resize(2*N, {-1, -1});
    }

    // A[k] -> a
    void update(int k, int a){
        int i = k;
        k += N-1;
        dat[k] = {a, i};
        while(k > 0){
            k = (k-1) / 2;
            dat[k] = std::max(dat[k*2 + 1] , dat[k*2 + 2]);
        }
    }

    val_type max(int l, int r){
        return query(l, r, 0, 0, N);
    }

};
segtree segB(0);

ll count(vector<int>& A, vector<int>& B, int l, int r){
    ll K = 0;
    while(true){
        auto t = segB.max(l, r);
        if(t.first == -1) return K;
        auto it = t.second;
        if(A[it] > B[it]) return -1;
        if(A[it] == B[it]){
            segB.update(it, -1);
        }
        else{
            ll p = B[(it-1 + A.size()) % A.size()], n = B[(it+1) % A.size()];
            ll dif = (B[it] - A[it]) / (p + n);
            if(dif == 0) return -1;
            B[it] -= dif * (p+n);
            segB.update(it, B[it]);
            K += dif;
        }
    }
}


void sub_main(istream &is) {
    int N;
    is >> N;
    if(!is) return;
    vector<int> A(N), B(N);
    segB = segtree(N);
    for (auto &&a : A) { is >> a; } // end a
    for (auto &&b : B) { is >> b; } // end b

    for (int i = 0; i < N; ++i) {
        segB.update(i, B[i]);
    } // end i


    ll K = count(A, B, 0, N);

    cout << K << endl;

}

int main(int argc, char *argv[]) {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << setprecision(16) << scientific;
#ifdef DEBUG
    string test_cases = "test_C.txt";
    cerr << "DEBUG MODE" <<  endl;
    cerr << test_cases << " -->" << endl;
    auto fs = fstream(test_cases, fstream::in);
    int lp = 0;
    while(fs) {
        lp++;
        cout << lp <<  "#------\n";
        sub_main(fs);
    }
    cout << "------#" << endl;
    if(lp <= 1) sub_main(cin);
#else
    sub_main(cin);
#endif
    return 0;
}


Measured memory_bytes: 6016