description: Monocarp is the coach of the Berland State University programming teams. He decided to compose a problemset for a training session for his teams.
  
  Monocarp has n problems that none of his students have seen yet. The i-th problem has a topic a_i (an integer from 1 to n) and a difficulty b_i (an integer from 1 to n). All problems are different, that is, there are no two tasks that have the same topic and difficulty at the same time.
  
  Monocarp decided to select exactly 3 problems from n problems for the problemset. The problems should satisfy at least one of two conditions (possibly, both):
  
    * the topics of all three selected problems are different; 
    * the difficulties of all three selected problems are different. 
  
  
  
  Your task is to determine the number of ways to select three problems for the problemset.
  
  Input
  
  The first line contains a single integer t (1 ≤ t ≤ 50000) — the number of testcases.
  
  The first line of each testcase contains an integer n (3 ≤ n ≤ 2 ⋅ 10^5) — the number of problems that Monocarp have.
  
  In the i-th of the following n lines, there are two integers a_i and b_i (1 ≤ a_i, b_i ≤ n) — the topic and the difficulty of the i-th problem.
  
  It is guaranteed that there are no two problems that have the same topic and difficulty at the same time.
  
  The sum of n over all testcases doesn't exceed 2 ⋅ 10^5.
  
  Output
  
  Print the number of ways to select three training problems that meet either of the requirements described in the statement.
  
  Example
  
  Input
  
  
  2
  4
  2 4
  3 4
  2 1
  1 3
  5
  1 5
  2 4
  3 3
  4 2
  5 1
  
  
  Output
  
  
  3
  10
  
  Note
  
  In the first example, you can take the following sets of three problems:
  
    * problems 1, 2, 4; 
    * problems 1, 3, 4; 
    * problems 2, 3, 4. 
  
  
  
  Thus, the number of ways is equal to three.
solution: import java.io.BufferedReader;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.util.*;
  import java.util.concurrent.LinkedBlockingDeque;
  
  import javax.print.attribute.HashAttributeSet;
  import javax.swing.JLabel;
  
  import java.io.PrintStream;
              
                  public class Solution {
  
                      public static boolean Local(){
                          try{ 
                              return System.getenv("LOCAL_SYS")!=null;
                          }catch(Exception e){
                              return false;
                          }
                      }   
  
                      public static boolean LOCAL;
  
                      static class FastScanner {
  
                              BufferedReader br;
                              StringTokenizer st ;
  
                              FastScanner(){
                                  br =  new BufferedReader(new InputStreamReader(System.in));
                                  st = new StringTokenizer("");
                              }
  
                              FastScanner(String file) {
  
                                  try{
                                      br =  new BufferedReader(new InputStreamReader(new FileInputStream(file)));
                                      st = new StringTokenizer("");
                                  }catch(FileNotFoundException e) {
                                      // TODO Auto-generated catch block
                                      System.out.println("file not found");
                                      e.printStackTrace();
                                  }
                                  
                              }
                              
  
                              String next() {
                                  while (!st.hasMoreTokens())
                                      try {
                                          st = new StringTokenizer(br.readLine());
                                      } catch (IOException e) {
                                      }
                                  return st.nextToken();
                              }
  
                              int nextInt() {
                                  return Integer.parseInt(next());
                              }
  
                              long nextLong() {
                                  return Long.parseLong(next());
                              }
                              String readLine() throws IOException{
                                  return br.readLine();
                              }
                          }
                                              
                      static class Pair<T,X> {
  
                          T first;
                          X second;
                          
                          Pair(T first,X second){
                              this.first = first;
                              this.second = second;
                          }
  
                          @Override
                          public int hashCode(){
                              return Objects.hash(first,second);
                          }
  
                          @Override
                          public boolean equals(Object obj){
                              return obj.hashCode() == this.hashCode();
                          }
  
                      }
  
                  
                  static PrintStream debug = null;
  
                  static long mod = (long)(Math.pow(10,9) + 7); 
                  
  
                  public static void main(String[] args) throws Exception {
                      
                      FastScanner s = new FastScanner();
  
                      LOCAL = Local();
  
                      
                      if(LOCAL){
                          s = new FastScanner("src/input.txt");
                          PrintStream o = new PrintStream("src/sampleout.txt");
                          debug = new PrintStream("src/debug.txt");
                          System.setOut(o);
                      }
  
                      long mod = 1000000007;
                      
                      int tcr =  s.nextInt();     
                  
                      StringBuilder sb = new StringBuilder();
  
                      int dx[] = {0,0,-1,1,1,-1,1,-1};
                      int dy[] = {-1,1,0,0,1,1,-1,-1};
                      
                  
                      for(int tc=0;tc<tcr;tc++){
  
                          int n = s.nextInt();
  
                          Map<Integer,Integer> topic = new HashMap<>();
                          Map<Integer,Integer> diff = new HashMap<>();
                          int arr[][] = new int[n][2];
                          for(int i=0;i<n;i++){
                              int tp = s.nextInt();
                              int dif = s.nextInt();
                              arr[i][0] = tp;
                              arr[i][1] = dif;
                              topic.put(tp,topic.getOrDefault(tp,0) + 1);
                              diff.put(dif,diff.getOrDefault(dif,0) + 1);
                          }
                          long ans = 0;
                          for(int i=0;i<n;i++){
                              ans -= (topic.get(arr[i][0]) - 1)*1l*(diff.get(arr[i][1]) - 1);
                          }
                          ans += ((n*1l*(n-1)*1l*(n-2))/6);
  
                          sb.append(ans+"\n");
  
                      }
  
  
                      print(sb.toString());
                  }
  
                  static long getPairsCount(int n, long sum,long arr[])
                  {
                      HashMap<Long, Integer> hm = new HashMap<>();
               
                  
                      for (int i = 0; i < n; i++) {
                       
                          if (!hm.containsKey(arr[i])){
                              hm.put(arr[i], 0);
                           }
               
                          hm.put(arr[i], hm.get(arr[i]) + 1);
                      }
                      long twice_count = 0;
                      for (int i = 0; i < n; i++) {
                          if (hm.get(sum - arr[i]) != null){
                              twice_count += hm.get(sum - arr[i]);
                          }
               
                       
                          if (sum - arr[i] == arr[i]){
                              twice_count--;
                          }
                      }
               
                      // return the half of twice_count
                      return twice_count / 2l;
                  }
                  public static long ncr(int n,int r,long fact[]){
                      if(r==0){return 1l;}
                      long ans = fact[n];
                      long denom = mulmod(fact[r], fact[n-r], mod);
                      ans = mulmod(ans,modpow(denom,mod-2, mod),mod);
                      return ans;
                  }
  
                  public static List<long[]> prime_factors(long n){
              
                      List<long[]> list = new ArrayList<>();
                      
                      for(long i=2;i<=(Math.sqrt(n));i++){
              
                          if(n % i == 0){
                              
                              int cnt = 0;
                              
                              while( (n % i) == 0){
                                  n = n/i;
                                  cnt++;
                                  
                              }
              
                              list.add(new long[]{i,cnt});
                          }
                      }
  
              
                      if(n!=1){
                          list.add(new long[]{n,1l});
                      }
              
                      return list;
              
                  }
  
                  public static boolean check(int arr[]){
                      for(int i=1;i<arr.length;i++){
                          if(arr[i] < arr[i-1]){
                              return false;
                          }
                      }
                      return true;
                  }
  
              
                  public static boolean inRange(int r1,int r2,int val){
                      return ((val >= r1) && (val <= r2));
                  }
  
                  static int len(long num){
                      return Long.toString(num).length();
                  }
  
                  static long mulmod(long a, long b,long mod)
                  {
                      long ans = 0l;
                      
                      while(b > 0l){
                          long curr = (b & 1l);
                          if(curr == 1l){
                              ans = ((ans % mod) + a) % mod;
                          }
                          
                          a = (a + a) % mod;
  
                          b = b >> 1;
                      }
  
                      return ans;
                  }
  
  
                  public static void dbg(PrintStream ps,Object... o) throws Exception{
                      if(ps == null){
                          return;
                      }
                      Debug.dbg(ps,o);
                  }
  
                  public static long modpow(long num,long pow,long mod){
  
                      long val = num;
                      long ans = 1l;
  
                      while(pow > 0l){
                          
                          long bit = pow & 1l;
  
                          if(bit == 1){
                              ans = (ans * (val%mod))%mod;
                          }
  
                          val = (val * val) % mod;
                          pow = pow >> 1;
                      }
  
                      return ans;
  
                  }
  
                  public static char get(int n){
                      return (char)('a' + n);
                  }
  
                  public static long[] sort(long arr[]){
                      List<Long> list = new ArrayList<>();
                      for(long n : arr){list.add(n);}
                      Collections.sort(list);
                      for(int i=0;i<arr.length;i++){
                          arr[i] = list.get(i);
                      }
                      return arr;
                  }
  
                  public static int[] sort(int arr[]){
                      List<Integer> list = new ArrayList<>();
                      for(int n : arr){list.add(n);}
                      Collections.sort(list);
                      for(int i=0;i<arr.length;i++){
                          arr[i] = list.get(i);
                      }
                      return arr;
                  }
  
                  // return the (index + 1)
                  // where index is the pos of just smaller element
                  // i.e count of elemets strictly less than num
                  public static int justSmaller(long arr[],long num){
                      //  System.out.println(num+"@");
                      int st = 0;
                      int e = arr.length - 1;
              
                      int ans = -1;
              
                      while(st <= e){
              
                          int mid = (st + e)/2;
              
                          if(arr[mid] >= num){
                              e = mid - 1;
                          }else{
                              ans = mid;
                              st = mid + 1;
                          }
              
                      }
              
              
                      return ans + 1;
              
                  }
                  public static int justSmaller(int arr[],int num){
                      //  System.out.println(num+"@");
                      int st = 0;
                      int e = arr.length - 1;
              
                      int ans = -1;
              
                      while(st <= e){
              
                          int mid = (st + e)/2;
              
                          if(arr[mid] >= num){
                              e = mid - 1;
                          }else{
                              ans = mid;
                              st = mid + 1;
                          }
              
                      }
              
              
                      return ans + 1;
              
                  }
                  
                  //return (index of just greater element)
                  //count of elements smaller than or equal to num
  
                  public static int justGreater(long arr[],long num){
                      int st = 0;
                      int e = arr.length - 1;
              
                      int ans = arr.length;
              
                      while(st <= e){
                          
                          int mid = (st + e)/2;
              
                          if(arr[mid] <= num){
                              st = mid + 1;
                          }else{
                              ans = mid;
                              e = mid - 1;
                          }
                      }
              
                      return ans;
              
                  }
  
                  public static int justGreater(int arr[],int num){
                      int st = 0;
                      int e = arr.length - 1;
              
                      int ans = arr.length;
              
                      while(st <= e){
                          
                          int mid = (st + e)/2;
              
                          if(arr[mid] <= num){
                              st = mid + 1;
                          }else{
                              ans = mid;
                              e = mid - 1;
                          }
                      }
              
                      return ans;
              
                  }
              
                  
  
                  public static void println(Object obj){
                      System.out.println(obj.toString());
                  }
  
                  public static void print(Object obj){
                      System.out.print(obj.toString());
                  }
  
                  public static int gcd(int a,int b){
                      if(b == 0){return a;}
                      return gcd(b,a%b);
                  }
  
                  public static long gcd(long a,long b){
                      if(b == 0l){
                          return a;
                      }
  
                      return gcd(b,a%b);
                  }
  
                  public static int find(int parent[],int v){
                      if(parent[v] == v){
                          return v;
                      }
                      
                      return parent[v] = find(parent, parent[v]);
                  }
  
              
  
                  public static List<Integer> sieve(){
                  
                          List<Integer> prime = new ArrayList<>();
  
                          int arr[] = new int[300001];
  
                      Arrays.fill(arr,1);
  
                      arr[1] = 0;
                      arr[2] = 1;
  
                      for(int i=2;i<300001;i++){
                          
                          if(arr[i] == 1){
                              
                              prime.add(i);
  
                              for(long j = (i*1l*i);j<300001;j+=i){
                                  arr[(int)j] = 0;
                              }
                          }
                      }
  
                      return prime;
                  }
  
                  static boolean isPower(long n,long a){
                      
                      long log = (long)(Math.log(n)/Math.log(a));
  
                      long power = (long)Math.pow(a,log);
  
                      if(power == n){return true;}
  
                      return false;
                  }
  
  
                  private static int mergeAndCount(int[] arr, int l,int m, int r)
                  {
  
                      // Left subarray
                      int[] left =  Arrays.copyOfRange(arr, l, m + 1);
  
                      // Right subarray
                      int[] right = Arrays.copyOfRange(arr, m + 1, r + 1);
  
                      int i = 0, j = 0, k = l, swaps = 0;
  
                      while (i < left.length && j < right.length) {
                          if (left[i] <= right[j])
                              arr[k++] = left[i++];
                          else {
                              arr[k++] = right[j++];
                              swaps += (m + 1) - (l + i);
                          }
                      }
                      while (i < left.length)
                          arr[k++] = left[i++];
                      while (j < right.length)
                          arr[k++] = right[j++];
                      return swaps;
                  }
  
                  // Merge sort function
                  private static int mergeSortAndCount(int[] arr, int l,int r)
                  {
  
                      // Keeps track of the inversion count at a
                      // particular node of the recursion tree
                      int count = 0;
  
                      if (l < r) {
                          int m = (l + r) / 2;
  
                          // Total inversion count = left subarray count
                          // + right subarray count + merge count
  
                          // Left subarray count
                          count += mergeSortAndCount(arr, l, m);
  
                          // Right subarray count
                          count += mergeSortAndCount(arr, m + 1, r);
  
                          // Merge count
                          count += mergeAndCount(arr, l, m, r);
                      }
  
                      return count;
                  }
  
                  static class Debug{
                      //change to System.getProperty("ONLINE_JUDGE")==null; for CodeForces
                      public static final boolean LOCAL = System.getProperty("ONLINE_JUDGE")==null;
  
                      
  
                      private static <T> String ts(T t) {
                          if(t==null) {
                              return "null";
                          }
                          try {
                              return ts((Iterable) t);
                          }catch(ClassCastException e) {
                              if(t instanceof int[]) {
                                  String s = Arrays.toString((int[]) t);
                                  return "{"+s.substring(1, s.length()-1)+"}\n";
                              }else if(t instanceof long[]) {
                                  String s = Arrays.toString((long[]) t);
                                  return "{"+s.substring(1, s.length()-1)+"}\n";
                              }else if(t instanceof char[]) {
                                  String s = Arrays.toString((char[]) t);
                                  return "{"+s.substring(1, s.length()-1)+"}\n";
                              }else if(t instanceof double[]) {
                                  String s = Arrays.toString((double[]) t);
                                  return "{"+s.substring(1, s.length()-1)+"}\n";
                              }else if(t instanceof boolean[]) {
                                  String s = Arrays.toString((boolean[]) t);
                                  return "{"+s.substring(1, s.length()-1)+"}\n";
                              }
                              try {
                                  return ts((Object[]) t);
                              }catch(ClassCastException e1) {
                                  return t.toString();
                              }
                          }
                      }
                      private static <T> String ts(T[] arr) {
                          StringBuilder ret = new StringBuilder();
                          ret.append("{");
                          boolean first = true;
                          for(T t: arr) {
                              if(!first) {
                                  ret.append(", ");
                              }
                              first = false;
                              ret.append(ts(t));
                          }
                          ret.append("}");
                          return ret.toString();
                      }
                      private static <T> String ts(Iterable<T> iter) {
                          StringBuilder ret = new StringBuilder();
                          ret.append("{");
                          boolean first = true;
                          for(T t: iter) {
                              if(!first) {
                                  ret.append(", ");
                              }
                              first = false;
                              ret.append(ts(t));
                          }
                          ret.append("}");
                          return ret.toString();
                      }
                      public static void dbg(PrintStream ps,Object... o) throws Exception {
                          if(LOCAL) {
                              System.setErr(ps);
                              System.err.print("Line #"+Thread.currentThread().getStackTrace()[2].getLineNumber()+": [");
                              for(int i = 0; i<o.length; i++) {
                                  if(i!=0) {
                                      System.err.print(", ");
                                  }
                                  System.err.print(ts(o[i]));
                              }
                              System.err.println("]");
                          }
                      }
                  }
  
          }
  
  
          