Problem:
G: DAG トリオ / DAG Trio
この問題は D: DAG Trio (Easy) と制約のみが異なる同じ設定の問題です。
プロローグ
弟は最近「だぐとりお」が欲しいとしきりに呟いています。
心配になった兄が調べたところ、弟のクラスでは $k$-DAG (有向グラフであって、ある $k$ 個の辺を削除すると、辺の向きを無視したときの連結成分数を $k$ にでき、かつそれら全てが DAG である) が流行っており、
3-DAG を特に DAG トリオと呼ぶことを突き止めました。
弟に尊敬されたい兄は、与えられたグラフが DAG トリオかどうかを判別するプログラムを作成することにしました。
問題文
$N$ 頂点 $M$ 辺の有向グラフが与えられます。
各頂点には $1$ から $N$ まで番号が振られています。
各有向辺には $1$ から $M$ まで番号が振られています。
有向辺 $i$ は頂点 $a_i$ から $b_i$ に向かいます。
グラフは連結かつ単純です (辺の向きを無視すると、任意の 2 点間に道があり自己ループと多重辺がありません)。
与えられたグラフが DAG トリオならば ”YES”、そうでないなら ”NO” を出力してください。
入力
$N \ M$
$a_1 \ b_1$
$a_2 \ b_2$
$\vdots$
$a_M \ b_M$
制約
$3 \le N \le 500$
$\max(3, N−1) \le M \le 30000$
$1 \le a_i, b_i \le N$
グラフは辺の向きを無視したときに連結である。
各 $i$ に対して$a_i \neq b_i$
異なる $i, j$ に対して $\{a_i, b_i\} \neq \{a_j, b_j\}$
出力
”YES”　または ”NO” を $1$ 行で出力してください。
サンプル
サンプル入力1
3 3
1 2
2 3
3 1
サンプル出力1
YES
サンプル入力2
6 7
1 2
2 3
4 3
4 5
5 6
6 4
3 6
サンプル出力2
YES
サンプル入力3
7 10
4 2
4 7
4 6
2 7
2 5
2 1
5 6
1 3
6 3
4 3
サンプル出力3
NO
サンプル入力4
4 4
1 2
3 2
4 3
2 4
サンプル出力4
YES
サンプル入力5
8 9
5 1
3 8
1 2
4 8
4 7
7 5
6 5
3 2
4 2
サンプル出力5
YES

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 50000
struct edge{ int from,to,id; };

int N,M;
int a[MAX_M],b[MAX_M];

vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
int par[MAX_N];
edge f_edge[MAX_N];

vector<edge> bridges;


vector<edge> edge_;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      f_edge[to]=G[pos][i];
      par[to]=pos;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
      edge_.push_back(G[pos][i]);
    }
  }
}

int countB(int id){
  bridges.clear();
  edge_.clear();
  
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  memset(par,-1,sizeof(par));
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

bool isDag(int id){
  queue<int> Q;  
  vector<int> C(N,0);
  int cc=0;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    C[ b[i] ]++;
  }
  for(int i=0;i<N;i++)if(C[i]==0)Q.push(i);

  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  return (cc==N);
}

void visit(int v){
  if(visited[v])return;
  visited[v]=true;
  for(int i=0;i<(int)G[v].size();i++){
    visit(G[v][i].to);
  }
}

int calcDec(int id){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    G[ b[i] ].push_back( (edge){b[i],a[i],i} );
  }
  int res=0;
  memset(visited,false,sizeof(visited));
  for(int i=0;i<N;i++){
    if(!visited[i]){
      res++;
      visit(i);
    }
  }
  return res;
}

map<int,int> mm;
bool check(int id){
  if(mm.count(id))return false;
  mm[id]=true;
  
  if(countB(id) + calcDec(id)>=3&&isDag(id))return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if( rec(e.to,si) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    loope.clear();
    if( rec(i,i) )break;
  }
  
  for(int i=0;i<(int)loope.size();i++)
    if(check( loope[i].id ))return true;

  return false;
}

bool solve(){
  int B=countB(-1);
  if(B==M)return false;
  
  if( !isDag(-1) )return solve2();

  int maxm=0;

  
  B=countB(-1);
  for(int i=0;i<(int)edge_.size();i++){
    edge e=edge_[i];
    int a=e.from;
    int cc=0;
    while(1){
      if(a==e.to)break;
      if(cnt[a]==1)cc++;
      a=par[a];
    }
    maxm=max(maxm,cc);
  }
  vector<int> v;
  for(int i=0;i<N;i++)
    if(depth[i]>0)
      v.push_back(f_edge[i].id);

  for(int i=0;i<(int)v.size();i++){
    if(check(v[i]))return true;
  }
  
  return (B+maxm>=2);
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 1
time_ms: 1050
memory_kb: 6092
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 50000
struct edge{ int from,to,id; };

int N,M;
int a[MAX_M],b[MAX_M];
bool flg[MAX_M];

vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
int par[MAX_N];


vector<edge> bridges;


vector<edge> edge_;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      par[to]=pos;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
      edge_.push_back(G[pos][i]);
    }
  }
}

int countB(int id){
  bridges.clear();
  edge_.clear();
  
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  memset(par,-1,sizeof(par));
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

bool isDag(int id){
  queue<int> Q;  
  vector<int> C(N,0);
  int cc=0;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    C[ b[i] ]++;
  }
  for(int i=0;i<N;i++)if(C[i]==0)Q.push(i);

  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  return (cc==N);
}

void visit(int v){
  if(visited[v])return;
  visited[v]=true;
  for(int i=0;i<(int)G[v].size();i++){
    visit(G[v][i].to);
  }
}

int calcDec(int id){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    G[ b[i] ].push_back( (edge){b[i],a[i],i} );
  }
  int res=0;
  memset(visited,false,sizeof(visited));
  for(int i=0;i<N;i++){
    if(!visited[i]){
      res++;
      visit(i);
    }
  }
  return res;
}

map<int,int> mm;
bool check(int id){
  if(mm.count(id))return false;
  mm[id]=true;
  
  if(countB(id) + calcDec(id)>=3&&isDag(id))return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if( rec(e.to,si) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    loope.clear();
    if( rec(i,i) )break;
  }
  
  for(int i=0;i<(int)loope.size();i++)
    if(check( loope[i].id ))return true;

  return false;
}

bool solve(){
  int B=countB(-1);
  if(B==M)return false;
  
  if( !isDag(-1) )return solve2();

  /*
  for(int i=0;i<M;i++){
    if(check(i)){
      return true;
    }
  }
  */
  int maxm=0;

  
  B=countB(-1);
  for(int i=0;i<(int)edge_.size();i++){
    edge e=edge_[i];
    int a=e.from;
    int cc=0;
    while(1){
      if(a==e.to)break;
      if(cnt[a]==1)cc++;
      a=par[a];
    }
    maxm=max(maxm,cc);
  }

  for(int i=0;i<M;i++)
    if(check(i))return true;
  /*
  vector<edge> tmp=edge_;
  for(int i=0;i<(int)tmp.size();i++){
    edge e=tmp[i];
    if(check(e.id))return true;
  }
  */
  return (B+maxm>=2);
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 1
time_ms: 1020
memory_kb: 6172
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 50000
struct edge{ int from,to,id; };

int N,M;
int a[MAX_M],b[MAX_M];
bool flg[MAX_M];

vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
int par[MAX_N];


vector<edge> bridges;


vector<edge> edge_;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      par[to]=pos;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
      edge_.push_back(G[pos][i]);
    }
  }
}

int countB(int id){
  bridges.clear();
  edge_.clear();
  
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  memset(par,-1,sizeof(par));
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

bool isDag(int id){
  queue<int> Q;  
  vector<int> C(N,0);
  int cc=0;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    C[ b[i] ]++;
  }
  for(int i=0;i<N;i++)if(C[i]==0)Q.push(i);

  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  return (cc==N);
}

void visit(int v){
  if(visited[v])return;
  visited[v]=true;
  for(int i=0;i<(int)G[v].size();i++){
    visit(G[v][i].to);
  }
}

int calcDec(int id){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    G[ b[i] ].push_back( (edge){b[i],a[i],i} );
  }
  int res=0;
  memset(visited,false,sizeof(visited));
  for(int i=0;i<N;i++){
    if(!visited[i]){
      res++;
      visit(i);
    }
  }
  return res;
}

map<int,int> mm;
bool check(int id){
  if(mm.count(id))return false;
  mm[id]=true;
  
  if(countB(id) + calcDec(id)>=3&&isDag(id))return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if( rec(e.to,si) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    loope.clear();
    if( rec(i,i) )break;
  }
  
  for(int i=0;i<(int)loope.size();i++)
    if(check( loope[i].id ))return true;

  return false;
}

bool solve(){
  int B=countB(-1);
  if(B==M)return false;
  
  if( !isDag(-1) )return solve2();

  /*
  for(int i=0;i<M;i++){
    if(check(i)){
      return true;
    }
  }
  */
  int maxm=0;

  
  B=countB(-1);
  for(int i=0;i<(int)edge_.size();i++){
    edge e=edge_[i];
    int a=e.from;
    int cc=0;
    while(1){
      if(a==e.to)break;
      if(cnt[a]==1)cc++;
      a=par[a];
    }
    maxm=max(maxm,cc);
  }
  vector<edge> tmp=edge_;
  for(int i=0;i<(int)tmp.size();i++){
    edge e=tmp[i];
    if(check(e.id))return true;
  }
  return (B+maxm>=2);
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 0.29411764705882354
time_ms: 240
memory_kb: 4448
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 50000
struct edge{ int from,to,id; };

int N,M;
int a[MAX_M],b[MAX_M];
bool flg[MAX_M];

vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
int par[MAX_N];


vector<edge> bridges;


vector<edge> edge_;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      par[to]=pos;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
      edge_.push_back(G[pos][i]);
    }
  }
}

int countB(int id){
  bridges.clear();
  edge_.clear();
  
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  memset(par,-1,sizeof(par));
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

bool isDag(int id){
  queue<int> Q;  
  vector<int> C(N,0);
  int cc=0;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    C[ b[i] ]++;
  }
  for(int i=0;i<N;i++)if(C[i]==0)Q.push(i);

  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  return (cc==N);
}

void visit(int v){
  if(visited[v])return;
  visited[v]=true;
  for(int i=0;i<(int)G[v].size();i++){
    visit(G[v][i].to);
  }
}

int calcDec(int id){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    G[ b[i] ].push_back( (edge){b[i],a[i],i} );
  }
  int res=0;
  memset(visited,false,sizeof(visited));
  for(int i=0;i<N;i++){
    if(!visited[i]){
      res++;
      visit(i);
    }
  }
  return res;
}

map<int,int> mm;
bool check(int id){
  if(mm.count(id))return false;
  mm[id]=true;
  
  if(countB(id) + calcDec(id)>=3&&isDag(id))return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if( rec(e.to,si) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    loope.clear();
    if( rec(i,i) )break;
  }
  
  for(int i=0;i<(int)loope.size();i++)
    if(check( loope[i].id ))return true;

  return false;
}

bool solve(){
  int B=countB(-1);
  if(B==M)return false;
  
  if( !isDag(-1) )return solve2();

  /*
  for(int i=0;i<M;i++){
    if(check(i)){
      return true;
    }
  }
  */
  int maxm=0;

  
  B=countB(-1);
  for(int i=0;i<(int)edge_.size();i++){
    edge e=edge_[i];
    int a=e.from;
    int cc=0;
    while(1){
      if(a==e.to)break;
      if(cnt[a]==1)cc++;
      a=par[a];
    }
    maxm=max(maxm,cc);

  }
  for(int i=0;i<(int)edge_.size();i++){
    edge e=edge_[i];
    if(check(e.id))return true;
  }
  return (B+maxm>=2);
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 0.29411764705882354
time_ms: 240
memory_kb: 4448
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 50000
struct edge{ int from,to,id; };

int N,M;
int a[MAX_M],b[MAX_M];
bool flg[MAX_M];

vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
int par[MAX_N];


vector<edge> bridges;


vector<edge> edge_;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      par[to]=pos;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
      edge_.push_back(G[pos][i]);
    }
  }
}

int countB(int id){
  bridges.clear();
  edge_.clear();
  
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  memset(par,-1,sizeof(par));
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

bool isDag(int id){
  queue<int> Q;  
  vector<int> C(N,0);
  int cc=0;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    C[ b[i] ]++;
  }
  for(int i=0;i<N;i++)if(C[i]==0)Q.push(i);

  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  return (cc==N);
}

void visit(int v){
  if(visited[v])return;
  visited[v]=true;
  for(int i=0;i<(int)G[v].size();i++){
    visit(G[v][i].to);
  }
}

int calcDec(int id){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    G[ b[i] ].push_back( (edge){b[i],a[i],i} );
  }
  int res=0;
  memset(visited,false,sizeof(visited));
  for(int i=0;i<N;i++){
    if(!visited[i]){
      res++;
      visit(i);
    }
  }
  return res;
}

map<int,int> mm;
bool check(int id){
  if(mm.count(id))return false;
  mm[id]=true;
  
  if(countB(id) + calcDec(id)>=3&&isDag(id))return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if( rec(e.to,si) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    loope.clear();
    if( rec(i,i) )break;
  }
  
  for(int i=0;i<(int)loope.size();i++)
    if(check( loope[i].id ))return true;

  return false;
}

bool solve(){
  int B=countB(-1);
  if(B==M)return false;
  
  if( !isDag(-1) )return solve2();

  /*
  for(int i=0;i<M;i++){
    if(check(i)){
      return true;
    }
  }
  */
  int maxm=0;

  
  B=countB(-1);
  for(int i=0;i<(int)edge_.size();i++){

    edge e=edge_[i];
    if(check(e.id))return true;
    /*
    int a=e.from;
    int cc=0;
    while(1){
      if(a==e.to)break;
      if(cnt[a]==1)cc++;
      a=par[a];
    }
    maxm=max(maxm,cc);
    */
  }
  return (B+maxm>=2);
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 0.23529411764705882
time_ms: 240
memory_kb: 4468
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 50000
struct edge{ int from,to,id; };

int N,M;
int a[MAX_M],b[MAX_M];
bool flg[MAX_M];

vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
int par[MAX_N];


vector<edge> bridges;


vector<edge> edge_;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      par[to]=pos;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
      edge_.push_back(G[pos][i]);
    }
  }
}

int countB(int id){
  bridges.clear();
  edge_.clear();
  
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  memset(par,-1,sizeof(par));
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

bool isDag(int id){
  queue<int> Q;  
  vector<int> C(N,0);
  int cc=0;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    C[ b[i] ]++;
  }
  for(int i=0;i<N;i++)if(C[i]==0)Q.push(i);

  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  return (cc==N);
}

void visit(int v){
  if(visited[v])return;
  visited[v]=true;
  for(int i=0;i<(int)G[v].size();i++){
    visit(G[v][i].to);
  }
}

int calcDec(int id){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    G[ b[i] ].push_back( (edge){b[i],a[i],i} );
  }
  int res=0;
  memset(visited,false,sizeof(visited));
  for(int i=0;i<N;i++){
    if(!visited[i]){
      res++;
      visit(i);
    }
  }
  return res;
}

map<int,int> mm;
bool check(int id){
  if(mm.count(id))return false;
  mm[id]=true;
  
  if(countB(id) + calcDec(id)>=3&&isDag(id))return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if( rec(e.to,si) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    loope.clear();
    if( rec(i,i) )break;
  }
  
  for(int i=0;i<(int)loope.size();i++)
    if(check( loope[i].id ))return true;

  return false;
}

bool solve(){
  int B=countB(-1);
  if(B==M)return false;


  
  if( !isDag(-1) )return solve2();

  for(int i=0;i<M;i++){
    if(check(i)){
      return true;
    }
  }
    
  int maxm=0;

  B=countB(-1);
  for(int i=0;i<(int)edge_.size();i++){
    edge e=edge_[i];
    int a=e.from;
    int cc=0;
    while(1){
      if(a==e.to)break;
      if(cnt[a]==1)cc++;
      a=par[a];
      //      cout<<"a="<<a<<endl;
      //      cout<<"par[a]="<<par[a]<<endl;
      //      cout<<e.from<<' '<<e.to<<endl;
    }
    maxm=max(maxm,cc);
  }
  return (B+maxm>=2);
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 1
time_ms: 1090
memory_kb: 6096
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 30000
struct edge{ int from,to,id; };

int N,M;
int a[MAX_M],b[MAX_M];
bool flg[MAX_M];

vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
int par[MAX_N];


vector<edge> bridges;


vector<edge> edge_;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      par[to]=pos;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
      edge_.push_back(G[pos][i]);
    }
  }
}

int countB(int id){
  bridges.clear();
  edge_.clear();
  
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  memset(par,-1,sizeof(par));
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

bool isDag(int id){
  queue<int> Q;  
  vector<int> C(N,0);
  int cc=0;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    C[ b[i] ]++;
  }
  for(int i=0;i<N;i++)if(C[i]==0)Q.push(i);

  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  return (cc==N);
}

void visit(int v){
  if(visited[v])return;
  visited[v]=true;
  for(int i=0;i<(int)G[v].size();i++){
    visit(G[v][i].to);
  }
}

int calcDec(int id){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    G[ b[i] ].push_back( (edge){b[i],a[i],i} );
  }
  int res=0;
  memset(visited,false,sizeof(visited));
  for(int i=0;i<N;i++){
    if(!visited[i]){
      res++;
      visit(i);
    }
  }
  return res;
}

map<int,int> mm;
bool check(int id){
  if(mm.count(id))return false;
  mm[id]=true;
  
  if(countB(id) + calcDec(id)>=3&&isDag(id))return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if( rec(e.to,si) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    loope.clear();
    if( rec(i,i) )break;
  }
  
  for(int i=0;i<(int)loope.size();i++)
    if(check( loope[i].id ))return true;

  return false;
}

bool solve(){
  int B=countB(-1);
  if(B==M)return false;


  
  if( !isDag(-1) )return solve2();

    for(int i=0;i<M;i++){
    if(check(i)){
      return true;
    }
  }
    
  int maxm=0;

  B=countB(-1);
  for(int i=0;i<(int)edge_.size();i++){
    edge e=edge_[i];
    int a=e.from;
    int cc=0;
    while(1){
      if(a==e.to)break;
      if(cnt[a]==1)cc++;
      a=par[a];
      //      cout<<"a="<<a<<endl;
      //      cout<<"par[a]="<<par[a]<<endl;
      //      cout<<e.from<<' '<<e.to<<endl;
    }
    maxm=max(maxm,cc);
  }
  return (B+maxm>=2);
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 0.4852941176470588
time_ms: 310
memory_kb: 4632
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 30000
struct edge{ int from,to,id; };

int N,M;
int a[MAX_M],b[MAX_M];
bool flg[MAX_M];

vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
int par[MAX_N];


vector<edge> bridges;


vector<edge> edge_;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      par[to]=pos;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
      edge_.push_back(G[pos][i]);
    }
  }
}

int countB(int id){
  bridges.clear();
  edge_.clear();
  
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  memset(par,-1,sizeof(par));
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

bool isDag(int id){
  queue<int> Q;  
  vector<int> C(N,0);
  int cc=0;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){a[i],b[i],i} );
    C[ b[i] ]++;
  }
  for(int i=0;i<N;i++)if(C[i]==0)Q.push(i);

  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  return (cc==N);
}

map<int,int> mm;
bool check(int id){
  if(mm.count(id))return false;
  mm[id]=true;
  if(flg[id])return false;
  
  int B=countB(id);
  if(B<2)return false;
  if(isDag(id))return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if( rec(e.to,si) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    loope.clear();
    if( rec(i,i) )break;
  }
  
  for(int i=0;i<(int)loope.size();i++)
    if(check( loope[i].id ))return true;

  return false;
}

bool solve(){
  int B=countB(-1);
  if(B==M)return false;
  for(int i=0;i<(int)bridges.size();i++)flg[ bridges[i].id ]=true;
  if( !isDag(-1) )return solve2();

  int maxm=0;

  for(int i=0;i<(int)edge_.size();i++){
    edge e=edge_[i];
    int a=e.from;
    int cc=0;
    while(1){
      if(a==e.to)break;
      if(cnt[a]==1)cc++;
      a=par[a];
      //      cout<<"a="<<a<<endl;
      //      cout<<"par[a]="<<par[a]<<endl;
      //      cout<<e.from<<' '<<e.to<<endl;
    }
    maxm=max(maxm,cc);
  }
  return (B+maxm>=2);
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 0.29411764705882354
time_ms: 140
memory_kb: 4368
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 30000
struct edge{ int from,to,id; };
int N,M;
int a[MAX_M],b[MAX_M];
vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
vector<edge> bridges;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
    }
  }
}

int countB(int id){
  bridges.clear();
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

map<int,int> mm;
bool check(int id){
  if(mm.count(id))return false;
  mm[id]=true;
  
  int B=countB(id);

  memset(visited,false,sizeof(visited));
  int U=0;
  for(int i=0;i<N;i++)
    if(!visited[i])U++,dfs(i,-1);
  
  if(B+U<3)return false;
  
  queue<int> Q;
  vector<int> C(N,0);
  for(int i=0;i<M;i++)
    if(id!=i)C[ b[i] ]++;
  for(int i=0;i<N;i++)
    if(C[i]==0)Q.push(i);
  int cc=0;
  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  if(cc==N)return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si,int pre=-1){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if(e.id==pre)continue;
    
    if( rec(e.to,si,e.id) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){

  map<int,bool> used;
  for(int i=0;i<M;i++){
    if(used[a[i]])continue;
    if(check(i))return true;
    used[ a[i] ]=true;
  }
  
  used.clear();
  for(int i=0;i<M;i++){
    if(used[b[i]])continue;
    if(check(i))return true;
    used[ b[i] ]=true;
  }
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    memset(depth,0,sizeof(depth));
    loope.clear();
    if( rec(i,i) ){
      break;
    }
  }
  for(int i=0;i<(int)loope.size();i++){
    if(check( loope[i].id ))return true;
  }
  return false;
}

bool solve(){
  if(countB(-1)==M)return false;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  if(solve2())return true;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  for(int i=0;i<M;i++)G[ b[i] ].push_back( (edge){b[i],a[i],i} );
  if(solve2())return true;  
  return false;
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 0.4852941176470588
time_ms: 530
memory_kb: 4176
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 500
#define MAX_M 30000
struct edge{ int from,to,id; };
int N,M;
int a[MAX_M],b[MAX_M];
vector<edge> G[MAX_N];

bool visited[MAX_N];
int depth[MAX_N];
int cnt[MAX_N];
vector<edge> bridges;

void dfs(int pos,int prev){
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    int to=G[pos][i].to;
    if(to==prev)continue;
    if(!visited[to]){
      depth[to]=depth[pos]+1;
      dfs(to,pos);
      cnt[pos]+=cnt[to];
      if(cnt[to]==0)bridges.push_back(G[pos][i]);
    }else if(depth[to]<depth[pos]){
      cnt[pos]++;
      cnt[to]--;
    }
  }
}

int countB(int id){
  bridges.clear();
  memset(visited,false,sizeof(visited));
  memset(depth,0,sizeof(depth));
  memset(cnt,0,sizeof(cnt));
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++){
    if(i==id)continue;
    G[ a[i] ].push_back( (edge){ a[i],b[i],i } );
    G[ b[i] ].push_back( (edge){ b[i],a[i],i } );
  }
  for(int i=0;i<N;i++){
    if(visited[i])continue;
    dfs(i,-1);
  }
  return bridges.size();
}

bool check(int id){
  int B=countB(id);

  memset(visited,false,sizeof(visited));
  int U=0;
  for(int i=0;i<N;i++)
    if(!visited[i])U++,dfs(i,-1);
  
  if(B+U<3)return false;
  
  queue<int> Q;
  vector<int> C(N,0);
  for(int i=0;i<M;i++)
    if(id!=i)C[ b[i] ]++;
  for(int i=0;i<N;i++)
    if(C[i]==0)Q.push(i);
  int cc=0;
  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    cc++;
    for(int i=0;i<(int)G[pos].size();i++){
      int to=G[pos][i].to;
      C[to]--;
      if(C[to]==0)Q.push(to);
    }
  }
  if(cc==N)return true;
  else return false;
}

vector<edge> loope;
bool rec(int pos,int si,int pre=-1){
  if(visited[pos])return (pos==si);
  visited[pos]=true;
  for(int i=0;i<(int)G[pos].size();i++){
    edge e=G[pos][i];
    if(e.id==pre)continue;
    
    if( rec(e.to,si,e.id) ){
      loope.push_back(e);
      return true;
    }
  }
  return false;
}

bool solve2(){

  map<int,bool> used;
  for(int i=0;i<M;i++){
    if(used[a[i]])continue;
    if(check(i))return true;
    used[ a[i] ]=true;
  }
  
  for(int i=0;i<N;i++){
    memset(visited,false,sizeof(visited));
    memset(depth,0,sizeof(depth));
    loope.clear();
    if( rec(i,i) ){
      break;
    }
  }
  for(int i=0;i<(int)loope.size();i++){
    if(check( loope[i].id ))return true;
  }
  return false;
}

bool solve(){
  if(countB(-1)==M)return false;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  if(solve2())return true;
  
  for(int i=0;i<N;i++)G[i].clear();
  for(int i=0;i<M;i++)G[ a[i] ].push_back( (edge){a[i],b[i],i} );
  for(int i=0;i<M;i++)G[ b[i] ].push_back( (edge){b[i],a[i],i} );
  if(solve2())return true;  
  return false;
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  cout<< ( solve() ? "YES" : "NO" ) <<endl;
  return 0;
}
accuracy: 0.4852941176470588
time_ms: 840
memory_kb: 4068
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define pb push_back
#define fi first
#define se second
template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

namespace SCC{
    void visit(const vector<vector<int>>&G,vector<int>&vs,vector<int>&used,int v){
        used[v]=true;
        for(auto u:G[v]){
            if(!used[u])visit(G,vs,used,u);
        }
        vs.push_back(v);
    }

    void visit2(const vector<vector<int>>&T,vector<int>&used,vector<int>&comp,vector<int>&vec,int k,int v){
        comp[v]=k;
        used[v]=true;
        vec.push_back(v);

        for(auto u:T[v]){
            if(!used[u])visit2(T,used,comp,vec,k,u);
        }
    }

    //G:?????£?????????????§£???????????°??????
    //H:?????£??????????????°??????1???????????????????´?????????°??????
    //comp:G????????????????????????H?????????????±????????????????
    void decompose(const vector<vector<int>>&G,vector<vector<int>>&H,vector<int>&comp){
        vector<vector<int>>T(G.size());
        for(int i=0;i<G.size();i++){
            for(auto v:G[i]){
                T[v].push_back(i);
            }
        }
        comp.resize(G.size());

        vector<int>vs(G.size());
        vector<int>used(G.size());
        for(int i=0;i<G.size();i++){
            if(!used[i])visit(G,vs,used,i);
        }
        reverse(vs.begin(),vs.end());
        fill(used.begin(),used.end(),0);

        int K=0;
        vector<vector<int>>S;
        for(auto v:vs){
            if(!used[v]){
                S.push_back(vector<int>());
                visit2(T,used,comp,S.back(),K++,v);
            }
        }

        H.resize(K);
        fill(used.begin(),used.end(),0);
        for(int i=0;i<K;i++){
            for(auto v:S[i]){
                for(auto u:G[v]){
                    if(used[comp[u]]||comp[v]==comp[u])continue;
                    used[comp[u]]=true;
                    H[comp[v]].push_back(comp[u]);
                }
            }
            for(auto v:H[i])used[v]=false;
        }

    }
}

struct UF{
    vector<int>par,sz;
    void init(int n){
        par.resize(n);
        sz.resize(n);
        for(int i=0;i<n;i++){
            par[i]=i;
            sz[i]=1;
        }
    }
    int find(int x){
        return x==par[x]?x:par[x]=find(par[x]);
    }
    void unite(int x,int y){
        x=find(x);y=find(y);
        if(x==y)return;
        sz[x]+=sz[y];
        par[y]=x;
    }
    bool same(int x,int y){
        return find(x)==find(y);
    }
    int size(int x){
        return sz[find(x)];
    }
};

vector<vint>G;
vector<pair<int, int> > bridge;
int ord[1000], low[1000];
bool vis[1000];

void dfs(int v, int p, int &k)
{
	vis[v] = true;

	ord[v] = k++;
	low[v] = ord[v];

	for (int i = 0; i < G[v].size(); i++){
		if (!vis[G[v][i]]){
			dfs(G[v][i], v, k);
			low[v] = min(low[v], low[G[v][i]]);
			if (ord[v] < low[G[v][i]]) bridge.push_back(make_pair(min(v, G[v][i]), max(v, G[v][i])));
		}
		else if (G[v][i] != p){
			low[v] = min(low[v], ord[G[v][i]]);
		}
	}
}

int A[100000],B[100000];

vint T[1000];

int N,M;
vpint backer;
int sum[1000];
int par[1000];
int dep[1000];
void dfs2(int v,int p,int d){
    vis[v]=true;
    par[v]=p;
    dep[v]=d;
    for(auto u:G[v]){
        if(u==p)continue;
        if(vis[u])backer.pb(pint(min(u,v),max(u,v)));
        else{
            dfs2(u,v,d+1);
        }
    }
}

void solve(){
    G=vector<vint>(N);
    rep(i,M)G[A[i]].pb(B[i]),G[B[i]].pb(A[i]);
    memset(vis,0,sizeof(vis));
    dfs2(0,-1,0);
    sort(all(backer));backer.erase(unique(all(backer)),backer.end());

    rep(i,backer.size()){
        int v=backer[i].fi,u=backer[i].se;
        while(v!=u){
            if(dep[v]<dep[u])swap(v,u);
            sum[v]++;
            v=par[v];
        }
    }

    rep(i,backer.size()){
        int v=backer[i].fi,u=backer[i].se;
        while(v!=u){
            if(dep[v]<dep[u])swap(v,u);
            sum[v]--;
            v=par[v];
        }
        int cnt=0;
        reps(j,1,N)if(sum[j]==0)cnt++;

        if(cnt>=2){
            cout<<"YES"<<endl;
            return;
        }

        v=backer[i].fi;u=backer[i].se;
        while(v!=u){
            if(dep[v]<dep[u])swap(v,u);
            sum[v]++;
            v=par[v];
        }
    }
    cout<<"NO"<<endl;
}

signed main(){
    cin>>N>>M;
    rep(i,M)cin>>A[i]>>B[i],A[i]--,B[i]--;

    bool flag=false;
    int deg[1000]={};
    {
        vector<vint>G(N),H;
        rep(i,M)G[A[i]].pb(B[i]);
        vint comp;
        SCC::decompose(G,H,comp);
        rep(i,M){
            if(comp[A[i]]==comp[B[i]])deg[B[i]]++;
        }
        if(H.size()==N)flag=true;
    }

    if(!flag){
        rep(i,M){
            if(deg[B[i]]!=1)continue;
            UF uf;
            uf.init(N);
            rep(j,M)if(i!=j)uf.unite(A[j],B[j]);
            bool ok=true;
            rep(j,N)if(uf.find(j)!=uf.find(0))ok=false;
            if(!ok)continue;
            G=vector<vint>(N);
            rep(j,M)if(i!=j)G[A[j]].pb(B[j]);
            vector<vint>H;vint comp;
            SCC::decompose(G,H,comp);
            if(H.size()!=N)continue;
            G=vector<vint>(N);
            rep(j,M)if(i!=j)G[A[j]].pb(B[j]),G[B[j]].pb(A[j]);
            memset(vis,0,sizeof(vis));
            int K=0;
            bridge.clear();
            dfs(0,-1,K);
            if(bridge.size()>=2){
                cout<<"YES"<<endl;
                return 0;
            }
        }
        cout<<"NO"<<endl;
        return 0;
    }

    solve();
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 10
memory_kb: 3884
final_rank: 8

code_snippet: #include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#define rep(i,n) for (int i = 0; i < n; ++i)
#define drep(i,n) for (int i = n-1; i >= 0; --i)
#define pb push_back
#define sz(x) int(x.size())
#define mins(x,y) x = min(x,y)
#define maxs(x,y) x = max(x,y)
using namespace std;
inline int in() { int x; scanf("%d", &x); return x;}
typedef vector<int> vi;
typedef vector<vi> vvi;

struct Lowlink {
  int n, k;
  vvi to, st, br;
  vi ord, low;
  Lowlink(int n=0):n(n),to(n),st(n),br(n),ord(n,-1),low(n){}
  void add(int a, int b) {
    to[a].pb(b); st[a].pb(0);
    to[b].pb(a); st[b].pb(0);
  }
  void dfs(int v, int p=-1) {
    ord[v] = low[v] = k++;
    rep(i,sz(to[v])) {
      int u = to[v][i];
      if (u == p) continue;
      if (ord[u] == -1) {
        st[v][i] = 1;
        dfs(u,v);
        mins(low[v],low[u]);
      } else {
        st[v][i] = -1;
        mins(low[v],ord[u]);
      }
    }
  }
  int init() {
    k = 0;
    dfs(0);
    int res = 0;
    rep(i,n)rep(j,sz(to[i])) {
      int v = i, u = to[i][j];
      if (ord[v] > ord[u]) swap(v,u);
      if (ord[u] == low[u]) res++;
      br[i].pb(ord[u] == low[u]);
    }
    return res/2;
  }
};

int n, m;
vvi to;
vi used, vs;

int rv;
bool cfs(vvi& to, int v) {
  if (used[v]) {
    if (used[v] == 2) return false;
    rv = v;
    return true;
  }
  used[v] = 1;
  for (int u : to[v]) {
    if (cfs(to,u)) {
      if (rv != -1) vs.pb(v);
      if (rv == v) rv = -1;
      return true;
    }
  }
  used[v] = 2;
  return false;
}
bool findCycle(vvi& to) {
  used = vi(n);
  rv = -1;
  rep(i,n) if (!used[i]) {
    if (cfs(to,i)) return true;
  }
  return false;
}
bool solve1(int u, int v) {
  // printf("%d %d\n", v, u);
  vvi t(n);
  rep(i,n) for (int j : to[i]) {
    if (i == v && j == u) continue;
    t[i].pb(j);
    // printf("edge %d %d\n", i, j);
  }
  if (findCycle(t)) return false;
  // printf("%d %d\n", v, u);
  Lowlink g(n);
  rep(i,n) for (int j : to[i]) {
    if (i == v && j == u) continue;
    g.add(i,j);
  }
  return g.init() >= 2;
}
bool solve2(Lowlink& g, int ei, int ej) {
  Lowlink t(n);
  rep(i,n)rep(j,sz(g.to[i])) {
    if (ei == i && ej == j) continue;
    int u = g.to[i][j];
    if (!g.st[i][j]) continue;
    if (g.st[i][j] == -1 && i < u) continue;
    t.add(i,u);
  }
  return t.init() >= 2;
}

int main() {
  n = in(); m = in();
  to = vvi(n);
  rep(i,m) {
    int a = in(), b = in();
    --a; --b;
    to[a].pb(b);
  }
  if (findCycle(to)) {
    int s = sz(vs);
    rep(i,s) {
      if (solve1(vs[i],vs[(i+1)%s])) {
        puts("YES");
        return 0;
      }
    }
  } else if (m >= n) {
    Lowlink g(n);
    rep(i,n) for (int u : to[i]) g.add(i,u);
    if (g.init() >= 2) {
      puts("YES");
      return 0;
    }
    rep(i,n) rep(j,sz(g.to[i])) {
      if (g.st[i][j] != 1 || g.br[i][j]) continue;
      if (solve2(g,i,j)) {
        puts("YES");
        return 0;
      }
    }
  }
  puts("NO");
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3496
final_rank: 1