/** * author: Sooh * created: 05.12.2021 10:58:35 **/ #include using namespace std; #if __has_include() #include using namespace atcoder; using mint = modint998244353; //using mint = modint1000000007; #endif #pragma region template using ll = long long; template using V = vector; #define rep(i,n) for(int i=0;i void view(T e){std::cerr << e;} template void view(pair e){std::cerr << "("; view(e.fi); std::cerr << ", "; view(e.se); std::cerr << ")";} template void view(const set &st){ std::cerr << "\n";for(const auto& e : st){view(e); std::cerr << " ";}} template void view(const multiset &st){ std::cerr << "\n";for(const auto& e : st){view(e); std::cerr << " ";}} template void view(const map &mp){ std::cerr << "\n";for(const auto& [k, v]: mp){std::cerr << "("; view(k); std::cerr << ", "; view(v); std::cerr << ") ";}} template void view(const unordered_map &mp){ std::cerr << "\n";for(const auto& [k, v]: mp){std::cerr << "("; view(k); std::cerr << ", "; view(v); std::cerr << ") ";}} template void view(const std::vector& v){std::cerr << "\n";for(const auto& e : v){ view(e); std::cerr << " "; }} template void view(const std::vector >& vv){std::cerr << "\n";int cnt = 0;for(const auto& v : vv){cerr << cnt << "th : "; view(v); cnt++; std::cerr << std::endl;}} #else #define debug(var) 0 #endif ll power(ll a, ll p){ll ret = 1; while(p){if(p & 1){ret = ret * a;} a = a * a; p >>= 1;} return ret;} ll modpow(ll a, ll p, ll mod){ll ret = 1; while(p){assert(a < mod); if(p & 1){ret = ret * a % mod;} a = a * a % mod; p >>= 1;} return ret;} ll modinv(ll a, ll m) {ll b = m, u = 1, v = 0; while (b) {ll t = a / b ;a -= t * b; swap(a, b);u -= t * v; swap(u, v);}u %= m;if (u < 0) u += m;return u;} templatebool chmax(T &a, const K b) { if (abool chmin(T &a, const K b) { if (b> tree; // siz : for recording the size of a tree at the time T std::vector>> siz; int count; public: Partially_Persistent_Union_Find(int n): tree(n, {1, std::numeric_limits::max()}), siz(n, std::vector>(1, {0, 1})), count(0){} int leader(const int t, int x){ while(tree[x].second <= t) x = tree[x].first; return x; } // you can get time if you change the return value int merge(int x, int y){ ++count; x = leader(count, x); y = leader(count, y); if(x == y) return count; if(tree[x].first < tree[y].first) std::swap(x, y); tree[x].first += tree[y].first; siz[x].emplace_back(count, tree[x].first); tree[y] = std::pair(x, count); return count; } bool same(const int t, int x, int y){return leader(t, x) == leader(t, y);} int size(const int t, int x){ x = leader(t, x); auto it = std::lower_bound(siz[x].begin(), siz[x].end(), std::pair(t + 1, 0)); return (--it)->second; } }; int main(){ cin.tie(nullptr); ios::sync_with_stdio(false); //cout << fixed << setprecision(20); int n, m, q; cin >> n >> m >> q; V a(m), b(m), c(q), d(q); rep(i,m) cin >> a[i] >> b[i], --a[i], --b[i]; set> st; rep(i,q){ cin >> c[i] >> d[i]; --c[i], --d[i]; st.insert({c[i], d[i]}); } Partially_Persistent_Union_Find uf(n); int base = m - q; rep(i,m){ if(st.count({a[i], b[i]})) continue; uf.merge(a[i], b[i]); } for(int i = q - 1; i >= 0; i--){ uf.merge(c[i], d[i]); } V ans(n); debug(base); for(int i = 1; i < n; i++){ if(uf.same(base, 0, i)){ ans[i] = -1; continue; } int ok = m + 1, ng = base; while(abs(ok - ng) > 1){ int mid = (ok + ng) / 2; if(uf.same(mid, 0, i)) ok = mid; else ng = mid; } ok -= base; ans[i] = (ok == m + 1 - base ? 0 : q - ok + 1); } for(int i = 1; i < n; i++) cout << ans[i] << endl; }