#include #define debug(x) cerr << #x << ": " << x << '\n' #define debugArray(x,n) for(long long hoge = 0; (hoge) < (n); ++ (hoge)) cerr << #x << "[" << hoge << "]: " << x[hoge] << '\n' using namespace std; typedef long long ll; typedef unsigned long long ull; typedef vector vll; const ll INF = INT_MAX; const ll MOD = 998244353; struct Edge{ int src,dst; Edge(ll s,ll t):src(s),dst(t){} }; using Edges=vector; using Graph=vector; struct BridgeBlockTree{ vector index; vector> block; Edges bridges; Graph g; BridgeBlockTree(Graph g_){ ll n=g_.size(); index.assign(n, -1); vector num(n), par(n,-1), cur(n); for (int s = 0; s < n; ++s) { if (num[s]) continue; int time = 0; vector snum, path, stack = {s}; while (!stack.empty()) { int u = stack.back(); if (cur[u] == 0) { num[u] = ++time; path.push_back(u); snum.push_back(num[u]); } if(cur[u] == (ll)g_[u].size()){ if (num[u] == snum.back()){ snum.pop_back(); block.push_back({}); while (1) { int w = path.back(); path.pop_back(); block.back().push_back(w); index[w] = block.size()-1; if (u == w) break; } } stack.pop_back(); }else{ int v = g_[u][cur[u]++].dst; if (!num[v]) { par[v] = u; stack.push_back(v); }else if (v != par[u] && index[v] < 0) { while (snum.back() > num[v]) snum.pop_back(); } } } } ll tn = block.size(); g.resize(tn); for (int u = 0; u < n; ++u)if(par[u] >= 0 && index[u] != index[par[u]]){ g[index[u]].emplace_back(index[u], index[par[u]]); g[index[par[u]]].emplace_back(index[par[u]],index[u]); bridges.emplace_back(index[u],index[par[u]]); } } int operator[](const int &k){ return index[k]; } }; struct HLDecomposition{ private: int t; void dfs_size(int v=0){ size[v]=1; for(Edge& e:g[v]){ if(par[e.dst]>=0){ swap(e,g[v].back()); if(e.dst==g[v].back().dst)continue; } par[e.dst]=v; dfs_size(e.dst); size[v]+=size[e.dst]; if(size[e.dst]>size[g[v][0].dst]){ swap(e,g[v][0]); } } } void dfs_hld(int v=0,int d=0){ in[v] = t++; inv[in[v]]=v; dep[v] = d; for(Edge& e:g[v]){ if(par[e.dst]!=v)continue; head[e.dst]=(e.dst==g[v][0].dst?head[v]:e.dst); dfs_hld(e.dst,d+1); } out[v]=t; } public: int V; Graph g; vector dep,par,head,size,inv; vector in,out; HLDecomposition(int size_) :t(0),V(size_),g(V),dep(V,0),par(V,-1),head(V),size(V),inv(V),in(V),out(V){} HLDecomposition(Graph g_) :t(0),V(g_.size()),g(g_),dep(V,0),par(V,-1),head(V),size(V),inv(V),in(V),out(V){} void add_edge(int u,int v){ g[u].emplace_back(u,v); g[v].emplace_back(v,u); } void build(int root=0){ par[root]=0; dfs_size(root); par[root]=-1; dfs_hld(root); } int lca(int u,int v){ while(1){ if(in[u]>in[v])swap(u,v); if(head[u]==head[v])return u; v=par[head[v]]; } } int distance(int u,int v){ return dep[u]+dep[v]-2*dep[lca(u,v)]; } int operator[](const int &k){ return in[k]; } }; template struct SegmentTree{ using T = typename M::T; int n; vector dat; SegmentTree(){} SegmentTree(int n_){init(n_);} SegmentTree(const vector &v){build(v);} void init(int n_){ n=1; while(n &v){ int n_=v.size(); init(n_); for(int i=0;i>=1) dat[k]=M::f(dat[(k<<1)|0],dat[(k<<1)|1]); } //[a,b) T query(int a,int b,int k=1,int l=0,int r=-1){ if(r<0)r=n; if(r<=a||b<=l) return M::ti(); if(a<=l&&r<=b) return dat[k]; T vl=query(a,b,k*2,l,(l+r)/2); T vr=query(a,b,k*2+1,(l+r)/2,r); return M::f(vl,vr); } T operator[](const int &k) const {return dat[k + n];} }; struct RmaxQ { struct T{ ll val,idx; T(ll v,ll i):val(v),idx(i){} }; static T ti() { return {-1,0}; } static T f(const T& l, const T & r) { return l.val>r.val? l:r; } }; signed main(){ cin.tie(0); ios::sync_with_stdio(false); ll N,M,Q;cin>>N>>M>>Q; Graph g(N); for(ll i=0;i>x>>y;x--;y--; g[x].emplace_back(x,y); g[y].emplace_back(y,x); } BridgeBlockTree bbt(g); HLDecomposition hld(bbt.g); hld.build(); SegmentTree seg(hld.V); for(ll i=0;i> que(hld.V); for(ll i=0;i>op; if(op&1){ ll U,W;cin>>U>>W;U--; ll u=bbt[U]; que[u].push(W); seg.set_val(u,{que[u].top(),u}); }else{ ll S,T;cin>>S>>T;S--;T--; ll u=bbt[S],v=bbt[T]; RmaxQ::T ans=RmaxQ::ti(); while(1){ if(hld[u]>hld[v])swap(u,v); ans = RmaxQ::f(ans,seg.query(max(hld[u],hld[hld.head[v]]),hld[v]+1)); if(hld.head[u]!=hld.head[v])v=hld.par[hld.head[v]]; else break; } cout<=0){ que[ans.idx].pop(); seg.set_val(ans.idx,{que[ans.idx].top(),ans.idx}); } } } return 0; }