#include <iostream>
#include <fstream>
using namespace std;
const int kMaxMessageLength = 100003;
const int kAlphabetSize = 10000;
const char kInputFile[] = "cifru2.in";
const char kOutputFile[] = "cifru2.out";
const int kHashKeys[] = {1000003, 1000033};
const int kBase = 10007;
ifstream inputfile(kInputFile);
ofstream outputfile(kOutputFile);
int distmessage[2 * kMaxMessageLength];
int distmessagecode[kMaxMessageLength];
int message[kMaxMessageLength];
int messagecode[kMaxMessageLength];
int alphabet[kAlphabetSize];
int lengthofmessage;
int lengthalphabet;
void ReadInputData();
void WriteOutputData();
void ConcatArray(int array[], int arraysize);
void PrinteArray(int array[], int arraysize);
int Pow(int number, int exponent, int modulo);
void SetAlphabet(int shift, int length, int dest[]);
pair<int, int> GetHashes(int source[], int srclength);
void SetDistaces(int source[], int destination[], int destsize);
void ComputeLPSArray(int pattern[], int patternsize, int lpsarray[]);
int GetMatchingPosition(int source[], int destination[], int srclength, int destlength);
int FindMatchingPosition(int source[], int destination[], int srclength, int destlength);
int main(){
ios::sync_with_stdio( false );
ReadInputData();
SetDistaces(message, distmessage, lengthofmessage);
//PrinteArray(distmessage, lengthofmessage);
ConcatArray(distmessage, lengthofmessage);
//PrinteArray(distmessage, 2 * lengthofmessage);
SetDistaces(messagecode, distmessagecode, lengthofmessage);
//PrinteArray(distmessagecode, lengthofmessage);
WriteOutputData();
inputfile.close();
outputfile.close();
return 0;
}
void SetAlphabet(int shift, int length, int dest[]){
int head = shift;
for (int ind = 1; ind <= length; ++ind) {
++head;
if (head > length) {
head = 1;
}
dest[message[ind]] = messagecode[head];
if (lengthalphabet < message[ind]){
lengthalphabet = message[ind];
}
}
}
void ComputeLPSArray(int pattern[], int patternsize, int lpsarray[]){
int suffixlength = 0;
lpsarray[1] = 0;
for (int ind = 2; ind <= patternsize; ++ind) {
while (suffixlength > 0 && pattern[suffixlength + 1] != pattern[ind]) suffixlength = lpsarray[suffixlength];
if (pattern[suffixlength + 1] == pattern[ind]) suffixlength++;
lpsarray[ind] = suffixlength;
}
}
int FindMatchingPosition(int source[], int destination[], int srclength, int destlength){
int lpsarray[srclength];
ComputeLPSArray(source, srclength, lpsarray);
int lengthmatch = 0;
for (int ind = 1; ind <= destlength; ++ind) {
while (lengthmatch > 0 && source[lengthmatch + 1] != destination[ind]) lengthmatch = lpsarray[lengthmatch];
if (source[lengthmatch + 1] == destination[ind]) ++lengthmatch;
if (lengthmatch == srclength){
return ind - srclength + 1;
}
}
return -1;
}
int GetMatchingPosition(int source[], int destination[], int srclength, int destlength){
pair<int, int> hs = GetHashes(source, srclength);
int powhashes[2];
int actualhashes[2] = { 0 };
//std::cout << hs.first << " " << hs.second << "\n";
powhashes[0] = Pow(kBase, srclength - 1, kHashKeys[0]);
powhashes[1] = Pow(kBase, srclength - 1, kHashKeys[1]);
for (int ind = 1; ind <= destlength; ++ind){
actualhashes[0] = ((long long)actualhashes[0] * kBase + destination[ind]) % kHashKeys[0];
actualhashes[1] = ((long long)actualhashes[1] * kBase + destination[ind]) % kHashKeys[1];
if (ind >= srclength){
//std::cout << actualhashes[0] << " " << actualhashes[1] << "\n";
if (actualhashes[0] == hs.first && actualhashes[1] == hs.second){
return ind - srclength + 1;
}
actualhashes[0] = (actualhashes[0] - (long long)destination[ind - srclength + 1] * powhashes[0]) % kHashKeys[0] + kHashKeys[0];
actualhashes[1] = (actualhashes[1] - (long long)destination[ind - srclength + 1] * powhashes[1]) % kHashKeys[1] + kHashKeys[1];
}
}
return -1;
}
int Pow(int number, int exponent, int modulo){
long long output = 1;
long long squarepow = number;
while (exponent > 0){
if (1 == (exponent & 1)){
output = output * squarepow % modulo;
}
squarepow = squarepow * squarepow % modulo;
exponent >>= 1;
}
return output;
}
pair<int, int> GetHashes(int source[], int srclength){
int hashes[2] = { 0 };
for (int index = 1; index <= srclength; ++index){
hashes[0] = ((long long)hashes[0] * kBase + source[index]) % kHashKeys[0];
hashes[1] = ((long long)hashes[1] * kBase + source[index]) % kHashKeys[1];
}
return make_pair(hashes[0], hashes[1]);
}
void ConcatArray(int array[], int arraysize){
for (int index = 1; index <= arraysize; ++index){
array[index + arraysize] = array[index];
}
}
void SetDistaces(int source[], int destination[], int destsize){
int lastappearences[kAlphabetSize] = { 0 };
for (int index = 1; index <= destsize; ++index){
lastappearences[source[index]] = index;
}
for (int index = 1; index <= destsize; ++index){
if (lastappearences[source[index]] > index) {
destination[index] = lastappearences[source[index]] - index;
}else {
destination[index] = destsize - index + lastappearences[source[index]];
}
lastappearences[source[index]] = index;
}
}
void ReadInputData(){
inputfile >> lengthofmessage >> lengthalphabet;
for(int index = 1; index <= lengthofmessage; ++index) {
inputfile >> message[index];
}
for (int index = 1; index <= lengthofmessage; ++index) {
inputfile >> messagecode[index];
}
}
void WriteOutputData(){
//int numberofrightshifts = lengthofmessage + 1 - GetMatchingPosition(distmessagecode, distmessage, lengthofmessage, 2 * lengthofmessage);
//int firstappearence = FindMatchingPosition(distmessagecode, distmessage, lengthofmessage, 2 * lengthofmessage);
int numberofrightshifts = lengthofmessage + 1 - FindMatchingPosition(distmessagecode, distmessage, lengthofmessage, 2 * lengthofmessage);
//std::cout << FindMatchingPosition(distmessagecode, distmessage, lengthofmessage, 2 * lengthofmessage) << "\n";
//std::cout << GetMatchingPosition(distmessagecode, distmessage, lengthofmessage, 2 * lengthofmessage) << "\n";
SetAlphabet(numberofrightshifts, lengthofmessage, alphabet);
outputfile << numberofrightshifts << "\n";
PrinteArray(alphabet, lengthalphabet);
}
void PrinteArray(int array[], int arraysize){
for (int i = 1; i <= arraysize; ++i){
outputfile << array[i] << " ";
}
outputfile << "\n";
}