OI XXXI - prz

// https://szkopul.edu.pl/problemset/problem/eQ4z7Bnhqsl67nKb_NlISLNZ/site/?key=statement

#include <bits/stdc++.h>

using namespace std;

constexpr int sizik = 1000 * 1001;
constexpr int sizik2 = 500 * 1001;
constexpr int sizik3 = 100 * 1001;

#define ar std::array
#define pr std::pair
#define vec std::vector

#define ca const auto

typedef long long ll;
typedef vec<vec<int>> _kra;

struct Guzik {
    int x, y;
    Guzik(int x1 = 0, int y1 = 0) { x = x1, y = y1; }
};

ar<int, sizik> we;
int n, m;

ar<Guzik, sizik2> bG;

std::map<pr<int, int>, int> Gi_;

ar<std::vector<int>, sizik3> mpv, mpv2;

std::bitset<sizik> visited, visited2, visited3, visited4, visited5, visited7, visited8;

ar<vec<int>, sizik> kra;
ar<std::vector<int>, sizik3> FF_R, FF_C;

int R[sizik3], C[sizik3];

bool Found = false;

void DFS(int v, int k, int p) {
    if (visited4[v]) {
        return;
    }

    visited4[v] = true;

    for (const auto& u : kra[v]) {
        if (u != p && !visited3[u]) {
            DFS(u, k + 1, v);
        }
    }
}

int visited6[sizik];
int GLOBAL_BFS_COUNTER = 1;
int BFS_TRACE[sizik];

void BFS(int p, int k, int z) {
    std::queue<ar<int, 2>> q;
    q.push({p, p});

    while (!q.empty()) {
        const auto [d, par] = q.front();
        q.pop();

        if (visited6[d] == z) {
            continue;
        }

        visited6[d] = z;
        BFS_TRACE[d] = par;

        for (const auto& u : kra[d]) {
            q.push({u, d});
        }
    }
}

void backtrack_BFS(int p, int k, std::vector<int>& res) {
    int x = k;

    while (BFS_TRACE[x] != p) {
        x = BFS_TRACE[x];
        res.push_back(x);
    }
}

int looker_DFS1_helper = -1, DFS1_p2 = -1;
bool found_DFS1_helper = false;
void DFS1(int v, int p1, int p2) {
    if (found_DFS1_helper) {
        return;
    }

    if (visited7[v]) {
        if (v == looker_DFS1_helper) {
            DFS1_p2 = p2;
            found_DFS1_helper = true;
        }
        return;
    }

    visited7[v] = true;

    for (const auto& u : kra[v]) {
        if (u != p1) {
            DFS1(u, v, p1);
        }
    }
}

ar<int, sizik> disc, low;
int time1 = 0;
vec<ar<int, 2>> bridges;

void BridgeDFS(int u, int p) {
    visited5[u] = true;

    disc[u] = ++time1;
    low[u] = disc[u];

    for (const auto& v : kra[u]) {
        if (v == p) continue;

        if (visited5[v]) {
            low[u] = std::min(low[u], disc[v]);
        } else {
            BridgeDFS(v, u);

            low[u] = min(low[u], low[v]);

            if (low[v] > disc[u]) {
                bridges.push_back({u, v});
            }
        }
    }
}

int depth_DFS3[sizik], parent_DFS3[sizik], count_DFS3 = 0;
void DFS3(int v, int p, int d) {
    depth_DFS3[v] = d;
    parent_DFS3[v] = p;
    count_DFS3++;

    for (const auto& u : kra[v]) {
        if (u != p) {
            DFS3(u, v, d + 1);
        }
    }
}

std::vector<int> ans_DFS4;
void DFS4(int v, int p) {
    if (v != p) {
        int x = v, y = p - n;
        if (v > p) {
            x = p, y = v - n;
        }

        ans_DFS4.push_back(Gi_[{x, y}]);
    }

    visited8[v] = true;

    for (const auto& u : kra[v]) {
        if (u != p) {
            DFS4(u, v);
        }
    }
}

void print_btn(int z, bool nl = true);
void brut(int n, int m);

void solve() {
    std::cin >> n >> m;

    for (int i = 0; i < m; i++) {
        int x, y;
        std::cin >> x >> y;

        mpv[x].push_back(y);
        mpv2[y].push_back(x);

        bG[i + 1] = {x, y};
        Gi_[{x, y}] = i + 1;
    }

    for (int i = 1; i <= n; i++) {
        std::sort(mpv[i].begin(), mpv[i].end());
        std::sort(mpv2[i].begin(), mpv2[i].end());
    }

    int dbg = 0;

    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < mpv[i].size(); j++) {
            if (j != 0) {
                kra[Gi_[{i, mpv[i][j]}]].push_back(Gi_[{i, mpv[i][j - 1]}]);
            }
            if (j != (int)mpv[i].size() - 1) {
                kra[Gi_[{i, mpv[i][j]}]].push_back(Gi_[{i, mpv[i][j + 1]}]);
            }
        }

        for (int j = 0; j < mpv2[i].size(); j++) {
            if (j != 0) {
                kra[Gi_[{mpv2[i][j], i}]].push_back(Gi_[{mpv2[i][j - 1], i}]);
            }
            if (j != (int)mpv2[i].size() - 1) {
                kra[Gi_[{mpv2[i][j], i}]].push_back(Gi_[{mpv2[i][j + 1], i}]);
            }
        }
    }

    std::queue<int> q;
    for (int i = 1; i <= m; i++) {
        ca d = kra[i].size();
        we[i] = d;

        if (d == 1) {
            q.push(i);
        } else if (d == 0) {
            visited2[i] = true;
        }
    }

    while (!q.empty()) {
        int z = q.front();
        q.pop();

        if (visited2[z]) {
            continue;
        }

        visited2[z] = true;

        for (const auto& s : kra[z]) {
            if (--we[s] <= 1) {
                q.push(s);
            }
        }
    }

    for (int i = 1; i <= m; i++) {
        if (!visited2[i]) {
            Found = true;
        }
    }

    for (int i = 0; i < kra.size(); i++) {
        kra[i].clear();
    }

    if (Found) {
        std::cout << "TAK\n";

        for (int i = 1; i <= m; i++) {
            if (!visited2[i]) {
                const auto [x, y] = bG[i];
                // kra2[x].push_back(y + n);
                kra[x].push_back(y + n);
                // kra2[y + n].push_back(x);
                kra[y + n].push_back(x);
            }
        }

        for (int i = 1; i <= 2 * n; i++) {
            std::sort(kra[i].begin(), kra[i].end());
        }

        std::queue<int> q1;
        for (int i = 1; i <= 2 * n; i++) {
            ca d = kra[i].size();
            we[i] = d;

            if (d == 1) {
                q1.push(i);
            } else if (d == 0) {
                visited3[i] = true;
            }
        }

        while (!q1.empty()) {
            int z = q1.front();
            q1.pop();

            if (visited3[z]) {
                continue;
            }

            visited3[z] = true;

            for (const auto& s : kra[z]) {
                if (--we[s] <= 1) {
                    q1.push(s);
                }
            }
        }

        for (int i = 1; i <= 2 * n; i++) {
            if (visited3[i]) {
                kra[i].clear();
            }
        }

        for (int i = 1; i <= 2 * n; i++) {
            if (kra[i].size() < 1) {
                visited3[i] = true;
            }
        }

        for (int i = 1; i <= n; i++) {
            if (!visited3[i]) {
                BridgeDFS(i, i);
                break;
            }
        }

        for (const auto& [a, b] : bridges) {
            auto ptr = std::lower_bound(kra[a].begin(), kra[a].end(), b);
            if (ptr != kra[a].end() && *ptr == b) {
                kra[a].erase(ptr);
            }

            auto ptr1 = std::lower_bound(kra[b].begin(), kra[b].end(), a);
            if (ptr1 != kra[b].end() && *ptr1 == a) {
                kra[b].erase(ptr1);
            }
        }

        bridges.clear();

        for (int i = 1; i <= 2 * n; i++) {
            if (kra[i].size() < 1) {
                visited3[i] = true;
            }
        }

        int po = -1, ko = -1;

        for (int i = 1; i <= n; i++) {
            if (!visited3[i] && !visited7[i]) {
                po = i;

                looker_DFS1_helper = po;
                DFS1(po, po, po);

                ko = DFS1_p2;
                break;
            }
        }

        BFS(po, ko, ++GLOBAL_BFS_COUNTER);

        std::vector<int> part_ans1, part_ans2;
        backtrack_BFS(po, ko, part_ans1);

        ++GLOBAL_BFS_COUNTER;
        for (const auto& a : part_ans1) {
            if (a != po && a != ko) {
                visited6[a] = GLOBAL_BFS_COUNTER;
            }
        }

        BFS(po, ko, GLOBAL_BFS_COUNTER);
        backtrack_BFS(po, ko, part_ans2);

        part_ans1.push_back(po);
        part_ans2.push_back(po);

        pr<int, int> temp{ko, 0};

        std::vector<int> REAL_ANS;

        for (const auto& a : part_ans1) {
            if (a > n) {
                temp.second = a - n;
            } else {
                temp.first = a;
            }

            REAL_ANS.push_back(Gi_[temp]);
        }

        temp = {ko, 0};

        for (const auto& a : part_ans2) {
            if (a > n) {
                temp.second = a - n;
            } else {
                temp.first = a;
            }

            REAL_ANS.push_back(Gi_[temp]);
        }

#ifndef NO_ANS
        std::cout << REAL_ANS.size() << '\n';
        for (const auto& a : REAL_ANS) {
            std::cout << a << " ";
        }
        std::cout << '\n';
#endif

        return;
    }

    for (int i = 1; i <= n; i++) {
        if (mpv[i].size() == 0 || mpv2[i].size() == 0) {
            std::cout << "NIE\n";
            return;
        }
    }

    for (int i = 1; i <= m; i++) {
        const auto [x, y] = bG[i];
        kra[x].push_back(y + n);
        kra[y + n].push_back(x);
    }

    bool isGood_HERE = true;

    for (int i = 1; i <= 2 * n; i++) {
        if (depth_DFS3[i] == 0) {
            count_DFS3 = 0;
            DFS3(i, i, 1);

            if (count_DFS3 % 2 == 1) {
                isGood_HERE = false;
                break;
            }
        }
    }

    if (!isGood_HERE) {
        std::cout << "NIE\n";
        return;
    }

    std::vector<int> v_NP;
    for (int i = 1; i <= 2 * n; i++) {
        v_NP.push_back(i);
        we[i] = kra[i].size();
    }

    for (int i = 1; i <= 2 * n; i++) {
        std::sort(kra[i].begin(), kra[i].end());
    }

    std::sort(v_NP.begin(), v_NP.end(), [](int a, int b) { return depth_DFS3[a] > depth_DFS3[b]; });

    for (const auto& z : v_NP) {
        if (we[z] % 2 == 0) {
            we[z]--;
            we[parent_DFS3[z]]--;

            auto ptr = std::lower_bound(kra[z].begin(), kra[z].end(), parent_DFS3[z]);
            if (ptr != kra[z].end() && *ptr == parent_DFS3[z]) {
                kra[z].erase(ptr);
            }

            auto ptr1 = std::lower_bound(kra[parent_DFS3[z]].begin(), kra[parent_DFS3[z]].end(), z);
            if (ptr1 != kra[parent_DFS3[z]].end() && *ptr1 == z) {
                kra[parent_DFS3[z]].erase(ptr1);
            }
        }
    }

    for (int i = 1; i <= 2 * n; i++) {
        if (!visited8[i]) {
            DFS4(i, i);
        }
    }

    std::cout << "TAK\n";
#ifndef NO_ANS
    std::cout << ans_DFS4.size() << '\n';
    for (const auto& a : ans_DFS4) {
        std::cout << a << ' ';
    }
    std::cout << '\n';
#endif
}

int32_t main() {
    std::ios_base::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);

    int t = 1;

    for (; t > 0; t--) {
        solve();
    }

    return 0;
}

void print_btn(int z, bool nl) {
    std::cout << z << " [ " << bG[z].x << " , " << bG[z].y << " ]";
    if (nl) std::cout << endl;
}

void brut(int n, int m) {
    std::vector<Guzik> v(m);

    for (int i = 1; i <= m; i++) {
        v[i - 1].x = bG[i].x;
        v[i - 1].y = bG[i].y;
    }

    for (int i = 1; i < (1 << m); i++) {
        std::vector<int> R(n + 1, 0), C(n + 1, 0), pt_ans;
        int temp_i = i;

        for (int j = 0; j < m; j++) {
            if (temp_i % 2 == 1) {
                const auto& b = v[j];
                R[b.y]++;
                C[b.x]++;

                pt_ans.push_back(j + 1);
            }

            temp_i >>= 1;
        }

        int chk = R[1] % 2;
        bool isGood = true;
        for (int j = 1; j <= n; j++) {
            if ((R[j] % 2) != chk) {
                isGood = false;
                break;
            }
            if ((C[j] % 2) != chk) {
                isGood = false;
                break;
            }
        }

        if (isGood) {
            std::cout << "TAK\n";
            std::cout << pt_ans.size() << '\n';
            for (const auto& a : pt_ans) {
                std::cout << a << ' ';
            }
            std::cout << '\n';
            return;
        }
    }

    std::cout << "NIE\n";
}