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.*;
  import java.util.*;
  
  public class Training{
      //--------------------------INPUT READER--------------------------------//
      static class fs {
          public BufferedReader br;
          StringTokenizer st = new StringTokenizer("");
  
          public fs() { this(System.in); }
          public fs(InputStream is) {
              br = new BufferedReader(new InputStreamReader(is));
          }
          String next() {
              while (!st.hasMoreTokens()) {
                  try { st = new StringTokenizer(br.readLine()); }
                  catch (IOException e) { e.printStackTrace(); }
              }
              return st.nextToken();
          }
  
          int ni() { return Integer.parseInt(next()); }
          long nl() { return Long.parseLong(next()); }
          double nd() { return Double.parseDouble(next()); }
          String ns() { return next(); }
  
          int[] na(int n) {
              int[] a = new int[n];
              for (int i = 0; i < n; i++) a[i] = ni();
              return a;
          }
  
          long[] nal(int n) {
              long[] l = new long[n];
              for(int i = 0; i < n; i++) l[i] = nl();
              return l;
          }
      }
      //-----------------------------------------------------------------------//
  
      //---------------------------PRINTER-------------------------------------//
      static class Printer {
          static PrintWriter w;
          public Printer() {this(System.out);}
          public Printer(OutputStream os) {
              w = new PrintWriter(os);
          }
          public void p(int i) {w.println(i);};
          public void p(long l) {w.println(l);};
          public void p(double d) {w.println(d);};
          public void p(String s) { w.println(s);};
          public void pr(int i) {w.println(i);};
          public void pr(long l) {w.print(l);};
          public void pr(double d) {w.print(d);};
          public void pr(String s) { w.print(s);};
          public void pl() {w.println();};
          public void close() {w.close();};
      }
      //------------------------------------------------------------------------//
  
      //--------------------------VARIABLES------------------------------------//
      static fs sc = new fs();
      static OutputStream outputStream = System.out;
      static Printer w = new Printer(outputStream);
      //-----------------------------------------------------------------------//
  
      //--------------------------ADMIN_MODE-----------------------------------//
      private static void ADMIN_MODE() throws IOException {
          if (System.getProperty("ONLINE_JUDGE") == null) {
              w = new Printer(new FileOutputStream("output.txt"));
              sc = new fs(new FileInputStream("input.txt"));
          }
      }
      //-----------------------------------------------------------------------//
  
      //----------------------------START--------------------------------------//
      public static void main(String[] args)
              throws IOException {
  
          ADMIN_MODE();
  
  
          int t = sc.ni();while(t-->0) {
              ct++;
              solve();
          }
  
  
          w.close();
      }
  
      static int ct = 0;
  
      static int n;
  
      static void solve() throws IOException {
          n = sc.ni();
          List<pr> li = new ArrayList<>();
          HashMap<Integer, List<Integer>> rightNum = new HashMap<>();
          hm<Integer> hm = new hm<>();
          for(int i = 0; i < n; i++) {
              int a = sc.ni(), b = sc.ni();
              li.add(new pr(a, b));
          }
          for(int i = 0; i < n; i++) {
              int a = li.get(i).a, b = li.get(i).b;
              if(rightNum.containsKey(b)) {
                  rightNum.get(b).add(a);
              } else {
                  List<Integer> curr = new ArrayList<>();
                  curr.add(a);
                  rightNum.put(b, curr);
              }
  
              hm.add(a);
          }
  
          long ans = 0;
          for(int i: rightNum.keySet()) {
              List<Integer> curr = rightNum.get(i);
              if(curr.size() < 2) continue;
              for(int ii: curr) {
                  if(hm.c(ii)) {
                      ans += (hm.hm.get(ii)-1)*(curr.size()-1);
                  }
              }
          }
  
          long num = (long) n *(n-1)*(n-2);
          num/=6;
          w.p(num-ans);
      }
  
      static class pr implements Comparable<pr>{
          int a, b;
  
          public pr(int a, int b) {
              this.a = a;
              this.b = b;
          }
  
          public int compareTo(pr p) {
              if(a==p.a && b==p.b) return 0;
              else return Integer.compare(a, p.a);
          }
      }
  
      static class hm <T extends Comparable<T>>{
          HashMap<T, Long> hm = new HashMap<>();
          long uniqueSz = 0;
          long sz = 0;
          public boolean c(T elem) {return hm.containsKey(elem);}
          public void rep(T elem, long i) {hm.replace(elem, hm.get(elem)+i);}
          public void add(T elem) {
              if(c(elem))rep(elem, 1L);
              else { hm.put(elem, 1L); uniqueSz++; }
              sz++;
          }
          public void del(T elem) {
              if(c(elem)) rep(elem, -1L);
              if(hm.get(elem)==0L) { hm.remove(elem); uniqueSz--; }
              sz--;
          }
          public Set<T> ks() { return hm.keySet();}
          public Collection<Long> val() {return hm.values();}
      }
  }