import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
private static boolean[][] field;
private static Queue<int[]> queue;
private static int[] dr = {-1, 0, 1, 0};
private static int[] dc = {0, 1, 0, -1};
private static int m, n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st;
int T = Integer.parseInt(br.readLine());
for (int tc = 0; tc < T; tc++) {
int minWormCnt = 0;
st = new StringTokenizer(br.readLine());
m = Integer.parseInt(st.nextToken());
n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
field = new boolean[n][m];
queue = new LinkedList<>();
for (int i = 0; i < k; i++) {
st = new StringTokenizer(br.readLine());
int c = Integer.parseInt(st.nextToken());
int r = Integer.parseInt(st.nextToken());
field[r][c] = true;
}
for (int r = 0; r < n; r++) {
for (int c = 0; c < m; c++) {
if (field[r][c]) {
bfs(r, c);
minWormCnt++;
}
}
}
sb.append(minWormCnt + "\n");
}
System.out.print(sb.toString());
br.close();
}
public static void bfs(int initRow, int initCol) {
queue.offer(new int[] {initRow, initCol});
while (!queue.isEmpty()) {
int[] curr = queue.poll();
int r = curr[0];
int c = curr[1];
if (r < 0 || r >= n || c < 0 || c >= m) continue;
if (!field[r][c]) continue;
field[r][c] = false;
for (int dir = 0; dir < 4; dir++) {
queue.offer(new int[] {r + dr[dir], c + dc[dir]});
}
}
}
}