#include <bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,l,r) for(int i=l,i##_end=r;i<i##_end;i++)
#define all(x) (x).begin(), (x).end()
#define pii pair<int, int>
#define f first
#define s second
 
template<template<typename> class Container, typename G>
ostream& operator<<(ostream& os, Container<G> x) {int f=0;os<<'{';for(auto&i:x)os<<(f++ ? ", " : ""),os<<i;os<<"}";return os;}
void _print() {cerr << "]\n";}
template<typename T, typename... V>
void _print(T t, V... v) {cerr << t; if (sizeof...(v)) cerr <<", "; _print(v...);}
#ifdef DEBUG
#define dbg(x...) cerr << "\e[91m"<<__func__<<":"<<__LINE__<<" [" << #x << "] = ["; _print(x); cerr << "\e[39m" << endl;
#else
#define dbg(x...)
#endif
int head[2005];
struct edge{int u,nxt;};
edge e[1000005];
int use[1000005],use2[1000005],in[2005],a[1000005],b[1000005];
vector<int>cur;
int32_t main(){
	cin.tie(0)->sync_with_stdio(false);
	int n,m;cin>>n>>m;
	F(i,0,m){
		int a,b;cin>>a>>b;
		::a[i+1]=a;::b[i+1]=b;
		//if(head[a]==0)head[a]=i+1;
		//else e[head[a]].nxt=i+1;
		e[i+1].u=b;e[i+1].nxt=0;
		e[i+1].nxt=head[a];
		head[a]=i+1;
	}
	// let's find a spanning tree
	vector<int>seen(n+1);
	vector<int>edges;
	vector<int>s(n+1),p(n+1),tin(n+1),tout(n+1);int c=0;
	int cnt=0;
	vector<vector<pii>>above(n+3);
	function<void(int)>build=[&](int u){
		tin[u]=cnt++;
		s[u]=1;
		for(int id=head[u];id!=0;id=e[id].nxt){
			if(!s[e[id].u] and use[id]==0){
				p[e[id].u]=id;
				cur.push_back(id);
				c++;
				use[id]=1;
				build(e[id].u);
			}
		}
		tout[u]=cnt++;
	};
	build(1);
	/*F(i,1,m+1){
		if(tin[a[i]]<=tin[b[i]] and tout[b[i]]<=tout[a[i]] and use[i]==0){
			dbg(b[i],a[i],i);
			above[b[i]].emplace_back(a[i],i);
		}
	}*/
	F(i,1,n+1){
		for(int id=head[i];id;id=e[id].nxt){
			if(tin[i]<=tin[e[id].u] and tout[e[id].u]<=tout[i] and use[id]==0){
				above[e[id].u].emplace_back(i,id);
			}
		}
	}
	dbg(cur);
	function<void(int)>dfs=[&](int u){
		if(seen[u])return;
		seen[u]=1;
		for(int id=head[u];id!=0;id=e[id].nxt){
			if(!seen[e[id].u]){
				if(use[id]==0){
					use[id]=2;
					dbg(id);
					dfs(e[id].u);
				}else if(above[e[id].u].size()){
					// these edges could substitute in our tree
					int from=above[e[id].u].back().f,ed=above[e[id].u].back().s;
					dbg(id,ed,b[ed],b[id],"SWAP");
					use[id]=2;use[ed]=1;
					above[e[id].u].pop_back();
					dfs(e[id].u);
				}
			}
		}
	};
	dfs(1);
	F(i,1,m+1){
		dbg(i,use[i]);
		if(use[i]==1)edges.push_back(i);
	}
	dbg(edges);
	// build one spanning tree, then let's see if we can build another without using his edges
	// when he does an edge and checks if it works, iff its in our tree, we delete that edge, and now we need to find a connection to it that isn't in his tree. If it connects to the converse of our subtree, we win, otherwise we need to like reorient everything?
	// we can afford an o(v) query
	// eh the data's probably weak and we can do an o(e) update of the tree
	vector<int>edges2;seen=vector<int>(n+1);
	function<void(int)>dfs2=[&](int u){
		if(seen[u])return;
		seen[u]=1;
		for(int id=head[u];id!=0;id=e[id].nxt){
			if(!seen[e[id].u] and use[id]!=1){
				edges2.push_back(id);
				dfs2(e[id].u);
			}
		}
	};
	dfs2(1);
	dbg(edges2.size(),edges2);
	if(edges.size()==n-1 and edges2.size()==n-1){
		F(i,0,n-1)cout<<edges[i]<<" \n"[i==n-2];
		F(i,0,n-1)cout<<edges2[i]<<" \n"[i==n-2];
	}else{
		cout<<"NONE\n";
	}
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |