#include <bits/stdc++.h>
using namespace std;
const int N = 1007;
const int M = 10007;
void NIE() {
	puts("NIE");
	exit(0);
}
vector<int> G[N];
int spojna[N];
int ojc[N];
bool usu[N];
int A[M], B[M];
char C[M];
int n, m;
int zrobione;
bool moze[N];
int bs[N];
void dfs(int v, int l) {
	spojna[v] = l;
	moze[v] = true;
	for(auto x : G[v]) {
		if(!usu[x] && !moze[x]) dfs(x, l);
	}
}
bool rob() {
	fill(moze, moze+n+1, true);
	for(int i=1; i<=m; i++) {
		if(spojna[A[i]] != spojna[B[i]]) continue;
		if(C[i] == 'T') moze[A[i]] = false;
		if(C[i] == 'N') moze[B[i]] = false;
	}
/*
	printf("moze:");
	for(int i=1; i<=n; i++) {
		printf(" %d", (int)moze[i]);
	}
	puts("");
*/
	vector<int> korzenie;
	for(int i=1; i<=n; i++) {
		if(!usu[i] && moze[i] && bs[spojna[i]] == 0) {
			korzenie.push_back(i);
			bs[spojna[i]] = i;
		} else moze[i] = false;
	}
	
	if(korzenie.empty()) return false;
	for(int i=1; i<=n; i++) if(!moze[i] && !usu[i]) ojc[i] = bs[spojna[i]];
	zrobione += korzenie.size();
	for(auto x: korzenie) {
		usu[x] = true;
		spojna[x] = -1;
	}
	fill(moze, moze+n+1, false);
	int licz = 0;
	for(int i=1; i<=n; i++) { 
		if(!usu[i] && !moze[i]) {
			bs[licz] = 0;
			dfs(i, licz++);
		}
	}
	return true;
}
int main() {
	scanf("%d %d", &n, &m);
	for(int i=1; i<=m; i++) {
		scanf("%d %d %c", A+i, B+i, C+i);
		if(C[i] == 'T') {
			G[A[i]].push_back(B[i]);
			G[B[i]].push_back(A[i]);
		}
	}
	
	while(zrobione < n) if(!rob()) NIE();
	
//	puts("TAK");
	for(int i=1; i<=n; i++) printf("%d\n", ojc[i]);
}
        | 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 | #include <bits/stdc++.h> using namespace std; const int N = 1007; const int M = 10007; void NIE() { puts("NIE"); exit(0); } vector<int> G[N]; int spojna[N]; int ojc[N]; bool usu[N]; int A[M], B[M]; char C[M]; int n, m; int zrobione; bool moze[N]; int bs[N]; void dfs(int v, int l) { spojna[v] = l; moze[v] = true; for(auto x : G[v]) { if(!usu[x] && !moze[x]) dfs(x, l); } } bool rob() { fill(moze, moze+n+1, true); for(int i=1; i<=m; i++) { if(spojna[A[i]] != spojna[B[i]]) continue; if(C[i] == 'T') moze[A[i]] = false; if(C[i] == 'N') moze[B[i]] = false; } /* printf("moze:"); for(int i=1; i<=n; i++) { printf(" %d", (int)moze[i]); } puts(""); */ vector<int> korzenie; for(int i=1; i<=n; i++) { if(!usu[i] && moze[i] && bs[spojna[i]] == 0) { korzenie.push_back(i); bs[spojna[i]] = i; } else moze[i] = false; } if(korzenie.empty()) return false; for(int i=1; i<=n; i++) if(!moze[i] && !usu[i]) ojc[i] = bs[spojna[i]]; zrobione += korzenie.size(); for(auto x: korzenie) { usu[x] = true; spojna[x] = -1; } fill(moze, moze+n+1, false); int licz = 0; for(int i=1; i<=n; i++) { if(!usu[i] && !moze[i]) { bs[licz] = 0; dfs(i, licz++); } } return true; } int main() { scanf("%d %d", &n, &m); for(int i=1; i<=m; i++) { scanf("%d %d %c", A+i, B+i, C+i); if(C[i] == 'T') { G[A[i]].push_back(B[i]); G[B[i]].push_back(A[i]); } } while(zrobione < n) if(!rob()) NIE(); // puts("TAK"); for(int i=1; i<=n; i++) printf("%d\n", ojc[i]); } | 
 
            
         English
                    English