#include <algorithm>
#include <iostream>
#include <tuple>
#include <vector>
using namespace std;
namespace {
class Impossible {};
class Solver {
private:
  int n;
  vector<vector<int>> upper;
  vector<vector<int>> not_upper;
  vector<vector<int>> lower;
  vector<vector<int>> not_lower;
public:
  Solver(int n_): n{n_}, upper(n), not_upper(n), lower(n), not_lower(n)
  {
  }
  void request(int a, int b, bool wants)
  {
    if (wants) {
      upper[a].emplace_back(b);
      lower[b].emplace_back(a);
    } else {
      not_upper[a].emplace_back(b);
      not_lower[b].emplace_back(a);
    }
  }
  void dfs(int v, vector<int> const& parent, vector<int>& visited, int time, vector<int>& all) const
  {
    if (parent[v] >= 0) return;
    if (visited[v] == time) return;
    visited[v] = time;
    all.emplace_back(v);
    for (int w: upper[v]) dfs(w, parent, visited, time, all);
    for (int w: lower[v]) dfs(w, parent, visited, time, all);
  }
  vector<int> solve() const
  {
    vector<int> parent(n, -1);
    int root = -1;
    for (int v = 0; v < n; ++v) {
      if (!upper[v].empty()) continue;
      if (!not_lower[v].empty()) continue;
      root = v;
      break;
    }
    if (root < 0) throw Impossible{};
    vector<int> group(n, root);
    parent[root] = root;
    int done = 1;
    vector<int> visited(n, -1);
    int time = 0;
    while (done < n) {
      int start = time;
      for (int v = 0; v < n; ++v) {
        if (parent[v] >= 0) continue;
        if (visited[v] >= start) continue;
        vector<int> component;
        dfs(v, parent, visited, time, component);
        ++time;
        auto our_component = [&visited, v](int w) {
          return visited[w] == visited[v];
        };
        int r = -1;
        for (int w: component) {
          if (any_of(upper[w].begin(), upper[w].end(), our_component)) continue;
          if (any_of(not_lower[w].begin(), not_lower[w].end(), our_component)) continue;
          r = w;
          break;
        }
        if (r < 0) throw Impossible{};
        ++done;
        parent[r] = group[r];
        for (int w: component) group[w] = r;
      }
    }
    return parent;
  }
};
}
int main()
{
  iostream::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  cin >> n >> m;
  Solver solver(n);
  for (int i = 0; i < m; ++i) {
    int a, b;
    char c;
    cin >> a >> b >> c;
    solver.request(a-1, b-1, c == 'T');
  }
  try {
    auto parent = solver.solve();
    for (int i = 0; i < n; ++i) {
      if (parent[i] == i) cout << "0\n";
      else cout << parent[i] + 1 << '\n';
    }
  } catch (Impossible&) {
    cout << "NIE\n";
    return 0;
  }
  return 0;
}
        | 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 120 121 122 123 124 125 126 127 128 129 | #include <algorithm> #include <iostream> #include <tuple> #include <vector> using namespace std; namespace { class Impossible {}; class Solver { private: int n; vector<vector<int>> upper; vector<vector<int>> not_upper; vector<vector<int>> lower; vector<vector<int>> not_lower; public: Solver(int n_): n{n_}, upper(n), not_upper(n), lower(n), not_lower(n) { } void request(int a, int b, bool wants) { if (wants) { upper[a].emplace_back(b); lower[b].emplace_back(a); } else { not_upper[a].emplace_back(b); not_lower[b].emplace_back(a); } } void dfs(int v, vector<int> const& parent, vector<int>& visited, int time, vector<int>& all) const { if (parent[v] >= 0) return; if (visited[v] == time) return; visited[v] = time; all.emplace_back(v); for (int w: upper[v]) dfs(w, parent, visited, time, all); for (int w: lower[v]) dfs(w, parent, visited, time, all); } vector<int> solve() const { vector<int> parent(n, -1); int root = -1; for (int v = 0; v < n; ++v) { if (!upper[v].empty()) continue; if (!not_lower[v].empty()) continue; root = v; break; } if (root < 0) throw Impossible{}; vector<int> group(n, root); parent[root] = root; int done = 1; vector<int> visited(n, -1); int time = 0; while (done < n) { int start = time; for (int v = 0; v < n; ++v) { if (parent[v] >= 0) continue; if (visited[v] >= start) continue; vector<int> component; dfs(v, parent, visited, time, component); ++time; auto our_component = [&visited, v](int w) { return visited[w] == visited[v]; }; int r = -1; for (int w: component) { if (any_of(upper[w].begin(), upper[w].end(), our_component)) continue; if (any_of(not_lower[w].begin(), not_lower[w].end(), our_component)) continue; r = w; break; } if (r < 0) throw Impossible{}; ++done; parent[r] = group[r]; for (int w: component) group[w] = r; } } return parent; } }; } int main() { iostream::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; Solver solver(n); for (int i = 0; i < m; ++i) { int a, b; char c; cin >> a >> b >> c; solver.request(a-1, b-1, c == 'T'); } try { auto parent = solver.solve(); for (int i = 0; i < n; ++i) { if (parent[i] == i) cout << "0\n"; else cout << parent[i] + 1 << '\n'; } } catch (Impossible&) { cout << "NIE\n"; return 0; } return 0; } | 
 
            
         English
                    English