#include <bits/stdc++.h>
using namespace std;

#define llong long long 
#define len(x) ((int)x.size())
#define rep(i,n) for (int i = -1; ++ i < n; )
#define rep1(i,n) for (int i = 0; i ++ < n; )
#define rand __rand
mt19937 rng(chrono::system_clock::now().time_since_epoch().count());  // or mt19937_64
template<class T = int> T rand(T range = numeric_limits<T>::max()) { return (T)(rng() % range); }

#define CONCAT_(x, y) x##y/*{{{*/
#define CONCAT(x, y) CONCAT_(x, y)
#define SPEC(name) CONCAT(name, __LINE__)
#ifdef LOCAL_DEBUG   
int __db_level = 0;
#define clog cerr << string(__db_level * 2, ' ')
struct debug_block {
    string msg;
    debug_block(const string& s): msg(s) { clog << "{ " << msg << endl; ++__db_level; }
    ~debug_block() { --__db_level; clog << "} " << msg << endl; }
};
#define DB(args...) stringstream SPEC(ss); SPEC(ss)<< args; debug_block SPEC(dbbl)(SPEC(ss).str())
#else
#define clog if (0) cerr
#define DB(...)
#endif
#define db(val) "[" #val " = " << val << "]; "
template<class U, class V> ostream& operator<<(ostream& out, const pair<U, V>& p) {
    return out << "(" << p.first << ", " << p.second << ")";
}
template<size_t i, class T> ostream& print_tuple_utils(ostream& out, const T& tup) {
    if constexpr(i == tuple_size<T>::value) return out << ")";
    else return print_tuple_utils<i + 1, T>(out << (i ? ", " : "(") << get<i>(tup), tup);
}
template<class ...U>
ostream& operator<<(ostream& out, const tuple<U...>& tup) { return print_tuple_utils<0, tuple<U...>>(out, tup); }
template<class, typename = void> struct has_const_iterator : false_type {};
template<class T> struct has_const_iterator<T, void_t<typename T::const_iterator>> : true_type {};
template<class T>
typename enable_if<has_const_iterator<T>::value && !is_same<T, string>::value, ostream&>::type
operator<<(ostream& out, const T& container) { 
    auto beg = container.begin(), end = container.end();
    out << "(" << container.size() << ") {";
    if (beg != end) out << *(beg++);
    while (beg != end) out << ", " << *(beg++);
    return out << "}";
}
#define ptrtype(x) typename iterator_traits<x>::value_type
template<class u> vector<ptrtype(u)> $v(u a, u b) { return vector<ptrtype(u)>(a, b); }/*}}}*/
// ACTUAL SOLUTION BELOW ////////////////////////////////////////////////////////////

const int maxn = 202020;
int n;
vector<int> a_pos[maxn], b_pos[maxn];
vector<int> same[maxn];
vector<int> diff_pos_a[maxn];
int diff_val_b[maxn];
int ans[maxn];

int main(void) {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin >> n;
    rep(i, n) {
        int val; cin >> val;
        a_pos[val].push_back(i);
    }
    
    rep(i, n) {
        int val; cin >> val;
        b_pos[val].push_back(i);
    }
    
    int cnt_same = 0;
    pair<int, int> mx_val_same = {0, 0};
    rep1(i, n) {
        if (len(a_pos[i]) + len(b_pos[i]) > n) {
            cout << "No";
            return 0;
        }
        int s = min(len(a_pos[i]), len(b_pos[i]));
        rep(f, s) {
            same[i].push_back(a_pos[i][f]);
        }
        mx_val_same = max(mx_val_same, {len(same[i]), i});
        cnt_same += s;
        diff_val_b[i] = len(b_pos[i]) - s;
        for (int f = s; f < len(a_pos[i]); ++f) diff_pos_a[i].push_back(a_pos[i][f]);
    }
    
    int domi = mx_val_same.second;
    while (mx_val_same.first * 2 > cnt_same) {
        --mx_val_same.first;
        --cnt_same;
        ++diff_val_b[domi];
        diff_pos_a[domi].push_back(same[domi].back());
        same[domi].pop_back();
    }
    
    vector<pair<int, int>> c;
    rep1(i, n) for (auto pos: same[i]) c.emplace_back(i, pos);
    rep(i, len(c))
        ans[c[i].second] = c[(i + len(c) / 2) % len(c)].first;
    
    for (int i = 1; i <= n and diff_pos_a[domi].size(); ++i) {
        if (i == domi) continue;
        while (diff_val_b[i] and len(diff_pos_a[domi])) {
            --diff_val_b[i];
            ans[diff_pos_a[domi].back()] = i;
            diff_pos_a[domi].pop_back();
        }
    }
    
    for (int u = 1, v = 1; u <= n; ++u) {
        while (len(diff_pos_a[u])) {
            while (!diff_val_b[v]) ++v;
            ans[diff_pos_a[u].back()] = v;
            --diff_val_b[v];
            diff_pos_a[u].pop_back();
        }
    }
    cout << "Yes\n";
    rep(i, n) cout << ans[i] << ' ';

    return 0;
}

// Remember:
// - Multitest? REFRESHING the data!!!
// - Constrains for each set of data may differs. Should NOT USE the same max constant (maxn)
//   for all of them.
// vim: foldmethod=marker



Measured memory_bytes: 44256