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

namespace ARC077_C
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = int.Parse(Console.ReadLine());

            Treap<int> treapA = new Treap<int>();
            {
                string[] strA = Console.ReadLine().Split(' ');
                for (int i = 0; i < n; ++i)
                {
                    treapA.Insert(int.Parse(strA[i]));
                }
            }

            Treap<int> treapB = new Treap<int>();
            {
                string[] strB = Console.ReadLine().Split(' ');
                for (int i = 0; i < n; ++i)
                {
                    treapB.Insert(int.Parse(strB[i]));
                }
            }

            Treap<int> treapC = new Treap<int>();
            {
                string[] strC = Console.ReadLine().Split(' ');
                for (int i = 0; i < n; ++i)
                {
                    treapC.Insert(int.Parse(strC[i]));
                }
            }

            long[] bigger = new long[n + 1];

            for (int i = n - 1; i >= 0; --i)
            {
                int threshold = treapB[i];

                int findIndex = treapC.FindIndex(threshold);
                if (findIndex == n) { continue; }
                while (treapC[findIndex] == threshold)
                {
                    ++findIndex;
                    if (findIndex == n) { break; }
                }
#if false
                if (treapC[findIndex] == threshold)
                {
                    findIndex = treapC.FindIndex(threshold + 1);
                    //++findIndex;
                }
#endif
                if (findIndex == n) { continue; }

                bigger[i] = (n - findIndex) + bigger[i + 1];
            }

            long count = 0;

            for (int i = 0; i < n; ++i)
            {
                int threshold = treapA[i];

                int findIndex = treapB.FindIndex(threshold);
                if (findIndex == n) { break; }
                while (treapB[findIndex] == threshold)
                {
                    ++findIndex;
                    if (findIndex == n) { break; }
                }
#if false
                if (treapB[findIndex] == threshold)
                {
                    findIndex = treapB.FindIndex(threshold + 1);
                    //++findIndex;
                }
#endif
                if (findIndex == n) { break; }

                count += bigger[findIndex];
            }

            Console.WriteLine("{0}", count);

            // int findIndex_ = treapC.FindIndex(8);
            // int threshold_ = treapC[findIndex_];
        }

        class Treap<T> where T : IComparable
        {
            private class Node
            {
                private static Random g_rand = new Random();
                private readonly int m_rank = g_rand.Next();
                private readonly T m_value;
                private Node m_lch;
                private Node m_rch;
                private int m_count;

                public Node(T value)
                {
                    m_value = value;
                    m_count = 1;
                }

                public static int Count(Node node)
                {
                    return (node != null) ? node.m_count : 0;
                }

                private Node Update()
                {
                    m_count = Count(m_lch) + Count(m_rch) + 1;
                    return this;
                }

                public static Node Merge(Node a, Node b)
                {
                    if (a == null) { return b; }
                    if (b == null) { return a; }
                    if (a.m_rank < b.m_rank)
                    {
                        a.m_rch = Merge(a.m_rch, b);
                        return a.Update();
                    }
                    else
                    {
                        b.m_lch = Merge(a, b.m_lch);
                        return b.Update();
                    }
                }

                public static Tuple<Node, Node> Split(Node t, int k)
                {
                    if (t == null) { return new Tuple<Node, Node>(null, null); }
                    if (k <= Count(t.m_lch))
                    {
                        var pair = Split(t.m_lch, k);
                        t.m_lch = pair.Item2;
                        return new Tuple<Node, Node>(pair.Item1, t.Update());
                    }
                    else
                    {
                        var pair = Split(t.m_rch, k - Count(t.m_lch) - 1);
                        t.m_rch = pair.Item1;
                        return new Tuple<Node, Node>(t.Update(), pair.Item2);
                    }
                }

                public int FindIndex(T value)
                {
                    int L = Count(m_lch);
                    if (value.CompareTo(m_value) < 0)
                    {
                        return (m_lch != null) ? m_lch.FindIndex(value) : 0;
                    }
                    else if (value.CompareTo(m_value) > 0)
                    {
                        return (m_rch != null) ? m_rch.FindIndex(value) + L + 1 : L + 1;
                    }
                    else
                    {
                        return L;
                    }
                }

                public T this[int i]
                {
                    get
                    {
                        int L = Count(m_lch);
                        if (i < L)
                        {
                            return m_lch[i];
                        }
                        else if (i > L)
                        {
                            return m_rch[i - L - 1];
                        }
                        else
                        {
                            return m_value;
                        }
                    }
                }
            }

            private Node node;

            public void Insert(T value)
            {
                if (node != null)
                {
                    int k = node.FindIndex(value);
                    var pair = Node.Split(node, k);
                    node = Node.Merge(Node.Merge(pair.Item1, new Node(value)), pair.Item2);
                }
                else
                {
                    node = new Node(value);
                }
            }

            public void Erase(T value)
            {
                if (node != null)
                {
                    int k = node.FindIndex(value);
                    var pair = Node.Split(node, k);
                    var pair2 = Node.Split(pair.Item2, 1);
                    node = Node.Merge(pair.Item1, pair2.Item2);
                }
            }

            public int Count()
            {
                return Node.Count(node);
            }

            /// <summary>
            /// 値がvalueなインデックスを返す
            /// valueが無いときは、value以上の値で一番小さいやつのインデックスを返す
            /// valueが全ての値よりも大きい場合は、インデックスはノードの個数を返す。
            /// （存在するインデックスよりもひとつ大きな値（＝ノードの個数の値）を返す）
            /// ※↑のインデックスで、treap[index]として参照しようとすると配列の範囲外アクセスで例外で止まってしまうので注意。
            /// ※もし、値がvalueなノードが複数ある場合、どのノードのindexが返るか不定なので注意。
            /// </summary>
            /// <param name="value"></param>
            /// <returns></returns>
            public int FindIndex(T value)
            {
                return node.FindIndex(value);
            }

            public T this[int i]
            {
                get
                {
                    return node[i];
                }
            }
        }

    }
}


Measured memory_bytes: 51600