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;

/*
より単純な解法（解説通り）
各Bについて、それより小さいAの個数と、それより大きいCの個数を計算し、
掛け合わせれば良い。
*/


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);

		//最大で(10^5)^3通り有り得るので、注意！
		long ans = 0;

		//各Bnに対して、組み合わせることができるAnの個数とCnの個数とを掛け合わせる
		for(int i=0; i<N; i++){
			//Biより小さくなる最大のAi
			int	idxA = BinarySearch.Array.LowerBound<int>(An, Bn[i]) - 1;
			if(idxA < 0){
				continue;
			}

			//Biより大きくなる最小のCi
			int idxC = BinarySearch.Array.UpperBound<int>(Cn, Bn[i]);
			if(idxC >= N){
				continue;
			}

			//組み合わせ
			long combi = (long)(idxA+1) * (long)(N - idxC);
			ans += combi;
		}

		//出力
		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: 49376