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
#include <bits/stdc++.h>
using namespace std;

vector <int> ile;
vector <int> rep;
vector <bool> used;

int Find(int a) {
	if (rep[a] != a)
		rep[a] = Find(rep[a]);
	return rep[a];
}

void Onion(int x, int y) {
	x = Find(x);
	y = Find(y);
	if (ile[x] > ile[y]) {
		ile[x] += ile[y];
		rep[y] = x;
	}
	else {
		ile[y] += ile[x];	
		rep[x] = y;
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n, k;
	cin >> n >> k;
	vector <int> v(2*n); // jaki kolorek na itym miejscu
	vector <int> mie(2*n); // gdzie jest ity kolorek
	for (int i = 0; i < 2*n; i++) {
		int a;
		cin >> a;
		a--;
		v[i] = a;
		mie[a] = i;
	}
	vector <int> res(n);
	for (int i = 0; i < 2*n; i++) {
		ile.clear();
		ile.resize(2*n); 
		rep.clear();
		rep.resize(2*n);
		used.clear();
		used.resize(2*n); // czy ite miejsce jest uzyte
		used[mie[i]] = 1;
		ile[i] = 1;
		rep[i] = i;
		int par = 1;
		res[par]++;
		for (int j = i+1; j < 2*n; j++) {
			set <int> s;
			used[mie[j]] = 1;
			rep[j] = j;
			ile[j] = 1;
			if (mie[j] == 0) {
				if (used[n-1]) s.insert(Find(v[n-1]));
			}
			else if (mie[j] == n) {
				if (used[2*n-1]) s.insert(Find(v[2*n-1]));
			}
			else {
				if (used[mie[j]-1]) s.insert(Find(v[mie[j]-1]));
			}
			if (mie[j] == n-1) {
				if (used[0]) s.insert(Find(v[0]));
			}
			else if (mie[j] == 2*n-1) {
				if (used[n]) s.insert(Find(v[n]));
			}
			else {
				if (used[mie[j]+1]) s.insert(Find(v[mie[j]+1]));
			}
			if (used[(mie[j]+n) % (2*n)])
				s.insert(Find(v[(mie[j]+n) % (2*n)]));
			if (s.size() == 0)
				par++;
			if (s.size() == 2)
				par--;
			if (s.size() == 3)
				par -= 2;
			for (auto a : s)
				Onion(j, a);
			res[par]++;
		}
	}
	for (int i = 1; i <= k; i++)
		cout << res[i] << " ";
}