1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Kacper Orszulak
#include <cstdio>
#include <vector>
#define fft(n) for (int i = 0; i < n; ++i) // Fast For Transform
using namespace std;
using pii = pair<int, int>;
constexpr pii INVALID_POINT(-1, -1);
inline bool amogus(int x, int a, int b) {
	return a <= x && x <= b;
}

int n, queries_cnt;
vector<int> arr[2];
vector<pii> pos_of;
int result[10+1];

struct fau_t {
	vector<int> rep;
	vector<int> subset_size;
	void reset(int size) {
		rep.resize(size);
		for (int i = 0; i < size; ++i)
			rep[i] = i;
		subset_size.assign(size, 1);
	}
	int find(int x) {
		if (rep[x] == x)
			return x;
		else
			return rep[x] = find(rep[x]);
	}
	void union_(int a, int b) {
		a = find(a);
		b = find(b);
		if (a == b)
			return;
		if (subset_size[a] > subset_size[b])
			swap(a, b);
		subset_size[b] += subset_size[a];
		subset_size[a] = 0;
		rep[a] = b;
	}
};

pii get_neighbor(pii v, const int id) {
	switch (id) {
		case 0:
			--v.first;
			break;
		case 1:
			++v.first;
			break;
		case 2:
			--v.second;
			break;
		case 3:
			++v.second;
			break;
		default:
			return INVALID_POINT;
	}
	v.second = (v.second+n)%n;
	if (v.first < 0 || v.first > 1)
		return INVALID_POINT;
	return v;
}

void subtask3() {
	fau_t fau;
	for (int l = 0; l < 2*n; ++l) {
		fau.reset(2*n);
		int subsets_cnt = 0;
		for (int r = l; r < 2*n; ++r) {
			const int v_color = r;
			const pii v = pos_of[v_color];
			++subsets_cnt;
			for (int id = 0; id < 4; ++id) {
				const pii w = get_neighbor(v, id);
				if (w == INVALID_POINT)
					continue;
				const int w_color = arr[w.first][w.second];
				if (!amogus(w_color, l, r))
					continue;
				const int v_rep = fau.find(v_color);
				const int w_rep = fau.find(w_color);
				if (v_rep == w_rep)
					continue;
				fau.union_(v_rep, w_rep);
				--subsets_cnt;
			}
			if (subsets_cnt <= 10)
				++result[subsets_cnt];
		}
	}
}

int main(void) {
	scanf("%d %d", &n, &queries_cnt);
	arr[0].resize(n);
	arr[1].resize(n);
	pos_of.resize(2*n);
	for (int i = 0; i < n; ++i) {
		int &e = arr[0][i];
		scanf("%d", &e);
		--e;
		pos_of[e] = {0, i};
	}
	for (int i = 0; i < n; ++i) {
		int &e = arr[1][i];
		scanf("%d", &e);
		--e;
		pos_of[e] = {1, i};
	}
	subtask3();
	for (int v = 1; v <= queries_cnt; ++v)
		printf("%d ", result[v]);
	printf("\n");
	return 0;
}