B - Uniform Sum
Source: atcoder
Difficulty: 500

Problem Statement
There are two sequences
A=(A_1,\dots,A_N)
and
B=(B_1,\dots,B_N)
. You can perform the following three types of operations any number of times in any order:
Choose an index
i
such that
A_i = -1
, and replace
A_i
with any non-negative integer.
Choose an index
i
such that
B_i = -1
, and replace
B_i
with any non-negative integer.
Rearrange the elements of sequence
A
in any order.
Determine whether it is possible, after these operations, for all elements of
A
and
B
to be non-negative and satisfy
A_1 + B_1 = A_2 + B_2 = \dots = A_N + B_N
.
Constraints
2 \leq N \leq 2000
-1 \leq A_i \leq 10^9
-1 \leq B_i \leq 10^9
All input values are integers.
Input
The input is given from Standard Input in the following format:
N
A_1
A_2
\ldots
A_N
B_1
B_2
\ldots
B_N
Output
If it is possible, after the operations, for all elements of
A
and
B
to be non-negative and satisfy
A_1 + B_1 = A_2 + B_2 = \dots = A_N + B_N
, print
Yes
. Otherwise, print
No
.
Sample Input 1
4
2 0 -1 3
3 -1 4 2
Sample Output 1
Yes
Consider the following operations:
Replace
A_3
with
1
.
Replace
B_2
with
1
.
Rearrange
A
to
(1,3,0,2)
.
After these operations,
A = (1,3,0,2)
and
B = (3,1,4,2)
: all elements of
A
and
B
are non-negative, and
A_1+B_1 = A_2+B_2 = A_3+B_3 = A_4+B_4 = 4
is satisfied.
Sample Input 2
3
1 2 3
1 2 4
Sample Output 2
No
No matter how you perform the operations, it is impossible to satisfy
A_1+B_1 = A_2+B_2 = A_3+B_3
.
Sample Input 3
3
1 2 -1
1 2 4
Sample Output 3
No

C++ solution:
#ifdef LOCAL
#include "template.hpp"
#else
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<utility>
#include<tuple>
#include<array>
#include<cstdint>
#include<cstdio>
#include<iomanip>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include<stack>
#include<deque>
#include<bitset>
#include<cctype>
#include<chrono>
#include<random>
#include<cassert>
#include<cstddef>
#include<iterator>
#include<string_view>
#include<type_traits>
#include<functional>

using namespace std;

namespace io {

template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
    is >> p.first >> p.second;
    return is;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
    for (auto &x : v) is >> x;
    return is;
}
template <typename T, size_t N = 0>
istream &operator>>(istream &is, array<T, N> &v) {
    for (auto &x : v) is >> x;
    return is;
}
template <size_t N = 0, typename T>
istream& cin_tuple_impl(istream &is, T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        is >> x;
        cin_tuple_impl<N + 1>(is, t);
    }
    return is;
}
template <class... T>
istream &operator>>(istream &is, tuple<T...> &t) {
    return cin_tuple_impl(is, t);
}

template<typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << p.first << " " << p.second;
    return os;
}
template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    int s = (int)v.size();
    for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
    return os;
}
template<typename T, size_t N>
ostream &operator<<(ostream &os, const array<T, N> &v) {
    size_t n = v.size();
    for (size_t i = 0; i < n; i++) {
        if (i) os << " ";
        os << v[i];
    }
    return os;
}
template <size_t N = 0, typename T>
ostream& cout_tuple_impl(ostream &os, const T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) os << " ";
        const auto &x = std::get<N>(t);
        os << x;
        cout_tuple_impl<N + 1>(os, t);
    }
    return os;
}
template <class... T>
ostream &operator<<(ostream &os, const tuple<T...> &t) {
    return cout_tuple_impl(os, t);
}

void in() {}
template<typename T, class... U>
void in(T &t, U &...u) {
    cin >> t;
    in(u...);
}
void out() { cout << "\n"; }
template<typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u) {
    cout << t;
    if (sizeof...(u)) cout << sep;
    out(u...);
}
void outr() {}
template<typename T, class... U, char sep = ' '>
void outr(const T &t, const U &...u) {
    cout << t;
    outr(u...);
}

void __attribute__((constructor)) _c() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);
}
} // namespace io

using io::in;
using io::out;
using io::outr;

#define SHOW(x) static_cast<void>(0)

using ll = long long;
using D = double;
using LD = long double;
using P = pair<ll, ll>;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i128 = __int128;
using u128 = unsigned __int128;
using vi = vector<ll>;
template <class T> using vc = vector<T>;
template <class T> using vvc = vector<vc<T>>;
template <class T> using vvvc = vector<vvc<T>>;
template <class T> using vvvvc = vector<vvvc<T>>;
template <class T> using vvvvvc = vector<vvvvc<T>>;
#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
template<typename T> using PQ = priority_queue<T,vector<T>>;
template<typename T> using minPQ = priority_queue<T, vector<T>, greater<T>>;

#define rep1(a)          for(ll i = 0; i < a; i++)
#define rep2(i, a)       for(ll i = 0; i < a; i++)
#define rep3(i, a, b)    for(ll i = a; i < b; i++)
#define rep4(i, a, b, c) for(ll i = a; i < b; i += c)
#define overload4(a, b, c, d, e, ...) e
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define rrep1(a)          for(ll i = (a)-1; i >= 0; i--)
#define rrep2(i, a)       for(ll i = (a)-1; i >= 0; i--)
#define rrep3(i, a, b)    for(ll i = (b)-1; i >= a; i--)
#define rrep4(i, a, b, c) for(ll i = (b)-1; i >= a; i -= c)
#define rrep(...) overload4(__VA_ARGS__, rrep4, rrep3, rrep2, rrep1)(__VA_ARGS__)
#define for_subset(t, s) for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define ALL(v) v.begin(), v.end()
#define RALL(v) v.rbegin(), v.rend()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() )
#define SZ(v) ll(v.size())
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(c, x) distance((c).begin(), lower_bound(ALL(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(ALL(c), (x)))
template <typename T, typename U>
T SUM(const vector<U> &v) {
    T res = 0;
    for(auto &&a : v) res += a;
    return res;
}
template <typename T>
vector<pair<T,int>> RLE(const vector<T> &v) {
    if (v.empty()) return {};
    T cur = v.front();
    int cnt = 1;
    vector<pair<T,int>> res;
    for (int i = 1; i < (int)v.size(); i++) {
        if (cur == v[i]) cnt++;
        else {
            res.emplace_back(cur, cnt);
            cnt = 1; cur = v[i];
        }
    }
    res.emplace_back(cur, cnt);
    return res;
}
template<class T, class S>
inline bool chmax(T &a, const S &b) { return (a < b ? a = b, true : false); }
template<class T, class S>
inline bool chmin(T &a, const S &b) { return (a > b ? a = b, true : false); }
void YESNO(bool flag) { out(flag ? "YES" : "NO"); }
void yesno(bool flag) { out(flag ? "Yes" : "No"); }

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
int popcnt_sgn(int x) { return (__builtin_parity(x) & 1 ? -1 : 1); }
int popcnt_sgn(u32 x) { return (__builtin_parity(x) & 1 ? -1 : 1); }
int popcnt_sgn(ll x) { return (__builtin_parityl(x) & 1 ? -1 : 1); }
int popcnt_sgn(u64 x) { return (__builtin_parityl(x) & 1 ? -1 : 1); }
int highbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int highbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int highbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int highbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T>
T get_bit(T x, int k) { return x >> k & 1; }
template <typename T>
T set_bit(T x, int k) { return x | T(1) << k; }
template <typename T>
T reset_bit(T x, int k) { return x & ~(T(1) << k); }
template <typename T>
T flip_bit(T x, int k) { return x ^ T(1) << k; }

template <typename T>
T popf(deque<T> &que) { T a = que.front(); que.pop_front(); return a; }
template <typename T>
T popb(deque<T> &que) { T a = que.back(); que.pop_back(); return a; }
template <typename T>
T pop(queue<T> &que) { T a = que.front(); que.pop(); return a; }
template <typename T>
T pop(stack<T> &que) { T a = que.top(); que.pop(); return a; }
template <typename T>
T pop(PQ<T> &que) { T a = que.top(); que.pop(); return a; }
template <typename T>
T pop(minPQ<T> &que) { T a = que.top(); que.pop(); return a; }

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
    if (check_ok) assert(check(ok));
    while (abs(ok -  ng) > 1) {
        ll mid = (ok + ng) / 2;
        (check(mid) ? ok : ng) = mid;
    }
    return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 60) {
    for (int _ = 0; _ < iter; _++) {
        double mid = (ok + ng) / 2;
        (check(mid) ? ok : ng) = mid;
    }
    return (ok + ng) / 2;
}

// max x s.t. b*x <= a
ll div_floor(ll a, ll b) {
    assert(b != 0);
    if (b < 0) a = -a, b = -b;
    return a / b - (a % b < 0);
}
// max x s.t. b*x < a
ll div_under(ll a, ll b) {
    assert(b != 0);
    if (b < 0) a = -a, b = -b;
    return a / b - (a % b <= 0);
}
// min x s.t. b*x >= a
ll div_ceil(ll a, ll b) {
    assert(b != 0);
    if (b < 0) a = -a, b = -b;
    return a / b + (a % b > 0);
}
// min x s.t. b*x > a
ll div_over(ll a, ll b) {
    assert(b != 0);
    if (b < 0) a = -a, b = -b;
    return a / b + (a % b >= 0);
}
// x = a mod b (b > 0), 0 <= x < b
ll modulo(ll a, ll b) {
    assert(b > 0);
    ll c = a % b;
    return c < 0 ? c + b : c;
}
// (q,r) s.t. a = b*q + r, 0 <= r < b (b > 0)
// div_floor(a,b), modulo(a,b)
pair<ll,ll> divmod(ll a, ll b) {
    ll q = div_floor(a,b);
    return {q, a - b*q};
}
#endif

struct custom_hash {
    const unsigned long long FIXED_RANDOM = chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
    static unsigned long long splitmix64(unsigned long long x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    template <typename T>
    unsigned long long hash_combine(unsigned long long hr, const T &x) const noexcept {
        return hr ^ ((*this)(x) + (hr << 11) + (hr >> 13));
    }
    template <typename T, typename U>
    unsigned long long operator()(const pair<T, U> &p) const noexcept {
        return hash_combine((*this)(p.first), p.second);
    }

    unsigned long long operator()(const unsigned long long x) const noexcept {
        return splitmix64(x + FIXED_RANDOM);
    }
    unsigned long long operator()(const string& x) const noexcept {
        return splitmix64(std::hash<string>()(x) + FIXED_RANDOM);
    }
};

template <typename K, typename V>
struct HashMap {
    using u32 = uint32_t;
    using u64 = uint64_t;

    HashMap (u32 n = 0) { build(n); }
    void build(u32 n) {
        u32 k = 8;
        while (k < n*2) k *= 2;
        cap = k/2, mask = k-1;
        key.resize(k), val.resize(k), used.assign(k, false);
    }

    // do not change size
    void clear() {
        used.assign(used.size(), false);
        cap = (mask+1)/2;
    }
    int size() const { return used.size()/2 - cap; }

    int index(const K& k) const {
        int i = 0;
        for (i = hash(k); used[i] and key[i] != k; i = (i+1)&mask);
        return i;
    }

    V& operator[](const K& k) {
        if (cap == 0) extend();
        int i = index(k);
        if (!used[i]) { used[i] = true, key[i] = k, val[i] = V{}, cap--; }
        return val[i];
    }

    V get(const K& k, V default_value) const {
        int i = index(k);
        return used[i] ? val[i] : default_value;
    }

    bool count(const K& k) const {
        int i = index(k);
        return used[i] and key[i] == k;
    }

    void erase(const K& k) {
        int i = index(k);
        if(used[i]) { used[i] = false, key[i] = 0, val[i] = V{}, cap++; }
    }

    // execute f(key, val) for every entry
    template <typename F>
    void enumerate_all(F f) const {
        for (int i = 0; i < (int)used.size(); i++) if (used[i]) f(key[i], val[i]);
    }

private:
    custom_hash ch;
    u32 cap, mask;
    vector<K> key;
    vector<V> val;
    vector<bool> used;

    u64 hash(K x) const {
        return ch(x) & mask;
    }

    void extend() {
        vector<pair<K, V>> dat;
        dat.reserve(used.size()/2-cap);
        for (int i = 0; i < (int)used.size(); i++) if (used[i]) dat.emplace_back(key[i], val[i]);
        build(2 * dat.size());
        for (const auto& [k, v] : dat) (*this)[k] = v;
    }
};

int main() {
    int n; in(n);
    vector<int> a(n),b(n); in(a,b);
    int qa = 0, qb = 0;
    HashMap<int,int> mpa, mpb;
    rep(i,n){
        if(a[i]==-1) qa++;
        else mpa[a[i]]++;
    }
    rep(i,n){
        if(b[i]==-1) qb++;
        else mpb[b[i]]++;
    }
    if(qa + qb >= n){
        out("Yes");
        return 0;
    }
    HashMap<int,int> mp;
    mpa.enumerate_all([&](int ai, int ac){
        mpb.enumerate_all([&](int bi, int bc){
            mp[ai+bi] += min(ac,bc);
        });
    });
    int mx = max(MAX(a), MAX(b));
    mp.enumerate_all([&](int val, int cnt){
        if(cnt >= n-qa-qb and val >= mx){
            out("Yes");
            exit(0);
        }
    });
    out("No");
}

Go solution:
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	scanner.Scan()
	n, _ := strconv.Atoi(scanner.Text())

	A := make([]int, n)
	for i := 0; i < n; i++ {
		scanner.Scan()
		A[i], _ = strconv.Atoi(scanner.Text())
	}

	B := make([]int, n)
	for i := 0; i < n; i++ {
		scanner.Scan()
		B[i], _ = strconv.Atoi(scanner.Text())
	}

	// Filter out -1 from A and B
	filteredA := make([]int, 0)
	filteredB := make([]int, 0)
	for _, a := range A {
		if a != -1 {
			filteredA = append(filteredA, a)
		}
	}
	for _, b := range B {
		if b != -1 {
			filteredB = append(filteredB, b)
		}
	}

	k := len(filteredA) + len(filteredB) - n
	if k <= 0 {
		fmt.Println("Yes")
		return
	}

	// Find the maximum in filteredA and filteredB
	m := 0
	if len(filteredA) > 0 {
		sort.Ints(filteredA)
		m = filteredA[len(filteredA)-1]
	}
	if len(filteredB) > 0 {
		sort.Ints(filteredB)
		if filteredB[len(filteredB)-1] > m {
			m = filteredB[len(filteredB)-1]
		}
	}

	// Count frequencies in A and B
	freqA := make(map[int]int)
	for _, a := range filteredA {
		freqA[a]++
	}
	freqB := make(map[int]int)
	for _, b := range filteredB {
		freqB[b]++
	}

	// Collect all possible sums >= m
	sums := make(map[int]int)
	for a, cntA := range freqA {
		for b, cntB := range freqB {
			s := a + b
			if s < m {
				continue
			}
			min := cntA
			if cntB < min {
				min = cntB
			}
			sums[s] += min
			if sums[s] >= k {
				fmt.Println("Yes")
				return
			}
		}
	}

	fmt.Println("No")
}

Java solution:
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] a = new int[n], b = new int[n];
        int aMax = -1, aNegCnt = 0, aNNegCnt = 0;
        for (int i = 0; i < n; i ++) {
            a[i] = in.nextInt();
            aMax = Math.max(aMax, a[i]);
            if (a[i] == -1) aNegCnt ++;
            else aNNegCnt ++;
        }
        int bMax = -1, bNegCnt = 0, bNNegCnt = 0;
        for (int i = 0; i < n; i ++) {
            b[i] = in.nextInt();
            bMax = Math.max(bMax, b[i]);
            if (b[i] == -1) bNegCnt ++;
            else bNNegCnt ++;
        }
        int max = Math.max(aMax, bMax);
        System.out.println(possible(n, a, b, aNegCnt, aNNegCnt, bNegCnt, bNNegCnt, max) ? "Yes" : "No");
    }

    private static boolean possible(int n, int[] a, int[] b, int aNegCnt, int aNNegCnt, int bNegCnt, int bNNegCnt, int max) {
        if (aNegCnt >= bNNegCnt && bNegCnt >= aNNegCnt) return true;
        // now there are fewer negatives in a than non negatives in b
        int overlap = n - aNegCnt - bNegCnt;
        return existsXEqualSums(n, a, b, max, overlap);
    }

    private static boolean existsXEqualSums(int n, int[] a, int[] b, int max, int x) {
        var sumCnt = new HashMap<Long, Integer>();
        Arrays.sort(a);
        Arrays.sort(b);
        int prevA = -1;
        int[] workingB = null;
        for (int i = 0; i < n; i ++) {
            if (a[i] == -1) continue;
            if (workingB == null || a[i] != prevA) workingB = Arrays.copyOf(b, n);
            prevA = a[i];

            int prevB = -1;
            for (int j = 0; j < n; j ++) {
                if (workingB[j] == -1) continue;
                long sum = (long) a[i] + workingB[j];
                if (sum < max) continue;
                if (workingB[j] == prevB) continue;
                prevB = workingB[j];

//                if (!used.add(Map.entry(a[i], j))) {
//                    prevB = -1;
//                    continue;
//                }
                if (sumCnt.merge(sum, 1, Integer::sum) >= x) return true;
                workingB[j] = -1;
            }
        }
        return false;
    }
}

JavaScript solution:
"use strict";
var input=require("fs").readFileSync("/dev/stdin","utf8");
var cin=input.split(/ |\n/),cid=0;
function next(){return +cin[cid++];}
function nextstr(){return cin[cid++];}
function nextbig(){return BigInt(cin[cid++]);}
function nexts(n,a){return a?cin.slice(cid,cid+=n):cin.slice(cid,cid+=n).map(a=>+a);}
function nextssort(n,a){return a?cin.slice(cid,cid+=n).map(a=>+a).sort((a,b)=>b-a):cin.slice(cid,cid+=n).map(a=>+a).sort((a,b)=>a-b);}
function nextm(h,w,a){var r=[],i=0;if(a)for(;i<h;i++)r.push(cin.slice(cid,cid+=w));else for(;i<h;i++)r.push(cin.slice(cid,cid+=w).map(a=>+a));return r;}
function xArray(v){var a=arguments,l=a.length,r="Array(a["+--l+"]).fill().map(x=>{return "+v+";})";while(--l)r="Array(a["+l+"]).fill().map(x=>"+r+")";return eval(r);}
var streams=[];function print(s){streams.push(s);}

var myOut = main();
if(myOut !== undefined)console.log(String(myOut));
if(streams.length)console.log(streams.join("\n"));

function main(){
  var q = 1;
  while(q--)print(solve()?"Yes":"No");
}

function solve(){
  var n = next();
  var a = [], z = n, mx = 0;
  for(var i = 0; i < n; i++){
    var t = next();
    if(t === -1)z--;
    else a.push(t), mx = Math.max(mx,t);
  }
  var b = [];
  for(var i = 0; i < n; i++){
    var t = next();
    if(t === -1)z--;
    else b.push(t), mx = Math.max(mx,t);
  }
  if(z <= 1)return 1;
  var al = a.length, bl = b.length;
  var mp = new Map();
  for(var i = 0; i < al; i++){
    for(var j = 0; j < bl; j++){
      var s = a[i]+b[j];
      if(s < mx)continue;
      if(mp.has(s)){
        mp.get(s).push([i,j]);
      }else{
        mp.set(s,[[i,j]]);
      }
    }
  }
  var k = 0;
  var c = xArray(0,al);
  var d = xArray(0,bl);
  for(var [k,v] of mp){
    if(v.length < z)continue;
    k++;
    var t = 0;
    for(var i = 0; i < v.length; i++){
      var [x,y] = v[i];
      if(c[x] !== k && d[y] !== k){
        t++;
        if(t === z)return 1;
        c[x] = d[y] = k;
      }
    }
  }
  return 0;
}

Python solution:
from collections import Counter, defaultdict
n = int(input())
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]

a.sort(reverse = True)
b.sort(reverse = True)

m = 0
while a and a[-1] == -1: a.pop(); m += 1
while b and b[-1] == -1: b.pop(); m += 1
if m >= n: exit(print('Yes'))

c, d = Counter(a), Counter(b)
s = defaultdict(int)

for i, j in c.items():
    for k, l in d.items():
        s[i + k] += min(j, l)

for i, j in s.items():
    if a[0] <= i >= b[0] and j + m >= n: exit(print('Yes'))
print('No')

Ruby solution:
n = gets.to_i
a = gets.split.map(&:to_i).sort
b = gets.split.map(&:to_i).sort

cnt_a = Hash.new(0)
cnt_b = Hash.new(0)
n.times do |i|
  cnt_a[a[i]] += 1
  cnt_b[b[i]] += 1
end

cnt_wild = a.count(-1) + b.count(-1)
if cnt_wild >= n-1
  puts "Yes"
  exit
end

hash = Hash.new(0)
n.times do |i|
  next if a[i] == -1
  tmp = Hash.new(false)
  n.times do |j|
    next if b[j] == -1
    v = a[i] + b[j]
    if tmp[v].!
      tmp[v] = true
      hash[v] += 1
    end
  end
end

a.uniq.each do |v|
  b.uniq.each do |w|
    if cnt_a[v] > cnt_b[w]
      hash[v+w] -= cnt_a[v] - cnt_b[w]
    end
  end
end

# print hash
min = [a.max, b.max].max
hash.each do |k,v|
  if v + cnt_wild >= n && k >= min
    puts "Yes"
    exit
  end
end

puts "No"