When you play the game of thrones, you win, or you die. There is no middle ground.

Cersei Lannister, A Game of Thrones by George R. R. Martin

There are n nobles, numbered from 1 to n. Noble i has a power of i. There are also m "friendships". A friendship between nobles a and b is always mutual.

A noble is defined to be vulnerable if both of the following conditions are satisfied: 

  * the noble has at least one friend, and 
  * all of that noble's friends have a higher power. 



You will have to process the following three types of queries. 

  1. Add a friendship between nobles u and v. 
  2. Remove a friendship between nobles u and v. 
  3. Calculate the answer to the following process. 



The process: all vulnerable nobles are simultaneously killed, and all their friendships end. Then, it is possible that new nobles become vulnerable. The process repeats itself until no nobles are vulnerable. It can be proven that the process will end in finite time. After the process is complete, you need to calculate the number of remaining nobles.

Note that the results of the process are not carried over between queries, that is, every process starts with all nobles being alive!

Input

The first line contains the integers n and m (1 ≤ n ≤ 2⋅ 10^5, 0 ≤ m ≤ 2⋅ 10^5) — the number of nobles and number of original friendships respectively.

The next m lines each contain the integers u and v (1 ≤ u,v ≤ n, u ≠ v), describing a friendship. No friendship is listed twice.

The next line contains the integer q (1 ≤ q ≤ 2⋅ {10}^{5}) — the number of queries. 

The next q lines contain the queries themselves, each query has one of the following three formats. 

  * 1 u v (1 ≤ u,v ≤ n, u ≠ v) — add a friendship between u and v. It is guaranteed that u and v are not friends at this moment. 
  * 2 u v (1 ≤ u,v ≤ n, u ≠ v) — remove a friendship between u and v. It is guaranteed that u and v are friends at this moment. 
  * 3 — print the answer to the process described in the statement. 

Output

For each type 3 query print one integer to a new line. It is guaranteed that there will be at least one type 3 query.

Examples

Input


4 3
2 1
1 3
3 4
4
3
1 2 3
2 3 1
3


Output


2
1


Input


4 3
2 3
3 4
4 1
1
3


Output


1

Note

Consider the first example. In the first type 3 query, we have the diagram below.

In the first round of the process, noble 1 is weaker than all of his friends (2 and 3), and is thus killed. No other noble is vulnerable in round 1. In round 2, noble 3 is weaker than his only friend, noble 4, and is therefore killed. At this point, the process ends, and the answer is 2.

<image>

In the second type 3 query, the only surviving noble is 4.

The second example consists of only one type 3 query. In the first round, two nobles are killed, and in the second round, one noble is killed. The final answer is 1, since only one noble survives.

<image>
3 0
2
1 2 1
3
 20 0
1
3
 1000 0
1
3
 20 0
20
3
3
1 17 19
1 19 20
1 4 8
1 9 18
1 1 14
1 16 19
1 10 19
1 1 7
1 6 10
1 18 19
1 9 16
1 15 17
1 11 12
1 10 15
3
1 2 9
1 1 13
1 16 20
 20 53
1 2
1 4
1 5
1 6
1 7
1 8
1 20
2 3
2 6
2 16
2 17
3 6
3 18
3 20
4 6
4 7
4 8
4 9
4 14
4 18
5 11
5 13
5 17
5 18
5 19
6 8
6 13
7 8
7 10
7 15
7 17
7 18
8 15
8 16
9 10
9 15
10 11
10 17
10 20
11 15
11 16
12 14
12 15
12 16
12 19
14 16
14 19
16 17
16 19
16 20
17 19
17 20
18 19
1
3

2
 20
 1000
 20
20
9
 4

import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.abs;
import static java.lang.System.out;
import java.util.*;
import java.io.*;
import java.math.*;
                                /*Give your 100%, that's it!*/
public class Template {
    
	static int mod = 1000000007;

	public static void main(String[] args){
        FastScanner sc = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);
        int yo = 1;
        while (yo-- > 0) {
            int n = sc.nextInt();
            int m = sc.nextInt();
            int[] count = new int[n];
            for(int i = 0; i < m; i++){
                int x = sc.nextInt()-1;
                int y = sc.nextInt()-1;
                count[min(x,y)]++;
            }
            
            int res = 0;
            for(int e : count){
                if(e == 0) res++;
            }
            
            int q = sc.nextInt();
            while(q-->0){
                int x = sc.nextInt();
                if(x == 1){ // add
                    int u = sc.nextInt()-1;
                    int v = sc.nextInt()-1;
                    count[min(u,v)]++;
                    if(count[min(u,v)] == 1){
                        res--;
                    }
                }
                else if(x == 2){ // remove
                    int u = sc.nextInt()-1;
                    int v = sc.nextInt()-1;
                    count[min(u,v)]--;
                    if(count[min(u,v)] == 0){
                        res++;
                    }
                }
                else if(x == 3){ // ans
                    out.println(res);
                }
            }
        }
        out.close();    
	}
    
   
    
    
    /*
         Random stuff to try when stuck:
            -if it's 2C then it's dp
            -for combo/probability problems, expand the given form we're interested in
            -make everything the same then build an answer (constructive, make everything 0 then do something)
            -something appears in parts of 2 --> model as graph
            -assume a greedy then try to show why it works
            -find way to simplify into one variable if multiple exist
            -treat it like fmc (note any passing thoughts/algo that could be used so you can revisit them)
            -find lower and upper bounds on answer
            -figure out what ur trying to find and isolate it
            -see what observations you have and come up with more continuations
            -work backwards (in constructive, go from the goal to the start)
            -turn into prefix/suffix sum argument (often works if problem revolves around adjacent array elements)
            -instead of solving for answer, try solving for complement (ex, find n-(min) instead of max)
            -draw something
            -simulate a process
            -dont implement something unless if ur fairly confident its correct
            -after 3 bad submissions move on to next problem if applicable
            -do something instead of nothing and stay organized
            -write stuff down
         Random stuff to check when wa:
            -if code is way too long/cancer then reassess
            -switched N/M
            -int overflow
            -switched variables
            -wrong MOD
            -hardcoded edge case incorrectly
         Random stuff to check when tle:
            -continue instead of break
            -condition in for/while loop bad
         Random stuff to check when rte:
            -switched N/M
            -long to int/int overflow
            -division by 0
            -edge case for empty list/data structure/N=1
      */

	public static class Pair {
		int x;
		int y;

		public Pair(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}

	public static void sort(int[] arr) {
		ArrayList<Integer> ls = new ArrayList<Integer>();
		for (int x : arr)
			ls.add(x);
		Collections.sort(ls);
		for (int i = 0; i < arr.length; i++)
			arr[i] = ls.get(i);
	}

	public static long gcd(long a, long b) {
		if (b == 0)
			return a;
		return gcd(b, a % b);
	}

	static boolean[] sieve(int N) {
		boolean[] sieve = new boolean[N + 1];
		for (int i = 2; i <= N; i++)
			sieve[i] = true;

		for (int i = 2; i <= N; i++) {
			if (sieve[i]) {
				for (int j = 2 * i; j <= N; j += i) {
					sieve[j] = false;
				}
			}
		}
		return sieve;
	}

	public static long power(long x, long y, long p) {
		long res = 1L;
		x = x % p;
		while (y > 0) {
			if ((y & 1) == 1)
				res = (res * x) % p;
			y >>= 1;
			x = (x * x) % p;
		}
		return res;
	}

	public static void print(int[] arr) {
		//for debugging only
		for (int x : arr)
			out.print(x + " ");
		out.println();
	}

	static class FastScanner {
		private int BS = 1 << 16;
		private char NC = (char) 0;
		private byte[] buf = new byte[BS];
		private int bId = 0, size = 0;
		private char c = NC;
		private double cnt = 1;
		private BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) {
			try {
				in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
			} catch (Exception e) {
				in = new BufferedInputStream(System.in, BS);
			}
		}

		private char getChar() {
			while (bId == size) {
				try {
					size = in.read(buf);
				} catch (Exception e) {
					return NC;
				}
				if (size == -1)
					return NC;
				bId = 0;
			}
			return (char) buf[bId++];
		}

		public int nextInt() {
			return (int) nextLong();
		}

		public int[] readInts(int N) {
			int[] res = new int[N];
			for (int i = 0; i < N; i++) {
				res[i] = (int) nextLong();
			}
			return res;
		}

		public long[] readLongs(int N) {
			long[] res = new long[N];
			for (int i = 0; i < N; i++) {
				res[i] = nextLong();
			}
			return res;
		}

		public long nextLong() {
			cnt = 1;
			boolean neg = false;
			if (c == NC)
				c = getChar();
			for (; (c < '0' || c > '9'); c = getChar()) {
				if (c == '-')
					neg = true;
			}
			long res = 0;
			for (; c >= '0' && c <= '9'; c = getChar()) {
				res = (res << 3) + (res << 1) + c - '0';
				cnt *= 10;
			}
			return neg ? -res : res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c != '.' ? cur : cur + nextLong() / cnt;
		}

		public double[] readDoubles(int N) {
			double[] res = new double[N];
			for (int i = 0; i < N; i++) {
				res[i] = nextDouble();
			}
			return res;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while (c <= 32)
				c = getChar();
			while (c > 32) {
				res.append(c);
				c = getChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while (c <= 32)
				c = getChar();
			while (c != '\n') {
				res.append(c);
				c = getChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if (c > 32)
				return true;
			while (true) {
				c = getChar();
				if (c == NC)
					return false;
				else if (c > 32)
					return true;
			}
		}
	}

	//	For Input.txt and Output.txt	
	//	FileInputStream in = new FileInputStream("input.txt");
	//	FileOutputStream out = new FileOutputStream("output.txt");
	//	PrintWriter pw = new PrintWriter(out);
	//	Scanner sc = new Scanner(in);
}