#include <bits/stdc++.h>
using namespace std;

template <const int U = 1 << 30>
class vEB {

	struct node {
		int min, max;
		node *summary, **cluster;
		node() : min(U), max(-1), summary(nullptr), cluster(nullptr) {}
		~node() {
			if (summary) delete summary;
			if (cluster) delete[] cluster;
		}
	} *root;

	int cnt;

private:

	int downsqrt(int u) const {
		assert(u != 0 && (u & (u - 1)) == 0 && u > 2);
		return 1 << (__builtin_ctz(u) >> 1);
	}

	int upsqrt(int u) {
		assert(u != 0 && (u & (u - 1)) == 0 && u > 2);
		int ctz = __builtin_ctz(u);
		return 1 << ((ctz >> 1) + (ctz & 1));
	}

	int high(int x, int u) const {
		return x / downsqrt(u);
	}

	int low(int x, int u) const {
		return x % downsqrt(u);
	}

	int index(int x, int y, int u) const {
		return x * downsqrt(u) + y;
	}

	int minimum(node *v) const {
		return v ? v->min : U;
	}

	int maximum(node *v) const {
		return v ? v->max : -1;
	}

	bool member(node *v, int x, int u) const {
		if (!v) return false;
		if (v->min == x || v->max == x) return true;
		if (!v->cluster) return false;
		return member(v->cluster[high(x, u)], low(x, u), downsqrt(u));
	}

	node* new_node(int u) {
		node *v = new node();
		if (u > 2) {
			int sz = upsqrt(u);
			v->cluster = new node*[sz];
			for (int i = 0; i < sz; i++) {
				v->cluster[i] = nullptr;
			}
		}
		return v;
	}

	node* empty_insert(node *v, int x, int u) {
		if (!v) v = new_node(u);
		v->min = v->max = x;
		return v;
	}

	node* insert(node *v, int x, int u) {
		if (!v) v = new_node(u);
		if (v->min == U) {
			empty_insert(v, x, u);
			return v;
		}
		if (x < v->min) swap(x, v->min);
		if (u > 2) {
			if (minimum(v->cluster[high(x, u)]) == U) {
				v->summary = insert(v->summary, high(x, u), upsqrt(u));
				v->cluster[high(x, u)] = empty_insert(v->cluster[high(x, u)], low(x, u), downsqrt(u));
			}
			else {
				v->cluster[high(x, u)] = insert(v->cluster[high(x, u)], low(x, u), downsqrt(u));
			}
		}
		if (x > v->max) v->max = x;
		return v;
	}

	node* erase(node *v, int x, int u) {
		if (v->min == v->max) {
			v->min = U;
			v->max = -1;
			delete v;
			return nullptr;
		}
		if (u <= 2) {
			v->max = v->min = (x == 0);
			return v;
		}
		if (x == v->min) {
			int first_cluster = minimum(v->summary);
			v->min = x = index(first_cluster, minimum(v->cluster[first_cluster]), u);
		}
		v->cluster[high(x, u)] = erase(v->cluster[high(x, u)], low(x, u), downsqrt(u));
		if (minimum(v->cluster[high(x, u)]) == U) {
			v->summary = erase(v->summary, high(x, u), upsqrt(u));
			if (x == v->max) {
				int summary_max = maximum(v->summary);
				if (summary_max == -1) {
					v->max = v->min;
				}
				else {
					v->max = index(summary_max, maximum(v->cluster[summary_max]), u);
				}
			}
		}
		else if (x == v->max) {
			v->max = index(high(x, u), maximum(v->cluster[high(x, u)]), u);
		}
		return v;
	}

	int successor(node *v, int x, int u) const {
		if (u <= 2) {
			if (x == 0 && v->max == 1) return 1;
			return U;
		}
		if (v->min != U && x < v->min) return v->min;
		int max_low = maximum(v->cluster[high(x, u)]);
		if (max_low != -1 && low(x, u) < max_low) {
			return index(high(x, u), successor(v->cluster[high(x, u)], low(x, u), downsqrt(u)), u);
		}
		int succ_cluster = successor(v->summary, high(x, u), upsqrt(u));
		if (succ_cluster == U) return U;
		return index(succ_cluster, minimum(v->cluster[succ_cluster]), u);
	}

	int predecessor(node *v, int x, int u) const {
		if (u <= 2) {
			if (x == 1 && v->min == 0) return 0;
			return -1;
		}
		if (v->max != -1 && x > v->max) return v->max;
		int min_low = minimum(v->cluster[high(x, u)]);
		if (min_low != U && low(x, u) > min_low) {
			return index(high(x, u), predecessor(v->cluster[high(x, u)], low(x, u), downsqrt(u)), u);
		}
		int pred_cluster = predecessor(v->summary, high(x, u), upsqrt(u));
		if (pred_cluster == -1) {
			if (v->min != -1 && x > v->min) return v->min;
			return -1;
		}
		return index(pred_cluster, maximum(v->cluster[pred_cluster]), u);
	}

public:

	vEB() : root(nullptr), cnt(0) {}

	~vEB() { if (root) delete root; }

	int size() const {
		return cnt;
	}

	bool member(int x) const {
		return member(root, x, U);
	}

	int minimum() const {
		return minimum(root);
	}

	int maximum() const {
		return maximum(root);
	}

	void insert(int x) {
		if (!member(x)) root = insert(root, x, U), cnt++;
	}

	void erase(int x) {
		if (member(x)) root = erase(root, x, U), cnt--;
	}

	int successor(int x) const {
		return successor(root, x, U);
	}

	int predecessor(int x) const {
		return predecessor(root, x, U);
	}

};

int main()
{
	int n, q;
	cin >> n;
	vEB<> veb;
	for (int i = 0; i < n; i++) {
		int si;
		cin >> si;
		veb.insert(si);
	}
	int res = 0;
	cin >> q;
	for (int j = 0; j < q; j++) {
		int ti;
		cin >> ti;
		res += veb.member(ti);
	}
	cout << res << endl;
	return 0;
}



Measured memory_bytes: 88512