#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int n, m, b[N];
struct node {
  int x, l, r;
  int Max;
} tree[N << 2];
struct Node {
  int x, y, z, w;
} a[N];
bool cmp1(Node a, Node b) { return a.y < b.y; }
bool cmp2(Node a, Node b) { return a.x > b.x; }
void pushup(int x) { tree[x].Max = max(tree[x * 2].Max, tree[x * 2 + 1].Max); }
void build(int x, int l, int r) {
  tree[x].l = l;
  tree[x].r = r;
  if (tree[x].l == tree[x].r) {
    tree[x].Max = -1;
    return;
  }
  int mid = (l + r) / 2;
  build(x * 2, l, mid);
  build(x * 2 + 1, mid + 1, r);
  pushup(x);
}
void update(int x, int p, int z) {
  int L = tree[x].l, R = tree[x].r;
  int mid = (L + R) / 2;
  if (L == R) {
    tree[x].Max = max(z, tree[x].Max);
    return;
  }
  if (p <= mid) update(2 * x, p, z);
  if (p > mid) update(2 * x + 1, p, z);
  pushup(x);
}
int query(int x, int l, int r) {
  int MAX = -1;
  int L = tree[x].l, R = tree[x].r;
  int mid = (L + R) / 2;
  if (l <= L && R <= r) return tree[x].Max;
  if (l <= mid) MAX = max(MAX, query(x * 2, l, r));
  if (r > mid) MAX = max(MAX, query(x * 2 + 1, l, r));
  return MAX;
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) scanf("%d", &a[i].x);
  for (int i = 0; i < n; i++) scanf("%d", &a[i].y);
  for (int i = 0; i < n; i++) scanf("%d", &a[i].z);
  sort(a, a + n, cmp1);
  for (int i = 0; i < n; i++) {
    if (i == 0 || a[i].y != a[i - 1].y) {
      a[i].w = ++m;
    } else
      a[i].w = m;
  }
  build(1, 1, m);
  sort(a, a + n, cmp2);
  int tot = 0, j;
  for (int i = 0; i < n; i = j) {
    for (j = i; j < n && a[j].x == a[i].x; j++) {
      if (a[j].z < query(1, a[j].w + 1, m)) tot++;
    }
    for (j = i; j < n && a[j].x == a[i].x; j++) {
      update(1, a[j].w, a[j].z);
    }
  }
  printf("%d\n", tot);
  return 0;
}
