Problem:
Problem E:
Huge Family
Mr. Dango's family has extremely huge number of members. Once it had about 100 members, and now it has as many as population of a city. It is jokingly guessed that the member might fill this planet in near future. They all have warm and gracious personality and are close each other.
They usually communicate by a phone. Of course, They are all taking a family plan. This family plan is such a thing: when
a
choose
b
, and
b
choose
a
as a partner, a family plan can be applied between them and then the calling fee per unit time between them discounted to
f
(
a
,
b
), which is cheaper than a default fee. Each person can apply a family plan at most 2 times, but no same pair of persons can apply twice. Now, choosing their partner appropriately, all members of Mr. Dango's family applied twice.
Since there are huge number of people, it is very difficult to send a message to all family members by a phone call. Mr. Dang have decided to make a phone calling network that is named '
clan
' using the family plan. Let us present a definition of
clan
.
Let
S
be an any subset of all phone calls that family plan is applied.
Clan
is
S
such that:
For any two persons (let them be
i
and
j
), if
i
can send a message to
j
through phone calls that family plan is applied (directly or indirectly), then
i
can send a message to
j
through only phone calls in
S
(directly or indirectly).
Meets condition 1 and a sum of the calling fee per unit time in
S
is minimized.
Clan
allows to send a message efficiently. For example, we suppose that one have sent a message through all calls related to him in the clan. Additionaly we suppose that every people follow a rule, "when he/she receives a message through a call in clan, he/she relays the message all other neibors in respect to clan." Then, we can prove that this message will surely be derivered to every people that is connected by all discounted calls, and that the message will never be derivered two or more times to same person.
By the way, you are given information about application of family plan of Mr. Dango's family. Please write a program that calculates that in how many ways a different clan can be constructed. You should output the answer modulo 10007 because it may be very big.
Input
The input consists of several datasets.
The first line of each dataset contains an integer
n
, which indicates the number of members in the family.
Next
n
lines represents information of the
i
-th member with four integers. The first two integers respectively represent
b
[0] (the partner of
i
) and f(
i
,
b
[0]) (the calling fee per unit time between
i
and
b
[0]). The following two integers represent
b
[1] and
f
(
i
,
b
[1]) in the same manner.
Input terminates with a dataset where n = 0.
Output
For each dataset, output the number of
clan
modulo 10007.
Constraints
3 ≤
n
≤ 100,000
Sample Input
3
1 1 2 3
0 1 2 2
1 2 0 3
7
1 2 2 1
0 2 3 2
0 1 3 1
2 1 1 2
5 3 6 2
4 3 6 1
4 2 5 1
0
Output for the Sample Input
1
2

Submitted solutions:

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

typedef pair<int,int> P;

vector<P> G[N];
bool used[N],used2[N];

map<int,int> cnt;
set<P> usedP;

void dfs(int x){
  
  if(used2[x])return;
  used2[x]=1;
  used[x]=1;
  
  for(int i=0;i<G[x].size();i++){

    int nx=G[x][i].first,cost=G[x][i].second;
    
    if(!usedP.count(P(min(x,nx),max(x,nx)))){
      usedP.insert(P(min(x,nx),max(x,nx)));
      if(cnt.count(cost))cnt[cost]++;
      else cnt[cost]=1;
    }

    dfs(nx);
    
  }
  
}

int main(){

  int n;
  
  while(1){
    
    cin>>n;
    if(!n)break;

    for(int i=0;i<n;i++)G[i].clear();
    
    for(int i=0;i<n;i++){
      int a,b;
      cin>>a>>b;
      G[i].push_back(P(a,b));
      cin>>a>>b;
      G[i].push_back(P(a,b));
    }
    
    memset(used,0,sizeof(used));
    
    int ans=1;
    
    for(int i=0;i<n;i++){
      if(used[i])continue;
      
      memset(used2,0,sizeof(used2));
      cnt.clear();
      usedP.clear();
      
      dfs(i);
      
      if(cnt.size()){
	map<int,int>::iterator ite=cnt.end();
	ite--;
	ans=(ans*(*ite).second)%10007;
      }
      
    }
    
    cout<<ans<<endl;
  }
  
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7644
final_rank: 15

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

int b[2][114514], f[2][114514];

bool used[114514];

signed main(){
  int n;
  int mod = 10007;
  while(cin >> n, n) {
    memset(b, -1, sizeof(b));
    memset(f, -1, sizeof(f));
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < 2; j++) cin >> b[j][i] >> f[j][i];
    }
    memset(used, false, sizeof(used));
    int ans = 1;
    for(int i = 0; i < n; i++) {
      if(used[i]) continue;
      set<int> st;
      queue<int> que;    
      que.push(i);
      while(!que.empty()) {
	int u = que.front(); que.pop();
	if(used[u]) continue;
	used[u] = true;
	st.insert(u);
	que.push(b[0][u]);	
	que.push(b[1][u]);
      }
      map<int, int> m;
      for(int j : st) {
	m[f[0][j]]++;
	m[f[1][j]]++;
      }
      auto it = m.end(); it--;
      (ans *= it->second/2) %=  mod;
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7252
final_rank: 14

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1e8;
class SCC{//cmp(0 - kk-1) is scc's return. Same number is group. The number is no relatoin.
	public:
	int n;
	vvi G,rG;
	vector<bool>used;
	vi vs,cmp;
	vvp cost;
	void init(int size){
		n=size;
		G=rG=vvi(n);
		used=vector<bool>(n);
		cmp=vi(n);
		cost=vvp(n);
		vs=vi(0);
	}
	void add_edge(int s,int t,int c){
		cost[s].pb(pii(t,c));
		G[s].pb(t);
		rG[t].pb(s);
	}
	void rdfs(int v,int k){
		used[v]=true;
		cmp[v]=k;
		rep(i,rG[v].size())if(!used[rG[v][i]])rdfs(rG[v][i],k);
	}
	void dfs(int v){
		used[v]=true;
		rep(i,G[v].size())if(!used[G[v][i]])dfs(G[v][i]);
		vs.pb(v);
	}
	int scc(){
		rep(i,n)used[i]=false;
		rep(v,n)if(!used[v])dfs(v);
		rep(i,n)used[i]=false;
		int kk=0;
		for(int i=vs.size()-1;i>=0;i--)if(!used[vs[i]])rdfs(vs[i],kk++);
		return kk;  
	}
	void solve(){
		int N=scc();
		vi ma(N),co(N);
		rep(i,n)rep(j,cost[i].size()){
			int t=cost[i][j].first;
			if(cmp[t]==cmp[i]){
				ma[cmp[t]]=max(ma[cmp[t]],cost[i][j].second);
			}
		}
		rep(i,n)rep(j,cost[i].size()){
			int t=cost[i][j].first;
			if(cmp[t]==cmp[i]&&ma[cmp[t]]==cost[i][j].second){
				co[cmp[t]]++;
			}
		}
		int out=1;
		rep(i,N)(out*=co[i]/2)%=10007;
		cout<<out<<endl;
	}
};
int main(){
	int n;
	SCC scc;
	while(cin>>n,n){
		scc.init(n);
		rep(i,n){
			int a,b,c,d;
			cin>>a>>b>>c>>d;
			scc.add_edge(i,a,b);
			scc.add_edge(i,c,d);
		}
		scc.solve();
	}
}
accuracy: 1
time_ms: 10
memory_kb: 4744
final_rank: 13

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

struct Edge { int src,dst,weight; };
const int MAX_V = 100100;
const int mod = 10007;
vector<Edge> G[MAX_V];
int V;
int group[MAX_V];
int maxi[MAX_V];

void dfs(int cur,int index){
  rep(i,(int)G[cur].size()) {
    int next = G[cur][i].dst;
    if( group[next] == -1 ) {
      group[next] = index;
      dfs(next,index);
    }
  }
}

int main(){
  while( cin >> V, V ){
    rep(i,V) G[i].clear();
    rep(i,V) {
      rep(_,2){
        int dst,weight;
        cin >> dst >> weight;
        G[i].push_back((Edge){i,dst,weight});
      }
    }
    memset(group,-1,sizeof(group));
    memset(maxi,0,sizeof(maxi));
    int size_ = 0;
    rep(i,V) if( group[i] == -1 ) {
      group[i] = size_;
      dfs(i,size_);
      ++size_;
    }

    rep(i,V) rep(j,(int)G[i].size()) maxi[group[i]] = max(maxi[group[i]],G[i][j].weight);
    vector<int> counter(size_,0);
    rep(i,V) rep(j,(int)G[i].size()) if( maxi[group[i]] == G[i][j].weight ) ++counter[group[i]];
    int answer = 1;
    rep(i,size_) ( answer *= int(counter[i]/2) ) %= mod;
    cout << answer << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5120
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int mod=10007;
typedef pair<int,int> P;
 
int M,cnt;
vector<P> v[100001];
bool u[100001];
vector<int> a;
 
void dfs(int x) {
  u[x]=true;
  a.push_back(x);
  for(int i=0; i<v[x].size(); i++) {
    if(!u[v[x][i].first]) {
      M=max(M,v[x][i].second);
      dfs(v[x][i].first);
    }
  }
}
 
void solve() {
  cnt=0;
  for(int i=0; i<a.size(); i++) {
    for(int j=0; j<v[a[i]].size(); j++) {
      if(M==v[a[i]][j].second) cnt++;
    }
  }
}
 
int main() {
  int n;
  while(cin >> n && n) {
    for(int i=0; i<n; i++) {
      v[i].clear();
      int x,y;
      cin >> x >> y;
      v[i].push_back(P(x,y));
      cin >> x >> y;
      v[i].push_back(P(x,y));
    }
    int ans=1;
    memset(u,false,sizeof(u));
    for(int i=0; i<n; i++) {
      if(!u[i]) {
    M=0;
    a.clear();
    dfs(i);
    solve();
    ans*=cnt/2;
    ans%=mod;
      }
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4388
final_rank: 12

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

struct Edge{
	int src,dst,weight;
	Edge(){}
	Edge(int s,int d,int w):src(s),dst(d),weight(w){}
};
typedef vector<vector<Edge>> Graph;

int main()
{
	for(int n;cin>>n && n;){
		Graph g(n);
		for(int u=0;u<n;u++)
			for(int j=0;j<2;j++){
				int v,w; cin>>v>>w;
				g[u].emplace_back(u,v,w);
			}
		
		int res=1;
		vector<int> vis(n);
		for(int i=0;i<n;i++) if(!vis[i]){
			vector<int> ws;
			int p=-1,u=i;
			do{
				vis[u]=1;
				for(auto e:g[u]) if(e.dst!=p){
					ws.push_back(e.weight);
					p=u,u=e.dst;
					break;
				}
			}while(u!=i);
			(res*=count(begin(ws),end(ws),*max_element(begin(ws),end(ws))))%=10007;
		}
		cout<<res<<endl;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 1900
final_rank: 6

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
int UF[110000];
int FIND(int a){
	if(UF[a]<0)return a;
	return UF[a]=FIND(UF[a]);
}
void UNION(int a,int b){
	a=FIND(a);b=FIND(b);if(a==b)return;UF[a]+=UF[b];UF[b]=a;
}
int c[110000];
int d[110000];
int e[110000];
int f[110000];
int mod=10007;
int m[110000];
int num[110000];
int main(){
	int a;
	while(scanf("%d",&a),a){
		for(int i=0;i<a;i++)UF[i]=-1;
		for(int i=0;i<a;i++){
			scanf("%d%d%d%d",c+i,d+i,e+i,f+i);
			UNION(c[i],i);
			UNION(e[i],i);
		}
		for(int i=0;i<110000;i++)m[i]=num[i]=0;
		for(int i=0;i<a;i++){
			int at=FIND(i);
			if(m[at]<d[i]){
				m[at]=d[i];num[at]=1;
			}else if(m[at]==d[i])num[at]++;
			if(m[at]<f[i]){
				m[at]=f[i];num[at]=1;
			}else if(m[at]==f[i])num[at]++;
		}
		int ret=1;
		for(int i=0;i<a;i++){
			if(FIND(i)==i){
				ret=ret*(num[i]/2)%mod;
			}
		}
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 2176
final_rank: 7

code_snippet: #include<iostream>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

int main() {
  while (true) {
    int n;
    cin >> n;
    if (n == 0) break;
    int edge[n][4];
    rep (i, n) rep (j, 4) cin >> edge[i][j];
    bool used[n];
    fill(used, used + n, false);
    long long res = 1;
    rep (i, n) if (!used[i]) {
      int mx = edge[i][1];
      int cnt = 1;
      int pp = i;
      used[i] = true;
      for (int p = edge[i][0]; p != i; ) {
	used[p] = true;
	if (edge[p][0] == pp) {
	  if (mx == edge[p][3]) {
	    ++cnt;
	  } else if (mx < edge[p][3]) {
	    cnt = 1;
	    mx = edge[p][3];
	  }
	  pp = p;
	  p = edge[p][2];
	} else {
	  if (mx == edge[p][1]) {
	    ++cnt;
	  } else if (mx < edge[p][1]) {
	    cnt = 1;
	    mx = edge[p][1];
	  }
	  pp = p;
	  p = edge[p][0];
	}
      }
      res *= cnt;
      res %= 10007;
    }
    cout << res << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1316
final_rank: 3

code_snippet: /*
テ」ツ?敕」ツつ古」ツ?榲」ツつ古」ツ?ョテゥツ?」テァツオツ静ヲツ按静・ツ按?」ツ?ョテヲツ慊?・ツ、ツァテ」ツ?ョティツセツコテ」ツ?ョテヲツ閉ーテ」ツつ津ヲツ閉ーテ」ツ?暗」ツ?ヲテヲツ篠崚」ツ?妥・ツ青暗」ツつ湘」ツ?崚」ツつ凝」ツ??
*/

#include<iostream>
#include<vector>
#include<algorithm>

#define to first
#define cnt first
#define cost second
#define MAX_N 100001
#define MOD 10007

using namespace std;

typedef pair<int,int> P;

vector<P>G[MAX_N];
bool vis[MAX_N];

P dfs(int n,P x){
  vis[n]=true;

  for(int i=0;i<G[n].size();i++){
    P e=G[n][i];
    if(x.cost<e.cost)x.cost=e.cost,x.cnt=1;
    else if(x.cost==e.cost)x.cnt++;
    if(!vis[e.to])x=dfs(e.to,x);
  }

  return x;
}

int main(void){

  int n,b,fb;

  while(cin >> n,n){

    for(int i=0;i<MAX_N;i++)G[i].clear();

    for(int i=0;i<n;i++){
      for(int j=0;j<2;j++){
	cin >> b >> fb;
	G[i].push_back(make_pair(b,fb));
      }
    }

    fill(vis,vis+MAX_N,false);
    int ans=1;
    for(int i=0;i<n;i++){
      if(!vis[i]){
	P x(0,0);
	x=dfs(i,x);
	ans=ans%MOD*x.cnt/2%MOD;
      }
    }
    cout << ans << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4252
final_rank: 10

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>

#define to first
#define cnt first
#define cost second
#define MAX_N 100001
#define MOD 10007

using namespace std;

typedef pair<int,int> P;

vector<P>G[MAX_N];
bool vis[MAX_N];

P dfs(int n,P x){
  vis[n]=true;

  for(int i=0;i<G[n].size();i++){
    P e=G[n][i];
    if(x.cost<e.cost)x.cost=e.cost,x.cnt=1;
    else if(x.cost==e.cost)x.cnt++;
    if(!vis[e.to])x=dfs(e.to,x);
  }

  return x;
}

int main(void){

  int n,b,fb;

  while(cin >> n,n){

    for(int i=0;i<MAX_N;i++)G[i].clear();

    for(int i=0;i<n;i++){
      for(int j=0;j<2;j++){
	cin >> b >> fb;
	G[i].push_back(make_pair(b,fb));
      }
    }

    fill(vis,vis+MAX_N,false);
    int ans=1;
    for(int i=0;i<n;i++){
      if(!vis[i]){
	P x(0,0);
	x=dfs(i,x);
	ans=ans%MOD*x.cnt/2%MOD;
      }
    }
    cout << ans << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4256
final_rank: 11

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 10007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct edge{
  int v, c;
  edge(int v, int c) : v(v), c(c) {}
};
typedef vector<edge> node;

int main(){
  int N;
  while(cin>>N && N){
    vector<node> G(N);
    REP(i, N){
      REP(iter, 2){
        int v, c;
        cin>>v>>c;
        G[i].push_back(edge(v, c));
      }
    }
    int s = 0;
    vector<int> color(N, -1);
    REP(i, N) if(color[i] == -1){
      queue<int> que;
      que.push(i);
      color[i] = s;
      while(!que.empty()){
        int u = que.front(); que.pop();
        REP(i, G[u].size()){
          edge e = G[u][i];
          if(color[e.v] == -1){
            que.push(e.v);
            color[e.v] = s;
          }
        }
      }
      s += 1;
    }
    ll ans = 1;
    REP(c, s){
      int max_c = -INF;
      REP(i, N) if(color[i] == c) REP(j, G[i].size()) max_c = max(max_c, G[i][j].c);
      int cnt = 0;
      REP(i, N) if(color[i] == c) REP(j, G[i].size()) if(G[i][j].c == max_c) cnt++;
      cnt /= 2;
      ans = (ans * cnt) % MOD;
    }
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1564
final_rank: 5

code_snippet: #include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

int done[100000];
vector< vector<int> > g;
vector< vector<int> > g_c;
int bfs(int x){
	queue<int> Q;
	vector<int> vec;
	Q.push(x);
	while(Q.size()){
		int q = Q.front(); Q.pop();
		if( done[q] ) continue;
		else done[q] = true;
		for(int i = 0 ; i < g[q].size() ; i++){
			Q.push(g[q][i]);
			vec.push_back(g_c[q][i]);
		}
	}
	//cout << x << " " << vec.size() << endl;
	sort(vec.begin(),vec.end());
	int answer = 0;
	for(int i = 0 ; i < vec.size() ; i++){
		if( vec[i] == vec.back() ) answer++;
	}
	return answer/2;
}


int main(){
	int n;
	while(cin >> n && n){
		for(int i = 0 ; i < 100000 ; i++)
			done[i] = 0;
		g.clear();
		g_c.clear();
		g.resize(n);
		g_c.resize(n);
		for(int i = 0 ; i < n ; i++){
			
			for(int j = 0 ; j < 2 ; j++){
				int a,b;
				cin >> a >> b;
				g[i].push_back(a);
				g_c[i].push_back(b);
			}
		}
		long long ans = 1;
		for(int i = 0 ; i < n ; i++){
			if( done[i] == 0 ){
				ans *= bfs(i);
				ans %= 10007;
			}
		}
		cout << ans << endl;
		
		
	}
}
accuracy: 1
time_ms: 10
memory_kb: 2892
final_rank: 8

code_snippet: //06
#include<iostream>
#include<map>
#include<algorithm>

using namespace std;

int p[100000];

int find(int x){
  return (x==p[x])?x:(p[x]=find(p[x]));
}

void unite(int a,int b){
  p[find(a)]=find(b);
}

int main(){
  for(int n;cin>>n,n;){
    int o[100000][2],f[100000][2];
    for(int i=0;i<n;i++){
      p[i]=i;
    }
    for(int i=0;i<n;i++){
      for(int j=0;j<2;j++){
	cin>>o[i][j]>>f[i][j];
	unite(i,o[i][j]);
      }
    }
    map<int,int> m;
    for(int i=0;i<n;i++){
      for(int j=0;j<2;j++){
	m[find(i)]=max(m[find(i)],f[i][j]);
      }
    }
    map<int,int> mm;
    for(int i=0;i<n;i++){
      for(int j=0;j<2;j++){
	mm[find(i)]+=m[find(i)]==f[i][j];
      }
    }
    int r=1;
    for(map<int,int>::iterator it=mm.begin();it!=mm.end();it++){
      r=r*it->second/2%10007;
    }
    cout<<r<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1480
final_rank: 4

code_snippet: #include<iostream>
using namespace std;

int n,b[2][100100],f[2][100100];
bool v[100100];

int dfs(int s, int now, int maxi, int num){
  v[now] = true;
  
  for(int i=0;i<2;i++){
    if(!v[b[i][now]]){
      if(maxi == f[i][now])num++;
      else if(maxi < f[i][now]){
	maxi = f[i][now];
	num = 1;
      }
      if(b[i][now] == s)return num;
      return dfs(s,b[i][now],maxi,num);
    }
  }
  if(maxi == f[1][s])return num+1;
  else if(maxi < f[1][s])return 1;
  else return num;
}

int main(){
  while(cin >> n,n){
    for(int i=0;i<n;i++){
      cin >> b[0][i] >> f[0][i] >> b[1][i] >> f[1][i];
      v[i] = false;
    }

    int ans = 1;
    for(int i=0;i<n;i++){
      if(!v[i]){
	v[i] = true;
	ans = (ans * dfs(i,b[0][i],f[0][i],1) ) % 10007;
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <stack>
#include <map>
using namespace std;

typedef vector <int> VI;
typedef vector <VI> VVI;
typedef pair <int, int> PII;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()

typedef int Weight;
struct Edge {
    int src, dst;
    Weight weight;
    Edge(int src, int dst, Weight weight) :
    src(src), dst(dst), weight(weight) { }
};
bool operator < (const Edge &e, const Edge &f) {
    return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
        e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void visit(const Graph &g, int v, vector< vector<int> >& scc,
    stack<int> &S, vector<bool> &inS,
    vector<int> &low, vector<int> &num, int& time) {
        low[v] = num[v] = ++time;
        S.push(v); inS[v] = true;
        FOR(e, g[v]) {
            int w = e->dst;
            if (num[w] == 0) {
                visit(g, w, scc, S, inS, low, num, time);
                low[v] = min(low[v], low[w]);
            } else if (inS[w])
                low[v] = min(low[v], num[w]);
        }
        if (low[v] == num[v]) {
            scc.push_back(vector<int>());
            while (1) {
                int w = S.top(); S.pop(); inS[w] = false;
                scc.back().push_back(w);
                if (v == w) break;
            }
        }
}

void stronglyConnectedComponents(const Graph& g,
    vector< vector<int> >& scc) {
        const int n = g.size();
        vector<int> num(n), low(n);
        stack<int> S;
        vector<bool> inS(n);
        int time = 0;
        REP(u, n) if (num[u] == 0)
            visit(g, u, scc, S, inS, low, num, time);
}

int main() {
    int n;
    while ( cin >> n && n ) {
        Graph G(n);
        for ( int i = 0; i < n; ++ i ) {
            for ( int j = 0; j < 2; ++ j ) {
                int b, f;
                cin >> b >> f;
                G[i].push_back( Edge( i, b, f ) );
            }
        }
        VVI scc;
        int res = 1;
        stronglyConnectedComponents( G, scc );
        for ( auto it = scc.begin(); it != scc.end(); ++ it ) {
            VI V = *it;
            int m = V.size();
            int maxf = 0;
            for ( int i = 0; i < m; ++ i ) {
                for ( int j = 0; j < 2; ++ j ) {
                    maxf = max( maxf, G[V[i]][j].weight );
                }
            }
            int cnt = 0;
            for ( int i = 0; i < m; ++ i ) {
                for ( int j = 0; j < 2; ++ j ) {
                    if ( maxf == G[V[i]][j].weight ) {
                        cnt ++;
                    }
                }
            }
            res = ( res * ( cnt / 2 ) ) % 10007;
        }
        cout << res << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3456
final_rank: 9

code_snippet: #include <iostream>
#include <algorithm>
using namespace std;

struct Edge {
  int to, cost;
};

const int MAX_N = 100002;
const int MOD = 10007;
int N;
Edge E[MAX_N][2];
bool vis[MAX_N];

int getMaxCostNum(int p) {
  int num = 0;
  int maxCost = 0;
  int pp = -1;
  while(1) {
    int d = (E[p][0].to == pp);
    bool flag = false;
    for(int i = 0; i < 2; ++i) {
      Edge &e = E[p][(i+d)%2];
      if(vis[e.to]) continue;

      vis[e.to] = true;
      pp = p;
      p = e.to;
      if(e.cost == maxCost) {
	++num;
      } else if(e.cost > maxCost) {
	num = 1;
	maxCost = e.cost;
      }
      flag = true;
      break;
    }
    if(!flag) return num;
  }
}

int solve() {
  int res = 1;
  fill(vis, vis+MAX_N, false);
  for(int i = 0; i < N; ++i) {
    if(vis[i]) continue;
    int tmp = getMaxCostNum(i);
    res = (res*tmp)%MOD;
  }
  return res;
}

int main() {
  while(cin >> N && N) {
    for(int i = 0; i < N; ++i) {
      for(int j = 0; j < 2; ++j) {
	cin >> E[i][j].to >> E[i][j].cost;
      }
    }
    cout << solve() << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 15

code_snippet: #include<iostream>
#include<vector>
#include<cassert>
using namespace std;
#define rep(i, n) for ( int i = 0; i < n; i++ )
#define MAX 100000
#define M 10007

class Edge{
public:
  int target, cost;
  Edge(int target, int cost):target(target), cost(cost){}
};

vector<Edge> G[MAX];
bool V[MAX];
int n;
int ncomp;

void dfs(int u, vector<int> &maxv){
  V[u] = true;
  ncomp++;

  rep(i, G[u].size()){
    int c = G[u][i].cost;
    if ( maxv[0] < c ){ maxv.clear(); maxv.push_back(c); }
    else if ( maxv[0] == c ) maxv.push_back(c);
  }

  rep(i, G[u].size()){
    int v = G[u][i].target;
    if ( V[v] ) continue;
    dfs(v, maxv);
  }
}

int component(int u){
  vector<int> maxv;
  maxv.push_back(-1);
  ncomp = 0;
  dfs(u, maxv);
  assert( ncomp >= 3 );
  assert( maxv.size()%2 == 0 );
  return maxv.size()/2;
}

void compute(){
  rep(i, n) V[i] = false;
  int p = 1;
  rep(u, n){
    if ( !V[u] ){
      p = (p*component(u))%M;
    }
  }
  cout << p << endl;
}


main(){
  int m, s, t1, t2, b1, b2, c;
  while(1){
    cin >> n;
    if ( n == 0 ) break;
    assert( 3 <= n && n <= 100000);

    rep(i, n) G[i].clear();
    rep(i, n){
      cin >> t1 >> b1 >> t2 >> b2;
      G[i].push_back(Edge(t1, b1));
      G[i].push_back(Edge(t2, b2));
      assert( 0 < b1 );
      assert( 0 < b2 );
    }

    rep(i, n) assert( G[i].size() == 2 );
    rep(i, n) assert( G[i][0].target != G[i][1].target );

    rep(i, n){
      t1 = G[i][0].target;
      t2 = G[i][1].target;
      int c1 = G[i][0].cost;
      int c2 = G[i][1].cost;

      assert( G[t1][0].target == i || G[t1][1].target == i );
      assert( G[t2][0].target == i || G[t2][1].target == i );

      if ( G[t1][0].target == i ) assert( G[t1][0].cost == c1 );
      if ( G[t1][1].target == i ) assert( G[t1][1].cost == c1 );

      if ( G[t2][0].target == i ) assert( G[t2][0].cost == c2 );
      if ( G[t2][1].target == i ) assert( G[t2][1].cost == c2 );
    }



    compute();
  }
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct edge{
public:
    int to,cost;
};

vector<edge> G[100001];
int n;
bool passed[100001];
const int mod=10007;
int maxCost;
int sumCost;
int cnt;

void dfs(int s,bool first,int from){
    if(!first)
        passed[s]=true;
    for(int i = 0; i < G[s].size(); i++){
        edge &e=G[s][i];
        if(passed[e.to]||e.to==from)
            continue;
        sumCost+=e.cost;
        if(maxCost<e.cost){
            cnt=1;maxCost=e.cost;
        }
        else if(maxCost==e.cost)
            cnt++;
        dfs(e.to,false,s);
        break;
    }
}

int main(){
    while(cin>>n&&n!=0){
        maxCost=0;
        for(int i = 0; i < n; i++)
            G[i].clear();
        fill(passed,passed+n,false);
        for(int i = 0; i < n; i++){
            for(int j = 0; j < 2; j++){
                int to,cost;
                cin>>to>>cost;
                edge e;
                e.to=to;e.cost=cost;
                G[i].push_back(e);
            }
        }
        int mul=1;
        for(int i = 0; i < n; i++){
            if(passed[i])
                continue;
            maxCost=0;
            sumCost=0;
            cnt=0;
            dfs(i,true,-1);
            mul*=cnt;
            mul%=mod;
        }
        cout<<mul%mod<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2300
final_rank: 18

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct edge{
public:
    int to,cost;
};

vector<edge> G[100001];
int n;
bool passed[100001];
const int mod=10007;
int maxCost;
int sumCost;
int cnt;

//vector<int> p;
void dfs(int s,bool first,int from){
    if(!first)
        passed[s]=true;
    for(int i = 0; i < G[s].size(); i++){
        edge &e=G[s][i];
        if(passed[e.to]||e.to==from)
            continue;
        sumCost+=e.cost;
        if(maxCost<e.cost){
            cnt=1;maxCost=e.cost;
        }
        else if(maxCost==e.cost)
            cnt++;
        dfs(e.to,false,s);
        break;
    }
}

int main(){
    while(cin>>n&&n!=0){
        maxCost=0;
        for(int i = 0; i < n; i++)
            G[i].clear();
        fill(passed,passed+n,false);
        for(int i = 0; i < n; i++){
            for(int j = 0; j < 2; j++){
                int to,cost;
                cin>>to>>cost;
                edge e;
                e.to=to;e.cost=cost;
                G[i].push_back(e);
            }
        }
        int mul=1;
        for(int i = 0; i < n; i++){
            if(passed[i])
                continue;
            maxCost=0;
            sumCost=0;
            cnt=0;
            dfs(i,true,-1);
            // ツづづ個陛督づーツ催ュツづゥツつゥ
  //          int maxNum=-1;
//            int sum=0;
//            int cnt=0;
            //for(int j = 0; j < p.size(); j++){
            //    if(maxNum==-1||maxNum<p[j]){
            //        maxNum=p[j];
            //        cnt=1;
            //    }
            //    else if(maxNum==p[j])
            //        cnt++;
            //}
            mul*=cnt;
            mul%=mod;
        }
        cout<<mul%mod<<endl;
    }

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2320
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct edge{
public:
    int to,cost;
};

vector<edge> G[100001];
int n;
bool passed[100001];
const int mod=10007;

vector<int> p;
void dfs(int s,bool first,int from){
    if(!first)
        passed[s]=true;
    for(int i = 0; i < G[s].size(); i++){
        edge &e=G[s][i];
        if(passed[e.to]||e.to==from)
            continue;
        p.push_back(e.cost);
        dfs(e.to,false,s);
        break;
    }
}

int main(){
    while(cin>>n&&n!=0){
        for(int i = 0; i < n; i++)
            G[i].clear();
        fill(passed,passed+n,false);
        for(int i = 0; i < n; i++){
            for(int j = 0; j < 2; j++){
                int to,cost;
                cin>>to>>cost;
                edge e;
                e.to=to;e.cost=cost;
                G[i].push_back(e);
            }
        }
        int mul=1;
        for(int i = 0; i < n; i++){
            if(passed[i])
                continue;
            p.clear();
            dfs(i,true,-1);
            // ツづづ個陛督づーツ催ュツづゥツつゥ
            int maxNum=-1;
            int sum=0;
            int cnt=0;
            for(int j = 0; j < p.size(); j++){
                if(maxNum==-1||maxNum<p[j]){
                    maxNum=p[j];
                    cnt=1;
                }
                else if(maxNum==p[j])
                    cnt++;
            }
            mul*=cnt;
            mul%=mod;
        }
        cout<<mul%mod<<endl;
    }

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 15