Problem:
Investigation of Club Activities
Akira, the student council president of A High School, decided to investigate which club activities the A High School students belong to. A High School has
N
students numbered from 1 to
N
and
M
types of club activities numbered from 1 to
M
.  There is no limit to the number of students in each club, and it is possible to have zero students in a club. However, according to the school rules of A High School, students can only belong to one club activity. All students follow this school rule.
Akira asked a student member to do some research and obtained a record of
K
lines such that each line is one of the following.
Student
a
and student
b
belong to the same club activity.
Student
c
belongs to club activity
x
.
However, there may be discrepancies in this record that would cause someone to violate the school rules. Akira decided to look at it from the first line and look for the first line where he could determine that there was a discrepancy.
Write a program to find the number of the first line that can be determined to be inconsistent from the given the record of
K
lines.
Input
Input is given in the following format.
N
M
K
record
1
record
2
:
record
K
In the first line, the number of students
N
(1 ≤
N
≤ 100000), the number of types of club activities
M
(1 ≤
M
≤ 100000), and the number of lines recorded
K
(1 ≤
K
≤ 200000) are given. Each
record
i
of the record is given in the following
K
line in one of the following formats:
1
a
b
or
2
c
x
When the first number is "1", student
a
(1 ≤
a
≤
N
) and student
b
(1 ≤
b
≤
N
) belongs to the same club activity. Note that
a
≠
b
.
When the first number is "2", the student
c
(1 ≤
c
≤
N
) is in the club activity
x
(1 ≤
x
≤
M
).
Output
Output the number of the first line that can be determined to be inconsistent in a single line. If none is found, output 0 in a single line.
Sample Input 1
3 2 5
1 1 2
1 2 3
2 1 1
2 3 2
2 2 1
Sample Output 1
4
Sample Input 2
3 2 4
1 1 2
2 1 1
2 3 2
2 2 1
Sample Output 2
0
Sample Input 3
3 2 2
1 1 2
2 1 1
Sample Output 3
0

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define rep(i, n) for (int i = 0; i < (int) (n); i++)

// Union-Find
struct UnionFind {
    vector<int> par, rank, siz;

    // 構造体の初期化
    UnionFind(int n) : par(n,-1), rank(n,0), siz(n,1) { }

    // 根を求める
    int root(int x) {
        if (par[x]==-1) return x; // x が根の場合は x を返す
        else return par[x] = root(par[x]); // 経路圧縮
    }

    // x と y が同じグループに属するか (= 根が一致するか)
    bool issame(int x, int y) {
        return root(x)==root(y);
    }

    // x を含むグループと y を含むグループを併合する
    bool unite(int x, int y) {
        int rx = root(x), ry = root(y); // x 側と y 側の根を取得する
        if (rx==ry) return false; // すでに同じグループのときは何もしない
        // union by rank
        if (rank[rx]<rank[ry]) swap(rx, ry); // ry 側の rank が小さくなるようにする
        par[ry] = rx; // ry を rx の子とする
        if (rank[rx]==rank[ry]) rank[rx]++; // rx 側の rank を調整する
        siz[rx] += siz[ry]; // rx 側の siz を調整する
        return true;
    }

    // x を含む根付き木のサイズを求める
    int size(int x) {
        return siz[root(x)];
    }
};

int main() {
    int N, M, K;
    cin >> N >> M >> K;

    UnionFind uf(N);
    vector<int> club(N, -1);

    rep(i, K) {
        int num;
        cin >> num;

        if (num == 1) {
            int a, b;
            cin >> a >> b;
            a--; b--;

            if (club[uf.root(a)] == club[uf.root(b)] || club[uf.root(a)] == -1 || club[uf.root(b)] == -1) {
                int nClub = max(club[uf.root(a)], club[uf.root(b)]);
                uf.unite(a, b);
                club[uf.root(a)] = nClub;
            } else {
                cout << i + 1 << endl;
                return 0;
            }
        } else {
            int c, x;
            cin >> c >> x;
            c--; x--;

            if (club[uf.root(c)] == x || club[uf.root(c)] == -1) {
                club[uf.root(c)] = x;
            } else {
                cout << i + 1 << endl;
                return 0;
            }
        }
    }

    cout << 0 << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 4652
final_rank: 6

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

using namespace std;
//using namespace atcoder;
#define rep(i,n) for(ll i=0; i<n; i++)
#define rrep(i,n) for(ll i=n-1; i>=0; i--)
#define print(a) cout<<a<<endl
typedef long long ll;
#define yn(flg) if(flg){cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}
#define YN(flg) if(flg){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}
#define so(a) sort(a.begin(),a.end())
#define mp make_pair
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define pb push_back
#define a2i(a,s) (ll)(a-s)
#define i2a(s,a) (char)(s+a)
#define ssize(a) a.size()
typedef pair<int, int> Pii;
typedef pair<int, ll> Pil;
typedef pair<pair<ll,ll>,ll> P3;
typedef pair<pair<ll,ll>,pair<ll,ll>> P4;

typedef pair<ll, ll> Pll;
typedef pair<ll,Pll> Plll;
typedef pair<Pii, int> Piii;
const ll INF = 1000000000000000000;

template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

class UnionFind{
public:
	ll par[100009];//親
	ll siz[100009];//クラブ
	ll siz2[100009];//クラブ
	//ｎ頂点のグラフ
	void init(ll n,ll m){
		for(ll i=1;i<=n;i++)par[i]=-1;
		for(ll i=1;i<=m;i++)siz[i]=0;
		for(ll i=1;i<=n;i++)siz2[i]=1;
	}
	//根
	ll root(ll x){
		while(true){
			if(par[x]==-1)break;
			x=par[x];
		}
		return x;
	}
	//統合
	bool unite(ll x,ll y){
		ll X=root(x);
		ll Y=root(y);
		if(X==Y)return true;
		if(siz2[X]<siz2[Y]){
			par[X]=Y;
			if(siz[Y]!=0&&siz[X]!=0&&siz[Y]!=siz[X])return false;
			siz[Y]=max(siz[X],siz[Y]);
			siz2[Y]=siz2[Y]+siz2[X];
		}
		else{
			par[Y]=X;
			if(siz[Y]!=0&&siz[X]!=0&&siz[Y]!=siz[X])return false;
			siz[X]=max(siz[X],siz[Y]);
			siz2[X]=siz2[Y]+siz2[X];
		}
		return true;
	}
	//クラブ入力
	bool nyuuryoku(ll x,ll y){
		ll X=root(x);
		if(siz[X]!=0&&siz[X]!=y)return false;
		siz[X]=y;
		return true;
	}
	//連結かどうか
	bool same(ll x,ll y){
		if(root(x)==root(y))return true;
		else return false;
	}
	//サイズ
	ll sizee(ll x){
		return siz2[root(x)];
	}

};
UnionFind uf;
int main(){
//入力

	cin.tie(0);
	ios::sync_with_stdio(0);

	ll n,m,k;
	cin>>n>>m>>k;

	uf.init(n,m);

	for(ll i=0;i<k;i++){
		ll a,b,c;
		cin>>a>>b>>c;
		if(a==1){
			bool t=uf.unite(b,c);
			if(t==false){
				cout<<i+1<<endl;
				return 0;
			}
		}
		else{
			bool t=uf.nyuuryoku(b,c);
			if(t==false){
				cout<<i+1<<endl;
				return 0;
			}
		}
	}
	cout<<0<<endl;

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5712
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#include <iomanip>
#include <numbers>
#include <cassert>
#include <numeric>
#ifdef _MSC_VER
#include <intrin.h>
#endif
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pint = pair<int, int>;
using pll = pair<ll, ll>;
template<typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
#define rep(i, n) for(int i = 0; i < (n); ++i)
template<typename T>
bool chmax(T & a, const T & b) { if (a < b) { a = b; return true; } return false; }
template<typename T>
bool chmin(T & a, const T & b) { if (a > b) { a = b; return true; } return false; }
const int inf = 1e9;
const ll linf = 1e18;
const int dy[] = { 0,0,1,-1 }, dx[] = { 1,-1,0,0 };
namespace atcoder {

    struct dsu {
    public:
        dsu() : _n(0) {}
        dsu(int n) : _n(n), parent_or_size(n, -1) {}

        int merge(int a, int b) {
            assert(0 <= a && a < _n);
            assert(0 <= b && b < _n);
            int x = leader(a), y = leader(b);
            if (x == y) return x;
            if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
            parent_or_size[x] += parent_or_size[y];
            parent_or_size[y] = x;
            return x;
        }

        bool same(int a, int b) {
            assert(0 <= a && a < _n);
            assert(0 <= b && b < _n);
            return leader(a) == leader(b);
        }

        int leader(int a) {
            assert(0 <= a && a < _n);
            if (parent_or_size[a] < 0) return a;
            return parent_or_size[a] = leader(parent_or_size[a]);
        }

        int size(int a) {
            assert(0 <= a && a < _n);
            return -parent_or_size[leader(a)];
        }

        std::vector<std::vector<int>> groups() {
            std::vector<int> leader_buf(_n), group_size(_n);
            for (int i = 0; i < _n; i++) {
                leader_buf[i] = leader(i);
                group_size[leader_buf[i]]++;
            }
            std::vector<std::vector<int>> result(_n);
            for (int i = 0; i < _n; i++) {
                result[i].reserve(group_size[i]);
            }
            for (int i = 0; i < _n; i++) {
                result[leader_buf[i]].push_back(i);
            }
            result.erase(
                std::remove_if(result.begin(), result.end(),
                    [&](const std::vector<int>& v) { return v.empty(); }),
                result.end());
            return result;
        }

    private:
        int _n;

        std::vector<int> parent_or_size;
    };

}
using namespace atcoder;
int main() {
    int n, m, k; cin >> n >> m >> k;
    dsu d(n);
    map<int, int> mp;
    rep(i, k) {
        int t; cin >> t;
        if (t == 1) {
            int a, b; cin >> a >> b;
            a--, b--;
            int ldA = d.leader(a), ldB = d.leader(b);
            bool existA = mp.count(ldA), existB = mp.count(ldB);
            if (existA && existB && mp[ldA] != mp[ldB]) {
                cout << i + 1 << endl;
                return 0;
            }
            d.merge(a, b);
            if (existA)mp[d.leader(a)] = mp[ldA];
            if (existB)mp[d.leader(a)] = mp[ldB];
        }
        else {
            int c, x; cin >> c >> x;
            c--;
            if (mp.count(d.leader(c)) && mp[d.leader(c)] != x) {
                cout << i + 1 << endl;
                return 0;
            }
            mp[d.leader(c)] = x;
        }
    }
    cout << 0 << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 8448
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
#include<atcoder/all>
using mint = atcoder::modint998244353;
using ld = long double;
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define rep(i,n) for(int i=0;i<(int)(n);++i)
template<typename T>bool chmin(T&a,T b){return b<a?(a=b,1):0;}
template<typename T>bool chmax(T&a,T b){return b>a?(a=b,1):0;}

struct UnionFind {
    int N;
    vector<int> parent;

    UnionFind(int N) : N(N), parent(N, -1) {}

    int leader(int x) {
        if (parent[x] < 0) return x;
        return parent[x] = leader(parent[x]);
    }

    int merge(int x, int y) {
        int xp = leader(x);
        int yp = leader(y);
        if (xp == yp) return xp;
        if (xp < yp) swap(xp, yp);
        parent[yp] += parent[xp];
        parent[xp] = yp;
        return yp;
    }

    bool same(int x, int y) { return leader(x) == leader(y); }

    int size(int x) { return -parent[leader(x)]; }

    vector<vector<int>> groups() {
        vector<vector<int>> a(N);
        rep(i, N) a[leader(i)].push_back(i);
        vector<vector<int>> uni;
        rep(i, N) if (!a[i].empty()) uni.push_back(a[i]);
        return uni;
    }
};


int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int N,M,K;
    cin>>N>>M>>K;
    vector<int> c(N,0);
    int ans=0;

    UnionFind uf(N);

    rep(i,K){
        int t,a,b;
        cin>>t>>a>>b;
        a--;b--;
        if(ans!=0) continue;
        if(t==1){
            a=uf.leader(a);
            b=uf.leader(b);
            if(a==b) continue;
            int l=uf.merge(a,b);
            if(c[a]==c[b]) continue;
            if(c[a]==0||c[b]==0) c[l]=c[a]|c[b];
            else ans=i+1;
        }
        else{
            int l=uf.leader(a);
            if(c[l]==b+1) continue;
            if(c[l]==0) c[l]=b+1;
            else ans=i+1;
            
        }
    }
    cout<<ans<<"\n";
}
accuracy: 1
time_ms: 20
memory_kb: 4096
final_rank: 2

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#define _USE_MATH_DEFINES
#include <math.h>
#include <cstring>
#include <numeric>
#include <algorithm>
#include <stdlib.h>
#include <functional>
#include <string>
#include <array>
#include <map>
#include <queue>
#include <limits.h>
#include <set>
#include <stack>
#include <random>
#include <complex>
#include <unordered_map>
#include <nmmintrin.h>
#include <chrono>
#define rep(i,s,n) for(int i = (s); (n) > i; i++)
#define REP(i,n) rep(i,0,n)
#define RANGE(x,a,b) ((a) <= (x) && (x) <= (b))
#define DUPLE(a,b,c,d) (RANGE(a,c,d) || RANGE(b,c,d) || RANGE(c,a,b) || RANGE(d,a,b))
#define INCLU(a,b,c,d) (RANGE(a,c,d) && (b,c,d))
#define PW(x) ((x)*(x))
#define ALL(x) (x).begin(), (x).end()
#define MODU 1000000007
#define bitcheck(a,b)   ((a >> b) & 1)
#define bitset(a,b)      ( a |= (1 << b))
#define bitunset(a,b)    (a &= ~(1 << b))
#define MP(a,b) make_pair((a),(b))
#define Manh(a,b) (abs((a).first-(b).first) + abs((a).second - ((b).second))
#define pritnf printf
#define scnaf scanf
#define itn int
#ifdef _MSC_VER
#define __builtin_popcount _mm_popcnt_u32
#define __builtin_popcountll _mm_popcnt_u64
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
ll gcd(ll a, ll b) {
	if (b == 0) return a;
	return gcd(b, a%b);
}
template<typename A, size_t N, typename T>
void Fill(A(&array)[N], const T &val) {
	std::fill((T*)array, (T*)(array + N), val);
}


struct UnionFind{
	vector<int> data;
	int n, m;

	UnionFind(int ns, int ms) : n(ns), m(ms), data(ns + ms, INT_MIN){
		REP(i, m){
			data[i + n] = -i-1;
		}
	}

	bool unite(int a, int b){//矛盾の判定
		a = root(a), b = root(b);

		if (a == b)
			return true;

		if (data[a] != INT_MIN && data[b] != INT_MIN){
			if (data[a] != data[b]){
				return false;
			}
			else {
				if (rand() % 2)
					data[b] = a;
				else
					data[a] = b;
			}
		}
		else if (data[a] != INT_MIN)
			data[b] = a;
		else if (data[b] != INT_MIN)
			data[a] = b;
		else{
			if (rand() % 2)
				data[b] = a;
			else
				data[a] = b;
		}
		return true;
	}


	bool unitebu(int a, int b){//矛盾の判定 aをbの部活
		a = root(a);
		b += n;

		if (data[a] == data[b])
			return true;
		if (data[a] != INT_MIN)
			return false;

		data[a] = b;
		return true;
	}

	bool findset(int a, int b){
		return root(a) == root(b);
	}

	int root(int x){
		return data[x] < 0 ? x : data[x] = root(data[x]);
	}
};

signed main() {
	int n, m, k;
	cin >> n >> m >> k;
	UnionFind uf(n,m);
	REP(i, k){
		int t, a, b;
		scanf("%d %d %d", &t, &a, &b);
		bool ret = 1;
		a--, b--;
		if (t == 1){
			ret = uf.unite(a, b);
		}
		else if (t == 2){
			ret = uf.unitebu(a, b);
		}

		if (!ret){
			printf("%d\n", i + 1);
			return 0;
		}
	}

	printf("0\n");

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

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,N) for(ll i=0;i<N;i++)
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define pb push_back
#define eb emplace_back

class UnionFind{
    public:
    int size;
    vector<int>parent;
    vector<int>depth;
    void init(int N){
        size =N;
        parent.assign(N,-1);
        depth.assign(N,1);
    }
    int root(int x){
        int o = x;
        while(parent[x]!=-1)x=parent[x];
        if(parent[o]!=-1)parent[o]=x;
        return x;
    }
    bool same(int a,int b){
        a = root(a);b=root(b);
        return a==b;
    }
    void unite(int a,int b){
        a = root(a);b=root(b);
        if(a==b)return;
        if(depth[a]>=depth[b]){
            parent[b]=a;
            depth[a]=max(depth[a],depth[b]+1);
        }
        else {
            parent[a]=b;
            depth[b]=max(depth[b],depth[a]+1);
        }
        return;
    }
};

int main(){
    int N,M,K;cin>>N>>M>>K;
    UnionFind UF;
    UF.init(N);
    vector<int>club(N,-1);
    rep(k,K){
        int t;cin>>t;
        if(t==1){
            int a,b;cin>>a>>b;a--;b--;
            a = UF.root(a);b = UF.root(b);
            if(club[a]>=0&&club[b]>=0&&club[a]!=club[b]){
                cout<<k+1<<endl;
                return 0;
            }
            UF.unite(a,b);
            club[UF.root(a)]=max(club[a],club[b]);
        }
        else {
            int c,x;cin>>c>>x;
            c--;
            c = UF.root(c);
            if(club[c]==-1)club[c]=x;
            else {
                if(club[c]!=x){
                    cout<<k+1<<endl;
                    return 0;
                }
            }
        }
    }
    cout<<0<<endl;
}
accuracy: 1
time_ms: 80
memory_kb: 4140
final_rank: 8

code_snippet: #ifdef GOHACHI
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128;
using u128 = unsigned __int128;
template<class T> using VC = vector<T>;
template<class T,class TT> using P = pair<T,TT>;
template<class T,class TT,class TTT> using TP = tuple<T,TT,TTT>;
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> using pqR = priority_queue<T>;
#define F first
#define S second
#define INF LLONG_MAX
ll DX[4] = { 0 , 1 , 0 , -1 };
ll DY[4] = { -1 , 0 , 1 , 0 };
#define st(x,y) sort(x,x+y)
#define stR(x,y) sort(x,x+y,greater<ll>())
#define ST(x) sort(x.begin(),x.end())
#define STR(x) sort(x.rbegin(),x.rend())
#define rep(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define repR(i,a,b) for(ll i=(ll)(a);i>=(ll)(b);i--)
#define rev(x,y) reverse(x,x+y)
#define REV(x) reverse(x.begin(),x.end())
#define dec(x) fixed << setprecision(x)
ll x;
void solve() {
	ll n,m,k; cin>>n>>m>>k;
	ll q,a,b;
	ll p[n+1],l[n+1];
	map<ll,ll>mp;
	rep(i,1,n+1) { p[i]=i; l[i]=1; }
	rep(i,0,k) { cin>>q>>a>>b;
		if (q==1) {
			while(a!=p[a]) a=p[a];
			while(b!=p[b]) b=p[b];
			if (mp[a]!=0 && mp[b]!=0 && mp[a]!=mp[b]) { x=i+1; break; }
			else if (mp[a]!=0 && mp[b]==0 && mp[a]!=mp[b]) mp[b]=mp[a];
			else if (mp[a]==0 && mp[b]!=0 && mp[a]!=mp[b]) mp[a]=mp[b];
			if (l[a]>l[b]) p[b]=a;
			else if (l[a]<l[b]) p[a]=b;
			else { p[b]=a; l[a]++; }
		}
		else {
			while(a!=p[a]) a=p[a];
			if (mp[a]!=0 && mp[a]!=b) { x=i+1; break; }
			mp[a]=b;
		}
	}
	cout<<x<<'\n';
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T=1;
    while(T--) solve();
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 11200
final_rank: 15

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

#define int long long

/*
6:51~7:05
13:07~13:20
20:24~
*/

struct UF{
	vector<int> par;
	UF(int n):par(n,-1){

	}

	int root(int x){
		if(par[x]<0)return x;
		return par[x]=root(par[x]);
	}

	void merge(int x,int y){
		x=root(x),y=root(y);

		if(x==y)return;

		if(par[x]>par[y]){
			swap(x,y);
		}

		par[y]=x;
	}
};

signed main(){
	int n,m,k;cin>>n>>m>>k;
	vector<int> vec(n,-1);
	UF uf(n);
	for(int q=1;q<=k;q++){
		int t;cin>>t;
		if(t==1){
			int a,b;cin>>a>>b;a--;b--;
			a=uf.root(a);
			b=uf.root(b);
			// cout<<"!"<<a<<" "<<b<<endl;
			if(vec[a]!=-1&&vec[b]!=-1&&vec[a]!=vec[b]){
				cout<<q<<endl;
				return 0;
			}
			uf.merge(a,b);
			if(vec[a]!=-1){
				vec[uf.root(a)]=vec[a];
			}
			if(vec[b]!=-1){
				vec[uf.root(b)]=vec[b];
			}
		}else{
			int c,x;cin>>c>>x;c--;
			c=uf.root(c);
			if(vec[c]!=-1&&vec[c]!=x){
				cout<<q<<endl;
				return 0;
			}
			vec[c]=x;
		}
	}

	cout<<0<<endl;
}
accuracy: 1
time_ms: 80
memory_kb: 4564
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
int leng[100001],par[100001],bu[100001];
int main(void)
{
	int n,m,k,i,z,a,b,c,x,flg;
	cin >>n>>m>>k;
	for(i=1;i<=n;i++)	{
		leng[i]=1;	par[i]=i; bu[i]=0;
	}
	flg=1;
	for(i=1;i<=k;i++)	{
		cin >>z;
		if(z==1)	{
			cin >>a>>b;
			while(a!=par[a])	a=par[a];
			while(b!=par[b])	b=par[b];
			if(bu[a]!=0 && bu[b]!=0 && bu[a]!=bu[b])	{
				flg=0;	break;
			}
			if(leng[a]>leng[b])	{
				par[b]=a;
				if(bu[a]==0)	bu[a]=bu[b];
			}
			else if(leng[a]<leng[b])	{
				par[a]=b;	
				if(bu[b]==0)	bu[b]=bu[a];
			}
			else {
				par[a]=b;	leng[b]++;
				if(bu[b]==0)	bu[b]=bu[a];
			}
		}
		else {
			cin >>c>>x;
			while(c!=par[c])	c=par[c];
			if(bu[c]!=0 && bu[c]!=x)	{
				flg=0;	break;
			}
			else bu[c]=x;
		}
	}
	if(flg==1)		cout<<"0"<<endl;
	else cout<<i<<endl;
	return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 4248
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vc<vc<T>>;
void solve();
int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    ll t = 1;
    // cin >> t;
    for (int i = 1; i <= t; i++) solve();
    return 0;
}
#define rep(i, a, b) for (ll i = (a); i < (b); i++)
ll dy[4] = {0, 1, 0, -1}, dx[4] = {1, 0, -1, 0};
// ll dy[8] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[8] = {0, 1, 1, 1, 0, -1, -1, -1};

#include <algorithm>
#include <cassert>
#include <vector>

namespace atcoder {

struct dsu {
  public:
    dsu() : _n(0) {}
    explicit dsu(int n) : _n(n), parent_or_size(n, -1) {}

    int merge(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
        parent_or_size[x] += parent_or_size[y];
        parent_or_size[y] = x;
        return x;
    }

    bool same(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        return leader(a) == leader(b);
    }

    int leader(int a) {
        assert(0 <= a && a < _n);
        if (parent_or_size[a] < 0) return a;
        return parent_or_size[a] = leader(parent_or_size[a]);
    }

    int size(int a) {
        assert(0 <= a && a < _n);
        return -parent_or_size[leader(a)];
    }

    std::vector<std::vector<int>> groups() {
        std::vector<int> leader_buf(_n), group_size(_n);
        for (int i = 0; i < _n; i++) {
            leader_buf[i] = leader(i);
            group_size[leader_buf[i]]++;
        }
        std::vector<std::vector<int>> result(_n);
        for (int i = 0; i < _n; i++) {
            result[i].reserve(group_size[i]);
        }
        for (int i = 0; i < _n; i++) {
            result[leader_buf[i]].push_back(i);
        }
        result.erase(
            std::remove_if(result.begin(), result.end(),
                           [&](const std::vector<int>& v) { return v.empty(); }),
            result.end());
        return result;
    }

  private:
    int _n;
    std::vector<int> parent_or_size;
};

}  // namespace atcoder

void solve() {
    ll n, m, k;
    cin >> n >> m >> k;
    atcoder::dsu d(n);
    vc<ll> club(n, -1);
    rep(i, 1, k + 1) {
        ll t, a, b;
        cin >> t >> a >> b;
        if (t == 1) {
            a--, b--;
            if (club[d.leader(a)] != -1 && club[d.leader(b)] != -1 &&
                club[d.leader(a)] != club[d.leader(b)]) {
                cout << i << endl;
                return;
            }
            ll c = -1;
            if (club[d.leader(a)] != -1) c = club[d.leader(a)];
            if (club[d.leader(b)] != -1) c = club[d.leader(b)];
            d.merge(a, b);
            if (c != -1) club[d.leader(a)] = c;
        } else {
            a--;
            if (club[d.leader(a)] != -1 && club[d.leader(a)] != b) {
                cout << i << endl;
                return;
            }
            club[d.leader(a)] = b;
        }
    }
    cout << 0 << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 4352
final_rank: 3

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

struct UnionFind {
    vector<int> par;
    vector<int> size;

    UnionFind(int n) {
        par.resize(n + 1, -1);
        size.resize(n + 1, 1);
    }

    int root(int x) {
        while (1) {
            if (par[x] == -1) {
                return(x);
            }
            x = par[x];
        }
    }

    void unite(int u, int v) {
        int RootU = root(u), RootV = root(v);
        if (RootU == RootV) {
            return;
        }
        if (size[RootU] < size[RootV]) {
            par[RootU] = RootV;
            size[RootV] += size[RootU];
        } else {
            par[RootV] = RootU;
            size[RootU] += size[RootV];
        }
        return;
    }
};

int main() {
    int n, m, k;
    cin >> n >> m >> k;
    UnionFind uf(n);
    vector<int> club(n, -1);
    int t, a, b;
    for (int i = 0; i < k; i++) {
        cin >> t >> a >> b;
        a--, b--;
        if (t == 1) {
            int roota = uf.root(a), rootb = uf.root(b);
            if (club[roota] != -1 && club[rootb] != -1 && club[roota] != club[rootb]) {
                cout << i + 1 << "\n";
                return(0);
            } else {
                club[roota] = max(club[roota], club[rootb]);
                club[rootb] = max(club[roota], club[rootb]);
                uf.unite(a, b);
            }
        } else {
            int root = uf.root(a);
            if (club[root] == -1) {
                club[root] = b;
            } else if (club[root] != b) {
                cout << i + 1 << "\n";
                return(0);
            }
        }
    }
    cout << 0 << "\n";
    return(0);
}
accuracy: 1
time_ms: 100
memory_kb: 3888
final_rank: 11

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

struct dsu {
  int n;
  vector<int> par;
  dsu(int n): n(n), par(n) {
    iota(par.begin(), par.end(), 0);
  }
  int leader(int v) {
    if(par[v] == v) return v;
    par[v] = leader(par[v]);
    return par[v];
  }
  void merge(int u, int v) {
    int lu = leader(u), lv = leader(v);
    if(lu > lv) swap(lu, lv);
    if(lu != lv) par[lv] = lu;
  }
};

int main() {
  int N, M, K;
  cin >> N >> M >> K;
  dsu uf(N+M);
  for(int q = 0; q < K; q++) {
    int t;
    cin >> t;
    if(t == 1) {
      int a, b;
      cin >> a >> b;
      a--, b--;
      int la = uf.leader(M+a), lb = uf.leader(M+b);
      if(la < M && lb < M && la != lb) {
        cout << q+1 << endl;
        return 0;
      }
      uf.merge(la, lb);
    }else {
      int c, x;
      cin >> c >> x;
      c--, x--;
      int lc = uf.leader(M+c);
      if(lc < M && lc != x) {
        cout << q+1 << endl;
        return 0;
      }
      uf.merge(lc, x);
    }
  }
  cout << 0 << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 3768
final_rank: 5

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

class unionfind {
private:
	int n;
	vector<int> par;
	vector<int> club;
	bool error;
public:
	unionfind() : n(0), par(vector<int>()), club(vector<int>()), error(false) {}
	unionfind(int n_) : n(n_), club(vector<int>(n, -1)), error(false) {
		par.resize(n);
		for (int i = 0; i < n; i++) {
			par[i] = i;
		}
	}
	int root(int x) {
		if (par[x] == x) {
			return x;
		}
		return par[x] = root(par[x]);
	}
	void link(int x, int y) {
		x = root(x);
		y = root(y);
		if (club[x] != club[y] && club[x] != -1 && club[y] != -1) {
			error = true;
		}
		par[y] = x;
		club[x] = max(club[x], club[y]);
	}
	void assign(int x, int id) {
		x = root(x);
		if (club[x] != id && club[x] != -1) {
			error = true;
		}
		club[x] = id;
	}
	bool connected(int x, int y) {
		return root(x) == root(y);
	}
	bool is_error() {
		return error;
	}
};

int main() {
	int N, M, K;
	cin >> N >> M >> K;
	unionfind uf(N);
	int answer = -1;
	for (int i = 0; i < K; i++) {
		int tp, a, b;
		cin >> tp >> a >> b;
		a -= 1;
		b -= 1;
		if (tp == 1) {
			uf.link(a, b);
		}
		else {
			uf.assign(a, b);
		}
		if (answer == -1 && uf.is_error()) {
			answer = i;
		}
	}
	cout << answer + 1 << endl;
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3856
final_rank: 7

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

class unionfind {
private:
	int n;
	vector<int> par;
public:
	unionfind() : n(0), par(vector<int>()) {}
	unionfind(int n_) : n(n_) {
		par.resize(n);
		for (int i = 0; i < n; i++) {
			par[i] = i;
		}
	}
	int root(int x) {
		if (x == par[x]) {
			return x;
		}
		return par[x] = root(par[x]);
	}
	void link(int x, int y) {
		x = root(x);
		y = root(y);
		if (x < y) {
			swap(x, y);
		}
		par[y] = x;
	}
	bool connected(int x, int y) {
		return root(x) == root(y);
	}
};

int main() {
	int N, M, K;
	cin >> N >> M >> K;
	unionfind uf(N + M);
	vector<int> cnt(N + M);
	for (int i = 0; i < N; i++) {
		cnt[i] += 1;
	}
	int answer = -1;
	for (int i = 0; i < K; i++) {
		int tp, a, b;
		cin >> tp >> a >> b;
		if (tp == 1) {
			a -= 1;
			b -= 1;
			if (uf.root(a) != uf.root(b) && uf.root(a) >= N && uf.root(b) >= N) {
				answer = i;
				break;
			}
			uf.link(a, b);
		}
		else {
			a -= 1;
			b -= 1;
			if (uf.root(a) != uf.root(b + N) && uf.root(a) >= N) {
				answer = i;
				break;
			}
			uf.link(a, b + N);
		}
	}
	cout << answer + 1 << endl;
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 4608
final_rank: 10

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

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

using namespace std;

int N; 

class UnionFind {
	public:
	int par[200009]; 
	int siz[200009]; 

	void init(int N){
		rep_(i, N) par[i] = -1; 
		rep_(i, N) siz[i] =  1; 
	}

	int root(int x){
		while (true){
			if (par[x] == -1) break; 
			x = par[x]; 
		}
		return x; 
	}

	int root_(int x){ // M := N + c 手前の親(set_rootする前のもともとの親)
		while (true){
			if (par[x] > N) break; 
			x = par[x]; 
		}
		return x; 
	}

	int set_root(int c, int x){
		int Rc = root(c); 
		if (Rc != N + x and Rc > N){ // すでにほかのに属してる
			return false; 
		}else{
			par[Rc] = N + x; 
			siz[Rc] = siz[Rc] + 1; 
			return true; 
		}
	}

	int unite(int u, int v){
		int RootU = root(u); 
		int RootV = root(v); 
		if (RootU > N && RootV > N){ // どちらともすでに属している
			return false; 
		}
		if (RootU == RootV) return true; 
		if (siz[RootU] < siz[RootV]){
			if (RootU > N){ // 親をM (:= N + c) で固定するため
				par[root_(u)] = RootV; 
				par[RootV] = RootU; 
				siz[RootV] = siz[RootU] + siz[RootV]; 
			}else{
				par[RootU] = RootV; 
				siz[RootV] = siz[RootU] + siz[RootV]; 
			}
			return true; 
		}else{
			if (RootV > N){
				par[root_(v)] = RootU; 
				par[RootU] = RootV; 
				siz[RootU] = siz[RootU] + siz[RootV]; 
			}else{
				par[RootV] = RootU; 
				siz[RootU] = siz[RootU] + siz[RootV]; 
			}
			return true; 
		}
	}

	bool same(int u, int v){
		if (root(u) == root(v)) return true; 
		return false; 
	}

}; 


int main(){
	int M, K; 
	cin >> N >> M >> K; 
	UnionFind uf; 
	uf.init(N + M); 
	rep(i, K){
		int q, a, b; 
		cin >> q >> a >> b; 
		if (q == 1){
			if (uf.unite(a, b)){
			}else{
				cout << i + 1 << endl; 
				/* cout << "cant unite" << endl; */ 
				return 0; 
			}
		}else{
			if (uf.set_root(a, b)){
			}else{
				cout << i + 1 << endl; 
				/* cout << "cant set_root" << endl; */ 
				return 0; 
			}
		}
	}
	cout << 0 << endl; 
}
accuracy: 0.5652173913043478
time_ms: 10
memory_kb: 4644
final_rank: 17

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

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

using namespace std;

int N; 

class UnionFind {
	public:
	int par[200009]; 
	int siz[200009]; 

	void init(int N){
		rep_(i, N) par[i] = -1; 
		rep_(i, N) siz[i] =  1; 
	}

	int root(int x){
		while (true){
			if (par[x] == -1) break; 
			x = par[x]; 
		}
		return x; 
	}

	int root_(int x){ // M := N + c 隰・唱辯慕ｸｺ・ｮ髫包ｽｪ(set_root邵ｺ蜷ｶ・玖恆髦ｪ繝ｻ郢ｧ繧・・郢ｧ繧・・邵ｺ・ｮ髫包ｽｪ)
		while (true){
			if (par[x] > N) break; 
			x = par[x]; 
		}
		return x; 
	}

	int set_root(int c, int x){
		int Rc = root(c); 
		if (Rc != N + x and Rc > N){ // 邵ｺ蜷ｶ縲堤ｸｺ・ｫ邵ｺ・ｻ邵ｺ荵昴・邵ｺ・ｫ陞ｻ讒ｭ・邵ｺ・ｦ郢ｧ繝ｻ
			return false; 
		}else{
			par[Rc] = N + x; 
			siz[Rc] = siz[Rc] + 1; 
			return true; 
		}
	}

	int unite(int u, int v){
		int RootU = root(u); 
		int RootV = root(v); 
		if (RootU > N && RootV > N){ // 邵ｺ・ｩ邵ｺ・｡郢ｧ蟲ｨ竊堤ｹｧ繧・・邵ｺ・ｧ邵ｺ・ｫ陞ｻ讒ｭ・邵ｺ・ｦ邵ｺ繝ｻ・・
			return false; 
		}
		if (RootU == RootV) return true; 
		if (siz[RootU] < siz[RootV]){
			if (RootU > N){ // 髫包ｽｪ郢ｧ讓ｽ (:= N + c) 邵ｺ・ｧ陜暦ｽｺ陞ｳ螢ｹ笘・ｹｧ荵昶螺郢ｧ繝ｻ
				par[root_(u)] = RootV; 
				par[RootV] = RootU; 
				siz[RootV] = siz[RootU] + siz[RootV]; 
			}else{
				par[RootU] = RootV; 
				siz[RootV] = siz[RootU] + siz[RootV]; 
			}
			return true; 
		}else{
			if (RootV > N){
				par[root_(v)] = RootU; 
				par[RootU] = RootV; 
				siz[RootU] = siz[RootU] + siz[RootV]; 
			}else{
				par[RootV] = RootU; 
				siz[RootU] = siz[RootU] + siz[RootV]; 
			}
			return true; 
		}
	}

	bool same(int u, int v){
		if (root(u) == root(v)) return true; 
		return false; 
	}

}; 


int main(){
	int M, K; 
	cin >> N >> M >> K; 
	UnionFind uf; 
	uf.init(N + M + 5); 
	rep(i, K){
		int q, a, b; 
		cin >> q >> a >> b; 
		if (q == 1){
			if (uf.unite(a, b)){
			}else{
				cout << i + 1 << endl; 
				/* cout << "cant unite" << endl; */ 
				return 0; 
			}
		}else{
			if (uf.set_root(a, b)){
			}else{
				cout << i + 1 << endl; 
				/* cout << "cant set_root" << endl; */ 
				return 0; 
			}
		}
	}
	cout << 0 << endl; 
}
accuracy: 0.5652173913043478
time_ms: 10
memory_kb: 4924
final_rank: 19

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

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

using namespace std;

int N; 

class UnionFind {
	public:
	int par[500009]; 
	int siz[500009]; 

	void init(int N){
		rep_(i, N) par[i] = -1; 
		rep_(i, N) siz[i] =  1; 
	}

	int root(int x){
		while (true){
			if (par[x] == -1) break; 
			x = par[x]; 
		}
		return x; 
	}

	int root_(int x){ // M := N + c 隰・唱辯慕ｸｺ・ｮ髫包ｽｪ(set_root邵ｺ蜷ｶ・玖恆髦ｪ繝ｻ郢ｧ繧・・郢ｧ繧・・邵ｺ・ｮ髫包ｽｪ)
		while (true){
			if (par[x] > N) break; 
			x = par[x]; 
		}
		return x; 
	}

	int set_root(int c, int x){
		int Rc = root(c); 
		if (Rc != N + x and Rc > N){ // 邵ｺ蜷ｶ縲堤ｸｺ・ｫ邵ｺ・ｻ邵ｺ荵昴・邵ｺ・ｫ陞ｻ讒ｭ・邵ｺ・ｦ郢ｧ繝ｻ
			return false; 
		}else{
			par[Rc] = N + x; 
			siz[Rc] = siz[Rc] + 1; 
			return true; 
		}
	}

	int unite(int u, int v){
		int RootU = root(u); 
		int RootV = root(v); 
		if (RootU > N && RootV > N){ // 邵ｺ・ｩ邵ｺ・｡郢ｧ蟲ｨ竊堤ｹｧ繧・・邵ｺ・ｧ邵ｺ・ｫ陞ｻ讒ｭ・邵ｺ・ｦ邵ｺ繝ｻ・・
			return false; 
		}
		if (RootU == RootV) return true; 
		if (siz[RootU] < siz[RootV]){
			if (RootU > N){ // 髫包ｽｪ郢ｧ讓ｽ (:= N + c) 邵ｺ・ｧ陜暦ｽｺ陞ｳ螢ｹ笘・ｹｧ荵昶螺郢ｧ繝ｻ
				par[root_(u)] = RootV; 
				par[RootV] = RootU; 
				siz[RootV] = siz[RootU] + siz[RootV]; 
			}else{
				par[RootU] = RootV; 
				siz[RootV] = siz[RootU] + siz[RootV]; 
			}
			return true; 
		}else{
			if (RootV > N){
				par[root_(v)] = RootU; 
				par[RootU] = RootV; 
				siz[RootU] = siz[RootU] + siz[RootV]; 
			}else{
				par[RootV] = RootU; 
				siz[RootU] = siz[RootU] + siz[RootV]; 
			}
			return true; 
		}
	}

	bool same(int u, int v){
		if (root(u) == root(v)) return true; 
		return false; 
	}

}; 


int main(){
	int M, K; 
	cin >> N >> M >> K; 
	UnionFind uf; 
	uf.init(N + M); 
	rep(i, K){
		int q, a, b; 
		cin >> q >> a >> b; 
		if (q == 1){
			if (uf.unite(a, b)){
			}else{
				cout << i + 1 << endl; 
				/* cout << "cant unite" << endl; */ 
				return 0; 
			}
		}else{
			if (uf.set_root(a, b)){
			}else{
				cout << i + 1 << endl; 
				/* cout << "cant set_root" << endl; */ 
				return 0; 
			}
		}
	}
	cout << 0 << endl; 
}
accuracy: 0.5652173913043478
time_ms: 10
memory_kb: 6244
final_rank: 20

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

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

using namespace std;

int N; 

class UnionFind {
	public:
	int par[200009]; 
	int siz[200009]; 

	void init(int N){
		rep_(i, N) par[i] = -1; 
		rep_(i, N) siz[i] =  1; 
	}

	int root(int x){
		while (true){
			if (par[x] == -1) break; 
			x = par[x]; 
		}
		return x; 
	}

	int root_(int x){
		while (true){
			if (par[x] > N) break; 
			x = par[x]; 
		}
		return x; 
	}

	int set_root(int c, int x){
		int Rc = root(c); 
		/* cout << "root" << c << ":" << root(c) << endl; */ 
		if (Rc != N + x and Rc > N){
			return false; 
		}else{
			par[Rc] = N + x; 
			siz[Rc] = siz[Rc] + 1; 
			return true; 
		}
	}

	int unite(int u, int v){
		int RootU = root(u); 
		int RootV = root(v); 
		if (RootU > N && RootV > N){
			return false; 
		}
		if (RootU == RootV) return true; 
		if (siz[RootU] < siz[RootV]){
			if (RootU > N){
				par[root_(u)] = RootV; 
				par[RootV] = RootU; 
				siz[RootV] = siz[RootU] + siz[RootV]; 
			}else{
				par[RootU] = RootV; 
				siz[RootV] = siz[RootU] + siz[RootV]; 
			}
			return true; 
		}else{
			if (RootV > N){
				par[root_(v)] = RootU; 
				par[RootU] = RootV; 
				siz[RootU] = siz[RootU] + siz[RootV]; 
			}else{
				par[RootV] = RootU; 
				siz[RootU] = siz[RootU] + siz[RootV]; 
			}
			return true; 
		}
	}

	bool same(int u, int v){
		if (root(u) == root(v)) return true; 
		return false; 
	}

}; 


int main(){
	int M, K; 
	cin >> N >> M >> K; 
	UnionFind uf; 
	uf.init(N + M); 
	rep(i, K){
		int q, a, b; 
		cin >> q >> a >> b; 
		if (q == 1){
			if (uf.unite(a, b)){
			}else{
				cout << i + 1 << endl; 
				/* cout << "cant unite" << endl; */ 
				return 0; 
			}
		}else{
			if (uf.set_root(a, b)){
			}else{
				cout << i + 1 << endl; 
				/* cout << "cant set_root" << endl; */ 
				return 0; 
			}
		}
	}
	cout << 0 << endl; 
}
accuracy: 0.5652173913043478
time_ms: 10
memory_kb: 4768
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF INT64_MAX;
int main(void)
{
    int n,m,k;
    cin>>n>>m>>k;
    bool flg=false;
    vector<int> par(n+1,0),rank(n+1,1),club(n+1,0);
    for(int i=0;i<=n;i++) par[i]=i;
    for(int i=0;i<=k;i++){
        if(flg){
            cout<<i<<endl;
            return 0;
        }
        if(i==k){
            cout<<"0"<<endl;
            return 0;
        }
        int cls,a,b,c,x;
        cin>>cls;
        if(cls==1){
            cin>>a>>b;
            while(a!=par[a]) a=par[a];
            while(b!=par[b]) b=par[b];
            if(a!=b){
                if((club[a]!=0 && club[b]!=0) && club[a]!=club[b]) flg=true;
                if(rank[a]>rank[b]){
                    club[a]=max(club[a],club[b]);
                    par[b]=a;
                }
                else if(rank[a]<rank[b]){
                    club[b]=max(club[a],club[b]);
                    par[a]=b;
                }
                else{
                    club[a]=max(club[a],club[b]);    
                    par[b]=a;
                    rank[a]++;
                }
            }
            else{
                if(club[a]!=club[b]) flg=true;
            }
        }
        else{
            cin>>c>>x;
            while(c!=par[c]) c=par[c];
            if(club[c]!=0 && club[c]!=x) flg=true;
            club[c]=x;
        }
    }
    cout<<"0"<<endl;
}
accuracy: 1
time_ms: 100
memory_kb: 3892
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF INT64_MAX;
int main(void)
{
    int n,m,k;
    cin>>n>>m>>k;
    bool flg=false;
    vector<int> par(n+1,0),rank(n+1,1),club(n+1,0);
    for(int i=0;i<=n;i++) par[i]=i;
    for(int i=0;i<k;i++){
        if(flg){
            cout<<i<<endl;
            return 0;
        }
        int cls,a,b,c,x;
        cin>>cls;
        if(cls==1){
            cin>>a>>b;
            while(a!=par[a]) a=par[a];
            while(b!=par[b]) b=par[b];
            if(a!=b){
                if((club[a]!=0 && club[b]!=0) && club[a]!=club[b]) flg=true;
                if(rank[a]>rank[b]){
                    club[a]=max(club[a],club[b]);
                    par[b]=a;
                }
                else if(rank[a]<rank[b]){
                    club[b]=max(club[a],club[b]);
                    par[a]=b;
                }
                else{
                    club[a]=max(club[a],club[b]);    
                    par[b]=a;
                    rank[a]++;
                }
            }
            else{
                if(club[a]!=club[b]) flg=true;
            }
        }
        else{
            cin>>c>>x;
            while(c!=par[c]) c=par[c];
            if(club[c]!=0 && club[c]!=x) flg=true;
            club[c]=x;
        }
    }
    cout<<"0"<<endl;
}
accuracy: 0.6086956521739131
time_ms: 50
memory_kb: 3884
final_rank: 16