import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;

import static java.util.Comparator.comparingInt;

public class B_Rising {

    public static void main(String[] args) throws IOException {
        MyScanner in = new MyScanner();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

        int n = in.nextInt();

        int[] mins = new int[n];
        int[] maxs = new int[n];
        int haveNotRising = 0;

        for (int i = 0; i < n; i++) {
            int m = in.nextInt();
            boolean isHasNotRising = true;
            int min = in.nextInt();
            int max = min;
            int j = 1;

            for (; j < m; j++) {
                int x = in.nextInt();
                if (x < min) {
                    min = x;
                } else if (x != min) {
                    isHasNotRising = false;
                    in.skipOtherElementsInLine();
                    break;
                }
            }

            if (isHasNotRising) {
                mins[haveNotRising] = min;
                maxs[haveNotRising] = max;
                haveNotRising++;
            }
        }

        mins = Arrays.copyOfRange(mins, 0, haveNotRising + 1);
        mins[haveNotRising] = Integer.MAX_VALUE;
        maxs = Arrays.copyOfRange(maxs, 0, haveNotRising);
        Arrays.sort(mins);
        Arrays.sort(maxs);

        long result = f(mins, maxs);

        long haveRising = n - haveNotRising;
        out.println(result + haveRising * haveRising + haveRising * haveNotRising * 2);

        out.close();
    }

    private static long f(int[] mins, int[] maxs) {
        long result = 0;
        int j = 0;
        for (int max : maxs) {
            while (/*j < mins.length && */mins[j] < max) {
                j++;
            }
            result += j;
        }
        return result;
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreElements()) {
                st = new StringTokenizer(br.readLine());
            }
            return st.nextToken();
        }

        void skipOtherElementsInLine() throws IOException {
            st = null;
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }
    }
}


import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;

import static java.util.Comparator.comparingInt;

public class B_Rising {

    public static void main(String[] args) throws IOException {
        MyScanner in = new MyScanner();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

        int n = in.nextInt();

        int[][] s = new int[n][2];
        int haveNotRising = 0;

        for (int i = 0; i < n; i++) {
            int m = in.nextInt();
            boolean isHasNotRising = true;
            int min = in.nextInt();
            int max = min;
            int j = 1;

            for (; j < m; j++) {
                int x = in.nextInt();
                if (x < min) {
                    min = x;
                } else if (x != min) {
                    isHasNotRising = false;
                    in.skipOtherElementsInLine();
                    break;
                }
            }

            if (isHasNotRising) {
                s[haveNotRising][0] = min;
                s[haveNotRising][1] = max;
                haveNotRising++;
            }
        }

        s = Arrays.copyOfRange(s, 0, haveNotRising);
        Arrays.sort(s, comparingInt(i -> i[0]));

        long result = 0;
        for (int i = 0; i < haveNotRising; i++) {
            for (int j = 0; j < haveNotRising; j++) {
                if (s[i][1] <= s[j][0]) {
                    break;
                }
                result++;
            }
        }

        long haveRising = n - haveNotRising;
        out.println(result + haveRising * haveRising + haveRising * haveNotRising * 2);

        out.close();
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreElements()) {
                st = new StringTokenizer(br.readLine());
            }
            return st.nextToken();
        }

        void skipOtherElementsInLine() throws IOException {
            st = null;
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }
    }
}


import java.io.*;
import java.util.StringTokenizer;

public class B_Rising {

    public static void main(String[] args) throws IOException {
        MyScanner in = new MyScanner();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

        int n = in.nextInt();

        int[][] s = new int[n][2];
        long haveNotRising = 0;

        for (int i = 0; i < n; i++) {
            int m = in.nextInt();
            boolean isHasNotRising = true;
            int min = in.nextInt();
            int max = min;
            int j = 1;

            for (; j < m; j++) {
                int x = in.nextInt();
                if (x < min) {
                    min = x;
                } else if (x != min) {
                    isHasNotRising = false;
                    in.skipOtherElementsInLine();
                    break;
                }
            }

            if (isHasNotRising) {
                s[haveNotRising][0] = min;
                s[haveNotRising][1] = max;
                haveNotRising++;
            }
        }

        long result = 0;
        for (int i = 0; i < haveNotRising; i++) {
            if (s[i][0] < s[i][1]) {
                result++;
            }
            for (int j = i + 1; j < haveNotRising; j++) {
                if (s[i][0] < s[j][1]) {
                    result++;
                }
                if (s[j][0] < s[i][1]) {
                    result++;
                }
            }
        }

        long haveRising = n - haveNotRising;
        out.println(result + haveRising * haveRising + haveRising * haveNotRising * 2);

        out.close();
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreElements()) {
                st = new StringTokenizer(br.readLine());
            }
            return st.nextToken();
        }

        void skipOtherElementsInLine() throws IOException {
            st = null;
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class B {

    private static BufferedReader br;
    private static StringTokenizer tokenizer;

    static class Data {
        boolean isOk;
        int min;
        int max;
        Data(boolean isOk, int min, int max) {
            this.isOk = isOk;
            this.min = min;
            this.max = max;
        }
    }

    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        int n = nextInt();
        Data[] datas = new Data[n];
        for (int i = 0; i < n; i++) {
            int len = nextInt();
            int min = Integer.MAX_VALUE;
            int max = Integer.MIN_VALUE;
            int[] arr = new int[len];
            for (int j = 0; j < len; j++) {
                arr[j] = nextInt();
            }

            boolean isOk = false;
            for (int j = 0; j < len; j++) {
                int num = arr[j];
                min = Math.min(min, num);
                max = Math.max(max, num);
                if (j > 0 && arr[j] > arr[j-1]) {
                    isOk = true;
                }
            }

            datas[i] = new Data(isOk, min, max);
        }

        long ans = 0;
        List<Integer> minList = new ArrayList<>();
        List<Integer> maxList = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            if (datas[i].isOk) {
                continue;
            }

            minList.add(datas[i].min);
            maxList.add(datas[i].max);
        }

        Collections.sort(minList);
        Collections.sort(maxList);

        int okCount = 0;
        int tmpSum = 0;
        for (int i = 0; i < n; i++) {
            if (datas[i].isOk) {
                ans += 2 * n - 1;
                okCount++;
                ans -= 2 * (okCount - 1);
            } else {
//                if (datas[i].min != datas[i].max) {
//                    ans--;
//                }

                int lastSmallerIndex = findSmaller(minList, datas[i].max);
                if (lastSmallerIndex != -1) {
                    tmpSum += lastSmallerIndex + 1;
                }

                int firstBiggerIndex = findBigger(maxList, datas[i].min);
                if (firstBiggerIndex != -1) {
                    tmpSum += maxList.size() - firstBiggerIndex;
                }

            }
        }

        System.out.println(ans + tmpSum / 2);
    }

    private static int findBigger(List<Integer> maxList, int target) {
        int size = maxList.size();
        int low = 0;
        int high = size - 1;
        while (low <= high) {
            int mid = (low +high) >>> 1;
            int midVal = maxList.get(mid);
            if (midVal > target) {
                if (mid == 0 || maxList.get(mid - 1) <= target) {
                    return mid;
                }

                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }

        return -1;
    }

    private static int findSmaller(List<Integer> minList, int target) {
        int size = minList.size();
        int low = 0;
        int high = size - 1;
        while (low <= high) {
            int mid = (low +high) >>> 1;
            int midVal = minList.get(mid);
            if (midVal < target) {
                if (mid == size - 1 || minList.get(mid + 1) >= target) {
                    return mid;
                }

                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }

        return -1;
    }

    public static String next() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            String line = br.readLine();
            if (line == null)
                throw new IOException();
            tokenizer = new StringTokenizer(line);
        }
        return tokenizer.nextToken();
    }

    public static int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    public static long nextLong() throws IOException {
        return Long.parseLong(next());
    }

    public static double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class B {

    private static BufferedReader br;
    private static StringTokenizer tokenizer;

    static class Data {
        boolean isOk;
        int min;
        int max;
        Data(boolean isOk, int min, int max) {
            this.isOk = isOk;
            this.min = min;
            this.max = max;
        }
    }

    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        int n = nextInt();
        Data[] datas = new Data[n];
        for (int i = 0; i < n; i++) {
            int len = nextInt();
            int min = Integer.MAX_VALUE;
            int max = Integer.MIN_VALUE;
            int[] arr = new int[len];
            for (int j = 0; j < len; j++) {
                arr[j] = nextInt();
            }

            boolean isOk = false;
            for (int j = 0; j < len; j++) {
                int num = arr[j];
                min = Math.min(min, num);
                max = Math.max(max, num);
                if (j > 0 && arr[j] > arr[j-1]) {
                    isOk = true;
                }
            }

            datas[i] = new Data(isOk, min, max);
        }

        long ans = 0;
        List<Integer> minList = new ArrayList<>();
        List<Integer> maxList = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            if (datas[i].isOk) {
                continue;
            }

            minList.add(datas[i].min);
            maxList.add(datas[i].max);
        }

        Collections.sort(minList);
        Collections.sort(maxList);

        int okCount = 0;
        long tmpSum = 0;
        for (int i = 0; i < n; i++) {
            if (datas[i].isOk) {
                ans += 2 * n - 1;
                okCount++;
                ans -= 2 * (okCount - 1);
            } else {
//                if (datas[i].min != datas[i].max) {
//                    ans--;
//                }

                int lastSmallerIndex = findSmaller(minList, datas[i].max);
                if (lastSmallerIndex != -1) {
                    tmpSum += lastSmallerIndex + 1;
                }

                int firstBiggerIndex = findBigger(maxList, datas[i].min);
                if (firstBiggerIndex != -1) {
                    tmpSum += maxList.size() - firstBiggerIndex;
                }

            }
        }

        System.out.println(ans + tmpSum / 2);
    }

    private static int findBigger(List<Integer> maxList, int target) {
        int size = maxList.size();
        int low = 0;
        int high = size - 1;
        while (low <= high) {
            int mid = (low +high) >>> 1;
            int midVal = maxList.get(mid);
            if (midVal > target) {
                if (mid == 0 || maxList.get(mid - 1) <= target) {
                    return mid;
                }

                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }

        return -1;
    }

    private static int findSmaller(List<Integer> minList, int target) {
        int size = minList.size();
        int low = 0;
        int high = size - 1;
        while (low <= high) {
            int mid = (low +high) >>> 1;
            int midVal = minList.get(mid);
            if (midVal < target) {
                if (mid == size - 1 || minList.get(mid + 1) >= target) {
                    return mid;
                }

                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }

        return -1;
    }

    public static String next() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            String line = br.readLine();
            if (line == null)
                throw new IOException();
            tokenizer = new StringTokenizer(line);
        }
        return tokenizer.nextToken();
    }

    public static int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    public static long nextLong() throws IOException {
        return Long.parseLong(next());
    }

    public static double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

//Mann Shah [ DAIICT ].
//fast io

public class Main {
	public static int mod = (int) (1e9 + 7);
	public static long inf = (long) 1e15 + 42;
	static InputReader in;
	static PrintWriter out;

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

	public static void main(String args[]) {

		in = new InputReader(System.in);
		out = new PrintWriter(System.out);

		int n = in.nextInt();
		int[] l = new int[n];
		ArrayList<ArrayList<Integer>> s = new ArrayList();
		for(int i=0;i<n;i++) {
			l[i]=in.nextInt();
			ArrayList<Integer> ss = new ArrayList();
			for(int j=0;j<l[i];j++) {
				ss.add(in.nextInt());
			}
			s.add(ss);
		}

		ArrayList<Integer> mx = new ArrayList();
		ArrayList<Integer> mn = new ArrayList();
		long count=0;
		for(int i=0;i<n;i++) {
			int f=0;
			int min =s.get(i).get(0);
			for(int j=1;j<l[i];j++) {
				//chk flag
				if(s.get(i).get(j) > min) {
					f=1;
					break;
				}
				if(s.get(i).get(j) < min) {
					min = s.get(i).get(j);
				}
			}

			if(f==0) {
				mx.add(0);
				mn.add(Integer.MAX_VALUE);
				for(int j=0;j<l[i];j++) {
					if(s.get(i).get(j) > mx.get(mx.size()-1) ) {
						mx.set(mx.size()-1,s.get(i).get(j));
					}
					if(s.get(i).get(j) < mn.get(mn.size()-1)) {
						mn.set(mn.size()-1,s.get(i).get(j));
					}
				}
			}
			else {
				count++;
			}
		}

		int[] pmx = new int[1000005];
		for(int i=0;i<mx.size();i++) {
			pmx[mx.get(i)]++;
		}

		pmx[0] = Math.max(0,mx.size() - pmx[0]);
		for(int i=1;i<1000005;i++) {
			pmx[i] =  Math.max(0,pmx[i-1] - pmx[i]);
		}

		long sum =0;
		for(int i=0;i<mx.size();i++) {
			sum = sum + pmx[mn.get(i)];
		}

		out.println(sum + (long)(((2*n)-count)*count));

		out.close();
	}

	/* TC space

	 */

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int snext() {
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n) {
			int a[] = new int[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n) {
			long a[] = new long[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextLong();
			}
			return a;
		}

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}

	}

}

// For Pair sorting

// Arrays.sort(arr,new Comparator<Pair>() {
// @Override public int compare(Pair p1, Pair p2)
// {
// return p1.x - p2.x;
// }
// });

class Pair {
	int x;
	int y;

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

	@Override
	public boolean equals(Object o) {
		Pair p =(Pair)o;
		return (x==p.x && y==p.y);
	}
}

class x{
	//declare variables
	int abc;

	//constructor
	public x(int abc) {
		this.abc = abc;
	}

}

class couple implements Comparable<couple> {
	int x, y;

	public couple(int m, int f) {
		x = m;
		y = f;
	}

	public int compareTo(couple o) {

		return x - o.x;
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

//Mann Shah [ DAIICT ].
//fast io

public class Main {
	public static int mod = (int) (1e9 + 7);
	public static long inf = (long) 1e15 + 42;
	static InputReader in;
	static PrintWriter out;

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

	public static void main(String args[]) {

		in = new InputReader(System.in);
		out = new PrintWriter(System.out);

		int n = in.nextInt();
		int[] l = new int[n];
		ArrayList<ArrayList<Integer>> s = new ArrayList();
		for(int i=0;i<n;i++) {
			l[i]=in.nextInt();
			ArrayList<Integer> ss = new ArrayList();
			for(int j=0;j<l[i];j++) {
				ss.add(in.nextInt());
			}
			s.add(ss);
		}

		int[] mx = new int[n];
		int[] mn = new int[n];
		int a=0;
		Arrays.fill(mn,Integer.MAX_VALUE);
		int count=0;
		for(int i=0;i<n;i++) {
			int f=0;
			int min =s.get(i).get(0);
			for(int j=1;j<l[i];j++) {

				//chk flag
				if(s.get(i).get(j) > min) {
					f=1;
					break;
				}
				if(s.get(i).get(j) < min) {
					min = s.get(i).get(j);
				}
			}

			if(f==0) {
				for(int j=0;j<l[i];j++) {
					if(s.get(i).get(j) > mx[a] ) {
						mx[a]  = s.get(i).get(j);
					}
					if(s.get(i).get(j) < mn[a]) {
						mn[a] = s.get(i).get(j);
					}
				}
				a++;
			}
			else {
				count++;
			}
		}

		int[] pmx = new int[1000005];
		for(int i=0;i<a;i++) {
			pmx[mx[i]]++;
		}

		pmx[0] = a - pmx[0];

		for(int i=1;i<1000005;i++) {
			pmx[i] =  Math.max(0,pmx[i-1] - pmx[i]);
		}

		long sum =0;
		for(int i=0;i<a;i++) {
			sum += pmx[mn[i]];
		}

		out.println(sum + (((2*n)-count)*count));

		out.close();
	}

	/* TC space

	 */

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int snext() {
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n) {
			int a[] = new int[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n) {
			long a[] = new long[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextLong();
			}
			return a;
		}

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}

	}

}

// For Pair sorting

// Arrays.sort(arr,new Comparator<Pair>() {
// @Override public int compare(Pair p1, Pair p2)
// {
// return p1.x - p2.x;
// }
// });

class Pair {
	int x;
	int y;

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

	@Override
	public boolean equals(Object o) {
		Pair p =(Pair)o;
		return (x==p.x && y==p.y);
	}
}

class x{
	//declare variables
	int abc;

	//constructor
	public x(int abc) {
		this.abc = abc;
	}

}

class couple implements Comparable<couple> {
	int x, y;

	public couple(int m, int f) {
		x = m;
		y = f;
	}

	public int compareTo(couple o) {

		return x - o.x;
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

//Mann Shah [ DAIICT ].
//fast io

public class Main {
	public static int mod = (int) (1e9 + 7);
	public static long inf = (long) 1e15 + 42;
	static InputReader in;
	static PrintWriter out;

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

	public static void main(String args[]) {

		in = new InputReader(System.in);
		out = new PrintWriter(System.out);

		int n = in.nextInt();
		int[] l = new int[n];
		ArrayList<ArrayList<Integer>> s = new ArrayList();
		for(int i=0;i<n;i++) {
			l[i]=in.nextInt();
			ArrayList<Integer> ss = new ArrayList();
			for(int j=0;j<l[i];j++) {
				ss.add(in.nextInt());
			}
			s.add(ss);
		}

		ArrayList<Integer> mx = new ArrayList();
		ArrayList<Integer> mn = new ArrayList();
		int count=0;
		for(int i=0;i<n;i++) {
			int f=0;
			int min =s.get(i).get(0);
			for(int j=1;j<l[i];j++) {
				//chk flag
				if(s.get(i).get(j) > min) {
					f=1;
					break;
				}
				if(s.get(i).get(j) < min) {
					min = s.get(i).get(j);
				}
			}

			if(f==0) {
				mx.add(0);
				mn.add(Integer.MAX_VALUE);
				for(int j=0;j<l[i];j++) {
					if(s.get(i).get(j) > mx.get(mx.size()-1) ) {
						mx.set(mx.size()-1,s.get(i).get(j));
					}
					if(s.get(i).get(j) < mn.get(mn.size()-1)) {
						mn.set(mn.size()-1,s.get(i).get(j));
					}
				}
			}
			else {
				count++;
			}
		}

		int[] pmx = new int[1000005];
		for(int i=0;i<mx.size();i++) {
			pmx[mx.get(i)]++;
		}

		pmx[0] = Math.max(0,mx.size() - pmx[0]);
		for(int i=1;i<1000005;i++) {
			pmx[i] =  Math.max(0,pmx[i-1] - pmx[i]);
		}

		long sum =0;
		for(int i=0;i<mx.size();i++) {
			sum = sum + pmx[mn.get(i)];
		}

		out.println(sum + (((2*n)-count)*count));

		out.close();
	}

	/* TC space

	 */

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int snext() {
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n) {
			int a[] = new int[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n) {
			long a[] = new long[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextLong();
			}
			return a;
		}

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}

	}

}

// For Pair sorting

// Arrays.sort(arr,new Comparator<Pair>() {
// @Override public int compare(Pair p1, Pair p2)
// {
// return p1.x - p2.x;
// }
// });

class Pair {
	int x;
	int y;

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

	@Override
	public boolean equals(Object o) {
		Pair p =(Pair)o;
		return (x==p.x && y==p.y);
	}
}

class x{
	//declare variables
	int abc;

	//constructor
	public x(int abc) {
		this.abc = abc;
	}

}

class couple implements Comparable<couple> {
	int x, y;

	public couple(int m, int f) {
		x = m;
		y = f;
	}

	public int compareTo(couple o) {

		return x - o.x;
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

//Mann Shah [ DAIICT ].
//fast io

public class Main {
	public static int mod = (int) (1e9 + 7);
	public static long inf = (long) 1e15 + 42;
	static InputReader in;
	static PrintWriter out;

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

	public static void main(String args[]) {

		in = new InputReader(System.in);
		out = new PrintWriter(System.out);

		int n = in.nextInt();
		int[] l = new int[n];
		ArrayList<ArrayList<Integer>> s = new ArrayList();
		for(int i=0;i<n;i++) {
			l[i]=in.nextInt();
			ArrayList<Integer> ss = new ArrayList();
			for(int j=0;j<l[i];j++) {
				ss.add(in.nextInt());
			}
			s.add(ss);
		}

		int[] mx = new int[n];
		int[] mn= new int[n];
		int a=0,b=0;
		Arrays.fill(mn,Integer.MAX_VALUE);
		int count=0;
		for(int i=0;i<n;i++) {
			mx[i] =0;
			int f=0;
			int min =Integer.MAX_VALUE;
			for(int j=0;j<l[i];j++) {

				//chk flag
				if(s.get(i).get(j) < min) {
					min = s.get(i).get(j);
				}

				if(s.get(i).get(j) > min) {
					f=1;
					break;
				}

			}
			if(f==0) {
				for(int j=0;j<l[i];j++) {
					if(s.get(i).get(j) > mx[a] ) {
						mx[a]  = s.get(i).get(j);
					}
					if(s.get(i).get(j) < mn[a]) {
						mn[a] = s.get(i).get(j);
					}
				}
				a++;
			}
			else {
				count++;
			}
		}

		int[] pmx = new int[1000005];
		for(int i=0;i<a;i++) {
			pmx[mx[i]]++;
		}

		pmx[0] = a - pmx[0];

		for(int i=1;i<1000005;i++) {
			pmx[i] =  pmx[i-1] - pmx[i];
		}

		long sum =0;
		for(int i=0;i<a;i++) {
			sum += pmx[mn[i]];
		}

		out.println(sum +((2*n)-count)*count);

		out.close();
	}

	/* TC space

	 */

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int snext() {
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n) {
			int a[] = new int[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n) {
			long a[] = new long[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextLong();
			}
			return a;
		}

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}

	}

}

// For Pair sorting

// Arrays.sort(arr,new Comparator<Pair>() {
// @Override public int compare(Pair p1, Pair p2)
// {
// return p1.x - p2.x;
// }
// });

class Pair {
	int x;
	int y;

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

	@Override
	public boolean equals(Object o) {
		Pair p =(Pair)o;
		return (x==p.x && y==p.y);
	}
}

class x{
	//declare variables
	int abc;

	//constructor
	public x(int abc) {
		this.abc = abc;
	}

}

class couple implements Comparable<couple> {
	int x, y;

	public couple(int m, int f) {
		x = m;
		y = f;
	}

	public int compareTo(couple o) {

		return x - o.x;
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

//Mann Shah [ DAIICT ].
//fast io

public class Main {
	public static int mod = (int) (1e9 + 7);
	public static long inf = (long) 1e15 + 42;
	static InputReader in;
	static PrintWriter out;

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

	public static void main(String args[]) {

		in = new InputReader(System.in);
		out = new PrintWriter(System.out);

		int n = in.nextInt();
		int[] l = new int[n];
		ArrayList<ArrayList<Integer>> s = new ArrayList();
		for(int i=0;i<n;i++) {
			l[i]=in.nextInt();
			ArrayList<Integer> ss = new ArrayList();
			for(int j=0;j<l[i];j++) {
				ss.add(in.nextInt());
			}
			s.add(ss);
		}

		int[] mx = new int[n];
		int[] mn= new int[n];
		int a=0,b=0;
		Arrays.fill(mn,Integer.MAX_VALUE);
		int count=0;
		for(int i=0;i<n;i++) {
			mx[i] =0;
			int f=0;
			int min =Integer.MAX_VALUE;
			for(int j=0;j<l[i];j++) {

				//chk flag
				if(s.get(i).get(j) < min) {
					min = s.get(i).get(j);
				}

				if(s.get(i).get(j) > min) {
					f=1;
				}

			}
			if(f==0) {
				for(int j=0;j<l[i];j++) {
					if(s.get(i).get(j) > mx[a] ) {
						mx[a]  = s.get(i).get(j);
					}
					if(s.get(i).get(j) < mn[a]) {
						mn[a] = s.get(i).get(j);
					}
				}
				a++;
			}
			else {
				count++;
			}
		}
		int mval =0 ;

		for(int i=0;i<a;i++) {
			if(mx[i] > mval) {
				mval = mx[i];
			}
		}

		int[] pmx = new int[mval+1];
		for(int i=0;i<a;i++) {
			pmx[mx[i]]++;
			//out.println(mx[i]);
		}

		pmx[0] = a - pmx[0];

		for(int i=1;i<=mval;i++) {
			pmx[i] =  pmx[i-1] - pmx[i];
		}

		long sum =0;
		for(int i=0;i<a;i++) {
			sum += pmx[mn[i]];
		}

		out.println(sum +((2*n)-count)*count);

		out.close();
	}

	/* TC space

	 */

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int snext() {
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n) {
			int a[] = new int[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n) {
			long a[] = new long[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextLong();
			}
			return a;
		}

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}

	}

}

// For Pair sorting

// Arrays.sort(arr,new Comparator<Pair>() {
// @Override public int compare(Pair p1, Pair p2)
// {
// return p1.x - p2.x;
// }
// });

class Pair {
	int x;
	int y;

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

	@Override
	public boolean equals(Object o) {
		Pair p =(Pair)o;
		return (x==p.x && y==p.y);
	}
}

class x{
	//declare variables
	int abc;

	//constructor
	public x(int abc) {
		this.abc = abc;
	}

}

class couple implements Comparable<couple> {
	int x, y;

	public couple(int m, int f) {
		x = m;
		y = f;
	}

	public int compareTo(couple o) {

		return x - o.x;
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

//Mann Shah [ DAIICT ].
//fast io

public class Main {
	public static int mod = (int) (1e9 + 7);
	public static long inf = (long) 1e15 + 42;
	static InputReader in;
	static PrintWriter out;

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

	public static void main(String args[]) {

		in = new InputReader(System.in);
		out = new PrintWriter(System.out);

		int n = in.nextInt();
		int[] l = new int[n];
		ArrayList<ArrayList<Integer>> s = new ArrayList();
		for(int i=0;i<n;i++) {
			l[i]=in.nextInt();
			ArrayList<Integer> ss = new ArrayList();
			for(int j=0;j<l[i];j++) {
				ss.add(in.nextInt());
			}
			s.add(ss);
		}

		int[] mx = new int[n];
		int[] mn= new int[n];
		int a=0,b=0;
		Arrays.fill(mn,Integer.MAX_VALUE);
		int count=0;
		for(int i=0;i<n;i++) {
			int f=0;
			int min =s.get(i).get(0);
			for(int j=1;j<l[i];j++) {

				//chk flag
				if(s.get(i).get(j) > min) {
					f=1;
					break;
				}
				if(s.get(i).get(j) < min) {
					min = s.get(i).get(j);
				}
			}
			if(f==0) {
				for(int j=0;j<l[i];j++) {
					if(s.get(i).get(j) > mx[a] ) {
						mx[a]  = s.get(i).get(j);
					}
					if(s.get(i).get(j) < mn[a]) {
						mn[a] = s.get(i).get(j);
					}
				}
				a++;
			}
			else {
				count++;
			}
		}

		int[] pmx = new int[1000005];
		for(int i=0;i<a;i++) {
			pmx[mx[i]]++;
		}

		pmx[0] = a - pmx[0];

		for(int i=1;i<1000005;i++) {
			pmx[i] =  pmx[i-1] - pmx[i];
		}

		long sum =0;
		for(int i=0;i<a;i++) {
			sum += pmx[mn[i]];
		}

		out.println(sum +((2*n)-count)*count);

		out.close();
	}

	/* TC space

	 */

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int snext() {
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n) {
			int a[] = new int[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n) {
			long a[] = new long[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextLong();
			}
			return a;
		}

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}

	}

}

// For Pair sorting

// Arrays.sort(arr,new Comparator<Pair>() {
// @Override public int compare(Pair p1, Pair p2)
// {
// return p1.x - p2.x;
// }
// });

class Pair {
	int x;
	int y;

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

	@Override
	public boolean equals(Object o) {
		Pair p =(Pair)o;
		return (x==p.x && y==p.y);
	}
}

class x{
	//declare variables
	int abc;

	//constructor
	public x(int abc) {
		this.abc = abc;
	}

}

class couple implements Comparable<couple> {
	int x, y;

	public couple(int m, int f) {
		x = m;
		y = f;
	}

	public int compareTo(couple o) {

		return x - o.x;
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

//Mann Shah [ DAIICT ].
//fast io

public class Main {
	public static int mod = (int) (1e9 + 7);
	public static long inf = (long) 1e15 + 42;
	static InputReader in;
	static PrintWriter out;

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

	public static void main(String args[]) {

		in = new InputReader(System.in);
		out = new PrintWriter(System.out);

		int n = in.nextInt();
		int[] l = new int[n];
		int[][] s = new int[n][1000002];
		int[] mx = new int[n];
		int[] mn= new int[n];
		int a=0,b=0;
		Arrays.fill(mn,Integer.MAX_VALUE);
		int count=0;
		for(int i=0;i<n;i++) {
			l[i]=in.nextInt();
			mx[i] =0;
			int f=0;
			int min =Integer.MAX_VALUE;
			for(int j=0;j<l[i];j++) {
				s[i][j] = in.nextInt();

				//chk flag
				if(s[i][j] < min) {
					min = s[i][j];
				}

				if(s[i][j] > min) {
					f=1;
				}

			}
			if(f==0) {
				for(int j=0;j<l[i];j++) {
					if(s[i][j] > mx[a] ) {
						mx[a]  = s[i][j];
					}
					if(s[i][j] < mn[a]) {
						mn[a] = s[i][j];
					}
				}
				a++;
			}
			else {
				count++;
			}
		}

		int[] pmx = new int[1000002];
		for(int i=0;i<a;i++) {
			pmx[mx[i]]++;
			//out.println(mx[i]);
		}

		pmx[0] = a - pmx[0];

		for(int i=1;i<1000002;i++) {
			pmx[i] =  pmx[i-1] - pmx[i];
		}

		long sum =0;
		for(int i=0;i<a;i++) {
			sum += pmx[mn[i]];
		}

		out.println(sum +((2*n)-count)*count);

		out.close();
	}

	/* TC space

	 */

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int snext() {
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n) {
			int a[] = new int[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n) {
			long a[] = new long[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextLong();
			}
			return a;
		}

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}

	}

}

// For Pair sorting

// Arrays.sort(arr,new Comparator<Pair>() {
// @Override public int compare(Pair p1, Pair p2)
// {
// return p1.x - p2.x;
// }
// });

class Pair {
	int x;
	int y;

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

	@Override
	public boolean equals(Object o) {
		Pair p =(Pair)o;
		return (x==p.x && y==p.y);
	}
}

class x{
	//declare variables
	int abc;

	//constructor
	public x(int abc) {
		this.abc = abc;
	}

}

class couple implements Comparable<couple> {
	int x, y;

	public couple(int m, int f) {
		x = m;
		y = f;
	}

	public int compareTo(couple o) {

		return x - o.x;
	}
}


/*	/ ﾌﾌ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ム
	/ )\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  Y
	(⠀⠀| ( ͡° ͜ʖ ͡°）⠀⌒(⠀ ノ
	(⠀ ﾉ⌒ Y ⌒ヽ-く __／
	| _⠀｡ノ| ノ｡ |/
	(⠀ー '_人`ー ﾉ
	⠀|\ ￣ _人'彡ﾉ
	⠀ )\⠀⠀ ｡⠀⠀ /
	⠀⠀(\⠀ #⠀ /
	⠀/⠀⠀⠀/ὣ====================D-
	/⠀⠀⠀/⠀ \ \⠀⠀\
	( (⠀)⠀⠀⠀⠀ ) ).⠀)
	(⠀⠀)⠀⠀⠀⠀⠀( | /
	|⠀ /⠀⠀⠀⠀⠀⠀ | /
	[_] ⠀⠀⠀⠀⠀[___]                     */
// Main Code at the Bottom
import java.util.*;
import java.lang.*;
import java.io.*;
public class Main {
	//Fast IO class
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
        public FastReader() {
        	boolean env=System.getProperty("ONLINE_JUDGE") != null;
        	if(!env) {
        		try {
					br=new BufferedReader(new FileReader("src\\input.txt"));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
        	}
        	else br = new BufferedReader(new InputStreamReader(System.in));
        }
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        int nextInt() {
            return Integer.parseInt(next());
        }
        long nextLong() {
            return Long.parseLong(next());
        }
        double nextDouble() {
            return Double.parseDouble(next());
        }
        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
    static long MOD=1000000000+7;
    //Euclidean Algorithm
    static long gcd(long A,long B){
        if(B==0) return A;
        return gcd(B,A%B);
    }
    //Modular Exponentiation
    static long fastExpo(long x,long n){
        if(n==0) return 1;
        if((n&1)==0) return fastExpo((x*x)%MOD,n/2)%MOD;
        return ((x%MOD)*fastExpo((x*x)%MOD,(n-1)/2))%MOD;
    }
    //Prime Number Algorithm
    static boolean isPrime(long n){
        if(n<=1) return false;
        if(n<=3) return true;
        if(n%2==0 || n%3==0) return false;
        for(int i=5;i*i<=n;i+=6) if(n%i==0 || n%(i+2)==0) return false;
        return true;
    }
    //Reverse an array
    static <T> void reverse(T arr[],int l,int r){
    	Collections.reverse(Arrays.asList(arr).subList(l, r));
    }
    //Print array
    static <T> void print1d(T arr[]) {
    	out.println(Arrays.toString(arr));
    }
    static <T> void print2d(T arr[][]) {
    	for(T a[]: arr) out.println(Arrays.toString(a));
    }
    // Pair
    static class pair{
    	long x,y;
    	pair(long a,long b){
    		this.x=a;
    		this.y=b;
    	}
    	public boolean equals(Object obj) {
    		if(obj == null || obj.getClass()!= this.getClass()) return false;
            pair p = (pair) obj;
            return (this.x==p.x && this.y==p.y);
        }
    	public int hashCode() {
            return Objects.hash(x,y);
        }
    }
    static FastReader sc=new FastReader();
    static PrintWriter out=new PrintWriter(System.out);
    static boolean check(ArrayList<Integer> a) {
    	ArrayList<Integer> tmp=new ArrayList<>();
    	for(Integer x: a) tmp.add(x);
    	Collections.sort(tmp,Collections.reverseOrder());
    	if(tmp.equals(a)) return true;
    	return false;
    }
    //Main function(The main code starts from here)
    public static void main (String[] args) throws java.lang.Exception {
    	int test=1;
        while(test-->0) {
        	int n=sc.nextInt();
        	ArrayList<Integer> a[]=new ArrayList[n];
        	int map[]=new int[1000000+1];
        	ArrayList<Integer> tmp=new ArrayList<>();
        	for(int i=0;i<n;i++) {
        		a[i]=new ArrayList<>();
        		int x=sc.nextInt();
        		for(int j=0;j<x;j++) a[i].add(sc.nextInt());
        		if(check(a[i])) {
        			map[a[i].get(0)]++;
        			tmp.add(a[i].get(x-1));
        		}
        	}
        	for(int i=1;i<1000000+1;i++) map[i]+=map[i-1];
        	long cnt=0;
        	for(Integer x: tmp) cnt+=map[x];
        	out.println((n*n)-cnt);
        }
        out.flush();
        out.close();
    }
}


/*	/ ???????????????
	/ )\????????????  Y
	(??| ( ?° ?? ?°)??(? ?
	(? ?? Y ??-? __/
	| _???| ?? |/
	(?? '_?`? ?
	?|\ ? _?'??
	? )\?? ??? /
	??(\? #? /
	?/???/?====================D-
	/???/? \ \??\
	( (?)???? ) ).?)
	(??)?????( | /
	|? /?????? | /
	[_] ?????[___]                     */
// Main Code at the Bottom
import java.util.*;
import java.lang.*;
import java.io.*;
public class Main {
	//Fast IO class
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
        public FastReader() {
        	boolean env=System.getProperty("ONLINE_JUDGE") != null;
        	if(!env) {
        		try {
					br=new BufferedReader(new FileReader("src\\input.txt"));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
        	}
        	else br = new BufferedReader(new InputStreamReader(System.in));
        }
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        int nextInt() {
            return Integer.parseInt(next());
        }
        long nextLong() {
            return Long.parseLong(next());
        }
        double nextDouble() {
            return Double.parseDouble(next());
        }
        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
    static long MOD=1000000000+7;
    //Euclidean Algorithm
    static long gcd(long A,long B){
        if(B==0) return A;
        return gcd(B,A%B);
    }
    //Modular Exponentiation
    static long fastExpo(long x,long n){
        if(n==0) return 1;
        if((n&1)==0) return fastExpo((x*x)%MOD,n/2)%MOD;
        return ((x%MOD)*fastExpo((x*x)%MOD,(n-1)/2))%MOD;
    }
    //Prime Number Algorithm
    static boolean isPrime(long n){
        if(n<=1) return false;
        if(n<=3) return true;
        if(n%2==0 || n%3==0) return false;
        for(int i=5;i*i<=n;i+=6) if(n%i==0 || n%(i+2)==0) return false;
        return true;
    }
    //Reverse an array
    static <T> void reverse(T arr[],int l,int r){
    	Collections.reverse(Arrays.asList(arr).subList(l, r));
    }
    //Print array
    static <T> void print1d(T arr[]) {
    	out.println(Arrays.toString(arr));
    }
    static <T> void print2d(T arr[][]) {
    	for(T a[]: arr) out.println(Arrays.toString(a));
    }
    // Pair
    static class pair{
    	long x,y;
    	pair(long a,long b){
    		this.x=a;
    		this.y=b;
    	}
    	public boolean equals(Object obj) {
    		if(obj == null || obj.getClass()!= this.getClass()) return false;
            pair p = (pair) obj;
            return (this.x==p.x && this.y==p.y);
        }
    	public int hashCode() {
            return Objects.hash(x,y);
        }
    }
    static FastReader sc=new FastReader();
    static PrintWriter out=new PrintWriter(System.out);
    static boolean check(ArrayList<Integer> a) {
    	ArrayList<Integer> tmp=new ArrayList<>();
    	for(Integer x: a) tmp.add(x);
    	Collections.sort(tmp,Collections.reverseOrder());
    	if(tmp.equals(a)) return false;
    	return true;
    }
    //Main function(The main code starts from here)
    public static void main (String[] args) throws java.lang.Exception {
    	int test=1;
        while(test-->0) {
        	int n=sc.nextInt();
        	ArrayList<Integer> a[]=new ArrayList[n];
        	int map1[]=new int[1000000+1],map2[]=new int[1000000+1];
        	for(int i=0;i<n;i++) {
        		int x=sc.nextInt(),max=-1,min=Integer.MAX_VALUE;
        		a[i]=new ArrayList<>();
        		for(int j=0;j<x;j++) {
        			a[i].add(sc.nextInt());
        			max=Math.max(max, a[i].get(j));
        			min=Math.min(min, a[i].get(j));
        		}
        		map1[max]++;
        		map2[min]++;
        	}
        	ArrayList<pair> tmp=new ArrayList<>();
        	for(int i=0;i<n;i++) {
        		int min=Integer.MAX_VALUE;
        		if(check(a[i])) {
        			for(Integer x: a[i]) min=Math.min(x, min);
            		tmp.add(new pair(i,min));
        		}
        	}
        	for(int i=1;i<1000000+1;i++) map2[i]+=map2[i-1];
        	long ans=0;
        	for(int i=0;i<n;i++) {
        		int flag=0,max=-1;
        		if(check(a[i])) flag=1;
        		if(flag==1) ans+=n;
        		else {
        			for(Integer x: a[i]) max=Math.max(max, x);
        			ans+=map2[max-1];
        			for(pair p: tmp) {
        				if(max<=p.y) ans++;
        			}
        		}
//        		if(flag==1) out.println(n);
//        		else out.println(map2[max-1]);
        	}
        	out.println(ans);
        }
        out.flush();
        out.close();
    }
}


/*	/ ﾌﾌ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ム
	/ )\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  Y
	(⠀⠀| ( ͡° ͜ʖ ͡°）⠀⌒(⠀ ノ
	(⠀ ﾉ⌒ Y ⌒ヽ-く __／
	| _⠀｡ノ| ノ｡ |/
	(⠀ー '_人`ー ﾉ
	⠀|\ ￣ _人'彡ﾉ
	⠀ )\⠀⠀ ｡⠀⠀ /
	⠀⠀(\⠀ #⠀ /
	⠀/⠀⠀⠀/ὣ====================D-
	/⠀⠀⠀/⠀ \ \⠀⠀\
	( (⠀)⠀⠀⠀⠀ ) ).⠀)
	(⠀⠀)⠀⠀⠀⠀⠀( | /
	|⠀ /⠀⠀⠀⠀⠀⠀ | /
	[_] ⠀⠀⠀⠀⠀[___]                     */
// Main Code at the Bottom
import java.util.*;
import java.lang.*;
import java.io.*;
public class Main {
	//Fast IO class
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
        public FastReader() {
        	boolean env=System.getProperty("ONLINE_JUDGE") != null;
        	if(!env) {
        		try {
					br=new BufferedReader(new FileReader("src\\input.txt"));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
        	}
        	else br = new BufferedReader(new InputStreamReader(System.in));
        }
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        int nextInt() {
            return Integer.parseInt(next());
        }
        long nextLong() {
            return Long.parseLong(next());
        }
        double nextDouble() {
            return Double.parseDouble(next());
        }
        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
    static long MOD=1000000000+7;
    //Euclidean Algorithm
    static long gcd(long A,long B){
        if(B==0) return A;
        return gcd(B,A%B);
    }
    //Modular Exponentiation
    static long fastExpo(long x,long n){
        if(n==0) return 1;
        if((n&1)==0) return fastExpo((x*x)%MOD,n/2)%MOD;
        return ((x%MOD)*fastExpo((x*x)%MOD,(n-1)/2))%MOD;
    }
    //Prime Number Algorithm
    static boolean isPrime(long n){
        if(n<=1) return false;
        if(n<=3) return true;
        if(n%2==0 || n%3==0) return false;
        for(int i=5;i*i<=n;i+=6) if(n%i==0 || n%(i+2)==0) return false;
        return true;
    }
    //Reverse an array
    static <T> void reverse(T arr[],int l,int r){
    	Collections.reverse(Arrays.asList(arr).subList(l, r));
    }
    //Print array
    static <T> void print1d(T arr[]) {
    	out.println(Arrays.toString(arr));
    }
    static <T> void print2d(T arr[][]) {
    	for(T a[]: arr) out.println(Arrays.toString(a));
    }
    // Pair
    static class pair{
    	long x,y;
    	pair(long a,long b){
    		this.x=a;
    		this.y=b;
    	}
    	public boolean equals(Object obj) {
    		if(obj == null || obj.getClass()!= this.getClass()) return false;
            pair p = (pair) obj;
            return (this.x==p.x && this.y==p.y);
        }
    	public int hashCode() {
            return Objects.hash(x,y);
        }
    }
    static FastReader sc=new FastReader();
    static PrintWriter out=new PrintWriter(System.out);
    static boolean check(ArrayList<Integer> a) {
    	ArrayList<Integer> tmp=new ArrayList<>();
    	for(Integer x: a) tmp.add(x);
    	Collections.sort(tmp,Collections.reverseOrder());
    	if(tmp.equals(a)) return true;
    	return false;
    }
    //Main function(The main code starts from here)
    public static void main (String[] args) throws java.lang.Exception {
    	int test=1;
        while(test-->0) {
        	int n=sc.nextInt();
        	ArrayList<Integer> a[]=new ArrayList[n];
        	int map[]=new int[1000000+1];
        	ArrayList<Integer> tmp=new ArrayList<>();
        	for(int i=0;i<n;i++) {
        		a[i]=new ArrayList<>();
        		int x=sc.nextInt();
        		for(int j=0;j<x;j++) a[i].add(sc.nextInt());
        		if(check(a[i])) {
        			map[a[i].get(0)]++;
        			tmp.add(a[i].get(x-1));
        		}
        	}
        	for(int i=1;i<1000000+1;i++) map[i]+=map[i-1];
        	long cnt=0L;
        	for(Integer x: tmp) cnt+=map[x];
        	out.println((long)((long)n*(long)n)-cnt);
        }
        out.flush();
        out.close();
    }
}


/*	/ ﾌﾌ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ム
	/ )\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  Y
	(⠀⠀| ( ͡° ͜ʖ ͡°）⠀⌒(⠀ ノ
	(⠀ ﾉ⌒ Y ⌒ヽ-く __／
	| _⠀｡ノ| ノ｡ |/
	(⠀ー '_人`ー ﾉ
	⠀|\ ￣ _人'彡ﾉ
	⠀ )\⠀⠀ ｡⠀⠀ /
	⠀⠀(\⠀ #⠀ /
	⠀/⠀⠀⠀/ὣ====================D-
	/⠀⠀⠀/⠀ \ \⠀⠀\
	( (⠀)⠀⠀⠀⠀ ) ).⠀)
	(⠀⠀)⠀⠀⠀⠀⠀( | /
	|⠀ /⠀⠀⠀⠀⠀⠀ | /
	[_] ⠀⠀⠀⠀⠀[___]                     */
// Main Code at the Bottom
import java.util.*;
import java.lang.*;
import java.io.*;
public class Main {
	//Fast IO class
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
        public FastReader() {
        	boolean env=System.getProperty("ONLINE_JUDGE") != null;
        	if(!env) {
        		try {
					br=new BufferedReader(new FileReader("src\\input.txt"));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
        	}
        	else br = new BufferedReader(new InputStreamReader(System.in));
        }
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        int nextInt() {
            return Integer.parseInt(next());
        }
        long nextLong() {
            return Long.parseLong(next());
        }
        double nextDouble() {
            return Double.parseDouble(next());
        }
        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
    static long MOD=1000000000+7;
    //Euclidean Algorithm
    static long gcd(long A,long B){
        if(B==0) return A;
        return gcd(B,A%B);
    }
    //Modular Exponentiation
    static long fastExpo(long x,long n){
        if(n==0) return 1;
        if((n&1)==0) return fastExpo((x*x)%MOD,n/2)%MOD;
        return ((x%MOD)*fastExpo((x*x)%MOD,(n-1)/2))%MOD;
    }
    //Prime Number Algorithm
    static boolean isPrime(long n){
        if(n<=1) return false;
        if(n<=3) return true;
        if(n%2==0 || n%3==0) return false;
        for(int i=5;i*i<=n;i+=6) if(n%i==0 || n%(i+2)==0) return false;
        return true;
    }
    //Reverse an array
    static <T> void reverse(T arr[],int l,int r){
    	Collections.reverse(Arrays.asList(arr).subList(l, r));
    }
    //Print array
    static <T> void print1d(T arr[]) {
    	out.println(Arrays.toString(arr));
    }
    static <T> void print2d(T arr[][]) {
    	for(T a[]: arr) out.println(Arrays.toString(a));
    }
    // Pair
    static class pair{
    	long x,y;
    	pair(long a,long b){
    		this.x=a;
    		this.y=b;
    	}
    	public boolean equals(Object obj) {
    		if(obj == null || obj.getClass()!= this.getClass()) return false;
            pair p = (pair) obj;
            return (this.x==p.x && this.y==p.y);
        }
    	public int hashCode() {
            return Objects.hash(x,y);
        }
    }
    static FastReader sc=new FastReader();
    static PrintWriter out=new PrintWriter(System.out);
    static boolean check(ArrayList<Integer> a) {
    	ArrayList<Integer> tmp=new ArrayList<>();
    	for(Integer x: a) tmp.add(x);
    	Collections.sort(tmp,Collections.reverseOrder());
    	if(tmp.equals(a)) return true;
    	return false;
    }
    //Main function(The main code starts from here)
    public static void main (String[] args) throws java.lang.Exception {
    	int test=1;
        while(test-->0) {
        	int n=sc.nextInt();
        	ArrayList<Integer> a[]=new ArrayList[n];
        	int map[]=new int[1000000+1];
        	ArrayList<Integer> tmp=new ArrayList<>();
        	for(int i=0;i<n;i++) {
        		a[i]=new ArrayList<>();
        		int x=sc.nextInt();
        		for(int j=0;j<x;j++) a[i].add(sc.nextInt());
        		if(check(a[i])) {
        			map[a[i].get(0)]++;
        			tmp.add(a[i].get(x-1));
        		}
        	}
        	for(int i=1;i<1000000+1;i++) map[i]+=map[i-1];
        	long cnt=0L;
        	for(Integer x: tmp) cnt+=map[x];
        	out.println((long)(n*n)-cnt);
        }
        out.flush();
        out.close();
    }
}


import java.util.*;
import java.io.*;
//import java.lang.*;
public class Task{
public static int gcd(int a,int b){
	if(b==0){return a;}
	return gcd(b,a%b);
}
public static void main(String[] args) throws FileNotFoundException, IOException{
       Scanner s=new Scanner(System.in);
       BufferedWriter out=new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuilder sb=new StringBuilder();
      int t=s.nextInt(), z=t;
     List<Integer>l=new ArrayList<>();
     Set<Integer>asc=new HashSet<>();
     int[] arr=new int[1000002];
     long ans=0;
      while(t--!=0){
      	int n=s.nextInt();

      	 int mx=0,mi=Integer.MAX_VALUE,pre=10000000;
      	 boolean b=true;
      	for(int i=0;i<n;i++){
      		int p=s.nextInt();
      		if(p>pre&&b){b=false;}
      		pre=p;
      		mi=Math.min(mi,p);
      		mx=Math.max(mx,p);
      	}
      	if(b){arr[mx]++;}
      	else{asc.add(l.size());}
      	l.add(mi);
      }
      for(int i=1000000;i>=0;i--){arr[i]=arr[i+1]+arr[i];}
    for(int i=0;i<z;i++){
    	if(asc.contains(i)){ans+=z;}
    	else{ans+=asc.size()+arr[l.get(i)+1];}
    }
      out.write(ans+"");
           out.flush();
      }
      }


import java.util.*;
import java.io.*;
//import java.lang.*;
public class Task{
public static int gcd(int a,int b){
	if(b==0){return a;}
	return gcd(b,a%b);
}
public static void main(String[] args) throws FileNotFoundException, IOException{
       Scanner s=new Scanner(System.in);
       BufferedWriter out=new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuilder sb=new StringBuilder();
      int t=s.nextInt(), z=t;
     List<Integer>l=new ArrayList<>();
     int[] arr=new int[1000002];
     long ans=0;
      while(t--!=0){
      	int n=s.nextInt();

      	 int mx=0,mi=Integer.MAX_VALUE;
      	for(int i=0;i<n;i++){
      		int p=s.nextInt();
      		mi=Math.min(mi,p);
      		mx=Math.max(mx,p);
      	}
      	arr[mx]++;
      	l.add(mi);
      	if(mx>mi){ans++;}
      }
      int[] dp=new int[1000002];
      for(int i=1000000;i>=0;i--){dp[i]=dp[i+1]+arr[i];}
    for(int i=0;i<z;i++){
    	ans+=dp[l.get(i)+1];
    	// out.write(l.get(i)+1+" ");
    }
      out.write(ans+"");
           out.flush();
      }
      }


import java.util.*;
import java.io.*;
import java.math.BigInteger;

public class Main implements Runnable {
  // static Scanner in;
  static FastReader in;
  static PrintWriter out;
  static int[][] dirs8 = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {-1, -1}, {-1, 1}, {1, -1}};
  static int[][] dirs = {{0, -1}, {1, 0}, {0, +1}, {-1, 0}};

  static int[][] E;
  // static List<int[]>[] adj;
  static List<Integer>[] adj;
  static int[] vis;

  static long INFL = (long) 1e15 + 7;
  static int INF = (int) 1e7 + 9;
  static int mod = 998244353;

  static int T, n, m, k, p;

  static boolean flag;
  static int[] a, b;
  static int[][] map;

  static int[][] dp;

  static void solve() throws Exception {
    n = in.nextInt();

    A[] a = new A[n];
    int len, min, max, cur, prev;
    int count = 0;
    for (int i = 0; i < n; i++) {
      a[i] = new A();
      len = in.nextInt();
      min = max = prev = in.nextInt();

      for (int k = 0; k < len - 1; k++) {
        cur = in.nextInt();
        min = Math.min(min, cur);
        max = Math.max(max, cur);
        if (cur > prev) {
          a[i].yes = true;
        }
        prev = cur;
      }
      if (a[i].yes) count++;
      a[i].min = min;
      a[i].max = max;
    }

    Arrays.sort(a, (x, y) -> {
      if (x.min == y.min) {
        return x.max - y.max;
      }
      return x.min - y.min;
    });

    A[] b = a.clone();
    Arrays.sort(b, (x, y) -> (x.max - y.max));

    int[] counta = new int[n];
    int[] countb = new int[n];
    countb[0] = b[0].yes ? 1 : 0;
    counta[n - 1] = a[n - 1].yes ? 1 : 0;
    for (int i = 1; i < n; i++) {
      countb[i] = countb[i - 1] + (b[i].yes ? 1 : 0);
    }

    for (int i = n - 2; i >= 0; i--) {
      counta[i] = counta[i + 1] + (a[i].yes ? 1 : 0);
    }

    // Jren.p(counta);
    // Jren.p(countb);

    // for (A i : a) {out.print(i + " ");}
    // out.println();

    // out.println(count  + "!!!");

    int res = 0;
    for (int i = 0; i < n; i++) {
      int idx1 = search1(a[i].min, b);
      res += (n - idx1);
      res += (idx1 == 0 ? 0 : countb[idx1 - 1] * 2);

      int idx2 = search2(a[i].max, a);
      res += (idx2 + 1);
      res += ((idx2 == n - 1) ? 0 : counta[idx2 + 1] * 2);

      // out.println((n - idx1) + " " + (idx2 + 1));
      // out.println(n - idx1 + 1 + idx2);
      // if (a[i].min < a[i].max) {res += 2;}
    }
    out.println(res / 2);

  }

  static int search1(int t, A[] b) {
    // find the index of first element whose max is > t
    int lo = 0, hi = b.length;
    while (lo < hi) {
      int mid = (lo + hi) >>> 1;
      if (b[mid].max <= t) {lo = mid + 1;}
      else {hi = mid;}
    }
    // out.println(t + " " + lo);
    return lo;
  }

  static int search2(int t, A[] a) {
    // find the index of first element whose min is < t
    int lo = -1, hi = a.length - 1;
    while (lo < hi) {
      int mid = (lo + hi + 1) >>> 1;
      if (a[mid].min >= t) {hi = mid - 1;}
      else {lo = mid;}
    }
    // out.println(t + " " + lo);
    return lo;
  }

  static class A {
    boolean yes;
    int min, max;
    public String toString() {
      return "(" + min + ", "  + max + "), ";
    }
  }

  public static void main(String[] args) throws Exception {

    // in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
    in = new FastReader();
    out = new PrintWriter(System.out);

    // int T = in.nextInt();
    // for (int tt = 1; tt <= T; tt++) {
    //   // Thread t = new Thread(null, new Main(), "Main", 1 << 28);
    //   // t.start();
    //   // t.join();
    //   solve();
    // }

    // // Thread t = new Thread(null, new Main(), "Main", 1 << 28);
    // // t.start();
    // // t.join();
    solve();

    out.flush();
    out.close();
  }

  @Override
  public void run() {
    try {
      solve();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  static class FastReader {
    public BufferedReader br;
    StringTokenizer st;
    public FastReader() {br = new BufferedReader(new InputStreamReader(System.in));}
    String next() {
      while (st == null || !st.hasMoreElements()) {
          try {st = new StringTokenizer(br.readLine());}
          catch (IOException e) {e.printStackTrace();}
      }
      return st.nextToken();
    }
    int nextInt() {return Integer.parseInt(next());}
    long nextLong() {return Long.parseLong(next());}
    double nextDouble() {return Double.parseDouble(next());}
    String nextLine() {
      String str = "";
        try {str = br.readLine();}
        catch (IOException e) {e.printStackTrace();}
        return str;
    }
  }

  static void as(boolean result) throws Exception {
    if (!result) {
      throw new Exception();
    }
  }

  static int modInverse(int a, int m) {
    int m0 = m;
    int y = 0, x = 1;
    if (m == 1) {return 0;}
    while (a > 1) {
        // q is quotient
      int q = a / m;
      int t = m;
      // m is remainder now, process
      // same as Euclid's algo
      m = a % m;
      a = t;
      t = y;
      // Update x and y
      y = x - q * y;
      x = t;
    }
    // Make x positive
    if (x < 0)
      x += m0;
    return x;
  }
}


import java.util.*;
import java.io.*;
import java.math.BigInteger;

public class Main implements Runnable {
  // static Scanner in;
  static FastReader in;
  static PrintWriter out;
  static int[][] dirs8 = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {-1, -1}, {-1, 1}, {1, -1}};
  static int[][] dirs = {{0, -1}, {1, 0}, {0, +1}, {-1, 0}};

  static int[][] E;
  // static List<int[]>[] adj;
  static List<Integer>[] adj;
  static int[] vis;

  static long INFL = (long) 1e15 + 7;
  static int INF = (int) 1e7 + 9;
  // static int mod = 998244353;
  static int mod;

  static int T, n, m, k, p;

  static boolean flag;
  static int[] a, b;
  static int[][] map;

  static int[][] dp;

  static void solve() throws Exception {
    n = in.nextInt();

  }

  public static void main(String[] args) throws Exception {

    // in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
    in = new FastReader();
    out = new PrintWriter(System.out);

    // int T = in.nextInt();
    // for (int tt = 1; tt <= T; tt++) {
    //   // Thread t = new Thread(null, new Main(), "Main", 1 << 28);
    //   // t.start();
    //   // t.join();
    //   solve();
    // }

    // // Thread t = new Thread(null, new Main(), "Main", 1 << 28);
    // // t.start();
    // // t.join();
    solve();

    out.flush();
    out.close();
  }

  @Override
  public void run() {
    try {
      solve();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  static class FastReader {
    public BufferedReader br;
    StringTokenizer st;
    public FastReader() {br = new BufferedReader(new InputStreamReader(System.in));}
    String next() {
      while (st == null || !st.hasMoreElements()) {
          try {st = new StringTokenizer(br.readLine());}
          catch (IOException e) {e.printStackTrace();}
      }
      return st.nextToken();
    }
    int nextInt() {return Integer.parseInt(next());}
    long nextLong() {return Long.parseLong(next());}
    double nextDouble() {return Double.parseDouble(next());}
    String nextLine() {
      String str = "";
        try {str = br.readLine();}
        catch (IOException e) {e.printStackTrace();}
        return str;
    }
  }

  static void as(boolean result) throws Exception {
    if (!result) {
      throw new Exception();
    }
  }

  static int modInverse(int a, int m) {
    int m0 = m;
    int y = 0, x = 1;
    if (m == 1) {return 0;}
    while (a > 1) {
        // q is quotient
      int q = a / m;
      int t = m;
      // m is remainder now, process
      // same as Euclid's algo
      m = a % m;
      a = t;
      t = y;
      // Update x and y
      y = x - q * y;
      x = t;
    }
    // Make x positive
    if (x < 0)
      x += m0;
    return x;
  }
}


import java.util.*;
import java.io.*;
import java.math.BigInteger;

public class Main implements Runnable {
  // static Scanner in;
  static FastReader in;
  static PrintWriter out;
  static int[][] dirs8 = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {-1, -1}, {-1, 1}, {1, -1}};
  static int[][] dirs = {{0, -1}, {1, 0}, {0, +1}, {-1, 0}};

  static int[][] E;
  // static List<int[]>[] adj;
  static List<Integer>[] adj;
  static int[] vis;

  static long INFL = (long) 1e15 + 7;
  static int INF = (int) 1e7 + 9;
  static int mod = 998244353;

  static int T, n, m, k, p;

  static boolean flag;
  static int[] a, b;
  static int[][] map;

  static int[][] dp;

  static void solve() throws Exception {
    n = in.nextInt();

    A[] a = new A[n];
    int len, min, max, cur, prev;
    int count = 0;
    int p = 0;
    for (int i = 0; i < n; i++) {
      // a[i] = new A();
      A curA = new A();
      len = in.nextInt();
      min = max = prev = in.nextInt();

      for (int k = 0; k < len - 1; k++) {
        cur = in.nextInt();
        min = Math.min(min, cur);
        max = Math.max(max, cur);
        if (cur > prev) {
          curA.yes = true;
        }
        prev = cur;
      }
      if (curA.yes) {count++; continue;}
      curA.min = min;
      curA.max = max;
      a[p++] = curA;
    }

    n = p;
    a = Arrays.copyOfRange(a, 0, p);

    Arrays.sort(a, (x, y) -> {
      if (x.min == y.min) {
        return x.max - y.max;
      }
      return x.min - y.min;
    });

    A[] b = a.clone();
    Arrays.sort(b, (x, y) -> (x.max - y.max));

    // int[] counta = new int[n];
    // int[] countb = new int[n];
    // countb[0] = b[0].yes ? 1 : 0;
    // counta[n - 1] = a[n - 1].yes ? 1 : 0;
    // for (int i = 1; i < n; i++) {
    //   countb[i] = countb[i - 1] + (b[i].yes ? 1 : 0);
    // }

    // for (int i = n - 2; i >= 0; i--) {
    //   counta[i] = counta[i + 1] + (a[i].yes ? 1 : 0);
    // }

    // Jren.p(counta);
    // Jren.p(countb);

    // for (A i : a) {out.print(i + " ");}
    // out.println();

    // out.println(count  + "!!!");

    int res = 0;
    for (int i = 0; i < n; i++) {
      int idx1 = search1(a[i].min, b);
      res += (n - idx1);
      // res += (idx1 == 0 ? 0 : countb[idx1 - 1] * 2);

      int idx2 = search2(a[i].max, a);
      res += (idx2 + 1);
      // res += ((idx2 == n - 1) ? 0 : counta[idx2 + 1] * 2);

      // out.println((n - idx1) + " " + (idx2 + 1));
      // out.println(n - idx1 + 1 + idx2);
      // if (a[i].min < a[i].max) {res += 2;}
    }

    // out.println(count);

    out.println(res / 2 + (2 * (n + count) - count) * count);

  }

  static int search1(int t, A[] b) {
    // find the index of first element whose max is > t
    int lo = 0, hi = b.length;
    while (lo < hi) {
      int mid = (lo + hi) >>> 1;
      if (b[mid].max <= t) {lo = mid + 1;}
      else {hi = mid;}
    }
    // out.println(t + " " + lo);
    return lo;
  }

  static int search2(int t, A[] a) {
    // find the index of first element whose min is < t
    int lo = -1, hi = a.length - 1;
    while (lo < hi) {
      int mid = (lo + hi + 1) >>> 1;
      if (a[mid].min >= t) {hi = mid - 1;}
      else {lo = mid;}
    }
    // out.println(t + " " + lo);
    return lo;
  }

  static class A {
    boolean yes;
    int min, max;
    public String toString() {
      return "(" + min + ", "  + max + "), ";
    }
  }

  public static void main(String[] args) throws Exception {

    // in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
    in = new FastReader();
    out = new PrintWriter(System.out);

    // int T = in.nextInt();
    // for (int tt = 1; tt <= T; tt++) {
    //   // Thread t = new Thread(null, new Main(), "Main", 1 << 28);
    //   // t.start();
    //   // t.join();
    //   solve();
    // }

    // // Thread t = new Thread(null, new Main(), "Main", 1 << 28);
    // // t.start();
    // // t.join();
    solve();

    out.flush();
    out.close();
  }

  @Override
  public void run() {
    try {
      solve();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  static class FastReader {
    public BufferedReader br;
    StringTokenizer st;
    public FastReader() {br = new BufferedReader(new InputStreamReader(System.in));}
    String next() {
      while (st == null || !st.hasMoreElements()) {
          try {st = new StringTokenizer(br.readLine());}
          catch (IOException e) {e.printStackTrace();}
      }
      return st.nextToken();
    }
    int nextInt() {return Integer.parseInt(next());}
    long nextLong() {return Long.parseLong(next());}
    double nextDouble() {return Double.parseDouble(next());}
    String nextLine() {
      String str = "";
        try {str = br.readLine();}
        catch (IOException e) {e.printStackTrace();}
        return str;
    }
  }

  static void as(boolean result) throws Exception {
    if (!result) {
      throw new Exception();
    }
  }

  static int modInverse(int a, int m) {
    int m0 = m;
    int y = 0, x = 1;
    if (m == 1) {return 0;}
    while (a > 1) {
        // q is quotient
      int q = a / m;
      int t = m;
      // m is remainder now, process
      // same as Euclid's algo
      m = a % m;
      a = t;
      t = y;
      // Update x and y
      y = x - q * y;
      x = t;
    }
    // Make x positive
    if (x < 0)
      x += m0;
    return x;
  }
}


import java.util.*;
import java.io.*;
import java.math.BigInteger;

public class Main implements Runnable {
  // static Scanner in;
  static FastReader in;
  static PrintWriter out;
  static int[][] dirs8 = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {-1, -1}, {-1, 1}, {1, -1}};
  static int[][] dirs = {{0, -1}, {1, 0}, {0, +1}, {-1, 0}};

  static int[][] E;
  // static List<int[]>[] adj;
  static List<Integer>[] adj;
  static int[] vis;

  static long INFL = (long) 1e15 + 7;
  static int INF = (int) 1e7 + 9;
  static int mod = 998244353;

  static int T, n, m, k, p;

  static boolean flag;
  static int[] a, b;
  static int[][] map;

  static int[][] dp;

  static void solve() throws Exception {
    n = in.nextInt();

    A[] a = new A[n];
    int len, min, max, cur, prev;
    int count = 0;
    int p = 0;
    for (int i = 0; i < n; i++) {
      // a[i] = new A();
      A curA = new A();
      len = in.nextInt();
      min = max = prev = in.nextInt();

      for (int k = 0; k < len - 1; k++) {
        cur = in.nextInt();
        min = Math.min(min, cur);
        max = Math.max(max, cur);
        if (cur > prev) {
          curA.yes = true;
        }
        prev = cur;
      }
      if (curA.yes) {count++; continue;}
      curA.min = min;
      curA.max = max;
      a[p++] = curA;
    }

    n = p;
    a = Arrays.copyOfRange(a, 0, p);

    Arrays.sort(a, (x, y) -> {
      if (x.min == y.min) {
        return x.max - y.max;
      }
      return x.min - y.min;
    });

    A[] b = a.clone();
    Arrays.sort(b, (x, y) -> (x.max - y.max));

    // int[] counta = new int[n];
    // int[] countb = new int[n];
    // countb[0] = b[0].yes ? 1 : 0;
    // counta[n - 1] = a[n - 1].yes ? 1 : 0;
    // for (int i = 1; i < n; i++) {
    //   countb[i] = countb[i - 1] + (b[i].yes ? 1 : 0);
    // }

    // for (int i = n - 2; i >= 0; i--) {
    //   counta[i] = counta[i + 1] + (a[i].yes ? 1 : 0);
    // }

    // Jren.p(counta);
    // Jren.p(countb);

    // for (A i : a) {out.print(i + " ");}
    // out.println();

    // out.println(count  + "!!!");

    long res = 0;
    for (int i = 0; i < n; i++) {
      int idx1 = search1(a[i].min, b);
      res += (n - idx1);
      // res += (idx1 == 0 ? 0 : countb[idx1 - 1] * 2);

      int idx2 = search2(a[i].max, a);
      res += (idx2 + 1);
      // res += ((idx2 == n - 1) ? 0 : counta[idx2 + 1] * 2);

      // out.println((n - idx1) + " " + (idx2 + 1));
      // out.println(n - idx1 + 1 + idx2);
      // if (a[i].min < a[i].max) {res += 2;}
    }

    // out.println(count);

    out.println(res / 2 + (2 * ((long) n + count) - count) * (long) count);

  }

  static int search1(int t, A[] b) {
    // find the index of first element whose max is > t
    int lo = 0, hi = b.length;
    while (lo < hi) {
      int mid = (lo + hi) >>> 1;
      if (b[mid].max <= t) {lo = mid + 1;}
      else {hi = mid;}
    }
    // out.println(t + " " + lo);
    return lo;
  }

  static int search2(int t, A[] a) {
    // find the index of first element whose min is < t
    int lo = -1, hi = a.length - 1;
    while (lo < hi) {
      int mid = (lo + hi + 1) >>> 1;
      if (a[mid].min >= t) {hi = mid - 1;}
      else {lo = mid;}
    }
    // out.println(t + " " + lo);
    return lo;
  }

  static class A {
    boolean yes;
    int min, max;
    public String toString() {
      return "(" + min + ", "  + max + "), ";
    }
  }

  public static void main(String[] args) throws Exception {

    // in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
    in = new FastReader();
    out = new PrintWriter(System.out);

    // int T = in.nextInt();
    // for (int tt = 1; tt <= T; tt++) {
    //   // Thread t = new Thread(null, new Main(), "Main", 1 << 28);
    //   // t.start();
    //   // t.join();
    //   solve();
    // }

    // // Thread t = new Thread(null, new Main(), "Main", 1 << 28);
    // // t.start();
    // // t.join();
    solve();

    out.flush();
    out.close();
  }

  @Override
  public void run() {
    try {
      solve();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  static class FastReader {
    public BufferedReader br;
    StringTokenizer st;
    public FastReader() {br = new BufferedReader(new InputStreamReader(System.in));}
    String next() {
      while (st == null || !st.hasMoreElements()) {
          try {st = new StringTokenizer(br.readLine());}
          catch (IOException e) {e.printStackTrace();}
      }
      return st.nextToken();
    }
    int nextInt() {return Integer.parseInt(next());}
    long nextLong() {return Long.parseLong(next());}
    double nextDouble() {return Double.parseDouble(next());}
    String nextLine() {
      String str = "";
        try {str = br.readLine();}
        catch (IOException e) {e.printStackTrace();}
        return str;
    }
  }

  static void as(boolean result) throws Exception {
    if (!result) {
      throw new Exception();
    }
  }

  static int modInverse(int a, int m) {
    int m0 = m;
    int y = 0, x = 1;
    if (m == 1) {return 0;}
    while (a > 1) {
        // q is quotient
      int q = a / m;
      int t = m;
      // m is remainder now, process
      // same as Euclid's algo
      m = a % m;
      a = t;
      t = y;
      // Update x and y
      y = x - q * y;
      x = t;
    }
    // Make x positive
    if (x < 0)
      x += m0;
    return x;
  }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

public class Main {

    static FastReader read;

    public static void main(String[] args) throws IOException {
        FastReader read = new FastReader();
        StringBuilder out = new StringBuilder();
        int n = read.nextInt();
        List<Integer> l[] = new ArrayList[n];
        Pair[] q = new Pair[n];
        boolean[] isAns = new boolean[n];

        for (int i = 0; i < n; i++) {
            int len = read.nextInt();
            l[i] = new ArrayList<>();
            q[i] = new Pair();
            for (int j = 0; j < len; j++) {
                int cur = read.nextInt();
                l[i].add(cur);
                q[i].mn = Math.min(q[i].mn, cur);
                q[i].mx = Math.max(q[i].mx, cur);
                if (cur > q[i].mn) {
                    isAns[i] = true;
                }
            }
        }
        long ans = 0;
        int arrs = n;
        for (int i = 0; i < n; i++) {
            if (isAns[i]) {
                arrs--;
                ans += 1;
                ans += (arrs * 2);
            }
        }
        List<Integer> maxs = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            if (!isAns[i]) {
                maxs.add(q[i].mx);
            }
        }

        Collections.sort(maxs);
        for (int i = 0; i < n; i++) {
            if (!isAns[i]) {
                int get = greater(q[i].mn, maxs);
                ans += get;
            }
        }

        System.out.println(ans);

    }

    public static int greater(int find, List<Integer> maxs) {
        if (maxs.get(0) > find) {
            return maxs.size();
        }
        int mn = 0;
        int mx = maxs.size() - 1;
        int md = 0;
        int best = 0;

        while (mn <= mx) {
            md = (mn + mx) / 2;
            if (maxs.get(md) > find) {
                mx = md - 1;
            } else if (maxs.get(md) < find) {
                mn = md + 1;
            } else {
                best = md;
                mn = md + 1;
            }
        }

        for (int i = best; i < maxs.size(); i++) {
            if (maxs.get(i) > find) {
                best = i;
                break;
            }
        }
        if (best == maxs.size() - 1 && maxs.get(maxs.size() - 1) == find) {
            return 0;
        }
        return maxs.size() - best;
    }

}

class Pair {

    public int mn;
    public int mx;

    public Pair() {
        this.mn = Integer.MAX_VALUE;
        this.mx = Integer.MIN_VALUE;
    }

}

class FastReader {

    BufferedReader br;
    StringTokenizer st;

    public FastReader() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

public class Main {

    static FastReader read;

    public static void main(String[] args) throws IOException {
        FastReader read = new FastReader();
        StringBuilder out = new StringBuilder();
        int n = read.nextInt();
        List<Integer> l[] = new ArrayList[n];
        Pair[] q = new Pair[n];
        boolean[] isAns = new boolean[n];

        for (int i = 0; i < n; i++) {
            int len = read.nextInt();
            l[i] = new ArrayList<>();
            q[i] = new Pair();
            for (int j = 0; j < len; j++) {
                int cur = read.nextInt();
                l[i].add(cur);
                q[i].mn = Math.min(q[i].mn, cur);
                q[i].mx = Math.max(q[i].mx, cur);
                if (cur > q[i].mn) {
                    isAns[i] = true;
                }
            }
        }
        long ans = 0;
        int arrs = n;
        for (int i = 0; i < n; i++) {
            if (isAns[i]) {
                arrs--;
                ans += 1;
                ans += (arrs * 2);
            }
        }
        Integer maxs[] = new Integer[arrs];
        int j = 0;
        for (int i = 0; i < n; i++) {
            if (!isAns[i]) {
                maxs[j] = q[i].mx;
                j++;
            }
        }

        Arrays.sort(maxs);
        for (int i = 0; i < n; i++) {
            if (!isAns[i]) {
                int get = greater(q[i].mn, maxs);
                ans += get;
            }
        }

        System.out.println(ans);

    }

    public static int greater(int find, Integer[] maxs) {
        if (maxs[0] > find) {
            return maxs.length;
        }
        int mn = 0;
        int mx = maxs.length - 1;
        int md = 0;
        int best = 0;

        while (mn <= mx) {
            md = (mn + mx) / 2;
            if (maxs[md] > find) {
                mx = md - 1;
            } else if (maxs[md] < find) {
                mn = md + 1;
            } else {
                best = md;
                mn = md + 1;
            }
        }

        for (int i = best; i < maxs.length; i++) {
            if (maxs[i] > find) {
                best = i;
                break;
            }
        }
        if (best == maxs.length - 1 && maxs[maxs.length - 1] == find) {
            return 0;
        }
        return maxs.length - best;
    }

}

class Pair {

    public int mn;
    public int mx;

    public Pair() {
        this.mn = Integer.MAX_VALUE;
        this.mx = Integer.MIN_VALUE;
    }

}

class FastReader {

    BufferedReader br;
    StringTokenizer st;

    public FastReader() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

public class Main {

    static FastReader read;

    public static void main(String[] args) throws IOException {
        FastReader read = new FastReader();
        StringBuilder out = new StringBuilder();
        int n = read.nextInt();
        List<Integer> l[] = new ArrayList[n];
        Pair[] q = new Pair[n];
        boolean[] isAns = new boolean[n];

        for (int i = 0; i < n; i++) {
            int len = read.nextInt();
            l[i] = new ArrayList<>();
            q[i] = new Pair();
            for (int j = 0; j < len; j++) {
                int cur = read.nextInt();
                l[i].add(cur);
                q[i].mn = Math.min(q[i].mn, cur);
                q[i].mx = Math.max(q[i].mx, cur);
                if (cur > q[i].mn) {
                    isAns[i] = true;
                }
            }
        }
        long ans = 0;
        int arrs = n;
        for (int i = 0; i < n; i++) {
            if (isAns[i]) {
                arrs--;
                ans += 1;
                ans += (arrs * 2);
            }
        }
        List<Integer> maxs = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            if (!isAns[i]) {
                maxs.add(q[i].mx);
            }
        }

        Collections.sort(maxs);
        for (int i = 0; i < n; i++) {
            if (!isAns[i]) {
                int get = greater(q[i].mn, maxs);
                ans += get;
                if (get != 0 && q[i].mn == q[i].mx && l[i].size() > 1) {
                    ans--;
                }
            }
        }

        System.out.println(ans);

    }

    public static int greater(int find, List<Integer> maxs) {
        if (maxs.get(0) > find) {
            return maxs.size();
        }
        int mn = 0;
        int mx = maxs.size() - 1;
        int md = 0;
        int best = 0;

        while (mn <= mx) {
            md = (mn + mx) / 2;
            if (maxs.get(md) > find) {
                mx = md - 1;
            } else if (maxs.get(md) < find) {
                mn = md + 1;
            } else {
                best = md;
                mn = md + 1;
            }
        }

        for (int i = best; i < maxs.size(); i++) {
            if (maxs.get(i) > find) {
                best = i;
                break;
            }
        }
        if (best == maxs.size() - 1 && maxs.get(maxs.size() - 1) == find) {
            return 0;
        }
        return maxs.size() - best;
    }

}

class Pair {

    public int mn;
    public int mx;

    public Pair() {
        this.mn = Integer.MAX_VALUE;
        this.mx = Integer.MIN_VALUE;
    }

}

class FastReader {

    BufferedReader br;
    StringTokenizer st;

    public FastReader() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }
}