Problem:
Score : 400 points

Problem Statement

On a two-dimensional plane, there are N red points and N blue points.
The coordinates of the i-th red point are (a_i, b_i), and the coordinates of the i-th blue point are (c_i, d_i).

A red point and a blue point can form a friendly pair when, the x-coordinate of the red point is smaller than that of the blue point, and the y-coordinate of the red point is also smaller than that of the blue point.

At most how many friendly pairs can you form? Note that a point cannot belong to multiple pairs.

Constraints

All input values are integers.

1 \leq N \leq 100

0 \leq a_i, b_i, c_i, d_i < 2N

a_1, a_2, ..., a_N, c_1, c_2, ..., c_N are all different.

b_1, b_2, ..., b_N, d_1, d_2, ..., d_N are all different.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
a_2 b_2
:
a_N b_N
c_1 d_1
c_2 d_2
:
c_N d_N

Output

Print the maximum number of friendly pairs.

Sample Input 1

3
2 0
3 1
1 3
4 2
0 4
5 5

Sample Output 1

2

For example, you can pair (2, 0) and (4, 2), then (3, 1) and (5, 5).

Sample Input 2

3
0 0
1 1
5 2
2 3
3 4
4 5

Sample Output 2

2

For example, you can pair (0, 0) and (2, 3), then (1, 1) and (3, 4).

Sample Input 3

2
2 2
3 3
0 0
1 1

Sample Output 3

0

It is possible that no pair can be formed.

Sample Input 4

5
0 0
7 3
2 2
4 8
1 6
8 5
6 9
5 4
9 1
3 7

Sample Output 4

5

Sample Input 5

5
0 0
1 1
5 5
6 6
7 7
2 2
3 3
4 4
8 8
9 9

Sample Output 5

4

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.Scanner;
import java.util.SplittableRandom;

public class Main {
  static Scanner sc = new Scanner(System.in);
  static long[] buf = new long[200000];

  public static void main(String[] args) {
    SplittableRandom rnd = new SplittableRandom();

//    for (int turn = 0; turn < 1000000; turn++) {
//      int N = rnd.nextInt(10) + 1;
//      long[] A = new long[N];
//      long[] B = new long[N];
//      for (int i = 0; i < N; i++) {
//        A[i] = rnd.nextInt(1 << 28);
//        B[i] = rnd.nextInt(1 << 28);
//      }
//      long brute = 0;
//      for (int i = 0; i < N; i++) {
//        for (int j = 0; j < N; j++) {
//          brute ^= A[i] + B[j];
//        }
//      }
//      System.err.println("brute:" + brute);

    int N = sc.nextInt();
    long[] A = new long[N];
    long[] B = new long[N];
    for (int i = 0; i < N; i++) {
      A[i] = sc.nextInt();
    }
    for (int i = 0; i < N; i++) {
      B[i] = sc.nextInt();
    }

      int ans = 0;
      for (int i = 0; i < 30; i++) {
        int bb = 0;
        for (int j = 0; j < N; j++) {
          if ((B[j] & (1 << i)) != 0) ++bb;
        }
        int bbAll = bb;
        long mask = (1L << i) - 1;
        long count = 0;
        int bp = N;
        for (int j = 0; j < N; j++) {
          long av = A[j] & mask;
          while (bp > 0) {
            if ((av + (B[bp - 1] & mask)) <= mask) {
              break;
            }
            --bp;
            if ((B[bp] & (1 << i)) != 0) --bb;
          }
          if ((A[j] & (1 << i)) == 0) {
            // zero & carry or one & no carry
            count += bb;
            count += N - bp - (bbAll - bb);
          } else {
            // zero & no carry or one & carry
            count += bp - bb;
            count += bbAll - bb;
          }
        }
        if (count % 2 == 1) ans |= 1 << i;
        sort(A, i);
        sort(B, i);
      }
//      if (brute != ans) {
//        System.out.println(turn);
//        System.out.println(Arrays.toString(A));
//        System.out.println(Arrays.toString(B));
//        System.out.println(brute);
//        System.out.println(ans);
//        System.exit(0);
//      }
      System.out.println(ans);
//    }
  }

  static void sort(long[] a, int k) {
    int ap = 0;
    int bp = 0;
    long bit = 1L << k;
    for (int i = 0; i < a.length; i++) {
      if ((a[i] & bit) == 0) {
        a[ap++] = a[i];
      } else {
        buf[bp++] = a[i];
      }
    }
    for (int i = 0; i < bp; i++) {
      a[ap++] = buf[i];
    }
  }

}