This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
	
    #include <iostream>
    #include <vector>
    #include <set>
    #include <iomanip>
    #include <algorithm>
    #include <functional>
    #include <stdio.h>
    #include <cmath>
    #include <queue>
    #include <string>
    #include <map>
    #include <unordered_map>
    #include <fstream>
    #include <complex>
    #include <random>
    #include <stack>
    #include <chrono>
    #include <set>
     
    #define FOR(i,n) for(int i=0;i<n;i++)
    #define FORE(i,a,b) for(int i=a;i<=b;i++)
    #define ll long long int
    #define vi vector<int>
    #define ii pair<int,int>
    #define pb push_back
    #define mp make_pair
    #define ff first
    #define ss second
    #define pll pair<ll,ll>
    #define cd complex<double> 
    #define ld long double
    #define pld pair<ld,ld>
    #define iii pair<ii,int>
    #define vv vector
     
    using namespace std;
     
    const int MAXN = 50*1000+1;
    const int MAXM = 2*MAXN;
    int n;
    struct DSU{
    	struct Oper{
    		int type; // change in parent = 1, change in rank = 2;checkpoint = 3;size =4
    		int a;
    		int b;
    		Oper(int t,int aa = 0,int bb = 0){
    			type = t;
    			a = aa;
    			b = bb;
    		}
		};
    	stack<Oper> st;
    	int parent[MAXN];
    	int sz[MAXN];
    	int rnk[MAXN];
    	void init(){
    		FOR(i,n)parent[i] = i;
    		FOR(i,n)sz[i] = 1;
    		FOR(i,n)rnk[i] = 1;
    	}
    	inline int find(int a){
    		if(a == parent[a])return a;
    		return find(parent[a]);
    	}
    	inline void merge(int a,int b){
    		if(isSame(a,b))return;
    		int pa = find(a);
    		int pb = find(b);
    		if(rnk[pa] > rnk[pb]){
    			st.push(Oper(1,pb));
    			st.push(Oper(2,pa,sz[pb]));
    			sz[pa] += sz[pb];
    			parent[pb] = pa;
    		}else if(rnk[pa] < rnk[pb]){
       			st.push(Oper(1,pa));
    			st.push(Oper(2,pb,sz[pa]));
				sz[pb] += sz[pa];
				parent[pa] = pb;
			}else{
				st.push(Oper(1,pb));
    			st.push(Oper(2,pa,sz[pb]));
				st.push(Oper(4,pa));
				sz[pa] += sz[pb];
				parent[pb] = pa;
				rnk[pa]++;
			}
    		
    		
    		
    	};
    	inline int getSize(int a){
    		return sz[find(a)];
    	}
		inline bool isSame(int a,int b){
    		return find(a) == find(b);
    	}
    	inline void setCheckPoint(){
    		st.push(Oper(3));
		}
		inline void rollback(){
			while(!st.empty()){
				auto e = st.top();st.pop();
				if(e.type == 3)break;
				else if(e.type == 1){
					parent[e.a] = e.a;
				}else if(e.type == 2){
					sz[e.a] -= e.b;
				}else{
					rnk[e.a]--;
				}
			}
		}
    };
     
    struct edge{
    	int ID;
    	int a,b;
    	int w;
    	edge(int id,int aa,int bb,int ww){
    		ID = id;
    		a = aa;
    		b = bb;
    		w = ww;
    	}
    };
    struct query{
    	int type; // 1 is update, 2 is query
    	int tm;
    	int info1; // node for query, edge for update
    	int info2; // value for either
    	int id;
    	query(int t,int a,int b,int c){
    		type = t;
    		tm = id = a;
    		info1 = b;
    		info2 = c;
     
    	}
    };
     
    int finalANS[MAXM];
    vv<edge> allEdges;
     
    vi rem;
    bool edg[MAXM];
     
    void processQueries(vv<query> allQueries){
    	//FOR(i,MAXM)edg[i] = 0;
    	for(auto e : rem)edg[e] = 0;
    	rem.clear();
    	for(auto e : allQueries){
    		if(e.type == 1){
    			edg[e.info1] = 1;
    			rem.pb(e.info1);
    		}
    	}
     	vv<query> actualQueries;
    	for(auto e : allQueries){
    		if(e.type == 2){
    			actualQueries.pb(e);
    		}
    	}
    	vv<edge> nonBlockEdges;
    	FOR(i,allEdges.size()){
    		if(edg[i])continue;
    		nonBlockEdges.pb(allEdges[i]);
		}
     	sort(nonBlockEdges.begin(),nonBlockEdges.end(),[&](edge a,edge b){
     		return a.w > b.w;
     	});
    	sort(actualQueries.begin(), actualQueries.end(), [&](query a,query b){
    		return a.info2 > b.info2;
    	});
     	int PTR = 0;
     	DSU dsu;
    	dsu.init();
    		
    	for(auto q : actualQueries){
    		//cout << "PROCESSING FOR QUERY : " << q.info1 << " " << q.info2 << endl;
    		while(PTR < nonBlockEdges.size() and nonBlockEdges[PTR].w >= q.info2){
				dsu.merge(nonBlockEdges[PTR].a,nonBlockEdges[PTR].b);
				PTR++;
			}	
    		dsu.setCheckPoint();
    		map<int,int> mp;
    		//mp.max_load_factor(0.25);
    		//mp.reserve(1024);
    		for(auto xx : rem){
    			mp[xx] = allEdges[xx].w;
    		}
    		for(auto e : allQueries){
    			if(e.type == 2)continue;
    			if(e.tm > q.tm)continue;
    			mp[e.info1] = e.info2;
    		}
    		for(auto x : mp){
    			if(x.ss >= q.info2){
    				dsu.merge(allEdges[x.ff].a,allEdges[x.ff].b);
    			}
    		}
    		finalANS[q.id] = dsu.getSize(q.info1);
    		dsu.rollback();
    	}
     
    	for(auto e : allQueries){
    		if(e.type == 1){
    			allEdges[e.info1].w = e.info2;
    		}
    	}
    }
    bool quer[MAXM];
    #define endl '\n'
    int main(){
    	ios_base::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	int m;
    	cin >> n >> m;
    	FOR(i,m){
    		int a,b,c;
    		cin >> a >> b >> c;
    		a--;b--;
    		allEdges.pb(edge(i,a,b,c));
    	}
    	int q;
    	cin >> q;
    	FOR(i,MAXM)finalANS[i] = -1;
    	int BLOCK = 40;
    	vv<query> allq;
     
    	FOR(i,q){
    		int a,b,c;
    		cin >> a >> b >> c;
    		if(a == 2)quer[i] = 1;
    		b--;
    		allq.pb(query(a,i,b,c));
    		if((i+1)%BLOCK == 0){
    			processQueries(allq);
    			allq.clear();
    		}
    	}
    	if(allq.size() > 0)processQueries(allq);
    	FOR(i,q){
    		//if(finalANS[i] == -1 and quer[i])while(1);
    		if(quer[i])cout << finalANS[i] << endl;
    	}
    	return 0;
    }
Compilation message (stderr)
bridges.cpp: In function 'void processQueries(std::vector<query>)':
bridges.cpp:22:35: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     #define FOR(i,n) for(int i=0;i<n;i++)
bridges.cpp:167:10:
      FOR(i,allEdges.size()){
          ~~~~~~~~~~~~~~~~~         
bridges.cpp:167:6: note: in expansion of macro 'FOR'
      FOR(i,allEdges.size()){
      ^~~
bridges.cpp:183:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       while(PTR < nonBlockEdges.size() and nonBlockEdges[PTR].w >= q.info2){
             ~~~~^~~~~~~~~~~~~~~~~~~~~~| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |