//ライブラリ
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <map>
#include <numeric>
#include <cmath>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <complex>
#include <string.h>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <iomanip>
#include <sys/time.h>
#include <tuple>
#include <random>
#include <functional>
using namespace std;

//ユーティリティ
#define rep(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define reps(i,n) for(int i=1, i##_len=(n); i<=i##_len; ++i)
#define rrep(i,n) for(int i=n-1; i>=0; --i)
#define rreps(i,n) for(int i=n; i>0; --i)
#define vmax(v) *max_element(all(v))
#define vmin(v) *min_element(all(v))
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define uniq(v) (v).erase(unique((v).begin(), (v).end()), (v).end())

template<class T>bool chmax(T &former, const T &b) {if (former<b) {former=b;return true;} return false;}
template<class T>bool chmin(T &former, const T &b) {if (former>b) {former=b;return true;} return false;}

//型
//型
typedef long long int ll;
typedef long long unsigned int ull;
typedef pair<int, int> pairi;
typedef pair<ull, ull> pairull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef priority_queue<int, vi> pq;
typedef priority_queue<int, vi, greater<int>> rpq;

//定数
#define INF (1e9+9)
#define MOD (1e9 + 7);
const double pi = (acos(-1));
const double eps = 1e-8;

//セグメント木
//データ構造
template< typename Monoid >
struct SegmentTree {
  using F = function< Monoid(Monoid, Monoid) >;
 
  int sz;
  vector< Monoid > seg;
 
  const F f;
  const Monoid M1;
 
  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while(sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }
 
  void set(int k, const Monoid &x) {
    seg[k + sz] = x;
  }
 
  void build() {
    for(int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }
 
  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }
 
  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) L = f(L, seg[a++]);
      if(b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }
 
  Monoid operator[](const int &k) const {
    return seg[k + sz];
  }
};

//グラフ
template< typename T >
struct edge {
  int src, to;
  T cost;

  edge(int to, T cost) : src(-1), to(to), cost(cost) {}

  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

  edge &operator=(const int &x) {
    to = x;
    return *this;
  }

  operator int() const { return to; }
};

template< typename T >
using Edges = vector< edge< T > >;
template< typename T >
using WeightedGraph = vector< Edges< T > >;
using UnWeightedGraph = vector< vector< int > >;
template< typename T >
using Matrix = vector< vector< T > >;

template< typename T >
void warshall_floyd(Matrix< T > &g, T inf) {
  for(int k = 0; k < g.size(); k++) {
    for(int i = 0; i < g.size(); i++) {
      for(int j = 0; j < g.size(); j++) {
        if(g[i][k] == inf || g[k][j] == inf) continue;
        g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
      }
    }
  }
}





/*
// 法の元の演算
// modを維持しながらべき乗。
ll mod_pow(ll x, ll n) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = (res * x) % mod;
        x = (x * x) % mod;
        n >>= 1;
    }
    return res;
}

// 逆元。オイラーの定理から？
// 有限体上での割り算に利用
// 3/4 = 3*(1/4) = 3x(4の逆数) = 3x3 mod 11
// 4の逆数はかけると1になるので、この場合は3
ll mod_inverse(ll x) {
    return mod_pow(x, mod-2);
}

const int fact_max_n = 1000000;
ll fact[fact_max_n];
ll fact_inv[fact_max_n];

void calc_fact() {
    fact[0] = 1;
    //階乗の算出。かける度にmodを取る。
    for (ll i = 1; i < fact_max_n; i++)
        fact[i] = (fact[i-1] * i) % mod;
    //階乗の逆元の算出。
    //1*2*3 => 1/(1*2*3)
    //1*2 => 1/(1*2*3)*3
    fact_inv[fact_max_n-1] = mod_inverse(fact[fact_max_n-1]);
    for (ll i = fact_max_n-2; i >= 0; i--) 
        fact_inv[i] = (fact_inv[i+1] * (i+1)) % mod;
}

//mod付き組み合わせ
// nCk= n!/(n-k)!k! を、modをかませながら演算
ll mod_comb(ll n, ll k) {
    if (n < 0 || k < 0 || n < k) return 0;
    return (fact[n] * fact_inv[k] % mod) * fact_inv[n-k] % mod;
}
*/

//GCD
int gcd(int a, int b) {
	while(1) {
		if (a<b) swap(a, b);
		if(!b) break;
		a %= b;
	}
	return a;
}

int gcd(const vector<int> &list) {
	int a = list[0];
	for(auto i=1; i<list.size(); i++) {
		a = gcd(a, list[i]);	
	}
	return a;
}

int N;
vll a, b, c;

void input() {
	cin >> N;
	cin.ignore();
	
	a = vll(N);
	b = vll(N);
	c = vll(N);
	
	rep(i, N) cin >> a[i];
	cin.ignore();
	rep(i, N) cin >> b[i];
	cin.ignore();
	rep(i, N) cin >> c[i];
	cin.ignore();
}

//BをN回して、小さいものの数と大きいものの数を調べる。

ll solve() {
	ll sum = 0;
	sort(all(a));
	sort(all(c));

	rep(i, N) {
		auto it = upper_bound(all(c),b[i]);
		ll high = distance(it, c.end());
		it = lower_bound(all(a), b[i]);
		ll low = N-distance(it, a.end());
		sum += high * low;
	}
	return sum;
}

int main() {
	input();
	cout << solve() << endl;
}	

Measured memory_bytes: 2560