import java.io.BufferedReader; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedList; import java.util.Scanner; import java.util.Set; import java.util.StringTokenizer; public class Main { public static class UnionFind { int[] par; // public UnionFind(int n) { par = new int[n]; for (int i = 0; i < n; i++) { par[i] = -1; } } public int find(int x) { if (par[x] < 0) { return x; } else { return par[x] = find(par[x]); } } public boolean union(int x, int y) { x = find(x); y = find(y); if (x != y) { if (par[y] < par[x]) { // 多い方が根になるようにスワップする. int tmp = x; x = y; y = tmp; } par[x] += par[y]; par[y] = x; return true; } else { return false; } } public boolean same(int x, int y) { return find(x) == find(y); } public int size(int x) { return -par[find(x)]; } } public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); final int N = sc.nextInt(); final int M = sc.nextInt(); final int Q = sc.nextInt(); ArrayList> first_adj = new ArrayList>(); for(int i = 0; i < N; i++){ first_adj.add(new HashSet()); } ArrayList> last_adj = new ArrayList>(); for(int i = 0; i < N; i++){ last_adj.add(new HashSet()); } ArrayList> query_adj = new ArrayList>(); for(int i = 0; i < N; i++){ query_adj.add(new HashSet()); } for(int i = 0; i < M; i++){ final int a = sc.nextInt() - 1; final int b = sc.nextInt() - 1; first_adj.get(a).add(b); first_adj.get(b).add(a); } int[] cs = new int[Q]; int[] ds = new int[Q]; for(int i = 0; i < Q; i++){ cs[i] = sc.nextInt() - 1; ds[i] = sc.nextInt() - 1; query_adj.get(cs[i]).add(ds[i]); query_adj.get(ds[i]).add(cs[i]); } UnionFind uf = new UnionFind(N); for(int from = 0; from < N; from++){ for(final int to : first_adj.get(from)){ final boolean breaked = query_adj.get(from).contains(to); if(!breaked){ uf.union(from, to); last_adj.get(from).add(to); last_adj.get(to).add(from); } } } int[] answer = new int[N]; boolean[] already = new boolean[N]; for(int i = 1; i < N; i++){ if(uf.same(0, i)){ answer[i] = -1; already[i] = true; }else{ answer[i] = 0; already[i] = false; } } //System.out.println(last_adj); LinkedList queue = new LinkedList(); for(int q = Q - 1; q >= 0; q--){ final int c = cs[q]; final int d = ds[q]; //System.out.println(Arrays.toString(uf.par)); uf.union(c, d); //System.out.println(c + " " + d); queue.clear(); queue.add(c); queue.add(d); while(!queue.isEmpty()){ final int node = queue.poll(); if(uf.same(0, node) && !already[node]){ answer[node] = q + 1; already[node] = true; for(final int next : last_adj.get(node)){ if(!already[next]){ queue.add(next); } } } } last_adj.get(c).add(d); last_adj.get(d).add(c); } for(int i = 1; i < N; i++){ System.out.println(answer[i]); } } public static class Scanner implements Closeable { private BufferedReader br; private StringTokenizer tok; public Scanner(InputStream is) throws IOException { br = new BufferedReader(new InputStreamReader(is)); } private void getLine() throws IOException { while (!hasNext()) { tok = new StringTokenizer(br.readLine()); } } private boolean hasNext() { return tok != null && tok.hasMoreTokens(); } public String next() throws IOException { getLine(); return tok.nextToken(); } public int nextInt() throws IOException { return Integer.parseInt(next()); } public long nextLong() throws IOException { return Long.parseLong(next()); } public double nextDouble() throws IOException { return Double.parseDouble(next()); } public void close() throws IOException { br.close(); } } }