This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <stdio.h>
#define N	100000
#define N_	5000
int max(int a, int b) { return a > b ? a : b; }
unsigned int X = 12345;
int rand_() {
	return (X *= 3) >> 1;
}
int aa[N];
void sort(int *ii, int l, int r) {
	while (l < r) {
		int i = l, j = l, k = r, i_ = ii[l + rand_() % (r - l)], tmp;
		while (j < k)
			if (aa[ii[j]] == aa[i_])
				j++;
			else if (aa[ii[j]] < aa[i_]) {
				tmp = ii[i], ii[i] = ii[j], ii[j] = tmp;
				i++, j++;
			} else {
				k--;
				tmp = ii[j], ii[j] = ii[k], ii[k] = tmp;
			}
		sort(ii, l, i);
		l = k;
	}
}
int ft[N];
void update(int i, int n, int x) {
	while (i < n) {
		ft[i] = max(ft[i], x);
		i |= i + 1;
	}
}
int query(int i) {
	int x = 0;
	while (i >= 0) {
		x = max(x, ft[i]);
		i &= i + 1, i--;
	}
	return x;
}
int main() {
	static int bb[N], qu[N], pp[N], qq[N], ii[N], dp[N_][N_];
	int n, cnt, i, j, b, k, lower, upper, same, good;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
		scanf("%d", &aa[i]);
	for (i = 0; i < n; i++)
		scanf("%d", &bb[i]);
	same = 1;
	for (i = 1; i < n; i++)
		if (bb[i] != bb[i - 1]) {
			same = 0;
			break;
		}
	if (same) {
		b = bb[0], k = 0;
		for (i = 0; i < n; i++)
			if (aa[i] <= b) {
				j = i;
				good = 0;
				while (j < n && aa[j] <= b)
					if (aa[j++] == b)
						good = 1;
				if (good)
					k += j - i;
				i = j;
			}
		printf("%d\n", k);
		return 0;
	}
	cnt = 0;
	for (i = 0; i < n; i++) {
		while (cnt && aa[qu[cnt - 1]] <= aa[i])
			cnt--;
		pp[i] = cnt ? qu[cnt - 1] : -1;
		qu[cnt++] = i;
	}
	cnt = 0;
	for (i = n - 1; i >= 0; i--) {
		while (cnt && aa[qu[cnt - 1]] <= aa[i])
			cnt--;
		qq[i] = cnt ? qu[cnt - 1] : n;
		qu[cnt++] = i;
	}
	if (n <= N_) {
		for (i = 0; i < n; i++)
			for (j = 0; j < n; j++)
				dp[i][j] = max(i == 0 ? 0 : dp[i - 1][j], (j == 0 ? 0 : dp[i][j - 1]) + (aa[i] == bb[j] && pp[i] < j && j < qq[i] ? 1 : 0));
		printf("%d\n", dp[n - 1][n - 1]);
	} else {
		for (i = 0; i < n; i++)
			ii[i] = i;
		sort(ii, 0, n);
		for (j = 0; j < n; j++) {
			lower = -1, upper = n;
			while (upper - lower > 1) {
				i = (lower + upper) / 2;
				if (aa[ii[i]] <= bb[j])
					lower = i;
				else
					upper = i;
			}
			if (lower >= 0 && aa[i = ii[lower]] == bb[j] && pp[i] < j && j < qq[i])
				update(i, n, query(i) + 1);
		}
		printf("%d\n", query(n - 1));
	}
	return 0;
}
Compilation message (stderr)
exam.c: In function 'main':
exam.c:58:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
   58 |  scanf("%d", &n);
      |  ^~~~~~~~~~~~~~~
exam.c:60:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
   60 |   scanf("%d", &aa[i]);
      |   ^~~~~~~~~~~~~~~~~~~
exam.c:62:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
   62 |   scanf("%d", &bb[i]);
      |   ^~~~~~~~~~~~~~~~~~~| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |