/*

https://csacademy.com/contest/beta-round-6/task/perm_matrix/solution/

First we assume the matrix has only two rows, as this problem can easily be generalized:

There is no solution if there is an element that occurs in the matrix more than M times. Now assume there isn't such an element and let's try to find a greedy approach:

Find the element X that appears most times in the matrix and consider one of it's occurrences.
Take a random element Y, different than X, such that Y occurs on a different line than X's chosen occurence.
Say that these two elements go on the same column and decrement their frequencies.
Repeat this procedure while there still are some unpaired elements.
This solution can be implemented in O(M log M) using a priority queue. It's worth mentioning a linear solution also exists, but this optimization was not necessary.

In order to generalize the solution, we can choose every pair of consecutive lines and run the greedy algorithm above. This way we compute for each element which other element should be below it on the next line.


*/
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;

int main() {
	int N = 2, M;
	cin >> M;
	vector<vector<int>> element(N, vector<int>(M));
	for (int i = 0; i < N; i += 1) {
		for (int j = 0; j < M; j += 1) {
			cin >> element[i][j];
		}
	}

	bool isCorrect = true;
	vector<vector<int>> resultLine(N);
	resultLine[0] = element[0];
	// just take the first line as it is and put it in result

	for (int line = 1; line < N && isCorrect; line += 1) {
		// we set the last line, now try to set the current one
		vector<int> lastLine = resultLine[line - 1];
		vector<int> currentLine = element[line];

		// We'll keep an unordered_map with the meaning that underElements[i]
		// represents a vector with the values from the current line that are
		// under values i from last line. We don't really care about the indices
		unordered_map<int, vector<int>> underElements;

		// We proved that for each element it's enought to chose a random
		// element from last line that it's different and put it under that one.
		// It's not mandatory to chose a random element, so we'll chose any
		// element. To do so, we'll keep a deque with the elements sorted inside
		// and that'll look like [1, 2, 2, 3, 3, 3]. If we want to get a element
		// we'll just take the element from the back. If somehow the element
		// from the back it's equal to our element, we'll take the one in the
		// front. If that's equal as well, it means that the deque only contains
		// only one element and we've done something wrong.
		deque<int> lastLineElements;
		for (auto itr : lastLine) {
			lastLineElements.push_back(itr);
		}

		// Sort all elements so that all elements which are the same should be
		// near each other.
		sort(lastLineElements.begin(), lastLineElements.end());

		unordered_map<int, int> currentLineCount;
		unordered_map<int, int> totalElementCount;

		for (auto itr : lastLine) {
			totalElementCount[itr] += 1;
		}

		for (auto itr : currentLine) {
			totalElementCount[itr] += 1;
			currentLineCount[itr] += 1;
		}

		// Insert all elements with the specific count into the priority_queue.
		// If the element is not on the second line or we got all it's
		// appearances we just ignore it since we check if the top element
		// still has appearances on the current line as well.
		priority_queue<pair<int, int>> elementHeap;
		for (auto itr : totalElementCount) {
			int element = itr.first;
			int count = itr.second;
			elementHeap.push(make_pair(count, element));

			if (count > M) {
				// We can't get a valid solution -> break and print -1.
				isCorrect = false;
			}
		}

		// There is no correct solution. Just break and print.
		if (!isCorrect) {
			break;
		}

		while (elementHeap.size()) {
			auto top = elementHeap.top();
			elementHeap.pop();
			int count = top.first;
			int element = top.second;

			// There's a case when we have the element X in heap with the count
			// P but we matched an element X on last line before we got this
			// element in the top of the priority_queue.
			if (totalElementCount[element] != count) {
				continue;
			}

			// Ignore the element if it doens't have appearances in the
			// current line
			if (currentLineCount[element] <= 0) {
				continue;
			}

			// Find another element in last line that is different than this one
			int lastLineMatch;

			if (lastLineElements.front() != element) {
				lastLineMatch = lastLineElements.front();
				lastLineElements.pop_front();
			} else {
				lastLineMatch = lastLineElements.back();
				lastLineElements.pop_back();
			}

			// We know that we paired the element from this line
			// with lastLineMatch

			// set that we have an pair (lastLineMatch, element)
			underElements[lastLineMatch].push_back(element);

			// Decrement the counter
			currentLineCount[element] -= 1;
			totalElementCount[element] -= 1;
			totalElementCount[lastLineMatch] -= 1;

			// Push the elements back into the priority_queue.
			elementHeap.push(make_pair(totalElementCount[element], element));
			// Update the matched element since it can be on the current line.
			elementHeap.push(make_pair(totalElementCount[lastLineMatch], lastLineMatch));
		}

		// Reconstruct current line using the computem element "pairs".
		currentLine = {};
		for (auto itr : lastLine) {
			currentLine.push_back(underElements[itr].back());
			underElements[itr].pop_back();
		}

		resultLine[line] = currentLine;
	}

	if (isCorrect) {
		cout << "Yes" << '\n';

		for (int j = 0; j < M; j += 1) {
			cout << resultLine[1][j] << ' ';
		}
		cout << '\n';
	} else {
		cout << "No" << '\n';
	}
	return 0;
}

Measured memory_bytes: 44356