using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Threading.Tasks;

/*
・概要（計算量はO(logN)：Nは要素数）
二分探索を行い、lower_boundないしupper_boundを返す。
lower_boundは、指定した値以上になる最初のインデックスを返す。（a <= b）
upper_boundは、指定した値より大きくなる最初のインデックスを返す。（a < b）

なお、配列・リストの最大値よりも大きい値をtargetとした場合、
要素数（＝最終インデックス + 1）を返すので、out of rangeに注意。

namespace BinarySearch内にある以下のクラスのstaticメソッドを使用。
即ち、
リストの場合はclass Listに、配列の場合はclass Arrayに、それぞれアクセスし、
当該クラス内のLowerBoundないしUpperBoundメソッドを使用する。


・使用法（リストの場合の例）
1. 当然だが、使用前にソート
2. 対象となるリストと値を、それぞれの関数に渡し、インデックスを取得する

e.g. intリストの場合
//元のリスト
List<int> intLs = new List<int>(intArr);
//ターゲット
int target = int.Parse(Console.ReadLine());
//lower_bound
int lowLs = BinarySearch.List.LowerBound<int>(intLs, target);
//upper_bound
int upLs = BinarySearch.List.UpperBound<int>(intLs, target);

*/


class Program
{
	//Main
	static void Main(string[] args)
	{
		//読み込む
		int N = int.Parse(Console.ReadLine());
		int[] An = Console.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();
		int[] Bn = Console.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();
		int[] Cn = Console.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();

		//ソート
		Array.Sort(An);
		Array.Sort(Bn);
		Array.Sort(Cn);

		//各Bnに対して、組み合わせることができるCnの個数を記憶
		long[] CforB = new long[N];
		for(int i=0; i<N; i++){
			//Biの対象となる最小のCi
			int indC = BinarySearch.Array.UpperBound<int>(Cn, Bn[i]);
			//組める相手がいない場合、終了
			if(indC >= N){
				break;
			}

			//それ以上のCiとは全てペアを組むことが可能
			CforB[i] = (long)(N-indC);
		}

		//iでペアを組める場合、i-1でもペアを組めるので、逆順の累積和にしておく
		for(int i=N-1; i>0; i--){
			CforB[i-1] += CforB[i];
		}

		//AnとセットにできるBnを確認し、それぞれとセットにできるCnの数を加算
		long ans = 0;
		for(int i=0; i<N; i++){
			//中部の対象
			int indB = BinarySearch.Array.UpperBound<int>(Bn, An[i]);
			//組める相手がいない場合、終了
			if(indB >= N){
				break;
			}

			//当該Bn以上と組めるCnの総数を加算
			ans += CforB[indB];
		}

		//出力
		Console.WriteLine(ans);
	}
}


/*
二分探索用の名前空間
*/
namespace BinarySearch{
	//対象が配列の場合
	class Array
	{
		//LowerBound
		/*
		引数は、対象の配列と、対象の値
		当該値以上になる最初のインデックスを返す
		*/
		public static int LowerBound<T>(T[] arr, T target)
			where T : IComparable
		{
			//長さを取得
			int len = arr.Length;

			//両端を初期化
			int max = len-1;
			int min = 0;

			//二分探索（条件を満たすまで探索）
			while(max >= min){
				//中央を更新
				int mid = min + (max-min)/2;

				//midより大きい場合（target > arr[mid]）
				/*
				cf. ここがLowerとUpperとの違い
				*/
				if(target.CompareTo(arr[mid]) > 0){
						min = mid + 1;
				}
				//小さい場合
				else{
						max = mid - 1;
				}
			}

			//target以上となる最初のインデックスを出力
			return min;
		}

		//UpperBound
		/*
		引数は、対象の配列と、対象の値
		当該値より大きくなる最初のインデックスを返す
		*/
		public static int UpperBound<T>(T[] arr, T target)
			where T : IComparable
		{
			//長さを取得
			int len = arr.Length;

			//両端を初期化
			int max = len-1;
			int min = 0;

			//二分探索（条件を満たすまで探索）
			while(max >= min){
				//中央を更新
				int mid = min + (max-min)/2;

				//mid以上の場合（target >= arr[mid]）
				/*
				cf. ここがLowerとUpperとの違い
				*/
				if(target.CompareTo(arr[mid]) >= 0){
						min = mid + 1;
				}
				//小さい場合
				else{
						max = mid - 1;
				}
			}

			//targetより大きくなる最初のインデックスを出力
			return min;
		}
	}

	//対象がリストの場合
	class List{
		//LowerBound
		/*
		引数は、対象のリストと、対象の値
		当該値以上になる最初のインデックスを返す
		*/
		public static int LowerBound<T>(List<T> list, T target)
			where T : IComparable
		{
			//長さを取得
			int len = list.Count();

			//両端を初期化
			int max = len-1;
			int min = 0;

			//二分探索（条件を満たすまで探索）
			while(max >= min){
				//中央を更新
				int mid = min + (max-min)/2;

				//midより大きい場合（target > list[mid]）
				/*
				cf. ここがLowerとUpperとの違い
				*/
				if(target.CompareTo(list[mid]) > 0){
						min = mid + 1;
				}
				//小さい場合
				else{
						max = mid - 1;
				}
			}

			//target以上となる最初のインデックスを出力
			return min;
		}

		//UpperBound
		/*
		引数は、対象のリストと、対象の値
		当該値より大きくなる最初のインデックスを返す
		*/
		public static int UpperBound<T>(List<T> list, T target)
			where T : IComparable
		{
			//長さを取得
			int len = list.Count();

			//両端を初期化
			int max = len-1;
			int min = 0;

			//二分探索（条件を満たすまで探索）
			while(max >= min){
				//中央を更新
				int mid = min + (max-min)/2;

				//mid以上の場合（target >= list[mid]）
				/*
				cf. ここがLowerとUpperとの違い
				*/
				if(target.CompareTo(list[mid]) >= 0){
						min = mid + 1;
				}
				//小さい場合
				else{
						max = mid - 1;
				}
			}

			//targetより大きくなる最初のインデックスを出力
			return min;
		}
	}
}



Measured memory_bytes: 49544