#include<bits/stdc++.h>
#define fo(i, a, b) for (Re int i = (a); i <= (b); ++i)
#define fd(i, a, b) for (Re int i = (a); i >= (b); --i)
#define edge(i, u) for (Re int i = head[u], v = e[i].v; i; i = e[i].nxt, v = e[i].v)
#define N 50005
#define Re register
#define pb push_back
#define F first
#define S second
#define ll long long
#define inf 1000000007
#define mp std::make_pair
#define lowbit(x) (x & -x)
#define ls (k << 1)
#define rs (k << 1 | 1)
#define mod 1000000007
int n, k;
int a[N][5], tmp2[N][5], tmp3[N][5], c[N], ans;
inline void add (int x, int val) {for (Re int i = x; i <= n; i += lowbit(i)) c[i] += val;}
inline int query (int x) {Re int ret = 0; for (Re int i = x; i; i -= lowbit(i)) ret += c[i]; return ret;}
inline void cdq3 (int l, int r, int mid1)//第二维是有序的，当前排序第三维，并且按照类似三维偏序的写法计算贡献
{
if (l == r) return;
int mid = l + r >> 1;
cdq3(l, mid, mid1); cdq3(mid + 1, r, mid1);
int L = l, R = mid + 1, i = l;
while (L <= mid && R <= r)
{
if (tmp2[L][3] < tmp2[R][3])
{
if (tmp2[L][1] <= mid1)
memcpy(tmp3[i++], tmp2[L++], sizeof tmp2[L]);
}
else
{
if (mid1 < tmp2[R][1])
ans += query(tmp2[R][4]);
memcpy(tmp3[i++], tmp2[R++], sizeof tmp2[R]);
}
}
int upL = L - 1;//前面有多少 L 被加到树状数组里了
while (L <= mid)
{
memcpy(tmp3[i++], tmp2[L++], sizeof tmp2[L]);
}
while (R <= r)
{
if (mid1 < tmp2[R][1])
ans += query(tmp2[R][4]);
memcpy(tmp3[i++], tmp2[R++], sizeof tmp2[R]);
}
fo (i, l, upL)//清空树状数组
if (tmp2[i][1] <= mid1)
fo (i, l, r) memcpy(tmp2[i], tmp3[i], sizeof tmp3[i]);
}
inline void cdq2 (int l, int r)//第一维现在是有序的，我们给第一维重标号，然后给第二维排序
{
if (l == r) return;
int mid = l + r >> 1;
int mid1 = a[mid][1];//用记录第一维最中间的值来重标号，减少复杂度
cdq2(l, mid); cdq2(mid + 1, r);
int L = l, R = mid + 1, i = l;
while (L <= mid && R <= r)
{
if (a[L][2] < a[R][2])
{
memcpy(tmp2[i++], a[L++], sizeof a[L]);
}
else
{
memcpy(tmp2[i++], a[R++], sizeof a[R]);
}
}
while (L <= mid)
memcpy(tmp2[i++], a[L++], sizeof a[L]);
while (R <= r)
memcpy(tmp2[i++], a[R++], sizeof a[R]);
fo (i, l, r) memcpy(a[i], tmp2[i], sizeof a[i]);//当前第二维是有序的，并且第一维小于等于 mid1 的值是更新值，大于 mid1 的值是查询值
cdq3(l, r, mid1);
}
int main ()
{
//  freopen("partial_order.in", "r", stdin);
//  freopen("partial_order.out", "w", stdout);
scanf("%d", &n);
k = 4;
fo (i, 1, n)
{
a[i][1] = i;
scanf("%d", &a[i][2]);
}
fo (i, 1, n) scanf("%d", &a[i][3]);
fo (i, 1, n) scanf("%d", &a[i][4]);
cdq2(1, n);
printf("%d\n", ans);
return 0;
}


#include<bits/stdc++.h>
#define fo(i, a, b) for (R int i = (a); i <= (b); ++i)
#define fd(i, a, b) for (R int i = (a); i >= (b); --i)
#define edge(i, u) for (R int i = head[u], v = e[i].v; i; i = e[i].nxt, v = e[i].v)
#define N 40005
#define R register
#define pb push_back
#define F first
#define S second
#define ll long long
#define inf 1000000007
#define mp std::make_pair
#define lowbit(x) (x & -x)
#define ls (k << 1)
#define rs (k << 1 | 1)
#define mod 1000000007
int n, k, sq, pre[205], suf[205], sum, t[8][N], c, bl[N + 233], up;
using namespace std;
pair<int, int> a[8][N];
bitset<N> b[8][205], now, ans;
int main ()
{
freopen("partial_order_plus.in", "r", stdin);
freopen("partial_order_plus.out", "w", stdout);
scanf("%d %d", &n, &k);
++k;
fo (j, 1, n) a[1][j] = mp(t[1][j] = j, j);
fo (i, 2, k)
fo (j, 1, n)
{
scanf("%d", &a[i][j].F);
t[i][j] = a[i][j].F;
a[i][j].S = j;
}
sq = (int) 500;
up = n / sq;
while (up * sq < n) ++up;
fo (i, 1, up)
{
pre[i] = (i - 1) * sq + 1;
suf[i] = i * sq;
fo (j, pre[i], suf[i]) bl[j] = i;
}
fo (i, 1, k) sort(a[i] + 1, a[i] + n + 1);
suf[up] = n;
fo (i, 1, k)
{
fo (j, 1, up)
{
b[i][j] = b[i][j - 1];//求前缀并
fo (k, pre[j], suf[j])
b[i][j].set(a[i][k].S);
}
}
fo (I, 1, n)
{
ans.set();
fo (i, 1, k)
{
int pos = lower_bound(a[i] + 1, a[i] + n + 1, mp(t[i][I], inf)) - a[i] - 1;//当前点该维度在当前维度前有多少个数
now = b[i][bl[pos] - 1];
fo (j, pre[bl[pos]], pos)
now.set(a[i][j].S);
ans &= now;
}
sum += ans.count() - 1;//减掉自己
}
printf("%d\n", sum);
return 0;
}